def prep_structure(rdmol): mb = Chem.MolToMolBlock(rdmol) ims = oechem.oemolistream() ims.SetFormat(oechem.OEFormat_SDF) ims.openstring(mb) for buf_mol in ims.GetOEMols(): oemol = oechem.OEMol(buf_mol) omega = oeomega.OEOmega() # omega.SetIncludeInput(True) omega.SetMaxSearchTime(30) omega.SetCanonOrder(False) omega.SetSampleHydrogens(True) eWindow = 15.0 omega.SetEnergyWindow(eWindow) # omega.SetMaxConfs(800) omega.SetMaxConfs(400) omega.SetRMSThreshold(1.0) if omega(oemol): result = oequacpac.OEAssignCharges(oemol, oequacpac.OEAM1BCCELF10Charges()) if result is False: return None else: charges = [] for index, atom in enumerate(oemol.GetAtoms()): q = atom.GetPartialCharge() * np.sqrt(ONE_4PI_EPS0) charges.append(q) return charges else: return None
def static_parameterize(mol): """ Parameters ---------- mol: Chem.ROMol molecule to be parameterized. """ # imported here for optional dependency from openeye import oechem from openeye import oequacpac mb = Chem.MolToMolBlock(mol) ims = oechem.oemolistream() ims.SetFormat(oechem.OEFormat_SDF) ims.openstring(mb) for buf_mol in ims.GetOEMols(): oemol = oechem.OEMol(buf_mol) result = oequacpac.OEAssignCharges(oemol, oequacpac.OEAM1BCCELF10Charges()) if result is False: raise Exception('Unable to assign charges') charges = [] for index, atom in enumerate(oemol.GetAtoms()): q = atom.GetPartialCharge() * np.sqrt(constants.ONE_4PI_EPS0) charges.append(q) return np.array(charges)
def oe_assign_charges(mol, charge_model="AM1BCCELF10"): """assign partial charges, then premultiply by sqrt(ONE_4PI_EPS0) as an optimization""" # imported here for optional dependency from openeye import oequacpac charge_engines = { "AM1": oequacpac.OEAM1Charges(symmetrize=True), "AM1BCC": oequacpac.OEAM1BCCCharges(symmetrize=True), "AM1BCCELF10": oequacpac.OEAM1BCCELF10Charges(), } charge_engine = charge_engines[charge_model] oemol = convert_to_oe(mol) result = oequacpac.OEAssignCharges(oemol, charge_engine) if result is False: raise Exception("Unable to assign charges") partial_charges = np.array( [atom.GetPartialCharge() for atom in oemol.GetAtoms()]) # https://github.com/proteneer/timemachine#forcefield-gotchas # "The charges have been multiplied by sqrt(ONE_4PI_EPS0) as an optimization." inlined_constant = np.sqrt(constants.ONE_4PI_EPS0) return inlined_constant * partial_charges
def prep_structure(rdmol): oemol = convert_to_oe(rdmol) omega = oeomega.OEOmega() # omega.SetIncludeInput(True) omega.SetMaxSearchTime(30) omega.SetCanonOrder(False) omega.SetSampleHydrogens(True) eWindow = 15.0 omega.SetEnergyWindow(eWindow) # omega.SetMaxConfs(800) omega.SetMaxConfs(400) omega.SetRMSThreshold(1.0) if omega(oemol): result = oequacpac.OEAssignCharges(oemol, oequacpac.OEAM1BCCELF10Charges()) if result is False: return None else: charges = [] for index, atom in enumerate(oemol.GetAtoms()): q = atom.GetPartialCharge() * np.sqrt(ONE_4PI_EPS0) charges.append(q) return charges else: return None
def charge_mols(infile, outfile, reffile=None): ### Read in molecules ifs = oechem.oemolistream() if not ifs.open(infile): oechem.OEThrow.Warning("Unable to open %s for reading" % infile) return ### Open output file ofs = oechem.oemolostream() if not ofs.open(outfile): oechem.OEThrow.Fatal("Unable to open %s for writing" % outfile) ### Charge the molecules and write output if reffile is None: for mol in ifs.GetOEMols(): if not oequacpac.OEAssignCharges(mol, oequacpac.OEAM1BCCELF10Charges()): oechem.OEThrow.Warning("Unable to charge mol {}".format( mol.GetTitle())) oechem.OEWriteConstMolecule(ofs, mol) ifs.close() ofs.close() else: ### Read in molecules rfs = oechem.oemolistream() if not rfs.open(reffile): oechem.OEThrow.Warning("Unable to open %s for reading" % reffile) return ### Set coordinates of desired molecule on the mol with charges for in_mol, ref_mol in zip(ifs.GetOEMols(), rfs.GetOEMols()): ref_mol.SetCoords(in_mol.GetCoords()) oechem.OEWriteConstMolecule(ofs, ref_mol) ifs.close() ofs.close()
def charge_mol(mol, omega): """Generate conformers and assign AM1BCCELF10 charges to mol""" if omega(mol): #black box function to assign charges to a molecule oequacpac.OEAssignCharges(mol, oequacpac.OEAM1BCCELF10Charges()) else: print("Failed to generate conformation(s) for molecule %s" % mol.GetTitle())
def AssignChargesByName(mol, name): if name == "noop": return oequacpac.OEAssignCharges(mol, oequacpac.OEChargeEngineNoOp()) elif name == "mmff" or name == "mmff94": return oequacpac.OEAssignCharges(mol, oequacpac.OEMMFF94Charges()) elif name == "am1bcc": return oequacpac.OEAssignCharges(mol, oequacpac.OEAM1BCCCharges()) elif name == "am1bccnosymspt": optimize = True symmetrize = True return oequacpac.OEAssignCharges( mol, oequacpac.OEAM1BCCCharges(not optimize, not symmetrize)) elif name == "amber" or name == "amberff94": return oequacpac.OEAssignCharges(mol, oequacpac.OEAmberFF94Charges()) elif name == "am1bccelf10": return oequacpac.OEAssignCharges(mol, oequacpac.OEAM1BCCELF10Charges()) return False
def assignELF10charges(molecule, max_confs=800, strictStereo=True): """ This function computes atomic partial charges for an OEMol by using the ELF10 method Parameters: ----------- molecule : OEMol object The molecule that needs to be charged max_confs : integer The max number of conformers used to calculate the atomic partial charges strictStereo : bool a flag used to check if atoms need to have assigned stereo chemistry or not Return: ------- mol_copy : OEMol a copy of the original molecule with assigned atomic partial charges """ mol_copy = molecule.CreateCopy() # The passed molecule could have already conformers. If the conformer number # does not exceed the max_conf threshold then max_confs conformations will # be generated if not mol_copy.GetMaxConfIdx() > 200: # Generate up to max_confs conformers mol_copy = generate_conformers(mol_copy, max_confs=max_confs, strictStereo=strictStereo) # Assign MMFF Atom types if not oechem.OEMMFFAtomTypes(mol_copy): raise RuntimeError("MMFF atom type assignment returned errors") # ELF10 charges status = oequacpac.OEAssignCharges(mol_copy, oequacpac.OEAM1BCCELF10Charges()) if not status: raise RuntimeError("OEAssignCharges returned error code %d" % status) return mol_copy
omega.SetStrictStereo(False) omega.SetStrictAtomTypes(False) omega.SetSampleHydrogens( True ) # Word to the wise: skipping this step can lead to significantly different charges! omega.SetEnergyWindow(15.0) omega.SetRMSThreshold( 1.0 ) # Word to the wise: skipping this step can lead to significantly different charges! if omega(mol_multiconf): # generate conformation # Generate am1bcc partial charges 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
def hybrid_docking(receptor_path, molecules_path, docked_molecules_path, n_poses=10): """Automated hybrid docking of small molecules to a receptor. Parameters ---------- receptor_path : str Path to PDB file containing receptor and reference ligand, or pre-prepared receptor for docking molecules_path : str Path to file containing one or more molecules (in OpenEye readable format) to be docked. (For example, list of SMILES) docked_molecules_path : str Path to output file to be created to contain docked molecules Uses OpenEye recognized file extension, such as .mol2 or .sdf n_poses : int, optional, default=1 Number of docked poses to generate receptor_filename : str, optional, default=None If not None, the pre-prepared receptor is loaded TODO: How can this API be improved? """ from .docking import create_receptor, load_receptor, pose_molecule from openeye import oedocking, oechem #import openmoltools as moltools # TODO: Bring these methods into this module # Try to load pre-prepared receptor from specified file receptor = oechem.OEGraphMol() print('Attempting to load receptor from {}...'.format(receptor_path)) if not oedocking.OEReadReceptorFile(receptor, receptor_path): # Load complex of receptor and reference ligand complex_istream = oechem.oemolistream(receptor_path) complex = oechem.OEGraphMol() oechem.OEReadMolecule(complex_istream, complex) # Attempt to split into components and build receptor based on reference ligand print('Attempting to split complex into components...') ligand = oechem.OEGraphMol() protein = oechem.OEGraphMol() water = oechem.OEGraphMol() other = oechem.OEGraphMol() if oechem.OESplitMolComplex(ligand, protein, water, other, complex): # Create receptor using bound ligand reference print('Creating receptor using reference ligand...') oedocking.OEMakeReceptor(receptor, protein, ligand) # TODO: We can store prepared receptor file if desired oedocking.OEWriteReceptorFile( receptor, '/home/guoj1/projects/INSPIRE/kinomodel/kinomodel/data/docking/prepared_receptor.oeb' ) else: raise Exception( 'Could not split specified PDB file {} into receptor and reference ligand' .format(receptor_path)) # Open file for writing docked molecules docked_molecules_ostream = oechem.oemolostream(docked_molecules_path) # Configure omega # From canonical recipe: https://docs.eyesopen.com/toolkits/cookbook/python/modeling/am1-bcc.html from openeye import oeomega omega = oeomega.OEOmega() omega.SetIncludeInput(False) omega.SetCanonOrder(False) omega.SetSampleHydrogens(True) eWindow = 15.0 omega.SetEnergyWindow(eWindow) omega.SetMaxConfs(800) omega.SetRMSThreshold(1.0) # Dock all molecules requested dock_method = oedocking.OEDockMethod_Hybrid2 dock_resolution = oedocking.OESearchResolution_Standard dock = oedocking.OEDock(dock_method, dock_resolution) dock.Initialize(receptor) molecules_istream = oechem.oemolistream(molecules_path) molecule = oechem.OEGraphMol() for molecule in molecules_istream.GetOEMols(): print("docking", molecule.GetTitle()) #docked_molecules = pose_molecule(receptor, molecule, n_poses=n_poses) #molecule = moltools.openeye.get_charges(molecule, keep_confs=10) # Generate conformers if not omega(molecule): continue # Apply charges from openeye import oequacpac oequacpac.OEAssignCharges(molecule, oequacpac.OEAM1BCCELF10Charges()) # Dock docked_molecule = oechem.OEGraphMol() dock.DockMultiConformerMolecule(docked_molecule, molecule) sdtag = oedocking.OEDockMethodGetName(dock_method) oedocking.OESetSDScore(docked_molecule, dock, sdtag) dock.AnnotatePose(docked_molecule) oechem.OEWriteMolecule(docked_molecules_ostream, docked_molecule)