Skip to content

Commit

Permalink
This update to the lfc() function allows for multiple LFCs to be
Browse files Browse the repository at this point in the history
identified within a sounding. This fixes Unidata#992 and begins to address
  • Loading branch information
zbruick committed Jun 13, 2019
1 parent 57497c2 commit b6a6602
Show file tree
Hide file tree
Showing 2 changed files with 53 additions and 6 deletions.
28 changes: 28 additions & 0 deletions metpy/calc/tests/test_thermo.py
Expand Up @@ -1201,6 +1201,34 @@ def test_lfc_not_below_lcl():
assert_almost_equal(lfc_temp, 6.4992871 * units.celsius, 6)


def test_multiple_lfcs():
"""Test sounding with multiple LFCs.
If return_all=False, return lowest-pressure LFC.
If return_all=True, return all LFCs
"""
levels = np.array([966., 937.2, 925., 904.6, 872.6, 853., 850., 836., 821., 811.6, 782.3,
754.2, 726.9, 700., 648.9, 624.6, 601.1, 595., 587., 576., 555.7,
534.2, 524., 500., 473.3, 400., 384.5, 358., 343., 308.3, 300., 276.,
273., 268.5, 250., 244.2, 233., 200.]) * units.mbar
temperatures = np.array([18.2, 16.8, 16.2, 15.1, 13.3, 12.2, 12.4, 14., 14.4,
13.7, 11.4, 9.1, 6.8, 4.4, -1.4, -4.4, -7.3, -8.1,
-7.9, -7.7, -8.7, -9.8, -10.3, -13.5, -17.1, -28.1, -30.7,
-35.3, -37.1, -43.5, -45.1, -49.9, -50.4, -51.1, -54.1, -55.,
-56.7, -57.5]) * units.degC
dewpoints = np.array([16.9, 15.9, 15.5, 14.2, 12.1, 10.8, 8.6, 0., -3.6, -4.4,
-6.9, -9.5, -12., -14.6, -15.8, -16.4, -16.9, -17.1, -27.9, -42.7,
-44.1, -45.6, -46.3, -45.5, -47.1, -52.1, -50.4, -47.3, -57.1,
-57.9, -58.1, -60.9, -61.4, -62.1, -65.1, -65.6,
-66.7, -70.5]) * units.degC
lfc_pressure, lfc_temp = lfc(levels, temperatures, dewpoints)
lfc_pressure_all, _ = lfc(levels, temperatures, dewpoints, return_all=True)
assert_almost_equal(lfc_pressure, 705.5170051 * units.mbar, 6)
assert_almost_equal(lfc_temp, 4.8922235 * units.degC, 6)
assert_almost_equal(len(lfc_pressure_all), 2, 0)


def test_cape_cin_custom_profile():
"""Test the CAPE and CIN calculation with a custom profile passed to LFC and EL."""
p = np.array([959., 779.2, 751.3, 724.3, 700., 269.]) * units.mbar
Expand Down
31 changes: 25 additions & 6 deletions metpy/calc/thermo.py
Expand Up @@ -362,7 +362,8 @@ def _lcl_iter(p, p0, w, t):
@exporter.export
@preprocess_xarray
@check_units('[pressure]', '[temperature]', '[temperature]', '[temperature]')
def lfc(pressure, temperature, dewpt, parcel_temperature_profile=None, dewpt_start=None):
def lfc(pressure, temperature, dewpt, parcel_temperature_profile=None, dewpt_start=None,
return_all=False):
r"""Calculate the level of free convection (LFC).
This works by finding the first intersection of the ideal parcel path and
Expand All @@ -382,11 +383,13 @@ def lfc(pressure, temperature, dewpt, parcel_temperature_profile=None, dewpt_sta
dewpt_start: `pint.Quantity`, optional
The dewpoint of the parcel for which to calculate the LFC. Defaults to the surface
dewpoint.
return_all: bool, optional
Option to return all LFCs in profile. Defaults to the lowest-pressure LFC.
Returns
-------
`pint.Quantity`
The LFC pressure and temperature
The LFC pressure and temperature, or lists of same if return_all=True
See Also
--------
Expand Down Expand Up @@ -439,11 +442,27 @@ def lfc(pressure, temperature, dewpt, parcel_temperature_profile=None, dewpt_sta
if not any(idx):
x, y = this_lcl
return x, y
# Otherwise, make select first candidate LFC above the LCL
# Otherwise, find all LFCs that exist above the LCL
else:
x = x[idx]
y = y[idx]
return x[0], y[0]
lfc_p_list, lfc_t_list = [], []
for i in np.where(x < this_lcl[0])[0]:
idp = np.where(pressure < x[i])[0][0]
env_lapse = (temperature[idp] - temperature[idp - 1]) / (pressure[idp]
- pressure[idp - 1])
prof_lapse = (parcel_temperature_profile[idp]
- parcel_temperature_profile[idp - 1]) / (pressure[idp]
- pressure[idp - 1])
# An intersection is a LFC if the environmental lapse rate is greater than
# the profile lapse rate
if env_lapse > prof_lapse:
lfc_p_list.append(x[i])
lfc_t_list.append(y[i])
# Return the lowest-pressure LFC if return_all=False, or return all if True
if return_all is False:
x, y = lfc_p_list[-1], lfc_t_list[-1]
else:
x, y = lfc_p_list, lfc_t_list
return x, y


@exporter.export
Expand Down

0 comments on commit b6a6602

Please sign in to comment.