From 671ecc85f99313f2743ecc86e84ca3dfe8bb7ce2 Mon Sep 17 00:00:00 2001 From: 01luyicheng <01luyicheng@users.noreply.github.com> Date: Fri, 10 Jul 2026 17:26:50 +0000 Subject: [PATCH 1/3] Add unit tests for Cube.coord_dims --- lib/iris/tests/unit/cube/test_Cube.py | 72 +++++++++++++++++++++++++++ 1 file changed, 72 insertions(+) diff --git a/lib/iris/tests/unit/cube/test_Cube.py b/lib/iris/tests/unit/cube/test_Cube.py index d91c7e81c0..46f5ba5125 100644 --- a/lib/iris/tests/unit/cube/test_Cube.py +++ b/lib/iris/tests/unit/cube/test_Cube.py @@ -3989,3 +3989,75 @@ def test_with_data(self): def test_without_data(self): cube = Cube(data=None, shape=self.shape) assert cube.is_dataless() + + +class Test_coord_dims: + """Tests for :meth:`iris.cube.Cube.coord_dims`.""" + + @pytest.fixture(autouse=True) + def _setup(self): + # Build a 3D cube with dimension coordinates, auxiliary coordinates + # spanning one and multiple dimensions, and a derived auxiliary + # coordinate provided by a hybrid-height factory. + data = np.arange(24).reshape(2, 3, 4) + x_coord = DimCoord(points=np.array([0, 1]), long_name="x") + y_coord = DimCoord(points=np.array([0, 1, 2]), long_name="y") + z_coord = DimCoord(points=np.array([0, 1, 2, 3]), long_name="z") + aux_1d = AuxCoord(points=np.array([0, 1]), long_name="aux_1d") + aux_2d = AuxCoord(points=np.arange(6).reshape(2, 3), long_name="aux_2d") + cube = Cube(data) + cube.add_dim_coord(x_coord, 0) + cube.add_dim_coord(y_coord, 1) + cube.add_dim_coord(z_coord, 2) + cube.add_aux_coord(aux_1d, 0) + cube.add_aux_coord(aux_2d, (0, 1)) + # Dependencies for a hybrid-height derived coordinate ("altitude"). + delta = AuxCoord(points=np.array([0, 1]), long_name="delta", units="m") + sigma = AuxCoord(points=np.array([0, 1]), long_name="sigma") + orography = AuxCoord( + np.arange(12).reshape(3, 4), units="m", long_name="orography" + ) + cube.add_aux_coord(delta, 0) + cube.add_aux_coord(sigma, 0) + cube.add_aux_coord(orography, (1, 2)) + factory = HybridHeightFactory(delta=delta, sigma=sigma, orography=orography) + cube.add_aux_factory(factory) + self.cube = cube + self.x_coord = x_coord + self.aux_1d = aux_1d + self.aux_2d = aux_2d + self.factory = factory + + def test_dim_coord(self): + # A dimension coordinate is found by object identity. + assert self.cube.coord_dims(self.x_coord) == (0,) + + def test_string_name(self): + # A coordinate may be looked up by its string name. + assert self.cube.coord_dims("y") == (1,) + + def test_aux_coord_single_dim(self): + # An auxiliary coordinate spanning a single dimension. + assert self.cube.coord_dims(self.aux_1d) == (0,) + + def test_aux_coord_multiple_dims(self): + # An auxiliary coordinate spanning multiple dimensions. + assert self.cube.coord_dims(self.aux_2d) == (0, 1) + + def test_aux_factory(self): + # A derived coordinate provided by an aux factory. + derived_coord = self.factory.make_coord(self.cube.coord_dims) + assert self.cube.coord_dims(derived_coord) == (0, 1, 2) + + def test_equivalent_coord_not_instance(self): + # An equivalent coordinate (same metadata, different instance) is + # resolved via the fallback coordinate lookup. + equivalent = self.x_coord.copy() + assert equivalent is not self.x_coord + assert self.cube.coord_dims(equivalent) == (0,) + + def test_no_match_raises(self): + # A coordinate that is not on the cube and matches nothing raises. + missing = DimCoord(points=np.array([0, 1]), long_name="missing") + with pytest.raises(CoordinateNotFoundError): + self.cube.coord_dims(missing) From c456fdfd51f672117eba59eb946512f2bbf22235 Mon Sep 17 00:00:00 2001 From: 01luyicheng <01luyicheng@users.noreply.github.com> Date: Fri, 10 Jul 2026 17:49:35 +0000 Subject: [PATCH 2/3] Add What's New changelog fragment for #4552 --- changelog/7198.internal.rst | 2 ++ 1 file changed, 2 insertions(+) create mode 100644 changelog/7198.internal.rst diff --git a/changelog/7198.internal.rst b/changelog/7198.internal.rst new file mode 100644 index 0000000000..aa0f1af23e --- /dev/null +++ b/changelog/7198.internal.rst @@ -0,0 +1,2 @@ +:user:`01luyicheng` added unit tests for :meth:`~iris.cube.Cube.coord_dims`. +(:issue:`4552`) From 8d101a24584fe79e0ba5ca5f3dccb8d555dcf3fa Mon Sep 17 00:00:00 2001 From: 01luyicheng <01luyicheng@gmail.com> Date: Thu, 23 Jul 2026 18:17:39 +0000 Subject: [PATCH 3/3] Refactor Test_coord_dims._setup for readability MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Address review feedback from @ESadek-MO: - Move hybrid-height set-up into the single test that uses it - Group _setup into clear blocks: cube → DimCoords → AuxCoords → assigns --- lib/iris/tests/unit/cube/test_Cube.py | 44 +++++++++++++++------------ 1 file changed, 25 insertions(+), 19 deletions(-) diff --git a/lib/iris/tests/unit/cube/test_Cube.py b/lib/iris/tests/unit/cube/test_Cube.py index 46f5ba5125..560aa5e650 100644 --- a/lib/iris/tests/unit/cube/test_Cube.py +++ b/lib/iris/tests/unit/cube/test_Cube.py @@ -3996,37 +3996,32 @@ class Test_coord_dims: @pytest.fixture(autouse=True) def _setup(self): - # Build a 3D cube with dimension coordinates, auxiliary coordinates - # spanning one and multiple dimensions, and a derived auxiliary - # coordinate provided by a hybrid-height factory. + # Build a 3D cube with dimension coordinates and auxiliary + # coordinates spanning one and multiple dimensions. + + # Set-up the cube. data = np.arange(24).reshape(2, 3, 4) + cube = Cube(data) + + # Set-up the DimCoords and add them to the cube. x_coord = DimCoord(points=np.array([0, 1]), long_name="x") y_coord = DimCoord(points=np.array([0, 1, 2]), long_name="y") z_coord = DimCoord(points=np.array([0, 1, 2, 3]), long_name="z") - aux_1d = AuxCoord(points=np.array([0, 1]), long_name="aux_1d") - aux_2d = AuxCoord(points=np.arange(6).reshape(2, 3), long_name="aux_2d") - cube = Cube(data) cube.add_dim_coord(x_coord, 0) cube.add_dim_coord(y_coord, 1) cube.add_dim_coord(z_coord, 2) + + # Set-up the AuxCoords and add them to the cube. + aux_1d = AuxCoord(points=np.array([0, 1]), long_name="aux_1d") + aux_2d = AuxCoord(points=np.arange(6).reshape(2, 3), long_name="aux_2d") cube.add_aux_coord(aux_1d, 0) cube.add_aux_coord(aux_2d, (0, 1)) - # Dependencies for a hybrid-height derived coordinate ("altitude"). - delta = AuxCoord(points=np.array([0, 1]), long_name="delta", units="m") - sigma = AuxCoord(points=np.array([0, 1]), long_name="sigma") - orography = AuxCoord( - np.arange(12).reshape(3, 4), units="m", long_name="orography" - ) - cube.add_aux_coord(delta, 0) - cube.add_aux_coord(sigma, 0) - cube.add_aux_coord(orography, (1, 2)) - factory = HybridHeightFactory(delta=delta, sigma=sigma, orography=orography) - cube.add_aux_factory(factory) + + # Assign them all to class variables. self.cube = cube self.x_coord = x_coord self.aux_1d = aux_1d self.aux_2d = aux_2d - self.factory = factory def test_dim_coord(self): # A dimension coordinate is found by object identity. @@ -4046,7 +4041,18 @@ def test_aux_coord_multiple_dims(self): def test_aux_factory(self): # A derived coordinate provided by an aux factory. - derived_coord = self.factory.make_coord(self.cube.coord_dims) + # Dependencies for a hybrid-height derived coordinate ("altitude"). + delta = AuxCoord(points=np.array([0, 1]), long_name="delta", units="m") + sigma = AuxCoord(points=np.array([0, 1]), long_name="sigma") + orography = AuxCoord( + np.arange(12).reshape(3, 4), units="m", long_name="orography" + ) + self.cube.add_aux_coord(delta, 0) + self.cube.add_aux_coord(sigma, 0) + self.cube.add_aux_coord(orography, (1, 2)) + factory = HybridHeightFactory(delta=delta, sigma=sigma, orography=orography) + self.cube.add_aux_factory(factory) + derived_coord = factory.make_coord(self.cube.coord_dims) assert self.cube.coord_dims(derived_coord) == (0, 1, 2) def test_equivalent_coord_not_instance(self):