def do_profile(cursor, fid, gdf): """Process this profile.""" profile = gdf[pd.notnull(gdf['tmpc']) & pd.notnull(gdf['dwpc'])] if profile.empty: LOG.info("profile %s is empty, skipping", fid) return if profile['pressure'].min() > 400: raise ValueError("Profile only up to %s mb" % (profile['pressure'].min(), )) pwater = precipitable_water(profile['dwpc'].values * units.degC, profile['pressure'].values * units.hPa) (sbcape, sbcin) = surface_based_cape_cin( profile['pressure'].values * units.hPa, profile['tmpc'].values * units.degC, profile['dwpc'].values * units.degC, ) (mucape, mucin) = most_unstable_cape_cin( profile['pressure'].values * units.hPa, profile['tmpc'].values * units.degC, profile['dwpc'].values * units.degC, ) cursor.execute( """ UPDATE raob_flights SET sbcape_jkg = %s, sbcin_jkg = %s, mucape_jkg = %s, mucin_jkg = %s, pwater_mm = %s, computed = 't' WHERE fid = %s """, (nonull(sbcape.to(units('joules / kilogram')).m), nonull(sbcin.to(units('joules / kilogram')).m), nonull(mucape.to(units('joules / kilogram')).m), nonull(mucin.to(units('joules / kilogram')).m), nonull(pwater.to(units('mm')).m), fid))
def test_most_unstable_cape_cin(): """Tests the most unstable CAPE/CIN calculation.""" pressure = np.array([1000., 959., 867.9, 850., 825., 800.]) * units.mbar temperature = np.array([18.2, 22.2, 17.4, 10., 0., 15]) * units.celsius dewpoint = np.array([19., 19., 14.3, 0., -10., 0.]) * units.celsius mucape, mucin = most_unstable_cape_cin(pressure, temperature, dewpoint) assert_almost_equal(mucape, 157.07111 * units('joule / kilogram'), 4) assert_almost_equal(mucin, -15.74772 * units('joule / kilogram'), 4)
def test_most_unstable_cape_cin_surface(): """Tests the most unstable CAPE/CIN calculation when surface is most unstable.""" pressure = np.array([959., 779.2, 751.3, 724.3, 700., 269.]) * units.mbar temperature = np.array([22.2, 14.6, 12., 9.4, 7., -38.]) * units.celsius dewpoint = np.array([19., -11.2, -10.8, -10.4, -10., -53.2]) * units.celsius mucape, mucin = most_unstable_cape_cin(pressure, temperature, dewpoint) assert_almost_equal(mucape, 58.0368212 * units('joule / kilogram'), 6) assert_almost_equal(mucin, -89.8073512 * units('joule / kilogram'), 6)
def test_most_unstable_cape_cin(): """Test the most unstable CAPE/CIN calculation.""" pressure = np.array([1000., 959., 867.9, 850., 825., 800.]) * units.mbar temperature = np.array([18.2, 22.2, 17.4, 10., 0., 15]) * units.celsius dewpoint = np.array([19., 19., 14.3, 0., -10., 0.]) * units.celsius mucape, mucin = most_unstable_cape_cin(pressure, temperature, dewpoint) assert_almost_equal(mucape, 157.07111 * units('joule / kilogram'), 4) assert_almost_equal(mucin, -15.74772 * units('joule / kilogram'), 4)
def test_most_unstable_cape_cin_surface(): """Test the most unstable CAPE/CIN calculation when surface is most unstable.""" pressure = np.array([959., 779.2, 751.3, 724.3, 700., 269.]) * units.mbar temperature = np.array([22.2, 14.6, 12., 9.4, 7., -38.]) * units.celsius dewpoint = np.array([19., -11.2, -10.8, -10.4, -10., -53.2]) * units.celsius mucape, mucin = most_unstable_cape_cin(pressure, temperature, dewpoint) assert_almost_equal(mucape, 58.0368212 * units('joule / kilogram'), 6) assert_almost_equal(mucin, -89.8073512 * units('joule / kilogram'), 6)
def calculate_stability_indicies(ds, temp_name="temperature", td_name="dewpoint_temperature", p_name="pressure", moving_ave_window=0): """ Function for calculating stability indices from sounding data. Parameters ---------- ds : ACT dataset The dataset to compute the stability indicies of. Must have temperature, dewpoint, and pressure in vertical coordinates. temp_name : str The name of the temperature field. td_name : str The name of the dewpoint field. p_name : str The name of the pressure field. moving_ave_window : int Number of points to do a moving average on sounding data to reduce noise. This is useful if noise in the sounding is preventing parcel ascent. Returns ------- ds : ACT dataset An ACT dataset with additional stability indicies added. """ if not METPY_AVAILABLE: raise ImportError("MetPy need to be installed on your system to " + "calculate stability indices") t = ds[temp_name] td = ds[td_name] p = ds[p_name] if not hasattr(t, "units"): raise AttributeError("Temperature field must have units" + " for ACT to discern!") if not hasattr(td, "units"): raise AttributeError("Dewpoint field must have units" + " for ACT to discern!") if not hasattr(p, "units"): raise AttributeError("Pressure field must have units" + " for ACT to discern!") if t.units == "C": t_units = units.degC else: t_units = getattr(units, t.units) if td.units == "C": td_units = units.degC else: td_units = getattr(units, td.units) p_units = getattr(units, p.units) # Sort all values by decreasing pressure t_sorted = np.array(t.values) td_sorted = np.array(td.values) p_sorted = np.array(p.values) ind_sort = np.argsort(p_sorted) t_sorted = t_sorted[ind_sort[-1:0:-1]] td_sorted = td_sorted[ind_sort[-1:0:-1]] p_sorted = p_sorted[ind_sort[-1:0:-1]] if moving_ave_window > 0: t_sorted = np.convolve( t_sorted, np.ones((moving_ave_window,)) / moving_ave_window) td_sorted = np.convolve( td_sorted, np.ones((moving_ave_window,)) / moving_ave_window) p_sorted = np.convolve( p_sorted, np.ones((moving_ave_window,)) / moving_ave_window) t_sorted = t_sorted * t_units td_sorted = td_sorted * td_units p_sorted = p_sorted * p_units t_profile = mpcalc.parcel_profile( p_sorted, t_sorted[0], td_sorted[0]) # Calculate parcel trajectory ds["parcel_temperature"] = t_profile.magnitude ds["parcel_temperature"].attrs['units'] = t_profile.units # Calculate CAPE, CIN, LCL sbcape, sbcin = mpcalc.surface_based_cape_cin( p_sorted, t_sorted, td_sorted) lcl = mpcalc.lcl( p_sorted[0], t_sorted[0], td_sorted[0]) try: lfc = mpcalc.lfc( p_sorted[0], t_sorted[0], td_sorted[0]) except IndexError: lfc = np.nan * p_sorted.units mucape, mucin = mpcalc.most_unstable_cape_cin( p_sorted, t_sorted, td_sorted) where_500 = np.argmin(np.abs(p_sorted - 500 * units.hPa)) li = t_sorted[where_500] - t_profile[where_500] ds["surface_based_cape"] = sbcape.magnitude ds["surface_based_cape"].attrs['units'] = "J/kg" ds["surface_based_cape"].attrs['long_name'] = "Surface-based CAPE" ds["surface_based_cin"] = sbcin.magnitude ds["surface_based_cin"].attrs['units'] = "J/kg" ds["surface_based_cin"].attrs['long_name'] = "Surface-based CIN" ds["most_unstable_cape"] = mucape.magnitude ds["most_unstable_cape"].attrs['units'] = "J/kg" ds["most_unstable_cape"].attrs['long_name'] = "Most unstable CAPE" ds["most_unstable_cin"] = mucin.magnitude ds["most_unstable_cin"].attrs['units'] = "J/kg" ds["most_unstable_cin"].attrs['long_name'] = "Most unstable CIN" ds["lifted_index"] = li.magnitude ds["lifted_index"].attrs['units'] = t_profile.units ds["lifted_index"].attrs['long_name'] = "Lifted index" ds["level_of_free_convection"] = lfc.magnitude ds["level_of_free_convection"].attrs['units'] = lfc.units ds["level_of_free_convection"].attrs['long_name'] = "Level of free convection" ds["lifted_condensation_level_temperature"] = lcl[1].magnitude ds["lifted_condensation_level_temperature"].attrs['units'] = lcl[1].units ds["lifted_condensation_level_temperature"].attrs['long_name'] = "Lifted condensation level temperature" ds["lifted_condensation_level_pressure"] = lcl[0].magnitude ds["lifted_condensation_level_pressure"].attrs['units'] = lcl[0].units ds["lifted_condensation_level_pressure"].attrs['long_name'] = "Lifted condensation level pressure" return ds
e = lev * q / (q + epsilon) #Td = (243.5 * np.log(e[:,2:]/6.112)) / (17.67 - np.log(e[:,2:]/6.112)) + 273.15 Td = (243.5 * np.log(e[:,5:]/6.112)) / (17.67 - np.log(e[:,5:]/6.112)) + 273.15 cape = np.zeros([t.shape[0]]) cin = np.zeros([t.shape[0]]) mx = np.zeros([t.shape[0]]) tmp = np.zeros([t.shape[0]]) print(cape.shape) print(cape[1]) for i in range(t.shape[0]): #lev1 = lev[5:].tolist() * units.hPa #t1 = t[i,5:].tolist() * units.kelvin #Td1 = Td[i,5:].tolist() * units.kelvin lev1 = lev[5:].tolist() * units.hPa t1 = t[i,5:].tolist() * units.kelvin Td1 = Td[i,:].tolist() * units.kelvin a,b = calc.most_unstable_cape_cin(lev1, t1, Td1) cape[i] = a.magnitude cin[i] = b.magnitude #np.savetxt("cape_metpy.txt", cape) np.savetxt("cin_mao.txt", cin)
def calculate_stability_indicies( ds, temp_name='temperature', td_name='dewpoint_temperature', p_name='pressure', rh_name='relative_humidity', moving_ave_window=0, ): """ Function for calculating stability indices from sounding data. Parameters ---------- ds : ACT dataset The dataset to compute the stability indicies of. Must have temperature, dewpoint, and pressure in vertical coordinates. temp_name : str The name of the temperature field. td_name : str The name of the dewpoint field. p_name : str The name of the pressure field. rh_name : str The name of the relative humidity field. moving_ave_window : int Number of points to do a moving average on sounding data to reduce noise. This is useful if noise in the sounding is preventing parcel ascent. Returns ------- ds : ACT dataset An ACT dataset with additional stability indicies added. """ if not METPY_AVAILABLE: raise ImportError( 'MetPy need to be installed on your system to ' + 'calculate stability indices' ) t = ds[temp_name] td = ds[td_name] p = ds[p_name] rh = ds[rh_name] if not hasattr(t, 'units'): raise AttributeError('Temperature field must have units' + ' for ACT to discern!') if not hasattr(td, 'units'): raise AttributeError('Dewpoint field must have units' + ' for ACT to discern!') if not hasattr(p, 'units'): raise AttributeError('Pressure field must have units' + ' for ACT to discern!') if t.units == 'C': t_units = units.degC else: t_units = getattr(units, t.units) if td.units == 'C': td_units = units.degC else: td_units = getattr(units, td.units) p_units = getattr(units, p.units) rh_units = getattr(units, rh.units) # Sort all values by decreasing pressure t_sorted = np.array(t.values) td_sorted = np.array(td.values) p_sorted = np.array(p.values) rh_sorted = np.array(rh.values) ind_sort = np.argsort(p_sorted) t_sorted = t_sorted[ind_sort[-1:0:-1]] td_sorted = td_sorted[ind_sort[-1:0:-1]] p_sorted = p_sorted[ind_sort[-1:0:-1]] rh_sorted = rh_sorted[ind_sort[-1:0:-1]] if moving_ave_window > 0: t_sorted = np.convolve(t_sorted, np.ones((moving_ave_window,)) / moving_ave_window) td_sorted = np.convolve(td_sorted, np.ones((moving_ave_window,)) / moving_ave_window) p_sorted = np.convolve(p_sorted, np.ones((moving_ave_window,)) / moving_ave_window) rh_sorted = np.convolve(rh_sorted, np.ones((moving_ave_window,)) / moving_ave_window) t_sorted = t_sorted * t_units td_sorted = td_sorted * td_units p_sorted = p_sorted * p_units rh_sorted = rh_sorted * rh_units # Calculate mixing ratio mr = mpcalc.mixing_ratio_from_relative_humidity(p_sorted, t_sorted, rh_sorted) # Discussion of issue #361 use virtual temperature. vt = mpcalc.virtual_temperature(t_sorted, mr) t_profile = mpcalc.parcel_profile(p_sorted, t_sorted[0], td_sorted[0]) # Calculate parcel trajectory ds['parcel_temperature'] = t_profile.magnitude ds['parcel_temperature'].attrs['units'] = t_profile.units # Calculate CAPE, CIN, LCL sbcape, sbcin = mpcalc.surface_based_cape_cin(p_sorted, vt, td_sorted) lcl = mpcalc.lcl(p_sorted[0], t_sorted[0], td_sorted[0]) try: lfc = mpcalc.lfc(p_sorted[0], t_sorted[0], td_sorted[0]) except IndexError: lfc = np.nan * p_sorted.units mucape, mucin = mpcalc.most_unstable_cape_cin(p_sorted, vt, td_sorted) where_500 = np.argmin(np.abs(p_sorted - 500 * units.hPa)) li = t_sorted[where_500] - t_profile[where_500] ds['surface_based_cape'] = sbcape.magnitude ds['surface_based_cape'].attrs['units'] = 'J/kg' ds['surface_based_cape'].attrs['long_name'] = 'Surface-based CAPE' ds['surface_based_cin'] = sbcin.magnitude ds['surface_based_cin'].attrs['units'] = 'J/kg' ds['surface_based_cin'].attrs['long_name'] = 'Surface-based CIN' ds['most_unstable_cape'] = mucape.magnitude ds['most_unstable_cape'].attrs['units'] = 'J/kg' ds['most_unstable_cape'].attrs['long_name'] = 'Most unstable CAPE' ds['most_unstable_cin'] = mucin.magnitude ds['most_unstable_cin'].attrs['units'] = 'J/kg' ds['most_unstable_cin'].attrs['long_name'] = 'Most unstable CIN' ds['lifted_index'] = li.magnitude ds['lifted_index'].attrs['units'] = t_profile.units ds['lifted_index'].attrs['long_name'] = 'Lifted index' ds['level_of_free_convection'] = lfc.magnitude ds['level_of_free_convection'].attrs['units'] = lfc.units ds['level_of_free_convection'].attrs['long_name'] = 'Level of free convection' ds['lifted_condensation_level_temperature'] = lcl[1].magnitude ds['lifted_condensation_level_temperature'].attrs['units'] = lcl[1].units ds['lifted_condensation_level_temperature'].attrs[ 'long_name' ] = 'Lifted condensation level temperature' ds['lifted_condensation_level_pressure'] = lcl[0].magnitude ds['lifted_condensation_level_pressure'].attrs['units'] = lcl[0].units ds['lifted_condensation_level_pressure'].attrs[ 'long_name' ] = 'Lifted condensation level pressure' return ds
def do_profile(cursor, fid, gdf, nt): """Process this profile.""" # The inbound profile may contain mandatory level data that is below # the surface. It seems the best we can do here is to ensure both # temperature and dewpoint are valid and call that the bottom. td_profile = gdf[pd.notnull(gdf["tmpc"]) & pd.notnull(gdf["dwpc"])] wind_profile = gdf[pd.notnull(gdf["u"])] # Presently we are all or nothing here. The length is arb if len(td_profile.index) < 5 or len(wind_profile.index) < 5: msg = ("quorum fail td: %s wind: %s, skipping") % ( len(td_profile.index), len(wind_profile.index), ) raise ValueError(msg) if gdf["pressure"].min() > 500: raise ValueError("Profile only up to %s mb" % (gdf["pressure"].min(), )) # Does a crude check that our metadata station elevation is within 50m # of the profile bottom, otherwise we ABORT station_elevation_m = get_station_elevation(td_profile, nt) # get surface wind u_sfc, v_sfc = get_surface_winds(wind_profile) u_1km, v_1km = get_aloft_winds(wind_profile, station_elevation_m + 1000.0) u_3km, v_3km = get_aloft_winds(wind_profile, station_elevation_m + 3000.0) u_6km, v_6km = get_aloft_winds(wind_profile, station_elevation_m + 6000.0) shear_sfc_1km_smps = np.sqrt((u_1km - u_sfc)**2 + (v_1km - v_sfc)**2) shear_sfc_3km_smps = np.sqrt((u_3km - u_sfc)**2 + (v_3km - v_sfc)**2) shear_sfc_6km_smps = np.sqrt((u_6km - u_sfc)**2 + (v_6km - v_sfc)**2) total_totals = compute_total_totals(td_profile) sweat_index = compute_sweat_index(td_profile, total_totals) try: bunkers_rm, bunkers_lm, mean0_6_wind = bunkers_storm_motion( wind_profile["pressure"].values * units.hPa, wind_profile["u"].values * units("m/s"), wind_profile["v"].values * units("m/s"), wind_profile["height"].values * units("m"), ) except ValueError: # Profile may not go up high enough bunkers_rm = [np.nan * units("m/s"), np.nan * units("m/s")] bunkers_lm = [np.nan * units("m/s"), np.nan * units("m/s")] mean0_6_wind = [np.nan * units("m/s"), np.nan * units("m/s")] bunkers_rm_smps = wind_speed(bunkers_rm[0], bunkers_rm[1]) bunkers_rm_drct = wind_direction(bunkers_rm[0], bunkers_rm[1]) bunkers_lm_smps = wind_speed(bunkers_lm[0], bunkers_lm[1]) bunkers_lm_drct = wind_direction(bunkers_lm[0], bunkers_lm[1]) mean0_6_wind_smps = wind_speed(mean0_6_wind[0], mean0_6_wind[1]) mean0_6_wind_drct = wind_direction(mean0_6_wind[0], mean0_6_wind[1]) try: ( srh_sfc_1km_pos, srh_sfc_1km_neg, srh_sfc_1km_total, ) = storm_relative_helicity( wind_profile["height"].values * units("m"), wind_profile["u"].values * units("m/s"), wind_profile["v"].values * units("m/s"), 1000.0 * units("m"), ) except ValueError: srh_sfc_1km_pos = np.nan * units("m") # blah srh_sfc_1km_neg = np.nan * units("m") # blah srh_sfc_1km_total = np.nan * units("m") # blah try: ( srh_sfc_3km_pos, srh_sfc_3km_neg, srh_sfc_3km_total, ) = storm_relative_helicity( wind_profile["height"].values * units("m"), wind_profile["u"].values * units("m/s"), wind_profile["v"].values * units("m/s"), 3000.0 * units("m"), ) except ValueError: srh_sfc_3km_pos = np.nan * units("m") # blah srh_sfc_3km_neg = np.nan * units("m") # blah srh_sfc_3km_total = np.nan * units("m") # blah pwater = precipitable_water( td_profile["pressure"].values * units.hPa, td_profile["dwpc"].values * units.degC, ) (sbcape, sbcin) = surface_based_cape_cin( td_profile["pressure"].values * units.hPa, td_profile["tmpc"].values * units.degC, td_profile["dwpc"].values * units.degC, ) (mucape, mucin) = most_unstable_cape_cin( td_profile["pressure"].values * units.hPa, td_profile["tmpc"].values * units.degC, td_profile["dwpc"].values * units.degC, ) (mlcape, mlcin) = mixed_layer_cape_cin( td_profile["pressure"].values * units.hPa, td_profile["tmpc"].values * units.degC, td_profile["dwpc"].values * units.degC, ) el_p, el_t = el( td_profile["pressure"].values * units.hPa, td_profile["tmpc"].values * units.degC, td_profile["dwpc"].values * units.degC, ) lfc_p, lfc_t = lfc( td_profile["pressure"].values * units.hPa, td_profile["tmpc"].values * units.degC, td_profile["dwpc"].values * units.degC, ) (lcl_p, lcl_t) = lcl( td_profile["pressure"].values[0] * units.hPa, td_profile["tmpc"].values[0] * units.degC, td_profile["dwpc"].values[0] * units.degC, ) vals = [ el_p.to(units("hPa")).m, lfc_p.to(units("hPa")).m, lcl_p.to(units("hPa")).m, ] [el_hght, lfc_hght, lcl_hght] = log_interp( np.array(vals, dtype="f"), td_profile["pressure"].values[::-1], td_profile["height"].values[::-1], ) el_agl = gt1(el_hght - station_elevation_m) lcl_agl = gt1(lcl_hght - station_elevation_m) lfc_agl = gt1(lfc_hght - station_elevation_m) args = ( nonull(sbcape.to(units("joules / kilogram")).m), nonull(sbcin.to(units("joules / kilogram")).m), nonull(mucape.to(units("joules / kilogram")).m), nonull(mucin.to(units("joules / kilogram")).m), nonull(mlcape.to(units("joules / kilogram")).m), nonull(mlcin.to(units("joules / kilogram")).m), nonull(pwater.to(units("mm")).m), nonull(el_agl), nonull(el_p.to(units("hPa")).m), nonull(el_t.to(units.degC).m), nonull(lfc_agl), nonull(lfc_p.to(units("hPa")).m), nonull(lfc_t.to(units.degC).m), nonull(lcl_agl), nonull(lcl_p.to(units("hPa")).m), nonull(lcl_t.to(units.degC).m), nonull(total_totals), nonull(sweat_index), nonull(bunkers_rm_smps.m), nonull(bunkers_rm_drct.m), nonull(bunkers_lm_smps.m), nonull(bunkers_lm_drct.m), nonull(mean0_6_wind_smps.m), nonull(mean0_6_wind_drct.m), nonull(srh_sfc_1km_pos.m), nonull(srh_sfc_1km_neg.m), nonull(srh_sfc_1km_total.m), nonull(srh_sfc_3km_pos.m), nonull(srh_sfc_3km_neg.m), nonull(srh_sfc_3km_total.m), nonull(shear_sfc_1km_smps), nonull(shear_sfc_3km_smps), nonull(shear_sfc_6km_smps), fid, ) cursor.execute( """ UPDATE raob_flights SET sbcape_jkg = %s, sbcin_jkg = %s, mucape_jkg = %s, mucin_jkg = %s, mlcape_jkg = %s, mlcin_jkg = %s, pwater_mm = %s, el_agl_m = %s, el_pressure_hpa = %s, el_tmpc = %s, lfc_agl_m = %s, lfc_pressure_hpa = %s, lfc_tmpc = %s, lcl_agl_m = %s, lcl_pressure_hpa = %s, lcl_tmpc = %s, total_totals = %s, sweat_index = %s, bunkers_rm_smps = %s, bunkers_rm_drct = %s, bunkers_lm_smps = %s, bunkers_lm_drct = %s, mean_sfc_6km_smps = %s, mean_sfc_6km_drct = %s, srh_sfc_1km_pos = %s, srh_sfc_1km_neg = %s, srh_sfc_1km_total = %s, srh_sfc_3km_pos = %s, srh_sfc_3km_neg = %s, srh_sfc_3km_total = %s, shear_sfc_1km_smps = %s, shear_sfc_3km_smps = %s, shear_sfc_6km_smps = %s, computed = 't' WHERE fid = %s """, args, )
#Pegando os dados do Wyoming com o Siphon: date = datetime.datetime(2017, 1, 31, 12) station = 'SBMT' #código do Campo de Marte sounding = WyomingUpperAir.request_data(date, station) #Aumentando a qualidade da iamgem plt.rcParams['savefig.dpi'] = 255 p = sounding['pressure'].values * units.hPa T = sounding['temperature'].values * units.degC Td = sounding['dewpoint'].values * units.degC u = sounding['u_wind'].values * units.knot v = sounding['v_wind'].values * units.knot #print(mpcalc.cape_cin(p, T, Td, prof)) print(mpcalc.most_unstable_cape_cin(p, T, Td)) print(mpcalc.surface_based_cape_cin(p, T, Td)) mask_100 = p >= 100 * units.hPa #máscara para plotar o vento até 100hPa fig = plt.figure(figsize=(7, 9)) gs = gridspec.GridSpec(3, 3) skew = SkewT(fig, rotation=45) skew = SkewT(fig, rotation=45) #SkewT Básico: skew.plot(p, T, 'r') skew.plot(p, Td, 'g') plt.xlabel('Temperatura (°C)', fontsize=12) plt.ylabel('Pressão (hPa)', fontsize=12)
def process_skewt(self): # Calculation index_p100 = get_pressure_level_index(self.p_i, 100) lcl_p, lcl_t = mpcalc.lcl(self.p_i[0], self.t_i[0], self.td_i[0]) lfc_p, lfc_t = mpcalc.lfc(self.p_i, self.t_i, self.td_i) el_p, el_t = mpcalc.el(self.p_i, self.t_i, self.td_i) prof = mpcalc.parcel_profile(self.p_i, self.t_i[0], self.td_i[0]).to('degC') cape, cin = mpcalc.cape_cin(self.p_i, self.t_i, self.td_i, prof) mucape, mucin = mpcalc.most_unstable_cape_cin(self.p_i, self.t_i, self.td_i) pwat = mpcalc.precipitable_water(self.td_i, self.p_i) i8 = get_pressure_level_index(self.p_i, 850) i7 = get_pressure_level_index(self.p_i, 700) i5 = get_pressure_level_index(self.p_i, 500) theta850 = mpcalc.equivalent_potential_temperature(850 * units('hPa'), self.t_i[i8], self.td_i[i5]) theta500 = mpcalc.equivalent_potential_temperature(500 * units('hPa'), self.t_i[i5], self.td_i[i5]) thetadiff = theta850 - theta500 k = self.t_i[i8] - self.t_i[i5] + self.td_i[i8] - (self.t_i[i7] - self.td_i[i7]) a = ((self.t_i[i8] - self.t_i[i5]) - (self.t_i[i8] - self.td_i[i5]) - (self.t_i[i7] - self.td_i[i7]) - (self.t_i[i5] - self.td_i[i5])) sw = c_sweat(np.array(self.t_i[i8].magnitude), np.array(self.td_i[i8].magnitude), np.array(self.t_i[i5].magnitude), np.array(self.u_i[i8].magnitude), np.array(self.v_i[i8].magnitude), np.array(self.u_i[i5].magnitude), np.array(self.v_i[i5].magnitude)) si = showalter_index(self.t_i[i8], self.td_i[i8], self.t_i[i5]) li = lifted_index(self.t_i[0], self.td_i[0], self.p_i[0], self.t_i[i5]) srh_pos, srh_neg, srh_tot = mpcalc.storm_relative_helicity(self.u_i, self.v_i, self.alt, 1000 * units('m')) sbcape, sbcin = mpcalc.surface_based_cape_cin(self.p_i, self.t_i, self.td_i) shr6km = mpcalc.bulk_shear(self.p_i, self.u_i, self.v_i, heights=self.alt, depth=6000 * units('m')) wshr6km = mpcalc.wind_speed(*shr6km) sigtor = mpcalc.significant_tornado(sbcape, delta_height(self.p_i[0], lcl_p), srh_tot, wshr6km)[0] # Plotting self.ax.set_ylim(1050, 100) self.ax.set_xlim(-40, 50) self.plot(self.p_i, self.t_i, 'r', linewidth=1) self.plot(self.p_i[:self.dp_idx], self.td_i[:self.dp_idx], 'g', linewidth=1) self.plot_barbs(self.p_i[:index_p100], self.u_i[:index_p100] * 1.94, self.v_i[:index_p100] * 1.94) self.plot(lcl_p, lcl_t, 'ko', markerfacecolor='black') self.plot(self.p_i, prof, 'k', linewidth=2) if cin.magnitude < 0: chi = -1 * cin.magnitude self.shade_cin(self.p_i, self.t_i, prof) elif cin.magnitude > 0: chi = cin.magnitude self.shade_cin(self.p_i, self.t_i, prof) else: chi = 0. self.shade_cape(self.p_i, self.t_i, prof) self.plot_dry_adiabats(linewidth=0.5) self.plot_moist_adiabats(linewidth=0.5) self.plot_mixing_lines(linewidth=0.5) plt.title('Skew-T Plot \nStation: {} Time: {}'.format(self.st, self.time.strftime('%Y.%m.%d %H:%M')), fontsize=14, loc='left') # Add hodograph ax = self._fig.add_axes([0.95, 0.71, 0.17, 0.17]) h = Hodograph(ax, component_range=50) h.add_grid(increment=20) h.plot_colormapped(self.u_i[:index_p100], self.v_i[:index_p100], self.alt[:index_p100], linewidth=1.2) # Annotate parameters # Annotate names namelist = ['CAPE', 'CIN', 'MUCAPE', 'PWAT', 'K', 'A', 'SWEAT', 'LCL', 'LFC', 'EL', 'SI', 'LI', 'T850-500', 'θse850-500', 'SRH', 'STP'] xcor = -50 ycor = -90 spacing = -9 for nm in namelist: ax.text(xcor, ycor, '{}: '.format(nm), fontsize=10) ycor += spacing # Annotate values varlist = [cape, chi, mucape, pwat, k, a, sw, lcl_p, lfc_p, el_p, si, li, self.t_i[i8] - self.t_i[i5], thetadiff, srh_tot, sigtor] xcor = 10 ycor = -90 for v in varlist: if hasattr(v, 'magnitude'): v = v.magnitude ax.text(xcor, ycor, str(np.round_(v, 2)), fontsize=10) ycor += spacing # Annotate units unitlist = ['J/kg', 'J/kg', 'J/kg', 'mm', '°C', '°C', '', 'hPa', 'hPa', 'hPa', '°C', '°C', '°C', '°C'] xcor = 45 ycor = -90 for u in unitlist: ax.text(xcor, ycor, ' {}'.format(u), fontsize=10) ycor += spacing
# log scaling in Y, as dictated by the typical meteorological plot skew.plot(p, T, 'r') skew.ax.set_xlabel('Temperature (Celsius)') skew.plot(p, Td, 'g') #plots the barbs my_interval = np.arange(100, 1000, 20) * units('mbar') ix = resample_nn_1d(p, my_interval) skew.plot_barbs(p[ix], u[ix], v[ix]) skew.ax.set_ylim(1075, 100) skew.ax.set_ylabel('Pressure (hPa)') lcl_pressure, lcl_temperature = mpcalc.lcl(p[0], T[0], Td[0]) #LCL pwat = mpcalc.precipitable_water(Td, p, 500 * units.hectopascal).to('in') #PWAT cape, cin = mpcalc.most_unstable_cape_cin(p[:], T[:], Td[:]) #MUCAPE cape_sfc, cin_sfc = mpcalc.surface_based_cape_cin(p, T, Td) #SBCAPE prof = mpcalc.parcel_profile(p, T[0], Td[0]).to('degC') #parcel profile equiv_pot_temp = mpcalc.equivalent_potential_temperature(p, T, Td) #equivalent potential temperature el_pressure, el_temperature = mpcalc.el(p, T, Td) #elevated level lfc_pressure, lfc_temperature = mpcalc.lfc(p, T, Td) #LFC #calculates shear u_threekm_bulk_shear, v_threekm_bulk_shear = mpcalc.bulk_shear(p, u, v, hgt, bottom = min(hgt), depth = 3000 * units.meter) threekm_bulk_shear = mpcalc.get_wind_speed(u_threekm_bulk_shear, v_threekm_bulk_shear) u_onekm_bulk_shear, v_onekm_bulk_shear = mpcalc.bulk_shear(p, u, v, hgt, bottom = min(hgt), depth = 1000 * units.meter) onekm_bulk_shear = mpcalc.get_wind_speed(u_onekm_bulk_shear, v_onekm_bulk_shear) #shows the level of the LCL, LFC, and EL. skew.ax.text(T[0].magnitude, p[0].magnitude + 5, str(int(np.round(T[0].to('degF').magnitude))), fontsize = 'medium', horizontalalignment = 'left', verticalalignment = 'top', color = 'red') skew.ax.text(Td[0].magnitude, p[0].magnitude + 5, str(int(np.round(Td[0].to('degF').magnitude))), fontsize = 'medium', horizontalalignment = 'right', verticalalignment = 'top', color = 'green')