From f2687a706c95f8f754ec7f105bc7036b1e3b6763 Mon Sep 17 00:00:00 2001 From: Pascal Bourgault Date: Tue, 16 Apr 2024 16:57:24 -0400 Subject: [PATCH 1/4] fix snow season --- CHANGES.rst | 4 + tests/test_indices.py | 16 ++- tests/test_snow.py | 18 +++- xclim/data/fr.json | 20 +++- xclim/indicators/land/_snow.py | 35 +++++- xclim/indices/_threshold.py | 187 +++++++++++++++++++++------------ 6 files changed, 194 insertions(+), 86 deletions(-) diff --git a/CHANGES.rst b/CHANGES.rst index f6ad34277..6e735c430 100644 --- a/CHANGES.rst +++ b/CHANGES.rst @@ -10,6 +10,10 @@ Announcements ^^^^^^^^^^^^^ * `xclim` has migrated its development branch name from `master` to `main`. (:issue:`1667`, :pull:`1669`). +New indicators +^^^^^^^^^^^^^^ +* New ``snw_season_length`` and ``snd_season_length`` computing the duration between the start and the end of the snow season, both defined as the first day of a continuous period with snow above/under a threshold. Previous versions of these indicators were renamed ``snw_days_above`` and ``snd_days_above`` to better reflect what they computed : the number of days with snow above a given threshold (with no notion of continuity). (:issue:`1703`, :pull:`1708`). + Bug fixes ^^^^^^^^^ * Fixed an bug in sdba's ``map_groups`` that prevented passing DataArrays with cftime coordinates if the ``sdba_encode_cf`` option was True. (:issue:`1673`, :pull:`1674`). diff --git a/tests/test_indices.py b/tests/test_indices.py index e815b1766..9fb3896cf 100644 --- a/tests/test_indices.py +++ b/tests/test_indices.py @@ -2820,21 +2820,27 @@ def test_nan_slices(self, snd_series, snw_series): class TestSnowCover: - @pytest.mark.parametrize("length", [0, 10]) + @pytest.mark.parametrize("length", [0, 15]) def test_snow_season_length(self, snd_series, snw_series, length): a = np.zeros(366) - a[10 : 10 + length] = 0.3 + a[20 : 20 + length] = 0.3 snd = snd_series(a) # kg m-2 = 1000 kg m-3 * 1 m snw = snw_series(1000 * a) out = xci.snd_season_length(snd) assert len(out) == 2 - assert out[0] == length + if length == 0: + assert out.isnull().all() + else: + assert out[0] == length out = xci.snw_season_length(snw) assert len(out) == 2 - assert out[0] == length + if length == 0: + assert out.isnull().all() + else: + assert out[0] == length def test_continous_snow_season_start(self, snd_series, snw_series): a = np.arange(366) / 100.0 @@ -2851,7 +2857,7 @@ def test_continous_snow_season_start(self, snd_series, snw_series): out = xci.snw_season_start(snw) assert len(out) == 2 - np.testing.assert_array_equal(out, [snw.time.dt.dayofyear[0].data + 2, np.nan]) + np.testing.assert_array_equal(out, [snw.time.dt.dayofyear[0].data + 1, np.nan]) for attr in ["units", "is_dayofyear", "calendar"]: assert attr in out.attrs.keys() assert out.attrs["units"] == "" diff --git a/tests/test_snow.py b/tests/test_snow.py index 054f53a58..13b0ce5b0 100644 --- a/tests/test_snow.py +++ b/tests/test_snow.py @@ -19,7 +19,7 @@ class TestSnowDepthCoverDuration: def test_simple(self, snd_series): snd = snd_series(np.ones(110), start="2001-01-01") - out = land.snd_season_length(snd, freq="ME") + out = land.snd_days_above(snd, freq="ME") assert out.units == "days" np.testing.assert_array_equal(out, [31, 28, 31, np.nan]) @@ -30,16 +30,17 @@ class TestSnowWaterCoverDuration: ) def test_simple(self, snw_series, factor, exp): snw = snw_series(np.ones(110) * factor, start="2001-01-01") - out = land.snw_season_length(snw, freq="ME") + out = land.snw_days_above(snw, freq="ME") assert out.units == "days" np.testing.assert_array_equal(out, exp) -class TestContinuousSnowDepthCoverStartEnd: +class TestContinuousSnowDepthSeason: def test_simple(self, snd_series): a = np.zeros(365) # snow depth a[100:200] = 0.03 + a[150:160] = 0 snd = snd_series(a, start="2001-07-01") snd = snd.expand_dims(lat=[0, 1, 2]) @@ -51,12 +52,17 @@ def test_simple(self, snd_series): assert out.units == "" np.testing.assert_array_equal(out.isel(lat=0), snd.time.dt.dayofyear[200]) + out = land.snd_season_length(snd) + assert out.units == "days" + np.testing.assert_array_equal(out.isel(lat=0), 100) + -class TestContinuousSnowWaterCoverStartEnd: +class TestContinuousSnowWaterSeason: def test_simple(self, snw_series): a = np.zeros(365) # snow amount a[100:200] = 0.03 * 1000 + a[150:160] = 0 snw = snw_series(a, start="2001-07-01") snw = snw.expand_dims(lat=[0, 1, 2]) @@ -68,6 +74,10 @@ def test_simple(self, snw_series): assert out.units == "" np.testing.assert_array_equal(out.isel(lat=0), snw.time.dt.dayofyear[200]) + out = land.snw_season_length(snw) + assert out.units == "days" + np.testing.assert_array_equal(out.isel(lat=0), 100) + class TestSndMaxDoy: def test_simple(self, snd_series): diff --git a/xclim/data/fr.json b/xclim/data/fr.json index 110c373b8..37b20bde2 100644 --- a/xclim/data/fr.json +++ b/xclim/data/fr.json @@ -1005,9 +1005,9 @@ }, "SND_SEASON_LENGTH": { "long_name": "Durée de couvert de neige", - "description": "Nombre {freq:m} de jours où l'épaisseur de neige est au-dessus ou égale à {thresh}.", + "description": "La saison débute lorsque l'épaisseur de neige est au-dessus de {thresh} durant {window} jours et se termine lorsqu'elle redescend sous {thresh} durant {window} jours.", "title": "Durée du couvert de neige (épaisseur)", - "abstract": "Nombre de jours pendant lesquels l'épaisseur de neige est au-dessus ou égale à un seuil donné." + "abstract": "Durée de la saison de neige, qui débute lorsque la quantité de neige est au-dessus d'un seuil donné durant un nombre de jours donnés et qui se termine lorsqu'elle redescend sous le seuil pour la même durée." }, "SND_SEASON_START": { "long_name": "Date du début du couvert de neige continu", @@ -1021,11 +1021,17 @@ "title": "Date du fin du couvert de neige (épaisseur)", "abstract": "Première date à partir de laquelle l'épaisseur de neige est sous à un seuil donné pendant un nombre de jours consécutifs suite au début du couvert de neige." }, + "SND_DAYS_ABOVE": { + "long_name": "Nombre de jours avec de la neige au sol.", + "description": "Nombre {freq:m} de jours avec au moins {thresh} de neige au sol.", + "title": "Nombre de jours avec de la neige au sol (épaisseur)", + "abstract": "Nombre de jours avec une épaisseur de neige au sol au-dessus d'un seuil donné." + }, "SNW_SEASON_LENGTH": { "long_name": "Durée de couvert de neige", - "description": "Nombre {freq:m} de jours où la quantité de neige est au-dessus ou égale à {thresh}.", + "description": "La saison débute lorsque la quantité de neige est au-dessus de {thresh} durant {window} jours et se termine lorsqu'elle redescend sous {thresh} durant {window} jours.", "title": "Durée du couvert de neige (quantité)", - "abstract": "Nombre de jours pendant lesquels la quantité de neige est au-dessus ou égale à un seuil donné." + "abstract": "Durée de la saison de neige, qui débute lorsque l'épaisseur de neige est au-dessus d'un seuil donné durant un nombre de jours donnés et qui se termine lorsqu'elle redescend sous le seuil pour la même durée." }, "SNW_SEASON_START": { "long_name": "Date du début du couvert de neige continu", @@ -1039,6 +1045,12 @@ "title": "Date du fin du couvert de neige (quantité)", "abstract": "Première date à partir de laquelle la quantité de neige est sous à un seuil donné pendant un nombre de jours consécutifs suite au début du couvert de neige." }, + "SNW_DAYS_ABOVE": { + "long_name": "Nombre de jours avec de la neige au sol.", + "description": "Nombre {freq:m} de jours avec au moins {thresh} de neige au sol.", + "title": "Nombre de jours avec de la neige au sol (quantité)", + "abstract": "Nombre de jours avec une quantité de neige au sol au-dessus d'un seuil donné." + }, "SND_MAX": { "long_name": "Épaisseur de neige maximale", "description": "Épaisseur maximale {freq:f} de la neige.", diff --git a/xclim/indicators/land/_snow.py b/xclim/indicators/land/_snow.py index 7ca13c007..c94c43419 100644 --- a/xclim/indicators/land/_snow.py +++ b/xclim/indicators/land/_snow.py @@ -6,6 +6,7 @@ __all__ = [ "blowing_snow", + "snd_days_above", "snd_max_doy", "snd_season_end", "snd_season_length", @@ -14,6 +15,7 @@ "snd_to_snw", "snow_depth", "snow_melt_we_max", + "snw_days_above", "snw_max", "snw_max_doy", "snw_season_end", @@ -43,8 +45,10 @@ class SnowWithIndexing(ResamplingIndicatorWithIndexing): identifier="snd_season_length", units="days", long_name="Snow cover duration", - description="The {freq} number of days with snow depth greater than or equal to {thresh}.", - abstract="Number of days when the snow depth is greater than or equal to a given threshold.", + description=( + "The duration of the snow season, starting with at least {window} days with snow depth above {thresh} " + "and ending with at least {window} days with snow depth under {thresh}." + ), compute=xci.snd_season_length, ) @@ -53,8 +57,10 @@ class SnowWithIndexing(ResamplingIndicatorWithIndexing): identifier="snw_season_length", units="days", long_name="Snow cover duration", - description="The {freq} number of days with snow amount greater than or equal to {thresh}.", - abstract="Number of days when the snow amount is greater than or equal to a given threshold.", + description=( + "The duration of the snow season, starting with at least {window} days with snow amount above {thresh} " + "and ending with at least {window} days with snow amount under {thresh}." + ), compute=xci.snw_season_length, ) @@ -231,3 +237,24 @@ class SnowWithIndexing(ResamplingIndicatorWithIndexing): var_name="snd", compute=xci.snw_to_snd, ) + + +snd_days_above = SnowWithIndexing( + title="Days with snow (depth)", + identifier="snd_days_above", + units="days", + long_name="Number of days with snow", + description="The {freq} number of days with snow depth greater than or equal to {thresh}.", + abstract="Number of days when the snow depth is greater than or equal to a given threshold.", + compute=xci.snd_days_above, +) + +snw_days_above = SnowWithIndexing( + title="Days with snow (amount)", + identifier="snw_days_above", + units="days", + long_name="Number of days with snow", + description="The {freq} number of days with snow amount greater than or equal to {thresh}.", + abstract="Number of days when the snow amount is greater than or equal to a given threshold.", + compute=xci.snw_days_above, +) diff --git a/xclim/indices/_threshold.py b/xclim/indices/_threshold.py index 5fff2322e..a770f303c 100644 --- a/xclim/indices/_threshold.py +++ b/xclim/indices/_threshold.py @@ -75,12 +75,14 @@ "rprctot", "sea_ice_area", "sea_ice_extent", + "snd_days_above", "snd_season_end", "snd_season_length", "snd_season_start", "snd_storm_days", "snowfall_frequency", "snowfall_intensity", + "snw_days_above", "snw_season_end", "snw_season_length", "snw_season_start", @@ -352,12 +354,8 @@ def snd_season_end( ) -> xarray.DataArray: r"""End date of continuous snow depth cover. - First day after the start of the continuous snow depth cover when snow depth is below a threshold (default: 2 cm) - for at least `N` (default: 14) consecutive days. - - Warnings - -------- - The default `freq` is valid for the northern hemisphere. + First day after the start of the continuous snow depth cover when snow depth is below a threshold + for at least `N` consecutive days. Parameters ---------- @@ -368,14 +366,12 @@ def snd_season_end( window : int Minimum number of days with snow depth below threshold. freq : str - Resampling frequency. + Resampling frequency. The default value is chosen for the northern hemisphere. Returns ------- xarray.DataArray, [dimensionless] - First day after the start of the continuous snow depth cover when the snow depth - goes below a threshold for a minimum duration. - If there is no such day, returns np.nan. + First day after the start of the continuous snow depth cover. References ---------- @@ -398,19 +394,14 @@ def snd_season_end( @declare_units(snw="[mass]/[area]", thresh="[mass]/[area]") def snw_season_end( snw: xarray.DataArray, - thresh: Quantified = "20.00 kg m-2", + thresh: Quantified = "4 kg m-2", window: int = 14, freq: str = "YS-JUL", ) -> xarray.DataArray: - r"""End date of continuous snow water cover. + r"""End date of continuous snow cover. First day after the start of the continuous snow water cover - when snow water is below a threshold (Current default: 20 kg m-2. xclim >=0.47.0 default: 4 kg m-2) - for at least `N` (default: 14) consecutive days. - - Warnings - -------- - The default `freq` is valid for the northern hemisphere. + when snow water is below a threshold for at least `N` consecutive days. Parameters ---------- @@ -421,23 +412,17 @@ def snw_season_end( window : int Minimum number of days with snow water below threshold. freq : str - Resampling frequency. + Resampling frequency. The default value is chosen for the northern hemisphere. Returns ------- xarray.DataArray, [dimensionless] - First day after the start of the continuous snow water cover when the snow water - goes below a threshold for a minimum duration. - If there is no such day, returns np.nan. + First day after the start of the continuous snow amount cover. References ---------- :cite:cts:`chaumont_elaboration_2017` """ - if thresh == "20.00 kg m-2": - warnings.warn( - "The default value for this threshold will change in xclim>=0.47.0, from `20 kg m-2` to `4 kg m-2`." - ) valid = at_least_n_valid(snw.where(snw > 0), n=1, freq=freq) thresh = convert_units_to(thresh, snw) @@ -461,12 +446,8 @@ def snd_season_start( ) -> xarray.DataArray: r"""Start date of continuous snow depth cover. - Day of year when snow depth is above or equal to a threshold (default: 2 cm) - for at least `N` (default: 14) consecutive days. - - Warnings - -------- - The default `freq` is valid for the northern hemisphere. + Day of year when snow depth is above or equal to a threshold + for at least `N` consecutive days. Parameters ---------- @@ -477,13 +458,12 @@ def snd_season_start( window : int Minimum number of days with snow depth above or equal to threshold. freq : str - Resampling frequency. + Resampling frequency. The default value is chosen for the northern hemisphere. Returns ------- xarray.DataArray, [dimensionless] First day of the year when the snow depth is superior to a threshold for a minimum duration. - If there is no such day, returns np.nan. References ---------- @@ -511,18 +491,14 @@ def snd_season_start( @declare_units(snw="[mass]/[area]", thresh="[mass]/[area]") def snw_season_start( snw: xarray.DataArray, - thresh: Quantified = "20.00 kg m-2", + thresh: Quantified = "4 kg m-2", window: int = 14, freq: str = "YS-JUL", ) -> xarray.DataArray: r"""Start date of continuous snow water cover. - Day of year when snow water is above or equal to a threshold (Current default: 20 kg m-2. xclim >=0.47.0 default: 4 kg m-2) - for at least `N` (default: 14) consecutive days. - - Warnings - -------- - The default `freq` is valid for the northern hemisphere. + Day of year when snow water is above or equal to a threshold + for at least `N` consecutive days. Parameters ---------- @@ -531,25 +507,20 @@ def snw_season_start( thresh : str Threshold snow amount. window : int - Minimum number of days with snow water above or equal to threshold. + Minimum number of days with snow amount above or equal to threshold. freq : str Resampling frequency. Returns ------- xarray.DataArray, [dimensionless] - First day of the year when the snow water is superior to a threshold for a minimum duration. - If there is no such day, returns np.nan. + First day of the year when the snow amount is superior to a threshold for a minimum duration. References ---------- :cite:cts:`chaumont_elaboration_2017` """ - if thresh == "20.00 kg m-2": - warnings.warn( - "The default value for this threshold will change in xclim>=0.47.0, from `20 kg m-2` to `4 kg m-2`." - ) valid = at_least_n_valid(snw.where(snw > 0), n=1, freq=freq) thresh = convert_units_to(thresh, snw) @@ -569,6 +540,96 @@ def snw_season_start( return out.where(~valid) +@declare_units(snd="[length]", thresh="[length]") +def snd_season_length( + snd: xarray.DataArray, + thresh: Quantified = "2 cm", + window: int = 14, + freq: str = "YS-JUL", +) -> xarray.DataArray: + r"""Snow season length. + + The season starts when snow depth is above a threshold for at least `N` consecutive days + and stops when it drops below the same threshold for the same number of days. + + Parameters + ---------- + snd : xarray.DataArray + Surface snow thickness. + thresh : Quantified + Threshold snow thickness. + window : int + Minimum number of days with snow depth above and below threshold. + freq : str + Resampling frequency. The default value is chosen for the northern hemisphere. + + Returns + ------- + xarray.DataArray, [days] + Length of the snow season. + + References + ---------- + :cite:cts:`chaumont_elaboration_2017` + """ + valid = at_least_n_valid(snd.where(snd > 0), n=1, freq=freq) + + thresh = convert_units_to(thresh, snd) + cond = snd >= thresh + + out = ( + cond.resample(time=freq) + .map(rl.season, window=window, dim="time", coord="dayofyear") + .length + ) + return to_agg_units(out.where(~valid), snd, "count") + + +@declare_units(snw="[mass]/[area]", thresh="[mass]/[area]") +def snw_season_length( + snw: xarray.DataArray, + thresh: Quantified = "4 kg m-2", + window: int = 14, + freq: str = "YS-JUL", +) -> xarray.DataArray: + r"""Snow season length. + + The season starts when the snow amount is above a threshold for at least `N` consecutive days + and stops when it drops below the same threshold for the same number of days. + + Parameters + ---------- + snw : xarray.DataArray + Surface snow amount. + thresh : Quantified + Threshold snow amount. + window : int + Minimum number of days with snow amount above and below threshold. + freq : str + Resampling frequency. The default value is chosen for the northern hemisphere. + + Returns + ------- + xarray.DataArray, [days] + Length of the snow season. + + References + ---------- + :cite:cts:`chaumont_elaboration_2017` + """ + valid = at_least_n_valid(snw.where(snw > 0), n=1, freq=freq) + + thresh = convert_units_to(thresh, snw) + cond = snw >= thresh + + out = ( + cond.resample(time=freq) + .map(rl.season, window=window, dim="time", coord="dayofyear") + .length + ) + return to_agg_units(out.where(~valid), snw, "count") + + @declare_units(snd="[length]", thresh="[length]") def snd_storm_days( snd: xarray.DataArray, thresh: Quantified = "25 cm", freq: str = "YS-JUL" @@ -2101,7 +2162,7 @@ def hot_spell_frequency( @declare_units(snd="[length]", thresh="[length]") -def snd_season_length( +def snd_days_above( snd: xarray.DataArray, thresh: Quantified = "2 cm", freq: str = "YS-JUL", @@ -2111,10 +2172,6 @@ def snd_season_length( Number of days where surface snow depth is greater or equal to given threshold (default: 2 cm). - Warnings - -------- - The default `freq` is valid for the northern hemisphere. - Parameters ---------- snd : xarray.DataArray @@ -2122,14 +2179,14 @@ def snd_season_length( thresh : Quantified Threshold snow thickness. freq : str - Resampling frequency. + Resampling frequency. The default value is chosen for the northern hemisphere. op : {">", ">=", "gt", "ge"} Comparison operation. Default: ">=". Returns ------- xarray.DataArray, [time] - Number of days where snow depth is greater than or equal to threshold. + Number of days where snow depth is greater than or equal to {thresh}. """ valid = at_least_n_valid(snd, n=1, freq=freq) thresh = convert_units_to(thresh, snd) @@ -2138,19 +2195,15 @@ def snd_season_length( @declare_units(snw="[mass]/[area]", thresh="[mass]/[area]") -def snw_season_length( +def snw_days_above( snw: xarray.DataArray, - thresh: Quantified = "20.00 kg m-2", + thresh: Quantified = "4 kg m-2", freq: str = "YS-JUL", op: str = ">=", ) -> xarray.DataArray: - """The number of days with snow water above a threshold. + """The number of days with snow amount above a threshold. - Number of days where surface snow water is greater or equal to given threshold (Current default: 20 kg m-2. xclim >=0.47.0 default: 4 kg m-2). - - Warnings - -------- - The default `freq` is valid for the northern hemisphere. + Number of days where surface snow amount is greater or equal to given threshold. Parameters ---------- @@ -2159,20 +2212,16 @@ def snw_season_length( thresh : str Threshold snow amount. freq : str - Resampling frequency. + Resampling frequency. The default value is chosen for the northern hemisphere. op : {">", ">=", "gt", "ge"} Comparison operation. Default: ">=". Returns ------- xarray.DataArray, [time] - Number of days where snow water is greater than or equal to threshold. + Number of days where snow amount is greater than or equal to {thresh}. """ - if thresh == "20.00 kg m-2": - warnings.warn( - "The default value for this threshold will change in xclim>=0.47.0, from `20 kg m-2` to `4 kg m-2`." - ) valid = at_least_n_valid(snw, n=1, freq=freq) thresh = convert_units_to(thresh, snw) out = threshold_count(snw, op, thresh, freq) From fb3a2f9d7395a5dfb5e623c70d3358084cb29a25 Mon Sep 17 00:00:00 2001 From: Pascal Bourgault Date: Wed, 17 Apr 2024 15:13:16 -0400 Subject: [PATCH 2/4] Add breaking changes entry --- CHANGES.rst | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/CHANGES.rst b/CHANGES.rst index c8254346c..856b6d2b1 100644 --- a/CHANGES.rst +++ b/CHANGES.rst @@ -14,6 +14,10 @@ New indicators ^^^^^^^^^^^^^^ * New ``snw_season_length`` and ``snd_season_length`` computing the duration between the start and the end of the snow season, both defined as the first day of a continuous period with snow above/under a threshold. Previous versions of these indicators were renamed ``snw_days_above`` and ``snd_days_above`` to better reflect what they computed : the number of days with snow above a given threshold (with no notion of continuity). (:issue:`1703`, :pull:`1708`). +Breaking changes +^^^^^^^^^^^^^^^^ +* Indicators ``snw_season_length`` and ``snd_season_length`` have been modified, see above. + Bug fixes ^^^^^^^^^ * Fixed an bug in sdba's ``map_groups`` that prevented passing DataArrays with cftime coordinates if the ``sdba_encode_cf`` option was True. (:issue:`1673`, :pull:`1674`). From 6f7f81e81f2d282ccaafa9aed6ea36b2bdf952bf Mon Sep 17 00:00:00 2001 From: Pascal Bourgault Date: Wed, 17 Apr 2024 15:23:22 -0400 Subject: [PATCH 3/4] Snow season title adj - grammaire --- xclim/data/fr.json | 8 ++++---- xclim/indicators/land/_snow.py | 6 ------ xclim/indices/_threshold.py | 12 ++++++------ 3 files changed, 10 insertions(+), 16 deletions(-) diff --git a/xclim/data/fr.json b/xclim/data/fr.json index 37b20bde2..c5616065a 100644 --- a/xclim/data/fr.json +++ b/xclim/data/fr.json @@ -1012,13 +1012,13 @@ "SND_SEASON_START": { "long_name": "Date du début du couvert de neige continu", "description": "Première date à laquelle l'épaisseur de neige est au-dessus ou égale à {thresh} pendant au moins {window} jours consécutifs.", - "title": "Date du début du couvert de neige (épaisseur)", + "title": "Date de début du couvert de neige (épaisseur)", "abstract": "Première date à partir de laquelle l'épaisseur de neige est au-dessus ou égale à un seuil donné pendant un nombre de jours consécutifs." }, "SND_SEASON_END": { "long_name": "Date de fin du couvert de neige continu", "description": "Première date à laquelle l'épaisseur de neige passe sous {thresh} pendant au moins {window} jours consécutifs suite à l'établissement du couvert de neige.", - "title": "Date du fin du couvert de neige (épaisseur)", + "title": "Date de fin du couvert de neige (épaisseur)", "abstract": "Première date à partir de laquelle l'épaisseur de neige est sous à un seuil donné pendant un nombre de jours consécutifs suite au début du couvert de neige." }, "SND_DAYS_ABOVE": { @@ -1036,13 +1036,13 @@ "SNW_SEASON_START": { "long_name": "Date du début du couvert de neige continu", "description": "Première date à laquelle la quantité de neige est au-dessus ou égale à {thresh} pendant au moins {window} jours consécutifs.", - "title": "Date du début du couvert de neige (quantité)", + "title": "Date de début du couvert de neige (quantité)", "abstract": "Première date à partir de laquelle la quantité de neige est au-dessus ou égale à un seuil donné pendant un nombre de jours consécutifs." }, "SNW_SEASON_END": { "long_name": "Date de fin du couvert de neige continu", "description": "Première date à laquelle la quantité de neige passe sous {thresh} pendant au moins {window} jours consécutifs suite à l'établissement du couvert de neige.", - "title": "Date du fin du couvert de neige (quantité)", + "title": "Date de fin du couvert de neige (quantité)", "abstract": "Première date à partir de laquelle la quantité de neige est sous à un seuil donné pendant un nombre de jours consécutifs suite au début du couvert de neige." }, "SNW_DAYS_ABOVE": { diff --git a/xclim/indicators/land/_snow.py b/xclim/indicators/land/_snow.py index c94c43419..ff9de4da1 100644 --- a/xclim/indicators/land/_snow.py +++ b/xclim/indicators/land/_snow.py @@ -41,7 +41,6 @@ class SnowWithIndexing(ResamplingIndicatorWithIndexing): snd_season_length = SnowWithIndexing( - title="Snow cover duration (depth)", identifier="snd_season_length", units="days", long_name="Snow cover duration", @@ -53,7 +52,6 @@ class SnowWithIndexing(ResamplingIndicatorWithIndexing): ) snw_season_length = SnowWithIndexing( - title="Snow cover duration (amount)", identifier="snw_season_length", units="days", long_name="Snow cover duration", @@ -65,7 +63,6 @@ class SnowWithIndexing(ResamplingIndicatorWithIndexing): ) snd_season_start = Snow( - title="Start date of continuous snow depth cover", identifier="snd_season_start", standard_name="day_of_year", long_name="Start date of continuous snow depth cover", @@ -77,7 +74,6 @@ class SnowWithIndexing(ResamplingIndicatorWithIndexing): ) snw_season_start = Snow( - title="Start date of continuous snow amount cover", identifier="snw_season_start", standard_name="day_of_year", long_name="Start date of continuous snow amount cover", @@ -89,7 +85,6 @@ class SnowWithIndexing(ResamplingIndicatorWithIndexing): ) snd_season_end = Snow( - title="End date of continuous snow depth cover", identifier="snd_season_end", standard_name="day_of_year", long_name="End date of continuous snow depth cover", @@ -100,7 +95,6 @@ class SnowWithIndexing(ResamplingIndicatorWithIndexing): ) snw_season_end = Snow( - title="End date of continuous snow amount cover", identifier="snw_season_end", standard_name="day_of_year", long_name="End date of continuous snow amount cover", diff --git a/xclim/indices/_threshold.py b/xclim/indices/_threshold.py index a770f303c..e7186ff12 100644 --- a/xclim/indices/_threshold.py +++ b/xclim/indices/_threshold.py @@ -352,7 +352,7 @@ def snd_season_end( window: int = 14, freq: str = "YS-JUL", ) -> xarray.DataArray: - r"""End date of continuous snow depth cover. + r"""Snow cover end date (depth). First day after the start of the continuous snow depth cover when snow depth is below a threshold for at least `N` consecutive days. @@ -398,7 +398,7 @@ def snw_season_end( window: int = 14, freq: str = "YS-JUL", ) -> xarray.DataArray: - r"""End date of continuous snow cover. + r"""Snow cover end date (amount). First day after the start of the continuous snow water cover when snow water is below a threshold for at least `N` consecutive days. @@ -444,7 +444,7 @@ def snd_season_start( window: int = 14, freq: str = "YS-JUL", ) -> xarray.DataArray: - r"""Start date of continuous snow depth cover. + r"""Snow cover start date (depth). Day of year when snow depth is above or equal to a threshold for at least `N` consecutive days. @@ -495,7 +495,7 @@ def snw_season_start( window: int = 14, freq: str = "YS-JUL", ) -> xarray.DataArray: - r"""Start date of continuous snow water cover. + r"""Snow cover start date (amount). Day of year when snow water is above or equal to a threshold for at least `N` consecutive days. @@ -547,7 +547,7 @@ def snd_season_length( window: int = 14, freq: str = "YS-JUL", ) -> xarray.DataArray: - r"""Snow season length. + r"""Snow cover duration (depth). The season starts when snow depth is above a threshold for at least `N` consecutive days and stops when it drops below the same threshold for the same number of days. @@ -592,7 +592,7 @@ def snw_season_length( window: int = 14, freq: str = "YS-JUL", ) -> xarray.DataArray: - r"""Snow season length. + r"""Snow cover duration (amount). The season starts when the snow amount is above a threshold for at least `N` consecutive days and stops when it drops below the same threshold for the same number of days. From af3e3693273d58ee7bcef71bba722282412a3da6 Mon Sep 17 00:00:00 2001 From: Pascal Bourgault Date: Thu, 18 Apr 2024 09:57:10 -0400 Subject: [PATCH 4/4] Apply suggestions from code review MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Éric Dupuis <71575674+coxipi@users.noreply.github.com> --- xclim/data/fr.json | 2 +- xclim/indices/_threshold.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/xclim/data/fr.json b/xclim/data/fr.json index c5616065a..da193349f 100644 --- a/xclim/data/fr.json +++ b/xclim/data/fr.json @@ -1007,7 +1007,7 @@ "long_name": "Durée de couvert de neige", "description": "La saison débute lorsque l'épaisseur de neige est au-dessus de {thresh} durant {window} jours et se termine lorsqu'elle redescend sous {thresh} durant {window} jours.", "title": "Durée du couvert de neige (épaisseur)", - "abstract": "Durée de la saison de neige, qui débute lorsque la quantité de neige est au-dessus d'un seuil donné durant un nombre de jours donnés et qui se termine lorsqu'elle redescend sous le seuil pour la même durée." + "abstract": "Durée de la saison de neige, qui débute lorsque la quantité de neige est au-dessus d'un seuil donné durant un nombre de jours donné et qui se termine lorsqu'elle redescend sous le seuil pour la même durée." }, "SND_SEASON_START": { "long_name": "Date du début du couvert de neige continu", diff --git a/xclim/indices/_threshold.py b/xclim/indices/_threshold.py index e7186ff12..f08b27761 100644 --- a/xclim/indices/_threshold.py +++ b/xclim/indices/_threshold.py @@ -355,7 +355,7 @@ def snd_season_end( r"""Snow cover end date (depth). First day after the start of the continuous snow depth cover when snow depth is below a threshold - for at least `N` consecutive days. + for at least `window` consecutive days. Parameters ----------