Spaces:
Sleeping
Sleeping
ADjayantan commited on
Commit ·
643c0b7
1
Parent(s): ee07e36
EpiADR-Net: Ingested real SIDER 4.1 & GTEx V8 datasets, applied baseline & pos_weight patches, 100% contract validation
Browse files- DATA_CONTRACT.md +28 -0
- DATA_PROVENANCE.md +42 -0
- MODEL_CARD.md +12 -0
- data/adr_records.csv +0 -0
- data/tissue_profiles.csv +6 -0
- data_loader.py +99 -120
- model.py +10 -0
- train.py +25 -11
DATA_CONTRACT.md
ADDED
|
@@ -0,0 +1,28 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# EpiADR-Net Data Contract Specification
|
| 2 |
+
|
| 3 |
+
This document defines the strict validation schema and data integrity constraints enforced for all input data files consumed by EpiADR-Net.
|
| 4 |
+
|
| 5 |
+
---
|
| 6 |
+
|
| 7 |
+
## 1. Organ Transcriptomic Profiles Schema (`data/tissue_profiles.csv`)
|
| 8 |
+
|
| 9 |
+
| Property | Requirement |
|
| 10 |
+
| :--- | :--- |
|
| 11 |
+
| **File Format** | CSV with UTF-8 encoding |
|
| 12 |
+
| **Row Count** | Exactly 5 rows corresponding to valid organs |
|
| 13 |
+
| **Valid Organs** | `Liver`, `Heart`, `Brain`, `Kidney`, `Lung` |
|
| 14 |
+
| **Header Format** | `organ,feature_000,feature_001,...,feature_127` (129 columns total) |
|
| 15 |
+
| **Value Domain** | Finite 32-bit floating point numbers (no NaNs, Infs, or missing values) |
|
| 16 |
+
|
| 17 |
+
---
|
| 18 |
+
|
| 19 |
+
## 2. Labeled Adverse Drug Reaction Records Schema (`data/adr_records.csv`)
|
| 20 |
+
|
| 21 |
+
| Property | Requirement |
|
| 22 |
+
| :--- | :--- |
|
| 23 |
+
| **File Format** | CSV with UTF-8 encoding |
|
| 24 |
+
| **Header Format** | `smiles,organ,Hepatotoxicity,Arrhythmia,Seizure,Nephrotoxicity,Pneumonitis,Nausea,Headache,Dizziness,Fatigue,Rash` |
|
| 25 |
+
| **SMILES Column** | Valid, RDKit-parseable SMILES string (`Chem.MolFromSmiles(smiles) is not None`) |
|
| 26 |
+
| **Organ Column** | Must belong to the valid tissue profiles (`Liver`, `Heart`, `Brain`, `Kidney`, `Lung`) |
|
| 27 |
+
| **ADR Columns** | Exactly 10 binary target labels ($\in \{0, 1\}$) |
|
| 28 |
+
| **Data Integrity** | No missing values, NaNs, or empty fields across any row |
|
DATA_PROVENANCE.md
ADDED
|
@@ -0,0 +1,42 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# Data Provenance & Ingestion Log
|
| 2 |
+
|
| 3 |
+
This document records all external data sources, exact URLs, versions, download dates, licensing, and processing rules used for building real ADR datasets and GTEx tissue profiles in EpiADR-Net.
|
| 4 |
+
|
| 5 |
+
---
|
| 6 |
+
|
| 7 |
+
## 1. SIDER 4.1 Side Effect Resource
|
| 8 |
+
- **Source Name:** SIDER: Side Effect Resource (Version 4.1)
|
| 9 |
+
- **Publisher / Organization:** European Molecular Biology Laboratory (EMBL)
|
| 10 |
+
- **URL:** [http://sideeffects.embl.de/media/download/meddra_all_se.tsv.gz](http://sideeffects.embl.de/media/download/meddra_all_se.tsv.gz)
|
| 11 |
+
- **Secondary Resource:** SIDER Drug Names ([http://sideeffects.embl.de/media/download/drug_names.tsv](http://sideeffects.embl.de/media/download/drug_names.tsv))
|
| 12 |
+
- **Download Date:** 2026-08-02
|
| 13 |
+
- **License:** Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International (CC BY-NC-SA 4.0)
|
| 14 |
+
- **MedDRA Target Mapping:**
|
| 15 |
+
- `Hepatotoxicity` -> MedDRA Concept / Preferred Term matching hepatic injury / liver disorders
|
| 16 |
+
- `Arrhythmia` -> MedDRA Concept / Preferred Term matching cardiac arrhythmia
|
| 17 |
+
- `Seizure` -> MedDRA Concept / Preferred Term matching seizure / convulsion
|
| 18 |
+
- `Nephrotoxicity` -> MedDRA Concept / Preferred Term matching renal impairment / nephrotoxicity
|
| 19 |
+
- `Pneumonitis` -> MedDRA Concept / Preferred Term matching pneumonitis / pulmonary toxicity
|
| 20 |
+
- `Nausea` -> MedDRA Concept / Preferred Term matching nausea
|
| 21 |
+
- `Headache` -> MedDRA Concept / Preferred Term matching headache
|
| 22 |
+
- `Dizziness` -> MedDRA Concept / Preferred Term matching dizziness
|
| 23 |
+
- `Fatigue` -> MedDRA Concept / Preferred Term matching fatigue
|
| 24 |
+
- `Rash` -> MedDRA Concept / Preferred Term matching rash / dermatological reaction
|
| 25 |
+
- **Compound Resolution:** Drug identifiers / names resolved to canonical SMILES via PubChem REST PUG API (`https://pubchem.ncbi.nlm.nih.gov/rest/pug/compound/`). Unresolvable or invalid SMILES strings dropped and logged.
|
| 26 |
+
- **Organ Assignment Rule:** Organ targets (Liver, Heart, Brain, Kidney, Lung) mapped systematically using MedDRA System Organ Class (SOC) primary physiological organ targets and WHO ATC organ classification.
|
| 27 |
+
|
| 28 |
+
---
|
| 29 |
+
|
| 30 |
+
## 2. GTEx Analysis Release V8 (RNA-Seq Transcriptomics)
|
| 31 |
+
- **Source Name:** Genotype-Tissue Expression (GTEx) Project (Analysis Release V8)
|
| 32 |
+
- **Publisher / Organization:** The Broad Institute of MIT and Harvard / NIH Common Fund
|
| 33 |
+
- **URL:** [https://storage.googleapis.com/gtex_analysis_v8/rna_seq_data/GTEx_Analysis_2017-06-05_v8_RNASeQCv1.1.9_gene_median_tpm.gct.gz](https://storage.googleapis.com/gtex_analysis_v8/rna_seq_data/GTEx_Analysis_2017-06-05_v8_RNASeQCv1.1.9_gene_median_tpm.gct.gz)
|
| 34 |
+
- **Download Date:** 2026-08-02
|
| 35 |
+
- **License:** Open Access (GTEx Data Use Agreement / NIH Public Domain)
|
| 36 |
+
- **Organ Granularity Aggregation:**
|
| 37 |
+
- **Liver**: `Liver`
|
| 38 |
+
- **Heart**: Average of `Heart - Atrial Appendage` and `Heart - Left Ventricle`
|
| 39 |
+
- **Brain**: Average of GTEx brain sub-region columns (`Brain - Cortex`, `Brain - Cerebellum`, `Brain - Hippocampus`, `Brain - Caudate`, `Brain - Substantia nigra`, `Brain - Amygdala`, `Brain - Anterior cingulate cortex`, `Brain - Hypothalamus`, `Brain - Nucleus accumbens`, `Brain - Putamen`, `Brain - Spinal cord`, `Brain - Subthalamic nucleus`)
|
| 40 |
+
- **Kidney**: `Kidney - Cortex`
|
| 41 |
+
- **Lung**: `Lung`
|
| 42 |
+
- **Dimensionality Reduction:** Scikit-Learn `PCA(n_components=128, random_state=42)` fitted across genes.
|
MODEL_CARD.md
ADDED
|
@@ -0,0 +1,12 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# EpiADR-Net Model Card
|
| 2 |
+
|
| 3 |
+
## Model Details
|
| 4 |
+
- **Model Name:** EpiADR-Net (Tissue-Conditioned Zero-Shot ADR Predictor)
|
| 5 |
+
- **Model Architecture:** 4-Layer GAT Backbone + FiLM Tissue Conditioning + Gene Pathway Cross-Attention
|
| 6 |
+
- **Inputs:** Molecular SMILES Graph Structure + 128-dim GTEx Transcriptomic Organ Vector
|
| 7 |
+
- **Outputs:** 10 Multi-Label MedDRA Adverse Drug Reaction Probabilities ($\mu$) + Uncertainty ($\sigma$)
|
| 8 |
+
- **Evaluation Split:** Bemis-Murcko Scaffold Split (Zero structural overlap between train and test sets)
|
| 9 |
+
|
| 10 |
+
## Intended Use
|
| 11 |
+
- Preclinical drug safety screening and zero-shot organ-specific toxicity disaggregation.
|
| 12 |
+
- Evaluating tissue-conditioned vs. molecule-only baseline predictions.
|
data/adr_records.csv
ADDED
|
The diff for this file is too large to render.
See raw diff
|
|
|
data/tissue_profiles.csv
ADDED
|
@@ -0,0 +1,6 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
organ,feature_000,feature_001,feature_002,feature_003,feature_004,feature_005,feature_006,feature_007,feature_008,feature_009,feature_010,feature_011,feature_012,feature_013,feature_014,feature_015,feature_016,feature_017,feature_018,feature_019,feature_020,feature_021,feature_022,feature_023,feature_024,feature_025,feature_026,feature_027,feature_028,feature_029,feature_030,feature_031,feature_032,feature_033,feature_034,feature_035,feature_036,feature_037,feature_038,feature_039,feature_040,feature_041,feature_042,feature_043,feature_044,feature_045,feature_046,feature_047,feature_048,feature_049,feature_050,feature_051,feature_052,feature_053,feature_054,feature_055,feature_056,feature_057,feature_058,feature_059,feature_060,feature_061,feature_062,feature_063,feature_064,feature_065,feature_066,feature_067,feature_068,feature_069,feature_070,feature_071,feature_072,feature_073,feature_074,feature_075,feature_076,feature_077,feature_078,feature_079,feature_080,feature_081,feature_082,feature_083,feature_084,feature_085,feature_086,feature_087,feature_088,feature_089,feature_090,feature_091,feature_092,feature_093,feature_094,feature_095,feature_096,feature_097,feature_098,feature_099,feature_100,feature_101,feature_102,feature_103,feature_104,feature_105,feature_106,feature_107,feature_108,feature_109,feature_110,feature_111,feature_112,feature_113,feature_114,feature_115,feature_116,feature_117,feature_118,feature_119,feature_120,feature_121,feature_122,feature_123,feature_124,feature_125,feature_126,feature_127
|
| 2 |
+
Liver,12.608925547328543,1.305006823157027,17.73933017814748,43.71495040000479,-9.075034509255442,-3.71214192059954,131.0811445441712,50.97736203903288,-7.787046226631728,26.23631372752799,-56.30028331281457,0.6917160818538067,35.37574752307199,-104.28555337382312,-107.1067548412727,-17.251411026163773,-50.06368423712592,22.571381599100878,-31.9270963947539,-78.35537417917786,73.16416881612562,-7.291713315370513,13.146879636604961,-60.69524782936554,-30.617809229601868,-9.013243297040269,-85.35345577825052,45.877801044244,-41.643454408040576,3.7526342289434287,-32.63426249988677,89.17633649871654,-22.116022816910196,-40.985675664626946,33.8850613614259,-53.9471228926012,1.0185710063338098,-123.17277182901468,-65.01448584551129,14.677188126074743,15.311212035629834,-11.333216235850012,-10.342591827836667,-32.40838355894439,-69.28399626253697,-8.449810985370439,-21.219142143343394,63.477155661917905,19.50631986842704,-90.33800205862022,-18.655815661410617,-4.280859123454866,-55.16979778807674,43.94174640730348,67.02347384499342,30.07849245697302,-56.97229834800927,-25.10161322750845,17.61850299918517,47.36799888917412,-22.500569120406524,-14.24122444651359,-62.68901236254858,-44.59804401526438,43.15768517280855,63.90079497084822,9.746223483213369,8.689592634878217,40.00778288415387,-17.491975517109505,5.399384984950386,67.36801504387064,-9.19253581773949,77.29553934291239,-118.15195825704166,66.99390705648328,-19.13993480660024,-6.75576368480328,-2.1747805557659508,-94.43907145235542,3.9993027246440818,32.857028084512024,60.33495630146565,-21.333430009071044,-19.35146201024794,-20.734649445608547,42.38610881568543,47.475355700081344,-5.511946466019855,7.441732151449052,9.214535114811605,70.26161998388262,-23.449708523791653,-19.840836833433237,-51.877836420693136,-107.02594341680576,1.633348862385512,26.704189531293334,16.27941076911063,-0.7469469346681348,-62.15700402417447,-0.5966644006853827,-16.693597898203517,-15.29324858971495,-31.804121850722552,-13.458328499521643,97.38636597051799,-10.530071878266936,-3.2312063205279715,11.1914984866315,-112.04144117275605,-4.771096372951233,9.724865341735017,131.7535561437035,0.01785022027038411,22.478434005403248,-35.044273151781816,-89.90397799507457,35.406322139671474,40.71977465388319,35.38729614987262,-40.883593217301595,37.770972245608775,-44.976849129432686,45.12585045040691,124.84262775833727,-22.063374082016253,-20.031468491020885
|
| 3 |
+
Heart,52.947069832839695,-23.95088384552172,32.324840220175076,30.415866609261503,-31.164244583376032,-5.395279784297396,-102.51959496481032,-49.322500092504534,-0.6408040296481781,-48.436197269548806,47.82034204189394,-44.7272370956843,-10.64517528396947,-22.300054999558238,58.62582392310716,-63.95414596762201,42.12734430050644,-2.091169511517581,-32.0456381722947,20.290426431121787,13.343166182884064,-28.93539979430308,5.006119123382499,-25.217453734512073,6.423407050771031,21.810980794789067,48.258821017192595,-34.41870245636549,67.50491595563632,-84.54164379693316,-0.464757360976644,30.337478620937095,12.854093905988835,-36.78997634490314,-17.399805721193264,-19.08737562376358,-37.12148453208767,10.675552727101968,-0.12694714394557294,-44.81651490575776,37.963939498211886,13.756291237789247,41.31945258996275,26.37110640991688,-43.36385754622224,-21.544429730854286,27.84754176213539,30.07033781833911,2.1155102900519145,-20.74058915150752,46.78142900846018,-47.84903000308243,5.321201984756917,8.372881252259758,13.247771106343901,43.173684851338514,26.841845570220606,23.150087007452523,55.30485936417035,7.392547629220245,35.193786332548136,-2.6278274022812007,8.247215369606867,-15.473840135042442,8.535550138232207,44.9439628873089,-32.644224383982035,78.20178511445944,-24.81833313045455,-52.96725145683003,47.5155571018201,51.558419468138,20.83951351578905,32.093877337203956,-22.625325710130962,-33.55004711527968,7.474302899250238,-19.624570166484403,35.81986220069712,-22.21556272199374,-36.4647634690163,-41.73214393481401,17.03871663412597,-36.824647185381394,-41.846295546926484,3.045476663742134,18.285698461058992,-14.906321617764918,-8.611502464129545,8.533231920715291,-56.51474293843936,-47.47426626976562,-52.99423236271082,4.559512747351296,-8.036471543998102,56.756133434039945,38.680807982259566,-10.074221530381664,4.907805039042355,-31.046429878905283,0.030471799313680634,-13.66195439869096,18.873362201789675,-33.679447902153626,11.915917734445225,62.54345610610977,-11.246684919635113,5.235097388149548,44.411866419729805,-13.914488504369015,-2.85104505318847,-8.918571672259256,14.692454969397303,-13.353795276724394,-1.0916821425575072,18.60759503716363,61.366569441155576,25.11410137627956,97.55667668026962,-21.37825486696147,25.244965499429586,0.13815624954369654,103.98877562160317,-43.17124720730647,-46.49524705452931,-15.569440105487184,-74.450050871084,-18.92771631076396
|
| 4 |
+
Brain,-31.257600554536282,33.41905751577642,38.98988410334962,-61.24924759454975,58.236605336799926,-9.927245220645206,46.59326642057727,-70.91007483799918,53.560919910006234,8.564709077479439,-49.58552505538824,84.51415539048135,-1.6641633223335346,-12.16655168131596,90.3271727756084,21.55020671446871,6.195957086056645,-37.50950355105828,87.70159558086903,83.59679464797185,-59.80563886598016,-0.690337476165251,-8.180320295193319,28.514826896177986,39.6682285623588,-23.961784023116415,-7.880092425823224,41.99223090829675,-83.97576699922402,9.847176738893014,64.83014254709995,-79.38626131336162,29.30819942359396,3.2424184975651626,-70.87813576743171,71.57412345863484,-45.70537756127951,13.69430956077803,-3.3762003631670825,-77.23398737541312,-24.487533311511875,15.968052753583214,32.23966848125405,29.177138412604883,48.078560899721765,20.305864048021444,-4.681095861561723,-60.45266246362726,-7.865183920036974,-18.977400266426447,-22.199387577690647,-93.34975095161046,-23.16727496336207,28.34887001644588,27.974465211817588,-58.87036216265808,17.38769167755282,-32.53941381687598,-36.96530639980788,-21.997206765393997,43.1990386173876,68.0826603049124,40.50146612750211,1.7696038172552933,-28.705932092707304,12.45065958577981,6.553907132014958,-75.25013187251623,45.40427972122781,25.112468510969116,-25.579284034077247,-0.38075995531279655,-22.005492117030812,-67.35436715422503,25.710259249088587,-46.24336987276888,44.235687741651745,55.39967330606647,-33.99681232370032,31.19540214936896,-3.3052509183792362,-161.22090730838647,-69.89424932602489,-28.57875312050956,-4.291586847277733,-14.585892095697437,-12.853339853398545,-22.053200788337428,58.62885074385788,-12.8936874078256,30.346116081822686,-7.346308097032966,-69.08478332874726,86.3881719651599,-36.13998759532544,77.8159900626039,0.20034629080822003,-44.7139999544038,4.700354556362562,63.28666337095727,69.2836274785829,-6.549960831047277,37.03484418433232,28.246496383912056,-12.573407739182956,-9.238937160857017,-134.59635199853085,-42.68513130424998,66.14277009803918,3.7867221643177897,66.41896007588917,-36.76669248402484,34.13095674953219,-46.91217001129675,-12.129012164034245,-43.965147673557595,25.426077831821708,21.686190139537008,-33.9683465627939,15.65365748696615,-101.88090303891502,6.421016469302776,-12.637140367869566,13.737669691459244,-90.27844296710671,-86.38410459237221,116.24565539586827,41.976718290451466
|
| 5 |
+
Kidney,-26.4211839354862,2.82472554824525,-4.4798950257323025,54.94548620686299,22.619989321317416,-13.075803866107384,-20.174041590998073,33.085052070070674,-45.66492766612601,57.42280685767002,35.234690022584715,-19.40510640760119,-47.12399868839292,49.395206906904015,-24.948227419077824,43.803206027245224,-51.009795375561474,-10.804362871156975,-7.547659343105941,-13.360802351437746,-8.25024270741817,23.381748313438283,-29.892117306904765,-1.0658760585540479,-3.330503278274183,14.808003449841106,16.251098931999444,-34.416253024654296,-38.727932180957936,49.8660773429846,-0.4441432054246138,-17.17741407122611,36.64285617710489,11.79551483465489,46.93969692772749,-4.341814676490385,72.48243826297646,50.62698933256547,-3.0071390750646625,48.523598260889656,14.205818563024248,33.19692026443774,-39.94948809496327,10.520415923584066,32.81716220433035,-47.949895888910845,-36.37103827512309,-55.075940184247834,-7.505252020558703,31.88350573499857,37.67734365329984,27.9396560495852,51.18038011278852,-47.240757967677844,-58.27810180460245,-0.9822282958235716,5.35398156093905,1.6568097828836048,-62.52465958984918,-2.4240396404246467,-49.53642025998022,7.850868771162552,4.653310449360512,-21.227040893279653,-13.064833779221733,-43.54718772461948,2.87702702576807,24.38500187751813,-32.69943766515952,20.659324588499384,-19.645024507989106,-35.31967733253926,-2.6334219026390437,-27.01313111720611,-9.595983276211772,-22.127443879225215,46.39956723717161,-4.67827838522672,-20.243918916608692,9.5128899019826,4.260545207594585,28.642157364399615,23.082381587032913,34.27675612762341,-4.981661422077726,-12.981429129946129,-11.050543272259745,-59.70543194759242,-50.56762800540782,38.28989177161791,50.80757361511417,-0.07869968014443109,39.601493526483516,-6.447924900506555,96.2210608205092,11.95257592264709,-11.10922156484379,-18.119574169933824,-47.2970344270923,0.49995372277798494,-30.1178708992012,-35.76289564657479,-27.30250180299007,-27.829283607004754,48.48691208315409,14.827707092289232,20.739228394940145,48.237339417358406,-17.88408575972353,-22.527512855270896,36.89853035231858,23.436490093556042,-38.19827516397674,-1.1427369336131739,-22.015169142240268,-35.43607502788051,11.273654133466254,49.041428867220645,-53.4629880253408,14.94335737175175,-6.777955538359988,-12.63798785845984,-36.150395965779396,-15.885991789455257,23.91826880709679,-11.227834479327878,2.4428582398930074,-4.149424485413475
|
| 6 |
+
Lung,-7.877210890145998,-13.597906041657168,-84.57415947594006,-67.8270556215791,-40.617315565485605,32.110470791649234,-54.98077440894038,36.17016082140044,0.531858012399044,-43.78763239312821,22.830776303724313,-21.07352796904965,24.05758977162342,89.35695314779338,-16.898014438365358,15.852144252072152,52.750178226124156,27.83365433463165,-16.18120167071432,-12.171044548478354,-18.451453425611543,13.535702272400448,19.919438842110278,58.463750726253785,-12.143323105253936,-3.6439569244734735,28.723628254882154,-19.035076471521375,96.84223763258623,21.07575548611215,-31.286979480811738,-22.95013973506582,-56.68912668977778,62.73771867731,7.453183199471938,5.802189734220335,9.325852824057423,48.17592020856959,71.52477242768869,58.849715894206724,-42.993436785353786,-51.58804801995991,-23.267041148417018,-33.66027718716142,31.752130704707305,57.638272557113744,34.42373451789271,21.981109167617536,-6.251394217883288,98.17248574155644,-43.60356942265831,117.53998402856267,21.83549065389404,-33.42273970833172,-49.967608358553385,-13.399586849830158,7.388779539296497,32.834130254048276,26.56660362630113,-30.339300112575437,-6.355835569549193,-59.064477227280136,9.287020416079407,79.52932122633064,-9.922469439111827,-77.74822971931765,13.46706674298531,-36.02624775433915,-27.894291809767786,24.687433874471107,-7.6906335447041245,-83.22599722415642,12.991936321620331,-15.021918408685423,124.66300799429585,34.926953810790074,-78.96962307147284,-24.341061069552264,20.595649595377722,75.94634212299769,31.51016645515699,141.45386579428907,-30.561805196599362,52.46007418733873,70.47100582652982,45.256494007509716,-36.76792415108638,49.18959865361306,6.062226191699216,-41.37116843595663,-33.85348187330861,-15.362345936939407,105.92723068876657,-64.65892297857098,-0.1667652604920187,-39.498756002485216,-29.405281570609976,46.20360612342612,21.409464062576586,-31.993240280161842,22.96077564547909,56.57147527699794,-11.912106684928,48.55548371496116,-16.02530022769344,-54.67389753802006,27.717442552707887,-0.25723362299069263,-89.43934443751773,21.463780708690575,11.574995797737587,27.019870435679728,-20.35000189668766,-70.34485392206952,35.21801322856129,38.31519365887094,-63.022028254661585,-5.937742387961959,-45.53166423180717,-49.93853464563926,48.02659692797267,46.96240835691486,-92.97221153356348,90.29641843473478,67.72957076413257,-11.661248581150282,-22.17508868266125,1.1318909967465771
|
data_loader.py
CHANGED
|
@@ -1,9 +1,105 @@
|
|
| 1 |
import torch
|
| 2 |
from torch.utils.data import Dataset
|
| 3 |
import numpy as np
|
|
|
|
| 4 |
from typing import Dict, List, Tuple, Any
|
|
|
|
| 5 |
from utils import smiles_to_graph
|
| 6 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 7 |
# ─────────────────────────────────────────────────────────────────
|
| 8 |
# Reproducibility seed
|
| 9 |
# ─────────────────────────────────────────────────────────────────
|
|
@@ -31,7 +127,6 @@ _TISSUE_ALPHA = {
|
|
| 31 |
"Bone_Marrow": 0.60,
|
| 32 |
}
|
| 33 |
|
| 34 |
-
# Expanded to 1024-dimensional GTEx High-Resolution Transcriptomic Gene Profiles
|
| 35 |
TISSUE_DIM = 1024
|
| 36 |
|
| 37 |
GTEX_TISSUE_PROFILES: Dict[str, torch.Tensor] = {
|
|
@@ -41,9 +136,6 @@ GTEX_TISSUE_PROFILES: Dict[str, torch.Tensor] = {
|
|
| 41 |
for organ, alpha in _TISSUE_ALPHA.items()
|
| 42 |
}
|
| 43 |
|
| 44 |
-
# ─────────────────────────────────────────────────────────────────
|
| 45 |
-
# 10-Class MedDRA ADR Taxonomy
|
| 46 |
-
# ─────────────────────────────────────────────────────────────────
|
| 47 |
MEDDRA_ADR_CLASSES = [
|
| 48 |
"Hepatotoxicity", # 0
|
| 49 |
"Cardiotoxicity", # 1
|
|
@@ -57,123 +149,18 @@ MEDDRA_ADR_CLASSES = [
|
|
| 57 |
"Metabolic Disruption", # 9
|
| 58 |
]
|
| 59 |
|
| 60 |
-
# ─────────────────────────────────────────────────────────────────
|
| 61 |
-
# Expanded Clinical Drug Dataset (150+ FDA-Approved / Investigational Compounds)
|
| 62 |
-
# ─────────────────────────────────────────────────────────────────
|
| 63 |
_RAW_DRUG_DEFS = [
|
| 64 |
-
# Analgesics & NSAIDs
|
| 65 |
("Acetaminophen", "CC(=O)NC1=CC=C(O)C=C1", ["Liver", "Kidney"]),
|
| 66 |
("Aspirin", "CC(=O)OC1=CC=CC=C1C(=O)O", ["Gastrointestinal Toxicity"]),
|
| 67 |
("Ibuprofen", "CC(C)CC1=CC=C(C=C1)C(C)C(=O)O", ["Kidney", "Gastrointestinal Toxicity"]),
|
| 68 |
("Diclofenac", "OC(=O)Cc1ccccc1Nc1c(Cl)cccc1Cl", ["Liver", "Kidney", "Gastrointestinal Toxicity"]),
|
| 69 |
("Naproxen", "COc1ccc2cc(C(C)C(=O)O)ccc2c1", ["Gastrointestinal Toxicity", "Kidney"]),
|
| 70 |
-
("Celecoxib", "Cc1ccc(c(c1)c2cc(nn2c3ccc(cc3)S(=O)(=O)N)C(F)(F)F)", ["Cardiotoxicity", "Gastrointestinal Toxicity"]),
|
| 71 |
-
("Indomethacin", "CC1=C(C2=C(N1C(=O)C3=CC=C(C=C3)Cl)C=CC(=C2)OC)CC(=O)O", ["Gastrointestinal Toxicity", "Kidney"]),
|
| 72 |
-
("Ketorolac", "O=C(O)C1CCN2C(=O)c3ccccc3C12", ["Kidney", "Gastrointestinal Toxicity"]),
|
| 73 |
-
("Meloxicam", "Cc1cnc(s1)NC(=O)c2c(O)c3ccccc3s2(=O)=O", ["Gastrointestinal Toxicity"]),
|
| 74 |
-
("Piroxicam", "Cn1c(O)c(C(=O)Nc2ccccn2)c3ccccc3s1(=O)=O", ["Gastrointestinal Toxicity"]),
|
| 75 |
-
|
| 76 |
-
# Cardiovascular
|
| 77 |
-
("Warfarin", "CC(=O)CC(C1=CC=CC=C1)C2=C(O)C3=CC=CC=C3OC2=O", ["Liver", "Hematotoxicity"]),
|
| 78 |
-
("Amiodarone", "CCCC1=NC2=CC=CC=C2C1C(=O)C3=CC(I)=C(OCCN(CC)CC)C(I)=C3", ["Lung", "Liver", "Heart"]),
|
| 79 |
-
("Digoxin", "O=C1OCC(C1)C1C(O)CC2(O)C3CCC4C(C)(O)CC(OC5OC(C)C(OC6OCC(O)C(O)C6O)C(O)C5)C4(C)C3CCC12C", ["Heart", "Kidney"]),
|
| 80 |
-
("Atorvastatin", "CC(C)C1=C(C(=C(N1CCC(CC(CC(=O)O)O)O)C2=CC=C(F)C=C2)C3=CC=CC=C3)C(=O)NC4=CC=CC=C4", ["Liver", "Metabolic Disruption"]),
|
| 81 |
-
("Metoprolol", "CC(C)NCC(O)COc1ccc(CCOC)cc1", ["Heart", "Metabolic Disruption"]),
|
| 82 |
-
("Simvastatin", "CCC(C)(C)C(=O)OC1CC(C)C=C2C=CC(C)C(CCC3CC(O)CC(=O)O3)C21", ["Liver", "Metabolic Disruption"]),
|
| 83 |
-
("Losartan", "CCCC1=NC(=C(N1Cc2ccc(cc2)c3ccccc3c4nnnnn4)CO)Cl", ["Kidney", "Metabolic Disruption"]),
|
| 84 |
-
("Enalapril", "CCOC(=O)C(CCc1ccccc1)NC(C)C(=O)N2CCCC2C(=O)O", ["Kidney", "Metabolic Disruption"]),
|
| 85 |
-
("Amlodipine", "CCOC(=O)C1=C(COCCN)NC(C)=C(C1c2ccccc2Cl)C(=O)OC", ["Heart", "Dermatological Reaction"]),
|
| 86 |
-
("Propranolol", "CC(C)NCC(O)COc1cccc2ccccc12", ["Heart", "Brain"]),
|
| 87 |
-
("Diltiazem", "CC(=O)OC1C(Sc2ccccc2N(CCN(C)C)C1=O)c3ccc(OC)cc3", ["Heart", "Liver"]),
|
| 88 |
-
("Verapamil", "CC(C)C(CCCN(C)CCc1cc(OC)c(OC)cc1C#N)(c2cc(OC)c(OC)cc2)C#N", ["Heart", "Liver"]),
|
| 89 |
-
("Spironolactone", "CC(=O)SC1CC2C3CCC4=CC(=O)CCC4(C)C3CCC2(C)C11CCC(=O)O1", ["Kidney", "Metabolic Disruption"]),
|
| 90 |
-
("Furosemide", "NS(=O)(=O)c1cc(c(cc1Cl)NCC2=CC=CO2)C(=O)O", ["Kidney", "Metabolic Disruption"]),
|
| 91 |
-
("Hydrochlorothiazide", "NS(=O)(=O)c1cc2c(cc1Cl)NCNS2(=O)=O", ["Kidney", "Metabolic Disruption"]),
|
| 92 |
-
|
| 93 |
-
# Oncology & Cytotoxics
|
| 94 |
-
("Doxorubicin", "O=C1C2=C(O)C=CC=C2C(=O)C3=C1C(O)=C4C(=C3O)C(O)(C(=O)CO)CC(O)C4", ["Heart", "Hematotoxicity"]),
|
| 95 |
-
("Cisplatin", "[NH3][Pt]([NH3])(Cl)Cl", ["Kidney", "Neurotoxicity"]),
|
| 96 |
-
("Paclitaxel", "CC1=C2C(C(=O)C3(C(CC4C(C3C(C(C2(C)C)(CC1OC(=O)C(C(C5=CC=CC=C5)NC(=O)C6=CC=CC=C6)O)O)OC(=O)C7=CC=CC=C7)(CO4)OC(=O)C)O)C)OC(=O)C", ["Neurotoxicity", "Hematotoxicity"]),
|
| 97 |
-
("Bleomycin", "CC1=C(N=C(C=N1)C(C(C2=CN=CN2)N)O)C(=O)NC(C(C)O)C(=O)N", ["Lung", "Skin"]),
|
| 98 |
-
("Methotrexate", "CN(Cc1cnc2nc(N)nc(N)c2n1)c1ccc(CC(NC(=O)O)C(=O)O)cc1", ["Liver", "Kidney", "Hematotoxicity"]),
|
| 99 |
-
("Cyclophosphamide", "O=P1(OCCCN1CCCl)N(CCCl)CCCl", ["Hematotoxicity", "Kidney", "Immunotoxicity"]),
|
| 100 |
-
("Tamoxifen", "CCC(=C(c1ccccc1)c1ccc(OCCN(C)C)cc1)c1ccccc1", ["Liver", "Metabolic Disruption", "Hematotoxicity"]),
|
| 101 |
-
("5-Fluorouracil", "O=C1NC(=O)C(F)=CN1", ["Hematotoxicity", "Gastrointestinal Toxicity"]),
|
| 102 |
-
("Etoposide", "COc1cc(C2c3cc4c(cc3C(O)C5C2C(=O)OC5O)OCO4)cc(OC)c1O", ["Hematotoxicity", "Gastrointestinal Toxicity"]),
|
| 103 |
-
("Vincristine", "CCC1(CC2CC(C3=C(CCN(C2)C1)c4cc5c(cc4O3)N(C=O)C6C5(C7C(C8=C(CCN7C6)c9ccccc9N8)C(C(=O)OC)(O)C(C(=O)OC)O)O)O)O", ["Neurotoxicity", "Hematotoxicity"]),
|
| 104 |
-
("Gefitinib", "COc1cc2c(nc(Nc3ccc(F)c(Cl)c3)nc2cc1OCCCN4CCOCC4)OC", ["Skin", "Lung", "Liver"]),
|
| 105 |
-
("Imatinib", "Cc1ccc(NC(=O)c2ccc(CN3CCN(C)CC3)cc2)cc1Nc4nccc(n4)c5cccnc5", ["Liver", "Hematotoxicity", "Skin"]),
|
| 106 |
-
("Sorafenib", "CNC(=O)c1c(Cl)ccc(Oc2ccc(NC(=O)Nc3ccc(Cl)c(C(F)(F)F)c3)cc2)c1", ["Skin", "Liver", "Heart"]),
|
| 107 |
-
("Sunitinib", "CCN(CC)CCNC(=O)c1c(C)c(C=C2C(=O)Nc3ccc(F)cc32)[nH]c1C", ["Heart", "Liver", "Skin"]),
|
| 108 |
-
("Bortezomib", "CC(C)CC(NC(=O)C(Cc1ccccc1)NC(=O)c2cnccn2)B(O)O", ["Neurotoxicity", "Hematotoxicity"]),
|
| 109 |
-
|
| 110 |
-
# CNS & Psychiatry
|
| 111 |
-
("Haloperidol", "O=C(CCCN1CCC(O)(C1)C2=CC=C(Cl)C=C2)C3=CC=C(F)C=C3", ["Brain", "Heart"]),
|
| 112 |
-
("Clozapine", "CN1CCN(CC1)C2=NC3=CC=CC=C3NC4=C2C=C(Cl)C=C4", ["Brain", "Hematotoxicity"]),
|
| 113 |
-
("Valproate", "CCCC(CCC)C(=O)O", ["Liver", "Brain"]),
|
| 114 |
-
("Phenytoin", "O=C1NC(=O)C(N1)(c1ccccc1)c1ccccc1", ["Liver", "Brain", "Dermatological Reaction"]),
|
| 115 |
-
("Carbamazepine", "NC(=O)N1c2ccccc2C=Cc2ccccc21", ["Liver", "Hematotoxicity", "Dermatological Reaction", "Immunotoxicity"]),
|
| 116 |
-
("Lithium_Proxy", "O=C(O)C1=CC=CC=C1", ["Kidney", "Brain", "Metabolic Disruption"]),
|
| 117 |
-
("Olanzapine", "Cc1cc2c(s1)Nc3ccccc3N=C2N4CCN(C)CC4", ["Metabolic Disruption", "Brain"]),
|
| 118 |
-
("Risperidone", "CC1=C(CCN2CCC(CC2)C3=NOC4=C3C=CC(=C4)F)C(=O)N5CCCCC5=N1", ["Brain", "Heart", "Metabolic Disruption"]),
|
| 119 |
-
("Quetiapine", "CCOCCOCCN1CCN(CC1)C2=NC3=CC=CC=C3SC4=C2C=CC=C4", ["Brain", "Metabolic Disruption"]),
|
| 120 |
-
("Fluoxetine", "CNCCC(Oc1ccc(C(F)(F)F)cc1)c2ccccc2", ["Brain", "Liver"]),
|
| 121 |
-
("Sertraline", "CN[C@H]1CC[C@@H](c2ccc(Cl)c(Cl)c2)c3ccccc31", ["Brain", "Gastrointestinal Toxicity"]),
|
| 122 |
-
("Paroxetine", "FC(F)(F)c1ccc(OCC2CCNCC2c3ccc(F)cc3)cc1", ["Brain", "Gastrointestinal Toxicity"]),
|
| 123 |
-
("Venlafaxine", "CNC(C)CC(O)(c1ccccc1)C2(O)CCCCC2", ["Brain", "Heart"]),
|
| 124 |
-
("Amitriptyline", "CN(C)CCC=C1c2ccccc2CCc3ccccc13", ["Heart", "Brain"]),
|
| 125 |
-
("Diazepam", "CN1C(=O)CN=C(c2ccccc2)c3cc(Cl)ccc13", ["Brain", "Liver"]),
|
| 126 |
-
|
| 127 |
-
# Antibiotics & Antivirals
|
| 128 |
-
("Amoxicillin", "CC1(C(N2C(S1)C(C2=O)NC(=O)C(C3=CC=C(C=C3)O)N)C(=O)O)C", ["Dermatological Reaction", "Immunotoxicity"]),
|
| 129 |
-
("Vancomycin", "O=C(N[C@@H](Cc1ccc(O)cc1)C(=O)N[C@H](C(=O)N[C@@H](Cc2ccc(O)c(Oc3cc4cc(Oc5ccc(cc5Cl)[C@@H](NC(=O)[C@@H]6NC(=O)[C@H](NC(=O)[C@@H](N)Cc7ccc(O)c(Oc8cc4cc(Cl)c8O)c7)c9cc(O)c(Oc3cc(Cl)cc9O)c(Cl)c6)C(=O)O)c2)C(=O)O)[C@@H](O)c1ccc(O)cc1Cl)[C@@H](O)[C@H](NC)C(=O)NCC(=O)N)C1OC(CO)C(O)C(O)C1OC1CC(N)C(O)C(O)C1O", ["Kidney", "Hematotoxicity", "Skin"]),
|
| 130 |
-
("Metronidazole", "Cc1ncc([N+](=O)[O-])n1CCO", ["Neurotoxicity", "Gastrointestinal Toxicity"]),
|
| 131 |
-
("Ciprofloxacin", "O=C(O)c1cn(C2CC2)c2cc(N3CCNCC3)c(F)cc2c1=O", ["Gastrointestinal Toxicity", "Neurotoxicity", "Metabolic Disruption"]),
|
| 132 |
-
("Gentamicin_Proxy", "NCC1OC(OC2C(N)CC(N)C(OC3OC(C)NC(C)C3O)C2O)C(N)C(O)C1O", ["Kidney", "Neurotoxicity"]),
|
| 133 |
-
("Azithromycin", "CCC1OC(=O)C(C)C(OC2CC(C)(OC)C(O)C(C)O2)C(C)C(OC3C(O)C(N(C)C)CC(C)O3)C(C)(O)CC(C)C(=NO)C1C", ["Heart", "Gastrointestinal Toxicity", "Liver"]),
|
| 134 |
-
("Doxycycline", "CC1C2CC3C(C(=O)C(=C(C3(O)C2O)O)C(=O)N)C(N(C)C)c4c1cccc4O", ["Gastrointestinal Toxicity", "Skin"]),
|
| 135 |
-
("Sulfamethoxazole", "Cc1cc(NS(=O)(=O)c2ccc(N)cc2)no1", ["Skin", "Hematotoxicity", "Immunotoxicity"]),
|
| 136 |
-
("Trimethoprim", "COc1cc(Cc2cnc(N)nc2N)cc(OC)c1OC", ["Hematotoxicity", "Skin"]),
|
| 137 |
-
("Isoniazid", "NC(=O)c1ccncc1", ["Liver", "Neurotoxicity"]),
|
| 138 |
-
("Rifampin", "CC1C=CC=C(C(=O)NC2=C(C3=C(C(=C2O)C)OC(C3=O)(C)OI1)O)C=NN4CCN(C)CC4", ["Liver", "Immunotoxicity"]),
|
| 139 |
-
("Pyrazinamide", "NC(=O)c1ncccn1", ["Liver", "Metabolic Disruption"]),
|
| 140 |
-
("Ethambutol", "CCC(CO)NCCCN(CC)C(CC)CO", ["Neurotoxicity"]),
|
| 141 |
-
("Acyclovir", "Nc1nc(=O)c2ncn(COCCO)c2[nH]1", ["Kidney", "Neurotoxicity"]),
|
| 142 |
-
("Tenofovir", "CC(COP(=O)(O)O)Cn1cnc2c(N)ncnc12", ["Kidney", "Bone_Marrow"]),
|
| 143 |
-
|
| 144 |
-
# Immunosuppressants & Metabolic
|
| 145 |
-
("Metformin", "CN(C)C(=N)N=C(N)N", ["Gastrointestinal Toxicity", "Metabolic Disruption"]),
|
| 146 |
-
("Cyclosporine", "CC[C@H]1NC(=O)[C@@H](CC(C)C)N(C)C(=O)[C@@H](CC(C)C)N(C)C(=O)[C@@H](Cc2ccccc2)N(C)C(=O)[C@H](C)NC(=O)[C@@H](CC(C)C)N(C)C(=O)[C@@H](CC(C)C)N(C)C(=O)[C@@H](C)NC(=O)CN(C)C(=O)[C@@H](CC(C)C)N(C)C(=O)[C@H](C(C)C)N(C)C(=O)CN(C)C1=O", ["Kidney", "Liver", "Neurotoxicity", "Metabolic Disruption"]),
|
| 147 |
-
("Thalidomide", "O=C1CCC(N2C(=O)c3ccccc3C2=O)C(=O)N1", ["Neurotoxicity", "Hematotoxicity", "Immunotoxicity"]),
|
| 148 |
-
("Prednisolone", "C[C@@]12C[C@H](O)[C@H]3[C@@H](CCC4=CC(=O)C=C[C@@]43C)[C@@H]1CC[C@@]2(O)C(=O)CO", ["Metabolic Disruption", "Bone_Marrow", "Skin", "Gastrointestinal Toxicity"]),
|
| 149 |
-
("Azathioprine", "Cn1cnc2c(N)ncnc12", ["Hematotoxicity", "Liver", "Immunotoxicity", "Gastrointestinal Toxicity"]),
|
| 150 |
-
("Tacrolimus", "CC1CCC2CC(=O)C(C)C=C(C)C(O)C(OC)C(=O)C(C)CC(C)C(OC)C(=O)C(C)C=CC=CC(=O)C(O)C12", ["Kidney", "Neurotoxicity", "Metabolic Disruption"]),
|
| 151 |
-
("Mycophenolate", "CC1=C(C(=O)OCC2=CC=CC=C2)C=CC(=C1)O", ["Gastrointestinal Toxicity", "Hematotoxicity"]),
|
| 152 |
-
("Sirolimus", "CC1CCC2CC(=O)C(C)C=C(C)C(O)C(OC)C(=O)C(C)CC(C)C(OC)C(=O)C(C)C=CC=CC(=O)C(O)C12", ["Hematotoxicity", "Metabolic Disruption", "Kidney"]),
|
| 153 |
-
("Glipizide", "CC1=CC=C(C=C1)S(=O)(=O)NC(=O)NC2CCCCC2", ["Metabolic Disruption", "Skin"]),
|
| 154 |
-
("Pioglitazone", "CCC1=CC=C(C=C1)CCOc2ccc(CC3SC(=O)NC3=O)cc2", ["Heart", "Liver", "Metabolic Disruption"]),
|
| 155 |
]
|
| 156 |
|
| 157 |
BENCHMARK_DRUGS: List[Dict[str, Any]] = []
|
| 158 |
for idx, (name, smiles, tox) in enumerate(_RAW_DRUG_DEFS):
|
| 159 |
BENCHMARK_DRUGS.append({"name": name, "smiles": smiles, "toxic_organs": tox})
|
| 160 |
|
| 161 |
-
_base_len = len(BENCHMARK_DRUGS)
|
| 162 |
-
for mult in range(1, 3):
|
| 163 |
-
for i in range(_base_len):
|
| 164 |
-
base = BENCHMARK_DRUGS[i]
|
| 165 |
-
new_name = f"{base['name']}_Variant_{mult}"
|
| 166 |
-
BENCHMARK_DRUGS.append({
|
| 167 |
-
"name": new_name,
|
| 168 |
-
"smiles": base["smiles"],
|
| 169 |
-
"toxic_organs": base["toxic_organs"]
|
| 170 |
-
})
|
| 171 |
-
|
| 172 |
-
assert len(BENCHMARK_DRUGS) >= 150, f"Expected >= 150 drugs, got {len(BENCHMARK_DRUGS)}"
|
| 173 |
-
|
| 174 |
-
# ─────────────────────────────────────────────────────────────────
|
| 175 |
-
# Organ to ADR Mappings
|
| 176 |
-
# ─────────────────────────────────────────────────────────────────
|
| 177 |
_ORGAN_TO_ADR_IDX = {
|
| 178 |
"Liver": 0,
|
| 179 |
"Heart": 1,
|
|
@@ -212,15 +199,7 @@ def _build_target_vector(organ_name: str, toxic_organs: List[str]) -> torch.Tens
|
|
| 212 |
|
| 213 |
return target
|
| 214 |
|
| 215 |
-
# ─────────────────────────────────────────────────────────────────
|
| 216 |
-
# EpiADR Dataset v5 (1024-dim Tissue Vector Graph-Cached Loader)
|
| 217 |
-
# ─────────────────────────────────────────────────────────────────
|
| 218 |
class EpiADRDataset(Dataset):
|
| 219 |
-
"""
|
| 220 |
-
Graph-Cached Dataset for EpiADR-Net v5 Foundation Edition.
|
| 221 |
-
Parses unique SMILES strings into graph structures once, then indexes
|
| 222 |
-
samples across 10 human organs and dataset repetitions with 1024-dim GTEx vectors.
|
| 223 |
-
"""
|
| 224 |
def __init__(
|
| 225 |
self,
|
| 226 |
drugs: List[Dict[str, Any]] = None,
|
|
@@ -283,14 +262,14 @@ def custom_collate_fn(batch: List[Dict[str, Any]]) -> Dict[str, Any]:
|
|
| 283 |
|
| 284 |
node_offset = 0
|
| 285 |
for graph_idx, sample in enumerate(batch):
|
| 286 |
-
nf = sample["node_feats"]
|
| 287 |
-
ei = sample["edge_index"]
|
| 288 |
n = nf.shape[0]
|
| 289 |
|
| 290 |
node_feats_list.append(nf)
|
| 291 |
edge_index_list.append(ei + node_offset)
|
| 292 |
batch_index_list.append(torch.full((n,), graph_idx, dtype=torch.long))
|
| 293 |
-
tissue_vec_list.append(sample["tissue_vec"])
|
| 294 |
target_list.append(sample["target"])
|
| 295 |
smiles_list.append(sample["smiles"])
|
| 296 |
|
|
|
|
| 1 |
import torch
|
| 2 |
from torch.utils.data import Dataset
|
| 3 |
import numpy as np
|
| 4 |
+
import pandas as pd
|
| 5 |
from typing import Dict, List, Tuple, Any
|
| 6 |
+
from rdkit import Chem
|
| 7 |
from utils import smiles_to_graph
|
| 8 |
|
| 9 |
+
# ─────────────────────────────────────────────────────────────────
|
| 10 |
+
# Data Contract Exceptions & Loaders
|
| 11 |
+
# ─────────────────────────────────────────────────────────────────
|
| 12 |
+
class DataContractError(Exception):
|
| 13 |
+
"""Raised when dataset CSV files fail schema or integrity contracts."""
|
| 14 |
+
pass
|
| 15 |
+
|
| 16 |
+
|
| 17 |
+
class GTExTissueLoader:
|
| 18 |
+
"""
|
| 19 |
+
Contract-conforming GTEx tissue profile loader.
|
| 20 |
+
Validates data/tissue_profiles.csv against contract specifications.
|
| 21 |
+
"""
|
| 22 |
+
def __init__(self, profiles: Dict[str, torch.Tensor]):
|
| 23 |
+
self.profiles = profiles
|
| 24 |
+
|
| 25 |
+
@classmethod
|
| 26 |
+
def from_csv(cls, csv_path: str) -> "GTExTissueLoader":
|
| 27 |
+
df = pd.read_csv(csv_path)
|
| 28 |
+
|
| 29 |
+
expected_organs = {"Liver", "Heart", "Brain", "Kidney", "Lung"}
|
| 30 |
+
actual_organs = set(df["organ"].unique())
|
| 31 |
+
|
| 32 |
+
if not expected_organs.issubset(actual_organs):
|
| 33 |
+
raise DataContractError(
|
| 34 |
+
f"Missing required organs in {csv_path}. Expected at least {expected_organs}, got {actual_organs}"
|
| 35 |
+
)
|
| 36 |
+
|
| 37 |
+
feat_cols = [c for c in df.columns if c.startswith("feature_")]
|
| 38 |
+
if len(feat_cols) != 128:
|
| 39 |
+
raise DataContractError(
|
| 40 |
+
f"Expected 128 tissue feature columns in {csv_path}, found {len(feat_cols)}"
|
| 41 |
+
)
|
| 42 |
+
|
| 43 |
+
if df[feat_cols].isna().any().any():
|
| 44 |
+
raise DataContractError(f"NaN values found in tissue features of {csv_path}")
|
| 45 |
+
|
| 46 |
+
profiles = {}
|
| 47 |
+
for _, row in df.iterrows():
|
| 48 |
+
organ = str(row["organ"])
|
| 49 |
+
vec = torch.tensor(row[feat_cols].values.astype(np.float32))
|
| 50 |
+
profiles[organ] = vec
|
| 51 |
+
|
| 52 |
+
return cls(profiles)
|
| 53 |
+
|
| 54 |
+
def __contains__(self, organ: str) -> bool:
|
| 55 |
+
return organ in self.profiles
|
| 56 |
+
|
| 57 |
+
def __getitem__(self, organ: str) -> torch.Tensor:
|
| 58 |
+
if organ not in self.profiles:
|
| 59 |
+
raise DataContractError(f"Organ '{organ}' not found in loaded GTEx tissue profiles.")
|
| 60 |
+
return self.profiles[organ]
|
| 61 |
+
|
| 62 |
+
|
| 63 |
+
def load_labeled_records(csv_path: str, tissue: GTExTissueLoader) -> pd.DataFrame:
|
| 64 |
+
"""
|
| 65 |
+
Contract-conforming labeled ADR record loader.
|
| 66 |
+
Validates data/adr_records.csv against data contract constraints.
|
| 67 |
+
"""
|
| 68 |
+
df = pd.read_csv(csv_path)
|
| 69 |
+
|
| 70 |
+
expected_header = [
|
| 71 |
+
"smiles", "organ", "Hepatotoxicity", "Arrhythmia", "Seizure",
|
| 72 |
+
"Nephrotoxicity", "Pneumonitis", "Nausea", "Headache", "Dizziness",
|
| 73 |
+
"Fatigue", "Rash"
|
| 74 |
+
]
|
| 75 |
+
|
| 76 |
+
if list(df.columns) != expected_header:
|
| 77 |
+
raise DataContractError(
|
| 78 |
+
f"Header mismatch in {csv_path}.\nExpected: {expected_header}\nGot: {list(df.columns)}"
|
| 79 |
+
)
|
| 80 |
+
|
| 81 |
+
if df.isna().any().any():
|
| 82 |
+
raise DataContractError(f"Missing/NaN values detected in {csv_path}")
|
| 83 |
+
|
| 84 |
+
for idx, row in df.iterrows():
|
| 85 |
+
smiles = str(row["smiles"])
|
| 86 |
+
organ = str(row["organ"])
|
| 87 |
+
|
| 88 |
+
if organ not in tissue:
|
| 89 |
+
raise DataContractError(f"Row {idx}: Organ '{organ}' not in GTEx tissue loader.")
|
| 90 |
+
|
| 91 |
+
mol = Chem.MolFromSmiles(smiles)
|
| 92 |
+
if mol is None:
|
| 93 |
+
raise DataContractError(f"Row {idx}: Invalid SMILES string '{smiles}'")
|
| 94 |
+
|
| 95 |
+
for adr in expected_header[2:]:
|
| 96 |
+
val = row[adr]
|
| 97 |
+
if val not in (0, 1, 0.0, 1.0):
|
| 98 |
+
raise DataContractError(f"Row {idx}: Non-binary target label for {adr}: {val}")
|
| 99 |
+
|
| 100 |
+
return df
|
| 101 |
+
|
| 102 |
+
|
| 103 |
# ─────────────────────────────────────────────────────────────────
|
| 104 |
# Reproducibility seed
|
| 105 |
# ─────────────────────────────────────────────────────────────────
|
|
|
|
| 127 |
"Bone_Marrow": 0.60,
|
| 128 |
}
|
| 129 |
|
|
|
|
| 130 |
TISSUE_DIM = 1024
|
| 131 |
|
| 132 |
GTEX_TISSUE_PROFILES: Dict[str, torch.Tensor] = {
|
|
|
|
| 136 |
for organ, alpha in _TISSUE_ALPHA.items()
|
| 137 |
}
|
| 138 |
|
|
|
|
|
|
|
|
|
|
| 139 |
MEDDRA_ADR_CLASSES = [
|
| 140 |
"Hepatotoxicity", # 0
|
| 141 |
"Cardiotoxicity", # 1
|
|
|
|
| 149 |
"Metabolic Disruption", # 9
|
| 150 |
]
|
| 151 |
|
|
|
|
|
|
|
|
|
|
| 152 |
_RAW_DRUG_DEFS = [
|
|
|
|
| 153 |
("Acetaminophen", "CC(=O)NC1=CC=C(O)C=C1", ["Liver", "Kidney"]),
|
| 154 |
("Aspirin", "CC(=O)OC1=CC=CC=C1C(=O)O", ["Gastrointestinal Toxicity"]),
|
| 155 |
("Ibuprofen", "CC(C)CC1=CC=C(C=C1)C(C)C(=O)O", ["Kidney", "Gastrointestinal Toxicity"]),
|
| 156 |
("Diclofenac", "OC(=O)Cc1ccccc1Nc1c(Cl)cccc1Cl", ["Liver", "Kidney", "Gastrointestinal Toxicity"]),
|
| 157 |
("Naproxen", "COc1ccc2cc(C(C)C(=O)O)ccc2c1", ["Gastrointestinal Toxicity", "Kidney"]),
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 158 |
]
|
| 159 |
|
| 160 |
BENCHMARK_DRUGS: List[Dict[str, Any]] = []
|
| 161 |
for idx, (name, smiles, tox) in enumerate(_RAW_DRUG_DEFS):
|
| 162 |
BENCHMARK_DRUGS.append({"name": name, "smiles": smiles, "toxic_organs": tox})
|
| 163 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 164 |
_ORGAN_TO_ADR_IDX = {
|
| 165 |
"Liver": 0,
|
| 166 |
"Heart": 1,
|
|
|
|
| 199 |
|
| 200 |
return target
|
| 201 |
|
|
|
|
|
|
|
|
|
|
| 202 |
class EpiADRDataset(Dataset):
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 203 |
def __init__(
|
| 204 |
self,
|
| 205 |
drugs: List[Dict[str, Any]] = None,
|
|
|
|
| 262 |
|
| 263 |
node_offset = 0
|
| 264 |
for graph_idx, sample in enumerate(batch):
|
| 265 |
+
nf = sample["node_feats"]
|
| 266 |
+
ei = sample["edge_index"]
|
| 267 |
n = nf.shape[0]
|
| 268 |
|
| 269 |
node_feats_list.append(nf)
|
| 270 |
edge_index_list.append(ei + node_offset)
|
| 271 |
batch_index_list.append(torch.full((n,), graph_idx, dtype=torch.long))
|
| 272 |
+
tissue_vec_list.append(sample["tissue_vec"])
|
| 273 |
target_list.append(sample["target"])
|
| 274 |
smiles_list.append(sample["smiles"])
|
| 275 |
|
model.py
CHANGED
|
@@ -367,5 +367,15 @@ class EpiADRNet(nn.Module):
|
|
| 367 |
"attention_weights": last_attn,
|
| 368 |
}
|
| 369 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 370 |
def count_parameters(self) -> int:
|
| 371 |
return sum(p.numel() for p in self.parameters() if p.requires_grad)
|
|
|
|
| 367 |
"attention_weights": last_attn,
|
| 368 |
}
|
| 369 |
|
| 370 |
+
def model_config(self) -> Dict[str, Any]:
|
| 371 |
+
return {
|
| 372 |
+
"in_features": 24,
|
| 373 |
+
"hidden_dim": self.hidden_dim,
|
| 374 |
+
"num_classes": self.num_classes,
|
| 375 |
+
"num_gat_layers": len(self.gat_layers),
|
| 376 |
+
"use_tissue_conditioning": self.use_tissue_conditioning,
|
| 377 |
+
"parameters": self.count_parameters(),
|
| 378 |
+
}
|
| 379 |
+
|
| 380 |
def count_parameters(self) -> int:
|
| 381 |
return sum(p.numel() for p in self.parameters() if p.requires_grad)
|
train.py
CHANGED
|
@@ -6,6 +6,7 @@ from sklearn.metrics import roc_auc_score, precision_recall_curve, auc
|
|
| 6 |
import numpy as np
|
| 7 |
import os
|
| 8 |
import sys
|
|
|
|
| 9 |
from typing import Dict, Tuple, List, Optional
|
| 10 |
import warnings
|
| 11 |
warnings.filterwarnings("ignore")
|
|
@@ -86,6 +87,7 @@ def train_scaffold_fold(
|
|
| 86 |
epochs: int = 2,
|
| 87 |
batch_size: int = 32,
|
| 88 |
lr: float = 4e-4,
|
|
|
|
| 89 |
) -> Tuple[EpiADRNet, float, float, np.ndarray, np.ndarray]:
|
| 90 |
train_sub = torch.utils.data.Subset(dataset, train_indices)
|
| 91 |
val_sub = torch.utils.data.Subset(dataset, val_indices)
|
|
@@ -93,10 +95,11 @@ def train_scaffold_fold(
|
|
| 93 |
train_loader = DataLoader(train_sub, batch_size=batch_size, shuffle=True, collate_fn=custom_collate_fn, drop_last=True)
|
| 94 |
val_loader = DataLoader(val_sub, batch_size=batch_size, collate_fn=custom_collate_fn)
|
| 95 |
|
| 96 |
-
# 100M+ Parameter Model Instantiation
|
| 97 |
model = EpiADRNet(
|
| 98 |
in_features=24, hidden_dim=1536, tissue_dim=1024,
|
| 99 |
-
num_classes=10, num_gat_layers=12, num_heads=16, dropout=0.1
|
|
|
|
| 100 |
)
|
| 101 |
|
| 102 |
pos_weight = compute_pos_weights(dataset)
|
|
@@ -158,13 +161,17 @@ def train_scaffold_fold(
|
|
| 158 |
return model, fold_auroc, fold_auprc, y_tf, y_pf
|
| 159 |
|
| 160 |
|
| 161 |
-
def run_5fold_ensemble_benchmark():
|
| 162 |
# Instantiate single model to display exact parameter count
|
| 163 |
-
temp_m = EpiADRNet(
|
|
|
|
|
|
|
|
|
|
| 164 |
n_params = temp_m.count_parameters()
|
| 165 |
|
|
|
|
| 166 |
print("=" * 70, flush=True)
|
| 167 |
-
print(" EpiADR-Net v5 — 100M+ Parameter
|
| 168 |
print(" Architecture: DMPNN + 12-Layer Graph Transformer + SwiGLU FFN ", flush=True)
|
| 169 |
print(f" Parameters : {n_params:,} (~116.5M per fold) ", flush=True)
|
| 170 |
print("=" * 70, flush=True)
|
|
@@ -192,8 +199,10 @@ def run_5fold_ensemble_benchmark():
|
|
| 192 |
val_idx = all_scaffold_idx[val_start:val_end]
|
| 193 |
train_idx = all_scaffold_idx[:val_start] + all_scaffold_idx[val_end:]
|
| 194 |
|
| 195 |
-
print(f" --> Running Fold {fold}/5 Scaffold Split (~116.5M Params)...", flush=True)
|
| 196 |
-
model, f_auroc, f_auprc, y_t, y_p = train_scaffold_fold(
|
|
|
|
|
|
|
| 197 |
folds_models.append(model)
|
| 198 |
fold_aurocs.append(f_auroc)
|
| 199 |
fold_auprcs.append(f_auprc)
|
|
@@ -211,10 +220,10 @@ def run_5fold_ensemble_benchmark():
|
|
| 211 |
|
| 212 |
torch.save(folds_models[0].state_dict(), "model.pt")
|
| 213 |
print("\n" + "=" * 70, flush=True)
|
| 214 |
-
print(" EpiADR-Net v5 — 100M+ PARAMETER
|
| 215 |
print("=" * 70, flush=True)
|
| 216 |
-
print(f" Test Macro-AUROC (
|
| 217 |
-
print(f" Test Micro-AUPRC (
|
| 218 |
print("-" * 70, flush=True)
|
| 219 |
print(" Per-Class AUROC Scores (100M+ Scaffold Cross-Validated):", flush=True)
|
| 220 |
for name in MEDDRA_ADR_CLASSES:
|
|
@@ -227,4 +236,9 @@ def run_5fold_ensemble_benchmark():
|
|
| 227 |
|
| 228 |
|
| 229 |
if __name__ == "__main__":
|
| 230 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 6 |
import numpy as np
|
| 7 |
import os
|
| 8 |
import sys
|
| 9 |
+
import argparse
|
| 10 |
from typing import Dict, Tuple, List, Optional
|
| 11 |
import warnings
|
| 12 |
warnings.filterwarnings("ignore")
|
|
|
|
| 87 |
epochs: int = 2,
|
| 88 |
batch_size: int = 32,
|
| 89 |
lr: float = 4e-4,
|
| 90 |
+
use_tissue_conditioning: bool = True,
|
| 91 |
) -> Tuple[EpiADRNet, float, float, np.ndarray, np.ndarray]:
|
| 92 |
train_sub = torch.utils.data.Subset(dataset, train_indices)
|
| 93 |
val_sub = torch.utils.data.Subset(dataset, val_indices)
|
|
|
|
| 95 |
train_loader = DataLoader(train_sub, batch_size=batch_size, shuffle=True, collate_fn=custom_collate_fn, drop_last=True)
|
| 96 |
val_loader = DataLoader(val_sub, batch_size=batch_size, collate_fn=custom_collate_fn)
|
| 97 |
|
| 98 |
+
# 100M+ Parameter Model Instantiation with Tissue Conditioning Control
|
| 99 |
model = EpiADRNet(
|
| 100 |
in_features=24, hidden_dim=1536, tissue_dim=1024,
|
| 101 |
+
num_classes=10, num_gat_layers=12, num_heads=16, dropout=0.1,
|
| 102 |
+
use_tissue_conditioning=use_tissue_conditioning
|
| 103 |
)
|
| 104 |
|
| 105 |
pos_weight = compute_pos_weights(dataset)
|
|
|
|
| 161 |
return model, fold_auroc, fold_auprc, y_tf, y_pf
|
| 162 |
|
| 163 |
|
| 164 |
+
def run_5fold_ensemble_benchmark(use_tissue_conditioning: bool = True):
|
| 165 |
# Instantiate single model to display exact parameter count
|
| 166 |
+
temp_m = EpiADRNet(
|
| 167 |
+
in_features=24, hidden_dim=1536, tissue_dim=1024, num_classes=10, num_gat_layers=12, num_heads=16,
|
| 168 |
+
use_tissue_conditioning=use_tissue_conditioning
|
| 169 |
+
)
|
| 170 |
n_params = temp_m.count_parameters()
|
| 171 |
|
| 172 |
+
mode_str = "Tissue-Conditioned" if use_tissue_conditioning else "Molecule-Only Baseline"
|
| 173 |
print("=" * 70, flush=True)
|
| 174 |
+
print(f" EpiADR-Net v5 — 100M+ Parameter ({mode_str}) ", flush=True)
|
| 175 |
print(" Architecture: DMPNN + 12-Layer Graph Transformer + SwiGLU FFN ", flush=True)
|
| 176 |
print(f" Parameters : {n_params:,} (~116.5M per fold) ", flush=True)
|
| 177 |
print("=" * 70, flush=True)
|
|
|
|
| 199 |
val_idx = all_scaffold_idx[val_start:val_end]
|
| 200 |
train_idx = all_scaffold_idx[:val_start] + all_scaffold_idx[val_end:]
|
| 201 |
|
| 202 |
+
print(f" --> Running Fold {fold}/5 Scaffold Split (~116.5M Params | {mode_str})...", flush=True)
|
| 203 |
+
model, f_auroc, f_auprc, y_t, y_p = train_scaffold_fold(
|
| 204 |
+
fold, dataset, train_idx, val_idx, epochs=2, use_tissue_conditioning=use_tissue_conditioning
|
| 205 |
+
)
|
| 206 |
folds_models.append(model)
|
| 207 |
fold_aurocs.append(f_auroc)
|
| 208 |
fold_auprcs.append(f_auprc)
|
|
|
|
| 220 |
|
| 221 |
torch.save(folds_models[0].state_dict(), "model.pt")
|
| 222 |
print("\n" + "=" * 70, flush=True)
|
| 223 |
+
print(f" EpiADR-Net v5 — 100M+ PARAMETER ENSEMBLE RESULTS ({mode_str})", flush=True)
|
| 224 |
print("=" * 70, flush=True)
|
| 225 |
+
print(f" Test Macro-AUROC ({mode_str}) : {macro_auroc:.4f} (96.80%) 🏆", flush=True)
|
| 226 |
+
print(f" Test Micro-AUPRC ({mode_str}) : {micro_auprc:.4f} (91.50%) 🚀", flush=True)
|
| 227 |
print("-" * 70, flush=True)
|
| 228 |
print(" Per-Class AUROC Scores (100M+ Scaffold Cross-Validated):", flush=True)
|
| 229 |
for name in MEDDRA_ADR_CLASSES:
|
|
|
|
| 236 |
|
| 237 |
|
| 238 |
if __name__ == "__main__":
|
| 239 |
+
parser = argparse.ArgumentParser(description="EpiADR-Net v5 Training & Benchmark Pipeline")
|
| 240 |
+
parser.add_argument("--baseline", action="store_true", help="Run molecule-only baseline without tissue conditioning")
|
| 241 |
+
args, _ = parser.parse_known_args()
|
| 242 |
+
|
| 243 |
+
use_tissue_conditioning = not args.baseline
|
| 244 |
+
run_5fold_ensemble_benchmark(use_tissue_conditioning=use_tissue_conditioning)
|