Skip to content

Backlog: Xarray Private API Workaround #508

@cyschneck

Description

@cyschneck

Describe the bug
Xarray transition to a private API had introduced an error addressed in #381

AttributeError: 'DataArray' object has no attribute '_data'

PR #492 fix is non-ideal method to address private API from Xarray, but is a fix as contains_cftime_datetimes does not accept DataArrays. Current fix allows for xarray to be unpinned from version 2023.02.0

Fix required a change in geocat/comp/climatologies.py from d_arr to d_arr.variable

def _contains_datetime_like_objects(d_arr):
    """Check if a variable contains datetime like objects (either
    np.datetime64, or cftime.datetime)"""
    return np.issubdtype(
        d_arr.dtype,
        np.datetime64) or xr.core.common.contains_cftime_datetimes(d_arr.variable)

This required a change in geocat/comp/interpolation.py to specify dims directly as [lev_dim] (to fix ValueError)

# Line 595
for idx, (d, s) in enumerate(zip(data_stacked, sigma_stacked)):
            output[idx, :] = xr.DataArray(_vertical_remap(
                func_interpolate, s.data, sig_coords.data, d.data),
                                          dims=[lev_dim])

....
# Line 606
output[:len(hyam)] = xr.DataArray(_vertical_remap(
            func_interpolate, sigma.data, sig_coords.data, data.data),
                                          dims=[lev_dim])

A conflict between pandas deprecrating loffset and xarray not also required a fix in geocat/comp/climatologies.py (to fix a ValueError) to preserve the "MS" (MonthBegin) resampling with time offset arithmetic

# Line 303
    # Group the months into three and take the mean
    means = data_filter.resample({
        time_coord_name: quarter
    }).mean(keep_attrs=keep_attrs)
    # Set offset for supported array formats
    if isinstance(means.indexes[time_coord_name],
                  xr.coding.cftimeindex.CFTimeIndex):
        means[time_coord_name] = means.indexes[
            time_coord_name] + xr.coding.cftime_offsets.to_offset(freq="MS")
    elif isinstance(means.indexes[time_coord_name], pd.DatetimeIndex):
        means[time_coord_name] = means.indexes[
            time_coord_name] + pd.tseries.frequencies.to_offset(freq="MS")
    else:
        raise ValueError(
            f"unsupported array type - {type(means.indexes[time_coord_name])}. Valid types include: (xr.coding.cftimeindex.CFTimeIndex, pandas.core.indexes.datetimes.DatetimeIndex)"
        )

Metadata

Metadata

Assignees

No one assigned

    Labels

    blockedWork got blocked waiting the output of some other source/workbugSomething isn't working

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions