Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix map_blocks for DataArray with cftime and sdba_encode_cf #1674

Merged
merged 3 commits into from
Mar 12, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions CHANGES.rst
Original file line number Diff line number Diff line change
Expand Up @@ -10,10 +10,15 @@ Announcements
^^^^^^^^^^^^^
* `xclim` has migrated its development branch name from `master` to `main`. (:issue:`1667`, :pull:`1669`).

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`).

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`).
Expand Down
15 changes: 15 additions & 0 deletions tests/test_sdba/test_base.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
import pytest
import xarray as xr

from xclim import set_options
from xclim.sdba.base import Grouper, Parametrizable, map_blocks, map_groups


Expand Down Expand Up @@ -234,3 +235,17 @@ def func(ds, *, group, lon=None):

with pytest.raises(ValueError, match="cannot be chunked"):
func(xr.Dataset(dict(tas=tas)), group="time")

@pytest.mark.parametrize("use_dask", [True, False])
def test_dataarray_cfencode(self, use_dask, open_dataset):
ds = open_dataset("sdba/CanESM2_1950-2100.nc")
if use_dask:
ds = ds.chunk()

@map_blocks(reduces=["location"], data=[])
def func(ds, *, group):
d = ds.mean("location")
return d.rename("data").to_dataset()

with set_options(sdba_encode_cf=True):
func(ds.convert_calendar("noleap").tasmax, group=Grouper("time"))
10 changes: 6 additions & 4 deletions xclim/sdba/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -591,7 +591,6 @@ def _map_blocks(ds, **kwargs): # noqa: C901
f"Dimension {dim} is meant to be added by the "
"computation but it is already on one of the inputs."
)

if uses_dask(ds):
# Use dask if any of the input is dask-backed.
chunks = (
Expand Down Expand Up @@ -673,9 +672,12 @@ def _map_blocks(ds, **kwargs): # noqa: C901
if OPTIONS[SDBA_ENCODE_CF]:
ds = ds.copy()
# Optimization to circumvent the slow pickle.dumps(cftime_array)
for name, crd in ds.coords.items():
if xr.core.common._contains_cftime_datetimes(crd.variable): # noqa
ds[name] = xr.conventions.encode_cf_variable(crd.variable)
# List of the keys to avoid changing the coords dict while iterating over it.
for crd in list(ds.coords.keys()):
if xr.core.common._contains_cftime_datetimes(
ds[crd].variable
): # noqa
ds[crd] = xr.conventions.encode_cf_variable(ds[crd].variable)

def _call_and_transpose_on_exit(dsblock, **f_kwargs):
"""Call the decorated func and transpose to ensure the same dim order as on the template."""
Expand Down