コード例 #1
0
def buildInitOrTerminalPhosOxy(curResAtoms, prevResAtoms=None):
    """build phosphoryl oxygens using only the O3' or O5'atom (intended for the first or last nucleotide of a chain/segment)
    
    ARGUMENTS:
        curResAtoms - a dictionary of the current nucleotide coordinates (i.e. the nucleotide to build the phosphoryl oxygens on) in the format atomName: [x, y, z]
                      this dictionary must contain at least the phosphate
    OPTIONAL ARGUMENTS:
        prevResAtoms - a dictionary of the previous nucleotide coordinates in the format atomName: [x, y, z]
                       if provided, the curResAtoms["P"] and prevResAtoms["O3'"] will be used to place the phosphoryl oxygens
                       if not provided, the curResAtoms["P"] and curResAtoms["O5'"]
    RETURNS:
        phosOxyCoords - a dictionary of the phosphoryl oxygen coordinates in the format atomName: [x, y, z]
        or None if the residue is missing the necessary atoms
    """

    try:
        P = curResAtoms["P"]
        if prevResAtoms is not None:
            O = prevResAtoms["O3'"]
            C = prevResAtoms["C3'"]
        else:
            O = curResAtoms["O5'"]
            C = curResAtoms["C5'"]
    except KeyError:
        return None

    #place atom along the P-O5' bond that is the appropriate distance from P
    phosOxy = minus(O, P)
    phosOxy = normalize(phosOxy, PHOSBONDLENGTH)

    #define plane with C5'-O5'-P
    norm = crossProd(minus(C, O), minus(P, O))
    norm = normalize(norm)

    #rotate dummy atom in plane about P by INITPHOSANGLE (which is the appropriate O5'-OP1 angle)
    (x, y, z) = phosOxy
    (u, v, w) = norm
    theta = -radians(
        INITPHOSANGLE
    )  #use the negative angle so that we rotate away from the C5'

    cosTheta = cos(theta)
    sinTheta = sin(theta)

    #perform the rotation
    a = u * x + v * y + w * z
    phosOxy[0] = a * u + (x - a * u) * cosTheta + (v * z - w * y) * sinTheta
    phosOxy[1] = a * v + (y - a * v) * cosTheta + (w * x - u * z) * sinTheta
    phosOxy[2] = a * w + (z - a * w) * cosTheta + (u * y - v * x) * sinTheta

    #rotate dummy atom about O5'-P axis by 59.8 and -59.8 degrees
    norm = minus(O, P)
    norm = normalize(norm)

    (x, y, z) = phosOxy
    (u, v, w) = norm
    angle = radians(PHOSBONDANGLE / 2)

    phosOxyCoords = {}
    for (atomName, theta) in (("OP1", angle), ("OP2", -angle)):
        cosTheta = cos(theta)
        sinTheta = sin(theta)

        #perform the rotation, and then add $P to the coordinates
        newX = a * u + (x - a * u) * cosTheta + (v * z -
                                                 w * y) * sinTheta + P[0]
        newY = a * v + (y - a * v) * cosTheta + (w * x -
                                                 u * z) * sinTheta + P[1]
        newZ = a * w + (z - a * w) * cosTheta + (u * y -
                                                 v * x) * sinTheta + P[2]

        phosOxyCoords[atomName] = [newX, newY, newZ]

    return phosOxyCoords
