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)
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)
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)
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)
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])))
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]) ) )
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
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.]
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
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.]