Skip to content

Commit f805590

Browse files
committed
add Tahoe data to DGB2
1 parent e50f8a1 commit f805590

2 files changed

Lines changed: 142 additions & 31 deletions

File tree

appyters/Drug_Gene_Budger2/appyter.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
"$schema": "https://raw.githubusercontent.com/MaayanLab/appyter-catalog/main/schema/appyter-validator.json",
33
"name": "Drug_Gene_Budger2",
44
"title": "Dr. Gene Budger (DGB) 2",
5-
"version": "0.0.7",
5+
"version": "0.0.8",
66
"description": "An appyter that retrieves drugs that up-regulate and down-regulate a single input gene across Connectivity Mapping datasets",
77
"image": "dgb_logo.png",
88
"authors": [

appyters/Drug_Gene_Budger2/drug_gene_budger2_appyter.ipynb

Lines changed: 141 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -100,6 +100,7 @@
100100
"- Ginkgo GDPx1 and GPDx2: Limma-Voom based differential gene expression results for 1,354 drugs.\n",
101101
"- Novartis DRUG-seq: Differential: Limma-Trend based differential gene expression results for 4,343 drugs. \n",
102102
"- LINCS L1000 Chemical Perturbations: Limma-Voom based differential gene expression results for a subset of 4,091 drugs from the LINCS L1000 Chemical Perturbation dataset. \n",
103+
"- Tahoe 100-M: DESeq based differential gene expression results for 376 drugs tested across 50 different cancer cell lines. \n",
103104
"\n",
104105
"The Ginkgo dataset includes 4 primary cell types (epithelial melanocytes, smooth aortic muscle cells, skeletal muscle myoblasts and dermal fibroblasts) and one cell line (A549 lung carcinoma cell line). Previous analysis showed distinct transcriptional responses by cell type, so the drug rankings for the Ginkgo dataset are separated by cell type.\n",
105106
"\n",
@@ -119,6 +120,7 @@
119120
"import re\n",
120121
"from itertools import combinations\n",
121122
"import warnings\n",
123+
"import hashlib\n",
122124
"\n",
123125
"## Tables\n",
124126
"from IPython.display import display, display_markdown, HTML\n",
@@ -129,6 +131,7 @@
129131
"\n",
130132
"## Venn Diagram\n",
131133
"from matplotlib_venn import venn3, venn2\n",
134+
"import matplotlib.pyplot as plt\n",
132135
"\n",
133136
"## Volcano Plot\n",
134137
"from bokeh.plotting import figure, show\n",
@@ -149,6 +152,7 @@
149152
"novartis_URL = 'https://appyters.maayanlab.cloud/storage/DrugRegulators_Appyter/novartis_de'\n",
150153
"lincs_URL = 'https://appyters.maayanlab.cloud/storage/DrugRegulators_Appyter/lincs_de'\n",
151154
"deepcover_moa_URL = 'https://appyters.maayanlab.cloud/storage/DrugRegulators_Appyter/deepcoverMoa_de'\n",
155+
"tahoe_URL = 'https://appyters.maayanlab.cloud/storage/DrugRegulators_Appyter/tahoe_de'\n",
152156
"\n",
153157
"# silence warnings\n",
154158
"warnings.filterwarnings('ignore')"
@@ -161,7 +165,7 @@
161165
"metadata": {},
162166
"outputs": [],
163167
"source": [
164-
"in_ginkgo = in_novartis = in_lincs = True"
168+
"in_ginkgo = in_novartis = in_lincs = in_tahoe = True"
165169
]
166170
},
167171
{
@@ -253,17 +257,51 @@
253257
" in_novartis=False"
254258
]
255259
},
260+
{
261+
"cell_type": "code",
262+
"execution_count": null,
263+
"id": "e7910ada",
264+
"metadata": {},
265+
"outputs": [],
266+
"source": [
267+
"# get Tahoe DE results for gene\n",
268+
"\n",
269+
"# hash_bucket function used to sort genes into buckets\n",
270+
"def hash_bucket(gene, num_buckets=512):\n",
271+
" '''\n",
272+
" gene: Gene symbol\n",
273+
" num_buckets: number of hash buckets to create\n",
274+
"\n",
275+
" Returns integer hash for gene name (between 0-n_buckets)\n",
276+
" '''\n",
277+
" return int(hashlib.md5(gene.encode()).hexdigest(),16) % num_buckets\n",
278+
"\n",
279+
"query_gene_encoded = hash_bucket(query_gene)\n",
280+
"\n",
281+
"try:\n",
282+
" tahoe_de = pd.read_parquet(f'{tahoe_URL}/gene_bucket_{query_gene_encoded}.parquet')\n",
283+
" tahoe_de = tahoe_de[tahoe_de['gene_name']==query_gene]\n",
284+
" tahoe_de['log10adj.P.Val'] = tahoe_de['padj'].replace(0,1e-323).map(np.log10)*-1\n",
285+
" tahoe_de.rename(columns = {'log2FoldChange':'logFC', 'drug':'Drug', 'padj':'adj.P.Val'}, inplace=True)\n",
286+
" tahoe_de['GeneDir'] = np.where(tahoe_de['UpReg']>0,'Up','Dn')\n",
287+
" \n",
288+
"except:\n",
289+
" print('Gene not in Tahoe-100M dataset')\n",
290+
" in_tahoe=False"
291+
]
292+
},
256293
{
257294
"cell_type": "code",
258295
"execution_count": null,
259296
"id": "c5607885",
260297
"metadata": {},
261298
"outputs": [],
262299
"source": [
263-
"if in_lincs + in_novartis + in_ginkgo < 1:\n",
300+
"if in_lincs + in_novartis + in_ginkgo + in_tahoe < 1:\n",
264301
" print(f\"LINCS: {in_lincs}\")\n",
265302
" print(f\"Novartis: {in_novartis}\")\n",
266303
" print(f\"Ginkgo: {in_ginkgo}\")\n",
304+
" print(f\"Tahoe-100M: {in_tahoe}\")\n",
267305
" raise Exception(\"Execution stopped, gene not found in any datasets\")"
268306
]
269307
},
@@ -290,7 +328,7 @@
290328
"outputs": [],
291329
"source": [
292330
"# Get pubchem ID dataframe\n",
293-
"pubchem_location = 'https://appyters.maayanlab.cloud/storage/DrugRegulators_Appyter/cmap_pubchem_ids.csv'\n",
331+
"pubchem_location = 'https://appyters.maayanlab.cloud/storage/DrugRegulators_Appyter/cmap_pubchem_ids_10062025.csv'\n",
294332
"pubchem_ids = pd.read_csv(pubchem_location, dtype = {'Drug':str, 'CID':str})"
295333
]
296334
},
@@ -533,6 +571,45 @@
533571
" display_markdown(f'**{query_gene}** not found in Novartis DRUG-seq', raw=True)"
534572
]
535573
},
574+
{
575+
"cell_type": "markdown",
576+
"id": "c04f416c",
577+
"metadata": {},
578+
"source": [
579+
"### Tahoe-100M"
580+
]
581+
},
582+
{
583+
"cell_type": "markdown",
584+
"id": "e07834e6",
585+
"metadata": {},
586+
"source": [
587+
"Drug rankings for the Tahoe-100M dataset. Top 20 by the chosen ranking method are shown, and the full results are available for download. "
588+
]
589+
},
590+
{
591+
"cell_type": "code",
592+
"execution_count": null,
593+
"id": "ca416e30",
594+
"metadata": {},
595+
"outputs": [],
596+
"source": [
597+
"if in_tahoe:\n",
598+
" tahoe_drugs_up = get_rankings(tahoe_de, 'Tahoe', '', 'up', ranking_method)\n",
599+
" tahoe_drugs_down = get_rankings(tahoe_de, 'Tahoe', '', 'down', ranking_method)\n",
600+
"\n",
601+
" display_markdown(f'**Top {top_n} up-regulators in Tahoe-100M**', raw=True)\n",
602+
" display(tahoe_drugs_up[0].head(top_n))\n",
603+
" display(HTML(download_link(tahoe_drugs_up[0], f'tahoe_drug_ranks_{query_gene}_UpReg.tsv', 'Download results averaged across drug dosages')))\n",
604+
" display(HTML(download_link(tahoe_drugs_up[1], f'tahoe_drug_ranks_{query_gene}_full_UpReg.tsv', 'Download results for all perturbations')))\n",
605+
" display_markdown(f'**Top {top_n} down-regulators in Tahoe-100M**', raw=True)\n",
606+
" display(tahoe_drugs_down[0].head(top_n))\n",
607+
" display(HTML(download_link(tahoe_drugs_down[0], f'tahoe_drug_ranks_{query_gene}_DnReg.tsv', 'Download results averaged across drug dosages')))\n",
608+
" display(HTML(download_link(tahoe_drugs_down[1], f'tahoe_drug_ranks_{query_gene}_full_DnReg.tsv', 'Download results for all perturbations')))\n",
609+
"else:\n",
610+
" display_markdown(f'**{query_gene}** not found in Tahoe-100M', raw=True)"
611+
]
612+
},
536613
{
537614
"cell_type": "code",
538615
"execution_count": null,
@@ -554,7 +631,11 @@
554631
"# get results from novartis\n",
555632
"if in_novartis:\n",
556633
" top_up['novartis'] = get_top(novartis_drugs_up[0], n=50)\n",
557-
" top_down['novartis'] = get_top(novartis_drugs_down[0], n=50)"
634+
" top_down['novartis'] = get_top(novartis_drugs_down[0], n=50)\n",
635+
"# get results from Tahoe\n",
636+
"if in_tahoe:\n",
637+
" top_up['tahoe'] = get_top(tahoe_drugs_up[0], n=50)\n",
638+
" top_down['tahoe'] = get_top(tahoe_drugs_down[0], n=50)"
558639
]
559640
},
560641
{
@@ -605,6 +686,7 @@
605686
" 'ginkgo_A549': 'ginkgo_A549',\n",
606687
" 'lincs_l1000': 'lincs_l1000',\n",
607688
" 'novartis': 'novartis',\n",
689+
" 'tahoe': 'tahoe',\n",
608690
" 'ginkgo_human_epithelial_melanocytes': 'ginkgo_melanocytes',\n",
609691
" 'ginkgo_human_dermal_fibroblast': 'ginkgo_fibroblasts',\n",
610692
" 'ginkgo_human_aortic_smooth_muscle_cells': 'ginkgo_muscle_cells',\n",
@@ -623,7 +705,7 @@
623705
"metadata": {},
624706
"outputs": [],
625707
"source": [
626-
"if in_ginkgo + in_lincs + in_novartis < 2:\n",
708+
"if in_ginkgo + in_lincs + in_novartis + in_tahoe < 2:\n",
627709
" display_markdown(f'**{query_gene}** not found in at least 2 datasets')\n",
628710
"else:\n",
629711
" display_markdown(f\"**Overlap among top up regulators of {query_gene}**\", raw=True)\n",
@@ -692,7 +774,7 @@
692774
"metadata": {},
693775
"outputs": [],
694776
"source": [
695-
"if in_ginkgo + in_lincs + in_novartis < 2:\n",
777+
"if in_ginkgo + in_lincs + in_novartis + in_tahoe < 2:\n",
696778
" display_markdown(f'**{query_gene}** not found in at least 2 datasets')\n",
697779
"else:\n",
698780
" overlap_down = get_overlapping_sets(top_down)\n",
@@ -713,14 +795,6 @@
713795
"outputs": [],
714796
"source": [
715797
"def get_ranking_averages(overlapping_df, data_dict, ranking_method):\n",
716-
" '''\n",
717-
" Retrieve average target ranking across datasets for drugs in overlapping sets. \n",
718-
"\n",
719-
" Returns dataframe with columns for:\n",
720-
" Drug\n",
721-
" Average Rank\n",
722-
" Number of datasets for which drug was a significant regulator of the query gene\n",
723-
" '''\n",
724798
" # get average, integrating across datasets\n",
725799
" average_rank_vals = {}\n",
726800
" average_pctrank_vals = {}\n",
@@ -777,7 +851,7 @@
777851
" # clean column names\n",
778852
" with_proteins.rename(columns = {'logFC':'Protein logFC', 'Pubchem' : 'PubChem CID'}, inplace=True)\n",
779853
" with_proteins.drop(columns='CID',inplace=True)\n",
780-
" return with_proteins"
854+
" return with_proteins.sort_values(['N Datasets', 'Avg Adj.P.Val'], ascending=[False,True])"
781855
]
782856
},
783857
{
@@ -794,11 +868,12 @@
794868
" 'human_epithelial_melanocytes': in_ginkgo,\n",
795869
" 'human_skeletal_muscle_myoblasts': in_ginkgo,\n",
796870
" 'novartis': in_novartis,\n",
797-
" 'lincs': in_lincs}\n",
871+
" 'lincs': in_lincs,\n",
872+
" 'tahoe': in_tahoe}\n",
798873
"data_dict_down ={}\n",
799874
"data_dict_up = {}\n",
800875
"for source,present in data_source_present.items():\n",
801-
" if (present) & (not source in ['novartis','lincs']):\n",
876+
" if (present) & (not source in ['novartis','lincs','tahoe']):\n",
802877
" data_dict_down[source] = ginkgo_drugs_down[source][1]\n",
803878
" data_dict_up[source] = ginkgo_drugs_up[source][1]\n",
804879
" elif (present) & (source == 'lincs'):\n",
@@ -807,8 +882,11 @@
807882
" elif (present) & (source == 'novartis'):\n",
808883
" data_dict_down[source] = novartis_drugs_down[1]\n",
809884
" data_dict_up[source] = novartis_drugs_up[1]\n",
885+
" elif (present) & (source == 'tahoe'):\n",
886+
" data_dict_down[source] = tahoe_drugs_down[1]\n",
887+
" data_dict_up[source] = tahoe_drugs_up[1]\n",
810888
"\n",
811-
"if in_ginkgo + in_lincs + in_novartis > 1:\n",
889+
"if in_ginkgo + in_lincs + in_novartis + in_tahoe > 1:\n",
812890
" overlapping_up_TargetRank = get_ranking_averages(overlap_up, data_dict_up, ranking_method)\n",
813891
" overlapping_down_TargetRank = get_ranking_averages(overlap_down, data_dict_down, ranking_method)"
814892
]
@@ -828,7 +906,7 @@
828906
"metadata": {},
829907
"outputs": [],
830908
"source": [
831-
"if in_ginkgo + in_lincs + in_novartis < 2:\n",
909+
"if in_ginkgo + in_lincs + in_novartis + in_tahoe < 2:\n",
832910
" display_markdown(f'**{query_gene}** not found in at least 2 datasets')\n",
833911
"else:\n",
834912
" display_markdown(\"**Averages across datasets: Up-regulating drugs**\", raw=True)\n",
@@ -909,7 +987,7 @@
909987
"source": [
910988
"## Venn Diagrams\n",
911989
"\n",
912-
"The venn diagrams show the overlap among either up-regulating or down-regulating drugs across the three datasets Novartis DRUG-seq, LINCS L1000, and Ginkgo (all cell types grouped). "
990+
"The venn diagrams show the pairwise overlap among either up-regulating or down-regulating drugs across the four Connectivity Mapping datasets Tahoe-100M, Novartis DRUG-seq, LINCS L1000, and Ginkgo (all cell types grouped). "
913991
]
914992
},
915993
{
@@ -930,7 +1008,8 @@
9301008
"# define input data for venn diagrams\n",
9311009
"data_source_present = {'ginkgo':in_ginkgo,\n",
9321010
" 'lincs_l1000':in_lincs,\n",
933-
" 'novartis':in_novartis}\n",
1011+
" 'novartis':in_novartis,\n",
1012+
" 'tahoe': in_tahoe}\n",
9341013
"venn_up = {}\n",
9351014
"venn_down = {}\n",
9361015
"for source,present in data_source_present.items():\n",
@@ -990,7 +1069,8 @@
9901069
" for datasets, overlap in results.items():\n",
9911070
" if len(overlap) == 0:\n",
9921071
" overlap = ['None']\n",
993-
" print(f\"{', '.join(datasets)}: {', '.join(overlap)}\")"
1072+
" # print(f\"{', '.join(datasets)}: {', '.join(overlap)}\")\n",
1073+
" return f\"{', '.join(datasets)}: {', '.join(overlap)}\""
9941074
]
9951075
},
9961076
{
@@ -1000,12 +1080,15 @@
10001080
"metadata": {},
10011081
"outputs": [],
10021082
"source": [
1003-
"if in_ginkgo + in_lincs + in_novartis < 2:\n",
1083+
"if in_ginkgo + in_lincs + in_novartis + in_tahoe < 2:\n",
10041084
" display_markdown(f'**{query_gene}** not found in at least 2 datasets')\n",
10051085
"else:\n",
10061086
" display_markdown(f'Overlap of top {query_gene} up-regulating drugs across sources', raw=True)\n",
1007-
" create_venn(venn_up)\n",
1008-
" print_overlap(venn_up)"
1087+
" for combo in combinations(list(venn_up.keys()), 2):\n",
1088+
" combo_venn = {k:venn_up[k] for k in combo if k in venn_up}\n",
1089+
" create_venn(combo_venn)\n",
1090+
" plt.title(print_overlap(combo_venn))\n",
1091+
" plt.show()"
10091092
]
10101093
},
10111094
{
@@ -1015,12 +1098,15 @@
10151098
"metadata": {},
10161099
"outputs": [],
10171100
"source": [
1018-
"if in_ginkgo + in_lincs + in_novartis < 2:\n",
1101+
"if in_ginkgo + in_lincs + in_novartis + in_tahoe < 2:\n",
10191102
" display_markdown(f'**{query_gene}** not found in at least 2 datasets')\n",
10201103
"else:\n",
10211104
" display_markdown(f'Overlap of top {query_gene} down-regulating drugs across sources', raw=True)\n",
1022-
" create_venn(venn_down)\n",
1023-
" print_overlap(venn_down)"
1105+
" for combo in combinations(list(venn_down.keys()), 2):\n",
1106+
" combo_venn = {k:venn_down[k] for k in combo if k in venn_down}\n",
1107+
" create_venn(combo_venn)\n",
1108+
" plt.title(print_overlap(combo_venn))\n",
1109+
" plt.show()"
10241110
]
10251111
},
10261112
{
@@ -1064,6 +1150,8 @@
10641150
" df['Label'] = df['Perturbation'] + '_' + df['Drug']\n",
10651151
" elif source == 'L1000':\n",
10661152
" df['Label'] = df['Perturbation']\n",
1153+
" elif source == 'Tahoe':\n",
1154+
" df['Label'] = df['Drug'] + '-' + df['concentration'].astype(str) + '-' + df['Cell_ID_Cellosaur']\n",
10671155
" elif source == 'Deepcover MoA':\n",
10681156
" df['Label'] = df['Drug']\n",
10691157
" df['abs_Zscore'] = df['Zscore'].apply(abs)\n",
@@ -1184,6 +1272,27 @@
11841272
" display_markdown(f'**{query_gene}** not found in Novartis DRUG-seq dataset', raw=True)"
11851273
]
11861274
},
1275+
{
1276+
"cell_type": "markdown",
1277+
"id": "7ada5a72",
1278+
"metadata": {},
1279+
"source": [
1280+
"### Tahoe-100M"
1281+
]
1282+
},
1283+
{
1284+
"cell_type": "code",
1285+
"execution_count": null,
1286+
"id": "679ff8cc",
1287+
"metadata": {},
1288+
"outputs": [],
1289+
"source": [
1290+
"if in_tahoe:\n",
1291+
" create_bokeh_volcano_plot(tahoe_de, query_gene, '','Tahoe')\n",
1292+
"else:\n",
1293+
" display_markdown(f'**{query_gene}** not found in Tahoe-100M dataset', raw=True)"
1294+
]
1295+
},
11871296
{
11881297
"cell_type": "markdown",
11891298
"id": "8c3df5f5",
@@ -1225,9 +1334,11 @@
12251334
"\n",
12261335
"[5] “LINCS L1000 Reverse Search.” n.d. Accessed September 5, 2025. https://lincs-reverse-search-dashboard.dev.maayanlab.cloud/.\n",
12271336
"\n",
1228-
"[6] Wang, Zichen, Edward He, Kevin Sani, Kathleen M. Jagodnik, Moshe C. Silverstein, and Avi Ma’ayan. 2019. “Drug Gene Budger (DGB): An Application for Ranking Drugs to Modulate a Specific Gene Based on Transcriptomic Signatures.” Bioinformatics (Oxford, England) 35 (7): 1247–48.\n",
1337+
"[6] Mitchell, Dylan C., Miljan Kuljanin, Jiaming Li, Jonathan G. Van Vranken, Nathan Bulloch, Devin K. Schweppe, Edward L. Huttlin, and Steven P. Gygi. 2023. “A Proteome-Wide Atlas of Drug Mechanism of Action.” Nature Biotechnology 41 (6): 845–57.\n",
1338+
"\n",
1339+
"[7] Zhang, Jesse, Airol A. Ubas, Richard de Borja, Valentine Svensson, Nicole Thomas, Neha Thakar, Aidan Winters, et al. 2025. “Tahoe-100M: A Giga-Scale Single-Cell Perturbation Atlas for Context-Dependent Gene Function and Cellular Modeling.” bioRxiv. https://doi.org/10.1101/2025.02.20.639398.\n",
12291340
"\n",
1230-
"[7] Mitchell, Dylan C., Miljan Kuljanin, Jiaming Li, Jonathan G. Van Vranken, Nathan Bulloch, Devin K. Schweppe, Edward L. Huttlin, and Steven P. Gygi. 2023. “A Proteome-Wide Atlas of Drug Mechanism of Action.” Nature Biotechnology 41 (6): 845–57."
1341+
"[8] Wang, Zichen, Edward He, Kevin Sani, Kathleen M. Jagodnik, Moshe C. Silverstein, and Avi Ma’ayan. 2019. “Drug Gene Budger (DGB): An Application for Ranking Drugs to Modulate a Specific Gene Based on Transcriptomic Signatures.” Bioinformatics (Oxford, England) 35 (7): 1247–48."
12311342
]
12321343
}
12331344
],

0 commit comments

Comments
 (0)