Ejemplo n.º 1
0
 def setUpRigidBodies(self):
     #set up one rigid body
     from pele.potentials.rigid_bodies.molecule import Molecule
     self.rb = Molecule()
     for atomlist in self.permlist:
         #make a rigid body from atomlist
         for i in atomlist:
             self.rb.insert_site( 0, self.XB0[i*3:i*3+3] )
Ejemplo n.º 2
0
class MinPermDistPotential(potential.potential):
    """
    Find the rotation (in angle-axis representation) which maximizes the
    permutation independent overlap between two structures.

    This potential defines the energy as the overlap, here defined as

    E = - sum_i sum_j exp( -|x_Ai - X_Bj|**2 / L**2 )

    There are other options for the overlap which are not implemented.  For
    instance something with a slower decay than exp(-R**2).
    """
    def __init__(self, XA, XB, L=0.2, permlist = []):
        self.XA0 = np.copy(XA)
        self.XB0 = np.copy(XB)
        self.XB = np.copy(XB)
        self.nsites = len(XA)/3
        self.L2 = L*L
        self.permlist = permlist
        if len(self.permlist) == 0:
            self.permlist = [range( self.nsites)]
        try:
            from overlap import overlap, overlap_gradient
            self.overlap = overlap
            self.overlap_gradient = overlap_gradient
        except ImportError:
            #self.overlap = overlap_fast
            self.overlap = overlap_fast
            self.overlap_gradient = overlap_gradient_slow
            print "MinPermDistPotential> Using python energy calculation. Compile overlap.f90 to speed things up (a little)"

        self.setUpRigidBodies()

    def setUpRigidBodies(self):
        #set up one rigid body
        from pele.potentials.rigid_bodies.molecule import Molecule
        self.rb = Molecule()
        for atomlist in self.permlist:
            #make a rigid body from atomlist
            for i in atomlist:
                self.rb.insert_site( 0, self.XB0[i*3:i*3+3] )

    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 getEnergy(self, AA):
        # Rotate rigid body according to angle axis AA
        self.XB = self.rb.getxyz( aa = AA )
        #get energy and gradient for each site
        E = 0.
        for atomlist in self.permlist:
            E -= self.overlap( self.XA0, self.XB, self.L2, atomlist, [self.nsites, len(atomlist)])
        return E


    def getEnergyGradient(self, AA):
        # Rotate XB0 according to angle axis AA
        # Rotate rigid body according to angle axis AA
        self.XB = self.rb.getxyz( aa = AA )
        #get energy and gradient for each site
        E = 0.
        grad = np.zeros(len(self.XB))
        for atomlist in self.permlist:
            de, dg = self.overlap_gradient( self.XA0, self.XB, self.L2, atomlist, [self.nsites, len(atomlist)])
            E -= de
            grad -= dg
        #convert site-gradients into angle -axis gradients
        #first calculate the rotation matrix and derivatives
        comgrad, aagrad = self.rb.getGradients(AA, grad, True)
        return E, aagrad


    def globalEnergyMin(self):
        """
        return the lowest energy theoretically possible.  This will happen if XB == XA
        """
        E = 0.
        for atomlist in self.permlist:
            E -= self.overlap( self.XA0, self.XA0, self.L2, atomlist, [self.nsites, len(atomlist)])
        return E