Skip to content

Commit

Permalink
Option to cap low winds to 0.5 m/s (#1635)
Browse files Browse the repository at this point in the history
### What kind of change does this PR introduce?

* Adds an option to the `universal_thermal_climate_index` function to
cap low wind to a minimum of 0.5 m/s

### Does this PR introduce a breaking change?

* No

### Other information:

References for the change:

* https://link.springer.com/article/10.1007/s00484-011-0454-1
* https://www.mdpi.com/2079-7737/12/6/802
  • Loading branch information
Zeitsperre authored Feb 7, 2024
2 parents 41379c5 + 3ac6c5d commit cfd5643
Show file tree
Hide file tree
Showing 6 changed files with 42 additions and 8 deletions.
4 changes: 4 additions & 0 deletions .zenodo.json
Original file line number Diff line number Diff line change
Expand Up @@ -125,6 +125,10 @@
"name": "Braun, Marco",
"affiliation": "Ouranos Consortium, Montréal, Québec, Canada",
"orcid": "0000-0001-5061-3217"
},
{
"name": "Castro, Dante",
"affiliation": "Helmholtz-Zentrum Hereon, Geesthacht, Germany"
}
],
"keywords": [
Expand Down
1 change: 1 addition & 0 deletions AUTHORS.rst
Original file line number Diff line number Diff line change
Expand Up @@ -40,3 +40,4 @@ Contributors
* Ag Stephens <[email protected]> `@agstephens <https://github.com/agstephens>`_
* Maliko Tanguy <[email protected]> `@malngu <https://github.com/malngu>`_
* Christopher Whelan `@qwhelan <https://github.com/qwhelan>`_
* Dante Castro <[email protected]> `@profesorpaiche <https://github.com/profesorpaiche>`_
3 changes: 2 additions & 1 deletion CHANGES.rst
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ Changelog

v0.48 (unreleased)
------------------
Contributors to this version: Juliette Lavoie (:user:`juliettelavoie`), Pascal Bourgault (:user:`aulemahal`), Trevor James Smith (:user:`Zeitsperre`), David Huard (:user:`huard`), Éric Dupuis (:user:`coxipi`).
Contributors to this version: Juliette Lavoie (:user:`juliettelavoie`), Pascal Bourgault (:user:`aulemahal`), Trevor James Smith (:user:`Zeitsperre`), David Huard (:user:`huard`), Éric Dupuis (:user:`coxipi`), Dante Castro (:user:`profesorpaiche`).

Announcements
^^^^^^^^^^^^^
Expand All @@ -21,6 +21,7 @@ New features and enhancements
* Support ``indexer`` keyword in YAML indicator description. (:issue:`1522`, :pull:`1561`).
* New ``xclim.core.calendar.stack_periods`` and ``unstack_periods`` for performing ``rolling(time=...).construct(..., stride=...)`` but with non-uniform temporal periods like years or months. They replace ``xclim.sdba.processing.construct_moving_yearly_window`` and ``unpack_moving_yearly_window`` which are deprecated and will be removed in a future release.
* New ``as_dataset`` options for ``xclim.set_options``. When True, indicators will output Datasets instead of DataArrays. (:issue:`1257`, :pull:`1625`).
* Added new option for UTCI calculation to cap low wind velocities to a minimum of 0.5 m/s following Bröde (2012) guidelines. (:issue:`1634`, :pull:`1635`).

Breaking changes
^^^^^^^^^^^^^^^^
Expand Down
16 changes: 16 additions & 0 deletions docs/references.bib
Original file line number Diff line number Diff line change
Expand Up @@ -2098,3 +2098,19 @@ @article{thom_1958
abstract = {Abstract The general properties of the gamma distribution, which has several applications in meteorology, are discussed. A short review of the general properties of good statistical estimators is given. This is applied to the gamma distribution to show that the maximum likelihood estimators are jointly sufficient. A new, simple approximation of the likelihood solutions is given, and the efficiency of the fitting procedure is computed.},
chapter = {Monthly Weather Review},
}

@article{brode_utci_2012,
author = {Bröde, Peter and Fiala, Dusan and Błażejczyk, Krzysztof and Holmér, Ingvar and Jendritzky, Gerd and Kampmann, Bernhard and Tinz, Birger and Havenith, George},
title = {Deriving the operational procedure for the Universal Thermal Climate Index (UTCI)},
journal = {International Journal of Biometeorology},
year = {2012},
month = {May},
day = {01},
volume = {56},
number = {3},
pages = {481-494},
abstract = {The Universal Thermal Climate Index (UTCI) aimed for a one-dimensional quantity adequately reflecting the human physiological reaction to the multi-dimensionally defined actual outdoor thermal environment. The human reaction was simulated by the UTCI-Fiala multi-node model of human thermoregulation, which was integrated with an adaptive clothing model. Following the concept of an equivalent temperature, UTCI for a given combination of wind speed, radiation, humidity and air temperature was defined as the air temperature of the reference environment, which according to the model produces an equivalent dynamic physiological response. Operationalising this concept involved (1) the definition of a reference environment with 50{\%} relative humidity (but vapour pressure capped at 20 hPa), with calm air and radiant temperature equalling air temperature and (2) the development of a one-dimensional representation of the multivariate model output at different exposure times. The latter was achieved by principal component analyses showing that the linear combination of 7 parameters of thermophysiological strain (core, mean and facial skin temperatures, sweat production, skin wettedness, skin blood flow, shivering) after 30 and 120 min exposure time accounted for two-thirds of the total variation in the multi-dimensional dynamic physiological response. The operational procedure was completed by a scale categorising UTCI equivalent temperature values in terms of thermal stress, and by providing simplified routines for fast but sufficiently accurate calculation, which included look-up tables of pre-calculated UTCI values for a grid of all relevant combinations of climate parameters and polynomial regression equations predicting UTCI over the same grid. The analyses of the sensitivity of UTCI to humidity, radiation and wind speed showed plausible reactions in the heat as well as in the cold, and indicate that UTCI may in this regard be universally useable in the major areas of research and application in human biometeorology.},
issn = {1432-1254},
doi = {10.1007/s00484-011-0454-1},
url = {https://doi.org/10.1007/s00484-011-0454-1}
}
15 changes: 10 additions & 5 deletions tests/test_indices.py
Original file line number Diff line number Diff line change
Expand Up @@ -3481,26 +3481,31 @@ def test_simple(self, pr_series):
np.testing.assert_allclose(out, [4 / 31, 0, 0, 2 / 31, 0, 0, 0, 0, 0, 0, 0, 0])


@pytest.mark.parametrize(
"wind_cap_min,wind,expected",
[(False, 2, 17.70), (False, 1, np.nan), (True, 1, 17.76)],
)
def test_universal_thermal_climate_index(
tas_series,
hurs_series,
sfcWind_series,
wind_cap_min,
wind,
expected,
):
tas = tas_series(np.array([16]) + K2C)
hurs = hurs_series(np.array([36]))
sfcWind = sfcWind_series(np.array([2]))
sfcWind = sfcWind_series(np.array([wind]))
mrt = tas_series(np.array([22]) + K2C)

# Expected values
utci_exp = [17.7]

utci = xci.universal_thermal_climate_index(
tas=tas,
hurs=hurs,
sfcWind=sfcWind,
mrt=mrt,
wind_cap_min=wind_cap_min,
)
np.testing.assert_allclose(utci, utci_exp, rtol=1e-03)
np.testing.assert_allclose(utci, expected, rtol=1e-03)


@pytest.mark.parametrize("stat,expected", [("sunlit", 295.0), ("instant", 294.9)])
Expand Down
11 changes: 9 additions & 2 deletions xclim/indices/_conversion.py
Original file line number Diff line number Diff line change
Expand Up @@ -1781,6 +1781,7 @@ def universal_thermal_climate_index(
rlus: xr.DataArray | None = None,
stat: str = "sunlit",
mask_invalid: bool = True,
wind_cap_min: bool = False,
) -> xr.DataArray:
r"""Universal thermal climate index (UTCI).
Expand Down Expand Up @@ -1818,6 +1819,10 @@ def universal_thermal_climate_index(
If True (default), UTCI values are NaN where any of the inputs are outside
their validity ranges : -50°C < tas < 50°C, -30°C < tas - mrt < 30°C
and 0.5 m/s < sfcWind < 17.0 m/s.
wind_cap_min: bool
If True, wind velocities are capped to a minimum of 0.5 m/s following
:cite:t:`brode_utci_2012` usage guidalines. This ensures UTCI calculation
for low winds. Default value False.
Returns
-------
Expand All @@ -1837,11 +1842,13 @@ def universal_thermal_climate_index(
References
----------
:cite:cts:`brode_utci_2009,blazejczyk_introduction_2013`
:cite:cts:`brode_utci_2009,brode_utci_2012,blazejczyk_introduction_2013`
"""
e_sat = saturation_vapor_pressure(tas=tas, method="its90")
tas = convert_units_to(tas, "degC")
sfcWind = convert_units_to(sfcWind, "m/s")
if wind_cap_min:
sfcWind = sfcWind.clip(0.5, None)
if mrt is None:
mrt = mean_radiant_temperature(
rsds=rsds, rsus=rsus, rlds=rlds, rlus=rlus, stat=stat
Expand All @@ -1868,7 +1875,7 @@ def universal_thermal_climate_index(
& (tas < 50.0)
& (-30 < delta)
& (delta < 30)
& (0.5 < sfcWind)
& (0.5 <= sfcWind)
& (sfcWind < 17.0)
)
return utci
Expand Down

0 comments on commit cfd5643

Please sign in to comment.