Skip to content

Fix XTCReader and TRRReader frame navigation when sub is set - #5308

Open
xovishnukosuri wants to merge 1 commit into
MDAnalysis:developfrom
xovishnukosuri:fix-sub-xdr-reader
Open

xovishnukosuri wants to merge 1 commit into
MDAnalysis:developfrom
xovishnukosuri:fix-sub-xdr-reader

Conversation

@xovishnukosuri

Copy link
Copy Markdown

Fixes #4116

Changes

When XTCReader or TRRReader is initialized with the sub keyword, _read_next_timestep called read_direct_x / read_direct_xvf and passed ts.positions (sized len(sub)) as the write buffer. The underlying C read_xtc / read_trr function wrote n_atoms values into that smaller buffer, causing memory corruption or a TypeError when navigating to any frame beyond frame 0.

Root cause: read_direct_x and read_direct_xvf use the passed array as a Cython typed memview (cnp.float32_t[:, ::1]). Fancy numpy indexing does not work on typed memviews, and the buffer size does not match n_atoms.

Fix: Skip the direct-read optimization when self._sub is not None. Use the regular read() instead, which allocates a full-atom numpy ndarray. _frame_to_ts then indexes frame.x[self._sub] with a regular numpy fancy index, which works correctly.

The fast read_direct_x / read_direct_xvf path is preserved for the normal (non-sub) case.

Added test: test_sub_frame_navigation iterates over all frames using direct index access (trajectory[i]) with sub active and compares positions against the reference solvated universe. The existing test_sub_coordinates only checked frame 0 and did not catch the regression.

LLM / AI generated code disclosure

LLMs or other AI-powered tools (beyond simple IDE use cases) were used in this contribution: yes
(Claude by Anthropic was used to help identify and structure the fix.)

PR Checklist

  • Issue raised/referenced?
  • Tests updated/added?
  • Documentation updated/added? (no doc change needed)
  • package/CHANGELOG file updated?
  • Is your name in package/AUTHORS?
  • LLM/AI disclosure was updated.

Developers Certificate of Origin

I certify that I can submit this code contribution as described in the Developer Certificate of Origin, under the MDAnalysis LICENSE.

When XTCReader or TRRReader is initialized with the sub keyword,
_read_next_timestep used read_direct_x / read_direct_xvf and passed
ts.positions (sized len(sub)) as the write buffer. The underlying C
call wrote n_atoms values into that smaller buffer, corrupting memory
or raising a TypeError on the second and later frames.

The fix skips the direct-read path when _sub is not None and falls back
to the regular read(), which allocates a full-atom array. _frame_to_ts
then correctly indexes frame.x with self._sub (a numpy array) to fill
ts.positions. A new test covers direct frame indexing across all frames
with sub active.

Fixes MDAnalysis#4116

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant