Example #1
0
def test_wind_shear():
    agl1 = 0
    agl2 = 1000
    msl1 = interp.to_msl(prof, agl1)
    msl2 = interp.to_msl(prof, agl2)
    pbot = interp.pres(prof, msl1)
    ptop = interp.pres(prof, msl2)
    correct_u, correct_v = -2.625075135691132, 10.226725739920353
    returned = winds.wind_shear(prof, pbot, ptop)
    npt.assert_almost_equal(returned, [correct_u, correct_v])
def test_wind_shear():
    agl1 = 0
    agl2 = 1000
    msl1 = interp.to_msl(prof, agl1)
    msl2 = interp.to_msl(prof, agl2)
    pbot = interp.pres(prof, msl1)
    ptop = interp.pres(prof, msl2)
    correct_u, correct_v = -2.625075135691132, 10.226725739920353
    returned = winds.wind_shear(prof, pbot, ptop)
    npt.assert_almost_equal(returned, [correct_u, correct_v])
Example #3
0
def bunkers_storm_motion(prof, pbot=None, **kwargs):
    '''
    Compute the Bunkers Storm Motion for a Right Moving Supercell using
    a parcel based approach.

    Inputs
    ------
        prof        (profile object)    Profile Object
        pbot        (float)             Base of effective-inflow layer (hPa)

    Returns
    -------
        rstu        (float)             Right Storm Motion U-component
        rstv        (float)             Right Storm Motion V-component
        lstu        (float)             Left Storm Motion U-component
        lstv        (float)             Left Storm Motion V-component
    '''
    d = MS2KTS(7.5)  # Deviation value emperically derived as 7.5 m/s

    # If MUPCL provided, use it, otherwise create MUPCL
    if 'mupcl' in kwargs:
        mupcl = kwargs.get('mupcl')
    else:
        mulplvals = params.DefineParcel(3, prof, pres=400)
        mupcl = params.parcelx(-1,
                               -1,
                               mulplvals.pres,
                               mulplvals.temp,
                               mulplvals.dwpt,
                               prof,
                               lplvals=mulplvals)

    mucape = mupcl.bplus
    mucinh = mupcl.bminus
    muel = mupcl.elhght
    if not pbot:
        pbot, ptop = effective_inflow_layer(100, -250, prof)
    base = interp.agl(interp.hght(pbot, prof), prof)
    if mucape > 100. and QC(muel) and base >= 750:
        depth = muel - base
        htop = base + depth / 2.
        ptop = interp.pres(interp.msl(base + htop, prof), prof)
        mnu, mnv = winds.mean_wind_npw(pbot, ptop, prof)
        sru, srv = winds.wind_shear(pbot, ptop, prof)
        srmag = vector.mag(sru, srv)
        uchg = d / srmag * srv
        vchg = d / srmag * sru
        rstu = mnu + uchg
        rstv = mnv - vchg
        lstu = mnu - uchg
        lstv = mnv + vchg
    else:
        rstu, rstv, lstu, lstv = winds.non_parcel_bunkers_motion(prof)

    return rstu, rstv, lstu, lstv
Example #4
0
def bunkers_storm_motion(prof, pbot=None, **kwargs):
    '''
    Compute the Bunkers Storm Motion for a Right Moving Supercell using
    a parcel based approach.

    Inputs
    ------
        prof        (profile object)    Profile Object
        pbot        (float)             Base of effective-inflow layer (hPa)

    Returns
    -------
        rstu        (float)             Right Storm Motion U-component
        rstv        (float)             Right Storm Motion V-component
        lstu        (float)             Left Storm Motion U-component
        lstv        (float)             Left Storm Motion V-component
    '''
    d = MS2KTS(7.5)     # Deviation value emperically derived as 7.5 m/s

    # If MUPCL provided, use it, otherwise create MUPCL
    if 'mupcl' in kwargs:
        mupcl = kwargs.get('mupcl')
    else:
        mulplvals = params.DefineParcel(3, prof, pres=400)
        mupcl = params.parcelx(-1, -1, mulplvals.pres, mulplvals.temp,
            mulplvals.dwpt, prof, lplvals=mulplvals)

    mucape = mupcl.bplus
    mucinh = mupcl.bminus
    muel = mupcl.elhght
    if not pbot:
        pbot, ptop = effective_inflow_layer(100, -250, prof)
    base = interp.agl(interp.hght(pbot, prof), prof)
    if mucape > 100. and QC(muel) and base >= 750:
        depth = muel - base
        htop = base + depth / 2.
        ptop = interp.pres(interp.msl(base + htop, prof), prof)
        mnu, mnv = winds.mean_wind_npw(pbot, ptop, prof)
        sru, srv = winds.wind_shear(pbot, ptop, prof)
        srmag = vector.mag(sru, srv)
        uchg = d / srmag * srv
        vchg = d / srmag * sru
        rstu = mnu + uchg
        rstv = mnv - vchg
        lstu = mnu - uchg
        lstv = mnv + vchg
    else:
        rstu, rstv, lstu, lstv =  winds.non_parcel_bunkers_motion(prof)

    return rstu, rstv, lstu, lstv
