Beispiel #1
0
def append_matrix_with_rmsd_to_previous_element(
        matrix, iterator, fieldname_rmsd="RMSD_to_previous"):
    import numpy
    ligands = []
    foobar = None
    rmsd = 0

    for pos in iterator:
        filename = matrix[pos]["filename"]
        ligands.append(openbabel.OBMol())
        obconversion.SetInFormat(filename[filename.rfind(".") + 1:])
        if obconversion.ReadFile(ligands[-1], filename):
            log.info('Successfully read ligand ' + str(filename))
        else:
            log.warning('Failed to read ligand ' + str(filename))

        if foobar == None:
            foobar = 1  # skip first
            continue
        else:
            #print "hi"
            foobar = openbabel.OBMolAtomIter(ligands[-2])
            for atom in openbabel.OBMolAtomIter(ligands[-1]):
                V = foobar.__next__().GetVector()
                W = atom.GetVector()
                rmsd += (V.distSq(W))
            rmsd /= ligands[-1].NumAtoms()
            rmsd = numpy.sqrt(rmsd)

            matrix[pos].update({fieldname_rmsd: rmsd})
    return
Beispiel #2
0
def CheckBondConnectivity(poltype,mol,optmol):
    atomitermol=openbabel.OBMolAtomIter(mol)
    atomiteroptmol=openbabel.OBMolAtomIter(optmol)
    for atm in atomitermol:
       
        atmidxmol=atm.GetIdx()
        
        atmoptmol=optmol.GetAtom(atmidxmol)
        atmidxoptmol=atmoptmol.GetIdx()
        atmneighbidxlist=[]
        iteratomatommol = openbabel.OBAtomAtomIter(atm)
        for newatm in iteratomatommol:
            atmneighbidxlist.append(newatm.GetIdx())
        atmneighbidxlistoptmol=[]
        iteratomatomoptmol = openbabel.OBAtomAtomIter(atmoptmol)
        for newatm in iteratomatomoptmol:
            atmneighbidxlistoptmol.append(newatm.GetIdx())
        if set(atmneighbidxlist)!=set(atmneighbidxlistoptmol):
            if len(set(atmneighbidxlist))>len(set(atmneighbidxlistoptmol)):
                diff=set(atmneighbidxlist)-set(atmneighbidxlistoptmol)
                idxset='mol'
            else:
                diff=set(atmneighbidxlistoptmol)-set(atmneighbidxlist)
                idxset='optmol'
            RaiseConnectivityError(poltype,diff,idxset)
Beispiel #3
0
def ApplyKabsch(molFit, COMFit, COMRef, rot):
    crd=[]
    for at in openbabel.OBMolAtomIter(molFit):
        crd.append([at.GetX()-COMFit[0], at.GetY()-COMFit[1], at.GetZ()-COMFit[2]])
    crd=np.array(crd)
    for i in xrange(len(crd)):
        crd[i]=np.dot(rot,crd[i])
    i = 0
    for at in openbabel.OBMolAtomIter(molFit):
        at.SetVector(crd[i][0]+COMRef[0], crd[i][1]+COMRef[1], crd[i][2]+COMRef[2])
        i+=1
    return True
Beispiel #4
0
def mol2amol(mol):
    mol.Kekulize()
    atoms = list()
    for a in openbabel.OBMolAtomIter(mol):
        atom = list()
        atom.append(a.GetHyb())
        atom.append(a.GetAtomicNum())
        atom.append(a.GetFormalCharge())
        atom.append(a.GetIsotope())
        if a.IsClockwise():
            stereo = 1
        elif a.IsAntiClockwise():
            stereo = 2
        elif a.IsChiral():
            stereo = 3
        else:
            stereo = 0
        atom.append(stereo)
        atom.append(a.GetSpinMultiplicity())
        if a.IsAromatic():
            aromatic = 1
        else:
            aromatic = 0
        atom.append(aromatic)

        atoms.append(atom)

    bonds = list()
    for b in openbabel.OBMolBondIter(mol):
        bond = list()
        bond.append(b.GetBeginAtomIdx())
        bond.append(b.GetEndAtomIdx())
        bond.append(b.GetBondOrder())
        if b.IsWedge():
            stereo = 1
        elif b.IsHash():
            stereo = 6
        else:
            stereo = 0
        bond.append(stereo)
        if b.IsAromatic():
            aromatic = 1
        else:
            aromatic = 0
        bond.append(aromatic)
        if b.IsUp():
            updown = 1
            print
            updown
        elif b.IsDown():
            updown = 2
            print
            updown
        else:
            updown = 0
        bond.append(updown)

        bonds.append(bond)

    return pickle.dumps([atoms, bonds], 2)
