Example #1
0
    def write(self,filename,start=None,step=None,delta=None,load=True):
        """Write hopping trajectory as standard dcd file.

        write('TAP')

        :Arguments:

        load = True     Immediately loads the trajectory so that further
                        calls to next() will use the computed
                        trajectory and don't use expensive mapping.

        Ignore the other options and leave them at the defaults. Currently,
        only the whole trajectory is written. All atoms in the original
        trajectory are written to the output so you should be able to use your
        original psf file.

        NOTE: Fixed atoms are possibly not accounted for properly.

        Note that it is your responsibility to load the TAP trajectory and the
        appropriate psf together as there is very limited information stored in
        the dcd itself.
        """
        set_verbosity(self.verbosity)  # this is stupid

        psfname = self.filename(filename,'psf')
        dcdname = self.filename(filename,'dcd')

        # see MDAnalysis/src/dcd/dcd.c for explanations
        if start is None:
            start = self.traj.start_timestep # starting time step for DCD file
        if step is None:
            step = self.traj.skip_timestep   # NSAVC (# ts between written DCD frames)
        if delta is None:
            delta = self.traj.delta          # length of ts (AKMA units)

        dcdwriter = MDAnalysis.DCD.DCDWriter(dcdname,self.ts.numatoms,
                                             start,step,delta,
                                             remarks='TAP trajectory')
        pm = ProgressMeter(self.numframes, interval=10,
                           format="Mapping TAP frame %(step)5d/%(numsteps)6d  [%(percentage)5.1f%%]\r")
        for ts in self.map_dcd():
            dcdwriter.write_next_timestep(ts)
            pm.echo(ts.frame)
        dcdwriter.close()
        logger.info("TAPTrajectory.write(): wrote TAP traj %r.", dcdname)

        if load is True:
            self.TAPtraj = MDAnalysis.DCD.DCDReader(dcdname)
            self.trajectory = self.TAPtraj
Example #2
0
    def convert(self, gentop=True):
        natoms = self.frames.numatoms
        nframes = self.frames.numframes
        if gentop:
            self.universe.atoms.write(self.top_new) # write first frame as topology
        self.frames.rewind()
        writer = MDAnalysis.Writer(self.trj_new, natoms)

        percentage = ProgressMeter(nframes, interval=10,
                format="Fitted frame %(step)5d/%(numsteps)d  [%(percentage)5.1f%%]\r")

        for ts in self.frames:
            writer.write(self.universe.atoms)
            percentage.echo(ts.frame)
        writer.close_trajectory()
Example #3
0
    def run(self, force=False):
        """
        Run all the required passes

        :Keywords:
          *force*
            Will overwrite previous results if they exist
        """
        # if results exist, don't waste any time
        if not self.solution['results'] is None and not force:
            return

        master_results = numpy.zeros_like(numpy.arange(self._starts[0],
                                                       self._stops[0],
                                                       self._skip),
                                          dtype=numpy.float32)
        # for normalising later
        counter = numpy.zeros_like(master_results, dtype=numpy.float32)

        pm = ProgressMeter(self.nruns,
                           interval=1,
                           format="Performing run %(step)5d/%(numsteps)d"
                           "[%(percentage)5.1f%%]\r")

        for i, (start, stop) in enumerate(izip(self._starts, self._stops)):
            pm.echo(i + 1)

            # needed else trj seek thinks a numpy.int64 isn't an int?
            results = self._single_run(int(start), int(stop))

            nresults = len(results)
            if nresults == len(master_results):
                master_results += results
                counter += 1.0
            else:
                master_results[:nresults] += results
                counter[:nresults] += 1.0

        master_results /= counter

        self.solution['time'] = numpy.arange(
            len(master_results),
            dtype=numpy.float32) * self.u.trajectory.dt * self._skip
        self.solution['results'] = master_results
Example #4
0
    def run(self, force=False):
        """
        Run all the required passes

        :Keywords:
          *force*
            Will overwrite previous results if they exist
        """
        # if results exist, don't waste any time
        if not self.solution["results"] is None and not force:
            return

        master_results = numpy.zeros_like(
            numpy.arange(self._starts[0], self._stops[0], self._skip), dtype=numpy.float32
        )
        # for normalising later
        counter = numpy.zeros_like(master_results, dtype=numpy.float32)

        pm = ProgressMeter(
            self.nruns, interval=1, format="Performing run %(step)5d/%(numsteps)d" "[%(percentage)5.1f%%]\r"
        )

        for i, (start, stop) in enumerate(izip(self._starts, self._stops)):
            pm.echo(i + 1)

            # needed else trj seek thinks a numpy.int64 isn't an int?
            results = self._single_run(int(start), int(stop))

            nresults = len(results)
            if nresults == len(master_results):
                master_results += results
                counter += 1.0
            else:
                master_results[:nresults] += results
                counter[:nresults] += 1.0

        master_results /= counter

        self.solution["time"] = (
            numpy.arange(len(master_results), dtype=numpy.float32) * self.u.trajectory.dt * self._skip
        )
        self.solution["results"] = master_results
