From d8ddda9e765e4a4a99f6b9f14b349e32f34fdfa1 Mon Sep 17 00:00:00 2001 From: lbdreyer Date: Tue, 6 Sep 2022 16:53:28 +0100 Subject: [PATCH 1/6] Fix cube repr for scalar anc_var and cell measures --- lib/iris/_representation/cube_printout.py | 4 ++ lib/iris/_representation/cube_summary.py | 38 ++++++++++++++----- .../cube_printout/test_CubePrintout.py | 32 +++++++++++++++- 3 files changed, 62 insertions(+), 12 deletions(-) diff --git a/lib/iris/_representation/cube_printout.py b/lib/iris/_representation/cube_printout.py index b0b569512d..e9bd2e2489 100644 --- a/lib/iris/_representation/cube_printout.py +++ b/lib/iris/_representation/cube_printout.py @@ -260,6 +260,10 @@ def add_scalar_row(name, value=""): elif title in ("attributes:", "cell methods:", "mesh:"): for title, value in zip(sect.names, sect.values): add_scalar_row(title, value) + elif title == "scalar ancillary variables:": + # These are just strings: nothing in the 'value' column. + for name in sect.contents: + add_scalar_row(name) elif title == "scalar cell measures:": # These are just strings: nothing in the 'value' column. for name in sect.contents: diff --git a/lib/iris/_representation/cube_summary.py b/lib/iris/_representation/cube_summary.py index 885de9acf3..0f75bcc060 100644 --- a/lib/iris/_representation/cube_summary.py +++ b/lib/iris/_representation/cube_summary.py @@ -219,6 +219,12 @@ def __init__(self, title, cell_measures): self.contents = [cm.name() for cm in cell_measures] +class ScalarAncillaryVariableSection(Section): + def __init__(self, title, ancillary_variables): + self.title = title + self.contents = [av.name() for av in ancillary_variables] + + class AttributeSection(Section): def __init__(self, title, attributes): self.title = title @@ -274,7 +280,7 @@ class CubeSummary: """ - def __init__(self, cube, shorten=False, name_padding=35): + def __init__(self, cube, name_padding=35): self.header = FullHeader(cube, name_padding) # Cache the derived coords so we can rely on consistent @@ -314,13 +320,23 @@ def __init__(self, cube, shorten=False, name_padding=35): if id(coord) not in scalar_coord_ids ] - # cell measures - vector_cell_measures = [ - cm for cm in cube.cell_measures() if cm.shape != (1,) - ] - # Ancillary Variables - vector_ancillary_variables = [av for av in cube.ancillary_variables()] + vector_ancillary_variables = [] + scalar_ancillary_variables = [] + for av, av_dims in cube._ancillary_variables_and_dims: + if av_dims: + vector_ancillary_variables.append(av) + else: + scalar_ancillary_variables.append(av) + + # Cell Measures + vector_cell_measures = [] + scalar_cell_measures = [] + for cm, cm_dims in cube._cell_measures_and_dims: + if cm_dims: + vector_cell_measures.append(cm) + else: + scalar_cell_measures.append(cm) # Sort scalar coordinates by name. scalar_coords.sort(key=lambda coord: coord.name()) @@ -334,9 +350,6 @@ def __init__(self, cube, shorten=False, name_padding=35): vector_derived_coords.sort( key=lambda coord: (cube.coord_dims(coord), coord.name()) ) - scalar_cell_measures = [ - cm for cm in cube.cell_measures() if cm.shape == (1,) - ] self.vector_sections = {} @@ -364,6 +377,11 @@ def add_scalar_section(section_class, title, *args): add_scalar_section( ScalarCoordSection, "Scalar coordinates:", cube, scalar_coords ) + add_scalar_section( + ScalarAncillaryVariableSection, + "Scalar ancillary variables:", + scalar_ancillary_variables, + ) add_scalar_section( ScalarCellMeasureSection, "Scalar cell measures:", diff --git a/lib/iris/tests/unit/representation/cube_printout/test_CubePrintout.py b/lib/iris/tests/unit/representation/cube_printout/test_CubePrintout.py index ff42acf566..21fc8efa73 100644 --- a/lib/iris/tests/unit/representation/cube_printout/test_CubePrintout.py +++ b/lib/iris/tests/unit/representation/cube_printout/test_CubePrintout.py @@ -349,6 +349,20 @@ def test_section_vector_ancils(self): ] self.assertEqual(rep, expected) + def test_section_vector_ancils_length_1(self): + # Check ancillary variables that map to a cube dimension of length 1 + # are not interpreted as scalar ancillary variables. + cube = Cube(np.zeros((1, 3)), long_name="name", units=1) + cube.add_ancillary_variable(AncillaryVariable([0], long_name="av1"), 0) + + rep = cube_replines(cube) + expected = [ + "name / (1) (-- : 1; -- : 3)", + " Ancillary variables:", + " av1 x -", + ] + self.assertEqual(rep, expected) + def test_section_vector_cell_measures(self): cube = Cube(np.zeros((2, 3)), long_name="name", units=1) cube.add_cell_measure(CellMeasure([0, 1, 2], long_name="cm"), 1) @@ -361,6 +375,20 @@ def test_section_vector_cell_measures(self): ] self.assertEqual(rep, expected) + def test_section_vector_cell_measures_length_1(self): + # Check cell measures that map to a cube dimension of length 1 are not + # interpreted as scalar cell measures. + cube = Cube(np.zeros((2, 1)), long_name="name", units=1) + cube.add_cell_measure(CellMeasure([0], long_name="cm"), 1) + + rep = cube_replines(cube) + expected = [ + "name / (1) (-- : 2; -- : 1)", + " Cell measures:", + " cm - x", + ] + self.assertEqual(rep, expected) + def test_section_scalar_coords(self): # incl points + bounds # TODO: ought to incorporate coord-based summary @@ -424,8 +452,8 @@ def test_section_scalar_ancillaries(self): rep = cube_replines(cube) expected = [ "name / (1) (-- : 2; -- : 3)", - " Ancillary variables:", - " av - -", + " Scalar ancillary variables:", + " av", ] self.assertEqual(rep, expected) From 90a9775f2ff9f54817885e7692c961ef0ef4892b Mon Sep 17 00:00:00 2001 From: lbdreyer Date: Tue, 6 Sep 2022 17:08:01 +0100 Subject: [PATCH 2/6] Add whatsnew --- docs/src/whatsnew/latest.rst | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/docs/src/whatsnew/latest.rst b/docs/src/whatsnew/latest.rst index a42a5a64be..5e941d1fc8 100644 --- a/docs/src/whatsnew/latest.rst +++ b/docs/src/whatsnew/latest.rst @@ -47,6 +47,13 @@ This document explains the changes made to Iris for this release differs from 0 or 2. This enables the use of this method on mesh coordinates. (:issue:`4672`, :pull:`4870`) +#. `@lbdreyer`_ fixed the cube print out such that scalar ancillary variables + are displayed in a dedicated section rather than being added to section for + vector ancillary variables. Further, ancillary variables and cell measures + that are scalar as they map to cube dimension of length 1 are included in the + respective vector sections, mathcing the handling of coordinates. + (:pull:`4945`) + 💣 Incompatible Changes ======================= From 637c094dfccdd0bffc1fed1be70495fadbe18153 Mon Sep 17 00:00:00 2001 From: lbdreyer Date: Tue, 6 Sep 2022 17:26:46 +0100 Subject: [PATCH 3/6] Fix cube summary tests --- .../tests/unit/representation/cube_summary/test_CubeSummary.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/lib/iris/tests/unit/representation/cube_summary/test_CubeSummary.py b/lib/iris/tests/unit/representation/cube_summary/test_CubeSummary.py index 8314c5c9ae..661c669706 100644 --- a/lib/iris/tests/unit/representation/cube_summary/test_CubeSummary.py +++ b/lib/iris/tests/unit/representation/cube_summary/test_CubeSummary.py @@ -74,6 +74,7 @@ def test_blank_cube(self): expected_scalar_sections = [ "Mesh:", "Scalar coordinates:", + "Scalar ancillary variables:", "Scalar cell measures:", "Cell methods:", "Attributes:", @@ -222,7 +223,7 @@ def test_scalar_cube(self): self.assertTrue( all(sect.is_empty() for sect in rep.vector_sections.values()) ) - self.assertEqual(len(rep.scalar_sections), 5) + self.assertEqual(len(rep.scalar_sections), 6) self.assertEqual( len(rep.scalar_sections["Scalar coordinates:"].contents), 1 ) From 53d15291a197fcfd4270cd388fae8a4855edc0a0 Mon Sep 17 00:00:00 2001 From: lbdreyer Date: Thu, 8 Sep 2022 14:38:38 +0100 Subject: [PATCH 4/6] Review actions: reword whats new, reorder scalar sections in cube printout --- docs/src/whatsnew/latest.rst | 12 ++++++------ lib/iris/_representation/cube_printout.py | 11 +++++------ lib/iris/_representation/cube_summary.py | 10 +++++----- 3 files changed, 16 insertions(+), 17 deletions(-) diff --git a/docs/src/whatsnew/latest.rst b/docs/src/whatsnew/latest.rst index 5e941d1fc8..4f429c80cc 100644 --- a/docs/src/whatsnew/latest.rst +++ b/docs/src/whatsnew/latest.rst @@ -47,12 +47,12 @@ This document explains the changes made to Iris for this release differs from 0 or 2. This enables the use of this method on mesh coordinates. (:issue:`4672`, :pull:`4870`) -#. `@lbdreyer`_ fixed the cube print out such that scalar ancillary variables - are displayed in a dedicated section rather than being added to section for - vector ancillary variables. Further, ancillary variables and cell measures - that are scalar as they map to cube dimension of length 1 are included in the - respective vector sections, mathcing the handling of coordinates. - (:pull:`4945`) +#. `@lbdreyer`_ and `@pp-mo`_ (reviewer) fixed the cube print out such that + scalar ancillary variables are displayed in a dedicated section rather than + being added to the vector ancillary variables section. Further, ancillary + variables and cell measures that map to a cube dimension of length 1 are now + included in the respective vector sections, matching the handling of + coordinates. (:pull:`4945`) 💣 Incompatible Changes diff --git a/lib/iris/_representation/cube_printout.py b/lib/iris/_representation/cube_printout.py index e9bd2e2489..1efd58f7bf 100644 --- a/lib/iris/_representation/cube_printout.py +++ b/lib/iris/_representation/cube_printout.py @@ -260,12 +260,11 @@ def add_scalar_row(name, value=""): elif title in ("attributes:", "cell methods:", "mesh:"): for title, value in zip(sect.names, sect.values): add_scalar_row(title, value) - elif title == "scalar ancillary variables:": - # These are just strings: nothing in the 'value' column. - for name in sect.contents: - add_scalar_row(name) - elif title == "scalar cell measures:": - # These are just strings: nothing in the 'value' column. + elif title in ( + "scalar ancillary variables:", + "scalar cell measures:", + ): + # These are just strings: nothing in the 'va"scalar cell measures:"lue' column. for name in sect.contents: add_scalar_row(name) else: diff --git a/lib/iris/_representation/cube_summary.py b/lib/iris/_representation/cube_summary.py index 0f75bcc060..6b0d4cf0f3 100644 --- a/lib/iris/_representation/cube_summary.py +++ b/lib/iris/_representation/cube_summary.py @@ -377,16 +377,16 @@ def add_scalar_section(section_class, title, *args): add_scalar_section( ScalarCoordSection, "Scalar coordinates:", cube, scalar_coords ) - add_scalar_section( - ScalarAncillaryVariableSection, - "Scalar ancillary variables:", - scalar_ancillary_variables, - ) add_scalar_section( ScalarCellMeasureSection, "Scalar cell measures:", scalar_cell_measures, ) + add_scalar_section( + ScalarAncillaryVariableSection, + "Scalar ancillary variables:", + scalar_ancillary_variables, + ) add_scalar_section( CellMethodSection, "Cell methods:", cube.cell_methods ) From a74645e3b6f0c33f41bac3938d7d501230f7286f Mon Sep 17 00:00:00 2001 From: lbdreyer Date: Thu, 8 Sep 2022 15:04:35 +0100 Subject: [PATCH 5/6] Fix cube summary test, update whatsnew --- docs/src/whatsnew/latest.rst | 3 +-- .../tests/unit/representation/cube_summary/test_CubeSummary.py | 2 +- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/docs/src/whatsnew/latest.rst b/docs/src/whatsnew/latest.rst index 4f429c80cc..4ae7b9dfd6 100644 --- a/docs/src/whatsnew/latest.rst +++ b/docs/src/whatsnew/latest.rst @@ -51,8 +51,7 @@ This document explains the changes made to Iris for this release scalar ancillary variables are displayed in a dedicated section rather than being added to the vector ancillary variables section. Further, ancillary variables and cell measures that map to a cube dimension of length 1 are now - included in the respective vector sections, matching the handling of - coordinates. (:pull:`4945`) + included in the respective vector sections. (:pull:`4945`) 💣 Incompatible Changes diff --git a/lib/iris/tests/unit/representation/cube_summary/test_CubeSummary.py b/lib/iris/tests/unit/representation/cube_summary/test_CubeSummary.py index 661c669706..bcf31a016f 100644 --- a/lib/iris/tests/unit/representation/cube_summary/test_CubeSummary.py +++ b/lib/iris/tests/unit/representation/cube_summary/test_CubeSummary.py @@ -74,8 +74,8 @@ def test_blank_cube(self): expected_scalar_sections = [ "Mesh:", "Scalar coordinates:", - "Scalar ancillary variables:", "Scalar cell measures:", + "Scalar ancillary variables:", "Cell methods:", "Attributes:", ] From 7673aa9c1d096fa59c64dab57c4d727ef170ed40 Mon Sep 17 00:00:00 2001 From: lbdreyer Date: Fri, 9 Sep 2022 13:27:12 +0100 Subject: [PATCH 6/6] Fix code comment --- lib/iris/_representation/cube_printout.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/iris/_representation/cube_printout.py b/lib/iris/_representation/cube_printout.py index 1efd58f7bf..ea32fc5126 100644 --- a/lib/iris/_representation/cube_printout.py +++ b/lib/iris/_representation/cube_printout.py @@ -264,7 +264,7 @@ def add_scalar_row(name, value=""): "scalar ancillary variables:", "scalar cell measures:", ): - # These are just strings: nothing in the 'va"scalar cell measures:"lue' column. + # These are just strings: nothing in the 'value' column. for name in sect.contents: add_scalar_row(name) else: