Exemplo n.º 1
0
def parcelUAV(T, Td, p):
	'''
	Inputs: temperature, dewpoint, and pressure
	Returns: lcl pressure, lcl temperature, isbelowlcl flag, profile temp
	'''
	lclpres, lcltemp = mcalc.lcl(p[0] * units.mbar, 
        T[0] * units.degC, Td[0] * units.degC)
	print 'LCL Pressure: %5.2f %s' % (lclpres.magnitude, lclpres.units)
	print 'LCL Temperature: %5.2f %s' % (lcltemp.magnitude, lcltemp.units)

	# parcel profile
	# determine if there are points sampled above lcl
	ilcl = np.squeeze(np.where((p * units.mbar) <= lclpres))
	# if not, entire profile dry adiabatic
	if ilcl.size == 0:
	    prof = mcalc.dry_lapse(p * units.mbar, T[0] * units.degC).to('degC')
	    isbelowlcl = 1
	# if there are, need to concat dry & moist profile ascents
	else:
	    ilcl = ilcl[0]
	    prof_dry = mcalc.dry_lapse(p[:ilcl] * units.mbar,
	        T[0] * units.degC).to('degC')
	    prof_moist = mcalc.moist_lapse(p[ilcl:] * units.mbar,
	        prof_dry[-1]).to('degC')
	    prof = np.concatenate((prof_dry, prof_moist)) * units.degC
	    isbelowlcl = 0

	return lclpres, lcltemp, isbelowlcl, prof
Exemplo n.º 2
0
def test_moist_lapse():
    """Test moist_lapse calculation."""
    temp = moist_lapse(
        np.array([1000., 800., 600., 500., 400.]) * units.mbar,
        293. * units.kelvin)
    true_temp = np.array([293, 284.64, 272.81, 264.42, 252.91]) * units.kelvin
    assert_array_almost_equal(temp, true_temp, 2)
Exemplo n.º 3
0
def test_moist_lapse_degc():
    """Test moist_lapse with Celsius temperatures."""
    temp = moist_lapse(
        np.array([1000., 800., 600., 500., 400.]) * units.mbar,
        19.85 * units.degC)
    true_temp = np.array([293, 284.64, 272.81, 264.42, 252.91]) * units.kelvin
    assert_array_almost_equal(temp, true_temp, 2)
Exemplo n.º 4
0
def showalter_index(pressure, temperature, dewpt):
    """Calculate Showalter Index from pressure temperature and 850 hPa lcl.

    Showalter Index derived from [Galway1956]_:
    SI = T500 - Tp500

    where:
    T500 is the measured temperature at 500 hPa
    Tp500 is the temperature of the lifted parcel at 500 hPa

    Parameters
    ----------

        pressure : `pint.Quantity`
            Atmospheric pressure level(s) of interest, in order from highest
            to lowest pressure

        temperature : `pint.Quantity`
            Parcel temperature for corresponding pressure

        dewpt (:class: `pint.Quantity`):
            Parcel dew point temperatures for corresponding pressure


     Returns
     -------

     `pint.Quantity`
        Showalter index in delta degrees celsius
    """

    # find the measured temperature and dew point temperature at 850 hPa.
    idx850 = np.where(pressure == 850 * units.hPa)
    T850 = temperature[idx850]
    Td850 = dewpt[idx850]

    # find the parcel profile temperature at 500 hPa.
    idx500 = np.where(pressure == 500 * units.hPa)
    Tp500 = temperature[idx500]

    # Calculate lcl at the 850 hPa level
    lcl_calc = mpcalc.lcl(850 * units.hPa, T850[0], Td850[0])
    lcl_calc = lcl_calc[0]

    # Define start and end heights for dry and moist lapse rate calculations
    p_strt = 1000 * units.hPa
    p_end = 500 * units.hPa

    # Calculate parcel temp when raised dry adiabatically from surface to lcl
    dl = mpcalc.dry_lapse(lcl_calc, temperature[0], p_strt)
    dl = (dl.magnitude - 273.15) * units.degC  # Change units to C

    # Calculate parcel temp when raised moist adiabatically from lcl to 500mb
    ml = mpcalc.moist_lapse(p_end, dl, lcl_calc)

    # Calculate the Showalter index
    shox = Tp500 - ml
    return shox
