Skip to content

Commit e4ea7a2

Browse files
committed
Fix Cube.rolling_window with lazy auxiliary coordinates
rolling_window built each window's coordinate bounds with new_bounds[:, (0, -1)]. A tuple index is treated by Dask as a multidimensional index, so a lazy coordinate along the windowed dimension raised a TypeError. Index with the list [0, -1] instead, which numpy and Dask both treat as selecting the first and last column, giving an identical (and still lazy) result. Fixes #6480.
1 parent d6beb2c commit e4ea7a2

3 files changed

Lines changed: 24 additions & 2 deletions

File tree

changelog/7123.bugfix.rst

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
:user:`gaoflow` fixed :meth:`iris.cube.Cube.rolling_window` so that it no
2+
longer raises a ``TypeError`` when the cube has a lazy auxiliary coordinate
3+
along the windowed dimension. (:issue:`6480`)

lib/iris/cube.py

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5243,12 +5243,15 @@ def rolling_window(
52435243
# window and the bounds are the first and last points in the
52445244
# window as with numeric coordinates.
52455245
new_points = np.apply_along_axis(lambda x: "|".join(x), -1, new_bounds)
5246-
new_bounds = new_bounds[:, (0, -1)]
5246+
# Index with a list rather than a tuple: a tuple is interpreted
5247+
# as a multidimensional index by Dask, so lazy coordinates would
5248+
# otherwise fail here (see #6480).
5249+
new_bounds = new_bounds[:, [0, -1]]
52475250
else:
52485251
# Take the first and last element of the rolled window (i.e.
52495252
# the bounds) and the new points are the midpoints of these
52505253
# bounds.
5251-
new_bounds = new_bounds[:, (0, -1)]
5254+
new_bounds = new_bounds[:, [0, -1]]
52525255
new_points = np.mean(new_bounds, axis=-1)
52535256

52545257
# wipe the coords points and set the bounds

lib/iris/tests/unit/cube/test_Cube.py

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1086,6 +1086,22 @@ def test_lazy(self):
10861086
)
10871087
_shared_utils.assert_masked_array_equal(expected_result, res_cube.data)
10881088

1089+
def test_lazy_aux_coord(self):
1090+
# A lazy aux-coord paralleling the rolled dimension must not cause a
1091+
# failure, and should give the same result as a real one, staying lazy
1092+
# (see #6480).
1093+
self.cube.add_aux_coord(AuxCoord(da.arange(6), long_name="lazy_extra"), 0)
1094+
res_cube = self.cube.rolling_window("val", iris.analysis.MEAN, 3)
1095+
result_coord = res_cube.coord("lazy_extra")
1096+
assert result_coord.has_lazy_points()
1097+
assert result_coord.has_lazy_bounds()
1098+
expected = AuxCoord(
1099+
np.array([1.0, 2.0, 3.0, 4.0]),
1100+
bounds=np.array([[0, 2], [1, 3], [2, 4], [3, 5]]),
1101+
long_name="lazy_extra",
1102+
)
1103+
assert result_coord == expected
1104+
10891105
def test_ancillary_variables_and_cell_measures_kept(self, dataless):
10901106
if dataless:
10911107
self.cube.data = None

0 commit comments

Comments
 (0)