Esempio n. 1
0
def get_ani_mol(coordinates, species, smiles):
    """ Given smiles string and list of elements as reference,
    get the RDKit mol with xyz.

    """

    mol = oechem.OEGraphMol()

    for symbol in species:
        mol.NewAtom(getattr(oechem, 'OEElemNo_' + symbol))

    mol.SetCoords(coordinates.reshape([-1]))
    mol.SetDimension(3)
    oechem.OEDetermineConnectivity(mol)
    oechem.OEFindRingAtomsAndBonds(mol)
    oechem.OEPerceiveBondOrders(mol)

    smiles_can = oechem.OECreateCanSmiString(mol)

    ims = oechem.oemolistream()
    ims.SetFormat(oechem.OEFormat_SMI)
    ims.openstring(smiles)
    mol_ref = next(ims.GetOEMols())
    smiles_ref = oechem.OECreateCanSmiString(mol_ref)

    assert smiles_can == smiles_ref

    g = hgfp.graph.from_oemol(mol, use_fp=True)

    return g, mol
    def createMolecule(self, mol, molTitle):
        '''
        Get a OE residue, return a OE molecule
        '''
        # Creating a new Res GraphMol
        newMol = oechem.OEGraphMol()
        newMol.SetTitle(molTitle)
        # Create every atom found in the OEHierResidue
        for atom in mol.GetAtoms():
            newMol.NewAtom(atom)

        #---------------------------------------------#
        # Recreate the molecule from atom coordinates #
        #---------------------------------------------#

        # Using OpenEye's charge model. Works on molecules with fully specified
        # hydrogen counts. Charge determined based on atom valence.
        oechem.OEDetermineConnectivity(newMol)
        oechem.OEFindRingAtomsAndBonds(newMol)
        oechem.OEPerceiveBondOrders(newMol)
        oechem.OEAssignImplicitHydrogens(newMol)
        oechem.OEAssignFormalCharges(newMol)

        # Other things to consider
        # Set atom radius
        #oechem.OEAssignBondiVdWRadii(newMol)
        #oechem.OEAssignPartialCharges(newMol,
        #                              oechem.OECharges_None,
        #                              False,
        #                              False)

        return newMol
Esempio n. 3
0
def mol_from_json(symbols, connectivity, geometry, permute_xyz=False):
    """
    Generate OEMol from QCSchema molecule specs
    Parameters
    ----------
    inp_molecule: dict
        Must have symbols and connectivity and/or geometry
        Note: If geometry is given, the molecule will have a tag indicating that the goemetry came from QCSchema. This
        will ensure that the order of the atoms and configuration is not change for generation of mapped SMILES and
        isomeric SMILES.

    Returns
    -------
    molecule: OEMol

    """

    molecule = oechem.OEMol()
    for s in symbols:
        molecule.NewAtom(_symbols[s])

    # Add connectivity
    for bond in connectivity:
        a1 = molecule.GetAtom(oechem.OEHasAtomIdx(bond[0]))
        a2 = molecule.GetAtom(oechem.OEHasAtomIdx(bond[1]))
        bond_order = bond[-1]
        if not isinstance(bond_order, int) and not bond_order.is_integer():
            raise ValueError(
                "bond order must be a whole number. A bond order of 1.5 is not allowed"
            )
        molecule.NewBond(a1, a2, int(bond_order))

    # Add geometry
    if molecule.NumAtoms() != geometry.shape[0] / 3:
        raise ValueError(
            "Number of atoms in molecule does not match length of position array"
        )

    molecule.SetCoords(oechem.OEFloatArray(geometry))
    molecule.SetDimension(3)

    if not permute_xyz:
        # Add tag that the geometry is from JSON and shouldn't be changed.
        geom_tag = oechem.OEGetTag("json_geometry")
        molecule.SetData(geom_tag, True)
    oechem.OEDetermineConnectivity(molecule)
    oechem.OEFindRingAtomsAndBonds(molecule)
    # No need to perceive Bond Order because the information was added from the connectivity table. Apparently, this
    # function does many different perceptions under the hood and it can add implicit hydrogens to divalent N that should be negatively charged.
    #oechem.OEPerceiveBondOrders(molecule)
    # This seems to add hydrogens that are not in the json
    #oechem.OEAssignImplicitHydrogens(molecule)
    oechem.OEAssignFormalCharges(molecule)
    oechem.OEAssignAromaticFlags(molecule)
    oechem.OEPerceiveChiral(molecule)
    oechem.OE3DToAtomStereo(molecule)
    oechem.OE3DToBondStereo(molecule)

    return molecule
Esempio n. 4
0
    def _pmdStructureToOEMol(self):
        top = self.structure.topology
        pos = self.structure.positions
        molecule = oeommtools.openmmTop_to_oemol(top, pos, verbose=False)
        oechem.OEPerceiveResidues(molecule)
        oechem.OEFindRingAtomsAndBonds(molecule)

        return molecule
Esempio n. 5
0
        def search(self, mol0, mol1):
            mol0 = mol0._struc
            mol1 = mol1._struc

            p0 = mol0.CreateCopy()
            p1 = mol1.CreateCopy()
            #set atom int type.
            for mol in (
                    p0,
                    p1,
            ):
                for atom in mol.GetAtoms():
                    if (atom.IsHydrogen()):
                        atom.SetIntType(1)
                    else:
                        atom.SetIntType(2)
            #suppress hydrogens before mcs search
            oechem.OESuppressHydrogens(p0)
            oechem.OESuppressHydrogens(p1)
            if (self._is_approximate):
                mcss = oechem.OEMCSSearch(p1, self._atom_expr, self._bond_expr,
                                          oechem.OEMCSType_Approximate)
            else:
                mcss = oechem.OEMCSSearch(p1, self._atom_expr, self._bond_expr)
            #set minimum atom of the mcs
            mcss.SetMinAtoms(1)
            #set the function to evalue the mcs search
            mcss.SetMCSFunc(oechem.OEMCSMaxAtomsCompleteCycles(1.5))

            # There could be multiple matches. We select the one with the maximum number of atoms.
            # If there are more than 1 matches with the same maximum number of atoms, we arbitrarily select the first one.
            mcs_mol = None
            max_num = 0
            #do the mcs search
            for match in mcss.Match(p0, True):
                num_atom = 0
                mcs_tmp = oechem.OEMol()
                oechem.OESubsetMol(mcs_tmp, match, True)
                oechem.OEFindRingAtomsAndBonds(mcs_tmp)
                for atom in mcs_tmp.GetAtoms():
                    if (not atom.IsHydrogen()):
                        num_atom += 1

                if (num_atom > max_num):
                    max_num = num_atom
                    mcs_mol = mcs_tmp
                    atom_match0 = []
                    atom_match1 = []
                    for matchpair in match.GetAtoms():
                        atom_match0.append(matchpair.target.GetIdx() + 1)
                        atom_match1.append(matchpair.pattern.GetIdx() + 1)
            #dump search result to kbase
            if (mcs_mol):
                mol0 = struc.OeStruc(mol0)
                mol1 = struc.OeStruc(mol1)
                mcs_mol = struc.OeStruc(mcs_mol)
                return self.deposit_to_kbase(mol0.id(), mol1.id(), atom_match0,
                                             atom_match1)