Exemplo n.º 5
0
def down_cape(p_start=None):

    if p_start not in ls.lev:
        raise ValueError(
            "Please provide pressure of one level of large-scale dataset to start calculating DCAPE from."
        )

    # find index of p_start
    start_level = int((abs(ls.lev - p_start)).argmin())

    # get temperature and humidity from large-scale state
    temp = ls.T.sel(lev=slice(None, 990)).metpy.unit_array
    mix = ls.r.sel(lev=slice(None, 990)).metpy.unit_array.to('kg/kg')
    p_vector = ls.lev.sel(lev=slice(None, 990)).metpy.unit_array

    # get dew-point temperature
    vap_pres = mpcalc.vapor_pressure(p_vector, mix)
    dew_temp = mpcalc.dewpoint(vap_pres)

    # pressure levels to integrate over
    p_down = ls.lev.sel(lev=slice(p_start, 990))

    # find NaNs
    l_valid = ls.T[:, start_level].notnull().values

    d_cape = xr.full_like(ls.cape, np.nan)
    x = p_down.values
    temp = temp[l_valid, :]
    dew_temp = dew_temp[l_valid, :]
    # loop over all non-NaN times in large-scale state
    for i, this_time in enumerate(ls.T[l_valid].time):
        print(i)
        # bug: p_start has to be multiplied with units when given as argument, not beforehand
        wb_temp = mpcalc.wet_bulb_temperature(p_start * units['hPa'],
                                              temp[i, start_level],
                                              dew_temp[i, start_level])

        # create placeholder for moist adiabat temperature
        moist_adiabat = temp[i, start_level:].to('degC')

        moist_adiabat_below = mpcalc.moist_lapse(p_vector[start_level + 1:],
                                                 wb_temp,
                                                 p_start * units['hPa'])
        moist_adiabat[0] = wb_temp
        moist_adiabat[1:] = moist_adiabat_below

        env_temp = temp[i, start_level:]
        temp_diff = moist_adiabat - env_temp

        y = temp_diff.magnitude
        d_cape.loc[this_time] = (mpconsts.Rd *
                                 (np.trapz(y, np.log(x)) * units.degK)).to(
                                     units('J/kg'))

    d_cape.attrs['long_name'] = 'Downward CAPE'
    return xr.merge([ls, xr.Dataset({'d_cape': d_cape})])
Exemplo n.º 6
0
def moist_adiabat(z, SST):
    p = 1000 * np.exp(-9.81 * z / (287. * 270.)) * units.hPa
    Tp = mpcalc.moist_lapse(p, (SST - 1) * units.K)
    qp = 0.8 * mpcalc.saturation_mixing_ratio(p, Tp)

    ztrop1 = 17e3
    ztrop2 = 19e3
    idx1 = np.argmin((z - ztrop1)**2)
    idx2 = np.argmin((z - ztrop2)**2)
    Tp[idx1:idx2] = Tp[idx1]
    Tp[idx2:] = Tp[idx1] + 2e-3 * (z[idx2:] - ztrop2) * units.K
    thetap = mpcalc.potential_temperature(p, Tp)
    thicknesses = [
        mpcalc.thickness_hydrostatic(p, Tp, bottom=p[i], depth=p[i] - p[i + 1])
        / units.m for i in range(len(p) - 1)
    ]
    zp = np.concatenate([[0.], np.cumsum(thicknesses)])

    thetaz = np.interp(z, zp, (thetap / units.K))
    qz = np.interp(z, zp, qp)
    idxs = z < 35000
    return z[idxs], np.array([float(x) for x in thetaz
                              ])[idxs], np.array([float(x) for x in qz])[idxs]
