Пример #1
0
 def angle(self, other):
     "Returns the angle to vector |other|."
     if not isVector(other):
         raise TypeError, "Angle between vector and non-vector"
     cosa = Numeric.add.reduce(self.array*other.array) / \
            Numeric.sqrt(Numeric.add.reduce(self.array*self.array) * \
                                Numeric.add.reduce(other.array*other.array))
     cosa = max(-1., min(1., cosa))
     return Numeric.arccos(cosa)
Пример #2
0
    def angle(self, other):
        "Returns the angle to vector |other|."
	if not isVector(other):
	    raise TypeError, "Angle between vector and non-vector"
	cosa = Numeric.add.reduce(self.array*other.array) / \
	       Numeric.sqrt(Numeric.add.reduce(self.array*self.array) * \
                            Numeric.add.reduce(other.array*other.array))
	cosa = max(-1.,min(1.,cosa))
	return Numeric.arccos(cosa)
Пример #3
0
def randomRotation():
    """
    Get random rotation matrix.

    @author: Michael Habeck

    @return: 3 x 3 array of float
    @rtype: array
    """
    alpha = RandomArray.random() * 2 * N.pi
    gamma = RandomArray.random() * 2 * N.pi
    beta = N.arccos(2 * (RandomArray.random() - 0.5))

    return eulerRotation(alpha, beta, gamma)
Пример #4
0
def randomRotation():
    """
    Get random rotation matrix.

    @author: Michael Habeck

    @return: 3 x 3 array of float
    @rtype: array
    """
    alpha = RandomArray.random() * 2 * N.pi
    gamma = RandomArray.random() * 2 * N.pi
    beta  = N.arccos(2*(RandomArray.random() - 0.5))

    return eulerRotation(alpha, beta, gamma)
Пример #5
0
def cartesianToPolar(xyz):
    """
    Convert cartesian coordinate array to polar coordinate array: 
    C{ x,y,z -> r, S{theta}, S{phi} }

    @param xyz: array of cartesian coordinates (x, y, z)
    @type  xyz: array

    @return: array of polar coordinates (r, theta, phi)
    @rtype: array
    """
    r = N.sqrt(N.sum(xyz**2, 1))
    p = N.arccos(xyz[:, 2] / r)

    ## have to take care of that we end up in the correct quadrant
    t = []
    for i in range(len(xyz)):
        ## for theta (arctan)
        t += [math.atan2(xyz[i, 1], xyz[i, 0])]

    return N.transpose(N.concatenate(([r], [t], [p])))
Пример #6
0
def cartesianToPolar( xyz ):
    """
    Convert cartesian coordinate array to polar coordinate array: 
    C{ x,y,z -> r, S{theta}, S{phi} }

    @param xyz: array of cartesian coordinates (x, y, z)
    @type  xyz: array

    @return: array of polar coordinates (r, theta, phi)
    @rtype: array
    """
    r = N.sqrt( N.sum( xyz**2, 1 ) )
    p = N.arccos( xyz[:,2] / r )

    ## have to take care of that we end up in the correct quadrant
    t=[]
    for i in range(len(xyz)):
        ## for theta (arctan)
        t += [math.atan2( xyz[i,1], xyz[i,0] )]

    return N.transpose( N.concatenate( ([r],[t],[p]) ) )
Пример #7
0
    def dihedral(self, coor1, coor2, coor3, coor4):
        """
        Calculates the torsion angle of a set of four atom coordinates.
        The dihedral angle returned is the angle between the projection
        of i1-i2 and the projection of i4-i3 onto a plane normal to i2-i3.

        @param coor1: coordinates
        @type  coor1: [float]
        @param coor2: coordinates
        @type  coor2: [float]
        @param coor3: coordinates
        @type  coor3: [float]
        @param coor4: coordinates
        @type  coor4: [float]        
        """
        vec21 = coor2 - coor1
        vec32 = coor3 - coor2
        L = N.cross(vec21, vec32)
        L_norm = N.sqrt(sum(L**2))

        vec43 = coor4 - coor3
        vec23 = coor2 - coor3
        R = N.cross(vec43, vec23)
        R_norm = N.sqrt(sum(R**2))

        S = N.cross(L, R)
        angle = sum(L * R) / (L_norm * R_norm)

        ## sometimes the value turns out to be ever so little greater than
        ## one, to prevent N.arccos errors for this, set angle = 1.0
        if angle > 1.0: angle = 1.0

        if angle < -1.0: angle = -1.0

        angle = N.arccos(angle) * 180 / N.pi
        if sum(S * vec32) < 0.0:
            angle = -angle

        return angle