Esempio n. 6
0
def MakeAlpha(ifs, ofs):
    phival = math.pi / -3.0
    psival = math.pi / -3.0
    chival = math.pi
    nrphis = 0
    nrpsis = 0
    nrchis = 0
    mol = oechem.OEGraphMol()
    while oechem.OEReadMolecule(ifs, mol):
        if not oechem.OEHasResidues(mol):
            oechem.OEPerceiveResidues(mol, oechem.OEPreserveResInfo_All)
        # remove cross-links
        for bond in mol.GetBonds():
            if bond.GetBgn().GetAtomicNum() == oechem.OEElemNo_S and \
               bond.GetEnd().GetAtomicNum() == oechem.OEElemNo_S:
                mol.DeleteBond(bond)

        oechem.OEFindRingAtomsAndBonds(mol)
        hv = oechem.OEHierView(mol)
        for res in hv.GetResidues():
            if not oechem.OEIsStandardProteinResidue(res):
                continue

            # set psi and phi angles
            if not oechem.OESetTorsion(res, oechem.OEProtTorType_Phi, phival):
                oeres = res.GetOEResidue()
                print("Unable to set phi for %s %d" %
                      (oeres.GetName(), oeres.GetResidueNumber()))
            else:
                nrphis += 1

            if not oechem.OESetTorsion(res, oechem.OEProtTorType_Psi, psival):
                oeres = res.GetOEResidue()
                print("Unable to set psi for %s %d" %
                      (oeres.GetName(), oeres.GetResidueNumber()))
            else:
                nrpsis += 1

            # set chis
            if oechem.OEGetResidueIndex(
                    res.GetOEResidue().GetName()) == oechem.OEResidueIndex_PRO:
                continue  # It does not make sense to set Proline chi angles to 180

            for chi in oechem.OEGetChis(res):
                if not oechem.OESetTorsion(res, chi, chival):
                    oeres = res.GetOEResidue()
                    print("Unable to set chi %s for %s %d" %
                          (oechem.OEGetProteinTorsionName(chi),
                           oeres.GetName(), oeres.GetResidueNumber()))
                else:
                    nrchis += 1
        oechem.OEWriteMolecule(ofs, mol)

    print(nrphis, " phi  torsion angle set to ", phival * oechem.cvar.Rad2Deg)
    print(nrpsis, " psi  torsion angle set to ", psival * oechem.cvar.Rad2Deg)
    print(nrchis, " chis torsion angle set to ", chival * oechem.cvar.Rad2Deg)
Esempio n. 7
0
def mol_from_json(symbols, connectivity, geometry, permute_xyz=False):
    """
    Generate OEMol from QCSchema molecule specs
    Parameters
    ----------
    inp_molecule: dict
        Must have symbols and connectivity and/or geometry
        Note: If geometry is given, the molecule will have a tag indicating that the goemetry came from QCSchema. This
        will ensure that the order of the atoms and configuration is not change for generation of mapped SMILES and
        isomeric SMILES.

    Returns
    -------
    molecule: OEMol

    """

    molecule = oechem.OEMol()
    for s in symbols:
        molecule.NewAtom(_symbols[s])

    # Add connectivity
    for bond in connectivity:
        a1 = molecule.GetAtom(oechem.OEHasAtomIdx(bond[0]))
        a2 = molecule.GetAtom(oechem.OEHasAtomIdx(bond[1]))
        molecule.NewBond(a1, a2, bond[-1])

    # Add geometry
    if molecule.NumAtoms() != geometry.shape[0] / 3:
        raise ValueError(
            "Number of atoms in molecule does not match length of position array"
        )

    molecule.SetCoords(oechem.OEFloatArray(geometry))
    molecule.SetDimension(3)

    if not permute_xyz:
        # Add tag that the geometry is from JSON and shouldn't be changed.
        geom_tag = oechem.OEGetTag("json_geometry")
        molecule.SetData(geom_tag, True)
    oechem.OEDetermineConnectivity(molecule)
    oechem.OEFindRingAtomsAndBonds(molecule)
    oechem.OEPerceiveBondOrders(molecule)
    # This seems to add hydrogens that are not in the json
    #oechem.OEAssignImplicitHydrogens(molecule)
    oechem.OEAssignFormalCharges(molecule)
    oechem.OEAssignAromaticFlags(molecule)
    oechem.OEPerceiveChiral(molecule)
    oechem.OE3DToAtomStereo(molecule)
    oechem.OE3DToBondStereo(molecule)

    return molecule