Exemplo n.º 7
0
def atmCalc(height, temp, humid):
    print("ATMCALC", height, temp, humid, file=sys.stderr)
    mtny = windh(MTNX, height, ratio=1,
                 yoffset=0)

    windx = XVALUES
    windy = windh(windx, height)

    temp_ = temp * units.degC
    initp = mc.height_to_pressure_std(windy[0] * units.meters)
    dewpt = mc.dewpoint_from_relative_humidity(temp_, humid / 100.)
    lcl_ = mc.lcl(initp, temp_, dewpt, max_iters=50, eps=1e-5)
    LCL = mc.pressure_to_height_std(lcl_[0])

    if (lcl_[0] > mc.height_to_pressure_std(max(windy) * units.meters)
            and LCL > windy[0] * units.meters * 1.000009):
        # add LCL to x
        xlcl = windh(LCL.to('meters').magnitude, height, inv=True)
        windx = np.sort(np.append(windx, xlcl))
        windy = windh(windx, height)

    pressures = mc.height_to_pressure_std(windy * units.meters)

    wvmr0 = mc.mixing_ratio_from_relative_humidity(initp, temp_, humid / 100.)

    # now calculate the air parcel temperatures and RH at each position
    if (lcl_[0] <= min(pressures)):
        T = mc.dry_lapse(pressures, temp_)
        RH = [
            mc.relative_humidity_from_mixing_ratio(
                wvmr0, t, p) for t, p in zip(
                T, pressures)]
    else:
        mini = np.argmin(pressures)
        p1 = pressures[:mini + 1]
        p2 = pressures[mini:]  # with an overlap
        p11 = p1[p1 >= lcl_[0] * .9999999]  # lower (with tol) with lcl
        p12 = p1[p1 < lcl_[0] * 1.000009]  # upper (with tol) with lcl
        T11 = mc.dry_lapse(p11, temp_)
        T12 = mc.moist_lapse(p12, lcl_[1])
        T1 = concatenate((T11[:-1], T12))
        T2 = mc.dry_lapse(p2, T1[-1])
        T = concatenate((T1, T2[1:]))
        wvmrtop = mc.saturation_mixing_ratio(pressures[mini], T[mini])
        RH=[]
        for i in range(len(pressures)):
            if pressures[i] > lcl_[0] and i <= mini:
                v=mc.relative_humidity_from_mixing_ratio(pressures[i], T[i], wvmr0)
            else:
                if i < mini:
                    v=1
                else:
                    v=mc.relative_humidity_from_mixing_ratio(pressures[i], T[i], wvmrtop)
            RH.append(v)
        
        #RH = [mc.relative_humidity_from_mixing_ratio(*tp, wvmr0) if tp[1] > lcl_[
            #0] and i <= mini else 1.0 if i < mini else
            #mc.relative_humidity_from_mixing_ratio(*tp, wvmrtop)
            #for i, tp in enumerate(zip(pressures, T))]

    RH = concatenate(RH)
    return windx, mtny, windy, lcl_, LCL, T.to("degC"), RH
Exemplo n.º 8
0
latitudes = my_state['latitude'].values

zenith_angle = np.radians(latitudes)

my_state['zenith_angle'].values[:] = zenith_angle[np.newaxis, :]

my_state['eastward_wind'].values[:] = np.random.randn(
    *my_state['eastward_wind'].shape)
my_state['ocean_mixed_layer_thickness'].values[:] = 50

surf_temp_profile = 290 - (40 * np.sin(zenith_angle)**2)
my_state['surface_temperature'].values[:] = surf_temp_profile[np.newaxis, :]

surf_temp = 280 * units.degK
pressure = my_state['air_pressure'][0, 0, :].values * units.pascal
temp_profile = np.array(calc.moist_lapse(pressure, surf_temp))
temp_profile[-5::] = temp_profile[-5]
my_state['air_temperature'].values[:] = temp_profile[np.newaxis, np.newaxis, :]

dycore.prognostics = [
    simple_physics, slab_surface, radiation_sw, radiation_lw, convection
]

for i in range(500000):
    output, diag = dycore(my_state)
    my_state.update(output)
    my_state.update(diag)
    my_state['time'] += model_time_step

    print('All q values are positive: ',
          np.all(my_state['specific_humidity'] >= 0))