コード例 #2
0
ファイル: buildPhosOxy.py プロジェクト: benmwebb/coot
def buildInitOrTerminalPhosOxy(curResAtoms, prevResAtoms = None):
    """build phosphoryl oxygens using only the O3' or O5'atom (intended for the first or last nucleotide of a chain/segment)
    
    ARGUMENTS:
        curResAtoms - a dictionary of the current nucleotide coordinates (i.e. the nucleotide to build the phosphoryl oxygens on) in the format atomName: [x, y, z]
                      this dictionary must contain at least the phosphate
    OPTIONAL ARGUMENTS:
        prevResAtoms - a dictionary of the previous nucleotide coordinates in the format atomName: [x, y, z]
                       if provided, the curResAtoms["P"] and prevResAtoms["O3'"] will be used to place the phosphoryl oxygens
                       if not provided, the curResAtoms["P"] and curResAtoms["O5'"]
    RETURNS:
        phosOxyCoords - a dictionary of the phosphoryl oxygen coordinates in the format atomName: [x, y, z]
        or None if the residue is missing the necessary atoms
    """
    
    try:
        P  = curResAtoms ["P"]
        if prevResAtoms is not None:
            O = prevResAtoms["O3'"]
            C = prevResAtoms["C3'"]
        else:
            O = curResAtoms["O5'"]
            C = curResAtoms["C5'"]
    except KeyError:
        return None
    
    #place atom along the P-O5' bond that is the appropriate distance from P
    phosOxy = minus(O, P)
    phosOxy = normalize(phosOxy, PHOSBONDLENGTH)
    
    #define plane with C5'-O5'-P
    norm = crossProd( minus(C, O), minus(P, O))
    norm = normalize(norm)
    
    #rotate dummy atom in plane about P by INITPHOSANGLE (which is the appropriate O5'-OP1 angle)
    (x, y, z) = phosOxy
    (u, v, w) = norm
    theta = -radians(INITPHOSANGLE) #use the negative angle so that we rotate away from the C5'
    
    cosTheta = cos(theta)
    sinTheta = sin(theta)
    
    #perform the rotation
    a = u*x + v*y + w*z
    phosOxy[0] = a*u + (x-a*u)*cosTheta + (v*z-w*y)*sinTheta
    phosOxy[1] = a*v + (y-a*v)*cosTheta + (w*x-u*z)*sinTheta
    phosOxy[2] = a*w + (z-a*w)*cosTheta + (u*y-v*x)*sinTheta
    
    #rotate dummy atom about O5'-P axis by 59.8 and -59.8 degrees
    norm = minus(O, P)
    norm = normalize(norm)
    
    (x, y, z) = phosOxy
    (u, v, w) = norm
    angle = radians(PHOSBONDANGLE / 2)
    
    phosOxyCoords = {}
    for (atomName, theta) in (("OP1", angle), ("OP2", -angle)):
        cosTheta = cos(theta)
        sinTheta = sin(theta)
        
        #perform the rotation, and then add $P to the coordinates
        newX = a*u + (x-a*u)*cosTheta + (v*z-w*y)*sinTheta + P[0]
        newY = a*v + (y-a*v)*cosTheta + (w*x-u*z)*sinTheta + P[1]
        newZ = a*w + (z-a*w)*cosTheta + (u*y-v*x)*sinTheta + P[2]
        
        phosOxyCoords[atomName] = [newX, newY, newZ]
    
    return phosOxyCoords
    
    
コード例 #3
0
def buildPhosOxy(curResAtoms, prevResAtoms):
    """Calculate non-bridging phosphoryl oxygen coordinates using the coordinates of the current and previous nucleotides
    
    ARGUMENTS:
        curResAtoms - a dictionary of the current nucleotide coordinates (i.e. the nucleotide to build the phosphoryl oxygens on) in the format atomName: [x, y, z]
        prevResAtoms - a dictionary of the previous nucleotide coordinates in the format atomName: [x, y, z]
    RETURNS:
        phosOxyCoords - a dictionary of the phosphoryl oxygen coordinates in the format atomName: [x, y, z]
        or None if the residue is missing the P, O5', or O3' atoms
    """

    try:
        P = curResAtoms["P"]
        O5 = curResAtoms["O5'"]
        O3 = prevResAtoms["O3'"]
    except KeyError:
        return None

    #calculate a line from O5' to O3'
    norm = minus(O5, O3)

    #calculate the intersection of a plane (with normal $norm and point $P) and a line (from O5' to O3')
    #using formula from http://local.wasp.uwa.edu.au/~pbourke/geometry/planeline/
    #       norm dot (P - O3)
    # i = ------------------------
    #       norm dot (O5 - O3)
    #intersecting point = O3 + i(O5 - O3)
    i = dotProd(norm, minus(P, O3)) / dotProd(norm, minus(O5, O3))
    interPoint = plus(O3, scalarProd(i, minus(O5, O3)))

    #move $interPoint so that the distance from $P to $interPoint is 1.485 (the length of the P-OP1 bond)
    #we also reflect the point about P
    PIline = minus(
        P, interPoint
    )  #here's is where the reflection occurs, because we do $P-$interPoint instead of $interPoint-$P
    #scaledPoint = scalarProd(1/magnitude(PIline) * PHOSBONDLENGTH, PIline)
    scaledPoint = normalize(PIline, PHOSBONDLENGTH)
    #to get the new point location, we would do P + scaledPoint
    #but we need to rotate the point first before translating it back

    #rotate this new point by 59.8 and -59.8 degrees to determine the phosphoryl oxygen locations
    #we rotate about the axis defined by $norm
    angle = radians(PHOSBONDANGLE / 2)
    (x, y, z) = scaledPoint

    #unitnorm = scalarProd( 1/magnitude(norm), norm)
    unitnorm = normalize(norm)
    (u, v, w) = unitnorm

    a = u * x + v * y + w * z

    phosOxyCoords = {}
    for (atomName, theta) in (("OP1", angle), ("OP2", -angle)):
        cosTheta = cos(theta)
        sinTheta = sin(theta)

        #perform the rotation, and then add $P to the coordinates
        newX = a * u + (x - a * u) * cosTheta + (v * z -
                                                 w * y) * sinTheta + P[0]
        newY = a * v + (y - a * v) * cosTheta + (w * x -
                                                 u * z) * sinTheta + P[1]
        newZ = a * w + (z - a * w) * cosTheta + (u * y -
                                                 v * x) * sinTheta + P[2]

        phosOxyCoords[atomName] = [newX, newY, newZ]

    return phosOxyCoords