Example #5
0
    def get_kinematics(self):
        '''
        Function to generate the numerous kinematic quantities
        used for display and calculations. It requires that the
        parcel calculations have already been called for the lcl
        to el shear and mean wind vectors, as well as indices
        that require an effective inflow layer.

        Parameters
        ----------
        None

        Returns
        -------
        None
        '''
        sfc = self.pres[self.sfc]
        heights = np.array([1000., 3000., 4000., 5000., 6000., 8000., 9000.])
        p1km, p3km, p4km, p5km, p6km, p8km, p9km = interp.pres(
            self, interp.to_msl(self, heights))
        ## 1km and 6km winds
        self.wind1km = interp.vec(self, p1km)
        self.wind6km = interp.vec(self, p6km)
        ## calcluate wind shear
        self.sfc_1km_shear = winds.wind_shear(self, pbot=sfc, ptop=p1km)
        self.sfc_3km_shear = winds.wind_shear(self, pbot=sfc, ptop=p3km)
        self.sfc_6km_shear = winds.wind_shear(self, pbot=sfc, ptop=p6km)
        self.sfc_8km_shear = winds.wind_shear(self, pbot=sfc, ptop=p8km)
        self.sfc_9km_shear = winds.wind_shear(self, pbot=sfc, ptop=p9km)
        self.lcl_el_shear = winds.wind_shear(self,
                                             pbot=self.mupcl.lclpres,
                                             ptop=self.mupcl.elpres)
        ## calculate mean wind
        self.mean_1km = utils.comp2vec(
            *winds.mean_wind(self, pbot=sfc, ptop=p1km))
        self.mean_3km = utils.comp2vec(
            *winds.mean_wind(self, pbot=sfc, ptop=p3km))
        self.mean_6km = utils.comp2vec(
            *winds.mean_wind(self, pbot=sfc, ptop=p6km))
        self.mean_8km = utils.comp2vec(
            *winds.mean_wind(self, pbot=sfc, ptop=p8km))
        self.mean_lcl_el = utils.comp2vec(*winds.mean_wind(
            self, pbot=self.mupcl.lclpres, ptop=self.mupcl.elpres))
        ## parameters that depend on the presence of an effective inflow layer
        if self.etop is ma.masked or self.ebottom is ma.masked:
            self.etopm = ma.masked
            self.ebotm = ma.masked
            self.srwind = winds.non_parcel_bunkers_motion(self)
            self.eff_shear = [MISSING, MISSING]
            self.ebwd = [MISSING, MISSING, MISSING]
            self.ebwspd = MISSING
            self.mean_eff = [MISSING, MISSING, MISSING]
            self.mean_ebw = [MISSING, MISSING, MISSING]
            self.srw_eff = [MISSING, MISSING, MISSING]
            self.srw_ebw = [MISSING, MISSING, MISSING]
            self.right_esrh = [ma.masked, ma.masked, ma.masked]
            self.left_esrh = [ma.masked, ma.masked, ma.masked]
            self.critical_angle = ma.masked
        else:
            self.srwind = params.bunkers_storm_motion(self,
                                                      mupcl=self.mupcl,
                                                      pbot=self.ebottom)
            depth = (self.mupcl.elhght - self.ebotm) / 2
            elh = interp.pres(self, interp.to_msl(self, self.ebotm + depth))
            ## calculate mean wind
            self.mean_eff = winds.mean_wind(self, self.ebottom, self.etop)
            self.mean_ebw = winds.mean_wind(self, pbot=self.ebottom, ptop=elh)
            ## calculate wind shear of the effective layer
            self.eff_shear = winds.wind_shear(self,
                                              pbot=self.ebottom,
                                              ptop=self.etop)
            self.ebwd = winds.wind_shear(self, pbot=self.ebottom, ptop=elh)
            self.ebwspd = utils.mag(self.ebwd[0], self.ebwd[1])
            ## calculate the mean sr wind
            self.srw_eff = winds.sr_wind(self,
                                         pbot=self.ebottom,
                                         ptop=self.etop,
                                         stu=self.srwind[0],
                                         stv=self.srwind[1])
            self.srw_ebw = winds.sr_wind(self,
                                         pbot=self.ebottom,
                                         ptop=elh,
                                         stu=self.srwind[0],
                                         stv=self.srwind[1])
            self.right_esrh = winds.helicity(self,
                                             self.ebotm,
                                             self.etopm,
                                             stu=self.srwind[0],
                                             stv=self.srwind[1])
            self.left_esrh = winds.helicity(self,
                                            self.ebotm,
                                            self.etopm,
                                            stu=self.srwind[2],
                                            stv=self.srwind[3])
            self.critical_angle = winds.critical_angle(self,
                                                       stu=self.srwind[0],
                                                       stv=self.srwind[1])
        ## calculate mean srw
        self.srw_1km = utils.comp2vec(*winds.sr_wind(
            self, pbot=sfc, ptop=p1km, stu=self.srwind[0], stv=self.srwind[1]))
        self.srw_3km = utils.comp2vec(*winds.sr_wind(
            self, pbot=sfc, ptop=p3km, stu=self.srwind[0], stv=self.srwind[1]))
        self.srw_6km = utils.comp2vec(*winds.sr_wind(
            self, pbot=sfc, ptop=p6km, stu=self.srwind[0], stv=self.srwind[1]))
        self.srw_8km = utils.comp2vec(*winds.sr_wind(
            self, pbot=sfc, ptop=p8km, stu=self.srwind[0], stv=self.srwind[1]))
        self.srw_4_5km = utils.comp2vec(*winds.sr_wind(
            self, pbot=p4km, ptop=p5km, stu=self.srwind[0],
            stv=self.srwind[1]))
        self.srw_lcl_el = utils.comp2vec(
            *winds.sr_wind(self,
                           pbot=self.mupcl.lclpres,
                           ptop=self.mupcl.elpres,
                           stu=self.srwind[0],
                           stv=self.srwind[1]))
        # This is for the red, blue, and purple bars that appear on the SR Winds vs. Height plot
        self.srw_0_2km = winds.sr_wind(self,
                                       pbot=sfc,
                                       ptop=interp.pres(
                                           self, interp.to_msl(self, 2000.)),
                                       stu=self.srwind[0],
                                       stv=self.srwind[1])
        self.srw_4_6km = winds.sr_wind(self,
                                       pbot=interp.pres(
                                           self, interp.to_msl(self, 4000.)),
                                       ptop=p6km,
                                       stu=self.srwind[0],
                                       stv=self.srwind[1])
        self.srw_9_11km = winds.sr_wind(
            self,
            pbot=interp.pres(self, interp.to_msl(self, 9000.)),
            ptop=interp.pres(self, interp.to_msl(self, 11000.)),
            stu=self.srwind[0],
            stv=self.srwind[1])

        ## calculate upshear and downshear
        self.upshear_downshear = winds.mbe_vectors(self)
        self.srh1km = winds.helicity(self,
                                     0,
                                     1000.,
                                     stu=self.srwind[0],
                                     stv=self.srwind[1])
        self.srh3km = winds.helicity(self,
                                     0,
                                     3000.,
                                     stu=self.srwind[0],
                                     stv=self.srwind[1])
Example #6
0
def indices(prof, debug=False):

    # return a formatted-string list of stability and kinematic indices

    sfcpcl = params.parcelx(prof, flag=1)
    mupcl = params.parcelx(prof, flag=3)  # most unstable
    mlpcl = params.parcelx(prof, flag=4)  # 100 mb mean layer parcel

    pcl = mupcl
    sfc = prof.pres[prof.sfc]
    p3km = interp.pres(prof, interp.to_msl(prof, 3000.))
    p6km = interp.pres(prof, interp.to_msl(prof, 6000.))
    p1km = interp.pres(prof, interp.to_msl(prof, 1000.))
    mean_3km = winds.mean_wind(prof, pbot=sfc, ptop=p3km)
    sfc_6km_shear = winds.wind_shear(prof, pbot=sfc, ptop=p6km)
    sfc_3km_shear = winds.wind_shear(prof, pbot=sfc, ptop=p3km)
    sfc_1km_shear = winds.wind_shear(prof, pbot=sfc, ptop=p1km)
    #print "0-3 km Pressure-Weighted Mean Wind (kt):", utils.comp2vec(mean_3km[0], mean_3km[1])[1]
    #print "0-6 km Shear (kt):", utils.comp2vec(sfc_6km_shear[0], sfc_6km_shear[1])[1]
    srwind = params.bunkers_storm_motion(prof)
    srh3km = winds.helicity(prof, 0, 3000., stu=srwind[0], stv=srwind[1])
    srh1km = winds.helicity(prof, 0, 1000., stu=srwind[0], stv=srwind[1])
    #print "0-3 km Storm Relative Helicity [m2/s2]:",srh3km[0]

    #### Calculating variables based off of the effective inflow layer:

    # The effective inflow layer concept is used to obtain the layer of buoyant parcels that feed a storm's inflow.
    # Here are a few examples of how to compute variables that require the effective inflow layer in order to calculate them:

    stp_fixed = params.stp_fixed(
        sfcpcl.bplus, sfcpcl.lclhght, srh1km[0],
        utils.comp2vec(sfc_6km_shear[0], sfc_6km_shear[1])[1])
    ship = params.ship(prof)

    # If you get an error about not converting masked constant to python int
    # use the round() function instead of int() - Ahijevych May 11 2016
    # 2nd element of list is the # of decimal places
    indices = {
        'SBCAPE': [sfcpcl.bplus, 0, 'J $\mathregular{kg^{-1}}$'],
        'SBCIN': [sfcpcl.bminus, 0, 'J $\mathregular{kg^{-1}}$'],
        'SBLCL': [sfcpcl.lclhght, 0, 'm AGL'],
        'SBLFC': [sfcpcl.lfchght, 0, 'm AGL'],
        'SBEL': [sfcpcl.elhght, 0, 'm AGL'],
        'SBLI': [sfcpcl.li5, 0, 'C'],
        'MLCAPE': [mlpcl.bplus, 0, 'J $\mathregular{kg^{-1}}$'],
        'MLCIN': [mlpcl.bminus, 0, 'J $\mathregular{kg^{-1}}$'],
        'MLLCL': [mlpcl.lclhght, 0, 'm AGL'],
        'MLLFC': [mlpcl.lfchght, 0, 'm AGL'],
        'MLEL': [mlpcl.elhght, 0, 'm AGL'],
        'MLLI': [mlpcl.li5, 0, 'C'],
        'MUCAPE': [mupcl.bplus, 0, 'J $\mathregular{kg^{-1}}$'],
        'MUCIN': [mupcl.bminus, 0, 'J $\mathregular{kg^{-1}}$'],
        'MULCL': [mupcl.lclhght, 0, 'm AGL'],
        'MULFC': [mupcl.lfchght, 0, 'm AGL'],
        'MUEL': [mupcl.elhght, 0, 'm AGL'],
        'MULI': [mupcl.li5, 0, 'C'],
        '0-1 km SRH': [srh1km[0], 0, '$\mathregular{m^{2}s^{-2}}$'],
        '0-1 km Shear':
        [utils.comp2vec(sfc_1km_shear[0], sfc_1km_shear[1])[1], 0, 'kt'],
        '0-3 km SRH': [srh3km[0], 0, '$\mathregular{m^{2}s^{-2}}$'],
        '0-6 km Shear':
        [utils.comp2vec(sfc_6km_shear[0], sfc_6km_shear[1])[1], 0, 'kt'],
        'PWV': [params.precip_water(prof), 2, 'inch'],
        'K-index': [params.k_index(prof), 0, ''],
        'STP(fix)': [stp_fixed, 1, ''],
        'SHIP': [ship, 1, '']
    }

    eff_inflow = params.effective_inflow_layer(prof)
    if any(eff_inflow):
        ebot_hght = interp.to_agl(prof, interp.hght(prof, eff_inflow[0]))
        etop_hght = interp.to_agl(prof, interp.hght(prof, eff_inflow[1]))
        #print "Effective Inflow Layer Bottom Height (m AGL):", ebot_hght
        #print "Effective Inflow Layer Top Height (m AGL):", etop_hght
        effective_srh = winds.helicity(prof,
                                       ebot_hght,
                                       etop_hght,
                                       stu=srwind[0],
                                       stv=srwind[1])
        indices['Eff. SRH'] = [
            effective_srh[0], 0, '$\mathregular{m^{2}s^{-2}}$'
        ]
        #print "Effective Inflow Layer SRH (m2/s2):", effective_srh[0]
        ebwd = winds.wind_shear(prof, pbot=eff_inflow[0], ptop=eff_inflow[1])
        ebwspd = utils.mag(*ebwd)
        indices['EBWD'] = [ebwspd, 0, 'kt']
        #print "Effective Bulk Wind Difference:", ebwspd
        scp = params.scp(mupcl.bplus, effective_srh[0], ebwspd)
        indices['SCP'] = [scp, 1, '']
        stp_cin = params.stp_cin(mlpcl.bplus, effective_srh[0], ebwspd,
                                 mlpcl.lclhght, mlpcl.bminus)
        indices['STP(cin)'] = [stp_cin, 1, '']
        #print "Supercell Composite Parameter:", scp
        #print "Significant Tornado Parameter (w/CIN):", stp_cin
        #print "Significant Tornado Parameter (fixed):", stp_fixed

    # Update the indices within the indices dictionary on the side of the plot.
    string = ''
    for index, value in sorted(indices.items()):
        if np.ma.is_masked(value[0]):
            if debug:
                print("skipping masked value for index=", index)
            continue
        if debug:
            print("index=", index)
            print("value=", value)
        format = '%.' + str(value[1]) + 'f'
        string += index + ": " + format % value[0] + " " + value[2] + '\n'

    return string