def GetFragments(mol, minbonds, maxbonds):
    from openeye import oegraphsim
    frags = []
    fptype = oegraphsim.OEGetFPType("Tree,ver=2.0.0,size=4096,bonds=%d-%d,atype=AtmNum,btype=Order"
                                    % (minbonds, maxbonds))

    for abset in oegraphsim.OEGetFPCoverage(mol, fptype, True):
        fragatompred = oechem.OEIsAtomMember(abset.GetAtoms())

        frag = oechem.OEGraphMol()
        adjustHCount = True
        oechem.OESubsetMol(frag, mol, fragatompred, adjustHCount)
        oechem.OEFindRingAtomsAndBonds(frag)
        frags.append(oechem.OEGraphMol(frag))

    return frags
Esempio n. 9
0
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
Esempio n. 10
0
 def extract(self, indices) :
     """                                               
     Return a new structure object which contains the atoms of the current structure that appear in the specified list.
     """                                               
     #make a copy before deleting atoms                  
     new_mol = self._struc.CreateCopy()
     for atom in new_mol.GetAtoms():
         oe_idx = atom.GetIdx() + 1
         if oe_idx not in indices:
             new_mol.DeleteAtom(atom)
     #make a copy after deleting to make sure the idx start from 1   
     new_mol_copy = new_mol.CreateCopy()               
     oechem.OEFindRingAtomsAndBonds(new_mol_copy)      
     ret = OeStruc(new_mol_copy)                       
     indices.sort()                                    
     for i, e in enumerate(indices, start = 1):        
         ret.atom_prop[i] = copy.deepcopy(self.atom_prop[e])              
     return ret
Esempio n. 11
0
    def GetSameRingAtoms(mol, atomSet):
        '''
        @type mol: OEGraphMol
        @type atomSet: OEAtomBondSet
        @return list[OEAtombase]
        '''
        oechem.OEFindRingAtomsAndBonds(mol)
        _, ringIdxPerAtom = oechem.OEDetermineRingSystems(mol)
        toKeepRings = {}
        for atom in atomSet.GetAtoms():
            if ringIdxPerAtom[atom.GetIdx()] > 0:
                toKeepRings[ringIdxPerAtom[atom.GetIdx()]] = True

        ringAtoms = []
        for i in range(0, len(ringIdxPerAtom)):
            if ringIdxPerAtom[i] in toKeepRings:
                ringAtoms.append(mol.GetAtom(oechem.OEHasAtomIdx(i)))

        return ringAtoms
