Skip to content

Commit

Permalink
Load data only once for ESMPy regridders (#2418)
Browse files Browse the repository at this point in the history
  • Loading branch information
bouweandela authored May 14, 2024
1 parent a51da92 commit 8b06a18
Show file tree
Hide file tree
Showing 2 changed files with 30 additions and 0 deletions.
5 changes: 5 additions & 0 deletions esmvalcore/preprocessor/_regrid_esmpy.py
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,9 @@ def __init__(
mask_threshold: float = 0.99,
):
"""Initialize class instance."""
# These regridders are not lazy, so load source and target data once.
src_cube.data # pylint: disable=pointless-statement
tgt_cube.data # pylint: disable=pointless-statement
self.src_cube = src_cube
self.tgt_cube = tgt_cube
self.method = method
Expand All @@ -86,6 +89,8 @@ def __call__(self, cube: Cube) -> Cube:
Regridded cube.
"""
# These regridders are not lazy, so load source data once.
cube.data # pylint: disable=pointless-statement
src_rep, dst_rep = get_grid_representants(cube, self.tgt_cube)
regridder = build_regridder(
src_rep, dst_rep, self.method, mask_threshold=self.mask_threshold
Expand Down
25 changes: 25 additions & 0 deletions tests/unit/preprocessor/_regrid_esmpy/test_regrid_esmpy.py
Original file line number Diff line number Diff line change
Expand Up @@ -713,6 +713,31 @@ def test_regrid_area_weighted(self, mock_build_regridder, mock_map_slices):
mock.sentinel.regridder,
self.cube_3d, self.cube)

@mock.patch('esmvalcore.preprocessor._regrid_esmpy.map_slices')
@mock.patch('esmvalcore.preprocessor._regrid_esmpy.build_regridder')
@mock.patch('esmvalcore.preprocessor._regrid_esmpy.get_grid_representants',
mock.Mock(side_effect=identity))
def test_data_realized_once(self, mock_build_regridder, mock_map_slices):
"""Test that the regridder realizes the data only once."""
src_cube = mock.MagicMock()
src_data = mock.PropertyMock()
type(src_cube).data = src_data
tgt_cube1 = mock.MagicMock()
tgt_data1 = mock.PropertyMock()
type(tgt_cube1).data = tgt_data1
# Check that constructing the regridder realizes the source and
# target data.
regridder = ESMPyAreaWeighted().regridder(src_cube, tgt_cube1)
src_data.assert_called_with()
tgt_data1.assert_called_with()
tgt_cube2 = mock.MagicMock()
tgt_data2 = mock.PropertyMock()
# Check that calling the regridder with another cube also realizes
# target data.
type(tgt_cube2).data = tgt_data2
regridder(tgt_cube2)
tgt_data2.assert_called_with()


@pytest.mark.parametrize(
'scheme,output',
Expand Down

0 comments on commit 8b06a18

Please sign in to comment.