Beispiel #5
0
 def get_atnums(self):
     if self._atnums is None:
         self._atnums = numpy.zeros((self.natoms, ))
         for at in openbabel.OBMolAtomIter(self.obmol):
             i = at.GetIdx() - 1
             self._atnums[i] = at.GetAtomicNum()
     return self._atnums
Beispiel #6
0
 def get_atmasses(self):
     if self._atmasses is None:
         self._atmasses = numpy.zeros((self.natoms, ))
         for at in openbabel.OBMolAtomIter(self.obmol):
             i = at.GetIdx() - 1
             self._atmasses[i] = at.GetExactMass()
     return self._atmasses
Beispiel #7
0
    def attype_groups_2(self):
        groupnames = ['NH', 'CO', 'CA', 'HA', 'CHB']
        groups = []

        for k in groupnames:
            groups.append([])
        for at in openbabel.OBMolAtomIter(self.obmol):
            attype = at.GetResidue().GetAtomID(at)
            attype = attype.strip()

            if attype in ['1HB', '2HB', '3HB', 'HB1', 'HB2', 'HB3']:
                attype = 'HB'
            if attype in ['1H', '2H', 'H 1', 'H 2', 'H1', 'H2']:
                attype = 'HXT'

            if attype in ['N', 'H', 'HXT']:
                attype = 'NH'
            elif attype in ['C', 'O', 'OXT']:
                attype = 'CO'
            elif attype in ['CB', 'HB']:
                attype = 'CHB'

            ind = groupnames.index(attype)
            groups[ind].append(at.GetIdx() - 1)

        return groups, groupnames
Beispiel #8
0
 def ComputeBondResidual(self, db):
     for f in self.frags:
         # constructing submolecule from the fragment
         efpmol = pyEFP.EFP2mol("./"+db.dirname+"/"+f.ename+"/"+f.fname+".efp")
         # fit atoms from the core lists
         rot, COMRef, COMFit = pyEFP.SolveKabsch(efpmol, f.subMol, f.efpcore, f.molcore)
         # deleting extra atoms
         complete = 0
         while (complete == 0):
             complete = 1
             for at in openbabel.OBMolAtomIter(efpmol):
                 extra = 0
                 if at.GetIndex()+1 not in f.efptotal:
                     extra = 1
                     for at1 in openbabel.OBAtomAtomIter(at):
                         if (at1.GetIndex()+1 in f.efptotal) and (at.GetAtomicNum() == 1):
                             extra = 0
                             break
                 if (extra == 1):
                     efpmol.DeleteAtom(at)
                     complete = 0
         efpmol.AddHydrogens()
         pyEFP.ApplyKabsch(efpmol, COMFit, COMRef, rot)
         for i in xrange(len(f.links)):
             dx = efpmol.GetAtom(f.links[i][0]).x() - self.frags[f.links[i][2]].subMol.GetAtom(f.links[i][4]).x() 
             dy = efpmol.GetAtom(f.links[i][0]).y() - self.frags[f.links[i][2]].subMol.GetAtom(f.links[i][4]).y() 
             dz = efpmol.GetAtom(f.links[i][0]).z() - self.frags[f.links[i][2]].subMol.GetAtom(f.links[i][4]).z()
             f.links[i].append(np.sqrt(dx*dx + dy*dy + dz*dz))
Beispiel #9
0
    def get_connectivity(self):
        '''
        Retrieve the connectivity matrix of the molecule.

        Returns:
            numpy.ndarray: (n_atoms x n_atoms) array containing the pairwise bond orders
                between atoms (0 for no bond).
        '''
        if self._connectivity is None:
            # get connectivity matrix
            connectivity = np.zeros((self.n_atoms, len(self.numbers)))
            for atom in ob.OBMolAtomIter(self.get_obmol()):
                index = atom.GetIdx() - 1
                # loop over all neighbors of atom
                for neighbor in ob.OBAtomAtomIter(atom):
                    idx = neighbor.GetIdx() - 1
                    bond_order = neighbor.GetBond(atom).GetBO()
                    #print(f'{index}-{idx}: {bond_order}')
                    # do not count bonds between two hydrogen atoms
                    if (self.numbers[index] == 1 and self.numbers[idx] == 1
                            and bond_order > 0):
                        bond_order = 0
                    connectivity[index, idx] = bond_order
            self._connectivity = connectivity
        return self._connectivity
