Skip to content

Commit a3f722e

Browse files
authored
Merge branch 'develop' into fix/replace-numpy-asserts
2 parents 32ad2ef + 9cbc8ea commit a3f722e

8 files changed

Lines changed: 82 additions & 14 deletions

File tree

.github/workflows/deploy.yaml

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,6 @@ jobs:
3838
matrix:
3939
buildplat:
4040
- [ubuntu-22.04, manylinux_x86_64, x86_64]
41-
- [macos-13, macosx_*, x86_64]
4241
- [windows-2022, win_amd64, AMD64]
4342
- [macos-14, macosx_*, arm64]
4443
python: ["cp311", "cp312", "cp313", "cp314"]

.github/workflows/gh-ci-cron.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -140,7 +140,7 @@ jobs:
140140
strategy:
141141
fail-fast: false
142142
matrix:
143-
os: [ubuntu-22.04, macos-13]
143+
os: [ubuntu-22.04, macos-14]
144144

145145
steps:
146146
- uses: actions/checkout@v4

package/CHANGELOG

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,11 +15,15 @@ The rules for this file:
1515

1616
-------------------------------------------------------------------------------
1717
??/??/?? IAlibay, orbeckst, marinegor, tylerjereddy, ljwoods2, marinegor,
18-
spyke7, talagayev, tanii1125
18+
spyke7, talagayev, tanii1125, BradyAJohnston
1919

2020
* 2.11.0
2121

2222
Fixes
23+
* HydrogenBondAnalysis: Fixed `count_by_time()` when using `run(FrameIterator)` that
24+
results in `self.start` and `self.end` being None (Issue #5200, PR #5202)
25+
* NoJump shows a more informative message and fails when applied
26+
outside of the first frame (Issue #4915, PR #5201)
2327
* DSSP now explicitly checks for a minimum of 6 residues and raises a clear
2428
error message, unlike the previous behavior where it would fail with an
2529
incomprehensible broadcasting error at execution time (Issue #5046, PR #5163)

package/MDAnalysis/analysis/hydrogenbonds/hbond_analysis.py

Lines changed: 6 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -911,17 +911,13 @@ def count_by_time(self):
911911
Can be used along with :attr:`HydrogenBondAnalysis.times` to plot
912912
the number of hydrogen bonds over time.
913913
"""
914+
hbond_frames = self.results.hbonds[:, 0].astype(int)
915+
frame_unique, frame_counts = np.unique(hbond_frames, return_counts=True)
916+
frame_min, frame_max = self.frames.min(), self.frames.max()
914917

915-
indices, tmp_counts = np.unique(self.results.hbonds[:, 0], axis=0,
916-
return_counts=True)
917-
918-
indices -= self.start
919-
indices /= self.step
920-
921-
counts = np.zeros_like(self.frames)
922-
counts[indices.astype(np.intp)] = tmp_counts
923-
924-
return counts
918+
counts = np.zeros(frame_max - frame_min + 1, dtype=int)
919+
counts[frame_unique - frame_min] = frame_counts
920+
return counts[self.frames - frame_min]
925921

926922
def count_by_type(self):
927923
"""Counts the total number of each unique type of hydrogen bond.

package/MDAnalysis/analysis/msd.py

Lines changed: 28 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -70,7 +70,34 @@
7070
7171
In MDAnalysis you can use the
7272
:class:`~MDAnalysis.transformations.nojump.NoJump`
73-
transformation.
73+
transformation to unwrap coordinates on-the-fly.
74+
75+
A minimal example:
76+
77+
.. code-block:: python
78+
79+
import MDAnalysis as mda
80+
from MDAnalysis.transformations import NoJump
81+
82+
u = mda.Universe(TOP, TRAJ)
83+
84+
# Apply NoJump transformation to unwrap coordinates
85+
u.trajectory.add_transformations(NoJump(u))
86+
87+
# Now the trajectory is unwrapped and MSD can be computed normally:
88+
from MDAnalysis.analysis.msd import EinsteinMSD
89+
MSD = EinsteinMSD(u, select="all", msd_type="xyz")
90+
MSD.run()
91+
92+
This example assumes that the trajectory contains periodic box
93+
dimensions. If no periodic boundary information is present, box
94+
dimensions must be defined before applying ``NoJump``, which can
95+
be accomplished by applying the
96+
:class:`~MDAnalysis.transformations.boxdimensions.set_dimensions`
97+
transformation *before* the
98+
:class:`~MDAnalysis.transformations.nojump.NoJump` transformation.
99+
100+
This replaces the need to preprocess trajectories externally.
74101
75102
In GROMACS, for example, this can be done using `gmx trjconv`_ with the
76103
``-pbc nojump`` flag.

package/MDAnalysis/transformations/nojump.py

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -118,6 +118,13 @@ def _transform(self, ts):
118118
except np.linalg.LinAlgError:
119119
msg = f"Periodic box dimensions are not invertible at step {ts.frame}"
120120
raise NoDataError(msg)
121+
122+
if self.prev is None and ts.frame != 0:
123+
raise ValueError(
124+
"NoJump transformation must be applied starting from frame 0. "
125+
f"Currently at frame {ts.frame}. Please reset trajectory to frame 0 before adding this transformation."
126+
)
127+
121128
if ts.frame == 0:
122129
# We don't need to apply the transformation here. However, we need to
123130
# ensure we have the 0th frame coordinates in reduced form. We also need to

testsuite/MDAnalysisTests/analysis/test_hydrogenbonds_analysis.py

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -760,3 +760,23 @@ def test_hbond_analysis(self, universe, client_HydrogenBondAnalysis):
760760
assert h.hydrogens_sel == ""
761761
assert h.acceptors_sel == ""
762762
assert h.results.hbonds.size == 0
763+
764+
765+
class TestHydrogenBondAnalysisFrameIterator:
766+
@staticmethod
767+
@pytest.fixture(scope="class")
768+
def universe():
769+
return MDAnalysis.Universe(waterPSF, waterDCD)
770+
771+
def test_frame_iterator(self, universe):
772+
frames = np.array([0, 1, 2, 5, 6, 7, 8])
773+
hbonds = HydrogenBondAnalysis(
774+
universe=universe,
775+
hydrogens_sel="name H1 H2",
776+
acceptors_sel="name OH2",
777+
update_selections=False,
778+
)
779+
hbonds.run(frames=frames)
780+
assert np.array_equal(
781+
hbonds.count_by_time(), np.array([2, 1, 4, 3, 3, 2, 2])
782+
)

testsuite/MDAnalysisTests/transformations/test_nojump.py

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -379,3 +379,18 @@ def test_notinvertible(nojump_universe):
379379
]
380380
u.trajectory.add_transformations(*workflow)
381381
transformed_coordinates = u.trajectory.timeseries()[0]
382+
383+
384+
@pytest.mark.parametrize("frame_index", [-1, 5])
385+
def test_nojump_fails_when_not_at_frame_0(frame_index):
386+
"""
387+
Test that NoJump raises a clear error when applied to a trajectory
388+
that is not at frame 0.
389+
"""
390+
u = mda.Universe(data.PSF_TRICLINIC, data.DCD_TRICLINIC)
391+
u.trajectory[frame_index]
392+
393+
with pytest.raises(
394+
ValueError, match="must be applied starting from frame 0"
395+
):
396+
u.trajectory.add_transformations(NoJump())

0 commit comments

Comments
 (0)