Exemple #1
0
def GetDihedralHs(atom):
    sp3carbonFound = False
    #find the proton neigbour, check that it is sp3 carbon
    for NbrAtom in OBAtomAtomIter(atom):
        if NbrAtom.GetAtomicNum() == 6 and NbrAtom.GetHyb() == 3:
            carbon = NbrAtom
            sp3carbonFound = True
            break

    if not sp3carbonFound:
        return 0
    #find the carbon neibours, check that they are sp3 hybridized
    ncarbons = []
    for NbrAtom in OBAtomAtomIter(carbon):
        if NbrAtom.GetAtomicNum() == 6 and NbrAtom.GetHyb() == 3:
            ncarbons.append(NbrAtom)
    #check that the carbon neighbours have protons and return them
    nHs = []
    for ncarbon in ncarbons:
        for NbrAtom in OBAtomAtomIter(ncarbon):
            if NbrAtom.GetAtomicNum() == 1:
                nHs.append(NbrAtom.GetIdx())

    if len(nHs) == 0:
        return 0
    else:
        return nHs
def methyl_protons(file):

    obconversion = OBConversion()
    obconversion.SetInFormat("sdf")
    obmol = OBMol()
    obconversion.ReadFile(obmol, file)

    methyl_protons = []

    for atom in OBMolAtomIter(obmol):

        count = 0

        nbrprotons = []

        for NbrAtom in OBAtomAtomIter(atom):

            if (atom.GetAtomicNum() == 6) & (NbrAtom.GetAtomicNum() == 1):

                l = NbrAtom.GetIndex()

                count += 1

                nbrprotons.append('H' + str(l + 1))

        if count == 3:
            methyl_protons.append(nbrprotons)

    return methyl_protons
def remove_labile_protons(sdffile, lbls, shifts):

    f = sdffile.split('.sdf')[0] + '.sdf'

    obconversion = OBConversion()
    obconversion.SetInFormat("sdf")
    obmol = OBMol()
    obconversion.ReadFile(obmol, f)

    CI = []

    for atom in OBMolAtomIter(obmol):

        if atom.GetAtomicNum() == 1:

            for NbrAtom in OBAtomAtomIter(atom):

                if (NbrAtom.GetAtomicNum() == 8):
                    CI.append('H' + str(atom.GetIndex() + 1))

    #remove these carbons

    for C in CI:

        ind = lbls.index(C)

        lbls.remove(C)

        for l in shifts:
            l.pop(ind)

    return lbls, shifts
Exemple #4
0
def FindSubstAtoms(atom, outAtom, al):

    indexes = [a.GetIdx() for a in al]
    for NbrAtom in OBAtomAtomIter(atom):

        if (NbrAtom.GetIdx() not in indexes) and\
                (NbrAtom.GetIdx() != outAtom.GetIdx()):
            al.append(NbrAtom)
            FindSubstAtoms(NbrAtom, outAtom, al)
Exemple #5
0
def RestoreNumsSDF(f, fold, AuxInfo):

    #Read molecule from file
    obconversion = OBConversion()
    obconversion.SetInFormat("sdf")
    obmol = OBMol()
    obconversion.ReadFile(obmol, f)
    #Get the atoms Hs are connected to
    oldHcons = GetHcons(fold)
    #translate the H connected atoms to the new numbering system
    amap = GetInchiRenumMap(AuxInfo)
    for i in range(0, len(oldHcons)):
        oldHcons[i][1] = amap.index(oldHcons[i][1]) + 1

    newHcons = []
    temp = []
    i = 0
    for atom in OBMolAtomIter(obmol):
        idx = atom.GetIdx()
        anum = atom.GetAtomicNum()
        #If atom is hydrogen, check what it is connected to
        if anum == 1:
            for NbrAtom in OBAtomAtomIter(atom):
                newHcons.append([idx, NbrAtom.GetIdx()])
        #Pick the temporary atom
        temp.append(atom)

    for i in range(0, len(newHcons)):
        conatom = newHcons[i][1]
        for b in range(0, len(oldHcons)):
            if conatom == oldHcons[b][1]:
                amap.append(oldHcons[b][0])
                #remove the number, so that it doesn't get added twice
                oldHcons[b][1] = 0

    newmol = OBMol()
    added = []

    for i in range(1, len(amap) + 1):
        newn = amap.index(i)
        newmol.AddAtom(temp[newn])
        added.append(newn)

    #Final runthrough to check that all atoms have been added,
    #tautomeric protons can be missed. If tautomeric proton tracking
    #is implemented this can be removed
    for i in range(0, len(temp)):
        if not i in added:
            newmol.AddAtom(temp[i])

    #Restore the bonds
    newmol.ConnectTheDots()
    newmol.PerceiveBondOrders()
    #Write renumbered molecule to file
    obconversion.SetOutFormat("sdf")
    obconversion.WriteFile(newmol, f)
