Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ChainedReader __repr__ fix for MemoryReader sub-readers #4407

Merged
merged 11 commits into from
Feb 12, 2024
4 changes: 3 additions & 1 deletion package/CHANGELOG
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ The rules for this file:


-------------------------------------------------------------------------------
??/??/?? IAlibay, HeetVekariya, marinegor, lilyminium
??/??/?? IAlibay, HeetVekariya, marinegor, lilyminium, ljwoods2

* 2.8.0

Expand All @@ -25,6 +25,8 @@ Fixes
`DistanceMatrix.run(frames=...)` (PR #4433)
* Fix doctest errors of lib/picklable_file_io.py (Issue #3925, PR #4371)
* Fix deploy action to use the correct version of the pypi upload action.
* Fix ChainReader `__repr__()` method when sub-reader is MemoryReader
ljwoods2 marked this conversation as resolved.
Show resolved Hide resolved
(Issue #3349, PR #4407)

Enhancements

Expand Down
24 changes: 18 additions & 6 deletions package/MDAnalysis/coordinates/chain.py
Original file line number Diff line number Diff line change
Expand Up @@ -269,8 +269,17 @@ def __init__(self, filenames, skip=1, dt=None, continuous=False,
kwargs['dt'] = dt
self.readers = [core.reader(filename, convert_units=convert_units, **kwargs)
for filename in filenames]
self.filenames = np.array([fn[0] if isinstance(fn, tuple) else fn
for fn in filenames])
# Iterate through all filenames, appending NoneType None for ndarrays
self.filenames = []
for fn in filenames:
if isinstance(fn, np.ndarray):
self.filenames.append(None)
elif isinstance(fn, tuple):
self.filenames.append(fn[0])
else:
self.filenames.append(fn)
self.filenames = np.array(self.filenames)

# pointer to "active" trajectory index into self.readers
self.__active_reader_index = 0

Expand Down Expand Up @@ -598,11 +607,14 @@ def close(self):

def __repr__(self):
if len(self.filenames) > 3:
fnames = "{fname} and {nfanmes} more".format(
fname=os.path.basename(self.filenames[0]),
nfanmes=len(self.filenames) - 1)
fname = (os.path.basename(self.filenames[0])
if self.filenames[0] else "numpy.ndarray")
fnames = "{fname} and {nfnames} more".format(
fname=fname,
nfnames=len(self.filenames) - 1)
else:
fnames = ", ".join([os.path.basename(fn) for fn in self.filenames])
fnames = ", ".join([os.path.basename(fn) if fn else "numpy.ndarray"
for fn in self.filenames])
return ("<{clsname} containing {fname} with {nframes} frames of {natoms} atoms>"
"".format(
clsname=self.__class__.__name__,
Expand Down
19 changes: 19 additions & 0 deletions testsuite/MDAnalysisTests/coordinates/test_chainreader.py
Original file line number Diff line number Diff line change
Expand Up @@ -455,3 +455,22 @@ def wrapped(ts):
# in the issue report values of ~25 were seen before the fix
# with the fix all values should be <1e-6
assert np.abs(com).max() < 1e-6


def test_issue_3349():
# test for repr of a chainreader when the subreaders are memoryreaders
cdx = np.random.random(3341 * 3 * 10)
cdx = cdx.reshape(-1, 3341, 3).astype(np.float32) * 10
u = mda.Universe(PSF, (cdx, DCD))
u2 = mda.Universe(PSF, (cdx, cdx, cdx, DCD))
u_expected_filenames = np.array([None, str(DCD)])
u2_expected_filenames = np.array([None, None, None, str(DCD)])

assert_equal("<ChainReader containing numpy.ndarray, adk_dims.dcd with " +
"108 frames of 3341 atoms>",
u.trajectory.__repr__())
assert_equal(u_expected_filenames, u.trajectory.filenames)
assert_equal("<ChainReader containing numpy.ndarray and 3 more with " +
"128 frames of 3341 atoms>",
u2.trajectory.__repr__())
assert_equal(u2_expected_filenames, u2.trajectory.filenames)
Loading