def draw(self, graphics):
        """
        Draw something on the canvas

        @param graphics: the graphics object (L{PolyLine3D},
                         or L{VisualizationGraphics}) to be drawn
        """
        self.last_draw = (graphics, )
        self.configure(cursor='watch')
        self.update_idletasks()
        graphics.project(self.axis, self.plane)
        p1, p2 = graphics.boundingBoxPlane()
        center = 0.5*(p1+p2)
        scale = self.plotbox_size / (p2-p1)
        sign = scale/Numeric.fabs(scale)
        if self.scale is None:
            minscale = Numeric.minimum.reduce(Numeric.fabs(scale))
            self.scale = 0.9*minscale
        scale = sign*self.scale
        box_center = self.plotbox_origin + 0.5*self.plotbox_size
        shift = -center*scale + box_center + self.translate
        graphics.scaleAndShift(scale, shift)
        items, depths = graphics.lines()
        sort = Numeric.argsort(depths)
        for index in sort:
            x1, y1, x2, y2, color, width = items[index]
            Line(self.canvas, x1, y1, x2, y2, fill=color, width=width)
        self.configure(cursor='top_left_arrow')
        self.update_idletasks()
    def draw(self, graphics):
        """
        Draw something on the canvas

        @param graphics: the graphics object (L{PolyLine3D},
                         or L{VisualizationGraphics}) to be drawn
        """
        self.last_draw = (graphics, )
        self.configure(cursor='watch')
        self.update_idletasks()
        graphics.project(self.axis, self.plane)
        p1, p2 = graphics.boundingBoxPlane()
        center = 0.5 * (p1 + p2)
        scale = self.plotbox_size / (p2 - p1)
        sign = scale / N.fabs(scale)
        if self.scale is None:
            minscale = N.minimum.reduce(N.fabs(scale))
            self.scale = 0.9 * minscale
        scale = sign * self.scale
        box_center = self.plotbox_origin + 0.5 * self.plotbox_size
        shift = -center * scale + box_center + self.translate
        graphics.scaleAndShift(scale, shift)
        items, depths = graphics.lines()
        sort = N.argsort(depths)
        for index in sort:
            x1, y1, x2, y2, color, width = items[index]
            Line(self.canvas, x1, y1, x2, y2, fill=color, width=width)
        self.configure(cursor='top_left_arrow')
        self.update_idletasks()
示例#3
0
    def __init__(self,
                 universe=None,
                 temperature=300. * Units.K,
                 subspace=None,
                 delta=None,
                 sparse=False):
        if universe == None:
            return
        Features.checkFeatures(self, universe)
        Core.NormalModes.__init__(
            self, universe, subspace, delta, sparse,
            ['array', 'imaginary', 'frequencies', 'omega_sq'])
        self.temperature = temperature

        self.weights = N.sqrt(self.universe.masses().array)
        self.weights = self.weights[:, N.NewAxis]

        self._forceConstantMatrix()
        ev = self._diagonalize()

        self.imaginary = N.less(ev, 0.)
        self.omega_sq = ev
        self.frequencies = N.sqrt(N.fabs(ev)) / (2. * N.pi)
        self.sort_index = N.argsort(self.frequencies)
        self.array.shape = (self.nmodes, self.natoms, 3)

        self.cleanup()
 def paintEvent(self, event):
     graphics = self.last_draw[0]
     if graphics is None:
         return
     graphics.project(self.axis, self.plane)
     p1, p2 = graphics.boundingBoxPlane()
     center = 0.5*(p1+p2)
     scale = self.plotbox_size / (p2-p1)
     sign = scale/N.fabs(scale)
     if self.scale is None:
         minscale = N.minimum.reduce(N.fabs(scale))
         self.scale = 0.9*minscale
     scale = sign*self.scale
     box_center = self.plotbox_origin + 0.5*self.plotbox_size
     shift = -center*scale + box_center + self.translate
     graphics.scaleAndShift(scale, shift)
     items, depths = graphics.lines()
     sort = N.argsort(depths)
     painter = QPainter()
     painter.begin(self)
     painter.fillRect(self.rect(), QBrush(self.background_color))
     if colors_by_name:
         for index in sort:
             x1, y1, x2, y2, color, width = items[index]
             painter.setPen(QPen(QColor(color), width, Qt.SolidLine))
             painter.drawLine(x1, y1, x2, y2)
     else:
         for index in sort:
             x1, y1, x2, y2, color, width = items[index]
             painter.setPen(QPen(getattr(Qt, color), width, Qt.SolidLine))
             painter.drawLine(x1, y1, x2, y2)
     painter.end()
