.. Contains the formatted docstrings for the transformations located in 'mdanalysis/MDAnalysis/transformations' .. _transformations: ********************************************************* Trajectory transformations ("on-the-fly" transformations) ********************************************************* .. module:: MDAnalysis.transformations In MDAnalysis, a *transformation* is a function that modifies the data for the current :class:`Timestep` and returns the :class:`Timestep`. For instance, coordinate transformations, such as PBC corrections and molecule fitting are often required for some analyses and visualization. Transformation functions (``transformation_1`` and ``transformation_2`` in the following example) can be called by the user for any given :class:`Timestep` of the trajectory, .. code-block:: python u = MDAnalysis.Universe(topology, trajectory) for ts in u.trajectory: ts = transformation_2(transformation_1(ts)) where they change the coordinates of the timestep ``ts`` in place. There is nothing special about these transformations except that they have to be written in such a way that they change the :class:`Timestep` in place. As described under :ref:`workflows`, multiple transformations can be grouped together and associated with a trajectory so that the trajectory is **transformed on-the-fly**, i.e., the data read from the trajectory file will be changed before it is made available in, say, the :attr:`AtomGroup.positions` attribute. The submodule :mod:`MDAnalysis.transformations` contains a collection of transformations (see :ref:`transformations-module`) that can be immediately used but one can always write custom transformations (see :ref:`custom-transformations`). .. _workflows: Workflows --------- Instead of manually applying transformations, it is much more convenient to associate a whole *workflow* of transformations with a trajectory and have the transformations be called automatically. A workflow is a sequence (tuple or list) of transformation functions that will be applied in this order. For example, .. code-block:: python workflow = [transformation_1, transformation_2] would effectively result in .. code-block:: python ts = transformation_2(transformation_1(ts)) for every time step in the trajectory. One can add a workflow using the :meth:`Universe.trajectory.add_transformations ` method of a trajectory (where the list ``workflow`` is taken from the example above), .. code-block:: python u.trajectory.add_transformations(*workflow) or upon :class:`Universe ` creation using the keyword argument `transformations`: .. code-block:: python u = MDAnalysis.Universe(topology, trajectory, transformations=workflow) Note that in these two cases, the workflow cannot be changed after having being added. .. _custom-transformations: Creating transformations ------------------------ A *transformation* is a function that takes a :class:`~MDAnalysis.coordinates.base.Timestep` as input, modifies it, and returns it. A simple transformation that takes no other arguments but a :class:`Timestep` can be defined as the following example: .. code-block:: python def up_by_2(ts): """ Translate all coordinates by 2 angstroms up along the Z dimension. """ ts.positions = ts.positions + np.array([0, 0, 2], dtype=np.float32) return ts If the transformation requires other arguments besides the :class:`Timestep`, the transformation takes these arguments, while a wrapped function takes the :class:`Timestep` object as argument. So, a transformation can be roughly defined as follows: .. code-block:: python def up_by_x(distance): """ Creates a transformation that will translate all coordinates by a given amount along the Z dimension. """ def wrapped(ts): ts.positions = ts.positions + np.array([0, 0, distance], dtype=np.float32) return ts return wrapped An alternative to using a wrapped function is using partials from :mod:`functools`. The above function can be written as: .. code-block:: python import functools def up_by_x(ts, distance): ts.positions = ts.positions + np.array([0, 0, distance], dtype=np.float32) return ts up_by_2 = functools.partial(up_by_x, distance=2) See :func:`MDAnalysis.transformations.translate` for a simple example of such a type of function. .. _transformations-module: Transformations in MDAnalysis ----------------------------- The module :mod:`MDAnalysis.transformations` contains transformations that can be immediately used in your own :ref:`workflows`. In order to use any of these transformations, the module must first be imported: .. code-block:: python import MDAnalysis.transformations A workflow can then be added to a trajectory as described above. See :ref:`implemented-transformations` for more on the existing transformations in :mod:`MDAnalysis.transformations`. How to transformations ---------------------- Translating the coordinates of a single frame (although one would normally add the transformation to a :ref:`workflow`, as shown in the subsequent examples): .. code-block:: python u = MDAnalysis.Universe(topology, trajectory) new_ts = MDAnalysis.transformations.translate([1,1,1])(u.trajectory.ts) Create a workflow and add it to the trajectory: .. code-block:: python u = MDAnalysis.Universe(topology, trajectory) workflow = [MDAnalysis.transformations.translate([1,1,1]), MDAnalysis.transformations.translate([1,2,3])] u.trajectory.add_transformations(*workflow) Giving a workflow as a keyword argument when defining the universe: .. code-block:: python workflow = [MDAnalysis.transformations.translate([1,1,1]), MDAnalysis.transformations.translate([1,2,3])] u = MDAnalysis.Universe(topology, trajectory, transformations=workflow) .. _implemented-transformations: Currently implemented transformations ------------------------------------- .. toctree:: ./transformations/translate ./transformations/rotate ./transformations/positionaveraging ./transformations/fit ./transformations/wrap