Example #5
0
def rms_fit_trj(traj,
                reference,
                select='all',
                filename=None,
                rmsdfile=None,
                prefix='rmsfit_',
                mass_weighted=False,
                tol_mass=0.1,
                force=True,
                quiet=False,
                **kwargs):
    """RMS-fit trajectory to a reference structure using a selection.

    Both reference *ref* and trajectory *traj* must be
    :class:`MDAnalysis.Universe` instances. If they contain a
    trajectory then it is used. The output file format is determined
    by the file extension of *filename*. One can also use the same
    universe if one wants to fit to the current frame.

    :Arguments:
      *traj*
         trajectory, :class:`MDAnalysis.Universe` object
      *reference*
         reference coordinates; :class:`MDAnalysis.Universe` object
         (uses the current time step of the object)
      *select*
         1. any valid selection string for
            :meth:`~MDAnalysis.core.AtomGroup.AtomGroup.selectAtoms` that produces identical
            selections in *mobile* and *reference*; or
         2. a dictionary ``{'mobile':sel1, 'reference':sel2}`` (the
            :func:`fasta2select` function returns such a
            dictionary based on a ClustalW_ or STAMP_ sequence alignment); or
         3. a tuple ``(sel1, sel2)``

         When using 2. or 3. with *sel1* and *sel2* then these selections can also each be
         a list of selection strings (to generate a AtomGroup with defined atom order as
         described under :ref:`ordered-selections-label`).
      *filename*
         file name for the RMS-fitted trajectory or pdb; defaults to the
         original trajectory filename (from *traj*) with *prefix* prepended
      *rmsdfile*
         file name for writing the RMSD timeseries [``None``]
      *prefix*
         prefix for autogenerating the new output filename
      *mass_weighted*
         do a mass-weighted RMSD fit
      *tol_mass*
         Reject match if the atomic masses for matched atoms differ by more than
         *tol_mass* [0.1]
      *force*
         - ``True``: Overwrite an existing output trajectory (default)
         - ``False``: simply return if the file already exists
      *quiet*
         - ``True``: suppress progress and logging for levels INFO and below.
         - ``False``: show all status messages and do not change the the logging
           level (default)

         .. Note:: If


      *kwargs*
         All other keyword arguments are passed on the trajectory
         :class:`~MDAnalysis.coordinates.base.Writer`; this allows manipulating/fixing
         trajectories on the fly (e.g. change the output format by changing the extension of *filename*
         and setting different parameters as described for the corresponding writer).

    :Returns: *filename* (either provided or auto-generated)

    .. _ClustalW: http://www.clustal.org/
    .. _STAMP: http://www.compbio.dundee.ac.uk/manuals/stamp.4.2/

    .. versionchanged:: 0.8
       Added *kwargs* to be passed to the trajectory :class:`~MDAnalysis.coordinates.base.Writer` and
       *filename* is returned.
    """
    frames = traj.trajectory
    if quiet:
        # should be part of a try ... finally to guarantee restoring the log level
        logging.disable(logging.WARN)

    kwargs.setdefault('remarks', 'RMS fitted trajectory to reference')
    if filename is None:
        path, fn = os.path.split(frames.filename)
        filename = os.path.join(path, prefix + fn)
        _Writer = frames.Writer
    else:
        _Writer = frames.OtherWriter
    if os.path.exists(filename) and not force:
        logger.warn(
            "{0} already exists and will NOT be overwritten; use force=True if you want this"
            .format(filename))
        return filename
    writer = _Writer(filename, **kwargs)
    del _Writer

    select = _process_selection(select)
    ref_atoms = reference.selectAtoms(*select['reference'])
    traj_atoms = traj.selectAtoms(*select['mobile'])
    natoms = traj_atoms.numberOfAtoms()

    check_same_atoms(ref_atoms, traj_atoms, tol_mass=tol_mass)

    logger.info("RMS-fitting on %d atoms." % len(ref_atoms))
    if mass_weighted:
        # if performing a mass-weighted alignment/rmsd calculation
        weight = ref_atoms.masses() / ref_atoms.masses().mean()
    else:
        weight = None

    # reference centre of mass system
    # (compatibility with pre 1.0 numpy: explicitly cast coords to float32)
    ref_com = ref_atoms.centerOfMass().astype(numpy.float32)
    ref_coordinates = ref_atoms.coordinates() - ref_com

    # allocate the array for selection atom coords
    traj_coordinates = traj_atoms.coordinates().copy()

    # RMSD timeseries
    nframes = len(frames)
    rmsd = numpy.zeros((nframes, ))

    # R: rotation matrix that aligns r-r_com, x~-x~com
    #    (x~: selected coordinates, x: all coordinates)
    # Final transformed traj coordinates: x' = (x-x~_com)*R + ref_com
    rot = numpy.zeros(9, dtype=numpy.float64)  # allocate space for calculation
    R = numpy.matrix(rot.reshape(3, 3))

    percentage = ProgressMeter(
        nframes,
        interval=10,
        quiet=quiet,
        format="Fitted frame %(step)5d/%(numsteps)d  [%(percentage)5.1f%%]\r")

    for k, ts in enumerate(frames):
        # shift coordinates for rotation fitting
        # selection is updated with the time frame
        x_com = traj_atoms.centerOfMass().astype(numpy.float32)
        traj_coordinates[:] = traj_atoms.coordinates() - x_com

        # Need to transpose coordinates such that the coordinate array is
        # 3xN instead of Nx3. Also qcp requires that the dtype be float64
        # (I think we swapped the position of ref and traj in CalcRMSDRotationalMatrix
        # so that R acts **to the left** and can be broadcasted; we're saving
        # one transpose. [orbeckst])
        rmsd[k] = qcp.CalcRMSDRotationalMatrix(
            ref_coordinates.T.astype(numpy.float64),
            traj_coordinates.T.astype(numpy.float64), natoms, rot, weight)
        R[:, :] = rot.reshape(3, 3)

        # Transform each atom in the trajectory (use inplace ops to avoid copying arrays)
        # (Marginally (~3%) faster than "ts._pos[:] = (ts._pos - x_com) * R + ref_com".)
        ts._pos -= x_com
        ts._pos[:] = ts._pos * R  # R acts to the left & is broadcasted N times.
        ts._pos += ref_com

        writer.write(traj.atoms)  # write whole input trajectory system
        percentage.echo(ts.frame)
    logger.info("Wrote %d RMS-fitted coordinate frames to file %r",
                frames.numframes, filename)
    if not rmsdfile is None:
        numpy.savetxt(rmsdfile, rmsd)
        logger.info("Wrote RMSD timeseries  to file %r", rmsdfile)

    if quiet:
        # should be part of a try ... finally to guarantee restoring the log level
        logging.disable(logging.NOTSET)

    return filename
