import pandas as pd import numpy as np import argparse #get data framw with ENST ids and tissue specific expression human_protein_atlas = '/home/omic/HPA_normal_ihc_data.tsv' mane = '/home/omic/MANE_all_transcipts.csv' #extrect enst with hight expression per tissue and match to enst ids HPA_normal_ihc_data = pd.read_csv(human_protein_atlas, sep = '\t') MANE_all_transcipts = pd.read_csv(mane) #change name to merge HPA_normal_ihc_data = HPA_normal_ihc_data.rename({'Gene':'Ensembl_Gene'}, axis=1) #merge dfs HPA_normal_ihc_data = MANE_all_transcipts.merge(HPA_normal_ihc_data, left_on='Ensembl_Gene', right_on='Ensembl_Gene') #drop not needed colums HPA_normal_ihc_data = HPA_normal_ihc_data.drop(['Unnamed: 0', 'seq', 'Ensembl_Gene'], axis=1) #get only hight expressed proteins HPA_normal_hight = HPA_normal_ihc_data[HPA_normal_ihc_data['Level'] == 'High'] def get_n_metabolites(file): """ Get number of metabolites for a drug input metabolite file from GET_FINAL_METABOLITES """ with open(file, 'r') as f: first_line = f.readline().strip() if first_line == 'NO_METABOLITES' or first_line == '': return 0 metabol = pd.read_csv(file, sep = '\t', header=None) return metabol.shape[0] def get_conplex_metric(file_drug, file_all_interactions, target): """ Get merrics of interest in dataframe and a list of ENTSs with durg/metabolite interactions with high expression based on Human Protein Atlas input files from CONPLEX (first for drug interaction only, second for all interaction above threshold) and traget ids from pipeline input csv file """ #drug target interaction drug_interactions = pd.read_csv(file_drug, sep = '\t') #drug target protein ents ensts = target scors = [] for enst in ensts: scor = drug_interactions[drug_interactions['Transcript'] == enst]['Score'] scors.append(scor) # mean_drug_scor = avg(scors) mean_drug_scor = 0 max_drug_scor = 0 if len(scors) > 0: mean_drug_scor = pd.concat(scors).mean() # 0 if empty max_drug_scor = pd.concat(scors).max() # 0 if empty #drug/metabolite target interaction — only 'transcipt' and 'conplex_score' are # referenced below (the 'smile' and 'drug/metabolite' columns are the bulk of the # 5+ GB file). Skipping them cuts memory ~10x and prevents OOM in 5 GB pods. drug_interactions = pd.read_csv(file_all_interactions, sep = '\t', usecols=['transcipt', 'conplex_score']) n_significant_int = len(drug_interactions) # Handle empty DataFrame case if n_significant_int == 0: df = pd.DataFrame([max_drug_scor, mean_drug_scor, np.nan, np.nan, 0, 0, 0, 0, np.nan]).T.rename( {0:'max_drug_scor',1:'mean_drug_scor',2:'max_target_scor',3:'mean_target_scor', 4:'n_significant_int',5:'n_unique_proteins_above_target_interaction', 6:'n_interactions_above_target_interaction',7:'n_enst_with_hight_expression', 8:'mean_scor_with_hight_expression'}, axis = 1) return df, [], drug_interactions #drug target protein ents ensts = target scors = [] for enst in ensts: scor = drug_interactions[drug_interactions['transcipt'] == enst]['conplex_score'] scors.append(scor) mean_target_scor = 0 max_target_scor = 0 if len(scors) > 0: mean_target_scor = pd.concat(scors).mean() # 0 if empty max_target_scor = pd.concat(scors).max() # 0 if empty if np.isnan(max_target_scor): pass else: drug_interactions = drug_interactions[drug_interactions['conplex_score'] >= max_target_scor].sort_values('conplex_score',ascending=False) n_unique_proteins_above_target_interaction = pd.unique(drug_interactions['transcipt']).shape[0] n_interactions_above_target_interaction = drug_interactions.shape[0] uniq_enst = pd.unique(drug_interactions['transcipt']) #get only ensts with hight expression uniq_enst_hight = list(set(pd.unique(HPA_normal_hight['transcipt'])).intersection(uniq_enst)) enst_with_hight_expression = len(uniq_enst_hight) #sort based on a conplex score drug_interactions = drug_interactions[[i in uniq_enst_hight for i in drug_interactions['transcipt']]] if len(drug_interactions) > 0: mean_scor_with_hight_expression = drug_interactions['conplex_score'].mean() hight_expression_enst_per_drug = pd.unique(drug_interactions['transcipt']) else: mean_scor_with_hight_expression = np.nan hight_expression_enst_per_drug = [] df = pd.DataFrame([max_drug_scor, mean_drug_scor, max_target_scor, mean_target_scor, n_significant_int,n_unique_proteins_above_target_interaction,n_interactions_above_target_interaction,enst_with_hight_expression, mean_scor_with_hight_expression]).T.rename({0:'max_drug_scor',1:'mean_drug_scor',2:'max_target_scor',3:'mean_target_scor',4:'n_significant_int',5:'n_unique_proteins_above_target_interaction',6:'n_interactions_above_target_interaction',7:'n_enst_with_hight_expression',8:'mean_scor_with_hight_expression'}, axis = 1) return df, hight_expression_enst_per_drug, drug_interactions #look at tissue interactions specificly def get_number_of_interacting_prot_per_tissue(names, hight_expression_enst_per_drug, drug_interactions, n_of_interactions = None): ''' Tissue specific interactions, only for high expressed proteins input: names; drug id, list hight_expression_enst_per_drug; ensts with interaction of interest, make sure if follows names order and enst orderd by importance based on highest conplex score, lisf of list drug_interactions; significant interactions filtered n_of_interactions; n proteins to analyse ,default None use all proteins, use when there is no drug target interaction, interger output: number and min_max of tissue highly exprest proteins in interaction with a drug/metabolites, pandas df ''' n_interactions = [] min_max_df = [] list_of_tissue_ids = [['Heart muscle'],\ ['Rectum', 'Gallbladder', 'Esophagus', 'Stomach', 'Small intestine', 'Duodenum', 'Colon', 'Salivary gland'],\ ['Breast', 'Lactating breast', 'Cervix', 'Fallopian tube', 'Ovary', 'Placenta', 'Endometrium', 'Vagina'],\ ['Testis', 'Prostate', 'Epididymis', 'Seminal vesicle'],\ ['Liver'],\ ['Kidney', 'Urinary bladder'],\ ['Cerebral cortex', 'Cerebellum', 'Caudate', 'Hippocampus', 'Hypothalamus', 'Dorsal raphe', 'Choroid plexus', 'Pituitary gland', 'Substantia nigra'],\ ['Adrenal gland', 'Pancreas', 'Parathyroid gland', 'Thyroid gland'],\ ['Appendix', 'Lymph node', 'Spleen', 'Thymus', 'Tonsil'],\ ['Bone marrow'],\ ['Bronchus', 'Lung', 'Nasopharynx', 'Oral mucosa'],\ ['Eye', 'Retina'],\ ['Skeletal muscle', 'Cartilage'],\ ['Adipose tissue', 'Hair', 'Skin', 'Smooth muscle', 'Soft tissue', 'Sole of foot']] list_of_tissue_names = ['heart', 'gasrto_intestin', 'female_tissues', 'male_tissues', 'liver', 'kidney', 'brain', 'endocrine', 'immune',\ 'hematopoietic', 'respiratory', 'sensory', 'musculoskeletal', 'others'] for t_id, t_name in zip(list_of_tissue_ids, list_of_tissue_names): HPA_normal_hight_tis = HPA_normal_hight[[i in t_id for i in HPA_normal_hight['Tissue']]] tis = [HPA_normal_hight_tis[[i in j[:n_of_interactions] for i in HPA_normal_hight_tis['transcipt']]] for j in hight_expression_enst_per_drug] tis = [i.drop_duplicates('transcipt') for i in tis] # Calculate highly expressed proteins once to use in both branches num_highly_expressed = len(HPA_normal_hight_tis.drop_duplicates('transcipt')) # Handle empty drug_interactions case if len(drug_interactions) == 0 or len(tis[0]) == 0: min_max_df.append(pd.DataFrame([names, [np.nan], [np.nan], [np.nan], [num_highly_expressed], [0.0], [np.nan]])\ .T.rename({0:'Drug_ID', 1:f'max_{t_name}_interaction', 2:f'min_{t_name}_interaction', 3:f'mean_{t_name}_interaction', 4:f'n_high_protein_in_{t_name}', 5:f'share_affected_{t_name}', 6:f'weighted_score_{t_name}'}, axis = 1)) else: #get max and min conplex sores for tissue specific ents !!! only for one drug ate a time not for a list (n_interactions is for a list) inter = drug_interactions[drug_interactions['transcipt'].isin(tis[0]['transcipt'])].sort_values('conplex_score', ascending=False) # Calculate new metrics based on `inter` num_affected = inter.shape[0] share_affected = num_affected / num_highly_expressed if num_highly_expressed > 0 else 0.0 mean_score = inter['conplex_score'].mean() weighted_score = share_affected * mean_score min_max_df.append(pd.DataFrame([names, [inter['conplex_score'].max()], [inter['conplex_score'].min()], [mean_score], [num_highly_expressed], [share_affected], [weighted_score]])\ .T.rename({0:'Drug_ID', 1:f'max_{t_name}_interaction', 2:f'min_{t_name}_interaction', 3:f'mean_{t_name}_interaction', 4:f'n_high_protein_in_{t_name}', 5:f'share_affected_{t_name}', 6:f'weighted_score_{t_name}'}, axis = 1)) #get number of interactions for tissue specific ents n_interactions.append(pd.DataFrame([names, [len(i) for i in tis]]).T.rename({0:'Drug_ID',1:f'n_enst_{t_name}_above_target_interaction'}, axis = 1)) #merge interaction data df_n_interactions = n_interactions[0] for d in n_interactions[1:]: df_n_interactions = df_n_interactions.merge(d, on='Drug_ID') #merge min max data df_min_max_df = min_max_df[0] for d in min_max_df[1:]: df_min_max_df = df_min_max_df.merge(d, on='Drug_ID') n_interactions = df_n_interactions.merge(df_min_max_df, left_on='Drug_ID', right_on='Drug_ID') return n_interactions if __name__ == "__main__": parser = argparse.ArgumentParser(description="Calculate biological metrics.") parser.add_argument("--metabolites", required=True, help="Path to the metabolites file.") parser.add_argument("--conplex_all_interactions", required=True, help="Path to the conplex_significant_interaction file.") parser.add_argument("--conplex_drug", required=True, help="Path to the conplex_significant_interaction_drug_only file.") parser.add_argument("--target", required=True, help="PATH to file csv with drug targets in ENST formet separated by space.") args = parser.parse_args() drug_name = args.metabolites.split('/')[-1].split('_out.txt')[0] n_metabolites = get_n_metabolites(args.metabolites) #get target target = pd.read_csv(args.target, header=None)[2:] if len(target) == 2: target = list(target.iloc[-1]) target = target[0].split(' ') else: target = [] df_1, target_ents, drug_interactions = get_conplex_metric(args.conplex_drug, args.conplex_all_interactions, target) #if no target interaction use only 200 unique proteins with highest interactions per tissue if df_1['max_target_scor'].isna()[0]: target_interaction = 0 df_2 = get_number_of_interacting_prot_per_tissue([drug_name], [target_ents], drug_interactions, n_of_interactions = 200) else: target_interaction = 1 df_2 = get_number_of_interacting_prot_per_tissue([drug_name], [target_ents], drug_interactions) df = pd.concat([df_2, df_1], axis=1) df['target_interaction_found'] = target_interaction df['n_metabolites'] = n_metabolites df.to_csv(f'{drug_name}_biological_properties.tsv', sep = '\t', index=False)