def calc_hail_prob(t, p, f, z, mask): sze = p[0].size shp = p.shape temp = t.reshape((shp[0], sze)).T geop = z.reshape((shp[0], sze)).T pres = p.reshape((shp[0], sze)).T relh = f.reshape((shp[0], sze)).T i = 0 prob = np.zeros(sze) for tm, gp, pr, rh in zip(temp, geop, pres, relh): wb = calc_tw(tm, pr, rh, method='annfit') wbz = nl.intercep(wb, 273.159, gp)[0] hgr = -1.67e-4 * wbz + 1.0737 k3 = 4.98957134574e-06 * 64.29275512704638 dr1 = (hgr - 0.0001 * wbz) var = np.var(dr1) prob[i] = 100. * np.exp(-dr1**2 / k3) #2.5e-4 if i % 100 == 0: print '%.1f %s' % (100. * i / sze, '%') i += 1 return np.where(mask, prob.reshape(shp[1:]), np.nan).clip(min=25.)
def pbl_stull(tempsn, pressn, relhum, zlevls): # Stull method ... parcel = calc_profile(tempsn, pressn, relhum, method='iterate', kind='it') sfc_parcel_virtual = calc_tv_from_f(parcel, pressn, relhum) sfc_soundg_virtual = calc_tv_from_f(tempsn, pressn, relhum) return nl.intercep(sfc_soundg_virtual, sfc_parcel_virtual, zlevls)
def calc_lcl(t_sfc, p, f_sfc, method='normand'): p_sfc = p[0] if method == 'normand': tdry = calc_t(calc_tp(t_sfc, p_sfc), p) tirm = calc_trm(t_sfc, p, f_sfc) return nl.intercep(tirm, tdry, p, i0=1, item=0) elif method == 'iterate': lcl_pre, lcl_tmp = lcl_iteratively(t_sfc, p_sfc, f_sfc) return lcl_pre[0], lcl_tmp[0]
def pbl_layer_height(t, p, f, u, v, z, zlim=4000.): # user defined height limit (default = 4000.)... ind_lim = z < zlim # using variables just below zlim: zlevls = z[ind_lim] ucompn = u[ind_lim] vcompn = v[ind_lim] tempsn = t[ind_lim] pressn = p[ind_lim] relhum = f[ind_lim] # Calculate virtual potential temperature: esatrn = calc_es(tempsn, pressn, 'fbuck') wvapor = relhum * calc_w_from_e(esatrn, pressn) thetad = calc_tp(tempsn, pressn) thetav = calc_tv_from_w(thetad, wvapor) # calculate Gradient Richardson number RiG = nl.low_pass(calc_gRi(thetav, ucompn, vcompn, zlevls), ipass=10) Rleng = zlevls[np.argsort(RiG)[:-10:-1]] depht = Rleng.max() - Rleng.min() # Truncating h0 = pbl_height_from_profiles(thetad, thetav, pressn, relhum, zlevls, z0=Rleng.min(), z1=Rleng.max()) if len(h0) == 0: return [] else: # Calculate Cloud base and Cloud top: lcl_p, _ = calc_lcl(t[0], p, f[0], method='iterate') cloud_base = nl.intercep(p, lcl_p, z)[0] if h0 > cloud_base: # If h0 is higher than the cloud base, we find the level at wish # the first stable layer is located within the cluod. # calculate equivalent temperature ind_lim = zlevls > cloud_base zlevls = zlevls[ind_lim] pressn = pressn[ind_lim] tempsn = tempsn[ind_lim] thetae = calc_tpe(tempsn, pressn) dthe_dz = nl.calc_derv_ngrid(thetae, zlevls) pbl_height = zlevls[dthe_dz > 0.0][0] else: pbl_height = h0[0] return depht, pbl_height
def calc_eql(t, parcel, p): # # Find Level of Equilibrium # return nl.intercep(t, parcel, p, item=-1)
def calc_lfc(t, parcel, p): # # Find Level of free conversion # return nl.intercep(t, parcel, p, d='all', i0=1, item=0)
def calc_ccl(t, p, f_sfc): # # Find Convertive Level for heated parcel # t_sfc = t[0] return nl.intercep(calc_trm(t_sfc, p, f_sfc), t, p, d='all')