diff --git a/.gitignore b/.gitignore index b9e2fd56..36721271 100644 --- a/.gitignore +++ b/.gitignore @@ -177,3 +177,4 @@ src/server/experiments/proteins/* src/server/experiments/conformations/* !/src/server/experiments/conformations/85e6d812-777c-4a79-97c6-054b7aa517f2 src/server/experiments/drug_discovery/25befab3-cb27-4f04-a454-b966ebedbc0c/targets/ +src/ai/custom_models/drug_target/p2rank_2.4.1 \ No newline at end of file diff --git a/src/ai/custom_models/drug_target/utils.py b/src/ai/custom_models/drug_target/utils.py index 4e811a0b..2b3a6892 100644 --- a/src/ai/custom_models/drug_target/utils.py +++ b/src/ai/custom_models/drug_target/utils.py @@ -6,6 +6,12 @@ dirname = os.path.dirname +import ssl + +# Create an unverified SSL context +ssl._create_default_https_context = ssl._create_unverified_context + + def install_p2rank(): # URL of the p2rank tar.gz file p2rank_url = "https://github.com/rdk/p2rank/releases/download/2.4.1/p2rank_2.4.1.tar.gz" diff --git a/src/ai/model.py b/src/ai/model.py index 857d591f..57edd29c 100644 --- a/src/ai/model.py +++ b/src/ai/model.py @@ -1,4 +1,5 @@ import shutil +import subprocess import torch from torch import Tensor @@ -11,6 +12,7 @@ import requests from tqdm import tqdm import pickle +from pathlib import Path from src.server import settings from src.server.services.progress import ProgressTracker @@ -332,19 +334,41 @@ def load_model(self): # Method to get raw model outputs def _raw_inference(self, protein_file_path: str, save_dir: str): protein_filename = os.path.split(protein_file_path)[1] - destination_protein_file = os.path.join(save_dir, protein_filename) - shutil.copyfile(protein_file_path, destination_protein_file) ds = f"{save_dir}/protein_list.ds" with open(ds, "w") as out: out.write(f"{protein_filename}\n") - p2rank_exec = dirname(os.path.abspath(__file__)) + "/custom_models/drug_target/p2rank_2.4.1/prank" - p2rank = f"bash {p2rank_exec}" - cmd = f"{p2rank} predict {ds} -o {save_dir}/p2rank -threads 1" - os.system(cmd) + p2rank_exec = os.path.join(os.path.dirname(os.path.abspath(__file__)), "custom_models/drug_target/p2rank_2.4.1/prank") + cmd = ["bash", p2rank_exec, "predict", ds, "-o", f"{save_dir}/p2rank", "-threads", "1"] + # Run the command and wait for it to complete + subprocess.run(cmd, check=True) + + p2rankFile = os.path.join(save_dir, 'p2rank', f"{Path(protein_filename).stem}.pdb_predictions.csv") + pocket = pd.read_csv(p2rankFile, skipinitialspace=True) + + # Check if the dataframe is empty + if pocket.empty: + return np.array([]) + + print("POCKET DF: ", pocket.columns) + + # Extract and process the 'residue_ids' column + # Splits the value by "_" and return only the integer on the right + residue_ids = pocket['residue_ids'].str.split() + all_ids = [int(item.split('_')[1]) for sublist in residue_ids for item in sublist] + + pocket_ids = np.sort(np.array(all_ids)) + + np.save(os.path.join(save_dir, "pocket.npy"), pocket_ids) + + pocket_ids = pocket_ids.tolist() + + return pocket_ids + + # Method to return raw outputs in the desired format def predict(self, protein_file_path: str, save_dir: str): - self._raw_inference(protein_file_path, save_dir) + return self._raw_inference(protein_file_path, save_dir) @@ -453,9 +477,9 @@ def load_model(self): pass - def _raw_inference(self, protein_ids, ligands, ligands_names, experiment_folder, target_positions, num_recycles): + def _raw_inference(self, protein_ids, ligands, ligands_names, experiment_folder, binding_pockets, num_recycles): experiment_progress_tracker = ProgressTracker(experiment_folder, protein_ids) - for ID in protein_ids: + for ID, binding_pocket in zip(protein_ids, binding_pockets): for LIGAND, LIGAND_NAME in zip(ligands, ligands_names): protein_folder = os.path.join(experiment_folder, ID) result_folder = os.path.join(protein_folder, 'result') @@ -475,7 +499,7 @@ def _raw_inference(self, protein_ids, ligands, ligands_names, experiment_folder, ID = ID.split('/')[-1] # Predict - predict(config.CONFIG, MSA_FEATS, LIGAND_FEATS, ID, target_positions, PARAMS, num_recycles, outdir=result_folder) + predict(config.CONFIG, MSA_FEATS, LIGAND_FEATS, ID, binding_pocket, PARAMS, num_recycles, outdir=result_folder) # Process the prediction RAW_PDB = os.path.join(result_folder, f'{ID}_pred_raw.pdb') @@ -507,13 +531,11 @@ def _raw_inference(self, protein_ids, ligands, ligands_names, experiment_folder, experiment_progress_tracker.update_progress(ID) - def predict(self, ligand_files_paths, protein_files, experiment_folder: str): + def predict(self, ligand_files_paths, protein_files, binding_pockets, experiment_folder: str): logger.info("Making dti predictions...") ligands_names, ligands_smiles = read_sdf_files(ligand_files_paths) protein_file_paths = [os.path.splitext(x)[0] for x in protein_files] - # TODO: ADD p2rank to identify target positions - target_array = np.asarray([]) protein_names = [os.path.splitext(protein_file_path)[-2] for protein_file_path in protein_files] self.prepare_data(ligands_names, ligands_smiles, protein_file_paths, protein_files, experiment_folder) self._raw_inference( @@ -521,5 +543,5 @@ def predict(self, ligand_files_paths, protein_files, experiment_folder: str): ligands=ligands_smiles, ligands_names=ligands_names, experiment_folder=experiment_folder, - target_positions=target_array, + binding_pockets=binding_pockets, num_recycles=3) diff --git a/src/server/api_handlers/drug_target.py b/src/server/api_handlers/drug_target.py index 620d4968..569d0823 100644 --- a/src/server/api_handlers/drug_target.py +++ b/src/server/api_handlers/drug_target.py @@ -1,6 +1,7 @@ import time from flask import Request, jsonify +import numpy as np from src.server.services.sdf_pdb_combine import combine_sdf_pdb from src.server import settings @@ -46,36 +47,42 @@ def load_targets(self, request): return {'id': experiment_id, 'name': experiment_name, 'targets': targets} def set_binding_pocket(self, request): - experiment_id = request.args.get('id') - protein_id = request.args.get('proteinId') - is_pocket_manual = request.args.get('isManualPocket') + data = request.json # Access data sent in the request body + experiment_id = data.get('id') + protein_id = data.get('proteinId') + selected_residues = data.get('selectedResidues', []) + + # Convert to NumPy array + selected_residues_array = np.array(selected_residues) - if is_pocket_manual: - pocket_sequence_ids = request.args.get('pocketIds') - self.experiments_loader.save_pocket(experiment_id, - protein_id, - is_pocket_manual, - pocket_sequence_ids) - else: - self.experiments_loader.save_pocket(experiment_id, - protein_id, - is_pocket_manual) + self.experiments_loader.set_binding_pocket(experiment_id, + protein_id, + selected_residues_array) + + return {} def get_binding_pocket(self, request): experiment_id = request.args.get('id') protein_id = request.args.get('proteinId') - is_pocket_manual = request.args.get('isManualPocket') - - pocket_ids = [] - pocket_ids = self.experiments_loader.load_pocket(experiment_id, - protein_id, - is_pocket_manual) + pocket_ids = self.experiments_loader.load_binding_pocket(experiment_id, + protein_id) return {"experimentId": experiment_id, "proteinId": protein_id, "pocketIds": pocket_ids} + + def predict_binding_pocket(self, request): + experiment_id = request.args.get('id') + protein_id = request.args.get('proteinId') + + pocket = self.drug_discovery.predict_pocket( + experiment_id=experiment_id, + protein_id=protein_id + ) + + return pocket diff --git a/src/server/drug_target_blueprint.py b/src/server/drug_target_blueprint.py index b3256a49..0a10cb84 100644 --- a/src/server/drug_target_blueprint.py +++ b/src/server/drug_target_blueprint.py @@ -25,6 +25,10 @@ def store_binding_pocket(): @drug_target_bp.route('/get-binding-pocket', methods=['GET']) def get_binding_pocket(): return api_handler.get_binding_pocket(request) + + @drug_target_bp.route('/predict-binding-pocket', methods=['GET']) + def predict_binding_pocket(): + return api_handler.predict_binding_pocket(request) @drug_target_bp.route('/experiments') def get_experiments(): diff --git a/src/server/experiments/drug_discovery/25befab3-cb27-4f04-a454-b966ebedbc0c/metadata.json b/src/server/experiments/drug_discovery/25befab3-cb27-4f04-a454-b966ebedbc0c/metadata.json index df5da817..0aed7b0a 100644 --- a/src/server/experiments/drug_discovery/25befab3-cb27-4f04-a454-b966ebedbc0c/metadata.json +++ b/src/server/experiments/drug_discovery/25befab3-cb27-4f04-a454-b966ebedbc0c/metadata.json @@ -1,5 +1,5 @@ { "id": "25befab3-cb27-4f04-a454-b966ebedbc0c", "name": "brinzolamide - CARBONIC ANHYDRASE", - "date": "2023-12-25T19:57:58.717714" + "date": "2023-12-26T21:00:48.870574" } \ No newline at end of file diff --git a/src/server/frontend/src/components/AminoAcidLab/TargetProteinViewer.vue b/src/server/frontend/src/components/AminoAcidLab/TargetProteinViewer.vue index 155638e4..134760d8 100644 --- a/src/server/frontend/src/components/AminoAcidLab/TargetProteinViewer.vue +++ b/src/server/frontend/src/components/AminoAcidLab/TargetProteinViewer.vue @@ -1,6 +1,6 @@