示例#5
0
    def normalizingTransformation(self, repr=None):
        """Returns a linear transformation that shifts the center of mass
        of the object to the coordinate origin and makes its
        principal axes of inertia parallel to the three coordinate
        axes.

        A specific representation can be chosen by setting |repr| to
          Ir    : x y z <--> b c a
          IIr   : x y z <--> c a b
          IIIr  : x y z <--> a b c
          Il    : x y z <--> c b a
          IIl   : x y z <--> a c b
          IIIl  : x y z <--> b a c
        """
        from Scientific.LA import determinant
        cm, inertia = self.centerAndMomentOfInertia()
        ev, diag = inertia.diagonalization()
        if determinant(diag.array) < 0:
            diag.array[0] = -diag.array[0]
        if repr != None:
            seq = Numeric.argsort(ev)
            if repr == 'Ir':
                seq = Numeric.array([seq[1], seq[2], seq[0]])
            elif repr == 'IIr':
                seq = Numeric.array([seq[2], seq[0], seq[1]])
            elif repr == 'Il':
                seq = Numeric.seq[2::-1]
            elif repr == 'IIl':
                seq[1:3] = Numeric.array([seq[2], seq[1]])
            elif repr == 'IIIl':
                seq[0:2] = Numeric.array([seq[1], seq[0]])
            elif repr != 'IIIr':
                print 'unknown representation'
            diag.array = Numeric.take(diag.array, seq)                
        return Transformation.Rotation(diag)*Transformation.Translation(-cm)
示例#6
0
    def normalizingTransformation(self, repr=None):
        """Returns a linear transformation that shifts the center of mass
        of the object to the coordinate origin and makes its
        principal axes of inertia parallel to the three coordinate
        axes.

        A specific representation can be chosen by setting |repr| to
          Ir    : x y z <--> b c a
          IIr   : x y z <--> c a b
          IIIr  : x y z <--> a b c
          Il    : x y z <--> c b a
          IIl   : x y z <--> a c b
          IIIl  : x y z <--> b a c
        """
        from Scientific.LA import determinant
        cm, inertia = self.centerAndMomentOfInertia()
        ev, diag = inertia.diagonalization()
        if determinant(diag.array) < 0:
            diag.array[0] = -diag.array[0]
        if repr != None:
            seq = Numeric.argsort(ev)
            if repr == 'Ir':
                seq = Numeric.array([seq[1], seq[2], seq[0]])
            elif repr == 'IIr':
                seq = Numeric.array([seq[2], seq[0], seq[1]])
            elif repr == 'Il':
                seq = Numeric.seq[2::-1]
            elif repr == 'IIl':
                seq[1:3] = Numeric.array([seq[2], seq[1]])
            elif repr == 'IIIl':
                seq[0:2] = Numeric.array([seq[1], seq[0]])
            elif repr != 'IIIr':
                print 'unknown representation'
            diag.array = Numeric.take(diag.array, seq)
        return Transformation.Rotation(diag) * Transformation.Translation(-cm)
    def __init__(self,
                 universe=None,
                 friction=None,
                 temperature=300. * Units.K,
                 subspace=None,
                 delta=None,
                 sparse=False):
        if universe == None:
            return
        Features.checkFeatures(self, universe)
        Core.NormalModes.__init__(self, universe, subspace, delta, sparse,
                                  ['array', 'inv_relaxation_times'])
        self.friction = friction
        self.temperature = temperature

        self.weights = N.sqrt(friction.array)
        self.weights = self.weights[:, N.NewAxis]

        self._forceConstantMatrix()
        ev = self._diagonalize()

        self.inv_relaxation_times = ev
        self.sort_index = N.argsort(self.inv_relaxation_times)
        self.array.shape = (self.nmodes, self.natoms, 3)

        self.cleanup()
