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 = utils.convert_units_to(tn10, tasmin) # Create time series out of doy values. thresh = utils.resample_doy(tn10, tasmin) below = tasmin < thresh return below.resample(time=freq).apply(rl.windowed_run_count, window=window, dim="time")
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 = utils.convert_units_to(per, pr) thresh = utils.convert_units_to(thresh, pr) tp = np.maximum(per, thresh) if "dayofyear" in per.coords: # Create time series out of doy values. tp = utils.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")
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 [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 Fraction of precipitation over threshold during wet days days. """ per = utils.convert_units_to(per, pr) thresh = utils.convert_units_to(thresh, pr) tp = np.maximum(per, thresh) if "dayofyear" in per.coords: # Create time series out of doy values. tp = utils.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") return over / total
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 = utils.convert_units_to(t10, tasmin) # Create time series out of doy values. thresh = utils.resample_doy(t10, tasmin) # Identify the days below the 10th percentile below = tasmin < thresh return below.resample(time=freq).sum(dim="time")
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 below 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 = utils.resample_doy(tx90, tasmax) above = tasmax > thresh return above.resample(time=freq).apply(rl.windowed_run_count, window=window, dim="time")
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 = utils.convert_units_to(t90, tasmax) # Create time series out of doy values. thresh = utils.resample_doy(t90, tasmax) # Identify the days with max temp above 90th percentile. over = tasmax > thresh return over.resample(time=freq).sum(dim="time")
def tn10p(tasmin, t10, freq="YS"): 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, optional Resampling frequency 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 ------- >>> t10 = percentile_doy(historical_tas, per=0.1) >>> cold_days = tg10p(tas, t10) """ t10 = utils.convert_units_to(t10, tasmin) # Create time series out of doy values. thresh = utils.resample_doy(t10, tasmin) # Identify the days below the 10th percentile below = tasmin < thresh return below.resample(time=freq).sum(dim="time")
def tx90p(tasmax, t90, freq="YS"): 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, optional Resampling frequency 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 ------- >>> t90 = percentile_doy(historical_tas, per=0.9) >>> hot_days = tg90p(tas, t90) """ t90 = utils.convert_units_to(t90, tasmax) # Create time series out of doy values. thresh = utils.resample_doy(t90, tasmax) # Identify the days with max temp above 90th percentile. over = tasmax > thresh return over.resample(time=freq).sum(dim="time")