Exemplo n.º 1
0
def main():
    natoms = 5
    X1 = np.random.uniform(-1,1,[natoms*3])*(float(natoms))**(1./3)
    X2 = np.random.uniform(-1,1,[natoms*3])*(float(natoms))**(1./3)

    #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)

    distinit = np.linalg.norm(X1-X2)
    print "distinit", distinit

    dist, X1, X2 = minDist(X1,X2)
    distfinal = np.linalg.norm(X1-X2)
    print "dist from eigenvalue", dist
    print "distfinal", distfinal

    import pygmin.printing.print_atoms_xyz as printxyz
    with open("out.xyz", "w") as fout:
        CoMToOrigin(X1i)
        CoMToOrigin(X2i)
        printxyz.printAtomsXYZ(fout, X1i )
        printxyz.printAtomsXYZ(fout, X2i )
        printxyz.printAtomsXYZ(fout, X1 )
        printxyz.printAtomsXYZ(fout, X2 )
Exemplo n.º 2
0
    def test_multiple(self):
        """test hungarian, munkres, and OPTIM algorithms agains each other"""
        import pygmin.defaults as defaults
        from pygmin.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)
Exemplo n.º 3
0
    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 pygmin.mindist import CoMToOrigin
        ct = 0 
        for coords in coordslist:
            ct = ct + 1 
            coords = CoMToOrigin(coords.copy())
            self.potential.copyToLocalCoords(coords) 
#            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)
Exemplo n.º 4
0
    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 pygmin.mindist import CoMToOrigin
        ct = 0 
        for coords in coordslist:
            ct = ct + 1 
            coords = CoMToOrigin(coords.copy())
            self.potential.copyToLocalCoords(coords) 
#            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)
Exemplo n.º 5
0
    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 pygmin.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)
Exemplo n.º 6
0
    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 pygmin.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)
Exemplo n.º 7
0
def minDist(X1, X2):
    """
    Minimize the distance between two clusters.  The following symmetries 
    will be accounted for.
    
    Translational symmetry

    Global rotational symmetry
    """
    #alignCoM(X1, X2)
    X1 = CoMToOrigin(X1)
    X2 = CoMToOrigin(X2)

    #align rotation degrees of freedom
    dist, X2 = alignRotation(X1, X2)
    return dist, X1, X2
Exemplo n.º 8
0
 def setUp(self):
     from pygmin.potentials import LJ
     from pygmin import defaults
     from pygmin.mindist import CoMToOrigin
     
     self.natoms = 15
     self.pot = LJ(self.natoms)
     self.permlist = [range(self.natoms)]
     
     self.X1 = np.random.uniform(-1,1,[self.natoms*3])*(float(self.natoms))**(1./3)/2
     ret = defaults.quenchRoutine(self.X1, self.pot.getEnergyGradient, tol=.1)
     self.X1 = ret[0]
     self.X1 = CoMToOrigin(self.X1)
Exemplo n.º 9
0
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
Exemplo n.º 10
0
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