def test_can_transform_a_3_x_3(self): a = array([[1.0000, 0.0000, 0.0000], [0.0000, 1.0000, 0.0000], [0.0000, 0.0000, 1.0000]]) b = array([[0.0000, 1.0000, 0.0000], [-1.0000, 0.0000, 0.0000], [0.0000, 0.0000, 1.0000]]) ans = array([[0.0000, 1.0000, 0.0000], [-1.0000, 0.0000, 0.0000], [0.0000, 0.0000, 1.0000]]) rotation, _, _, _, _ = besttransformation(a, b) assert_almost_equal(ans, rotation)
def setUp(self): a = array([[1.0000, 0.0000, 0.0000], [0.0000, 1.0000, 0.0000], [0.0000, 0.0000, 1.0000], [-1.0000, 0.0000, 0.0000], [0.0000, -1.0000, 0.0000], [0.0000, 0.0000, -1.0000]]) b = array([[0.0000, 1.0000, 0.0000], [-1.0000, 0.0000, 0.0000], [0.0000, 0.0000, 1.0000], [0.0000, -1.0000, 0.0000], [1.0000, 0.0000, 0.0000], [0.0000, 0.0000, -1.0000]]) self.transformation, _, _, _, _ = besttransformation(a, b)
def test_can_transform_a_4_x_3_45degreezrotation(self): theta = numpy.pi/4.0 ans = array([[numpy.cos(theta), -1*numpy.sin(theta), 0.0000], [numpy.sin(theta), numpy.cos(theta), 0.0000], [0.0000, 0.0000, 1.0000]]) a = array([[3.0000, 7.0000, 1.0000], [5.0000, 9.0000, 2.0000], [7.0000, 4.0000, 6.0000], [1.0000, 1.0000, 1.0000]]) J = numpy.ones((4, 4)) meana = numpy.dot(J,a)/4.0 b = numpy.dot(a-meana,ans) rotation, _, _, _, _ = besttransformation(a, b) assert_almost_equal(ans, rotation) angle = angle_of_rotation(rotation) assert_almost_equal(angle, 45.0*numpy.pi/180.)
def infer_hydrogens(self): """Infer the coordinates of the hydrogen atoms of this component. Currently, it only works for RNA with .sequence """ if self.sequence not in defs.RNAbaseheavyatoms: return None R = [] S = [] baseheavy = defs.RNAbaseheavyatoms[self.sequence] for atom in self.atoms(name=baseheavy): coordinates = atom.coordinates() R.append(coordinates) S.append(defs.RNAbasecoordinates[self.sequence][atom.name]) R = np.array(R) R = R.astype(np.float) S = np.array(S) try: rotation_matrix, fitted, base_center, rmsd, sse = \ besttransformation(R, S) except: return None self.rotation_matrix = rotation_matrix hydrogens = defs.RNAbasehydrogens[self.sequence] coordinates = defs.RNAbasecoordinates[self.sequence] for hydrogenatom in hydrogens: hydrogencoordinates = coordinates[hydrogenatom] newcoordinates = base_center + \ np.dot(hydrogencoordinates, np.transpose(rotation_matrix)) self._atoms.append( Atom(name=hydrogenatom, x=newcoordinates[0, 0], y=newcoordinates[0, 1], z=newcoordinates[0, 2]))
def test_can_transform_a_4_x_3_generalrotation(self): theta1 = numpy.pi/4.0 theta2 = numpy.pi/3.0 theta3 = numpy.pi/9.0 R1 = array([[1.0000, 0.0000, 0.0000], [0.0000, numpy.cos(theta1), -1*numpy.cos(theta1)], [0.0000, numpy.sin(theta1), numpy.cos(theta1)]]) R2 = array([[numpy.cos(theta2), 0.0000, numpy.sin(theta2)], [0.0000, 1.0000, 0.0000], [-1*numpy.sin(theta2), 0.0000, numpy.cos(theta2)]]) R3 = array([[numpy.cos(theta3), -1*numpy.sin(theta3), 0.0000], [numpy.sin(theta3), numpy.cos(theta3), 0.0000], [0.0000, 0.0000, 1.0000]]) ans = numpy.dot(numpy.dot(R1,R2),R3) a = array([[3.0000, 7.0000, 1.0000], [5.0000, 9.0000, 2.0000], [7.0000, 4.0000, 6.0000], [1.0000, 1.0000, 1.0000]]) J = numpy.ones((4, 4)) meana = numpy.dot(J,a)/4.0 b = numpy.dot(a-meana,ans) rotation, _, _, _, _ = besttransformation(a, b) assert_almost_equal(ans, rotation)
def infer_hydrogens(self): """Infer the coordinates of the hydrogen atoms of this component. Currently, it only works for RNA with .sequence """ if self.sequence not in defs.RNAbaseheavyatoms: return None R = [] S = [] baseheavy = defs.RNAbaseheavyatoms[self.sequence] for atom in self.atoms(name=baseheavy): coordinates = atom.coordinates() R.append(coordinates) S.append(defs.RNAbasecoordinates[self.sequence][atom.name]) R = np.array(R) R = R.astype(np.float) S = np.array(S) try: rotation_matrix, fitted, base_center, rmsd, sse = \ besttransformation(R, S) except: return None self.rotation_matrix = rotation_matrix hydrogens = defs.RNAbasehydrogens[self.sequence] coordinates = defs.RNAbasecoordinates[self.sequence] for hydrogenatom in hydrogens: hydrogencoordinates = coordinates[hydrogenatom] newcoordinates = base_center + \ np.dot(hydrogencoordinates, np.transpose(rotation_matrix)) self._atoms.append(Atom(name=hydrogenatom, x=newcoordinates[0, 0], y=newcoordinates[0, 1], z=newcoordinates[0, 2]))
def calculate_rotation_matrix(self): """Calculate a rotation matrix that will rotate the atoms in an RNA base into a standard orientation in the xy plane with the Watson- Crick edge in the positive x and y quadrant. """ if self.sequence not in defs.NAbaseheavyatoms and \ self.sequence not in defs.modified_nucleotides: return None R = [] # 3d coordinates of observed base S = [] # 3d coordinates of standard base in xy plane if self.sequence in defs.NAbaseheavyatoms: baseheavy = defs.NAbaseheavyatoms[self.sequence] for atom in self.atoms(name=baseheavy): R.append(atom.coordinates()) S.append(defs.NAbasecoordinates[self.sequence][atom.name]) if self.sequence in defs.modified_nucleotides: current = defs.modified_nucleotides[self.sequence] standard_coords = defs.NAbasecoordinates[current["standard"]] for atom in self.atoms(name=current["atoms"].keys()): R.append(atom.coordinates()) S.append(standard_coords[atom.name]) R = np.array(R) R = R.astype(np.float) S = np.array(S) S = S.astype(np.float) try: rotation_matrix, fitted, meanR, rmsd, sse, meanS = \ besttransformation(R, S) except: if len(R) != len(S): print( "%s Rotation matrix calculation failed, sizes %d and %d" % (self.unit_id(), len(R), len(S))) elif len(R) < 3: print("%s Rotation matrix calculation failed, %d new atoms" % (self.unit_id(), len(R))) elif len(S) < 3: print( "%s Rotation matrix calculation failed, %d standard atoms" % (self.unit_id(), len(S))) else: print("%s Rotation matrix calculation failed, not sure why" % self.unit_id()) return None self.rotation_matrix = rotation_matrix # map the origin out to where the center of the base should be if self.sequence in defs.NAbaseheavyatoms: # standard bases are designed to have meanS zero; less work self.base_center = meanR else: # some modified bases are missing some heavy atoms, meanS not zero # this comes out as a numpy matrix? different than meanR above base_center = np.subtract(meanR, np.dot(rotation_matrix, meanS)) self.base_center = np.array( [base_center[0, 0], base_center[0, 1], base_center[0, 2]]) """ For the life of me, I could not figure out any other way of