Skip to content

Value error calculating CAPE for a layer #2315

@dopplershift

Description

@dopplershift

This example from a StackOverflow question fails:

from datetime import datetime, timedelta   
from siphon.catalog import TDSCatalog
from siphon.ncss import NCSS
import numpy as np
from metpy.units import units
import cartopy.crs as ccrs
from metpy.calc import (dewpoint_from_relative_humidity, mixed_parcel, most_unstable_parcel, parcel_profile, pressure_to_height_std, lcl, height_to_pressure_std, get_layer, cape_cin)

year=2019
month=5
day=23
hour=0

cenlat = 34.91269
cenlon = -98.21048

time_start = datetime(year, month, day, hour, 0) #specified time
hour = time_start.hour
if hour < 10:
    hour = '0'+str(hour)
day = time_start.day
if day < 10:
    day = '0'+str(day)
month = time_start.month
if month < 10:
    month = '0'+str(month)

cat = TDSCatalog('https://www.ncdc.noaa.gov/thredds/catalog/model-rap130-old/'+str(time_start.year)+str(month)+'/'+str(time_start.year)+str(month)+str(day)+'/catalog.html?dataset=rap130-old/'+str(time_start.year)+str(month)+'/'+str(time_start.year)+str(month)+str(day)+'/rap_130_'+str(time_start.year)+str(month)+str(day)+'_'+str(hour)+'00_000.grb2')
latest_ds = list(cat.datasets.values())[0]
print(latest_ds.access_urls)
ncss = NCSS(latest_ds.access_urls['NetcdfSubset'])

query = ncss.query()
query.variables('Pressure_surface').variables('Geopotential_height_isobaric').variables('Geopotential_height_surface').variables('Relative_humidity_isobaric').variables('Temperature_isobaric').variables('Dewpoint_temperature_height_above_ground').variables('Temperature_height_above_ground').variables
query.add_lonlat().lonlat_box(cenlon-2.1, cenlon +2.1, cenlat-2.1, cenlat+2.1)
data1 = ncss.get_data(query)
dlev = data1.variables['Geopotential_height_isobaric'].dimensions[1]
dlat = data1.variables['Geopotential_height_isobaric'].dimensions[2]
dlon = data1.variables['Geopotential_height_isobaric'].dimensions[3]

SFCP = (np.asarray(data1.variables['Pressure_surface'][:])/100.) * units('hPa')
hgt = np.asarray(data1.variables['Geopotential_height_isobaric'][:]) * units('meter')
sfc_hgt = np.asarray(data1.variables['Geopotential_height_surface'][:]) * units('meter')
Temp_up = np.asarray(data1.variables['Temperature_isobaric'][:]) * units('kelvin')
RH_up = np.asarray(data1.variables['Relative_humidity_isobaric'][:])
Td = (np.asarray(data1.variables['Dewpoint_temperature_height_above_ground'][:]) * units('kelvin')).to('degC')
T = np.asarray(data1.variables['Temperature_height_above_ground'][:]) * units('kelvin')

# Get the dimension data
lats_r = data1.variables[dlat][:]
lons_r= data1.variables[dlon][:]
lev = (np.asarray(data1.variables[dlev][:])/100.) * units('hPa')

# Set up our array of latitude and longitude values and transform to the desired projection.
flon = float(cenlon)
flat = float(cenlat)
crs = ccrs.PlateCarree()
crlons, crlats = np.meshgrid(lons_r[:]*1000, lats_r[:]*1000)
trlatlons = crs.transform_points(ccrs.LambertConformal(central_longitude=265, central_latitude=25, standard_parallels=(25.,25.)),crlons,crlats)
trlons = trlatlons[:,:,0]
trlats = trlatlons[:,:,1]
dlon = np.abs(trlons - cenlon)
dlat = np.abs(trlats - cenlat)
ilon = np.where(dlon == np.min(dlon)) #position in the dlon array with minimal difference between gridpoint lon and input lon
ilat = np.where(dlat == np.min(dlat)) #position in the dlat array with minimal difference between gridpoint lat and input lat

Tdc_up = dewpoint_from_relative_humidity(Temp_up[0,:,ilat[0][0], ilon[1][0]],RH_up[0,:,ilat[0][0], ilon[1][0]]/100)

p_sounding = np.sort(np.append(lev, SFCP[0,ilat[0][0], ilon[1][0]]))
ind = np.where(p_sounding >= SFCP[0,ilat[0][0], ilon[1][0]])[0][0]
hgt_sounding = np.insert(hgt[0,:,ilat[0][0], ilon[1][0]].magnitude, ind, sfc_hgt[0,ilat[0][0], ilon[1][0]].magnitude) * hgt.units
T_sounding = (np.insert(Temp_up[0,:,ilat[0][0], ilon[1][0]].magnitude, ind, T[0,0,ilat[0][0], ilon[1][0]].magnitude) * T.units).to(Tdc_up.units)
Td_sounding = np.insert(Tdc_up.magnitude, ind, Td[0,0,ilat[0][0], ilon[1][0]].magnitude) * Tdc_up.units
p_skewt = p_sounding[p_sounding <= SFCP[0,ilat[0][0], ilon[1][0]]]
hgt_skewt = hgt_sounding[p_sounding <= SFCP[0,ilat[0][0], ilon[1][0]]]
T_skewt = T_sounding[p_sounding <= SFCP[0,ilat[0][0], ilon[1][0]]]
Td_skewt = Td_sounding[p_sounding <= SFCP[0,ilat[0][0], ilon[1][0]]]

AGLhgts = hgt_skewt[::-1]-hgt_skewt[-1]

ml_p, ml_T, ml_Td = mixed_parcel(np.flip(p_skewt), np.flip(T_skewt), np.flip(Td_skewt))
ml_profile = parcel_profile(p_skewt[::-1], ml_T, ml_Td)
ml_profile = (ml_profile - 273.15*units('kelvin')).magnitude*units('degC')

mu_p, mu_T, mu_Td, mu_index = most_unstable_parcel(np.flip(p_skewt), np.flip(T_skewt), np.flip(Td_skewt))
mu_profile = parcel_profile(p_skewt[::-1], mu_T, mu_Td)
mu_profile = (mu_profile - 273.15*units('kelvin')).magnitude*units('degC')

#Note: sbpcl_profile will have the exact same values of p_skewt, T_skewt, and Td_skewt in pprof below:
pprof = parcel_profile(p_skewt[::-1], T_skewt[-1], Td_skewt[-1])
pprof = (pprof - 273.15*units('kelvin')).magnitude*units('degC')

mllcl = lcl(ml_p, ml_T, ml_Td)
mllcl_h = pressure_to_height_std(mllcl[0]) - hgt_skewt[-1]

mulcl = lcl(mu_p, mu_T, mu_Td)
mulcl_h = pressure_to_height_std(mulcl[0]) - hgt_skewt[-1]

sblcl = lcl(p_skewt[-1], T_skewt[-1], Td_skewt[-1])
sblcl_h = pressure_to_height_std(sblcl[0]) - hgt_skewt[-1]

mllcl2000 = mllcl_h + 2*units('kilometer')
mulcl2000 = mulcl_h + 2*units('kilometer')
sblcl2000 = sblcl_h + 2*units('kilometer')
mllcl2000_p = height_to_pressure_std(mllcl2000)
mulcl2000_p = height_to_pressure_std(mulcl2000)
sblcl2000_p = height_to_pressure_std(sblcl2000)

ml_LCL_CAPE_layer = get_layer(p_skewt, T_skewt, Td_skewt, ml_profile[::-1], bottom = mllcl[0], depth = mllcl[0] - mllcl2000_p)
mu_LCL_CAPE_layer = get_layer(p_skewt, T_skewt, Td_skewt, mu_profile[::-1], bottom = mulcl[0], depth = mulcl[0] - mulcl2000_p)
sb_LCL_CAPE_layer = get_layer(p_skewt, T_skewt, Td_skewt, pprof[::-1], bottom = sblcl[0], depth = sblcl[0] - sblcl2000_p)

mlLCLCAPE = cape_cin(ml_LCL_CAPE_layer[0], ml_LCL_CAPE_layer[1], ml_LCL_CAPE_layer[2], ml_LCL_CAPE_layer[3])
muLCLCAPE = cape_cin(mu_LCL_CAPE_layer[0], mu_LCL_CAPE_layer[1], mu_LCL_CAPE_layer[2], mu_LCL_CAPE_layer[3])
sbLCLCAPE = cape_cin(sb_LCL_CAPE_layer[0], sb_LCL_CAPE_layer[1], sb_LCL_CAPE_layer[2], sb_LCL_CAPE_layer[3])

with the following:

---------------------------------------------------------------------------
ValueError                                Traceback (most recent call last)
/var/folders/r8/bhrhn4m56lgdckj491rm6_w40000gp/T/ipykernel_18027/3613122800.py in <module>
      4 
      5 mlLCLCAPE = cape_cin(ml_LCL_CAPE_layer[0], ml_LCL_CAPE_layer[1], ml_LCL_CAPE_layer[2], ml_LCL_CAPE_layer[3])
----> 6 muLCLCAPE = cape_cin(mu_LCL_CAPE_layer[0], mu_LCL_CAPE_layer[1], mu_LCL_CAPE_layer[2], mu_LCL_CAPE_layer[3])
      7 sbLCLCAPE = cape_cin(sb_LCL_CAPE_layer[0], sb_LCL_CAPE_layer[1], sb_LCL_CAPE_layer[2], sb_LCL_CAPE_layer[3])

~/repos/metpy/src/metpy/xarray.py in wrapper(*args, **kwargs)
   1228 
   1229             # Evaluate inner calculation
-> 1230             result = func(*bound_args.args, **bound_args.kwargs)
   1231 
   1232             # Wrap output based on match and match_unit

~/repos/metpy/src/metpy/units.py in wrapper(*args, **kwargs)
    286         def wrapper(*args, **kwargs):
    287             _check_units_inner_helper(func, sig, defaults, dims, *args, **kwargs)
--> 288             return func(*args, **kwargs)
    289 
    290         return wrapper

~/repos/metpy/src/metpy/calc/thermo.py in cape_cin(pressure, temperature, dewpoint, parcel_profile, which_lfc, which_el)
   1856                                                                    dewpoint, parcel_profile)
   1857     # Calculate LFC limit of integration
-> 1858     lfc_pressure, _ = lfc(pressure, temperature, dewpoint,
   1859                           parcel_temperature_profile=parcel_profile, which=which_lfc)
   1860 

~/repos/metpy/src/metpy/xarray.py in wrapper(*args, **kwargs)
   1228 
   1229             # Evaluate inner calculation
-> 1230             result = func(*bound_args.args, **bound_args.kwargs)
   1231 
   1232             # Wrap output based on match and match_unit

~/repos/metpy/src/metpy/units.py in wrapper(*args, **kwargs)
    286         def wrapper(*args, **kwargs):
    287             _check_units_inner_helper(func, sig, defaults, dims, *args, **kwargs)
--> 288             return func(*args, **kwargs)
    289 
    290         return wrapper

~/repos/metpy/src/metpy/calc/thermo.py in lfc(pressure, temperature, dewpoint, parcel_temperature_profile, dewpoint_start, which)
    556                                                 temperature[1:], direction='decreasing',
    557                                                 log_x=True)
--> 558             if np.min(el_pressure) > this_lcl[0]:
    559                 x = units.Quantity(np.nan, pressure.units)
    560                 y = units.Quantity(np.nan, temperature.units)

~/miniconda3/envs/py310/lib/python3.10/site-packages/numpy/core/overrides.py in amin(*args, **kwargs)

~/miniconda3/envs/py310/lib/python3.10/site-packages/pint/quantity.py in __array_function__(self, func, types, args, kwargs)
   1724 
   1725     def __array_function__(self, func, types, args, kwargs):
-> 1726         return numpy_wrap("function", func, args, kwargs, types)
   1727 
   1728     _wrapped_numpy_methods = ["flatten", "astype", "item"]

~/miniconda3/envs/py310/lib/python3.10/site-packages/pint/numpy_func.py in numpy_wrap(func_type, func, args, kwargs, types)
    919     if name not in handled or any(is_upcast_type(t) for t in types):
    920         return NotImplemented
--> 921     return handled[name](*args, **kwargs)

~/miniconda3/envs/py310/lib/python3.10/site-packages/pint/numpy_func.py in implementation(*args, **kwargs)
    751         for i, unwrapped_unit_arg in enumerate(unwrapped_unit_args):
    752             bound_args.arguments[valid_unit_arguments[i]] = unwrapped_unit_arg
--> 753         ret = func(*bound_args.args, **bound_args.kwargs)
    754 
    755         # Conditionally wrap output

~/miniconda3/envs/py310/lib/python3.10/site-packages/numpy/core/overrides.py in amin(*args, **kwargs)

~/miniconda3/envs/py310/lib/python3.10/site-packages/numpy/core/fromnumeric.py in amin(a, axis, out, keepdims, initial, where)
   2914     6
   2915     """
-> 2916     return _wrapreduction(a, np.minimum, 'min', axis, None, out,
   2917                           keepdims=keepdims, initial=initial, where=where)
   2918 

~/miniconda3/envs/py310/lib/python3.10/site-packages/numpy/core/fromnumeric.py in _wrapreduction(obj, ufunc, method, axis, dtype, out, **kwargs)
     84                 return reduction(axis=axis, out=out, **passkwargs)
     85 
---> 86     return ufunc.reduce(obj, axis, dtype, out, **passkwargs)
     87 
     88 

ValueError: zero-size array to reduction operation minimum which has no identity

Metadata

Metadata

Assignees

No one assigned

    Labels

    Area: CalcPertains to calculationsType: BugSomething is not working like it should

    Type

    No type

    Projects

    Status

    No status

    Milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions