Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

release 2.1.0 #38

Merged
merged 10 commits into from
Nov 11, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions ChangeLog.rst
Original file line number Diff line number Diff line change
@@ -1,6 +1,12 @@
ChangeLog
=========

Version 2.1.0
-------------

* Fix computaiton of normal effective temperature
* Fix documentation links to new repository URL

Version 2.0.0
-------------

Expand Down
45 changes: 20 additions & 25 deletions README.rst
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
.. image:: https://raw.githubusercontent.com/ecmwf-projects/thermofeel/master/thermofeel.png
.. image:: https://raw.githubusercontent.com/ecmwf/thermofeel/master/thermofeel.png
:width: 600
:alt: thermofeel logo

|license| |tag_release| |docs|
|license| |tag_release| |docs| |ci|

**thermofeel** (pronounced *thermo-feel*)

Expand Down Expand Up @@ -36,11 +36,6 @@ Install with::

$ pip install thermofeel

Testing
=======

|ci| |codecov|

System dependencies
===================

Expand Down Expand Up @@ -68,24 +63,24 @@ The main changes are:

Please consult ChangeLog_ for more details.

.. _ChangeLog: https://github.com/ecmwf-projects/thermofeel/blob/master/ChangeLog.rst
.. _ChangeLog: https://github.com/ecmwf/thermofeel/blob/master/ChangeLog.rst


Contributing
============

The main repository is hosted on `GitHub <https://github.com/ecmwf-projects/thermofeel>`_. Testing, bug reports and contributions are highly welcomed and appreciated.
The main repository is hosted on `GitHub <https://github.com/ecmwf/thermofeel>`_. Testing, bug reports and contributions are highly welcomed and appreciated.

Please see the Contributing_ document for the best way to help.

.. _Contributing: https://github.com/ecmwf-projects/thermofeel/blob/master/CONTRIBUTING.rst
.. _Contributing: https://github.com/ecmwf/thermofeel/blob/master/CONTRIBUTING.rst

Current developers:

- Claudia Di Napoli - `ECMWF <https://ecmwf.int>`_
- Tiago Quintino - `ECMWF <https://ecmwf.int>`_

See also the `contributors <https://github.com/ecmwf-projects/thermofeel/contributors>`_ for a more complete list.
See also the `contributors <https://github.com/ecmwf/thermofeel/contributors>`_ for a more complete list.

License
=======
Expand Down Expand Up @@ -130,16 +125,16 @@ Acknowledgements
Past and current funding and support for **thermofeel** is listed in the adjoning Acknowledgements_


.. _Acknowledgements: https://github.com/ecmwf-projects/thermofeel/blob/master/ACKNOWLEDGEMENTS.rst
.. _Acknowledgements: https://github.com/ecmwf/thermofeel/blob/master/ACKNOWLEDGEMENTS.rst


.. |last_commit| image:: https://img.shields.io/github/last-commit/ecmwf-projects/thermofeel
:target: https://github.com/ecmwf-projects/thermofeel
.. |last_commit| image:: https://img.shields.io/github/last-commit/ecmwf/thermofeel
:target: https://github.com/ecmwf/thermofeel

.. |commits_since_release| image:: https://img.shields.io/github/commits-since/ecmwf-projects/thermofeel/latest?sort=semver
:target: https://github.com/ecmwf-projects/thermofeel
.. |commits_since_release| image:: https://img.shields.io/github/commits-since/ecmwf/thermofeel/latest?sort=semver
:target: https://github.com/ecmwf/thermofeel

.. |license| image:: https://img.shields.io/github/license/ecmwf-projects/thermofeel
.. |license| image:: https://img.shields.io/github/license/ecmwf/thermofeel
:target: https://www.apache.org/licenses/LICENSE-2.0.html

.. |pypi_release| image:: https://img.shields.io/pypi/v/thermofeel?color=green
Expand All @@ -148,20 +143,20 @@ Past and current funding and support for **thermofeel** is listed in the adjonin
.. |pypi_status| image:: https://img.shields.io/pypi/status/thermofeel
:target: https://pypi.org/project/thermofeel

.. |tag_release| image:: https://img.shields.io/github/v/release/ecmwf-projects/thermofeel?sort=semver
:target: https://github.com/ecmwf-projects/thermofeel
.. |tag_release| image:: https://img.shields.io/github/v/release/ecmwf/thermofeel?sort=semver
:target: https://github.com/ecmwf/thermofeel

.. |codecov| image:: https://codecov.io/gh/ecmwf-projects/thermofeel/branch/master/graph/badge.svg
:target: https://codecov.io/gh/ecmwf-projects/thermofeel
.. |codecov| image:: https://codecov.io/gh/ecmwf/thermofeel/branch/master/graph/badge.svg
:target: https://codecov.io/gh/ecmwf/thermofeel