Example #7
0
''' Create the Sounding (Profile) Object '''
Example #8
0
def plot_sounding(file, imgName):
    try:
        prof, time, location = decode(file)
    except Exception as e:
        print(
            "\n Oops! Couldn't decode the sounding data. No plot produced!\n")
        print(e)
        # return None

    # Open up the text file with the data in columns (e.g. the sample OAX file distributed with SHARPpy)
    locInfo = location.split('_')
    title = locInfo[0] + ' ' + locInfo[1] + ' ' + locInfo[
        2] + '   ' + time.strftime('%Y%m%d/%H%M') + '   (Observed)'

    # Set up the figure in matplotlib.
    fig = plt.figure(figsize=(14, 7.25))
    gs = gridspec.GridSpec(4, 6, width_ratios=[1, 5, 1, 0.5, 3, 3])
    ax = plt.subplot(gs[0:3, 0:2], projection='skewx')
    plt.title(title, fontsize=14, loc='left', color='w')
    ax.set_facecolor('k')
    ax.spines['left'].set_color('w')
    ax.spines['right'].set_color('w')
    ax.spines['bottom'].set_color('w')
    ax.spines['top'].set_color('w')

    #     xticks = ax.xaxis.get_major_ticks() #mute a tick label outside plot
    #     xticks[-4].label1.set_visible(False)

    ax.tick_params(axis='both', colors='w', grid_color='silver')
    ax.ticklabel_format(style='plain')

    # ax.xaxis.label.set_color('w')
    # ax.yaxis.label.set_color('w')
    ax.grid(True)
    plt.grid(True)

    # Ask user for default limits or custom limits
    pt_plot, t_lower, t_upper = ask_limits(prof.pres[~prof.dwpc.mask],
                                           prof.dwpc[~prof.dwpc.mask])

    # Bounds of the pressure axis
    pb_plot = 1050
    dp_plot = 10
    plevs_plot = np.arange(pb_plot, pt_plot - 1, -dp_plot)

    # Plot the background variables
    # presvals = np.arange(1000, 0, -10)

    #draw mixing ratio lines
    draw_mixing_ratio_lines(ax)

    ax.semilogy(prof.tmpc[~prof.tmpc.mask],
                prof.pres[~prof.tmpc.mask],
                'r',
                lw=2)
    ax.semilogy(prof.dwpc[~prof.dwpc.mask],
                prof.pres[~prof.dwpc.mask],
                'lime',
                lw=2)
    ax.semilogy(prof.vtmp[~prof.dwpc.mask],
                prof.pres[~prof.dwpc.mask],
                'r--',
                lw=1)
    ax.semilogy(prof.wetbulb[~prof.dwpc.mask],
                prof.pres[~prof.dwpc.mask],
                'cyan',
                '-',
                lw=1)

    #write sfc temp and dewpoint in F
    sfcT = prof.tmpc[~prof.tmpc.mask][0]
    sfcTd = prof.dwpc[~prof.dwpc.mask][0]
    sfcW = prof.wetbulb[~prof.dwpc.mask][0]
    sfcP = prof.pres[~prof.tmpc.mask][0]
    ax.annotate(str(int(sfcW * (9 / 5) + 32)), (sfcW, sfcP),
                xytext=(-6, -9),
                textcoords='offset points',
                color='cyan',
                weight='black',
                size=8,
                path_effects=[pe.withStroke(linewidth=2, foreground="black")])
    ax.annotate(str(int(sfcT * (9 / 5) + 32)), (sfcT, sfcP),
                xytext=(-2, -9),
                textcoords='offset points',
                color='r',
                weight='black',
                size=8,
                path_effects=[pe.withStroke(linewidth=2, foreground="black")])
    ax.annotate(str(int(sfcTd * (9 / 5) + 32)), (sfcTd, sfcP),
                xytext=(-12, -9),
                textcoords='offset points',
                color='lime',
                weight='black',
                size=8,
                path_effects=[pe.withStroke(linewidth=2, foreground="black")])

    #plot significant levels
    plot_sig_levels(ax, prof)

    # Plot the parcel trace, but this may fail.  If it does so, inform the user.
    try:
        ax.semilogy(prof.mupcl.ttrace, prof.mupcl.ptrace, 'w--')
    except:
        print("Couldn't plot parcel traces...")

    # Highlight the 0 C and -20 C isotherms.
    l = ax.axvline(0, color='b', ls='--')
    l = ax.axvline(-20, color='b', ls='--')

    #plot dry adiabats
    skew.draw_dry_adiabats(ax, color='silver')

    #draw heights
    skew.draw_heights(ax, prof)

    # Disables the log-formatting that comes with semilogy
    ax.yaxis.set_major_formatter(ScalarFormatter())
    pmin = prof.pres[~prof.dwpc.mask][-1]
    if pmin > 700.:
        ax.set_yticks(np.arange(100, 1000, 50))
    else:
        ax.set_yticks(np.linspace(100, 1000, 10))
    ax.set_ylim(pb_plot, pt_plot)

    # Plot the hodograph data.
    # inset_axes = draw_hodo_inset(ax, prof)
    hodoAx = plt.subplot(gs[0:3, 3:])
    hodoAx.set_facecolor('k')
    hodoAx.axis('off')
    hodoAx = draw_hodo_inset(hodoAx, prof)

    # plotHodo(inset_axes, prof.hght, prof.u, prof.v, color='r')
    plotHodo(hodoAx, prof.hght, prof.u, prof.v, color='r')

    #plot bunkers motion unless the most unstable EL does not exist
    srwind = params.bunkers_storm_motion(prof)
    if isinstance(prof.mupcl.elpres, np.float64):
        hodoAx.text(srwind[0], srwind[1], 'RM', color='w', fontsize=8)
        hodoAx.text(srwind[2], srwind[3], 'LM', color='w', fontsize=8)
    else:
        print("couldn't plot Bunkers vectors")

    # inset_axes.text(srwind[0], srwind[1], 'RM', color='r', fontsize=8)
    # inset_axes.text(srwind[2], srwind[3], 'LM', color='b', fontsize=8)

    #mask out barbs above the top of the plot
    below_pmin = np.where(prof.pres >= pt_plot)[0]

    # Draw the wind barbs axis and everything that comes with it.
    if pmin > 700.:
        ax.xaxis.set_major_locator(MultipleLocator(5))
    else:
        ax.xaxis.set_major_locator(MultipleLocator(10))
    ax.set_xlim(t_lower, t_upper)

    ax2 = plt.subplot(gs[0:3, 2])
    ax3 = plt.subplot(gs[3, 0:3])
    plot_wind_axes(ax2, pb_plot, pt_plot, plevs_plot)

    #setting the stride for how many wind barbs plot
    # st = 15

    # plot_wind_barbs(ax2, prof.pres[below_pmin][~prof.pres.mask[below_pmin]][::st],
    #                 prof.u[below_pmin][~prof.u.mask[below_pmin]][::st],
    #                 prof.v[below_pmin][~prof.v.mask[below_pmin]][::st],
    #                 pt_plot)
    plot_wind_barbs(ax2, prof.pres[below_pmin][~prof.pres.mask[below_pmin]],
                    prof.u[below_pmin][~prof.u.mask[below_pmin]],
                    prof.v[below_pmin][~prof.v.mask[below_pmin]], pt_plot)

    gs.update(left=0.05, bottom=0.05, top=0.95, right=1, wspace=0.025)

    # Calculate indices to be shown.  More indices can be calculated here using the tutorial and reading the params module.
    p1km = interp.pres(prof, interp.to_msl(prof, 1000.))
    p6km = interp.pres(prof, interp.to_msl(prof, 6000.))
    sfc = prof.pres[prof.sfc]
    sfc_1km_shear = winds.wind_shear(prof, pbot=sfc, ptop=p1km)
    sfc_6km_shear = winds.wind_shear(prof, pbot=sfc, ptop=p6km)
    srh3km = winds.helicity(prof, 0, 3000., stu=srwind[0], stv=srwind[1])
    srh1km = winds.helicity(prof, 0, 1000., stu=srwind[0], stv=srwind[1])
    scp = params.scp(prof.mupcl.bplus, prof.right_esrh[0], prof.ebwspd)
    stp_cin = params.stp_cin(prof.mlpcl.bplus, prof.right_esrh[0], prof.ebwspd,
                             prof.mlpcl.lclhght, prof.mlpcl.bminus)
    stp_fixed = params.stp_fixed(
        prof.sfcpcl.bplus, prof.sfcpcl.lclhght, srh1km[0],
        utils.comp2vec(prof.sfc_6km_shear[0], prof.sfc_6km_shear[1])[1])
    ship = params.ship(prof)

    # A routine to perform the correct formatting when writing the indices out to the figure.
    def fmt(value, fmt='int'):
        if fmt == 'int':
            try:
                val = int(value)
            except:
                val = str("M")
        else:
            try:
                val = round(value, 1)
            except:
                val = "M"
        return val

    # Setting a dictionary that is a collection of all of the indices we'll be showing on the figure.
    # the dictionary includes the index name, the actual value, and the units.
    indices = {'SBCAPE': [fmt(prof.sfcpcl.bplus), 'J/kg'],\
               'SBCIN': [fmt(prof.sfcpcl.bminus), 'J/kg'],\
               'SBLCL': [fmt(prof.sfcpcl.lclhght), 'm AGL'],\
               'SBLFC': [fmt(prof.sfcpcl.lfchght), 'm AGL'],\
               'SBEL': [fmt(prof.sfcpcl.elhght), 'm AGL'],\
               'SBLI': [fmt(prof.sfcpcl.li5), 'C'],\
               'MLCAPE': [fmt(prof.mlpcl.bplus), 'J/kg'],\
               'MLCIN': [fmt(prof.mlpcl.bminus), 'J/kg'],\
               'MLLCL': [fmt(prof.mlpcl.lclhght), 'm AGL'],\
               'MLLFC': [fmt(prof.mlpcl.lfchght), 'm AGL'],\
               'MLEL': [fmt(prof.mlpcl.elhght), 'm AGL'],\
               'MLLI': [fmt(prof.mlpcl.li5), 'C'],\
               'MUCAPE': [fmt(prof.mupcl.bplus), 'J/kg'],\
               'MUCIN': [fmt(prof.mupcl.bminus), 'J/kg'],\
               'MULCL': [fmt(prof.mupcl.lclhght), 'm AGL'],\
               'MULFC': [fmt(prof.mupcl.lfchght), 'm AGL'],\
               'MUEL': [fmt(prof.mupcl.elhght), 'm AGL'],\
               'MULI': [fmt(prof.mupcl.li5), 'C'],\
               '0-1 km SRH': [fmt(srh1km[0]), 'm2/s2'],\
               '0-1 km Shear': [fmt(utils.comp2vec(sfc_1km_shear[0], sfc_1km_shear[1])[1]), 'kts'],\
               '0-3 km SRH': [fmt(srh3km[0]), 'm2/s2'],\
               '0-6 km Shear': [fmt(utils.comp2vec(sfc_6km_shear[0], sfc_6km_shear[1])[1]), 'kts'],\
               'Eff. SRH': [fmt(prof.right_esrh[0]), 'm2/s2'],\
               'EBWD': [fmt(prof.ebwspd), 'kts'],\
               'PWV': [round(prof.pwat, 2), 'inch'],\
               'K-index': [fmt(params.k_index(prof)), ''],\
               'STP(fix)': [fmt(stp_fixed, 'flt'), ''],\
               'SHIP': [fmt(ship, 'flt'), ''],\
               'SCP': [fmt(scp, 'flt'), ''],\
               'STP(cin)': [fmt(stp_cin, 'flt'), '']}

    # List the indices within the indices dictionary on the side of the plot.
    trans = transforms.blended_transform_factory(ax.transAxes, ax.transData)

    # Write out all of the indices to the figure.
    #print("##############")
    #print("   INDICES    ")
    #print("##############")
    string = ''
    keys = np.sort(list(indices.keys()))
    x = 0
    counter = 0
    for key in keys:
        string = string + key + ': ' + str(
            indices[key][0]) + ' ' + indices[key][1] + '\n'
        #    print((key + ": " + str(indices[key][0]) + ' ' + indices[key][1]))
        if counter < 7:
            counter += 1
            continue
        else:
            counter = 0
            ax3.text(x,
                     1,
                     string,
                     verticalalignment='top',
                     transform=ax3.transAxes,
                     fontsize=11,
                     color='w')
            string = ''
            x += 0.3
    ax3.text(x,
             1,
             string,
             verticalalignment='top',
             transform=ax3.transAxes,
             fontsize=11,
             color='w')
    ax3.set_axis_off()

    # Show SARS matches (edited for Keith Sherburn)
    #try:
    #    supercell_matches = prof.supercell_matches
    #    hail_matches = prof.matches
    #except:
    #    supercell_matches = prof.right_supercell_matches
    #    hail_matches = prof.right_matches

    #print()
    #print("#############")
    #print(" SARS OUTPUT ")
    #print("#############")
    #for mtype, matches in zip(['Supercell', 'Hail'], [supercell_matches, hail_matches]):
    #    print(mtype)
    #    print('-----------')
    #    if len(matches[0]) == 0:
    #        print("NO QUALITY MATCHES")
    #    for i in range(len(matches[0])):
    #        print(matches[0][i] + ' ' + matches[1][i])
    #    print("Total Loose Matches:", matches[2])
    #    print("# of Loose Matches that met Criteria:", matches[3])
    #    print("SVR Probability:", matches[4])
    #    print()

    #plot logos
    im = plt.imread('logo.png')
    #left, bottom, width, height = [0.25, 0.6, 0.2, 0.2]
    #left, bottom, width, height = [0.1, 0.175, 0.4, 0.4] #bottom left
    left, bottom, width, height = [0.035, 0.65, 0.4, 0.4]
    # ax4 = fig.add_axes([left, bottom, width, height])
    ax4 = plt.subplot(gs[3, 4])
    implot = ax4.imshow(im, alpha=0.99)
    ax4.axis('off')
    ax4.set_facecolor('k')

    im2 = plt.imread('essc_logo.png')
    ax5 = plt.subplot(gs[3, 5])
    implot = ax5.imshow(im2, alpha=0.99)
    ax5.axis('off')
    ax5.set_facecolor('k')

    #plot SHARPpy acknowledgement
    # plt.text(1, 1, 'Plotted with SHARPpy', horizontalalignment='right',
    #             verticalalignment='top', transform=ax.transAxes, color='w')
    hodoAx.annotate(
        'Plotted with SHARPpy - https://sharppy.github.io/SHARPpy/',
        (0.7, 0.96),
        xycoords='figure fraction',
        va='center',
        color='w')

    #filename for the plot
    # plotName = os.path.splitext(file)[0] + '.png'

    # Finalize the image formatting and alignments, and save the image to the file.
    #gs.tight_layout(fig)
    plt.style.use('dark_background')
    fn = time.strftime(
        '%Y%m%d.%H%M') + '_' + locInfo[0] + '_' + locInfo[1] + '.png'
    fn = fn.replace('/', '')
    print('SHARPpy quick-look image output at: ' + imgName)
    #plt.savefig(fn, bbox_inches='tight', dpi=180)
    plt.savefig(imgName, dpi=180)
Example #9
0
# Convert wind speed and direction to components
u, v = get_wind_components(spd, direc)
u_std, v_std = get_wind_components(spd_std, direc_std)

#PARCEL CALCULATIONS with sharppy
sfcpcl = params.parcelx(prof, flag=1)  # Surface Parcel
fcstpcl = params.parcelx(prof, flag=2)  # Forecast Parcel
mupcl = params.parcelx(prof, flag=3)  # Most-Unstable Parcel
mlpcl = params.parcelx(prof, flag=4)  # 100 mb Mean Layer Parcel

sfc = prof.pres[prof.sfc]
p3km = interp.pres(prof, interp.to_msl(prof, 3000.))
p6km = interp.pres(prof, interp.to_msl(prof, 6000.))
p1km = interp.pres(prof, interp.to_msl(prof, 1000.))
mean_3km = winds.mean_wind(prof, pbot=sfc, ptop=p3km)
sfc_6km_shear = winds.wind_shear(prof, pbot=sfc, ptop=p6km)
sfc_3km_shear = winds.wind_shear(prof, pbot=sfc, ptop=p3km)
sfc_1km_shear = winds.wind_shear(prof, pbot=sfc, ptop=p1km)
srwind = params.bunkers_storm_motion(prof)
srh3km = winds.helicity(prof, 0, 3000., stu=srwind[0], stv=srwind[1])
srh1km = winds.helicity(prof, 0, 1000., stu=srwind[0], stv=srwind[1])