Пример #8
0
def mat_to_quat(matrix, transpose=1):
    """ takes a four by four matrix (optionally with shape (16,) and
    converts it into the axis of rotation and angle to rotate by
    (x,y,z,theta). It does not expect an OpenGL style, transposed
    matrix, so is consistent with rotax
    """

    if N.shape(matrix) not in ((16, ), (4, 4)):
        raise ValueError("Argument must Numeric array of shape (4,4) or (16,)")

    if N.shape(matrix) == (4, 4):
        matrix = N.reshape(matrix, (16, ))

    cofactor1 = matrix[5] * matrix[10] - matrix[9] * matrix[6]
    cofactor2 = matrix[8] * matrix[6] - matrix[4] * matrix[10]
    cofactor3 = matrix[4] * matrix[9] - matrix[8] * matrix[5]

    det = matrix[0] * cofactor1 + matrix[1] * cofactor2 + matrix[2] * cofactor3
    if not (0.999 < det < 1.001):
        print "Not a unit matrix: so not a pure rotation"
        print 'Value of Determinant is: ', det
    trace = matrix[0] + matrix[5] + matrix[10] + matrix[15]
    if trace > 0.0000001:  # rotation other than 180deg
        S = 0.5 / sqrt(trace)
        Qw = 0.25 / S
        Qx = (matrix[9] - matrix[6]) * S
        Qy = (matrix[2] - matrix[8]) * S
        Qz = (matrix[4] - matrix[1]) * S
    else:  #180deg rotation, just need to figure out the axis
        Qw = 0.
        diagonal = ((matrix[0], 0), (matrix[5], 5), (matrix[10], 10))
        idx = max(diagonal)[1]
        if idx == 0:
            S = sqrt(1.0 + matrix[0] - matrix[5] - matrix[10]) * 2
            Qy = (matrix[1] + matrix[4]) / S
            Qz = (matrix[2] + matrix[8]) / S
            Qx = N.sqrt(1 - Qy * Qy - Qz * Qz)
        elif idx == 5:
            S = sqrt(1.0 + matrix[5] - matrix[0] - matrix[10]) * 2
            Qx = (matrix[1] + matrix[4]) / S
            Qz = (matrix[6] + matrix[9]) / S
            Qy = N.sqrt(1 - Qx * Qx - Qz * Qz)
        elif idx == 10:
            S = sqrt(1.0 + matrix[10] - matrix[0] - matrix[5]) * 2
            Qx = (matrix[2] + matrix[8]) / S
            Qy = (matrix[6] + matrix[9]) / S
            Qz = N.sqrt(1 - Qx * Qx - Qy * Qy)
    # check if identity or not
    if Qw != 1.:
        angle = N.arccos(Qw)
        theta = angle * 360. / N.pi
        Z = sqrt(Qx * Qx + Qy * Qy + Qz * Qz)
        if transpose:
            Qx = -Qx / Z
            Qy = -Qy / Z
            Qz = -Qz / Z
        else:
            Qx = Qx / Z
            Qy = Qy / Z
            Qz = Qz / Z
        Qw = theta
        return [Qx, Qy, Qz, Qw]
    else:
        return [0., 0., 0., 0.]
Пример #9
0
def hbonds(model):
    """
    Collect a list with all potential hydrogen bonds in model.

    @param model: PDBModel for which 
    @type  model: PDBModel

    @return: a list of potential hydrogen bonds containing a lists
             with donor index, acceptor index, distance and angle.
    @rtype: [ int, int, float, float ]
    """
    hbond_lst = []
    donors = molU.hbonds['donors']
    accept = molU.hbonds['acceptors']

    ## indices if potential donors
    d_ind = []
    for res, aList in donors.items():
        for a in aList:
            if a in molU.hydrogenSynonyms.keys():
                aList.append(molU.hydrogenSynonyms[a])

        d_ind += model.filterIndex(residue_name=res, name=aList)

    ## indices if potential acceptors
    a_ind = []
    for res, aList in accept.items():
        a_ind += model.filterIndex(residue_name=res, name=aList)

    ## calculate pairwise distances and angles
    for d in d_ind:
        d_xyz = model.xyz[d]
        d_nr = model.atoms['residue_number'][d]
        d_cid = model.atoms['chain_id'][d]
        d_segi = model.atoms['segment_id'][d]

        for a in a_ind:
            a_xyz = model.xyz[a]
            a_nr = model.atoms['residue_number'][a]
            a_cid = model.atoms['chain_id'][a]
            a_segi = model.atoms['segment_id'][a]

            dist = N.sqrt(sum((d_xyz - a_xyz)**2))

            ## don't calculate angles within the same residue and
            ##  for distances definately are not are h-bonds
            if dist < 3.0 and not\
                  ( d_nr == a_nr and d_cid == a_cid and d_segi == a_segi ):

                ## calculate angle for potenital hbond
                d_xyz_cov = xyzOfNearestCovalentNeighbour(d, model)
                a_xyz_cov = xyzOfNearestCovalentNeighbour(a, model)
                d_vec = d_xyz_cov - d_xyz
                a_vec = a_xyz - a_xyz_cov

                d_len = N.sqrt(sum((d_vec)**2))
                a_len = N.sqrt(sum((a_vec)**2))

                da_dot = N.dot(d_vec, a_vec)

                angle = 180 - N.arccos(da_dot / (d_len * a_len)) * 180 / N.pi

                if hbondCheck(angle, dist):
                    hbond_lst += [[d, a, dist, angle]]

    return hbond_lst
Пример #10
0
def mat_to_quat(matrix,transpose=1):
    """ takes a four by four matrix (optionally with shape (16,) and
    converts it into the axis of rotation and angle to rotate by
    (x,y,z,theta). It does not expect an OpenGL style, transposed
    matrix, so is consistent with rotax
    """
    
    if N.shape(matrix) not in ((16,),(4,4)):
        raise ValueError("Argument must Numeric array of shape (4,4) or (16,)")

    if N.shape(matrix) == (4, 4):
        matrix = N.reshape(matrix,(16,))

    cofactor1 = matrix[5]*matrix[10] - matrix[9]*matrix[6]
    cofactor2 = matrix[8]*matrix[6] - matrix[4]*matrix[10] 
    cofactor3 = matrix[4]*matrix[9] - matrix[8]*matrix[5]

    det = matrix[0]*cofactor1 + matrix[1]*cofactor2 + matrix[2]*cofactor3
    if not (0.999 < det < 1.001):
        print "Not a unit matrix: so not a pure rotation"
        print 'Value of Determinant is: ',det
    trace = matrix[0] + matrix[5] + matrix[10] + matrix[15]       
    if trace > 0.0000001:# rotation other than 180deg
        S = 0.5/sqrt(trace)
        Qw = 0.25/S
        Qx = (matrix[9]-matrix[6])*S
        Qy = (matrix[2]-matrix[8])*S
        Qz = (matrix[4]-matrix[1])*S
    else: #180deg rotation, just need to figure out the axis
        Qw = 0.
        diagonal = ((matrix[0],0),
                    (matrix[5],5),
                    (matrix[10],10))
        idx = max(diagonal)[1]
        if idx == 0:
            S  = sqrt(1.0 + matrix[0] - matrix[5] - matrix[10])*2
            Qy = (matrix[1] + matrix[4] ) / S
            Qz = (matrix[2] + matrix[8] ) / S
            Qx = N.sqrt(1-Qy*Qy-Qz*Qz)
        elif idx==5:
            S  = sqrt( 1.0 + matrix[5] - matrix[0] - matrix[10] )*2
            Qx = (matrix[1] + matrix[4] ) / S
            Qz = (matrix[6] + matrix[9] ) / S
            Qy = N.sqrt(1-Qx*Qx-Qz*Qz)
        elif idx==10:
            S  = sqrt( 1.0 + matrix[10] - matrix[0] - matrix[5] )*2
            Qx = (matrix[2] + matrix[8] ) / S
            Qy = (matrix[6] + matrix[9] ) / S
            Qz = N.sqrt(1-Qx*Qx-Qy*Qy)
    # check if identity or not
    if Qw != 1.:
        angle = N.arccos(Qw)
        theta = angle*360./N.pi
        Z = sqrt(Qx*Qx + Qy*Qy + Qz*Qz)
        if transpose:
            Qx = -Qx/Z
            Qy = -Qy/Z
            Qz = -Qz/Z
        else:
            Qx = Qx/Z
            Qy = Qy/Z
            Qz = Qz/Z                
        Qw = theta
        return [Qx,Qy,Qz,Qw]
    else:
        return [0.,0.,0.,0.]