コード例 #1
0
ファイル: mindistutils.py プロジェクト: borislavujo/pele
def alignRotation(XA, XB):
    """
    Align structure XB with XA

    Align structure XB to be as similar as possible to structure XA.
    To be precise, rotate XB, so as to minimize the distance |XA - XB|.

    Rotations will be done around the origin, not the center of mass
    """
    nsites = len(XA)/3

    dist, Q2 = getAlignRotation(XA, XB)
    ###################################################################
    # Q2 contains the quaternion which rotates XB to best align with X1.
    # rotate XB according to Q2
    ###################################################################

    rot_mx = rot.q2mx( Q2 )
    #print rot_mx
    for j in range(nsites):
        i = 3*j
        XB[i:i+3] = np.dot( rot_mx, XB[i:i+3] )
    
    dist = np.linalg.norm(XA - XB) #more precise than what it returned

    return dist, XB
コード例 #2
0
ファイル: test_rotations.py プロジェクト: dimaslave/pele
 def test_invert3x3(self):
     q = rotations.random_q()
     mx = rotations.q2mx(q)
     mxi1 = invert3x3(mx)
     mxi2 = np.linalg.inv(mx)
     self.assertEqual(mxi1.shape, mxi2.shape)
     for v1, v2 in izip(mxi1.reshape(-1), mxi2.reshape(-1)):
         self.assertAlmostEqual(v1, v2, places=5)
コード例 #3
0
 def test_invert3x3(self):
     q = rotations.random_q()
     mx = rotations.q2mx(q)
     mxi1 = invert3x3(mx)
     mxi2 = np.linalg.inv(mx)
     self.assertEqual(mxi1.shape, mxi2.shape)
     for v1, v2 in zip(mxi1.reshape(-1), mxi2.reshape(-1)):
         self.assertAlmostEqual(v1, v2, places=5)
コード例 #4
0
    def test1(self):
        rot = q2mx(random_q())
        x2 = self.x1.copy()
        self.transform.rotate(x2, rot)
        
        x1 = self.x1
        dist, mx = self.findrot(x1, x2)
        self.assertLess(dist, 1e-4)
        
        self.transform.translate(x2, -self.measure.get_com(x2))
        self.transform.rotate(x2, mx)
        self.transform.translate(x2, self.measure.get_com(x1))

        assert_arrays_almost_equal(self, x1, x2)
コード例 #5
0
    def test1(self):
        rot = q2mx(random_q())
        x2 = self.x1.copy()
        self.transform.rotate(x2, rot)

        x1 = self.x1
        dist, mx = self.findrot(x1, x2)
        self.assertLess(dist, 1e-4)

        self.transform.translate(x2, -self.measure.get_com(x2))
        self.transform.rotate(x2, mx)
        self.transform.translate(x2, self.measure.get_com(x1))

        assert_arrays_almost_equal(self, x1, x2)
コード例 #6
0
ファイル: exact_match.py プロジェクト: jaotta/pele
def test():  # pragma: no cover
    natoms = 35
    from pele.utils import rotations

    for i in xrange(100):
        xx1 = np.random.random(3 * natoms) * 5
        xx1 = xx1.reshape([-1, 3])
        mx = rotations.q2mx(rotations.random_q())
        xx2 = -np.dot(mx, xx1.transpose()).transpose()
        xx2 += 2.0 * (np.random.random(xx2.shape) - 0.5) * 0.001
        # xx2 = xx1.copy()
        tmp = xx2[1].copy()
        xx2[1] = xx2[4]
        xx2[4] = tmp
        print i, ExactMatchCluster()(xx1.flatten(), xx2.flatten())
コード例 #7
0
ファイル: exact_match.py プロジェクト: spraharsh/pele
def test():  # pragma: no cover
    natoms = 35
    from pele.utils import rotations

    for i in range(100):
        xx1 = np.random.random(3 * natoms) * 5
        xx1 = xx1.reshape([-1, 3])
        mx = rotations.q2mx(rotations.random_q())
        xx2 = -np.dot(mx, xx1.transpose()).transpose()
        xx2 += 2. * (np.random.random(xx2.shape) - 0.5) * 0.001
        #xx2 = xx1.copy()
        tmp = xx2[1].copy()
        xx2[1] = xx2[4]
        xx2[4] = tmp
        print(i, ExactMatchCluster()(xx1.flatten(), xx2.flatten()))