Exemple #6
0
def GetENCorrection(atom, satom):
    Anum = atom.GetAtomicNum()
    if Anum != 6:
        return ENs[Anum - 1] - ENs[0], 0.0
    else:
        ENcorr = 0.0
        for NbrAtom in OBAtomAtomIter(atom):
            if NbrAtom.GetIdx() != satom.GetIdx():
                neighbAnum = NbrAtom.GetAtomicNum()
                ENcorr += ENs[neighbAnum - 1] - ENs[0]

        return ENs[Anum - 1] - ENs[0], ENcorr
Exemple #7
0
def GetHcons(f):
    obconversion = OBConversion()
    obconversion.SetInFormat("sdf")
    obmol = OBMol()
    obconversion.ReadFile(obmol, f)
    Hcons = []
    for atom in OBMolAtomIter(obmol):
        idx = atom.GetIdx()
        anum = atom.GetAtomicNum()
        if anum == 1:
            for NbrAtom in OBAtomAtomIter(atom):
                Hcons.append([idx, NbrAtom.GetIdx()])
    return Hcons
def labile_protons(file):
    obconversion = OBConversion()
    obconversion.SetInFormat("sdf")
    obmol = OBMol()
    obconversion.ReadFile(obmol, file)

    count = 0

    for atom in OBMolAtomIter(obmol):
        for NbrAtom in OBAtomAtomIter(atom):
            if (atom.GetAtomicNum() == 8) & (NbrAtom.GetAtomicNum() == 1):
                count += 1

    return count
