Skip to content
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
162 changes: 90 additions & 72 deletions lib/iris/cube.py
Original file line number Diff line number Diff line change
Expand Up @@ -2233,6 +2233,11 @@ def summary(self, shorten=False, name_padding=35):
versus length and optionally relevant coordinate information.

"""
try:
ugrid_mesh = self.ugrid
except AttributeError:
ugrid_mesh = None

# Create a set to contain the axis names for each data dimension.
dim_names = [set() for dim in range(len(self.shape))]

Expand All @@ -2241,10 +2246,16 @@ def summary(self, shorten=False, name_padding=35):
for dim in range(len(self.shape)):
dim_coords = self.coords(contains_dimension=dim, dim_coords=True)
if dim_coords:
dim_names[dim].add(dim_coords[0].name())
dim_name = dim_coords[0].name()
else:
dim_names[dim].add("-- ")
dim_name = "-- "

if ugrid_mesh:
# Identify the unstructured dimension with an `*`.
if dim == ugrid_mesh.cube_dim:
dim_name = "*" + dim_name

dim_names[dim].add(dim_name)
# Convert axes sets to lists and sort.
dim_names = [sorted(names, key=sorted_axes) for names in dim_names]

Expand Down Expand Up @@ -2328,17 +2339,17 @@ def summary(self, shorten=False, name_padding=35):
)

#
# Generate textual summary of cube vector coordinates.
# Generate textual summary of cube vector coordinates, cell measures, ancillary variables and ugrid_mesh.
#
def vector_summary(
vector_coords,
vector_items,
dim_function,
cube_header,
max_line_offset,
cell_measures=None,
ancillary_variables=None,
add_extra_lines=False,
):
"""
Generates a list of suitably aligned strings containing coord
Generates a list of suitably aligned strings containing item
names and dimensions indicated by one or more 'x' symbols.

