def max_wind(lower, upper, prof): ''' Finds the maximum wind speed of the layer given by lower and upper levels. In the event of the maximum wind speed occurring at multiple levels, the lowest level it occurs is returned. Inputs ------ lower (float) Bottom level of layer (m, AGL) upper (float) Top level of layer (m, AGL) prof (profile object) Profile Object Returns ------- p (float) Pressure level (hPa) of max wind speed maxu (float) Maximum U-component maxv (float) Maximum V-component ''' if lower == -1: lower = prof.gSndg[prof.sfc][prof.pind] if upper == -1: upper = prof.gSndg[prof.gNumLevels - 1][prof.pind] # Find lower and upper ind bounds for looping i = 0 while prof.gSndg[i][prof.pind] > lower: i += 1 lptr = i while prof.gSndg[i][prof.pind] > upper: i += 1 uptr = i # Start with interpolated bottom level maxu, maxv = interp.components(lower, prof) maxspd = vector.comp2vec(maxu, maxv)[1] p = lower # Loop through all levels in layer for i in range(lptr, uptr + 1): if QC(prof.gSndg[i][prof.pind]) and QC(prof.gSndg[i][prof.uind]) and \ QC(prof.gSndg[i][prof.vind]): spd = vector.comp2vec(prof.gSndg[i][prof.uind], prof.gSndg[i][prof.vind])[1] if spd > maxspd: maxspd = spd maxu = prof.gSndg[i][prof.uind] maxv = prof.gSndg[i][prof.vind] p = prof.gSndg[i][prof.pind] # Finish with interpolated top level tmpu, tmpv = interp.components(upper, prof) tmpspd = vector.comp2vec(tmpu, tmpv)[1] if tmpspd > maxspd: maxu = tmpu maxv = tmpv maxspd = tmpspd p = upper return p, maxu, maxv
def max_wind(lower, upper, prof): ''' Finds the maximum wind speed of the layer given by lower and upper levels. In the event of the maximum wind speed occurring at multiple levels, the lowest level it occurs is returned. Inputs ------ lower (float) Bottom level of layer (m, AGL) upper (float) Top level of layer (m, AGL) prof (profile object) Profile Object Returns ------- p (float) Pressure level (hPa) of max wind speed maxu (float) Maximum U-component maxv (float) Maximum V-component ''' if lower == -1: lower = prof.gSndg[prof.sfc][prof.pind] if upper == -1: upper = prof.gSndg[prof.gNumLevels-1][prof.pind] # Find lower and upper ind bounds for looping i = 0 while prof.gSndg[i][prof.pind] > lower: i+=1 lptr = i while prof.gSndg[i][prof.pind] > upper: i+=1 uptr = i # Start with interpolated bottom level maxu, maxv = interp.components(lower, prof) maxspd = vector.comp2vec(maxu, maxv)[1] p = lower # Loop through all levels in layer for i in range(lptr, uptr+1): if QC(prof.gSndg[i][prof.pind]) and QC(prof.gSndg[i][prof.uind]) and \ QC(prof.gSndg[i][prof.vind]): spd = vector.comp2vec(prof.gSndg[i][prof.uind], prof.gSndg[i][prof.vind])[1] if spd > maxspd: maxspd = spd maxu = prof.gSndg[i][prof.uind] maxv = prof.gSndg[i][prof.vind] p = prof.gSndg[i][prof.pind] # Finish with interpolated top level tmpu, tmpv = interp.components(upper, prof) tmpspd = vector.comp2vec(tmpu, tmpv)[1] if tmpspd > maxspd: maxu = tmpu maxv = tmpv maxspd = tmpspd p = upper return p, maxu, maxv
def non_parcel_bunkers_motion(prof): ''' Compute the Bunkers Storm Motion for a Right Moving Supercell Inputs ------ prof (profile object) Profile Object 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 msl6km = interp.msl(6000., prof) p6km = interp.pres(msl6km, prof) # SFC-6km Mean Wind mnu6, mnv6 = mean_wind_npw(prof.gSndg[prof.sfc][prof.pind], p6km, prof, 20) # SFC-6km Shear Vector shru6, shrv6 = wind_shear(prof.gSndg[prof.sfc][prof.pind], p6km, prof) # Bunkers Right Motion tmp = d / vector.comp2vec(shru6, shrv6)[1] rstu = mnu6 + (tmp * shrv6) rstv = mnv6 - (tmp * shru6) lstu = mnu6 - (tmp * shrv6) lstv = mnv6 + (tmp * shru6) return rstu, rstv, lstu, lstv
def bulk_rich(pcl, prof): ''' Calculates the Bulk Richardson Number for a given parcel. Inputs ------ pcl (parcel object) Parcel Object prof (profile object) Profile Object Returns ------- Bulk Richardson Number ''' # Make sure parcel is initialized if pcl.lplvals.flag == RMISSD: pbot = RMISSD elif pcl.lplvals.flag > 0 and pcl.lplvals.flag < 4: ptop = interp.pres(interp.msl(6000., prof), prof) pbot = prof.gSndg[prof.sfc][prof.pind] else: h0 = interp.hght(pcl.pres, prof) try: pbot = interp.pres(h0 - 500., prof) except: pbot = RMISSD if not QC(pbot): pbot = prof.gSndg[prof.sfc][prof.pind] h1 = interp.hght(pbot, prof) ptop = interp.pres(h1 + 6000., prof) if not QC(pbot) or not QC(ptop): pcl.brnshear = RMISSD pcl.brn = RMISSD return pcl # Calculate lowest 500m mean wind p = interp.pres(interp.hght(pbot, prof) + 500., prof) mnlu, mnlv = winds.mean_wind(pbot, p, prof) # Calculate the 6000m mean wind mnuu, mnuv = winds.mean_wind(pbot, ptop, prof) # Make sure CAPE and Shear are available if not QC(pcl.bplus) or not QC(mnlu) or not QC(mnuu): pcl.brnshear = RMISSD pcl.brn = RMISSD return pcl # Calculate shear between levels dx = mnuu - mnlu dy = mnuv - mnlv pcl.brnshear = KTS2MS(vector.comp2vec(dx, dy)[1]) pcl.brnshear = pcl.brnshear**2 / 2. pcl.brn = pcl.bplus / pcl.brnshear return pcl
def vec(p, prof): ''' Interpolates the given component data to a given pressure level and returns the interpolated direction and speed Inputs ------ p (float) Pressure (hPa) of a level prof (profile object) Profile object Returns ------- dir (float) Direction mag (float) Magnitude ''' u = interp_from_pres(p, prof, prof.uind) v = interp_from_pres(p, prof, prof.vind) return vector.comp2vec(u, v)