예제 #1
0
def superpositionFit(confs):
    """
    :param confs: the weight, reference position, and alternate
                  position for each atom
    :type confs: sequence of (float, Vector, Vector)
    :returns: the quaternion representing the rotation,
              the center of mass in the reference configuration,
              the center of mass in the alternate configuraton,
              and the RMS distance after the optimal superposition
    """
    w_sum = 0.
    wr_sum = N.zeros((3,), N.Float)
    for w, r_ref, r in confs:
        w_sum += w
        wr_sum += w*r_ref.array
    ref_cms = wr_sum/w_sum
    pos = N.zeros((3,), N.Float)
    possq = 0.
    cross = N.zeros((3, 3), N.Float)
    for w, r_ref, r in confs:
        w = w/w_sum
        r_ref = r_ref.array-ref_cms
        r = r.array
        pos = pos + w*r
        possq = possq + w*N.add.reduce(r*r) \
                      + w*N.add.reduce(r_ref*r_ref)
        cross = cross + w*r[:, N.NewAxis]*r_ref[N.NewAxis, :]
    k = N.zeros((4, 4), N.Float)
    k[0, 0] = -cross[0, 0]-cross[1, 1]-cross[2, 2]
    k[0, 1] = cross[1, 2]-cross[2, 1]
    k[0, 2] = cross[2, 0]-cross[0, 2]
    k[0, 3] = cross[0, 1]-cross[1, 0]
    k[1, 1] = -cross[0, 0]+cross[1, 1]+cross[2, 2]
    k[1, 2] = -cross[0, 1]-cross[1, 0]
    k[1, 3] = -cross[0, 2]-cross[2, 0]
    k[2, 2] = cross[0, 0]-cross[1, 1]+cross[2, 2]
    k[2, 3] = -cross[1, 2]-cross[2, 1]
    k[3, 3] = cross[0, 0]+cross[1, 1]-cross[2, 2]
    for i in range(1, 4):
        for j in range(i):
            k[i, j] = k[j, i]
    k = 2.*k
    for i in range(4):
        k[i, i] = k[i, i] + possq - N.add.reduce(pos*pos)
    from Scientific import LA
    e, v = LA.eigenvectors(k)
    i = N.argmin(e)
    v = v[i]
    if v[0] < 0: v = -v
    if e[i] <= 0.:
        rms = 0.
    else:
        rms = N.sqrt(e[i])
    from Scientific.Geometry import Quaternion
    return Quaternion.Quaternion(v), Vector(ref_cms), \
           Vector(pos), rms
예제 #2
0
def superpositionFit(confs):
    """
    :param confs: the weight, reference position, and alternate
                  position for each atom
    :type confs: sequence of (float, Vector, Vector)
    :returns: the quaternion representing the rotation,
              the center of mass in the reference configuration,
              the center of mass in the alternate configuraton,
              and the RMS distance after the optimal superposition
    """
    w_sum = 0.
    wr_sum = N.zeros((3, ), N.Float)
    for w, r_ref, r in confs:
        w_sum += w
        wr_sum += w * r_ref.array
    ref_cms = wr_sum / w_sum
    pos = N.zeros((3, ), N.Float)
    possq = 0.
    cross = N.zeros((3, 3), N.Float)
    for w, r_ref, r in confs:
        w = w / w_sum
        r_ref = r_ref.array - ref_cms
        r = r.array
        pos = pos + w * r
        possq = possq + w*N.add.reduce(r*r) \
                      + w*N.add.reduce(r_ref*r_ref)
        cross = cross + w * r[:, N.NewAxis] * r_ref[N.NewAxis, :]
    k = N.zeros((4, 4), N.Float)
    k[0, 0] = -cross[0, 0] - cross[1, 1] - cross[2, 2]
    k[0, 1] = cross[1, 2] - cross[2, 1]
    k[0, 2] = cross[2, 0] - cross[0, 2]
    k[0, 3] = cross[0, 1] - cross[1, 0]
    k[1, 1] = -cross[0, 0] + cross[1, 1] + cross[2, 2]
    k[1, 2] = -cross[0, 1] - cross[1, 0]
    k[1, 3] = -cross[0, 2] - cross[2, 0]
    k[2, 2] = cross[0, 0] - cross[1, 1] + cross[2, 2]
    k[2, 3] = -cross[1, 2] - cross[2, 1]
    k[3, 3] = cross[0, 0] + cross[1, 1] - cross[2, 2]
    for i in range(1, 4):
        for j in range(i):
            k[i, j] = k[j, i]
    k = 2. * k
    for i in range(4):
        k[i, i] = k[i, i] + possq - N.add.reduce(pos * pos)
    from Scientific import LA
    e, v = LA.eigenvectors(k)
    i = N.argmin(e)
    v = v[i]
    if v[0] < 0: v = -v
    if e[i] <= 0.:
        rms = 0.
    else:
        rms = N.sqrt(e[i])
    from Scientific.Geometry import Quaternion
    return Quaternion.Quaternion(v), Vector(ref_cms), \
           Vector(pos), rms
