Skip to content

Commit

Permalink
remove unused functions (units, get_calendar)
Browse files Browse the repository at this point in the history
  • Loading branch information
coxipi committed Oct 31, 2024
1 parent 16e594c commit 1e7dc68
Show file tree
Hide file tree
Showing 7 changed files with 94 additions and 433 deletions.
7 changes: 3 additions & 4 deletions src/xsdba/adjustment.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,10 +14,9 @@
from scipy import stats
from xarray.core.dataarray import DataArray

from xsdba.base import get_calendar
from xsdba.formatting import gen_call_string, update_history
from xsdba.options import OPTIONS, XSDBA_EXTRA_OUTPUT, set_options
from xsdba.units import convert_units_to, pint2str, units2str
from xsdba.units import convert_units_to
from xsdba.utils import uses_dask

from ._adjustment import (
Expand Down Expand Up @@ -94,7 +93,7 @@ def _check_inputs(cls, *inputs, group):
)

# All calendars used by the inputs
calendars = {get_calendar(inda, group.dim) for inda in inputs}
calendars = {inda.time.dt.calendar for inda in inputs}
if not cls._allow_diff_calendars and len(calendars) > 1:
raise ValueError(
"Inputs are defined on different calendars,"
Expand Down Expand Up @@ -246,7 +245,7 @@ def train(cls, ref: DataArray, hist: DataArray, **kwargs) -> TrainAdjust:
ds, params = cls._train(ref, hist, **kwargs)
obj = cls(
_trained=True,
hist_calendar=get_calendar(hist),
hist_calendar=hist.time.dt.calendar,
train_units=train_units,
**params,
)
Expand Down
53 changes: 5 additions & 48 deletions src/xsdba/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -200,7 +200,7 @@ def get_coordinate(self, ds: xr.Dataset | None = None) -> xr.DataArray:
)
if self.prop == "dayofyear":
if ds is not None:
cal = get_calendar(ds, dim=self.dim)
cal = ds.time.dt.calendar
mdoy = max(
xr.coding.calendar_ops._days_in_year(yr, cal)
for yr in np.unique(ds[self.dim].dt.year)
Expand Down Expand Up @@ -1081,49 +1081,6 @@ def compare_offsets(freqA: str, op: str, freqB: str) -> bool:
return get_op(op)(t_a, t_b)


# XC: calendar
def get_calendar(obj: Any, dim: str = "time") -> str:
"""Return the calendar of an object.
Parameters
----------
obj : Any
An object defining some date.
If `obj` is an array/dataset with a datetime coordinate, use `dim` to specify its name.
Values must have either a datetime64 dtype or a cftime dtype.
`obj` can also be a python datetime.datetime, a cftime object or a pandas Timestamp
or an iterable of those, in which case the calendar is inferred from the first value.
dim : str
Name of the coordinate to check (if `obj` is a DataArray or Dataset).
Raises
------
ValueError
If no calendar could be inferred.
Returns
-------
str
The Climate and Forecasting (CF) calendar name.
Will always return "standard" instead of "gregorian", following CF conventions 1.9.
"""
if isinstance(obj, xr.DataArray | xr.Dataset):
return obj[dim].dt.calendar
if isinstance(obj, xr.CFTimeIndex):
obj = obj.values[0]
else:
obj = np.take(obj, 0)
# Take zeroth element, overcome cases when arrays or lists are passed.
if isinstance(obj, pydt.datetime): # Also covers pandas Timestamp
return "standard"
if isinstance(obj, cftime.datetime):
if obj.calendar == "gregorian":
return "standard"
return obj.calendar

raise ValueError(f"Calendar could not be inferred from object of type {type(obj)}.")


# XC: calendar
def construct_offset(mult: int, base: str, start_anchored: bool, anchor: str | None):
"""Reconstruct an offset string from its parts.
Expand Down Expand Up @@ -1251,9 +1208,9 @@ def stack_periods(
The coordinate of `period` is the first timestep of each window.
"""
# Import in function to avoid cyclical imports
from xclim.core.units import ( # pylint: disable=import-outside-toplevel
ensure_cf_units,
from xsdba.units import ( # pylint: disable=import-outside-toplevel
infer_sampling_units,
units2str,
)

stride = stride or window
Expand Down Expand Up @@ -1357,7 +1314,7 @@ def stack_periods(
# Length as a pint-ready array : with proper units, but values are not usable as indexes anymore
m, u = infer_sampling_units(da)
lengths = lengths * m
lengths.attrs["units"] = ensure_cf_units(u)
lengths.attrs["units"] = units2str(u)
# Start points for each period and remember parameters for unstacking
starts = xr.DataArray(
[da.time[slc.start].item() for slc in periods],
Expand Down Expand Up @@ -1429,7 +1386,7 @@ def unstack_periods(da: xr.DataArray | xr.Dataset, dim: str = "period"):
0 o o o x x
=== === === === === === === ===
"""
from xclim.core.units import ( # pylint: disable=import-outside-toplevel
from xsdba.units import ( # pylint: disable=import-outside-toplevel
infer_sampling_units,
)

Expand Down
2 changes: 1 addition & 1 deletion src/xsdba/processing.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@
from ._processing import _adapt_freq, _normalize, _reordering
from .base import Grouper, parse_offset, uses_dask
from .nbutils import _escore
from .units import convert_units_to, harmonize_units, pint2str
from .units import convert_units_to, harmonize_units
from .utils import ADDITIVE, copy_all_attrs

__all__ = [
Expand Down
51 changes: 30 additions & 21 deletions src/xsdba/properties.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,9 +23,9 @@

from xsdba.units import (
convert_units_to,
infer_sampling_units,
pint2cfattrs,
pint2str,
to_agg_units,
units,
units2pint,
)
from xsdba.utils import uses_dask
Expand Down Expand Up @@ -130,11 +130,11 @@ def _mean(da: xr.DataArray, *, group: str | Grouper = "time") -> xr.DataArray:
xr.DataArray, [same as input]
Mean of the variable.
"""
units = da.units
u = da.units
if group.prop != "group":
da = da.groupby(group.name)
out = da.mean(dim=group.dim)
return out.assign_attrs(units=units)
return out.assign_attrs(units=u)


mean = StatisticalProperty(
Expand Down Expand Up @@ -164,12 +164,11 @@ def _var(da: xr.DataArray, *, group: str | Grouper = "time") -> xr.DataArray:
xr.DataArray, [square of the input units]
Variance of the variable.
"""
units = da.units
u = da.units
if group.prop != "group":
da = da.groupby(group.name)
out = da.var(dim=group.dim)
u2 = units2pint(units) ** 2
out.attrs["units"] = pint2str(u2)
out.attrs["units"] = str((units(u) ** 2).units)
return out


Expand Down Expand Up @@ -201,11 +200,11 @@ def _std(da: xr.DataArray, *, group: str | Grouper = "time") -> xr.DataArray:
xr.DataArray,
Standard deviation of the variable.
"""
units = da.units
u = da.units
if group.prop != "group":
da = da.groupby(group.name)
out = da.std(dim=group.dim)
out.attrs["units"] = units
out.attrs["units"] = u
return out


Expand Down Expand Up @@ -282,11 +281,11 @@ def _quantile(
xr.DataArray, [same as input]
Quantile {q} of the variable.
"""
units = da.units
u = da.units
if group.prop != "group":
da = da.groupby(group.name)
out = da.quantile(q, dim=group.dim, keep_attrs=True).drop_vars("quantile")
return out.assign_attrs(units=units)
return out.assign_attrs(units=u)


quantile = StatisticalProperty(
Expand Down Expand Up @@ -406,7 +405,12 @@ def _spell_stats(
stat=stat,
stat_resample=stat_resample or stat,
).out
return to_agg_units(out, da, op="count")
# in xclim this was managed by to_agg_units
# will hard-code this part for now
m, freq_u_raw = infer_sampling_units(da["time"])
with xr.set_options(keep_attrs=True):
out = (out * m).assign_attrs({"units": freq_u_raw})
return out


spell_length_distribution = StatisticalProperty(
Expand Down Expand Up @@ -581,7 +585,7 @@ def _annual_cycle(
{stat} of the annual cycle.
"""
group = group if isinstance(group, Grouper) else Grouper(group)
units = da.units
u = da.units

ac = da.groupby("time.dayofyear").mean()
if window > 1: # smooth the cycle
Expand All @@ -596,7 +600,7 @@ def _annual_cycle(
# TODO: In April 2024, use a match-case.
if stat == "absamp":
out = ac.max("dayofyear") - ac.min("dayofyear")
out.attrs.update(pint2cfattrs(units2pint(units), is_difference=True))
out.attrs.update(pint2cfattrs(units2pint(u), is_difference=True))
elif stat == "relamp":
out = (ac.max("dayofyear") - ac.min("dayofyear")) * 100 / ac.mean("dayofyear")
out.attrs["units"] = "%"
Expand All @@ -605,10 +609,10 @@ def _annual_cycle(
out.attrs.update(units="", is_dayofyear=np.int32(1))
elif stat == "min":
out = ac.min("dayofyear")
out.attrs["units"] = units
out.attrs["units"] = u
elif stat == "max":
out = ac.max("dayofyear")
out.attrs["units"] = units
out.attrs["units"] = u
elif stat == "asymmetry":
out = (ac.idxmax("dayofyear") - ac.idxmin("dayofyear")) % 365 / 365
out.attrs["units"] = "yr"
Expand Down Expand Up @@ -704,7 +708,7 @@ def _annual_statistic(
xr.DataArray, [same units as input or dimensionless]
Average annual {stat}.
"""
units = da.units
u = da.units

if window > 1:
da = da.rolling(time=window, center=True).mean()
Expand All @@ -713,7 +717,7 @@ def _annual_statistic(

if stat == "absamp":
out = yrs.max() - yrs.min()
out.attrs.update(pint2cfattrs(units2pint(units), is_difference=True))
out.attrs.update(pint2cfattrs(units2pint(u), is_difference=True))
elif stat == "relamp":
out = (yrs.max() - yrs.min()) * 100 / yrs.mean()
out.attrs["units"] = "%"
Expand Down Expand Up @@ -971,7 +975,12 @@ def _bivariate_spell_stats(
stat=stat,
stat_resample=stat_resample or stat,
).out
return to_agg_units(out, da1, op="count")
# in xclim this was managed by to_agg_units
# will hard-code this part for now
m, freq_u_raw = infer_sampling_units(da["time"])
with xr.set_options(keep_attrs=True):
out = (out * m).assign_attrs({"units": freq_u_raw})
return out


bivariate_spell_length_distribution = StatisticalProperty(
Expand Down Expand Up @@ -1229,7 +1238,7 @@ def _trend(
numpy.polyfit
"""
units = da.units
u = da.units

da = da.resample({group.dim: group.freq}) # separate all the {group}
da_mean = da.mean(dim=group.dim) # avg over all {group}
Expand All @@ -1250,7 +1259,7 @@ def modified_lr(
vectorize=True,
dask="parallelized",
)
out.attrs["units"] = f"{units}/year"
out.attrs["units"] = f"{u}/year"
return out


Expand Down
Loading

0 comments on commit 1e7dc68

Please sign in to comment.