def calcOmega(piAcidCentroid, piResCentroid):
    cent1cent2Vec = np.array(piResCentroid["coords"]) - np.array(
        piAcidCentroid["coords"])
    cent1cent2Vec = normalize(cent1cent2Vec)

    planeNormVec = np.cross(cent1cent2Vec, piAcidCentroid["normVec"])
    planeNormVec = normalize(planeNormVec)

    return degrees(acos(np.inner(planeNormVec, piResCentroid["normVec"])))
Ejemplo n.º 2
0
def isFlat(allAtomsList, atomsIndList, substituents):
    """
    Sprawdz czy wybrane atomy leza w jednej plaszczyznie.
    Procedura: na podstawie polozen trzech pierwszych atomow wyznacza sie 
    wektor normalnych do wyznaczonej przez nich plaszczyzny. Nastepnie 
    sprawdzane jest czy kolejne wiazania tworza wektory prostopadle
    do wektora normalnego. Dopuszczalne jest odchylenie 5 stopni.
    
    TODO: Nie lepiej byloby obliczyc tensor momentu bezwladnosci, 
    zdiagonalizowac go i rozstrzygnac na podstawie jego wartosci wlasnych?
    
    Wejscie:
    allAtomsList - lista obiektow Atom (cala czasteczka)
    atomsIndList - lista indeksow atomow, ktore maja byc zweryfikowane
                    pod wzgledem lezenia w jednej plaszczyznie
                    
    Wyjscie:
    verdict - slownik, posiada klucze: isFlat (zmienna logiczna, True jesli
                struktura jest plaska), normVec (3-elementowa lista float,
                wspolrzedne wektora normalnego plaszczyzny, jesli struktura nie
                jest plaska wszystkie jego wspolrzedne sa rowne 0)
    """

    verdict = {'isFlat': False, 'normVec': [0, 0, 0]}

    if len(atomsIndList) < 3:
        print("Znaleziono 2-wu elementowy cykl!!!")
        return verdict

    norm_vec = getNormVec(allAtomsList, atomsIndList)

    if len(atomsIndList) <= 3:
        verdict['normVec'] = norm_vec
        return verdict

    centroid = getAverageCoords(allAtomsList, atomsIndList)
    for i in range(1, len(atomsIndList)):
        atomInd = atomsIndList[i]
        D = np.array(allAtomsList[atomInd].get_coord())
        new_vec = normalize(centroid - D)

        if abs(np.inner(new_vec, norm_vec)) > 0.09:
            return verdict

    for substituentKey in substituents:
        D = np.array(allAtomsList[substituentKey].get_coord())
        E = np.array(allAtomsList[substituents[substituentKey]].get_coord())
        new_vec = normalize(E - D)

        if abs(np.inner(new_vec, norm_vec)) > 0.20:
            return verdict

    verdict['isFlat'] = True
    verdict['normVec'] = norm_vec
    verdict['coords'] = centroid
    return verdict
