… add an affix-function to a standard name table during runtime?#
If you are using the standard name convention, you are familiar with transformation functions like “derivative_of_<SN1>wrt<SN2>” or “square_of_<SN>”.
Now, you want to add your custom transformation function without changing the package code. Say, you want to add the transformation “maximum_of_
Here is the current state, which fails as expected:
import h5rdmtoolbox as h5tbx
from h5rdmtoolbox.convention.standard_names.transformation import Transformation
from h5rdmtoolbox.convention.standard_names import StandardName
snt = h5tbx.convention.standard_names.StandardNameTable.from_zenodo(doi_or_recid=10428795)
# check if the problem really exists:
try:
snt['maximum_of_pressure']
except h5tbx.errors.StandardNameError as e:
print(e)
---------------------------------------------------------------------------
KeyError Traceback (most recent call last)
Cell In[1], line 5
2 from h5rdmtoolbox.convention.standard_names.transformation import Transformation
3 from h5rdmtoolbox.convention.standard_names import StandardName
----> 5 snt = h5tbx.convention.standard_names.StandardNameTable.from_zenodo(doi_or_recid=10428795)
7 # check if the problem really exists:
8 try:
File ~/checkouts/readthedocs.org/user_builds/h5rdmtoolbox/checkouts/v1.4.1/h5rdmtoolbox/convention/standard_names/table.py:755, in StandardNameTable.from_zenodo(source, doi_or_recid)
752 z = zenodo.ZenodoRecord(rec_id)
753 assert z.exists()
--> 755 filenames = [file.download(target_folder=UserDir['standard_name_tables']) for file in z.files.values()]
756 # filenames = z.download_files(target_folder=UserDir['standard_name_tables'])
757 assert len(filenames) == 1
File ~/checkouts/readthedocs.org/user_builds/h5rdmtoolbox/checkouts/v1.4.1/h5rdmtoolbox/repository/zenodo/core.py:602, in ZenodoRecord.files(self)
595 @property
596 def files(self) -> Dict[str, RepositoryFile]:
597 # def _parse_download_url(filename):
598 # if filename is None:
599 # return filename
600 # return f"{self.rec_url}/{self.rec_id}/files/{filename}"
--> 602 is_submitted = self.submitted()
604 def _parse_download_url(url, filename):
605 if url is None:
File ~/checkouts/readthedocs.org/user_builds/h5rdmtoolbox/checkouts/v1.4.1/h5rdmtoolbox/repository/zenodo/core.py:558, in ZenodoRecord.is_published(self)
556 def is_published(self) -> bool:
557 """Check if the deposit is published."""
--> 558 return self.json()['submitted']
KeyError: 'submitted'
Implementing a new transformation function#
We need to do two things:
write a
functionwhich takes a regex result and generates the new standard nameinit a
Transformationobject which performs the regex match
The respective regex pattern to the above is ^maximum_of_(.*)$.
The respective function is implemented in the following. It takes the result from a re.match() call and the standard name table object. The function then constructs a new standard name and returns it. Even if the regex match succeeded, it is still possible, that the function raises an error because the base standard_name may not exist.
def maximum_of(match, snt):
# match is the result of `re.match(`^maximum_of_(.*)$, <user_input_value>)`
groups = match.groups()
assert len(groups) == 1
sn = snt[groups[0]]
new_description = f"Maximum of {sn.name}. {sn.description}"
return StandardName(match.string, sn.units, new_description)
The actual transformation is managed by the class Transformation. It takes the above defined function and the respective regex pattern:
max_of = Transformation(r"^maximum_of_(.*)$", maximum_of)
We can already check if the pattern matching works:
max_of.match('maximum_static_pressure') is None
True
max_of.match('maximum_of_static_pressure') is None
False
Add it to an existing standard name table during runtime:#
snt.add_transformation(max_of)
snt['maximum_of_static_pressure']
-
- units : Pa
- description : Maximum of static_pressure. Static pressure refers to the force per unit area exerted by a fluid. Pressure is a scalar quantity.
snt.transformations[-1] == max_of
True