Source code for h5rdmtoolbox.convention.standard_names.name

import pint
import re
import warnings
from typing import Dict, Union

from h5rdmtoolbox import get_ureg
from . import consts
from .utils import _units_power_fix
from ..utils import equal_base_units
from ... import errors


[docs] class StandardName: """Standard Name class"""
[docs] def __init__(self, name: str, units: Union[str, pint.Unit] = None, description: str = None, canonical_units: str = None, isvector: bool = False, alias: str = None): StandardName.check_syntax(name) self._is_vector = isvector self.name = name if canonical_units is not None: warnings.warn('Parameter "canonical_units" is depreciated. Use "units" instead.', DeprecationWarning) units = canonical_units if description is None: # TODO if canonical_units is removed, then default value None must be removed for description, too raise ValueError('A description must be provided') if isinstance(units, str): self.units = get_ureg().Unit(_units_power_fix(units)) elif isinstance(units, pint.Unit): self.units = units else: raise TypeError(f"units must be a str or a pint.Unit, not {type(units)}") # convert units to base units: q = 1 * self.units self.unit = q.to_base_units().units if description[-1] != '.': description += '.' # add a dot at the end of the description self.description = description if alias is not None: self.check_syntax(alias) self.alias = alias
def __to_h5attr__(self) -> str: return self.name def __str__(self): return self.name def __repr__(self): return f'<StandardName: "{self.name}" [{self.units}] {self.description}>' def __eq__(self, other): if isinstance(other, StandardName): return self.name == other.name and self.units == other.units and self.description == other.description elif isinstance(other, str): return self.name == other raise TypeError(f'Cannot compare StandardName with {type(other)}') def _repr_html_(self, checkbox_state='checked'): # collapsable html representation if self.is_vector(): sn_name = f'{self.name} (vector quantity)' else: sn_name = self.name from time import perf_counter_ns _id = self.name + perf_counter_ns().__str__() out = f"""<ul style="list-style-type: none;" class="h5grp-sections"> <li> <input id="group-{_id}" type="checkbox" {checkbox_state}> <label style="font-weight: bold" for="group-{_id}"> {sn_name}</label> <ul class="h5tb-attr-list"> """ out += f' <li style="list-style-type: none; font-style: italic">units : {self.units}</li>' out += f' <li style="list-style-type: none; font-style: italic">description : {self.description}</li>' out += """ </il> </ul> </ul>""" return out def equal_unit(self, other_unit: pint): """compares the base units of this standard name with another unit provided as a string or pint.Unit""" return equal_base_units(self.units, other_unit) @staticmethod def check_syntax(standard_name: str): """formal check of the syntax""" if not isinstance(standard_name, str): raise TypeError(f'Standard name must be type string but is {type(standard_name)}') if len(standard_name) == 0: raise errors.StandardNameError('Name too short!') if re.sub(consts.VALID_CHARACTERS, '', standard_name) != standard_name: raise errors.StandardNameError('Invalid special characters in name ' f'"{standard_name}": Only "{consts.VALID_CHARACTERS}" ' 'is allowed.') if consts.PATTERN != '' and consts.PATTERN is not None: if re.match(consts.PATTERN, standard_name): raise errors.StandardNameError( f'Standard name "{standard_name}" does not match pattern "{consts.PATTERN}"') def to_dict(self) -> Dict: """Return dictionary representation of StandardName""" return dict(name=self.name, units=str(self.units), description=self.description) def check(self, snt: "StandardNameTable"): """check if is a valid standard name of the provided table""" return snt.check(self.name) def is_vector(self) -> bool: """check if is a vector""" return self._is_vector