import re
from collections import OrderedDict
[docs]
class GraphConvention:
"""Define a naming convention for graph elements."""
[docs]
def __init__(self, node, edge, face, nodes=None, edges=None, faces=None):
"""Define a graph element naming convention.
Parameters
----------
node : str
Name to use for "nodes".
edge : str
Name to use for "edges".
face : str
Name to use for "faces".
nodes : str, optional
Plural of "nodes"
edges : str, optional
Plural of "edges"
faces : str, optional
Plural of "faces"
Examples
--------
>>> from landlab.graph import GraphConvention
>>> convention = GraphConvention("node", "edge", "face")
>>> convention.node
'node'
>>> convention.edge
'edge'
>>> convention.edges
'edges'
>>> convention = GraphConvention("node", "link", "patch", faces="patches")
>>> convention.face
'patch'
>>> convention.faces
'patches'
"""
self._node = node
self._edge = edge
self._face = face
self._nodes = nodes or node + "s"
self._edges = edges or edge + "s"
self._faces = faces or face + "s"
@property
def node(self):
"""The name of things that are points."""
return self._node
@property
def nodes(self):
"""The plural name for node."""
return self._nodes
@property
def edge(self):
"""The name of lines that connect two nodes."""
return self._edge
@property
def edges(self):
"""The plural name of edge."""
return self._edges
@property
def face(self):
"""The name of objects made up of a closed set of edges."""
return self._face
@property
def faces(self):
"""The plural name for face."""
return self._faces
[docs]
class ConventionConverter:
"""Convert between graph element naming conventions."""
CONVENTION = {
"nlp": GraphConvention("node", "link", "patch", faces="patches"),
"nef": GraphConvention("node", "edge", "face"),
"cfc": GraphConvention("corner", "face", "cell"),
}
[docs]
def __init__(self, convention="nlp"):
"""
Parameters
----------
convention : {"nlp", "nef", "cfc"}
Naming convention to which to conform.
"""
self.convention = convention
@property
def convention(self):
"""Name of the convention to conform to."""
return self._convention
@convention.setter
def convention(self, val):
if val not in ("nlp", "cfc", "nef"):
raise ValueError(f"convention not understood ({val})")
self._convention = val
@staticmethod
def _convention_mapper(from_convention, to_convention):
"""Create a mapper to convert names between conventions."""
elements = ("nodes", "edges", "faces", "node", "edge", "face")
from_elements = [getattr(from_convention, name) for name in elements]
to_elements = [getattr(to_convention, name) for name in elements]
return OrderedDict(
list(zip(to_elements, from_elements))
+ list(zip(from_elements, to_elements))
)
@classmethod
def _as_convention(cls, name):
"""Get a named convention as a GraphConvention object."""
try:
return cls.CONVENTION[name]
except KeyError as exc:
raise ValueError(f"convention not understood ({name})") from exc