コード例 #8
0
    def test2(self):
        rot = q2mx(random_q())
        dx = .01
        x2 = self.x1.copy()
        x2[0] += .01
        self.transform.rotate(x2, rot)

        x1old = self.x1.copy()
        x2old = x2.copy()
        dist, mx = self.findrot(self.x1, x2)
        # check it didn't change the arrays
        assert_arrays_almost_equal(self, x1old, self.x1)
        assert_arrays_almost_equal(self, x2old, x2)

        self.assertLess(dist, dx)
コード例 #9
0
 def test2(self):
     rot = q2mx(random_q())
     dx = .01
     x2 = self.x1.copy()
     x2[0] += .01
     self.transform.rotate(x2, rot)
     
     x1old = self.x1.copy()
     x2old = x2.copy()
     dist, mx = self.findrot(self.x1, x2)
     # check it didn't change the arrays
     assert_arrays_almost_equal(self, x1old, self.x1)
     assert_arrays_almost_equal(self, x2old, x2)
     
     self.assertLess(dist, dx)
コード例 #10
0
ファイル: exact_match.py プロジェクト: borislavujo/pele
def test():
    natoms = 35
    from pele.utils import rotations

    for i in xrange(100):
        xx1 = np.random.random(3*natoms)*5
        xx1 = xx1.reshape([-1,3])
        mx = rotations.q2mx(rotations.random_q())
        xx2 = -np.dot(mx, xx1.transpose()).transpose()
        xx2 +=2.*(np.random.random(xx2.shape)-0.5)*0.001
        #xx2 = xx1.copy()
        tmp = xx2[1].copy()
        xx2[1] = xx2[4]
        xx2[4] = tmp
        #dist, x1n, x2n = findBestPermutation(xx1.flatten(), xx2.flatten())
        #print dist
        print i,ExactMatchCluster()(xx1.flatten(), xx2.flatten())
コード例 #11
0
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
コード例 #12
0
ファイル: rmsfit.py プロジェクト: borislavujo/pele
def findrotation_kearsley(coords1, coords2, align_com=True):
    """
    Return the quaternion which aligns XB with XA
    
    Return the matrix which
    aligns structure XB to be as similar as possible to structure XA.
    To be precise, rotate XB, so as to minimize the distance |XA - XB|.

    Rotations will be done around the origin, not the center of mass

    Rotational alignment follows the prescription of
    Kearsley, Acta Cryst. A, 45, 208-210, 1989
    http://dx.doi.org/10.1107/S0108767388010128
    """

    if(coords1.size != coords2.size):
        raise BaseException("dimension of arrays does not match")
    
    # reshape the arrays
    x1 = coords1.flatten()
    x2 = coords2.flatten()
    
    x1 = x1.reshape([-1,3])
    x2 = x2.reshape([-1,3])
#    
#    # determine number of atoms
    natoms = x1.shape[0]
    
    # set both com to zero
    if(align_com):
        com1 = np.sum(x1,axis=0) / float(natoms)
        com2 = np.sum(x2,axis=0) / float(natoms)
        x1 = x1.copy() - com1
        x2 = x2.copy() - com2

    x1 = x1.flatten() 
    x2 = x2.flatten()
    
    # TODO: this is very dirty!
    #########################################
    #Create matrix QMAT
    #########################################

    QMAT = np.zeros([4,4], np.float64)
    for J1 in xrange(natoms):
        J2 = 3*(J1) -1
        XM = x1[J2+1] - x2[J2+1]
        YM = x1[J2+2] - x2[J2+2]
        ZM = x1[J2+3] - x2[J2+3]
        XP = x1[J2+1] + x2[J2+1]
        YP = x1[J2+2] + x2[J2+2]
        ZP = x1[J2+3] + x2[J2+3]
        QMAT[0,0] = QMAT[0,0] + XM**2 + YM**2 + ZM**2
        QMAT[0,1] = QMAT[0,1] - YP*ZM + YM*ZP
        QMAT[0,2] = QMAT[0,2] - XM*ZP + XP*ZM
        QMAT[0,3] = QMAT[0,3] - XP*YM + XM*YP
        QMAT[1,1] = QMAT[1,1] + YP**2 + ZP**2 + XM**2
        QMAT[1,2] = QMAT[1,2] + XM*YM - XP*YP
        QMAT[1,3] = QMAT[1,3] + XM*ZM - XP*ZP
        QMAT[2,2] = QMAT[2,2] + XP**2 + ZP**2 + YM**2
        QMAT[2,3] = QMAT[2,3] + YM*ZM - YP*ZP
        QMAT[3,3] = QMAT[3,3] + XP**2 + YP**2 + ZM**2

    QMAT[1,0] = QMAT[0,1]
    QMAT[2,0] = QMAT[0,2]
    QMAT[2,1] = QMAT[1,2]
    QMAT[3,0] = QMAT[0,3]
    QMAT[3,1] = QMAT[1,3]
    QMAT[3,2] = QMAT[2,3]

    ###########################################
    """
    Find eigenvalues and eigenvectors of QMAT.  The eigenvector corresponding
    to the smallest eigenvalue is the quaternion which rotates XB into best
    alignment with XA.  The smallest eigenvalue is the squared distance between
    the resulting structures.
    """
    ###########################################
    (eigs, vecs) = np.linalg.eig(QMAT)
    #print "eigenvalues", eigs

    imin = np.argmin(eigs)
    eigmin = eigs[imin] #the minimum eigenvector
    Q2 = vecs[:,imin]  #the eigenvector corresponding to the minimum eigenvalue
    if eigmin < 0.:
        if abs(eigmin) < 1e-6:
            eigmin = 0.
        else:
            print 'minDist> WARNING minimum eigenvalue is ',eigmin,' change to absolute value'
            eigmin = -eigmin

    dist = np.sqrt(eigmin) #this is the minimized distance between the two structures
    #print "dist from eigenvalue", dist
    #print "Q2", Q2, "norm", np.linalg.norm(Q2)
    #aa = rot.q2aa( Q2)
    #print "aa ", aa, "norm", np.linalg.norm(aa)

    return dist, rotations.q2mx(Q2)
