def set_aromaticity_mdl(self): """ Sets the aromaticity flags in this molecule to use the MDL model """ oechem.OEClearAromaticFlags(self.mol) oechem.OEAssignAromaticFlags(self.mol, oechem.OEAroModel_MDL) oechem.OEAssignHybridization(self.mol)
def createOEMolFromSDF(sdf_filename, index=0): """ 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 # Assign aromaticity and hydrogens. for molecule in mol_list: oechem.OEAssignAromaticFlags(molecule, oechem.OEAroModelOpenEye) oechem.OEAssignHybridization(molecule) oechem.OEAddExplicitHydrogens(molecule) mol_to_return = mol_list[index] return mol_to_return
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 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 _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 get_sf_elements(mol): sfObj = SymmetryFunction() oechem.OEAssignFormalCharges(mol) oechem.OEAssignHybridization(mol) rsf, asf = sfObj.CalculateSymmetryFunction(mol) tsf1 = sfObj.CalculateTorsionSymmetryFunction(mol, 1) tsf2 = sfObj.CalculateTorsionSymmetryFunction(mol, 2) tsf = [] for elem1, elem2 in zip(tsf1, tsf2): tsf.append(elem1 + elem2) sf_elements = rsf sf_elements.extend(asf) sf_elements.extend(tsf) return sf_elements
def generate_initial_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") # Assign aromaticity and hydrogens and hybridization. oechem.OEAddExplicitHydrogens(mol) oechem.OEAssignAromaticFlags(mol, oechem.OEAroModelOpenEye) oechem.OEAssignHybridization(mol) oechem.OETriposAtomNames(mol) oechem.OETriposBondTypeNames(mol) omega = oeomega.OEOmega() omega.SetMaxConfs(1) omega(mol) return mol
def iupac_to_oemol(iupac, title='MOL', max_confs=1): """ Generate an oemol from an IUPAC name Parameters ---------- iupac : str iupac name 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 oeiupac, oeomega # Create molecule molecule = oechem.OEMol() oeiupac.OEParseIUPACName(molecule, iupac) # 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) # Assign geometry omega = oeomega.OEOmega() omega.SetMaxConfs(max_confs) omega.SetIncludeInput(False) omega.SetStrictStereo(True) omega(molecule) return molecule
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 oeiupac, oeomega # Create molecule molecule = oechem.OEMol() oechem.OESmilesToMol(molecule, smiles) # Set title. molecule.SetTitle(title) # Assign aromaticity and hydrogens. oechem.OEAssignAromaticFlags(molecule, oechem.OEAroModelOpenEye) oechem.OEAssignHybridization(molecule) oechem.OEAddExplicitHydrogens(molecule) # Create atom names. oechem.OETriposAtomNames(molecule) # Assign geometry omega = oeomega.OEOmega() omega.SetMaxConfs(max_confs) omega.SetIncludeInput(False) omega.SetStrictStereo(True) omega(molecule) return molecule
def addCoordFiles(self, *coordFiles): # print(f'\n\033[1m Read Coordinate files... \033[0m') if len(coordFiles) == 0: print( 'Skip this molecule? Empty molecule object will be created since no conformers is provided.' ) self.mols.append(oechem.OEMol()) self.atomids.append([]) self.elems.append([]) self.resnames.append([]) self.atomnames.append([]) self.resnumbers.append([]) self.listofpolars.append([]) self.listofburieds.append([]) xyzs = [] self.nmols.append(len(xyzs)) indices = [] charge = 0 number = len(self.elems) resname = 'mol%d' % (number) chargeinfo = [[indices, resname, charge]] self.listofchargeinfo.append(chargeinfo) else: xyzs = [] listofoemol = [] firstconf = True for coordFile in coordFiles: fbmol = Molecule(coordFile) xyz = fbmol.xyzs[0] xyz = np.array(xyz) / bohr2Ang xyzs.append(xyz) # Making oemol using openeye toolkit : for atomID(?), equivGroup and listofpolar ifs = oechem.oemolistream(coordFile) oemol = oechem.OEGraphMol() oechem.OEReadMolecule(ifs, oemol) listofoemol.append(oemol) oechem.OEPerceiveSymmetry(oemol) if firstconf == True: firstconf = False atomicNum = [] elem = fbmol.elem if 'resid' not in list(fbmol.Data.keys()): print( ' - Are you using xyz file? Default resid, resname, atomname will be assigned.' ) resnumber = [1 for i in elem] resname = list('MOL' for i in elem) atomname = [ '%s%d' % (i, idx + 1) for idx, i in enumerate(elem) ] else: resnumber = fbmol.resid resname = fbmol.resname atomname = fbmol.atomname for elm in elem: atomicNum.append( list(PeriodicTable.keys()).index(elm) + 1) atomid = [] if len(self.atomidinfo) == 0: atmid = 1 else: atmid = max(list(self.atomidinfo.keys())) + 1 # if resname is 'MOL', assign resname to be moli if resname == list('MOL' for i in elem): fnm = Path(coordFile).stem newresname = fnm.split('_')[0] print( ' - Is this file generated from esp_generator? The residue name is MOL, which is a default residue name for small organic molecule.' ) print( ' It reassigns the residue name to %s not to confuse with other molecules while forcing symmetry.' % newresname) resname = list(newresname for i in elem) num = 1 for res, atom in zip(resname, elem): val = { 'resname': res, 'atomname': '%s%d' % (atom, num) } atomid.append(atmid) self.atomidinfo[atmid] = [val] atmid += 1 num += 1 else: for res, atom in zip(resname, atomname): val = {'resname': res, 'atomname': atom} if len(self.atomidinfo) == 0: atomid.append(atmid) self.atomidinfo[atmid] = [val] atmid += 1 elif any(val in v for v in list(self.atomidinfo.values())): for k, v in self.atomidinfo.items(): if val in v: atomid.append(int(k)) else: atomid.append(atmid) self.atomidinfo[atmid] = [val] atmid += 1 # Using openeye tool, make listofpolar, symmetryClass = [] listofpolar = [] listofburied = [] oechem.OEAssignHybridization(oemol) for atom in oemol.GetAtoms(): symmetryClass.append(atom.GetSymmetryClass()) if atom.IsCarbon() and int(atom.GetHyb()) != 3: listofpolar.append(atom.GetIdx()) if len([bond for bond in atom.GetBonds()]) > 3: listofburied.append(atom.GetIdx()) # ispolar = False # for bond in atom.GetBonds(): # atom2 = bond.GetNbr(atom) # if bond.GetOrder() == 1 and ispolar == False: # continue # else: # ispolar = True # break # if ispolar == True: # listofpolar.append(atom.GetIdx()) for atom in oemol.GetAtoms(): if atom.IsHydrogen(): for bond in atom.GetBonds(): atom2 = bond.GetNbr(atom) if atom2.IsPolar(): listofpolar.append(atom.GetIdx()) elif atom2.IsCarbon() and atom2.GetIdx( ) in listofpolar: listofpolar.append(atom.GetIdx()) if atom2.GetIdx() in listofburied: listofburied.append( atom.GetIdx() ) # store hydrogens bonded to buried atoms if atom.IsPolar(): listofpolar.append(atom.GetIdx()) listofpolar = sorted(set(listofpolar)) listofburied = sorted(set(listofburied)) idxof1statm, resnameof1statm = self.getidxof1statm( resnumber, resname) unique_resid = set(resnameof1statm) sameresid = [[ i for i, v in enumerate(resnameof1statm) if v == value ] for value in unique_resid] sameresid.sort() #sameresid = self.removeSingleElemList(sameresid) idxof1statm.append(len(resnumber)) equiv_ids = [] #print('symmetryClass', symmetryClass) #print('sameresid', sameresid) for equivresidgroup in sameresid: resnum = equivresidgroup[0] listofsym = symmetryClass[ idxof1statm[resnum]:idxof1statm[resnum + 1]] #print(listofsym) unique_sym = set(listofsym) equiv_sym = [[ i + idxof1statm[resnum] for i, v in enumerate(listofsym) if v == value ] for value in unique_sym] equiv_sym = self.removeSingleElemList(equiv_sym) #print('equiv_sym', equiv_sym) # change index to ID equiv_ID = [] for lst in equiv_sym: newlist = [] for item in lst: newlist.append(atomid[item]) equiv_ID.append(newlist) for i in equiv_ID: i.sort() equiv_ids.append(i) # weird:\ needtoremove = [] for idx, equiv_id in enumerate(equiv_ids): if len(set(equiv_id)) == 1: needtoremove.append(idx) needtoremove.sort(reverse=True) for i in needtoremove: del equiv_ids[i] if self.inp is not None: list_of_new_equiv_atoms = self.convert_equiv_atoms( self.inp.equiv_atoms, self.atomidinfo) else: list_of_new_equiv_atoms = [] equiv_ids_comb = [] for i in equiv_ids: equiv_ids_comb.append(i) for i in list_of_new_equiv_atoms: equiv_ids_comb.append(i) for i in equiv_ids_comb: i.sort() equiv_ids_comb.sort() newatomid = atomid.copy() newatomidinfo = copy.deepcopy(self.atomidinfo) for equiv_id in equiv_ids_comb: newid = equiv_id[0] for i in equiv_id[1:]: newatomid = [ newid if x == i else x for x in newatomid ] for j in self.atomidinfo[i]: newatomidinfo[newid].append(j) del newatomidinfo[i] # print('newatomidinfo', newatomidinfo) # print('oldatomidinfo', self.atomidinfo) # print('newatomid', newatomid) # print('oldatomid', atomid) if self.inp is not None: # print( f' * symmetry: {self.inp.symmetry}') if self.inp.symmetry == False: self.atomids.append(atomid) self.atomidinfo = self.atomidinfo else: self.atomids.append(newatomid) self.atomidinfo = newatomidinfo else: self.atomids.append(newatomid) self.atomidinfo = newatomidinfo self.elems.append(atomicNum) self.resnames.append(resname) self.atomnames.append(atomname) self.resnumbers.append(resnumber) self.listofpolars.append(listofpolar) self.listofburieds.append(listofburied) if self.inp is not None: chargeinfo = self.gen_chargeinfo( self.inp.resChargeDict, newatomid, self.atomidinfo, resnumber) else: indices = list(range(len(elem))) charge = None number = len(self.elems) + 1 resname = 'mol%d' % (number) chargeinfo = [[indices, resname, charge]] self.listofchargeinfo.append(chargeinfo) self.nmols.append(len(xyzs)) for xyz in xyzs: self.xyzs.append(xyz) for oemol in listofoemol: self.mols.append(oemol)
def set_aromaticity_mdl(self): oechem.OEClearAromaticFlags(self.mol) oechem.OEAssignAromaticFlags(self.mol, oechem.OEAroModel_MDL) oechem.OEAssignHybridization(self.mol)
# current license or subscription to the applicable OpenEye offering. # THE SAMPLE CODE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, # EXPRESS OR IMPLIED. OPENEYE DISCLAIMS ALL WARRANTIES, INCLUDING, BUT # NOT LIMITED TO, WARRANTIES OF MERCHANTABILITY, FITNESS FOR A # PARTICULAR PURPOSE AND NONINFRINGEMENT. In no event shall OpenEye be # liable for any damages or liability in connection with the Sample Code # or its use. from openeye import oechem from openeye import oedepict from openeye import oegrapheme # @ <SNIPPET-ANNOTATE-ATOM-PROPERTY> mol = oechem.OEGraphMol() oechem.OESmilesToMol(mol, "c1cc(N)cc(S(=O)(=O)O)c1") oechem.OEAssignHybridization(mol) oedepict.OEPrepareDepiction(mol) opts = oedepict.OE2DMolDisplayOptions(350, 250, oedepict.OEScale_AutoScale) opts.SetTitleLocation(oedepict.OETitleLocation_Hidden) disp = oedepict.OE2DMolDisplay(mol, opts) sp2pen = oedepict.OEPen(oechem.OEWhite, oechem.OEBlueTint, oedepict.OEFill_Off, 1.5) glyphSP2 = oegrapheme.OEAtomGlyphCircle(sp2pen, oegrapheme.OECircleStyle_Sun, 1.2) oegrapheme.OEAddGlyph(disp, glyphSP2, oechem.OEIsAtomHybridization(oechem.OEHybridization_sp2)) sp3pen = oedepict.OEPen(oechem.OEWhite, oechem.OEPinkTint, oedepict.OEFill_Off, 1.5)
def GetTorsions(mol): ''' Goes through each rotatable bond in the molecule and extracts torsion atoms (a-b-c-d) Core torsion atoms are extended by one bond If core or extended atoms are part of a ring, then entire ring is kept Keep ortho substitution Keep functional groups that have at least one atom overlap with the core/extended torsion atoms Functional group inclusion criteria: - <= 5 heavy atoms - must contain at least one hetero atom - non-ring Add methyl cap if bond involving hetero atom is broken @param mol: OEGraphMol @type mol: OEGraphMol @return: list[OEGraphMol] ''' # mol = OEGraphMol(input_mol) oechem.OEAssignHybridization(mol) funcGrps = TorsionGenerator.GetFuncGroups(mol) includedTorsions = oechem.OEAtomBondSet() torsionMols = [] for atom in mol.GetAtoms(): atom.SetData("idx", atom.GetIdx() + 1) torsions = get_canonical_torsions(mol) if torsions is None: torsions = oechem.OEGetTorsions(mol, oechem.OEIsRotor()) for torsion in torsions: if torsion.a.IsHydrogen() or torsion.b.IsHydrogen() or \ torsion.c.IsHydrogen() or torsion.d.IsHydrogen(): continue torsion_bond = mol.GetBond(torsion.b, torsion.c) if includedTorsions.HasBond(torsion_bond): continue # if includedTorsions.HasAtom(torsion.b) and \ # includedTorsions.HasAtom(torsion.c): # continue # revert map idx to zero in original mol for atom in mol.GetAtoms(): atom.SetMapIdx(0) # includedTorsions.AddAtom(torsion.b) # includedTorsions.AddAtom(torsion.c) includedTorsions.AddBond(torsion_bond) torsionSet = oechem.OEAtomBondSet(mol.GetBonds()) torsionSet.AddAtoms([torsion.a, torsion.b, torsion.c, torsion.d]) for atom in torsionSet.GetAtoms(): atom.SetMapIdx(1) # extend core torsion atoms by one bond nbrs = TorsionGenerator.GetNbrs(torsionSet) torsionSet.AddAtoms(nbrs) # include ring atoms ringAtoms = TorsionGenerator.GetSameRingAtoms(mol, torsionSet) torsionSet.AddAtoms(ringAtoms) for atom in torsionSet.GetAtoms(): if not atom.GetMapIdx() == 1: atom.SetMapIdx(2) # add functional groups that overlap with torsion set TorsionGenerator.AddFuncGroupAtoms(funcGrps, torsionSet) # add relevant ring atoms (ortho substituents and ring H) TorsionGenerator.AddRelevantRingAtoms(mol, torsion, torsionSet) # special treatment for C=O for atom in torsionSet.GetAtoms( oechem.OEAndAtom( oechem.OEIsOxygen(), oechem.OEIsAtomHybridization( oechem.OEHybridization_sp2))): for nbr in atom.GetAtoms(): if torsionSet.HasAtom(nbr): for nbr2 in nbr.GetAtoms(oechem.OEIsHeavy()): if not torsionSet.HasAtom(nbr2): nbr2.SetMapIdx(2) torsionSet.AddAtom(nbr2) # mark bridging atom and cap if needed BRIDGE_ATOM_IDX = 4 TorsionGenerator.MarkBridgingAtoms(BRIDGE_ATOM_IDX, mol, torsionSet) A_IDX = 11 B_IDX = 12 C_IDX = 13 D_IDX = 14 torsion.a.SetMapIdx(A_IDX) torsion.b.SetMapIdx(B_IDX) torsion.c.SetMapIdx(C_IDX) torsion.d.SetMapIdx(D_IDX) torsionMol = oechem.OEGraphMol() oechem.OESubsetMol(torsionMol, mol, torsionSet, True) torsionMol.Sweep() torsionMols.append(torsionMol) # change bridge atom to Carbon for atom in torsionMol.GetAtoms( oechem.OEHasMapIdx(BRIDGE_ATOM_IDX)): atom.SetAtomicNum(oechem.OEElemNo_C) explicit_valence = atom.GetExplicitValence() if explicit_valence < 4: atom.SetImplicitHCount(4 - explicit_valence) TorsionGenerator.SetSDData(A_IDX, B_IDX, C_IDX, D_IDX, torsion, torsionMol) # set map idx to zero in torsion mol for atom in torsionMol.GetAtoms(): atom.SetMapIdx(0) # revert map idx to zero in original mol for atom in mol.GetAtoms(): atom.SetMapIdx(0) return torsionMols