예제 #3
0
 def findTransformationAsQuaternion(self, conf1, conf2=None):
     universe = self.universe()
     if conf1.universe != universe:
         raise ValueError("conformation is for a different universe")
     if conf2 is None:
         conf1, conf2 = conf2, conf1
     else:
         if conf2.universe != universe:
             raise ValueError("conformation is for a different universe")
     ref = conf1
     conf = conf2
     weights = universe.masses()
     weights = weights / self.mass()
     ref_cms = self.centerOfMass(ref).array
     pos = Numeric.zeros((3, ), Numeric.Float)
     possq = 0.
     cross = Numeric.zeros((3, 3), Numeric.Float)
     for a in self.atomList():
         r = a.position(conf).array
         r_ref = a.position(ref).array - ref_cms
         w = weights[a]
         pos = pos + w * r
         possq = possq + w*Numeric.add.reduce(r*r) \
                       + w*Numeric.add.reduce(r_ref*r_ref)
         cross = cross + w * r[:,
                               Numeric.NewAxis] * r_ref[Numeric.NewAxis, :]
     k = Numeric.zeros((4, 4), Numeric.Float)
     k[0, 0] = -cross[0, 0] - cross[1, 1] - cross[2, 2]
     k[0, 1] = cross[1, 2] - cross[2, 1]
     k[0, 2] = cross[2, 0] - cross[0, 2]
     k[0, 3] = cross[0, 1] - cross[1, 0]
     k[1, 1] = -cross[0, 0] + cross[1, 1] + cross[2, 2]
     k[1, 2] = -cross[0, 1] - cross[1, 0]
     k[1, 3] = -cross[0, 2] - cross[2, 0]
     k[2, 2] = cross[0, 0] - cross[1, 1] + cross[2, 2]
     k[2, 3] = -cross[1, 2] - cross[2, 1]
     k[3, 3] = cross[0, 0] + cross[1, 1] - cross[2, 2]
     for i in range(1, 4):
         for j in range(i):
             k[i, j] = k[j, i]
     k = 2. * k
     for i in range(4):
         k[i, i] = k[i, i] + possq - Numeric.add.reduce(pos * pos)
     from Scientific import LA
     e, v = LA.eigenvectors(k)
     i = Numeric.argmin(e)
     v = v[i]
     if v[0] < 0: v = -v
     if e[i] <= 0.:
         rms = 0.
     else:
         rms = Numeric.sqrt(e[i])
     return Quaternion.Quaternion(v), Vector(ref_cms), \
            Vector(pos), rms