コード例 #4
0
ファイル: buildPhosOxy.py プロジェクト: benmwebb/coot
def buildPhosOxy(curResAtoms, prevResAtoms):
    """Calculate non-bridging phosphoryl oxygen coordinates using the coordinates of the current and previous nucleotides
    
    ARGUMENTS:
        curResAtoms - a dictionary of the current nucleotide coordinates (i.e. the nucleotide to build the phosphoryl oxygens on) in the format atomName: [x, y, z]
        prevResAtoms - a dictionary of the previous nucleotide coordinates in the format atomName: [x, y, z]
    RETURNS:
        phosOxyCoords - a dictionary of the phosphoryl oxygen coordinates in the format atomName: [x, y, z]
        or None if the residue is missing the P, O5', or O3' atoms
    """
    
    try:
        P  = curResAtoms ["P"]
        O5 = curResAtoms ["O5'"]
        O3 = prevResAtoms["O3'"]
    except KeyError:
        return None
    
    #calculate a line from O5' to O3'
    norm = minus(O5, O3)
    
    #calculate the intersection of a plane (with normal $norm and point $P) and a line (from O5' to O3')
    #using formula from http://local.wasp.uwa.edu.au/~pbourke/geometry/planeline/
    #       norm dot (P - O3)
    # i = ------------------------
    #       norm dot (O5 - O3)
    #intersecting point = O3 + i(O5 - O3)
    i = dotProd(norm, minus(P, O3)) / dotProd(norm, minus(O5, O3))
    interPoint = plus(O3, scalarProd(i, minus(O5, O3)))
    
    #move $interPoint so that the distance from $P to $interPoint is 1.485 (the length of the P-OP1 bond)
    #we also reflect the point about P
    PIline = minus(P, interPoint) #here's is where the reflection occurs, because we do $P-$interPoint instead of $interPoint-$P
    #scaledPoint = scalarProd(1/magnitude(PIline) * PHOSBONDLENGTH, PIline)
    scaledPoint = normalize(PIline, PHOSBONDLENGTH)
    #to get the new point location, we would do P + scaledPoint
    #but we need to rotate the point first before translating it back
    
    #rotate this new point by 59.8 and -59.8 degrees to determine the phosphoryl oxygen locations
    #we rotate about the axis defined by $norm
    angle = radians(PHOSBONDANGLE / 2)
    (x, y, z) = scaledPoint
    
    #unitnorm = scalarProd( 1/magnitude(norm), norm)
    unitnorm = normalize(norm)
    (u, v, w) = unitnorm
    
    a = u*x + v*y + w*z
    
    phosOxyCoords = {}
    for (atomName, theta) in (("OP1", angle), ("OP2", -angle)):
        cosTheta = cos(theta)
        sinTheta = sin(theta)
        
        #perform the rotation, and then add $P to the coordinates
        newX = a*u + (x-a*u)*cosTheta + (v*z-w*y)*sinTheta + P[0]
        newY = a*v + (y-a*v)*cosTheta + (w*x-u*z)*sinTheta + P[1]
        newZ = a*w + (z-a*w)*cosTheta + (u*y-v*x)*sinTheta + P[2]
        
        phosOxyCoords[atomName] = [newX, newY, newZ]
    
    return phosOxyCoords