def enumerateChiral(mol):
        """ enumerate tetrahedral stereocenters
            in the molecule
        """
        if not mol.IsChiral():
            yield mol # we know the molecule is not chiral
        else:
            chiral = []
            chiralSet = []
            facade = ob.OBStereoFacade(mol)
            for a in ob.OBMolAtomIter(mol):
                idx = a.GetIdx()
                if a.IsChiral():
                    chiral.append(idx)
            if len(chiral) == 0:
                yield mol # no chiral centers
            else:
                atomList = chiral
                step = len(atomList)

                for winding in itertools.product([1,2], repeat=step):
                    for idx, aIdx in enumerate(atomList):
                        ts = facade.GetTetrahedralStereo(aIdx-1)
                        config = ts.GetConfig()
                        config.winding = winding[idx]
                        config.specified = True
                        ts.SetConfig(config)
                    yield mol
Beispiel #11
0
    def to_graph(self, molw: pybel.Molecule) -> nx.Graph:
        mol = molw.OBMol
        if self._add_hydrogens:
            mol.AddHydrogens()
        else:
            mol.DeleteHydrogens()

        g = nx.Graph()
        for atom in openbabel.OBMolAtomIter(mol):
            node_features = {
                'Symbol': self._element_tabel.GetSymbol(atom.GetAtomicNum())
            }
            g.add_node(atom.GetIdx(), **node_features)
            self._node_types.add(node_features['Symbol'])

        for b in openbabel.OBMolBondIter(mol):
            idx_a = b.GetBeginAtomIdx()
            idx_b = b.GetEndAtomIdx()
            edge_features = {'BondType': b.GetBondOrder()}
            g.add_edge(idx_a, idx_b, **edge_features)
            self._edge_types.add(edge_features['BondType'])

        # canonical SMILES format
        text = molw.write(format='can')
        g.graph['smiles'] = text.split('\t', 1)[0]
        g.graph['name'] = molw.title.split('\t', 1)[0]

        return g
Beispiel #12
0
def make_conv_input(mol,A,B,gshape=64):
    """
    Takes an openbabel molecule input, mol, and the atom indices for the two atoms for which  you are interested in the coupling
    returns a flattend numpy array of the electrostatic potential with the X,Y,Z coordinates of A and B appended
    """
    
    epsilon=0.00000001
    grid=np.linspace(-6.,6.,gshape)
    XXX,YYY,ZZZ=np.meshgrid(grid,grid,grid)
    
    V=np.zeros((gshape,gshape,gshape,2))
    atom_iter=ob.OBMolAtomIter(mol)
    for atom in atom_iter:
        atomic_num=atom.GetAtomicNum()
        x=atom.GetX()
        y=atom.GetY()
        z=atom.GetZ()
        RRR=np.sqrt((XXX-x)**2+(YYY-y)**2+(ZZZ-z)**2)
#        V[:,:,:,0]=V[:,:,:,0] - atomic_num/(RRR+epsilon)
        V[:,:,:,0]=V[:,:,:,0]-atomic_num*np.exp(-0.5*RRR*RRR)
        
    atom=mol.GetAtom(A)
    x=atom.GetX()
    y=atom.GetY()
    z=atom.GetZ()
    RRR2=(XXX-x)**2+(YYY-y)**2+(ZZZ-z)**2
    V[:,:,:,1]=V[:,:,:,1] +np.exp(-0.5*(RRR2))
    atom=mol.GetAtom(B)
    x=atom.GetX()
    y=atom.GetY()
    z=atom.GetZ()
    RRR2=(XXX-x)**2+(YYY-y)**2+(ZZZ-z)**2
    V[:,:,:,1]=V[:,:,:,1] +np.exp(-0.5*(RRR2))
    return V
