Source code for axsdb.units

"""
Unit handling components, based on the `Pint <https://github.com/hgrecco/pint>`__
library.

.. note::
    By default,
    `Pint's application registry <https://pint.readthedocs.io/en/stable/getting/pint-in-your-projects.html#having-a-shared-registry>`__
    is used.
"""

from __future__ import annotations

from typing import Any
import xarray as xr
import pint

# Internal unit registry. If None, use application registry
_ureg: pint.UnitRegistry | None = None


[docs] def set_unit_registry(ureg: pint.UnitRegistry | None) -> None: """ Set internal unit registry. Parameters ---------- ureg : pint.UnitRegistry or None New default unit registry. Set to ``None`` to reset to the default (the application registry). """ global _ureg _ureg = ureg
[docs] def get_unit_registry() -> pint.UnitRegistry: """ Access the internal unit registry. By default, the Pint application registry is returned. """ global _ureg return _ureg if _ureg is not None else pint.get_application_registry()
[docs] def ensure_units( value: Any, default_units: pint.Unit, convert: bool = False ) -> pint.Quantity: """ Ensure that a value is wrapped in a Pint quantity container. Parameters ---------- value Checked value. default_units : pint.Unit Units to use to initialize the :class:`pint.Quantity` if ``value`` is not a :class:`pint.Quantity`. convert : bool, default: False If ``True``, ``value`` will also be converted to ``default_units`` if it is a :class:`pint.Quantity`. Returns ------- Converted ``value``. """ if isinstance(value, pint.Quantity): if convert: return value.to(default_units) else: return value else: return value * default_units
[docs] def xarray_to_quantity(da: xr.DataArray) -> pint.Quantity: """ Converts a :class:`~xarray.DataArray` to a :class:`~pint.Quantity`. The array's ``attrs`` metadata mapping must contain a ``units`` field. Parameters ---------- da : DataArray :class:`~xarray.DataArray` instance which will be converted. Returns ------- quantity The corresponding Pint quantity. Raises ------ ValueError If array attributes do not contain a ``units`` field. Notes ----- This function can also be used on coordinate variables. """ try: units = da.attrs["units"] except KeyError as e: raise ValueError("this DataArray has no 'units' attribute field") from e ureg = get_unit_registry() return ureg.Quantity(da.values, units)