コード例 #13
0
ファイル: rmsfit.py プロジェクト: borislavujo/pele
    imin = np.argmin(eigs)
    eigmin = eigs[imin] #the minimum eigenvector
    Q2 = vecs[:,imin]  #the eigenvector corresponding to the minimum eigenvalue
    if eigmin < 0.:
        if abs(eigmin) < 1e-6:
            eigmin = 0.
        else:
            print 'minDist> WARNING minimum eigenvalue is ',eigmin,' change to absolute value'
            eigmin = -eigmin

    dist = np.sqrt(eigmin) #this is the minimized distance between the two structures
    #print "dist from eigenvalue", dist
    #print "Q2", Q2, "norm", np.linalg.norm(Q2)
    #aa = rot.q2aa( Q2)
    #print "aa ", aa, "norm", np.linalg.norm(aa)

    return dist, rotations.q2mx(Q2)

findrotation = findrotation_kearsley

if __name__ == "__main__":
    from pele.utils import rotations
    x1 = np.random.random(24)
    mx = rotations.q2mx(rotations.random_q())
    
    x2 = np.dot(mx,x1.reshape(-1,3).transpose()).transpose().reshape(-1)
    print x2-x1
    print mx-findrotation_kabsch(x1,x2)
    print findrotation_kabsch(x1,x2)
    print findrotation_kearsley(x1,x2)[1]
    
コード例 #14
0
 def rrot(self, x):
     q = rotations.random_q()
     mx = rotations.q2mx(q)
     self.transform.rotate(x, mx)
コード例 #15
0
ファイル: rmsfit.py プロジェクト: yangxi1209/pele
    eigmin = eigs[imin]  # the minimum eigenvector
    Q2 = vecs[:,
              imin]  # the eigenvector corresponding to the minimum eigenvalue
    if eigmin < 0.:
        if abs(eigmin) < 1e-6:
            eigmin = 0.
        else:
            print 'minDist> WARNING minimum eigenvalue is ', eigmin, ' change to absolute value'
            eigmin = -eigmin

    dist = np.sqrt(
        eigmin)  # this is the minimized distance between the two structures

    Q2 = np.real_if_close(Q2, 1e-10)
    if np.iscomplexobj(Q2):
        raise ValueError("Q2 is complex")
    return dist, rotations.q2mx(Q2)


findrotation = findrotation_kearsley

if __name__ == "__main__":
    x1 = np.random.random(24)
    mx = rotations.q2mx(rotations.random_q())

    x2 = np.dot(mx, x1.reshape(-1, 3).transpose()).transpose().reshape(-1)
    print x2 - x1
    print mx - findrotation_kabsch(x1, x2)
    print findrotation_kabsch(x1, x2)
    print findrotation_kearsley(x1, x2)[1]
コード例 #16
0
ファイル: test_rotations.py プロジェクト: dimaslave/pele
 def test_mx2aa(self):
     mx = rotations.q2mx(random_q())
     p1 = mx2aa(mx)
     p2 = rotations.mx2aa(mx)
     self.arrays_equal(p1, p2)
コード例 #17
0
ファイル: test_rotations.py プロジェクト: dimaslave/pele
def aa2mx( p ):
    return q2mx( aa2q( p ) )