Esempio n. 12
0
 def ring_size (self):                                 
     """
     Returns a dictionary, which is atom's index correspoding to the ring size the atom in.
     @rtype : C{dic} of C{int} : C{int}
     @return: A dictionary of atom indices correspoing to the size of the ring they are in.          
     """
     ring_size = {}                                    
     oechem.OEFindRingAtomsAndBonds(self._struc)       
     nrrings, rings = oechem.OEDetermineRingSystems(self._struc)     
     ring_dic = {}                                     
     for ring_idx in rings:                            
         if not ring_dic.has_key(ring_idx):            
             ring_dic[ring_idx] = []                   
     for key in ring_dic.keys():                       
         if key > 0:                                   
             ring_dic[key] = rings.count(key)          
         else:                                         
             ring_dic[key] = 0                         
     for (idx, atom) in enumerate(rings):                            
         oe_idx = idx +1                                             
         ring_size [oe_idx] = ring_dic[atom]           
                                                       
     return ring_size
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
Esempio n. 14
0
def create_openeye_molecule(pdb, options, verbose=True):
    """
    Create OpenEye molecule from PDB representation.

    The molecule will have hydrogens added and be normalized, but the overall geometry will not be altered.

    Parameters
    ----------
    pdb : Pdb
       The PDB-extracted entries for the ligand.

    Returns
    -------
    molecule : openeye.oechem.OEMol
        Molecule representation.
    options : options struct
        Options structure.

    """

    # Create a molecule container.
    molecule = oechem.OEGraphMol()

    # Open a PDB file reader from the stored PDB string representation of HETATM and CONECT records.
    print pdb.pdb_extract
    ifs = oechem.oemolistream()
    ifs.openstring(pdb.pdb_extract)
    flavor = oechem.OEIFlavor_Generic_Default | oechem.OEIFlavor_PDB_Default | oechem.OEIFlavor_PDB_ALL
    ifs.SetFlavor(oechem.OEFormat_PDB, flavor)
    oechem.OEReadPDBFile(ifs, molecule)

    # Add explicit hydrogens.
    oechem.OEDetermineConnectivity(molecule)
    oechem.OEFindRingAtomsAndBonds(molecule)
    oechem.OEAssignAromaticFlags(molecule) # check aromaticity
    oechem.OEPerceiveBondOrders(molecule)

    # We must assign implicit hydrogens first so that the valence model will be correct.
    oechem.OEAssignImplicitHydrogens(molecule)
    oechem.OEAssignFormalCharges(molecule)

    # Now add explicit hydrogens.
    polarOnly = False
    set3D = True
    oechem.OEAddExplicitHydrogens(molecule, polarOnly, set3D)

    # TODO: Sequentially number hydrogen atoms.

    # Perceive stereochemostry.
    oechem.OEPerceiveChiral(molecule)

    # Set title.
    molecule.SetTitle(options.ligand)

    # Write out PDB form of this molecule.
    # TODO: Fix atom numbering.
    #if verbose: print "Writing input molecule as PDB..."
    #outmol = oechem.OEMol(molecule)
    #ofs = oechem.oemolostream()
    #flavor = oechem.OEOFlavor_Generic_Default | oechem.OEOFlavor_PDB_Default
    #ofs.SetFlavor(oechem.OEFormat_PDB, flavor)
    #ofs.open(options.ligand + '.pdb')
    #oechem.OEWriteMolecule(ofs, outmol)
    #ofs.close()

    # Write mol2 file for this molecule.
    if verbose: print "Writing input molecule as mol2..."
    outmol = oechem.OEMol(molecule)
    ofs = oechem.oemolostream()
    filename = options.ligand + '.mol2'
    ofs.open(filename)
    oechem.OEWriteMolecule(ofs, outmol)
    ofs.close()
    # Use low level writer to get atom names correct.
    ofs = oechem.oemolostream()
    ofs.open(filename)
    for (dest_atom, src_atom) in zip(outmol.GetAtoms(), molecule.GetAtoms()):
        dest_atom.SetName(src_atom.GetName())
    oechem.OEWriteMol2File(ofs, outmol, True)
    ofs.close()
    # Read and write in PDB format.
    if verbose: print "Converting mol2 to PDB..."
    ifs = oechem.oemolistream()
    ofs = oechem.oemolostream()
    if ifs.open(options.ligand + '.mol2'):
        if ofs.open(options.ligand + '.pdb'):
            for mol in ifs.GetOEGraphMols():
                oechem.OEWriteMolecule(ofs, mol)

    return molecule
Esempio n. 15
0
def infer_mol_from_coordinates(
    coordinates,
    species,
    smiles_ref=None,
    coordinates_unit="angstrom",
):

    # local import
    from openeye import oechem
    from simtk import unit
    from simtk.unit import Quantity

    if isinstance(coordinates_unit, str):
        coordinates_unit = getattr(unit, coordinates_unit)

    # make sure we have the coordinates
    # in the unit system
    coordinates = Quantity(coordinates, coordinates_unit).value_in_unit(
        unit.angstrom  # to make openeye happy
    )

    # initialize molecule
    mol = oechem.OEGraphMol()

    if all(isinstance(symbol, str) for symbol in species):
        [
            mol.NewAtom(getattr(oechem, "OEElemNo_" + symbol))
            for symbol in species
        ]

    elif all(isinstance(symbol, int) for symbol in species):
        [
            mol.NewAtom(
                getattr(oechem,
                        "OEElemNo_" + oechem.OEGetAtomicSymbol(symbol)))
            for symbol in species
        ]

    else:
        raise RuntimeError(
            "The species can only be all strings or all integers.")

    mol.SetCoords(coordinates.reshape([-1]))
    mol.SetDimension(3)
    oechem.OEDetermineConnectivity(mol)
    oechem.OEFindRingAtomsAndBonds(mol)
    oechem.OEPerceiveBondOrders(mol)

    if smiles_ref is not None:
        smiles_can = oechem.OECreateCanSmiString(mol)
        ims = oechem.oemolistream()
        ims.SetFormat(oechem.OEFormat_SMI)
        ims.openstring(smiles_ref)
        mol_ref = next(ims.GetOEMols())
        smiles_ref = oechem.OECreateCanSmiString(mol_ref)
        assert (smiles_ref == smiles_can
                ), "SMILES different. Input is %s, ref is %s" % (
                    smiles_can,
                    smiles_ref,
                )

    from openff.toolkit.topology import Molecule

    _mol = Molecule.from_openeye(mol, allow_undefined_stereo=True)
    g = esp.Graph(_mol)

    return g
