def create_box_receptor( protein: oechem.OEGraphMol, box_dimensions: Tuple[float, float, float, float, float, float], ) -> oechem.OEGraphMol: """ Create a box receptor for docking. Parameters ---------- protein: oechem.OEGraphMol An OpenEye molecule holding a prepared protein structure. box_dimensions: tuple of float The box dimensions in the order of xmax, ymax, zmax, xmin, ymin, zmin. Returns ------- receptor: oechem.OEGraphMol An OpenEye molecule holding a receptor with defined binding site via box dimensions. """ from openeye import oedocking # create receptor box = oedocking.OEBox(*box_dimensions) receptor = oechem.OEGraphMol() oedocking.OEMakeReceptor(receptor, protein, box) return receptor
def main(argv=[__name__]): path = "receptor_pdbs/*.pdb" #input: pdbs from clustering files = glob.glob(path) for i in files: centroid_number = i[-5:-4] imstr = oechem.oemolistream(i) proteinStructure = oechem.OEGraphMol() oechem.OEReadMolecule(imstr, proteinStructure) coordinates_dictionary = oechem.OEMolBase.GetCoords(proteinStructure) x_coord = [] y_coord = [] z_coord = [] for key in coordinates_dictionary: x = coordinates_dictionary[key][0] y = coordinates_dictionary[key][1] z = coordinates_dictionary[key][2] x_coord.append(x) y_coord.append(y) z_coord.append(z) x_max = max(x_coord) x_min = min(x_coord) y_max = max(y_coord) y_min = min(y_coord) z_max = max(z_coord) z_min = min(z_coord) box = oedocking.OEBox( x_max, y_max, z_max, x_min, y_min, z_min) #Box set using max and min coordinates of entire protein receptor = oechem.OEGraphMol() oedocking.OEMakeReceptor(receptor, proteinStructure, box) oedocking.OEWriteReceptorFile(receptor, "receptor_oebs/receptor" + str(centroid_number) + ".oeb") #output: receptor oebs return 0
def create_hint_receptor( protein: oechem.OEGraphMol, hintx: Union[float, int], hinty: Union[float, int], hintz: Union[float, int], ) -> oechem.OEGraphMol: """ Create a hint receptor for docking. Parameters ---------- protein: oechem.OEGraphMol An OpenEye molecule holding a prepared protein structure. hintx: float or int A number defining the hint x coordinate. hinty: float or int A number defining the hint y coordinate. hintz: float or int A number defining the hint z coordinate. Returns ------- receptor: oechem.OEGraphMol An OpenEye molecule holding a receptor with defined binding site via hint coordinates. """ from openeye import oedocking # create receptor receptor = oechem.OEGraphMol() oedocking.OEMakeReceptor(receptor, protein, hintx, hinty, hintz) return receptor
def create_bound_receptor(protein_pdb_path, ligand_file_path): """Create an OpenEye receptor from a PDB file and ligand file. Parameters ---------- protein_pdb_path : str Path to the receptor PDB file. ligand_file_path : str Path to the ligand file (e.g. Tripos mol2). Can be any file format supported by openeye. Returns ------- receptor : openeye.oedocking.OEReceptor The OpenEye receptor object """ from openeye import oechem, oedocking # Load in protein input_mol_stream = oechem.oemolistream(protein_pdb_path) protein_oemol = oechem.OEGraphMol() oechem.OEReadMolecule(input_mol_stream, protein_oemol) # Load in ligand input_mol_stream = oechem.oemolistream(ligand_file_path) ligand_oemol = oechem.OEGraphMol() oechem.OEReadMolecule(input_mol_stream, ligand_oemol) receptor = oechem.OEGraphMol() oedocking.OEMakeReceptor(receptor, protein_oemol, ligand_oemol) return receptor
def _create_receptor(self): """Create an OpenEye receptor from a mol2 file. Returns ------- openeye.oedocking.OEReceptor The OpenEye receptor object. """ from openeye import oechem, oedocking input_stream = oechem.oemolistream(self.receptor_coordinate_file) original_receptor_molecule = oechem.OEGraphMol() oechem.OEReadMolecule(input_stream, original_receptor_molecule) center_of_mass = oechem.OEFloatArray(3) oechem.OEGetCenterOfMass(original_receptor_molecule, center_of_mass) receptor = oechem.OEGraphMol() oedocking.OEMakeReceptor( receptor, original_receptor_molecule, center_of_mass[0], center_of_mass[1], center_of_mass[2], ) return receptor
def create_receptor(protein_pdb_path, box): """Create an OpenEye receptor from a PDB file. Parameters ---------- protein_pdb_path : str Path to the receptor PDB file. box : 1x6 array of float The minimum and maximum values of the coordinates of the box representing the binding site [xmin, ymin, zmin, xmax, ymax, zmax]. Returns ------- receptor : openeye.oedocking.OEReceptor The OpenEye receptor object. """ input_mol_stream = oechem.oemolistream(protein_pdb_path) protein_oemol = oechem.OEGraphMol() oechem.OEReadMolecule(input_mol_stream, protein_oemol) box = oedocking.OEBox(*box) receptor = oechem.OEGraphMol() oedocking.OEMakeReceptor(receptor, protein_oemol, box) return receptor
def prepare_receptor(complex_pdb_filename, prefix): # Read the receptor and identify design units from openeye import oespruce, oechem complex = read_pdb_file(complex_pdb_filename) print('Identifying design units...') design_units = list(oespruce.OEMakeDesignUnits(complex)) for i, design_unit in enumerate(design_units): filename = f'DU_{i}.oedu' print(f'Writing design unit {i} to {filename}') oechem.OEWriteDesignUnit(filename, design_unit) if len(design_units) > 1: print('More than one design unit found---using first one') design_unit = design_units[0] # Prepare the receptor print('Preparing receptor...') from openeye import oedocking protein = oechem.OEGraphMol() design_unit.GetProtein(protein) ligand = oechem.OEGraphMol() design_unit.GetLigand(ligand) receptor = oechem.OEGraphMol() oedocking.OEMakeReceptor(receptor, protein, ligand) oedocking.OEWriteReceptorFile(receptor, f'{prefix}-receptor.oeb.gz') with oechem.oemolostream(f'{prefix}-protein.pdb') as ofs: oechem.OEWriteMolecule(ofs, protein) with oechem.oemolostream(f'{prefix}-ligand.mol2') as ofs: oechem.OEWriteMolecule(ofs, ligand) with oechem.oemolostream(f'{prefix}-ligand.pdb') as ofs: oechem.OEWriteMolecule(ofs, ligand) with oechem.oemolostream(f'{prefix}-ligand.sdf') as ofs: oechem.OEWriteMolecule(ofs, ligand)
def create_box_receptor(protein, xmax, ymax, zmax, xmin, ymin, zmin, receptor_save_path=None): """ Create a box receptor for docking. Parameters ---------- protein: oechem.OEGraphMol An oechem.OEGraphMol object holding a prepared protein structure. xmax: float or int Maximal number in x direction. ymax: float or int Maximal number in y direction. zmax: float or int Maximal number in z direction. xmin: float or int Minimal number in x direction. ymin: float or int Minimal number in x direction. zmin: float or int Minimal number in z direction. receptor_save_path: str File path for saving created receptor. If receptor_save_path is not provided, receptor will not be saved. Returns ------- receptor: oechem.OEGraphMol An oechem.OEGraphMol object holding a receptor with defined binding site via box dimensions. """ # Standard libraries import pathlib # External libraries from openeye import oechem, oedocking # create receptor box = oedocking.OEBox(xmax, ymax, zmax, xmin, ymin, zmin) receptor = oechem.OEGraphMol() oedocking.OEMakeReceptor(receptor, protein, box) # save receptor if receptor_save_path is not None: oedocking.OEWriteReceptorFile( receptor, str(pathlib.Path(receptor_save_path).absolute())) return receptor
def make_docking_system(design_unit: oechem.OEDesignUnit) -> DockingSystem: protein = oechem.OEGraphMol() design_unit.GetProtein(protein) ligand = oechem.OEGraphMol() design_unit.GetLigand(ligand) receptor = oechem.OEGraphMol() oedocking.OEMakeReceptor(receptor, protein, ligand) system = DockingSystem(protein=protein, ligand=ligand, receptor=receptor) return system
def create_receptor(output_name, pdb_file, bp_min, bp_max): check_oeb = output_name proteinStructure = oechem.OEGraphMol() ifs = oechem.oemolistream(pdb_file) ifs.SetFormat(oechem.OEFormat_PDB) oechem.OEReadMolecule(ifs, proteinStructure) box = oedocking.OEBox(*bp_max, *bp_min) receptor = oechem.OEGraphMol() s = oedocking.OEMakeReceptor(receptor, proteinStructure, box) oedocking.OEWriteReceptorFile(receptor, check_oeb)
def __init__(self, pdb_file, xmax, ymax, zmax, xmin, ymin, zmin): self.receptor = oechem.OEGraphMol() self.scorers = oedocking.OEScore(oedocking.OEScoreType_Chemgauss4) proteinStructure = oechem.OEGraphMol() ifs = oechem.oemolistream(pdb_file) ifs.SetFormat(oechem.OEFormat_PDB) oechem.OEReadMolecule(ifs, proteinStructure) box = oedocking.OEBox(xmax, ymax, zmax, xmin, ymin, zmin) receptor = oechem.OEGraphMol() s = oedocking.OEMakeReceptor(receptor, proteinStructure, box) self.scorers.Initialize(receptor)
def create_hint_receptor(protein, hintx, hinty, hintz, receptor_save_path=None): """ Create a hint receptor for docking. Parameters ---------- protein: oechem.OEGraphMol An oechem.OEGraphMol object holding a prepared protein structure. hintx: float or int A number defining the hint x coordinate. hinty: float or int A number defining the hint y coordinate. hintz: float or int A number defining the hint z coordinate. receptor_save_path: str File path for saving created receptor. If receptor_save_path is not provided, receptor will not be saved. Returns ------- receptor: oechem.OEGraphMol An oechem.OEGraphMol object holding a receptor with defined binding site via hint coordinates. """ # Standard libraries import pathlib # External libraries from openeye import oechem, oedocking # create receptor receptor = oechem.OEGraphMol() oedocking.OEMakeReceptor(receptor, protein, hintx, hinty, hintz) # save receptor if receptor_save_path is not None: oedocking.OEWriteReceptorFile( receptor, str(pathlib.Path(receptor_save_path).absolute())) return receptor
def main(argv=[__name__]): if len(sys.argv) != 5: oechem.OEThrow.Usage( "MakeReceptorWithHintXYZ.py <protein> <hint x> <hint y> <hint z>") # @ <SNIPPET-MAKE-RECEPTOR-WITH-HINT-XYZ-1> protein = oechem.OEGraphMol() imstr = oechem.oemolistream(sys.argv[1]) oechem.OEReadMolecule(imstr, protein) hintX = float(sys.argv[2]) hintY = float(sys.argv[3]) hintZ = float(sys.argv[4]) receptor = oechem.OEGraphMol() oedocking.OEMakeReceptor(receptor, protein, hintX, hintY, hintZ) # @ </SNIPPET-MAKE-RECEPTOR-WITH-HINT-XYZ-1> oedocking.OEWriteReceptorFile(receptor, "receptor.oeb.gz")
def main(argv): if len(argv) != 3: oechem.OEThrow.Usage( "MakeReceptorWithLigand.py <protein> <bound ligand>") proteinMolStream = oechem.oemolistream(argv[1]) ligandMolStream = oechem.oemolistream(argv[2]) # @ <SNIPPET-MAKE-RECEPTOR-WITH-LIGAND-1> protein = oechem.OEGraphMol() oechem.OEReadMolecule(proteinMolStream, protein) ligand = oechem.OEGraphMol() oechem.OEReadMolecule(ligandMolStream, ligand) receptor = oechem.OEGraphMol() oedocking.OEMakeReceptor(receptor, protein, ligand) # @ </SNIPPET-MAKE-RECEPTOR-WITH-LIGAND-1> oedocking.OEWriteReceptorFile(receptor, "receptor.oeb.gz")
def __init__(self, pdb_file, xmax, ymax, zmax, xmin, ymin, zmin): self.receptor = oechem.OEGraphMol() self.scorers = { 'Shapegauss': oedocking.OEScore(oedocking.OEScoreType_Shapegauss), 'Chemscore': oedocking.OEScore(oedocking.OEScoreType_Chemscore), 'Chemgauss': oedocking.OEScore(oedocking.OEScoreType_Chemgauss), 'Chemgauss3': oedocking.OEScore(oedocking.OEScoreType_Chemgauss3), 'Chemgauss4': oedocking.OEScore(oedocking.OEScoreType_Chemgauss4), } proteinStructure = oechem.OEGraphMol() ifs = oechem.oemolistream(pdb_file) ifs.SetFormat(oechem.OEFormat_PDB) oechem.OEReadMolecule(ifs, proteinStructure) box = oedocking.OEBox(xmax, ymax, zmax, xmin, ymin, zmin) receptor = oechem.OEGraphMol() s = oedocking.OEMakeReceptor(receptor, proteinStructure, box) for _, score in self.scorers.items(): assert (s != False) score.Initialize(receptor)
def make_receptor( pdb): from openeye import oedocking, oechem import os.path file_name = str(os.path.basename(pdb)) check_oeb = conf['cache'] + file_name.split(".")[0] + ".oeb" if os.path.isfile(check_oeb): g = oechem.OEGraphMol() oedocking.OEReadReceptorFile(g, check_oeb) return g else: proteinStructure = oechem.OEGraphMol() ifs = oechem.oemolistream(pdb) ifs.SetFormat(oechem.OEFormat_PDB) oechem.OEReadMolecule(ifs, proteinStructure) box = oedocking.OEBox(*conf['bp_max'], *conf['bp_min']) receptor = oechem.OEGraphMol() s = oedocking.OEMakeReceptor(receptor, proteinStructure, box) oedocking.OEWriteReceptorFile(receptor, check_oeb) assert (s != False) return receptor
def create_hybrid_receptor( protein: oechem.OEGraphMol, ligand: oechem.OEGraphMol ) -> oechem.OEGraphMol: """ Create a receptor for hybrid docking. Parameters ---------- protein: oechem.OEGraphMol An OpenEye molecule holding a prepared protein structure. ligand: oechem.OEGraphMol An OpenEye molecule holding a prepared ligand structure. Returns ------- receptor: oechem.OEGraphMol An OpenEye molecule holding a receptor with protein and ligand. """ from openeye import oedocking # create receptor receptor = oechem.OEGraphMol() oedocking.OEMakeReceptor(receptor, protein, ligand) return receptor
def create_hybrid_receptor(protein, ligand, receptor_save_path=None): """ Create a receptor for hybrid docking. Parameters ---------- protein: oechem.OEGraphMol An oechem.OEGraphMol object holding a prepared protein structure. ligand: oechem.OEGraphMol An oechem.OEGraphMol object holding a prepared ligand structure. receptor_save_path: str File path for saving created receptor. If receptor_save_path is not provided, receptor will not be saved. Returns ------- receptor: oechem.OEGraphMol An oechem.OEGraphMol object holding a receptor with protein and ligand. """ # Standard libraries import pathlib # External libraries from openeye import oechem, oedocking # create receptor receptor = oechem.OEGraphMol() oedocking.OEMakeReceptor(receptor, protein, ligand) # save receptor if receptor_save_path is not None: oedocking.OEWriteReceptorFile( receptor, str(pathlib.Path(receptor_save_path).absolute())) return receptor
def main(argv=[__name__]): if len(sys.argv) != 8: oechem.OEThrow.Usage("MakeReceptorFromBox.py \ <protein> <xmax> <ymax> <zmax> <xmin> <ymin> <zmin>" ) xmax = float(sys.argv[2]) ymax = float(sys.argv[3]) zmax = float(sys.argv[4]) xmin = float(sys.argv[5]) ymin = float(sys.argv[6]) zmin = float(sys.argv[7]) # @ <SNIPPET-MAKE-RECEPTOR-WITH-BOX-1> imstr = oechem.oemolistream(sys.argv[1]) proteinStructure = oechem.OEGraphMol() oechem.OEReadMolecule(imstr, proteinStructure) box = oedocking.OEBox(xmax, ymax, zmax, xmin, ymin, zmin) receptor = oechem.OEGraphMol() oedocking.OEMakeReceptor(receptor, proteinStructure, box) # @ </SNIPPET-MAKE-RECEPTOR-WITH-BOX-1> oedocking.OEWriteReceptorFile(receptor, "receptor.oeb.gz")
def __init__(self, env, sort='dscores', return_docked_pose=False, num_returns=-1, orig_pdb=None, useHybrid=False, trackHScores=True, optimize=False): self.logger = make_message_writer(env.verbose, self.__class__.__name__) with self.logger("__init__") as logger: self.sort = sort if self.sort not in ['iscores', 'dscores', 'hscores', 'pscores']: logger.failure( f"{self.sort} is not a valid sorting method. Exiting", exit_all=True) self.return_docked_pose = return_docked_pose self.num_returns = num_returns self.env = env self.orig_pdb = orig_pdb self.start_dobj = None self.start_receptor = None self.track_hscores = trackHScores if not self.track_hscores and self.sort == 'hscores': logger.error( "Track hscores is set to false but the sorting method desired is hscores. Assuming this was error, continuing by setting track_hscores to True" ) self.track_hscores = True self.past_receptors = [] self.past_dockobjs = [] self.past_coordinates = [] self.optimize = optimize self.dockmethod = oedocking.OEDockMethod_Hybrid if useHybrid else oedocking.OEDockMethod_Chemgauss4 if (not (self.sort != 'iscores' and self.optimize)) and self.orig_pdb is not None: pdb = oechem.OEMol() prot = oechem.OEMol() lig = oechem.OEMol() wat = oechem.OEGraphMol() other = oechem.OEGraphMol() ifs = oechem.oemolistream(self.orig_pdb) oechem.OEReadMolecule(ifs, pdb) ifs.close() if not oechem.OESplitMolComplex(lig, prot, wat, other, pdb): logger.failure("Could not split complex", exit_all=True) self.start_receptor = oechem.OEGraphMol() logger.log("Building initial receptor file...") oedocking.OEMakeReceptor(self.start_receptor, prot, lig) self.start_dobj = oedocking.OEDock(self.dockmethod) self.start_dobj.Initialize(self.start_receptor) assert (self.start_dobj.IsInitialized()) logger.log("done") elif self.sort != 'iscores' and self.optimize: logger.log( "Skipping building inital receptor because optmize is set and sorting method is not iscore" ) else: logger.log( "Skipping building inital receptor because orig_pdb was not provided." )
def PrepareReceptor(pdb,padding=4,outpath=""): """ Prepares a receptor from a pdb with a crystalized ligand Padding controls the docking region. If outpath is given, PrepareReceptor will write an openeye binary (oeb) of the receptor structure. This will be faster than rebuilding the receptor every time. """ print("STOP CALLING THIS FUNCTION") exit() com = oechem.OEGraphMol() ifs = oechem.oemolistream() if ifs.open(pdb): oechem.OEReadPDBFile(ifs, com) ifs.close() """ Sorry, this requires some explanation. Openeye wasn't recognizing the previously docked ligand, so I tried to find other ways. The next blocks of code take our system and split it based on its connected components, for which its REQUIRED that our protein only has a single chain. It assumes that the last component is the ligand. It then creates the ligand (lig) and protein (prot) as separate molecules. Next, it finds the minimum and maximum 3D coordinates of the current ligand and produces a box around it with the specified padding. Finally it uses this box to create a 'receptor' object into which ligands can be docked. Only the receptor is returned. Openeye's docking shouldn't be this involved, but I couldn't get it to run the typical 'hybrid' docking without error. """ oechem.OEDetermineConnectivity(com) nparts, connect = oechem.OEDetermineComponents(com) if(nparts != 2): print("ERR in dock_conf::prepareReceptor. PDB doesn't have 2 connected components") exit() ## TODO: What is a good way to catch errors? # Get apo pred = oechem.OEPartPredAtom(connect) pred.SelectPart(nparts) lig = oechem.OEGraphMol() oechem.OESubsetMol(lig, com, pred) print(lig) # Get protein pred = oechem.OEPartPredAtom(connect) pred.SelectPart(1) prot = oechem.OEGraphMol() oechem.OESubsetMol(prot, com, pred) # Get box dimensions by iterating over ligand x_min = y_min = z_min = float('inf') x_max = y_max = z_max = -float('inf') crd = lig.GetCoords() print("CRD", crd) for atm in crd: x,y,z = crd[atm] if x < x_min: x_min = x if y < y_min: y_min = y if z < z_min: z_min = z if x > x_max: x_max = x if y > y_max: y_max = y if z > z_max: z_max = z x_min -= padding y_min -= padding z_min -= padding x_max += padding y_max += padding z_max += padding print(x_min,y_min,z_max, y_max) # Now prepare the receptor receptor = oechem.OEGraphMol() box = oedocking.OEBox() box.Setup(x_max, y_max, z_max, x_min, y_min, z_min) oedocking.OEMakeReceptor(receptor, prot, box) if not outpath == "": oedocking.OEWriteReceptorFile(receptor,f'{outpath}/receptor.oeb') return receptor
def dock_molecule(trajectory_frame, original_ligands, new_ligands, title_list, keep_ions=None, override_replacement=False, gen_xml=False, location="./") -> List[mdtraj.Trajectory]: """ Docks ligands or a list of ligands in place of another ligand Parameters ---------- trajectory_frame: mdtraj.Trajectory, required The trajectory to dock to- water will be removed, but every other atoms will stay the same original_ligands: [str], required The original ligand to replace, must be an mdtraj selection string. If more than one residue or no residue is selected, program will throw an index error new_ligands: [[str]], required For each original ligand, a list of SMILES string representing the new ligand to dock. title_list: [[str]], required For each new ligand, the title the user wishes to have. keep_ions: [str], optional, default:None A list of ions to keep when removing solvent. Must be an mdtraj selection. override_replacement: bool, optional, default:False Setting to true will prevent replacing ligand with canonical molecule from PDB. gen_xml: bool, optional, default:False Setting to true runs the generate xml subroutine and saves openmm forcefield compatible XMLs in location. WARNING: Using this option requires antechmaber and is time-consuming location: str, optional, default:None The location to save xml files. Default is current directory Returns ------- output: [mdtraj.Trajectory] A list of trajectories for all combinations of ligands """ # Check inputs if len(original_ligands) != len(new_ligands): raise ValueError( "Original and new ligand arrays must have the same length.") # Produces pdb file in memory overall_dry_frame = trajectory_frame.remove_solvent( exclude=keep_ions) # type: mdtraj.Trajectory complex_prot = _trajectory_to_oemol_(overall_dry_frame) # Bookkeeping ligand_stream = [] output = [] i = 0 # Being processing a ligand for ligand in original_ligands: try: ligand_traj = overall_dry_frame.atom_slice( overall_dry_frame.top.select( ligand)) # type: mdtraj.Trajectory except IndexError as e: print("Ligand selection was invalid") print("Exception: %s" % str(e), file=sys.stderr) traceback.print_tb(e.__traceback__, file=sys.stderr) sys.exit(1) # Find approximate location of binding pocket ligand_center = np.average(ligand_traj.xyz[0], axis=0) * 10 # Convert from nm to angstrom # Explicit value necessary for generated methods x = float(ligand_center[0]) y = float(ligand_center[1]) z = float(ligand_center[2]) # Create receptor molecule receptor = oechem.OEGraphMol() oedocking.OEMakeReceptor(receptor, complex_prot, x, y, z) # Write out and open ligand in OpenEye lig_initial = _trajectory_to_oemol_(ligand_traj) lig_initial.SetTitle(ligand_traj.top.residue(0).name) # Validate if ligand is correct by checking against SMILES lig_smiles = NameToSMILES.getSMILE(ligand_traj.top.residue(0).name) if lig_smiles is not None: neutral_ph_smiles = NameToSMILES.addH(lig_smiles) validation_ligand = oechem.OEGraphMol() validation_ligand.SetTitle(ligand_traj.top.residue(0).name) oechem.OESmilesToMol(validation_ligand, neutral_ph_smiles) if (oechem.OEMolToSmiles(validation_ligand) != oechem.OEMolToSmiles(lig_initial) ) and not override_replacement: ligand_posed = _docking_internal(receptor, lig_initial, validation_ligand) complex_prot = _trajectory_to_oemol_( overall_dry_frame.atom_slice( overall_dry_frame.top.select("not ( %s )" % ligand))) oechem.OEAddMols(receptor, ligand_posed) print( "Warning: Original ligand had either incorrect stereochemistry or missing heavy atoms. Ligand from pdb database placed instead. " ) else: ligand_posed = lig_initial else: print("ligand not found in PDB: No validation and continuing") # Dock new ligands ligand_position = [] # type: List[OEGraphMol] j = 0 for new_ligand in new_ligands[i]: new_structure = oechem.OEGraphMol() oechem.OESmilesToMol(new_structure, new_ligand) new_structure.SetTitle("ligand replacement") print(title_list[i][j]) docked_ligand = _docking_internal(receptor, ligand_posed, new_ligand) docked_ligand.SetTitle(title_list[i][j]) ligand_position.append(docked_ligand) j = j + 1 ligand_stream.append(ligand_position) overall_dry_frame.atom_slice(overall_dry_frame.top.select( "not ( %s )" % ligand), inplace=True) i = i + 1 # Produce output trajectories for all combos of ligands for ligand_combo in itertools.product(*ligand_stream): new_frame_prot = overall_dry_frame # type: Trajectory for built_ligand in ligand_combo: # Rename ligand ligand_dummy = tempfile.NamedTemporaryFile(suffix=".pdb") outputter_lig = oechem.oemolostream(ligand_dummy.name) oechem.OEWriteMolecule(outputter_lig, built_ligand) ligand_final_traj = mdtraj.load(ligand_dummy.name) ligand_dummy.close() for residue in ligand_final_traj.top.residues: residue.name = built_ligand.GetTitle() ligand_named = tempfile.NamedTemporaryFile(suffix=".pdb") ligand_final_traj.save(ligand_named.name) if gen_xml: if not os.path.isfile(location + built_ligand.GetTitle() + ".xml"): generate_xml(ligand_named.name, location, oechem.OENetCharge(built_ligand), built_ligand.GetTitle()) else: print(built_ligand.GetTitle() + ".xml already exists") new_frame_prot = new_frame_prot.stack(ligand_final_traj) output.append(new_frame_prot) print("End") return output
def prepare_receptor(complex_pdb_filename, output_basepath, dimer=False, retain_water=False): """ Parameters ---------- complex_pdb_filename : str The complex PDB file to read in output_basepath : str Base path for output dimer : bool, optional, default=False If True, generate the dimer as the biological unit retain_water : bool, optional, default=False If True, will retain waters """ # Check whether this is a diamond SARS-CoV-2 Mpro structure or not import re is_diamond_structure = (re.search('-x\d+_', complex_pdb_filename) is not None) import os basepath, filename = os.path.split(complex_pdb_filename) prefix, extension = os.path.splitext(filename) prefix = os.path.join(output_basepath, prefix) # Check if receptor already exists receptor_filename = f'{prefix}-receptor.oeb.gz' thiolate_receptor_filename = f'{prefix}-receptor-thiolate.oeb.gz' if os.path.exists(receptor_filename) and os.path.exists( thiolate_receptor_filename): return # Read in PDB file, skipping UNK atoms (left over from processing covalent ligands) pdbfile_lines = [ line for line in open(complex_pdb_filename, 'r') if 'UNK' not in line ] # Check if biological symmetry header is present has_biological_symmetry_header = False for line in pdbfile_lines: if 'REMARK 350' in line: has_biological_symmetry_header = True break # Prepend REMARK 350 (biological symmetry) header lines for Mpro (from 5RGG) if not present if is_diamond_structure and (not has_biological_symmetry_header): pdbfile_lines = [ line + '\n' for line in BIOLOGICAL_SYMMETRY_HEADER.split('\n') ] + pdbfile_lines # If monomer is specified, drop crystal symmetry lines if not dimer: pdbfile_lines = [ line for line in pdbfile_lines if 'REMARK 350' not in line ] # Filter out waters if not retain_water: pdbfile_lines = [line for line in pdbfile_lines if 'HOH' not in line] # Filter out LINK records to covalent inhibitors so we can model non-covalent complex pdbfile_lines = [line for line in pdbfile_lines if 'LINK' not in line] # Reconstruct PDBFile contents pdbfile_contents = ''.join(pdbfile_lines) # Append SEQRES to all structures if they do not have it seqres = """\ SEQRES 1 A 306 SER GLY PHE ARG LYS MET ALA PHE PRO SER GLY LYS VAL SEQRES 2 A 306 GLU GLY CYS MET VAL GLN VAL THR CYS GLY THR THR THR SEQRES 3 A 306 LEU ASN GLY LEU TRP LEU ASP ASP VAL VAL TYR CYS PRO SEQRES 4 A 306 ARG HIS VAL ILE CYS THR SER GLU ASP MET LEU ASN PRO SEQRES 5 A 306 ASN TYR GLU ASP LEU LEU ILE ARG LYS SER ASN HIS ASN SEQRES 6 A 306 PHE LEU VAL GLN ALA GLY ASN VAL GLN LEU ARG VAL ILE SEQRES 7 A 306 GLY HIS SER MET GLN ASN CYS VAL LEU LYS LEU LYS VAL SEQRES 8 A 306 ASP THR ALA ASN PRO LYS THR PRO LYS TYR LYS PHE VAL SEQRES 9 A 306 ARG ILE GLN PRO GLY GLN THR PHE SER VAL LEU ALA CYS SEQRES 10 A 306 TYR ASN GLY SER PRO SER GLY VAL TYR GLN CYS ALA MET SEQRES 11 A 306 ARG PRO ASN PHE THR ILE LYS GLY SER PHE LEU ASN GLY SEQRES 12 A 306 SER CYS GLY SER VAL GLY PHE ASN ILE ASP TYR ASP CYS SEQRES 13 A 306 VAL SER PHE CYS TYR MET HIS HIS MET GLU LEU PRO THR SEQRES 14 A 306 GLY VAL HIS ALA GLY THR ASP LEU GLU GLY ASN PHE TYR SEQRES 15 A 306 GLY PRO PHE VAL ASP ARG GLN THR ALA GLN ALA ALA GLY SEQRES 16 A 306 THR ASP THR THR ILE THR VAL ASN VAL LEU ALA TRP LEU SEQRES 17 A 306 TYR ALA ALA VAL ILE ASN GLY ASP ARG TRP PHE LEU ASN SEQRES 18 A 306 ARG PHE THR THR THR LEU ASN ASP PHE ASN LEU VAL ALA SEQRES 19 A 306 MET LYS TYR ASN TYR GLU PRO LEU THR GLN ASP HIS VAL SEQRES 20 A 306 ASP ILE LEU GLY PRO LEU SER ALA GLN THR GLY ILE ALA SEQRES 21 A 306 VAL LEU ASP MET CYS ALA SER LEU LYS GLU LEU LEU GLN SEQRES 22 A 306 ASN GLY MET ASN GLY ARG THR ILE LEU GLY SER ALA LEU SEQRES 23 A 306 LEU GLU ASP GLU PHE THR PRO PHE ASP VAL VAL ARG GLN SEQRES 24 A 306 CYS SER GLY VAL THR PHE GLN """ has_seqres = 'SEQRES' in pdbfile_contents if not has_seqres: #print('Adding SEQRES') pdbfile_contents = seqres + pdbfile_contents # Read the receptor and identify design units from openeye import oespruce, oechem from tempfile import NamedTemporaryFile with NamedTemporaryFile(delete=False, mode='wt', suffix='.pdb') as pdbfile: pdbfile.write(pdbfile_contents) pdbfile.close() complex = read_pdb_file(pdbfile.name) # TODO: Clean up # Strip protons from structure to allow SpruceTK to add these back # See: 6wnp, 6wtj, 6wtk, 6xb2, 6xqs, 6xqt, 6xqu, 6m2n #print('Suppressing hydrogens') #print(f' Initial: {sum([1 for atom in complex.GetAtoms()])} atoms') for atom in complex.GetAtoms(): if atom.GetAtomicNum() > 1: oechem.OESuppressHydrogens(atom) #print(f' Final: {sum([1 for atom in complex.GetAtoms()])} atoms') # Delete and rebuild C-terminal residue because Spruce causes issues with this # See: 6m2n 6lze #print('Deleting C-terminal residue O') pred = oechem.OEIsCTerminalAtom() for atom in complex.GetAtoms(): if pred(atom): for nbor in atom.GetAtoms(): if oechem.OEGetPDBAtomIndex(nbor) == oechem.OEPDBAtomName_O: complex.DeleteAtom(nbor) #pred = oechem.OEAtomMatchResidue(["GLN:306:.*:.*:.*"]) #for atom in complex.GetAtoms(pred): # if oechem.OEGetPDBAtomIndex(atom) == oechem.OEPDBAtomName_O: # print('Deleting O') # complex.DeleteAtom(atom) #het = oespruce.OEHeterogenMetadata() #het.SetTitle("LIG") # real ligand 3 letter code #het.SetID("CovMoonShot1234") # in case you have corporate IDs #het.SetType(oespruce.OEHeterogenType_Ligand) # mdata.AddHeterogenMetadata(het) #print('Identifying design units...') # Produce zero design units if we fail to protonate # Log warnings errfs = oechem.oeosstream( ) # create a stream that writes internally to a stream oechem.OEThrow.SetOutputStream(errfs) oechem.OEThrow.Clear() oechem.OEThrow.SetLevel( oechem.OEErrorLevel_Verbose) # capture verbose error output opts = oespruce.OEMakeDesignUnitOptions() #print(f'ligand atoms: min {opts.GetSplitOptions().GetMinLigAtoms()}, max {opts.GetSplitOptions().GetMaxLigAtoms()}') opts.GetSplitOptions().SetMinLigAtoms( 7) # minimum fragment size (in heavy atoms) mdata = oespruce.OEStructureMetadata() opts.GetPrepOptions().SetStrictProtonationMode(True) # Both N- and C-termini should be zwitterionic # Mpro cleaves its own N- and C-termini # See https://www.pnas.org/content/113/46/12997 opts.GetPrepOptions().GetBuildOptions().SetCapNTermini(False) opts.GetPrepOptions().GetBuildOptions().SetCapCTermini(False) # Don't allow truncation of termini, since force fields don't have parameters for this opts.GetPrepOptions().GetBuildOptions().GetCapBuilderOptions( ).SetAllowTruncate(False) # Build loops and sidechains opts.GetPrepOptions().GetBuildOptions().SetBuildLoops(True) opts.GetPrepOptions().GetBuildOptions().SetBuildSidechains(True) # Don't flip Gln189 #pred = oechem.OEAtomMatchResidue(["GLN:189: :A"]) pred = oechem.OEAtomMatchResidue(["GLN:189:.*:.*:.*"]) protonate_opts = opts.GetPrepOptions().GetProtonateOptions() place_hydrogens_opts = protonate_opts.GetPlaceHydrogensOptions() #place_hydrogens_opts.SetBypassPredicate(pred) place_hydrogens_opts.SetNoFlipPredicate(pred) #protonate_opts = oespruce.OEProtonateDesignUnitOptions(place_hydrogens_opts) #opts.GetPrepOptions().SetProtonateOptions(protonate_options); # Make design units design_units = list(oespruce.OEMakeDesignUnits(complex, mdata, opts)) # Restore error stream oechem.OEThrow.SetOutputStream(oechem.oeerr) # Capture the warnings to a string warnings = errfs.str().decode("utf-8") if len(design_units) >= 1: design_unit = design_units[0] print('') print('') print(f'{complex_pdb_filename} : SUCCESS') print(warnings) elif len(design_units) == 0: print('') print('') print(f'{complex_pdb_filename} : FAILURE') print(warnings) msg = f'No design units found for {complex_pdb_filename}\n' msg += warnings msg += '\n' raise Exception(msg) # Prepare the receptor #print('Preparing receptor...') from openeye import oedocking protein = oechem.OEGraphMol() design_unit.GetProtein(protein) ligand = oechem.OEGraphMol() design_unit.GetLigand(ligand) # Create receptor and other files receptor = oechem.OEGraphMol() oedocking.OEMakeReceptor(receptor, protein, ligand) oedocking.OEWriteReceptorFile(receptor, receptor_filename) with oechem.oemolostream(f'{prefix}-protein.pdb') as ofs: oechem.OEWriteMolecule(ofs, protein) with oechem.oemolostream(f'{prefix}-ligand.mol2') as ofs: oechem.OEWriteMolecule(ofs, ligand) with oechem.oemolostream(f'{prefix}-ligand.pdb') as ofs: oechem.OEWriteMolecule(ofs, ligand) with oechem.oemolostream(f'{prefix}-ligand.sdf') as ofs: oechem.OEWriteMolecule(ofs, ligand) # Filter out UNK from PDB files (which have covalent adducts) pdbfile_lines = [ line for line in open(f'{prefix}-protein.pdb', 'r') if 'UNK' not in line ] with open(f'{prefix}-protein.pdb', 'wt') as outfile: outfile.write(''.join(pdbfile_lines)) # Adjust protonation state of CYS145 to generate thiolate form #print('Deprotonating CYS145...') # DEBUG #pred = oechem.OEAtomMatchResidue(["CYS:145: :A"]) pred = oechem.OEAtomMatchResidue(["CYS:145:.*:.*:.*"]) place_hydrogens_opts.SetBypassPredicate(pred) for atom in protein.GetAtoms(pred): if oechem.OEGetPDBAtomIndex(atom) == oechem.OEPDBAtomName_SG: #print('Modifying CYS 145 SG') oechem.OESuppressHydrogens(atom) atom.SetFormalCharge(-1) atom.SetImplicitHCount(0) #print('Protonating HIS41...') # DEBUG #pred = oechem.OEAtomMatchResidue(["HIS:41: :A"]) pred = oechem.OEAtomMatchResidue(["HIS:41:.*:.*:.*"]) place_hydrogens_opts.SetBypassPredicate(pred) for atom in protein.GetAtoms(pred): if oechem.OEGetPDBAtomIndex(atom) == oechem.OEPDBAtomName_ND1: #print('Protonating HIS 41 ND1') oechem.OESuppressHydrogens(atom) # strip hydrogens from residue atom.SetFormalCharge(+1) atom.SetImplicitHCount(1) # Update the design unit with the modified formal charge for CYS 145 SG oechem.OEUpdateDesignUnit(design_unit, protein, oechem.OEDesignUnitComponents_Protein) # Don't flip Gln189 #pred = oechem.OEAtomMatchResidue(["GLN:189: :A"]) #protonate_opts = opts.GetPrepOptions().GetProtonateOptions(); #place_hydrogens_opts = protonate_opts.GetPlaceHydrogensOptions() #place_hydrogens_opts.SetNoFlipPredicate(pred) # Adjust protonation states #print('Re-optimizing hydrogen positions...') # DEBUG #place_hydrogens_opts = oechem.OEPlaceHydrogensOptions() #place_hydrogens_opts.SetBypassPredicate(pred) #protonate_opts = oespruce.OEProtonateDesignUnitOptions(place_hydrogens_opts) success = oespruce.OEProtonateDesignUnit(design_unit, protonate_opts) design_unit.GetProtein(protein) # Write thiolate form of receptor receptor = oechem.OEGraphMol() oedocking.OEMakeReceptor(receptor, protein, ligand) oedocking.OEWriteReceptorFile(receptor, thiolate_receptor_filename) with oechem.oemolostream(f'{prefix}-protein-thiolate.pdb') as ofs: oechem.OEWriteMolecule(ofs, protein) # Filter out UNK from PDB files (which have covalent adducts) pdbfile_lines = [ line for line in open(f'{prefix}-protein-thiolate.pdb', 'r') if 'UNK' not in line ] with open(f'{prefix}-protein-thiolate.pdb', 'wt') as outfile: outfile.write(''.join(pdbfile_lines))
def prepare_receptor(complex_pdb_filename, output_basepath, dimer=False): """ Parameters ---------- complex_pdb_filename : str The complex PDB file to read in output_basepath : str Base path for output dimer : bool, optional, default=False If True, generate the dimer as the biological unit """ import os basepath, filename = os.path.split(complex_pdb_filename) prefix, extension = os.path.splitext(filename) prefix = os.path.join(output_basepath, prefix) # Check if receptor already exists receptor_filename = f'{prefix}-receptor.oeb.gz' thiolate_receptor_filename = f'{prefix}-receptor-thiolate.oeb.gz' if os.path.exists(receptor_filename) and os.path.exists( thiolate_receptor_filename): return # Read in PDB file pdbfile_lines = [ line for line in open(complex_pdb_filename, 'r') if 'UNK' not in line ] # If monomer is specified, drop crystal symmetry lines if not dimer: pdbfile_lines = [ line for line in pdbfile_lines if 'REMARK 350' not in line ] # Reconstruct PDBFile contents pdbfile_contents = ''.join(pdbfile_lines) # Read the receptor and identify design units from openeye import oespruce, oechem from tempfile import NamedTemporaryFile with NamedTemporaryFile(delete=False, mode='wt', suffix='.pdb') as pdbfile: pdbfile.write(pdbfile_contents) pdbfile.close() complex = read_pdb_file(pdbfile.name) # TODO: Clean up #print('Identifying design units...') design_units = list(oespruce.OEMakeDesignUnits(complex)) if len(design_units) == 1: design_unit = design_units[0] elif len(design_units) > 1: #print('More than one design unit found---using first one') design_unit = design_units[0] elif len(design_units) == 0: raise Exception(f' * No design units found for {complex_pdb_filename}') # Prepare the receptor #print('Preparing receptor...') from openeye import oedocking protein = oechem.OEGraphMol() design_unit.GetProtein(protein) ligand = oechem.OEGraphMol() design_unit.GetLigand(ligand) receptor = oechem.OEGraphMol() oedocking.OEMakeReceptor(receptor, protein, ligand) oedocking.OEWriteReceptorFile(receptor, receptor_filename) with oechem.oemolostream(f'{prefix}-protein.pdb') as ofs: oechem.OEWriteMolecule(ofs, protein) with oechem.oemolostream(f'{prefix}-ligand.mol2') as ofs: oechem.OEWriteMolecule(ofs, ligand) with oechem.oemolostream(f'{prefix}-ligand.pdb') as ofs: oechem.OEWriteMolecule(ofs, ligand) with oechem.oemolostream(f'{prefix}-ligand.sdf') as ofs: oechem.OEWriteMolecule(ofs, ligand) # Filter out UNK from PDB files (which have covalent adducts) pdbfile_lines = [ line for line in open(f'{prefix}-protein.pdb', 'r') if 'UNK' not in line ] with open(f'{prefix}-protein.pdb', 'wt') as outfile: outfile.write(''.join(pdbfile_lines)) # Adjust protonation state of CYS145 to generate thiolate form #print('Deprotonating CYS145...') pred = oechem.OEAtomMatchResidue(["CYS:145: :A"]) for atom in protein.GetAtoms(pred): if oechem.OEGetPDBAtomIndex(atom) == oechem.OEPDBAtomName_SG: oechem.OESuppressHydrogens(atom) atom.SetFormalCharge(-1) atom.SetImplicitHCount(0) # Adjust protonation states #print('Re-optimizing hydrogen positions...') place_hydrogens_opts = oechem.OEPlaceHydrogensOptions() place_hydrogens_opts.SetBypassPredicate(pred) protonate_opts = oespruce.OEProtonateDesignUnitOptions( place_hydrogens_opts) success = oespruce.OEProtonateDesignUnit(design_unit, protonate_opts) design_unit.GetProtein(protein) # Old hacky way to adjust protonation states #opts = oechem.OEPlaceHydrogensOptions() #opts.SetBypassPredicate(pred) #describe = oechem.OEPlaceHydrogensDetails() #success = oechem.OEPlaceHydrogens(protein, describe, opts) #if success: # oechem.OEUpdateDesignUnit(design_unit, protein, oechem.OEDesignUnitComponents_Protein) # Write thiolate form of receptor receptor = oechem.OEGraphMol() oedocking.OEMakeReceptor(receptor, protein, ligand) oedocking.OEWriteReceptorFile(receptor, thiolate_receptor_filename) with oechem.oemolostream(f'{prefix}-protein-thiolate.pdb') as ofs: oechem.OEWriteMolecule(ofs, protein) # Filter out UNK from PDB files (which have covalent adducts) pdbfile_lines = [ line for line in open(f'{prefix}-protein-thiolate.pdb', 'r') if 'UNK' not in line ] with open(f'{prefix}-protein-thiolate.pdb', 'wt') as outfile: outfile.write(''.join(pdbfile_lines))
def hybrid_docking(receptor_path, molecules_path, docked_molecules_path, n_poses=10): """Automated hybrid docking of small molecules to a receptor. Parameters ---------- receptor_path : str Path to PDB file containing receptor and reference ligand, or pre-prepared receptor for docking molecules_path : str Path to file containing one or more molecules (in OpenEye readable format) to be docked. (For example, list of SMILES) docked_molecules_path : str Path to output file to be created to contain docked molecules Uses OpenEye recognized file extension, such as .mol2 or .sdf n_poses : int, optional, default=1 Number of docked poses to generate receptor_filename : str, optional, default=None If not None, the pre-prepared receptor is loaded TODO: How can this API be improved? """ from .docking import create_receptor, load_receptor, pose_molecule from openeye import oedocking, oechem #import openmoltools as moltools # TODO: Bring these methods into this module # Try to load pre-prepared receptor from specified file receptor = oechem.OEGraphMol() print('Attempting to load receptor from {}...'.format(receptor_path)) if not oedocking.OEReadReceptorFile(receptor, receptor_path): # Load complex of receptor and reference ligand complex_istream = oechem.oemolistream(receptor_path) complex = oechem.OEGraphMol() oechem.OEReadMolecule(complex_istream, complex) # Attempt to split into components and build receptor based on reference ligand print('Attempting to split complex into components...') ligand = oechem.OEGraphMol() protein = oechem.OEGraphMol() water = oechem.OEGraphMol() other = oechem.OEGraphMol() if oechem.OESplitMolComplex(ligand, protein, water, other, complex): # Create receptor using bound ligand reference print('Creating receptor using reference ligand...') oedocking.OEMakeReceptor(receptor, protein, ligand) # TODO: We can store prepared receptor file if desired oedocking.OEWriteReceptorFile( receptor, '/home/guoj1/projects/INSPIRE/kinomodel/kinomodel/data/docking/prepared_receptor.oeb' ) else: raise Exception( 'Could not split specified PDB file {} into receptor and reference ligand' .format(receptor_path)) # Open file for writing docked molecules docked_molecules_ostream = oechem.oemolostream(docked_molecules_path) # Configure omega # From canonical recipe: https://docs.eyesopen.com/toolkits/cookbook/python/modeling/am1-bcc.html from openeye import oeomega omega = oeomega.OEOmega() omega.SetIncludeInput(False) omega.SetCanonOrder(False) omega.SetSampleHydrogens(True) eWindow = 15.0 omega.SetEnergyWindow(eWindow) omega.SetMaxConfs(800) omega.SetRMSThreshold(1.0) # Dock all molecules requested dock_method = oedocking.OEDockMethod_Hybrid2 dock_resolution = oedocking.OESearchResolution_Standard dock = oedocking.OEDock(dock_method, dock_resolution) dock.Initialize(receptor) molecules_istream = oechem.oemolistream(molecules_path) molecule = oechem.OEGraphMol() for molecule in molecules_istream.GetOEMols(): print("docking", molecule.GetTitle()) #docked_molecules = pose_molecule(receptor, molecule, n_poses=n_poses) #molecule = moltools.openeye.get_charges(molecule, keep_confs=10) # Generate conformers if not omega(molecule): continue # Apply charges from openeye import oequacpac oequacpac.OEAssignCharges(molecule, oequacpac.OEAM1BCCELF10Charges()) # Dock docked_molecule = oechem.OEGraphMol() dock.DockMultiConformerMolecule(docked_molecule, molecule) sdtag = oedocking.OEDockMethodGetName(dock_method) oedocking.OESetSDScore(docked_molecule, dock, sdtag) dock.AnnotatePose(docked_molecule) oechem.OEWriteMolecule(docked_molecules_ostream, docked_molecule)
def getscores(self, actions, gsmis, prot, lig, num_returns=10, return_docked_pose=False, refmol=None): with self.logger("getscores") as logger: if num_returns <= 0: num_returns = len(actions) - 1 logger.log("Action space is ", len(actions)) idxs = list( np.random.choice(len(actions), min(num_returns, len(actions) - 1), replace=False).flatten()) actions = [actions[idx] for idx in idxs] gsmis = [gsmis[idx] for idx in idxs] protein = oechem.OEMol(prot) receptor = oechem.OEGraphMol() if not (self.sort == 'iscores' and self.optimize): logger.log( "Creating receptor from recent pdb, this might take awhile" ) oedocking.OEMakeReceptor(receptor, protein, lig) dockobj = oedocking.OEDock(self.dockmethod) dockobj.Initialize(receptor) assert (dockobj.IsInitialized()) logger.log("done") else: dockobj = None logger.log( "Skipping receptor building as optimize is set and sort method is iscore." ) pscores = [] dscores = [] ds_old_scores = [] ds_start_scores = [] data = [] with multiprocessing.Pool() as p: imapiter = p.imap( self.env.action.aligner.__class__.call_static, zip(actions, gsmis, [copy.deepcopy(refmol)] * len(actions))) for idx, res in enumerate(imapiter): try: if res is None: logger.error( "Alignment failed and returned none for ", gsmis[idx]) continue ps, ds, ds_start, ds_old = None, None, None, [] new_mol, new_mol2, gs, action = res if dockobj is not None: dockedpose = oechem.OEMol() newmol2 = oechem.OEMol(new_mol) dockobj.DockMultiConformerMolecule( dockedpose, newmol2, 1) ds = dockedpose.GetEnergy() ps = dockobj.ScoreLigand(new_mol) dscores.append(ds) pscores.append(ps) if return_docked_pose: new_mol_ = oechem.OEMol(dockedpose) if self.start_dobj is not None: dockedpose2 = oechem.OEMol() newmol2 = oechem.OEMol(new_mol) self.start_dobj.DockMultiConformerMolecule( dockedpose2, newmol2, 1) ds_start = dockedpose2.GetEnergy() ds_start_scores.append(ds_start) if self.track_hscores: for olddobj in self.past_dockobjs: dockedpose2 = oechem.OEMol() newmol2 = oechem.OEMol(new_mol) olddobj.DockMultiConformerMolecule( dockedpose2, newmol2, 1) ds_old.append(dockedpose2.GetEnergy()) ds_old_scores.append(ds_old) if dockobj is not None and return_docked_pose: new_mol = new_mol_ oechem.OEAssignAromaticFlags(new_mol) oechem.OEAddExplicitHydrogens(new_mol) oechem.OE3DToInternalStereo(new_mol) new_mol2 = oechem.OEMol(new_mol) gs = oechem.OECreateSmiString( new_mol, oechem.OESMILESFlag_DEFAULT | oechem.OESMILESFlag_Hydrogens | oechem.OESMILESFlag_Isotopes | oechem.OESMILESFlag_BondStereo | oechem.OESMILESFlag_AtomStereo) logger.log( f"(idx / {len(idxs)}: Pose Score {ps}, Dock Score {ds}, Init Score {ds_start}" ) data.append((new_mol, new_mol2, gs, action)) except Exception as p: logger.error(p) traceback.print_tb(p.__traceback__) continue self.past_dockobjs.append(dockobj) self.past_receptors.append(receptor) logger.log("Sorting on", self.sort) if self.sort == 'dscores': order = np.argsort(dscores) logger.log([dscores[i] for i in order]) elif self.sort == 'pscores': order = np.argsort(pscores) logger.log([pscores[i] for i in order]) elif self.sort == 'iscores': order = np.argsort(ds_start_scores) logger.log([ds_start_scores[i] for i in order]) elif self.sort == 'hscores': hscores = [ np.quantile(np.clip(scoreset, None, 0), 0.) for scoreset in ds_old_scores ] order = np.argsort(hscores) logger.log([hscores[i] for i in order]) else: assert (False) self.env.data['dscores'].append(dscores) self.env.data['pscores'].append(pscores) self.env.data['iscores'].append(ds_start_scores) self.env.data['hscores'].append(ds_old_scores) data = [data[i] for i in order] return data