Ejemplo n.º 3
0
def getNormVec(allAtomsList, atomsIndList):
    norm_vec = np.array([0., 0., 0.])
    expanded_list = atomsIndList + atomsIndList[:2]
    for i in range(len(expanded_list) - 2):
        A = np.array(allAtomsList[expanded_list[i]].get_coord())
        B = np.array(allAtomsList[expanded_list[i + 1]].get_coord())
        C = np.array(allAtomsList[expanded_list[i + 2]].get_coord())

        vec1 = A - B
        vec2 = B - C

        norm_vec += normalize(np.cross(vec1, vec2))

    return normalize(norm_vec)
    def writeAnionPiLinearResults(self,
                                  ligand,
                                  centroid,
                                  lineData,
                                  modelIndex,
                                  anionGroupId,
                                  symmetrizeAlpha=False):
        resultsFileName = self.linearAnionPiLog

        ligandCode = ligand.get_resname()
        ligandId = str(ligand.get_id()[1])
        ligandChain = ligand.get_parent().get_id()
        resultsFile = open(resultsFileName, "a+")

        vector = lineData.atomsInvolved[1].get_coord(
        ) - lineData.atomsInvolved[0].get_coord()
        vector = normalize(vector)

        inner_prod = np.inner(vector, centroid["normVec"])
        if abs(inner_prod) > 1.0:
            if abs(inner_prod) < 1.1:
                angle = 0
            else:
                angle = 666
        else:
            angle = degrees(acos(inner_prod))

        if symmetrizeAlpha and angle > 90.0:
            angle = 180 - angle

        atom = lineData.atomsInvolved[0]
        anion = atom.get_parent()
        residueName = anion.get_resname()
        anionChain = anion.get_parent().get_id()
        anionId = str(anion.get_id()[1])
        centroidCoords = centroid["coords"]
        anionGroupCoords = getAverageCoords(
            lineData.atomsInvolved, list(range(len(lineData.atomsInvolved))))

        resultsFile.write(self.pdbCode + "\t")
        resultsFile.write(ligandCode + "\t")
        resultsFile.write(ligandChain + "\t")
        resultsFile.write(ligandId + "\t")
        resultsFile.write(str(centroid["cycleId"]) + "\t")
        resultsFile.write(residueName + "\t")
        resultsFile.write(anionChain + "\t")
        resultsFile.write(anionId + "\t")
        resultsFile.write(str(anionGroupId) + "\t")
        resultsFile.write(str(angle) + "\t")

        resultsFile.write(str(centroidCoords[0]) + "\t")
        resultsFile.write(str(centroidCoords[1]) + "\t")
        resultsFile.write(str(centroidCoords[2]) + "\t")

        resultsFile.write(str(anionGroupCoords[0]) + "\t")
        resultsFile.write(str(anionGroupCoords[1]) + "\t")
        resultsFile.write(str(anionGroupCoords[2]) + "\t")

        resultsFile.write(str(modelIndex) + "\n")
        resultsFile.close()
def angleNormVecPoint(centroid, point):
    coords = np.array(point)
    centroidCoords = np.array(centroid["coords"])
    normVec = centroid["normVec"]

    centrAtomVec = normalize(coords - centroidCoords)
    inner_prod = np.inner(normVec, centrAtomVec)

    return degrees(acos(inner_prod))
def calcDirectionalVector(planeData, centroid):
    vecCoords = []
    for pointData in planeData.directionalVector:
        kind = list(pointData.keys())[0]
        if kind == "atom":
            vecCoords.append(pointData[kind].get_coord())
        elif kind == "center":
            atomsList = pointData[kind]
            vecCoords.append(
                getAverageCoords(atomsList, list(range(len(atomsList)))))
        elif kind == "closest":
            atomsList = pointData[kind]

            minDist = 1000
            closestAtom = None

            for atom in atomsList:
                dist = atomDistanceFromCentroid(atom, centroid)

                if dist < minDist:
                    minDist = dist
                    closestAtom = atom

            vecCoords.append(closestAtom.get_coord())

    vec = normalize(vecCoords[1] - vecCoords[0])
    vec2 = normalize(np.array(centroid["coords"]) - vecCoords[1])

    inner_prod = np.inner(vec, vec2)
    if abs(inner_prod) > 1.0:
        if abs(inner_prod) < 1.1:
            return 0.0
        else:
            return 666.0

    return degrees(acos(inner_prod))
    def trigonal(self, atom):
        number_of_protons_to_add = self.moleculeGraph.nodes[atom]["number_of_protons_to_add"]
        
        if number_of_protons_to_add == 0:
            return
        
        rot_angle = math.radians(120.0)
        bonded_atoms_ids = list(self.moleculeGraph.neighbors(atom))
        
        if len(bonded_atoms_ids) == 0:
            return

        if len(bonded_atoms_ids) == 1:
            A = self.atomList[atom].get_coord()
            B = self.atomList[ bonded_atoms_ids[0] ].get_coord()
            
            Bneighbors = list(self.moleculeGraph.neighbors(bonded_atoms_ids[0]))
            for cCandidate in Bneighbors:
                if cCandidate != atom and self.atomList[cCandidate].element in [ "N" , "C" ]:
                    C = self.atomList[cCandidate].get_coord()
                    norm_vec = -normalize(np.cross(A-B, B-C))
                    break
            else:
                norm_vec = normalize( np.cross( B-A, self.anionCoords - A ) )
