Skip to content

Commit 4ef8ce4

Browse files
committed
Mixed-layer CAPE/CIN accepts depth in units of height
mixed_layer_cape_cin() can handle `depth` in units of height passed through kwargs. This works regardless of whether a `height` profile is provided.
1 parent 06c3bac commit 4ef8ce4

File tree

2 files changed

+45
-6
lines changed

2 files changed

+45
-6
lines changed

src/metpy/calc/thermo.py

+24-6
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
import scipy.optimize as so
1111
import xarray as xr
1212

13+
from .basic import height_to_pressure_std
1314
from .tools import (_greater_or_close, _less_or_close, _remove_nans, find_bounding_indices,
1415
find_intersections, first_derivative, get_layer)
1516
from .. import constants as mpconsts
@@ -2337,8 +2338,8 @@ def mixed_layer_cape_cin(pressure, temperature, dewpoint, **kwargs):
23372338
of a given upper air profile and mixed-layer parcel path. CIN is integrated between the
23382339
surface and LFC, CAPE is integrated between the LFC and EL (or top of sounding).
23392340
Intersection points of the measured temperature profile and parcel profile are
2340-
logarithmically interpolated. Kwargs for `mixed_parcel` can be provided, such as `depth`.
2341-
Default mixed-layer depth is 100 hPa.
2341+
logarithmically interpolated. Kwargs for `mixed_parcel` can be provided, such as `depth`
2342+
and `height`. Default mixed-layer depth is 100 hPa.
23422343
23432344
Parameters
23442345
----------
@@ -2352,7 +2353,9 @@ def mixed_layer_cape_cin(pressure, temperature, dewpoint, **kwargs):
23522353
Dewpoint profile
23532354
23542355
kwargs
2355-
Additional keyword arguments to pass to `mixed_parcel`
2356+
Additional keyword arguments to pass to `mixed_parcel`. If `depth` is passed with units
2357+
of height without also passing a `height` profile, `depth` will be converted to a
2358+
pressure with `height_to_pressure_std`.
23562359
23572360
Returns
23582361
-------
@@ -2372,14 +2375,29 @@ def mixed_layer_cape_cin(pressure, temperature, dewpoint, **kwargs):
23722375
Quantities even when given xarray DataArray profiles.
23732376
23742377
"""
2378+
height = kwargs.get('height')
23752379
depth = kwargs.get('depth', units.Quantity(100, 'hPa'))
2380+
2381+
# Convert depth from a height to a presure if needed
2382+
if depth.check('[length]') and height is None:
2383+
depth = height_to_pressure_std(units.Quantity(0, 'm')) - height_to_pressure_std(depth)
2384+
kwargs['depth'] = depth
2385+
warnings.warn('Depth of the mixed layer was given as a height, but no height profile '
2386+
'was provided. Depth of mixed layer was converted to '
2387+
+ str(round(depth, 2)) + ' using US standard atmosphere.')
2388+
23762389
parcel_pressure, parcel_temp, parcel_dewpoint = mixed_parcel(pressure, temperature,
23772390
dewpoint, **kwargs)
23782391

23792392
# Remove values below top of mixed layer and add in the mixed layer values
2380-
pressure_prof = pressure[pressure < (pressure[0] - depth)]
2381-
temp_prof = temperature[pressure < (pressure[0] - depth)]
2382-
dew_prof = dewpoint[pressure < (pressure[0] - depth)]
2393+
if depth.check('[length]'): # Depth is given as a height
2394+
pressure_prof = pressure[height > (depth - height[0])]
2395+
temp_prof = temperature[height > (depth - height[0])]
2396+
dew_prof = dewpoint[height > (depth - height[0])]
2397+
else: # Depth is given as a pressure
2398+
pressure_prof = pressure[pressure < (pressure[0] - depth)]
2399+
temp_prof = temperature[pressure < (pressure[0] - depth)]
2400+
dew_prof = dewpoint[pressure < (pressure[0] - depth)]
23832401
pressure_prof = concatenate([parcel_pressure, pressure_prof])
23842402
temp_prof = concatenate([parcel_temp, temp_prof])
23852403
dew_prof = concatenate([parcel_dewpoint, dew_prof])

tests/calc/test_thermo.py

+21
Original file line numberDiff line numberDiff line change
@@ -1323,6 +1323,27 @@ def test_mixed_layer_cape_cin(multiple_intersections):
13231323
assert_almost_equal(mlcin, -20.6727628 * units('joule / kilogram'), 2)
13241324

13251325

1326+
def test_mixed_layer_cape_cin_with_depth_as_height():
1327+
"""Test passing depth in units of height to mixed layer cape/cin calculation."""
1328+
pressure = np.array([1003., 1000., 972., 925., 901., 851., 850., 727., 708.]) * units.hPa
1329+
temperature = np.array([24.8, 24.4, 23., 20.6, 19.3, 16.4, 16.4, 11.4, 11.]) * units.degC
1330+
dewpoint = np.array([21.1, 21.5, 21., 20.2, 19., 16.3, 16.3, 8.1, 6.8]) * units.degC
1331+
height = np.array([140, 110, 358, 792, 1018, 1510, 1520, 2843, 3065]) * units.meter
1332+
1333+
# Test passing depth as height without a height profile
1334+
with pytest.warns(UserWarning):
1335+
mlcape, mlcin = mixed_layer_cape_cin(pressure, temperature, dewpoint,
1336+
depth=units.Quantity(500, 'm'))
1337+
assert_almost_equal(mlcape, 6.6591 * units('joule / kilogram'), 2)
1338+
assert_almost_equal(mlcin, -24.0292 * units('joule / kilogram'), 2)
1339+
1340+
# Test passing depth as height with a height profile
1341+
mlcape, mlcin = mixed_layer_cape_cin(pressure, temperature, dewpoint, height=height,
1342+
depth=units.Quantity(500, 'm'))
1343+
assert_almost_equal(mlcape, 7.2832 * units('joule / kilogram'), 2)
1344+
assert_almost_equal(mlcin, -23.3026 * units('joule / kilogram'), 2)
1345+
1346+
13261347
def test_mixed_layer():
13271348
"""Test the mixed layer calculation."""
13281349
pressure = np.array([959., 779.2, 751.3, 724.3, 700., 269.]) * units.hPa

0 commit comments

Comments
 (0)