示例#8
0
    def _setupSimilarities(self, items, similarities, symmetric,
                           minimal_similarity):
        self.similarities = []
        self.index = {}
        self.smallest_similarity = None
        self.largest_similarity = None
        self.median_similarity = None

        # Check for array of similarities
        if isinstance(similarities, N.ArrayType):
            if similarities.shape != 2 * (self.nitems, ):
                raise ValueError("Similarity array has wrong shape")
            for i in range(self.nitems):
                for k in range(self.nitems):
                    if i != k:
                        self._storeSimilarity(i, k, similarities[i, k],
                                              minimal_similarity)

        # Check for callable similarity function
        elif callable(similarities):
            for i in range(self.nitems):
                for k in range(i + 1, self.nitems):
                    s = similarities(self.items[i], self.items[k])
                    self._storeSimilarity(i, k, s, minimal_similarity)
                    if not symmetric:
                        s = similarities(self.items[k], self.items[i])
                    self._storeSimilarity(k, i, s, minimal_similarity)

        # Assume list of (i, k, s) triples
        else:
            for i, k, s in similarities:
                if i < 0 or i > self.nitems or k < 0 or k > self.nitems:
                    raise ValueError("Index out of range in " + str((i, k, s)))
                if i == k:
                    raise ValueError("Equal indices in " + str((i, k, s)))
                self._storeSimilarity(i, k, s, minimal_similarity)
                if symmetric:
                    self._storeSimilarity(k, i, s, minimal_similarity)

        # Add indices for self terms
        for i in range(self.nitems):
            self._storeSimilarity(i, i, None, None)

        # Convert similarities to array
        self.nsimilarities = len(self.similarities)
        self.similarities = N.array(self.similarities[:-self.nitems])

        # Find smallest, largest, and median
        self.smallest_similarity = N.minimum.reduce(self.similarities)
        self.largest_similarity = N.maximum.reduce(self.similarities)
        sort_indices = N.argsort(self.similarities)
        ns = int(len(self.similarities) / 2)

        if ns % 2 == 1:
            self.median_similarity = self.similarities[sort_indices[ns]]
        else:
            self.median_similarity = \
              (self.similarities[sort_indices[ns]]
               + self.similarities[sort_indices[ns-1]])/2.
    def _setupSimilarities(self, items, similarities,
                           symmetric, minimal_similarity):
        self.similarities = []
        self.index = {}
        self.smallest_similarity = None
        self.largest_similarity = None
        self.median_similarity = None

        # Check for array of similarities
        if isinstance(similarities, N.ArrayType):
            if similarities.shape != 2*(self.nitems,):
                raise ValueError("Similarity array has wrong shape")
            for i in range(self.nitems):
                for k in range(self.nitems):
                    if i != k:
                        self._storeSimilarity(i, k, similarities[i, k],
                                              minimal_similarity)

        # Check for callable similarity function
        elif callable(similarities):
            for i in range(self.nitems):
                for k in range(i+1, self.nitems):
                    s = similarities(self.items[i], self.items[k])
                    self._storeSimilarity(i, k, s, minimal_similarity)
                    if not symmetric:
                        s = similarities(self.items[k], self.items[i])
                    self._storeSimilarity(k, i, s, minimal_similarity)

        # Assume list of (i, k, s) triples
        else:
            for i, k, s in similarities:
                if i < 0 or i > self.nitems or k < 0 or k > self.nitems:
                    raise ValueError("Index out of range in " + str((i, k, s)))
                if i == k:
                    raise ValueError("Equal indices in " + str((i, k, s)))
                self._storeSimilarity(i, k, s, minimal_similarity)
                if symmetric:
                    self._storeSimilarity(k, i, s, minimal_similarity)

        # Add indices for self terms
        for i in range(self.nitems):
            self._storeSimilarity(i, i, None, None)

        # Convert similarities to array
        self.nsimilarities = len(self.similarities)
        self.similarities = N.array(self.similarities[:-self.nitems])

        # Find smallest, largest, and median
        self.smallest_similarity = N.minimum.reduce(self.similarities)
        self.largest_similarity = N.maximum.reduce(self.similarities)
        sort_indices = N.argsort(self.similarities)
        ns = len(self.similarities)
        if ns % 2 == 1:
            self.median_similarity = self.similarities[sort_indices[ns/2]]
        else:
            self.median_similarity = \
              (self.similarities[sort_indices[ns/2]]
               + self.similarities[sort_indices[ns/2-1]])/2.
示例#10
0
 def defineResolutionShells(self, nrefl_per_shell):
     assert nrefl_per_shell <= self.nreflections
     indices = N.argsort(self.ssq)
     self.res_shells = []
     for first in range(0, len(indices), nrefl_per_shell/2):
         self.res_shells.append(indices[first:first+nrefl_per_shell])
         if len(self.res_shells[-1]) < nrefl_per_shell:
             self.res_shells[-1] = indices[-nrefl_per_shell:]
             break
     self.ssq_av_shell = N.array([0.99*N.minimum.reduce(self.ssq)] +
                                 [N.sum(N.take(self.ssq, rs))/len(rs)
                                  for rs in self.res_shells] + \
                                  [1.001*N.maximum.reduce(self.ssq)])
     # Separate each list into centric and acentric reflections
     self.res_shells = [(N.array([ri for ri in rs
                                  if self.centric[ri]], N.Int32),
                         N.array([ri for ri in rs
                                  if not self.centric[ri]], N.Int32))
                        for rs in self.res_shells]
    def __init__(self, universe=None, temperature = 300,
                 subspace = None, delta = None, sparse = False):
        if universe == None:
            return
        Features.checkFeatures(self, universe)
        Core.NormalModes.__init__(self, universe, subspace, delta, sparse,
                                  ['array', 'force_constants'])
        self.temperature = temperature

        self.weights = N.ones((1, 1), N.Float)

        self._forceConstantMatrix()
        ev = self._diagonalize()

        self.force_constants = ev
        self.sort_index = N.argsort(self.force_constants)
        self.array.shape = (self.nmodes, self.natoms, 3)

        self.cleanup()
示例#12
0
    def __init__(self, universe = None, friction = None,
                 temperature = 300.*Units.K,
                 subspace = None, delta = None, sparse = False):
        if universe == None:
            return
        Features.checkFeatures(self, universe)
        Core.NormalModes.__init__(self, universe, subspace, delta, sparse,
                                  ['array', 'inv_relaxation_times'])
        self.friction = friction
        self.temperature = temperature

        self.weights = N.sqrt(friction.array)
        self.weights = self.weights[:, N.NewAxis]

        self._forceConstantMatrix()
        ev = self._diagonalize()

        self.inv_relaxation_times = ev
        self.sort_index = N.argsort(self.inv_relaxation_times)
        self.array.shape = (self.nmodes, self.natoms, 3)

        self.cleanup()
示例#13
0
    def normalizingTransformation(self, repr=None):
        """
        Calculate a linear transformation that shifts the center of mass
        of the object to the coordinate origin and makes its
        principal axes of inertia parallel to the three coordinate
        axes.

        :param repr: the specific representation for axis alignment:
          Ir    : x y z <--> b c a
          IIr   : x y z <--> c a b
          IIIr  : x y z <--> a b c
          Il    : x y z <--> c b a
          IIl   : x y z <--> a c b
          IIIl  : x y z <--> b a c
        :returns: the normalizing transformation
        :rtype: Scientific.Geometry.Transformation.RigidBodyTransformation
        """
        from Scientific.LA import determinant
        cm, inertia = self.centerAndMomentOfInertia()
        ev, diag = inertia.diagonalization()
        if determinant(diag.array) < 0:
            diag.array[0] = -diag.array[0]
        if repr != None:
            seq = N.argsort(ev)
            if repr == 'Ir':
                seq = N.array([seq[1], seq[2], seq[0]])
            elif repr == 'IIr':
                seq = N.array([seq[2], seq[0], seq[1]])
            elif repr == 'Il':
                seq = N.seq[2::-1]
            elif repr == 'IIl':
                seq[1:3] = N.array([seq[2], seq[1]])
            elif repr == 'IIIl':
                seq[0:2] = N.array([seq[1], seq[0]])
            elif repr != 'IIIr':
                print 'unknown representation'
            diag.array = N.take(diag.array, seq)
        return Transformation.Rotation(diag) * Transformation.Translation(-cm)
示例#14
0
    def normalizingTransformation(self, repr=None):
        """
        Calculate a linear transformation that shifts the center of mass
        of the object to the coordinate origin and makes its
        principal axes of inertia parallel to the three coordinate
        axes.

        :param repr: the specific representation for axis alignment:
          Ir    : x y z <--> b c a
          IIr   : x y z <--> c a b
          IIIr  : x y z <--> a b c
          Il    : x y z <--> c b a
          IIl   : x y z <--> a c b
          IIIl  : x y z <--> b a c
        :returns: the normalizing transformation
        :rtype: Scientific.Geometry.Transformation.RigidBodyTransformation
        """
        from Scientific.LA import determinant
        cm, inertia = self.centerAndMomentOfInertia()
        ev, diag = inertia.diagonalization()
        if determinant(diag.array) < 0:
            diag.array[0] = -diag.array[0]
        if repr != None:
            seq = N.argsort(ev)
            if repr == 'Ir':
                seq = N.array([seq[1], seq[2], seq[0]])
            elif repr == 'IIr':
                seq = N.array([seq[2], seq[0], seq[1]])
            elif repr == 'Il':
                seq = N.seq[2::-1]
            elif repr == 'IIl':
                seq[1:3] = N.array([seq[2], seq[1]])
            elif repr == 'IIIl':
                seq[0:2] = N.array([seq[1], seq[0]])
            elif repr != 'IIIr':
                print 'unknown representation'
            diag.array = N.take(diag.array, seq)                
        return Transformation.Rotation(diag)*Transformation.Translation(-cm)
    def __init__(self, universe=None, temperature = 300.*Units.K,
                 subspace = None, delta = None, sparse = False):
        if universe == None:
            return
        Features.checkFeatures(self, universe)
        Core.NormalModes.__init__(self, universe, subspace, delta, sparse,
                                  ['array', 'imaginary',
                                   'frequencies', 'omega_sq'])
        self.temperature = temperature

        self.weights = N.sqrt(self.universe.masses().array)
        self.weights = self.weights[:, N.NewAxis]

        self._forceConstantMatrix()
        ev = self._diagonalize()

        self.imaginary = N.less(ev, 0.)
        self.omega_sq = ev
        self.frequencies = N.sqrt(N.fabs(ev)) / (2.*N.pi)
        self.sort_index = N.argsort(self.frequencies)
        self.array.shape = (self.nmodes, self.natoms, 3)

        self.cleanup()
示例#16
0
    def __init__(self,
                 universe=None,
                 temperature=300,
                 subspace=None,
                 delta=None,
                 sparse=False):
        if universe == None:
            return
        Features.checkFeatures(self, universe)
        Core.NormalModes.__init__(self, universe, subspace, delta, sparse,
                                  ['array', 'force_constants'])
        self.temperature = temperature

        self.weights = N.ones((1, 1), N.Float)

        self._forceConstantMatrix()
        ev = self._diagonalize()

        self.force_constants = ev
        self.sort_index = N.argsort(self.force_constants)
        self.array.shape = (self.nmodes, self.natoms, 3)

        self.cleanup()
示例#17
0
universe.protein = Protein('bala1')

# Minimize
minimizer = ConjugateGradientMinimizer(universe,
                                       actions=[StandardLogOutput(50)])
minimizer(convergence = 1.e-3, steps = 10000)

# Set up the subspace: rigid-body translation and rotation for each residue
subspace = RigidMotionSubspace(universe, universe.protein.residues())

# Calculate normal modes
modes = VibrationalModes(universe, subspace=subspace)

# Calculate full  modes for comparison
full_modes = VibrationalModes(universe, subspace=None)

# Compare the modes. For each reduced mode, find the full mode with
# the most similar displacement vector. Print both frequencies and
# the overlap of the displacement vectors.
masses = universe.masses()
for i in range(6, len(modes)):
    m1 = modes[i]
    overlap = []
    for m2 in full_modes:
	o = m1.massWeightedDotProduct(m2) / \
	    N.sqrt(m1.massWeightedDotProduct(m1)) / \
	    N.sqrt(m2.massWeightedDotProduct(m2))
	overlap.append(abs(o))
    best = N.argsort(overlap)[-1]
    print m1.frequency, full_modes[best].frequency, overlap[best]
示例#18
0
    def __init__(self,
                 universe=None,
                 temperature=300. * Units.K,
                 subspace=None,
                 delta=None,
                 sparse=False):
        """
        :param universe: the system for which the normal modes are calculated;
                         it must have a force field which provides the second
                         derivatives of the potential energy
        :type universe: :class:~MMTK.Universe.Universe
        :param temperature: the temperature for which the amplitudes of the
                            atomic displacement vectors are calculated. A
                            value of None can be specified to have no scaling
                            at all. In that case the mass-weighted norm
                            of each normal mode is one.
        :type temperature: float
        :param subspace: the basis for the subspace in which the normal modes
                         are calculated (or, more precisely, a set of vectors
                         spanning the subspace; it does not have to be
                         orthogonal). This can either be a sequence of
                         :class:~MMTK.ParticleProperties.ParticleVector objects
                         or a tuple of two such sequences. In the second case,
                         the subspace is defined by the space spanned by the
                         second set of vectors projected on the complement of
                         the space spanned by the first set of vectors.
                         The first set thus defines directions that are
                         excluded from the subspace.
                         The default value of None indicates a standard
                         normal mode calculation in the 3N-dimensional
                         configuration space.
        :param delta: the rms step length for numerical differentiation.
                      The default value of None indicates analytical
                      differentiation.
                      Numerical differentiation is available only when a
                      subspace basis is used as well. Instead of calculating
                      the full force constant matrix and then multiplying
                      with the subspace basis, the subspace force constant
                      matrix is obtained by numerical differentiation of the
                      energy gradients along the basis vectors of the subspace.
                      If the basis is much smaller than the full configuration
                      space, this approach needs much less memory.
        :type delta: float
        :param sparse: a flag that indicates if a sparse representation of
                       the force constant matrix is to be used. This is of
                       interest when there are no long-range interactions and
                       a subspace of smaller size then 3N is specified. In that
                       case, the calculation will use much less memory with a
                       sparse representation.
        :type sparse: bool
        """

        if universe == None:
            return
        Features.checkFeatures(self, universe)
        Core.NormalModes.__init__(
            self, universe, subspace, delta, sparse,
            ['array', 'imaginary', 'frequencies', 'omega_sq'])
        self.temperature = temperature

        self.weights = N.sqrt(self.universe.masses().array)
        self.weights = self.weights[:, N.NewAxis]

        self._forceConstantMatrix()
        ev = self._diagonalize()

        self.imaginary = N.less(ev, 0.)
        self.omega_sq = ev
        self.frequencies = N.sqrt(N.fabs(ev)) / (2. * N.pi)
        self.sort_index = N.argsort(self.frequencies)
        self.array.shape = (self.nmodes, self.natoms, 3)

        self.cleanup()
