Secure your code as it's written. Use Snyk Code to scan source code in minutes - no build needed - and fix issues immediately.
@is_xarray(0)
def smooth_goddard_2013(
ds,
tsmooth_kws={'lead': 4},
d_lon_lat_kws={'lon': 5, 'lat': 5},
how='mean',
**xesmf_kwargs,
):
"""Wrapper to smooth as suggested by Goddard et al. 2013:
- 4-year composites
- 5x5 degree regridding
Reference:
* Goddard, L., A. Kumar, A. Solomon, D. Smith, G. Boer, P.
Gonzalez, V. Kharin, et al. “A Verification Framework for
Interannual - to - Decadal Predictions Experiments.” Climate
Dynamics 40, no. 1–2 (January 1, 2013): 245–72.
@is_xarray([0, 1])
def compute_hindcast(
hind,
verif,
metric='pearson_r',
comparison='e2o',
dim='init',
alignment='same_verifs',
add_attrs=True,
**metric_kwargs,
):
"""Verify hindcast predictions against verification data.
Args:
hind (xarray object): Hindcast ensemble.
Expected to follow package conventions:
* ``init`` : dim of initialization dates
@is_xarray(0)
def temporal_smoothing(ds, tsmooth_kws=None, how='mean', d_lon_lat_kws=None):
"""Apply temporal smoothing by creating rolling smooth-timestep means.
Reference:
* Goddard, L., A. Kumar, A. Solomon, D. Smith, G. Boer, P.
Gonzalez, V. Kharin, et al. “A Verification Framework for
Interannual - to - Decadal Predictions Experiments.” Climate
Dynamics 40, no. 1–2 (January 1, 2013): 245–72.
https://doi.org/10/f4jjvf.
Args:
ds(xr.object): input.
tsmooth_kws(dict): length of smoothing of timesteps.
Defaults to {'time': 4} (see Goddard et al. 2013).
how(str): aggregation type for smoothing. default: 'mean'
d_lon_lat_kws (None): leads nowhere but consistent with
@is_xarray(0)
def decorrelation_time(da, r=20, dim='time'):
"""Calculate the decorrelaton time of a time series.
.. math::
\\tau_{d} = 1 + 2 * \\sum_{k=1}^{r}(\\alpha_{k})^{k}
Args:
da (xarray object): Time series.
r (optional int): Number of iterations to run the above formula.
dim (optional str): Time dimension for xarray object.
Returns:
Decorrelation time of time series.
Reference:
* Storch, H. v, and Francis W. Zwiers. Statistical Analysis in Climate
@is_xarray(1)
def add_observations(self, xobj, name):
"""Add a verification data with which to verify the initialized ensemble.
Args:
xobj (xarray object): Dataset/DataArray to append to the
``HindcastEnsemble`` object.
name (str): Short name for referencing the verification data.
"""
if isinstance(xobj, xr.DataArray):
xobj = xobj.to_dataset()
match_initialized_dims(self._datasets['initialized'], xobj)
match_initialized_vars(self._datasets['initialized'], xobj)
# Check that time is int, cftime, or datetime; convert ints or cftime to
# datetime.
xobj = convert_time_index(xobj, 'time', 'xobj[init]')
# For some reason, I could only get the non-inplace method to work
@is_xarray([0, 1])
def compute_persistence(
hind,
verif,
metric='pearson_r',
alignment='same_verifs',
add_attrs=True,
**metric_kwargs,
):
"""Computes the skill of a persistence forecast from a simulation.
Args:
hind (xarray object): The initialized ensemble.
verif (xarray object): Verification data.
metric (str): Metric name to apply at each lag for the persistence computation.
Default: 'pearson_r'
alignment (str): which inits or verification times should be aligned?
@is_xarray(1)
def add_uninitialized(self, xobj):
"""Add a companion uninitialized ensemble for comparison to verification data.
Args:
xobj (xarray object): Dataset/DataArray of the uninitialzed
ensemble.
"""
if isinstance(xobj, xr.DataArray):
xobj = xobj.to_dataset()
match_initialized_dims(self._datasets['initialized'], xobj, uninitialized=True)
match_initialized_vars(self._datasets['initialized'], xobj)
# Check that init is int, cftime, or datetime; convert ints or cftime to
# datetime.
xobj = convert_time_index(xobj, 'time', 'xobj[init]')
datasets = self._datasets.copy()
datasets.update({'uninitialized': xobj})
@is_xarray([0, 1])
def compute_perfect_model(
init_pm,
control,
metric='pearson_r',
comparison='m2e',
dim=None,
add_attrs=True,
**metric_kwargs,
):
"""
Compute a predictability skill score for a perfect-model framework
simulation dataset.
Args:
init_pm (xarray object): ensemble with dims ``lead``, ``init``, ``member``.
control (xarray object): control with dimension ``time``.
@is_xarray([0, 1])
def compute_uninitialized(
hind,
uninit,
verif,
metric='pearson_r',
comparison='e2o',
dim='time',
alignment='same_verifs',
add_attrs=True,
**metric_kwargs,
):
"""Verify an uninitialized ensemble against verification data.
.. note::
Based on Decadal Prediction protocol, this should only be computed for the
first lag and then projected out to any further lags being analyzed.
@is_xarray(1)
def __init__(self, xobj):
if isinstance(xobj, xr.DataArray):
# makes applying prediction functions easier, etc.
xobj = xobj.to_dataset()
has_dims(xobj, ['init', 'lead'], 'PredictionEnsemble')
# Check that init is int, cftime, or datetime; convert ints or cftime to
# datetime.
xobj = convert_time_index(xobj, 'init', 'xobj[init]')
# Put this after `convert_time_index` since it assigns 'years' attribute if the
# `init` dimension is a `float` or `int`.
has_valid_lead_units(xobj)
# Add initialized dictionary and reserve sub-dictionary for an uninitialized
# run.
self._datasets = {'initialized': xobj, 'uninitialized': {}}
self.kind = 'prediction'
self._temporally_smoothed = None