Skip to content

Commit

Permalink
Lazy iris.cube.Cube.rolling_window
Browse files Browse the repository at this point in the history
  • Loading branch information
bouweandela committed Mar 4, 2024
1 parent c6151e8 commit 3427c19
Show file tree
Hide file tree
Showing 3 changed files with 35 additions and 12 deletions.
19 changes: 8 additions & 11 deletions lib/iris/cube.py
Original file line number Diff line number Diff line change
Expand Up @@ -4502,12 +4502,6 @@ def rolling_window(self, coord, aggregator, window, **kwargs):
-------
:class:`iris.cube.Cube`.
Notes
-----
.. note::
This operation does not yet have support for lazy evaluation.
Examples
--------
>>> import iris, iris.analysis
Expand Down Expand Up @@ -4611,7 +4605,7 @@ def rolling_window(self, coord, aggregator, window, **kwargs):
# this will add an extra dimension to the data at dimension + 1 which
# represents the rolled window (i.e. will have a length of window)
rolling_window_data = iris.util.rolling_window(
self.data, window=window, axis=dimension
self.core_data(), window=window, axis=dimension
)

# now update all of the coordinates to reflect the aggregation
Expand All @@ -4630,7 +4624,7 @@ def rolling_window(self, coord, aggregator, window, **kwargs):
"coordinate." % coord_.name()
)

new_bounds = iris.util.rolling_window(coord_.points, window)
new_bounds = iris.util.rolling_window(coord_.core_points(), window)

if np.issubdtype(new_bounds.dtype, np.str_):
# Handle case where the AuxCoord contains string. The points
Expand Down Expand Up @@ -4676,9 +4670,12 @@ def rolling_window(self, coord, aggregator, window, **kwargs):
kwargs["weights"] = iris.util.broadcast_to_shape(
weights, rolling_window_data.shape, (dimension + 1,)
)
data_result = aggregator.aggregate(
rolling_window_data, axis=dimension + 1, **kwargs
)

if aggregator.lazy_func is not None and self.has_lazy_data():
agg_method = aggregator.lazy_aggregate
else:
agg_method = aggregator.aggregate
data_result = agg_method(rolling_window_data, axis=dimension + 1, **kwargs)
result = aggregator.post_process(new_cube, data_result, [coord], **kwargs)
return result

Expand Down
26 changes: 26 additions & 0 deletions lib/iris/tests/test_analysis.py
Original file line number Diff line number Diff line change
Expand Up @@ -1452,6 +1452,32 @@ def test_longitude_masked(self):

self.assertMaskedArrayEqual(expected_result, res_cube.data)

def test_longitude_masked_lazy(self):
self.cube.data = ma.array(
self.cube.data,
mask=[
[True, True, True, True],
[True, False, True, True],
[False, False, False, False],
],
)
self.cube.data = self.cube.lazy_data()
res_cube = self.cube.rolling_window("longitude", iris.analysis.MEAN, window=2)

expected_result = np.ma.array(
[[-99.0, -99.0, -99.0], [12.0, 12.0, -99.0], [15.0, 11.0, 8.0]],
mask=[
[True, True, True],
[False, False, True],
[False, False, False],
],
dtype=np.float64,
)

self.assertTrue(self.cube.has_lazy_data())
self.assertTrue(res_cube.has_lazy_data())
self.assertMaskedArrayEqual(expected_result, res_cube.data)

def test_longitude_circular(self):
cube = self.cube
cube.coord("longitude").circular = True
Expand Down
2 changes: 1 addition & 1 deletion lib/iris/tests/unit/cube/test_Cube.py
Original file line number Diff line number Diff line change
Expand Up @@ -877,7 +877,7 @@ def setUp(self):
self.cell_measure = CellMeasure([0, 1, 2, 0, 1, 2], long_name="bar")
self.multi_dim_cube.add_cell_measure(self.cell_measure, 1)

self.mock_agg = mock.Mock(spec=Aggregator)
self.mock_agg = mock.Mock(spec=Aggregator, lazy_func=None)
self.mock_agg.aggregate = mock.Mock(return_value=np.empty([4]))
self.mock_agg.post_process = mock.Mock(side_effect=lambda x, y, z: x)

Expand Down

0 comments on commit 3427c19

Please sign in to comment.