sasdata.data_util.nxsunit module¶
Define unit conversion support for NeXus style units.
The unit format is somewhat complicated. There are variant spellings and incorrect capitalization to worry about, as well as forms such as “mili*metre” and “1e-7 seconds”.
This is a minimal implementation of units including only what I happen to need now. It does not support the complete dimensional analysis provided by the package udunits on which NeXus is based, or even the units used in the NeXus definition files.
Unlike other units packages, this package does not carry the units along with the value but merely provides a conversion function for transforming values.
Usage example:
import nxsunit
u = nxsunit.Converter('mili*metre') # Units stored in mm
v = u(3000,'m') # Convert the value 3000 mm into meters
NeXus example:
# Load sample orientation in radians regardless of how it is stored.
# 1. Open the path
file.openpath('/entry1/sample/sample_orientation')
# 2. scan the attributes, retrieving 'units'
units = [for attr,value in file.attrs() if attr == 'units']
# 3. set up the converter (assumes that units actually exists)
u = nxsunit.Converter(units[0])
# 4. read the data and convert to the correct units
v = u(file.read(),'radians')
This is a standalone module, not relying on either DANSE or NeXus, and can be used for other unit conversion tasks.
Note: minutes are used for angle and seconds are used for time. We cannot tell what the correct interpretation is without knowing something about the fields themselves. If this becomes an issue, we will need to allow the application to set the dimension for the unit rather than inferring the dimension from an example unit.
- class sasdata.data_util.nxsunit.Converter(units: str | None = None, dimension: List[str] | None = None)¶
Bases:
objectUnit converter for NeXus style units.
The converter is initialized with the units of the source value. Various source values can then be converted to target values based on target value name.
- __annotate_func__ = None¶
- __annotations_cache__ = {'_units': 'List[str]', 'dimension': 'List[str]', 'scalebase': 'float', 'scalemap': 'List[Dict[str, ConversionType]]', 'scaleoffset': 'float', 'units': 'str'}¶
- __call__(value: T, units: str | None = '') List[float] | T¶
Call self as a function.
- __dict__ = mappingproxy({'__module__': 'sasdata.data_util.nxsunit', '__firstlineno__': 349, '__doc__': '\nUnit converter for NeXus style units.\n\nThe converter is initialized with the units of the source value. Various\nsource values can then be converted to target values based on target\nvalue name.\n', '_units': None, 'dimension': None, 'scalemap': None, 'scalebase': None, 'scaleoffset': None, 'units': <property object>, '__init__': <function Converter.__init__>, 'scale': <function Converter.scale>, '_scale_with_offset': <function Converter._scale_with_offset>, '_get_scale_for_units': <function Converter._get_scale_for_units>, 'get_compatible_units': <function Converter.get_compatible_units>, '__call__': <function Converter.__call__>, '__static_attributes__': ('_units', 'dimension', 'scalebase', 'scalemap', 'scaleoffset', 'units'), '__dict__': <attribute '__dict__' of 'Converter' objects>, '__weakref__': <attribute '__weakref__' of 'Converter' objects>, '__annotations_cache__': {'_units': 'List[str]', 'dimension': 'List[str]', 'scalemap': 'List[Dict[str, ConversionType]]', 'scalebase': 'float', 'scaleoffset': 'float', 'units': 'str'}})¶
- __doc__ = '\nUnit converter for NeXus style units.\n\nThe converter is initialized with the units of the source value. Various\nsource values can then be converted to target values based on target\nvalue name.\n'¶
- __firstlineno__ = 349¶
- __init__(units: str | None = None, dimension: List[str] | None = None)¶
- __module__ = 'sasdata.data_util.nxsunit'¶
- __static_attributes__ = ('_units', 'dimension', 'scalebase', 'scalemap', 'scaleoffset', 'units')¶
- __weakref__¶
list of weak references to the object
- _get_scale_for_units(units: List[str])¶
Protected method to get scale factor and scale offset as a combined value
- _scale_with_offset(value: float, scale_base: Tuple[float, float]) float¶
Scale the given value and add the offset using the units string supplied
- _units: List[str] = None¶
Name of the source units (km, Ang, us, …)
- dimension: List[str] = None¶
Type of the source units (distance, time, frequency, …)
- get_compatible_units() List[str]¶
Return a list of compatible units for the current Convertor object
- scale(units: str = '', value: T = None) List[float] | T¶
Scale the given value using the units string supplied
- scalebase: float = None¶
Scale base for the source units
- scalemap: List[Dict[str, float | Tuple[float, float]]] = None¶
Scale converter, mapping unit name to scale factor or (scale, offset) for temperature units.
- scaleoffset: float = None¶
- property units: str¶
- class sasdata.data_util.nxsunit.TypeVar¶
Bases:
objectType variable.
The preferred way to construct a type variable is via the dedicated syntax for generic functions, classes, and type aliases:
class Sequence[T]: # T is a TypeVar ...
This syntax can also be used to create bound and constrained type variables:
# S is a TypeVar bound to str class StrSequence[S: str]: ... # A is a TypeVar constrained to str or bytes class StrOrBytesSequence[A: (str, bytes)]: ...
Type variables can also have defaults:
- class IntDefault[T = int]:
…
However, if desired, reusable type variables can also be constructed manually, like so:
T = TypeVar('T') # Can be anything S = TypeVar('S', bound=str) # Can be any subtype of str A = TypeVar('A', str, bytes) # Must be exactly str or bytes D = TypeVar('D', default=int) # Defaults to int
Type variables exist primarily for the benefit of static type checkers. They serve as the parameters for generic types as well as for generic function and type alias definitions.
The variance of type variables is inferred by type checkers when they are created through the type parameter syntax and when
infer_variance=Trueis passed. Manually created type variables may be explicitly marked covariant or contravariant by passingcovariant=Trueorcontravariant=True. By default, manually created type variables are invariant. See PEP 484 and PEP 695 for more details.- __bound__¶
- __constraints__¶
- __contravariant__¶
- __covariant__¶
- __default__¶
- __doc__ = "Type variable.\n\nThe preferred way to construct a type variable is via the dedicated\nsyntax for generic functions, classes, and type aliases::\n\n class Sequence[T]: # T is a TypeVar\n ...\n\nThis syntax can also be used to create bound and constrained type\nvariables::\n\n # S is a TypeVar bound to str\n class StrSequence[S: str]:\n ...\n\n # A is a TypeVar constrained to str or bytes\n class StrOrBytesSequence[A: (str, bytes)]:\n ...\n\nType variables can also have defaults:\n\n class IntDefault[T = int]:\n ...\n\nHowever, if desired, reusable type variables can also be constructed\nmanually, like so::\n\n T = TypeVar('T') # Can be anything\n S = TypeVar('S', bound=str) # Can be any subtype of str\n A = TypeVar('A', str, bytes) # Must be exactly str or bytes\n D = TypeVar('D', default=int) # Defaults to int\n\nType variables exist primarily for the benefit of static type\ncheckers. They serve as the parameters for generic types as well\nas for generic function and type alias definitions.\n\nThe variance of type variables is inferred by type checkers when they\nare created through the type parameter syntax and when\n``infer_variance=True`` is passed. Manually created type variables may\nbe explicitly marked covariant or contravariant by passing\n``covariant=True`` or ``contravariant=True``. By default, manually\ncreated type variables are invariant. See PEP 484 and PEP 695 for more\ndetails.\n"¶
- __infer_variance__¶
- __module__ = 'typing'¶
- __mro_entries__(object, /)¶
- __name__ = 'TypeVar'¶
- classmethod __new__(*args, **kwargs)¶
- __or__(value, /)¶
Return self|value.
- __reduce__()¶
Helper for pickle.
- __repr__()¶
Return repr(self).
- __ror__(value, /)¶
Return value|self.
- __typing_prepare_subst__(alias, args, /)¶
- __typing_subst__(arg, /)¶
- evaluate_bound¶
- evaluate_constraints¶
- evaluate_default¶
- has_default()¶
- class sasdata.data_util.nxsunit.Union¶
Bases:
objectRepresent a union type
E.g. for int | str
- __args__¶
- classmethod __class_getitem__(object, /)¶
See PEP 585
- __doc__ = 'Represent a union type\n\nE.g. for int | str'¶
- __eq__(value, /)¶
Return self==value.
- __ge__(value, /)¶
Return self>=value.
- __getattribute__(name, /)¶
Return getattr(self, name).
- __getitem__(key, /)¶
Return self[key].
- __gt__(value, /)¶
Return self>value.
- __hash__()¶
Return hash(self).
- __le__(value, /)¶
Return self<=value.
- __lt__(value, /)¶
Return self<value.
- __mro_entries__(object, /)¶
- __name__ = 'Union'¶
- __ne__(value, /)¶
Return self!=value.
- __or__(value, /)¶
Return self|value.
- __origin__¶
Always returns the type
- __parameters__¶
Type variables in the types.UnionType.
- __qualname__ = 'Union'¶
- __repr__()¶
Return repr(self).
- __ror__(value, /)¶
Return value|self.
- sasdata.data_util.nxsunit._build_all_units()¶
Fill in the global variables DIMENSIONS and AMBIGUITIES for all available dimensions.
- sasdata.data_util.nxsunit._build_degree_units(name: str, symbol: str, conversion: float | Tuple[float, float]) Dict[str, float | Tuple[float, float]]¶
Builds variations on the temperature unit name, including the degree symbol or the word degree.
- sasdata.data_util.nxsunit._build_inv_n_metric_units(unit: str, abbr: str, n: int = 2) Dict[str, float | Tuple[float, float]]¶
Using the return from _build_metric_units, build inverse to the nth power variations on all units (1/x^n, invx^n, x^{-n} and x^-n)
- sasdata.data_util.nxsunit._build_inv_n_units(names: Sequence[str], conversion: float | Tuple[float, float], n: int = 2) Dict[str, float | Tuple[float, float]]¶
Builds variations on inverse x to the nth power units, including 1/x^n, invx^n, x^-n and x^{-n}.
- sasdata.data_util.nxsunit._build_metric_units(unit: str, abbr: str) Dict[str, float]¶
Construct standard SI names for the given unit. Builds e.g.,
s, ns, n*s, n_s second, nanosecond, nano*second, nano_second seconds, nanoseconds, nano*seconds, nano_seconds
Includes prefixes for femto through peta.
Ack! Allows, e.g., Coulomb and coulomb even though Coulomb is not a unit because some NeXus files store it that way!
Returns a dictionary of names and scales.
- sasdata.data_util.nxsunit._build_plural_units(**kw: Dict[str, float | Tuple[float, float]]) Dict[str, float | Tuple[float, float]]¶
Construct names for the given units. Builds singular and plural form.
- sasdata.data_util.nxsunit._format_unit_structure(unit: str | None = None) List[str]¶
Format units a common way :param unit: Unit string to be formatted :return: Formatted unit string
- sasdata.data_util.nxsunit.standardize_units(unit: str | None) List[str]¶
Convert supplied units to a standard format for maintainability :param unit: Raw unit as supplied :return: Unit with known, reduced values