示例#19
0
    def internalRun(self):
        """Runs the analysis."""
        
        self.chrono = default_timer()

        orderedAtoms = sorted(self.universe.atomList(), key = operator.attrgetter('index'))

        selectedAtoms = Collection([orderedAtoms[ind] for ind in self.subset])
                
        M1_2 = N.zeros((3*self.nSelectedAtoms,), N.Float)
        
        weightList = [N.sqrt(el[1]) for el in sorted([(at.index, at.mass()) for at in selectedAtoms])]
        
        for i in range(len(weightList)):
            M1_2[3*i:3*(i+1)] = weightList[i]
            
        invM1_2 = (1.0/M1_2)*N.identity(3*self.nSelectedAtoms, typecode = N.Float)
            
        # The initial structure configuration.
        initialStructure = self.trajectory.configuration[self.first]

        averageStructure = ParticleVector(self.universe)

        for conf in self.trajectory.configuration[self.first:self.last:self.skip]:
            averageStructure += self.universe.configurationDifference(initialStructure, conf)

        averageStructure = averageStructure/self.nFrames
        averageStructure = initialStructure + averageStructure        
        
        mdr  = N.zeros((self.nFrames, 3*self.nSelectedAtoms), N.Float)
        
        # Calculate the fluctuation matrix.
        sigmaPrim = N.zeros((3*self.nSelectedAtoms, 3*self.nSelectedAtoms), N.Float)
        comp = 0
        for conf in self.trajectory.configuration[self.first:self.last:self.skip]:
            mdr[comp,:] = M1_2*N.ravel(N.compress(self.mask,(conf-averageStructure).array,0)) 
            sigmaPrim += mdr[comp,:, N.NewAxis] * mdr[N.NewAxis, comp, :]            
            comp += 1
                        
        sigmaPrim = sigmaPrim/float(self.nFrames)

        try:
            # Calculate the quasiharmonic modes
            omega, dx = Heigenvectors(sigmaPrim)
            
        except MemoryError:
            raise Error('Not enough memory to diagonalize the %sx%s fluctuation matrix.' % sigmaPrim.shape)
            
        # Due to numerical imprecisions, the result can have imaginary parts.
        # In that case, throw the imaginary parts away.
        # Conversion from uma*nm2 to kg*m2 (SI)
        omega = omega.real/(Units.kg*Units.m**2)        
        omega = (Units.Hz/Units.invcm)*N.sqrt((Units.k_B*Units.K*self.temperature/Units.J)*(1.0/omega))

        dx = dx.real
        dx = N.dot(invM1_2, dx)

        # Sort eigen vectors by decreasing fluctuation amplitude.
        indices = N.argsort(omega)[::-1]
        
        omega = N.take(omega, indices)
        dx = N.take(dx, indices)

        # Eq 66 of the reference paper.
        mdr = N.take(mdr, indices, axis = 1)
        at = N.dot(mdr,N.transpose(dx))
        
        # The NetCDF output file is opened.
        outputFile       = NetCDFFile(self.output, 'w')
        outputFile.title = self.__class__.__name__
        outputFile.jobinfo = self.information + '\nOutput file written on: %s\n\n' % asctime()

        # The universe is emptied from its objects keeping just its topology.
        self.universe.removeObject(self.universe.objectList()[:])
        # The atoms of the subset are copied
        atoms = copy.deepcopy(selectedAtoms.atomList())
        
        # And their parent attribute removed to allow their transfer in the empty universe.
        for a in atoms:
            a.parent = None
        ac = AtomCluster(atoms,name='QHACluster')
        self.universe.addObject(ac)

        # Some dimensions are created.
        # NEIVALS = the number eigen values
        outputFile.createDimension('NEIGENVALS', len(omega))

        # UDESCR = the universe description length
        outputFile.createDimension('UDESCR', len(self.universe.description()))

        # NATOMS = the number of atoms of the universe
        outputFile.createDimension('NATOMS', self.nSelectedAtoms)

        # NFRAMES = the number of frames.
        outputFile.createDimension('NFRAMES', self.nFrames)

        # NCOORDS = the number of coordinates (always = 3).
        outputFile.createDimension('NCOORDS', 3)

        # 3N.
        outputFile.createDimension('3N', 3*self.nSelectedAtoms)

        if self.universe.cellParameters() is not None:
            outputFile.createDimension('BOXDIM', len(self.universe.cellParameters()))

        # Creation of the NetCDF output variables.
        # EIVALS = the eigen values.
        OMEGA = outputFile.createVariable('omega', N.Float, ('NEIGENVALS',))
        OMEGA[:] = omega

        # EIVECS = array of eigen vectors.
        DX = outputFile.createVariable('dx', N.Float, ('NEIGENVALS','NEIGENVALS'))
        DX[:,:] = dx

        # The time.
        TIMES = outputFile.createVariable('time', N.Float, ('NFRAMES',))
        TIMES[:] = self.times[:]
        TIMES.units = 'ps'

        # MODE = the mode number.
        MODE = outputFile.createVariable('mode', N.Float, ('3N',))
        MODE[:] = 1 + N.arange(3*self.nSelectedAtoms)
                
        # LCI = local character indicator. See eq 56.
        LCI = outputFile.createVariable('local_character_indicator', N.Float, ('3N',))
        LCI[:] = (dx**4).sum(0)
        
        # GCI = global character indicator. See eq 57.
        GCI = outputFile.createVariable('global_character_indicator', N.Float, ('3N',))
        GCI[:] = (N.sqrt(3.0*self.nSelectedAtoms)/(N.absolute(dx)).sum(0))**4

        # Projection of MD traj onto normal modes. See eq 66..
        AT = outputFile.createVariable('at', N.Float, ('NFRAMES','3N'))
        AT[:,:] = at[:,:]
        
        # DESCRIPTION = the universe description.
        DESCRIPTION = outputFile.createVariable('description', N.Character, ('UDESCR',))
        DESCRIPTION[:] = self.universe.description()

        # AVGSTRUCT = the average structure.
        AVGSTRUCT = outputFile.createVariable('avgstruct', N.Float, ('NATOMS','NCOORDS'))
        AVGSTRUCT[:,:] = N.compress(self.mask,averageStructure.array,0)

        # If the universe is periodic, create an extra variable storing the box size.
        if self.universe.cellParameters() is not None:
            BOXSIZE = outputFile.createVariable('box_size', N.Float, ('BOXDIM',))
            BOXSIZE[:] = self.universe.cellParameters()

        outputFile.close()

        self.toPlot = None

        self.chrono = default_timer() - self.chrono
        
        return None