def getRingAtomsMulti(molfilePath):
    for m in pybel.readfile("mol", molfilePath):
        #print m.OBMol.GetFormula()
        outString = ""
        rings = m.OBMol.GetSSSR()
        numR = 0
        for r in rings:
            numR = numR + 1
        outString += "Ring count " + str(numR) + "\n"
        for r in rings:
            outString += "Ring size " + str(r.Size()) + "\n"
            path = r._path
            for p in path:
                outString += str(p - 1) + "\n"

        outString += "Atom count " + str(m.OBMol.NumAtoms()) + "\n"
        outString += "Index HowManyRings RingSize Hybridization Hydro_count Aromaticity AntiClockwise_chiral" + "\n"
        i = 0
        for a in openbabel.OBMolAtomIter(m.OBMol):
            outString += str(i) + " " + str(a.MemberOfRingCount()) + " " + str(
                a.MemberOfRingSize()) + " " + str(a.GetHyb()) + " " + str(
                    a.ImplicitHydrogenCount()) + " "
            if a.IsAromatic():
                outString += "1" + " "
            else:
                outString += "0" + " "
            if a.IsClockwise():
                outString += "1" + "\n"
            else:
                outString += "0" + "\n"
            i = i + 1

    return outString
Beispiel #14
0
def assign_atom_types(selection='all'):
    """
    TODO document me!

    read http://openbabel.org/dev-api/classOpenBabel_1_1OBAtom.shtml#ae09ed28481ac044dab3f31c8605b44a9
    for available functions provided by openbabel to extract atom properties. There is a GetType() function
    but I found that function very limited.
    """
    atom_types = []
    pdb_string = cmd.get_pdbstr(selection)
    mol = ob.OBMol()
    obconversion = ob.OBConversion()
    obconversion.SetInAndOutFormats('pdb', 'pdb')
    obconversion.ReadString(mol, pdb_string)
    rings = mol.GetSSSR()
    for at in ob.OBMolAtomIter(mol):
        ring_member = [ring.IsMember(at) for ring in rings]
        neighbors = [
            neighbor.GetAtomicNum() for neighbor in ob.OBAtomAtomIter(at)
        ]
        atom_types.append(
            (at.GetIndex(), at.GetAtomicNum(), at.GetHvyValence(),
             any(ring_member), at.IsAromatic(), at.MemberOfRingCount(),
             (neighbors)))
    return atom_types
Beispiel #15
0
def CalculateSymmetry(poltype,pmol, frag_atoms, symmetry_classes):
    """
    Intent: Uses and builds on openbabel's 'GetGIVector' method which,
    "Calculates a set of graph invariant indexes using the graph theoretical distance,
    number of connected heavy atoms, aromatic boolean,
    ring boolean, atomic number, and summation of bond orders connected to the atom", to
    find initial symmetry classes.
    Input: 
        pmol: OBMol object 
        frag_atoms: OBBitVec object containing information about the largest fragment in 'pmol' 
        symmetry_classes: the symmetry_classes array which will be filled in
    Output: 
		nclasses: # of classes
        symmetry_classes: array is filled in
    Referenced By: gen_canonicallabels
    Description:
    1. vectorUnsignedInt object is created, 'vgi'
    2. It is filled in with the call to GetGIVector
    3. The 'symmetry_classes' array is initially filled in to match with 'vgi'
    4. These initial invariant classes do not suit our needs perfectly,
       so the ExtendInvariants method is called to find the more 
       refined classes that we need
    """

    vgi = openbabel.vectorUnsignedInt()
    natoms = pmol.NumAtoms()
    nfragatoms = frag_atoms.CountBits()
    pmol.GetGIVector(vgi)
    iteratom = openbabel.OBMolAtomIter(pmol)
    for atom in iteratom:
        idx = atom.GetIdx()
        if(frag_atoms.BitIsOn(idx)):
            symmetry_classes.append([atom, vgi[idx-1]])
    nclasses = ExtendInvariants(poltype,pmol, symmetry_classes,frag_atoms,nfragatoms,natoms)
    return nclasses
Beispiel #16
0
 def check_charges(
         self,
         negcharges=False):  # negcharges True means that they are allowed
     atoms = list(openbabel.OBMolAtomIter(self.obmol))
     for atom in self.G.nodes:
         a = atom - 1  # G indices are OBMol indices+1
         if self.mapping:  # means OBMol was loaded from G at some point
             a = self.mapping[atom] - 1  # G indices are OBMol indices+1
         if self.G.nodes[atom]['Charge'] > 0:  # iterate thru charged atoms
             if atoms[a].ExplicitHydrogenCount(
             ):  # check if OBMol bonded a hydrogen to the atom to compensate for false charge
                 self.G.nodes[atom]['Charge'] = 0  # reset charge in self.G
                 self.obmol.BeginModify(
                 )  # need this to make changes to existing OBMol object
                 atoms[a].SetFormalCharge(
                     0
                 )  # delete charge (yes this will cause problems for >+1, but best method I could come up with)
                 self.obmol.EndModify(
                 )  # need this to save changes to existing OBMol object
             else:  # set charge to 0, check valences, re-adjust
                 if atoms[a].ImplicitHydrogenCount() > 0:
                     self.G.nodes[atom]['Charge'] = 0
                     self.obmol.BeginModify()
                     atoms[a].SetFormalCharge(0)
                     self.obmol.EndModify()
         if self.G.nodes[atom][
                 'Charge'] < 0 and negcharges is False:  # means we will remove this neg charge
             self.G.nodes[atom]['Charge'] = 0  # set to 0
     self.remove_hydrogens()  # remove hydrogens that aren't needed anymore
     self.update()  # reset OBMol, SMILES, and pybelMol
     return
