-
Notifications
You must be signed in to change notification settings - Fork 1.1k
Calculate Relative Humidity via Magnus Tetens Equation #2286
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
Changes from 21 commits
70e0156
0ec0cbf
5eb9d00
ab2de3a
f62bd8e
77025c7
b52f9a9
58b246e
a06871a
caa4417
edd84b1
9c32f6a
63ed5c7
6312f92
410e95f
d94df47
e6b5908
63a9226
459d5a6
05b846f
0ae31e1
337f723
8bc9b86
9651c3b
b860ca5
2bdc1dc
c39c449
b5a6f09
aedc835
4fcb9e3
c956c91
f682815
0bfc6cb
71a165e
25527d6
1eff53f
df33a31
b4802a3
3893692
11d81c3
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change | ||||
---|---|---|---|---|---|---|
|
@@ -337,6 +337,82 @@ | |||||
return pw | ||||||
|
||||||
|
||||||
def rh_from_tdew(temperature, dewpoint, coeff=(6.112, 17.62, 243.12)): | ||||||
""" | ||||||
Calculate relative humidity from dewpoint temperature using the Magnus equation. | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. (inner grammarian emerges) the term is either "dewpoint" or "dew point": NOAA glossary. The AMS glossary prefers "dewpoint". I can't find any instances of "dew-point" as a hyphenated adjective, although I understand that's what grammar rules suggest it should be, rather than "dew point". There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Admittedly I didn't search beyond the WMO document we referenced, so it could be an old-world / new-world thing. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Happy to use any term that you all prefer There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Looks like EPW and TMY3 files use the hyphen. Most of the pvlib docs use "dew point", with the exception of the Nomenclature page which says "Dewpoint". I suggest we leave this for a potential package-wide cleanup and not worry about it here. |
||||||
|
||||||
Parameters | ||||||
---------- | ||||||
temperature : numeric | ||||||
Air temperature (dry-bulb temperature) in degrees Celsius | ||||||
dewpoint : numeric | ||||||
Dewpoint temperature in degrees Celsius | ||||||
kurt-rhee marked this conversation as resolved.
Show resolved
Hide resolved
|
||||||
coeff: tuple | ||||||
Magnus equation coefficient (A, B, C) | ||||||
kurt-rhee marked this conversation as resolved.
Show resolved
Hide resolved
|
||||||
|
||||||
Returns | ||||||
------- | ||||||
numeric | ||||||
Relative humidity as percentage (0.0-100.0) | ||||||
kurt-rhee marked this conversation as resolved.
Show resolved
Hide resolved
|
||||||
|
||||||
References | ||||||
---------- | ||||||
.. [1] "Guide to Instruments and Methods of Observation", | ||||||
World Meteorological Organization, WMO-No. 8, 2023. | ||||||
https://library.wmo.int/idurl/4/68695 | ||||||
""" | ||||||
|
||||||
# Calculate vapor pressure (e) and saturation vapor pressure (es) | ||||||
e = coeff[0] * np.exp((coeff[1] * temperature) / (coeff[2] + temperature)) | ||||||
es = coeff[0] * np.exp((coeff[1] * dewpoint) / (coeff[2] + dewpoint)) | ||||||
|
||||||
# Calculate relative humidity as percentage | ||||||
relative_humidity = 100 * (es / e) | ||||||
|
||||||
return relative_humidity | ||||||
|
||||||
|
||||||
def tdew_from_rh( | ||||||
temperature, relative_humidity, coeff=(6.112, 17.62, 243.12) | ||||||
): | ||||||
""" | ||||||
Calculate dewpoint temperature using Magnus equation. | ||||||
This is a reversal of the calculation in :py:func:`rh_from_tdew`. | ||||||
|
||||||
Parameters | ||||||
---------- | ||||||
temperature : numeric | ||||||
Air temperature (dry-bulb temperature) in degrees Celsius | ||||||
relative_humidity : numeric | ||||||
Relative humidity as percentage (0-100) | ||||||
kurt-rhee marked this conversation as resolved.
Show resolved
Hide resolved
|
||||||
|
||||||
kurt-rhee marked this conversation as resolved.
Show resolved
Hide resolved
|
||||||
Returns | ||||||
------- | ||||||
numeric | ||||||
Dewpoint temperature in degrees Celsius | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
kurt-rhee marked this conversation as resolved.
Show resolved
Hide resolved
|
||||||
|
||||||
References | ||||||
---------- | ||||||
.. [1] "Guide to Instruments and Methods of Observation", | ||||||
World Meteorological Organization, WMO-No. 8, 2023. | ||||||
https://library.wmo.int/idurl/4/68695 | ||||||
""" | ||||||
# Calculate the term inside the log | ||||||
# From RH = 100 * (es/e), we get es = (RH/100) * e | ||||||
# Substituting the Magnus equation and solving for dewpoint | ||||||
|
||||||
# First calculate ln(es/A) | ||||||
ln_term = ( | ||||||
(coeff[1] * temperature) / (coeff[2] + temperature) | ||||||
+ np.log(relative_humidity/100) | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. looks like RH zero might throw an error or warning here There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Should we add a check for zero values or leave the original message in the stack trace? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I don't think it's necessary, RH=0% is practically impossible (source). |
||||||
) | ||||||
|
||||||
# Then solve for dewpoint | ||||||
dewpoint = coeff[2] * ln_term / (coeff[1] - ln_term) | ||||||
|
||||||
return dewpoint | ||||||
|
||||||
|
||||||
first_solar_spectral_correction = deprecated( | ||||||
since='0.10.0', | ||||||
alternative='pvlib.spectrum.spectral_factor_firstsolar' | ||||||
|
kurt-rhee marked this conversation as resolved.
Show resolved
Hide resolved
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,108 @@ | ||
import numpy as np | ||
|
||
|
||
def magnus_tetens_aekr(temperature, dewpoint, A=6.112, B=17.62, C=243.12): | ||
""" | ||
Calculate relative humidity using Magnus equation with AEKR coefficients. | ||
This function was used by First Solar in creating their spectral model | ||
and is therefore relevant to the first solar spectral model in pvlib. | ||
Default magnus equation coefficients are from [2]. | ||
kurt-rhee marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
||
Parameters | ||
---------- | ||
temperature : pd.Series | ||
Air temperature in degrees Celsius | ||
kurt-rhee marked this conversation as resolved.
Show resolved
Hide resolved
|
||
dewpoint : pd.Series | ||
Dewpoint temperature in degrees Celsius | ||
kurt-rhee marked this conversation as resolved.
Show resolved
Hide resolved
|
||
A: float | ||
Magnus equation coefficient A | ||
B: float | ||
Magnus equation coefficient B | ||
C: float | ||
Magnus equation coefficient C | ||
kurt-rhee marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
||
Returns | ||
------- | ||
pd.Series | ||
Relative humidity as percentage (0-100) | ||
|
||
Notes | ||
----- | ||
Uses the AEKR coefficients which minimize errors between -40 and | ||
50 degrees C according to reference [1]. | ||
|
||
References | ||
---------- | ||
.. [1] https://www.osti.gov/servlets/purl/548871-PjpxAP/webviewable/ | ||
.. [2] https://www.schweizerbart.de//papers/metz/detail/3/89544/Advancements_in_the_field_of_hygrometry?af=crossref | ||
""" | ||
|
||
# Calculate vapor pressure (e) and saturation vapor pressure (es) | ||
e = A * np.exp((B * temperature) / (C + temperature)) | ||
es = A * np.exp((B * dewpoint) / (C + dewpoint)) | ||
|
||
# Calculate relative humidity as percentage | ||
relative_humidity = 100 * (es / e) | ||
|
||
return relative_humidity | ||
|
||
|
||
def reverse_magnus_tetens_aekr( | ||
temperature, relative_humidity, B=17.62, C=243.12 | ||
): | ||
""" | ||
Calculate dewpoint temperature using Magnus equation with | ||
AEKR coefficients. This is just a reversal of the calculation | ||
in calculate_relative_humidity. | ||
|
||
Parameters | ||
---------- | ||
temperature : pd.Series | ||
Air temperature in degrees Celsius | ||
relative_humidity : pd.Series | ||
Relative humidity as percentage (0-100) | ||
|
||
Returns | ||
------- | ||
pd.Series | ||
Dewpoint temperature in degrees Celsius | ||
|
||
Notes | ||
----- | ||
Derived by solving the Magnus equation for dewpoint given | ||
relative humidity. | ||
Valid for temperatures between -40 and 50 degrees C. | ||
|
||
References | ||
---------- | ||
.. [1] https://www.osti.gov/servlets/purl/548871-PjpxAP/webviewable/ | ||
""" | ||
# Calculate the term inside the log | ||
# From RH = 100 * (es/e), we get es = (RH/100) * e | ||
# Substituting the Magnus equation and solving for dewpoint | ||
|
||
# First calculate ln(es/A) | ||
ln_term = ( | ||
(B * temperature) / (C + temperature) | ||
+ np.log(relative_humidity/100) | ||
) | ||
|
||
# Then solve for dewpoint | ||
dewpoint = C * ln_term / (B - ln_term) | ||
|
||
return dewpoint | ||
|
||
|
||
if __name__ == "__main__": | ||
kurt-rhee marked this conversation as resolved.
Show resolved
Hide resolved
|
||
import pandas as pd | ||
rh = magnus_tetens_aekr( | ||
temperature=pd.Series([20.0, 25.0, 30.0, 15.0, 10.0]), | ||
dewpoint=pd.Series([15.0, 20.0, 25.0, 12.0, 8.0]) | ||
) | ||
|
||
dewpoint = reverse_magnus_tetens_aekr( | ||
temperature=pd.Series([20.0, 25.0, 30.0, 15.0, 10.0]), | ||
relative_humidity=rh | ||
) | ||
print(rh) | ||
print(dewpoint) | ||
kurt-rhee marked this conversation as resolved.
Show resolved
Hide resolved
kurt-rhee marked this conversation as resolved.
Show resolved
Hide resolved
|
Uh oh!
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I noticed earlier but forgot to comment: we should rename this parameter to
temp_dew
, the name used by other pvlib models and iotools functions. I'll push a commit for that to give @kurt-rhee a break from this PR :Pedit: and same for
temp_air
of course