예제 #4
0
 def findTransformationAsQuaternion(self, conf1, conf2 = None):
     universe = self.universe()
     if conf1.universe != universe:
         raise ValueError("conformation is for a different universe")
     if conf2 is None:
         conf1, conf2 = conf2, conf1
     else:
         if conf2.universe != universe:
             raise ValueError("conformation is for a different universe")
     ref = conf1
     conf = conf2
     weights = universe.masses()
     weights = weights/self.mass()
     ref_cms = self.centerOfMass(ref).array
     pos = Numeric.zeros((3,), Numeric.Float)
     possq = 0.
     cross = Numeric.zeros((3, 3), Numeric.Float)
     for a in self.atomList():
         r = a.position(conf).array
         r_ref = a.position(ref).array-ref_cms
         w = weights[a]
         pos = pos + w*r
         possq = possq + w*Numeric.add.reduce(r*r) \
                       + w*Numeric.add.reduce(r_ref*r_ref)
         cross = cross + w*r[:, Numeric.NewAxis]*r_ref[Numeric.NewAxis, :]
     k = Numeric.zeros((4, 4), Numeric.Float)
     k[0, 0] = -cross[0, 0]-cross[1, 1]-cross[2, 2]
     k[0, 1] = cross[1, 2]-cross[2, 1]
     k[0, 2] = cross[2, 0]-cross[0, 2]
     k[0, 3] = cross[0, 1]-cross[1, 0]
     k[1, 1] = -cross[0, 0]+cross[1, 1]+cross[2, 2]
     k[1, 2] = -cross[0, 1]-cross[1, 0]
     k[1, 3] = -cross[0, 2]-cross[2, 0]
     k[2, 2] = cross[0, 0]-cross[1, 1]+cross[2, 2]
     k[2, 3] = -cross[1, 2]-cross[2, 1]
     k[3, 3] = cross[0, 0]+cross[1, 1]-cross[2, 2]
     for i in range(1, 4):
         for j in range(i):
             k[i, j] = k[j, i]
     k = 2.*k
     for i in range(4):
         k[i, i] = k[i, i] + possq - Numeric.add.reduce(pos*pos)
     from Scientific import LA
     e, v = LA.eigenvectors(k)
     i = Numeric.argmin(e)
     v = v[i]
     if v[0] < 0: v = -v
     if e[i] <= 0.:
         rms = 0.
     else:
         rms = Numeric.sqrt(e[i])
     return Quaternion.Quaternion(v), Vector(ref_cms), \
            Vector(pos), rms
예제 #5
0
def symmetricTensorBasis(cell, space_group):
    from CDTK.Crystal import UnitCell
    subspace = 1. * N.equal.outer(N.arange(6), N.arange(6))
    for tr in cartesianCoordinateSymmetryTransformations(cell, space_group):
        rot = symmetricTensorRotationMatrix(tr.tensor.array)
        ev, axes = LA.eigenvectors(rot)
        new_subspace = []
        for i in range(6):
            if abs(ev[i] - 1.) < 1.e-12:
                p = N.dot(N.transpose(subspace), N.dot(subspace, axes[i].real))
                new_subspace.append(p)
        m, s, subspace = LA.singular_value_decomposition(N.array(new_subspace))
        nb = N.sum(s / s[0] > 1.e-12)
        subspace = subspace[:nb]
    return [SymmetricTensor(a) for a in subspace]
from MMTK import *
from MMTK.Proteins import Protein
from Scientific import N, LA

# Import the graphics module. Substitute any other graphics
# module name to make the example use that module.
from Scientific.Visualization import VRML2
module = VRML2

# Create the protein and find its center of mass and tensor of inertia.
protein = Protein('insulin')
center, inertia = protein.centerAndMomentOfInertia()

# Diagonalize the inertia tensor and scale the axes to a suitable length.
mass = protein.mass()
diagonal, directions = LA.eigenvectors(inertia.array)
diagonal = N.sqrt(diagonal / mass)

# Generate the backbone graphics objects.
graphics = protein.graphicsObjects(graphics_module=module,
                                   model='backbone',
                                   color='red')

# Add an atomic wireframe representation of all valine sidechains
valines = protein.residuesOfType('val')
sidechains = valines.map(lambda r: r.sidechain)
graphics = graphics + sidechains.graphicsObjects(
    graphics_module=module, model='wireframe', color='blue')

# Add three arrows corresponding to the principal axes of inertia.
for length, axis in map(None, diagonal, directions):