.. 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