def gen_torsional_confs(mol, dih, num_points, include_input=False): """Drives the primary torsion in the molecule and generates labeled torsional conformers. Inputs: mol - OEMol must have a 'CONFORMER_LABEL' in the sd_data """ angle_list = [2*i*oechem.Pi/num_points for i in range(num_points)] dih_atoms = [x for x in dih.GetAtoms()] # Create new output OEMol torsion_conformers = oechem.OEMol(mol) if not include_input: torsion_conformers.DeleteConfs() for conf_id, conf in enumerate(mol.GetConfs()): conf_name = get_sd_data(conf, 'CONFORMER_LABEL') for angle_idx, angle in enumerate(angle_list): angle_deg = int(round(angle*oechem.Rad2Deg)) oechem.OESetTorsion(conf, dih_atoms[0], dih_atoms[1], dih_atoms[2], dih_atoms[3], angle) new_conf = torsion_conformers.NewConf(conf) new_conf.SetDimension(3) new_conf_name = conf_name + '_{:02d}'.format(angle_idx) oechem.OESetSDData(new_conf, 'CONFORMER_LABEL', new_conf_name) oechem.OESetSDData(new_conf, 'TORSION_ANGLE', "{:.0f}".format(angle_deg)) new_conf.SetDoubleData('TORSION_ANGLE', angle_deg) new_conf.SetTitle('{}: Angle {:.0f}'.format(conf_name, angle_deg)) return torsion_conformers
def main(argv=[__name__]): itf = oechem.OEInterface(InterfaceData) if not oechem.OEParseCommandLine(itf, argv): return 1 imstr = oechem.oemolistream(itf.GetString("-in")) omstr = oechem.oemolostream(itf.GetString("-out")) receptors = [] for receptor_filename in itf.GetStringList("-receptors"): receptor = oechem.OEGraphMol() if not oedocking.OEReadReceptorFile(receptor, receptor_filename): oechem.OEThrow.Fatal("Unable to read receptor from %s" % receptor_filename) receptors.append(receptor) poser = oedocking.OEPosit() for receptor in receptors: poser.AddReceptor(receptor) for mcmol in imstr.GetOEMols(): print("posing", mcmol.GetTitle()) result = oedocking.OESinglePoseResult() ret_code = poser.Dock(result, mcmol) if ret_code == oedocking.OEDockingReturnCode_Success: posedMol = result.GetPose() oechem.OESetSDData(posedMol, poser.GetName(), str(result.GetProbability())) oechem.OESetSDData(posedMol, "Receptor Index", str(result.GetReceptorIndex())) oechem.OEWriteMolecule(omstr, posedMol) else: errMsg = oedocking.OEDockingReturnCodeGetName(ret_code) oechem.OEThrow.Warning("%s: %s" % (mcmol.GetTitle(), errMsg)) return 0
def main(argv=[__name__]): if len(argv) != 5: oechem.OEThrow.Usage("%s <reffile> <fitfile> <out.sdf> <keepsize>" % argv[0]) reffs = oechem.oemolistream(argv[1]) fitfs = oechem.oemolistream(argv[2]) outfs = oechem.oemolostream(argv[3]) keepsize = int(argv[4]) refmol = oechem.OEMol() oechem.OEReadMolecule(reffs, refmol) print("Ref. Title:", refmol.GetTitle(), "Num Confs:", refmol.NumConfs()) # Prepare reference molecule for calculation # With default options this will remove any explicit # hydrogens present and add color atoms prep = oeshape.OEOverlapPrep() prep.Prep(refmol) overlay = oeshape.OEMultiRefOverlay() overlay.SetupRef(refmol) for fitmol in fitfs.GetOEMols(): print("Fit Title:", fitmol.GetTitle(), "Num Confs:", fitmol.NumConfs()) prep.Prep(fitmol) resCount = 0 # Sort all scores according to highest tanimoto scoreiter = oeshape.OEBestOverlayScoreIter() oeshape.OESortOverlayScores(scoreiter, overlay.Overlay(fitmol), oeshape.OEHighestTanimoto()) for score in scoreiter: outmol = oechem.OEGraphMol( fitmol.GetConf(oechem.OEHasConfIdx(score.GetFitConfIdx()))) score.Transform(outmol) oechem.OESetSDData(outmol, "RefConfIdx", "%-d" % score.GetRefConfIdx()) oechem.OESetSDData(outmol, "tanimoto combo", "%-.3f" % score.GetTanimotoCombo()) oechem.OEWriteMolecule( outfs, refmol.GetConf(oechem.OEHasConfIdx(score.GetRefConfIdx()))) oechem.OEWriteMolecule(outfs, outmol) resCount += 1 # Break at the user specified size if resCount == keepsize: break print(resCount, "results returned")
def process(self, mol, port): kT_in_kcal_per_mole = self.kT.value_in_unit(unit.kilocalories_per_mole) # Retrieve data about which molecule we are processing title = mol.GetTitle() with TemporaryDirectory() as output_directory: try: # Print out which molecule we are processing self.log.info('Processing {} in directory {}.'.format(title, output_directory)) # Check that molecule is charged. if not molecule_is_charged(mol): raise Exception('Molecule %s has no charges; input molecules must be charged.' % mol.GetTitle()) # Write the specified molecule out to a mol2 file without changing its name. mol2_filename = os.path.join(output_directory, 'input.mol2') ofs = oechem.oemolostream(mol2_filename) oechem.OEWriteMol2File(ofs, mol) # Undo oechem fuckery with naming mol2 substructures `<0>` from YankCubes.utils import unfuck_oechem_mol2_file unfuck_oechem_mol2_file(mol2_filename) # Run YANK on the specified molecule. from yank.yamlbuild import YamlBuilder yaml = self.construct_yaml(output_directory=output_directory) yaml_builder = YamlBuilder(yaml) yaml_builder.build_experiments() self.log.info('Ran Yank experiments for molecule {}.'.format(title)) # Analyze the hydration free energy. from yank.analyze import estimate_free_energies (Deltaf_ij_solvent, dDeltaf_ij_solvent) = estimate_free_energies(netcdf.Dataset(output_directory + '/experiments/solvent1.nc', 'r')) (Deltaf_ij_vacuum, dDeltaf_ij_vacuum) = estimate_free_energies(netcdf.Dataset(output_directory + '/experiments/solvent2.nc', 'r')) DeltaG_hydration = Deltaf_ij_vacuum[0,-1] - Deltaf_ij_solvent[0,-1] dDeltaG_hydration = np.sqrt(Deltaf_ij_vacuum[0,-1]**2 + Deltaf_ij_solvent[0,-1]**2) # Add result to original molecule oechem.OESetSDData(mol, 'DeltaG_yank_hydration', str(DeltaG_hydration * kT_in_kcal_per_mole)) oechem.OESetSDData(mol, 'dDeltaG_yank_hydration', str(dDeltaG_hydration * kT_in_kcal_per_mole)) self.log.info('Analyzed and stored hydration free energy for molecule {}.'.format(title)) # Emit molecule to success port. self.success.emit(mol) except Exception as e: self.log.info('Exception encountered when processing molecule {}.'.format(title)) # Attach error message to the molecule that failed # TODO: If there is an error in the leap setup log, # we should capture that and attach it to the failed molecule. self.log.error(traceback.format_exc()) mol.SetData('error', str(e)) # Return failed molecule self.failure.emit(mol)
def main(argv=[__name__]): itf = oechem.OEInterface(InterfaceData, argv) # Set up best overlay to the query molecule qfs = oechem.oemolistream() if not qfs.open(itf.GetString("-q")): oechem.OEThrow.Fatal("Unable to open %s" % itf.GetString("-q")) qmol = oechem.OEMol() oechem.OEReadMolecule(qfs, qmol) # Set up overlap to protein exclusion volume efs = oechem.oemolistream() if not efs.open(itf.GetString("-e")): oechem.OEThrow.Fatal("Unable to open %s" % itf.GetString("-e")) emol = oechem.OEMol() oechem.OEReadMolecule(efs, emol) evol = oeshape.OEExactShapeFunc() evol.SetupRef(emol) # open database and output streams ifs = oechem.oemolistream() if not ifs.open(itf.GetString("-d")): oechem.OEThrow.Fatal("Unable to open %s" % itf.GetString("-d")) ofs = oechem.oemolostream() if not ofs.open(itf.GetString("-o")): oechem.OEThrow.Fatal("Unable to open %s" % itf.GetString("-o")) print("Title Combo Rescore") for mol in ifs.GetOEMols(): res = oeshape.OEROCSResult() oeshape.OEROCSOverlay(res, qmol, mol) outmol = res.GetOverlayConf() # calculate overlap with protein eres = oeshape.OEOverlapResults() evol.Overlap(outmol, eres) frac = eres.GetOverlap() / eres.GetFitSelfOverlap() rescore = res.GetTanimotoCombo() - frac # attach data to molecule and write it oechem.OESetSDData(outmol, "TanimotoCombo", "%-.3f" % res.GetTanimotoCombo()) oechem.OESetSDData(outmol, "Exclusion Volume", "%-.3f" % eres.overlap) oechem.OESetSDData(outmol, "Fraction Overlap", "%-.3f" % frac) oechem.OESetSDData(outmol, "Rescore", "%-.3f" % rescore) oechem.OEWriteMolecule(ofs, outmol) print("%-20s %.3f %.3f" % (outmol.GetTitle(), res.GetTanimotoCombo(), rescore))
def expand_stereochemistry(mols): """Expand stereochemistry when uncertain Parameters ---------- mols : openeye.oechem.OEGraphMol Molecules to be expanded Returns ------- expanded_mols : openeye.oechem.OEMol Expanded molecules """ expanded_mols = list() from openeye import oechem, oeomega omegaOpts = oeomega.OEOmegaOptions() omega = oeomega.OEOmega(omegaOpts) maxcenters = 12 forceFlip = False enumNitrogen = False warts = True # add suffix for stereoisomers for mol in mols: compound_title = mol.GetTitle() compound_smiles = oechem.OEMolToSmiles(mol) enantiomers = list() for enantiomer in oeomega.OEFlipper(mol, maxcenters, forceFlip, enumNitrogen, warts): enantiomer = oechem.OEMol(enantiomer) enantiomer_smiles = oechem.OEMolToSmiles(enantiomer) oechem.OESetSDData(enantiomer, 'compound', compound_title) oechem.OESetSDData(enantiomer, 'compound_smiles', compound_smiles) oechem.OESetSDData(enantiomer, 'enantiomer_smiles', enantiomer_smiles) enantiomers.append(enantiomer) expanded_mols += enantiomers # DEBUG if 'EDJ-MED-e4b030d8-2' in mol.GetTitle(): msg = 'Enumerated microstates for compound: ' msg += mol.GetTitle() + '\n' msg += f'{"":5s} ' + oechem.OEMolToSmiles(mol) + '\n' for index, m in enumerate(enantiomers): msg += f'{index:5d} : ' + oechem.OEMolToSmiles(m) + '\n' print(msg) return expanded_mols
def expand_stereochemistry(mols): """Expand stereochemistry when uncertain Parameters ---------- mols : openeye.oechem.OEGraphMol Molecules to be expanded Returns ------- expanded_mols : openeye.oechem.OEMol Expanded molecules """ expanded_mols = list() from openeye import oechem, oeomega omegaOpts = oeomega.OEOmegaOptions() omega = oeomega.OEOmega(omegaOpts) maxcenters = 12 forceFlip = False enumNitrogen = True warts = True # add suffix for stereoisomers for mol in mols: compound_title = mol.GetTitle() for enantiomer in oeomega.OEFlipper(mol, maxcenters, forceFlip, enumNitrogen, warts): enantiomer = oechem.OEMol(enantiomer) oechem.OESetSDData(enantiomer, 'compound', compound_title) expanded_mols.append(enantiomer) return expanded_mols
def searchFingerPrints(self, oeQueryMol, fpType, minFpScore=None, maxFpResults=50, annotateMols=False, verbose=False): hL = [] retStatus = True try: fpDb = self.__fpDbD[fpType] if fpType in self.__fpDbD else {} if not fpDb: retStatus = False return retStatus, hL # opts = oegraphsim.OEFPDatabaseOptions(maxFpResults, oegraphsim.OESimMeasure_Tanimoto) if minFpScore: opts.SetCutoff(minFpScore) # if verbose: logger.info("Using %d fingerprint %s type %s", fpDb.NumFingerPrints(), fpType, fpDb.GetFPTypeBase().GetFPTypeString()) startTime = time.time() # scores = fpDb.GetSortedScores(oeQueryMol, opts) oeMol = oechem.OEGraphMol() for si in scores: if self.__oeMolDb.GetMolecule(oeMol, si.GetIdx()): ccId = self.__oeMolDb.GetTitle(si.GetIdx()) if annotateMols: tS = "For %s index %r %r similarity score %.4f " % (ccId, si.GetIdx(), self.__idxTitleD[si.GetIdx()], si.GetScore()) oechem.OESetSDData(oeMol, fpType, tS) hL.append(MatchResults(ccId=ccId, oeMol=oeMol, searchType="fp", fpType=fpType, fpScore=si.GetScore())) if verbose: endTime = time.time() logger.info("Fingerprint %s returning %d hits (%.4f sec)", fpType, len(hL), endTime - startTime) except Exception as e: retStatus = False logger.exception("Failing fpType %r with %s", fpType, str(e)) return retStatus, hL
def QuickOpt(Mol): """ Fast MM optimization to whittle down number of conformers before QM. Default Szybki OEOptType type set to steepest descent (SD) based on preliminary comparisons. Parameters ---------- Mol: single OEChem molecule (aka single conformer) Returns ------- boolean: True if completed successfully, False otherwise. """ # set general energy options along with the run type specification optSzybki = oeszybki.OESzybkiOptions() optSzybki.SetForceFieldType(oeszybki.OEForceFieldType_MMFF94S) optSzybki.SetSolventModel(oeszybki.OESolventModel_Sheffield) optSzybki.SetOptimizerType(oeszybki.OEOptType_SD) taglabel = 'MM Szybki SD Energy' # generate szybki MMFF94 engine for minimization szOpt = oeszybki.OESzybki(optSzybki) # construct a results object to contain the results of a szybki calculation szResults = oeszybki.OESzybkiResults() # work on a copy of the molecule tmpmol = oechem.OEMol(Mol) if not szOpt(tmpmol, szResults): print('szybki run failed for %s' % tmpmol.GetTitle()) return False Mol.SetCoords(tmpmol.GetCoords()) oechem.OESetSDData(Mol, oechem.OESDDataPair(taglabel, "%.12f" \ % szResults.GetTotalEnergy())) return True
def main(args): if len(args) != 3: oechem.OEThrow.Usage("%s input_molecule output_molecule" % args[0]) ifs = oechem.oemolistream() if not ifs.open(args[1]): oechem.OEThrow.Fatal("Unable to open %s for reading" % args[1]) ofs = oechem.oemolostream() if not ofs.open(args[2]): oechem.OEThrow.Fatal("Unable to open %s for writing" % args[2]) opts = oeszybki.OESzybkiOptions() opts.GetOptOptions().SetOptimizerType(oeszybki.OEOptType_NEWTON) opts.GetGeneralOptions().SetForceFieldType( oeszybki.OEForceFieldType_MMFF94S) opts.GetSolventOptions().SetSolventModel(oeszybki.OESolventModel_Sheffield) opts.GetSolventOptions().SetChargeEngine(oequacpac.OEChargeEngineNoOp()) sz = oeszybki.OESzybki(opts) res = oeszybki.OESzybkiResults() for mol in ifs.GetOEMols(): for conf in mol.GetConfs(): if sz(conf, res): oechem.OESetSDData( conf, oechem.OESDDataPair('Total_energy', "%0.4f" % res.GetTotalEnergy())) oechem.OEWriteMolecule(ofs, mol) ifs.close() ofs.close() return 0
def write_energy_profile_to_sddata(mol, energy_profile): """ Writes energy profile to a OEGraphMol object. This will fail for multi-conformer OEMol objects. """ data = generate_energy_profile_sddata(energy_profile) return oechem.OESetSDData(mol, ENERGY_PROFILE_TAG, data)
def main(argv=[__name__]): itf = oechem.OEInterface(InterfaceData, argv) cutoff = itf.GetFloat("-cutoff") ofs = oechem.oemolostream() if not ofs.open(itf.GetString("-clusters")): oechem.OEThrow.Fatal("Unable to open '%s'" % itf.GetString("-clusters")) if ofs.GetFormat() != oechem.OEFormat_OEB: oechem.OEThrow.Fatal("Output file must be OEB") sdtag = "TanimotoComboFromHead" if itf.GetBool("-shapeOnly"): sdtag = "ShapeTanimotoFromHead" getter = GetScoreGetter(itf.GetBool("-shapeOnly")) cluster = ShapeCluster(itf.GetString("-dbase"), cutoff, itf.GetBool("-shapeOnly")) # do the clustering while cluster.HasRemainingMolecules(): clusterHead = cluster.GetNextClusterHead() print("Searching for neighbors of %s" % clusterHead.GetTitle()) for nbrMol, score in cluster.GetCluster(clusterHead): oechem.OESetSDData(nbrMol, sdtag, "%.4f" % getter(score)) score.Transform(nbrMol) clusterHead.AddData(nbrMol.GetTitle(), nbrMol) oechem.OEWriteMolecule(ofs, clusterHead) return 0
def main(argv=[__name__]): if len(argv) != 4: oechem.OEThrow.Usage("%s <reffile> <rocs_hits_file> <output.sdf>" % argv[0]) reffs = oechem.oemolistream(argv[1]) fitfs = oechem.oemolistream(argv[2]) outfs = oechem.oemolostream(argv[3]) refmol = oechem.OEGraphMol() oechem.OEReadMolecule(reffs, refmol) # Prepare reference molecule for calculation # With default options this will add required color atoms prep = oeshape.OEOverlapPrep() prep.Prep(refmol) # Get appropriate function to calculate analytic color colorFunc = oeshape.OEAnalyticColorFunc() colorFunc.SetupRef(refmol) res = oeshape.OEOverlapResults() for fitmol in fitfs.GetOEGraphMols(): prep.Prep(fitmol) colorFunc.Overlap(fitmol, res) oechem.OESetSDData(fitmol, "AnalyticColorTanimoto", "%.2f" % res.GetColorTanimoto()) oechem.OEWriteMolecule(outfs, fitmol) print("Fit Title: %s Color Tanimoto: %.2f" % (fitmol.GetTitle(), res.GetColorTanimoto()))
def resolve_clashes(mol, clashfile): """ Minimize conformers with severe steric interaction. Parameters ---------- mol : single OEChem molecule (single conformer) clashfile : string name of file to write output Returns ------- boolean True if completed successfully, False otherwise. """ # set general energy options along with the single-point specification spSzybki = oeszybki.OESzybkiOptions() spSzybki.SetForceFieldType(oeszybki.OEForceFieldType_MMFF94S) spSzybki.SetSolventModel(oeszybki.OESolventModel_Sheffield) spSzybki.SetRunType(oeszybki.OERunType_SinglePoint) # generate the szybki MMFF94 engine for single points szSP = oeszybki.OESzybki(spSzybki) # construct minimiz options from single-points options to get general optns optSzybki = oeszybki.OESzybkiOptions(spSzybki) # now reset the option for minimization optSzybki.SetRunType(oeszybki.OERunType_CartesiansOpt) # generate szybki MMFF94 engine for minimization szOpt = oeszybki.OESzybki(optSzybki) # add strong harmonic restraints to nonHs szOpt.SetHarmonicConstraints(10.0) # construct a results object to contain the results of a szybki calculation szResults = oeszybki.OESzybkiResults() # work on a copy of the molecule tmpmol = oechem.OEMol(mol) if not szSP(tmpmol, szResults): print('szybki run failed for %s' % tmpmol.GetTitle()) return False Etotsp = szResults.GetTotalEnergy() Evdwsp = szResults.GetEnergyTerm(oeszybki.OEPotentialTerms_MMFFVdW) if Evdwsp > 35: if not szOpt(tmpmol, szResults): print('szybki run failed for %s' % tmpmol.GetTitle()) return False Etot = szResults.GetTotalEnergy() Evdw = szResults.GetEnergyTerm(oeszybki.OEPotentialTerms_MMFFVdW) wfile = open(clashfile, 'a') wfile.write('%s resolved bad clash: initial vdW: %.4f ; ' 'resolved EvdW: %.4f\n' % (tmpmol.GetTitle(), Evdwsp, Evdw)) wfile.close() mol.SetCoords(tmpmol.GetCoords()) oechem.OESetSDData(mol, oechem.OESDDataPair('MM Szybki Single Point Energy'\ , "%.12f" % szResults.GetTotalEnergy())) return True
def get_best_conf(mol, dih, num_points): """Drive the primary torsion in the molecule and select the lowest energy conformer to represent each dihedral angle """ delta = 360.0 / num_points angle_list = [2 * i * oechem.Pi / num_points for i in range(num_points)] dih_atoms = [x for x in dih.GetAtoms()] # Create new output OEMol title = mol.GetTitle() tor_mol = oechem.OEMol() opts = oeszybki.OETorsionScanOptions() opts.SetDelta(delta) opts.SetForceFieldType(oeszybki.OEForceFieldType_MMFF94) opts.SetSolvationType(oeszybki.OESolventModel_NoSolv) tmp_angle = 0.0 tor = oechem.OETorsion(dih_atoms[0], dih_atoms[1], dih_atoms[2], dih_atoms[3], tmp_angle) oeszybki.OETorsionScan(tor_mol, mol, tor, opts) oechem.OECopySDData(tor_mol, mol) # if 0 and 360 sampled because of rounding if tor_mol.NumConfs() > num_points: for conf in tor_mol.GetConfs(): continue tor_mol.DeleteConf(conf) for angle, conf in zip(angle_list, tor_mol.GetConfs()): angle_deg = int(round(angle * oechem.Rad2Deg)) tor_mol.SetActive(conf) oechem.OESetTorsion(conf, dih_atoms[0], dih_atoms[1], dih_atoms[2], dih_atoms[3], angle) conf_name = title + '_{:02d}'.format(conf.GetIdx()) oechem.OESetSDData(conf, 'CONFORMER_LABEL', conf_name) oechem.OESetSDData(conf, 'TORSION_ANGLE', "{:.0f}".format(angle_deg)) conf.SetDoubleData('TORSION_ANGLE', angle_deg) conf.SetTitle('{}: Angle {:.0f}'.format(conf_name, angle_deg)) return tor_mol
def DockConf_(dock, mol, lig, MAX_POSES=1, receptor_filename="Not Available"): err = dock.DockMultiConformerMolecule(lig, mol, MAX_POSES) if (err != oedocking.OEDockingReturnCode_Success): print("Docking Failed with error code " + oedocking.OEDockingReturnCodeGetName(err)) sdtag = dock.GetName() oedocking.OESetSDScore(lig, dock, sdtag) dock.AnnotatePose(lig) oechem.OESetSDData(lig, "receptor", receptor_filename) return lig
def save_sddata(mol, data_kv_pairs): """ Writes data from the input dictionary as SD property If the input is a multi-conformer molecule, the data will be written to each conformer :param mol: OEMol|OEGraphMol :param data_kv_pairs: dict[str, str] :return: None """ if type(mol) == oechem.OEGraphMol: for k, v in data_kv_pairs.items(): oechem.OESetSDData(mol, k, str(v)) elif type(mol) == oechem.OEMol: for conf in mol.GetConfs(): for k, v in data_kv_pairs.items(): oechem.OESetSDData(conf, k, str(v)) else: print("Unknown object type encountered in save_sddata")
def dock_molecule(molecule, default_receptor='x0387'): """ Dock the specified molecules, writing out to specified file Parameters ---------- molecule : OEMol The molecule to dock default_receptor : str, optional, default='0387' The default receptor to dock to Returns ------- all_docked_molecules : list of OEMol All docked molecules """ import os import oechem # Make a copy of the molecule molecule = oechem.OEMol(molecule) # Extract list of corresponding receptor(s) fragments = list() fragments = oechem.OEGetSDData(molecule, "fragments").split(',') fragments = [ fragment for fragment in fragments if os.path.exists(f'../receptors/Mpro-{fragment}-receptor.oeb.gz') ] if len(fragments) == 0: fragments = [default_receptor] # Dock them all_docked_molecules = list() for fragment in fragments: molecule_to_dock = oechem.OEMol(molecule) import os receptor_filename = os.path.join( f'../receptors/Mpro-{fragment}-receptor.oeb.gz') oechem.OESetSDData(molecule_to_dock, "fragments", fragment) # Enumerate reasonable protomers/tautomers from openeye import oequacpac protomer = oechem.OEMol() protomers = [ oechem.OEMol(protomer) for protomer in oequacpac.OEGetReasonableProtomers(molecule_to_dock) ] docked_molecules = dock_molecules_to_receptor(receptor_filename, protomers) all_docked_molecules += docked_molecules return all_docked_molecules
def gen_starting_confs(mol, torsion_library, max_one_bond_away=True, num_conformers=MAX_CONFS, rms_cutoff=0.0, energy_window=25): # Identify the atoms in the dihedral TAGNAME = 'TORSION_ATOMS_FRAGMENT' if not has_sd_data(mol, TAGNAME): raise ValueError("Molecule does not have the SD Data Tag '{}'.".format(TAGNAME)) dihedralAtomIndices = [int(x)-1 for x in get_sd_data(mol, TAGNAME).split()] inDih = \ oechem.OEOrAtom(oechem.OEOrAtom(oechem.OEHasAtomIdx(dihedralAtomIndices[0]), oechem.OEHasAtomIdx(dihedralAtomIndices[1])), oechem.OEOrAtom(oechem.OEHasAtomIdx(dihedralAtomIndices[2]), oechem.OEHasAtomIdx(dihedralAtomIndices[3])) ) mol1 = mol.CreateCopy() mc_mol = oechem.OEMol(mol1) if num_conformers > 1: # Set criterion for rotatable bond if False and max_one_bond_away: # this max function makes this seem potentially broken only_one_bond_away = distance_predicate(dihedralAtomIndices[1], dihedralAtomIndices[2]) rotor_predicate = oechem.OEAndBond(only_one_bond_away, oechem.PyBondPredicate(isRotatableBond)) elif False: # this ONLY samples special bonds & neglects "regualr" torsions rotor_predicate = oechem.PyBondPredicate(isRotatableBond) else: # try this more general sampling, but leave prior versions untouched rotor_predicate = oechem.OEOrBond(oechem.OEIsRotor(), oechem.PyBondPredicate(isRotatableBond)) #Initialize conformer generator and multi-conformer library conf_generator = configure_omega(torsion_library, rotor_predicate, rms_cutoff, energy_window, num_conformers) # Generator conformers if not conf_generator(mc_mol, inDih): raise ValueError("Conformers cannot be generated.") logging.debug("Generated a total of %d conformers for %s.", mc_mol.NumConfs(), mol.GetTitle()) for conf_no, conf in enumerate(mc_mol.GetConfs()): conformer_label = mol.GetTitle()+'_' +\ '_'.join(get_sd_data(mol, 'TORSION_ATOMS_ParentMol').split()) +\ '_{:02d}'.format(conf_no) oechem.OESetSDData(conf, "CONFORMER_LABEL", conformer_label) conf.SetTitle(conformer_label) return mc_mol
def reorder_sd_props(mol: oechem.OEGraphMol): strain1 = oechem.OEGetSDData(mol, TOTAL_STRAIN_TAG) data_pairs = [(TOTAL_STRAIN_TAG, strain1)] for dp in oechem.OEGetSDDataPairs(mol): if dp.GetTag() == TOTAL_STRAIN_TAG: pass else: data_pairs.append((dp.GetTag(), dp.GetValue())) oechem.OEClearSDData(mol) for k, v in data_pairs: oechem.OESetSDData(mol, k, v) data_pairs = [] for dp in oechem.OEGetSDDataPairs(mol): data_pairs.append((dp.GetTag(), dp.GetValue())) oechem.OEClearSDData(mol) for k, v in data_pairs: oechem.OESetSDData(mol, k, v)
def SetSDData(A_IDX, B_IDX, C_IDX, D_IDX, torsion, torsionMol): taIdx = torsionMol.GetAtom(oechem.OEHasMapIdx(A_IDX)).GetIdx() + 1 tbIdx = torsionMol.GetAtom(oechem.OEHasMapIdx(B_IDX)).GetIdx() + 1 tcIdx = torsionMol.GetAtom(oechem.OEHasMapIdx(C_IDX)).GetIdx() + 1 tdIdx = torsionMol.GetAtom(oechem.OEHasMapIdx(D_IDX)).GetIdx() + 1 apStr = "cs1:0:1;1%{}:1%{}:1%{}:1%{}".format(taIdx, tbIdx, tcIdx, tdIdx) oechem.OESetSDData(torsionMol, "TORSION_ATOMPROP", apStr) fragTorAtoms = "{} {} {} {}".format(taIdx, tbIdx, tcIdx, tdIdx) oechem.OESetSDData(torsionMol, TORSION_ATOMS_FRAG_KEY, fragTorAtoms) parentTorAtoms = "{} {} {} {}".format(torsion.a.GetIdx() + 1, torsion.b.GetIdx() + 1, torsion.c.GetIdx() + 1, torsion.d.GetIdx() + 1) oechem.OESetSDData(torsionMol, TORSION_ATOMS_PARENT_MOL_KEY, parentTorAtoms) atom_map = "" for atom in torsionMol.GetAtoms(): atom_map += str(atom.GetIdx() + 1) + "_" + str( atom.GetData("idx")) + "-" atom_map = atom_map[:-1] oechem.OESetSDData(torsionMol, FRAGMENT_TO_PARENT_ATOMS_KEY, atom_map)
def min_mmff94x(mol, ofs, mmff94s=False): """ Minimize the mol with MMFF94 or MMFF94S force field. Parameters ---------- mol : OpenEye single-conformer molecule ofs : OpenEye output filestream mmff94s : Boolean True to minimize with MMFF94S """ # make copy of the input mol oe_mol = oechem.OEGraphMol(mol) # set general energy options along with the run type specification optSzybki = oeszybki.OESzybkiOptions() optSzybki.SetSolventModel(oeszybki.OESolventModel_NoSolv) optSzybki.SetOptimizerType(oeszybki.OEOptType_BFGS) # minimize with input charges not mmff94(s) charges # https://docs.eyesopen.com/toolkits/python/szybkitk/examples.html#optimization-of-all-conformers-of-a-ligand optSzybki.GetSolventOptions().SetChargeEngine(oequacpac.OEChargeEngineNoOp()) # set the particular force field if mmff94s: sdlabel = "MMFF94S" optSzybki.SetForceFieldType(oeszybki.OEForceFieldType_MMFF94S) else: sdlabel = "MMFF94" optSzybki.SetForceFieldType(oeszybki.OEForceFieldType_MMFF94) # generate minimization engine szOpt = oeszybki.OESzybki(optSzybki) # make object to hold szybki results szResults = oeszybki.OESzybkiResults() # perform minimization if not szOpt(oe_mol, szResults): smilabel = oechem.OEGetSDData(oe_mol, "SMILES QCArchive") print( ' >>> MMFF94x minimization failed for %s\n' % smilabel ) energy = szResults.GetTotalEnergy() # save geometry, save energy as tag, write mol to file oechem.OESetSDData(oe_mol, f"Energy {sdlabel}", str(energy)) oechem.OEWriteConstMolecule(ofs, oe_mol)
def gen_starting_confs(mol, torsion_library, num_conformers=MAX_CONFS, rms_cutoff=0.0, energy_window=25): # Identify the atoms in the dihedral TAGNAME = 'TORSION_ATOMS_FRAGMENT' if not has_sd_data(mol, TAGNAME): raise ValueError( "Molecule does not have the SD Data Tag '{}'.".format(TAGNAME)) dihedralAtomIndices = [ int(x) - 1 for x in get_sd_data(mol, TAGNAME).split() ] inDih = \ oechem.OEOrAtom(oechem.OEOrAtom(oechem.OEHasAtomIdx(dihedralAtomIndices[0]), oechem.OEHasAtomIdx(dihedralAtomIndices[1])), oechem.OEOrAtom(oechem.OEHasAtomIdx(dihedralAtomIndices[2]), oechem.OEHasAtomIdx(dihedralAtomIndices[3])) ) mol1 = mol.CreateCopy() mc_mol = oechem.OEMol(mol1) if num_conformers > 1: rotor_predicate = oechem.OEOrBond( oechem.OEIsRotor(), oechem.PyBondPredicate(isRotatableBond)) #Initialize conformer generator and multi-conformer library conf_generator = configure_omega(torsion_library, rotor_predicate, rms_cutoff, energy_window, num_conformers) # Generator conformers if not conf_generator(mc_mol, inDih): raise ValueError("Conformers cannot be generated.") logging.debug("Generated a total of %d conformers for %s.", mc_mol.NumConfs(), mol.GetTitle()) for conf_no, conf in enumerate(mc_mol.GetConfs()): conformer_label = mol.GetTitle()+'_' +\ '_'.join(get_sd_data(mol, 'TORSION_ATOMS_ParentMol').split()) +\ '_{:02d}'.format(conf_no) oechem.OESetSDData(conf, "CONFORMER_LABEL", conformer_label) conf.SetTitle(conformer_label) return mc_mol
def Mol2Nam(itf): ifs = oechem.oemolistream() if not ifs.open(itf.GetString("-in")): oechem.OEThrow.Fatal("Unable to open '%s' for reading" % itf.GetString("-in")) ofs = oechem.oemolostream() outname = None if itf.HasString("-out"): outname = itf.GetString("-out") if not ofs.open(outname): oechem.OEThrow.Fatal("Unable to open '%s' for reading" % outname) language = oeiupac.OEGetIUPACLanguage(itf.GetString("-language")) charset = oeiupac.OEGetIUPACCharSet(itf.GetString("-encoding")) style = oeiupac.OEGetIUPACNamStyle(itf.GetString("-style")) for mol in ifs.GetOEGraphMols(): name = oeiupac.OECreateIUPACName(mol, style) if language > 0: name = oeiupac.OEToLanguage(name, language) if itf.GetBool("-capitalize"): name = oeiupac.OECapitalizeName(name) if charset == oeiupac.OECharSet_ASCII: name = oeiupac.OEToAscii(name) elif charset == oeiupac.OECharSet_UTF8: name = oeiupac.OEToUTF8(name) elif charset == oeiupac.OECharSet_HTML: name = oeiupac.OEToHTML(name) elif charset == oeiupac.OECharSet_SJIS: name = oeiupac.OEToSJIS(name) elif charset == oeiupac.OECharSet_EUCJP: name = oeiupac.OEToEUCJP(name) if outname: if itf.HasString("-delim"): title = mol.GetTitle() name = title + itf.GetString("-delim") + name if itf.HasString("-tag"): oechem.OESetSDData(mol, itf.GetString("-tag"), name) mol.SetTitle(name) oechem.OEWriteMolecule(ofs, mol) else: print(name)
def min_ffxml(mol, ofs, ffxml): """ Minimize the mol with force field input from FFXML file. Parameters ---------- mol : OpenEye single-conformer molecule ofs : OpenEye output filestream ffxml : string name of FFXML file """ # make copy of the input mol oe_mol = oechem.OEGraphMol(mol) try: # create openforcefield molecule ==> prone to triggering Exception off_mol = Molecule.from_openeye(oe_mol) # load in force field ff = ForceField(ffxml) # create components for OpenMM system topology = Topology.from_molecules(molecules=[off_mol]) # create openmm system ==> prone to triggering Exception #system = ff.create_openmm_system(topology, charge_from_molecules=[off_mol]) system = ff.create_openmm_system(topology) except Exception as e: smilabel = oechem.OEGetSDData(oe_mol, "SMILES QCArchive") print( ' >>> openforcefield failed to create OpenMM system: ' f'{oe_mol.GetTitle()} {smilabel}: {e}') return positions = structure.extractPositionsFromOEMol(oe_mol) # minimize structure with ffxml newpos, energy = run_openmm(topology, system, positions) # save geometry, save energy as tag, write mol to file oe_mol.SetCoords(oechem.OEFloatArray(newpos)) oechem.OESetSDData(oe_mol, "Energy FFXML", str(energy)) oechem.OEWriteConstMolecule(ofs, oe_mol) return
def dock_molecule(molecule, ofs, default_receptor='x0387'): """ Dock the specified molecules, writing out to specified file Parameters ---------- molecule : OEMol The molecule to dock ofs : oechem.oemolostream The filename to stream docked molecules to default_receptor : str, optional, default='0387' The default receptor to dock to """ # Make a copy of the molecule molecule = oechem.OEMol(molecule) import os # Extract list of corresponding receptor(s) import oechem print(f'\n{molecule.GetTitle()}') if oechem.OEHasSDData(molecule, "fragments"): fragments = oechem.OEGetSDData(molecule, "fragments").split(',') print(f'fragments before filter: {fragments}') fragments = [ fragment for fragment in fragments if os.path.exists(f'../receptors/Mpro-{fragment}-receptor.oeb.gz') ] print(f'fragments after filter: {fragments}') if len(fragments) == 0: fragments = [default_receptor] for fragment in fragments: molecule_to_dock = oechem.OEMol(molecule) import os receptor_filename = os.path.join( f'../receptors/Mpro-{fragment}-receptor.oeb.gz') oechem.OESetSDData(molecule_to_dock, "fragments", fragment) # Enumerate reasonable protomers/tautomers from openeye import oequacpac protomer = oechem.OEMol() protomers = [ oechem.OEMol(protomer) for protomer in oequacpac.OEGetReasonableProtomers(molecule_to_dock) ] dock_molecules_to_receptor(receptor_filename, protomers, ofs)
def Nam2Mol(itf): ifp = sys.stdin if itf.GetString("-in") != "-": ifp = open(itf.GetString("-in")) ofs = oechem.oemolostream() if not ofs.open(itf.GetString("-out")): oechem.OEThrow.Fatal("Unable to open output file: %s" % itf.GetString("-out")) language = oeiupac.OEGetIUPACLanguage(itf.GetString("-language")) charset = oeiupac.OEGetIUPACCharSet(itf.GetString("-charset")) mol = oechem.OEGraphMol() for name in ifp: name = name.strip() mol.Clear() # Speculatively reorder CAS permuted index names str = oeiupac.OEReorderIndexName(name) if len(str) == 0: str = name if charset == oeiupac.OECharSet_HTML: str = oeiupac.OEFromHTML(str) if charset == oeiupac.OECharSet_UTF8: str = oeiupac.OEFromUTF8(str) str = oeiupac.OELowerCaseName(str) if language != oeiupac.OELanguage_AMERICAN: str = oeiupac.OEFromLanguage(str, language) done = oeiupac.OEParseIUPACName(mol, str) if not done and itf.GetBool("-empty"): mol.Clear() done = True if done: if itf.HasString("-tag"): oechem.OESetSDData(mol, itf.GetString("-tag"), name) mol.SetTitle(name) oechem.OEWriteMolecule(ofs, mol)
def copy_QM_calc_parameters(srcMol, dstMol): for tag in [ "PSI4_OPT_METHOD", "PSI4_OPT_BASIS", "PSI4_SPE_METHOD", "PSI4_SPE_BASIS", "scf_type", "fail_on_maxiter", "guess_basis", "use_soscf", "dft_radial_points", "dft_spherical_points", "num_processors", ]: value = "" if has_sd_data(srcMol, tag): value = get_sd_data(srcMol, tag) oechem.OESetSDData(dstMol, tag, value)
def process(self, mcmol, port): try: dockedMol = oechem.OEMol() res = self.dock.DockMultiConformerMolecule(dockedMol, mcmol) if res == oedocking.OEDockingReturnCode_Success: oedocking.OESetSDScore(dockedMol, self.dock, self.sdtag) self.dock.AnnotatePose(dockedMol) score = self.dock.ScoreLigand(dockedMol) self.log.info("{} {} score = {:.4f}".format(self.sdtag, dockedMol.GetTitle(), score)) oechem.OESetSDData(dockedMol, self.sdtag, "{}".format(score)) self.clean(dockedMol) self.success.emit(dockedMol) except Exception as e: # Attach error message to the molecule that failed self.log.error(traceback.format_exc()) mcmol.SetData('error', str(e)) # Return failed molecule self.failure.emit(mcmol)
def main(argv=[__name__]): if len(argv) != 4: oechem.OEThrow.Usage("%s <reffile> <rocs_hits_file> <output.sdf>" % argv[0]) reffs = oechem.oemolistream(argv[1]) fitfs = oechem.oemolistream(argv[2]) outfs = oechem.oemolostream(argv[3]) refmol = oechem.OEGraphMol() oechem.OEReadMolecule(reffs, refmol) # Get appropriate function to calculate analytic shape shapeFunc = oeshape.OEAnalyticShapeFunc() shapeFunc.SetupRef(refmol) res = oeshape.OEOverlapResults() for fitmol in fitfs.GetOEGraphMols(): shapeFunc.Overlap(fitmol, res) oechem.OESetSDData(fitmol, "AnalyticTanimoto", "%.2f" % res.GetTanimoto()) oechem.OEWriteMolecule(outfs, fitmol)