Example #6
0
    def run(self, **kwargs):
        """Analyze trajectory and produce timeseries.

        Stores the hydrogen bond data per frame
        as :attr:`HydrogenBondAnalysis.timeseries` (see there for
        output format).

        .. SeeAlso:: :meth:`HydrogenBondAnalysis.generate_table` for processing
                     the data into a different format.

        .. versionchanged:: 0.7.6
           Results are not returned, only stored in
           :attr:`~HydrogenBondAnalysis.timeseries` and duplicate hydrogen bonds
           are removed from output (can be suppressed with *remove_duplicates* =
           ``False``)

        """
        logger.info("HBond analysis: starting")
        logger.debug("HBond analysis: donors    %r", self.donors)
        logger.debug("HBond analysis: acceptors %r", self.acceptors)

        remove_duplicates = kwargs.pop('remove_duplicates', True) # False: old behaviour
        if not remove_duplicates:
            logger.warn("Hidden feature remove_duplicates = True activated: you will probably get duplicate H-bonds.")

        verbose = kwargs.pop('verbose', False)
        if verbose != self.verbose:
            self.verbose = verbose
            logger.debug("Toggling verbose to %r", self.verbose)
        if not self.verbose:
            logger.debug("HBond analysis: For full step-by-step debugging output use verbose=True")

        self.timeseries = []
        self.timesteps = []

        logger.info("checking trajectory...")  # numframes can take a while!
        try:
            frames = numpy.arange(self.u.trajectory.numframes)[self.traj_slice]
        except:
            logger.error("Problem reading trajectory or trajectory slice incompatible.")
            logger.exception()
            raise
        pm = ProgressMeter(len(frames),
                           format="HBonds frame %(step)5d/%(numsteps)d [%(percentage)5.1f%%]\r")

        try:
            self.u.trajectory.time
            def _get_timestep():
                return self.u.trajectory.time
            logger.debug("HBond analysis is recording time step")
        except NotImplementedError:
            # chained reader or xyz(?) cannot do time yet
            def _get_timestep():
                return self.u.trajectory.frame
            logger.warn("HBond analysis is recording frame number instead of time step")


        logger.info("Starting analysis (frame index start=%d stop=%d, step=%d)",
                    (self.traj_slice.start or 0),
                    (self.traj_slice.stop or self.u.trajectory.numframes), self.traj_slice.step or 1)

        for ts in self.u.trajectory[self.traj_slice]:
            # all bonds for this timestep
            frame_results = []
            # dict of tuples (atomid, atomid) for quick check if
            # we already have the bond (to avoid duplicates)
            already_found = {}

            frame = ts.frame
            timestep = _get_timestep()
            self.timesteps.append(timestep)

            pm.echo(ts.frame)
            self.logger_debug("Analyzing frame %(frame)d, timestep %(timestep)f ps", vars())
            if self.update_selection1:
                self._update_selection_1()
            if self.update_selection2:
                self._update_selection_2()

            if self.selection1_type in ('donor', 'both'):
                self.logger_debug("Selection 1 Donors <-> Acceptors")
                ns_acceptors = NS.AtomNeighborSearch(self._s2_acceptors)
                for i,donor_h_set in self._s1_donors_h.items():
                    d = self._s1_donors[i]
                    for h in donor_h_set:
                        res = ns_acceptors.search_list(AtomGroup([h]), self.distance)
                        for a in res:
                            angle = self.calc_angle(d,h,a)
                            dist = self.calc_eucl_distance(h,a)
                            if angle >= self.angle and dist <= self.distance:
                                self.logger_debug("S1-D: %s <-> S2-A: %s %f A, %f DEG" % (h.number+1, a.number+1, dist, angle))
                                #self.logger_debug("S1-D: %r <-> S2-A: %r %f A, %f DEG" % (h, a, dist, angle))
                                frame_results.append([h.number+1, a.number+1, '%s%s:%s' % (h.resname, repr(h.resid), h.name), '%s%s:%s' % (a.resname, repr(a.resid), a.name), dist, angle])
                                already_found[(h.number+1, a.number+1)] = True
            if self.selection1_type in ('acceptor', 'both'):
                self.logger_debug("Selection 1 Acceptors <-> Donors")
                ns_acceptors = NS.AtomNeighborSearch(self._s1_acceptors)
                for i,donor_h_set in self._s2_donors_h.items():
                    d = self._s2_donors[i]
                    for h in donor_h_set:
                        res = ns_acceptors.search_list(AtomGroup([h]), self.distance)
                        for a in res:
                            if remove_duplicates and \
                                    ((h.number+1, a.number+1) in already_found or \
                                         (a.number+1, h.number+1) in already_found):
                                continue
                            angle = self.calc_angle(d,h,a)
                            dist = self.calc_eucl_distance(h,a)
                            if angle >= self.angle and dist <= self.distance:
                                self.logger_debug("S1-A: %s <-> S2-D: %s %f A, %f DEG" % (a.number+1, h.number+1, dist, angle))
                                #self.logger_debug("S1-A: %r <-> S2-D: %r %f A, %f DEG" % (a, h, dist, angle))
                                frame_results.append([h.number+1, a.number+1, '%s%s:%s' % (h.resname, repr(h.resid), h.name), '%s%s:%s' % (a.resname, repr(a.resid), a.name), dist, angle])
            self.timeseries.append(frame_results)

        logger.info("HBond analysis: complete; timeseries with %d hbonds in %s.timeseries",
                    self.count_by_time().count.sum(), self.__class__.__name__)
Example #7
0
    def run(self, **kwargs):
        """Analyze trajectory and produce timeseries.

        Stores the hydrogen bond data per frame
        as :attr:`HydrogenBondAnalysis.timeseries` (see there for
        output format).

        .. SeeAlso:: :meth:`HydrogenBondAnalysis.generate_table` for processing
                     the data into a different format.

        .. versionchanged:: 0.7.6
           Results are not returned, only stored in
           :attr:`~HydrogenBondAnalysis.timeseries` and duplicate hydrogen bonds
           are removed from output (can be suppressed with *remove_duplicates* =
           ``False``)

        """
        logger.info("HBond analysis: starting")
        logger.debug("HBond analysis: donors    %r", self.donors)
        logger.debug("HBond analysis: acceptors %r", self.acceptors)

        remove_duplicates = kwargs.pop('remove_duplicates',
                                       True)  # False: old behaviour
        if not remove_duplicates:
            logger.warn(
                "Hidden feature remove_duplicates = True activated: you will probably get duplicate H-bonds."
            )

        verbose = kwargs.pop('verbose', False)
        if verbose != self.verbose:
            self.verbose = verbose
            logger.debug("Toggling verbose to %r", self.verbose)
        if not self.verbose:
            logger.debug(
                "HBond analysis: For full step-by-step debugging output use verbose=True"
            )

        self.timeseries = []
        self.timesteps = []

        logger.info("checking trajectory...")  # numframes can take a while!
        try:
            frames = numpy.arange(self.u.trajectory.numframes)[self.traj_slice]
        except:
            logger.error(
                "Problem reading trajectory or trajectory slice incompatible.")
            logger.exception()
            raise
        pm = ProgressMeter(
            len(frames),
            format="HBonds frame %(step)5d/%(numsteps)d [%(percentage)5.1f%%]\r"
        )

        try:
            self.u.trajectory.time

            def _get_timestep():
                return self.u.trajectory.time

            logger.debug("HBond analysis is recording time step")
        except NotImplementedError:
            # chained reader or xyz(?) cannot do time yet
            def _get_timestep():
                return self.u.trajectory.frame

            logger.warn(
                "HBond analysis is recording frame number instead of time step"
            )

        logger.info(
            "Starting analysis (frame index start=%d stop=%d, step=%d)",
            (self.traj_slice.start or 0),
            (self.traj_slice.stop or self.u.trajectory.numframes),
            self.traj_slice.step or 1)

        for ts in self.u.trajectory[self.traj_slice]:
            # all bonds for this timestep
            frame_results = []
            # dict of tuples (atomid, atomid) for quick check if
            # we already have the bond (to avoid duplicates)
            already_found = {}

            frame = ts.frame
            timestep = _get_timestep()
            self.timesteps.append(timestep)

            pm.echo(ts.frame)
            self.logger_debug(
                "Analyzing frame %(frame)d, timestep %(timestep)f ps", vars())
            if self.update_selection1:
                self._update_selection_1()
            if self.update_selection2:
                self._update_selection_2()

            if self.selection1_type in ('donor', 'both'):
                self.logger_debug("Selection 1 Donors <-> Acceptors")
                ns_acceptors = NS.AtomNeighborSearch(self._s2_acceptors)
                for i, donor_h_set in self._s1_donors_h.items():
                    d = self._s1_donors[i]
                    for h in donor_h_set:
                        res = ns_acceptors.search_list(AtomGroup([h]),
                                                       self.distance)
                        for a in res:
                            angle = self.calc_angle(d, h, a)
                            if self.distance_type in ('hydrogen'):
                                dist = self.calc_eucl_distance(h, a)
                            if self.distance_type in ('heavy'):
                                dist = self.calc_eucl_distance(d, a)
                            #print "{0}\n{1}\n{2}\n{3}\n{4}\n{5}\n".format(d,h,a,dist,dist2,angle)
                            if angle >= self.angle and dist <= self.distance:
                                self.logger_debug(
                                    "S1-D: %s <-> S2-A: %s %f A, %f DEG" %
                                    (h.number + 1, a.number + 1, dist, angle))
                                #self.logger_debug("S1-D: %r <-> S2-A: %r %f A, %f DEG" % (h, a, dist, angle))
                                frame_results.append([
                                    h.number + 1, a.number + 1,
                                    '%s%s:%s' %
                                    (h.resname, repr(h.resid), h.name),
                                    '%s%s:%s' %
                                    (a.resname, repr(a.resid), a.name), dist,
                                    angle
                                ])
                                already_found[(h.number + 1,
                                               a.number + 1)] = True
            if self.selection1_type in ('acceptor', 'both'):
                self.logger_debug("Selection 1 Acceptors <-> Donors")
                ns_acceptors = NS.AtomNeighborSearch(self._s1_acceptors)
                for i, donor_h_set in self._s2_donors_h.items():
                    d = self._s2_donors[i]
                    for h in donor_h_set:
                        res = ns_acceptors.search_list(AtomGroup([h]),
                                                       self.distance)
                        for a in res:
                            if remove_duplicates and \
                                    ((h.number+1, a.number+1) in already_found or \
                                         (a.number+1, h.number+1) in already_found):
                                continue
                            angle = self.calc_angle(d, h, a)
                            if self.distance_type in ('hydrogen'):
                                dist = self.calc_eucl_distance(h, a)
                            if self.distance_type in ('heavy'):
                                dist = self.calc_eucl_distance(d, a)
                            if angle >= self.angle and dist <= self.distance:
                                self.logger_debug(
                                    "S1-A: %s <-> S2-D: %s %f A, %f DEG" %
                                    (a.number + 1, h.number + 1, dist, angle))
                                #self.logger_debug("S1-A: %r <-> S2-D: %r %f A, %f DEG" % (a, h, dist, angle))
                                frame_results.append([
                                    h.number + 1, a.number + 1,
                                    '%s%s:%s' %
                                    (h.resname, repr(h.resid), h.name),
                                    '%s%s:%s' %
                                    (a.resname, repr(a.resid), a.name), dist,
                                    angle
                                ])
            self.timeseries.append(frame_results)

        logger.info(
            "HBond analysis: complete; timeseries with %d hbonds in %s.timeseries",
            self.count_by_time().count.sum(), self.__class__.__name__)
