# Buggy code
def cape_cin(pressure, temperature, dewpt, parcel_profile):
    r"""Calculate CAPE and CIN.

    Calculate the convective available potential energy (CAPE) and convective inhibition (CIN)
    of a given upper air profile and parcel path. CIN is integrated between the surface and
    LFC, CAPE is integrated between the LFC and EL (or top of sounding). Intersection points of
    the measured temperature profile and parcel profile are linearly interpolated.

    Parameters
    ----------
    pressure : `pint.Quantity`
        The atmospheric pressure level(s) of interest, in order from highest to
        lowest pressure.
    temperature : `pint.Quantity`
        The atmospheric temperature corresponding to pressure.
    dewpt : `pint.Quantity`
        The atmospheric dewpoint corresponding to pressure.
    parcel_profile : `pint.Quantity`
        The temperature profile of the parcel.

    Returns
    -------
    `pint.Quantity`
        Convective Available Potential Energy (CAPE).
    `pint.Quantity`
        Convective INhibition (CIN).

    Notes
    -----
    Formula adopted from [Hobbs1977]_.

    .. math:: \text{CAPE} = -R_d \int_{LFC}^{EL} (T_{parcel} - T_{env}) d\text{ln}(p)

    .. math:: \text{CIN} = -R_d \int_{SFC}^{LFC} (T_{parcel} - T_{env}) d\text{ln}(p)


    * :math:`CAPE` Convective available potential energy
    * :math:`CIN` Convective inhibition
    * :math:`LFC` Pressure of the level of free convection
    * :math:`EL` Pressure of the equilibrium level
    * :math:`SFC` Level of the surface or beginning of parcel path
    * :math:`R_d` Gas constant
    * :math:`g` Gravitational acceleration
    * :math:`T_{parcel}` Parcel temperature
    * :math:`T_{env}` Environment temperature
    * :math:`p` Atmospheric pressure

    See Also
    --------
    lfc, el

    """
    # Calculate LFC limit of integration
    lfc_pressure, _ = lfc(
        pressure, temperature, dewpt, parcel_temperature_profile=parcel_profile
    )

    # If there is no LFC, no need to proceed.
    if np.isnan(lfc_pressure):
        return 0 * units("J/kg"), 0 * units("J/kg")
    else:
        lfc_pressure = lfc_pressure.magnitude

    # Calculate the EL limit of integration
    el_pressure, _ = el(
        pressure, temperature, dewpt, parcel_temperature_profile=parcel_profile
    )

    # No EL and we use the top reading of the sounding.
    if np.isnan(el_pressure):
        el_pressure = pressure[-1].magnitude
    else:
        el_pressure = el_pressure.magnitude

    # Difference between the parcel path and measured temperature profiles
    y = (parcel_profile - temperature).to(units.degK)

    # Estimate zero crossings
    x, y = _find_append_zero_crossings(np.copy(pressure), y)

    # CAPE
    # Only use data between the LFC and EL for calculation
    p_mask = _less_or_close(x.m, lfc_pressure) & _greater_or_close(x.m, el_pressure)
    x_clipped = x[p_mask].magnitude
    y_clipped = y[p_mask].magnitude
    cape = (mpconsts.Rd * (np.trapz(y_clipped, np.log(x_clipped)) * units.degK)).to(
        units("J/kg")
    )

    # CIN
    # Only use data between the surface and LFC for calculation
    p_mask = _greater_or_close(x.m, lfc_pressure)
    x_clipped = x[p_mask].magnitude
    y_clipped = y[p_mask].magnitude
    cin = (mpconsts.Rd * (np.trapz(y_clipped, np.log(x_clipped)) * units.degK)).to(
        units("J/kg")
    )

    return cape, cin


# Traceback (ValueError)
Traceback (most recent call last):
File "trouble_sounding.py", line 18, in <module>
filtered['dewpoint'].values * units.degC)
File "/opt/miniconda3/envs/prod/lib/python3.6/site-packages/metpy/xarray.py", line 571, in wrapper
return func(*args, **kwargs)
File "/opt/miniconda3/envs/prod/lib/python3.6/site-packages/metpy/units.py", line 312, in wrapper
return func(*args, **kwargs)
File "/opt/miniconda3/envs/prod/lib/python3.6/site-packages/metpy/calc/thermo.py", line 1756, in surface_based_cape_cin
return cape_cin(p, t, td, profile)
File "/opt/miniconda3/envs/prod/lib/python3.6/site-packages/metpy/xarray.py", line 571, in wrapper
return func(*args, **kwargs)
File "/opt/miniconda3/envs/prod/lib/python3.6/site-packages/metpy/units.py", line 312, in wrapper
return func(*args, **kwargs)
File "/opt/miniconda3/envs/prod/lib/python3.6/site-packages/metpy/calc/thermo.py", line 1430, in cape_cin
parcel_temperature_profile=parcel_profile)
File "/opt/miniconda3/envs/prod/lib/python3.6/site-packages/metpy/xarray.py", line 571, in wrapper
return func(*args, **kwargs)
File "/opt/miniconda3/envs/prod/lib/python3.6/site-packages/metpy/units.py", line 312, in wrapper
return func(*args, **kwargs)
File "/opt/miniconda3/envs/prod/lib/python3.6/site-packages/metpy/calc/thermo.py", line 451, in lfc
if np.min(el_pres) > this_lcl[0]:
File "<__array_function__ internals>", line 6, in amin
File "/opt/miniconda3/envs/prod/lib/python3.6/site-packages/numpy/core/fromnumeric.py", line 2746, in amin
keepdims=keepdims, initial=initial, where=where)
File "/opt/miniconda3/envs/prod/lib/python3.6/site-packages/numpy/core/fromnumeric.py", line 88, in _wrapreduction
return reduction(axis=axis, out=out, **passkwargs)
File "/opt/miniconda3/envs/prod/lib/python3.6/site-packages/pint/quantity.py", line 1357, in __numpy_method_wrap
value = func(*args, **kwargs)
File "/opt/miniconda3/envs/prod/lib/python3.6/site-packages/numpy/core/_methods.py", line 34, in _amin
return umr_minimum(a, axis, None, out, keepdims, initial, where)
ValueError: zero-size array to reduction operation minimum which has no identity

