Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix cube repr for scalar anc_var and cell measures #4945

Merged
merged 7 commits into from
Sep 9, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions docs/src/whatsnew/latest.rst
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,12 @@ This document explains the changes made to Iris for this release
#. `@bjlittle`_ and `@lbdreyer`_ (reviewer) fixed the building of the CF
Standard Names module ``iris.std_names`` for the ``setup.py`` commands
``develop`` and ``std_names``. (:issue:`4951`, :pull:`4952`)

#. `@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. (:pull:`4945`)


💣 Incompatible Changes
Expand Down
5 changes: 4 additions & 1 deletion lib/iris/_representation/cube_printout.py
Original file line number Diff line number Diff line change
Expand Up @@ -260,7 +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 cell measures:":
elif title in (
"scalar ancillary variables:",
"scalar cell measures:",
):
# These are just strings: nothing in the 'value' column.
for name in sect.contents:
add_scalar_row(name)
Expand Down
38 changes: 28 additions & 10 deletions lib/iris/_representation/cube_summary.py
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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())
Expand All @@ -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 = {}

Expand Down Expand Up @@ -369,6 +382,11 @@ def add_scalar_section(section_class, title, *args):
"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
)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand All @@ -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
Expand Down Expand Up @@ -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)

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,7 @@ def test_blank_cube(self):
"Mesh:",
"Scalar coordinates:",
"Scalar cell measures:",
"Scalar ancillary variables:",
"Cell methods:",
"Attributes:",
]
Expand Down Expand Up @@ -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
)
Expand Down