IllegalMonthError for calculatng rx5day for a season from March until December for one year
MiriamSch opened this issue · 9 comments
- icclim version: 5.2.1
- Python version: 3.8.11
Description
I want to calculate the climate index rx5day for the season from March until December in one particular year (1971). However, I get an llegalMonthError: bad month number 13
.
If I change the season to March until November, no error occurs. -> slice_mode=['season',([3,4,5,6,7,8,9,10,11])
And if I aggregate the index per month, no error occurs. -> slice_mode=['month',([3,4,5,6,7,8,9,10,11,12])
Minimal reproducible example
rx5day = rx5day(in_files=climate_data_daily_tp_season, slice_mode=['season',([3,4,5,6,7,8,9,10,11,12])]).RX5day
climate_data_daily_tp_season is an xarray dataarray with daily precipitation values (units: m day-1) only for the selected time range (=season), that is from 1971-03-01 unil 1971-12-31 (see below).
<xarray.DataArray 'tp' (time: 306, latitude: 39, longitude: 57)>
array([[[7.28301518e-03, 7.04554655e-03, 7.14751147e-03, ...,
6.08131289e-04, 7.19747506e-04, 8.73158686e-04],
...
[1.90066732e-03, 1.63517799e-03, 1.26864016e-03, ...,
2.90336926e-03, 1.36739295e-03, 7.80833885e-04]]], dtype=float32)
Coordinates:
time (time) datetime64[ns] 1971-03-01 1971-03-02 ... 1971-12-31
longitude (longitude) float64 -4.5 -4.25 -4.0 -3.75 ... 8.75 9.0 9.25 9.5
latitude (latitude) float64 51.0 50.75 50.5 50.25 ... 42.0 41.75 41.5
spatial_ref int64 0
Attributes:
units: m day-1
long_name: Total precipitation
Output received
Traceback (most recent call last):
File "/dss/dsshome1/lxc0B/di75cey/venv/pyvenv_1/lib/python3.8/site-packages/dateutil/parser/_parser.py", line 649, in parse
ret = self._build_naive(res, default)
File "/dss/dsshome1/lxc0B/di75cey/venv/pyvenv_1/lib/python3.8/site-packages/dateutil/parser/_parser.py", line 1232, in _build_naive
if cday > monthrange(cyear, cmonth)[1]:
File "/dss/dsshome1/lrz/sys/spack/release/22.2.1/views/python/._3.8.11-extended/vyrdu7nuykwx7hmkj4c4hs5zjwgvfuh3/lib/python3.8/calendar.py", line 124, in monthrange
raise IllegalMonthError(month)
calendar.IllegalMonthError: bad month number 13; must be 1-12
The above exception was the direct cause of the following exception:
Traceback (most recent call last):
File "pandas/_libs/tslib.pyx", line 536, in pandas._libs.tslib.array_to_datetime
File "pandas/_libs/tslibs/parsing.pyx", line 281, in pandas._libs.tslibs.parsing.parse_datetime_string
File "/dss/dsshome1/lxc0B/di75cey/venv/pyvenv_1/lib/python3.8/site-packages/dateutil/parser/_parser.py", line 1368, in parse
return DEFAULTPARSER.parse(timestr, **kwargs)
File "/dss/dsshome1/lxc0B/di75cey/venv/pyvenv_1/lib/python3.8/site-packages/dateutil/parser/_parser.py", line 651, in parse
six.raise_from(ParserError(str(e) + ": %s", timestr), e)
File "<string>", line 3, in raise_from
dateutil.parser._parser.ParserError: bad month number 13; must be 1-12: 1971-13
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "pandas/_libs/tslib.pyx", line 547, in pandas._libs.tslib.array_to_datetime
TypeError: invalid string coercion to datetime
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "/dss/dsshome1/lxc0B/di75cey/venv/pyvenv_1/lib/python3.8/site-packages/dateutil/parser/_parser.py", line 649, in parse
ret = self._build_naive(res, default)
File "/dss/dsshome1/lxc0B/di75cey/venv/pyvenv_1/lib/python3.8/site-packages/dateutil/parser/_parser.py", line 1232, in _build_naive
if cday > monthrange(cyear, cmonth)[1]:
File "/dss/dsshome1/lrz/sys/spack/release/22.2.1/views/python/._3.8.11-extended/vyrdu7nuykwx7hmkj4c4hs5zjwgvfuh3/lib/python3.8/calendar.py", line 124, in monthrange
raise IllegalMonthError(month)
calendar.IllegalMonthError: bad month number 13; must be 1-12
The above exception was the direct cause of the following exception:
Traceback (most recent call last):
File "2.3.1_prepare_climate_data_ERA5.py", line 200, in <module>
predictor_grid = rx5day(in_files = climate_data_daily_tp_season, slice_mode=['season',(crop_growing_season)]).RX5day
File "/dss/dsshome1/lxc0B/di75cey/venv/pyvenv_1/lib/python3.8/site-packages/icclim/_generated_api.py", line 2745, in rx5day
return icclim.index(
File "/dss/dsshome1/lxc0B/di75cey/venv/pyvenv_1/lib/python3.8/site-packages/icclim/main.py", line 262, in index
result_ds = _compute_ecad_index_dataset(
File "/dss/dsshome1/lxc0B/di75cey/venv/pyvenv_1/lib/python3.8/site-packages/icclim/main.py", line 344, in _compute_ecad_index_dataset
result_ds = _compute_ecad_index(index, config, current_history)
File "/dss/dsshome1/lxc0B/di75cey/venv/pyvenv_1/lib/python3.8/site-packages/icclim/main.py", line 406, in _compute_ecad_index
resampled_da, time_bounds = config.freq.post_processing(da)
File "/dss/dsshome1/lxc0B/di75cey/venv/pyvenv_1/lib/python3.8/site-packages/icclim/models/frequency.py", line 78, in add_time_bounds
end = pd.to_datetime(f"{year_of_season_end}-{end_month + 1}")
File "/dss/dsshome1/lxc0B/di75cey/venv/pyvenv_1/lib/python3.8/site-packages/pandas/core/tools/datetimes.py", line 1078, in to_datetime
result = convert_listlike(np.array([arg]), format)[0]
File "/dss/dsshome1/lxc0B/di75cey/venv/pyvenv_1/lib/python3.8/site-packages/pandas/core/tools/datetimes.py", line 402, in _convert_listlike_datetimes
result, tz_parsed = objects_to_datetime64ns(
File "/dss/dsshome1/lxc0B/di75cey/venv/pyvenv_1/lib/python3.8/site-packages/pandas/core/arrays/datetimes.py", line 2217, in objects_to_datetime64ns
raise err
File "/dss/dsshome1/lxc0B/di75cey/venv/pyvenv_1/lib/python3.8/site-packages/pandas/core/arrays/datetimes.py", line 2199, in objects_to_datetime64ns
result, tz_parsed = tslib.array_to_datetime(
File "pandas/_libs/tslib.pyx", line 381, in pandas._libs.tslib.array_to_datetime
File "pandas/_libs/tslib.pyx", line 613, in pandas._libs.tslib.array_to_datetime
File "pandas/_libs/tslib.pyx", line 751, in pandas._libs.tslib._array_to_datetime_object
File "pandas/_libs/tslib.pyx", line 742, in pandas._libs.tslib._array_to_datetime_object
File "pandas/_libs/tslibs/parsing.pyx", line 281, in pandas._libs.tslibs.parsing.parse_datetime_string
File "/dss/dsshome1/lxc0B/di75cey/venv/pyvenv_1/lib/python3.8/site-packages/dateutil/parser/_parser.py", line 1368, in parse
return DEFAULTPARSER.parse(timestr, **kwargs)
File "/dss/dsshome1/lxc0B/di75cey/venv/pyvenv_1/lib/python3.8/site-packages/dateutil/parser/_parser.py", line 651, in parse
six.raise_from(ParserError(str(e) + ": %s", timestr), e)
File "<string>", line 3, in raise_from
dateutil.parser._parser.ParserError: bad month number 13; must be 1-12: 1971-13
Hi @MiriamSch thanks for reporting the bug.
I can reproduce it on master and I'll try to work on a fix for the 5.3 release.
Okay, thanks for your quick reply! Do you have an idea for a work around for now?
You can work around it by playing with icclim's internals:
from icclim.models.frequency import get_seasonal_time_updater, Frequency
custom_frequency = Frequency.lookup(['season',([3,4,5,6,7,8,9,10,11,12])])
custom_frequency._freq.post_processing = get_seasonal_time_updater(
start_month=3,
end_month=12,
start_day=1,
end_day=31
)
rx5day = icclim.rx5day(in_files=climate_data_daily_tp_season,
slice_mode=custom_frequency
).RX5day
(For the record, the bug is on the inference of end_day
that we try to guess by creating a date with date(end_month + 1) - delta("1 day")
... )
As a side note, beware of the results of spell indices (such as RX5day, CDD, CWD...) on seasonal frequencies in icclim 5.2.
Indeed, if you have a strong rainy event the 28th of Feb, you would probably want to account it in your results.
However, these spell based indices are not taking into account spells that have started before the first date, 1st of march in your case. This also makes it difficult to compare result to yearly frequencies or others seasons.
In 5.3, this behavior will be explicit. You will need to use "clipped_season" in place of "season" in slice_mode
to preserve the current behavior.
On the other hand, "season" keyword will be reserved for indices where we (in xclim) have implemented this "spell already started" awareness, as well as for indices not relying on spells.
As of today, this awareness on rx5day is not implemented.
if I try the work around, I get the following mistake:
TypeError: get_seasonal_time_updater() got an unexpected keyword argument 'start_day'
Similarly, for the following input:
custom_frequency._freq.post_processing = get_seasonal_time_updater(3,12,1,31)
I receive the following error:
TypeError: get_seasonal_time_updater() takes 2 positional arguments but 4 were given
And if I put only the months:
custom_frequency._freq.post_processing = get_seasonal_time_updater(3,12)
I get the same error as described in the first posts.
Any ideas how to solve that issue?
I forgot that start_day
and end_day
parameters were not yet available in 5.2, I don't see an easy workaround in 5.2 sorry.
However, I have just merged the fix #181.
You can either install the latest unstable version of icclim with pip install git+https://github.com/cerfacs-globc/icclim
.
Or wait for the 5.3 release which should come quite soon (this week or the next).
lovely, i will try it with the latest version and then with the new release! Thank you!
the unstable version unfortunately does not work for me. When will version 5.3 be released?
Hi @MiriamSch, sorry for putting so long to release 5.3, the issues we wanted to include in it are taking much more time than expected to complete (especially #189).
I'm going to work on a 5.3 release asap, without the blocking issues.
5.3 has now been released on conda-forge an pypi.