.. note::
Expand All @@ -2347,12 +2358,7 @@ def vector_summary(
returned with the list of strings.

"""
if cell_measures is None:
cell_measures = []
if ancillary_variables is None:
ancillary_variables = []
vector_summary = []
vectors = []

# Identify offsets for each dimension text marker.
alignment = np.array(
Expand All @@ -2363,19 +2369,17 @@ def vector_summary(
]
)

# Generate basic textual summary for each vector coordinate
# Generate basic textual summary for each vector item
# - WITHOUT dimension markers.
for dim_meta in (
vector_coords + cell_measures + ancillary_variables
):
for dim_meta in vector_items:
vector_summary.append(
"%*s%s"
% (indent, " ", iris.util.clip_string(dim_meta.name()))
)
min_alignment = min(alignment)

# Determine whether the cube header requires realignment
# due to one or more longer vector coordinate summaries.
# due to one or more longer vector item summaries.
if max_line_offset >= min_alignment:
delta = max_line_offset - min_alignment + 5
cube_header = "%-*s (%s)" % (
Expand All @@ -2385,59 +2389,40 @@ def vector_summary(
)
alignment += delta

if vector_coords:
# Generate full textual summary for each vector coordinate
# - WITH dimension markers.
for index, coord in enumerate(vector_coords):
dims = self.coord_dims(coord)

for dim in range(len(self.shape)):
width = alignment[dim] - len(vector_summary[index])
char = "x" if dim in dims else "-"
line = "{pad:{width}}{char}".format(
pad=" ", width=width, char=char
)
vector_summary[index] += line
vectors = vectors + vector_coords
if cell_measures:
# Generate full textual summary for each vector cell
# measure - WITH dimension markers.
for index, cell_measure in enumerate(cell_measures):
dims = self.cell_measure_dims(cell_measure)

for dim in range(len(self.shape)):
width = alignment[dim] - len(vector_summary[index])
char = "x" if dim in dims else "-"
line = "{pad:{width}}{char}".format(
pad=" ", width=width, char=char
)
vector_summary[index] += line
vectors = vectors + cell_measures
if ancillary_variables:
# Generate full textual summary for each vector ancillary
# variable - WITH dimension markers.
for index, av in enumerate(ancillary_variables):
dims = self.ancillary_variable_dims(av)

for dim in range(len(self.shape)):
width = alignment[dim] - len(vector_summary[index])
char = "x" if dim in dims else "-"
line = "{pad:{width}}{char}".format(
pad=" ", width=width, char=char
)
vector_summary[index] += line
vectors = vectors + ancillary_variables
# Interleave any extra lines that are needed to distinguish
# the coordinates.
vector_summary = self._summary_extra(
vectors, vector_summary, extra_indent
)
# Generate full textual summary for each vector item
# - WITH dimension markers.
for index, coord in enumerate(vector_items):
dims = dim_function(coord)

for dim in range(len(self.shape)):
width = alignment[dim] - len(vector_summary[index])
char = "x" if dim in dims else "-"
line = "{pad:{width}}{char}".format(
pad=" ", width=width, char=char
)
vector_summary[index] += line

if add_extra_lines:
# Interleave any extra lines that are needed to distinguish
# the coordinates.
# TODO: This should also be done for cell measures and
# ancillary variables.
vector_summary = self._summary_extra(
vector_items, vector_summary, extra_indent
)

return vector_summary, cube_header

# Calculate the maximum line offset.
max_line_offset = 0
for coord in all_coords:
dimension_metadata_to_check = (
list(all_coords)
+ vector_cell_measures
+ vector_ancillary_variables
)
if ugrid_mesh:
dimension_metadata_to_check += [ugrid_mesh]
for coord in dimension_metadata_to_check:
max_line_offset = max(
max_line_offset,
len(
Expand All @@ -2452,23 +2437,35 @@ def vector_summary(

if vector_dim_coords:
dim_coord_summary, cube_header = vector_summary(
vector_dim_coords, cube_header, max_line_offset
vector_dim_coords,
self.coord_dims,
cube_header,
max_line_offset,
add_extra_lines=True,
)
summary += "\n Dimension coordinates:\n" + "\n".join(
dim_coord_summary
)

if vector_aux_coords:
aux_coord_summary, cube_header = vector_summary(
vector_aux_coords, cube_header, max_line_offset
vector_aux_coords,
self.coord_dims,
cube_header,
max_line_offset,
add_extra_lines=True,
)
summary += "\n Auxiliary coordinates:\n" + "\n".join(
aux_coord_summary
)

if vector_derived_coords:
derived_coord_summary, cube_header = vector_summary(
vector_derived_coords, cube_header, max_line_offset
vector_derived_coords,
self.coord_dims,
cube_header,
max_line_offset,
add_extra_lines=True,
)
summary += "\n Derived coordinates:\n" + "\n".join(
derived_coord_summary
Expand All @@ -2479,10 +2476,10 @@ def vector_summary(
#
if vector_cell_measures:
cell_measure_summary, cube_header = vector_summary(
[],
vector_cell_measures,
self.cell_measure_dims,
cube_header,
max_line_offset,
cell_measures=vector_cell_measures,
)
summary += "\n Cell measures:\n"
summary += "\n".join(cell_measure_summary)
Expand All @@ -2492,14 +2489,35 @@ def vector_summary(
#
if vector_ancillary_variables:
ancillary_variable_summary, cube_header = vector_summary(
[],
vector_ancillary_variables,
self.ancillary_variable_dims,
cube_header,
max_line_offset,
ancillary_variables=vector_ancillary_variables,
)
summary += "\n Ancillary variables:\n"
summary += "\n".join(ancillary_variable_summary)

#
# Generate summary of ugrid mesh object.
#
if ugrid_mesh:
ugrid_mesh_summary, cube_header = vector_summary(
[ugrid_mesh],
lambda mesh: [mesh.cube_dim],
cube_header,
max_line_offset,
)
summary += "\n ugrid information:\n"
summary += "\n".join(ugrid_mesh_summary)
summary += "\n{pad:{width}}topology_dimension: {val}".format(
pad=" ", width=indent, val=ugrid_mesh.topology_dimension,
)
summary += "\n{pad:{width}}node_coordinates: {val}".format(
pad=" ",
width=indent,
val=" ".join(ugrid_mesh.node_coordinates),
)

#
# Generate textual summary of cube scalar coordinates.
#
Expand Down
20 changes: 17 additions & 3 deletions lib/iris/experimental/representation.py
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,7 @@ def __init__(self, cube):
"Derived coordinates:": None,
"Cell measures:": None,
"Ancillary variables:": None,
"ugrid information:": None,
"Scalar coordinates:": None,
"Scalar cell measures:": None,
"Attributes:": None,
Expand All @@ -102,6 +103,7 @@ def __init__(self, cube):
"Derived coordinates:",
"Cell measures:",
"Ancillary variables:",
"ugrid information:",
]

self.two_cell_headers = ["Scalar coordinates:", "Attributes:"]
Expand All @@ -123,6 +125,11 @@ def _get_dim_names(self):
Note: borrows from `cube.summary`.

"""
try:
ugrid_mesh = self.cube.ugrid
except AttributeError:
ugrid_mesh = None

# Create a set to contain the axis names for each data dimension.
dim_names = list(range(len(self.cube.shape)))

Expand All @@ -133,9 +140,16 @@ def _get_dim_names(self):
contains_dimension=dim, dim_coords=True
)
if dim_coords:
dim_names[dim] = dim_coords[0].name()
dim_name = dim_coords[0].name()
else:
dim_names[dim] = "--"
dim_name = "--"

if ugrid_mesh:
# Identify the unstructured dimension with an `*`.
if dim == ugrid_mesh.cube_dim:
dim_name = "*" + dim_name

dim_names[dim] = dim_name
return dim_names

def _dim_names(self):
Expand Down Expand Up @@ -285,7 +299,7 @@ def _make_content(self):
for line in v:
# Add every other row in the sub-heading.
if k in self.dim_desc_coords:
body = re.findall(r"[\w-]+", line)
body = re.findall(r"[\w\.-]+", line)
title = body.pop(0)
colspan = 0
elif k in self.two_cell_headers:
Expand Down
Loading