def getEnergyGradient(self, coords): #return self.getEnergy(coords), self.NumericalDerivative(coords) E, grad = GMINPotential.getEnergyGradient(self, coords) ca = CoordsAdapter(nrigid=old_div(coords.size, 6), coords=coords) RMX = [rotMatDeriv(p, True) for p in ca.rotRigid] xback = [ x - 0.4 * np.dot(r[0], np.array([1., 0., 0.])) for x, r in zip(ca.posRigid, RMX) ] xbase = [ x - 0.4 * np.dot(r[0], np.array([1., 0., 0.])) for x, r in zip(ca.posRigid, RMX) ] gback = np.zeros_like(xback) Eangle = 0. v2 = xback[1] - xback[0] absv2 = np.linalg.norm(v2) v2 /= absv2 for i in range(1, ca.nrigid - 1): v1 = -v2 absv1 = absv2 v2 = xback[i + 1] - xback[i] absv2 = np.linalg.norm(v2) v2 /= absv2 v1v2 = np.dot(v1, v2) theta = np.arccos(v1v2) Eangle += 0.5 * self.k * (theta - self.theta0)**2 acos_prime = 1. / np.sqrt(1. - v1v2**2) s = self.k * (theta - self.theta0) * acos_prime gback[i - 1] += s * (old_div(-v2, absv1) + old_div(v1v2 * v1, absv1)) gback[i] += s * (old_div(v1, absv2) + old_div(v2, absv1) - old_div( v1v2 * v1, absv1) - old_div(v1v2 * v2, absv2)) gback[i + 1] += s * (old_div(-v1, absv2) + old_div(v1v2 * v2, absv2)) Etorsion = 0 if self.use_torsion: for i in range(ca.nrigid - 3): r = xback[i:i + 4] theta = dihedral_angle(r) e_theta, g_theta = U_torsion_back_grad(theta) Etorsion += e_theta gback[i:i + 4] += g_theta * dihedral_gradient(r) cg = CoordsAdapter(nrigid=ca.nrigid, coords=grad) cg.posRigid += gback for i in range(ca.nrigid): x = -0.4 * np.array([1., 0., 0.]) R = RMX[i] cg.rotRigid[i][0] += np.dot(gback[i], np.dot(R[1], x)) cg.rotRigid[i][1] += np.dot(gback[i], np.dot(R[2], x)) cg.rotRigid[i][2] += np.dot(gback[i], np.dot(R[3], x)) return E + Eangle + Etorsion, grad
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.radius * (np.random.random(ca.posRigid.shape) - 0.5) # random rotation for angle-axis vectors for rot in ca.rotRigid: rot[:] = rotations.random_aa()
def finalize_best_match(self, x1, best_x2): ''' do final processing of the best match ''' ca1 = CoordsAdapter(coords=x1) ca2 = CoordsAdapter(coords=best_x2) dx = ca1.posRigid - ca2.posRigid dx = np.round(dx / self.boxvec) * self.boxvec self.transform.translate(best_x2, dx) dist = self.measure.get_dist(x1, best_x2) # if (dist - self.distbest) > 1e-6: # raise RuntimeError(dist, self.distbest, "Permutational alignment has increased the distance metric") if self.verbose: print("finaldist", dist, "distmin", self.distbest) return dist, best_x2
def translate(self, X, d): """ Performs an in-place translation of coordinates X by vector d """ ca = CoordsAdapter(coords=X) if (ca.nrigid > 0): ca.posRigid += d if (ca.natoms > 0): ca.posAtom += d
def getEnergy(self, coords): E = GMINPotential.getEnergy(self, coords) ca = CoordsAdapter(nrigid=old_div(coords.size, 6), coords=coords) RMX = [rotMatDeriv(p, True) for p in ca.rotRigid] xback = np.array([ x - 0.4 * np.dot(r[0], np.array([1., 0., 0.])) for x, r in zip(ca.posRigid, RMX) ]) xbase = np.array([ x + 0.4 * np.dot(r[0], np.array([1., 0., 0.])) for x, r in zip(ca.posRigid, RMX) ]) Eangle = 0 v2 = xback[1] - xback[0] v2 /= np.linalg.norm(v2) for i in range(1, ca.nrigid - 1): v1 = -v2.copy() v2 = xback[i + 1] - xback[i] v2 /= np.linalg.norm(v2) theta = np.arccos(np.dot(v1, v2)) Eangle += 0.5 * self.k * (theta - self.theta0)**2 # add the torsion angle Etorsion = 0 if self.use_torsion: for i in range(ca.nrigid - 3): theta = dihedral_angle(xback[i:i + 4]) Etorsion += U_torsion_back(theta) return E + Eangle + Etorsion
def takeStep(self, coords, **kwargs): # easy access to coordinates ca = CoordsAdapter(nrigid=old_div(coords.size, 6), coords=coords) # random displacement for positions ca.posRigid[:] += 2. * self.displace * ( np.random.random(ca.posRigid.shape) - 0.5) # random rotation for angle-axis vectors takestep.rotate(self.rotate, ca.rotRigid)
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 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_fragments(self, coords1, coords2): """ Obtain the best alignment between two configurations of a periodic system Parameters ---------- coords1, coords2 : np.array the structures to align. X2 will be aligned with X1 Both structures are arrays of rigid body com positions and aa vectors Returns ------- a triple of (dist, coords1, coords2). coords1 are the unchanged coords1 and coords2 are brought in best alignment with coords2 """ if self.verbose: print("Measure:") print(self.measure) print("Transform:") print(self.transform) print("Measure.topology:") print(self.measure.topology) print("Called by", stack()) # we don't want to change the given coordinates coords1 = coords1.copy() coords2 = coords2.copy() x1 = np.copy(coords1) x2 = np.copy(coords2) self.distbest = self.measure.get_dist(x1, x2) ca1 = CoordsAdapter(coords=x1) ca2 = CoordsAdapter(coords=x2) dx = ca1.posRigid - ca2.posRigid dx -= np.round(dx / self.boxvec) * self.boxvec ave2 = dx.sum(0) / ca1.nrigid self.transform.translate(x2, ave2) dist, x2 = self.finalize_best_match(coords1, x2) return dist, coords1, x2
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 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 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 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 takeStep(self, coords, **kwargs): # easy access to coordinates ca = CoordsAdapter(nrigid=old_div(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 += 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 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)
exit() db=Database(db="oxdna.sqlite") path[0]=db.minima()[19].coords path[-1]=db.minima()[0].coords e1 = [] e2 = [] e1.append(pot.getEnergy(path[0])) 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:
pickle.dump(path, open("interpolate.pickle", "w")) exit() db = Database(db="oxdna.sqlite") path[0] = db.minima()[19].coords path[-1] = db.minima()[0].coords e1 = [] e2 = [] e1.append(pot.getEnergy(path[0])) 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)