Example #8
0
    def run(self, **kwargs):
        """Perform RMSD analysis on the trajectory.

        A number of parameters can be changed from the defaults. The
        result is stored as the array :attr:`RMSD.rmsd`.

        :Keywords:
          *start*, *stop*, *step*
             start and stop frame index with step size: analyse
             ``trajectory[start:stop:step]`` [``None``]
          *mass_weighted*
             do a mass-weighted RMSD fit
          *tol_mass*
             Reject match if the atomic masses for matched atoms differ by more than
             *tol_mass*
          *ref_frame*
             frame index to select frame from *reference*

        """
        from itertools import izip

        start = kwargs.pop('start', None)
        stop = kwargs.pop('stop', None)
        step = kwargs.pop('step', None)
        mass_weighted = kwargs.pop('mass_weighted', self.mass_weighted)
        ref_frame = kwargs.pop('ref_frame', self.ref_frame)

        natoms = self.traj_atoms.numberOfAtoms()
        trajectory = self.universe.trajectory
        traj_atoms = self.traj_atoms

        if mass_weighted:
            # if performing a mass-weighted alignment/rmsd calculation
            weight = self.ref_atoms.masses() / self.ref_atoms.masses().mean()
        else:
            weight = None

        # reference centre of mass system
        current_frame = self.reference.trajectory.ts.frame - 1
        try:
            # Move to the ref_frame
            # (coordinates MUST be stored in case the ref traj is advanced elsewhere or if ref == mobile universe)
            self.reference.trajectory[ref_frame]
            ref_com = self.ref_atoms.centerOfMass()
            ref_coordinates = self.ref_atoms.positions - ref_com  # makes a copy
            if self.groupselections_atoms:
                groupselections_ref_coords_T_64 = [
                    self.reference.selectAtoms(*s['reference']).positions.T.astype(numpy.float64) for s in
                    self.groupselections]
        finally:
            # Move back to the original frame
            self.reference.trajectory[current_frame]
        ref_coordinates_T_64 = ref_coordinates.T.astype(numpy.float64)

        # allocate the array for selection atom coords
        traj_coordinates = traj_atoms.coordinates().copy()

        if self.groupselections_atoms:
            # Only carry out a rotation if we want to calculate secondary RMSDs.
            # R: rotation matrix that aligns r-r_com, x~-x~com
            #    (x~: selected coordinates, x: all coordinates)
            # Final transformed traj coordinates: x' = (x-x~_com)*R + ref_com
            rot = numpy.zeros(9, dtype=numpy.float64)  # allocate space for calculation
            R = numpy.matrix(rot.reshape(3, 3))
        else:
            rot = None

        # RMSD timeseries
        nframes = len(numpy.arange(0, len(trajectory))[start:stop:step])
        rmsd = numpy.zeros((nframes, 3 + len(self.groupselections_atoms)))

        percentage = ProgressMeter(nframes, interval=10,
                                   format="RMSD %(rmsd)5.2f A at frame %(step)5d/%(numsteps)d  [%(percentage)5.1f%%]\r")

        for k, ts in enumerate(trajectory[start:stop:step]):
            # shift coordinates for rotation fitting
            # selection is updated with the time frame
            x_com = traj_atoms.centerOfMass().astype(numpy.float32)
            traj_coordinates[:] = traj_atoms.coordinates() - x_com

            rmsd[k, :2] = ts.frame, trajectory.time

            if self.groupselections_atoms:
                # 1) superposition structures
                # Need to transpose coordinates such that the coordinate array is
                # 3xN instead of Nx3. Also qcp requires that the dtype be float64
                # (I think we swapped the position of ref and traj in CalcRMSDRotationalMatrix
                # so that R acts **to the left** and can be broadcasted; we're saving
                # one transpose. [orbeckst])
                rmsd[k, 2] = qcp.CalcRMSDRotationalMatrix(ref_coordinates_T_64,
                                                          traj_coordinates.T.astype(numpy.float64),
                                                          natoms, rot, weight)
                R[:, :] = rot.reshape(3, 3)

                # Transform each atom in the trajectory (use inplace ops to avoid copying arrays)
                # (Marginally (~3%) faster than "ts._pos[:] = (ts._pos - x_com) * R + ref_com".)
                ts._pos -= x_com
                ts._pos[:] = ts._pos * R  # R acts to the left & is broadcasted N times.
                ts._pos += ref_com

                # 2) calculate secondary RMSDs
                for igroup, (refpos, atoms) in enumerate(
                        izip(groupselections_ref_coords_T_64, self.groupselections_atoms), 3):
                    rmsd[k, igroup] = qcp.CalcRMSDRotationalMatrix(refpos,
                                                                   atoms['mobile'].positions.T.astype(numpy.float64),
                                                                   atoms['mobile'].numberOfAtoms(), None, weight)
            else:
                # only calculate RMSD by setting the Rmatrix to None
                # (no need to carry out the rotation as we already get the optimum RMSD)
                rmsd[k, 2] = qcp.CalcRMSDRotationalMatrix(ref_coordinates_T_64,
                                                          traj_coordinates.T.astype(numpy.float64),
                                                          natoms, None, weight)

            percentage.echo(ts.frame, rmsd=rmsd[k, 2])
        self.rmsd = rmsd
