Exemple #1
0
def test_wet_bulb_temperature_1d():
    """Test wet bulb calculation with 1d list."""
    pressures = [1013, 1000, 990] * units.hPa
    temperatures = [25, 20, 15] * units.degC
    dewpoints = [20, 15, 10] * units.degC
    val = wet_bulb_temperature(pressures, temperatures, dewpoints)
    truth = [21.4449794, 16.7368576, 12.0656909] * units.degC
    # 21.58, 16.86, 12.18 from NWS Calculator
    assert_array_almost_equal(val, truth)
Exemple #2
0
def test_wet_bulb_temperature_1d():
    """Test wet bulb calculation with 1d list."""
    pressures = [1013, 1000, 990] * units.hPa
    temperatures = [25, 20, 15] * units.degC
    dewpoints = [20, 15, 10] * units.degC
    val = wet_bulb_temperature(pressures, temperatures, dewpoints)
    truth = [21.4449794, 16.7368576, 12.0656909] * units.degC
    # 21.58, 16.86, 12.18 from NWS Calculator
    assert_array_almost_equal(val, truth)
Exemple #3
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})])
def _try_normand_wtb(s, t, d):
    # wrapper for metpy's implementation for cases where it doesn't converge
    # onto a solution (exceeds max iteration) so just return NaN
    try:
        return wet_bulb_temperature(
            np.array([s]) * units('hPa'),
            np.array([t]) * units('degC'),
            np.array([d]) * units('degC')).m
    except:
        return np.nan
Exemple #5
0
def test_wet_bulb_temperature_2d():
    """Test wet bulb calculation with 2d list."""
    pressures = [[1013, 1000, 990], [1012, 999, 989]] * units.hPa
    temperatures = [[25, 20, 15], [24, 19, 14]] * units.degC
    dewpoints = [[20, 15, 10], [19, 14, 9]] * units.degC
    val = wet_bulb_temperature(pressures, temperatures, dewpoints)
    truth = [[21.4449794, 16.7368576, 12.0656909],
             [20.5021631, 15.801218, 11.1361878]] * units.degC
    # 21.58, 16.86, 12.18
    # 20.6, 15.9, 11.2 from NWS Calculator
    assert_array_almost_equal(val, truth)
Exemple #6
0
def test_wet_bulb_temperature_2d():
    """Test wet bulb calculation with 2d list."""
    pressures = [[1013, 1000, 990],
                 [1012, 999, 989]] * units.hPa
    temperatures = [[25, 20, 15],
                    [24, 19, 14]] * units.degC
    dewpoints = [[20, 15, 10],
                 [19, 14, 9]] * units.degC
    val = wet_bulb_temperature(pressures, temperatures, dewpoints)
    truth = [[21.4449794, 16.7368576, 12.0656909],
             [20.5021631, 15.801218, 11.1361878]] * units.degC
    # 21.58, 16.86, 12.18
    # 20.6, 15.9, 11.2 from NWS Calculator
    assert_array_almost_equal(val, truth)
def wetbulb_with_nan(pressure,temperature,dewpoint):
    '''
    This function uses the MetPy wet_bulb_temperature method to calculate the
    actual wet bulb temperature using pressure, temperature, and dew point info.

    Inputs: pressure, temperature, dewpoint pint arrays

    Output: wetbulb_full pint array

    This function was constructed using code graciously suggested by Jon Thielen
    '''
    nan_mask = np.isnan(pressure) | np.isnan(temperature) | np.isnan(dewpoint)
    idx = np.arange(pressure.size)[~nan_mask]
    wetbulb_valid_only = mpcalc.wet_bulb_temperature(pressure[idx], temperature[idx], dewpoint[idx])
    wetbulb_full = np.full(pressure.size, np.nan) * wetbulb_valid_only.units
    wetbulb_full[idx] = wetbulb_valid_only

    return wetbulb_full
