def test_multiple(self): """test hungarian, munkres, and OPTIM algorithms agains each other""" import pele.defaults as defaults from pele.mindist import CoMToOrigin X1 = np.copy(self.X1) X2 = np.random.uniform(-1,1,[self.natoms*3])*(float(self.natoms))**(1./3)/2 X2 = CoMToOrigin(X2) X1 = CoMToOrigin(X1) X2i = X2.copy() d1, X11, X21 = findBestPermutationListHungarian(X1, X2, self.permlist[0]) d1calc = np.linalg.norm(X11-X21) X2 = X2i.copy() d2, X12, X22 = findBestPermutationListOPTIM(X1, X2, self.permlist[0]) d2calc = np.linalg.norm(X12-X22) X2 = X2i.copy() d3, X13, X23 = findBestPermutationListMunkres(X1, X2, self.permlist[0]) d3calc = np.linalg.norm(X13-X23) self.assertAlmostEqual(d1, d2, 5) self.assertAlmostEqual(d1, d1calc, 5) self.assertAlmostEqual(d2, d2calc, 5) self.assertAlmostEqual(d1, d3, 5) self.assertAlmostEqual(d3, d3calc, 5)
def load_coords_pymol(self, coordslist, oname, index=1): """load the coords into pymol the new object must be named oname so we can manipulate it later Parameters ---------- coordslist : list of arrays oname : str the new pymol object must be named oname so it can be manipulated later index : int we can have more than one molecule on the screen at one time. index tells which one to draw. They are viewed at the same time, so should be visually distinct, e.g. different colors. accepted values are 1 or 2 Notes ----- the implementation here is a bit hacky. we create a temporary xyz file from coords and load the molecule in pymol from this file. """ # pymol is imported here so you can do, e.g. basinhopping without installing pymol import pymol # create the temporary file suffix = ".pdb" f = tempfile.NamedTemporaryFile(mode="w", suffix=suffix) fname = f.name from simtk.openmm.app import pdbfile as openmmpdb # write the coords into pdb file from pele.mindist import CoMToOrigin ct = 0 for coords in coordslist: ct += 1 coords = CoMToOrigin(coords.copy()) self.potential.copyToLocalCoords(coords) from simtk.unit import angstrom as openmm_angstrom # openmmpdb.PDBFile.writeFile(self.potential.prmtop.topology , self.potential.localCoords * openmm_angstrom , file=sys.stdout, modelIndex=1) openmmpdb.PDBFile.writeModel(self.potential.prmtop.topology, self.potential.localCoords * openmm_angstrom, file=f, modelIndex=ct) print "closing file" f.flush() # load the molecule from the temporary file pymol.cmd.load(fname) # get name of the object just created and change it to oname objects = pymol.cmd.get_object_list() objectname = objects[-1] pymol.cmd.set_name(objectname, oname) # set the representation pymol.cmd.hide("everything", oname) pymol.cmd.show("lines", oname)
def load_coords_pymol(self, coordslist, oname, index=1): # pragma: no cover """load the coords into pymol the new object must be named oname so we can manipulate it later Parameters ---------- coordslist : list of arrays oname : str the new pymol object must be named oname so it can be manipulated later index : int we can have more than one molecule on the screen at one time. index tells which one to draw. They are viewed at the same time, so should be visually distinct, e.g. different colors. accepted values are 1 or 2 Notes ----- the implementation here is a bit hacky. we create a temporary xyz file from coords and load the molecule in pymol from this file. """ # pymol is imported here so you can do, e.g. basinhopping without installing pymol import pymol # create the temporary file suffix = ".xyz" f = tempfile.NamedTemporaryFile(mode="w", suffix=suffix) fname = f.name # write the coords into the xyz file from pele.mindist import CoMToOrigin for coords in coordslist: coords = CoMToOrigin(coords.copy()) write_xyz(f, coords, title=oname, atomtypes=["LA"]) f.flush() # load the molecule from the temporary file pymol.cmd.load(fname) # get name of the object just create and change it to oname objects = pymol.cmd.get_object_list() objectname = objects[-1] pymol.cmd.set_name(objectname, oname) # set the representation pymol.cmd.hide("everything", oname) pymol.cmd.show("spheres", oname) # set the color according to index if index == 1: pymol.cmd.color("red", oname) else: pymol.cmd.color("gray", oname)
def load_coords_pymol(self, coordslist, oname, index=1): # pragma: no cover """load the coords into pymol the new object must be named oname so we can manipulate it later Parameters ---------- coordslist : list of arrays oname : str the new pymol object must be named oname so it can be manipulated later index : int we can have more than one molecule on the screen at one time. index tells which one to draw. They are viewed at the same time, so should be visually distinct, e.g. different colors. accepted values are 1 or 2 Notes ----- the implementation here is a bit hacky. we create a temporary xyz file from coords and load the molecule in pymol from this file. """ # pymol is imported here so you can do, e.g. basinhopping without installing pymol from . import pymol # create the temporary file suffix = ".xyz" f = tempfile.NamedTemporaryFile(mode="w", suffix=suffix) fname = f.name # write the coords into the xyz file from pele.mindist import CoMToOrigin for coords in coordslist: coords = CoMToOrigin(coords.copy()) write_xyz(f, coords, title=oname, atomtypes=["LA"]) f.flush() # load the molecule from the temporary file pymol.cmd.load(fname) # get name of the object just create and change it to oname objects = pymol.cmd.get_object_list() objectname = objects[-1] pymol.cmd.set_name(objectname, oname) # set the representation pymol.cmd.hide("everything", oname) pymol.cmd.show("spheres", oname) # set the color according to index if index == 1: pymol.cmd.color("red", oname) else: pymol.cmd.color("gray", oname)
def load_coords_pymol(self, coordslist, oname, index=1): """load the coords into pymol the new object must be named oname so we can manipulate it later Parameters ---------- coordslist : list of arrays oname : str the new pymol object must be named oname so it can be manipulated later index : int we can have more than one molecule on the screen at one time. index tells which one to draw. They are viewed at the same time, so should be visually distinct, e.g. different colors. accepted values are 1 or 2 Notes ----- the implementation here is a bit hacky. we create a temporary xyz file from coords and load the molecule in pymol from this file. """ #pymol is imported here so you can do, e.g. basinhopping without installing pymol import pymol #create the temporary file suffix = ".xyz" f = tempfile.NamedTemporaryFile(mode="w", suffix=suffix) fname = f.name #write the coords into the xyz file from pele.mindist import CoMToOrigin labels = ["LA" for i in range(self.ntypeA)] + \ ["LB" for i in range(self.natoms - self.ntypeA)] for coords in coordslist: coords = CoMToOrigin(coords.copy()) write_xyz(f, coords, title=oname, atomtypes=labels) f.flush() # self.f = f # so the file is not deleted # print fname #load the molecule from the temporary file pymol.cmd.load(fname) #get name of the object just create and change it to oname objects = pymol.cmd.get_object_list() objectname = objects[-1] pymol.cmd.set_name(objectname, oname) #set the representation pymol.cmd.hide("everything", oname) pymol.cmd.show("spheres", oname) #make the B atoms smaller seleA = "%s and name LA" % (oname) seleB = "%s and name LB" % (oname) pymol.cmd.set("sphere_scale", value=1.0, selection=seleA) pymol.cmd.set("sphere_scale", value=0.8, selection=seleB) #set the color according to index if index == 1: pymol.cmd.color("red", selection=seleA) pymol.cmd.color("firebrick", selection=seleB) else: pymol.cmd.color("deepolive", selection=seleA) pymol.cmd.color("smudge", selection=seleB)
def minPermDistStochastic(X1, X2, niter=100, permlist=None, verbose=False, accuracy=0.01, check_inversion=True, use_quench=False): """ Minimize the distance between two clusters. Parameters ---------- X1, X2 : the structures to align. X2 will be aligned with X1, both the center of masses will be shifted to the origin niter : int the number of basinhopping iterations to perform permlist : a list of lists of atoms A list of lists of atoms which are interchangable. e.g. if all the atoms are interchangable permlist = [range(natoms)] For a 50/50 binary mixture, permlist = [range(1,natoms/2), range(natoms/2,natoms)] verbose : whether to print status information accuracy : accuracy for determining if the structures are identical check_inversion : if true, account for point inversion symmetry use_quench : for each step of the iteration, minimize a permutationally invariant distance metric. This slows the algorithm, but can potentially make it more accurate. Notes ----- The following symmetries will be accounted for:: 1. Translational symmetry #. Global rotational symmetry #. Permutational symmetry #. Point inversion symmetry The algorithm here to find the best distance is for i in range(niter): random_rotation(coords) findBestPermutation(coords) alignRotation(coords) """ natoms = len(X1) / 3 if permlist is None: permlist = [range(natoms)] X1init = X1 X2init = X2 X1 = np.copy(X1) X2 = np.copy(X2) #first check for exact match exactmatch = ExactMatchCluster(accuracy=accuracy, permlist=permlist) if exactmatch(X1, X2): #this is kind of cheating, I would prefer to return #X2 in best alignment and the actual (small) distance return 0.0, X1, X1.copy() #bring center of mass of x1 and x2 to the origin #save the center of mass of X1 for later X1com = X1.reshape([-1,3]).sum(0) / natoms X1 = CoMToOrigin(X1) X2 = CoMToOrigin(X2) #print "X2.shape", X2.shape #find the best rotation stochastically X20 = X2.copy() distbest, mxbest = _optimizePermRot(X1, X2, niter, permlist, verbose=verbose, use_quench=use_quench) use_inversion = False if check_inversion: X20i = -X20.copy() X2 = X20i.copy() distbest1, mxbest1 = _optimizePermRot(X1, X2, niter, permlist, verbose=verbose, use_quench=use_quench) if distbest1 < distbest: if verbose: print "using inversion in minpermdist" use_inversion = True distbest = distbest1 mxbest = mxbest1 #now we know the best rotation if use_inversion: X20 = X20i X2 = applyRotation(mxbest, X20) dist, X1, X2 = findBestPermutation(X1, X2, permlist) dist, X2 = alignRotation(X1, X2) if dist > distbest+0.001: print "ERROR: minPermDistRanRot: dist is different from distbest %f %f" % (dist, distbest) if verbose: print "finaldist", dist, "distmin", distbest #add back in the center of mass of X1 X1 = X1.reshape([-1,3]) X2 = X2.reshape([-1,3]) X1 += X1com X2 += X1com X1 = X1.reshape(-1) X2 = X2.reshape(-1) return dist, X1, X2