Exemple #9
0
def pication(rings, pos_charged, protcharged):
    """Return all pi-Cation interaction between aromatic rings and positively charged groups.
    For tertiary and quaternary amines, check also the angle between the ring and the nitrogen.
    """
    data = namedtuple(
        'pication', 'ring charge distance offset type restype resnr reschain restype_l resnr_l reschain_l protcharged')
    pairings = []
    if len(rings) == 0 or len(pos_charged) == 0:
        return pairings
    for ring in rings:
        c = ring.center
        for p in pos_charged:
            d = euclidean3d(c, p.center)
            # Project the center of charge into the ring and measure distance to ring center
            proj = projection(ring.normal, ring.center, p.center)
            offset = euclidean3d(proj, ring.center)
            if not config.MIN_DIST < d < config.PICATION_DIST_MAX or not offset < config.PISTACK_OFFSET_MAX:
                continue
            if type(p).__name__ == 'lcharge' and p.fgroup == 'tertamine':
                # Special case here if the ligand has a tertiary amine, check an additional angle
                # Otherwise, we might have have a pi-cation interaction 'through' the ligand
                n_atoms = [a_neighbor for a_neighbor in OBAtomAtomIter(p.atoms[0].OBAtom)]
                n_atoms_coords = [(a.x(), a.y(), a.z()) for a in n_atoms]
                amine_normal = np.cross(vector(n_atoms_coords[0], n_atoms_coords[1]),
                                        vector(n_atoms_coords[2], n_atoms_coords[0]))
                b = vecangle(ring.normal, amine_normal)
                # Smallest of two angles, depending on direction of normal
                a = min(b, 180 - b if not 180 - b < 0 else b)
                if not a > 30.0:
                    resnr, restype = whichresnumber(ring.atoms[0]), whichrestype(ring.atoms[0])
                    reschain = whichchain(ring.atoms[0])
                    resnr_l, restype_l = whichresnumber(p.orig_atoms[0]), whichrestype(p.orig_atoms[0])
                    reschain_l = whichchain(p.orig_atoms[0])
                    contact = data(ring=ring, charge=p, distance=d, offset=offset, type='regular',
                                   restype=restype, resnr=resnr, reschain=reschain,
                                   restype_l=restype_l, resnr_l=resnr_l, reschain_l=reschain_l,
                                   protcharged=protcharged)
                    pairings.append(contact)
                break
            resnr = whichresnumber(p.atoms[0]) if protcharged else whichresnumber(ring.atoms[0])
            resnr_l = whichresnumber(ring.orig_atoms[0]) if protcharged else whichresnumber(p.orig_atoms[0])
            restype = whichrestype(p.atoms[0]) if protcharged else whichrestype(ring.atoms[0])
            restype_l = whichrestype(ring.orig_atoms[0]) if protcharged else whichrestype(p.orig_atoms[0])
            reschain = whichchain(p.atoms[0]) if protcharged else whichchain(ring.atoms[0])
            reschain_l = whichchain(ring.orig_atoms[0]) if protcharged else whichchain(p.orig_atoms[0])
            contact = data(ring=ring, charge=p, distance=d, offset=offset, type='regular', restype=restype,
                           resnr=resnr, reschain=reschain, restype_l=restype_l, resnr_l=resnr_l,
                           reschain_l=reschain_l, protcharged=protcharged)
            pairings.append(contact)
    return filter_contacts(pairings)
Exemple #10
0
def FixTautProtons(f, inchi, AuxInfo):

    #Get tautomeric protons and atoms they are connected to from Inchi
    TautProts = GetTautProtons(inchi)
    amap = GetInchiRenumMap(AuxInfo)

    #get the correspondence of the Inchi numbers to the source numbers
    hmap = []
    for taut in TautProts:
        for heavyatom in range(1, len(taut)):
            hmap.append([int(taut[heavyatom]), amap[int(taut[heavyatom]) - 1]])

    #Read molecule from file
    obconversion = OBConversion()
    obconversion.SetInFormat("sdf")
    obmol = OBMol()
    obconversion.ReadFile(obmol, f)

    Fixprotpos = []
    for heavyatom in hmap:
        atom = obmol.GetAtom(heavyatom[1])
        for nbratom in OBAtomAtomIter(atom):
            if nbratom.GetAtomicNum() == 1:
                Fixprotpos.append(heavyatom[0])
    draftFH = []
    for i in range(0, len(Fixprotpos)):
        if Fixprotpos[i] not in [a[0] for a in draftFH]:
            draftFH.append([Fixprotpos[i], Fixprotpos.count(Fixprotpos[i])])

    fixedlayer = '/f/h'
    for h in draftFH:
        if h[1] == 1:
            fixedlayer = fixedlayer + str(h[0]) + 'H,'
        else:
            fixedlayer = fixedlayer + str(h[0]) + 'H' + str(h[1]) + ','

    resinchi = inchi + fixedlayer[:-1]

    return resinchi
Exemple #11
0
 def neighbors(self):
     return [Atom(a) for a in OBAtomAtomIter(self.OBAtom)]