コード例 #18
0
ファイル: rmsfit.py プロジェクト: yangxi1209/pele
def findrotation_kearsley(x1, x2, align_com=True):
    """Return the rotation matrix which aligns XB with XA
    
    Return the matrix which
    aligns structure XB to be as similar as possible to structure XA.
    To be precise, rotate XB, so as to minimize the distance |XA - XB|.

    Rotations will be done around the origin, not the center of mass

    Rotational alignment follows the prescription of
    Kearsley, Acta Cryst. A, 45, 208-210, 1989
    http://dx.doi.org/10.1107/S0108767388010128
    """
    if x1.size != x2.size:
        raise ValueError("dimension of arrays does not match")

    # reshape the arrays
    x1 = x1.reshape([-1, 3]).copy()
    x2 = x2.reshape([-1, 3]).copy()
    # determine number of atoms
    natoms = x1.shape[0]

    # set both com to zero
    if align_com:
        com1 = np.sum(x1, axis=0) / float(natoms)
        com2 = np.sum(x2, axis=0) / float(natoms)
        x1 -= com1
        x2 -= com2

    x1 = x1.ravel()
    x2 = x2.ravel()

    # TODO: this is very dirty!
    #########################################
    # Create matrix QMAT
    #########################################

    QMAT = np.zeros([4, 4], np.float64)
    for J1 in xrange(natoms):
        J2 = 3 * J1 - 1
        XM = x1[J2 + 1] - x2[J2 + 1]
        YM = x1[J2 + 2] - x2[J2 + 2]
        ZM = x1[J2 + 3] - x2[J2 + 3]
        XP = x1[J2 + 1] + x2[J2 + 1]
        YP = x1[J2 + 2] + x2[J2 + 2]
        ZP = x1[J2 + 3] + x2[J2 + 3]
        QMAT[0, 0] = QMAT[0, 0] + XM**2 + YM**2 + ZM**2
        QMAT[0, 1] = QMAT[0, 1] - YP * ZM + YM * ZP
        QMAT[0, 2] = QMAT[0, 2] - XM * ZP + XP * ZM
        QMAT[0, 3] = QMAT[0, 3] - XP * YM + XM * YP
        QMAT[1, 1] = QMAT[1, 1] + YP**2 + ZP**2 + XM**2
        QMAT[1, 2] = QMAT[1, 2] + XM * YM - XP * YP
        QMAT[1, 3] = QMAT[1, 3] + XM * ZM - XP * ZP
        QMAT[2, 2] = QMAT[2, 2] + XP**2 + ZP**2 + YM**2
        QMAT[2, 3] = QMAT[2, 3] + YM * ZM - YP * ZP
        QMAT[3, 3] = QMAT[3, 3] + XP**2 + YP**2 + ZM**2

    QMAT[1, 0] = QMAT[0, 1]
    QMAT[2, 0] = QMAT[0, 2]
    QMAT[2, 1] = QMAT[1, 2]
    QMAT[3, 0] = QMAT[0, 3]
    QMAT[3, 1] = QMAT[1, 3]
    QMAT[3, 2] = QMAT[2, 3]

    ###########################################
    """
    Find eigenvalues and eigenvectors of QMAT.  The eigenvector corresponding
    to the smallest eigenvalue is the quaternion which rotates XB into best
    alignment with XA.  The smallest eigenvalue is the squared distance between
    the resulting structures.
    """
    ###########################################
    (eigs, vecs) = np.linalg.eig(QMAT)

    imin = np.argmin(eigs)
    eigmin = eigs[imin]  # the minimum eigenvector
    Q2 = vecs[:,
              imin]  # the eigenvector corresponding to the minimum eigenvalue
    if eigmin < 0.:
        if abs(eigmin) < 1e-6:
            eigmin = 0.
        else:
            print 'minDist> WARNING minimum eigenvalue is ', eigmin, ' change to absolute value'
            eigmin = -eigmin

    dist = np.sqrt(
        eigmin)  # this is the minimized distance between the two structures

    Q2 = np.real_if_close(Q2, 1e-10)
    if np.iscomplexobj(Q2):
        raise ValueError("Q2 is complex")
    return dist, rotations.q2mx(Q2)
コード例 #19
0
 def test_mx2aa(self):
     mx = rotations.q2mx(random_q())
     p1 = mx2aa(mx)
     p2 = rotations.mx2aa(mx)
     self.arrays_equal(p1, p2)
コード例 #20
0
def aa2mx(p):
    return q2mx(aa2q(p))