Example #9
0
    # create universe with trajectory elements; make reference universe
    u = md.Universe(args.top, args.traj)
    uref = md.Universe(args.ref)

    # establish resnums
    A = u.selectAtoms('segid PROA')
    B = u.selectAtoms('segid PROB')
    A.residues.set_resnum(A.residues.resids() + 2)
    B.residues.set_resnum(A.residues.resids() + 2)

    Aref = uref.selectAtoms('segid PROA')
    Bref = uref.selectAtoms('segid PROB')
    Aref.residues.set_resnum(Aref.residues.resids() + 2)
    Bref.residues.set_resnum(Aref.residues.resids() + 2)

    # get selections of dimerization domain
    dimersel = [NapA_ss[x] for x in NapA_dimer]
    dimer = u.selectAtoms(*dimersel)
    dimerref = uref.selectAtoms(*dimersel)

    # loop through trajectory fitting to ref, write out
    w = md.Writer(args.outtraj, u.trajectory.numatoms)
    pm = ProgressMeter(u.trajectory.numframes, interval=100)
    for ts in u.trajectory:
        pm.echo(ts.frame)
        aln.alignto(dimer, dimerref)
        w.write(ts)

    w.close_trajectory()
Example #10
0
    def write(self,filename,start=None,step=None,delta=None,load=True):
        """Write hopping trajectory as standard dcd file, together with a minimal psf.

        write('hop')

        Arguments:

        load = True     Immediately loads the trajectory so that further
                        calls to next() will use the computed
                        trajectory and don't use expensive mapping.

        Ignore the other options and leave them at the
        defaults. Currently, only the whole trajectory is written. For
        visualization one also needs the dummy psf of the group.

        Results:

        filename.trajectory and filename.psf

        Note that it is your responsibility to load the hopping
        trajectory and the appropriate psf together as there is very
        limited information stored in the dcd itself.
        """
        set_verbosity(self.verbosity)  # this is stupid

        psfname = self.filename(filename,'psf')
        dcdname = self.filename(filename,'dcd')

        # see MDAnalysis/src/dcd/dcd.c for explanations;
        # other trajectories do not have certain values so we just fake them...
        if start is None:
            try:
                start = self.traj.start_timestep # starting time step for DCD file
            except AttributeError:
                start = 1
        if step is None:
            try:
                step = self.traj.skip_timestep   # NSAVC (# ts between written DCD frames)
            except AttributeError:
                step = 1
        if delta is None:
            from MDAnalysis.core.units import get_conversion_factor
            delta_ps = self.traj.convert_time_from_native(self.traj.delta)  # length of ts in ps
            delta = get_conversion_factor('time', 'ps', 'AKMA') * delta_ps

        dcdwriter = MDAnalysis.coordinates.DCD.DCDWriter(dcdname,self.ts.numatoms,
                                             start,step,delta,
                                             remarks='Hopping trajectory: x=site y=orbit_site z=0')
        pm = ProgressMeter(self.numframes, interval=10,
                           format="Mapping frame %(step)5d/%(numsteps)6d  [%(percentage)5.1f%%]\r")
        for ts in self.map_dcd():
            dcdwriter.write_next_timestep(ts)
            pm.echo(ts.frame)
	    dcdwriter.close()
        logger.info("HoppingTrajectory.write(): wrote hoptraj %r.", dcdname)

        self.write_psf(psfname)
        logger.info("HoppingTrajectory.write(): wrote hoppsf %r.", psfname)

        if load is True:
            self.__init__(filename=filename,verbosity=self.verbosity)
Example #11
0
def rms_fit_trj(traj, reference, select='all', filename=None, rmsdfile=None, prefix='rmsfit_',
                mass_weighted=False, tol_mass=0.1, force=True, quiet=False, **kwargs):
    """RMS-fit trajectory to a reference structure using a selection.

    Both reference *ref* and trajectory *traj* must be
    :class:`MDAnalysis.Universe` instances. If they contain a
    trajectory then it is used. The output file format is determined
    by the file extension of *filename*. One can also use the same
    universe if one wants to fit to the current frame.

    :Arguments:
      *traj*
         trajectory, :class:`MDAnalysis.Universe` object
      *reference*
         reference coordinates; :class:`MDAnalysis.Universe` object
         (uses the current time step of the object)
      *select*
         1. any valid selection string for
            :meth:`~MDAnalysis.core.AtomGroup.AtomGroup.selectAtoms` that produces identical
            selections in *mobile* and *reference*; or
         2. a dictionary ``{'mobile':sel1, 'reference':sel2}`` (the
            :func:`fasta2select` function returns such a
            dictionary based on a ClustalW_ or STAMP_ sequence alignment); or
         3. a tuple ``(sel1, sel2)``

         When using 2. or 3. with *sel1* and *sel2* then these selections can also each be
         a list of selection strings (to generate a AtomGroup with defined atom order as
         described under :ref:`ordered-selections-label`).
      *filename*
         file name for the RMS-fitted trajectory or pdb; defaults to the
         original trajectory filename (from *traj*) with *prefix* prepended
      *rmsdfile*
         file name for writing the RMSD timeseries [``None``]
      *prefix*
         prefix for autogenerating the new output filename
      *mass_weighted*
         do a mass-weighted RMSD fit
      *tol_mass*
         Reject match if the atomic masses for matched atoms differ by more than
         *tol_mass* [0.1]
      *force*
         - ``True``: Overwrite an existing output trajectory (default)
         - ``False``: simply return if the file already exists
      *quiet*
         - ``True``: suppress progress and logging for levels INFO and below.
         - ``False``: show all status messages and do not change the the logging
           level (default)

         .. Note:: If


      *kwargs*
         All other keyword arguments are passed on the trajectory
         :class:`~MDAnalysis.coordinates.base.Writer`; this allows manipulating/fixing
         trajectories on the fly (e.g. change the output format by changing the extension of *filename*
         and setting different parameters as described for the corresponding writer).

    :Returns: *filename* (either provided or auto-generated)

    .. _ClustalW: http://www.clustal.org/
    .. _STAMP: http://www.compbio.dundee.ac.uk/manuals/stamp.4.2/

    .. versionchanged:: 0.8
       Added *kwargs* to be passed to the trajectory :class:`~MDAnalysis.coordinates.base.Writer` and
       *filename* is returned.
    """
    frames = traj.trajectory
    if quiet:
        # should be part of a try ... finally to guarantee restoring the log level
        logging.disable(logging.WARN)

    kwargs.setdefault('remarks', 'RMS fitted trajectory to reference')
    if filename is None:
        path, fn = os.path.split(frames.filename)
        filename = os.path.join(path, prefix + fn)
        _Writer = frames.Writer
    else:
        _Writer = frames.OtherWriter
    if os.path.exists(filename) and not force:
        logger.warn("{0} already exists and will NOT be overwritten; use force=True if you want this".format(filename))
        return filename
    writer = _Writer(filename, **kwargs)
    del _Writer

    select = _process_selection(select)
    ref_atoms = reference.selectAtoms(*select['reference'])
    traj_atoms = traj.selectAtoms(*select['mobile'])
    natoms = traj_atoms.numberOfAtoms()

    check_same_atoms(ref_atoms, traj_atoms, tol_mass=tol_mass)

    logger.info("RMS-fitting on %d atoms." % len(ref_atoms))
    if mass_weighted:
        # if performing a mass-weighted alignment/rmsd calculation
        weight = ref_atoms.masses() / ref_atoms.masses().mean()
    else:
        weight = None

    # reference centre of mass system
    # (compatibility with pre 1.0 numpy: explicitly cast coords to float32)
    ref_com = ref_atoms.centerOfMass().astype(numpy.float32)
    ref_coordinates = ref_atoms.coordinates() - ref_com

    # allocate the array for selection atom coords
    traj_coordinates = traj_atoms.coordinates().copy()

    # RMSD timeseries
    nframes = len(frames)
    rmsd = numpy.zeros((nframes,))

    # R: rotation matrix that aligns r-r_com, x~-x~com
    #    (x~: selected coordinates, x: all coordinates)
    # Final transformed traj coordinates: x' = (x-x~_com)*R + ref_com
    rot = numpy.zeros(9, dtype=numpy.float64)  # allocate space for calculation
    R = numpy.matrix(rot.reshape(3, 3))

    percentage = ProgressMeter(nframes, interval=10, quiet=quiet,
                               format="Fitted frame %(step)5d/%(numsteps)d  [%(percentage)5.1f%%]\r")

    for k, ts in enumerate(frames):
        # shift coordinates for rotation fitting
        # selection is updated with the time frame
        x_com = traj_atoms.centerOfMass().astype(numpy.float32)
        traj_coordinates[:] = traj_atoms.coordinates() - x_com

        # Need to transpose coordinates such that the coordinate array is
        # 3xN instead of Nx3. Also qcp requires that the dtype be float64
        # (I think we swapped the position of ref and traj in CalcRMSDRotationalMatrix
        # so that R acts **to the left** and can be broadcasted; we're saving
        # one transpose. [orbeckst])
        rmsd[k] = qcp.CalcRMSDRotationalMatrix(ref_coordinates.T.astype(numpy.float64),
                                               traj_coordinates.T.astype(numpy.float64),
                                               natoms, rot, weight)
        R[:, :] = rot.reshape(3, 3)

        # Transform each atom in the trajectory (use inplace ops to avoid copying arrays)
        # (Marginally (~3%) faster than "ts._pos[:] = (ts._pos - x_com) * R + ref_com".)
        ts._pos -= x_com
        ts._pos[:] = ts._pos * R  # R acts to the left & is broadcasted N times.
        ts._pos += ref_com

        writer.write(traj.atoms)  # write whole input trajectory system
        percentage.echo(ts.frame)
    logger.info("Wrote %d RMS-fitted coordinate frames to file %r",
                frames.numframes, filename)
    if not rmsdfile is None:
        numpy.savetxt(rmsdfile, rmsd)
        logger.info("Wrote RMSD timeseries  to file %r", rmsdfile)

    if quiet:
        # should be part of a try ... finally to guarantee restoring the log level
        logging.disable(logging.NOTSET)

    return filename