| ''' |
| Find drug targets in DrugBank, maps drugs to drugs in LINCS |
| ''' |
|
|
|
|
| import pandas as pd |
| from rdkit import Chem |
| import numpy as np |
| import matplotlib.pyplot as plt |
| import json |
|
|
| import os |
| import csv |
| import gzip |
| import collections |
| import re |
| import io |
| import json |
| import os.path as osp |
| import xml.etree.ElementTree as ET |
|
|
| import requests |
| from bs4 import BeautifulSoup |
| import pickle |
|
|
| outdir = '../../processed/lincs/chemical' |
| os.makedirs(outdir, exist_ok=True) |
| outdir_df = '../../processed/lincs/chemical/dataframes/' |
| os.makedirs(outdir_df, exist_ok=True) |
|
|
|
|
| def load_data(DATA_ROOT,log_handle): |
|
|
| |
| |
| df_lincs=pd.read_csv(os.path.join(DATA_ROOT, 'instinfo_beta.txt'), sep="\t", low_memory=False) |
| df_cpmeta=pd.read_csv(os.path.join(DATA_ROOT, 'compoundinfo_beta.txt'), sep="\t", low_memory=False) |
|
|
| df_trtcp=df_lincs.loc[np.logical_and(df_lincs['pert_type'] == 'trt_cp', df_lincs['failure_mode'].isna())] |
| unique_cp=df_trtcp.pert_id.unique() |
|
|
| log_handle.write('LINCS Compound Data\n------\n') |
| log_handle.write('Compound treatments in inst_info:\t{}\n'.format(df_trtcp.shape[0])) |
| log_handle.write('Unique pert_ids:\t{}\n'.format(df_cpmeta.pert_id.unique().shape[0])) |
| log_handle.write('Unique inchi_keys:\t{}\n'.format(df_cpmeta.inchi_key.unique().shape[0])) |
|
|
| |
| DATAROOT= '../../raw/drugbank/2022-11-DrugBank/data/' |
| xml_path = os.path.join(DATAROOT, 'all-full-database.xml') |
| with open(xml_path) as xml_file: |
| tree = ET.parse(xml_file) |
| root = tree.getroot() |
|
|
|
|
| ns = '{http://www.drugbank.ca}' |
| inchikey_template = "{ns}calculated-properties/{ns}property[{ns}kind='InChIKey']/{ns}value" |
| inchi_template = "{ns}calculated-properties/{ns}property[{ns}kind='InChI']/{ns}value" |
| SMILES_template = "{ns}calculated-properties/{ns}property[{ns}kind='SMILES']/{ns}value" |
|
|
|
|
| rows = list() |
| |
|
|
|
|
| for i, drug in enumerate(root): |
| row = collections.OrderedDict() |
| assert drug.tag == ns + 'drug' |
| row['type'] = drug.get('type') |
| row['drugbank_id'] = drug.findtext(ns + "drugbank-id[@primary='true']") |
| row['name'] = drug.findtext(ns + "name") |
| row['description'] = drug.findtext(ns + "description") |
| row['groups'] = [group.text for group in |
| drug.findall("{ns}groups/{ns}group".format(ns = ns))] |
| row['atc_codes'] = [code.get('code') for code in |
| drug.findall("{ns}atc-codes/{ns}atc-code".format(ns = ns))] |
| |
| row['categories'] = [x.findtext(ns + 'category') for x in |
| drug.findall("{ns}categories/{ns}category".format(ns = ns))] |
|
|
| row['inchi'] = drug.findtext(inchi_template.format(ns = ns)) |
| row['inchi_key'] = drug.findtext(inchikey_template.format(ns = ns)) |
| row['SMILES']=drug.findtext(SMILES_template.format(ns=ns)) |
| |
| |
| aliases = { |
| elem.text for elem in |
| drug.findall("{ns}international-brands/{ns}international-brand".format(ns = ns)) + |
| drug.findall("{ns}synonyms/{ns}synonym[@language='English']".format(ns = ns)) + |
| drug.findall("{ns}international-brands/{ns}international-brand".format(ns = ns)) + |
| drug.findall("{ns}products/{ns}product/{ns}name".format(ns = ns)) |
|
|
| } |
| aliases.add(row['name']) |
| row['aliases'] = sorted(aliases) |
|
|
| rows.append(row) |
| |
| columns = ['drugbank_id', 'name', 'type', 'groups', 'atc_codes', 'categories', 'inchi_key', 'inchi','SMILES', 'description'] |
| drugbank_df = pd.DataFrame.from_dict(rows)[columns] |
| drugbank_slim_df = drugbank_df[ |
| drugbank_df.inchi.map(lambda x: x is not None) & |
| drugbank_df.SMILES.map(lambda x: x is not None) |
| ] |
| return drugbank_slim_df, unique_cp, df_cpmeta |
|
|
|
|
|
|
|
|
|
|
|
|
| |
|
|
| def pert_id2inchikey(pertid, df): |
| """Returns InChIKey of the corresponding pert_id""" |
| |
| |
| pertid_index=df.index[df['pert_id']==pertid][0] |
| return (pertid_index, df.at[pertid_index,'inchi_key']) |
|
|
| |
| def df_pert_id2inchikey(pert_idarr, df_cpmeta): |
| """ Returns a DataFrame with corresponding InChIKeys of each pert_id in pert_idarr""" |
|
|
| d = {'pert_id': [], 'compoundinfo_index': [], 'inchi_key': []} |
| for i in range(len(pert_idarr)): |
| d['pert_id'].append(pert_idarr[i]) |
| index, inchikey = pert_id2inchikey(pert_idarr[i], df_cpmeta) |
| d['compoundinfo_index'].append(index) |
| d['inchi_key'].append(inchikey) |
| inchikey_df=pd.DataFrame(data=d) |
| return inchikey_df |
|
|
|
|
| def df_DrugBankCol_inchi(df,drugbank_slim_df): |
| """Adds a column to df with InChIKeys mapped to DrugBank IDs from drugbank_canSmiles_df""" |
| in_drugbank = set(list(drugbank_slim_df['inchi_key'])) |
| assert 'inchi_key' in df.columns.values |
| for i in range(df.shape[0]): |
| inchikey = df['inchi_key'][i] |
| if type(inchikey) ==float: |
| df.at[i,"DrugBank_ID"] = "None" |
| else: |
| if inchikey not in in_drugbank: |
| df.at[i,"DrugBank_ID"] = "Not in DrugBank" |
| else: |
| ik_index=drugbank_slim_df.index[drugbank_slim_df['inchi_key']==inchikey][0] |
| x= (ik_index, drugbank_slim_df.at[ik_index,'drugbank_id']) |
| df.at[i,"DrugBank_ID"] = x[1] |
| return df |
|
|
|
|
|
|
| def createMappedDF(df): |
| """Returns a copy of the df that were mapped to DrugBankIDs""" |
| df_new = df.copy(deep=True) |
| df_new=df_new.loc[(df_new['DrugBank_ID']!='Not in DrugBank')&(df_new['DrugBank_ID']!= "None")] |
| df_new.reset_index(drop=True, inplace=True) |
| return df_new |
|
|
|
|
|
|
|
|
|
|
| |
| def load_targets_drugbank(path): |
| return pd.read_csv(path) |
|
|
|
|
| def summarize_drugbank_targets(mapped_DrugBankDF, df_targets): |
| mapped_DrugBankDF_new = mapped_DrugBankDF.copy(deep=True) |
| mapped_DrugBankDF_new['targets'] = '' |
| for i in range(len(mapped_DrugBankDF)): |
| dbid = mapped_DrugBankDF['DrugBank_ID'].tolist()[i] |
| targets = df_targets[df_targets['DrugBank_ID']==dbid]['idd'].tolist() |
| mapped_DrugBankDF_new.at[i, 'targets'] = targets |
| return mapped_DrugBankDF_new |
|
|
|
|
|
|
|
|
| def countTargets(df): |
| |
| df['num_targets']=0 |
| for i in range(df.shape[0]): |
| if df.notna().at[i,'targets']: |
| str_list=df.at[i,'targets'] |
| df.at[i,'num_targets']=len(df.at[i,'targets']) |
| return df |
| |
|
|
|
|
| def target_stats(df_targets, log_handle): |
| |
| log_handle.write('DrugBank Target Stats\n------\n') |
| for index,value in pd.Series.iteritems(pd.DataFrame(df_targets['num_targets']).describe()): |
| log_handle.write('{}:\t{}\n'.format(index, value)) |
| x = list(df_targets['num_targets']) |
| fig, ax1 = plt.subplots() |
| ax1.hist(np.clip(x,0,30), bins=60) |
| ax1.set_xlabel("# of Targets") |
| ax1.set_ylabel("# of Compounds") |
| ax1.set_title('Number of DrugBank Targets') |
| fig.savefig(osp.join(outdir,'num_target_distribution.png')) |
|
|
|
|
|
|
| def main(): |
| DATA_ROOT = "../../raw/lincs/2022-02-LINCS_Level3/data/" |
| log_handle = open(osp.join(outdir, 'log_process_data_chemical_1.txt'), 'w') |
| drugbank_slim_df, unique_cp, df_cpmeta = load_data(DATA_ROOT, log_handle) |
|
|
| |
| pert_id_inchikeyDF=df_pert_id2inchikey(unique_cp, df_cpmeta) |
|
|
|
|
| |
| pert_id_DrugBankDF=df_DrugBankCol_inchi(pert_id_inchikeyDF,drugbank_slim_df) |
| mapped_DrugBankDF=createMappedDF(pert_id_DrugBankDF) |
|
|
| log_handle.write('Fraction of compounds found in DrugBank:\t{}/{}\n'.format(mapped_DrugBankDF.shape[0],pert_id_DrugBankDF.shape[0])) |
|
|
|
|
| |
|
|
| df_targets = load_targets_drugbank('../../processed/drugbank/targets.txt') |
| df_targets.columns = ['DrugBank_ID', 'DrugBank_name', 'synonyms', 'idd', 'name', 'gene_name', 'gene_synonyms', 'identifiers', 'organism'] |
|
|
| |
|
|
| mapped_DrugBankDF = summarize_drugbank_targets(mapped_DrugBankDF, df_targets) |
| mapped_DrugBankDF=countTargets(mapped_DrugBankDF) |
|
|
|
|
| target_stats(mapped_DrugBankDF, log_handle) |
| no_targets=mapped_DrugBankDF.loc[mapped_DrugBankDF['num_targets']==0].shape[0] |
| log_handle.write('Fraction of compounds without DrugBank targets:\t{}/{}\n'.format(no_targets,mapped_DrugBankDF.shape[0])) |
|
|
|
|
| with open(osp.join(outdir_df,"df_targets.pickle"), 'wb') as f: |
| pickle.dump(mapped_DrugBankDF, f) |
| mapped_DrugBankDF.to_csv(osp.join(outdir_df,"df_targets.csv")) |
|
|
|
|
|
|
| if __name__ == "__main__": |
| main() |
|
|
|
|
|
|
|
|