Example #1
0
def cold_spell_duration_index(tasmin: xarray.DataArray,
                              tn10: xarray.DataArray,
                              window: int = 6,
                              freq: str = "YS") -> xarray.DataArray:
    r"""Cold spell duration index

    Number of days with at least six consecutive days where the daily minimum temperature is below the 10th
    percentile.

    Parameters
    ----------
    tasmin : xarray.DataArray
      Minimum daily temperature.
    tn10 : xarray.DataArray
      10th percentile of daily minimum temperature with `dayofyear` coordinate.
    window : int
      Minimum number of days with temperature below threshold to qualify as a cold spell. Default: 6.
    freq : str
      Resampling frequency; Defaults to "YS".

    Returns
    -------
    xarray.DataArray
      Count of days with at least six consecutive days where the daily minimum temperature is below the 10th
      percentile [days].

    Notes
    -----
    Let :math:`TN_i` be the minimum daily temperature for the day of the year :math:`i` and :math:`TN10_i` the 10th
    percentile of the minimum daily temperature over the 1961-1990 period for day of the year :math:`i`, the cold spell
    duration index over period :math:`\phi` is defined as:

    .. math::

       \sum_{i \in \phi} \prod_{j=i}^{i+6} \left[ TN_j < TN10_j \right]

    where :math:`[P]` is 1 if :math:`P` is true, and 0 if false.

    References
    ----------
    From the Expert Team on Climate Change Detection, Monitoring and Indices (ETCCDMI).

    Example
    -------
    >>> import xclim.utils as xcu
    >>> tn10 = xcu.percentile_doy(historical_tasmin, per=.1)
    >>> cold_spell_duration_index(reference_tasmin, tn10)
    """
    tn10 = convert_units_to(tn10, tasmin)

    # Create time series out of doy values.
    thresh = resample_doy(tn10, tasmin)

    below = tasmin < thresh

    return below.resample(time=freq).map(rl.windowed_run_count,
                                         window=window,
                                         dim="time")
Example #2
0
def warm_spell_duration_index(
    tasmax: xarray.DataArray, tx90: xarray.DataArray, window: int = 6, freq: str = "YS"
) -> xarray.DataArray:
    r"""Warm spell duration index.

    Number of days inside spells of a minimum number of consecutive days where the daily maximum temperature is above the 90th
    percentile. The 90th percentile should be computed for a 5-day moving window, centered on each calendar day in the
    1961-1990 period.

    Parameters
    ----------
    tasmax : xarray.DataArray
      Maximum daily temperature.
    tx90 : xarray.DataArray
      90th percentile of daily maximum temperature.
    window : int
      Minimum number of days with temperature above threshold to qualify as a warm spell.
    freq : str
      Resampling frequency.

    Returns
    -------
    xarray.DataArray, [time]
      Warm spell duration index.

    Examples
    --------
    Note that this example does not use a proper 1961-1990 reference period.

    >>> from xclim.core.calendar import percentile_doy
    >>> from xclim.indices import warm_spell_duration_index

    >>> tasmax = xr.open_dataset(path_to_tasmax_file).tasmax.isel(lat=0, lon=0)
    >>> tx90 = percentile_doy(tasmax, per=90).sel(percentiles=90)
    >>> warm_spell_duration_index(tasmax, tx90)

    References
    ----------
    From the Expert Team on Climate Change Detection, Monitoring and Indices (ETCCDMI).
    Used in Alexander, L. V., et al. (2006), Global observed changes in daily climate extremes of temperature and
    precipitation, J. Geophys. Res., 111, D05109, doi: 10.1029/2005JD006290.

    """
    thresh = convert_units_to(tx90, tasmax)

    # Create time series out of doy values.
    thresh = resample_doy(thresh, tasmax)

    above = tasmax > thresh

    out = above.resample(time=freq).map(
        rl.windowed_run_count, window=window, dim="time"
    )
    return to_agg_units(out, tasmax, "count")
