From fa54e062fce8312bf97b914646d9af1bf94acb39 Mon Sep 17 00:00:00 2001 From: lbdreyer Date: Tue, 1 Oct 2019 15:13:13 +0100 Subject: [PATCH] Fix handling of cell measures during transposes --- ...19-Oct-01_cube_transpose_cell_measures.txt | 1 + lib/iris/cube.py | 23 +++++++++++-------- .../tests/unit/coords/test_CellMeasure.py | 5 +++- lib/iris/tests/unit/cube/test_Cube.py | 23 +++++++++++++++++++ 4 files changed, 42 insertions(+), 10 deletions(-) create mode 100644 docs/iris/src/whatsnew/contributions_2.3.0/bugfix_2019-Oct-01_cube_transpose_cell_measures.txt diff --git a/docs/iris/src/whatsnew/contributions_2.3.0/bugfix_2019-Oct-01_cube_transpose_cell_measures.txt b/docs/iris/src/whatsnew/contributions_2.3.0/bugfix_2019-Oct-01_cube_transpose_cell_measures.txt new file mode 100644 index 0000000000..75dce7ff53 --- /dev/null +++ b/docs/iris/src/whatsnew/contributions_2.3.0/bugfix_2019-Oct-01_cube_transpose_cell_measures.txt @@ -0,0 +1 @@ +* Cell measures are now handled correctly when a cube is transposed. diff --git a/lib/iris/cube.py b/lib/iris/cube.py index 88b8a39347..92ef15be4c 100644 --- a/lib/iris/cube.py +++ b/lib/iris/cube.py @@ -2819,17 +2819,22 @@ def transpose(self, new_order=None): dim_mapping = {src: dest for dest, src in enumerate(new_order)} - def remap_dim_coord(coord_and_dim): - coord, dim = coord_and_dim - return coord, dim_mapping[dim] - self._dim_coords_and_dims = list(map(remap_dim_coord, - self._dim_coords_and_dims)) + # Remap all cube dimensional metadata (dim and aux coords and cell + # measures). + def remap_cube_metadata(metadata_and_dims): + metadata, dims = metadata_and_dims + if isinstance(dims, Iterable): + dims = tuple(dim_mapping[dim] for dim in dims) + else: + dims = dim_mapping[dims] + return metadata, dims - def remap_aux_coord(coord_and_dims): - coord, dims = coord_and_dims - return coord, tuple(dim_mapping[dim] for dim in dims) - self._aux_coords_and_dims = list(map(remap_aux_coord, + self._dim_coords_and_dims = list(map(remap_cube_metadata, + self._dim_coords_and_dims)) + self._aux_coords_and_dims = list(map(remap_cube_metadata, self._aux_coords_and_dims)) + self._cell_measures_and_dims = list(map(remap_cube_metadata, + self._cell_measures_and_dims)) def xml(self, checksum=False, order=True, byteorder=True): """ diff --git a/lib/iris/tests/unit/coords/test_CellMeasure.py b/lib/iris/tests/unit/coords/test_CellMeasure.py index 109357aabc..f0b5851881 100644 --- a/lib/iris/tests/unit/coords/test_CellMeasure.py +++ b/lib/iris/tests/unit/coords/test_CellMeasure.py @@ -1,4 +1,4 @@ -# (C) British Crown Copyright 2015 - 2018, Met Office +# (C) British Crown Copyright 2015 - 2019, Met Office # # This file is part of Iris. # @@ -133,5 +133,8 @@ def test__repr__(self): "var_name='area', attributes={'notes': '1m accuracy'})") self.assertEqual(self.measure.__repr__(), expected) + def test__eq__(self): + self.assertEqual(self.measure, self.measure) + if __name__ == '__main__': tests.main() diff --git a/lib/iris/tests/unit/cube/test_Cube.py b/lib/iris/tests/unit/cube/test_Cube.py index c4e7b249d5..7d02f2d0ca 100644 --- a/lib/iris/tests/unit/cube/test_Cube.py +++ b/lib/iris/tests/unit/cube/test_Cube.py @@ -1863,6 +1863,29 @@ def test_bad_transpose_order(self): with self.assertRaisesRegexp(ValueError, exp_emsg): self.cube.transpose([1]) + def test_dim_coords(self): + x_coord = DimCoord(points=np.array([2, 3, 4]), + long_name='x') + self.cube.add_dim_coord(x_coord, 0) + self.cube.transpose() + self.assertEqual(self.cube._dim_coords_and_dims, [(x_coord, 2)]) + + def test_aux_coords(self): + x_coord = AuxCoord(points=np.array([[2, 3], [8, 4], [7, 9]]), + long_name='x') + self.cube.add_aux_coord(x_coord, (0, 1)) + self.cube.transpose() + self.assertEqual(self.cube._aux_coords_and_dims, + [(x_coord, (2, 1))]) + + def test_cell_measures(self): + area_cm = CellMeasure(data=np.arange(12).reshape(3, 4), + long_name='area of cells', measure='area') + self.cube.add_cell_measure(area_cm, (0, 2)) + self.cube.transpose() + self.assertEqual(self.cube._cell_measures_and_dims, + [(area_cm, (2, 0))]) + class Test_convert_units(tests.IrisTest): def test_convert_unknown_units(self):