Beispiel #17
0
def process_types(poltype, mol):
    """
    Intent: Set up scalelist array for scaling certain multipole values
For alchol, the quadrupole on O and H should be mannually scaled by 0.6. This only applies to OH that connect to sp3 Carbon. Similarly for NH in amine (that connects to a sp3 C), scale the Q by 0.75 or 75%. See JCC 2011 32(5):967-77. 
    """
    scalelist = {}
    multipole_scale_dict = {}

    for atm in openbabel.OBMolAtomIter(mol):
        if symm.get_class_number(poltype, atm.GetIdx()) not in scalelist:
            scalelist[symm.get_class_number(poltype, atm.GetIdx())] = []
            scalelist[symm.get_class_number(poltype,
                                            atm.GetIdx())].append(None)
            scalelist[symm.get_class_number(poltype,
                                            atm.GetIdx())].append(None)
            scalelist[symm.get_class_number(poltype,
                                            atm.GetIdx())].append(None)
            multipole_scale_dict = {}

    #multipole_scale_dict['[OH][CX4]'] = [2, 0.6]
    #multipole_scale_dict['[NH2][CX4]'] = [2, 0.75]
    for (sckey, scval) in multipole_scale_dict.items():
        sp = openbabel.OBSmartsPattern()
        openbabel.OBSmartsPattern.Init(sp, sckey)
        match = sp.Match(mol)
        for ia in sp.GetUMapList():
            scalelist[symm.get_class_number(poltype,
                                            ia[0])][scval[0]] = scval[1]

    return scalelist
Beispiel #18
0
 def FitCoords(self, db):
     Fitmol = openbabel.OBMol()
     for f in self.frags:
         # constructing submolecule from the fragment
         efpmol = pyEFP.EFP2mol("./"+db.dirname+"/"+f.ename+"/"+f.fname+".efp")
         # fit atoms from the core lists
         sys.stdout.flush()
         rot, COMRef, COMFit = pyEFP.SolveKabsch(efpmol, f.subMol, f.efpcore, f.molcore)
         f.rotat = [rot, COMRef, COMFit]
         # deleting extra atoms
         complete = 0
         while (complete == 0):
             complete = 1
             for at in openbabel.OBMolAtomIter(efpmol):
                 extra = 0
                 if at.GetIndex()+1 not in f.efpcore:
                     extra = 1
                     for at1 in openbabel.OBAtomAtomIter(at):
                         if (at1.GetIndex()+1 in f.efpcore) and (at.GetAtomicNum() == 1):
                             extra = 0
                             break
                 if (extra == 1):
                     efpmol.DeleteAtom(at)
                     complete = 0
         pyEFP.ApplyKabsch(efpmol, COMFit, COMRef, rot)
         Fitmol += efpmol
     return Fitmol
Beispiel #19
0
def save_structfile(poltype,molstruct, structfname):
    """
    Intent: Output the data in the OBMol structure to a file (such as *.xyz)
    Input:
        molstruct: OBMol structure
        structfname: output file name
    Output:
        file is output to structfname
    Referenced By: tor_opt_sp, compute_mm_tor_energy
    Description: -
    """
    strctext = os.path.splitext(structfname)[1]
    tmpconv = openbabel.OBConversion()
    if strctext in '.xyz':
        tmpfh = open(structfname, "w")
        maxidx =  max(poltype.symmetryclass)
        iteratom = openbabel.OBMolAtomIter(molstruct)
        etab = openbabel.OBElementTable()
        tmpfh.write('%6d   %s\n' % (molstruct.NumAtoms(), molstruct.GetTitle()))
        for ia in iteratom:
            tmpfh.write( '%6d %2s %13.6f %11.6f %11.6f %5d' % (ia.GetIdx(), etab.GetSymbol(ia.GetAtomicNum()), ia.x(), ia.y(), ia.z(), poltype.prmstartidx + (maxidx - poltype.symmetryclass[ia.GetIdx() - 1])))
            iteratomatom = openbabel.OBAtomAtomIter(ia)
            neighbors = []
            for iaa in iteratomatom:
                neighbors.append(iaa.GetIdx())
            neighbors = sorted(neighbors)
            for iaa in neighbors:
                tmpfh.write('%5d' % iaa)
            tmpfh.write('\n')
    else:
        inFormat = openbabel.OBConversion.FormatFromExt(structfname)
        tmpconv.SetOutFormat(inFormat)
    return tmpconv.WriteFile(molstruct, structfname)
