From a0f22237e7bc7518b12ea3163bf13c49bce77454 Mon Sep 17 00:00:00 2001 From: Shreya Bhakat Date: Sun, 22 Feb 2026 16:37:20 +0000 Subject: [PATCH] Fix #5100: Auto-switch to non-linear MSD for custom frames --- package/MDAnalysis/analysis/msd.py | 32 ++++++++++++++---------------- 1 file changed, 15 insertions(+), 17 deletions(-) diff --git a/package/MDAnalysis/analysis/msd.py b/package/MDAnalysis/analysis/msd.py index 814ea37bed..49c86d5a31 100644 --- a/package/MDAnalysis/analysis/msd.py +++ b/package/MDAnalysis/analysis/msd.py @@ -64,26 +64,26 @@ .. warning:: To correctly compute the MSD using this analysis module, you must supply - coordinates in the **unwrapped** convention, also known as **no-jump**. - That is, when atoms pass the periodic boundary, they must not be wrapped + coordinates in the **unwrapped** convention, also known as **no-jump**. + That is, when atoms pass the periodic boundary, they must not be wrapped back into the primary simulation cell. - - In MDAnalysis you can use the + + In MDAnalysis you can use the :class:`~MDAnalysis.transformations.nojump.NoJump` transformation to unwrap coordinates on-the-fly. - + A minimal example: .. code-block:: python - + import MDAnalysis as mda from MDAnalysis.transformations import NoJump - + u = mda.Universe(TOP, TRAJ) - + # Apply NoJump transformation to unwrap coordinates u.trajectory.add_transformations(NoJump(u)) - + # Now the trajectory is unwrapped and MSD can be computed normally: from MDAnalysis.analysis.msd import EinsteinMSD MSD = EinsteinMSD(u, select="all", msd_type="xyz") @@ -94,11 +94,11 @@ dimensions must be defined before applying ``NoJump``, which can be accomplished by applying the :class:`~MDAnalysis.transformations.boxdimensions.set_dimensions` - transformation *before* the + transformation *before* the :class:`~MDAnalysis.transformations.nojump.NoJump` transformation. - + This replaces the need to preprocess trajectories externally. - + In GROMACS, for example, this can be done using `gmx trjconv`_ with the ``-pbc nojump`` flag. @@ -427,7 +427,7 @@ def _single_frame(self): ] def _conclude(self): - if self.non_linear: + if self.non_linear or (self.frames is not None and not self.fft): self._conclude_non_linear() else: if self.fft: @@ -457,8 +457,7 @@ def _conclude_fft(self): # with FFT, np.float64 bit prescision required. try: import tidynamics except ImportError: - raise ImportError( - """ERROR --- tidynamics was not found! + raise ImportError("""ERROR --- tidynamics was not found! tidynamics is required to compute an FFT based MSD (default) @@ -466,8 +465,7 @@ def _conclude_fft(self): # with FFT, np.float64 bit prescision required. pip install tidynamics - or set fft=False""" - ) + or set fft=False""") positions = self._position_array.astype(np.float64) for n in ProgressBar(