diff --git a/esmvalcore/preprocessor/_regrid_esmpy.py b/esmvalcore/preprocessor/_regrid_esmpy.py index dd47b08e9e..c7edfa829c 100755 --- a/esmvalcore/preprocessor/_regrid_esmpy.py +++ b/esmvalcore/preprocessor/_regrid_esmpy.py @@ -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 @@ -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 diff --git a/tests/unit/preprocessor/_regrid_esmpy/test_regrid_esmpy.py b/tests/unit/preprocessor/_regrid_esmpy/test_regrid_esmpy.py index 611966ab75..371ab49684 100644 --- a/tests/unit/preprocessor/_regrid_esmpy/test_regrid_esmpy.py +++ b/tests/unit/preprocessor/_regrid_esmpy/test_regrid_esmpy.py @@ -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',