.. |ci| image:: https://img.shields.io/github/workflow/status/ecmwf-projects/thermofeel/ci
:target: https://github.com/ecmwf-projects/thermofeel/actions
.. |ci| image:: https://img.shields.io/github/actions/workflow/status/ecmwf/thermofeel/ci.yml
:target: https://github.com/ecmwf/thermofeel/actions

.. |pypi_downloads| image:: https://img.shields.io/pypi/dm/thermofeel
:target: https://pypi.org/project/thermofeel

.. |code_size| image:: https://img.shields.io/github/languages/code-size/ecmwf-projects/thermofeel?color=green
:target: https://github.com/ecmwf-projects/thermofeel
.. |code_size| image:: https://img.shields.io/github/languages/code-size/ecmwf/thermofeel?color=green
:target: https://github.com/ecmwf/thermofeel

.. |docs| image:: https://readthedocs.org/projects/thermofeel/badge/?version=latest
:target: https://thermofeel.readthedocs.io/en/latest/?badge=latest
Expand Down
100 changes: 50 additions & 50 deletions tests/net.csv
Original file line number Diff line number Diff line change
@@ -1,50 +1,50 @@
3.033889702205782442e+02
2.928502091976476436e+02
2.770285138080615752e+02
2.770490005238265780e+02
2.770928248276744625e+02
2.771638191543268022e+02
2.772180430167822465e+02
2.773481405053552180e+02
2.774187263366436014e+02
2.774623803824222819e+02
2.775973885081999697e+02
2.776094978681781527e+02
2.775812180858250713e+02
2.775939616382239024e+02
2.775908341477433510e+02
2.775773393811281267e+02
2.775198416488409521e+02
2.774920248106813006e+02
2.774635394202203997e+02
2.773664551403895189e+02
2.773095070329615623e+02
2.772699512899097840e+02
2.772017131727243964e+02
2.771203280402834821e+02
2.769705081825984507e+02
2.769574995185245712e+02
2.937299618046274645e+02
2.935924042492049466e+02
2.933120777011570226e+02
2.932935807975503053e+02
2.933526871192943872e+02
2.936544161860668964e+02
2.938921675892892722e+02
2.941795452139757003e+02
2.947574518545506521e+02
2.950281071095799916e+02
2.950420555947761159e+02
2.948682023918578352e+02
2.946889368890751939e+02
2.945812316730967950e+02
2.945970172400211027e+02
2.945403954938864217e+02
2.947040000154167956e+02
2.947692211015685757e+02
2.949256961037862652e+02
2.951105589804234341e+02
2.949321900709687725e+02
2.947569560678213065e+02
2.942588330787240238e+02
2.942205457588216859e+02
3.010065622860677763e+02
2.978004713493879763e+02
2.762241215897753364e+02
2.762341286739048769e+02
2.763012956155728830e+02
2.764059939851455852e+02
2.764790654938740317e+02
2.766273813534896249e+02
2.766893014126333696e+02
2.766966993523136011e+02
2.767887884697527738e+02
2.767496737064529952e+02
2.769510933062428535e+02
2.768837969370093788e+02
2.768171117155841898e+02
2.767348212481284122e+02
2.766230919517424240e+02
2.765545420051105907e+02
2.765267374915458731e+02
2.764466352440045398e+02
2.764088648567151267e+02
2.763790656581484200e+02
2.763100466759992742e+02
2.762046876422498372e+02
2.762623057754365163e+02
2.761689174526972579e+02
2.911413948240829654e+02
2.910768702461481325e+02
2.907986242602605671e+02
2.907857526147024601e+02
2.907969231665560415e+02
2.911296388794274321e+02
2.914604298204376391e+02
2.918874048860148491e+02
2.928703177480205682e+02
2.936264195426511492e+02
2.948825390578576844e+02
2.951751610936696579e+02
2.953622575333719738e+02
2.954328487477691283e+02
2.953756039592274760e+02
2.949602578417895415e+02
2.946793060090293466e+02
2.939725759663496092e+02
2.934531765165319825e+02
2.931004552660506874e+02
2.923946543653016761e+02
2.918684112352694342e+02
2.913048255487498182e+02
2.910969750368326459e+02
23 changes: 19 additions & 4 deletions tests/test_scalars.py
Original file line number Diff line number Diff line change
Expand Up @@ -144,7 +144,7 @@ def test_normal_effective_temperature(self):
rh = np.array([80])
net = np.array([tmf.calculate_normal_effective_temperature(t2_k, va, rh)])
# print(f"net {net}")
assert net == pytest.approx(314.7102642987715, abs=1e-6)
assert net == pytest.approx(304.13650125, abs=1e-6)

def test_apparent_temperature(self):
t2_k = np.array([tmf.celsius_to_kelvin(25.0)])
Expand All @@ -154,11 +154,26 @@ def test_apparent_temperature(self):
# print(f"at {at}")
assert at == pytest.approx(299.86678322384626, abs=1e-6)

def test_windchill(self):
def test_wind_chill(self):
t2_k = np.array([270])
va = np.array([10])
wc = np.array([tmf.calculate_wind_chill(t2_k, va)])
assert wc == pytest.approx(261.92338925380074, abs=1e-6)
wc_k = np.array([tmf.calculate_wind_chill(t2_k, va)])
assert wc_k == pytest.approx(261.92338925380074, abs=1e-6)
# reference result from from wikipedia article https://en.wikipedia.org/wiki/Wind_chill
t2_k = np.array([tmf.celsius_to_kelvin(-20)]) # -20C to K
va = np.array([5 / 3.6]) # 5 km/h to m/s
wc_k = np.array([tmf.calculate_wind_chill(t2_k, va)])
wc_c = tmf.kelvin_to_celsius(wc_k)
assert wc_c == pytest.approx(
-24.27850328, abs=1e-6
) # around ~ -24C for wind chill (not exact)
va = np.array([30 / 3.6]) # 30 km/h to m/s
wc_k = np.array([tmf.calculate_wind_chill(t2_k, va)])
wc_c = tmf.kelvin_to_celsius(wc_k)
print(f"wc_c {wc_c}")
assert wc_c == pytest.approx(
-32.56804448, abs=1e-6
) # around ~ -33C for wind chill (not exact)

def test_heat_index_simplified(self):
t2_k = np.array([tmf.celsius_to_kelvin(21.0)])
Expand Down
2 changes: 1 addition & 1 deletion thermofeel/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,4 +8,4 @@

from .thermofeel import * # noqa

__version__ = "2.0.0"
__version__ = "2.1.0"
19 changes: 10 additions & 9 deletions thermofeel/thermofeel.py
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,7 @@ def calculate_saturation_vapour_pressure(t2_k):
]
ess = g[7] * np.log(t2_k)
for i in range(7):
ess += g[i] * np.power(t2_k, (i - 2))
ess = ess + g[i] * np.power(t2_k, (i - 2))

ess = np.exp(ess) * 0.01 # hPa

Expand All @@ -98,14 +98,15 @@ def calculate_saturation_vapour_pressure_multiphase(t2_k, phase):
:param t2_k: (float array) 2m temperature [K]
:param phase: 0 over liquid water and 1 over ice
returns pressure of water vapor over a surface of liquid water or ice [hPa] == [mBar]
Reference: ECMWF IFS Documentation CY45R1 - Part IV : Physical processes (2018)
Reference: ECMWF IFS Documentation CY45R1 - Part IV : Physical processes (2018) pp. 116
https://doi.org/10.21957/4whwo8jw0
https://metview.readthedocs.io/en/latest/api/functions/saturation_vapour_pressure.html
"""

T0 = 273.16 # triple point of water 273.16 K (0.01 °C) at 611.73 Pa
es = np.zeros_like(t2_k)
y = (t2_k - 273.16) / (t2_k - 32.19) # over liquid water
y = (t2_k - T0) / (t2_k - 32.19) # over liquid water
es[phase == 0] = 6.1121 * np.exp(17.502 * y[phase == 0])
y = (t2_k - 273.16) / (t2_k + 0.7) # over ice
y = (t2_k - T0) / (t2_k + 0.7) # over ice
es[phase == 1] = 6.1121 * np.exp(22.587 * y[phase == 1])

return es
Expand Down Expand Up @@ -677,7 +678,7 @@ def calculate_normal_effective_temperature(t2_k, va, rh):
ditermeq = 1 / (1.76 + 1.4 * v**0.75)
net = (
37
- (37 - t2_k / (0.68 - 0.0014 * rh + ditermeq))
- ((37 - t2_k) / (0.68 - 0.0014 * rh + ditermeq))
- 0.29 * t2_k * (1 - 0.01 * rh)
)
net_k = celsius_to_kelvin(net)
Expand Down Expand Up @@ -710,11 +711,11 @@ def calculate_wind_chill(t2_k, va):
:param t2_k: (float array) 2m Temperature [K]
:param va: (float array) wind speed at 10 meters [m/s]
returns wind chill [K]
Temperature must be between -50°C and 5°C; wind speed must be between 5km/h and 80km/h
Wind chill from input values outside those ranges are not to be considered valid
Computation is only valid for temperatures between -50°C and 5°C and wind speeds between 5km/h and 80km/h.
For input values outside those ranges, computed results not be considered valid.
Reference: Blazejczyk et al. (2012)
https://doi.org/10.1007/s00484-011-0453-2
See also: http://www.ec.gc.ca/meteo-weather/default.asp?lang=n&n=5FBF816A-1#wc6
See also: https://web.archive.org/web/20130627223738/http://climate.weatheroffice.gc.ca/prods_servs/normals_documentation_e.html # noqa
"""
t2_c = kelvin_to_celsius(t2_k) # kelvin_to_celsius(tk)
v = va * 3.6 # convert to kilometers per hour
Expand Down
Loading