Source code for grid_process.da_utils

# Copyright (c) 2026 MeteoSwiss, contributors listed in AUTHORS
#
# Distributed under the terms of the BSD 3-Clause License.
#
# SPDX-License-Identifier: BSD-3-Clause

"""
Module with general utility functions that operate on xarray.DataArray
"""

import logging
from typing import Any
from collections.abc import Sequence, Hashable
from functools import partial

import xarray as xr
import numpy as np

from grid_process.helpers import make_accessor, update_vars_attrs

logger = logging.getLogger(__name__)


# Register xarray accessor so module functions can also be called as methods
# on xr.DataArray objects
[docs] @xr.register_dataarray_accessor("da_utils") class DaUtils: """ Xarray accessors class for general utility functions on DataArray """ def __init__(self, da: xr.DataArray): self._data = da
dataarray_accessor = partial(make_accessor, accessor_class=DaUtils)
[docs] @dataarray_accessor def da_to_ds(da: xr.DataArray, vars_attrs: dict[Hashable, dict[Hashable, Any]]) -> xr.Dataset: """ Transform a dataarray, containing model data and one or several variables specified by the `variable` dimension, to a dataset. The function also reassign the attributes of the data variables saved in ``vars_attrs``. Parameters ---------- da : xarray.DataArray contains one or more variables specified in the `variable` dimension vars_attrs : dict contains the attributes of each variables found along the `variable` dimension Returns ------- ds : xarray.Dataset the dataset is composed of the data variables of the input DataArray See also -------- :func:`~grid_process.ds_utils.ds_to_da` which is the inverse function """ ds = da.to_dataset("variable") update_vars_attrs(ds, vars_attrs) return ds
[docs] @dataarray_accessor def bin_to_class( da: xr.DataArray, bins: Sequence[float], bins_label: Sequence[str | int], da_name: str | None = None, ) -> xr.DataArray: """ Convert numerical values into classes as defined by ``bins`` and ``bins_label``. Parameters: ----------- da : xarray.DataArray array with numerical values bins : sequence of floats defines the boudaries for the classes bins_label : sequence of str or int class labels. len(``bin_labels``) = len(``bins``) + 1 da_name : str, optional used to rename the output DataArray. By default no renaming is done. Returns ------- class_da : xarray.DataArray same as input array but with data converted from numerical values to classes """ bins_label_arr = np.asarray(bins_label) class_da = xr.apply_ufunc(lambda x: bins_label_arr[np.digitize(x, bins=bins, right=True)], da) if da_name is not None: class_da = class_da.rename(da_name) return class_da