def get_parcels(self): ''' Function to generate various parcels and parcel traces. Returns nothing, but sets the following variables: self.mupcl : Most Unstable Parcel self.sfcpcl : Surface Based Parcel self.mlpcl : Mixed Layer Parcel self.fcstpcl : Forecast Surface Parcel self.ebottom : The bottom pressure level of the effective inflow layer self.etop : the top pressure level of the effective inflow layer self.ebotm : The bottom, meters (agl), of the effective inflow layer self.etopm : The top, meters (agl), of the effective inflow layer Parameters ---------- None Returns ------- None ''' self.mupcl = params.parcelx( self, flag=3 ) if self.mupcl.lplvals.pres == self.pres[self.sfc]: self.sfcpcl = self.mupcl else: self.sfcpcl = params.parcelx( self, flag=1 ) self.fcstpcl = params.parcelx( self, flag=2 ) self.mlpcl = params.parcelx( self, flag=4 ) self.usrpcl = params.Parcel() ## get the effective inflow layer data self.ebottom, self.etop = params.effective_inflow_layer( self, mupcl=self.mupcl ) ## if there was no effective inflow layer, set the values to masked if self.etop is ma.masked or self.ebottom is ma.masked: self.ebotm = ma.masked; self.etopm = ma.masked self.effpcl = self.sfcpcl # Default to surface parcel, as in params.DefineProfile(). ## otherwise, interpolate the heights given to above ground level else: self.ebotm = interp.to_agl(self, interp.hght(self, self.ebottom)) self.etopm = interp.to_agl(self, interp.hght(self, self.etop)) # The below code was adapted from params.DefineProfile() # Lifting one additional parcel probably won't slow the program too much. # It's just one more lift compared to all the lifts in the params.effective_inflow_layer() call. mtha = params.mean_theta(self, self.ebottom, self.etop) mmr = params.mean_mixratio(self, self.ebottom, self.etop) effpres = (self.ebottom+self.etop)/2. efftmpc = thermo.theta(1000., mtha, effpres) effdwpc = thermo.temp_at_mixrat(mmr, effpres) self.effpcl = params.parcelx(self, flag=5, pres=effpres, tmpc=efftmpc, dwpc=effdwpc) #This is the effective parcel.
def get_parcels(self): ''' Function to generate various parcels and parcel traces. Returns nothing, but sets the following variables: self.mupcl : Most Unstable Parcel self.sfcpcl : Surface Based Parcel self.mlpcl : Mixed Layer Parcel self.fcstpcl : Forecast Surface Parcel self.ebottom : The bottom pressure level of the effective inflow layer self.etop : the top pressure level of the effective inflow layer self.ebotm : The bottom, meters (agl), of the effective inflow layer self.etopm : The top, meters (agl), of the effective inflow layer Parameters ---------- None Returns ------- None ''' self.mupcl = params.parcelx( self, flag=3 ) if self.mupcl.lplvals.pres == self.pres[self.sfc]: self.sfcpcl = self.mupcl else: self.sfcpcl = params.parcelx( self, flag=1 ) self.fcstpcl = params.parcelx( self, flag=2 ) self.mlpcl = params.parcelx( self, flag=4 ) self.usrpcl = params.Parcel() ## get the effective inflow layer data self.ebottom, self.etop = params.effective_inflow_layer( self, mupcl=self.mupcl ) ## if there was no effective inflow layer, set the values to masked if self.etop is ma.masked or self.ebottom is ma.masked: self.ebotm = ma.masked; self.etopm = ma.masked self.effpcl = self.sfcpcl # Default to surface parcel, as in params.DefineProfile(). ## otherwise, interpolate the heights given to above ground level else: self.ebotm = interp.to_agl(self, interp.hght(self, self.ebottom)) self.etopm = interp.to_agl(self, interp.hght(self, self.etop)) # The below code was adapted from params.DefineProfile() # Lifting one additional parcel probably won't slow the program too much. # It's just one more lift compared to all the lifts in the params.effective_inflow_layer() call. mtha = params.mean_theta(self, self.ebottom, self.etop) mmr = params.mean_mixratio(self, self.ebottom, self.etop) effpres = (self.ebottom+self.etop)/2. efftmpc = thermo.theta(1000., mtha, effpres) effdwpc = thermo.temp_at_mixrat(mmr, effpres) self.effpcl = params.parcelx(self, flag=5, pres=effpres, tmpc=efftmpc, dwpc=effdwpc) #This is the effective parcel.
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
''' Create the Sounding (Profile) Object '''
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, etop_hght, stu=srwind[0], stv=srwind[1]) ebwd = winds.wind_shear(prof, pbot=eff_inflow[0], ptop=eff_inflow[1]) ebwspd = utils.mag(ebwd[0], ebwd[1]) scp = params.scp(mupcl.bplus, effective_srh[0], ebwspd) stp_cin = params.stp_cin(mlpcl.bplus, effective_srh[0], ebwspd, mlpcl.lclhght, mlpcl.bminus) indices = {'SBCAPE': [int(sfcpcl.bplus), 'J/kg'],\ 'SBCIN': [int(sfcpcl.bminus), 'J/kg'],\
# annotate temperature in F at bottom of T profile temperatureF = skew.ax.text(prof.tmpc[0], prof.pres[0]+10, utils.INT2STR(thermo.ctof(prof.tmpc[0])), verticalalignment='top', horizontalalignment='center', size=7, color=temperature_trace.get_color()) skew.plot(prof.pres, prof.vtmp, 'r', linewidth=0.5) # Virtual temperature profile skew.plot(prof.pres, prof.wetbulb, 'c-') # wetbulb profile dwpt_trace, = skew.plot(prof.pres, prof.dwpc, 'g', linewidth=2) # dewpoint profile # annotate dewpoint in F at bottom of dewpoint profile dewpointF = skew.ax.text(prof.dwpc[0], prof.pres[0]+10, utils.INT2STR(thermo.ctof(prof.dwpc[0])), verticalalignment='top', horizontalalignment='center', size=7, color=dwpt_trace.get_color()) skew.plot(pcl.ptrace, pcl.ttrace, 'brown', linestyle="dashed" ) # parcel temperature trace skew.ax.set_ylim(1050,100) skew.ax.set_xlim(-50,45) # Plot the effective inflow layer using purple horizontal lines eff_inflow = params.effective_inflow_layer(prof) inflow_bot = skew.ax.axhline(eff_inflow[0], color='purple',xmin=0.38, xmax=0.45) inflow_top = skew.ax.axhline(eff_inflow[1], color='purple',xmin=0.38, xmax=0.45) srwind = params.bunkers_storm_motion(prof) # annotate effective inflow layer SRH if eff_inflow[0]: 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, etop_hght, stu = srwind[0], stv = srwind[1]) # Set position of label # x position is mean of horizontal line bounds # For some reason this makes a big white space on the left side and for all subsequent plots. inflow_SRH = skew.ax.text( np.mean(inflow_top.get_xdata()), eff_inflow[1], '%.0f' % effective_srh[0] + ' ' + '$\mathregular{m^{2}s^{-2}}$', verticalalignment='bottom', horizontalalignment='center', size=6, transform=inflow_bot.get_transform(), color=inflow_top.get_color()