From 1453fb58bb0c49413c8226aeeb394f7835e0b178 Mon Sep 17 00:00:00 2001 From: Yuxuan Zhuang Date: Wed, 24 Jun 2020 21:20:06 +0200 Subject: [PATCH 1/8] enable travis temporarily --- .travis.yml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index d526eb12d93..10ac800ebef 100644 --- a/.travis.yml +++ b/.travis.yml @@ -6,7 +6,8 @@ branches: only: - master - develop - + - serialize_io + os: linux From 8a923fe75561c8b831dcbc3b61f835b026db99f5 Mon Sep 17 00:00:00 2001 From: Yuxuan Zhuang Date: Wed, 24 Jun 2020 21:24:22 +0200 Subject: [PATCH 2/8] restore travis --- .travis.yml | 1 - 1 file changed, 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index e4fa60eaef3..e14785752eb 100644 --- a/.travis.yml +++ b/.travis.yml @@ -6,7 +6,6 @@ branches: only: - master - develop - - serialize_io os: linux From 0ba02add9de575ab1e6a0b514b8032e6fa428e59 Mon Sep 17 00:00:00 2001 From: Yuxuan Zhuang Date: Thu, 2 Jul 2020 16:55:36 +0200 Subject: [PATCH 3/8] remove extra generator --- package/MDAnalysis/coordinates/chain.py | 55 +++++++++++++------------ 1 file changed, 28 insertions(+), 27 deletions(-) diff --git a/package/MDAnalysis/coordinates/chain.py b/package/MDAnalysis/coordinates/chain.py index c0c0fea3e53..c7eec5596b2 100644 --- a/package/MDAnalysis/coordinates/chain.py +++ b/package/MDAnalysis/coordinates/chain.py @@ -44,7 +44,6 @@ import warnings import os.path -import itertools import bisect import copy @@ -141,7 +140,7 @@ def filter_times(times, dt): def check_allowed_filetypes(readers, allowed): """ - Make a check that all readers have the same filetype and are of the + Make a check that all readers have the same filetype and are of the allowed files types. Throws Exception on failure. Parameters @@ -149,7 +148,7 @@ def check_allowed_filetypes(readers, allowed): readers : list of MDA readers allowed : list of allowed formats """ - classname = type(readers[0]) + classname = type(readers[0]) only_one_reader = np.all([isinstance(r, classname) for r in readers]) if not only_one_reader: readernames = [type(r) for r in readers] @@ -158,7 +157,7 @@ def check_allowed_filetypes(readers, allowed): "Found: {}".format(readernames)) if readers[0].format not in allowed: raise NotImplementedError("ChainReader: continuous=True only " - "supported for formats: {}".format(allowed)) + "supported for formats: {}".format(allowed)) class ChainReader(base.ProtoReader): @@ -263,7 +262,8 @@ def __init__(self, filenames, skip=1, dt=None, continuous=False, **kwargs): kwargs['dt'] = dt self.readers = [core.reader(filename, **kwargs) for filename in filenames] - self.filenames = np.array([fn[0] if isinstance(fn, tuple) else fn for fn in filenames]) + self.filenames = np.array([fn[0] if isinstance(fn, tuple) else fn + for fn in filenames]) # pointer to "active" trajectory index into self.readers self.__active_reader_index = 0 @@ -290,9 +290,6 @@ def __init__(self, filenames, skip=1, dt=None, continuous=False, **kwargs): self.dts = np.array(self._get('dt')) self.total_times = self.dts * n_frames - #: source for trajectories frame (fakes trajectory) - self.__chained_trajectories_iter = None - # calculate new start_frames to have a time continuous trajectory. if continuous: check_allowed_filetypes(self.readers, ['XTC', 'TRR']) @@ -346,7 +343,8 @@ def __init__(self, filenames, skip=1, dt=None, continuous=False, **kwargs): # check for interleaving r1[1] if r1_start_time < start_time < r1.time: - raise RuntimeError("ChainReader: Interleaving not supported with continuous=True.") + raise RuntimeError("ChainReader: Interleaving not supported " + "with continuous=True.") # find end where trajectory was restarted from for ts in r1[::-1]: @@ -439,8 +437,6 @@ def copy(self): new.ts = self.ts.copy() return new - - # attributes that can change with the current reader @property def filename(self): @@ -561,17 +557,12 @@ def _read_frame(self, frame): # update Timestep self.ts = self.active_reader.ts self.ts.frame = frame # continuous frames, 0-based + self._current_frame = frame return self.ts def _chained_iterator(self): """Iterator that presents itself as a chained trajectory.""" self._rewind() # must rewind all readers - for i in range(self.n_frames): - j, f = self._get_local_frame(i) - self.__activate_reader(j) - self.ts = self.active_reader[f] - self.ts.frame = i - yield self.ts def _read_next_timestep(self, ts=None): self.ts = next(self.__chained_trajectories_iter) @@ -580,30 +571,26 @@ def _read_next_timestep(self, ts=None): def rewind(self): """Set current frame to the beginning.""" self._rewind() - self.__chained_trajectories_iter = self._chained_iterator() - # set time step for frame 1 - self.ts = next(self.__chained_trajectories_iter) def _rewind(self): """Internal method: Rewind trajectories themselves and trj pointer.""" + self._current_frame = -1 self._apply('rewind') - self.__activate_reader(0) + self.__next__() def close(self): self._apply('close') def __iter__(self): - """Generator for all frames, starting at frame 1.""" - self._rewind() + """Generator for all frames, starting at frame 0.""" + self._current_frame = -1 # start from first frame - self.__chained_trajectories_iter = self._chained_iterator() - for ts in self.__chained_trajectories_iter: - yield ts + return self def __repr__(self): if len(self.filenames) > 3: fnames = "{fname} and {nfanmes} more".format( - fname=os.path.basename(self.filenames[0]), + fname=os.path.basename(self.filenames[0]), nfanmes=len(self.filenames) - 1) else: fnames = ", ".join([os.path.basename(fn) for fn in self.filenames]) @@ -656,3 +643,17 @@ def _apply_transformations(self, ts): # to avoid applying the same transformations multiple times on each frame return ts + + def __next__(self): + if self._current_frame < self.n_frames - 1: + j, f = self._get_local_frame(self._current_frame + 1) + self.__activate_reader(j) + self.ts = self.active_reader[f] + self.ts.frame = self._current_frame + 1 + self._current_frame += 1 + return self.ts + else: + raise StopIteration() + + def next(self): + return self.__next__() From 9588d88a57333279f6551a9891de1eb60f899104 Mon Sep 17 00:00:00 2001 From: Yuxuan Zhuang Date: Thu, 2 Jul 2020 17:07:30 +0200 Subject: [PATCH 4/8] legacy --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 07f8874fffe..623408a2836 100644 --- a/.travis.yml +++ b/.travis.yml @@ -6,7 +6,7 @@ branches: only: - master - develop - + os: linux From bcf944f02b4a704e54110064ac1be2ba3ff84d3f Mon Sep 17 00:00:00 2001 From: Yuxuan Zhuang Date: Thu, 2 Jul 2020 17:12:30 +0200 Subject: [PATCH 5/8] test --- testsuite/MDAnalysisTests/coordinates/test_chainreader.py | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/testsuite/MDAnalysisTests/coordinates/test_chainreader.py b/testsuite/MDAnalysisTests/coordinates/test_chainreader.py index c8d1f9e4b48..27d6989763d 100644 --- a/testsuite/MDAnalysisTests/coordinates/test_chainreader.py +++ b/testsuite/MDAnalysisTests/coordinates/test_chainreader.py @@ -96,6 +96,11 @@ def test_frame_numbering(self, universe): universe.trajectory[98] # index is 0-based and frames are 0-based assert_equal(universe.trajectory.frame, 98, "wrong frame number") + def test_next_after_frame_numbering(self, universe): + universe.trajectory[98] # index is 0-based and frames are 0-based + universe.trajectory.next() + assert_equal(universe.trajectory.frame, 99, "wrong frame number") + def test_frame(self, universe): universe.trajectory[0] coord0 = universe.atoms.positions.copy() From 44a8cf4de8907a73893bc98889bd7e51e3443a52 Mon Sep 17 00:00:00 2001 From: Yuxuan Zhuang Date: Thu, 2 Jul 2020 20:51:54 +0200 Subject: [PATCH 6/8] remove legacy code --- package/MDAnalysis/coordinates/chain.py | 13 ++++--------- 1 file changed, 4 insertions(+), 9 deletions(-) diff --git a/package/MDAnalysis/coordinates/chain.py b/package/MDAnalysis/coordinates/chain.py index c7eec5596b2..b3f49daa1ef 100644 --- a/package/MDAnalysis/coordinates/chain.py +++ b/package/MDAnalysis/coordinates/chain.py @@ -38,7 +38,6 @@ .. automethod:: _get .. automethod:: _get_same .. automethod:: _read_frame - .. automethod:: _chained_iterator """ import warnings @@ -560,13 +559,12 @@ def _read_frame(self, frame): self._current_frame = frame return self.ts - def _chained_iterator(self): - """Iterator that presents itself as a chained trajectory.""" - self._rewind() # must rewind all readers def _read_next_timestep(self, ts=None): - self.ts = next(self.__chained_trajectories_iter) - return self.ts + if ts is None: + ts = self.ts + ts = self.__next__() + return ts def rewind(self): """Set current frame to the beginning.""" @@ -654,6 +652,3 @@ def __next__(self): return self.ts else: raise StopIteration() - - def next(self): - return self.__next__() From a586c3904110a60e39097d6613f4822283ca5797 Mon Sep 17 00:00:00 2001 From: Yuxuan Zhuang Date: Thu, 2 Jul 2020 20:54:02 +0200 Subject: [PATCH 7/8] make _current_frame private --- package/MDAnalysis/coordinates/chain.py | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/package/MDAnalysis/coordinates/chain.py b/package/MDAnalysis/coordinates/chain.py index b3f49daa1ef..d76f34a1140 100644 --- a/package/MDAnalysis/coordinates/chain.py +++ b/package/MDAnalysis/coordinates/chain.py @@ -556,7 +556,7 @@ def _read_frame(self, frame): # update Timestep self.ts = self.active_reader.ts self.ts.frame = frame # continuous frames, 0-based - self._current_frame = frame + self.__current_frame = frame return self.ts @@ -572,7 +572,7 @@ def rewind(self): def _rewind(self): """Internal method: Rewind trajectories themselves and trj pointer.""" - self._current_frame = -1 + self.__current_frame = -1 self._apply('rewind') self.__next__() @@ -581,7 +581,7 @@ def close(self): def __iter__(self): """Generator for all frames, starting at frame 0.""" - self._current_frame = -1 + self.__current_frame = -1 # start from first frame return self @@ -643,12 +643,12 @@ def _apply_transformations(self, ts): return ts def __next__(self): - if self._current_frame < self.n_frames - 1: - j, f = self._get_local_frame(self._current_frame + 1) + if self.__current_frame < self.n_frames - 1: + j, f = self._get_local_frame(self.__current_frame + 1) self.__activate_reader(j) self.ts = self.active_reader[f] - self.ts.frame = self._current_frame + 1 - self._current_frame += 1 + self.ts.frame = self.__current_frame + 1 + self.__current_frame += 1 return self.ts else: raise StopIteration() From 6ae2b68ea13d33ef7036c1728abfd7ee8f57d1d3 Mon Sep 17 00:00:00 2001 From: Yuxuan Zhuang Date: Thu, 2 Jul 2020 21:00:16 +0200 Subject: [PATCH 8/8] changelog --- package/CHANGELOG | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/package/CHANGELOG b/package/CHANGELOG index ded76760b0d..1ef09f5f0f4 100644 --- a/package/CHANGELOG +++ b/package/CHANGELOG @@ -14,7 +14,7 @@ The rules for this file: ------------------------------------------------------------------------------ ??/??/?? richardjgowers, IAlibay, hmacdope, orbeckst, cbouy, lilyminium, - daveminh + daveminh, yuxuanzhuang * 2.0.0 @@ -24,6 +24,8 @@ Fixes * TOPParser no longer guesses elements when missing atomic number records (Issues #2449, #2651) * Testsuite does not any more matplotlib.use('agg') (#2191) + * In ChainReader, read_frame does not trigger change of iterating position. + (Issue #2723, PR #2815) Enhancements * Added the RDKitParser which creates a `core.topology.Topology` object from