diff --git a/CHANGES.rst b/CHANGES.rst index b28c92180..dad298a91 100644 --- a/CHANGES.rst +++ b/CHANGES.rst @@ -4,12 +4,16 @@ Changelog v0.49.0 (unreleased) -------------------- -Contributors to this version: Trevor James Smith (:user:`Zeitsperre`). +Contributors to this version: Trevor James Smith (:user:`Zeitsperre`), Pascal Bourgault (:user:`aulemahal`). Announcements ^^^^^^^^^^^^^ * `xclim` has migrated its development branch name from `master` to `main`. (:issue:`1667`, :pull:`1669`). +Internal changes +^^^^^^^^^^^^^^^^ +* Added "doymin" and "doymax" to the possible operations of ``generic.stats``. Fixed a warning issue when ``op`` was "integral". (:pull:`1672`). + v0.48.2 (2024-02-26) -------------------- Contributors to this version: Juliette Lavoie (:user:`juliettelavoie`). diff --git a/tests/test_generic_indicators.py b/tests/test_generic_indicators.py index fa9737ff8..6411e1479 100644 --- a/tests/test_generic_indicators.py +++ b/tests/test_generic_indicators.py @@ -1,6 +1,7 @@ from __future__ import annotations import numpy as np +import pytest from xclim import generic, set_options @@ -84,10 +85,14 @@ def test_empty(self, ndq_series): class TestStats: """See other tests in test_land::TestStats""" - def test_simple(self, pr_series, random): + @pytest.mark.parametrize( + "op,word", + [("min", "Minimum"), ("integral", "Integral"), ("doymin", "Day of minimum")], + ) + def test_simple(self, pr_series, random, op, word): pr = pr_series(random.random(400)) - out = generic.stats(pr, freq="YS", op="min", season="MAM") - assert out.units == pr.units + out = generic.stats(pr, freq="YS", op=op) + assert out.long_name == f"{word} of variable" def test_ndq(self, ndq_series): out = generic.stats(ndq_series, freq="YS", op="min", season="MAM") diff --git a/xclim/core/formatting.py b/xclim/core/formatting.py index b5cd8ab83..dbbde8f44 100644 --- a/xclim/core/formatting.py +++ b/xclim/core/formatting.py @@ -186,7 +186,11 @@ def _match_value(self, value): "m10": ["october"], "m11": ["november"], "m12": ["december"], - # Arguments to "op / reducer / stat" + # Arguments to "op / reducer / stat" (for example for generic.stats) + "integral": ["integrated", "integral"], + "count": ["count"], + "doymin": ["day of minimum"], + "doymax": ["day of maximum"], "mean": ["average"], "max": ["maximal", "maximum"], "min": ["minimal", "minimum"], diff --git a/xclim/data/fr.json b/xclim/data/fr.json index 4acf7f6fd..110c373b8 100644 --- a/xclim/data/fr.json +++ b/xclim/data/fr.json @@ -112,6 +112,22 @@ "m12": [ "decembre" ], + "integral": [ + "intégré", + "intégrée", + "intégrés", + "intégrées", + "intégrale" + ], + "count": [ + "décompte" + ], + "doymin": [ + "jour du minimum" + ], + "doymax": [ + "jour du maximum" + ], "mean": [ "moyen", "moyenne", diff --git a/xclim/indices/generic.py b/xclim/indices/generic.py index 8d92d08c1..07b109bc2 100644 --- a/xclim/indices/generic.py +++ b/xclim/indices/generic.py @@ -93,6 +93,8 @@ def select_resample_op( """ da = select_time(da, **indexer) r = da.resample(time=freq) + if op in _xclim_ops: + op = _xclim_ops[op] if isinstance(op, str): out = getattr(r, op.replace("integral", "sum"))(dim="time", keep_attrs=True) else: @@ -164,6 +166,9 @@ def doymin(da: xr.DataArray) -> xr.DataArray: return to_agg_units(out, da, "doymin") +_xclim_ops = {"doymin": doymin, "doymax": doymax} + + def default_freq(**indexer) -> str: """Return the default frequency.""" freq = "YS-JAN"