mdanalysis icon indicating copy to clipboard operation
mdanalysis copied to clipboard

Added NoJump on-the-fly example to MSD documentation (Issue #4169)

Open tanii1125 opened this issue 3 weeks ago • 3 comments

This PR updates the MSD documentation inside MDAnalysis.analysis.msd to show users how to correctly apply the NoJump transformation using on-the-fly trajectory transformations.

Issue #4169 noted that although NoJump exists, there was no example showing how to use it directly in MDAnalysis.

This PR adds:

  • A minimal working example demonstrating NoJump usage
  • Clarification that wrapped coordinates must be unwrapped
  • A modern MDAnalysis-based workflow that does not require external tools

Fixes: #4169 I would appreciate any feedback or suggestions for improvement. Reviews are very welcome, and I’m happy to revise the PR based on your guidance.


📚 Documentation preview 📚: https://mdanalysis--5165.org.readthedocs.build/en/5165/

tanii1125 avatar Dec 02 '25 17:12 tanii1125

Thank you for pointing this out! I’ve updated the file to restore the correct license header (LGPL v2.1+).

tanii1125 avatar Dec 02 '25 17:12 tanii1125

Codecov Report

:white_check_mark: All modified and coverable lines are covered by tests. :white_check_mark: Project coverage is 92.72%. Comparing base (bbcef1b) to head (66d7f12). :warning: Report is 1 commits behind head on develop.

Additional details and impacted files
@@           Coverage Diff            @@
##           develop    #5165   +/-   ##
========================================
  Coverage    92.72%   92.72%           
========================================
  Files          180      180           
  Lines        22472    22472           
  Branches      3188     3188           
========================================
  Hits         20837    20837           
  Misses        1177     1177           
  Partials       458      458           

:umbrella: View full report in Codecov by Sentry.
:loudspeaker: Have feedback on the report? Share it here.

:rocket: New features to boost your workflow:
  • :snowflake: Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

codecov[bot] avatar Dec 02 '25 17:12 codecov[bot]

@orbeckst

  • Added the example script used to verify the documentation change.
  • Updated the AUTHORS file to follow the existing formatting.
  • Updated the documentation to clarify that NoJump requires periodic boundary conditions, avoiding errors when PBC information is not present.

As input , I used the built-in MDAnalysis random walk test data:

  • RANDOM_WALK_TOPO
  • RANDOM_WALK

Below is the MSD plot produced by running the example script. After applying NoJump, the MSD increases linearly with lag time, as expected for normal diffusion, and follows the known 3D Brownian behavior (≈ 6τ).

image

tanii1125 avatar Dec 13 '25 14:12 tanii1125

Is RANDOM_WALK a good example, namely, did you check that it was actually generated with periodic boundary conditions?

In order to demonstrate that the example is working, I'd expect to see a comparison between omitting and using NoJump.

Thanks for the clarification,

After checking more carefully, I realized that:-

  • Relying on existing trajectories (e.g. RANDOM_WALK or other test data) is not reliable for demonstrating NoJump, since many of them are either not generated with periodic boundary conditions or do not exhibit explicit single-frame boundary crossings.

Instead of assuming wrapping is present in the input data, I will construct a deterministic test where a periodic box is defined and an artificial jump across the boundary is introduced between consecutive frames. This allows us to verify the intended behavior directly.

tanii1125 avatar Dec 17 '25 10:12 tanii1125

@orbeckst Without NoJump, periodic wrapping causes an artificial discontinuity; applying NoJump restores the continuous trajectory across the boundary. Figure_1

the code i used to demonstrate this --

import numpy as np
import matplotlib.pyplot as plt
import MDAnalysis as mda
from MDAnalysis.coordinates.memory import MemoryReader
from MDAnalysis.transformations import NoJump


n_atoms = 1
n_frames = 2
box_length = 10.0  # cubic box, Ã…

pos0 = np.array([[9.8, 5.0, 5.0]])

pos1 = np.array([[0.2, 5.0, 5.0]])

coords = np.array([pos0, pos1])  # shape (n_frames, n_atoms, 3)

dimensions = np.array([
    [box_length, box_length, box_length, 90, 90, 90],
    [box_length, box_length, box_length, 90, 90, 90],
])

# ----------------------------
# 2. Universe WITHOUT NoJump
# ----------------------------

u_plain = mda.Universe.empty(
    n_atoms,
    trajectory=True,
)

u_plain.load_new(
    coords,
    format=MemoryReader,
    dimensions=dimensions,
)

x_plain = [u_plain.atoms.positions[0,0] for _ in u_plain.trajectory]

# ----------------------------
# 3. Universe WITH NoJump
# ----------------------------

u_nj = mda.Universe.empty(
    n_atoms,
    trajectory=True,
)

u_nj.load_new(
    coords,
    format=MemoryReader,
    dimensions=dimensions,
)

u_nj.trajectory.add_transformations(NoJump())

x_nj = [u_nj.atoms.positions[0,0] for _ in u_nj.trajectory]

# ----------------------------
# 4. Plot
# ----------------------------

frames=[0,1]

plt.figure()
plt.plot(frames, x_plain, marker='o', label="Without nojump")
plt.plot(frames, x_nj,marker='o', label="With nojump")

plt.axhline(box_length, linestyle='--', linewidth=1)
plt.axhline(0, linestyle='--', linewidth=1)

plt.xlabel("Frame")
plt.ylabel("x position (A)")
plt.title("Effect of NoJump on Periodic Boundary Crossing")
plt.legend()
plt.show()

tanii1125 avatar Dec 17 '25 13:12 tanii1125