#                norm_vec = get_ortonormal(B-A)
            
            bondDirection = B-A
            for i in range(number_of_protons_to_add):
                bondDirection = rotateVector(bondDirection, norm_vec, rot_angle)
                bondDirection = normalize(bondDirection)* self.bond_lengths[ self.atomList[atom].element ]
                
                newAtomCoords = A + bondDirection
                self.hydrogenAtomsList.append(HydrogenAtom(newAtomCoords))
                self.connected2H.append(atom)
                
        elif len(bonded_atoms_ids) == 2:
            A = self.atomList[atom].get_coord()
            B = self.atomList[ bonded_atoms_ids[0] ].get_coord()
            C = self.atomList[ bonded_atoms_ids[1] ].get_coord()
            
            AB = normalize(B-A)
            AC = normalize(C-A)
            
            bondDirection = -(AB+AC)
            bondDirection = normalize(bondDirection)* self.bond_lengths[ self.atomList[atom].element ]
            
            newAtomCoords = A + bondDirection
            
            self.hydrogenAtomsList.append(HydrogenAtom(newAtomCoords))
            self.connected2H.append(atom)

        return
def atomAngleNomVecCentroid(atom, centroid):
    """
    Funkcja pomocnicza, oblicza kat pomiedzy kierunkiem od srodka 
    pierscienia do atomu a wektorem normalnym plaszczyzny pierscienia
    
    Wejscie:
    atom - obiekt Atom (Biopython)
    centroid - slownik, klucze: coords, normVec
    
    Wyjscie:
    kat w stopniach
    """
    atomCoords = np.array(atom.get_coord())
    centroidCoords = np.array(centroid["coords"])
    normVec = centroid["normVec"]

    centrAtomVec = normalize(atomCoords - centroidCoords)
    inner_prod = np.inner(normVec, centrAtomVec)

    return degrees(acos(inner_prod))
def get_ortonormal(vec):
    closest2zeroIndex = -1
    dist = 100
    for i, el in enumerate(vec):
        if abs(el) < dist:
            closest2zeroIndex = i
            dist = abs(el)
            
    vecOut = np.array([0.0, 0.0, 0.0])
    
    aInd = (closest2zeroIndex+1)%3
    bInd = (closest2zeroIndex+2)%3
    
    if abs(vec[bInd]) < 0.001:
        vecOut[bInd]=1
        return vecOut
    
    vecOut[aInd] =1
    vecOut[bInd] = -vec[aInd]/vec[bInd]
    
    return normalize(vecOut)
    def tetrahedral(self, atom):
        number_of_protons_to_add = self.moleculeGraph.nodes[atom]["number_of_protons_to_add"]
        rot_angle = math.radians(109.5)
        
        if number_of_protons_to_add == 0:
            return
        
        bonded_atoms_ids = list(self.moleculeGraph.neighbors(atom))
        
        if len(bonded_atoms_ids) == 0:
            return

        if len(bonded_atoms_ids) == 1:
            A = self.atomList[atom].get_coord()
            B = self.atomList[ bonded_atoms_ids[0] ].get_coord()
            