Exemple #12
0
def CalcJ(atom1, atom2):

    #Get the 2 carbon atoms joining the protons
    for NbrAtom in OBAtomAtomIter(atom1):
        if NbrAtom.GetAtomicNum() == 6 and NbrAtom.GetHyb() == 3:
            carbon1 = NbrAtom
            break
    for NbrAtom in OBAtomAtomIter(atom2):
        if NbrAtom.GetAtomicNum() == 6 and NbrAtom.GetHyb() == 3:
            carbon2 = NbrAtom
            break
    #Get the 2 planes formed by the carbons and each of the protons
    normal1, d = FindPlane(carbon1, atom1, carbon2)
    normal2, d = FindPlane(carbon2, atom2, carbon1)

    sign = VectAngleSign(BondVect(carbon1, atom1), BondVect(carbon2, atom2),
                         BondVect(carbon1, carbon2))
    angle = VectorAngle(normal1, normal2)
    if dotproduct(BondVect(carbon1, atom1), BondVect(carbon2, atom2)) > 0 and \
        angle < 0.5*pi:
        dihedral = angle * sign
    else:
        dihedral = (pi - angle) * sign

    #Count the substituents, get their electronegativities
    nSubst = 0
    relENs = []
    ENcorrs = []
    signs = []

    for NbrAtom in OBAtomAtomIter(carbon1):
        ANum = NbrAtom.GetAtomicNum()
        if NbrAtom.GetIdx() != carbon2.GetIdx() and ANum != 1:
            nSubst += 1
            relEN, ENcorr = GetENCorrection(NbrAtom, carbon1)
            relENs.append(relEN)
            ENcorrs.append(ENcorr)
            signs.append(
                VectAngleSign(BondVect(carbon1, atom1),
                              BondVect(carbon1, NbrAtom),
                              BondVect(carbon1, carbon2)))

    for NbrAtom in OBAtomAtomIter(carbon2):
        ANum = NbrAtom.GetAtomicNum()
        if NbrAtom.GetIdx() != carbon1.GetIdx() and ANum != 1:
            nSubst += 1
            relEN, ENcorr = GetENCorrection(NbrAtom, carbon2)
            relENs.append(relEN)
            ENcorrs.append(ENcorr)
            signs.append(
                VectAngleSign(BondVect(carbon2, atom2),
                              BondVect(carbon2, NbrAtom),
                              BondVect(carbon2, carbon1)))

    SubstEffects = 0
    if nSubst < 2:
        for relEN, ENcorr, sign in zip(relENs, ENcorrs, signs):
            corrRelEN = relEN - (Params[0][6]) * ENcorr
            SubstEffects += SubstEffect(dihedral, corrRelEN, sign, 0)

        J = Params[0][0] * cos(dihedral)**2 + Params[0][1] * cos(dihedral)
    else:
        for relEN, sign in zip(relENs, signs):
            corrRelEN = relEN - (Params[nSubst - 1][6]) * ENcorr
            SubstEffects += SubstEffect(dihedral, corrRelEN, sign, nSubst - 1)

        J = Params[nSubst - 1][0] * cos(dihedral)**2 + Params[
            nSubst - 1][1] * cos(dihedral)

    return J + SubstEffects
Exemple #13
0
def mol_fragments(mole,outfile):

    obconv = OBConversion()

    obconv.SetOutFormat("xyz")

    c = 1

    for atom, exp,dft,diff in zip(OBMolAtomIter(mole)):

        # if this is a carbon atom start a breadth first search for other carbon atoms with depth specified

        # create a new mol instance

        new_mol = OBMol()

        # add this atom

        # new_mol.AddAtom(atom)

        fragment_ind = []

        l = atom.GetIndex()

        fragment_ind.append(l)

        # for iteration depth radius

        old_queue = [atom]

        for iteration in range(0, 3):

            new_queue = []

            for a in old_queue:

                for atom2 in OBAtomAtomIter(a):

                    i = atom2.GetIndex()

                    # if the atom has not been seen before add it to the fragment ind list and to the new molecule

                    if i not in fragment_ind:
                        new_queue.append(atom2)

                        fragment_ind.append(i)

                        # new_mol.AddAtom(atom2)

            old_queue = copy.copy(new_queue)

        fragment_ind = [fragment_ind[0]] + sorted(fragment_ind[1:])

        for i in fragment_ind:

            for a in OBMolAtomIter(mole):

                if a.GetIndex() == i:
                    new_mol.AddAtom(a)

        f = open(outfile + "frag" + str(l).zfill(3) + ".xyz", "w+")

        f.write(str(new_mol.NumAtoms()) + "\n\n")

        i = 0

        for atom in OBMolAtomIter(new_mol):

            f.write(atom.GetType()[0] + " " + str(atom.GetX()) + " " + str(atom.GetY()) + " " + str(
                atom.GetZ()) + "\n")


            i+=1

        f.close()

        c += 1
