Skip to content

Commit

Permalink
Merge pull request #3056 from 23ccozad/thermo-profile-nans
Browse files Browse the repository at this point in the history
Adjust user-provided parcel temperature profile for NaN values in EL and LFC
  • Loading branch information
dopplershift authored Jun 8, 2023
2 parents 7f4c5c7 + 278d02c commit 5b3a062
Show file tree
Hide file tree
Showing 2 changed files with 54 additions and 6 deletions.
18 changes: 12 additions & 6 deletions src/metpy/calc/thermo.py
Original file line number Diff line number Diff line change
Expand Up @@ -667,12 +667,15 @@ def lfc(pressure, temperature, dewpoint, parcel_temperature_profile=None, dewpoi
Renamed ``dewpt``,``dewpoint_start`` parameters to ``dewpoint``, ``dewpoint_start``
"""
pressure, temperature, dewpoint = _remove_nans(pressure, temperature, dewpoint)
# Default to surface parcel if no profile or starting pressure level is given
if parcel_temperature_profile is None:
new_stuff = parcel_profile_with_lcl(pressure, temperature, dewpoint)
pressure, temperature, dewpoint, parcel_temperature_profile = new_stuff
pressure, temperature, dewpoint = _remove_nans(pressure, temperature, dewpoint)
new_profile = parcel_profile_with_lcl(pressure, temperature, dewpoint)
pressure, temperature, dewpoint, parcel_temperature_profile = new_profile
parcel_temperature_profile = parcel_temperature_profile.to(temperature.units)
else:
new_profile = _remove_nans(pressure, temperature, dewpoint, parcel_temperature_profile)
pressure, temperature, dewpoint, parcel_temperature_profile = new_profile

if dewpoint_start is None:
dewpoint_start = dewpoint[0]
Expand Down Expand Up @@ -878,12 +881,15 @@ def el(pressure, temperature, dewpoint, parcel_temperature_profile=None, which='
Renamed ``dewpt`` parameter to ``dewpoint``
"""
pressure, temperature, dewpoint = _remove_nans(pressure, temperature, dewpoint)
# Default to surface parcel if no profile or starting pressure level is given
if parcel_temperature_profile is None:
new_stuff = parcel_profile_with_lcl(pressure, temperature, dewpoint)
pressure, temperature, dewpoint, parcel_temperature_profile = new_stuff
pressure, temperature, dewpoint = _remove_nans(pressure, temperature, dewpoint)
new_profile = parcel_profile_with_lcl(pressure, temperature, dewpoint)
pressure, temperature, dewpoint, parcel_temperature_profile = new_profile
parcel_temperature_profile = parcel_temperature_profile.to(temperature.units)
else:
new_profile = _remove_nans(pressure, temperature, dewpoint, parcel_temperature_profile)
pressure, temperature, dewpoint, parcel_temperature_profile = new_profile

# If the top of the sounding parcel is warmer than the environment, there is no EL
if parcel_temperature_profile[-1] > temperature[-1]:
Expand Down
42 changes: 42 additions & 0 deletions tests/calc/test_thermo.py
Original file line number Diff line number Diff line change
Expand Up @@ -663,6 +663,27 @@ def test_lfc_equals_lcl():
assert_almost_equal(lfc_temp, 15.8714 * units.celsius, 2)


def test_lfc_profile_nan():
"""Test LFC when the profile includes NaN values."""
levels = np.array([959., 779.2, 751.3, 724.3, 700., 269.]) * units.mbar
temperatures = np.array([22.2, 14.6, np.nan, 9.4, 7., -38.]) * units.degC
dewpoints = np.array([19., -11.2, -10.8, -10.4, np.nan, -53.2]) * units.degC
lfc_pressure, lfc_temperature = lfc(levels, temperatures, dewpoints)
assert_almost_equal(lfc_pressure, 727.3365 * units.mbar, 3)
assert_almost_equal(lfc_temperature, 9.6977 * units.degC, 3)


def test_lfc_profile_nan_with_parcel_profile():
"""Test LFC when the profile includes NaN values, and parcel temp profile is specified."""
levels = np.array([959., 779.2, 751.3, 724.3, 700., 269.]) * units.mbar
temperatures = np.array([22.2, 14.6, np.nan, 9.4, 7., -38.]) * units.degC
dewpoints = np.array([19., -11.2, -10.8, -10.4, np.nan, -53.2]) * units.degC
parcel_temps = parcel_profile(levels, temperatures[0], dewpoints[0]).to('degC')
lfc_pressure, lfc_temperature = lfc(levels, temperatures, dewpoints, parcel_temps)
assert_almost_equal(lfc_pressure, 727.3365 * units.mbar, 3)
assert_almost_equal(lfc_temperature, 9.6977 * units.degC, 3)


def test_sensitive_sounding():
"""Test quantities for a sensitive sounding (#902)."""
# This sounding has a very small positive area in the low level. It's only captured
Expand Down Expand Up @@ -987,6 +1008,27 @@ def test_el_below_lcl():
assert_nan(el_t, t.units)


def test_el_profile_nan():
"""Test EL when the profile includes NaN values."""
levels = np.array([959., 779.2, 751.3, 724.3, 700., 269.]) * units.mbar
temperatures = np.array([22.2, 14.6, np.nan, 9.4, 7., -38.]) * units.degC
dewpoints = np.array([19., -11.2, -10.8, -10.4, np.nan, -53.2]) * units.degC
el_pressure, el_temperature = el(levels, temperatures, dewpoints)
assert_almost_equal(el_pressure, 673.0104 * units.mbar, 3)
assert_almost_equal(el_temperature, 5.8853 * units.degC, 3)


def test_el_profile_nan_with_parcel_profile():
"""Test EL when the profile includes NaN values, and a parcel temp profile is specified."""
levels = np.array([959., 779.2, 751.3, 724.3, 700., 269.]) * units.mbar
temperatures = np.array([22.2, 14.6, np.nan, 9.4, 7., -38.]) * units.degC
dewpoints = np.array([19., -11.2, -10.8, -10.4, np.nan, -53.2]) * units.degC
parcel_temps = parcel_profile(levels, temperatures[0], dewpoints[0]).to('degC')
el_pressure, el_temperature = el(levels, temperatures, dewpoints, parcel_temps)
assert_almost_equal(el_pressure, 673.0104 * units.mbar, 3)
assert_almost_equal(el_temperature, 5.8853 * units.degC, 3)


def test_wet_psychrometric_vapor_pressure():
"""Test calculation of vapor pressure from wet and dry bulb temperatures."""
p = 1013.25 * units.mbar
Expand Down

0 comments on commit 5b3a062

Please sign in to comment.