Calculating Root-Mean-Square Deviations (RMSD) — pmda.rms

This module contains parallel versions of analysis tasks in MDAnalysis.analysis.rms.RMSD.

class pmda.rms.rmsd.RMSD(mobile, ref, superposition=True)[source]

Parallel RMSD analysis.

Optimally superimpose the coordinates in the AtomGroup mobile onto ref for each frame in the trajectory of mobile, and calculate the time series of the RMSD. The single frame calculation is performed with MDAnalysis.analysis.rms.rmsd() (with superposition=True by default).


Contains the time series of the RMSD as a Tx3 numpy.ndarray array with content [[frame, time (ps), RMSD (Å)], [...], ...], where T is the number of time steps selected in the run() method.



  • mobile (AtomGroup) – atoms that are optimally superimposed on ref before the RMSD is calculated for all atoms. The coordinates of mobile change with each frame in the trajectory.

  • ref (AtomGroup) – fixed reference coordinates

  • superposition (bool, optional) – True perform a RMSD-superposition, False only calculates the RMSD. The default is True.


If you use trajectory data from simulations performed under periodic boundary conditions then you must make your molecules whole before performing RMSD calculations so that the centers of mass of the mobile and reference structure are properly superimposed.

Run the analysis with, which stores the results in the array RMSD.rmsd.

The root mean square deviation \(\rho(t)\) of a group of \(N\) atoms relative to a reference structure as a function of time is calculated as:

\[\rho(t) = \sqrt{\frac{1}{N} \sum_{i=1}^N \left(\mathbf{x}_i(t) - \mathbf{x}_i^{\text{ref}}\right)^2}\]

The selected coordinates from atomgroup are optimally superimposed (translation and rotation) on the reference coordinates at each time step as to minimize the RMSD.

At the moment, this class has far fewer features than its serial counterpart, MDAnalysis.analysis.rms.RMSD.


In this example we will globally fit a protein to a reference structure. The example is a DIMS trajectory of adenylate kinase, which samples a large closed-to-open transition.

The trajectory is included in the MDAnalysis test data files. The data in RMSD.rmsd is plotted with matplotlib.pyplot.plot():

import MDAnalysis
from MDAnalysis.tests.datafiles import PSF, DCD, CRD
mobile = MDAnalysis.Universe(PSF,DCD).atoms
# reference closed AdK (1AKE) (with the default ref_frame=0)
ref = MDAnalysis.Universe(PSF,DCD).atoms

from pmda.rms import RMSD

R = RMSD(mobile, ref)

import matplotlib.pyplot as plt
rmsd = R.rmsd.T[2]  # transpose makes it easier for plotting
time = rmsd[0]
fig = plt.figure(figsize=(4,4))
ax = fig.add_subplot(111)
ax.plot(time, rmsd,  label="all")
ax.set_xlabel("time (ps)")
ax.set_ylabel(r"RMSD ($\\AA$)")
  • Universe (Universe) – a MDAnalysis.core.groups.Universe (the atomgroups must belong to this Universe)

  • atomgroups (tuple of AtomGroup) – atomgroups that are iterated in parallel


The raw data from each process are stored as a list of lists, with each sublist containing the return values from pmda.parallel.ParallelAnalysisBase._single_frame().




Set the attributes of this class to be read only

Useful to avoid the class being modified when passing it around.

To be used as a context manager:

with analysis.readonly_attributes():
run(start=None, stop=None, step=None, n_jobs=1, n_blocks=None)

Perform the calculation

  • start (int, optional) – start frame of analysis

  • stop (int, optional) – stop frame of analysis

  • step (int, optional) – number of frames to skip between each analysed frame

  • n_jobs (int, optional) – number of jobs to start, if -1 use number of logical cpu cores. This argument will be ignored when the distributed scheduler is used

  • n_blocks (int, optional) – number of blocks to divide trajectory into. If None set equal to n_jobs or number of available workers in scheduler.