Source code for processing.regrid
import xarray as xr
import cf_xarray
try:
# Import check for xesmf as it has non-python dependencies. This ensures valenspy can function without xesmf - for example when installed via pip.
import xesmf as xe
XESM_AVAILABLE = True
except ImportError:
XESM_AVAILABLE = False
[docs]
def remap_xesmf(data : xr.Dataset | xr.DataTree, ds_out : xr.Dataset, method : str ="bilinear", regridder_kwargs : dict ={}, regridding_kwargs: dict ={}):
"""Remap the input dataset to the target grid using xESMF.
If lat_bounds and lon_bounds are not present in the input dataset, they will be added.
Parameters
----------
data : xarray.Dataset or xarray.DataTree
The input data to remap.
ds_out : xarray.Dataset
The target grid dataset.
method : str, optional
The remap method to use, by default "bilinear".
regridder_kwargs : dict
Keyword arguments for the creation of the regridder. See :func:`xesmf.Regridder`.
regridding_kwargs : dict
Keyword arguments for the actual regridding. See :func:`xesmf.Regridder.regrid_dataset()`.
Returns
-------
xarray.Dataset or xarray.DataTree
The remapped data.
"""
if not XESM_AVAILABLE:
raise ImportError(f"The xesmf dependency ESMF and esmpy (EMSF's python interface) are not installed. Please install it with 'conda install -c conda-forge esmpy' or similar to use this function.")
if isinstance(data, xr.DataTree):
return _remap_xesmf_dt(data, ds_out, method, regridder_kwargs, regridding_kwargs)
elif isinstance(data, xr.Dataset):
return _remap_xesmf_ds(data, ds_out, method, regridder_kwargs, regridding_kwargs)
else:
raise TypeError("Input data must be either an xarray Dataset or a DataTree.")
[docs]
def _remap_xesmf_dt(dt : xr.DataTree, ds_out : xr.Dataset, method : str ="bilinear", regridder_kwargs : dict ={}, regridding_kwargs: dict ={}):
"""
Remap the input DataTree to the target grid using xESMF. Applies _remap_xesmf_ds to each dataset in the DataTree.
"""
return dt.map_over_datasets(
_remap_xesmf_ds,
ds_out,
method,
regridder_kwargs,
regridding_kwargs
)
[docs]
def _remap_xesmf_ds(ds : xr.Dataset, ds_out : xr.Dataset, method : str ="bilinear", regridder_kwargs : dict ={}, regridding_kwargs: dict ={}):
"""Remap the input dataset to the target grid using xESMF.
If lat_bounds and lon_bounds are not present in the input dataset, they will be added.
"""
if not ds.data_vars:
return ds
if method=="conservative":
if not ("lat_bounds" in ds.variables and "lon_bounds" in ds.variables):
ds = ds.cf.add_bounds(("lat", "lon"))
regridder = xe.Regridder(ds, ds_out, method, **regridder_kwargs)
ds_reg = regridder(ds, **regridding_kwargs)
return ds_reg