Exemplo n.º 9
0
# setup sample Ts points
# N_sample_pts = 20    # test
N_sample_pts = 200  # full run
minT = 100
maxT = 400
T_surf_sample = np.linspace(minT, maxT, N_sample_pts)

T_data = np.zeros((N_sample_pts, N_levels))
T_data[:, 0] = T_surf_sample

print('Calculating moist adiabats...')
for i in range(N_sample_pts):
    if i % 10 == 0:
        print(i)
    T_data[i, :] = moist_lapse(temperature=T_data[i, 0] * units('K'),
                               pressure=pressures * units('Pa'))

# Keep T constant above 200 hPa for a Tropopause
for i in range(len(pressures)):
    if pressures[i] / 100 < 200:
        T_data[:, i] = T_data[:, i - 1]

# Debug plots:
f = plt.figure(figsize=(9, 9))
skew = SkewT(f, rotation=45)
for i in range(N_sample_pts):
    skew.plot(pressures / 100, T_data[i, :] - 273.15, 'r')
skew.ax.set_ylim(1000, 100)
skew.ax.set_xlim(minT - 273.15 - 5, maxT - 273.15 + 5)
skew.plot_moist_adiabats()
plt.show()
Exemplo n.º 10
0
    print 'LCL Temperature: {}'.format(lcltemp)

    # parcel profile
    # determine if there are points sampled above lcl
    ilcl = np.squeeze(np.where((pres * units.mbar) <= lclpres))
    # if not, entire profile dry adiabatic
    if ilcl.size == 0:
        prof = mcalc.dry_lapse(pres * units.mbar,
                               Tmean[0] * units.degC).to('degC')
        isbelowlcl = 1
    # if there are, need to concat dry & moist profile ascents
    else:
        ilcl = ilcl[0]
        prof_dry = mcalc.dry_lapse(pres[:ilcl] * units.mbar,
                                   Tmean[0] * units.degC).to('degC')
        prof_moist = mcalc.moist_lapse(pres[ilcl:] * units.mbar,
                                       prof_dry[-1]).to('degC')
        prof = np.concatenate((prof_dry, prof_moist)) * units.degC
        isbelowlcl = 0

    # CAPE
    SBCAPE = wxtools.uavCAPE(Tmean * units.degC, prof, pres)
    print 'Parcel Buoyancy: {}'.format(SBCAPE)
else:
    isbelowlcl = 0

# Wind shear
bulkshear = wind_kts[-3] - wind_kts[0]
print '0-{0:.0f} m Bulk Shear: {1:.0f} kts'.format(sampleHeights_m[-3],
                                                   bulkshear)

######################
Exemplo n.º 11
0
def test_moist_lapse_degc():
    """Test moist_lapse with Celsius temperatures."""
    temp = moist_lapse(np.array([1000., 800., 600., 500., 400.]) * units.mbar,
                       19.85 * units.degC)
    true_temp = np.array([293, 284.64, 272.81, 264.42, 252.91]) * units.kelvin
    assert_array_almost_equal(temp, true_temp, 2)
Exemplo n.º 12
0
def test_moist_lapse():
    """Test moist_lapse calculation."""
    temp = moist_lapse(np.array([1000., 800., 600., 500., 400.]) * units.mbar,
                       293. * units.kelvin)
    true_temp = np.array([293, 284.64, 272.81, 264.42, 252.91]) * units.kelvin
    assert_array_almost_equal(temp, true_temp, 2)
Exemplo n.º 13
0
def lifted_index(tsfc, tdsfc, psfc, t500):
    plcl, tlcl = mpcalc.lcl(psfc, tsfc, tdsfc)
    p = np.array([plcl.magnitude, 500]) * units('hPa')
    out = mpcalc.moist_lapse(p, tlcl)
    return t500.magnitude - out[1].magnitude
Exemplo n.º 14
0
def showalter_index(t850, td850, t500):
    plcl, tlcl = mpcalc.lcl(850 * units('hPa'), t850, td850)
    p = np.array([plcl.magnitude, 500]) * units('hPa')
    out = mpcalc.moist_lapse(p, tlcl)
    return t500.magnitude - out[1].magnitude