示例#20
0
universe.protein = Protein('bala1')

# Minimize
minimizer = ConjugateGradientMinimizer(universe,
                                       actions=[StandardLogOutput(50)])
minimizer(convergence=1.e-3, steps=10000)

# Set up the subspace: rigid-body translation and rotation for each residue
subspace = RigidMotionSubspace(universe, universe.protein.residues())

# Calculate normal modes
modes = VibrationalModes(universe, subspace=subspace)

# Calculate full  modes for comparison
full_modes = VibrationalModes(universe, subspace=None)

# Compare the modes. For each reduced mode, find the full mode with
# the most similar displacement vector. Print both frequencies and
# the overlap of the displacement vectors.
masses = universe.masses()
for i in range(6, len(modes)):
    m1 = modes[i]
    overlap = []
    for m2 in full_modes:
        o = m1.massWeightedDotProduct(m2) / \
            N.sqrt(m1.massWeightedDotProduct(m1)) / \
            N.sqrt(m2.massWeightedDotProduct(m2))
        overlap.append(abs(o))
    best = N.argsort(overlap)[-1]
    print(f"{m1.frequency} {full_modes[best].frequency} {overlap[best]}")
示例#21
0
    def __init__(self, universe = None, friction = None,
                 temperature = 300.*Units.K,
                 subspace = None, delta = None, sparse = False):
        """
        :param universe: the system for which the normal modes are calculated;
                         it must have a force field which provides the second
                         derivatives of the potential energy
        :type universe: :class:`~MMTK.Universe.Universe`
        :param friction: the friction coefficient for each particle.
                         Note: The friction coefficients are not mass-weighted,
                         i.e. they have the dimension of an inverse time.
        :type friction: :class:`~MMTK.ParticleProperties.ParticleScalar`
        :param temperature: the temperature for which the amplitudes of the
                            atomic displacement vectors are calculated. A
                            value of None can be specified to have no scaling
                            at all. In that case the mass-weighted norm
                            of each normal mode is one.
        :type temperature: float
        :param subspace: the basis for the subspace in which the normal modes
                         are calculated (or, more precisely, a set of vectors
                         spanning the subspace; it does not have to be
                         orthogonal). This can either be a sequence of
                         :class:`~MMTK.ParticleProperties.ParticleVector` objects
                         or a tuple of two such sequences. In the second case,
                         the subspace is defined by the space spanned by the
                         second set of vectors projected on the complement of
                         the space spanned by the first set of vectors.
                         The first set thus defines directions that are
                         excluded from the subspace.
                         The default value of None indicates a standard
                         normal mode calculation in the 3N-dimensional
                         configuration space.
        :param delta: the rms step length for numerical differentiation.
                      The default value of None indicates analytical
                      differentiation.
                      Numerical differentiation is available only when a
                      subspace basis is used as well. Instead of calculating
                      the full force constant matrix and then multiplying
                      with the subspace basis, the subspace force constant
                      matrix is obtained by numerical differentiation of the
                      energy gradients along the basis vectors of the subspace.
                      If the basis is much smaller than the full configuration
                      space, this approach needs much less memory.
        :type delta: float
        :param sparse: a flag that indicates if a sparse representation of
                       the force constant matrix is to be used. This is of
                       interest when there are no long-range interactions and
                       a subspace of smaller size then 3N is specified. In that
                       case, the calculation will use much less memory with a
                       sparse representation.
        :type sparse: bool
        """

        if universe == None:
            return
        Features.checkFeatures(self, universe)
        Core.NormalModes.__init__(self, universe, subspace, delta, sparse,
                                  ['array', 'inv_relaxation_times'])
        self.friction = friction
        self.temperature = temperature

        self.weights = N.sqrt(friction.array)
        self.weights = self.weights[:, N.NewAxis]

        self._forceConstantMatrix()
        ev = self._diagonalize()

        self.inv_relaxation_times = ev
        self.sort_index = N.argsort(self.inv_relaxation_times)
        self.array.shape = (self.nmodes, self.natoms, 3)

        self.cleanup()