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 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 test_rotate_aa(self): print "\ntest rotate_aa" p1 = np.array(range(1,4), dtype=float) p2 = p1 + 1 p3 = rotations.rotate_aa(p1, p2) print repr(p3) ptrue = np.array([ 0.74050324, 1.64950785, 2.20282887]) for v1, v2 in izip(p3, ptrue): self.assertAlmostEqual(v1, v2, 4)
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 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(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 takeStep(self, coords, **kwargs): # easy access to coordinates ca = CoordsAdapter(nrigid=old_div(coords.size, 6), coords=coords) for i in range(ca.nrigid): a = np.dot(rotations.aa2mx(ca.rotRigid[i]), np.array([1., 0., 0.])) a *= 2. * (np.random.random() - 0.5) * self.rotate_base ca.rotRigid[i] = rotations.rotate_aa(ca.rotRigid[i], a) # random rotation for angle-axis vectors if self.rotate_backbone != 0.: for j in range(self.ntorsionmoves): # choose bond to rotate around, index is first bead that changes index = choose_bond(ca.nrigid - 1, self.P_mid) + 1 # determine backbone beads a1 = np.dot(rotations.aa2mx(ca.rotRigid[index - 1]), np.array([1., 0., 0.])) a2 = np.dot(rotations.aa2mx(ca.rotRigid[index]), np.array([1., 0., 0.])) x1 = ca.posRigid[index - 1] - 0.4 * a1 # backbone bead x2 = ca.posRigid[index] - 0.4 * a2 # backbone bead # get bond vector as axis of rotation + random magnitude p = x2 - x1 p /= np.linalg.norm(p) p *= 2. * (np.random.random() - 0.5) * self.rotate_backbone # convert random rotation to a matrix mx = rotations.aa2mx(p) # center of rotation is in middle of backbone bond center = 0.5 * (x1 + x2) # apply rotation to positions and orientations for i in range(index, ca.nrigid): a = np.dot(rotations.aa2mx(ca.rotRigid[i]), np.array([1., 0., 0.])) ca.rotRigid[i] = rotations.rotate_aa(ca.rotRigid[i], p) x = ca.posRigid[i] - 0.4 * a ca.posRigid[i] = np.dot(mx, x - center) + center a = np.dot(rotations.aa2mx(ca.rotRigid[i]), np.array([1., 0., 0.])) ca.posRigid[i] += 0.4 * a
def coordsApplyRotation(coordsin, aa): coords = coordsin.copy() nmol = len(coords) / 3 / 2 rmat = rot.aa2mx(aa) # rotate center of mass coords for imol in range(nmol): k = imol * 3 coords[k : k + 3] = np.dot(rmat, coords[k : k + 3]) # update aa coords for imol in range(nmol): k = nmol * 3 + imol * 3 coords[k : k + 3] = rot.rotate_aa(coords[k : k + 3], aa) return coords
def takeStep(self, coords, **kwargs): # easy access to coordinates ca = CoordsAdapter(nrigid=coords.size / 6, coords=coords) for i in xrange(ca.nrigid): a = np.dot(rotations.aa2mx(ca.rotRigid[i]), np.array([1., 0., 0.])) a *= 2. * (np.random.random() - 0.5) * self.rotate_base ca.rotRigid[i] = rotations.rotate_aa(ca.rotRigid[i], a) # random rotation for angle-axis vectors if self.rotate_backbone != 0.: for j in xrange(self.ntorsionmoves): # choose bond to rotate around, index is first bead that changes index = choose_bond(ca.nrigid - 1, self.P_mid) + 1 # determine backbone beads a1 = np.dot(rotations.aa2mx(ca.rotRigid[index - 1]), np.array([1., 0., 0.])) a2 = np.dot(rotations.aa2mx(ca.rotRigid[index]), np.array([1., 0., 0.])) x1 = ca.posRigid[index - 1] - 0.4 * a1 # backbone bead x2 = ca.posRigid[index] - 0.4 * a2 # backbone bead # get bond vector as axis of rotation + random magnitude p = x2 - x1 p /= np.linalg.norm(p) p *= 2. * (np.random.random() - 0.5) * self.rotate_backbone # convert random rotation to a matrix mx = rotations.aa2mx(p) # center of rotation is in middle of backbone bond center = 0.5 * (x1 + x2) # apply rotation to positions and orientations for i in xrange(index, ca.nrigid): a = np.dot(rotations.aa2mx(ca.rotRigid[i]), np.array([1., 0., 0.])) ca.rotRigid[i] = rotations.rotate_aa(ca.rotRigid[i], p) x = ca.posRigid[i] - 0.4 * a ca.posRigid[i] = np.dot(mx, x - center) + center a = np.dot(rotations.aa2mx(ca.rotRigid[i]), np.array([1., 0., 0.])) ca.posRigid[i] += 0.4 * a
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 takeStep(self, coords, **kwargs): # easy access to coordinates ca = CoordsAdapter(nrigid=coords.size / 6, coords=coords) # random displacement for positions ca.posRigid[:] += 2. * self.displace * (np.random.random(ca.posRigid.shape) - 0.5) # determine backbone beads for com, p in zip(ca.posRigid, ca.rotRigid): p_rnd = rotations.small_random_aa(self.rotate) # adjust center of mass if self.rotate_around_backbone: a1 = np.dot(rotations.aa2mx(p), np.array([1., 0., 0.])) x1 = com - 0.4 * a1 mx = rotations.aa2mx(p_rnd) com[:] = np.dot(mx, com - x1) + x1 # random rotation for angle-axis vectors p[:] = rotations.rotate_aa(p, p_rnd)
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 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 getSymmetries(self, com, aa ): """ a generator which iteratively returns the absolute xyz coordinates of the molecule subject to it's symmetries com: the center of mass coords of the molecule aa: the orientation of the molecule in angle-axis """ com = np.array(com) rmat = rot.aa2mx(aa) #rotation matrix #first yield the unaltered molecule xyz = self.getxyz_rmat(rmat, com=com) yield xyz, aa #now loop through the symmetries for p in self.symmetrylist_rot: #combine the two rotations into one rmat_comb = np.dot( rmat, rot.aa2mx(p) ) xyz = self.getxyz_rmat(rmat_comb, com=com) newaa = rot.rotate_aa(p, aa) #print rmat_comb #print rot.aa2mx( newaa) yield xyz, newaa
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 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_rotate_aa(self): p1 = random_aa() p2 = random_aa() p3 = rotate_aa(p1, p2) p4 = rotations.rotate_aa(p1, p2) self.arrays_equal(p3, p4)
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 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
xyz = otp.getxyz() from pele.printing.print_atoms_xyz import printAtomsXYZ as printxyz import sys #with open("out.xyz", "w") as fout: printxyz(sys.stdout, xyz) aa = np.array([.2, .3, .4]) for xyz, aanew in otp.getSymmetries( np.zeros(3), aa): printxyz(sys.stdout, xyz, line2="symmetry") xyz = otp.getxyz(aa = aanew) printxyz(sys.stdout, xyz, line2="symmetry from returned aa") if __name__ == "__main__": test_molecule() aa1 = rot.random_aa() aa2 = rot.random_aa() rmat1 = rot.aa2mx(aa1) rmat2 = rot.aa2mx(aa2) rmat21 = np.dot(rmat2, rmat1) aa21 = rot.rotate_aa(aa1, aa2) rmat21aa = rot.aa2mx(aa21) print rmat21 print rmat21aa print abs(rmat21 - rmat21aa) < 1e-12
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