Beispiel #20
0
def make_mol_paths(mol, minpath, maxpath, smarts_flag):
    alist = list()
    molpath = list()
    for a in openbabel.OBMolAtomIter(mol):
        if a.GetAtomicNum() < 2: continue  # break path for * or H atom
        make_atom_paths(molpath, alist, a, a, 0, minpath, maxpath, smarts_flag)
        del alist[:]
    return molpath
Beispiel #21
0
def fromOBMol(mol, obmol):
    """
    Convert a OpenBabel Mol object `obmol` to a molecular structure. Uses
    `OpenBabel <http://openbabel.org/>`_ to perform the conversion.
    """
    # Below are the declared variables for cythonizing the module
    # cython.declare(i=cython.int)
    # cython.declare(radicalElectrons=cython.int, charge=cython.int, lonePairs=cython.int)
    # cython.declare(atom=Atom, atom1=Atom, atom2=Atom, bond=Bond)

    mol.vertices = []

    # Add hydrogen atoms to complete molecule if needed
    obmol.AddHydrogens()
    # TODO Chem.rdmolops.Kekulize(obmol, clearAromaticFlags=True)

    # iterate through atoms in obmol
    for obatom in openbabel.OBMolAtomIter(obmol):
        idx = obatom.GetIdx()  #openbabel idx starts at 1!

        # Use atomic number as key for element
        number = obatom.GetAtomicNum()
        element = elements.getElement(number)
        # Process charge
        charge = obatom.GetFormalCharge()
        obatom_multiplicity = obatom.GetSpinMultiplicity()
        radicalElectrons = obatom_multiplicity - 1 if obatom_multiplicity != 0 else 0

        atom = Atom(element, radicalElectrons, charge, '', 0)
        mol.vertices.append(atom)

    # iterate through bonds in obmol
    for obbond in openbabel.OBMolBondIter(obmol):
        order = 0
        # Process bond type
        oborder = obbond.GetBondOrder()
        if oborder == 1: order = 'S'
        elif oborder == 2: order = 'D'
        elif oborder == 3: order = 'T'
        elif obbond.IsAromatic(): order = 'B'

        bond = Bond(mol.vertices[obbond.GetBeginAtomIdx() - 1],
                    mol.vertices[obbond.GetEndAtomIdx() - 1],
                    order)  #python array indices start at 0
        mol.addBond(bond)

    # Set atom types and connectivity values
    mol.updateConnectivityValues()
    mol.updateAtomTypes()
    mol.updateMultiplicity()
    mol.updateLonePairs()

    # Assume this is always true
    # There are cases where 2 radicalElectrons is a singlet, but
    # the triplet is often more stable,
    mol.multiplicity = mol.getRadicalCount() + 1

    return mol
