Esempio n. 1
0
def ice_days(tasmax: xarray.DataArray, freq: str = "YS"):  # noqa: D401
    r"""Number of ice/freezing days.

    Number of days where daily maximum temperatures are below 0℃.

    Parameters
    ----------
    tasmax : xarray.DataArray
      Maximum daily temperature [℃] or [K]
    freq : str
      Resampling frequency; Defaults to "YS" (yearly).

    Returns
    -------
    xarray.DataArray
      Number of ice/freezing days.

    Notes
    -----
    Let :math:`TX_{ij}` be the daily maximum temperature at day :math:`i` of period :math:`j`. Then
    counted is the number of days where:

    .. math::

        TX_{ij} < 0℃
    """
    tu = units.parse_units(tasmax.attrs["units"].replace("-", "**-"))
    fu = "degC"
    frz = 0
    if fu != tu:
        frz = units.convert(frz, fu, tu)
    f = (tasmax < frz) * 1
    return f.resample(time=freq).sum(dim="time")
Esempio n. 2
0
def frost_days(tasmin: xarray.DataArray, freq: str = "YS"):
    r"""Frost days index

    Number of days where daily minimum temperatures are below 0℃.

    Parameters
    ----------
    tasmin : xarray.DataArray
      Minimum daily temperature [℃] or [K]
    freq : str
      Resampling frequency; Defaults to "YS" (yearly).

    Returns
    -------
    xarray.DataArray
      Frost days index.

    Notes
    -----
    Let :math:`TN_{ij}` be the daily minimum temperature at day :math:`i` of period :math:`j`. Then
    counted is the number of days where:

    .. math::

        TN_{ij} < 0℃
    """
    tu = units.parse_units(tasmin.attrs["units"].replace("-", "**-"))
    fu = "degC"
    frz = 0
    if fu != tu:
        frz = units.convert(frz, fu, tu)
    f = (tasmin < frz) * 1
    return f.resample(time=freq).sum(dim="time")
Esempio n. 3
0
def liquid_precip_ratio(
    pr: xarray.DataArray,
    prsn: Optional[xarray.DataArray] = None,
    tas: Optional[xarray.DataArray] = None,
    freq: str = "QS-DEC",
) -> xarray.DataArray:
    r"""Ratio of rainfall to total precipitation.

    The ratio of total liquid precipitation over the total precipitation. If solid precipitation is not provided,
    then precipitation is assumed solid if the temperature is below 0°C.

    Parameters
    ----------
    pr : xarray.DataArray
      Mean daily precipitation flux [Kg m-2 s-1] or [mm].
    prsn : Optional[xarray.DataArray]
      Mean daily solid precipitation flux [Kg m-2 s-1] or [mm].
    tas : Optional[xarray.DataArray]
      Mean daily temperature [℃] or [K]
    freq : str
      Resampling frequency; Defaults to "QS-DEC".

    Returns
    -------
    xarray.DataArray
      Ratio of rainfall to total precipitation

    Notes
    -----
    Let :math:`PR_i` be the mean daily precipitation of day :math:`i`, then for a period :math:`j` starting at
    day :math:`a` and finishing on day :math:`b`:

    .. math::

        PR_{ij} = \sum_{i=a}^{b} PR_i

        PRwet_{ij}

    See Also
    --------
    winter_rain_ratio
    """
    if prsn is None and tas is not None:
        tu = units.parse_units(tas.attrs["units"].replace("-", "**-"))
        fu = "degC"
        frz = 0
        if fu != tu:
            frz = units.convert(frz, fu, tu)
        prsn = pr.where(tas < frz, 0)
    else:
        raise KeyError("prsn or tas must be supplied.")

    tot = pr.resample(time=freq).sum(dim="time")
    rain = tot - prsn.resample(time=freq).sum(dim="time")
    ratio = rain / tot
    return ratio
Esempio n. 4
0
def consecutive_frost_days(tasmin: xarray.DataArray, freq: str = "AS-JUL"):
    r"""Maximum number of consecutive frost days (Tmin < 0℃).

    Resample the daily minimum temperature series by computing the maximum number
    of days below the freezing point over each period.

    Parameters
    ----------
    tasmin : xarray.DataArray
      Minimum daily temperature values [℃] or [K]
    freq : str
      Resampling frequency; Defaults to "YS" (yearly).

    Returns
    -------
    xarray.DataArray
      The maximum number of consecutive days below the freezing point.

    Notes
    -----
    Let :math:`\mathbf{x}=x_0, x_1, \ldots, x_n` be a daily minimum temperature series and
    :math:`\mathbf{s}` be the sorted vector of indices :math:`i` where :math:`[p_i < 0^\circ C] \neq [p_{i+1} <
    0^\circ C]`, that is, the days when the temperature crosses the freezing point.
    Then the maximum number of consecutive frost days is given by

    .. math::

       \max(\mathbf{d}) \quad \mathrm{where} \quad d_j = (s_j - s_{j-1}) [x_{s_j} > 0^\circ C]

    where :math:`[P]` is 1 if :math:`P` is true, and 0 if false. Note that this formula does not handle sequences at
    the start and end of the series, but the numerical algorithm does.
    """
    tu = units.parse_units(tasmin.attrs["units"].replace("-", "**-"))
    fu = "degC"
    frz = 0
    if fu != tu:
        frz = units.convert(frz, fu, tu)
    group = (tasmin < frz).resample(time=freq)
    return group.map(rl.longest_run, dim="time")
Esempio n. 5
0
    def test_fraction(self):
        q = 5 * units.percent
        assert q.to("dimensionless") == 0.05

        q = 5 * units.parse_units("pct")
        assert q.to("dimensionless") == 0.05
Esempio n. 6
0
 def test_dimensionality(self):
     with units.context("hydro"):
         fu = 1 * units.parse_units("kg / m**2 / s")
         tu = 1 * units.parse_units("mm / d")
         fu.to("mmday")
         tu.to("mmday")
Esempio n. 7
0
 def test_pcic(self):
     with units.context("hydro"):
         fu = units.parse_units("kilogram / d / meter ** 2")
         tu = units.parse_units("mm/day")
         np.isclose(1 * fu, 1 * tu)