From f42e166f6da6b5ef0591b476de9e98e666663527 Mon Sep 17 00:00:00 2001 From: Pascal Bourgault Date: Thu, 17 Oct 2024 14:02:10 -0400 Subject: [PATCH 1/2] fix subdaily rate2amount - add lwe length to amount to hydro --- CHANGELOG.rst | 2 ++ tests/test_units.py | 14 ++++++++++++++ xclim/core/units.py | 12 ++++++++---- 3 files changed, 24 insertions(+), 4 deletions(-) diff --git a/CHANGELOG.rst b/CHANGELOG.rst index 2a7db84cb..8f968ec8e 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -33,6 +33,8 @@ New features and enhancements Bug fixes ^^^^^^^^^ +* Fixed ``rate2amount`` and ``amount2rate`` for sub-daily frequencies. (:issue:`1962`, :pull:`1963`). +* Added the liquid water equivalent thickness ("[length]") to amount ("[mass]/[area]") transformation to the ``hydro`` context (the inverse operation was already there). (:pull:`1963`). * Fixed a small inefficiency in ``_otc_adjust``, and the `standardize` method of `OTC/dOTC` is now applied on individual variable (:pull:`1890`, :pull:`1896`). * Remove deprecated cells in the tutorial notebook `sdba.ipynb` (:pull:`1895`). diff --git a/tests/test_units.py b/tests/test_units.py index f330519cf..a0781ad4e 100644 --- a/tests/test_units.py +++ b/tests/test_units.py @@ -234,6 +234,20 @@ def test_rate2amount(pr_series): np.testing.assert_array_equal(am_ys, 86400 * np.array([365, 366, 365])) +@pytest.mark.parametrize( + "srcfreq, exp", [("h", 3600), ("min", 60), ("s", 1), ("ns", 1e-9)] +) +def test_rate2amount_subdaily(srcfreq, exp): + pr = xr.DataArray( + np.ones(1000), + dims=("time",), + coords={"time": xr.date_range("2019-01-01", periods=1000, freq=srcfreq)}, + attrs={"units": "kg m-2 s-1"}, + ) + am = rate2amount(pr) + np.testing.assert_array_equal(am, exp) + + def test_amount2rate(pr_series): pr = pr_series(np.ones(365 + 366 + 365), start="2019-01-01") am = rate2amount(pr) diff --git a/xclim/core/units.py b/xclim/core/units.py index c44f13367..c22d17b20 100644 --- a/xclim/core/units.py +++ b/xclim/core/units.py @@ -90,6 +90,11 @@ "[length]", lambda ureg, x: x / (1000 * ureg.kg / ureg.m**3), ) +hydro.add_transformation( + "[length]", + "[mass] / [length]**2", + lambda ureg, x: x * (1000 * ureg.kg / ureg.m**3), +) hydro.add_transformation( "[mass] / [length]**2 / [time]", "[length] / [time]", @@ -461,12 +466,11 @@ def cf_conversion( FREQ_UNITS = { "D": "d", "W": "week", - "h": "h", } """ Resampling frequency units for :py:func:`xclim.core.units.infer_sampling_units`. -Mapping from offset base to CF-compliant unit. Only constant-length frequencies are included. +Mapping from offset base to CF-compliant unit. Only constant-length frequencies that are not also pint units are included """ @@ -718,7 +722,7 @@ def _rate_and_amount_converter( "can be used as the sampling rate, pass `sampling_rate_from_coord=True`." ) from err if freq is not None: - multi, base, start_anchor, _ = parse_offset(freq) + _, base, start_anchor, _ = parse_offset(freq) if base in ["M", "Q", "A", "Y"]: start = time.indexes[dim][0] if not start_anchor: @@ -743,7 +747,7 @@ def _rate_and_amount_converter( attrs=time.attrs, ) else: - m, u = multi, FREQ_UNITS[base] + m, u = infer_sampling_units(da, freq) out: xr.DataArray # Freq is month, season or year, which are not constant units, or simply freq is not inferrable. From 2184e74d8319306354550323dc94f2731fd4fb60 Mon Sep 17 00:00:00 2001 From: Pascal Bourgault Date: Thu, 17 Oct 2024 14:30:04 -0400 Subject: [PATCH 2/2] Update xclim/core/units.py Co-authored-by: Trevor James Smith <10819524+Zeitsperre@users.noreply.github.com> --- xclim/core/units.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/xclim/core/units.py b/xclim/core/units.py index c22d17b20..38b21a3ff 100644 --- a/xclim/core/units.py +++ b/xclim/core/units.py @@ -470,7 +470,7 @@ def cf_conversion( """ Resampling frequency units for :py:func:`xclim.core.units.infer_sampling_units`. -Mapping from offset base to CF-compliant unit. Only constant-length frequencies that are not also pint units are included +Mapping from offset base to CF-compliant unit. Only constant-length frequencies that are not also pint units are included. """