def get_wbo_growth(fragmenter, fragment_mol, atoms, bonds, target_bond, heuristic): wbos = [] fragments = [] fragment_mol = fragmenter.fragments[target_bond] oechem.OEAddExplicitHydrogens(fragment_mol) try: charged_fragment = chemi.get_charges(fragment_mol, strict_stereo=False, strict_types=False) a1 = charged_fragment.GetAtom(oechem.OEHasMapIdx(target_bond[0])) a2 = charged_fragment.GetAtom(oechem.OEHasMapIdx(target_bond[-1])) bond = charged_fragment.GetBond(a1, a2) wbos.append(bond.GetData('WibergBondOrder')) fragments.append(charged_fragment) except RuntimeError: print('Bad fragment. Continuing to adding the next bond') pass while fragment_mol.GetMaxAtomIdx() < fragmenter.molecule.GetMaxAtomIdx(): atoms, bonds = add_one_bond( molecule=fragmenter.molecule, atoms=atoms, bonds=bonds, functional_groups=fragmenter.functional_groups, ring_systems=fragmenter.ring_systems, target_bond=target_bond, heuristic=heuristic) ab_set = fragmenter._to_atom_bond_set(atoms, bonds) fragment_mol = fragmenter.atom_bond_set_to_mol( ab_set, expand_stereoisomers=False) oechem.OEAddExplicitHydrogens(fragment_mol) try: charged_fragment = chemi.get_charges(fragment_mol, strict_stereo=False, strict_types=False) a1 = charged_fragment.GetAtom(oechem.OEHasMapIdx(target_bond[0])) a2 = charged_fragment.GetAtom(oechem.OEHasMapIdx(target_bond[-1])) bond = charged_fragment.GetBond(a1, a2) fragment_wbo = bond.GetData('WibergBondOrder') wbos.append(fragment_wbo) mol_copy = copy.deepcopy(charged_fragment) fragments.append(mol_copy) except RuntimeError: pass return wbos, fragments
def createOEMolFromSDF(sdf_filename, index=0, add_hydrogens=True): """ # 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 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.OEAddExplicitHydrogens(molecule) oechem.OEPerceiveChiral(molecule) # perceive chirality 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(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]) mmff = oeff.OEMMFF() # Setup adaptor. The first (false) means not to pass ownership of mmff, # and the second (false) means not to exclude interactions related # to the subset which would be fixed for calculations. adaptor = oeff.OETorAdaptor(mmff, False, False) # Use a simple predicate for the subset of torsions to optimize adaptor.Set(oechem.OEIsRotor()) mol = oechem.OEMol() while oechem.OEReadMolecule(ifs, mol): oechem.OEAddExplicitHydrogens(mol) # Use a simple atoms predicate for the subset, followed by setup if (not mmff.PrepMol(mol)) or (not adaptor.Setup(mol)): oechem.OEThrow.Warning("Unable to process molecule: title = '%s'" % mol.GetTitle()) oechem.OEWriteMolecule(ofs, mol) continue vecCoords = oechem.OEDoubleArray(3*mol.GetMaxAtomIdx()) for conf in mol.GetConfs(): oechem.OEThrow.Info("Molecule: %s Conformer: %d" % (mol.GetTitle(), conf.GetIdx()+1)) conf.GetCoords(vecCoords) # Get adaptor variables set corresponding to the coordinates vecX = oechem.OEDoubleArray(adaptor.NumVar()) adaptor.GetVar(vecX, vecCoords) # Calculate energy using adaptor energy = adaptor(vecX) oechem.OEThrow.Info("Initial energy: %d kcal/mol" % energy) # Optimize the adaptor optimizer = oeff.OEBFGSOpt() energy = optimizer(adaptor, vecX, vecX) oechem.OEThrow.Info("Optimized energy: %d kcal/mol" % energy) # Get optimized coordinates corresponding to the adaptor optimized variables adaptor.AdaptVar(vecCoords, vecX) conf.SetCoords(vecCoords) oechem.OEWriteMolecule(ofs, mol) return 0
def sanitizeOEMolecule(molecule): """ This function checks if the molecule has coordinates, explicit hydrogens, aromaticity missing and not unique atom names. If the molecule does not have coordinates a fatal error is raised. If the molecule does not have hydrogens or aramatic flags are missing then a copy of the molecule is fixed, if missing or not unique atom names are found then a copy of the molecule is fixed Parameters: ----------- molecule: OEMol The molecule to be checked Return: ------- mol_copy: OEMol A copy of the checked molecule with fixed aromaticity, hydrogens and unique atom names if they are missing """ mol_copy = oechem.OEMol(molecule) # Check if the molecule has 3D coordinates if not mol_copy.NumAtoms() == 1: # Mono-atomic molecules are skipped if not oechem.OEGetDimensionFromCoords(mol_copy): raise ValueError("The molecule coordinates are set to zero") # Check if the molecule has hydrogens if not oechem.OEHasExplicitHydrogens(mol_copy): oechem.OEAddExplicitHydrogens(mol_copy) # Check if the molecule has assigned aromaticity if not mol_copy.HasPerceived(oechem.OEPerceived_Aromaticity): # oechem.OEAssignAromaticFlags(mol_copy, oechem.OEAroModelOpenEye) oechem.OEAssignAromaticFlags(mol_copy, oechem.OEAroModelMDL) if not mol_copy.HasPerceived(oechem.OEPerceived_Chiral): oechem.OEPerceiveChiral(mol_copy) # Check for any missing and not unique atom names. # If found reassign all of them as Tripos atom names atm_list_names = [] for atom in mol_copy.GetAtoms(): atm_list_names.append(atom.GetName()) reassign_names = False if len(set(atm_list_names)) != len(atm_list_names): reassign_names = True if '' in atm_list_names: reassign_names = True if reassign_names: oechem.OETriposAtomNames(mol_copy) return mol_copy
def get_molecule_torsion_fragments(mol): torgen = TorsionGenerator() tormols = torgen.GetTorsions(mol) ## Add missing hydrogens for tormol in tormols: oechem.OEAddExplicitHydrogens(tormol, False, True) return tormols
def create_molecule_from_smiles(smiles): """ Create an ``OEMol`` molecule from a smiles pattern. .. todo:: Replace with the toolkit function when finished. Parameters ---------- smiles : str Smiles pattern Returns ------- molecule : OEMol OEMol with 3D coordinates, but no charges """ from openeye import oechem, oeomega # Check cache if smiles in _cached_molecules: return copy.deepcopy(_cached_molecules[smiles]) # Create molecule from smiles. molecule = oechem.OEMol() parse_smiles_options = oechem.OEParseSmilesOptions(quiet=True) if not oechem.OEParseSmiles(molecule, smiles, parse_smiles_options): logging.warning('Could not parse SMILES: ' + smiles) return False # Normalize molecule oechem.OEAssignAromaticFlags(molecule, oechem.OEAroModelOpenEye) oechem.OEAddExplicitHydrogens(molecule) # oechem.OETriposAtomNames(molecule) # Create configuration omega = oeomega.OEOmega() omega.SetMaxConfs(1) omega.SetIncludeInput(False) omega.SetCanonOrder(False) omega.SetSampleHydrogens(True) omega.SetStrictStereo(True) omega.SetStrictAtomTypes(False) status = omega(molecule) if not status: logging.warning('Could not generate a conformer for ' + smiles) return False _cached_molecules[smiles] = molecule return molecule
def substructure_search(smi, target_smiles='[!C;!c]-[F,Cl,Br]'): from openeye import oechem ss = oechem.OESubSearch(target_smiles) oemol = oechem.OEGraphMol() oechem.OESmilesToMol(oemol, smi) oechem.OEAddExplicitHydrogens(oemol) oechem.OEPrepareSearch(oemol, ss) return ss.SingleMatch(oemol)
def test_has_stereochemistry(input1, input2, toolkit_name): mol = utils.load_molecule(input1, toolkit_name) if toolkit_name == 'openeye': from openeye import oechem oechem.OEAddExplicitHydrogens(mol) if toolkit_name == 'rdkit': from rdkit import Chem mol = Chem.AddHs(mol) assert utils.has_stereo_defined(mol) == True mol = utils.load_molecule(input2, toolkit_name) if toolkit_name == 'openeye': from openeye import oechem oechem.OEAddExplicitHydrogens(mol) if toolkit_name == 'rdkit': from rdkit import Chem mol = Chem.AddHs(mol) with pytest.warns(UserWarning): utils.has_stereo_defined(mol)
def smiles_to_oemol(smiles, title='MOL', max_confs=1): """ Generate an oemol from a SMILES string Parameters ---------- smiles : str SMILES string of molecule title : str, default 'MOL' title of OEMol molecule max_confs : int, default 1 maximum number of conformers to generate Returns ------- molecule : openeye.oechem.OEMol OEMol object of the molecule """ from openeye import oeomega # Create molecule molecule = oechem.OEMol() oechem.OESmilesToMol(molecule, smiles) # create unique atom names if len([atom.GetName() for atom in molecule.GetAtoms()]) > len( set([atom.GetName() for atom in molecule.GetAtoms()])): # the atom names are not unique molecule = generate_unique_atom_names(molecule) else: pass # Set title. molecule.SetTitle(title) # Assign aromaticity and hydrogens. oechem.OEAssignAromaticFlags(molecule, oechem.OEAroModelOpenEye) oechem.OEAssignHybridization(molecule) oechem.OEAddExplicitHydrogens(molecule) oechem.OEPerceiveChiral(molecule) # Create atom names. oechem.OETriposAtomNames(molecule) oechem.OETriposBondTypeNames(molecule) # perceive chirality before attempting omega geometry proposal assert oechem.OEPerceiveChiral(molecule), f"chirality perception failed" # Assign geometry omega = oeomega.OEOmega() omega.SetMaxConfs(max_confs) omega.SetIncludeInput(False) omega.SetStrictStereo(True) omega(molecule) return molecule
def fastrocs_query(self, qmol, numHits, host): with self.logger("fastrocs_query") as logger: ofs = oechem.oemolostream() ofs.SetFormat(oechem.OEFormat_OEB) ofs.openstring() oechem.OEWriteMolecule(ofs, qmol) bytes = ofs.GetString() s = ServerProxy("http://" + host) data = Binary(bytes) # idx = s.SubmitQuery(data, numHits) dargs = { 'altStarts': 'random', 'tversky': False, 'shapeOnly': False } assert (numHits is not None) assert (data is not None) assert (dargs is not None) idx = s.SubmitQuery(data, numHits, 'oeb', 'oeb', dargs) first = False while True: try: current, total = s.QueryStatus(idx, True) except Fault as e: logger.error((str(e))) return 1 if total == 0: continue if first: # logger.log("%s/%s" % ("current", "total")) first = False # logger.log("%i/%i" % (current, total)) if total <= current: break results = s.QueryResults(idx) ifs = oechem.oemolistream() ifs.openstring(results.data) ifs.SetFormat(oechem.OEFormat_OEB) mols = [] for mol in ifs.GetOEMols(): good_mol = oechem.OEMol(mol) oechem.OEAddExplicitHydrogens(good_mol) oechem.OEClearSDData(good_mol) oeshape.OEDeleteCompressedColorAtoms(good_mol) oeshape.OEClearCachedSelfColor(good_mol) oeshape.OEClearCachedSelfShape(good_mol) oeshape.OERemoveColorAtoms(good_mol) mols.append(good_mol) return mols
def generate_initial_molecule(mol_smiles): """ Generate an oemol with a geometry """ mol = oechem.OEMol() oechem.OESmilesToMol(mol, mol_smiles) oechem.OEAddExplicitHydrogens(mol) omega = oeomega.OEOmega() omega.SetMaxConfs(1) omega(mol) return mol
def test_chiral_bond_exception(smiles, toolkit): """ Test bonds to ignore """ mol = utils.load_molecule(smiles, toolkit) if toolkit == 'openeye': from openeye import oechem oechem.OEAddExplicitHydrogens(mol) if toolkit == 'rdkit': from rdkit import Chem mol = Chem.AddHs(mol) with pytest.warns(UserWarning): utils.has_stereo_defined(mol)
def filter_molecules(input_molstream, output_molstream, allow_repeats=False, allow_warnings=False, max_heavy_atoms=100, remove_smirks=list(), max_metals=0, explicitHs=True, elements=None, check_type=None): """ Takes input file and removes molecules using given criteria then writes a new output file """ errs = oechem.oeosstream() oechem.OEThrow.SetOutputStream(errs) molecule = oechem.OECreateOEGraphMol() smiles = list() count = 0 warnings = 0 smile_count = 0 saved = 0 while oechem.OEReadMolecule(input_molstream, molecule): count += 1 if ("warning" in errs.str().lower()) and not allow_warnings: warnings += 1 errs.clear() continue smi = oechem.OECreateIsoSmiString(molecule) mol_copy = oechem.OEMol(molecule) if explicitHs: oechem.OEAddExplicitHydrogens(mol_copy) new_smile = smi not in smiles if not new_smile: smile_count += 1 if new_smile or allow_repeats: keep = keep_molecule(mol_copy, max_heavy_atoms, remove_smirks, max_metals, elements, check_type) if keep: smiles.append(smi) oechem.OEWriteMolecule(output_molstream, mol_copy) saved += 1 errs.clear() print(f"{count} molecules in input stream") print(f"{warnings} molecules resulted in warnings when parsing") print(f"{smile_count} molecules were had repeated isomeric SMILES") print(f"{saved} molecules saved")
def find_ortho_substituents(frag_smi): from openeye import oechem oemol = oechem.OEGraphMol() oechem.OESmilesToMol(oemol, frag_smi) oechem.OEAddExplicitHydrogens(oemol) ortho = '[!#1]~!@[*;r]~;@[*;r]~!@[!#1]' ss = oechem.OESubSearch(ortho) oechem.OEPrepareSearch(oemol, ss) return ss.SingleMatch(oemol)
def mol2svg(self, mol, svg_file): oechem.OEAssignImplicitHydrogens(mol) oechem.OEAddExplicitHydrogens(mol) oedepict.OEPrepareDepiction(mol) width = 1000 height = 1000 opts = oedepict.OE2DMolDisplayOptions(width, height, oedepict.OEScale_AutoScale) pens = opts.GetDefaultBondPen() pens.SetLineWidth(10) disp = oedepict.OE2DMolDisplay(mol, opts) oedepict.OERenderMolecule(svg_file, disp)
def _docking_internal(receptor: oechem.OEGraphMol, bound_ligand: oechem.OEGraphMol, ligand_string): """ Internal method for docking to a receptor given a bound ligand and ligand to dock to Parameters ---------- receptor: oechem.OEGraphMol, required An oechem receptor to dock to bound_ligand: oechem.OEGraphMol, required The ligand bound to the current receptor pocket docking_ligand: oechem.OEGraphMol, required The ligand to dock. Returns ------- An oechem molecule with coordinates of its docking """ # Create posit config oedocking.OEReceptorSetBoundLigand(receptor, bound_ligand) poser = oedocking.OEHybrid(oedocking.OEDockMethod_Hybrid2, oedocking.OESearchResolution_High) poser.Initialize(receptor) # Create multiple conformations omegaOpts = oeomega.OEOmegaOptions() omegaOpts.SetMaxConfs(1000) omega_driver = oeomega.OEOmega(omegaOpts) conformer_docking = oechem.OEMol() # type: OEMol oechem.OESmilesToMol(conformer_docking, ligand_string) oechem.OEAddExplicitHydrogens(conformer_docking) print(conformer_docking.NumAtoms()) if not omega_driver(conformer_docking): single_sdf = tempfile.NamedTemporaryFile(suffix=".sdf") double_sdf = tempfile.NamedTemporaryFile(suffix=".sdf") smiles = ligand_string subprocess.run( "obabel -:'%s' -O %s --gen3d; obabel %s -O %s --confab --conf = 100" % (smiles, single_sdf.name, single_sdf.name, double_sdf.name), shell=True) ins = oechem.oemolistream() ins.SetConfTest(oechem.OEOmegaConfTest()) ins.open(double_sdf.name) oechem.OEReadMolecule(ins, conformer_docking) # Dock and get top conformer posed_ligand = oechem.OEGraphMol() # type: OEGraphMol poser.DockMultiConformerMolecule(posed_ligand, conformer_docking) return posed_ligand
def from_oemol(self, from_oemol): with self.logger("from_oemol") as logger: tautomer_options = oequacpac.OETautomerOptions() tautomer_options.SetMaxTautomersGenerated(4096) tautomer_options.SetMaxTautomersToReturn(16) tautomer_options.SetCarbonHybridization(True) tautomer_options.SetMaxZoneSize(50) tautomer_options.SetApplyWarts(True) pKa_norm = True omegaOpts = oeomega.OEOmegaOptions(oeomega.OEOmegaSampling_Pose) omegaOpts.SetStrictAtomTypes(False) omegaOpts.SetSampleHydrogens(True) omegaOpts.SetMaxSearchTime(30) omegaOpts.SetFixDeleteH(True) omega = oeomega.OEOmega(omegaOpts) options = oeshape.OEROCSOptions() overlayoptions = oeshape.OEOverlayOptions() overlayoptions.SetOverlapFunc( oeshape.OEOverlapFunc(oeshape.OEAnalyticShapeFunc())) options.SetOverlayOptions(overlayoptions) # options.SetNumBestHits(10) options.SetConfsPerHit(200) # options.SetMaxHits(10000) rocs = oeshape.OEROCS(options) for tautomer in oequacpac.OEGetReasonableTautomers( from_oemol, tautomer_options, pKa_norm): logger.log("got enantiomer") for enantiomer in oeomega.OEFlipper(tautomer, 4, False): logger.log("got tautomer ") enantiomer_ = oechem.OEMol(enantiomer) ret_code = omega.Build(enantiomer_) if ret_code != oeomega.OEOmegaReturnCode_Success: logger.error("got oemeg_failed", oeomega.OEGetOmegaError(ret_code)) else: rocs.AddMolecule(oechem.OEMol(enantiomer_)) for res in rocs.Overlay(self.refmol): outmol = oechem.OEMol(res.GetOverlayConfs()) good_mol = oechem.OEMol(outmol) oechem.OEAddExplicitHydrogens(good_mol) oechem.OEClearSDData(good_mol) oeshape.OEDeleteCompressedColorAtoms(good_mol) oeshape.OEClearCachedSelfColor(good_mol) oeshape.OEClearCachedSelfShape(good_mol) oeshape.OERemoveColorAtoms(good_mol) return good_mol logger.error("Returning None.") return None
def __init__(self, smiles): """ Parameters ---------- smiles: str SMILES string for a molecule """ mol = oechem.OEMol() if not oechem.OESmilesToMol(mol, smiles): raise ValueError('Could not parse SMILES %s' % smiles) oechem.OEAddExplicitHydrogens(mol) Mol.__init__(self, mol)
def _process_mol(mol: oechem.OEMol, explicit_H: Optional[str] = None): if explicit_H == 'all': oechem.OEAddExplicitHydrogens(mol) elif explicit_H == 'polar': oechem.OESuppressHydrogens(mol, explicit_H) elif explicit_H is None: oechem.OESuppressHydrogens(mol) else: raise ValueError oechem.OEAssignAromaticFlags(mol) oechem.OEAssignHybridization(mol) oechem.OEAssignFormalCharges(mol) mol.Sweep()
def _createMolecule(self, iupac_name): """Create molecule from IUPAC name. Best practices for creating initial coordinates can be applied here. Parameters ---------- iupac_name : str IUPAC name Returns ------- molecule : OEMol OEMol with 3D coordinates, but no charges """ # Check cache if iupac_name in self._cached_molecules: return copy.deepcopy(self._cached_molecules[iupac_name]) # Create molecule from IUPAC name. molecule = oechem.OEMol() if not oeiupac.OEParseIUPACName(molecule, iupac_name): raise ValueError( "The supplied IUPAC name '%s' could not be parsed." % iupac_name) # Set molecule name molecule.SetTitle(iupac_name) # Normalize molecule oechem.OEAssignAromaticFlags(molecule, oechem.OEAroModelOpenEye) oechem.OEAddExplicitHydrogens(molecule) oechem.OETriposAtomNames(molecule) # Create configuration omega = oeomega.OEOmega() omega.SetMaxConfs(1) omega.SetIncludeInput(False) omega.SetCanonOrder(False) omega.SetSampleHydrogens(True) omega.SetStrictStereo(True) omega.SetStrictAtomTypes(False) status = omega(molecule) if not status: raise (RuntimeError("omega returned error code %d" % status)) # Cache molecule self._cached_molecules[iupac_name] = molecule return molecule
def run_create_mol2_pdb(**kwargs): nmol = kwargs['nmol'] input_txt = kwargs['input'] resname = kwargs['resname'] density = kwargs['density'] tries = kwargs['tries'] # Disable Gromacs backup file creation os.environ['GMX_MAXBACKUP'] = "-1" smiles_string = open(input_txt).readlines()[0].strip() print("The following SMILES string will be converted: %s" % smiles_string) # create a new molecule oemol = oechem.OEGraphMol() # convert the SMILES string into a molecule if oechem.OESmilesToMol(oemol, smiles_string): # do something interesting with mol pass else: print("SMILES string was invalid!") # Add explicit oechem.OEAddExplicitHydrogens(oemol) # Generate a single conformer oemol = openmoltools.openeye.generate_conformers(oemol, max_confs=1) # Modify residue names oechem.OEPerceiveResidues(oemol, oechem.OEPreserveResInfo_All) for atom in oemol.GetAtoms(): thisRes = oechem.OEAtomGetResidue(atom) thisRes.SetName(resname) # Write output files ofs = oechem.oemolostream() output_fnms = ['%s.mol2' % resname, '%s.pdb' % resname] for output_fnm in output_fnms: if not ofs.open(output_fnm): oechem.OEThrow.Fatal("Unable to create %s" % output_fnm) oechem.OEWriteMolecule(ofs, oemol) print("-=# Output #=- Created %s containing single molecule" % output_fnm) grams_per_mole = CalculateMolecularWeight(oemol) boxlen = CalculateBoxSize(nmol, grams_per_mole, density) GenerateBox('%s.pdb' % resname, '%s-box.pdb' % resname, boxlen, nmol, tries)
def generate_initial_molecule(iupac_name): """ Generate an oemol with a geometry """ mol = oechem.OEMol() oeiupac.OEParseIUPACName(mol, iupac_name) oechem.OEAddExplicitHydrogens(mol) oechem.OETriposAtomNames(mol) oechem.OETriposBondTypeNames(mol) omega = oeomega.OEOmega() omega.SetStrictStereo(False) omega.SetMaxConfs(1) omega(mol) return mol
def calculate_t142_central_wbo(mol: oechem.OEMol, params: Dict[str, List[List[int]]]) -> float: """Calculates the WBO between the central atoms in the t142 param in the molecule. (WBO is Wiberg Bond Order.) The `params` argument contains the parameters of the molecule (see `calculate_mol_params`). Returns -1 if the calculation fails. """ # Only use first occurrence of the parameter. indices = params['t142'][0] # For torsion parameters such as t142, the central atoms should be at the # second and third index. central_indices = [indices[1], indices[2]] # Generate molecule conformer. oechem.OEAddExplicitHydrogens(mol) omega = oeomega.OEOmega() omega.SetMaxConfs(1) omega.SetCanonOrder(False) omega.SetSampleHydrogens(True) omega.SetEnergyWindow(15.0) #unit? omega.SetRMSThreshold(1.0) # Don't generate random stereoisomer if not specified. omega.SetStrictStereo(True) status = omega(mol) if status is False: omega.SetStrictStereo(False) new_status = omega(mol) if new_status is False: logger.error("Failed to generate conformer for %s", oechem.OEMolToSmiles(mol)) return -1 # Calculate the WBO between the two central atoms. conf = next(iter(mol.GetConfs())) charged_copy = oechem.OEMol(conf) results = oequacpac.OEAM1Results() if not AM1_CALCULATOR.CalcAM1(results, charged_copy): logger.error("Failed to assign partial charges to %s", oechem.OEMolToSmiles(mol)) return -2 return results.GetBondOrder(central_indices[0], central_indices[1])
def ammonia_fake() -> (oechem.OEMol, oechem.OEAtomBase): """ Creates an ammonia molecule with fake Wiberg bond orders. Also returns the trivalent nitrogen in the molecule """ ammonia = oechem.OEMol() oechem.OESmilesToMol(ammonia, "N") oechem.OEAddExplicitHydrogens(ammonia) fake_wbo = [1.01, 1.03, 1.05] for i, bond in enumerate(ammonia.GetBonds()): bond.SetData(danceprops.DANCE_BOND_ORDER_KEY, fake_wbo[i]) for atom in ammonia.GetAtoms(oechem.OEIsInvertibleNitrogen()): tri_n = atom return ammonia, tri_n
def read_split_mols(filename): ifs = oechem.oemolistream() # open input file that contains many molecules ifs.open(filename) # get all molecules from sdf file mol_list = [] for mol in ifs.GetOEMols(): # explicit declaring oechem.OEGraphMol is needed oe_mol = oechem.OEMol(mol) # add explicit hydrogens oechem.OEAddExplicitHydrogens(oe_mol) mol_list.append(oe_mol) ifs.close() print(f"Loaded {len(mol_list)} molecules") return mol_list
def size_and_wbo_fingerprint(mol: oechem.OEMol): """Fingerprint with number of atoms in the mol and WBO between central atoms in the t142 param. (WBO is Wiberg Bond Order.) Note: The indices are the same in OpenEye and OFF molecules, so the parameter indices are correct, even though they were calculated for the OFF mol. """ oechem.OEAddExplicitHydrogens(mol) params = smirnoff_param_utils.read_params_from_mol(mol) return ( mol.NumAtoms(), smirnoff_param_utils.calculate_t142_central_wbo(mol, params), )
def _openeye_setter(cls, smiles, **kwargs): """ Prepares an openeye molecule with 3D coordinates. Parameters ------------ smiles : str SMILES string of the solute moleulce Returns --------- mol : oechem.OEMol """ from openeye import oechem # OpenEye Python toolkits from openeye import oeomega # Omega toolkit # from openeye import oequacpac #Charge toolkit cls.smiles = smiles cls.omega = oeomega.OEOmega() # modified in accordance to recommendation on omega example script: https://docs.eyesopen.com/toolkits/cookbook/python/modeling/am1-bcc.html # reduced the default total number of confs from 800 to 100 to save execution time eWindow = 15.0 cls.omega.SetEnergyWindow(eWindow) if "openeye_maxconf" in kwargs and type( kwargs["openeye_maxconf"] ) is int and kwargs["openeye_maxconf"] > 0: cls.omega.SetMaxConfs(kwargs["openeye_maxconf"]) else: cls.omega.SetMaxConfs(100) cls.omega.SetRMSThreshold(1.0) cls.omega.SetIncludeInput(False) cls.omega.SetStrictStereo( False ) #Refuse to generate conformers if stereochemistry not provided # cls.charge_engine = oequacpac.OEAM1BCCCharges() mol = oechem.OEMol() oechem.OESmilesToMol(mol, smiles) oechem.OEAddExplicitHydrogens(mol) oechem.OETriposAtomNames(mol) # Generate conformers with Omega; keep only best conformer status = cls.omega(mol) if not status: raise ValueError("Error generating conformers for %s." % (cls.smiles)) #TODO return mol
def generate_OE_molecule(mol_smiles): """ Generate an oemol with a geometry """ import openeye.oechem as oechem import openeye.oeomega as oeomega mol = oechem.OEMol() oechem.OESmilesToMol(mol, mol_smiles) mol.SetTitle("MOL") oechem.OEAddExplicitHydrogens(mol) oechem.OETriposAtomNames(mol) oechem.OETriposBondTypeNames(mol) omega = oeomega.OEOmega() omega.SetMaxConfs(1) omega(mol) return mol
def call_opt(infile, outfile): ifs = oechem.oemolistream() if not ifs.open(infile): oechem.OEThrow.Warning("Unable to open %s for reading" % smiles) ofs = oechem.oemolostream() if not ofs.open(outfile): oechem.OEThrow.Fatal("Unable to open %s for writing" % outfile) for mol in ifs.GetOEMols(): oechem.OETriposAtomNames(mol) oechem.OEAddExplicitHydrogens(mol) initialize_confs.quick_opt(mol) oechem.OEWriteConstMolecule(ofs, mol) call_writer(mol) return mol
def test_MDL_aromaticity(verbose=False): """Test support for alternate aromaticity models.""" ffxml = StringIO(ffxml_MDL_contents) ff = ForceField(ffxml) from openeye import oechem mol = oechem.OEMol() oechem.OEParseSmiles(mol, 'c12c(cccc1)occ2') oechem.OEAddExplicitHydrogens(mol) labels = ff.labelMolecules([mol], verbose=True) # The bond 6-7 should get the b16 parameter iff the MDL model is working, otherwise it will pick up just the generic details = labels[0]['HarmonicBondGenerator'] found = False for (atom_indices, pid, smirks) in details: if pid == 'b16' and atom_indices == [6, 7]: found = True if not found: raise Exception("Didn't find right param.")