Exemple #8
0
def calculate_sounding_data(df,field_height,field_temp):
    ###################################### CALCULATION MAGIC #################################################
    # We will pull the data out of the latest soudning into individual variables and assign units.           #
    # This will Return a dictionary with all the vallculate values. Keys are:                                #
    # "pressure", "temperature", "dewpoint", "height", "windspeed","wind_dir"                               
    ###################################### CALCULATION MAGIC #################################################
    cache = settings.AppCache
    #Retrieves Sounding Details and returns them
    key='calculation'+str(field_height)+'_'+str(field_temp)
    #If soundings are cached and valid, returns the cache, otherwise retreive new sounding
    calc = cache.get(key)

    if calc is not None:
        logging.info("Calculation Cache Hit")
        print("Calculation Cahce Hit")
        return calc
    
    logging.info("Calculation Cache Miss")
    print("Calculation Cahce Miss")
    p = df['pressure'].values * units.hPa
    T = df['temperature'].values * units.degC
    Td = df['dewpoint'].values * units.degC
    alt = df['height'].values * units.ft
    wind_speed = df['speed'].values * units.knots
    wind_dir = df['direction'].values * units.degrees
    wet_bulb = mpcalc.wet_bulb_temperature(p,T,Td)
    field_pressure = mpcalc.height_to_pressure_std(field_height*units.ft)
    adiabat_line = mpcalc.dry_lapse(p,field_temp*units.degC,ref_pressure=mpcalc.height_to_pressure_std(field_height*units.ft))
    
    #Interpolate Missing Values using linear interpolation
    Td_linear = interp1d(alt.magnitude,Td.magnitude)
    T_linear = interp1d(alt.magnitude,T.magnitude)
    
    #Calculate the LCL Based on Max Temperature
    lcl_pressure, lcl_temperature = mpcalc.lcl(field_pressure,field_temp*units.degC ,Td_linear(field_height)*units.degC)
    #parcel_prof = mpcalc.parcel_profile(p, T[0], Td[0]).to('degC')
    calc = MeteoCast.UpperAtmData(df, p, T, Td,alt,wind_speed,wind_dir,wet_bulb,field_pressure,lcl_pressure,lcl_temperature,adiabat_line)
    cache.set(key, calc, expire=600,tag='Calculation Data ')
    return calc
                    #%%
                    ###########################################
                    # We will pull the data out of the example dataset into individual variables and
                    # assign units.

                    p = df_selected_time['pressure'].values * units.hPa
                    T = df_selected_time['temperature'].values * units.degC
                    Td = df_selected_time['dewpoint'].values * units.degC
                    wind_speed = df_selected_time['speed'].values * units.knots
                    wind_dir = df_selected_time[
                        'direction'].values * units.degrees
                    u, v = mpcalc.wind_components(wind_speed, wind_dir)

                    # Calculate web bulb temperature
                    df_selected_time[
                        'wet_bulb_T'] = mpcalc.wet_bulb_temperature(p, T, Td)

                    # Calculate potential temperature
                    df_selected_time[
                        'potential_T'] = mpcalc.potential_temperature(p, T)
                    df_selected_time['potential_T_C'] = df_selected_time[
                        'potential_T'].values - 273.15

                    # Calculate saturation vaper pressure
                    df_selected_time[
                        'saturation_vaper_pressure'] = mpcalc.saturation_vapor_pressure(
                            T)
                    df_selected_time[
                        'vaper_pressure'] = mpcalc.saturation_vapor_pressure(
                            Td)
                    SVP = df_selected_time[
Exemple #10
0
def test_wet_bulb_temperature():
    """Test wet bulb calculation with scalars."""
    val = wet_bulb_temperature(1000 * units.hPa, 25 * units.degC,
                               15 * units.degC)
    truth = 18.34345936 * units.degC  # 18.59 from NWS calculator
    assert_almost_equal(val, truth)
def f(fullname, selected_time):
    fullname_el = fullname.split('/')
    #fullname_el = fullname.split('\\')
    filename = fullname_el[-1]
    filename_el = filename.split('_')
    save_base_dir_name = '../1data/'
    save_dir_name = '{0}{1}/'.format(save_base_dir_name + dir_name, obs_year)
    print('site : {0}'.format(dir_name))

    if os.path.isfile('{0}{1}_{2}_student.csv'\
                      .format(save_dir_name, filename_el[-5], selected_time[:13]))\
        and os.path.isfile('{0}{1}_{2}_solution.csv'\
                      .format(save_dir_name, filename_el[-5], selected_time[:13])):
        write_log(log_file, '{3} ::: {0}{1}_{2} files are already exist'\
                  .format(save_dir_name, filename_el[-5], selected_time[:13], datetime.now()))
    else:
        try:
            f = lambda s: selected_time in s
            ids = df['time'].apply(f)
            df_selected_time = df[ids]
            df_selected_time = df_selected_time.sort_values('pressure',
                                                            ascending=False)

            print('filename : {0}'.format(fullname))
            print('df_selected_time.\n{0}'.format(df_selected_time))

            df_selected_time.to_csv(r'{0}{1}_{2}_student.csv'\
                      .format(save_dir_name, filename_el[-5], selected_time[:13]))

            #################################################################################
            ### We will pull the data out of the example dataset into individual variables and
            ### assign units.
            #################################################################################

            p = df_selected_time['pressure'].values * units.hPa
            T = df_selected_time['temperature'].values * units.degC
            Td = df_selected_time['dewpoint'].values * units.degC
            wind_speed = df_selected_time['speed'].values * units.knots
            wind_dir = df_selected_time['direction'].values * units.degrees
            u, v = mpcalc.wind_components(wind_speed, wind_dir)

            # Calculate web bulb temperature
            df_selected_time['wet_bulb_T'] = mpcalc.wet_bulb_temperature(
                p, T, Td)

            # Calculate potential temperature
            df_selected_time['potential_T'] = mpcalc.potential_temperature(
                p, T)
            df_selected_time['potential_T_C'] = df_selected_time[
                'potential_T'].values - 273.15

            # Calculate saturation vaper pressure
            df_selected_time[
                'saturation_vaper_pressure'] = mpcalc.saturation_vapor_pressure(
                    T)
            df_selected_time[
                'vaper_pressure'] = mpcalc.saturation_vapor_pressure(Td)
            SVP = df_selected_time[
                'saturation_vaper_pressure'].values * units.hPa
            VP = df_selected_time['vaper_pressure'].values * units.hPa

            # Calculate mixing ratio
            df_selected_time['saturation_mixing_ratio'] = mpcalc.mixing_ratio(
                SVP, p)
            df_selected_time['mixing_ratio'] = mpcalc.mixing_ratio(VP, p)
            SMR = df_selected_time['saturation_mixing_ratio'].values * units(
                'g/kg')
            MR = df_selected_time['mixing_ratio'].values * units('g/kg')

            # Calculate relative humidity
            df_selected_time['relative_humidity_from_dewpoint'] \
                = mpcalc.relative_humidity_from_dewpoint(T, Td)
            df_selected_time['relative_humidity_from_mixing_ratio'] \
                = mpcalc.relative_humidity_from_mixing_ratio(MR, T, p)

            # Calculate virtual temperature
            df_selected_time['virtual_temperature'] \
                = mpcalc.virtual_temperature(T, MR)

            # Calculate virtual potential temperature
            df_selected_time['virtual_potential_temperature'] \
                = mpcalc.virtual_potential_temperature(p, T, MR)

            print('df_selected_time after drop nan.\n{0}'.format(
                df_selected_time))

            df_selected_time.to_csv(r'{0}{1}_{2}_solution.csv'\
                      .format(save_dir_name, filename_el[-5], selected_time[:13]))

        except Exception as err:
            write_log(err_log_file, '{4} ::: {0} with {1}{2} on {3}'\
                      .format(err, dir_name, filename, selected_time[:13], datetime.now()))
    print('Thread {0} is finished'.format(selected_time))
    return 0  # Return a dummy value
Exemple #12
0
def plot_soundings(fig,
                   ax,
                   temp,
                   rh,
                   sfc_pressure,
                   centerlat,
                   centerlon,
                   domainsize,
                   model,
                   cape=False,
                   wetbulb=False):
    """
    This function will plot a bunch of little soundings onto a matplotlib fig,ax.

    temp is an xarray dataarray with temperature data on pressure levels at least
    between 1000 and 300mb (you can change the ylimits for other datasets)

    rh is an xarray dataarray with temperature data on pressure levels at least
    between 1000 and 300mb (you can change )

    sfc_pressure is an xarray dataarray with surface pressure data (NOT MSLP!)

    centerlat and centerlon are the coordinates around which you want your map
    to be centered. both are floats or integers and are in degrees of latitude
    and degrees of longitude west (i.e. 70W would be input as positive 70 here)

    domainsize is a string either 'local' for ~WFO-size domains or 'regional' for
    NE/SE/Mid-Atlantic-size domains (12 deg lat by 15 deg lon). More will be added soon.

    model is a string that specifies which model is providing data for the plots.
    This determines a few things, most importantly longitude selections. Models
    currently supported are 'GFS','NAM',and 'RAP'

    cape is a boolean to indicate whether you want to overlay parcel paths and
    shade CAPE/CIN on soundings with >100 J/kg of CAPE (this value can be changed)

    wetbulb is a boolean to indicate whether you want to draw wet bulb profiles

    note that this function doesn't "return" anything but if you just call it and
    provide the right arguments, it works.

    for example:
        import soundingmaps as smap
        ...
        smap.plot_soundings(fig,ax1,data['temperature'],data['rh'],30.5,87.5,'local',cape=True)

    """
    r = 5
    if domainsize == "local":
        init_lat_delt = 1.625
        init_lon_delt = 0.45
        lat_delts = [0.2, 0.7, 1.2, 1.75, 2.25, 2.8]
        londelt = 0.76
        startlon = centerlon - 2 + 0.45

    elif domainsize == "regional":
        init_lat_delt = 6
        init_lon_delt = 1.6
        lat_delts = [0.6, 2.5, 4.5, 6.4, 8.4, 10.25]
        londelt = 2.9
        startlon = centerlon - 7.5 + 1.6

    # Lon adjustment for GFS because it's [0,360] not [-180,180]
    if model == 'GFS':
        startlon = 360 - startlon

    # set lat/lon grid from which to pull data to plot soundings
    startlat = centerlat - init_lat_delt

    sound_lats = []
    sound_lons = []
    for i in range(0, 6):
        lats = startlat + lat_delts[i]
        sound_lats.append(lats)

    for i in range(0, r):
        if model == 'GFS':
            lons = startlon - (londelt * i)
        else:
            lons = -startlon - (londelt * i)
        sound_lons.append(lons)

    # this sets how high each row of soundings is on the plot
    plot_elevs = [0.2, 0.3, 0.4, 0.5, 0.6, 0.7]

    # whole bunch of legend stuff
    dashed_red_line = lines.Line2D([], [],
                                   linestyle='solid',
                                   color='r',
                                   label='Temperature')
    dashed_purple_line = lines.Line2D([], [],
                                      linestyle='dashed',
                                      color='purple',
                                      label='0C Isotherm')
    dashed_green_line = lines.Line2D([], [],
                                     linestyle='solid',
                                     color='g',
                                     label='Dew Point')
    grey_line = lines.Line2D([], [], color='darkgray', label='MSLP (hPa)')
    blue_line = lines.Line2D([], [], color='b', label='Wet Bulb')
    pink_line = lines.Line2D([], [],
                             color='fuchsia',
                             label='Surface-Based Parcel Path')
    teal_line = lines.Line2D([], [],
                             linestyle='dashed',
                             color='teal',
                             label='HGZ')
    green_dot = lines.Line2D([], [],
                             marker='o',
                             color='forestgreen',
                             label='LCL')
    black_dot = lines.Line2D([], [],
                             marker='o',
                             color='k',
                             label='Sounding Origin')

    red = mpatches.Patch(color='tab:red', label='CAPE')
    blue = mpatches.Patch(color='tab:blue', label='CIN')

    # do the plotting based on user inputs
    if cape and wetbulb is True:
        print('CAPE + Wetbulb')
        for i, plot_elev in enumerate(plot_elevs):
            soundlat = sound_lats[i]

            if k < 2:
                s = 1
            else:
                s = 0

            for i in range(s, r):
                levs_abv_ground = []
                soundlon = sound_lons[i]
                sound_temps = temp.interp(lat=soundlat, lon=soundlon) - 273.15
                sound_rh = rh.interp(lat=soundlat, lon=soundlon)
                sound_pres = temp.lev
                spres = sfc_pressure.interp(lat=soundlat, lon=soundlon)
                sound_dp = mpcalc.dewpoint_from_relative_humidity(
                    sound_temps.data * units.degC,
                    sound_rh.data * units.percent)
                sound_wb = mpcalc.wet_bulb_temperature(
                    sound_pres, sound_temps.data * units.degC, sound_dp)

                #Only want data above the ground
                abv_sfc_temp = spt.mask_below_terrain(spres, sound_temps,
                                                      sound_pres)[0]
                abv_sfc_dewp = spt.mask_below_terrain(spres, sound_dp,
                                                      sound_pres)[0]
                abv_sfc_wetb = spt.mask_below_terrain(spres, sound_wb,
                                                      sound_pres)[0]
                pres_abv_ground = spt.mask_below_terrain(
                    spres, sound_temps, sound_pres)[1]

                #sound_wb = sound_wb*units.degC
                skew = SkewT(fig=fig,
                             rect=(0.75 - (0.15 * i), plot_elev, .15, .1))

                parcel_prof = mpcalc.parcel_profile(
                    pres_abv_ground, abv_sfc_temp[0].data * units.degC,
                    abv_sfc_dewp[0])
                cape = mpcalc.cape_cin(pres_abv_ground,
                                       abv_sfc_temp.data * units.degC,
                                       abv_sfc_dewp, parcel_prof)
                capeout = int(cape[0].m)
                cinout = int(cape[1].m)

                #skew.ax.axvspan(-30, -10, color='cyan', alpha=0.4)

                skew.plot(pres_abv_ground, abv_sfc_wetb, 'b', linewidth=2)
                skew.plot(pres_abv_ground, abv_sfc_dewp, 'g', linewidth=3)
                skew.plot(pres_abv_ground, abv_sfc_temp, 'r', linewidth=3)

                if capeout > 100:
                    # Shade areas of CAPE and CIN
                    print(pres_abv_ground)
                    print(abv_sfc_temp.data * units.degC)
                    print(parcel_prof)
                    skew.shade_cin(pres_abv_ground,
                                   abv_sfc_temp.data * units.degC, parcel_prof)
                    skew.shade_cape(pres_abv_ground,
                                    abv_sfc_temp.data * units.degC,
                                    parcel_prof)
                    skew.plot(pres_abv_ground,
                              parcel_prof,
                              color='fuchsia',
                              linewidth=1)
                    lcl_pressure, lcl_temperature = mpcalc.lcl(
                        pres_abv_ground[0], abv_sfc_temp.data[0] * units.degC,
                        abv_sfc_dewp[0])
                    skew.plot(lcl_pressure,
                              lcl_temperature,
                              'ko',
                              markerfacecolor='forestgreen')
                    skew.ax.axvline(-30,
                                    color='teal',
                                    linestyle='--',
                                    linewidth=1)
                    skew.ax.axvline(-10,
                                    color='teal',
                                    linestyle='--',
                                    linewidth=1)
                skew.plot(975, 0, 'ko', markerfacecolor='k')

                skew.ax.axvline(0, color='purple', linestyle='--', linewidth=3)
                skew.ax.set_ylim((1000, 300))
                skew.ax.axis('off')

        leg = ax.legend(handles=[
            dashed_red_line, dashed_green_line, blue_line, dashed_purple_line,
            teal_line, green_dot, pink_line, red, blue, black_dot
        ],
                        title='Sounding Legend',
                        loc=4,
                        framealpha=1)
    elif cape == True and wetbulb == False:
        print('CAPE no wetbulb')
        for k in range(len(plot_elevs)):
            soundlat = sound_lats[k]
            plot_elev = plot_elevs[k]

            if k == 0:
                s = 1
            else:
                s = 0

            for i in range(s, r):
                levs_abv_ground = []
                soundlon = sound_lons[i]
                sound_temps = temp.interp(lat=soundlat, lon=soundlon) - 273.15
                sound_rh = rh.interp(lat=soundlat, lon=soundlon)
                sound_pres = temp.lev
                spres = sfc_pressure.interp(lat=soundlat, lon=soundlon)
                sound_dp = mpcalc.dewpoint_from_relative_humidity(
                    sound_temps.data * units.degC,
                    sound_rh.data * units.percent)

                abv_sfc_temp = spt.mask_below_terrain(spres, sound_temps,
                                                      sound_pres)[0]
                abv_sfc_dewp = spt.mask_below_terrain(spres, sound_dp,
                                                      sound_pres)[0]
                pres_abv_ground = spt.mask_below_terrain(
                    spres, sound_temps, sound_pres)[1]

                skew = SkewT(fig=fig,
                             rect=(0.75 - (0.15 * i), plot_elev, .15, .1))

                parcel_prof = mpcalc.parcel_profile(
                    pres_abv_ground, abv_sfc_temp[0].data * units.degC,
                    abv_sfc_dewp[0])
                cape = mpcalc.cape_cin(pres_abv_ground,
                                       abv_sfc_temp.data * units.degC,
                                       abv_sfc_dewp, parcel_prof)
                capeout = int(cape[0].m)
                cinout = int(cape[1].m)

                skew.plot(pres_abv_ground, abv_sfc_dewp, 'g', linewidth=3)
                skew.plot(pres_abv_ground, abv_sfc_temp, 'r', linewidth=3)

                if capeout > 100:
                    # Shade areas of CAPE and CIN
                    skew.shade_cin(pres_abv_ground,
                                   abv_sfc_temp.data * units.degC, parcel_prof)
                    skew.shade_cape(pres_abv_ground,
                                    abv_sfc_temp.data * units.degC,
                                    parcel_prof)
                    skew.plot(pres_abv_ground,
                              parcel_prof,
                              color='fuchsia',
                              linewidth=1)
                    print(abv_sfc_temp)
                    lcl_pressure, lcl_temperature = mpcalc.lcl(
                        pres_abv_ground[0], abv_sfc_temp.data[0] * units.degC,
                        abv_sfc_dewp[0])
                    skew.plot(lcl_pressure,
                              lcl_temperature,
                              'ko',
                              markerfacecolor='forestgreen')
                    skew.ax.axvline(-30,
                                    color='teal',
                                    linestyle='--',
                                    linewidth=1)
                    skew.ax.axvline(-10,
                                    color='teal',
                                    linestyle='--',
                                    linewidth=1)

                skew.plot(975, 0, 'ko', markerfacecolor='k')

                skew.ax.axvline(0, color='purple', linestyle='--', linewidth=3)
                skew.ax.set_ylim((1000, 300))
                skew.ax.axis('off')

        leg = ax.legend(handles=[
            dashed_red_line, dashed_green_line, dashed_purple_line, teal_line,
            green_dot, pink_line, red, blue, black_dot
        ],
                        title='Sounding Legend',
                        loc=4,
                        framealpha=1)

    elif wetbulb == True and cape == False:
        print('Wetbulb no CAPE')
        for k in range(len(plot_elevs)):
            soundlat = sound_lats[k]
            plot_elev = plot_elevs[k]

            if k == 0:
                s = 1
            else:
                s = 0

            for i in range(s, r):
                levs_abv_ground = []
                soundlon = sound_lons[i]
                sound_temps = temp.interp(lat=soundlat, lon=soundlon) - 273.15
                sound_rh = rh.interp(lat=soundlat, lon=soundlon)
                sound_pres = temp.lev
                spres = sfc_pressure.interp(lat=soundlat, lon=soundlon)

                sound_dp = mpcalc.dewpoint_from_relative_humidity(
                    sound_temps.data * units.degC,
                    sound_rh.data * units.percent)

                sound_wb = mpcalc.wet_bulb_temperature(
                    sound_pres, sound_temps.data * units.degC, sound_dp)

                abv_sfc_temp = spt.mask_below_terrain(spres, sound_temps,
                                                      sound_pres)[0]
                abv_sfc_dewp = spt.mask_below_terrain(spres, sound_dp,
                                                      sound_pres)[0]
                abv_sfc_wetb = spt.mask_below_terrain(spres, sound_wb,
                                                      sound_pres)[0]
                pres_abv_ground = spt.mask_below_terrain(
                    spres, sound_temps, sound_pres)[1]

                #sound_wb = sound_wb*units.degC
                skew = SkewT(fig=fig,
                             rect=(0.75 - (0.15 * i), plot_elev, .15, .1))

                skew.plot(pres_abv_ground, abv_sfc_wetb, 'b', linewidth=2)
                skew.plot(pres_abv_ground, abv_sfc_dewp, 'g', linewidth=3)
                skew.plot(pres_abv_ground, abv_sfc_temp, 'r', linewidth=3)

                skew.ax.axvline(0, color='purple', linestyle='--', linewidth=3)
                skew.ax.set_ylim((1000, 300))
                skew.ax.axis('off')
    else:
        print('No Wetbulb or CAPE')
        for k in range(len(plot_elevs)):
            soundlat = sound_lats[k]
            plot_elev = plot_elevs[k]

            if k == 0:
                s = 1
            else:
                s = 0

            for i in range(s, r):
                sound_pres = temp.lev
                sound_temps = temp.interp(lat=soundlat, lon=soundlon) - 273.15
                sound_rh = rh.interp(lat=soundlat, lon=soundlon)
                sound_dp = mpcalc.dewpoint_from_relative_humidity(
                    sound_temps.data * units.degC,
                    sound_rh.data * units.percent)
                skew = SkewT(fig=fig,
                             rect=(0.75 - (0.15 * i), plot_elev, .15, .1))
                skew.plot(sound_pres, sound_dp, 'g', linewidth=3)
                skew.plot(sound_pres, sound_temps, 'r', linewidth=3)
                skew.plot(1000, 0, 'ko', markerfacecolor='k')

                skew.ax.axvline(0, color='purple', linestyle='--', linewidth=3)
                skew.ax.set_ylim((1000, 300))
                skew.ax.axis('off')

        leg = ax.legend(handles=[
            dashed_red_line, dashed_green_line, blue_line, dashed_purple_line,
            black_dot
        ],
                        title='Sounding Legend',
                        loc=4,
                        framealpha=1)
           .format(save_dir_name, filename_el[-5], selected_time[:13]))
 
 #################################################################################
 ### We will pull the data out of the example dataset into individual variables and
 ### assign units.
 #################################################################################
 
 p = df_selected_time['pressure'].values * units.hPa
 T = df_selected_time['temperature'].values * units.degC
 Td = df_selected_time['dewpoint'].values * units.degC
 wind_speed = df_selected_time['speed'].values * units.knots
 wind_dir = df_selected_time['direction'].values * units.degrees
 u, v = mpcalc.wind_components(wind_speed, wind_dir)
                     
 # Calculate web bulb temperature
 df_selected_time['wet_bulb_T'] = mpcalc.wet_bulb_temperature(p, T, Td)
 
 # Calculate potential temperature
 df_selected_time['potential_T'] = mpcalc.potential_temperature(p, T)
 df_selected_time['potential_T_C'] = df_selected_time['potential_T'].values - 273.15
 
 # Calculate saturation vaper pressure
 df_selected_time['saturation_vaper_pressure'] = mpcalc.saturation_vapor_pressure(T)
 df_selected_time['vaper_pressure']  = mpcalc.saturation_vapor_pressure(Td)
 SVP = df_selected_time['saturation_vaper_pressure'].values * units.hPa
 VP = df_selected_time['vaper_pressure'].values * units.hPa
 
 # Calculate mixing ratio
 df_selected_time['saturation_mixing_ratio'] = mpcalc.mixing_ratio(SVP, p)
 df_selected_time['mixing_ratio'] = mpcalc.mixing_ratio(VP, p)
 SMR = df_selected_time['saturation_mixing_ratio'].values * units('g/kg')
Exemple #14
0
def test_wet_bulb_temperature():
    """Test wet bulb calculation with scalars."""
    val = wet_bulb_temperature(1000 * units.hPa, 25 * units.degC, 15 * units.degC)
    truth = 18.34345936 * units.degC  # 18.59 from NWS calculator
    assert_almost_equal(val, truth)