def distance_squared(self, com1, p1, com2, p2): ''' distance measure between 2 angle axis bodies of same type Parameters ---------- com1: center of mass of 1st site p1: angle axis vector of 1st site com2: center of mass of 2nd site p2: angle axis vector of 2nd site sitetype: AASiteType, optional angle axis site type with mass and moment of inertia tensor returns: distance squared ''' return _aadist.sitedist(self.get_smallest_rij(com1, com2), p1, p2, self.S, self.W, self.cog) R1 = rotations.aa2mx(p1) R2 = rotations.aa2mx(p2) dR = R2 - R1 dR = dR d_M = self.W*np.sum((com2-com1)**2) # dR_kl S_lm dR_km d_P = np.trace(np.dot(dR, np.dot(self.S, dR.transpose()))) d_mix = 2.*self.W * np.dot((com2-com1), np.dot(dR, self.cog)) return d_M + d_P + d_mix
def compareTransformed(coords1, coords2, x1, x2, M): # the lattice matrix ml1 = lattice.lowerTriangular(coords1.lattice) ml2 = lattice.lowerTriangular(coords2.lattice) # the inerse lattice matrix iml2 = vec3.invert3x3(ml2) for i in xrange(coords1.nrigid): ptest = coords1.rotRigid[i] ptrans = rotations.mx2aa(rotations.np.dot(M, rotations.aa2mx(ptest))) for d in [np.zeros(3),[0.,1.,0.],[0.,1.,0.],[0.,0.,1.]]: xtest = coords1.posRigid[i] + np.array(d) - x1 xtrans = np.dot(iml2, np.dot(M, np.dot(ml1, xtest))) match = False for j in xrange(coords1.nrigid): dx = coords2.posRigid[j] - xtrans - x2 dx = dx - np.floor(dx) dx[dx>0.8]-=1.0 dp = rotations.mx2aa(np.dot(vec3.invert3x3(rotations.aa2mx(ptrans)),rotations.aa2mx(coords2.rotRigid[j]))) match = np.linalg.norm(np.dot(ml2, dx)) < tol_shift \ and np.linalg.norm(dp) < tol_rot if(match): break if(not match): return False return True
def distance_squared(self, com1, p1, com2, p2): ''' distance measure between 2 angle axis bodies of same type Parameters ---------- com1: center of mass of 1st site p1: angle axis vector of 1st site com2: center of mass of 2nd site p2: angle axis vector of 2nd site sitetype: AASiteType, optional amgle axis site type with mass and moment of inertia tensor returns: distance squared ''' R1 = rotations.aa2mx(p1) R2 = rotations.aa2mx(p2) dR = R2 - R1 dR = dR d_M = self.W*np.sum((com2-com1)**2) # dR_kl S_lm dR_km d_P = np.trace(np.dot(dR, np.dot(self.S, dR.transpose()))) d_mix = 2.*self.W * np.dot((com2-com1), np.dot(dR, self.cog)) return d_M + d_P + d_mix
def zeroEV(self, x): zev = [] ca = self.coords_adapter(x) cv = self.coords_adapter(np.zeros(x.shape)) translate_rigid = zeroev.zeroEV_translation(ca.posRigid) for v in translate_rigid: cv.posRigid[:] = v zev.append(cv.coords.copy()) #rotate_r = zeroev.zeroEV_rotation(ca.posRigid) #rotate_aa = transform = TransformAngleAxisCluster(self) d = 1e-5 dx = x.copy() transform.rotate(dx, rotations.aa2mx(np.array([d, 0, 0]))) self.align_path([x, dx]) dx -= x dx /= np.linalg.norm(dx) dy = x.copy() transform.rotate(dy, rotations.aa2mx(np.array([0, d, 0]))) self.align_path([x, dy]) dy -= x dy /= np.linalg.norm(dy) dz = x.copy() transform.rotate(dz, rotations.aa2mx(np.array([0, 0, d]))) self.align_path([x, dz]) dz -= x dz /= np.linalg.norm(dz) #print "Zero eigenvectors", zev return zev + [dx, dy, dz]
def compareStructures(coords1, coords2): for refmol1 in xrange(coords1.nrigid): for refmol2 in xrange(refmol1, coords1.nrigid): x1 = coords1.posRigid[refmol1] x2 = coords2.posRigid[refmol2] pref1 = coords1.rotRigid[refmol1] pref2 = coords2.rotRigid[refmol2] #print "pref",pref1,pref2 M = vec3.invert3x3(rotations.aa2mx(pref1)) M = np.dot(rotations.aa2mx(pref2), M) # print x1,x2 ptest = pref1 ptrans = rotations.mx2aa(rotations.np.dot(M, rotations.aa2mx(ptest))) #print "---------------- start try",refmol1,refmol2 match1 = compareTransformed(coords1, coords2, x1, x2, M) match2 = compareTransformed(coords2, coords1, x2, x1, vec3.invert3x3(M)) if(match1 and match2): #print "Structures match" return True #import dmagmin_ as GMIN #GMIN.writeCIF("1.cif", coords1.coords) #GMIN.writeCIF("2.cif", coords2.coords) #import pickle #pickle.dump(coords1, open("1.dat", "w")) #pickle.dump(coords2, open("2.dat", "w")) #exit() return False
def test_dist(self): aadistance(self.v1, self.v2) v1n = np.linalg.norm(self.v1) v2n = np.linalg.norm(self.v2) v1inn = np.linalg.norm(self.v1in) v1inn = np.linalg.norm(self.v1in) distbefore = np.linalg.norm(self.v1in - self.v2in) distafter = np.linalg.norm(self.v1 - self.v2) self.assertTrue(distbefore >= distafter, "distance between aa vectors increased") import pygmin.utils.rotations as rot rot1 = rot.aa2mx(self.v1) rot1i = rot.aa2mx(self.v1in) self.assertTrue(all((rot1 == rot1i)[:].tolist()), "aa vector returned different rotation matrix") rot2 = rot.aa2mx(self.v2) rot2i = rot.aa2mx(self.v2in) self.assertTrue(all((rot2 == rot2i)[:].tolist()), "aa vector returned different rotation matrix")
def takeStep(self, coords, **kwargs): # easy access to coordinates ca = CoordsAdapter(nrigid=coords.size/6, coords = coords) # random rotation for angle-axis vectors for j in xrange(ca.nrigid): # choose bond to rotate around, index is first bead that changes index = np.random.randint(1, ca.nrigid) # 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 *= np.random.random()*self.stepsize # 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(p, ca.rotRigid[i]) 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 mouseMoveEvent(self, event): self.last_mouse_pos delta = (event.posF() - self.last_mouse_pos)*0.01 self.last_mouse_pos = event.posF() if(event.buttons() == Qt.LeftButton): drot = rot.aa2mx(-np.array([delta.y(), delta.x(), 0.])) self.rotation = np.dot(self.rotation, drot) elif(event.buttons() == Qt.RightButton): drot = rot.aa2mx(np.array([0., 0., delta.x()])) self.rotation = np.dot(self.rotation, drot) self.zoom *= 1.0 - 0.2*delta.y() self.repaint()
def mouseMoveEvent(self, event): self.last_mouse_pos delta = (event.posF() - self.last_mouse_pos) * 0.01 self.last_mouse_pos = event.posF() if (event.buttons() == Qt.LeftButton): drot = rot.aa2mx(-np.array([delta.y(), delta.x(), 0.])) self.rotation = np.dot(self.rotation, drot) elif (event.buttons() == Qt.RightButton): drot = rot.aa2mx(np.array([0., 0., delta.x()])) self.rotation = np.dot(self.rotation, drot) self.zoom *= 1.0 - 0.2 * delta.y() self.repaint()
def export_xyz(fl, coords): ca = CoordsAdapter(nrigid=coords.size/6, coords = coords) fl.write("%d\n\n"%(2*ca.nrigid)) for i in xrange(ca.nrigid): a = np.dot(rotations.aa2mx(ca.rotRigid[i]), np.array([1., 0., 0.])) x_back = ca.posRigid[i] - 0.4*a # backbone bead x_stack = ca.posRigid[i] + 0.4*a a = np.dot(rotations.aa2mx(ca.rotRigid[i]), np.array([0., 0., 1.])) x_tmp = x_back + 0.2*a fl.write("C %f %f %f\n"%(x_back[0], x_back[1], x_back[2])) fl.write("H %f %f %f\n"%(x_stack[0], x_stack[1], x_stack[2]))
def export_xyz(fl, coords): ca = CoordsAdapter(nrigid=coords.size / 6, coords=coords) fl.write("%d\n\n" % (2 * ca.nrigid)) for i in xrange(ca.nrigid): a = np.dot(rotations.aa2mx(ca.rotRigid[i]), np.array([1., 0., 0.])) x_back = ca.posRigid[i] - 0.4 * a # backbone bead x_stack = ca.posRigid[i] + 0.4 * a a = np.dot(rotations.aa2mx(ca.rotRigid[i]), np.array([0., 0., 1.])) x_tmp = x_back + 0.2 * a fl.write("C %f %f %f\n" % (x_back[0], x_back[1], x_back[2])) fl.write("H %f %f %f\n" % (x_stack[0], x_stack[1], x_stack[2]))
def Align(self, coords1, coords2): from pygmin.mindist import rmsfit,aamindist potential = GMINPotential(GMIN) ca1 = CoordsAdapter(nrigid=coords1.size/6, coords = coords1) ca2 = CoordsAdapter(nrigid=coords2.size/6, coords = coords2) rot = rmsfit.findrotation_kabsch(ca2.posRigid, ca1.posRigid) ca2.posRigid[:] = np.dot(rot,ca2.posRigid.transpose()).transpose() for p in ca2.rotRigid: p[:] = rotations.mx2aa((np.dot(rot, rotations.aa2mx(p)))) print "before" print potential.getEnergy(coords1), potential.getEnergy(coords2) print ca2.rotRigid - ca1.rotRigid for p1,p2 in zip(ca1.rotRigid, ca2.rotRigid): p1[:],p2[:] = aamindist.aadistance(p1, p2) print "after" print potential.getEnergy(coords1), potential.getEnergy(coords2) print ca2.rotRigid - ca1.rotRigid path = InterpolatedPath(coords1, coords2, 40) print potential.getEnergy(path[0]) print "Interpolated energies" for x in InterpolatedPath(coords1, coords2, 40): print potential.getEnergy(x) print "done" return coords1, coords2
def test_distpot(): #define two structures natoms = 12 X1 = np.random.uniform(-1,1,[natoms*3])*(float(natoms))**(1./3) X2 = np.random.uniform(-1,1,[natoms*3])*(float(natoms))**(1./3) #make X2 a rotation of X1 print "testing with", natoms, "atoms, with X2 a rotated and permuted isomer of X1" aa = rot.random_aa() rot_mx = rot.aa2mx( aa ) for j in range(natoms): i = 3*j X2[i:i+3] = np.dot( rot_mx, X1[i:i+3] ) #import random, mindistutils #perm = range(natoms) #random.shuffle( perm ) #print perm #X2 = mindistutils.permuteArray( X2, perm) pot = MinPermDistPotential(X1, X2, L = .2) aa = rot.random_aa() e = pot.getEnergy(aa) print "energy", e de, dg = pot.getEnergyGradient(aa) print "energy from gradient", de, "diff", e-de den, dgn = pot.getEnergyGradientNumerical(aa) maxgrad= np.max( np.abs( dg ) ) maxdiff = np.max( np.abs( dg - dgn ) ) print "maximum gradient", maxgrad print "max difference in analytical vs numerical gradient", maxdiff
def testBLJ_isomer(self): """ test with BLJ potential. We have two classes of permutable atoms test case where X2 is an isomer of X1. """ import pygmin.utils.rotations as rot X1i = np.copy(self.X1) X1 = np.copy(self.X1) X2 = np.copy(X1) #rotate X2 randomly aa = rot.random_aa() rot_mx = rot.aa2mx( aa ) for j in range(self.natoms): i = 3*j X2[i:i+3] = np.dot( rot_mx, X1[i:i+3] ) #permute X2 import random, copy from pygmin.mindist.permutational_alignment import permuteArray for atomlist in self.permlist: perm = copy.copy(atomlist) random.shuffle( perm ) X2 = permuteArray( X2, perm) X2i = np.copy(X2) #distreturned, X1, X2 = self.runtest(X1, X2) distreturned, X1, X2 = self.runtest(X1, X2, minPermDistStochastic) #it's an isomer, so the distance should be zero self.assertTrue( abs(distreturned) < 1e-14, "didn't find isomer: dist = %g" % (distreturned) )
def test_distpot(): #define two structures natoms = 12 X1 = np.random.uniform(-1, 1, [natoms * 3]) * (float(natoms))**(1. / 3) X2 = np.random.uniform(-1, 1, [natoms * 3]) * (float(natoms))**(1. / 3) #make X2 a rotation of X1 print "testing with", natoms, "atoms, with X2 a rotated and permuted isomer of X1" aa = rot.random_aa() rot_mx = rot.aa2mx(aa) for j in range(natoms): i = 3 * j X2[i:i + 3] = np.dot(rot_mx, X1[i:i + 3]) #import random, mindistutils #perm = range(natoms) #random.shuffle( perm ) #print perm #X2 = mindistutils.permuteArray( X2, perm) pot = MinPermDistPotential(X1, X2, L=.2) aa = rot.random_aa() e = pot.getEnergy(aa) print "energy", e de, dg = pot.getEnergyGradient(aa) print "energy from gradient", de, "diff", e - de den, dgn = pot.getEnergyGradientNumerical(aa) maxgrad = np.max(np.abs(dg)) maxdiff = np.max(np.abs(dg - dgn)) print "maximum gradient", maxgrad print "max difference in analytical vs numerical gradient", maxdiff
def test_binary_LJ(natoms=12, **kwargs): import pygmin.defaults import pygmin.utils.rotations as rot quench = pygmin.defaults.quenchRoutine printlist = [] ntypea = int(natoms * .8) from pygmin.potentials.ljpshift import LJpshift lj = LJpshift(natoms, ntypea) permlist = [range(ntypea), range(ntypea, natoms)] X1 = np.random.uniform(-1, 1, [natoms * 3]) * (float(natoms))**(1. / 3) / 2 printlist.append((X1.copy(), "very first")) #quench X1 ret = quench(X1, lj.getEnergyGradient) X1 = ret[0] printlist.append((X1.copy(), "after quench")) X2 = np.random.uniform(-1, 1, [natoms * 3]) * (float(natoms))**(1. / 3) #make X2 a rotation of X1 print "testing with", natoms, "atoms,", ntypea, "type A atoms, with X2 a rotated and permuted isomer of X1" aa = rot.random_aa() rot_mx = rot.aa2mx(aa) for j in range(natoms): i = 3 * j X2[i:i + 3] = np.dot(rot_mx, X1[i:i + 3]) printlist.append((X2.copy(), "x2 after rotation")) import random, copy from pygmin.mindist.permutational_alignment import permuteArray for atomlist in permlist: perm = copy.copy(atomlist) random.shuffle(perm) print perm X2 = permuteArray(X2, perm) printlist.append((X2.copy(), "x2 after permutation")) #X1 = np.array( [ 0., 0., 0., 1., 0., 0., 0., 0., 1.,] ) #X2 = np.array( [ 0., 0., 0., 1., 0., 0., 0., 1., 0.,] ) X1i = copy.copy(X1) X2i = copy.copy(X2) atomtypes = ["N" for i in range(ntypea)] for i in range(natoms - ntypea): atomtypes.append("O") print "******************************" print "testing binary LJ ISOMER" print "******************************" test(X1, X2, lj, atomtypes=atomtypes, permlist=permlist, **kwargs) print "******************************" print "testing binary LJ non isomer" print "******************************" X2 = np.random.uniform(-1, 1, [natoms * 3]) * (float(natoms))**(1. / 3) ret = quench(X2, lj.getEnergyGradient) X2 = ret[0] test(X1, X2, lj, atomtypes=atomtypes, permlist=permlist, **kwargs)
def testBLJ_isomer(self): """ test with BLJ potential. We have two classes of permutable atoms test case where X2 is an isomer of X1. """ import pygmin.utils.rotations as rot X1i = np.copy(self.X1) X1 = np.copy(self.X1) X2 = np.copy(X1) #rotate X2 randomly aa = rot.random_aa() rot_mx = rot.aa2mx(aa) for j in range(self.natoms): i = 3 * j X2[i:i + 3] = np.dot(rot_mx, X1[i:i + 3]) #permute X2 import random, copy from pygmin.mindist.permutational_alignment import permuteArray for atomlist in self.permlist: perm = copy.copy(atomlist) random.shuffle(perm) X2 = permuteArray(X2, perm) X2i = np.copy(X2) #distreturned, X1, X2 = self.runtest(X1, X2) distreturned, X1, X2 = self.runtest(X1, X2, minPermDistStochastic) #it's an isomer, so the distance should be zero self.assertTrue( abs(distreturned) < 1e-14, "didn't find isomer: dist = %g" % (distreturned))
def __init__(self, parent): QGLWidget.__init__(self, parent) self.setMinimumSize(200, 200) # glutInit()#sys.argv) self.coords = {} self.minima = {} self.last_mouse_pos = QtCore.QPointF(0., 0.) self.rotation = rot.aa2mx(np.array([0.,0.,0.])) # np.array([0., 0.]) self.zoom = 1.0
def __init__(self, parent): QGLWidget.__init__(self, parent) self.setMinimumSize(200, 200) # glutInit()#sys.argv) self.coords = {1: None, 2: None} self.minima = {1: None, 2: None} self.last_mouse_pos = QtCore.QPointF(0., 0.) self.rotation = rot.aa2mx(np.array([0., 0., 0.])) # np.array([0., 0.]) self.zoom = 1.0
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 __call__(self, coords1, coords2): ''' Parameters ---------- coords1, coords2 : np.array the structures to align. X2 will be aligned with X1, both the center of masses will be shifted to the origin Returns ------- a tripple of (dist, coords1, coords2). coords1 are the unchanged coords1 and coords2 are brought in best alignment with coords2 ''' # we don't want to change the given coordinates check_inversion = False x1 = np.copy(coords1) x2 = np.copy(coords2) com1 = self.measure.get_com(x1) self.transform.translate(x1, -com1) com2 = self.measure.get_com(x2) self.transform.translate(x2, -com2) self.com_shift = com1 self.mxbest = np.identity(3) self.distbest = self.measure.get_dist(x1, x2) self.x2_best = x2.copy() if self.distbest < self.tol: return self.distbest, x1, x2 for rot, invert in self._standard_alignments(x1, x2): self.check_match(x1, x2, rot, invert) if self.distbest < self.tol: dist, x2 = self.finalize_best_match(coords1) return dist, coords1, x2 # if we didn't find a perfect match here, try random rotations to optimize the match for i in range(self.niter): rot = rotations.aa2mx(rotations.random_aa()) self.check_match(x1, x2, rot, False) if (self.transform.can_invert()): self.check_match(x1, x2, rot, True) # self.transform.rotate(X2, mxbest) # dist, perm = self.measure.find_permutation(X1, X2) # X2 = self.transform.permute(X2, perm) # tmp, mx = self.measure.find_rotation(X1.copy(), X2.copy()) # self.transform.rotate(X2, mx) # TODO: should we do an additional sanity check for permutation / rotation? dist, x2 = self.finalize_best_match(coords1) return dist, coords1, 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 __call__(self, coords1, coords2): ''' Parameters ---------- coords1, coords2 : np.array the structures to align. X2 will be aligned with X1, both the center of masses will be shifted to the origin Returns ------- a tripple of (dist, coords1, coords2). coords1 are the unchanged coords1 and coords2 are brought in best alignment with coords2 ''' # we don't want to change the given coordinates check_inversion = False x1 = np.copy(coords1) x2 = np.copy(coords2) com1 = self.measure.get_com(x1) self.transform.translate(x1, -com1) com2 = self.measure.get_com(x2) self.transform.translate(x2, -com2) self.com_shift = com1 self.mxbest = np.identity(3) self.distbest = self.measure.get_dist(x1, x2) self.x2_best = x2.copy() if self.distbest < self.tol: return self.distbest, x1, x2 for rot, invert in self._standard_alignments(x1, x2): self.check_match(x1, x2, rot, invert) if self.distbest < self.tol: dist, x2 = self.finalize_best_match(coords1) return dist, coords1, x2 # if we didn't find a perfect match here, try random rotations to optimize the match for i in range(self.niter): rot = rotations.aa2mx(rotations.random_aa()) self.check_match(x1, x2, rot, False) if(self.transform.can_invert()): self.check_match(x1, x2, rot, True) # self.transform.rotate(X2, mxbest) # dist, perm = self.measure.find_permutation(X1, X2) # X2 = self.transform.permute(X2, perm) # tmp, mx = self.measure.find_rotation(X1.copy(), X2.copy()) # self.transform.rotate(X2, mx) # TODO: should we do an additional sanity check for permutation / rotation? dist, x2 = self.finalize_best_match(coords1) return dist, coords1, x2
def aa2xyz(XB, AA): """ Rotate XB according to angle axis AA """ nsites = len(XB)/3 XBnew = np.copy(XB) rot_mx = rot.aa2mx( AA ) for j in range(nsites): i = 3*j XBnew[i:i+3] = np.dot( rot_mx, XBnew[i:i+3] ) return XBnew
def aa2xyz(XB, AA): """ Rotate XB according to angle axis AA """ nsites = len(XB) / 3 XBnew = np.copy(XB) rot_mx = rot.aa2mx(AA) for j in range(nsites): i = 3 * j XBnew[i:i + 3] = np.dot(rot_mx, XBnew[i:i + 3]) return XBnew
def test_LJ(natoms = 12, **kwargs): from pygmin.potentials.lj import LJ from pygmin.optimize import mylbfgs import pygmin.utils.rotations as rot from pygmin.mindist.permutational_alignment import permuteArray import random quench = mylbfgs lj = LJ() X1 = np.random.uniform(-1,1,[natoms*3])*(float(natoms))**(1./3) #quench X1 ret = quench( X1, lj) X1 = ret.coords X2 = np.random.uniform(-1,1,[natoms*3])*(float(natoms))**(1./3) #make X2 a rotation of X1 print "testing with", natoms, "atoms, with X2 a rotated and permuted isomer of X1" aa = rot.random_aa() rot_mx = rot.aa2mx( aa ) for j in range(natoms): i = 3*j X2[i:i+3] = np.dot( rot_mx, X1[i:i+3] ) perm = range(natoms) random.shuffle( perm ) print perm X2 = permuteArray( X2, perm) #X1 = np.array( [ 0., 0., 0., 1., 0., 0., 0., 0., 1.,] ) #X2 = np.array( [ 0., 0., 0., 1., 0., 0., 0., 1., 0.,] ) import copy X1i = copy.copy(X1) X2i = copy.copy(X2) print "******************************" print "testing normal LJ ISOMER" print "******************************" test(X1, X2, lj, **kwargs) print "******************************" print "testing normal LJ non isomer" print "******************************" X2 = np.random.uniform(-1,1,[natoms*3])*(float(natoms))**(1./3) ret = quench( X2, lj) X2 = ret.coords Y = X1.reshape([-1,3]) Y+=np.random.random(3) X1[:] = Y.flatten() test(X1, X2, lj, **kwargs) distinit = np.linalg.norm(X1-X2) print "distinit", distinit
def test(v1in, v2in, aadistfunc=aadistance): v1 = np.copy(v1in) v2 = np.copy(v2in) print v1, v2 v1n = np.linalg.norm(v1) v2n = np.linalg.norm(v2) print "initial norms", v1n, v2n aadistfunc(v1, v2) v3n = np.linalg.norm(v1) v4n = np.linalg.norm(v2) print "final norms ", v3n, v4n import pygmin.utils.rotations as rot print "v1 unchanged:", all((rot.aa2mx(v1) == rot.aa2mx(v1in))[:].tolist()) print "v2 unchanged:", all((rot.aa2mx(v2) == rot.aa2mx(v2in))[:].tolist()) print "cartesian distance between vectors before", np.linalg.norm(v1in - v2in) print "cartesian distance between vectors after ", np.linalg.norm(v1 - v2)
def test_LJ(natoms=12, **kwargs): from pygmin.potentials.lj import LJ from pygmin.optimize import mylbfgs import pygmin.utils.rotations as rot from pygmin.mindist.permutational_alignment import permuteArray import random quench = mylbfgs lj = LJ() X1 = np.random.uniform(-1, 1, [natoms * 3]) * (float(natoms))**(1. / 3) #quench X1 ret = quench(X1, lj) X1 = ret.coords X2 = np.random.uniform(-1, 1, [natoms * 3]) * (float(natoms))**(1. / 3) #make X2 a rotation of X1 print "testing with", natoms, "atoms, with X2 a rotated and permuted isomer of X1" aa = rot.random_aa() rot_mx = rot.aa2mx(aa) for j in range(natoms): i = 3 * j X2[i:i + 3] = np.dot(rot_mx, X1[i:i + 3]) perm = range(natoms) random.shuffle(perm) print perm X2 = permuteArray(X2, perm) #X1 = np.array( [ 0., 0., 0., 1., 0., 0., 0., 0., 1.,] ) #X2 = np.array( [ 0., 0., 0., 1., 0., 0., 0., 1., 0.,] ) import copy X1i = copy.copy(X1) X2i = copy.copy(X2) print "******************************" print "testing normal LJ ISOMER" print "******************************" test(X1, X2, lj, **kwargs) print "******************************" print "testing normal LJ non isomer" print "******************************" X2 = np.random.uniform(-1, 1, [natoms * 3]) * (float(natoms))**(1. / 3) ret = quench(X2, lj) X2 = ret.coords Y = X1.reshape([-1, 3]) Y += np.random.random(3) X1[:] = Y.flatten() test(X1, X2, lj, **kwargs) distinit = np.linalg.norm(X1 - X2) print "distinit", distinit
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 test(v1in, v2in, aadistfunc = aadistance): v1 = np.copy(v1in) v2 = np.copy(v2in) print v1, v2 v1n = np.linalg.norm(v1) v2n = np.linalg.norm(v2) print "initial norms", v1n, v2n aadistfunc(v1, v2) v3n = np.linalg.norm(v1) v4n = np.linalg.norm(v2) print "final norms ", v3n, v4n import pygmin.utils.rotations as rot print "v1 unchanged:", all( (rot.aa2mx( v1) == rot.aa2mx( v1in))[:].tolist() ) print "v2 unchanged:", all( (rot.aa2mx( v2) == rot.aa2mx( v2in))[:].tolist() ) print "cartesian distance between vectors before", np.linalg.norm(v1in-v2in) print "cartesian distance between vectors after ", np.linalg.norm(v1-v2)
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 getEnergy_no_rigid_body(self, AA ): # Rotate XB0 according to angle axis AA rot_mx = rot.aa2mx( AA ) for j in range(self.nsites): i = 3*j self.XB[i:i+3] = np.dot( rot_mx, self.XB0[i:i+3] ) #return distance between XB and XA0 E = 0. for atomlist in self.permlist: E -= self.overlap( self.XA0, self.XB, self.L2, atomlist, [self.nsites, len(atomlist)]) #if E < -10.5: # print E, atomlist, [self.nsites, len(atomlist)], len(self.XA0), len(self.XB) return E
def _optimizePermRot(X1, X2, niter, permlist, verbose=False, use_quench=True): if use_quench: pot = MinPermDistPotential(X1, X2.copy(), permlist=permlist) distbest = getDistxyz(X1, X2) mxbest = np.identity(3) X20 = X2.copy() for i in range(niter): #get and apply a random rotation aa = random_aa() if not use_quench: mx = aa2mx(aa) mxtot = mx #print "X2.shape", X2.shape else: #optimize the rotation using a permutationally invariand distance metric ret = defaults.quenchRoutine(aa, pot.getEnergyGradient, tol=0.01) aa1 = ret[0] mx1 = aa2mx(aa1) mxtot = mx1 X2 = applyRotation(mxtot, X20) #optimize the permutations dist, X1, X2 = findBestPermutation(X1, X2, permlist) if verbose: print "dist", dist, "distbest", distbest #print "X2.shape", X2.shape #optimize the rotation dist, Q2 = getAlignRotation(X1, X2) # print "dist", dist, "Q2", Q2 mx2 = q2mx(Q2) mxtot = np.dot(mx2, mxtot) if dist < distbest: distbest = dist mxbest = mxtot return distbest, mxbest
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 test_dist(self): aadistance(self.v1, self.v2) v1n = np.linalg.norm(self.v1) v2n = np.linalg.norm(self.v2) v1inn = np.linalg.norm(self.v1in) v1inn = np.linalg.norm(self.v1in) distbefore = np.linalg.norm(self.v1in - self.v2in) distafter = np.linalg.norm(self.v1 - self.v2) self.assertTrue(distbefore >= distafter, "distance between aa vectors increased") import pygmin.utils.rotations as rot rot1 = rot.aa2mx( self.v1 ) rot1i = rot.aa2mx( self.v1in ) self.assertTrue( all( (rot1 == rot1i)[:].tolist() ), "aa vector returned different rotation matrix" ) rot2 = rot.aa2mx( self.v2 ) rot2i = rot.aa2mx( self.v2in ) self.assertTrue( all( (rot2 == rot2i)[:].tolist() ), "aa vector returned different rotation matrix" )
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 getEnergy_no_rigid_body(self, AA): # Rotate XB0 according to angle axis AA rot_mx = rot.aa2mx(AA) for j in range(self.nsites): i = 3 * j self.XB[i:i + 3] = np.dot(rot_mx, self.XB0[i:i + 3]) #return distance between XB and XA0 E = 0. for atomlist in self.permlist: E -= self.overlap(self.XA0, self.XB, self.L2, atomlist, [self.nsites, len(atomlist)]) #if E < -10.5: # print E, atomlist, [self.nsites, len(atomlist)], len(self.XA0), len(self.XB) return E
def test_LJ(natoms = 12, **kwargs): from pygmin.potentials.lj import LJ import pygmin.defaults import pygmin.utils.rotations as rot from pygmin.mindist.permutational_alignment import permuteArray import random quench = pygmin.defaults.quenchRoutine lj = LJ() X1 = np.random.uniform(-1,1,[natoms*3])*(float(natoms))**(1./3) #quench X1 ret = quench( X1, lj.getEnergyGradient) X1 = ret[0] X2 = np.random.uniform(-1,1,[natoms*3])*(float(natoms))**(1./3) #make X2 a rotation of X1 print "testing with", natoms, "atoms, with X2 a rotated and permuted isomer of X1" aa = rot.random_aa() rot_mx = rot.aa2mx( aa ) for j in range(natoms): i = 3*j X2[i:i+3] = np.dot( rot_mx, X1[i:i+3] ) perm = range(natoms) random.shuffle( perm ) print perm X2 = permuteArray( X2, perm) #X1 = np.array( [ 0., 0., 0., 1., 0., 0., 0., 0., 1.,] ) #X2 = np.array( [ 0., 0., 0., 1., 0., 0., 0., 1., 0.,] ) import copy X1i = copy.copy(X1) X2i = copy.copy(X2) print "******************************" print "testing normal LJ ISOMER" print "******************************" test(X1, X2, lj, **kwargs) print "******************************" print "testing normal LJ non isomer" print "******************************" X2 = np.random.uniform(-1,1,[natoms*3])*(float(natoms))**(1./3) ret = quench( X2, lj.getEnergyGradient) X2 = ret[0] test(X1, X2, lj, **kwargs) distinit = np.linalg.norm(X1-X2) print "distinit", distinit
def draw(self, coordslinear, index): ca = CoordsAdapter(nrigid=coordslinear.size/6,coords=coordslinear) from OpenGL import GL,GLUT com=np.mean(ca.posRigid, axis=0) for xx, rot in zip(ca.posRigid, ca.rotRigid): p = np.dot(rotations.aa2mx(rot), np.array([1., 0., 0.])) x=xx-com x = x - 0.4*p GL.glPushMatrix() GL.glTranslate(x[0],x[1],x[2]) GLUT.glutSolidSphere(0.3,30,30) p=0.8*p self.drawCylinder([0.,0.,0.], p) GL.glTranslate(p[0],p[1],p[2]) GLUT.glutSolidSphere(0.1,30,30) GL.glPopMatrix()
def takeStep(self, coords, **kwargs): # easy access to coordinates ca = CoordsAdapter(nrigid=coords.size/6, coords = coords) backbone = np.zeros(3) # random rotation for angle-axis vectors for pos, rot in zip(ca.posRigid, ca.rotRigid): backbone = backbone + rotations.vec_random( )*0.7525 # choose a random rotation rot[:] = rotations.random_aa() # calcualte center of base from backgone a1 = np.dot(rotations.aa2mx(rot), np.array([1., 0., 0.])) pos[:] = backbone + 0.4 * a1
def test_LJ(natoms=12, **kwargs): from pygmin.potentials.lj import LJ import pygmin.defaults import pygmin.utils.rotations as rot from pygmin.mindist.permutational_alignment import permuteArray import random quench = pygmin.defaults.quenchRoutine lj = LJ() X1 = np.random.uniform(-1, 1, [natoms * 3]) * (float(natoms))**(1. / 3) #quench X1 ret = quench(X1, lj.getEnergyGradient) X1 = ret[0] X2 = np.random.uniform(-1, 1, [natoms * 3]) * (float(natoms))**(1. / 3) #make X2 a rotation of X1 print "testing with", natoms, "atoms, with X2 a rotated and permuted isomer of X1" aa = rot.random_aa() rot_mx = rot.aa2mx(aa) for j in range(natoms): i = 3 * j X2[i:i + 3] = np.dot(rot_mx, X1[i:i + 3]) perm = range(natoms) random.shuffle(perm) print perm X2 = permuteArray(X2, perm) #X1 = np.array( [ 0., 0., 0., 1., 0., 0., 0., 0., 1.,] ) #X2 = np.array( [ 0., 0., 0., 1., 0., 0., 0., 1., 0.,] ) import copy X1i = copy.copy(X1) X2i = copy.copy(X2) print "******************************" print "testing normal LJ ISOMER" print "******************************" test(X1, X2, lj, **kwargs) print "******************************" print "testing normal LJ non isomer" print "******************************" X2 = np.random.uniform(-1, 1, [natoms * 3]) * (float(natoms))**(1. / 3) ret = quench(X2, lj.getEnergyGradient) X2 = ret[0] test(X1, X2, lj, **kwargs) distinit = np.linalg.norm(X1 - X2) print "distinit", distinit
def distance_squared_grad(self, com1, p1, com2, p2): ''' calculate spring force between 2 sites Parameters ---------- com1: center of mass of 1st site p1: angle axis vector of 1st site com2: center of mass of 2nd site p2: angle axis vector of 2nd site sitetype: AASiteType, optional amgle axis site type with mass and moment of inertia tensor returns: tuple spring cart, spring rot ''' return _aadist.sitedist_grad(self.get_smallest_rij(com1, com2), p1, p2, self.S, self.W, self.cog) R1, R11, R12, R13 = rotMatDeriv(p1, True) R2 = rotations.aa2mx(p2) dR = R2 - R1 dR = dR g_M = -2.*self.W*(com2-com1) # dR_kl S_lm dR_km g_P = np.zeros(3) g_P[0] = -2.*np.trace(np.dot(R11, np.dot(self.S, dR.transpose()))) g_P[1] = -2.*np.trace(np.dot(R12, np.dot(self.S, dR.transpose()))) g_P[2] = -2.*np.trace(np.dot(R13, np.dot(self.S, dR.transpose()))) g_M -= 2.*self.W * np.dot(dR, self.cog) g_P[0] -= 2.*self.W * np.dot((com2-com1), np.dot(R11, self.cog)) g_P[1] -= 2.*self.W * np.dot((com2-com1), np.dot(R12, self.cog)) g_P[2] -= 2.*self.W * np.dot((com2-com1), np.dot(R13, self.cog)) return g_M, g_P
xyz = otp.getxyz() from pygmin.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
def getxyz(self, com=np.array([0.,0.,0.]), aa=np.array([0.,0.,1e-6]) ): """return the xyz positions of all sites in the molecule-frame""" mx = rot.aa2mx(aa) return self.getxyz_rmat(mx, com)
x -= np.average(x, axis=0, weights=masses) cog = np.average(x, axis=0) S=np.zeros([3,3]) for i in xrange(3): for j in xrange(3): S[i][j]=np.sum(x[:,i]*x[:,j]) site = AASiteType(M=natoms, S=S, W=natoms, cog=cog) X1=np.zeros(3) p1=np.zeros(3) X1 = 10.1*np.random.random(3) X2 = 10.1*np.random.random(3) p1 = rotations.random_aa() p2 = rotations.random_aa() R1 = rotations.aa2mx(p1) R2 = rotations.aa2mx(p2) x1 = np.dot(R1, x.transpose()).transpose() + X1 x2 = np.dot(R2, x.transpose()).transpose() + X2 print "site representation:", np.sum((x1-x2)**2) print "distance function: ", site.distance_squared(X1, p1, X2, p2) print site.distance_squared_grad(X1, p1, X2, p2) g_M = np.zeros(3) g_P = np.zeros(3) for i in xrange(3): eps = 1e-6 delta = np.zeros(3) delta[i] = eps
def getxyz(self, com=np.array([0., 0., 0.]), aa=np.array([0., 0., 1e-6])): """return the xyz positions of all sites in the molecule-frame""" mx = rot.aa2mx(aa) return self.getxyz_rmat(mx, com)
x -= np.average(x, axis=0, weights=masses) cog = np.average(x, axis=0) S=np.zeros([3,3]) for i in xrange(3): for j in xrange(3): S[i][j]=np.sum(x[:,i]*x[:,j]) site = AASiteType(M=natoms, S=S, W=natoms, cog=cog) X1=np.zeros(3) p1=np.zeros(3) X1 = 10.1*np.random.random(3) X2 = 10.1*np.random.random(3) p1 = rotations.random_aa() p2 = rotations.random_aa() R1 = rotations.aa2mx(p1) R2 = rotations.aa2mx(p2) x1 = np.dot(R1, x.transpose()).transpose() + X1 x2 = np.dot(R2, x.transpose()).transpose() + X2 import _aadist print "site representation:", np.sum((x1-x2)**2) print "distance function: ", site.distance_squared(X1, p1, X2, p2) print "fortran function: ", _aadist.sitedist(X2 - X1, p1, p2, site.S, site.W, cog) coords1 = np.random.random(120) coords2 = np.random.random(120) import time
def test_molecule(): otp = setupLWOTP() xyz = otp.getxyz() from pygmin.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
def test_binary_LJ(natoms = 12, **kwargs): import pygmin.defaults import pygmin.utils.rotations as rot quench = pygmin.defaults.quenchRoutine printlist = [] ntypea = int(natoms*.8) from pygmin.potentials.ljpshift import LJpshift lj = LJpshift(natoms, ntypea) permlist = [range(ntypea), range(ntypea, natoms)] X1 = np.random.uniform(-1,1,[natoms*3])*(float(natoms))**(1./3)/2 printlist.append( (X1.copy(), "very first")) #quench X1 ret = quench( X1, lj.getEnergyGradient) X1 = ret[0] printlist.append((X1.copy(), "after quench")) X2 = np.random.uniform(-1,1,[natoms*3])*(float(natoms))**(1./3) #make X2 a rotation of X1 print "testing with", natoms, "atoms,", ntypea, "type A atoms, with X2 a rotated and permuted isomer of X1" aa = rot.random_aa() rot_mx = rot.aa2mx( aa ) for j in range(natoms): i = 3*j X2[i:i+3] = np.dot( rot_mx, X1[i:i+3] ) printlist.append((X2.copy(), "x2 after rotation")) import random, copy from pygmin.mindist.permutational_alignment import permuteArray for atomlist in permlist: perm = copy.copy(atomlist) random.shuffle( perm ) print perm X2 = permuteArray( X2, perm) printlist.append((X2.copy(), "x2 after permutation")) #X1 = np.array( [ 0., 0., 0., 1., 0., 0., 0., 0., 1.,] ) #X2 = np.array( [ 0., 0., 0., 1., 0., 0., 0., 1., 0.,] ) X1i = copy.copy(X1) X2i = copy.copy(X2) atomtypes = ["N" for i in range(ntypea)] for i in range(natoms-ntypea): atomtypes.append("O") print "******************************" print "testing binary LJ ISOMER" print "******************************" test(X1, X2, lj, atomtypes=atomtypes, permlist = permlist, **kwargs) print "******************************" print "testing binary LJ non isomer" print "******************************" X2 = np.random.uniform(-1,1,[natoms*3])*(float(natoms))**(1./3) ret = quench( X2, lj.getEnergyGradient) X2 = ret[0] test(X1, X2, lj, atomtypes=atomtypes, permlist=permlist, **kwargs)