diff --git a/docs/src/whatsnew/latest.rst b/docs/src/whatsnew/latest.rst index 825508dca3..eb5bdab05b 100644 --- a/docs/src/whatsnew/latest.rst +++ b/docs/src/whatsnew/latest.rst @@ -36,7 +36,10 @@ This document explains the changes made to Iris for this release 🐛 Bugs Fixed ============= -#. N/A +#. :user:`gaoflow` fixed regridding so that the horizontal coordinates of the + result are copies of, rather than references to, the target grid's + coordinates. Previously, modifying a result coordinate would also modify the + target cube's coordinate (and vice versa). (:issue:`6844`) 💣 Incompatible Changes diff --git a/lib/iris/analysis/_regrid.py b/lib/iris/analysis/_regrid.py index 23d25ecc42..497ecaca39 100644 --- a/lib/iris/analysis/_regrid.py +++ b/lib/iris/analysis/_regrid.py @@ -1040,6 +1040,10 @@ def _create_cube(data, src, src_dims, tgt_coords, num_tgt_dims, regrid_callback) if num_tgt_dims == 1: grid_dim_x = grid_dim_y = min(src_dims) for tgt_coord, dim in zip(tgt_coords, (grid_dim_x, grid_dim_y)): + # Copy so that the result does not share coordinate objects with the + # target grid (mutating one would otherwise mutate the other). See + # #6844. + tgt_coord = tgt_coord.copy() if len(tgt_coord.shape) == 1: if isinstance(tgt_coord, DimCoord) and dim is not None: result.add_dim_coord(tgt_coord, dim) diff --git a/lib/iris/tests/unit/analysis/area_weighted/test_AreaWeightedRegridder.py b/lib/iris/tests/unit/analysis/area_weighted/test_AreaWeightedRegridder.py index c7208a841c..d06543f1a6 100644 --- a/lib/iris/tests/unit/analysis/area_weighted/test_AreaWeightedRegridder.py +++ b/lib/iris/tests/unit/analysis/area_weighted/test_AreaWeightedRegridder.py @@ -122,6 +122,22 @@ def test_src_and_target_are_the_same(self): result = regridder(src) _shared_utils.assert_array_all_close(result.data, target.data) + def test_result_coords_independent_of_target(self): + # The horizontal coordinates of the result must be copies, not the + # same objects as the target's: mutating one must not mutate the + # other (#6844). + src, target = self.grids() + regridder = AreaWeightedRegridder(src, target) + result = regridder(src) + for name in ("latitude", "longitude"): + result_coord = result.coord(name) + target_coord = target.coord(name) + assert result_coord == target_coord + assert result_coord is not target_coord + original = target_coord.points.copy() + result_coord.points = result_coord.points + 100 + _shared_utils.assert_array_equal(target.coord(name).points, original) + def test_multiple_src_on_same_grid(self): coord_names = ["latitude", "longitude"] src1 = self.cube(np.linspace(20, 32, 4), np.linspace(10, 22, 4))