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 CanSmi(mol, isomeric, kekule): oechem.OEFindRingAtomsAndBonds(mol) oechem.OEAssignAromaticFlags(mol, oechem.OEAroModel_OpenEye) smiflag = oechem.OESMILESFlag_Canonical if isomeric: smiflag |= oechem.OESMILESFlag_ISOMERIC if kekule: for bond in mol.GetBonds(oechem.OEIsAromaticBond()): bond.SetIntType(5) oechem.OECanonicalOrderAtoms(mol) oechem.OECanonicalOrderBonds(mol) oechem.OEClearAromaticFlags(mol) oechem.OEKekulize(mol) smi = oechem.OECreateSmiString(mol, smiflag) return smi
def CanSmi(mol, isomeric, kekule): """ Returns the cannonical smile from the OEMol provided :param mol: OEMolBase object :param isomeric: force isometric :param kekule: use kekule cleaning :return: string of OESmiles """ oechem.OEFindRingAtomsAndBonds(mol) oechem.OEAssignAromaticFlags(mol, oechem.OEAroModel_OpenEye) smiflag = oechem.OESMILESFlag_Canonical if isomeric: smiflag |= oechem.OESMILESFlag_ISOMERIC if kekule: for bond in mol.GetBonds(oechem.OEIsAromaticBond()): bond.SetIntType(5) oechem.OECanonicalOrderAtoms(mol) oechem.OECanonicalOrderBonds(mol) oechem.OEClearAromaticFlags(mol) oechem.OEKekulize(mol) smi = oechem.OECreateSmiString(mol, smiflag) return smi
def generateOEMolFromTopologyResidue(residue, geometry=False, tripos_atom_names=False): """ 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. geometry : bool, optional, default=False If True, will generate a single configuration with OEOmega. Note that stereochemistry will be *random*. tripos_atom_names : bool, optional, default=False If True, will generate and assign Tripos atom names. 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) oeatom.AddData("topology_index", atom.index) 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])) oechem.OEClearAromaticFlags(molecule) for (bond, antechamber_bond_type) in zip(molecule.GetBonds(), antechamber_bond_types): #bond.SetOrder(order_map[antechamber_bond_type]) bond.SetIntType(order_map[antechamber_bond_type]) oechem.OEFindRingAtomsAndBonds(molecule) oechem.OEKekulize(molecule) oechem.OEAssignFormalCharges(molecule) oechem.OEAssignAromaticFlags(molecule, oechem.OEAroModelOpenEye) # Clean up. os.unlink(mol2_input_filename) os.unlink(ac_output_filename) os.rmdir(tmpdir) # Generate Tripos atom names if requested. if tripos_atom_names: oechem.OETriposAtomNames(molecule) # Assign geometry if geometry: from openeye import oeomega omega = oeomega.OEOmega() omega.SetMaxConfs(1) omega.SetIncludeInput(False) omega.SetStrictStereo(False) omega(molecule) return molecule
def _assign_am1bcc(cls, oe_molecule: OEMol): """Applies aromaticity flags based upon the aromaticity model outlined in the original AM1BCC publications _[1]. Parameters ---------- oe_molecule The molecule to assign aromatic flags to. References ---------- [1] Jakalian, A., Jack, D. B., & Bayly, C. I. (2002). Fast, efficient generation of high-quality atomic charges. AM1-BCC model: II. Parameterization and validation. Journal of computational chemistry, 23(16), 1623–1641. """ from openeye import oechem oechem.OEClearAromaticFlags(oe_molecule) x_type = "[#6X3,#7X2,#15X2,#7X3+1,#15X3+1,#8X2+1,#16X2+1:N]" y_type = "[#6X2-1,#7X2-1,#8X2,#16X2,#7X3,#15X3:N]" z_type = x_type # Case 1) case_1_smirks = (f"{x_type.replace('N', '1')}1" f"=@{x_type.replace('N', '2')}" f"-@{x_type.replace('N', '3')}" f"=@{x_type.replace('N', '4')}" f"-@{x_type.replace('N', '5')}" f"=@{x_type.replace('N', '6')}-@1") case_1_matches = match_smirks(case_1_smirks, oe_molecule, unique=True) case_1_atoms = { match for matches in case_1_matches for match in matches.values() } cls._set_aromatic(case_1_matches, oe_molecule) # Track the ar6 assignments as there is no atom attribute to # safely determine if an atom is in a six member ring when # that same atom is also in a five member ring. ar6_assignments = {*case_1_atoms} # Case 2) case_2_smirks = (f"{x_type.replace('N', '1')}1" f"=@{x_type.replace('N', '2')}" f"-@{x_type.replace('N', '3')}" f"=@{x_type.replace('N', '4')}" f"-@{x_type.replace('N', '5')}" f":@{x_type.replace('N', '6')}-@1") previous_case_2_atoms = None case_2_atoms = {} while previous_case_2_atoms != case_2_atoms: case_2_matches = match_smirks(case_2_smirks, oe_molecule, unique=True) # Enforce the ar6 condition case_2_matches = [ case_2_match for case_2_match in case_2_matches if case_2_match[4] in ar6_assignments and case_2_match[5] in ar6_assignments ] previous_case_2_atoms = case_2_atoms case_2_atoms = { match for matches in case_2_matches for match in matches.values() } ar6_assignments.update(case_2_atoms) cls._set_aromatic(case_2_matches, oe_molecule) # Case 3) case_3_smirks = (f"{x_type.replace('N', '1')}1" f"=@{x_type.replace('N', '2')}" f"-@{x_type.replace('N', '3')}" f":@{x_type.replace('N', '4')}" f"~@{x_type.replace('N', '5')}" f":@{x_type.replace('N', '6')}-@1") previous_case_3_atoms = None case_3_atoms = {} while previous_case_3_atoms != case_3_atoms: case_3_matches = match_smirks(case_3_smirks, oe_molecule, unique=True) # Enforce the ar6 condition case_3_matches = [ case_3_match for case_3_match in case_3_matches if case_3_match[2] in ar6_assignments and case_3_match[3] in ar6_assignments and case_3_match[4] in ar6_assignments and case_3_match[5] in ar6_assignments ] previous_case_3_atoms = case_3_atoms case_3_atoms = { match for matches in case_3_matches for match in matches.values() } ar6_assignments.update(case_3_atoms) cls._set_aromatic(case_3_matches, oe_molecule) # Case 4) case_4_smirks = ("[#6+1:1]1" f"-@{x_type.replace('N', '2')}" f"=@{x_type.replace('N', '3')}" f"-@{x_type.replace('N', '4')}" f"=@{x_type.replace('N', '5')}" f"-@{x_type.replace('N', '6')}" f"=@{x_type.replace('N', '7')}-@1") case_4_matches = match_smirks(case_4_smirks, oe_molecule, unique=True) case_4_atoms = { match for matches in case_4_matches for match in matches.values() } cls._set_aromatic(case_4_matches, oe_molecule) # Case 5) case_5_smirks = (f"{y_type.replace('N', '1')}1" f"-@{z_type.replace('N', '2')}" f"=@{z_type.replace('N', '3')}" f"-@{x_type.replace('N', '4')}" f"=@{x_type.replace('N', '5')}-@1") ar_6_ar_7_matches = { *case_1_atoms, *case_2_atoms, *case_3_atoms, *case_4_atoms, } case_5_matches = match_smirks(case_5_smirks, oe_molecule, unique=True) case_5_matches = [ matches for matches in case_5_matches if matches[1] not in ar_6_ar_7_matches and matches[2] not in ar_6_ar_7_matches ] cls._set_aromatic(case_5_matches, oe_molecule)
def set_aromaticity_mdl(self): oechem.OEClearAromaticFlags(self.mol) oechem.OEAssignAromaticFlags(self.mol, oechem.OEAroModel_MDL) oechem.OEAssignHybridization(self.mol)
def main(): opt = parser.parse_args() global which_gaff if opt.gaff: which_gaff = opt.gaff else: which_gaff = 1 # 2--> gaff2 global lig_input_mol2 if opt.lig: lig_input_mol2 = opt.lig else: lig_input_mol2 = 'lig_in.mol2' # ============== # # new protocol: # (1) amber bond typer --> ac file (2) openeye convert aromatic mol2 --> kekule form assignment with oechem.OEKekulize(mol) # ============== # command = '$AMBERHOME/bin/antechamber -i %s -fi mol2 -o lig.ac -fo ac -j 2 -dr n -pf y' % lig_input_mol2 print(command) subprocess.call(command, shell=True) molecule = oechem.OEGraphMol() ifs = oechem.oemolistream(lig_input_mol2) flavor = oechem.OEIFlavor_Generic_Default | oechem.OEIFlavor_MOL2_Default | oechem.OEIFlavor_MOL2_Forcefield ifs.SetFlavor(oechem.OEFormat_MOL2, flavor) oechem.OEReadMol2File(ifs, molecule) print(molecule.GetTitle()) # 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('lig.ac') 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])) oechem.OEClearAromaticFlags(molecule) for (bond, antechamber_bond_type) in zip(molecule.GetBonds(), antechamber_bond_types): #bond.SetOrder(order_map[antechamber_bond_type]) bond.SetIntType(order_map[antechamber_bond_type]) oechem.OEFindRingAtomsAndBonds(molecule) oechem.OEKekulize(molecule) oechem.OEAssignFormalCharges(molecule) oechem.OEAssignAromaticFlags(molecule, oechem.OEAroModelOpenEye) """ charges = [ atom.GetFormalCharge() for atom in molecule.GetAtoms() ] net_charge = np.array(charges).sum() print("Net Charge:", net_charge) """ subprocess.call('grep CHARGE lig.ac', shell=True) with open('lig.ac', "r") as f: line = f.readline() # if line.find("CHARGE") > -1 and len(line.split())> 2: # net_charge = int( float( line.split()[1] ) ) if line.find("CHARGE") > -1: net_charge = int(line[line.find("(") + 1:line.find(")")]) print("Net Charge:", net_charge) # Write mol2 file for this molecule. outmol = oechem.OEMol(molecule) ofs = oechem.oemolostream() filename = 'lig_oe.mol2' ofs.open(filename) oechem.OEWriteMolecule(ofs, outmol) ofs.close() if which_gaff == 1: gaff = "gaff" elif which_gaff == 2: gaff = "gaff2" command = "$AMBERHOME/bin/antechamber -i lig_oe.mol2 -fi mol2 -o lig_bcc.mol2 -fo mol2 -c bcc -at %s -nc %i -j 5 -pf y -dr n" \ % (gaff, net_charge) print(command) subprocess.call(command, shell=True) command = "$AMBERHOME/bin/parmchk2 -i lig_bcc.mol2 -f mol2 -s %d -o lig.frcmod" % ( which_gaff) print(command) subprocess.call(command, shell=True)
#!/usr/bin/env python # (C) 2017 OpenEye Scientific Software Inc. All rights reserved. # # TERMS FOR USE OF SAMPLE CODE The software below ("Sample Code") is # provided to current licensees or subscribers of OpenEye products or # SaaS offerings (each a "Customer"). # Customer is hereby permitted to use, copy, and modify the Sample Code, # subject to these terms. OpenEye claims no rights to Customer's # modifications. Modification of Sample Code is at Customer's sole and # exclusive risk. Sample Code may require Customer to have a then # 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. # @ <SNIPPET> from __future__ import print_function from openeye import oechem mol = oechem.OEGraphMol() oechem.OEParseSmiles(mol, "n1ccncc1") print("Canonical smiles :", oechem.OECreateCanSmiString(mol)) oechem.OEClearAromaticFlags(mol) oechem.OEKekulize(mol) print("Kekule smiles :", oechem.OECreateCanSmiString(mol)) # @ </SNIPPET>