diff --git a/package/CHANGELOG b/package/CHANGELOG index 8edb21f16e8..26b12359385 100644 --- a/package/CHANGELOG +++ b/package/CHANGELOG @@ -33,6 +33,8 @@ The rules for this file: * Removed FormatError, now replaced by ValueError * distances.contact_matrix(): changed keyword 'suppress_progmet' to 'quiet' + * base.Reader now defines __iter__ + * __iter__ removed from many Readers (now use base.Reader implementation) Fixes * analysis.hbonds.HydrogenBondAnalysis performs a sanity check for diff --git a/package/MDAnalysis/coordinates/DCD.py b/package/MDAnalysis/coordinates/DCD.py index b8b8aff6f8f..1d50e7d1b8b 100644 --- a/package/MDAnalysis/coordinates/DCD.py +++ b/package/MDAnalysis/coordinates/DCD.py @@ -462,20 +462,9 @@ def _dcd_header(self): 'charmm', 'first', 'with_unitcell'] return dict(zip(desc, struct.unpack("LLiiiiidiPPiiii", self._dcd_C_str))) - def __iter__(self): - # Reset the trajectory file, read from the start - # usage is "from ts in dcd:" where dcd does not have indexes + def _reopen(self): self._reset_dcd_read() - def iterDCD(): - for i in xrange(0, self.numframes, self.skip): # FIXME: skip is not working!!! - try: - yield self._read_next_timestep() - except IOError: - raise StopIteration - - return iterDCD() - def _read_next_timestep(self, ts=None): if ts is None: ts = self.ts diff --git a/package/MDAnalysis/coordinates/DLPoly.py b/package/MDAnalysis/coordinates/DLPoly.py index 1c8354a1f86..3a2c1cc32ba 100644 --- a/package/MDAnalysis/coordinates/DLPoly.py +++ b/package/MDAnalysis/coordinates/DLPoly.py @@ -260,15 +260,6 @@ def _read_numframes(self): return numframes - def __iter__(self): - self._reopen() - while True: - try: - yield self._read_next_timestep() - except IOError: - self.rewind() - raise StopIteration - def rewind(self): self._reopen() self.next() diff --git a/package/MDAnalysis/coordinates/GMS.py b/package/MDAnalysis/coordinates/GMS.py index ecd660009d7..31be545a4fa 100644 --- a/package/MDAnalysis/coordinates/GMS.py +++ b/package/MDAnalysis/coordinates/GMS.py @@ -165,16 +165,6 @@ def _read_out_numframes(self, filename): self.close() return int(counter) - def __iter__(self): - self.ts.frame = 0 # start at 0 so that the first frame becomes 1 - self._reopen() - while True: - try: - yield self._read_next_timestep() - except EOFError: - self.close() - raise StopIteration - def _read_next_timestep(self, ts=None): # check that the timestep object exists if ts is None: diff --git a/package/MDAnalysis/coordinates/MOL2.py b/package/MDAnalysis/coordinates/MOL2.py index 9f122e3b3a1..9566d330fe3 100644 --- a/package/MDAnalysis/coordinates/MOL2.py +++ b/package/MDAnalysis/coordinates/MOL2.py @@ -96,13 +96,6 @@ def __init__(self, filename, convert_units=None, **kwargs): self.delta = 0 self.skip_timestep = 1 - def __iter__(self): - for i in xrange(0, self.numframes): - try: - yield self._read_frame(i) - except IOError: - raise StopIteration - def parse_block(self, block): sections = {} cursor = None diff --git a/package/MDAnalysis/coordinates/PDB.py b/package/MDAnalysis/coordinates/PDB.py index 12a3cbaea4a..fa7ea0f8bf2 100644 --- a/package/MDAnalysis/coordinates/PDB.py +++ b/package/MDAnalysis/coordinates/PDB.py @@ -551,12 +551,13 @@ def Writer(self, filename, **kwargs): kwargs.setdefault('multiframe', self.numframes > 1) return PrimitivePDBWriter(filename, **kwargs) - def __iter__(self): - for i in xrange(0, self.numframes): - try: - yield self._read_frame(i) - except IOError: - raise StopIteration + def rewind(self): + self._read_frame(0) + + def _reopen(self): + # Pretend the current TS is 0 (in 1 based) so "next" is the + # first frame + self.ts.frame = 0 def _read_next_timestep(self, ts=None): if ts is None: @@ -571,8 +572,6 @@ def _read_next_timestep(self, ts=None): return self._read_frame(frame) def _read_frame(self, frame): - if numpy.dtype(type(frame)) != numpy.dtype(int): - raise TypeError("frame must be a integer") # Assume _read_frame is passed a 0-based frame number. Convert this to # 1-based. frame += 1 diff --git a/package/MDAnalysis/coordinates/TRJ.py b/package/MDAnalysis/coordinates/TRJ.py index ac324e4ede6..7acfecc1682 100644 --- a/package/MDAnalysis/coordinates/TRJ.py +++ b/package/MDAnalysis/coordinates/TRJ.py @@ -109,9 +109,6 @@ .. autoclass:: NCDFReader :members: - .. automethod:: __getitem__ - .. automethod:: __iter__ - .. autoclass:: NCDFWriter :members: @@ -369,15 +366,6 @@ def rewind(self): self._reopen() self.next() - def __iter__(self): - self._reopen() - while True: - try: - yield self._read_next_timestep() - except EOFError: - self.rewind() - raise StopIteration - class NCDFReader(base.Reader): """Reader for `AMBER NETCDF format`_ (version 1.0). @@ -536,6 +524,9 @@ def _read_frame(self, frame): self._current_frame = frame return ts + def _reopen(self): + self._current_frame = -1 + def _read_next_timestep(self, ts=None): if ts is None: ts = self.ts @@ -544,21 +535,6 @@ def _read_next_timestep(self, ts=None): except IndexError: raise IOError - def _sliced_iter(self, start, stop, step): - def iterNETCDF(start=start, stop=stop, step=step): - for i in xrange(start, stop, step): - yield self._read_frame(i) - - return iterNETCDF() - - def __iter__(self): - """Iterate over the whole trajectory""" - for i in xrange(0, self.numframes): - try: - yield self._read_frame(i) - except IndexError: - raise StopIteration - def close(self): """Close trajectory; any further access will raise an :exc:`IOError`""" if not self.trjfile is None: diff --git a/package/MDAnalysis/coordinates/TRZ.py b/package/MDAnalysis/coordinates/TRZ.py index cc2f09376fc..d01405d58f5 100644 --- a/package/MDAnalysis/coordinates/TRZ.py +++ b/package/MDAnalysis/coordinates/TRZ.py @@ -341,15 +341,6 @@ def skip_timestep(self): self.rewind() return self._skip_timestep - def __iter__(self): - self._reopen() - while True: - try: - yield self._read_next_timestep() - except IOError: - self.rewind() - raise StopIteration - # can use base.Reader __getitem__ implementation def _read_frame(self, frame): """Move to *frame* and fill timestep with data.""" diff --git a/package/MDAnalysis/coordinates/XYZ.py b/package/MDAnalysis/coordinates/XYZ.py index 60f014c4daf..eb741088436 100644 --- a/package/MDAnalysis/coordinates/XYZ.py +++ b/package/MDAnalysis/coordinates/XYZ.py @@ -315,16 +315,6 @@ def _read_xyz_numframes(self, filename): numframes = int(counter / linesPerFrame) return numframes - def __iter__(self): - self.ts.frame = 0 # start at 0 so that the first frame becomes 1 - self._reopen() - while True: - try: - yield self._read_next_timestep() - except EOFError: - self.close() - raise StopIteration - def _read_next_timestep(self, ts=None): # check that the timestep object exists if ts is None: diff --git a/package/MDAnalysis/coordinates/base.py b/package/MDAnalysis/coordinates/base.py index 2cff26cc3f9..e60e946aec1 100644 --- a/package/MDAnalysis/coordinates/base.py +++ b/package/MDAnalysis/coordinates/base.py @@ -622,7 +622,8 @@ def next(self): def rewind(self): """Position at beginning of trajectory""" - self[0] + self._reopen() + self.next() @property def dt(self): @@ -689,7 +690,20 @@ def __del__(self): self.close() def __iter__(self): - raise NotImplementedError("BUG: Override __iter__() in the trajectory reader (%s)!" % type(self)) + self._reopen() + while True: + try: + yield self._read_next_timestep() + except (EOFError, IOError): + self.rewind() + raise StopIteration + + def _reopen(self): + """Should position Reader to just before first frame + + Calling next after this should return the first frame + """ + pass def __getitem__(self, frame): """Return the Timestep corresponding to *frame*. @@ -742,7 +756,7 @@ def _sliced_iter(self, start, stop, step): def _iter(start=start, stop=stop, step=step): try: for i in xrange(start, stop, step): - yield self[i] + yield self._read_frame(i) except TypeError: # if _read_frame not implemented raise TypeError("{0} does not support slicing." "".format(self.__class__.__name__)) @@ -1172,6 +1186,12 @@ def _read_first_frame(self): # Override this in subclasses to create and fill a Timestep pass + def rewind(self): + pass + + def _reopen(self): + pass + def next(self): raise IOError(self._err.format(self.__class__.__name__)) diff --git a/package/MDAnalysis/coordinates/xdrfile/core.py b/package/MDAnalysis/coordinates/xdrfile/core.py index edd9d778f39..4ae28b40641 100644 --- a/package/MDAnalysis/coordinates/xdrfile/core.py +++ b/package/MDAnalysis/coordinates/xdrfile/core.py @@ -718,11 +718,6 @@ def __iter__(self): else: yield ts - def rewind(self): - """Position at beginning of trajectory""" - self._reopen() - self.next() # read first frame - def _reopen(self): self.close() self.open_trajectory() @@ -744,19 +739,6 @@ def _read_frame(self, frame): # Renamed this once upon a time. _goto_frame = _read_frame - def _sliced_iter(self, start, stop, step): - def _iter(start=start, stop=stop, step=step): - if step == 1: - rng = xrange(start + 1, stop, step) - yield self._read_frame(start) - for framenr in rng: - yield self._read_frame(framenr) - else: - rng = xrange(start, stop, step) - for framenr in rng: - yield self._read_frame(framenr) - return _iter() - def timeseries(self, asel, start=0, stop=-1, skip=1, format='afc'): raise NotImplementedError("timeseries not available for Gromacs trajectories")