Esempio n. 16
0
# 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 openeye import oechem

# @ <SNIPPET-CORRECT-COMPLEX>
mol = oechem.OEGraphMol()
oechem.OESmilesToMol(mol, "c1ccccc1")
# Code that modifies the molecule
# and creates new atoms and bonds
oechem.OEFindRingAtomsAndBonds(mol)
oechem.OEAssignAromaticFlags(mol)
for bond in mol.GetBonds():
    if bond.IsAromatic():
        bond.SetIntType(5)
    elif bond.GetOrder() != 0:
        bond.SetIntType(bond.GetOrder())
    else:
        bond.SetIntType(1)
oechem.OEKekulize(mol)
# @ </SNIPPET-CORRECT-COMPLEX>
# @ </SNIPPET>
Esempio n. 17
0
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)
Esempio n. 18
0
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
Esempio n. 19
0
def oemol_from_rdmol(rdmol):
    """
    Creates an openeye molecule object that is identical to the input rdkit molecule
    """
    # RDK automatically includes explicit hydrogens in its SMILES patterns
    print("Starting molecule: ", Chem.MolToSmiles(Chem.RemoveHs(rdmol)))

    # openeye stores bond orders as integers regardless of aromaticity
    # in order to properly extract these, we need to have the "Kekulized" version of the rdkit mol
    kekul_mol = Chem.Mol(rdmol)
    Chem.Kekulize(kekul_mol, True)

    oemol = oechem.OEMol()
    map_atoms = dict()  # {rd_idx: oe_atom}

    # setting chirality in openey requires using neighbor atoms
    # therefore we can't do it until after the atoms and bonds are all added
    chiral_atoms = dict()  # {rd_idx: openeye chirality}
    for rda in rdmol.GetAtoms():
        rd_idx = rda.GetIdx()

        # create a new atom
        oe_a = oemol.NewAtom(rda.GetAtomicNum())
        map_atoms[rd_idx] = oe_a
        oe_a.SetFormalCharge(rda.GetFormalCharge())
        oe_a.SetAromatic(rda.GetIsAromatic())

        # If chiral, store the chirality to be set later
        tag = rda.GetChiralTag()
        if tag == Chem.CHI_TETRAHEDRAL_CCW:
            chiral_atoms[rd_idx] = oechem.OECIPAtomStereo_R
        if tag == Chem.CHI_TETRAHEDRAL_CW:
            chiral_atoms[rd_idx] = oechem.OECIPAtomStereo_S

    # Similar to chirality, stereochemistry of bonds in OE is set relative to their neighbors
    stereo_bonds = list()
    # stereo_bonds stores tuples in the form (oe_bond, rd_idx1, rd_idx2, OE stereo specification)
    # where rd_idx1 and 2 are the atoms on the outside of the bond
    # i.e. Cl and F in the example above
    aro_bond = 0
    for rdb in rdmol.GetBonds():
        a1 = rdb.GetBeginAtomIdx()
        a2 = rdb.GetEndAtomIdx()

        # create a new bond
        newbond = oemol.NewBond(map_atoms[a1], map_atoms[a2])

        order = rdb.GetBondTypeAsDouble()
        if order == 1.5:
            # get the bond order for this bond in the kekulized molecule
            order = kekul_mol.GetBondWithIdx(
                rdb.GetIdx()).GetBondTypeAsDouble()
            newbond.SetAromatic(True)
        else:
            newbond.SetAromatic(False)
        newbond.SetOrder(int(order))

        # determine if stereochemistry is needed
        tag = rdb.GetStereo()
        if tag == Chem.BondStereo.STEREOCIS or tag == Chem.BondStereo.STEREOZ:
            stereo_atoms = rdb.GetStereoAtoms()
            stereo_bonds.append((newbond, stereo_atoms[0], stereo_atoms[1],
                                 oechem.OEBondStereo_Cis))

            bond2 = rdmol.GetBondBetweenAtoms(stereo_atoms[0], a1)
            bond4 = rdmol.GetBondBetweenAtoms(stereo_atoms[1], a2)
            print(tag, bond2.GetBondDir(), bond4.GetBondDir())
        if tag == Chem.BondStereo.STEREOTRANS or tag == Chem.BondStereo.STEREOE:
            stereo_atoms = rdb.GetStereoAtoms()
            stereo_bonds.append((newbond, stereo_atoms[0], stereo_atoms[1],
                                 oechem.OEBondStereo_Trans))
            bond2 = rdmol.GetBondBetweenAtoms(stereo_atoms[0], a1)
            bond4 = rdmol.GetBondBetweenAtoms(stereo_atoms[1], a2)
            print(tag, bond2.GetBondDir(), bond4.GetBondDir())

    # Now that all of the atoms are connected we can set stereochemistry
    # starting with atom chirality
    for rd_idx, chirality in chiral_atoms.items():
        # chirality is set relative to neighbors, so we will get neighboring atoms
        # assign Right handed direction, check the cip stereochemistry
        # if the cip stereochemistry isn't correct then we'll set left and double check

        oea = map_atoms[rd_idx]
        neighs = [n for n in oea.GetAtoms()]
        # incase you look at the documentation oe has two options for handedness for example:
        # oechem.OEAtomStereo_Left == oechem.OEAtomStereo_LeftHanded
        oea.SetStereo(neighs, oechem.OEAtomStereo_Tetra,
                      oechem.OEAtomStereo_Right)
        cip = oechem.OEPerceiveCIPStereo(oemol, oea)
        if cip != chirality:
            oea.SetStereo(neighs, oechem.OEAtomStereo_Tetra,
                          oechem.OEAtomStereo_Left)
            new_cip = oechem.OEPerceiveCIPStereo(oemol, oea)
            if new_cip != chirality:
                # Note, I haven't seen this happen yet, but it shouldn't be a problem since there
                # is only 2 directions for handedness and we're only running this for chiral atoms
                print("PANIC!")

    # Set stereochemistry using the reference atoms extracted above
    for oeb, idx1, idx2, oestereo in stereo_bonds:
        oeb.SetStereo([map_atoms[idx1], map_atoms[idx2]],
                      oechem.OEBondStereo_CisTrans, oestereo)

    # If the rdmol has a conformer, add its coordinates to the oemol
    # Note, this currently only adds the first conformer, it will need to be adjusted if the
    # you wanted to convert multiple sets of coordinates
    if rdmol.GetConformers():
        conf = rdmol.GetConformer()
        for rd_idx, oeatom in map_atoms.items():
            coords = conf.GetAtomPosition(rd_idx)
            oemol.SetCoords(oeatom, oechem.OEFloatArray(coords))

    # If RDMol has a title save it
    if rdmol.HasProp("_Name"):
        oemol.SetTitle(rdmol.GetProp("_Name"))

    # Clean Up phase
    # The only feature of a molecule that wasn't perceived above seemed to be ring connectivity, better to run it
    # here then for someone to inquire about ring sizes and get 0 when it shouldn't be
    oechem.OEFindRingAtomsAndBonds(oemol)

    print('Final Molecule: ', oechem.OEMolToSmiles(oemol))
    return oemol