diff --git a/enacts/calc.py b/enacts/calc.py index 7fa22942..7f6c2998 100644 --- a/enacts/calc.py +++ b/enacts/calc.py @@ -619,6 +619,14 @@ def daily_tobegroupedby_season( return daily_tobegroupedby_season +def dayofyear366(time_coord): + """maps dates into 1-to-366 integers day-of-year""" + return xr.where( + (~time_coord.dt.is_leap_year) & (time_coord.dt.dayofyear >= (31+29)), + time_coord.dt.dayofyear + 1, + time_coord.dt.dayofyear, + ) + # Seasonal Functions def seasonal_onset_date( diff --git a/enacts/onset/tests/test_calc.py b/enacts/onset/tests/test_calc.py index 71ac18c4..6e2a9089 100644 --- a/enacts/onset/tests/test_calc.py +++ b/enacts/onset/tests/test_calc.py @@ -277,6 +277,33 @@ def test_water_balance_et_has_T_reduce_True(): assert np.array_equal(wb.soil_moisture, expected) +def test_dayofyear366(): + + t = pd.date_range(start="2000-01-01", end="2005-02-28", freq="1D") + data = xr.DataArray(range(t.size), dims=["T"], coords={"T": t}) + data_clim = (data + .groupby(calc.dayofyear366(data["T"])) + .mean() + .rename({"group": "T_doy"}) + ) + print(data_clim) + #Let's have anomalies computed on a random other slice of the data + data_ano = data.sel(T=slice("2000-02-28", "2005-02-28")) + data_ano = (data_ano + .groupby(calc.dayofyear366(data_ano["T"])) + #can still do non-reducing transformation if feel like it + .cumsum() + #compute ano + .groupby(calc.dayofyear366(data_ano["T"])) + #I like the idea of having a reserved name for daily clim dim + #other than "group" but maybe not necessary... + - data_clim.rename({"T_doy": "group"}) + ) + print(data_ano) + + assert True + + def test_daily_tobegroupedby_season_cuts_on_days(): precip = data_test_calc.multi_year_data_sample()