stp_fixed = params.stp_fixed(
    sfcpcl.bplus, sfcpcl.lclhght, srh1km[0],
    utils.comp2vec(sfc_6km_shear[0], sfc_6km_shear[1])[1])
ship = params.ship(prof)
eff_inflow = params.effective_inflow_layer(prof)
ebot_hght = interp.to_agl(prof, interp.hght(prof, eff_inflow[0]))
etop_hght = interp.to_agl(prof, interp.hght(prof, eff_inflow[1]))
effective_srh = winds.helicity(prof,
                               ebot_hght,
Example #10
0
 def get_kinematics(self):
     '''
     Function to generate the numerous kinematic quantities
     used for display and calculations. It requires that the
     parcel calculations have already been called for the lcl
     to el shear and mean wind vectors, as well as indices
     that require an effective inflow layer.
     Parameters
     ----------
     None
     Returns
     -------
     None
     '''
     sfc = self.pres[self.sfc]
     heights = np.array([1000., 3000., 4000., 5000., 6000., 8000., 9000.])
     p1km, p3km, p4km, p5km, p6km, p8km, p9km = interp.pres(self, interp.to_msl(self, heights))
     ## 1km and 6km winds
     self.wind1km = interp.vec(self, p1km)
     self.wind6km = interp.vec(self, p6km)
     ## calcluate wind shear
     self.sfc_1km_shear = winds.wind_shear(self, pbot=sfc, ptop=p1km)
     self.sfc_3km_shear = winds.wind_shear(self, pbot=sfc, ptop=p3km)
     self.sfc_6km_shear = winds.wind_shear(self, pbot=sfc, ptop=p6km)
     self.sfc_8km_shear = winds.wind_shear(self, pbot=sfc, ptop=p8km)
     self.sfc_9km_shear = winds.wind_shear(self, pbot=sfc, ptop=p9km)
     self.lcl_el_shear = winds.wind_shear(self, pbot=self.mupcl.lclpres, ptop=self.mupcl.elpres)
     ## calculate mean wind
     self.mean_1km = utils.comp2vec(*winds.mean_wind(self, pbot=sfc, ptop=p1km))
     self.mean_3km = utils.comp2vec(*winds.mean_wind(self, pbot=sfc, ptop=p3km))
     self.mean_6km = utils.comp2vec(*winds.mean_wind(self, pbot=sfc, ptop=p6km))
     self.mean_8km = utils.comp2vec(*winds.mean_wind(self, pbot=sfc, ptop=p8km))
     self.mean_lcl_el = utils.comp2vec(*winds.mean_wind(self, pbot=self.mupcl.lclpres, ptop=self.mupcl.elpres))
     ## parameters that depend on the presence of an effective inflow layer
     if self.etop is ma.masked or self.ebottom is ma.masked:
         self.etopm = ma.masked; self.ebotm = ma.masked
         self.srwind = winds.non_parcel_bunkers_motion( self )
         self.eff_shear = [MISSING, MISSING]
         self.ebwd = [MISSING, MISSING, MISSING]
         self.ebwspd = MISSING
         self.mean_eff = [MISSING, MISSING, MISSING]
         self.mean_ebw = [MISSING, MISSING, MISSING]
         self.srw_eff = [MISSING, MISSING, MISSING]
         self.srw_ebw = [MISSING, MISSING, MISSING]
         self.right_esrh = [ma.masked, ma.masked, ma.masked]
         self.left_esrh = [ma.masked, ma.masked, ma.masked]
         self.critical_angle = ma.masked
     else:
         self.srwind = params.bunkers_storm_motion(self, mupcl=self.mupcl, pbot=self.ebottom)
         depth = ( self.mupcl.elhght - self.ebotm ) / 2
         elh = interp.pres(self, interp.to_msl(self, self.ebotm + depth))
         ## calculate mean wind
         self.mean_eff = winds.mean_wind(self, self.ebottom, self.etop )
         self.mean_ebw = winds.mean_wind(self, pbot=self.ebottom, ptop=elh )
         ## calculate wind shear of the effective layer
         self.eff_shear = winds.wind_shear(self, pbot=self.ebottom, ptop=self.etop)
         self.ebwd = winds.wind_shear(self, pbot=self.ebottom, ptop=elh)
         self.ebwspd = utils.mag( self.ebwd[0], self.ebwd[1] )
         ## calculate the mean sr wind
         self.srw_eff = winds.sr_wind(self, pbot=self.ebottom, ptop=self.etop, stu=self.srwind[0], stv=self.srwind[1] )
         self.srw_ebw = winds.sr_wind(self, pbot=self.ebottom, ptop=elh, stu=self.srwind[0], stv=self.srwind[1] )
         self.right_esrh = winds.helicity(self, self.ebotm, self.etopm, stu=self.srwind[0], stv=self.srwind[1])
         self.left_esrh = winds.helicity(self, self.ebotm, self.etopm, stu=self.srwind[2], stv=self.srwind[3])
         self.critical_angle = winds.critical_angle(self, stu=self.srwind[0], stv=self.srwind[1])
     ## calculate mean srw
     self.srw_1km = utils.comp2vec(*winds.sr_wind(self, pbot=sfc, ptop=p1km, stu=self.srwind[0], stv=self.srwind[1] ))
     self.srw_3km = utils.comp2vec(*winds.sr_wind(self, pbot=sfc, ptop=p3km, stu=self.srwind[0], stv=self.srwind[1] ))
     self.srw_6km = utils.comp2vec(*winds.sr_wind(self, pbot=sfc, ptop=p6km, stu=self.srwind[0], stv=self.srwind[1] ))
     self.srw_8km = utils.comp2vec(*winds.sr_wind(self, pbot=sfc, ptop=p8km, stu=self.srwind[0], stv=self.srwind[1] ))
     self.srw_4_5km = utils.comp2vec(*winds.sr_wind(self, pbot=p4km, ptop=p5km, stu=self.srwind[0], stv=self.srwind[1] ))
     self.srw_lcl_el = utils.comp2vec(*winds.sr_wind(self, pbot=self.mupcl.lclpres, ptop=self.mupcl.elpres, stu=self.srwind[0], stv=self.srwind[1] ))
     # This is for the red, blue, and purple bars that appear on the SR Winds vs. Height plot
     self.srw_0_2km = winds.sr_wind(self, pbot=sfc, ptop=interp.pres(self, interp.to_msl(self, 2000.)), stu=self.srwind[0], stv=self.srwind[1])
     self.srw_4_6km = winds.sr_wind(self, pbot=interp.pres(self, interp.to_msl(self, 4000.)), ptop=p6km, stu=self.srwind[0], stv=self.srwind[1])
     self.srw_9_11km = winds.sr_wind(self, pbot=interp.pres(self, interp.to_msl(self, 9000.)), ptop=interp.pres(self, interp.to_msl(self, 11000.)), stu=self.srwind[0], stv=self.srwind[1])
     
     ## calculate upshear and downshear
     self.upshear_downshear = winds.mbe_vectors(self)
     self.srh1km = winds.helicity(self, 0, 1000., stu=self.srwind[0], stv=self.srwind[1])
     self.srh3km = winds.helicity(self, 0, 3000., stu=self.srwind[0], stv=self.srwind[1])
                                               1050, 25)
    skew.plot_wind_barbs(ax2, p_less, u_less, v_less)

    srwind = params.bunkers_storm_motion(prof)
    gs.update(left=0.05, bottom=0.05, top=0.95, right=1, wspace=0.025)

    #########################

    # Calculate indices to be shown.
    p1km = interp.pres(prof, interp.to_msl(prof, 1000.))
    p3km = interp.pres(prof, interp.to_msl(prof, 3000.))
    p6km = interp.pres(prof, interp.to_msl(prof, 6000.))
    p8km = interp.pres(prof, interp.to_msl(prof, 8000.))
    p9km = interp.pres(prof, interp.to_msl(prof, 9000.))
    sfc = prof.pres[prof.sfc]
    sfc_1km_shear = winds.wind_shear(prof, pbot=sfc, ptop=p1km)
    sfc_3km_shear = winds.wind_shear(prof, pbot=sfc, ptop=p3km)
    sfc_6km_shear = winds.wind_shear(prof, pbot=sfc, ptop=p6km)
    sfc_8km_shear = winds.wind_shear(prof, pbot=sfc, ptop=p8km)
    sfc_9km_shear = winds.wind_shear(prof, pbot=sfc, ptop=p9km)
    srh3km = winds.helicity(prof, 0, 3000., stu=srwind[0], stv=srwind[1])
    srh1km = winds.helicity(prof, 0, 1000., stu=srwind[0], stv=srwind[1])
    scp = params.scp(prof.mupcl.bplus, prof.right_esrh[0], prof.ebwspd)
    stp_cin = params.stp_cin(prof.mlpcl.bplus, prof.right_esrh[0], prof.ebwspd,
                             prof.mlpcl.lclhght, prof.mlpcl.bminus)
    stp_fixed = params.stp_fixed(
        prof.sfcpcl.bplus, prof.sfcpcl.lclhght, srh1km[0],
        utils.comp2vec(prof.sfc_6km_shear[0], prof.sfc_6km_shear[1])[1])
    ship = params.ship(prof)

    #########################
Example #12
0
                            color='r',
                            alpha=0.7,
                            linestyle="None",
                            marker="o",
                            markersize=5,
                            mew=0,
                            label="right mover")
    # Explanation for red and blue dots. Put only 1 point in the legend entry.
    bunkerleg = hodo_ax.legend(handles=[bunkerL, bunkerR],
                               fontsize=5,
                               frameon=False,
                               numpoints=1)

    # show Bunker left/right movers if 0-6km shear magnitude >= 20kts
    p6km = interp.pres(prof, interp.to_msl(prof, 6000.))
    sfc_6km_shear = winds.wind_shear(prof, pbot=prof.pres[prof.sfc], ptop=p6km)
    if utils.comp2vec(sfc_6km_shear[0], sfc_6km_shear[1])[1] >= 20.:
        bunkerR.set_visible(True)
        bunkerL.set_visible(True)
        bunkerleg.set_visible(True)
        bunkerR.set_data(srwind[0],
                         srwind[1])  # Update Bunker's Storm motion right mover
        bunkerL.set_data(srwind[2],
                         srwind[3])  # Update Bunker's Storm motion left mover
    else:
        bunkerR.set_visible(False)
        bunkerL.set_visible(False)
        bunkerleg.set_visible(False)

    if debug:
        print("about to plot wind barbs")