Exemple #14
0
def main(f, settings):
    """
    Find the axis atoms
    Find all the atoms to be rotated

    Rotate it and the substituents to the other side of the plane
    """
    obconversion = OBConversion()
    obconversion.SetInFormat("sdf")
    obmol = OBMol()

    obconversion.ReadFile(obmol, f)

    obmol.ConnectTheDots()

    #Find the atoms composing furan ring
    Rings = obmol.GetSSSR()
    furan = []
    for ring in Rings:
        if len(settings.RingAtoms) == 5:
            if all(x in ring._path for x in settings.RingAtoms):
                furan = ring
                break
        else:
            if ring.Size() == 5 and not ring.IsAromatic():
                furan = ring
                break

    if furan == []:
        "No five membered rings to rotate. Quitting..."
        quit()
    #Find the plane of the 5-membered ring and the outlying atom
    norm, d, outAtom = FindFuranPlane(obmol, furan)

    #Find the atoms connected to the outlying atom and sort them
    #as either part of the ring(axis atoms) or as atoms to be rotated
    AxisAtoms = []
    RotAtoms = []

    for NbrAtom in OBAtomAtomIter(outAtom):
        #if NbrAtom.IsInRingSize(5):
        if furan.IsInRing(NbrAtom.GetIdx()):
            AxisAtoms.append(NbrAtom)
        else:
            RotAtoms.append(NbrAtom)
            FindSubstAtoms(NbrAtom, outAtom, RotAtoms)

    #Simple switch to help detect if the atoms are rotated the right way
    WasAbove90 = False
    angle = FindRotAngle(AxisAtoms[0], AxisAtoms[1], outAtom, norm)
    if angle > 0.5 * pi:
        WasAbove90 = True
        rotangle = 2 * (angle - 0.5 * pi)
    else:
        WasAbove90 = False
        rotangle = 2 * (0.5 * pi - angle)
    OldAtomCoords = outAtom.GetVector()
    print("Atom " + str(outAtom.GetAtomicNum()) + " will be rotated by " +\
        str(rotangle*57.3) + ' degrees')
    RotateAtom(outAtom, AxisAtoms[0], AxisAtoms[1], rotangle)
    angle2 = FindRotAngle(AxisAtoms[0], AxisAtoms[1], outAtom, norm)

    #if the atom is on the same side of the plane as it was,
    # it has been rotated in the wrong direction
    if ((angle2 > 0.5 * pi) and WasAbove90) or ((angle2 < 0.5 * pi)
                                                and not WasAbove90):
        #Flip the sign of the rotation angle, restore the coords
        #and rotate the atom in the opposite direction
        print("Atom was rotated the wrong way, switching the direction")
        rotangle = -rotangle
        outAtom.SetVector(OldAtomCoords)
        RotateAtom(outAtom, AxisAtoms[0], AxisAtoms[1], rotangle)

    RotatedAtoms = []  # Index to make sure that atoms are not rotated twice
    for atom in RotAtoms:
        if atom not in RotatedAtoms:
            RotateAtom(atom, AxisAtoms[0], AxisAtoms[1], rotangle)
            RotatedAtoms.append(atom)
        else:
            print("Atom already rotated, skipping")

    obconversion.SetOutFormat("sdf")
    obconversion.WriteFile(obmol, f[:-4] + 'rot.sdf')