def main(argv=sys.argv): if len(argv) != 2: oechem.OEThrow.Usage("%s <infile (oeb file prefix)>" % argv[0]) ifs = oechem.oemolistream() if not ifs.open(argv[1] + '.oeb'): oechem.OEThrow.Fatal("Unable to open %s for reading" % argv[1] + '.oeb') ofsff = oechem.oemolostream() ofsff.SetFlavor(oechem.OEFormat_MOL2, oechem.OEOFlavor_MOL2_Forcefield) if not ofsff.open(argv[1] + '_ff.mol2'): oechem.OEThrow.Fatal("Unable to open %s for writing" % argv[1] + '_ff.mol2') ofsTri = oechem.oemolostream() ofsTri.SetFlavor(oechem.OEFormat_MOL2, oechem.OEOFlavor_MOL2_Forcefield) if not ofsTri.open(argv[1] + '_tripos.mol2'): oechem.OEThrow.Fatal("Unable to open %s for writing" % argv[1] + '_tripos.mol2') for mol in ifs.GetOEMols(): oechem.OETriposAtomNames(mol) oechem.OEWriteConstMolecule(ofsff, mol) oechem.OETriposAtomTypeNames(mol) oechem.OEWriteConstMolecule(ofsTri, mol) ifs.close() ofsff.close() ofsTri.close() return 0
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 write (self , filename, format = "mol2", mode = "w"): """ Writes this structure into a file in the designated format. @type format: C{str} @param format: Format must be one of the following case-sensitive strings: "pdb", "mol2", "xyz","sdf" and "smi" """ if mode == "a": raise ValueError("OeStruc write doesn't support append method") elif mode == "w": if format == "pdb": ofs = oechem.oemolostream(filename + '.pdb') ofs.SetFormat(oechem.OEFormat_PDB) elif format == "mol2": ofs = oechem.oemolostream(filename + '.mol2') ofs.SetFormat(oechem.OEFormat_MOL2) elif format == "xyz": ofs = oechem.oemolostream(filename + '.xyz') ofs.SetFormat(oechem.OEFormat_XYZ) elif format == "sdf": ofs = oechem.oemolostream(filename + '.sdf') ofs.SetFormat(oechem.OEFormat_SDF) elif format == "smi": ofs = oechem.oemolostream(filename + '.smi') ofs.SetFormat(oechem.OEFormat_SMI) else: raise ValueError( "Invalid value for `mode' argument: '%s', should be one of 'a' and 'w'.") return oechem.OEWriteMolecule(ofs, self._struc )
def main(argv=sys.argv): if len(argv) != 2: oechem.OEThrow.Usage("%s <infile (oeb file prefix)>" % argv[0]) ifs = oechem.oemolistream() if not ifs.open(argv[1]+'.oeb'): oechem.OEThrow.Fatal("Unable to open %s for reading" % argv[1]+'.oeb' ) ofsff = oechem.oemolostream() ofsff.SetFlavor( oechem.OEFormat_MOL2, oechem.OEOFlavor_MOL2_Forcefield ) if not ofsff.open(argv[1]+'_ff.mol2'): oechem.OEThrow.Fatal("Unable to open %s for writing" % argv[1]+'_ff.mol2') ofsTri = oechem.oemolostream() ofsTri.SetFlavor( oechem.OEFormat_MOL2, oechem.OEOFlavor_MOL2_Forcefield ) if not ofsTri.open(argv[1]+'_tripos.mol2'): oechem.OEThrow.Fatal("Unable to open %s for writing" % argv[1]+'_tripos.mol2') for mol in ifs.GetOEMols(): oechem.OETriposAtomNames(mol) oechem.OEWriteConstMolecule(ofsff, mol) oechem.OETriposAtomTypeNames(mol) oechem.OEWriteConstMolecule(ofsTri, mol) ifs.close() ofsff.close() ofsTri.close()
def create_conformers(infile=None, outfile=None, resname=None, folder= None, name = None): """ This function takes a mol1 file and runs Openeye's omega to create conformers for the molecules The conformers are stored in separated files, adding the number of the conformer at the end of the filename :param infile: Path to input file :param outfile: Path to output file return :param folder: Name of the folder for the target. If not specified. {name}-liquid is used. :param resname: Abbreviation of the Residue. Specified in the mol2 :return: Number of conformers for this molecule """ if folder is None and name is None: log.error('Please specify keyword argument folder or name') sys.exit(1) elif folder is None: folder = name +'-liquid' infilepath = os.path.join(folder, infile) outfilepath = os.path.join(folder, outfile) ifs = oechem.oemolistream() if not ifs.open(infilepath): oechem.OEThrow.Fatal("Unable to open %s for reading" % infilepath) ofs = oechem.oemolostream() if not ofs.open(outfilepath): oechem.OEThrow.Fatal("Unable to open %s for writing" % outfilepath) if not oechem.OEIs2DFormat(ofs.GetFormat()): oechem.OEThrow.Fatal("Invalid output file format for 2D coordinates!") omegaOpts = oeomega.OEOmegaOptions() omega = oeomega.OEOmega(omegaOpts) omega.SetCommentEnergy(True) omega.SetEnumNitrogen(True) omega.SetSampleHydrogens(True) omega.SetEnergyWindow(9.0) omega.SetMaxConfs(5) omega.SetRangeIncrement(2) omega.SetRMSRange([0.5, 1.0, 1.5, 2.0, 2.5, 3.0, 3.5]) filename = '{}-conformers'.format(resname) for mol in ifs.GetOEMols(): ret_code = omega.Build(mol) if ret_code == oeomega.OEOmegaReturnCode_Success: oechem.OEWriteMolecule(ofs, mol) for k, conf in enumerate(mol.GetConfs()): ofs1 = oechem.oemolostream() if not ofs1.open(os.path.join(folder, filename + '_' + str(k + 1) + '.mol2')): oechem.OEThrow.Fatal("Unable to open %s for writing" % os.path.join(folder, filename + '_' + str(k + 1) + '.mol2')) oechem.OEWriteMolecule(ofs1, conf) nconf = k + 1 log.info('Created conformations for {} and saved them to {}'.format(infilepath, outfilepath)) else: oechem.OEThrow.Warning("%s: %s" % (mol.GetTitle(), oeomega.OEGetOmegaError(ret_code))) return nconf
def main(argv=[__name__]): itf = oechem.OEInterface(InterfaceData) if not oechem.OEParseCommandLine(itf, argv): oechem.OEThrow.Fatal("Unable to interpret command line!") ifs = oechem.oemolistream() inputFile = itf.GetString("-in") if not ifs.open(inputFile): oechem.OEThrow.Fatal("Unable to open %s for reading" % inputFile) ofs = oechem.oemolostream() outFile = itf.GetString("-out") if not ofs.open(outFile): oechem.OEThrow.Fatal("Unable to open %s for writing" % outFile) chargeName = itf.GetString("-method") mol = oechem.OEMol() while oechem.OEReadMolecule(ifs, mol): if not AssignChargesByName(mol, chargeName): oechem.OEThrow.Warning("Unable to assign %s charges to mol %s" % (chargeName, mol.GetTitle())) oechem.OEWriteMolecule(ofs, mol) ifs.close() ofs.close()
def traj_conf_extraction(ctx): for record in ctx.obj['records']: sys_id = check_sys_id(record) if not record.has_field(Fields.Analysis.oetraj_rec): raise ValueError("Multi Conf Trajectory record field is missing") oetraj_rec = record.get_value(Fields.Analysis.oetraj_rec) traj_names = ["LigTraj", "ProtTraj_OPLMD", "WatTraj"] ofs = oechem.oemolostream(sys_id + "_traj_confs.oeb") for fd in oetraj_rec.get_fields(): name = fd.get_name() if name in traj_names: mol = oetraj_rec.get_value(fd) mol.SetTitle(name) oechem.OEWriteConstMolecule(ofs, mol) ofs.close()
def main(args): if len(args) != 3: oechem.OEThrow.Usage("%s <input> <output>" % 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]) mol = oechem.OEMol() oechem.OEReadMolecule(ifs, mol) opts = oeszybki.OEFreeFormConfOptions() ffconf = oeszybki.OEFreeFormConf(opts) # Estimate free energies to ontain the minimum energy conformers omol = oechem.OEMol(mol) if not (ffconf.EstimateFreeEnergies(omol) == oeszybki.OEFreeFormReturnCode_Success): oechem.OEThrow.Error("Failed to estimate conformational free energies") # Find similar conformers to the ones we started with, from the # pool of minimum energy conformers fmol = oechem.OEMol(mol) for conf in mol.GetConfs(): ffconf.FindSimilarConfs(fmol, omol, conf, oechem.OESimilarByRMSD(0.05)) oechem.OEWriteMolecule(ofs, fmol) 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 combineSDF(infiles, ftype, outfile): ### Glob for input files to combine. ext = '*.'+ftype molfiles = glob.glob(os.path.join(infiles, ext)) ### Open output file to write molecules. ofs = oechem.oemolostream() if os.path.exists(outfile) and os.path.getsize(outfile) > 10: sys.exit("Output .sdf file already exists. Exiting.\n") return if not ofs.open(outfile): oechem.OEThrow.Fatal("Unable to open %s for writing" % outfile) ### Loop over mols. for f in molfiles: print(f) ifs = oechem.oemolistream() if not ifs.open(f): oechem.OEThrow.Warning("Unable to open %s for reading" % f) try: mol = next(ifs.GetOEMols()) except StopIteration: print('No mol loaded for %s' % mol.GetTitle()) ifs.close() mol.SetTitle(f.split('/')[-1].split('.')[0]) oechem.OEWriteConstMolecule(ofs, mol) ofs.close()
def main(argv=[__name__]): itf = oechem.OEInterface(InterfaceData) if not oechem.OEParseCommandLine(itf, argv): oechem.OEThrow.Fatal("Unable to interpret command line!") iname = itf.GetString("-i") oname = itf.GetString("-o") ims = oechem.oemolistream() if not ims.open(iname): oechem.OEThrow.Fatal("Cannot open input file!") oms = oechem.oemolostream() if not oms.open(oname): oechem.OEThrow.Fatal("Cannot open output file!") inmol = oechem.OEGraphMol() if not oechem.OEReadMolecule(ims, inmol): oechem.OEThrow.Fatal("Cannot read input file!") allSites = itf.GetBool("-a") splitCovalent = itf.GetBool("-c") separateResidues = itf.GetBool("-s") combineFilters = itf.GetBool("-pw") if combineFilters: SplitMolComplexCombineFilters(oms, inmol) elif allSites: SplitMolComplexAllSites(oms, inmol, splitCovalent) else: SplitMolComplex(oms, inmol, splitCovalent, separateResidues) oms.close()
def convertSDFfile(reffile, filtfile, writeout): refifs = oechem.oemolistream() filtifs = oechem.oemolistream() ofs = oechem.oemolostream() ### Read in reference file, but don't need its old conformers if not refifs.open(reffile): oechem.OEThrow.Warning("Unable to open %s for reading" % reffile) return ### Read in filtered file and distinguish each molecule's conformers filtifs.SetConfTest( oechem.OEAbsoluteConfTest() ) if not filtifs.open(filtfile): oechem.OEThrow.Warning("Unable to open %s for reading" % filtfile) return ### Open outstream file. if os.path.exists(writeout): print("File already exists: %s. Skip getting results.\n" % (writeout)) return if not ofs.open(writeout): oechem.OEThrow.Fatal("Unable to open %s for writing" % writeout) ### Loop and write molecules. (though refifs should only have ONE mol) for rmol in refifs.GetOEMols(): for fmol in filtifs.GetOEMols(): for i, conf in enumerate( fmol.GetConfs()): rmol.SetCoords(conf.GetCoords()) oechem.OEWriteConstMolecule(ofs, rmol) refifs.close() filtifs.close() ofs.close()
def smi2sdf(sdfout, smiles): """ From a file containing smiles strings, generate omega conformers, resolve steric clashes, do a quick MM opt, and write SDF output. Parameters ---------- sdfout: str - output sdf file. E.g. "name.sdf" smiles: str - name of the smiles file. E.g. "name.smi" """ ### Read in smiles file. ifs = oechem.oemolistream() if not ifs.open(smiles): oechem.OEThrow.Warning("Unable to open %s for reading" % smiles) ### Open output file to write molecules. ofs = oechem.oemolostream() if os.path.exists(sdfout): #sys.exit("Output .sdf file already exists. Exiting.\n") print("Output .sdf file already exists. Exiting.\n") return if not ofs.open(sdfout): oechem.OEThrow.Fatal("Unable to open %s for writing" % sdfout) ### For each molecule: label atoms, generate 1 conf, write output. for smimol in ifs.GetOEMols(): oechem.OETriposAtomNames(smimol) mol = GenerateConfs(smimol) oechem.OEWriteConstMolecule(ofs, mol) ### Close files. ifs.close() ofs.close()
def main(argv=[__name__]): ifs = oechem.oemolistream() ofs = oechem.oemolostream() path = "Docking_Results/*.oeb" #Convert ligand poses from oeb to pdb format files = glob.glob(path) for i in files: centroid_number = i[-5:-4] if ifs.open(i): if ofs.open("ligand_poses_pdbs/" + "pose" + str(centroid_number) + ".pdb"): for mol in ifs.GetOEGraphMols(): oechem.OEWriteMolecule(ofs, mol) else: oechem.OEThrow.Fatal("Unable to create output") else: oechem.OEThrow.Fatal("Unable to open input") path2 = "receptor_oebs/*.oeb" #Convert receptors from oeb to pdb format files = glob.glob(path2) for j in files: centroid_number = j[-5:-4] if ifs.open(j): if ofs.open("receptor_pdbs_converted_from_oebs/" + "receptor" + str(centroid_number) + ".pdb"): for mol in ifs.GetOEGraphMols(): oechem.OEWriteMolecule(ofs, mol) else: oechem.OEThrow.Fatal("Unable to create output") else: oechem.OEThrow.Fatal("Unable to open input") return 0
def main(args): if len(args) != 3: oechem.OEThrow.Usage("%s <input> <output>" % 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]) mol = oechem.OEMol() oechem.OEReadMolecule(ifs, mol) opts = oeszybki.OEFreeFormConfOptions() ffconf = oeszybki.OEFreeFormConf(opts) omol = oechem.OEMol(mol) if not (ffconf.EstimateFreeEnergies(omol) == oeszybki.OEFreeFormReturnCode_Success): oechem.OEThrow.Error("Failed to estimate conformational free energies") res = oeszybki.OEFreeFormConfResults(omol) oechem.OEThrow.Info("Number of unique conformations: %d" % res.GetNumUniqueConfs()) oechem.OEThrow.Info("Conf. Delta_G Vibrational_Entropy") oechem.OEThrow.Info(" [kcal/mol] [J/(mol K)]") for r in res.GetResultsForConformations(): oechem.OEThrow.Info("%2d %10.2f %14.2f" % (r.GetConfIdx(), r.GetDeltaG(), r.GetVibrationalEntropy())) oechem.OEWriteMolecule(ofs, omol) return 0
def dock_molecules(receptor_filename, molecules, filename): """ Dock the specified molecules, writing out to specified file Parameters ---------- receptor_filename : str Receptor .oeb.gz filename molecules : list of openeye.oechem.OEMol The read molecules to dock filename : str The filename to stream docked molecules to """ # Read the receptor print('Loading receptor...') from openeye import oechem, oedocking receptor = oechem.OEGraphMol() if not oedocking.OEReadReceptorFile(receptor, 'receptor.oeb.gz'): oechem.OEThrow.Fatal("Unable to read receptor") if oedocking.OEReceptorHasBoundLigand(receptor): print("Receptor has a bound ligand") else: print("Receptor does not have bound ligand") print('Initializing receptor...') dockMethod = oedocking.OEDockMethod_Hybrid2 dockResolution = oedocking.OESearchResolution_High dock = oedocking.OEDock(dockMethod, dockResolution) success = dock.Initialize(receptor) # Set up Omega from openeye import oeomega omegaOpts = oeomega.OEOmegaOptions(oeomega.OEOmegaSampling_Dense) #omegaOpts = oeomega.OEOmegaOptions() omega = oeomega.OEOmega(omegaOpts) omega.SetStrictStereo(False) # Dock molecules with oechem.oemolostream(filename) as ofs: from tqdm import tqdm for mol in tqdm(molecules): dockedMol = oechem.OEGraphMol() # Expand conformers omega.Build(mol) # Dock molecule retCode = dock.DockMultiConformerMolecule(dockedMol, mol) if (retCode != oedocking.OEDockingReturnCode_Success): oechem.OEThrow.Fatal("Docking Failed with error code " + oedocking.OEDockingReturnCodeGetName(retCode)) # Store docking data sdtag = oedocking.OEDockMethodGetName(dockMethod) oedocking.OESetSDScore(dockedMol, dock, sdtag) dock.AnnotatePose(dockedMol) # Write molecule oechem.OEWriteMolecule(ofs, dockedMol)
def reload_system(self, ln: str, smis: oechem.OEMol, old_pdb: str, is_oe_already: bool = False): with self.logger("reload_system") as logger: logger.log("Loading {} with new smiles {}".format(old_pdb, ln)) with tempfile.TemporaryDirectory() as dirpath: ofs = oechem.oemolostream("{}/newlig.mol2".format(dirpath)) oechem.OEWriteMolecule(ofs, smis) ofs.close() cmd.reinitialize() cmd.load(old_pdb) cmd.remove("not polymer") cmd.load("{}/newlig.mol2".format(dirpath), "UNL") cmd.alter("UNL", "resn='UNL'") cmd.alter("UNL", "chain='A'") self.config.pdb_file_name = self.config.tempdir() + "reloaded.pdb" cmd.save(self.config.pdb_file_name) cmd.save(self.config.tempdir() + "apo.pdb") with open(self.config.pdb_file_name, 'r') as f: self.pdb = app.PDBFile(f) self.positions, self.topology = self.pdb.getPositions(), self.pdb.getTopology() if self.config.explicit and self.config.method == 'amber': self.system, self.topology, self.positions = self.__setup_system_ex_amber( pdbfile=self.config.pdb_file_name) elif self.config.explicit: self.system, self.topology, self.positions = self.__setup_system_ex_mm() else: self.system, self.topology, self.positions = self.__setup_system_im( pdbfile=self.config.pdb_file_name) return self.system
def main(argv=[__name__]): itf = oechem.OEInterface(InterfaceData, argv) ifname = itf.GetString("-in") ofname = itf.GetString("-out") ifs = oechem.oemolistream() if not ifs.open(ifname): oechem.OEThrow.Fatal("Unable to open %s for reading" % ifname) if not oechem.OEIs2DFormat(ifs.GetFormat()): oechem.OEThrow.Fatal("Invalid input format: need 2D coordinates") ofs = oechem.oemolostream() if not ofs.open(ofname): oechem.OEThrow.Fatal("Unable to open %s for writing" % ofname) if not oechem.OEIs2DFormat(ofs.GetFormat()): oechem.OEThrow.Fatal( "Invalid output format: unable to write 2D coordinates") nrrings = 0 for mol in ifs.GetOEGraphMols(): for ring in oechem.OEExtractRingTemplates(mol): nrrings += 1 oechem.OEWriteMolecule(ofs, ring) oechem.OEThrow.Info("%d number of ring templates extracted" % nrrings)
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]) mol = oechem.OEMol() oechem.OEReadMolecule(ifs, mol) opts = oeszybki.OESzybkiOptions() opts.GetOptOptions().SetOptimizerType(oeszybki.OEOptType_NEWTON) opts.GetSolventOptions().SetSolventModel(oeszybki.OESolventModel_Sheffield) sz = oeszybki.OESzybki(opts) res = oeszybki.OESzybkiResults() if (sz(mol, res)): oechem.OEWriteMolecule(ofs, mol) res.Print(oechem.oeout) return 0
def cluster_extraction(ctx): for record in ctx.obj['records']: sys_id = check_sys_id(record) if not record.has_field(Fields.Analysis.oeclus_rec): raise ValueError("Cluster record field is missing") oeclus_rec = record.get_value(Fields.Analysis.oeclus_rec) clust_names = [ "ClusLigAvgMol", "ClusProtAvgMol", "ClusLigMedMol", "ClusProtMedMol" ] ofs = oechem.oemolostream(sys_id + "_clusters.oeb") for fd in oeclus_rec.get_fields(): name = fd.get_name() if name in clust_names: mol = oeclus_rec.get_value(fd) mol.SetTitle(name) oechem.OEWriteConstMolecule(ofs, mol) ofs.close()
def main(args=[__name__]): if len(args) != 3: oechem.OEThrow.Usage("%s <molfile> <outfile>" % 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]) mol = oechem.OEMol() oechem.OEReadMolecule(ifs, mol) opts = oeszybki.OESzybkiOptions() opts.GetGeneralOptions().SetForceFieldType(oeszybki.OEForceFieldType_SMIRNOFF) sz = oeszybki.OESzybki(opts) results = oeszybki.OESzybkiResults() if not sz(mol, results): return 1 oechem.OEWriteMolecule(ofs, mol) results.Print(oechem.oeout) return 0
def main(argv=[__name__]): itf = oechem.OEInterface(InterfaceData, argv) ifs = oechem.oemolistream() if not ifs.open(itf.GetString("-i")): oechem.OEThrow.Fatal("Unable to open %s for reading" % itf.GetString("-i")) ofs = oechem.oemolostream(".ism") if itf.HasString("-o"): if not ofs.open(itf.GetString("-o")): oechem.OEThrow.Fatal("Unable to open %s for writing" % itf.GetString("-o")) minhac = float("-inf") if itf.HasInt("-minhac"): minhac = itf.GetInt("-minhac") maxhac = float("inf") if itf.HasInt("-maxhac"): maxhac = itf.GetInt("-maxhac") minwt = float("-inf") if itf.HasDouble("-minwt"): minwt = itf.GetDouble("-minwt") maxwt = float("inf") if itf.HasDouble("-maxwt"): maxwt = itf.GetDouble("-maxwt") for mol in ifs.GetOEMols(): if not IsMoleculeInHeavyAtomCountRange(minhac, maxhac, mol): continue if not IsMoleculeInMolWtRange(minwt, maxwt, mol): continue oechem.OEWriteMolecule(ofs, mol)
def test_ncmc_engine_molecule(): """ Check alchemical elimination for alanine dipeptide in vacuum with 0, 1, 2, and 50 switching steps. """ molecule_names = ['pentane', 'biphenyl', 'imatinib'] #if os.environ.get("TRAVIS", None) == 'true': # molecule_names = ['pentane'] for molecule_name in molecule_names: from perses.tests.utils import createSystemFromIUPAC [molecule, system, positions, topology] = createSystemFromIUPAC(molecule_name) natoms = system.getNumParticles() # DEBUG print(molecule_name) from openeye import oechem ofs = oechem.oemolostream('%s.mol2' % molecule_name) oechem.OEWriteMol2File(ofs, molecule) ofs.close() # Eliminate half of the molecule # TODO: Use a more rigorous scheme to make sure we are really cutting the molecule in half and not just eliminating hydrogens or something. new_to_old_atom_map = { atom.index : atom.index for atom in topology.atoms() if str(atom.element.name) in ['carbon','nitrogen'] } # DEBUG print(new_to_old_atom_map) from perses.rjmc.topology_proposal import TopologyProposal topology_proposal = TopologyProposal( new_topology=topology, new_system=system, old_topology=topology, old_system=system, old_chemical_state_key='', new_chemical_state_key='', logp_proposal=0.0, new_to_old_atom_map=new_to_old_atom_map, metadata={'test':0.0}) for ncmc_nsteps in [0, 1, 50]: f = partial(check_alchemical_null_elimination, topology_proposal, positions, ncmc_nsteps=ncmc_nsteps) f.description = "Testing alchemical null elimination for '%s' with %d NCMC steps" % (molecule_name, ncmc_nsteps) yield f
def write_mols(mols_dict, outfile): """ Save all mols in the given dictionary to 'outfile'. Parameters ---------- mols_dict : dict of dicts the first level key is the SMILES string and the value of that key is a dict with the following key/value pairs-- metric geometric measurement structure OEGraphMol of the structure outfile : string name of output file """ # open an outstream file ofs = oechem.oemolostream() if not ofs.open(outfile): oechem.OEThrow.Fatal("Unable to open %s for writing" % outfile) # go through all the molecules for key in mols_dict: print(f"writing out {key}") mymol = mols_dict[key]['structure'] oechem.OEWriteConstMolecule(ofs, mymol)
def run_select_final(args): """Generates an SMI file with final selected molecules from SELECT mode.""" logging.info("STARTING SELECT-FINAL") directory = args["select_final_dir"] output_file = args["select_final_output_file"] ofs = oechem.oemolostream(output_file) n = args["select_final_n"] logging.info( f"Reading molecules in {directory}, selecting and writing to {output_file}" ) for f in glob.iglob(f"{directory}/*.smi"): ifs = oechem.oemolistream(f) mols = [] mol = oechem.OEMol() while oechem.OEReadMolecule(ifs, mol): mols.append(oechem.OEMol(mol)) ifs.close() logging.debug(f"Found {len(mols)} mols in {f}") mols.sort(key=lambda m: m.NumAtoms()) for m in mols[:n]: oechem.OEWriteMolecule(ofs, m) ofs.close() logging.info("FINISHED SELECT-FINAL")
def write_guest_molecules(old_molecule: oechem.OEMol, new_molecule: oechem.OEMol, filepath: str): """ Write out a file containing the guest molecules with the "old molecule" first. Parameters ---------- old_molecule : oechem.OEMol The molecule to be written first. It should have coordinates placing it within the guest new_molecule : oechem.OEMol The molecule to be written next. It does not need to have coordinates, as these will be generated filepath : str The path to the file that is being written """ ostream = oechem.oemolostream() ostream.open(filepath) # set molecule names to avoid template name collision: old_molecule.SetTitle("oldmol") new_molecule.SetTitle("newmol") # set tripos atom names oechem.OETriposAtomNames(old_molecule) oechem.OETriposAtomNames(new_molecule) # write the molecules in order: oechem.OEWriteMolecule(ostream, old_molecule) oechem.OEWriteMolecule(ostream, new_molecule) ostream.close()
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) != 3: oechem.OEThrow.Usage("%s <infile> <outfile>" % argv[0]) ifs = oechem.oemolistream() if not ifs.open(argv[1]): oechem.OEThrow.Fatal("Unable to open %s for reading" % argv[1]) ofs = oechem.oemolostream() if not ofs.open(argv[2]): oechem.OEThrow.Fatal("Unable to open %s for writing" % argv[2]) if not oechem.OEIs3DFormat(ofs.GetFormat()): oechem.OEThrow.Fatal("Invalid output file format for 3D coordinates!") omegaOpts = oeomega.OEMacrocycleOmegaOptions() mcomega = oeomega.OEMacrocycleOmega(omegaOpts) for mol in ifs.GetOEMols(): oechem.OEThrow.Info("Title: %s" % mol.GetTitle()) ret_code = mcomega.Build(mol) if ret_code == oeomega.OEOmegaReturnCode_Success: oechem.OEWriteMolecule(ofs, mol) else: oechem.OEThrow.Warning("%s: %s" % (mol.GetTitle(), oeomega.OEGetOmegaError(ret_code))) return 0
def add_dataset(self): url = self.args.url + "/datasets/" act_mol_idx = {} dataset = None parameters = {} self.dataset = tempfile.NamedTemporaryFile(suffix='.oeb', mode='wb', delete=False) with oechem.oemolostream(self.dataset.name) as ofs: for idx, mol in enumerate(self.act_list): act_mol_idx[mol.GetTitle()] = idx oechem.OEWriteMolecule(ofs, mol) self.dataset.flush() dataset = open(self.dataset.name, 'rb') parameters["dataset"] = (self.dataset.name, dataset, 'application/octet-stream') parameters["name"] = 'dataset of active molecules' multipart_data = MultipartEncoder(fields=parameters) response = requests.post( url, data=multipart_data, headers={"content-type": multipart_data.content_type}) if dataset is not None: dataset.close() os.remove(self.dataset.name) data = response.json() dataset_infos = (data["id"], act_mol_idx) return dataset_infos
def main(argv=[__name__]): itf = oechem.OEInterface(InterfaceData, argv) haslist = itf.HasString("-list") hastitle = itf.HasString("-title") if not (haslist ^ hastitle): oechem.OEThrow.Usage("Must give either -list or -title") ifs = oechem.oemolistream() if not ifs.open(itf.GetString("-i")): oechem.OEThrow.Fatal("Unable to open %s for reading" % itf.GetString("-i")) ofs = oechem.oemolostream() if not ofs.open(itf.GetString("-o")): oechem.OEThrow.Fatal("Unable to open %s for writing" % itf.GetString("-o")) # collect names nameset = set() if itf.HasString("-list"): try: lfs = open(itf.GetString("-list")) except IOError: oechem.OEThrow.Fatal("Unable to open %s for reading" % itf.GetString("-list")) for name in lfs.readlines(): name = name.strip() nameset.add(name) elif itf.HasString("-title"): nameset.add(itf.GetString("-title")) if len(nameset) == 0: oechem.OEThrow.Fatal("No titles requested") MolExtract(ifs, ofs, nameset)
def write_guest_molecules(old_molecule: oechem.OEMol, new_molecule: oechem.OEMol, filepath: str): """ Write out a file containing the guest molecules with the "old molecule" first. Parameters ---------- old_molecule : oechem.OEMol The molecule to be written first. It should have coordinates placing it within the guest new_molecule : oechem.OEMol The molecule to be written next. It does not need to have coordinates, as these will be generated filepath : str The path to the file that is being written """ ostream = oechem.oemolostream() ostream.open(filepath) #set molecule names to avoid template name collision: old_molecule.SetTitle("oldmol") new_molecule.SetTitle("newmol") #set tripos atom names oechem.OETriposAtomNames(old_molecule) oechem.OETriposAtomNames(new_molecule) #write the molecules in order: oechem.OEWriteMolecule(ostream, old_molecule) oechem.OEWriteMolecule(ostream, new_molecule) ostream.close()
def main(): args = parse_args() start_time = time.time() ifs = oechem.oemolistream() if ifs.open(args.infile): mols = [oechem.OEMol(mol) for mol in ifs.GetOEGraphMols()] ifs.close() else: oechem.OEThrow.Fatal(f"Unable to open {args.infile}") out_mols = generate_ml_profiles(mols, args.model_file, args.scaler_file) count = len(out_mols) ofs = oechem.oemolostream() if ofs.open(args.outfile): for mol in out_mols: oechem.OEWriteMolecule(ofs, mol) ofs.close() else: oechem.OEThrow.Fatal(f"Unable to open {args.outfile}") time_elapsed = time.time() - start_time logging.warning('Generated profiles for %d molecules in %.1f seconds', count, time_elapsed)
def FromMol(mol, isomer=True, num_enantiomers=-1): """ Generates a set of conformers as an OEMol object Inputs: mol is an OEMol isomers is a boolean controling whether or not the various diasteriomers of a molecule are created num_enantiomers is the allowable number of enantiomers. For all, set to -1 """ omegaOpts = oeomega.OEOmegaOptions() omegaOpts.SetMaxConfs(199) omega = oeomega.OEOmega(omegaOpts) out_conf = [] ofs = oechem.oemolostream("test.sdf") if not isomer: ret_code = omega.Build(mol) if ret_code == oeomega.OEOmegaReturnCode_Success: out_conf.append(mol) else: oechem.OEThrow.Warning("%s: %s" % (mol.GetTitle(), oeomega.OEGetOmegaError(ret_code))) elif isomer: for enantiomer in oeomega.OEFlipper(mol.GetActive(), 12, True): enantiomer = oechem.OEMol(enantiomer) ret_code = omega.Build(enantiomer) if ret_code == oeomega.OEOmegaReturnCode_Success: out_conf.append(enantiomer) num_enantiomers -= 1 oechem.OEWriteMolecule(ofs, mol) if num_enantiomers == 0: break else: oechem.OEThrow.Warning("%s: %s" % (mol.GetTitle(), oeomega.OEGetOmegaError(ret_code))) return out_conf
def create_molecule(name, filename): # Open output file. ofs = oechem.oemolostream() ofs.open(filename) # Create molecule. mol = oechem.OEMol() # Speculatively reorder CAS permuted index names str = oeiupac.OEReorderIndexName(name) if len(str)==0: str=name done = oeiupac.OEParseIUPACName(mol, str) # Create conformation. omega = oeomega.OEOmega() omega.SetIncludeInput(False) # don't include input omega.SetMaxConfs(1) # set maximum number of conformations to 1 omega(mol) # Set molecule name mol.SetTitle(name) # Write molecule. oechem.OEWriteMolecule(ofs, mol) # Close stream. ofs.close() return
def hasAmberParams( mol, cmd_string): ofslig = oechem.oemolostream( 'lig.mol2') ofslig.SetFlavor( oechem.OEFormat_MOL2, oechem.OEOFlavor_MOL2_Forcefield ); oechem.OEWriteConstMolecule(ofslig, mol) ofslig.close() os.system( cmd_string) paramsNotSaved = 'Parameter file was not saved' leaplog = open( 'leap_lig.stdout', 'r' ).read() hasParams = not paramsNotSaved in leaplog return hasParams
def ProtonateLig_openeye(file_in,file_out,protonate=True,type_in=None,type_out=None): """ Function to protonate small molecule using OpenEye's python libraries. Requires OpenEye licence. More information found https://docs.eyesopen.com/toolkits/python/quickstart-python/index.html Also doubles as a file conversion script. Files types can be specified or detected via the file extension. File types supported by OpenEye listed here: https://docs.eyesopen.com/toolkits/python/oechemtk/molreadwrite.html Parameters ---------- file_in: str Name of the input file containing the coordinates of the molecule. One molecule expected. file_out: str Name of the output file. type_in: str File type of input file. Typically the file extension. type_out: str File type of the output file. Typically the file extension. Returns ------- The output is written to a file """ try: import openeye.oechem as oechem if type_in == None: type_in = file_in.split('.')[-1] if type_out == None: type_out = file_out.split('.')[-1] mol = oechem.OEGraphMol() # initialising molecule object ifs = oechem.oemolistream() # initialising input stream for reading in data ofs = oechem.oemolostream() # initialising the OUTPUT stream for writing data ifs.SetFormat(eval('oechem.OEFormat_' + type_in.upper())) ofs.SetFormat(eval('oechem.OEFormat_' + type_out.upper())) ifs.open(file_in) if oechem.OEReadMolecule(ifs,mol): # this function automatically returns True or False, to help spot for errors. pass else: print "Problem loading molecule!" mol = oechem.OEMol(mol) oechem.OEAssignAromaticFlags(mol, oechem.OEAroModelOpenEye) if protonate==True: oechem.OEAddExplicitHydrogens(mol) ofs.open(file_out) oechem.OEWriteMolecule(ofs,mol) except ImportError: print 'OpenEye python bindings not found'
def write_mol2_preserving_atomnames(filename, molecules, residue_name): ofs = oechem.oemolostream() ofs.open(filename) ofs.SetFlavor(oechem.OEFormat_MOL2, oechem.OEOFlavor_MOL2_GeneralFFFormat) try: for molecule in molecules: oechem.OEWriteMolecule(ofs, molecule) except: oechem.OEWriteMolecule(ofs, molecules) ofs.close() fix_mol2_resname(filename, residue_name)
def setup_yank_calculation(receptor_file_name, ligand_file_name, setup_directory_name, solvate=False): # Cleanup setup directory if os.path.exists(setup_directory_name): shutil.rmtree(setup_directory_name) os.makedirs(setup_directory_name) # Read ligand and receptor molecule ifs_mol2 = oechem.oemolistream() ifs_mol2.open(ligand_file_name) ligand_oemol = oechem.OEGraphMol() oechem.OEReadMolecule(ifs_mol2, ligand_oemol) ifs_mol2.close() ifs_mol2 = oechem.oemolistream() ifs_mol2.open(receptor_file_name) receptor_oemol = oechem.OEGraphMol() oechem.OEReadMolecule(ifs_mol2, receptor_oemol) ifs_mol2.close() # Push ligand close to receptor pull_close(receptor_oemol, ligand_oemol, MIN_DISTANCE, MAX_DISTANCE) # Add residue name 'MOL' residue = oechem.OEResidue() residue.SetName('MOL') for atom in ligand_oemol.GetAtoms(): oechem.OEAtomSetResidue(atom, residue) # Parametrize ligand with working_directory(setup_directory_name): # Save translated ligand ofs = oechem.oemolostream() ofs.open('ligand.mol2') oechem.OEWriteMolecule(ofs, ligand_oemol) ofs.close() # Parametrize ligand print "Parameterizing ligand with GAFF..." run_command('antechamber -fi mol2 -i ligand.mol2 -fo mol2 -o ligand.gaff.mol2') run_command('parmchk -i ligand.gaff.mol2 -o ligand.gaff.frcmod -f mol2') # Copy receptor so that leap will know the PDB file name shutil.copyfile(receptor_file_name, 'receptor.pdb') # Create AMBER prmtop/inpcrd files. print "Creating AMBER prmtop/inpcrd files..." cmd = 'tleap -f {!s} > setup.leap.out' if solvate: run_command(cmd.format(LEAP_IN_EXPLICIT)) else: run_command(cmd.format(LEAP_IN_IMPLICIT))
def normalize_molecule(mol): # Assign aromaticity. oechem.OEAssignAromaticFlags(mol, oechem.OEAroModelOpenEye) # Add hydrogens. oechem.OEAddExplicitHydrogens(mol) # Check for any missing atom names, if found reassign all of them. if any([atom.GetName() == '' for atom in mol.GetAtoms()]): oechem.OETriposAtomNames(mol) ofs = oechem.oemolostream('out.mol2') ofs.SetFormat(oechem.OEFormat_MOL2H) oechem.OEWriteMolecule(ofs, mol) ofs.close() return mol
def new_output_stream(outname): """ This function creates a new oechem.oemolostream. Parameters ---------- outname: str name of outputfile. Returns ------- ofs: oechem.oemolostream """ ofs = oechem.oemolostream() if not ofs.open(outname): oechem.OEThrow.Fatal("Unable to open {} for writing".format(outname)) return ofs
def hasAmberParams( mol, leaprc_string): # write mol2 file title = mol.GetTitle() ofsmol2 = oechem.oemolostream(title+'.mol2') ofsmol2.SetFlavor( oechem.OEFormat_MOL2, oechem.OEOFlavor_MOL2_Forcefield ); oechem.OEWriteConstMolecule(ofsmol2, mol) ofsmol2.close() # write tleap input file os.system( 'echo """lig = loadMol2 '+title+'.mol2""" >| '+title+'.leap_in') os.system( 'echo """saveAmberParm lig '+title+'.top '+title+'.crd""" >> '+title+'.leap_in') os.system( 'echo quit >> '+title+'.leap_in') # run tleap #print( 'tleap -f '+leaprc_string+' -f '+title+'.leap_in >| leap_lig.stdout' ) os.system( 'tleap -f '+leaprc_string+' -f '+title+'.leap_in >| leap_lig.stdout' ) # check if param file was not saved (implies parameterization problems) paramsNotSaved = 'Parameter file was not saved' leaplog = open( 'leap_lig.stdout', 'r' ).read() hasParams = not paramsNotSaved in leaplog return hasParams
def write_tripos_mol2(molecule, filename, substructure_name='MOL', nconfs=None): """ Write the molecule as a Tripos mol2 file. Parameters ---------- molecule : openeye.oechem.OEMol The molecule to be written. filename : str The file to write to. substructure_name : str, optional, default='MOL' The name of the substructure to write. nconfs : int, optional, default=None The number of conformers to write. """ # Avoid changing molecule by making a deep copy. molecule = oechem.OEMol(molecule) # Select number of conformers to write. if nconfs is None: nconfs = molecule.GetConfs() # Write the molecule in Tripos mol2 format. ofs = oechem.oemolostream(filename) ofs.SetFormat(oechem.OEFormat_MOL2H) for k, mol in enumerate(molecule.GetConfs()): if (k < nconfs): oechem.OEWriteMolecule(ofs, mol) ofs.close() # Replace <0> substructure names with valid text. if substructure_name: infile = open(filename, 'r') lines = infile.readlines() infile.close() newlines = [line.replace('<0>', substructure_name) for line in lines] outfile = open(filename, 'w') outfile.writelines(newlines) outfile.close() return
def main(argv=sys.argv): if len(argv) != 3: oechem.OEThrow.Usage("%s <infile (forcefield types)> <outfile (Tripos types)>" % argv[0]) ifs = oechem.oemolistream() flavor = oechem.OEIFlavor_Generic_Default | oechem.OEIFlavor_MOL2_Default | oechem.OEIFlavor_MOL2_Forcefield ifs.SetFlavor(oechem.OEFormat_MOL2, flavor) if not ifs.open(argv[1]): oechem.OEThrow.Fatal("Unable to open %s for reading" % argv[1]) ofs = oechem.oemolostream() if not ofs.open(argv[2]): oechem.OEThrow.Fatal("Unable to open %s for writing" % argv[2]) for mol in ifs.GetOEMols(): oechem.OETriposAtomNames(mol) oechem.OEWriteConstMolecule(ofs, mol) ifs.close() ofs.close()
def write_host(host_oemol : oechem.OEMol, filepath: str): """ Write out the host molecule on its own. Parameters ---------- host_oemol : oechem.OEMol the OEMol containing the host filepath : str where to write the OEMol """ ostream = oechem.oemolostream() ostream.open(filepath) #set title to avoid template name collision: host_oemol.SetTitle("host") #set tripos atom names oechem.OETriposAtomNames(host_oemol) oechem.OEWriteMolecule(ostream, host_oemol) ostream.close()
def write_oe_molecule(oe_mol, file_path, mol2_resname=None): """Write all conformations in a file and automatically detects format.""" from openeye import oechem # Get correct OpenEye format extension = os.path.splitext(file_path)[1][1:] # remove dot oe_format = getattr(oechem, 'OEFormat_' + extension.upper()) # Open stream and write molecule ofs = oechem.oemolostream() ofs.SetFormat(oe_format) if not ofs.open(file_path): oechem.OEThrow.Fatal('Unable to create {}'.format(file_path)) oechem.OEWriteMolecule(ofs, oe_mol) ofs.close() # If this is a mol2 file, we need to replace the resname # TODO when you merge to openmoltools, incapsulate this and add to molecule_to_mol2() if mol2_resname is not None and extension == 'mol2': with open(file_path, 'r') as f: lines = f.readlines() lines = [line.replace('<0>', mol2_resname) for line in lines] with open(file_path, 'w') as f: f.writelines(lines)
def mol_to_tagged_smiles(infile, outfile): """ Generate .smi from input mol with index-tagged explicit hydrogen SMILES Parameters ---------- infile: str input molecule file outfile: str output smi file. Must be smi or ism """ ifs = oechem.oemolistream() if not ifs.open(infile): oechem.OEThrow.Fatal("Unable to open {} for reading".format(infile)) ofs = oechem.oemolostream() if not ofs.open(outfile): oechem.OEThrow.Fatal("Unable to open {} for writing".format(outfile)) if ofs.GetFormat() not in [oechem.OEFormat_ISM, oechem.OEFormat_SMI]: oechem.OEThrow.Fatal("Output format must be SMILES") for mol in ifs.GetOEMols(): smiles = create_mapped_smiles(mol) oechem.OEWriteMolecule(ofs, mol)
def mk_conformers(options, molecule, maxconf=99, verbose=True): """ Enumerate the list of conformers and associated properties for each protonation and tautomeric state. Parameters ---------- options molecule : openeye.oechem The molecule read from the PDB whose protomer and tautomer states are to be enumerated. maxconf : int, optional, default=128 Maximum number of protomers/tautomers to generate. Returns ------- conformers : list of Conformer The list of protomers/tautomers generated. """ conformers = list() formalChargeOptions = oequacpac.OEFormalChargeOptions(maxconf) tautomerOptions = oequacpac.OETautomerOptions(maxconf) # enumerate pka states index = 0 for pkaState in oequacpac.OEEnumerateFormalCharges(molecule, formalChargeOptions): if (index > maxconf): break # enumerate tautomers of pka states for tautomer in oequacpac.OEEnumerateTautomers(pkaState, tautomerOptions): if (index > maxconf): break # Assign conformer name. name = options.ligand+'%02d' % index tautomer.SetTitle(name) # DEBUG: Write molecule before charging. ofs = oechem.oemolostream() ofs.open(name + '-before.mol2') outmol = oechem.OEMol(tautomer) oechem.OEWriteMolecule(ofs, outmol) ofs.close() # Compute formal charge. oechem.OEAssignFormalCharges(tautomer) formal_charge = 0.0 for atom in tautomer.GetAtoms(): formal_charge += atom.GetFormalCharge() if verbose: print "formal charge: %d" % formal_charge # Assign canonical AM1BCC charges. assign_canonical_am1bcc_charges(tautomer) # DEBUG: Write molecule after charging. ofs = oechem.oemolostream() outmol = oechem.OEMol(tautomer) ofs.open(name + '-after.mol2') oechem.OEWriteMolecule(ofs, outmol) ofs.close() # Create conformer. conformer = Conformer(name, formal_charge, tautomer) # Append to protomer/tautomer list. conformers.append(conformer) # Keep count of protomers/tautomers. index += 1 # Show output if requested. if verbose: print "%12s %+5d %8d atoms" % (name, conformer.charge, conformer.natoms) if verbose: print "%d protomer/tautomer states were enumerated" % len(conformers) return conformers
def enumerate_conformations(name, smiles=None, pdbname=None): """Run Epik to get protonation states using PDB residue templates for naming. Parameters ---------- name : str Common name of molecule (used to create subdirectory) smiles : str Isomeric SMILES string pdbname : str Three-letter PDB code (e.g. 'DB8') """ # Create output subfolder output_basepath = os.path.join(output_dir, name) if not os.path.isdir(output_basepath): os.mkdir(output_basepath) output_basepath = os.path.join(output_basepath, name) if pdbname: # Make sure to only use one entry if there are mutliple if ' ' in pdbname: pdbnames = pdbname.split(' ') print("Splitting '%s' into first entry only: '%s'" % (pdbname, pdbnames[0])) pdbname = pdbnames[0] # Retrieve PDB (for atom names) url = 'http://ligand-expo.rcsb.org/reports/%s/%s/%s_model.pdb' % (pdbname[0], pdbname, pdbname) pdb_filename = output_basepath + '-input.pdb' retrieve_url(url, pdb_filename) pdb_molecule = read_molecule(pdb_filename) # Retrieve SDF (for everything else) url = 'http://ligand-expo.rcsb.org/reports/%s/%s/%s_model.sdf' % (pdbname[0], pdbname, pdbname) sdf_filename = output_basepath + '-input.sdf' retrieve_url(url, sdf_filename) sdf_molecule = read_molecule(sdf_filename) # Replace atom names in SDF for (sdf_atom, pdb_atom) in zip(sdf_molecule.GetAtoms(), pdb_molecule.GetAtoms()): sdf_atom.SetName(pdb_atom.GetName()) # Assign Tripos atom types oechem.OETriposAtomTypeNames(sdf_molecule) oechem.OETriposBondTypeNames(sdf_molecule) oe_molecule = sdf_molecule # We already know the residue name residue_name = pdbname elif smiles: # Generate molecule geometry with OpenEye print("Generating molecule {}".format(name)) oe_molecule = openeye.smiles_to_oemol(smiles) # Assign Tripos atom types oechem.OETriposAtomTypeNames(oe_molecule) oechem.OETriposBondTypeNames(oe_molecule) try: oe_molecule = openeye.get_charges(oe_molecule, keep_confs=1) except RuntimeError as e: traceback.print_exc() print("Skipping molecule " + name) return residue_name = re.sub('[^A-Za-z]+', '', name.upper())[:3] else: raise Exception('Must provide SMILES string or pdbname') # Save mol2 file, preserving atom names print("Running epik on molecule {}".format(name)) mol2_file_path = output_basepath + '-input.mol2' write_mol2_preserving_atomnames(mol2_file_path, oe_molecule, residue_name) # Run epik on mol2 file mae_file_path = output_basepath + '-epik.mae' schrodinger.run_epik(mol2_file_path, mae_file_path, tautomerize=False, max_structures=100, min_probability=np.exp(-MAX_ENERGY_PENALTY), ph=7.4) # Convert maestro file to sdf and mol2 output_sdf_filename = output_basepath + '-epik.sdf' output_mol2_filename = output_basepath + '-epik.mol2' schrodinger.run_structconvert(mae_file_path, output_sdf_filename) schrodinger.run_structconvert(mae_file_path, output_mol2_filename) # Read SDF file. ifs_sdf = oechem.oemolistream() ifs_sdf.SetFormat(oechem.OEFormat_SDF) ifs_sdf.open(output_sdf_filename) sdf_molecule = oechem.OEGraphMol() # Read MOL2 file. ifs_mol2 = oechem.oemolistream() ifs_mol2.open(output_mol2_filename) mol2_molecule = oechem.OEMol() # Assign charges. charged_molecules = list() index = 0 while oechem.OEReadMolecule(ifs_sdf, sdf_molecule): oechem.OEReadMolecule(ifs_mol2, mol2_molecule) index += 1 print("Charging molecule %d" % (index)) try: # Charge molecule. charged_molecule = openeye.get_charges(mol2_molecule, max_confs=800, strictStereo=False, normalize=True, keep_confs=None) # Assign Tripos types oechem.OETriposAtomTypeNames(charged_molecule) oechem.OETriposBondTypeNames(charged_molecule) # Store tags. oechem.OECopySDData(charged_molecule, sdf_molecule) # Store molecule charged_molecules.append(charged_molecule) except Exception as e: print(e) print("Skipping protomer/tautomer because of failed charging.") # Clean up ifs_sdf.close() ifs_mol2.close() # Write state penalites. outfile = open(output_basepath + '-state-penalties.out', 'w') for (index, charged_molecule) in enumerate(charged_molecules): # Get Epik data. epik_Ionization_Penalty = float(oechem.OEGetSDData(charged_molecule, "r_epik_Ionization_Penalty")) epik_Ionization_Penalty_Charging = float(oechem.OEGetSDData(charged_molecule, "r_epik_Ionization_Penalty_Charging")) epik_Ionization_Penalty_Neutral = float(oechem.OEGetSDData(charged_molecule, "r_epik_Ionization_Penalty_Neutral")) epik_State_Penalty = float(oechem.OEGetSDData(charged_molecule, "r_epik_State_Penalty")) epik_Tot_Q = int(oechem.OEGetSDData(charged_molecule, "i_epik_Tot_Q")) outfile.write('%16.8f\n' % epik_State_Penalty) outfile.close() # Write as PDB charged_pdb_filename = output_basepath + '-epik-charged.pdb' ofs = oechem.oemolostream(charged_pdb_filename) flavor = oechem.OEOFlavor_PDB_CurrentResidues | oechem.OEOFlavor_PDB_ELEMENT | oechem.OEOFlavor_PDB_BONDS | oechem.OEOFlavor_PDB_HETBONDS | oechem.OEOFlavor_PDB_BOTH ofs.SetFlavor(oechem.OEFormat_PDB, flavor) for (index, charged_molecule) in enumerate(charged_molecules): # Fix residue names for atom in charged_molecule.GetAtoms(): residue = oechem.OEAtomGetResidue(atom) residue.SetName(residue_name) oechem.OEAtomSetResidue(atom, residue) #oechem.OEWritePDBFile(ofs, charged_molecule, flavor) oechem.OEWriteMolecule(ofs, charged_molecule) ofs.close() # Write molecules as mol2. charged_mol2_filename = output_basepath + '-epik-charged.mol2' write_mol2_preserving_atomnames(charged_mol2_filename, charged_molecules, residue_name)
def generate_torsions(mol, path, interval): """ This function takes a 3D molecule (pdf, mol2 or sd file) and generates structures for a torsion drive on all torsions in the molecule. This function uses OpenEye Parameters ---------- mol : str path to molecule file (pdb, mol2, sd, etc.) path: str path to output files interval: int angle (in degrees) of interval for torsion drive """ filename = mol.split('/')[-1].split('.')[0] ifs = oechem.oemolistream(mol) inp_mol = oechem.OEMol() oechem.OEReadMolecule(ifs, inp_mol) ifs.close() mid_tors = [[tor.a, tor.b, tor.c, tor.d ] for tor in oechem.OEGetTorsions(inp_mol)] # This smarts should match terminal torsions such as -CH3, -NH2, -NH3+, -OH, and -SH smarts = '[*]~[*]-[X2H1,X3H2,X4H3]-[#1]' qmol=oechem.OEQMol() if not oechem.OEParseSmarts(qmol, smarts): warnings.warn('OEParseSmarts failed') ss = oechem.OESubSearch(qmol) mol = oechem.OEMol(inp_mol) h_tors = [] oechem.OEPrepareSearch(mol, ss) unique = True for match in ss.Match(mol, unique): tor = [] for ma in match.GetAtoms(): tor.append(ma.target) h_tors.append(tor) # Combine middle and terminal torsions all_tors = mid_tors + h_tors # Sort all_tors so that it's grouped by central bond central_bonds = np.zeros((len(all_tors), 3), dtype=int) for i, tor in enumerate(all_tors): central_bonds[i][0] = i central_bonds[i][1] = tor[1].GetIdx() central_bonds[i][2] = tor[2].GetIdx() grouped = central_bonds[central_bonds[:, 2].argsort()] sorted_tors = [all_tors[i] for i in grouped[:, 0]] # Keep only one torsion per rotatable bond tors = [] best_tor = [sorted_tors[0][0], sorted_tors[0][0], sorted_tors[0][0], sorted_tors[0][0]] first_pass = True for tor in sorted_tors: logger().info("Idxs: {} {} {} {}".format(tor[0].GetIdx(), tor[1].GetIdx(), tor[2].GetIdx(), tor[3].GetIdx())) logger().info("Atom Numbers: {} {} {} {}".format(tor[0].GetAtomicNum(), tor[1].GetAtomicNum(), tor[2].GetAtomicNum(), tor[3].GetAtomicNum())) if tor[1].GetIdx() != best_tor[1].GetIdx() or tor[2].GetIdx() != best_tor[2].GetIdx(): new_tor = True if not first_pass: logger().info("Adding to list: {} {} {} {}".format(best_tor[0].GetIdx(), best_tor[1].GetIdx(), best_tor[2].GetIdx(), best_tor[3].GetIdx())) tors.append(best_tor) first_pass = False best_tor = tor best_tor_order = tor[0].GetAtomicNum() + tor[3].GetAtomicNum() logger().info("new_tor with central bond across atoms: {} {}".format(tor[1].GetIdx(), tor[2].GetIdx())) else: logger().info("Not a new_tor but now with end atoms: {} {}".format(tor[0].GetIdx(), tor[3].GetIdx())) tor_order = tor[0].GetAtomicNum() + tor[3].GetAtomicNum() if tor_order > best_tor_order: best_tor = tor best_tor_order = tor_order logger().info("Adding to list: {} {} {} {}".format(best_tor[0].GetIdx(), best_tor[1].GetIdx(), best_tor[2].GetIdx(), best_tor[3].GetIdx())) tors.append(best_tor) logger().info("List of torsion to drive:") for tor in tors: logger().info("Idx: {} {} {} {}".format(tor[0].GetIdx(), tor[1].GetIdx(), tor[2].GetIdx(), tor[3].GetIdx())) logger().info("Atom numbers: {} {} {} {}".format(tor[0].GetAtomicNum(), tor[1].GetAtomicNum(), tor[2].GetAtomicNum(), tor[3].GetAtomicNum())) conf = mol.GetConfs().next() coords = oechem.OEFloatArray(conf.GetMaxAtomIdx() * 3) conf.GetCoords(coords) mol.DeleteConfs() for tor in tors: tor_name = str((tor[0].GetIdx())+1) + '_' + str((tor[1].GetIdx())+1) + '_' + str((tor[2].GetIdx())+1) + '_' + str((tor[3].GetIdx())+1) folder = os.path.join(path, tor_name) try: os.makedirs(folder) except FileExistsError: logger().info("Overwriting existing directory {}".format(tor_name)) for angle in range(0, 360, interval): angle_folder = os.path.join(folder, str(angle)) os.makedirs(angle_folder) newconf = mol.NewConf(coords) oechem.OESetTorsion(newconf, tor[0], tor[1], tor[2], tor[3], radians(angle)) pdb = oechem.oemolostream('{}/{}_{}_{}.pdb'.format(angle_folder, filename, tor_name, angle)) oechem.OEWritePDBFile(pdb, newconf)
def generate_torsions(inp_mol, output_path, interval, base_name=None, tar=True): """ This function takes a 3D molecule (pdf, mol2 or sd file) and generates structures for a torsion drive on all torsions in the molecule. This function uses OpenEye Parameters ---------- mol : OEMol molecule to generate 1D torsion scans output_path: str path to output file directory interval: int angle (in degrees) of interval for torsion drive base_name: str base name for file. Default is None. If default, use title in OEMol for base name tar: bool If true, will compress output """ if not base_name: base_name = inp_mol.GetTitle() mid_tors = [[tor.a, tor.b, tor.c, tor.d ] for tor in oechem.OEGetTorsions(inp_mol)] # This smarts should match terminal torsions such as -CH3, -NH2, -NH3+, -OH, and -SH smarts = '[*]~[*]-[X2H1,X3H2,X4H3]-[#1]' qmol=oechem.OEQMol() if not oechem.OEParseSmarts(qmol, smarts): warnings.warn('OEParseSmarts failed') ss = oechem.OESubSearch(qmol) mol = oechem.OEMol(inp_mol) h_tors = [] oechem.OEPrepareSearch(mol, ss) unique = True for match in ss.Match(mol, unique): tor = [] for ma in match.GetAtoms(): tor.append(ma.target) h_tors.append(tor) # Combine middle and terminal torsions all_tors = mid_tors + h_tors # Sort all_tors so that it's grouped by central bond central_bonds = np.zeros((len(all_tors), 3), dtype=int) for i, tor in enumerate(all_tors): central_bonds[i][0] = i central_bonds[i][1] = tor[1].GetIdx() central_bonds[i][2] = tor[2].GetIdx() grouped = central_bonds[central_bonds[:, 2].argsort()] sorted_tors = [all_tors[i] for i in grouped[:, 0]] # Keep only one torsion per rotatable bond tors = [] best_tor = [sorted_tors[0][0], sorted_tors[0][0], sorted_tors[0][0], sorted_tors[0][0]] first_pass = True for tor in sorted_tors: logger().info("Idxs: {} {} {} {}".format(tor[0].GetIdx(), tor[1].GetIdx(), tor[2].GetIdx(), tor[3].GetIdx())) logger().info("Atom Numbers: {} {} {} {}".format(tor[0].GetAtomicNum(), tor[1].GetAtomicNum(), tor[2].GetAtomicNum(), tor[3].GetAtomicNum())) if tor[1].GetIdx() != best_tor[1].GetIdx() or tor[2].GetIdx() != best_tor[2].GetIdx(): new_tor = True if not first_pass: logger().info("Adding to list: {} {} {} {}".format(best_tor[0].GetIdx(), best_tor[1].GetIdx(), best_tor[2].GetIdx(), best_tor[3].GetIdx())) tors.append(best_tor) first_pass = False best_tor = tor best_tor_order = tor[0].GetAtomicNum() + tor[3].GetAtomicNum() logger().info("new_tor with central bond across atoms: {} {}".format(tor[1].GetIdx(), tor[2].GetIdx())) else: logger().info("Not a new_tor but now with end atoms: {} {}".format(tor[0].GetIdx(), tor[3].GetIdx())) tor_order = tor[0].GetAtomicNum() + tor[3].GetAtomicNum() if tor_order > best_tor_order: best_tor = tor best_tor_order = tor_order logger().info("Adding to list: {} {} {} {}".format(best_tor[0].GetIdx(), best_tor[1].GetIdx(), best_tor[2].GetIdx(), best_tor[3].GetIdx())) tors.append(best_tor) logger().info("List of torsion to drive:") for tor in tors: logger().info("Idx: {} {} {} {}".format(tor[0].GetIdx(), tor[1].GetIdx(), tor[2].GetIdx(), tor[3].GetIdx())) logger().info("Atom numbers: {} {} {} {}".format(tor[0].GetAtomicNum(), tor[1].GetAtomicNum(), tor[2].GetAtomicNum(), tor[3].GetAtomicNum())) conf = mol.GetConfs().next() coords = oechem.OEFloatArray(conf.GetMaxAtomIdx() * 3) conf.GetCoords(coords) # Check if coordinates are not zero values = np.asarray([coords.__getitem__(i) == 0 for i in range(coords.__len__())]) if values.all(): # Generate new coordinates. mol2 = generate_conformers(mol, max_confs=1) conf = mol2.GetConfs().next() coords = oechem.OEFloatArray(conf.GetMaxAtomIdx() * 3) conf.GetCoords(coords) mol2.DeleteConfs() mol.DeleteConfs() for tor in tors: tor_name = str((tor[0].GetIdx())+1) + '_' + str((tor[1].GetIdx())+1) + '_' + str((tor[2].GetIdx())+1) + '_' + str((tor[3].GetIdx())+1) folder = os.path.join(output_path, tor_name) try: os.makedirs(folder) except FileExistsError: logger().info("Overwriting existing directory {}".format(tor_name)) for angle in range(0, 360, interval): angle_folder = os.path.join(folder, str(angle)) try: os.mkdir(angle_folder) except FileExistsError: logger().info("Overwriting existing directory {}".format(tor_name)) newconf = mol.NewConf(coords) oechem.OESetTorsion(newconf, tor[0], tor[1], tor[2], tor[3], radians(angle)) pdb = oechem.oemolostream('{}/{}_{}_{}.pdb'.format(angle_folder, base_name, tor_name, angle)) oechem.OEWritePDBFile(pdb, newconf) if tar: # tar archive output out = tarfile.open('{}.tar.gz'.format(output_path), mode='w:gz') os.chdir(output_path) os.chdir('../') out.add('{}'.format(base_name)) out.close()
def generateOEMolFromTopologyResidue(residue): """ Generate an OpenEye OEMol molecule from an OpenMM Topology Residue. Parameters ---------- residue : simtk.openmm.app.topology.Residue The topology Residue from which an OEMol is to be created. An Exception will be thrown if this residue has external bonds. Returns ------- molecule : openeye.oechem.OEMol The OEMol molecule corresponding to the topology. Atom order will be preserved and bond orders assigned. The Antechamber `bondtype` program will be used to assign bond orders, and these will be converted back into OEMol bond type assignments. Note that there is no way to preserve stereochemistry since `Residue` does not note stereochemistry in any way. """ # Raise an Exception if this residue has external bonds. if len(list(residue.external_bonds())) > 0: raise Exception("Cannot generate an OEMol from residue '%s' because it has external bonds." % residue.name) from openeye import oechem # Create OEMol where all atoms have bond order 1. molecule = oechem.OEMol() molecule.SetTitle(residue.name) # name molecule after first residue for atom in residue.atoms(): oeatom = molecule.NewAtom(atom.element.atomic_number) oeatom.SetName(atom.name) oeatoms = { oeatom.GetName() : oeatom for oeatom in molecule.GetAtoms() } for (atom1, atom2) in residue.bonds(): order = 1 molecule.NewBond(oeatoms[atom1.name], oeatoms[atom2.name], order) # Write out a mol2 file without altering molecule. import tempfile tmpdir = tempfile.mkdtemp() mol2_input_filename = os.path.join(tmpdir,'molecule-before-bond-perception.mol2') ac_output_filename = os.path.join(tmpdir,'molecule-after-bond-perception.ac') ofs = oechem.oemolostream(mol2_input_filename) m2h = True substruct = False oechem.OEWriteMol2File(ofs, molecule, m2h, substruct) ofs.close() # Run Antechamber bondtype import subprocess #command = 'bondtype -i %s -o %s -f mol2 -j full' % (mol2_input_filename, ac_output_filename) command = 'antechamber -i %s -fi mol2 -o %s -fo ac -j 2' % (mol2_input_filename, ac_output_filename) [status, output] = getstatusoutput(command) # Define mapping from GAFF bond orders to OpenEye bond orders. order_map = { 1 : 1, 2 : 2, 3: 3, 7 : 1, 8: 2, 9 : 5, 10 : 5 } # Read bonds. infile = open(ac_output_filename) lines = infile.readlines() infile.close() antechamber_bond_types = list() for line in lines: elements = line.split() if elements[0] == 'BOND': antechamber_bond_types.append(int(elements[4])) for (bond, antechamber_bond_type) in zip(molecule.GetBonds(), antechamber_bond_types): bond.SetOrder(order_map[antechamber_bond_type]) # Clean up. os.unlink(mol2_input_filename) os.unlink(ac_output_filename) os.rmdir(tmpdir) # Set aromaticity. # TODO: Is this necessary? oechem.OEClearAromaticFlags(molecule) oechem.OEAssignAromaticFlags(molecule, oechem.OEAroModelOpenEye) # Assign Tripos atom types. # TODO: Is this necessary? oechem.OETriposAtomTypeNames(molecule) oechem.OETriposBondTypeNames(molecule) # Assign geometry # TODO: Is this necessary? from openeye import oeomega omega = oeomega.OEOmega() omega.SetMaxConfs(1) omega.SetIncludeInput(False) omega.SetStrictStereo(False) omega(molecule) return molecule
os.system( cmd_string) paramsNotSaved = 'Parameter file was not saved' leaplog = open( 'leap_lig.stdout', 'r' ).read() hasParams = not paramsNotSaved in leaplog return hasParams # In[4]: fileprefix= 'AlkEthOH_chain_filt1' #fileprefix= 'AlkEthOH_rings_filt1' #fileprefix= 'test_filt1' #fileprefix= 'AlkEthOH_r21' #fileprefix= 'thp23diol' ifs = oechem.oemolistream(fileprefix+'.oeb') ofs = oechem.oemolostream(fileprefix+'_hasParam.oeb') ofsFail = oechem.oemolostream(fileprefix+'_lacksParam.oeb') #ofs.SetFlavor( oechem.OEFormat_MOL2, oechem.OEOFlavor_MOL2_Forcefield ); # In[5]: cmd_string = 'tleap -f leaprc.Frosst_AlkEthOH -f lig.leap_in >| leap_lig.stdout' mol = oechem.OEMol() for mol in ifs.GetOEMols(): if hasAmberParams(mol,cmd_string): print( 'Has Amber params: %s' % mol.GetTitle() ) oechem.OEWriteConstMolecule(ofs, mol) else: print( 'Lacks Amber params: %s' % mol.GetTitle() ) oechem.OEWriteConstMolecule(ofsFail, mol)
oequacpac.OEAssignCharges(mol_multiconf, oequacpac.OEAM1BCCELF10Charges()) # Get total charge conf = mol_multiconf.GetConf(oechem.OEHasConfIdx(0)) absFCharge = 0 sumFCharge = 0 sumPCharge = 0.0 for atm in mol_multiconf.GetAtoms(): sumFCharge += atm.GetFormalCharge() absFCharge += abs(atm.GetFormalCharge()) sumPCharge += atm.GetPartialCharge() oechem.OEThrow.Info("%s: %d formal charges give total charge %d ; Sum of Partial Charges %5.4f" % (mol_multiconf.GetTitle(), absFCharge, sumFCharge, sumPCharge)) # Output file ofs = oechem.oemolostream(charged_FN) ofs.SetFormat(oechem.OEFormat_MOL2H) oechem.OEWriteMolecule(ofs, conf) ofs.close() else: # Conformer generation failed. Use Ballon + Chimera print 'Conformer generation with OETools failed.' if (args.UseOpenEye=='N') or not step_complete(charged_FN): if not step_complete(balloon_FN): # Run Balloon to convert from a SMILES string to a 3D structure MMFF94_FN = os.path.join(os.path.dirname(command_paths['balloon']),'MMFF94.mff') command = command_paths['balloon'] + ' -f ' + MMFF94_FN + \ ' --nconfs 1 --nGenerations 300 "' + smi + '" ' + balloon_FN os.system(command)
def run_epik(name, filename, residue_name, perceive_bonds=False): """Generate conformer with OpenEye omega, protonation states with Schrodinger Epik, and charges with OpenEye AM1-BCC. Parameters ---------- name : str The name of the output directory to generate. filename : str The mol2, PDB, or SDF file to read in. residue_name : str Three uppercase letters to name residue. perceive_bonds : bool, optional, default=False If True, will use geometry to perceive connectivity. This is necessary for PDB files. """ # Generate molecule geometry with OpenEye print("Generating molecule %s from %s" % (name, filename)) oe_molecule = read_molecules(filename) if perceive_bonds: oechem.OEDetermineConnectivity(oe_molecule) # Assign geometry and charges with Omega oe_molecule = openeye.get_charges(oe_molecule, max_confs=1, strictStereo=False, normalize=True, keep_confs=1) # Create output subfolder output_basepath = os.path.join(output_dir, name) if not os.path.isdir(output_basepath): os.mkdir(output_basepath) output_basepath = os.path.join(output_basepath, name) # Save mol2 file with residue name = first three uppercase letters print "Running epik on molecule {}".format(name) mol2_file_path = output_basepath + '-input.mol2' residue_name = re.sub('[^A-Za-z]+', '', name.upper())[:3] #openeye.molecule_to_mol2(oe_molecule, mol2_file_path, residue_name=residue_name) from openeye import oechem ofs = oechem.oemolostream(mol2_file_path) oechem.OEWriteMol2File(ofs, oe_molecule, True, False) ofs.close() # Run epik on mol2 file mae_file_path = output_basepath + '-epik.mae' schrodinger.run_epik(mol2_file_path, mae_file_path, tautomerize=False, max_structures=100, min_probability=np.exp(-6), ph=7.4) # Convert maestro file to sdf and mol2 output_sdf_filename = output_basepath + '-epik.sdf' output_mol2_filename = output_basepath + '-epik.mol2' schrodinger.run_structconvert(mae_file_path, output_sdf_filename) schrodinger.run_structconvert(mae_file_path, output_mol2_filename) # Read SDF file. ifs_sdf = oechem.oemolistream() ifs_sdf.SetFormat(oechem.OEFormat_SDF) ifs_sdf.open(output_sdf_filename) sdf_molecule = oechem.OEMol() uncharged_molecules = read_molecules(output_sdf_filename) # Read MOL2 file. ifs_mol2 = oechem.oemolistream() ifs_mol2.open(output_mol2_filename) mol2_molecule = oechem.OEMol() uncharged_molecules = read_molecules(output_sdf_filename) # Assign charges. charged_molecules = list() index = 0 while oechem.OEReadMolecule(ifs_sdf, sdf_molecule): molecule = oechem.OEReadMolecule(ifs_mol2, mol2_molecule) index += 1 print "Charging molecule %d / %d" % (index, len(uncharged_molecules)) try: # Charge molecule. charged_molecule = openeye.get_charges(sdf_molecule, max_confs=800, strictStereo=False, normalize=True, keep_confs=None) # Store tags. oechem.OECopySDData(charged_molecule, sdf_molecule) charged_molecules.append(charged_molecule) except Exception as e: print(e) print("Skipping protomer/tautomer because of failed charging.") # Clean up ifs_sdf.close() ifs_mol2.close() # Write molecules. charged_mol2_filename = output_basepath + '-epik-charged.mol2' ofs = oechem.oemolostream(charged_mol2_filename) for (index, charged_molecule) in enumerate(charged_molecules): oechem.OEWriteMolecule(ofs, charged_molecule) ofs.close() # Write state penalites. outfile = open(output_basepath + '-state-penalties.out', 'w') for (index, charged_molecule) in enumerate(charged_molecules): # Get Epik data. epik_Ionization_Penalty = float(oechem.OEGetSDData(charged_molecule, "r_epik_Ionization_Penalty")) epik_Ionization_Penalty_Charging = float(oechem.OEGetSDData(charged_molecule, "r_epik_Ionization_Penalty_Charging")) epik_Ionization_Penalty_Neutral = float(oechem.OEGetSDData(charged_molecule, "r_epik_Ionization_Penalty_Neutral")) epik_State_Penalty = float(oechem.OEGetSDData(charged_molecule, "r_epik_State_Penalty")) epik_Tot_Q = int(oechem.OEGetSDData(charged_molecule, "i_epik_Tot_Q")) outfile.write('%16.8f\n' % epik_State_Penalty) outfile.close()
def pack_box(molecules, n_copies, tolerance=2.0, box_size=None, mass_density=None, verbose=False): """Run packmol to generate a box containing a mixture of molecules. Parameters ---------- molecules : list of OEMol Molecules in the system (with 3D geometries) n_copies : list of int (same length as 'molecules') Number of copies of the molecules tolerance : float, optional, default=2.0 The mininum spacing between molecules during packing. In ANGSTROMS! box_size : simtk.unit.Quantity in units compatible with angstroms The size of the box to generate. Default generates boxes that are very large for increased stability. May require extra time for energy minimization and equilibration. mass_density : simtk.unit.Quantity with units compatible with grams/milliliters, optional, default = 1.0*grams/milliliters Target mass density for final system, if available. verbose : bool, optional, default=False If True, verbose output is written. Returns ------- topology : simtk.openmm.Topology Topology of the resulting system positions : simtk.unit.Quantity wrapped [natoms,3] numpy array with units compatible with angstroms Single frame trajectory with mixture box. """ assert len(molecules) == len(n_copies), "Length of 'molecules' and 'n_copies' must be identical" # Create PDB files for all components pdb_filenames = list() pdb_flavor = oechem.OEOFlavor_PDB_CurrentResidues | oechem.OEOFlavor_PDB_ELEMENT | oechem.OEOFlavor_PDB_BONDS | oechem.OEOFlavor_PDB_HETBONDS | oechem.OEOFlavor_PDB_BOTH for molecule in molecules: tmp_filename = tempfile.mktemp(suffix=".pdb") pdb_filenames.append(tmp_filename) # Write PDB file mol_copy = copy.deepcopy(molecule) ofs = oechem.oemolostream(tmp_filename) ofs.SetFlavor(oechem.OEFormat_PDB, pdb_flavor) # Fix residue names residue_name = "".join([random.choice(string.ascii_uppercase) for i in range(3)]) for atom in mol_copy.GetAtoms(): residue = oechem.OEAtomGetResidue(atom) residue.SetName(residue_name) oechem.OEAtomSetResidue(atom, residue) oechem.OEWriteMolecule(ofs, mol_copy) ofs.close() # Run packmol PACKMOL_PATH = find_executable("packmol") if PACKMOL_PATH is None: raise(IOError("Packmol not found, cannot run pack_box()")) output_filename = tempfile.mktemp(suffix=".pdb") # Approximate volume to initialize box if (box_size is None): if (mass_density is not None): # Estimate box_size from mass density. box_size = approximate_volume_by_density(molecules, n_copies, mass_density=mass_density) else: # Use vdW radii to estimate box_size box_size = approximate_volume(molecules, n_copies) header = HEADER_TEMPLATE % (tolerance, output_filename) for (pdb_filename, molecule, count) in zip(pdb_filenames, molecules, n_copies): header = header + BOX_TEMPLATE % (pdb_filename, count, box_size / unit.angstroms, box_size / unit.angstroms, box_size / unit.angstroms) pwd = os.getcwd() if verbose: print(header) # Write packmol input packmol_filename = "packmol_input.txt" packmol_filename = tempfile.mktemp(suffix=".txt") file_handle = open(packmol_filename, 'w') file_handle.write(header) file_handle.close() os.system("%s < %s" % (PACKMOL_PATH, packmol_filename)) # Read the resulting PDB file. pdbfile = app.PDBFile(output_filename) # Extract topology and positions topology = pdbfile.getTopology() positions = pdbfile.getPositions() return [topology, positions]
oechem.OEAddExplicitHydrogens(molecule) oechem.OETriposAtomNames(molecule) oechem.OEAssignAromaticFlags(molecule, oechem.OEAroModelOpenEye) # Create configuration. omega = oeomega.OEOmega() omega.SetStrictStereo(True) omega.SetIncludeInput(False) omega(molecule) # Create charges. oequacpac.OEAssignPartialCharges(molecule, oequacpac.OECharges_AM1BCCSym) # Write molecule. filename = '%s.tripos.mol2' % name print filename ofs = oechem.oemolostream() ofs.open(filename) oechem.OEWriteMolecule(ofs, molecule) ofs.close() # Replace <0> with resname. infile = open(filename, 'r') lines = infile.readlines() infile.close() newlines = [line.replace('<0>', resname) for line in lines] outfile = open(filename, 'w') outfile.writelines(newlines) outfile.close()
def create_openeye_molecule(pdb, options, verbose=True): """ Create OpenEye molecule from PDB representation. The molecule will have hydrogens added and be normalized, but the overall geometry will not be altered. Parameters ---------- pdb : Pdb The PDB-extracted entries for the ligand. Returns ------- molecule : openeye.oechem.OEMol Molecule representation. options : options struct Options structure. """ # Create a molecule container. molecule = oechem.OEGraphMol() # Open a PDB file reader from the stored PDB string representation of HETATM and CONECT records. print pdb.pdb_extract ifs = oechem.oemolistream() ifs.openstring(pdb.pdb_extract) flavor = oechem.OEIFlavor_Generic_Default | oechem.OEIFlavor_PDB_Default | oechem.OEIFlavor_PDB_ALL ifs.SetFlavor(oechem.OEFormat_PDB, flavor) oechem.OEReadPDBFile(ifs, molecule) # Add explicit hydrogens. oechem.OEDetermineConnectivity(molecule) oechem.OEFindRingAtomsAndBonds(molecule) oechem.OEAssignAromaticFlags(molecule) # check aromaticity oechem.OEPerceiveBondOrders(molecule) # We must assign implicit hydrogens first so that the valence model will be correct. oechem.OEAssignImplicitHydrogens(molecule) oechem.OEAssignFormalCharges(molecule) # Now add explicit hydrogens. polarOnly = False set3D = True oechem.OEAddExplicitHydrogens(molecule, polarOnly, set3D) # TODO: Sequentially number hydrogen atoms. # Perceive stereochemostry. oechem.OEPerceiveChiral(molecule) # Set title. molecule.SetTitle(options.ligand) # Write out PDB form of this molecule. # TODO: Fix atom numbering. #if verbose: print "Writing input molecule as PDB..." #outmol = oechem.OEMol(molecule) #ofs = oechem.oemolostream() #flavor = oechem.OEOFlavor_Generic_Default | oechem.OEOFlavor_PDB_Default #ofs.SetFlavor(oechem.OEFormat_PDB, flavor) #ofs.open(options.ligand + '.pdb') #oechem.OEWriteMolecule(ofs, outmol) #ofs.close() # Write mol2 file for this molecule. if verbose: print "Writing input molecule as mol2..." outmol = oechem.OEMol(molecule) ofs = oechem.oemolostream() filename = options.ligand + '.mol2' ofs.open(filename) oechem.OEWriteMolecule(ofs, outmol) ofs.close() # Use low level writer to get atom names correct. ofs = oechem.oemolostream() ofs.open(filename) for (dest_atom, src_atom) in zip(outmol.GetAtoms(), molecule.GetAtoms()): dest_atom.SetName(src_atom.GetName()) oechem.OEWriteMol2File(ofs, outmol, True) ofs.close() # Read and write in PDB format. if verbose: print "Converting mol2 to PDB..." ifs = oechem.oemolistream() ofs = oechem.oemolostream() if ifs.open(options.ligand + '.mol2'): if ofs.open(options.ligand + '.pdb'): for mol in ifs.GetOEGraphMols(): oechem.OEWriteMolecule(ofs, mol) return molecule
return Image(data = "".join(ofs.str())) # In[15]: # filters for peroxides, 3-memb-rings, ketals badSmarts = [ 'OO', '[r3]', '[O&H1]C[O&H1]' ] badSSlst = [ oechem.OESubSearch( smarts) for smarts in badSmarts] # In[16]: fileprefix= 'AlkEthOH_chain' #fileprefix= 'AlkEthOH_rings' ifs = oechem.oemolistream(fileprefix+'.smi') ofs = oechem.oemolostream(fileprefix+'_filt1.smi') #molLst1 = [ mol for mol in ifs.GetOEMols() ] # In[17]: mol = oechem.OEMol() for mol in ifs.GetOEMols(): goodMol = True for badSS in badSSlst: oechem.OEPrepareSearch(mol, badSS) if badSS.SingleMatch(mol): goodMol = False display( depict(mol)) if goodMol: oechem.OEWriteConstMolecule(ofs, mol)
def mk_conformers_epik(options, molecule, maxconf=99, verbose=True, pH=7): """ Enumerate the list of conformers and associated properties for each protonation and tautomeric state using epik from the Schrodinger Suite. Parameters ---------- options molecule : openeye.oechem The molecule read from the PDB whose protomer and tautomer states are to be enumerated. maxconf : int, optional, default=128 Maximum number of protomers/tautomers to generate. pH : float, optional, default=7.0 pH to use for conformer enumeration Returns ------- conformers : list of Conformer The list of protomers/tautomers generated. """ from schrodinger import structure # Requires Schrodinger Suite # Write mol2 file. if verbose: print "Writing input file as mol2..." outmol = oechem.OEMol(molecule) ofs = oechem.oemolostream() ofs.open('epik-input.mol2') oechem.OEWriteMolecule(ofs, outmol) ofs.close() # Use low level writer to get atom names correct. ofs = oechem.oemolostream() ofs.open('epik-input.mol2') for (dest_atom, src_atom) in zip(outmol.GetAtoms(), molecule.GetAtoms()): dest_atom.SetName(src_atom.GetName()) oechem.OEWriteMol2File(ofs, outmol, True) ofs.close() # Write mol2 file. if verbose: print "Writing input file as sdf..." outmol = oechem.OEMol(molecule) ofs = oechem.oemolostream() ofs.open('epik-input.sdf') oechem.OEWriteMolecule(ofs, outmol) ofs.close() # Write pdb file. if verbose: print "Writing input file as pdb..." outmol = oechem.OEMol(molecule) ofs = oechem.oemolostream() ofs.open('epik-input.pdb') oechem.OEWriteMolecule(ofs, outmol) ofs.close() # Write input for epik. if verbose: print "Converting input file to Maestro format..." reader = structure.StructureReader("epik-input.mol2") writer = structure.StructureWriter("epik-input.mae") for st in reader: writer.append(st) reader.close() writer.close() # Run epik to enumerate protomers/tautomers and get associated state penalties. if verbose: print "Running Epik..." cmd = '%s/epik -imae epik-input.mae -omae epik-output.mae -pht 10.0 -ms 100 -nt -pKa_atom -ph %f -WAIT' % (os.environ['SCHRODINGER'], pH) output = commands.getoutput(cmd) if verbose: print output # Convert output from epik from .mae to .sdf. if verbose: print "Converting output file to SDF..." reader = structure.StructureReader("epik-output.mae") writer = structure.StructureWriter("epik-output.sdf") for st in reader: writer.append(st) reader.close() writer.close() # Also convert to .mol2. if verbose: print "Converting output file to MOL2..." reader = structure.StructureReader("epik-output.mae") writer = structure.StructureWriter("epik-output.mol2") for st in reader: writer.append(st) reader.close() writer.close() # Find minimum charge. ifs = oechem.oemolistream() ifs.open('epik-output.mol2') molecule = oechem.OEGraphMol() min_formal_charge = 1000 while oechem.OEReadMolecule(ifs, molecule): # Check aromaticity. oechem.OEAssignAromaticFlags(molecule) # Assign formal charge oechem.OEAssignFormalCharges(molecule) formal_charge = 0 for atom in molecule.GetAtoms(): formal_charge += atom.GetFormalCharge() # Keep most negative formal charge min_formal_charge = min(min_formal_charge, formal_charge) ifs.close() if verbose: print "Minimum formal charge = %d" % min_formal_charge # Read conformers from SDF and mol2 (converted from Epik). if verbose: print "Reading conformers from SDF..." ifs_sdf = oechem.oemolistream() ifs_sdf.SetFormat(oechem.OEFormat_SDF) ifs_sdf.open('epik-output.sdf') sdf_molecule = oechem.OEGraphMol() ifs_mol2 = oechem.oemolistream() ifs_mol2.open('epik-output.mol2') mol2_molecule = oechem.OEGraphMol() conformer_index = 1 conformers = list() while oechem.OEReadMolecule(ifs_sdf, sdf_molecule): if verbose: print "Conformer %d" % conformer_index # Read corresponding mol2 molecule. oechem.OEReadMolecule(ifs_mol2, mol2_molecule) oechem.OEAssignAromaticFlags(mol2_molecule) # check aromaticity # Make a copy of the mol2 molecule. molecule = oechem.OEMol(mol2_molecule) # Set name name = options.ligand+'%02d' % conformer_index molecule.SetTitle(name) # Assign formal charge oechem.OEAssignFormalCharges(molecule) formal_charge = 0.0 for atom in molecule.GetAtoms(): formal_charge += atom.GetFormalCharge() if verbose: print "formal charge: %d" % formal_charge # DEBUG: Write mol2 file before assigning charges. if verbose: print "Writing %s to mol2..." % name outmol = oechem.OEMol(molecule) ofs = oechem.oemolostream() ofs.open(name + '.mol2') oechem.OEWriteMolecule(ofs, outmol) ofs.close() # Assign canonical AM1BCC charges. try: if verbose: print "Assigning AM1-BCC charges..." #assign_canonical_am1bcc_charges(molecule) assign_simple_am1bcc_charges(molecule) except Exception as e: print str(e) continue # Get Epik data. epik_Ionization_Penalty = float(oechem.OEGetSDData(sdf_molecule, "r_epik_Ionization_Penalty")) epik_Ionization_Penalty_Charging = float(oechem.OEGetSDData(sdf_molecule, "r_epik_Ionization_Penalty_Charging")) epik_Ionization_Penalty_Neutral = float(oechem.OEGetSDData(sdf_molecule, "r_epik_Ionization_Penalty_Neutral")) epik_State_Penalty = float(oechem.OEGetSDData(sdf_molecule, "r_epik_State_Penalty")) epik_Tot_Q = int(oechem.OEGetSDData(sdf_molecule, "i_epik_Tot_Q")) # Compute number of protons. nprotons = epik_Tot_Q - min_formal_charge + 1 # Compute effective pKa. import numpy as np kT = 298 * 6.022e23 * 1.381e-23 / 4184 # kcal/mol for 298 K pKa = options.pH - epik_State_Penalty / (nprotons * kT * np.log(10)) print "effective pKa = %8.3f" % pKa # DEBUG print "%24s : pKa penalty %8.3f kcal/mol | tautomer penalty %8.3f kcal/mol | total state penalty %8.3f\n" % (name, epik_Ionization_Penalty, epik_State_Penalty - epik_Ionization_Penalty, epik_State_Penalty) # Create a conformer and append it to the list. conformer = Conformer(name, epik_Tot_Q, molecule, state_penalty=epik_State_Penalty) conformers.append(conformer) print epik_Tot_Q # DEBUG # Increment counter. conformer_index += 1 ifs_sdf.close() ifs_mol2.close() if verbose: print "%d protomer/tautomer states were enumerated" % len(conformers) return conformers
def generateResidueTemplate(molecule, residue_atoms=None): """ Generate an residue template for simtk.openmm.app.ForceField using GAFF/AM1-BCC. This requires the OpenEye toolkit. Parameters ---------- molecule : openeye.oechem.OEMol The molecule to be parameterized. The molecule must have explicit hydrogens. Charge will be inferred from the net formal charge. residue_atomset : set of OEAtom, optional, default=None If not None, only the atoms in this set will be used to construct the residue template Returns ------- template : simtk.openmm.app.forcefield._TemplateData Residue template for ForceField using atom types and parameters from `gaff.xml`. additional_parameters_ffxml : str Contents of ForceField `ffxml` file defining additional parameters from parmchk(2). Note that this method preserves stereochemistry during AM1-BCC charge parameterization. """ # Generate a unique residue template name to avoid namespace collisions. # TODO: Can we come up with a more intelligent name? #from uuid import uuid4 #template_name = str(uuid4()) template_name = molecule.GetTitle() # Compute net formal charge. from openeye import oechem oechem.OEAssignFormalCharges(molecule) charges = [ atom.GetFormalCharge() for atom in molecule.GetAtoms() ] net_charge = np.array(charges).sum() # Generate canonical AM1-BCC charges and a reference conformation. molecule = get_charges(molecule, strictStereo=False, keep_confs=1) # Create temporary directory for running antechamber. import tempfile tmpdir = tempfile.mkdtemp() input_mol2_filename = os.path.join(tmpdir, template_name + '.tripos.mol2') gaff_mol2_filename = os.path.join(tmpdir, template_name + '.gaff.mol2') frcmod_filename = os.path.join(tmpdir, template_name + '.frcmod') # Write Tripos mol2 file as antechamber input. ofs = oechem.oemolostream(input_mol2_filename) oechem.OEWriteMolecule(ofs, molecule) ofs.close() # Parameterize the molecule with antechamber. run_antechamber(template_name, input_mol2_filename, charge_method=None, net_charge=net_charge, gaff_mol2_filename=gaff_mol2_filename, frcmod_filename=frcmod_filename) # Read the resulting GAFF mol2 file as a ParmEd structure. ifs = oechem.oemolistream(gaff_mol2_filename) ifs.SetFlavor(oechem.OEFormat_MOL2, oechem.OEIFlavor_MOL2_DEFAULT | oechem.OEIFlavor_MOL2_M2H | oechem.OEIFlavor_MOL2_Forcefield) m2h = True oechem.OEReadMolecule(ifs, molecule) ifs.close() # If residue_atoms = None, add all atoms to the residues if residue_atoms == None: residue_atoms = [ atom for atom in molecule.GetAtoms() ] # Modify partial charges so that charge on residue atoms is integral. residue_charge = 0.0 sum_of_absolute_charge = 0.0 for atom in residue_atoms: charge = atom.GetPartialCharge() residue_charge += charge sum_of_absolute_charge += abs(charge) excess_charge = residue_charge - net_charge if sum_of_absolute_charge == 0.0: sum_of_absolute_charge = 1.0 for atom in residue_atoms: charge = atom.GetPartialCharge() atom.SetPartialCharge( charge + excess_charge * (abs(charge) / sum_of_absolute_charge) ) # Create residue template. template = ForceField._TemplateData(template_name) for (index, atom) in enumerate(molecule.GetAtoms()): atomname = atom.GetName() typename = atom.GetType() element = Element.getByAtomicNumber(atom.GetAtomicNum()) charge = atom.GetPartialCharge() parameters = { 'charge' : charge } atom_template = ForceField._TemplateAtomData(atomname, typename, element, parameters) template.atoms.append(atom_template) for bond in molecule.GetBonds(): if (bond.GetBgn() in residue_atoms) and (bond.GetEnd() in residue_atoms): template.addBondByName(bond.GetBgn().GetName(), bond.GetEnd().GetName()) elif (bond.GetBgn() in residue_atoms) and (bond.GetEnd() not in residue_atoms): template.addExternalBondByName(bond.GetBgn().GetName()) elif (bond.GetBgn() not in residue_atoms) and (bond.GetEnd() in residue_atoms): template.addExternalBondByName(bond.GetEnd().GetName()) # Generate ffxml file contents for parmchk-generated frcmod output. leaprc = StringIO("parm = loadamberparams %s" % frcmod_filename) params = parmed.amber.AmberParameterSet.from_leaprc(leaprc) params = parmed.openmm.OpenMMParameterSet.from_parameterset(params) ffxml = StringIO() params.write(ffxml) return template, ffxml.getvalue()