#            norm_vec = get_ortonormal(B-A)
            norm_vec = normalize( np.cross( B-A, self.anionCoords - A ) )
            dih_rot = math.radians(120)
            bondDirection = rotateVector(B-A, norm_vec, rot_angle)
            bondDirection = normalize(bondDirection)* self.bond_lengths[ self.atomList[atom].element ]
            
            for i in range(number_of_protons_to_add):
                newAtomCoords = A + bondDirection
                self.hydrogenAtomsList.append(HydrogenAtom(newAtomCoords))
                self.connected2H.append(atom)
                
                bondDirection = rotateVector(bondDirection, B-A, dih_rot)
                
        # 1 bond
        
        elif len(bonded_atoms_ids) == 2:
            A = self.atomList[atom].get_coord()
            B = self.atomList[ bonded_atoms_ids[0] ].get_coord()
            C = self.atomList[ bonded_atoms_ids[1] ].get_coord()
            
            AB = normalize(B-A)
            AC = normalize(C-A)
            
            axis = AB+AC
            bondDirection = rotateVector(-AB, axis, math.radians(90))
            bondDirection = normalize(bondDirection)*self.bond_lengths[ self.atomList[atom].element ]
            
            newAtomCoords = A + bondDirection
            self.hydrogenAtomsList.append(HydrogenAtom(newAtomCoords))
            self.connected2H.append(atom)
            
            if number_of_protons_to_add > 1:
                bondDirection = rotateVector(bondDirection, axis, math.radians(180))
                newAtomCoords = A + bondDirection
                self.hydrogenAtomsList.append(HydrogenAtom(newAtomCoords))
                self.connected2H.append(atom)
                
        elif len(bonded_atoms_ids) == 3:
            A = self.atomList[atom].get_coord()
            B = self.atomList[ bonded_atoms_ids[0] ].get_coord()
            C = self.atomList[ bonded_atoms_ids[1] ].get_coord()
            D = self.atomList[ bonded_atoms_ids[2] ].get_coord()
            
            AB = normalize(B-A)
            AC = normalize(C-A)
            AD = normalize(D-A)
            
            bondDirection = -(AB+AC+AD)
            bondDirection = bondDirection*self.bond_lengths[ self.atomList[atom].element ]
            
            
            newAtomCoords = A + bondDirection
            self.hydrogenAtomsList.append(HydrogenAtom(newAtomCoords))
            self.connected2H.append(atom)
            

        return
    def writeHbondsResults(self, hDonors, atom, modelIndex):
        resultsFileName = self.hBondsLog

        anionAtom = atom["Atom"]
        anion = anionAtom.get_parent()
        anionCode = anion.get_resname()
        anionId = str(anion.get_id()[1])
        anionChain = anion.get_parent().get_id()
        anionCoord = anionAtom.get_coord()

        resultsFile = open(resultsFileName, "a+")

        for hDonData in hDonors:
            hDon = hDonData["donor"]
            distance = anionAtom - hDon

            hDonCoords = hDon.get_coord()
            hDonRes = hDon.get_parent()

            residueName = hDonRes.get_resname()
            resChain = hDonRes.get_parent().get_id()
            resId = str(hDonRes.get_id()[1])

            resultsFile.write(self.pdbCode + "\t")

            resultsFile.write(anionCode + "\t")
            resultsFile.write(anionChain + "\t")
            resultsFile.write(anionId + "\t")

            resultsFile.write(residueName + "\t")
            resultsFile.write(resChain + "\t")
            resultsFile.write(resId + "\t")

            resultsFile.write(atom["AnionType"] + "\t")
            resultsFile.write(anionAtom.element + "\t")
            resultsFile.write(str(anionAtom.anionData.anionId) + "\t")

            resultsFile.write(str(anionCoord[0]) + "\t")
            resultsFile.write(str(anionCoord[1]) + "\t")
            resultsFile.write(str(anionCoord[2]) + "\t")

            resultsFile.write(hDon.element + "\t" + hDon.element + "\t")

            resultsFile.write(str(hDonCoords[0]) + "\t")
            resultsFile.write(str(hDonCoords[1]) + "\t")
            resultsFile.write(str(hDonCoords[2]) + "\t")

            hydrogenAtom = hDonData["hydrogen"]
            hydrogenCoords = hydrogenAtom.get_coord()

            resultsFile.write(str(hydrogenCoords[0]) + "\t")
            resultsFile.write(str(hydrogenCoords[1]) + "\t")
            resultsFile.write(str(hydrogenCoords[2]) + "\t")

            resultsFile.write(str(hDonData["HFromExp"]) + "\t")

            vec1 = normalize(anionCoord - hydrogenCoords)
            vec2 = normalize(hDonCoords - hydrogenCoords)
            angle = degrees(acos(np.inner(vec1, vec2)))
            hDistance = anionAtom - hydrogenAtom

            resultsFile.write(str(angle) + "\t")
            resultsFile.write(str(hDistance) + "\t")

            resultsFile.write(str(distance) + "\t")

            resultsFile.write(str(modelIndex) + "\n")

        resultsFile.close()