def _align_pythonic(self, coords1, coords2): """the slow pythonic version of align""" # note: this minimizes the angle-distance, but it might be better to # minimize the atomistic distance. These are not always the same c1 = self.topology.coords_adapter(coords1) c2 = self.topology.coords_adapter(coords2) # now account for inner-molecular symmetry for p1, p2, site in izip(c1.rotRigid,c2.rotRigid, self.topology.sites): theta_min = 10. mx2 = rotations.aa2mx(p2) mx1 = rotations.aa2mx(p1).transpose() mx = np.dot(mx1, mx2) # find the symmetry operation which puts p2 into best alignment with p1 for rot in site.symmetries: mx_diff = np.dot(mx, rot) # theta is the rotation angle between p1 and p2 after # applying the symmetry operation rot to site2 theta = np.linalg.norm(rotations.mx2aa(mx_diff)) # remove any extra factors of 2*pi theta -= int(theta / (2.*pi)) * 2.*pi if theta < theta_min: theta_min = theta rot_best = rot p2[:] = rotations.rotate_aa(rotations.mx2aa(rot_best), p2)
def _align_pythonic(self, coords1, coords2): """the slow pythonic version of align""" # note: this minimizes the angle-distance, but it might be better to # minimize the atomistic distance. These are not always the same c1 = self.topology.coords_adapter(coords1) c2 = self.topology.coords_adapter(coords2) # now account for inner-molecular symmetry for p1, p2, site in zip(c1.rotRigid, c2.rotRigid, self.topology.sites): theta_min = 10. mx2 = rotations.aa2mx(p2) mx1 = rotations.aa2mx(p1).transpose() mx = np.dot(mx1, mx2) # find the symmetry operation which puts p2 into best alignment with p1 for rot in site.symmetries: mx_diff = np.dot(mx, rot) # theta is the rotation angle between p1 and p2 after # applying the symmetry operation rot to site2 theta = np.linalg.norm(rotations.mx2aa(mx_diff)) # remove any extra factors of 2*pi theta -= int(old_div(theta, (2. * pi))) * 2. * pi if theta < theta_min: theta_min = theta rot_best = rot p2[:] = rotations.rotate_aa(rotations.mx2aa(rot_best), p2)
def finalize_setup(self, shift_com=True): """finalize setup after all sites have been added This will shift the center of mass to the origin and calculate the total mass and weighted tensor of gyration """ # first correct for the center of mass com = np.average(self.atom_positions, axis=0, weights=self.atom_masses) if shift_com: for x in self.atom_positions: x[:] -= com self.cog = np.average(self.atom_positions, axis=0) self.W = float(len(self.atom_masses)) # calculate total mass self.M = np.sum(self.atom_masses) # now calculate the weighted moment of inertia tensor self.S[:] = 0. for x in self.atom_positions: self.S[:] += np.outer(x, x) self.Sm = np.zeros([3, 3]) for x, m in zip(self.atom_positions, self.atom_masses): self.Sm[:] += m * np.outer(x, x) self._determine_symmetries() # calculate aa rotations for later self.symmetriesaa = [] for rot in self.symmetries: self.symmetriesaa.append(mx2aa(rot))
def test_mx2aa(self): print "test mx2aa" mx = np.array(range(9)).reshape([3,3]) aa = rotations.mx2aa(mx) print repr(aa) aatrue = np.array([ 0.29425463, -0.58850926, 0.29425463]) for v1, v2 in izip(aa, aatrue): self.assertAlmostEqual(v1, v2, 4)
def rotate(self, X, mx): ca = self.topology.coords_adapter(X) if(ca.nrigid > 0): ca.posRigid[:] = np.dot(mx, ca.posRigid.transpose()).transpose() dp = rotations.mx2aa(mx) for p in ca.rotRigid: p[:] = rotations.rotate_aa(p, dp) if(ca.natoms > 0): ca.posAtom[:] = np.dot(mx, ca.posAtom.transpose()).transpose()
def test_align_exact(self): x1 = np.array([random_aa() for _ in range(2 * self.nrigid)]).ravel() x2 = x1.copy() tet = create_tetrahedron() mx = tet.symmetries[2].copy() p = x2[-3:].copy() x2[-3:] = rotations.rotate_aa(rotations.mx2aa(mx), p) self.measure._align_pythonic(x1, x2) assert_arrays_almost_equal(self, x1, x2)
def align(self, coords1, coords2): c1 = self.topology.coords_adapter(coords1) c2 = self.topology.coords_adapter(coords2) # now account for symmetry in water for p1, p2, site in zip(c1.rotRigid,c2.rotRigid, self.topology.sites): theta_min = 10. mx2 = rotations.aa2mx(p2) mx1 = rotations.aa2mx(p1).transpose() mx = np.dot(mx1, mx2) for rot in site.symmetries: mx_diff = np.dot(mx, rot) theta = np.linalg.norm(rotations.mx2aa(mx_diff)) theta -= int(theta/2./pi)*2.*pi if(theta < theta_min): theta_min = theta rot_best = rot p2[:] = rotations.rotate_aa(rotations.mx2aa(rot_best), p2)
def test_align_exact(self): x1 = np.array([random_aa() for _ in range(2*self.nrigid)]).ravel() x2 = x1.copy() tet = create_tetrahedron() mx = tet.symmetries[2].copy() p = x2[-3:].copy() x2[-3:] = rotations.rotate_aa(rotations.mx2aa(mx), p) self.measure._align_pythonic(x1, x2) assert_arrays_almost_equal(self, x1, x2)
def _rotate_python(self, X, mx): """the slow pythonic version of rotate""" ca = self.topology.coords_adapter(X) if ca.nrigid > 0: # rotate the center of mass positions ca.posRigid[:] = np.dot(ca.posRigid, mx.transpose()) # rotate the angle axis rotations dp = rotations.mx2aa(mx) for p in ca.rotRigid: p[:] = rotations.rotate_aa(p, dp) if ca.natoms > 0: ca.posAtom[:] = np.dot(mx, ca.posAtom.transpose()).transpose()
def align(self, coords1, coords2): """align the rotations so that the atomistic coordinates will be in best alignment""" try: return self.cpp_measure.align(coords1, coords2) except AttributeError: pass c1 = self.topology.coords_adapter(coords1) c2 = self.topology.coords_adapter(coords2) # now account for inner-molecular symmetry for p1, p2, site in zip(c1.rotRigid, c2.rotRigid, self.topology.sites): theta_min = 10. mx2 = rotations.aa2mx(p2) mx1 = rotations.aa2mx(p1).transpose() mx = np.dot(mx1, mx2) for rot in site.symmetries: mx_diff = np.dot(mx, rot) theta = np.linalg.norm(rotations.mx2aa(mx_diff)) theta -= int(theta / 2. / pi) * 2. * pi if theta < theta_min: theta_min = theta rot_best = rot p2[:] = rotations.rotate_aa(rotations.mx2aa(rot_best), p2)
def align(self, coords1, coords2): """align the rotations so that the atomistic coordinates will be in best alignment""" try: return self.cpp_measure.align(coords1, coords2) except AttributeError: pass c1 = self.topology.coords_adapter(coords1) c2 = self.topology.coords_adapter(coords2) # now account for symmetry in water for p1, p2, site in zip(c1.rotRigid,c2.rotRigid, self.topology.sites): theta_min = 10. mx2 = rotations.aa2mx(p2) mx1 = rotations.aa2mx(p1).transpose() mx = np.dot(mx1, mx2) for rot in site.symmetries: mx_diff = np.dot(mx, rot) theta = np.linalg.norm(rotations.mx2aa(mx_diff)) theta -= int(theta/2./pi)*2.*pi if(theta < theta_min): theta_min = theta rot_best = rot p2[:] = rotations.rotate_aa(rotations.mx2aa(rot_best), p2)
def align(system, coords1, coords2): c1 = system.coords_adapter(coords1) c2 = system.coords_adapter(coords2) R = findrotation_kabsch(c2.posRigid, c1.posRigid).transpose() #R = rotations.aa2mx(p) for x, p in zip(c2.posRigid, c2.rotRigid): x[:] = np.dot(R, x) p[:] = rotations.rotate_aa(p, rotations.mx2aa(R)) # now account for symmetry in water for p1, p2 in zip(c1.rotRigid,c2.rotRigid): theta1 = np.linalg.norm(rotations.rotate_aa(p2,-p1)) p2n = rotations.rotate_aa(np.array([0., 0., pi]), p2) theta2 = np.linalg.norm(rotations.rotate_aa(p2n,-p1)) theta1 -= int(theta1/2./pi)*2.*pi theta2 -= int(theta2/2./pi)*2.*pi if(theta2 < theta1): p2[:]=p2n
def align(system, coords1, coords2): c1 = system.coords_adapter(coords1) c2 = system.coords_adapter(coords2) R = findrotation_kabsch(c2.posRigid, c1.posRigid).transpose() #R = rotations.aa2mx(p) for x, p in zip(c2.posRigid, c2.rotRigid): x[:] = np.dot(R, x) p[:] = rotations.rotate_aa(p, rotations.mx2aa(R)) # now account for symmetry in water for p1, p2 in zip(c1.rotRigid, c2.rotRigid): theta1 = np.linalg.norm(rotations.rotate_aa(p2, -p1)) p2n = rotations.rotate_aa(np.array([0., 0., pi]), p2) theta2 = np.linalg.norm(rotations.rotate_aa(p2n, -p1)) theta1 -= int(theta1 / 2. / pi) * 2. * pi theta2 -= int(theta2 / 2. / pi) * 2. * pi if (theta2 < theta1): p2[:] = p2n
def rotate(self, X, mx): """rotate the com + angle-axis position X by the rotation matrix mx """ try: return self.cpp_transform.rotate(X, mx) except AttributeError: pass ca = self.topology.coords_adapter(X) if ca.nrigid > 0: # rotate the center of mass positions ca.posRigid[:] = np.dot(ca.posRigid, mx.transpose()) # rotate the angle axis rotations dp = rotations.mx2aa(mx) for p in ca.rotRigid: p[:] = rotations.rotate_aa(p, dp) if ca.natoms > 0: ca.posAtom[:] = np.dot(mx, ca.posAtom.transpose()).transpose()
def rotate(self, X, mx): """rotate the com + angle-axis position X by the rotation matrix mx """ try: return self.cpp_transform.rotate(X, mx) except AttributeError: pass ca = self.topology.coords_adapter(X) if(ca.nrigid > 0): # rotate the center of mass positions ca.posRigid[:] = np.dot(ca.posRigid, mx.transpose()) # rotate the angle axis rotations dp = rotations.mx2aa(mx) for p in ca.rotRigid: p[:] = rotations.rotate_aa(p, dp) if(ca.natoms > 0): ca.posAtom[:] = np.dot(mx, ca.posAtom.transpose()).transpose()
def map_to_aa(xyz): coords = np.zeros(6 * 13) ca = CoordsAdapter(nrigid=13, coords=coords) for i in range(13): ca.posRigid[i] = 0.5 * (xyz[2 * i] + xyz[2 * i + 1]) a1 = -(xyz[2 * i] - xyz[2 * i + 1]) if (i < 12): a3 = -(xyz[2 * i + 1] - xyz[2 * i + 3]) else: a3 = -(xyz[2 * i - 1] - xyz[2 * i + 1]) a2 = -np.cross(a1, a3) a3 = np.cross(a1, a2) a1 /= np.linalg.norm(a1) a2 /= np.linalg.norm(a2) a3 /= np.linalg.norm(a3) # print np.dot(a1, a2), np.dot(a1, a3), np.dot(a2, a3) mx = np.array([a1, a2, a3]).transpose() p = rotations.mx2aa(mx) #print mx - rotations.aa2mx(p) # print a1-np.dot(rotations.aa2mx(p), np.array([1., 0., 0.])) ca.rotRigid[i] = p return coords
def map_to_aa(xyz): coords = np.zeros(6*13) ca = CoordsAdapter(nrigid=13, coords=coords) for i in xrange(13): ca.posRigid[i] = 0.5*(xyz[2*i] + xyz[2*i+1]) a1 = -(xyz[2*i] - xyz[2*i+1]) if(i<12): a3 = -(xyz[2*i+1] - xyz[2*i+3]) else: a3 = -(xyz[2*i-1] - xyz[2*i+1]) a2 = -np.cross(a1, a3) a3 = np.cross(a1, a2) a1/=np.linalg.norm(a1) a2/=np.linalg.norm(a2) a3/=np.linalg.norm(a3) # print np.dot(a1, a2), np.dot(a1, a3), np.dot(a2, a3) mx = np.array([a1, a2, a3]).transpose() p = rotations.mx2aa(mx) #print mx - rotations.aa2mx(p) # print a1-np.dot(rotations.aa2mx(p), np.array([1., 0., 0.])) ca.rotRigid[i] = p return coords
def invert(self, X): """invert the structure""" ca = self.topology.coords_adapter(X) ca.posRigid[:] = -ca.posRigid for p, site in zip(ca.rotRigid, self.topology.sites): p[:] = rotations.rotate_aa(rotations.mx2aa(site.inversion), p)
e2.append(pot.getEnergy(path[0])) #for i in xrange(1): for i in xrange(len(path) - 1): e1.append(pot.getEnergy(path[i + 1])) c1 = CoordsAdapter(nrigid=13, coords=path[i]) c2 = CoordsAdapter(nrigid=13, coords=path[i + 1]) com1 = np.sum(c1.posRigid, axis=0) / float(13) com2 = np.sum(c1.posRigid, axis=0) / float(13) c1.posRigid -= com1 c2.posRigid -= com2 mx = findrotation_kabsch(c2.posRigid, c1.posRigid).transpose() # print mx c2.posRigid[:] = np.dot(mx, c2.posRigid.transpose()).transpose() for p in c2.rotRigid: p[:] = rotations.rotate_aa(p, rotations.mx2aa(mx)) e2.append(pot.getEnergy(path[i + 1])) for p1, p2 in zip(c1.rotRigid, c2.rotRigid): n2 = p2 / np.linalg.norm(p2) * 2. * pi while True: p2n = p2 + n2 if (np.linalg.norm(p2n - p1) > np.linalg.norm(p2 - p1)): break p2[:] = p2n while True: p2n = p2 - n2 if (np.linalg.norm(p2n - p1) > np.linalg.norm(p2 - p1)): break
e2.append(pot.getEnergy(path[0])) #for i in xrange(1): for i in range(len(path) - 1): e1.append(pot.getEnergy(path[i + 1])) c1 = CoordsAdapter(nrigid=13, coords=path[i]) c2 = CoordsAdapter(nrigid=13, coords=path[i + 1]) com1 = np.sum(c1.posRigid, axis=0) / float(13) com2 = np.sum(c1.posRigid, axis=0) / float(13) c1.posRigid -= com1 c2.posRigid -= com2 mx = findrotation_kabsch(c2.posRigid, c1.posRigid).transpose() # print mx c2.posRigid[:] = np.dot(mx, c2.posRigid.transpose()).transpose() for p in c2.rotRigid: p[:] = rotations.rotate_aa(p, rotations.mx2aa(mx)) e2.append(pot.getEnergy(path[i + 1])) for p1, p2 in zip(c1.rotRigid, c2.rotRigid): n2 = old_div(p2, np.linalg.norm(p2) * 2. * pi) while True: p2n = p2 + n2 if (np.linalg.norm(p2n - p1) > np.linalg.norm(p2 - p1)): break p2[:] = p2n while True: p2n = p2 - n2 if (np.linalg.norm(p2n - p1) > np.linalg.norm(p2 - p1)): break
def invert(self, X): """invert the structure""" ca = self.topology.coords_adapter(X) ca.posRigid[:] = - ca.posRigid for p, site in zip(ca.rotRigid, self.topology.sites): p[:] = rotations.rotate_aa(rotations.mx2aa(site.inversion), p)
def test_mx2aa(self): mx = rotations.q2mx(random_q()) p1 = mx2aa(mx) p2 = rotations.mx2aa(mx) self.arrays_equal(p1, p2)
def relative_angle(aa1, aa2): m1 = rotations.aa2mx(aa1) m2 = rotations.aa2mx(aa2) m2 = m1.transpose().dot(m2) theta = np.linalg.norm(rotations.mx2aa(m2)) return theta