Skip to content

Commit

Permalink
Speed up operations that use the Coord.cells method for time coordi…
Browse files Browse the repository at this point in the history
…nates (#4969)

* Convert all time points at once before generating cells

* Small simplification

* Add a whatnew entry

* Fix link

Co-authored-by: Martin Yeo <40734014+trexfeathers@users.noreply.github.com>

Co-authored-by: Martin Yeo <40734014+trexfeathers@users.noreply.github.com>
  • Loading branch information
bouweandela and trexfeathers authored Sep 29, 2022
1 parent f69b93f commit 2742211
Show file tree
Hide file tree
Showing 2 changed files with 20 additions and 17 deletions.
4 changes: 4 additions & 0 deletions docs/src/whatsnew/latest.rst
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,10 @@ This document explains the changes made to Iris for this release
:obj:`~iris.analysis.SUM`, :obj:`~iris.analysis.COUNT` and
:obj:`~iris.analysis.PROPORTION` on real data. (:pull:`4905`)

#. `@bouweandela`_ made :meth:`iris.coords.Coord.cells` faster for time
coordinates. This also affects :meth:`iris.cube.Cube.extract`,
:meth:`iris.cube.Cube.subset`, and :meth:`iris.coords.Coord.intersect`.
(:pull:`4969`)

🔥 Deprecations
===============
Expand Down
33 changes: 16 additions & 17 deletions lib/iris/coords.py
Original file line number Diff line number Diff line change
Expand Up @@ -1895,7 +1895,22 @@ def cells(self):
...
"""
return _CellIterator(self)
if self.ndim != 1:
raise iris.exceptions.CoordinateMultiDimError(self)

points = self.points
bounds = self.bounds
if self.units.is_time_reference():
points = self.units.num2date(points)
if self.has_bounds():
bounds = self.units.num2date(bounds)

if self.has_bounds():
for point, bound in zip(points, bounds):
yield Cell(point, bound)
else:
for point in points:
yield Cell(point)

def _sanity_check_bounds(self):
if self.ndim == 1:
Expand Down Expand Up @@ -3137,22 +3152,6 @@ def xml_element(self, doc):
return cellMethod_xml_element


# See Coord.cells() for the description/context.
class _CellIterator(Iterator):
def __init__(self, coord):
self._coord = coord
if coord.ndim != 1:
raise iris.exceptions.CoordinateMultiDimError(coord)
self._indices = iter(range(coord.shape[0]))

def __next__(self):
# NB. When self._indices runs out it will raise StopIteration for us.
i = next(self._indices)
return self._coord.cell(i)

next = __next__


# See ExplicitCoord._group() for the description/context.
class _GroupIterator(Iterator):
def __init__(self, points):
Expand Down

0 comments on commit 2742211

Please sign in to comment.