# Fixed code
def cape_cin(pressure, temperature, dewpt, parcel_profile):
    r"""Calculate CAPE and CIN.

    Calculate the convective available potential energy (CAPE) and convective inhibition (CIN)
    of a given upper air profile and parcel path. CIN is integrated between the surface and
    LFC, CAPE is integrated between the LFC and EL (or top of sounding). Intersection points of
    the measured temperature profile and parcel profile are linearly interpolated.

    Parameters
    ----------
    pressure : `pint.Quantity`
        The atmospheric pressure level(s) of interest, in order from highest to
        lowest pressure.
    temperature : `pint.Quantity`
        The atmospheric temperature corresponding to pressure.
    dewpt : `pint.Quantity`
        The atmospheric dewpoint corresponding to pressure.
    parcel_profile : `pint.Quantity`
        The temperature profile of the parcel.

    Returns
    -------
    `pint.Quantity`
        Convective Available Potential Energy (CAPE).
    `pint.Quantity`
        Convective INhibition (CIN).

    Notes
    -----
    Formula adopted from [Hobbs1977]_.

    .. math:: \text{CAPE} = -R_d \int_{LFC}^{EL} (T_{parcel} - T_{env}) d\text{ln}(p)

    .. math:: \text{CIN} = -R_d \int_{SFC}^{LFC} (T_{parcel} - T_{env}) d\text{ln}(p)


    * :math:`CAPE` Convective available potential energy
    * :math:`CIN` Convective inhibition
    * :math:`LFC` Pressure of the level of free convection
    * :math:`EL` Pressure of the equilibrium level
    * :math:`SFC` Level of the surface or beginning of parcel path
    * :math:`R_d` Gas constant
    * :math:`g` Gravitational acceleration
    * :math:`T_{parcel}` Parcel temperature
    * :math:`T_{env}` Environment temperature
    * :math:`p` Atmospheric pressure

    See Also
    --------
    lfc, el

    """
    # Calculate LFC limit of integration
    lfc_pressure, _ = lfc(
        pressure, temperature, dewpt, parcel_temperature_profile=parcel_profile
    )

    # If there is no LFC, no need to proceed.
    if np.isnan(lfc_pressure):
        return 0 * units("J/kg"), 0 * units("J/kg")
    else:
        lfc_pressure = lfc_pressure.magnitude

    # Calculate the EL limit of integration
    el_pressure, _ = el(
        pressure, temperature, dewpt, parcel_temperature_profile=parcel_profile
    )

    # No EL and we use the top reading of the sounding.
    if np.isnan(el_pressure):
        el_pressure = pressure[-1].magnitude
    else:
        el_pressure = el_pressure.magnitude

    # Difference between the parcel path and measured temperature profiles
    y = (parcel_profile - temperature).to(units.degK)

    # Estimate zero crossings
    x, y = _find_append_zero_crossings(np.copy(pressure), y)

    # CAPE
    # Only use data between the LFC and EL for calculation
    p_mask = _less_or_close(x.m, lfc_pressure) & _greater_or_close(x.m, el_pressure)
    x_clipped = x[p_mask].magnitude
    y_clipped = y[p_mask].magnitude
    cape = (mpconsts.Rd * (np.trapz(y_clipped, np.log(x_clipped)) * units.degK)).to(
        units("J/kg")
    )

    # CIN
    # Only use data between the surface and LFC for calculation
    p_mask = _greater_or_close(x.m, lfc_pressure)
    x_clipped = x[p_mask].magnitude
    y_clipped = y[p_mask].magnitude
    cin = (mpconsts.Rd * (np.trapz(y_clipped, np.log(x_clipped)) * units.degK)).to(
        units("J/kg")
    )

    # Set CIN to 0 if it's returned as a positive value (#1190)
    if cin > 0 * units("J/kg"):
        cin = 0 * units("J/kg")
    return cape, cin