Example #3
0
def days_over_precip_thresh(
    pr: xarray.DataArray,
    per: xarray.DataArray,
    thresh: str = "1 mm/day",
    freq: str = "YS",
) -> xarray.DataArray:
    r"""Number of wet days with daily precipitation over a given percentile.

    Number of days over period where the precipitation is above a threshold defining wet days and above a given
    percentile for that day.

    Parameters
    ----------
    pr : xarray.DataArray
      Mean daily precipitation flux [Kg m-2 s-1] or [mm/day]
    per : xarray.DataArray
      Daily percentile of wet day precipitation flux [Kg m-2 s-1] or [mm/day].
    thresh : str
       Precipitation value over which a day is considered wet [Kg m-2 s-1] or [mm/day].
    freq : str
      Resampling frequency; Defaults to "YS".

    Returns
    -------
    xarray.DataArray
      Count of days with daily precipitation above the given percentile [days]

    Example
    -------
    >>> import xarray as xr
    >>> import xclim
    >>> pr = xr.open_dataset("precipitation_data.nc").pr
    >>> p75 = pr.quantile(.75, dim="time", keep_attrs=True)
    >>> r75p = xclim.indices.days_over_precip_thresh(pr, p75)
    """
    per = convert_units_to(per, pr)
    thresh = convert_units_to(thresh, pr)

    tp = np.maximum(per, thresh)
    if "dayofyear" in per.coords:
        # Create time series out of doy values.
        tp = resample_doy(tp, pr)

    # Compute the days where precip is both over the wet day threshold and the percentile threshold.
    over = pr > tp

    return over.resample(time=freq).sum(dim="time")
Example #4
0
def fraction_over_precip_thresh(
    pr: xarray.DataArray,
    per: xarray.DataArray,
    thresh: str = "1 mm/day",
    freq: str = "YS",
) -> xarray.DataArray:
    r"""Fraction of precipitation due to wet days with daily precipitation over a given percentile.

    Percentage of the total precipitation over period occurring in days where the precipitation is above a threshold
    defining wet days and above a given percentile for that day.

    Parameters
    ----------
    pr : xarray.DataArray
      Mean daily precipitation flux.
    per : xarray.DataArray
      Daily percentile of wet day precipitation flux.
    thresh : str
       Precipitation value over which a day is considered wet.
    freq : str
      Resampling frequency.

    Returns
    -------
    xarray.DataArray, [dimensionless]
      Fraction of precipitation over threshold during wet days days.

    """
    per = convert_units_to(per, pr)
    thresh = convert_units_to(thresh, pr)

    tp = np.maximum(per, thresh)
    if "dayofyear" in per.coords:
        # Create time series out of doy values.
        tp = resample_doy(tp, pr)

    # Total precip during wet days over period
    total = pr.where(pr > thresh).resample(time=freq).sum(dim="time")

    # Compute the days where precip is both over the wet day threshold and the percentile threshold.
    over = pr.where(pr > tp).resample(time=freq).sum(dim="time")

    out = over / total
    out.attrs["units"] = ""
    return out
Example #5
0
def days_over_precip_thresh(
    pr: xarray.DataArray,
    per: xarray.DataArray,
    thresh: str = "1 mm/day",
    freq: str = "YS",
) -> xarray.DataArray:  # noqa: D401
    r"""Number of wet days with daily precipitation over a given percentile.

    Number of days over period where the precipitation is above a threshold defining wet days and above a given
    percentile for that day.

    Parameters
    ----------
    pr : xarray.DataArray
      Mean daily precipitation flux.
    per : xarray.DataArray
      Daily percentile of wet day precipitation flux.
    thresh : str
       Precipitation value over which a day is considered wet.
    freq : str
      Resampling frequency.

    Returns
    -------
    xarray.DataArray, [time]
      Count of days with daily precipitation above the given percentile [days].

    Examples
    --------
    >>> from xclim.indices import days_over_precip_thresh
    >>> pr = xr.open_dataset(path_to_pr_file).pr
    >>> p75 = pr.quantile(.75, dim="time", keep_attrs=True)
    >>> r75p = days_over_precip_thresh(pr, p75)
    """
    per = convert_units_to(per, pr)
    thresh = convert_units_to(thresh, pr)

    tp = np.maximum(per, thresh)
    if "dayofyear" in per.coords:
        # Create time series out of doy values.
        tp = resample_doy(tp, pr)

    # Compute the days where precip is both over the wet day threshold and the percentile threshold.
    out = threshold_count(pr, ">", tp, freq)
    return to_agg_units(out, pr, "count")
Example #6
0
def tn10p(tasmin: xarray.DataArray,
          t10: xarray.DataArray,
          freq: str = "YS") -> xarray.DataArray:
    r"""Number of days with daily minimum temperature below the 10th percentile.

    Number of days with daily minimum temperature below the 10th percentile.

    Parameters
    ----------

    tasmin : xarray.DataArray
      Mean daily temperature [℃] or [K]
    t10 : xarray.DataArray
      10th percentile of daily minimum temperature [℃] or [K]
    freq : str
      Resampling frequency; Defaults to "YS".

    Returns
    -------
    xarray.DataArray
      Count of days with daily minimum temperature below the 10th percentile [days]

    Notes
    -----
    The 10th percentile should be computed for a 5 day window centered on each calendar day for a reference period.

    Example
    -------
    >>> import xarray as xr
    >>> import xclim.utils
    >>> tas = xr.open_dataset("temperature_data.nc").tas
    >>> t10 = xclim.utils.percentile_doy(tas, per=0.1)
    >>> cold_days = tg10p(tas, t10)
    """
    t10 = convert_units_to(t10, tasmin)

    # Create time series out of doy values.
    thresh = resample_doy(t10, tasmin)

    # Identify the days below the 10th percentile
    below = tasmin < thresh

    return below.resample(time=freq).sum(dim="time")
Example #7
0
def tx10p(tasmax: xarray.DataArray,
          t10: xarray.DataArray,
          freq: str = "YS") -> xarray.DataArray:  # noqa: D401
    r"""Number of days with daily maximum temperature below the 10th percentile.

    Number of days with daily maximum temperature below the 10th percentile.

    Parameters
    ----------
    tasmax : xarray.DataArray
      Maximum daily temperature [℃] or [K]
    t10 : xarray.DataArray
      10th percentile of daily maximum temperature [℃] or [K]
    freq : str
      Resampling frequency; Defaults to "YS".

    Returns
    -------
    xarray.DataArray
      Count of days with daily maximum temperature below the 10th percentile [days]

    Notes
    -----
    The 10th percentile should be computed for a 5 day window centered on each calendar day for a reference period.

    Examples
    --------
    >>> from xclim.core.calendar import percentile_doy
    >>> from xclim.indices import tx10p
    >>> tas = xr.open_dataset(path_to_tas_file).tas
    >>> t10 = percentile_doy(tas, per=0.1)
    >>> cold_days = tx10p(tas, t10)
    """
    t10 = convert_units_to(t10, tasmax)

    # Create time series out of doy values.
    thresh = resample_doy(t10, tasmax)

    # Identify the days below the 10th percentile
    below = tasmax < thresh

    return below.resample(time=freq).sum(dim="time")
Example #8
0
def warm_spell_duration_index(tasmax: xarray.DataArray,
                              tx90: float,
                              window: int = 6,
                              freq: str = "YS") -> xarray.DataArray:
    r"""Warm spell duration index

    Number of days with at least six consecutive days where the daily maximum temperature is above the 90th
    percentile. The 90th percentile should be computed for a 5-day window centred on each calendar day in the
    1961-1990 period.

    Parameters
    ----------
    tasmax : xarray.DataArray
      Maximum daily temperature [℃] or [K]
    tx90 : float
      90th percentile of daily maximum temperature [℃] or [K]
    window : int
      Minimum number of days with temperature above threshold to qualify as a warm spell.
    freq : str
      Resampling frequency; Defaults to "YS".

    Returns
    -------
    xarray.DataArray
      Count of days with at least six consecutive days where the daily maximum temperature is above the 90th
      percentile [days].

    References
    ----------
    From the Expert Team on Climate Change Detection, Monitoring and Indices (ETCCDMI).
    Used in Alexander, L. V., et al. (2006), Global observed changes in daily climate extremes of temperature and
    precipitation, J. Geophys. Res., 111, D05109, doi: 10.1029/2005JD006290.

    """
    # Create time series out of doy values.
    thresh = resample_doy(tx90, tasmax)

    above = tasmax > thresh

    return above.resample(time=freq).map(rl.windowed_run_count,
                                         window=window,
                                         dim="time")
Example #9
0
def tx90p(tasmax: xarray.DataArray,
          t90: xarray.DataArray,
          freq: str = "YS") -> xarray.DataArray:
    r"""Number of days with daily maximum temperature over the 90th percentile.

    Number of days with daily maximum temperature over the 90th percentile.

    Parameters
    ----------
    tasmax : xarray.DataArray
      Maximum daily temperature [℃] or [K]
    t90 : xarray.DataArray
      90th percentile of daily maximum temperature [℃] or [K]
    freq : str
      Resampling frequency; Defaults to "YS".

    Returns
    -------
    xarray.DataArray
      Count of days with daily maximum temperature below the 10th percentile [days]

    Notes
    -----
    The 90th percentile should be computed for a 5 day window centered on each calendar day for a reference period.

    Example
    -------
    >>> import xarray as xr
    >>> import xclim.utils
    >>> tas = xr.open_dataset("temperature_data.nc").tas
    >>> t90 = xclim.utils.percentile_doy(tas, per=0.9)
    >>> hot_days = tg90p(tas, t90)
    """
    t90 = convert_units_to(t90, tasmax)

    # Create time series out of doy values.
    thresh = resample_doy(t90, tasmax)

    # Identify the days with max temp above 90th percentile.
    over = tasmax > thresh

    return over.resample(time=freq).sum(dim="time")
Example #10
0
def tn90p(
    tasmin: xarray.DataArray, t90: xarray.DataArray, freq: str = "YS"
) -> xarray.DataArray:  # noqa: D401
    r"""Number of days with daily minimum temperature over the 90th percentile.

    Number of days with daily minimum temperature over the 90th percentile.

    Parameters
    ----------
    tasmin : xarray.DataArray
      Minimum daily temperature.
    t90 : xarray.DataArray
      90th percentile of daily minimum temperature.
    freq : str
      Resampling frequency.

    Returns
    -------
    xarray.DataArray, [time]
      Count of days with daily minimum temperature below the 10th percentile [days].

    Notes
    -----
    The 90th percentile should be computed for a 5 day window centered on each calendar day for a reference period.

    Examples
    --------
    >>> from xclim.core.calendar import percentile_doy
    >>> from xclim.indices import tn90p
    >>> tas = xr.open_dataset(path_to_tas_file).tas
    >>> t90 = percentile_doy(tas, per=90).sel(percentiles=90)
    >>> hot_days = tn90p(tas, t90)
    """
    t90 = convert_units_to(t90, tasmin)

    # Create time series out of doy values.
    thresh = resample_doy(t90, tasmin)

    # Identify the days with min temp above 90th percentile.
    out = threshold_count(tasmin, ">", thresh, freq)
    return to_agg_units(out, tasmin, "count")
Example #11
0
def cold_spell_duration_index(
    tasmin: xarray.DataArray, tn10: xarray.DataArray, window: int = 6, freq: str = "YS"
) -> xarray.DataArray:
    r"""Cold spell duration index.

    Number of days with at least six consecutive days where the daily minimum temperature is below the 10th
    percentile.

    Parameters
    ----------
    tasmin : xarray.DataArray
      Minimum daily temperature.
    tn10 : xarray.DataArray
      10th percentile of daily minimum temperature with `dayofyear` coordinate.
    window : int
      Minimum number of days with temperature below threshold to qualify as a cold spell.
    freq : str
      Resampling frequency.

    Returns
    -------
    xarray.DataArray, [time]
      Count of days with at least six consecutive days where the daily minimum temperature is below the 10th
      percentile.

    Notes
    -----
    Let :math:`TN_i` be the minimum daily temperature for the day of the year :math:`i` and :math:`TN10_i` the 10th
    percentile of the minimum daily temperature over the 1961-1990 period for day of the year :math:`i`, the cold spell
    duration index over period :math:`\phi` is defined as:

    .. math::

       \sum_{i \in \phi} \prod_{j=i}^{i+6} \left[ TN_j < TN10_j \right]

    where :math:`[P]` is 1 if :math:`P` is true, and 0 if false.

    References
    ----------
    From the Expert Team on Climate Change Detection, Monitoring and Indices (ETCCDMI).

    Examples
    --------
    # Note that this example does not use a proper 1961-1990 reference period.
    >>> from xclim.core.calendar import percentile_doy
    >>> from xclim.indices import cold_spell_duration_index

    >>> tasmin = xr.open_dataset(path_to_tasmin_file).tasmin.isel(lat=0, lon=0)
    >>> tn10 = percentile_doy(tasmin, per=10).sel(percentiles=10)
    >>> cold_spell_duration_index(tasmin, tn10)
    """
    tn10 = convert_units_to(tn10, tasmin)

    # Create time series out of doy values.
    thresh = resample_doy(tn10, tasmin)

    below = tasmin < thresh

    out = below.resample(time=freq).map(
        rl.windowed_run_count, window=window, dim="time"
    )
    return to_agg_units(out, tasmin, "count")