Example #13
0
    # Update the hodograph on the Skew-T.
    # Draw the hodograph on the Skew-T.
    hodo_ax = myskewt.draw_hodo()
    hodo, AGL = myskewt.add_hodo(hodo_ax, prof)

    # Plot Bunker's Storm motion left mover as a blue dot
    bunkerL, = hodo_ax.plot([], [], color='b', alpha=0.7, linestyle="None", marker="o", markersize=5, mew=0, label="left mover")
    # Plot Bunker's Storm motion right mover as a red dot
    # The comma after bunkerR de-lists it.
    bunkerR, = hodo_ax.plot([], [], color='r', alpha=0.7, linestyle="None", marker="o", markersize=5, mew=0, label="right mover")
    # Explanation for red and blue dots. Put only 1 point in the legend entry.
    bunkerleg = hodo_ax.legend(handles=[bunkerL,bunkerR], fontsize=5, frameon=False, numpoints=1)

    # show Bunker left/right movers if 0-6km shear magnitude >= 20kts
    p6km = interp.pres(prof, interp.to_msl(prof, 6000.))
    sfc_6km_shear = winds.wind_shear(prof, pbot=prof.pres[prof.sfc], ptop=p6km)
    if utils.comp2vec(sfc_6km_shear[0], sfc_6km_shear[1])[1] >= 20.:
        bunkerR.set_visible(True)
        bunkerL.set_visible(True)
        bunkerleg.set_visible(True)
        bunkerR.set_data(srwind[0], srwind[1]) # Update Bunker's Storm motion right mover
        bunkerL.set_data(srwind[2], srwind[3]) # Update Bunker's Storm motion left mover
    else:
        bunkerR.set_visible(False)
        bunkerL.set_visible(False)
        bunkerleg.set_visible(False)

    # Recreate stack of wind barbs
    s = []
    bot=2000.
    # Space out wind barbs evenly on log axis.
Example #14
0
# Draw the wind barbs axis and everything that comes with it.
ax.xaxis.set_major_locator(MultipleLocator(10))
ax.set_xlim(-50, 50)
ax2 = plt.subplot(gs[0:3, 2])
ax3 = plt.subplot(gs[3, 0:3])
skew.plot_wind_axes(ax2)
skew.plot_wind_barbs(ax2, prof.pres, prof.u, prof.v)
srwind = params.bunkers_storm_motion(prof)
gs.update(left=0.05, bottom=0.05, top=0.95, right=1, wspace=0.025)

# Calculate indices to be shown.  More indices can be calculated here using the tutorial and reading the params module.
p1km = interp.pres(prof, interp.to_msl(prof, 1000.))
p6km = interp.pres(prof, interp.to_msl(prof, 6000.))
sfc = prof.pres[prof.sfc]
sfc_1km_shear = winds.wind_shear(prof, pbot=sfc, ptop=p1km)
sfc_6km_shear = winds.wind_shear(prof, pbot=sfc, ptop=p6km)
srh3km = winds.helicity(prof, 0, 3000., stu=srwind[0], stv=srwind[1])
srh1km = winds.helicity(prof, 0, 1000., stu=srwind[0], stv=srwind[1])
scp = params.scp(prof.mupcl.bplus, prof.right_esrh[0], prof.ebwspd)
stp_cin = params.stp_cin(prof.mlpcl.bplus, prof.right_esrh[0], prof.ebwspd,
                         prof.mlpcl.lclhght, prof.mlpcl.bminus)
stp_fixed = params.stp_fixed(
    prof.sfcpcl.bplus, prof.sfcpcl.lclhght, srh1km[0],
    utils.comp2vec(prof.sfc_6km_shear[0], prof.sfc_6km_shear[1])[1])
ship = params.ship(prof)


# A routine to perform the correct formatting when writing the indices out to the figure.
def fmt(value, fmt='int'):
    if fmt == 'int':