Skip to content

Commit

Permalink
add mesh __str__ and __repr__ support (#4033)
Browse files Browse the repository at this point in the history
  • Loading branch information
bjlittle authored Feb 25, 2021
1 parent e719ae0 commit 208e020
Show file tree
Hide file tree
Showing 2 changed files with 137 additions and 21 deletions.
145 changes: 132 additions & 13 deletions lib/iris/experimental/ugrid.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
from abc import ABC, abstractmethod
from collections import Iterable, namedtuple
from functools import wraps
import re

import dask.array as da
import numpy as np
Expand Down Expand Up @@ -50,6 +51,12 @@
]


#: Numpy "threshold" printoptions default argument.
NP_PRINTOPTIONS_THRESHOLD = 10
#: Numpy "edgeitems" printoptions default argument.
NP_PRINTOPTIONS_EDGEITEMS = 2


# Configure the logger.
logger = get_logger(__name__, fmt="[%(cls)s.%(funcName)s]")

Expand Down Expand Up @@ -205,6 +212,58 @@ def validate_arg_vs_list(arg_name, arg, valid_list):
attributes=attributes,
)

def __repr__(self):
def kwargs_filter(k, v):
result = False
if k != "cf_role":
if v is not None:
result = True
if (
not isinstance(v, str)
and isinstance(v, Iterable)
and not v
):
result = False
elif k == "units" and v == "unknown":
result = False
return result

def array2repr(array):
if self.has_lazy_indices():
result = repr(array)
else:
with np.printoptions(
threshold=NP_PRINTOPTIONS_THRESHOLD,
edgeitems=NP_PRINTOPTIONS_EDGEITEMS,
):
result = re.sub("\n *", " ", repr(array))
return result

# positional arguments
args = ", ".join(
[
f"{array2repr(self.core_indices())}",
f"cf_role={self.cf_role!r}",
]
)

# optional arguments (metadata)
kwargs = ", ".join(
[
f"{k}={v!r}"
for k, v in self.metadata._asdict().items()
if kwargs_filter(k, v)
]
)

return f"{self.__class__.__name__}({', '.join([args, kwargs])})"

def __str__(self):
args = ", ".join(
[f"cf_role={self.cf_role!r}", f"start_index={self.start_index!r}"]
)
return f"{self.__class__.__name__}({args})"

@property
def _values(self):
# Overridden just to allow .setter override.
Expand Down Expand Up @@ -833,13 +892,13 @@ def __init__(
topology_dimension,
node_coords_and_axes,
connectivities,
edge_coords_and_axes=None,
face_coords_and_axes=None,
standard_name=None,
long_name=None,
var_name=None,
units=None,
attributes=None,
edge_coords_and_axes=None,
face_coords_and_axes=None,
node_dimension=None,
edge_dimension=None,
face_dimension=None,
Expand Down Expand Up @@ -935,8 +994,75 @@ def __ne__(self, other):
return result

def __repr__(self):
# TBD
args = []
def to_coord_and_axis(members):
def axis(member):
return member.split("_")[1]

result = [
f"({coord!s}, {axis(member)!r})"
for member, coord in members._asdict().items()
if coord is not None
]
result = f"[{', '.join(result)}]" if result else None
return result

node_coords_and_axes = to_coord_and_axis(self.node_coords)
connectivities = [
str(connectivity)
for connectivity in self.all_connectivities
if connectivity is not None
]

if len(connectivities) == 1:
connectivities = connectivities[0]
else:
connectivities = f"[{', '.join(connectivities)}]"

# positional arguments
args = [
f"topology_dimension={self.topology_dimension!r}",
f"node_coords_and_axes={node_coords_and_axes}",
f"connectivities={connectivities}",
]

# optional argument
edge_coords_and_axes = to_coord_and_axis(self.edge_coords)
if edge_coords_and_axes:
args.append(f"edge_coords_and_axes={edge_coords_and_axes}")

# optional argument
if self.topology_dimension > 1:
face_coords_and_axes = to_coord_and_axis(self.face_coords)
if face_coords_and_axes:
args.append(f"face_coords_and_axes={face_coords_and_axes}")

def kwargs_filter(k, v):
result = False
if k != "topology_dimension":
if not (
self.topology_dimension == 1 and k == "face_dimension"
):
if v is not None:
result = True
if (
not isinstance(v, str)
and isinstance(v, Iterable)
and not v
):
result = False
elif k == "units" and v == "unknown":
result = False
return result

# optional arguments (metadata)
args.extend(
[
f"{k}={v!r}"
for k, v in self.metadata._asdict().items()
if kwargs_filter(k, v)
]
)

return f"{self.__class__.__name__}({', '.join(args)})"

def __setstate__(self, state):
Expand All @@ -945,11 +1071,6 @@ def __setstate__(self, state):
self._coord_manager = coord_manager
self._connectivity_manager = connectivity_manager

def __str__(self):
# TBD
args = []
return f"{self.__class__.__name__}({', '.join(args)})"

def _set_dimension_names(self, node, edge, face, reset=False):
args = (node, edge, face)
currents = (
Expand Down Expand Up @@ -1335,9 +1456,7 @@ def __setstate__(self, state):
self._members = state

def __str__(self):
args = [
f"{member}=True" for member, coord in self if coord is not None
]
args = [f"{member}" for member, coord in self if coord is not None]
return f"{self.__class__.__name__}({', '.join(args)})"

def _remove(self, **kwargs):
Expand Down Expand Up @@ -1740,7 +1859,7 @@ def __setstate__(self, state):

def __str__(self):
args = [
f"{member}=True"
f"{member}"
for member, connectivity in self
if connectivity is not None
]
Expand Down
13 changes: 5 additions & 8 deletions lib/iris/tests/unit/experimental/ugrid/test_Connectivity.py
Original file line number Diff line number Diff line change
Expand Up @@ -96,19 +96,16 @@ def test_src_lengths(self):

def test___str__(self):
expected = (
"Connectivity(array([[1, 2, 3],\n [4, 5, 6],\n [7, 8, 9]]), "
"standard_name=None, units=Unit('unknown'), "
"long_name='my_face_nodes', var_name='face_nodes', "
"attributes={'notes': 'this is a test'})"
"Connectivity(cf_role='face_node_connectivity', start_index=1)"
)
self.assertEqual(expected, self.connectivity.__str__())

def test___repr__(self):
expected = (
"Connectivity(array([[1, 2, 3],\n [4, 5, 6],\n [7, 8, 9]]), "
"standard_name=None, units=Unit('unknown'), "
"long_name='my_face_nodes', var_name='face_nodes', "
"attributes={'notes': 'this is a test'})"
"Connectivity(array([[1, 2, 3], [4, 5, 6], [7, 8, 9]]), "
"cf_role='face_node_connectivity', long_name='my_face_nodes', "
"var_name='face_nodes', attributes={'notes': 'this is a test'}, "
"start_index=1, src_dim=1)"
)
self.assertEqual(expected, self.connectivity.__repr__())

Expand Down

0 comments on commit 208e020

Please sign in to comment.