diff --git a/src/xclim/core/indicator.py b/src/xclim/core/indicator.py index 7d417e2e1..37543fec6 100644 --- a/src/xclim/core/indicator.py +++ b/src/xclim/core/indicator.py @@ -1311,7 +1311,7 @@ def _format( # Add formatting {} around values to be able to replace them with _attrs_mapping using format. for k, v in args.items(): if isinstance(v, units.Quantity): - mba[k] = f"{v:g~P}" + mba[k] = f"{v:gcf}" elif isinstance(v, int | float): mba[k] = f"{v:g}" # TODO: What about InputKind.NUMBER_SEQUENCE diff --git a/src/xclim/core/units.py b/src/xclim/core/units.py index db2797de7..036835d3e 100644 --- a/src/xclim/core/units.py +++ b/src/xclim/core/units.py @@ -22,7 +22,6 @@ import pint import xarray as xr from boltons.funcutils import wraps -from pint import UndefinedUnitError from yaml import safe_load from xclim.core._exceptions import ValidationError @@ -64,20 +63,15 @@ units = deepcopy(cf_xarray.units.units) # Changing the default string format for units/quantities. # CF is implemented by cf-xarray, g is the most versatile float format. -# The following try/except logic can be removed when xclim drops support for pint < 0.24 (i.e. numpy <2.0). -try: - units.formatter.default_format = "gcf" -except UndefinedUnitError: - units.default_format = "gcf" - +units.formatter.default_format = "gcf" # CF-xarray forces numpy arrays even for scalar values, not sure why. # We don't want that in xclim, the magnitude of a scalar is a scalar (float). units.force_ndarray_like = False -# Precipitation units. This is an artificial unit that we're using to verify that a given unit can be converted into -# a precipitation unit. It is essentially added for convenience when writing `declare_units` decorators. +# Define dimensionalities for convenience with the `declare_units` decorator units.define("[precipitation] = [mass] / [length] ** 2 / [time]") units.define("[discharge] = [length] ** 3 / [time]") +units.define("[radiation] = [power] / [length]**2") # Default context. This is essentially a convenience, so that we can pass a context systemtically to pint's methods. null = pint.Context("none") @@ -110,6 +104,7 @@ # Set as application registry pint.set_application_registry(units) + with (files("xclim.data") / "variables.yml").open() as variables: CF_CONVERSIONS = safe_load(variables)["conversions"] _CONVERSIONS = {} @@ -136,10 +131,6 @@ def _func_register(func: Callable) -> Callable: return _func_register -# Radiation units -units.define("[radiation] = [power] / [length]**2") - - def units2pint( value: xr.DataArray | units.Unit | units.Quantity | dict | str, ) -> pint.Unit: diff --git a/tests/test_indicators.py b/tests/test_indicators.py index 8df70f4dd..20f71fdac 100644 --- a/tests/test_indicators.py +++ b/tests/test_indicators.py @@ -564,18 +564,18 @@ def test_formatting(pr_series): # pint 0.10 now pretty print day as d. assert ( out.attrs["long_name"] - == "Number of days with daily precipitation at or above 1 mm/d" + == "Number of days with daily precipitation at or above 1 mm d-1" ) assert out.attrs["description"] in [ - "Annual number of days with daily precipitation at or above 1 mm/d." + "Annual number of days with daily precipitation at or above 1 mm d-1." ] out = atmos.wetdays(pr_series(np.arange(366)), thresh=1.5 * units.mm / units.day) assert ( out.attrs["long_name"] - == "Number of days with daily precipitation at or above 1.5 mm/d" + == "Number of days with daily precipitation at or above 1.5 mm d-1" ) assert out.attrs["description"] in [ - "Annual number of days with daily precipitation at or above 1.5 mm/d." + "Annual number of days with daily precipitation at or above 1.5 mm d-1." ]