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: object

Unit 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.

__call__(value: T, units: str | None = '') list[float] | T

Call self as a function.

__dict__ = mappingproxy({'__module__': 'sasdata.data_util.nxsunit', '__firstlineno__': 350, '__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__': {'_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__ = 350
__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, ConversionType]] = None

Scale converter, mapping unit name to scale factor or (scale, offset) for temperature units.

scaleoffset: float = None
property units: str
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