Beispiel #22
0
def from_ob_mol(mol, obmol, raise_atomtype_exception=True):
    """
    Convert a OpenBabel Mol object `obmol` to a molecular structure. Uses
    `OpenBabel <http://openbabel.org/>`_ to perform the conversion.
    """
    # Below are the declared variables for cythonizing the module
    # cython.declare(i=cython.int)
    # cython.declare(radical_electrons=cython.int, charge=cython.int, lone_pairs=cython.int)
    # cython.declare(atom=mm.Atom, atom1=mm.Atom, atom2=mm.Atom, bond=mm.Bond)
    if openbabel is None:
        raise DependencyError(
            'OpenBabel is not installed. Please install or use RDKit.')

    mol.vertices = []

    # Add hydrogen atoms to complete molecule if needed
    obmol.AddHydrogens()
    # TODO Chem.rdmolops.Kekulize(obmol, clearAromaticFlags=True)

    # iterate through atoms in obmol
    for obatom in openbabel.OBMolAtomIter(obmol):
        # Use atomic number as key for element
        number = obatom.GetAtomicNum()
        isotope = obatom.GetIsotope()
        element = elements.get_element(number, isotope or -1)
        # Process charge
        charge = obatom.GetFormalCharge()
        obatom_multiplicity = obatom.GetSpinMultiplicity()
        radical_electrons = obatom_multiplicity - 1 if obatom_multiplicity != 0 else 0

        atom = mm.Atom(element, radical_electrons, charge, '', 0)
        mol.vertices.append(atom)

    # iterate through bonds in obmol
    for obbond in openbabel.OBMolBondIter(obmol):
        # Process bond type
        oborder = obbond.GetBondOrder()
        if oborder not in [1, 2, 3, 4] and obbond.IsAromatic():
            oborder = 1.5

        bond = mm.Bond(mol.vertices[obbond.GetBeginAtomIdx() - 1],
                       mol.vertices[obbond.GetEndAtomIdx() - 1],
                       oborder)  # python array indices start at 0
        mol.add_bond(bond)

    # Set atom types and connectivity values
    mol.update_connectivity_values()
    mol.update_atomtypes(log_species=True,
                         raise_exception=raise_atomtype_exception)
    mol.update_multiplicity()
    mol.identify_ring_membership()

    # Assume this is always true
    # There are cases where 2 radical_electrons is a singlet, but
    # the triplet is often more stable,
    mol.multiplicity = mol.get_radical_count() + 1

    return mol
Beispiel #23
0
 def testIterators(self):
     """Basic check that at least two iterators are working"""
     mol = pybel.readstring("smi", "c1ccccc1C(=O)Cl")
     atoms = list(ob.OBMolAtomIter(mol.OBMol))
     self.assertEqual(len(atoms), 9)
     elements = [atom.GetAtomicNum() for atom in atoms]
     self.assertEqual(elements, [6, 6, 6, 6, 6, 6, 6, 8, 17])
     bonds = list(ob.OBMolBondIter(mol.OBMol))
     self.assertEqual(len(bonds), 9)
    def minimization(self, options=[]):
        temp1 = tempfile.NamedTemporaryFile(suffix='.pdb')
        temp2 = tempfile.NamedTemporaryFile(suffix='.pdb')
        bufMol = ob.OBMol()
        obConversion = ob.OBConversion()
        obConversion.SetInAndOutFormats('pdb', 'pdb')
        obConversion.WriteFile(self.molecule, temp1.name)
        popenargs = ['obminimize'] + options + [temp1.name]
        subprocess.run(popenargs, stdout=temp2)
        obConversion.ReadFile(bufMol, temp2.name)
        temp1.close()
        temp2.close()

        # Update coordinates
        pairs = zip(ob.OBMolAtomIter(self.molecule), ob.OBMolAtomIter(bufMol))
        for (ai, aj) in pairs:
            x, y, z = aj.x(), aj.y(), aj.z()
            ai.SetVector(x, y, z)
Beispiel #25
0
 def get_coordinates(self):
     if self._coords is None:
         self._coords = numpy.zeros((self.natoms, 3))
         for at in openbabel.OBMolAtomIter(self.obmol):
             i = at.GetIdx() - 1
             self._coords[i, 0] = at.GetX()
             self._coords[i, 1] = at.GetY()
             self._coords[i, 2] = at.GetZ()
     return self._coords
Beispiel #26
0
def get_binder_atom(binder, smarts):
    log.debug("Counting atoms to find the binder atom...")
    i = 1
    for atom in openbabel.OBMolAtomIter(binder):
        log.debug(i)
        i += 1
        if atom.MatchesSMARTS(smarts):
            log.debug("found ya!")
            return atom
