def main(argv=[__name__]): itf = oechem.OEInterface(InterfaceData, argv) isomeric = itf.GetBool("-isomeric") kekule = itf.GetBool("-kekule") from3d = itf.GetBool("-from3d") if from3d: isomeric = True ifs = oechem.oemolistream() ifile = itf.GetString("-i") if not ifs.open(ifile): oechem.OEThrow.Fatal("Unable to open %s for reading" % ifile) if itf.HasString("-o"): ofile = itf.GetString("-o") try: ofs = open(ofile, 'w') except Exception: oechem.OEThrow.Fatal("Unable to open %s for writing" % ofile) else: ofs = sys.stdout mol = oechem.OEGraphMol() while oechem.OEReadMolecule(ifs, mol): if from3d: oechem.OE3DToInternalStereo(mol) smi = CanSmi(mol, isomeric, kekule) if mol.GetTitle(): smi += (" %s" % mol.GetTitle()) ofs.write("%s\n" % smi)
def createOEMolFromSDF(sdf_filename, index=0, add_hydrogens=True, allow_undefined_stereo=False): """ # TODO change this to return a list of all the mols if required Load an SDF file into an OEMol. Since SDF files can contain multiple molecules, an index can be provided as well. Parameters ---------- sdf_filename : str The name of the SDF file index : int, default 0 The index of the molecule in the SDF file allow_undefined_stereo : bool, default=False wether to skip stereo perception Returns ------- mol : openeye.oechem.OEMol object The loaded oemol object """ # TODO this needs a test ifs = oechem.oemolistream() ifs.open(sdf_filename) # get the list of molecules mol_list = [oechem.OEMol(mol) for mol in ifs.GetOEMols()] # we'll always take the first for now # pick out molecule of interest molecule = mol_list[index] # Generate unique atom names if len([atom.GetName() for atom in molecule.GetAtoms()]) > len( set([atom.GetName() for atom in molecule.GetAtoms()])): molecule = generate_unique_atom_names(molecule) # Assign aromaticity and hydrogens. oechem.OEAssignAromaticFlags(molecule, oechem.OEAroModelOpenEye) oechem.OEAssignHybridization(molecule) if add_hydrogens: oechem.OEAddExplicitHydrogens(molecule) oechem.OEPerceiveChiral(molecule) # perceive chirality if not allow_undefined_stereo: assert oechem.OE3DToInternalStereo( molecule ), f"the stereochemistry perception from 3D coordinates failed" assert not has_undefined_stereocenters( molecule), f"there is an atom with an undefined stereochemistry" return molecule
def main(infile): # open multi-molecule, multi-conformer file ifs = oechem.oemolistream() ifs.SetConfTest(oechem.OEAbsCanonicalConfTest()) if not ifs.open(infile): raise FileNotFoundError(f"Unable to open {infile} for reading") mols = ifs.GetOEMols() for i, mol in enumerate(mols): # perceive stereochemistry for mol oechem.OEPerceiveChiral(mol) oechem.OEAssignAromaticFlags(mol, oechem.OEAroModel_MDL) # assign charges to copy of mol # note that chg_mol does NOT have conformers try: chg_mol = charge_mol(mol) except RuntimeError: # perceive stereochem #find_unspecified_stereochem(mol) oechem.OE3DToInternalStereo(mol) # reset perceived and call OE3DToBondStereo, since it may be missed # by OE3DToInternalStereo if it thinks mol is flat mol.ResetPerceived() oechem.OE3DToBondStereo(mol) try: chg_mol = charge_mol(mol) print(f'fixed stereo: {mol.GetTitle()}') except RuntimeError: find_unspecified_stereochem(mol) title = mol.GetTitle() smilabel = oechem.OEGetSDData(mol, "SMILES QCArchive") print(' >>> Charge assignment failed due to unspecified ' f'stereochemistry {title} {smilabel}') continue
def main(infile, ffxml): # open multi-molecule, multi-conformer file ifs = oechem.oemolistream() ifs.SetConfTest(oechem.OEAbsCanonicalConfTest()) if not ifs.open(infile): raise FileNotFoundError(f"Unable to open {infile} for reading") mols = ifs.GetOEMols() for i, mol in enumerate(mols): # perceive stereochemistry for mol oechem.OEPerceiveChiral(mol) oechem.OEAssignAromaticFlags(mol, oechem.OEAroModel_MDL) for j, conf in enumerate(mol.GetConfs()): # perceive sterochemistry for conf coordinates oechem.OE3DToInternalStereo(conf) min_ffxml(conf, ffxml)
def main(infile, outfile, ffxml, minimizer): # open multi-molecule, multi-conformer file ifs = oechem.oemolistream() ifs.SetConfTest(oechem.OEAbsCanonicalConfTest()) if not ifs.open(infile): raise FileNotFoundError(f"Unable to open {infile} for reading") mols = ifs.GetOEMols() # open an outstream file ofs = oechem.oemolostream() if os.path.exists(outfile): raise FileExistsError("Output file {} already exists in {}".format( outfile, os.getcwd())) if not ofs.open(outfile): oechem.OEThrow.Fatal("Unable to open %s for writing" % outfile) # minimize with openforcefield ffxml file for i, mol in enumerate(mols): # perceive stereochemistry for mol oechem.OEPerceiveChiral(mol) oechem.OEAssignAromaticFlags(mol, oechem.OEAroModel_MDL) # assign charges to copy of mol # note that chg_mol does NOT have conformers try: chg_mol = charge_mol(mol) except RuntimeError: # perceive stereochem #find_unspecified_stereochem(mol) oechem.OE3DToInternalStereo(mol) # reset perceived and call OE3DToBondStereo, since it may be missed # by OE3DToInternalStereo if it thinks mol is flat mol.ResetPerceived() oechem.OE3DToBondStereo(mol) try: chg_mol = charge_mol(mol) print(f'fixed stereo: {mol.GetTitle()}') except RuntimeError: title = mol.GetTitle() smilabel = oechem.OEGetSDData(mol, "SMILES QCArchive") print(' >>> Charge assignment failed due to unspecified ' f'stereochemistry {title} {smilabel}') continue for j, conf in enumerate(mol.GetConfs()): # perceive sterochemistry for conf coordinates oechem.OE3DToInternalStereo(conf) # assign charges to the conf itself chg_conf = charge_conf(chg_mol, conf) if minimizer == 'ffxml': # minimize with parsley (charges set by ff not used from conf) min_ffxml(chg_conf, ofs, ffxml) if minimizer == 'mmff94': # minimize with mmff94 min_mmff94x(chg_conf, ofs, mmff94s=False) if minimizer == 'mmff94s': # minimize with mmff94S min_mmff94x(chg_conf, ofs, mmff94s=True) if minimizer == 'gaff': # minimize with gaff min_gaffx(chg_conf, ofs, gaff2=False) if minimizer == 'gaff2': # minimize with gaff2 min_gaffx(chg_conf, ofs, gaff2=True) ifs.close() ofs.close()
def getscores(self, actions, gsmis, prot, lig, num_returns=10, return_docked_pose=False, refmol=None): with self.logger("getscores") as logger: if num_returns <= 0: num_returns = len(actions) - 1 logger.log("Action space is ", len(actions)) idxs = list( np.random.choice(len(actions), min(num_returns, len(actions) - 1), replace=False).flatten()) actions = [actions[idx] for idx in idxs] gsmis = [gsmis[idx] for idx in idxs] protein = oechem.OEMol(prot) receptor = oechem.OEGraphMol() if not (self.sort == 'iscores' and self.optimize): logger.log( "Creating receptor from recent pdb, this might take awhile" ) oedocking.OEMakeReceptor(receptor, protein, lig) dockobj = oedocking.OEDock(self.dockmethod) dockobj.Initialize(receptor) assert (dockobj.IsInitialized()) logger.log("done") else: dockobj = None logger.log( "Skipping receptor building as optimize is set and sort method is iscore." ) pscores = [] dscores = [] ds_old_scores = [] ds_start_scores = [] data = [] with multiprocessing.Pool() as p: imapiter = p.imap( self.env.action.aligner.__class__.call_static, zip(actions, gsmis, [copy.deepcopy(refmol)] * len(actions))) for idx, res in enumerate(imapiter): try: if res is None: logger.error( "Alignment failed and returned none for ", gsmis[idx]) continue ps, ds, ds_start, ds_old = None, None, None, [] new_mol, new_mol2, gs, action = res if dockobj is not None: dockedpose = oechem.OEMol() newmol2 = oechem.OEMol(new_mol) dockobj.DockMultiConformerMolecule( dockedpose, newmol2, 1) ds = dockedpose.GetEnergy() ps = dockobj.ScoreLigand(new_mol) dscores.append(ds) pscores.append(ps) if return_docked_pose: new_mol_ = oechem.OEMol(dockedpose) if self.start_dobj is not None: dockedpose2 = oechem.OEMol() newmol2 = oechem.OEMol(new_mol) self.start_dobj.DockMultiConformerMolecule( dockedpose2, newmol2, 1) ds_start = dockedpose2.GetEnergy() ds_start_scores.append(ds_start) if self.track_hscores: for olddobj in self.past_dockobjs: dockedpose2 = oechem.OEMol() newmol2 = oechem.OEMol(new_mol) olddobj.DockMultiConformerMolecule( dockedpose2, newmol2, 1) ds_old.append(dockedpose2.GetEnergy()) ds_old_scores.append(ds_old) if dockobj is not None and return_docked_pose: new_mol = new_mol_ oechem.OEAssignAromaticFlags(new_mol) oechem.OEAddExplicitHydrogens(new_mol) oechem.OE3DToInternalStereo(new_mol) new_mol2 = oechem.OEMol(new_mol) gs = oechem.OECreateSmiString( new_mol, oechem.OESMILESFlag_DEFAULT | oechem.OESMILESFlag_Hydrogens | oechem.OESMILESFlag_Isotopes | oechem.OESMILESFlag_BondStereo | oechem.OESMILESFlag_AtomStereo) logger.log( f"(idx / {len(idxs)}: Pose Score {ps}, Dock Score {ds}, Init Score {ds_start}" ) data.append((new_mol, new_mol2, gs, action)) except Exception as p: logger.error(p) traceback.print_tb(p.__traceback__) continue self.past_dockobjs.append(dockobj) self.past_receptors.append(receptor) logger.log("Sorting on", self.sort) if self.sort == 'dscores': order = np.argsort(dscores) logger.log([dscores[i] for i in order]) elif self.sort == 'pscores': order = np.argsort(pscores) logger.log([pscores[i] for i in order]) elif self.sort == 'iscores': order = np.argsort(ds_start_scores) logger.log([ds_start_scores[i] for i in order]) elif self.sort == 'hscores': hscores = [ np.quantile(np.clip(scoreset, None, 0), 0.) for scoreset in ds_old_scores ] order = np.argsort(hscores) logger.log([hscores[i] for i in order]) else: assert (False) self.env.data['dscores'].append(dscores) self.env.data['pscores'].append(pscores) self.env.data['iscores'].append(ds_start_scores) self.env.data['hscores'].append(ds_old_scores) data = [data[i] for i in order] return data