Skip to content
1 change: 1 addition & 0 deletions package/AUTHORS
Original file line number Diff line number Diff line change
Expand Up @@ -277,6 +277,7 @@ Chronological list of authors
- Ayush Agarwal
- Parth Uppal
- Olivier Languin--Cattoën
- Charity Grey

External code
-------------
Expand Down
3 changes: 2 additions & 1 deletion package/CHANGELOG
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ The rules for this file:
* 2.11.0

Fixes
* `MDAnalysis.analysis.atomicdistances.AtomicDistances` results are now consistent with expected `analysis` documentation data type = Results (Issue #4819, PR #5347) Note: This fix is backwards-incompatible.
* Fix mixed-case atom types in guess_bonds (Issue #5342, PR #5343)
* Fixes msd for non-linear frames, when non_linear is not explicitly
provided (Issue #5100, PR #5254)
Expand All @@ -38,7 +39,7 @@ Fixes
incomprehensible broadcasting error at execution time (Issue #5046, PR #5163)
* Fixes the verbose=False in EinsteinMSD, and only shows progress bar when
verbose=True (Issue #5144, PR #5153)
* Fix incorrect assignment of topology_format to format (and vice versa)
* Fix incorrect assignment of topology_format to format (and vexice versa)
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not sure why this is changed.

when a parsing class is provided to either (Issue #5147, PR #5148)
* Fix incorrect TPR file parsing for GROMACS topologies produced prior
to version 5.1.0 (Issue #5145, PR #5146)
Expand Down
25 changes: 19 additions & 6 deletions package/MDAnalysis/analysis/atomicdistances.py
Original file line number Diff line number Diff line change
Expand Up @@ -74,10 +74,10 @@
>>> ag2 = u.atoms[4000:4005]

We can run the calculations using any variable of choice such as
``my_dists`` and access our results using ``my_dists.results``: ::
``my_dists`` and access our results using ``my_dists.results.distances``: ::

>>> my_dists = ad.AtomicDistances(ag1, ag2).run()
>>> my_dists.results
>>> my_dists.results.distances
array([[37.80813681, 33.2594864 , 34.93676414, 34.51183299, 34.96340209],
[27.11746625, 31.19878079, 31.69439435, 32.63446126, 33.10451345],
[23.27210749, 30.38714688, 32.48269361, 31.91444505, 31.84583838],
Expand All @@ -94,7 +94,7 @@
in this case: ::

>>> my_dists_nopbc = ad.AtomicDistances(ag1, ag2, pbc=False).run()
>>> my_dists_nopbc.results
>>> my_dists_nopbc.results.distances
array([[37.80813681, 33.2594864 , 34.93676414, 34.51183299, 34.96340209],
[27.11746625, 31.19878079, 31.69439435, 32.63446126, 33.10451345],
[23.27210749, 30.38714688, 32.482695 , 31.91444505, 31.84583838],
Expand All @@ -108,9 +108,13 @@

"""


import numpy as np

from MDAnalysis.lib.distances import calc_bonds
from MDAnalysis.analysis.results import (
Copy link
Copy Markdown
Contributor

@jeremyleung521 jeremyleung521 Apr 10, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could probably remove the comma and parenthesis to truncate into one line

Results,
)

import logging
from .base import AnalysisBase
Expand All @@ -134,7 +138,7 @@ class AtomicDistances(AnalysisBase):

Attributes
----------
results : :class:`numpy.ndarray`
results.distances : :class:`numpy.ndarray`
The distances :math:`|ag1[i] - ag2[i]|` for all :math:`i`
from :math:`0` to `n_atoms` :math:`- 1` for each frame over
the trajectory.
Expand All @@ -145,6 +149,14 @@ class AtomicDistances(AnalysisBase):


.. versionadded:: 2.5.0
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

do not remove any of the versionchanged/versionadded; just add the new one below

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

and do not remove empty lines – they are necessary for the proper formatting

.. versionchanged:: 2.11.0
Distance data are now made available in :attr:`results.distances` instead
of :attr:`results` and :attr:`results` is now a
:class:`~MDAnalysis.analysis.results.Results` instance; this fixes an API issue
(see `Issue #4819`_) in a *backwards-incompatible* manner.

.. _Issue #4819`: https://github.com/MDAnalysis/mdanalysis/issues/4819

"""

def __init__(self, ag1, ag2, pbc=True, **kwargs):
Expand All @@ -167,11 +179,12 @@ def __init__(self, ag1, ag2, pbc=True, **kwargs):

def _prepare(self):
# initialize NumPy array of frames x distances for results
self.results = np.zeros((self.n_frames, self._ag1.atoms.n_atoms))
distances = np.zeros((self.n_frames, self._ag1.atoms.n_atoms))
self.results = Results(distances=distances)

def _single_frame(self):
# if PBCs considered, get box size
box = self._ag1.dimensions if self._pbc else None
self.results[self._frame_index] = calc_bonds(
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

https://github.com/MDAnalysis/mdanalysis/actions/runs/23987727902/job/69962349164?pr=5347#step:8:518

Tests show that an all zeros array is passed back in both tests, suggesting the actual numbers/results are not saved properly into the Results object. This is the most important part of the PR(!) so please triple check.

self._ag1.positions, self._ag2.positions, box
)
)
11 changes: 8 additions & 3 deletions testsuite/MDAnalysisTests/analysis/test_atomicdistances.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
import MDAnalysis.analysis.atomicdistances as ad
from MDAnalysis.lib.distances import calc_bonds
import MDAnalysis.transformations.boxdimensions as bd
from MDAnalysis.analysis.results import Results

from numpy.testing import assert_allclose
import numpy as np
Expand Down Expand Up @@ -121,15 +122,19 @@ def test_ad_pairwise_dist(self, ad_ag1, ad_ag2, expected_dist):
correctly calculated without PBCs."""
pairwise_no_pbc = ad.AtomicDistances(ad_ag1, ad_ag2, pbc=False).run()
actual = pairwise_no_pbc.results

assert isinstance(actual, Results)

distances = actual.distances
# compare with expected values from dist()
assert_allclose(actual, expected_dist)
assert_allclose(distances, expected_dist)

def test_ad_pairwise_dist_pbc(self, ad_ag1, ad_ag2, expected_pbc_dist):
"""Ensure that pairwise distances between atoms are
correctly calculated with PBCs."""
pairwise_pbc = ad.AtomicDistances(ad_ag1, ad_ag2).run()
actual = pairwise_pbc.results
assert isinstance(actual, Results)

distances = actual.distances
# compare with expected values from dist()
assert_allclose(actual, expected_pbc_dist)
assert_allclose(distances, expected_pbc_dist)
Loading