Beispiel #27
0
    def skelCN_groups(self, res):

        groupnames = [
            'NCA0', 'HA0', 'CO0', 'H+1', 'NCA+1', 'HA+1', 'CHB+1', 'CO+1',
            'H+2', 'NCA+2', 'R'
        ]
        groups = []

        for k in groupnames:
            groups.append([])
        for at in openbabel.OBMolAtomIter(self.obmol):
            attype = at.GetResidue().GetAtomID(at)
            attype = attype.strip()

            rnum = at.GetResidue().GetNum()

            if attype in ['1HB', '2HB', '3HB', 'HB1', 'HB2', 'HB3']:
                attype = 'HB'

            if rnum == res:
                if attype in ['C', 'O']:
                    attype = 'CO0'
                elif attype in ['N', 'CA']:
                    attype = 'NCA0'
                elif attype in ['HA']:
                    attype = 'HA0'
                else:
                    attype = 'R'
            elif rnum == res + 1:
                if attype in ['H']:
                    attype = 'H+1'
                elif attype in ['C', 'O']:
                    attype = 'CO+1'
                elif attype in ['N', 'CA']:
                    attype = 'NCA+1'
                elif attype in ['HA']:
                    attype = 'HA+1'
                elif attype in ['CB', 'HB']:
                    attype = 'CHB+1'
            elif rnum == res + 2:
                if attype in ['H']:
                    attype = 'H+2'
                elif attype in ['N', 'CA']:
                    attype = 'NCA+2'
                else:
                    attype = 'R'
            else:
                attype = 'R'

            try:
                ind = groupnames.index(attype)
            except ValueError:
                print attype
                raise
            groups[ind].append(at.GetIdx() - 1)

        return groups, groupnames
Beispiel #28
0
def _compute_all_sybyl(system_ob, indices=None):
    sybyl_dict = {}

    for atom in ob.OBMolAtomIter(system_ob):
        if indices is not None and atom.GetIndex() not in indices:
            continue
        sybyl_dict[atom.GetIndex()] = atom.GetType()

    return (sybyl_dict)
Beispiel #29
0
def chain_ffopt(ff, mol, frozenats):
    ### FORCE FIELD OPTIMIZATION ##
    # INPUT
    #   - ff: force field to use, available MMFF94, UFF< Ghemical, GAFF
    #   - mol: mol3D to be ff optimized
    #   - connected: indices of connection atoms to metal
    #   - constopt: flag for constrained optimization
    # OUTPUT
    #   - mol: force field optimized mol3D
    metals = range(21, 31) + range(39, 49) + range(72, 81)
    ### check requested force field
    ffav = 'mmff94, uff, ghemical, gaff, mmff94s'  # force fields
    if ff.lower() not in ffav:
        print 'Requested force field not available. Defaulting to MMFF94'
        ff = 'mmff94'
    ### convert mol3D to OBMol via xyz file, because AFTER/END option have coordinates
    backup_mol = mol3D()
    backup_mol.copymol3D(mol)
    #   print('bck ' + str(backup_mol.getAtom(0).coords()))
    #   print('mol_ibf ' + str(mol.getAtom(0).coords()))
    mol.convert2OBMol()
    ### initialize constraints
    constr = openbabel.OBFFConstraints()
    ### openbabel indexing starts at 1 ### !!!
    # convert metals to carbons for FF
    indmtls = []
    mtlsnums = []
    for iiat, atom in enumerate(openbabel.OBMolAtomIter(OBMol)):
        if atom.atomicnum in metals:
            indmtls.append(iiat)
            mtlsnums.append(atom.GetAtomicNum())
            atom.OBAtom.SetAtomicNum(19)
    for cat in frozenats:
        constr.AddAtomConstraint(cat + 1)  # indexing babel
    ### set up forcefield
    forcefield = openbabel.OBForceField.FindForceField(ff)
    OBMol = mol.OBMol
    forcefield.Setup(obmol, constr)
    ## force field optimize structure
    forcefield.ConjugateGradients(2500)
    forcefield.GetCoordinates(OBMol)
    mol.OBMol = OBMol

    # reset atomic number to metal
    for i, iiat in enumerate(indmtls):
        mol.OBMol.GetAtomById(iiat).SetAtomicNum(mtlsnums[i])
    mol.convert2mol3D()

    en = forcefield.Energy()
    #   print(str(mol.OBmol.atoms[1].OBAtom.GetVector().GetZ()))
    #    print(str(forcefield.Validate()))
    # print('mol_af ' + str(mol.getAtom(0).coords()))

    #  print('ff delta = ' + str(backup_mol.rmsd(mol)))
    del forcefield, constr, OBMol
    return mol, en
Beispiel #30
0
 def pymatgen_mol(self):
     """
     Returns pymatgen Molecule object.
     """
     sp = []
     coords = []
     for atom in ob.OBMolAtomIter(self._obmol):
         sp.append(atom.GetAtomicNum())
         coords.append([atom.GetX(), atom.GetY(), atom.GetZ()])
     return Molecule(sp, coords)