def read_merra2(domain,times,pres=True,delta_t=1): #Read 3-hourly MERRA2 pressure level/surface data if len(times) > 1: date_list = date_seq(times,"hours",delta_t) else: date_list = times files_3d = []; files_2d = [] for d in date_list: files_3d.append(glob.glob("/g/data/rr7/MERRA2/raw/M2I3NPASM.5.12.4/"+d.strftime("%Y")+"/"+d.strftime("%m")+"/MERRA2*"+d.strftime("%Y%m%d")+"*.nc4")[0]) files_2d.append(glob.glob("/g/data/ua8/MERRA2/1hr/M2I1NXASM.5.12.4/"+d.strftime("%Y")+"/"+d.strftime("%m")+"/MERRA2*"+d.strftime("%Y%m%d")+"*.nc4")[0]) files_3d = np.unique(files_3d) files_2d = np.unique(files_2d) f3d = xr.open_mfdataset(files_3d, combine="by_coords").sel({"time":date_list, "lev":slice(1000,100), "lon":slice(domain[2], domain[3]), "lat":slice(domain[0], domain[1])}) f2d = xr.open_mfdataset(files_2d, combine="by_coords").sel({"time":date_list, "lon":slice(domain[2], domain[3]), "lat":slice(domain[0], domain[1])}) ta_file = f3d["T"]; z_file = f3d["H"]; ua_file = f3d["U"]; va_file = f3d["V"]; hur_file = f3d["RH"] uas_file = f2d["U10M"]; vas_file = f2d["V10M"]; hus_file = f2d["QV2M"]; tas_file = f2d["T2M"]; ps_file = f2d["PS"] ta = ta_file.values - 273.15 ua = ua_file.values va = va_file.values hgt = z_file.values hur = hur_file.values * 100 hur[hur<0] = 0 hur[hur>100] = 100 dp = get_dp(ta,hur) uas = uas_file.values vas = vas_file.values tas = tas_file.values - 273.15 ps = ps_file.values / 100 ta2d = np.array(mpcalc.dewpoint_from_specific_humidity(hus_file.values, tas*units.units.degC, \ ps*units.units.hectopascal)) terrain = f3d["PHIS"].isel({"time":0}).values / 9.8 lon = f2d["lon"].values lat = f2d["lat"].values p = f3d["lev"].values return [ta,dp,hur,hgt,terrain,p,ps,ua,va,uas,vas,tas,ta2d,lon,lat,date_list]
def append_tq(): #Load each ERA-Interim sa_small netcdf file, and append cape*s06^1.67 start_lat = -44.525 end_lat = -9.975 start_lon = 111.975 end_lon = 156.275 domain = [start_lat, end_lat, start_lon, end_lon] model = "erai" region = "aus" dates = [] for y in np.arange(1980, 2019): for m in [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12]: if (m != 12): dates.append([dt.datetime(y,m,1,0,0,0),\ dt.datetime(y,m+1,1,0,0,0)-dt.timedelta(hours = 6)]) else: dates.append([dt.datetime(y,m,1,0,0,0),\ dt.datetime(y+1,1,1,0,0,0)-dt.timedelta(hours = 6)]) for t in np.arange(0, len(dates)): print(str(dates[t][0]) + " - " + str(dates[t][1])) fname = "/g/data/eg3/ab4502/ExtremeWind/"+region+"/"+model+"/"+model+"_"+\ dt.datetime.strftime(dates[t][0],"%Y%m%d")+"_"+\ dt.datetime.strftime(dates[t][-1],"%Y%m%d")+".nc" ta,dp,hur,hgt,terrain,p,ps,wap,ua,va,uas,vas,tas,ta2d,cp,wg10,cape,lon,lat,date_list = \ read_erai(domain,dates[t]) dp = get_dp(ta, hur, dp_mask=False) param_file = nc.Dataset(fname, "a") tq_var = param_file.createVariable("tq",float,\ ("time","lat","lon")) tq_var.units = "" tq_var.long_name = "tq" tq_var[:] = ta[:,np.where(p==850)[0][0],:,:] + dp[:,np.where(p==850)[0][0],:,:] - \ 1.7*ta[:,np.where(p==700)[0][0],:,:] param_file.close()
def main(): load_start = dt.datetime.now() #Try parsing arguments using argparse parser = argparse.ArgumentParser(description='wrf non-parallel convective diagnostics processer') parser.add_argument("-m",help="Model name",required=True) parser.add_argument("-r",help="Region name (default is aus)",default="aus") parser.add_argument("-t1",help="Time start YYYYMMDDHH",required=True) parser.add_argument("-t2",help="Time end YYYYMMDDHH",required=True) parser.add_argument("-e", help="CMIP5 experiment name (not required if using era5, erai or barra)", default="") parser.add_argument("--ens", help="CMIP5 ensemble name (not required if using era5, erai or barra)", default="r1i1p1") parser.add_argument("--group", help="CMIP6 modelling group name", default="") parser.add_argument("--project", help="CMIP6 modelling intercomparison project", default="CMIP") parser.add_argument("--ver6hr", help="Version on al33 for 6hr data", default="") parser.add_argument("--ver3hr", help="Version on al33 for 3hr data", default="") parser.add_argument("--issave",help="Save output (True or False, default is False)", default="False") parser.add_argument("--outname",help="Name of saved output. In the form *outname*_*t1*_*t2*.nc. Default behaviour is the model name",default=None) parser.add_argument("--al33",help="Should data be gathered from al33? Default is False, and data is gathered from r87. If True, then group is required",default="False") args = parser.parse_args() #Parse arguments from cmd line and set up inputs (date region model) model = args.m region = args.r t1 = args.t1 t2 = args.t2 issave = args.issave al33 = args.al33 if args.outname==None: out_name = model else: out_name = args.outname experiment = args.e ensemble = args.ens group = args.group project = args.project ver6hr = args.ver6hr ver3hr = args.ver3hr if region == "sa_small": start_lat = -38; end_lat = -26; start_lon = 132; end_lon = 142 elif region == "aus": start_lat = -44.525; end_lat = -9.975; start_lon = 111.975; end_lon = 156.275 elif region == "global": start_lat = -70; end_lat = 70; start_lon = -180; end_lon = 179.75 else: raise ValueError("INVALID REGION\n") domain = [start_lat,end_lat,start_lon,end_lon] try: time = [dt.datetime.strptime(t1,"%Y%m%d%H"),dt.datetime.strptime(t2,"%Y%m%d%H")] except: raise ValueError("INVALID START OR END TIME. SHOULD BE YYYYMMDDHH\n") if issave=="True": issave = True elif issave=="False": issave = False else: raise ValueError("\n INVALID ISSAVE...SHOULD BE True OR False") if al33=="True": al33 = True elif al33=="False": al33 = False else: raise ValueError("\n INVALID al33...SHOULD BE True OR False") #Load data print("LOADING DATA...") if model in ["ACCESS1-0","ACCESS1-3","GFDL-CM3","GFDL-ESM2M","CNRM-CM5","MIROC5",\ "MRI-CGCM3","IPSL-CM5A-LR","IPSL-CM5A-MR","GFDL-ESM2G","bcc-csm1-1","MIROC-ESM",\ "BNU-ESM"]: #Check that t1 and t2 are in the same year year = np.arange(int(t1[0:4]), int(t2[0:4])+1) ta, hur, hgt, terrain, p_3d, ps, ua, va, uas, vas, tas, ta2d, tp, lon, lat, \ date_list = read_cmip(model, experiment, \ ensemble, year, domain, cmip_ver=5, al33=al33, group=group, ver6hr=ver6hr, ver3hr=ver3hr) p = np.zeros(p_3d[0,:,0,0].shape) tp = tp.astype("float32", order="C") elif model in ["ACCESS-ESM1-5", "ACCESS-CM2"]: year = np.arange(int(t1[0:4]), int(t2[0:4])+1) ta, hur, hgt, terrain, p_3d, ps, ua, va, uas, vas, tas, ta2d, lon, lat, \ date_list = read_cmip(model, experiment,\ ensemble, year, domain, cmip_ver=6, group=group, project=project) p = np.zeros(p_3d[0,:,0,0].shape) else: raise ValueError("Model not recognised") ta = ta.astype("float32", order="C") hur = hur.astype("float32", order="C") hgt = hgt.astype("float32", order="C") terrain = terrain.astype("float32", order="C") p = p.astype("float32", order="C") ps = ps.astype("float32", order="C") ua = ua.astype("float32", order="C") va = va.astype("float32", order="C") uas = uas.astype("float32", order="C") vas = vas.astype("float32", order="C") tas= tas.astype("float32", order="C") ta2d = ta2d.astype("float32", order="C") lon = lon.astype("float32", order="C") lat = lat.astype("float32", order="C") gc.collect() #This param list was originally given to AD for ERA5 global lightning report #param = np.array(["mu_cape", "eff_cape","ncape","mu_cin", "muq", "s06", "s0500", "lr700_500", "mhgt", "ta500","tp","cp","laplacian","t_totals"]) #This param list is intended for application to GCMs based on AD ERA5 lightning report param = np.array(["mu_cape","s06","laplacian","t_totals","ta850","ta500","dp850","tp",\ "muq","lr700_500","mhgt","z500"]) #Set output array output_data = np.zeros((ps.shape[0], ps.shape[1], ps.shape[2], len(param))) #Assign p levels to a 3d array, with same dimensions as input variables (ta, hgt, etc.) #If the 3d p-lvl array already exists, then declare the variable "mdl_lvl" as true. try: p_3d; mdl_lvl = True full_p3d = p_3d except: mdl_lvl = False p_3d = np.moveaxis(np.tile(p,[ta.shape[2],ta.shape[3],1]),[0,1,2],[1,2,0]).\ astype(np.float32) print("LOAD TIME..."+str(dt.datetime.now()-load_start)) tot_start = dt.datetime.now() for t in np.arange(0,ta.shape[0]): output = np.zeros((1, ps.shape[1], ps.shape[2], len(param))) cape_start = dt.datetime.now() print(date_list[t]) if mdl_lvl: p_3d = full_p3d[t] dp = get_dp(hur=hur[t], ta=ta[t], dp_mask = False) #Insert surface arrays, creating new arrays with "sfc" prefix sfc_ta = np.insert(ta[t], 0, tas[t], axis=0) sfc_hgt = np.insert(hgt[t], 0, terrain, axis=0) sfc_dp = np.insert(dp, 0, ta2d[t], axis=0) sfc_p_3d = np.insert(p_3d, 0, ps[t], axis=0) sfc_ua = np.insert(ua[t], 0, uas[t], axis=0) sfc_va = np.insert(va[t], 0, vas[t], axis=0) #Sort by ascending p a,temp1,temp2 = np.meshgrid(np.arange(sfc_p_3d.shape[0]) , np.arange(sfc_p_3d.shape[1]),\ np.arange(sfc_p_3d.shape[2])) sort_inds = np.flip(np.lexsort([np.swapaxes(a,1,0),sfc_p_3d],axis=0), axis=0) sfc_hgt = np.take_along_axis(sfc_hgt, sort_inds, axis=0) sfc_dp = np.take_along_axis(sfc_dp, sort_inds, axis=0) sfc_p_3d = np.take_along_axis(sfc_p_3d, sort_inds, axis=0) sfc_ua = np.take_along_axis(sfc_ua, sort_inds, axis=0) sfc_va = np.take_along_axis(sfc_va, sort_inds, axis=0) sfc_ta = np.take_along_axis(sfc_ta, sort_inds, axis=0) #Calculate q and wet bulb for pressure level arrays with surface values sfc_ta_unit = units.units.degC*sfc_ta sfc_dp_unit = units.units.degC*sfc_dp sfc_p_unit = units.units.hectopascals*sfc_p_3d sfc_hur_unit = mpcalc.relative_humidity_from_dewpoint(sfc_ta_unit, sfc_dp_unit)*\ 100*units.units.percent sfc_q_unit = mpcalc.mixing_ratio_from_relative_humidity(sfc_hur_unit,\ sfc_ta_unit,sfc_p_unit) sfc_q = np.array(sfc_q_unit) #Now get most-unstable CAPE (max CAPE in vertical, ensuring parcels used are AGL) cape3d = wrf.cape_3d(sfc_p_3d,sfc_ta+273.15,\ sfc_q,sfc_hgt,\ terrain,ps[t],\ True,meta=False, missing=0) cape = cape3d.data[0] cin = cape3d.data[1] lfc = cape3d.data[2] lcl = cape3d.data[3] el = cape3d.data[4] #Mask values which are below the surface and above 350 hPa AGL cape[(sfc_p_3d > ps[t]) | (sfc_p_3d<(ps[t]-350))] = np.nan cin[(sfc_p_3d > ps[t]) | (sfc_p_3d<(ps[t]-350))] = np.nan lfc[(sfc_p_3d > ps[t]) | (sfc_p_3d<(ps[t]-350))] = np.nan lcl[(sfc_p_3d > ps[t]) | (sfc_p_3d<(ps[t]-350))] = np.nan el[(sfc_p_3d > ps[t]) | (sfc_p_3d<(ps[t]-350))] = np.nan #Get maximum (in the vertical), and get cin, lfc, lcl for the same parcel mu_cape_inds = np.tile(np.nanargmax(cape,axis=0), (cape.shape[0],1,1)) mu_cape = np.take_along_axis(cape, mu_cape_inds, 0)[0] muq = np.take_along_axis(sfc_q, mu_cape_inds, 0)[0] * 1000 #Calculate other parameters #Thermo thermo_start = dt.datetime.now() lr700_500 = get_lr_p(ta[t], p_3d, hgt[t], 700, 500) melting_hgt = get_t_hgt(sfc_ta,np.copy(sfc_hgt),0,terrain) melting_hgt = np.where((melting_hgt < 0) | (np.isnan(melting_hgt)), 0, melting_hgt) ta500 = get_var_p_lvl(np.copy(sfc_ta), sfc_p_3d, 500) ta850 = get_var_p_lvl(np.copy(sfc_ta), sfc_p_3d, 850) dp850 = get_var_p_lvl(np.copy(sfc_dp), sfc_p_3d, 850) v_totals = ta850 - ta500 c_totals = dp850 - ta500 t_totals = v_totals + c_totals #Winds winds_start = dt.datetime.now() s06 = get_shear_hgt(sfc_ua, sfc_va, np.copy(sfc_hgt), 0, 6000, terrain) #Laplacian x, y = np.meshgrid(lon,lat) dx, dy = mpcalc.lat_lon_grid_deltas(x,y) if mdl_lvl: z500 = get_var_p_lvl(hgt[t], p_3d, 500) laplacian = np.array(mpcalc.laplacian(z500,deltas=[dy,dx])*1e9) else: z500 = np.squeeze(hgt[t,p==500]) laplacian = np.array(mpcalc.laplacian(uniform_filter(z500, 4),deltas=[dy,dx])*1e9) #Fill output output = fill_output(output, t, param, ps, "mu_cape", mu_cape) output = fill_output(output, t, param, ps, "muq", muq) output = fill_output(output, t, param, ps, "s06", s06) output = fill_output(output, t, param, ps, "lr700_500", lr700_500) output = fill_output(output, t, param, ps, "ta500", ta500) output = fill_output(output, t, param, ps, "ta850", ta850) output = fill_output(output, t, param, ps, "dp850", dp850) output = fill_output(output, t, param, ps, "mhgt", melting_hgt) output = fill_output(output, t, param, ps, "tp", tp[t]) output = fill_output(output, t, param, ps, "laplacian", laplacian) output = fill_output(output, t, param, ps, "t_totals", t_totals) output = fill_output(output, t, param, ps, "z500", z500) output_data[t] = output print("SAVING DATA...") param_out = [] for param_name in param: temp_data = output_data[:,:,:,np.where(param==param_name)[0][0]] param_out.append(temp_data) #If the mhgt variable is zero everywhere, then it is likely that data has not been read. #In this case, all values are missing, set to zero. for t in np.arange(param_out[0].shape[0]): if param_out[np.where(param=="mhgt")[0][0]][t].max() == 0: for p in np.arange(len(param_out)): param_out[p][t] = np.nan if issave: save_netcdf(region, model, out_name, date_list, lat, lon, param, param_out, \ out_dtype = "f4", compress=True) print(dt.datetime.now() - tot_start)
def read_erai_points(points,times): #Open ERA-Interim netcdf files and extract variables needed for a range of # times at a given set of spatial points #Format dates and times ref = dt.datetime(1900,1,1,0,0,0) date_list = date_seq(times,"hours",6) formatted_dates = [format_dates(x) for x in date_list] unique_dates = np.unique(formatted_dates) time_hours = np.empty(len(date_list)) for t in np.arange(0,len(date_list)): time_hours[t] = (date_list[t] - ref).total_seconds() / (3600) #Get time-invariant pressure and spatial info no_p, pres, p_ind = get_pressure(100) lon,lat = get_lat_lon() [lon_ind, lat_ind, lon_used, lat_used] = get_lat_lon_inds(points,lon,lat) terrain_new = reform_terrain(lon,lat) #Initialise arrays for each variable ta = np.empty((len(date_list),no_p,len(points))) dp = np.empty((len(date_list),no_p,len(points))) hur = np.empty((len(date_list),no_p,len(points))) hgt = np.empty((len(date_list),no_p,len(points))) p = np.empty((len(date_list),no_p,len(points))) ua = np.empty((len(date_list),no_p,len(points))) va = np.empty((len(date_list),no_p,len(points))) uas = np.empty((len(date_list),len(points))) vas = np.empty((len(date_list),len(points))) ps = np.empty((len(date_list),len(points))) for date in unique_dates: print(date) #Load ERA-Interim reanalysis files ta_file = nc.Dataset(glob.glob("/g/data/ub4/erai/netcdf/6hr/atmos/oper_an_pl/v01/ta/\ ta_6hrs_ERAI_historical_an-pl_"+date+"*.nc")[0]) z_file = nc.Dataset(glob.glob("/g/data/ub4/erai/netcdf/6hr/atmos/oper_an_pl/v01/z/\ z_6hrs_ERAI_historical_an-pl_"+date+"*.nc")[0]) ua_file = nc.Dataset(glob.glob("/g/data/ub4/erai/netcdf/6hr/atmos/oper_an_pl/v01/ua/\ ua_6hrs_ERAI_historical_an-pl_"+date+"*.nc")[0]) va_file = nc.Dataset(glob.glob("/g/data/ub4/erai/netcdf/6hr/atmos/oper_an_pl/v01/va/\ va_6hrs_ERAI_historical_an-pl_"+date+"*.nc")[0]) hur_file = nc.Dataset(glob.glob("/g/data/ub4/erai/netcdf/6hr/atmos/oper_an_pl/v01/hur/\ hur_6hrs_ERAI_historical_an-pl_"+date+"*.nc")[0]) uas_file = nc.Dataset(glob.glob("/g/data/ub4/erai/netcdf/6hr/atmos/oper_an_sfc/v01/uas/\ uas_6hrs_ERAI_historical_an-sfc_"+date+"*.nc")[0]) vas_file = nc.Dataset(glob.glob("/g/data/ub4/erai/netcdf/6hr/atmos/oper_an_sfc/v01/vas/\ vas_6hrs_ERAI_historical_an-sfc_"+date+"*.nc")[0]) ps_file = nc.Dataset(glob.glob("/g/data/ub4/erai/netcdf/6hr/atmos/oper_an_sfc/v01/ps/\ ps_6hrs_ERAI_historical_an-sfc_"+date+"*.nc")[0]) #Get times to load in from file times = ta_file["time"][:] time_ind = [np.where(x==times)[0][0] for x in time_hours if (x in times)] date_ind = np.where(np.array(formatted_dates) == date)[0] #Load data for each spatial point given to function for point in np.arange(0,len(points)): ta[date_ind,:,point] = ta_file["ta"][time_ind,p_ind,lat_ind[point]\ ,lon_ind[point]] - 273.15 ua[date_ind,:,point] = ua_file["ua"][time_ind,p_ind,lat_ind[point]\ ,lon_ind[point]] va[date_ind,:,point] = va_file["va"][time_ind,p_ind,lat_ind[point]\ ,lon_ind[point]] hgt[date_ind,:,point] = z_file["z"][time_ind,p_ind,lat_ind[point]\ ,lon_ind[point]] / 9.8 hur[date_ind,:,point] = hur_file["hur"][time_ind,p_ind,lat_ind[point]\ ,lon_ind[point]] hur[hur<0] = 0 dp[date_ind,:,point] = get_dp(ta[date_ind,:,point],hur[date_ind,:,point]) uas[date_ind,point] = uas_file["uas"][time_ind,lat_ind[point]\ ,lon_ind[point]] vas[date_ind,point] = vas_file["vas"][time_ind,lat_ind[point]\ ,lon_ind[point]] ps[date_ind,point] = ps_file["ps"][time_ind,lat_ind[point]\ ,lon_ind[point]] /100 p[date_ind,:,point] = pres[p_ind] ta_file.close();z_file.close();ua_file.close();va_file.close();hur_file.close();uas_file.close();vas_file.close();ps_file.close() #Save lat/lon as array lon = np.empty((len(points))) lat = np.empty((len(points))) terrain = np.empty((len(points))) for point in np.arange(0,len(points)): lon[point] = points[point][0] lat[point] = points[point][1] terrain[point] = terrain_new[lat_ind[point],lon_ind[point]] return [ta,dp,hur,hgt,terrain,p,ps,ua,va,uas,vas,lon,lat,lon_used,lat_used,date_list]
def read_erai(domain,times): #Open ERA-Interim netcdf files and extract variables needed for a range of times # and given spatial domain #Option to also use one time (include hour) ref = dt.datetime(1900,1,1,0,0,0) if len(times) > 1: date_list = date_seq(times,"hours",6) else: date_list = times formatted_dates = [format_dates(x) for x in date_list] unique_dates = np.unique(formatted_dates) time_hours = np.empty(len(date_list)) for t in np.arange(0,len(date_list)): time_hours[t] = (date_list[t] - ref).total_seconds() / (3600) if (date_list[0].day==1) & (date_list[0].hour<3): fc_unique_dates = np.insert(unique_dates, 0, format_dates(date_list[0] - dt.timedelta(1))) else: fc_unique_dates = np.copy(unique_dates) #Get time-invariant pressure and spatial info no_p, p, p_ind = get_pressure(100) p = p[p_ind] lon,lat = get_lat_lon() lon_ind = np.where((lon >= domain[2]) & (lon <= domain[3]))[0] lat_ind = np.where((lat >= domain[0]) & (lat <= domain[1]))[0] lon = lon[lon_ind] lat = lat[lat_ind] terrain = reform_terrain(lon,lat) #Initialise arrays for each variable ta = np.empty((len(date_list),no_p,len(lat_ind),len(lon_ind))) dp = np.empty((len(date_list),no_p,len(lat_ind),len(lon_ind))) hur = np.empty((len(date_list),no_p,len(lat_ind),len(lon_ind))) hgt = np.empty((len(date_list),no_p,len(lat_ind),len(lon_ind))) ua = np.empty((len(date_list),no_p,len(lat_ind),len(lon_ind))) va = np.empty((len(date_list),no_p,len(lat_ind),len(lon_ind))) wap = np.empty((len(date_list),no_p,len(lat_ind),len(lon_ind))) uas = np.empty((len(date_list),len(lat_ind),len(lon_ind))) vas = np.empty((len(date_list),len(lat_ind),len(lon_ind))) ps = np.empty((len(date_list),len(lat_ind),len(lon_ind))) cp = np.zeros(ps.shape) * np.nan tp = np.zeros(ps.shape) * np.nan cape = np.zeros(ps.shape) * np.nan wg10 = np.zeros(ps.shape) * np.nan tas = np.empty((len(date_list),len(lat_ind),len(lon_ind))) ta2d = np.empty((len(date_list),len(lat_ind),len(lon_ind))) for date in unique_dates: #Load ERA-Interim reanalysis files ta_file = nc.Dataset(glob.glob("/g/data/ub4/erai/netcdf/6hr/atmos/oper_an_pl/v01/ta/\ ta_6hrs_ERAI_historical_an-pl_"+date+"*.nc")[0]) z_file = nc.Dataset(glob.glob("/g/data/ub4/erai/netcdf/6hr/atmos/oper_an_pl/v01/z/\ z_6hrs_ERAI_historical_an-pl_"+date+"*.nc")[0]) wap_file = nc.Dataset(glob.glob("/g/data/ub4/erai/netcdf/6hr/atmos/oper_an_pl/v01/wap/\ wap_6hrs_ERAI_historical_an-pl_"+date+"*.nc")[0]) ua_file = nc.Dataset(glob.glob("/g/data/ub4/erai/netcdf/6hr/atmos/oper_an_pl/v01/ua/\ ua_6hrs_ERAI_historical_an-pl_"+date+"*.nc")[0]) va_file = nc.Dataset(glob.glob("/g/data/ub4/erai/netcdf/6hr/atmos/oper_an_pl/v01/va/\ va_6hrs_ERAI_historical_an-pl_"+date+"*.nc")[0]) hur_file = nc.Dataset(glob.glob("/g/data/ub4/erai/netcdf/6hr/atmos/oper_an_pl/v01/hur/\ hur_6hrs_ERAI_historical_an-pl_"+date+"*.nc")[0]) uas_file = nc.Dataset(glob.glob("/g/data/ub4/erai/netcdf/6hr/atmos/oper_an_sfc/v01/uas/\ uas_6hrs_ERAI_historical_an-sfc_"+date+"*.nc")[0]) vas_file = nc.Dataset(glob.glob("/g/data/ub4/erai/netcdf/6hr/atmos/oper_an_sfc/v01/vas/\ vas_6hrs_ERAI_historical_an-sfc_"+date+"*.nc")[0]) ta2d_file = nc.Dataset(glob.glob("/g/data/ub4/erai/netcdf/6hr/atmos/oper_an_sfc/v01/ta2d/\ ta2d_6hrs_ERAI_historical_an-sfc_"+date+"*.nc")[0]) tas_file = nc.Dataset(glob.glob("/g/data/ub4/erai/netcdf/6hr/atmos/oper_an_sfc/v01/tas/\ tas_6hrs_ERAI_historical_an-sfc_"+date+"*.nc")[0]) ps_file = nc.Dataset(glob.glob("/g/data/ub4/erai/netcdf/6hr/atmos/oper_an_sfc/v01/ps/\ ps_6hrs_ERAI_historical_an-sfc_"+date+"*.nc")[0]) #Get times to load in from file times = ta_file["time"][:] time_ind = [np.where(x==times)[0][0] for x in time_hours if (x in times)] date_ind = np.where(np.array(formatted_dates) == date)[0] #Load analysis data ta[date_ind,:,:,:] = ta_file["ta"][time_ind,p_ind,lat_ind,lon_ind] - 273.15 wap[date_ind,:,:,:] = wap_file["wap"][time_ind,p_ind,lat_ind,lon_ind] ua[date_ind,:,:,:] = ua_file["ua"][time_ind,p_ind,lat_ind,lon_ind] va[date_ind,:,:,:] = va_file["va"][time_ind,p_ind,lat_ind,lon_ind] hgt[date_ind,:,:,:] = z_file["z"][time_ind,p_ind,lat_ind,lon_ind] / 9.8 hur[date_ind,:,:,:] = hur_file["hur"][time_ind,p_ind,lat_ind,lon_ind] hur[hur<0] = 0 hur[hur>100] = 100 dp[date_ind,:,:,:] = get_dp(ta[date_ind,:,:,:],hur[date_ind,:,:,:]) uas[date_ind,:,:] = uas_file["uas"][time_ind,lat_ind,lon_ind] vas[date_ind,:,:] = vas_file["vas"][time_ind,lat_ind,lon_ind] tas[date_ind,:,:] = tas_file["tas"][time_ind,lat_ind,lon_ind] - 273.15 ta2d[date_ind,:,:] = ta2d_file["ta2d"][time_ind,lat_ind,lon_ind] - 273.15 ps[date_ind,:,:] = ps_file["ps"][time_ind,lat_ind,lon_ind] / 100 ta_file.close();z_file.close();ua_file.close();va_file.close();hur_file.close();uas_file.close();vas_file.close();tas_file.close();ta2d_file.close();ps_file.close();wap_file.close() for date in fc_unique_dates: if int(date) >= 197900: tp_file = nc.Dataset(glob.glob("/g/data/ub4/erai/netcdf/3hr/atmos/oper_fc_sfc/v01/tp/"\ +"tp_3hrs_ERAI_historical_fc-sfc_"+date+"*.nc")[0]) cp_file = nc.Dataset(glob.glob("/g/data/ub4/erai/netcdf/3hr/atmos/oper_fc_sfc/v01/cp/"\ +"cp_3hrs_ERAI_historical_fc-sfc_"+date+"*.nc")[0]) cape_file = nc.Dataset(glob.glob("/g/data/ub4/erai/netcdf/3hr/atmos/oper_fc_sfc/v01/cape/"\ +"cape_3hrs_ERAI_historical_fc-sfc_"+date+"*.nc")[0]) wg10_file = nc.Dataset(glob.glob("/g/data/ub4/erai/netcdf/3hr/atmos/oper_fc_sfc/v01/wg10/"\ +"wg10_3hrs_ERAI_historical_fc-sfc_"+date+"*.nc")[0]) #Load forecast data fc_times = nc.num2date(cp_file["time"][:], cp_file["time"].units) #an_times = nc.num2date(ps_file["time"][time_ind], ps_file["time"].units) an_times = date_list fc_cp = cp_file.variables["cp"][:,lat_ind,lon_ind] fc_tp = tp_file.variables["tp"][:,lat_ind,lon_ind] fc_cape = cape_file.variables["cape"][:,lat_ind,lon_ind] fc_wg10 = wg10_file.variables["wg10"][:,lat_ind,lon_ind] cnt = 0 for an_t in an_times: try: fc_ind = np.where(an_t == np.array(fc_times))[0][0] cp[cnt] = ((fc_cp[fc_ind] - fc_cp[fc_ind - 1]) * 1000.) tp[cnt] = ((fc_tp[fc_ind] - fc_tp[fc_ind - 1]) * 1000.) cape[cnt] = (fc_cape[fc_ind]) wg10[cnt] = (fc_wg10[fc_ind]) except: pass cnt = cnt + 1 cp_file.close(); cape_file.close(); wg10_file.close(); tp_file.close() return [ta,dp,hur,hgt,terrain,p,ps,wap,ua,va,uas,vas,tas,ta2d,cp,tp,wg10,cape,lon,lat,date_list]
def read_era5(domain,times,pres=True,delta_t=1): #Open ERA5 netcdf files and extract variables needed for a range of times # and given spatial domain ref = dt.datetime(1900,1,1,0,0,0) if len(times) > 1: date_list = date_seq(times,"hours",delta_t) else: date_list = times formatted_dates = [format_dates(x) for x in date_list] unique_dates = np.unique(formatted_dates) time_hours = np.empty(len(date_list)) for t in np.arange(0,len(date_list)): time_hours[t] = (date_list[t] - ref).total_seconds() / (3600) if (date_list[0].day==1) & (date_list[0].hour<3): fc_unique_dates = np.insert(unique_dates, 0, format_dates(date_list[0] - dt.timedelta(1))) else: fc_unique_dates = np.copy(unique_dates) #Get time-invariant pressure and spatial info no_p, p, p_ind = get_pressure(100) p = p[p_ind] lon,lat = get_lat_lon() lon_ind = np.where((lon >= domain[2]) & (lon <= domain[3]))[0] lat_ind = np.where((lat >= domain[0]) & (lat <= domain[1]))[0] lon = lon[lon_ind] lat = lat[lat_ind] terrain = reform_terrain(lon,lat) sfc_lon,sfc_lat = get_lat_lon_sfc() sfc_lon_ind = np.where((sfc_lon >= domain[2]) & (sfc_lon <= domain[3]))[0] sfc_lat_ind = np.where((sfc_lat >= domain[0]) & (sfc_lat <= domain[1]))[0] sfc_lon = sfc_lon[sfc_lon_ind] sfc_lat = sfc_lat[sfc_lat_ind] #Initialise arrays for each variable if pres: ta = np.empty((len(date_list),no_p,len(lat_ind),len(lon_ind))) dp = np.empty((len(date_list),no_p,len(lat_ind),len(lon_ind))) hur = np.empty((len(date_list),no_p,len(lat_ind),len(lon_ind))) hgt = np.empty((len(date_list),no_p,len(lat_ind),len(lon_ind))) ua = np.empty((len(date_list),no_p,len(lat_ind),len(lon_ind))) va = np.empty((len(date_list),no_p,len(lat_ind),len(lon_ind))) wap = np.empty((len(date_list),no_p,len(lat_ind),len(lon_ind))) uas = np.empty((len(date_list),len(sfc_lat_ind),len(sfc_lon_ind))) vas = np.empty((len(date_list),len(sfc_lat_ind),len(sfc_lon_ind))) ps = np.empty((len(date_list),len(sfc_lat_ind),len(sfc_lon_ind))) cp = np.zeros(ps.shape) * np.nan cape = np.zeros(ps.shape) * np.nan wg10 = np.zeros(ps.shape) * np.nan tas = np.empty((len(date_list),len(sfc_lat_ind),len(sfc_lon_ind))) ta2d = np.empty((len(date_list),len(sfc_lat_ind),len(sfc_lon_ind))) for date in unique_dates: #Load ERA-Interim reanalysis files if pres: ta_file = nc.Dataset(glob.glob("/g/data/ub4/era5/netcdf/pressure/t/"+date[0:4]+\ "/t_era5_aus_"+date+"*.nc")[0]) z_file = nc.Dataset(glob.glob("/g/data/ub4/era5/netcdf/pressure/z/"+date[0:4]+\ "/z_era5_aus_"+date+"*.nc")[0]) ua_file = nc.Dataset(glob.glob("/g/data/ub4/era5/netcdf/pressure/u/"+date[0:4]+\ "/u_era5_aus_"+date+"*.nc")[0]) va_file = nc.Dataset(glob.glob("/g/data/ub4/era5/netcdf/pressure/v/"+date[0:4]+\ "/v_era5_aus_"+date+"*.nc")[0]) hur_file = nc.Dataset(glob.glob("/g/data/ub4/era5/netcdf/pressure/r/"+date[0:4]+\ "/r_era5_aus_"+date+"*.nc")[0]) uas_file = nc.Dataset(glob.glob("/g/data/ub4/era5/netcdf/surface/u10/"+date[0:4]+\ "/u10_era5_global_"+date+"*.nc")[0]) vas_file = nc.Dataset(glob.glob("/g/data/ub4/era5/netcdf/surface/v10/"+date[0:4]+\ "/v10_era5_global_"+date+"*.nc")[0]) ta2d_file = nc.Dataset(glob.glob("/g/data/ub4/era5/netcdf/surface/d2m/"+date[0:4]+\ "/d2m_era5_global_"+date+"*.nc")[0]) tas_file = nc.Dataset(glob.glob("/g/data/ub4/era5/netcdf/surface/t2m/"+date[0:4]+\ "/t2m_era5_global_"+date+"*.nc")[0]) ps_file = nc.Dataset(glob.glob("/g/data/ub4/era5/netcdf/surface/sp/"+date[0:4]+\ "/sp_era5_global_"+date+"*.nc")[0]) cape_file = nc.Dataset(glob.glob("/g/data/ub4/era5/netcdf/surface/cape/"+date[0:4]+\ "/cape_era5_global_"+date+"*.nc")[0]) cp_file = nc.Dataset(glob.glob("/g/data/ub4/era5/netcdf/surface/cp/"+date[0:4]+\ "/cp_era5_global_"+date+"*.nc")[0]) wg10_file = nc.Dataset(glob.glob("/g/data/ub4/era5/netcdf/surface/fg10/"+date[0:4]+\ "/fg10_era5_global_"+date+"*.nc")[0]) #Get times to load in from file if pres: times = ta_file["time"][:] time_ind = [np.where(x==times)[0][0] for x in time_hours if (x in times)] date_ind = np.where(np.array(formatted_dates) == date)[0] else: times = uas_file["time"][:] time_ind = [np.where(x==times)[0][0] for x in time_hours if (x in times)] date_ind = np.where(np.array(formatted_dates) == date)[0] #Get times to load in from forecast files (wg10 and cp) fc_times = cp_file["time"][:] fc_time_ind = [np.where(x==fc_times)[0][0] for x in time_hours if (x in fc_times)] #Load analysis data if pres: ta[date_ind,:,:,:] = ta_file["t"][time_ind,p_ind,lat_ind,lon_ind] - 273.15 #wap[date_ind,:,:,:] = wap_file["wap"][time_ind,p_ind,lat_ind,lon_ind] ua[date_ind,:,:,:] = ua_file["u"][time_ind,p_ind,lat_ind,lon_ind] va[date_ind,:,:,:] = va_file["v"][time_ind,p_ind,lat_ind,lon_ind] hgt[date_ind,:,:,:] = z_file["z"][time_ind,p_ind,lat_ind,lon_ind] / 9.8 hur[date_ind,:,:,:] = hur_file["r"][time_ind,p_ind,lat_ind,lon_ind] hur[hur<0] = 0 hur[hur>100] = 100 dp[date_ind,:,:,:] = get_dp(ta[date_ind,:,:,:],hur[date_ind,:,:,:]) uas[date_ind,:,:] = uas_file["u10"][time_ind,sfc_lat_ind,sfc_lon_ind] vas[date_ind,:,:] = vas_file["v10"][time_ind,sfc_lat_ind,sfc_lon_ind] tas[date_ind,:,:] = tas_file["t2m"][time_ind,sfc_lat_ind,sfc_lon_ind] - 273.15 ta2d[date_ind,:,:] = ta2d_file["d2m"][time_ind,sfc_lat_ind,sfc_lon_ind] - 273.15 ps[date_ind,:,:] = ps_file["sp"][time_ind,sfc_lat_ind,sfc_lon_ind] / 100 fc_date_ind = np.in1d(date_list, nc.num2date(cp_file["time"][fc_time_ind], cp_file["time"].units)) cp[fc_date_ind,:,:] = cp_file["cp"][fc_time_ind,sfc_lat_ind,sfc_lon_ind] cape[fc_date_ind,:,:] = cape_file["cape"][fc_time_ind,sfc_lat_ind,sfc_lon_ind] wg10[fc_date_ind,:,:] = wg10_file["fg10"][fc_time_ind,sfc_lat_ind,sfc_lon_ind] if pres: ta_file.close();z_file.close();ua_file.close();va_file.close();hur_file.close() uas_file.close();vas_file.close();tas_file.close();ta2d_file.close();ps_file.close() if pres: p = np.flip(p) ta = np.flip(ta, axis=1) dp = np.flip(dp, axis=1) hur = np.flip(hur, axis=1) hgt = np.flip(hgt, axis=1) ua = np.flip(ua, axis=1) va = np.flip(va, axis=1) return [ta,dp,hur,hgt,terrain,p,ps,ua,va,uas,vas,tas,ta2d,cp,wg10,cape,lon,lat,date_list] else: return [ps,uas,vas,tas,ta2d,cp,wg10,cape,sfc_lon,sfc_lat,date_list]
def read_era5_cds(pres_path, sfc_path, domain,times,delta_t=1): #Read data downloaded from the ERA5 CDS. Give this function the file paths for the pressure level # and surface level files ref = dt.datetime(1900,1,1,0,0,0) if len(times) > 1: date_list = date_seq(times,"hours",delta_t) else: date_list = times formatted_dates = [format_dates(x) for x in date_list] unique_dates = np.unique(formatted_dates) time_hours = np.empty(len(date_list)) for t in np.arange(0,len(date_list)): time_hours[t] = (date_list[t] - ref).total_seconds() / (3600) if (date_list[0].day==1) & (date_list[0].hour<3): fc_unique_dates = np.insert(unique_dates, 0, format_dates(date_list[0] - dt.timedelta(1))) else: fc_unique_dates = np.copy(unique_dates) #Get time-invariant pressure and spatial info p = xr.open_dataset(pres_path).level.values p_ind = p>=100 p = p[p_ind] no_p = len(p) lon = xr.open_dataset(pres_path).longitude.values lat = xr.open_dataset(pres_path).latitude.values lon_ind = np.where((lon >= domain[2]) & (lon <= domain[3]))[0] lat_ind = np.where((lat >= domain[0]) & (lat <= domain[1]))[0] lon = lon[lon_ind] lat = lat[lat_ind] sfc_lon = xr.open_dataset(sfc_path).longitude.values sfc_lat = xr.open_dataset(sfc_path).latitude.values sfc_lon_ind = np.where((sfc_lon >= domain[2]) & (sfc_lon <= domain[3]))[0] sfc_lat_ind = np.where((sfc_lat >= domain[0]) & (sfc_lat <= domain[1]))[0] sfc_lon = sfc_lon[sfc_lon_ind] sfc_lat = sfc_lat[sfc_lat_ind] #Initialise arrays for each variable ta = np.empty((len(date_list),no_p,len(lat_ind),len(lon_ind))) dp = np.empty((len(date_list),no_p,len(lat_ind),len(lon_ind))) hur = np.empty((len(date_list),no_p,len(lat_ind),len(lon_ind))) hgt = np.empty((len(date_list),no_p,len(lat_ind),len(lon_ind))) ua = np.empty((len(date_list),no_p,len(lat_ind),len(lon_ind))) va = np.empty((len(date_list),no_p,len(lat_ind),len(lon_ind))) wap = np.empty((len(date_list),no_p,len(lat_ind),len(lon_ind))) uas = np.empty((len(date_list),len(sfc_lat_ind),len(sfc_lon_ind))) vas = np.empty((len(date_list),len(sfc_lat_ind),len(sfc_lon_ind))) ps = np.empty((len(date_list),len(sfc_lat_ind),len(sfc_lon_ind))) cp = np.zeros(ps.shape) * np.nan tp = np.zeros(ps.shape) * np.nan cape = np.zeros(ps.shape) * np.nan wg10 = np.zeros(ps.shape) * np.nan tas = np.empty((len(date_list),len(sfc_lat_ind),len(sfc_lon_ind))) ta2d = np.empty((len(date_list),len(sfc_lat_ind),len(sfc_lon_ind))) for date in unique_dates: #Load ERA-Interim reanalysis files pres_file = nc.Dataset(pres_path) sfc_file = nc.Dataset(sfc_path) cp_file = xr.open_dataset(sfc_path).isel({"longitude":sfc_lon_ind, "latitude":sfc_lat_ind})\ .resample(indexer={"time":str(delta_t)+"H"},\ label="right",closed="right").sum("time")["cp"][1:,:,:] tp_file = xr.open_dataset(sfc_path).isel({"longitude":sfc_lon_ind, "latitude":sfc_lat_ind})\ .resample(indexer={"time":str(delta_t)+"H"},\ label="right",closed="right").sum("time")["tp"][1:,:,:] #Get times to load in from file times = pres_file["time"][:] time_ind = [np.where(x==times)[0][0] for x in time_hours if (x in times)] date_ind = np.where(np.array(formatted_dates) == date)[0] #Get times to load in from forecast files (wg10) fc_times = sfc_file["time"][:] fc_time_ind = [np.where(x==fc_times)[0][0] for x in time_hours if (x in fc_times)] #Get times to load in from precip files (tp) tp_time_ind = np.in1d(tp_file.time, [np.datetime64(date_list[i]) for i in np.arange(len(date_list))]) #Load analysis data ta[date_ind,:,:,:] = pres_file["t"][time_ind,p_ind,lat_ind,lon_ind] - 273.15 ua[date_ind,:,:,:] = pres_file["u"][time_ind,p_ind,lat_ind,lon_ind] va[date_ind,:,:,:] = pres_file["v"][time_ind,p_ind,lat_ind,lon_ind] hgt[date_ind,:,:,:] = pres_file["z"][time_ind,p_ind,lat_ind,lon_ind] / 9.8 hur[date_ind,:,:,:] = pres_file["r"][time_ind,p_ind,lat_ind,lon_ind] hur[hur<0] = 0 hur[hur>100] = 100 dp[date_ind,:,:,:] = get_dp(ta[date_ind,:,:,:],hur[date_ind,:,:,:]) uas[date_ind,:,:] = sfc_file["u10"][time_ind,sfc_lat_ind,sfc_lon_ind] vas[date_ind,:,:] = sfc_file["v10"][time_ind,sfc_lat_ind,sfc_lon_ind] tas[date_ind,:,:] = sfc_file["t2m"][time_ind,sfc_lat_ind,sfc_lon_ind] - 273.15 ta2d[date_ind,:,:] = sfc_file["d2m"][time_ind,sfc_lat_ind,sfc_lon_ind] - 273.15 ps[date_ind,:,:] = sfc_file["sp"][time_ind,sfc_lat_ind,sfc_lon_ind] / 100 fc_date_ind = np.in1d(date_list, nc.num2date(sfc_file["time"][fc_time_ind], sfc_file["time"].units)) tp_date_ind = np.in1d([np.datetime64(date_list[i]) for i in np.arange(len(date_list))],tp_file.time.values) cp[tp_date_ind,:,:] = cp_file.isel({"time":tp_time_ind}).values * 1000 tp[tp_date_ind,:,:] = tp_file.isel({"time":tp_time_ind}).values * 1000 cape[fc_date_ind,:,:] = sfc_file["cape"][fc_time_ind,sfc_lat_ind,sfc_lon_ind] wg10[fc_date_ind,:,:] = sfc_file["fg10"][fc_time_ind,sfc_lat_ind,sfc_lon_ind] terrain = sfc_file["z"][0,sfc_lat_ind,sfc_lon_ind] / 9.8 tp_file.close(); cp_file.close(); sfc_file.close(); pres_file.close() p = np.flip(p) ta = np.flip(ta, axis=1) dp = np.flip(dp, axis=1) hur = np.flip(hur, axis=1) hgt = np.flip(hgt, axis=1) ua = np.flip(ua, axis=1) va = np.flip(va, axis=1) return [ta,dp,hur,hgt,terrain,p,ps,ua,va,uas,vas,tas,ta2d,cp,tp,wg10,cape,lon,lat,date_list]
def read_era5_rt52(domain,times,pres=True,delta_t=1): #Open ERA5 netcdf files and extract variables needed for a range of times # and given spatial domain ref = dt.datetime(1900,1,1,0,0,0) if len(times) > 1: date_list = date_seq(times,"hours",delta_t) else: date_list = times formatted_dates = [format_dates(x) for x in date_list] unique_dates = np.unique(formatted_dates) time_hours = np.empty(len(date_list)) for t in np.arange(0,len(date_list)): time_hours[t] = (date_list[t] - ref).total_seconds() / (3600) if (date_list[0].day==1) & (date_list[0].hour<3): fc_unique_dates = np.insert(unique_dates, 0, format_dates(date_list[0] - dt.timedelta(1))) else: fc_unique_dates = np.copy(unique_dates) #Get time-invariant pressure and spatial info no_p, p, p_ind = get_pressure(100) p = p[p_ind] lon,lat = get_lat_lon_rt52() lon_ind = np.where((lon >= domain[2]) & (lon <= domain[3]))[0] lat_ind = np.where((lat >= domain[0]) & (lat <= domain[1]))[0] lon = lon[lon_ind] lat = lat[lat_ind] terrain = reform_terrain(lon,lat) sfc_lon,sfc_lat = get_lat_lon_sfc() sfc_lon_ind = np.where((sfc_lon >= domain[2]) & (sfc_lon <= domain[3]))[0] sfc_lat_ind = np.where((sfc_lat >= domain[0]) & (sfc_lat <= domain[1]))[0] sfc_lon = sfc_lon[sfc_lon_ind] sfc_lat = sfc_lat[sfc_lat_ind] #Initialise arrays for each variable if pres: ta = np.empty((len(date_list),no_p,len(lat_ind),len(lon_ind))) dp = np.empty((len(date_list),no_p,len(lat_ind),len(lon_ind))) hur = np.empty((len(date_list),no_p,len(lat_ind),len(lon_ind))) hgt = np.empty((len(date_list),no_p,len(lat_ind),len(lon_ind))) ua = np.empty((len(date_list),no_p,len(lat_ind),len(lon_ind))) va = np.empty((len(date_list),no_p,len(lat_ind),len(lon_ind))) wap = np.empty((len(date_list),no_p,len(lat_ind),len(lon_ind))) uas = np.empty((len(date_list),len(sfc_lat_ind),len(sfc_lon_ind))) vas = np.empty((len(date_list),len(sfc_lat_ind),len(sfc_lon_ind))) sst = np.empty((len(date_list),len(sfc_lat_ind),len(sfc_lon_ind))) ps = np.empty((len(date_list),len(sfc_lat_ind),len(sfc_lon_ind))) cp = np.zeros(ps.shape) * np.nan tp = np.zeros(ps.shape) * np.nan cape = np.zeros(ps.shape) * np.nan wg10 = np.zeros(ps.shape) * np.nan tas = np.empty((len(date_list),len(sfc_lat_ind),len(sfc_lon_ind))) ta2d = np.empty((len(date_list),len(sfc_lat_ind),len(sfc_lon_ind))) for date in unique_dates: #Load ERA-Interim reanalysis files if pres: ta_file = nc.Dataset(glob.glob("/g/data/rt52/era5/pressure-levels/reanalysis/t/"+date[0:4]+\ "/t_era5_oper_pl_"+date+"*.nc")[0]) z_file = nc.Dataset(glob.glob("/g/data/rt52/era5/pressure-levels/reanalysis/z/"+date[0:4]+\ "/z_era5_oper_pl_"+date+"*.nc")[0]) ua_file = nc.Dataset(glob.glob("/g/data/rt52/era5/pressure-levels/reanalysis/u/"+date[0:4]+\ "/u_era5_oper_pl_"+date+"*.nc")[0]) va_file = nc.Dataset(glob.glob("/g/data/rt52/era5/pressure-levels/reanalysis/v/"+date[0:4]+\ "/v_era5_oper_pl_"+date+"*.nc")[0]) hur_file = nc.Dataset(glob.glob("/g/data/rt52/era5/pressure-levels/reanalysis/r/"+date[0:4]+\ "/r_era5_oper_pl_"+date+"*.nc")[0]) uas_file = nc.Dataset(glob.glob("/g/data/rt52/era5/single-levels/reanalysis/10u/"+date[0:4]+\ "/10u_era5_oper_sfc_"+date+"*.nc")[0]) vas_file = nc.Dataset(glob.glob("/g/data/rt52/era5/single-levels/reanalysis/10v/"+date[0:4]+\ "/10v_era5_oper_sfc_"+date+"*.nc")[0]) sst_file = nc.Dataset(glob.glob("/g/data/rt52/era5/single-levels/reanalysis/sst/"+date[0:4]+\ "/sst_era5_oper_sfc_"+date+"*.nc")[0]) ta2d_file = nc.Dataset(glob.glob("/g/data/rt52/era5/single-levels/reanalysis/2d/"+date[0:4]+\ "/2d_era5_oper_sfc_"+date+"*.nc")[0]) tas_file = nc.Dataset(glob.glob("/g/data/rt52/era5/single-levels/reanalysis/2t/"+date[0:4]+\ "/2t_era5_oper_sfc_"+date+"*.nc")[0]) ps_file = nc.Dataset(glob.glob("/g/data/rt52/era5/single-levels/reanalysis/sp/"+date[0:4]+\ "/sp_era5_oper_sfc_"+date+"*.nc")[0]) cape_file = nc.Dataset(glob.glob("/g/data/rt52/era5/single-levels/reanalysis/cape/"+date[0:4]+\ "/cape_era5_oper_sfc_"+date+"*.nc")[0]) cp_file = (xr.open_dataset(glob.glob("/g/data/rt52/era5/single-levels/reanalysis/mcpr/"+date[0:4]+\ "/mcpr_era5_oper_sfc_"+date+"*.nc")[0]).isel({"longitude":sfc_lon_ind, "latitude":sfc_lat_ind}) * 3600)\ .resample(indexer={"time":str(delta_t)+"H"},\ label="right",closed="right").sum("time")["mcpr"][1:,:,:] tp_file = (xr.open_dataset(glob.glob("/g/data/rt52/era5/single-levels/reanalysis/mtpr/"+date[0:4]+\ "/mtpr_era5_oper_sfc_"+date+"*.nc")[0]).isel({"longitude":sfc_lon_ind, "latitude":sfc_lat_ind}) * 3600)\ .resample(indexer={"time":str(delta_t)+"H"},\ label="right",closed="right").sum("time")["mtpr"][1:,:,:] wg10_file = nc.Dataset(glob.glob("/g/data/rt52/era5/single-levels/reanalysis/10fg/"+date[0:4]+\ "/10fg_era5_oper_sfc_"+date+"*.nc")[0]) #Get times to load in from file if pres: times = ta_file["time"][:] time_ind = [np.where(x==times)[0][0] for x in time_hours if (x in times)] date_ind = np.where(np.array(formatted_dates) == date)[0] else: times = uas_file["time"][:] time_ind = [np.where(x==times)[0][0] for x in time_hours if (x in times)] date_ind = np.where(np.array(formatted_dates) == date)[0] #Get times to load in from forecast files (wg10) fc_times = wg10_file["time"][:] fc_time_ind = [np.where(x==fc_times)[0][0] for x in time_hours if (x in fc_times)] #Get times to load in from precip files (tp) tp_time_ind = np.in1d(tp_file.time, [np.datetime64(date_list[i]) for i in np.arange(len(date_list))]) #Load analysis data if pres: ta[date_ind,:,:,:] = ta_file["t"][time_ind,p_ind,lat_ind,lon_ind] - 273.15 #wap[date_ind,:,:,:] = wap_file["wap"][time_ind,p_ind,lat_ind,lon_ind] ua[date_ind,:,:,:] = ua_file["u"][time_ind,p_ind,lat_ind,lon_ind] va[date_ind,:,:,:] = va_file["v"][time_ind,p_ind,lat_ind,lon_ind] hgt[date_ind,:,:,:] = z_file["z"][time_ind,p_ind,lat_ind,lon_ind] / 9.8 hur[date_ind,:,:,:] = hur_file["r"][time_ind,p_ind,lat_ind,lon_ind] hur[hur<0] = 0 hur[hur>100] = 100 dp[date_ind,:,:,:] = get_dp(ta[date_ind,:,:,:],hur[date_ind,:,:,:]) uas[date_ind,:,:] = uas_file["u10"][time_ind,sfc_lat_ind,sfc_lon_ind] vas[date_ind,:,:] = vas_file["v10"][time_ind,sfc_lat_ind,sfc_lon_ind] sst[date_ind,:,:] = sst_file["sst"][time_ind,sfc_lat_ind,sfc_lon_ind] - 273.15 tas[date_ind,:,:] = tas_file["t2m"][time_ind,sfc_lat_ind,sfc_lon_ind] - 273.15 ta2d[date_ind,:,:] = ta2d_file["d2m"][time_ind,sfc_lat_ind,sfc_lon_ind] - 273.15 ps[date_ind,:,:] = ps_file["sp"][time_ind,sfc_lat_ind,sfc_lon_ind] / 100 fc_date_ind = np.in1d(date_list, nc.num2date(wg10_file["time"][fc_time_ind], wg10_file["time"].units)) tp_date_ind = np.in1d([np.datetime64(date_list[i]) for i in np.arange(len(date_list))],tp_file.time.values) cp[tp_date_ind,:,:] = cp_file.isel({"time":tp_time_ind}).values tp[tp_date_ind,:,:] = tp_file.isel({"time":tp_time_ind}).values cape[fc_date_ind,:,:] = cape_file["cape"][fc_time_ind,sfc_lat_ind,sfc_lon_ind] wg10[fc_date_ind,:,:] = wg10_file["fg10"][fc_time_ind,sfc_lat_ind,sfc_lon_ind] if pres: ta_file.close();z_file.close();ua_file.close();va_file.close();hur_file.close() uas_file.close();vas_file.close();tas_file.close();ta2d_file.close();ps_file.close() sst_file.close() if pres: p = np.flip(p) ta = np.flip(ta, axis=1) dp = np.flip(dp, axis=1) hur = np.flip(hur, axis=1) hgt = np.flip(hgt, axis=1) ua = np.flip(ua, axis=1) va = np.flip(va, axis=1) return [ta,dp,hur,hgt,terrain,p,ps,ua,va,uas,vas,tas,ta2d,cp,tp,wg10,cape,sst,lon,lat,date_list] else: return [ps,uas,vas,tas,ta2d,cp,tp,wg10,cape,sfc_lon,sfc_lat,date_list]
def main(): load_start = dt.datetime.now() #Try parsing arguments using argparse parser = argparse.ArgumentParser( description='wrf non-parallel convective diagnostics processer') parser.add_argument("-m", help="Model name", required=True) parser.add_argument("-r", help="Region name (default is aus)", default="aus") parser.add_argument("-t1", help="Time start YYYYMMDDHH", required=True) parser.add_argument("-t2", help="Time end YYYYMMDDHH", required=True) parser.add_argument( "-e", help= "CMIP5 experiment name (not required if using era5, erai or barra)", default="") parser.add_argument( "--barpa_forcing_mdl", help="BARPA forcing model (erai or ACCESS1-0). Default erai.", default="erai") parser.add_argument( "--ens", help="CMIP5 ensemble name (not required if using era5, erai or barra)", default="r1i1p1") parser.add_argument("--group", help="CMIP6 modelling group name", default="") parser.add_argument("--project", help="CMIP6 modelling intercomparison project", default="CMIP") parser.add_argument("--ver6hr", help="Version on al33 for 6hr data", default="") parser.add_argument("--ver3hr", help="Version on al33 for 3hr data", default="") parser.add_argument("--issave", help="Save output (True or False, default is False)", default="False") parser.add_argument( "--ub4", help= "Where to get era5 data. Default True for ub4 project, otherwise rt52", default="True") parser.add_argument( "--outname", help= "Name of saved output. In the form *outname*_*t1*_*t2*.nc. Default behaviour is the model name", default=None) parser.add_argument( "--is_dcape", help="Should DCAPE be calculated? (1 or 0. Default is 1)", default=1) parser.add_argument( "--al33", help= "Should data be gathered from al33? Default is False, and data is gathered from r87. If True, then group is required", default="False") parser.add_argument( "--delta_t", help= "Time step spacing for ERA5 data, in hours. Default is one the minimum spacing (1 hour)", default="1") parser.add_argument( "--era5_interp", help= "Horizontally interpolate model data before calculating convective parameters", default="False") args = parser.parse_args() #Parse arguments from cmd line and set up inputs (date region model) model = args.m region = args.r t1 = args.t1 t2 = args.t2 issave = args.issave ub4 = args.ub4 al33 = args.al33 if args.outname == None: out_name = model else: out_name = args.outname is_dcape = args.is_dcape barpa_forcing_mdl = args.barpa_forcing_mdl experiment = args.e ensemble = args.ens group = args.group project = args.project ver6hr = args.ver6hr ver3hr = args.ver3hr delta_t = int(args.delta_t) era5_interp = args.era5_interp if region == "sa_small": start_lat = -38 end_lat = -26 start_lon = 132 end_lon = 142 elif region == "aus": start_lat = -44.525 end_lat = -9.975 start_lon = 111.975 end_lon = 156.275 elif region == "global": start_lat = -70 end_lat = 70 start_lon = -180 end_lon = 179.75 else: raise ValueError("INVALID REGION\n") domain = [start_lat, end_lat, start_lon, end_lon] try: time = [ dt.datetime.strptime(t1, "%Y%m%d%H"), dt.datetime.strptime(t2, "%Y%m%d%H") ] except: raise ValueError("INVALID START OR END TIME. SHOULD BE YYYYMMDDHH\n") if era5_interp == "True": era5_interp = True elif era5_interp == "False": era5_interp = False else: raise ValueError("\n INVALID era5_interp...SHOULD BE True OR False") if ub4 == "True": ub4 = True elif ub4 == "False": ub4 = False else: raise ValueError("\n INVALID ub4...SHOULD BE True OR False") if issave == "True": issave = True elif issave == "False": issave = False else: raise ValueError("\n INVALID ISSAVE...SHOULD BE True OR False") if al33 == "True": al33 = True elif al33 == "False": al33 = False else: raise ValueError("\n INVALID al33...SHOULD BE True OR False") #Load data print("LOADING DATA...") if model == "erai": ta,temp1,hur,hgt,terrain,p,ps,wap,ua,va,uas,vas,tas,ta2d,\ cp,tp,wg10,mod_cape,lon,lat,date_list = \ read_erai(domain,time) cp = cp.astype("float32", order="C") tp = tp.astype("float32", order="C") mod_cape = mod_cape.astype("float32", order="C") elif model == "era5": if ub4: ta,temp1,hur,hgt,terrain,p,ps,ua,va,uas,vas,tas,ta2d,\ cp,wg10,mod_cape,lon,lat,date_list = \ read_era5(domain,time,delta_t=delta_t) else: ta,temp1,hur,hgt,terrain,p,ps,ua,va,uas,vas,tas,ta2d,\ cp,tp,wg10,mod_cape,lon,lat,date_list = \ read_era5_rt52(domain,time,delta_t=delta_t) cp = cp.astype("float32", order="C") tp = tp.astype("float32", order="C") mod_cape = mod_cape.astype("float32", order="C") wap = np.zeros(hgt.shape) elif model == "barra": ta,temp1,hur,hgt,terrain,p,ps,wap,ua,va,uas,vas,tas,ta2d,wg10,lon,lat,date_list = \ read_barra(domain,time) elif model == "barra_fc": ta,temp1,hur,hgt,terrain,p,ps,wap,ua,va,uas,vas,tas,ta2d,wg10,lon,lat,date_list = \ read_barra_fc(domain,time) elif model == "barpa": ta,hur,hgt,terrain,p,ps,ua,va,uas,vas,tas,ta2d,wg10,lon,lat,date_list = \ read_barpa(domain, time, experiment, barpa_forcing_mdl, ensemble) wap = np.zeros(hgt.shape) temp1 = None elif model == "barra_ad": wg10,temp2,ta,temp1,hur,hgt,terrain,p,ps,wap,ua,va,uas,vas,tas,ta2d,lon,lat,date_list = \ read_barra_ad(domain, time, False) elif model in ["ACCESS1-0","ACCESS1-3","GFDL-CM3","GFDL-ESM2M","CNRM-CM5","MIROC5",\ "MRI-CGCM3","IPSL-CM5A-LR","IPSL-CM5A-MR","GFDL-ESM2G","bcc-csm1-1","MIROC-ESM",\ "BNU-ESM"]: #Check that t1 and t2 are in the same year year = np.arange(int(t1[0:4]), int(t2[0:4]) + 1) ta, hur, hgt, terrain, p_3d, ps, ua, va, uas, vas, tas, ta2d, tp, lon, lat, \ date_list = read_cmip(model, experiment, \ ensemble, year, domain, cmip_ver=5, al33=al33, group=group, ver6hr=ver6hr, ver3hr=ver3hr) wap = np.zeros(hgt.shape) wg10 = np.zeros(ps.shape) mod_cape = np.zeros(ps.shape) p = np.zeros(p_3d[0, :, 0, 0].shape) #date_list = pd.to_datetime(date_list).to_pydatetime() temp1 = None tp = tp.astype("float32", order="C") elif model in ["ACCESS-ESM1-5", "ACCESS-CM2"]: year = np.arange(int(t1[0:4]), int(t2[0:4]) + 1) ta, hur, hgt, terrain, p_3d, ps, ua, va, uas, vas, tas, ta2d, lon, lat, \ date_list = read_cmip(model, experiment,\ ensemble, year, domain, cmip_ver=6, group=group, project=project) wap = np.zeros(hgt.shape) wg10 = np.zeros(ps.shape) p = np.zeros(p_3d[0, :, 0, 0].shape) #date_list = pd.to_datetime(date_list).to_pydatetime() temp1 = None else: raise ValueError("Model not recognised") del temp1 ta = ta.astype("float32", order="C") hur = hur.astype("float32", order="C") hgt = hgt.astype("float32", order="C") terrain = terrain.astype("float32", order="C") p = p.astype("float32", order="C") ps = ps.astype("float32", order="C") wap = wap.astype("float32", order="C") ua = ua.astype("float32", order="C") va = va.astype("float32", order="C") uas = uas.astype("float32", order="C") vas = vas.astype("float32", order="C") tas = tas.astype("float32", order="C") ta2d = ta2d.astype("float32", order="C") wg10 = wg10.astype("float32", order="C") lon = lon.astype("float32", order="C") lat = lat.astype("float32", order="C") gc.collect() param = np.array([ "mu_cape", "mu_cin", "muq", "s06", "s0500", "lr700_500", "mhgt", "ta500", "tp" ]) if model in ["erai", "era5"]: param = np.concatenate([param, ["mod_cape"]]) #Option to interpolate to the ERA5 grid if era5_interp: #Interpolate model data to the ERA5 grid from era5_read import get_lat_lon_rt52 as get_era5_lat_lon era5_lon, era5_lat = get_era5_lat_lon() era5_lon_ind = np.where((era5_lon >= domain[2]) & (era5_lon <= domain[3]))[0] era5_lat_ind = np.where((era5_lat >= domain[0]) & (era5_lat <= domain[1]))[0] era5_lon = era5_lon[era5_lon_ind] era5_lat = era5_lat[era5_lat_ind] terrain = interp_era5(terrain, lon, lat, era5_lon, era5_lat, d3=False) #Set output array output_data = np.zeros( (ps.shape[0], era5_lat.shape[0], era5_lon.shape[0], len(param))) else: output_data = np.zeros( (ps.shape[0], ps.shape[1], ps.shape[2], len(param))) #Assign p levels to a 3d array, with same dimensions as input variables (ta, hgt, etc.) #If the 3d p-lvl array already exists, then declare the variable "mdl_lvl" as true. try: p_3d mdl_lvl = True full_p3d = p_3d except: mdl_lvl = False if era5_interp: p_3d = np.moveaxis(np.tile(p,[ta.shape[2],ta.shape[3],1]),[0,1,2],[1,2,0]).\ astype(np.float32) else: p_3d = np.moveaxis(np.tile(p,[era5_lat.shape[0],era5_lon.shape[0],1]),[0,1,2],[1,2,0]).\ astype(np.float32) print("LOAD TIME..." + str(dt.datetime.now() - load_start)) tot_start = dt.datetime.now() for t in np.arange(0, ta.shape[0]): cape_start = dt.datetime.now() if era5_interp: ta_t = interp_era5(ta[t], lon, lat, era5_lon, era5_lat, d3=True) hur_t = interp_era5(hur[t], lon, lat, era5_lon, era5_lat, d3=True) hgt_t = interp_era5(hgt[t], lon, lat, era5_lon, era5_lat, d3=True) ps_t = interp_era5(ps[t], lon, lat, era5_lon, era5_lat, d3=False) wap_t = interp_era5(wap[t], lon, lat, era5_lon, era5_lat, d3=True) ua_t = interp_era5(ua[t], lon, lat, era5_lon, era5_lat, d3=True) va_t = interp_era5(va[t], lon, lat, era5_lon, era5_lat, d3=True) uas_t = interp_era5(uas[t], lon, lat, era5_lon, era5_lat, d3=False) vas_t = interp_era5(vas[t], lon, lat, era5_lon, era5_lat, d3=False) tas_t = interp_era5(tas[t], lon, lat, era5_lon, era5_lat, d3=False) ta2d_t = interp_era5(ta2d[t], lon, lat, era5_lon, era5_lat, d3=False) tp_t = interp_era5(tp[t], lon, lat, era5_lon, era5_lat, d3=False) mod_cape_t = interp_era5(mod_cape[t], lon, lat, era5_lon, era5_lat, d3=False) else: ta_t = ta[t] hur_t = hur[t] hgt_t = hgt[t] ps_t = ps[t] wap_t = wap[t] ua_t = ua[t] va_t = va[t] uas_t = uas[t] vas_t = vas[t] tas_t = tas[t] ta2d_t = ta2d[t] tp_t = tp[t] mod_cape_t = mod_cape[t] print(date_list[t]) output = np.zeros((1, ps_t.shape[0], ps_t.shape[1], len(param))) if mdl_lvl: if era5_interp: p_3d = interp_era5(full_p3d[t], lon, lat, era5_lon, era5_lat, d3=True) else: p_3d = full_p3d[t] dp = get_dp(hur=hur_t, ta=ta_t, dp_mask=False) #Insert surface arrays, creating new arrays with "sfc" prefix sfc_ta = np.insert(ta_t, 0, tas_t, axis=0) sfc_hgt = np.insert(hgt_t, 0, terrain, axis=0) sfc_dp = np.insert(dp, 0, ta2d_t, axis=0) sfc_p_3d = np.insert(p_3d, 0, ps_t, axis=0) sfc_ua = np.insert(ua_t, 0, uas_t, axis=0) sfc_va = np.insert(va_t, 0, vas_t, axis=0) sfc_wap = np.insert(wap_t, 0, np.zeros(vas_t.shape), axis=0) #Sort by ascending p a,temp1,temp2 = np.meshgrid(np.arange(sfc_p_3d.shape[0]) , np.arange(sfc_p_3d.shape[1]),\ np.arange(sfc_p_3d.shape[2])) sort_inds = np.flip(np.lexsort([np.swapaxes(a, 1, 0), sfc_p_3d], axis=0), axis=0) sfc_hgt = np.take_along_axis(sfc_hgt, sort_inds, axis=0) sfc_dp = np.take_along_axis(sfc_dp, sort_inds, axis=0) sfc_p_3d = np.take_along_axis(sfc_p_3d, sort_inds, axis=0) sfc_ua = np.take_along_axis(sfc_ua, sort_inds, axis=0) sfc_va = np.take_along_axis(sfc_va, sort_inds, axis=0) sfc_ta = np.take_along_axis(sfc_ta, sort_inds, axis=0) #Calculate q and wet bulb for pressure level arrays with surface values sfc_ta_unit = units.units.degC * sfc_ta sfc_dp_unit = units.units.degC * sfc_dp sfc_p_unit = units.units.hectopascals * sfc_p_3d hur_unit = mpcalc.relative_humidity_from_dewpoint(ta_t*units.units.degC, dp*units.units.degC)*\ 100*units.units.percent q_unit = mpcalc.mixing_ratio_from_relative_humidity(hur_unit,\ ta_t*units.units.degC,np.array(p_3d)*units.units.hectopascals) sfc_hur_unit = mpcalc.relative_humidity_from_dewpoint(sfc_ta_unit, sfc_dp_unit)*\ 100*units.units.percent sfc_q_unit = mpcalc.mixing_ratio_from_relative_humidity(sfc_hur_unit,\ sfc_ta_unit,sfc_p_unit) sfc_theta_unit = mpcalc.potential_temperature(sfc_p_unit, sfc_ta_unit) sfc_thetae_unit = mpcalc.equivalent_potential_temperature( sfc_p_unit, sfc_ta_unit, sfc_dp_unit) sfc_thetae = np.array(mpcalc.equivalent_potential_temperature(ps_t*units.units.hectopascals,tas_t*units.units.degC,\ ta2d_t*units.units.degC)) sfc_q = np.array(sfc_q_unit) sfc_hur = np.array(sfc_hur_unit) #sfc_wb = np.array(wrf.wetbulb( sfc_p_3d*100, sfc_ta+273.15, sfc_q, units="degC")) #Use getcape.f90 #cape_gb_mu1, cape_gb_mu4 = getcape_driver(sfc_p_3d, sfc_ta, sfc_dp, ps_t) #Now get most-unstable CAPE (max CAPE in vertical, ensuring parcels used are AGL) cape3d = wrf.cape_3d(sfc_p_3d,sfc_ta+273.15,\ sfc_q,sfc_hgt,\ terrain,ps_t,\ True,meta=False, missing=0) cape = cape3d.data[0] cin = cape3d.data[1] lfc = cape3d.data[2] lcl = cape3d.data[3] el = cape3d.data[4] #Mask values which are below the surface and above 350 hPa AGL cape[(sfc_p_3d > ps_t) | (sfc_p_3d < (ps_t - 350))] = np.nan cin[(sfc_p_3d > ps_t) | (sfc_p_3d < (ps_t - 350))] = np.nan lfc[(sfc_p_3d > ps_t) | (sfc_p_3d < (ps_t - 350))] = np.nan lcl[(sfc_p_3d > ps_t) | (sfc_p_3d < (ps_t - 350))] = np.nan el[(sfc_p_3d > ps_t) | (sfc_p_3d < (ps_t - 350))] = np.nan #Get maximum (in the vertical), and get cin, lfc, lcl for the same parcel mu_cape_inds = np.tile(np.nanargmax(cape, axis=0), (cape.shape[0], 1, 1)) mu_cape = np.take_along_axis(cape, mu_cape_inds, 0)[0] mu_cin = np.take_along_axis(cin, mu_cape_inds, 0)[0] mu_lfc = np.take_along_axis(lfc, mu_cape_inds, 0)[0] mu_lcl = np.take_along_axis(lcl, mu_cape_inds, 0)[0] mu_el = np.take_along_axis(el, mu_cape_inds, 0)[0] muq = np.take_along_axis(sfc_q, mu_cape_inds, 0)[0] * 1000 #Calculate other parameters #Thermo thermo_start = dt.datetime.now() lr700_500 = get_lr_p(ta_t, p_3d, hgt_t, 700, 500) melting_hgt = get_t_hgt(sfc_ta, np.copy(sfc_hgt), 0, terrain) melting_hgt = np.where((melting_hgt < 0) | (np.isnan(melting_hgt)), 0, melting_hgt) ta500 = get_var_p_lvl(np.copy(sfc_ta), sfc_p_3d, 500) ta925 = get_var_p_lvl(np.copy(sfc_ta), sfc_p_3d, 925) ta850 = get_var_p_lvl(np.copy(sfc_ta), sfc_p_3d, 850) ta700 = get_var_p_lvl(np.copy(sfc_ta), sfc_p_3d, 700) rho = mpcalc.density( np.array(sfc_p_3d) * (units.units.hectopascal), sfc_ta * units.units.degC, sfc_q_unit) rho925 = np.array(get_var_p_lvl(np.array(rho), sfc_p_3d, 925)) rho850 = np.array(get_var_p_lvl(np.array(rho), sfc_p_3d, 850)) rho700 = np.array(get_var_p_lvl(np.array(rho), sfc_p_3d, 700)) #Winds winds_start = dt.datetime.now() s06 = get_shear_hgt(sfc_ua, sfc_va, np.copy(sfc_hgt), 0, 6000, terrain) s0500 = get_shear_p(ua_t, va_t, p_3d, "sfc", np.array([500]), p_3d, uas=uas_t, vas=vas_t)[0] #WAP if model in ["erai", "era5"]: sfc_w = mpcalc.vertical_velocity( wap_t * (units.units.pascal / units.units.second),\ np.array(p_3d) * (units.units.hectopascal), \ ta_t * units.units.degC, q_unit) w925 = np.array(get_var_p_lvl(np.array(sfc_w), p_3d, 925)) w850 = np.array(get_var_p_lvl(np.array(sfc_w), p_3d, 850)) w700 = np.array(get_var_p_lvl(np.array(sfc_w), p_3d, 700)) #Convergence if era5_interp: x, y = np.meshgrid(era5_lon, era5_lat) else: x, y = np.meshgrid(lon, lat) dx, dy = mpcalc.lat_lon_grid_deltas(x, y) u925 = np.array(get_var_p_lvl(np.copy(sfc_ua), sfc_p_3d, 925)) u850 = np.array(get_var_p_lvl(np.copy(sfc_ua), sfc_p_3d, 850)) u700 = np.array(get_var_p_lvl(np.copy(sfc_ua), sfc_p_3d, 700)) v925 = np.array(get_var_p_lvl(np.copy(sfc_va), sfc_p_3d, 925)) v850 = np.array(get_var_p_lvl(np.copy(sfc_va), sfc_p_3d, 850)) v700 = np.array(get_var_p_lvl(np.copy(sfc_va), sfc_p_3d, 700)) conv925 = -1e5 * np.array( mpcalc.divergence(u925 * (units.units.meter / units.units.second), v925 * (units.units.meter / units.units.second), dx, dy)) conv850 = -1e5 * np.array( mpcalc.divergence(u850 * (units.units.meter / units.units.second), v850 * (units.units.meter / units.units.second), dx, dy)) conv700 = -1e5 * np.array( mpcalc.divergence(u700 * (units.units.meter / units.units.second), v700 * (units.units.meter / units.units.second), dx, dy)) #CS6 mucs6 = mu_cape * np.power(s06, 1.67) #Fill output output = fill_output(output, t, param, ps, "mu_cape", mu_cape) output = fill_output(output, t, param, ps, "mu_cin", mu_cin) output = fill_output(output, t, param, ps, "muq", muq) output = fill_output(output, t, param, ps, "s06", s06) output = fill_output(output, t, param, ps, "s0500", s0500) output = fill_output(output, t, param, ps, "lr700_500", lr700_500) output = fill_output(output, t, param, ps, "ta500", ta500) output = fill_output(output, t, param, ps, "mhgt", melting_hgt) output = fill_output(output, t, param, ps, "tp", tp_t) if (model == "erai") | (model == "era5"): output = fill_output(output, t, param, ps, "mod_cape", mod_cape_t) output_data[t] = output print("SAVING DATA...") param_out = [] for param_name in param: temp_data = output_data[:, :, :, np.where(param == param_name)[0][0]] param_out.append(temp_data) #If the mhgt variable is zero everywhere, then it is likely that data has not been read. #In this case, all values are missing, set to zero. for t in np.arange(param_out[0].shape[0]): if param_out[np.where(param == "mhgt")[0][0]][t].max() == 0: for p in np.arange(len(param_out)): param_out[p][t] = np.nan if issave: if era5_interp: save_netcdf(region, model, out_name, date_list, era5_lat, era5_lon, param, param_out, \ out_dtype = "f4", compress=True) else: save_netcdf(region, model, out_name, date_list, lat, lon, param, param_out, \ out_dtype = "f4", compress=True) print(dt.datetime.now() - tot_start)
def append_wbz(): #Load each ERA-Interim netcdf file, and append wbz start_lat = -44.525 end_lat = -9.975 start_lon = 111.975 end_lon = 156.275 domain = [start_lat, end_lat, start_lon, end_lon] model = "erai" region = "aus" dates = [] for y in np.arange(1979, 2019): for m in [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12]: if (m != 12): dates.append([dt.datetime(y,m,1,0,0,0),\ dt.datetime(y,m+1,1,0,0,0)-dt.timedelta(hours = 6)]) else: dates.append([dt.datetime(y,m,1,0,0,0),\ dt.datetime(y+1,1,1,0,0,0)-dt.timedelta(hours = 6)]) for t in np.arange(0, len(dates)): print(str(dates[t][0]) + " - " + str(dates[t][1])) fname = "/g/data/eg3/ab4502/ExtremeWind/"+region+"/"+model+"/"+model+"_"+\ dt.datetime.strftime(dates[t][0],"%Y%m%d")+"_"+\ dt.datetime.strftime(dates[t][-1],"%Y%m%d")+".nc" ta,dp,hur,hgt,terrain,p,ps,wap,ua,va,uas,vas,tas,ta2d,cp,wg10,cape,lon,lat,date_list = \ read_erai(domain,dates[t]) dp = get_dp(ta, hur, dp_mask=False) agl_idx = (p <= ps) #Replace masked dp values dp = replace_dp(dp) try: prof = profile.create_profile(pres = np.insert(p[agl_idx],0,ps), \ hght = np.insert(hgt[agl_idx],0,terrain), \ tmpc = np.insert(ta[agl_idx],0,tas), \ dwpc = np.insert(dp[agl_idx],0,ta2d), \ u = np.insert(ua[agl_idx],0,uas), \ v = np.insert(va[agl_idx],0,vas), \ strictqc=False, omeg=np.insert(wap[agl_idx],0,wap[agl_idx][0]) ) except: p = p[agl_idx] ua = ua[agl_idx] va = va[agl_idx] hgt = hgt[agl_idx] ta = ta[agl_idx] \ dp = dp[agl_idx] p[0] = ps ua[0] = uas va[0] = vas hgt[0] = terrain ta[0] = tas dp[0] = ta2d prof = profile.create_profile(pres = p, \ hght = hgt, \ tmpc = ta, \ dwpc = dp, \ u = ua, \ v = va, \ strictqc=False, omeg=wap[agl_idx]) pwb0 = params.temp_lvl(prof, 0, wetbulb=True) hwb0 = interp.to_agl(prof, interp.hght(prof, pwb0)) param_file = nc.Dataset(fname, "a") wbz_var = param_file.createVariable("wbz",float,\ ("time","lat","lon")) wbz_var.units = "m" wbz_var.long_name = "wet_bulb_zero_height" wbz_var[:] = hwb0 T1 = abs( thermo.wetlift(prof.pres[0], prof.tmpc[0], 600) - interp.temp(prof, 600)) T2 = abs( thermo.wetlift(pwb0, interp.temp(prof, pwb0), sfc) - prof.tmpc[0]) Vprime = utils.KTS2MS(13 * np.sqrt((T1 + T2) / 2) + (1 / 3 * (Umean01))) Vprime_var = param_file.createVariable("Vprime",float,\ ("time","lat","lon")) Vprime_var.units = "m/s" Vprime_var.long_name = "miller_1972_wind_speed" Vprime_var[:] = Vprime param_file.close()
def main(): load_start = dt.datetime.now() #Try parsing arguments using argparse parser = argparse.ArgumentParser(description='wrf non-parallel convective diagnostics processer') parser.add_argument("-m",help="Model name",required=True) parser.add_argument("-r",help="Region name (default is aus)",default="aus") parser.add_argument("-t1",help="Time start YYYYMMDDHH",required=True) parser.add_argument("-t2",help="Time end YYYYMMDDHH",required=True) parser.add_argument("-e", help="CMIP5 experiment name (not required if using era5, erai or barra)", default="") parser.add_argument("--barpa_forcing_mdl", help="BARPA forcing model (erai or ACCESS1-0). Default erai.", default="erai") parser.add_argument("--ens", help="CMIP5 ensemble name (not required if using era5, erai or barra)", default="r1i1p1") parser.add_argument("--group", help="CMIP6 modelling group name", default="") parser.add_argument("--project", help="CMIP6 modelling intercomparison project", default="CMIP") parser.add_argument("--ver6hr", help="Version on al33 for 6hr data", default="") parser.add_argument("--ver3hr", help="Version on al33 for 3hr data", default="") parser.add_argument("--issave",help="Save output (True or False, default is False)", default="False") parser.add_argument("--outname",help="Name of saved output. In the form *outname*_*t1*_*t2*.nc. Default behaviour is the model name",default=None) parser.add_argument("--is_dcape",help="Should DCAPE be calculated? (1 or 0. Default is 1)",default=1) parser.add_argument("--al33",help="Should data be gathered from al33? Default is False, and data is gathered from r87. If True, then group is required",default="False") parser.add_argument("--params",help="Should the full set of convective parameters be calculated (full) or just a reduced set (reduced)",default="full") args = parser.parse_args() #Parse arguments from cmd line and set up inputs (date region model) if args.params == "full": full_params = True else: full_params = False model = args.m region = args.r t1 = args.t1 t2 = args.t2 issave = args.issave al33 = args.al33 if args.outname==None: out_name = model else: out_name = args.outname is_dcape = args.is_dcape barpa_forcing_mdl = args.barpa_forcing_mdl experiment = args.e ensemble = args.ens group = args.group project = args.project ver6hr = args.ver6hr ver3hr = args.ver3hr if region == "sa_small": start_lat = -38; end_lat = -26; start_lon = 132; end_lon = 142 elif region == "aus": start_lat = -44.525; end_lat = -9.975; start_lon = 111.975; end_lon = 156.275 else: raise ValueError("INVALID REGION\n") domain = [start_lat,end_lat,start_lon,end_lon] try: time = [dt.datetime.strptime(t1,"%Y%m%d%H"),dt.datetime.strptime(t2,"%Y%m%d%H")] except: raise ValueError("INVALID START OR END TIME. SHOULD BE YYYYMMDDHH\n") if issave=="True": issave = True elif issave=="False": issave = False else: raise ValueError("\n INVALID ISSAVE...SHOULD BE True OR False") if al33=="True": al33 = True elif al33=="False": al33 = False else: raise ValueError("\n INVALID al33...SHOULD BE True OR False") #Load data print("LOADING DATA...") if model == "erai": ta,temp1,hur,hgt,terrain,p,ps,wap,ua,va,uas,vas,tas,ta2d,\ cp,wg10,mod_cape,lon,lat,date_list = \ read_erai(domain,time) cp = cp.astype("float32", order="C") mod_cape = mod_cape.astype("float32", order="C") elif model == "era5": ta,temp1,hur,hgt,terrain,p,ps,ua,va,uas,vas,tas,ta2d,\ cp,wg10,mod_cape,lon,lat,date_list = \ read_era5(domain,time) cp = cp.astype("float32", order="C") mod_cape = mod_cape.astype("float32", order="C") wap = np.zeros(hgt.shape) elif model == "barra": ta,temp1,hur,hgt,terrain,p,ps,wap,ua,va,uas,vas,tas,ta2d,wg10,lon,lat,date_list = \ read_barra(domain,time) elif model == "barra_fc": ta,temp1,hur,hgt,terrain,p,ps,wap,ua,va,uas,vas,tas,ta2d,wg10,lon,lat,date_list = \ read_barra_fc(domain,time) elif model == "barpa": ta,hur,hgt,terrain,p,ps,ua,va,uas,vas,tas,ta2d,wg10,lon,lat,date_list = \ read_barpa(domain, time, experiment, barpa_forcing_mdl, ensemble) wap = np.zeros(hgt.shape) temp1 = None elif model == "barra_ad": wg10,temp2,ta,temp1,hur,hgt,terrain,p,ps,wap,ua,va,uas,vas,tas,ta2d,lon,lat,date_list = \ read_barra_ad(domain, time, False) elif model in ["ACCESS1-0","ACCESS1-3","GFDL-CM3","GFDL-ESM2M","CNRM-CM5","MIROC5",\ "MRI-CGCM3","IPSL-CM5A-LR","IPSL-CM5A-MR","GFDL-ESM2G","bcc-csm1-1","MIROC-ESM",\ "BNU-ESM"]: #Check that t1 and t2 are in the same year year = np.arange(int(t1[0:4]), int(t2[0:4])+1) ta, hur, hgt, terrain, p_3d, ps, ua, va, uas, vas, tas, ta2d, lon, lat, \ date_list = read_cmip(model, experiment, \ ensemble, year, domain, cmip_ver=5, al33=al33, group=group, ver6hr=ver6hr, ver3hr=ver3hr) wap = np.zeros(hgt.shape) wg10 = np.zeros(ps.shape) p = np.zeros(p_3d[0,:,0,0].shape) #date_list = pd.to_datetime(date_list).to_pydatetime() temp1 = None elif model in ["ACCESS-ESM1-5", "ACCESS-CM2"]: year = np.arange(int(t1[0:4]), int(t2[0:4])+1) ta, hur, hgt, terrain, p_3d, ps, ua, va, uas, vas, tas, ta2d, lon, lat, \ date_list = read_cmip(model, experiment,\ ensemble, year, domain, cmip_ver=6, group=group, project=project) wap = np.zeros(hgt.shape) wg10 = np.zeros(ps.shape) p = np.zeros(p_3d[0,:,0,0].shape) #date_list = pd.to_datetime(date_list).to_pydatetime() temp1 = None else: raise ValueError("Model not recognised") del temp1 ta = ta.astype("float32", order="C") hur = hur.astype("float32", order="C") hgt = hgt.astype("float32", order="C") terrain = terrain.astype("float32", order="C") p = p.astype("float32", order="C") ps = ps.astype("float32", order="C") wap = wap.astype("float32", order="C") ua = ua.astype("float32", order="C") va = va.astype("float32", order="C") uas = uas.astype("float32", order="C") vas = vas.astype("float32", order="C") tas= tas.astype("float32", order="C") ta2d = ta2d.astype("float32", order="C") wg10 = wg10.astype("float32", order="C") lon = lon.astype("float32", order="C") lat = lat.astype("float32", order="C") gc.collect() if full_params: param = np.array(["ml_cape", "mu_cape", "sb_cape", "ml_cin", "sb_cin", "mu_cin",\ "ml_lcl", "mu_lcl", "sb_lcl", "eff_cape", "eff_cin", "eff_lcl",\ "lr01", "lr03", "lr13", "lr36", "lr24", "lr_freezing","lr_subcloud",\ "qmean01", "qmean03", "qmean06", \ "qmeansubcloud", "q_melting", "q1", "q3", "q6",\ "rhmin01", "rhmin03", "rhmin13", \ "rhminsubcloud", "tei", "wbz", \ "mhgt", "mu_el", "ml_el", "sb_el", "eff_el", \ "pwat", "v_totals", "c_totals", "t_totals", \ "te_diff", "dpd850", "dpd700", "dcape", "ddraft_temp", "sfc_thetae", \ \ "srhe_left", "srh01_left", "srh03_left", "srh06_left", \ "ebwd", "s010", "s06", "s03", "s01", "s13", "s36", "scld", \ "U500", "U10", "U1", "U3", "U6", \ "Ust_left", "Usr01_left",\ "Usr03_left", "Usr06_left", \ "Uwindinf", "Umeanwindinf", "Umean800_600", "Umean06", \ "Umean01", "Umean03", "wg10",\ \ "dcp", "stp_cin_left", "stp_fixed_left",\ "scp", "scp_fixed", "ship",\ "mlcape*s06", "mucape*s06", "sbcape*s06", "effcape*s06", \ "dmgwind", "dmgwind_fixed", "hmi", "wmsi_ml",\ "dmi", "mwpi_ml", "convgust_wet", "convgust_dry", "windex",\ "gustex", "eff_sherb", "sherb", "mmp", \ "wndg","mburst","sweat","k_index","wmpi",\ \ "F10", "Fn10", "Fs10", "icon10", "vgt10", "conv10", "vo10",\ ]) else: param = np.array(["ml_cape", "mu_cape", "sb_cape", "ml_cin", "sb_cin", "mu_cin",\ "ml_lcl", "mu_lcl", "sb_lcl", "eff_cape", "eff_cin", "eff_lcl",\ "lr36", "lr_freezing","lr_subcloud",\ "qmean01", \ "qmeansubcloud",\ "mhgt", "mu_el", "ml_el", "sb_el", "eff_el", \ "pwat", "t_totals", \ "dcape", \ \ "srhe_left", "srh03_left", \ "ebwd", "s06", "s03", \ "U10", \ "Umean800_600", "Umean06", \ "wg10",\ \ "dcp", "stp_cin_left", "stp_fixed_left",\ "scp", "scp_fixed", "ship",\ "mlcape*s06", "mucape*s06", "sbcape*s06", "effcape*s06", \ "dmgwind", "dmgwind_fixed", \ "convgust_wet", "convgust_dry", "windex",\ "gustex", "mmp", \ "wndg","sweat","k_index"\ ]) if model != "era5": param = np.concatenate([param, ["omega01", "omega03", "omega06", \ "maxtevv", "mosh", "moshe"]]) else: param = np.concatenate([param, ["cp"]]) if model == "erai": param = np.concatenate([param, ["cape","cp","cape*s06"]]) #Set output array output_data = np.zeros((ps.shape[0], ps.shape[1], ps.shape[2], len(param))) #Assign p levels to a 3d array, with same dimensions as input variables (ta, hgt, etc.) #If the 3d p-lvl array already exists, then declare the variable "mdl_lvl" as true. try: p_3d; mdl_lvl = True full_p3d = p_3d except: mdl_lvl = False p_3d = np.moveaxis(np.tile(p,[ta.shape[2],ta.shape[3],1]),[0,1,2],[1,2,0]).\ astype(np.float32) print("LOAD TIME..."+str(dt.datetime.now()-load_start)) tot_start = dt.datetime.now() for t in np.arange(0,ta.shape[0]): output = np.zeros((1, ps.shape[1], ps.shape[2], len(param))) cape_start = dt.datetime.now() print(date_list[t]) if mdl_lvl: p_3d = full_p3d[t] dp = get_dp(hur=hur[t], ta=ta[t], dp_mask = False) #Insert surface arrays, creating new arrays with "sfc" prefix sfc_ta = np.insert(ta[t], 0, tas[t], axis=0) sfc_hgt = np.insert(hgt[t], 0, terrain, axis=0) sfc_dp = np.insert(dp, 0, ta2d[t], axis=0) sfc_p_3d = np.insert(p_3d, 0, ps[t], axis=0) sfc_ua = np.insert(ua[t], 0, uas[t], axis=0) sfc_va = np.insert(va[t], 0, vas[t], axis=0) sfc_wap = np.insert(wap[t], 0, np.zeros(vas[t].shape), axis=0) #Sort by ascending p a,temp1,temp2 = np.meshgrid(np.arange(sfc_p_3d.shape[0]) , np.arange(sfc_p_3d.shape[1]),\ np.arange(sfc_p_3d.shape[2])) sort_inds = np.flip(np.lexsort([np.swapaxes(a,1,0),sfc_p_3d],axis=0), axis=0) sfc_hgt = np.take_along_axis(sfc_hgt, sort_inds, axis=0) sfc_dp = np.take_along_axis(sfc_dp, sort_inds, axis=0) sfc_p_3d = np.take_along_axis(sfc_p_3d, sort_inds, axis=0) sfc_ua = np.take_along_axis(sfc_ua, sort_inds, axis=0) sfc_va = np.take_along_axis(sfc_va, sort_inds, axis=0) sfc_ta = np.take_along_axis(sfc_ta, sort_inds, axis=0) #Calculate q and wet bulb for pressure level arrays with surface values sfc_ta_unit = units.units.degC*sfc_ta sfc_dp_unit = units.units.degC*sfc_dp sfc_p_unit = units.units.hectopascals*sfc_p_3d sfc_hur_unit = mpcalc.relative_humidity_from_dewpoint(sfc_ta_unit, sfc_dp_unit)*\ 100*units.units.percent sfc_q_unit = mpcalc.mixing_ratio_from_relative_humidity(sfc_hur_unit,\ sfc_ta_unit,sfc_p_unit) sfc_theta_unit = mpcalc.potential_temperature(sfc_p_unit,sfc_ta_unit) sfc_thetae_unit = mpcalc.equivalent_potential_temperature(sfc_p_unit,sfc_ta_unit,sfc_dp_unit) sfc_q = np.array(sfc_q_unit) sfc_hur = np.array(sfc_hur_unit) sfc_wb = np.array(wrf.wetbulb( sfc_p_3d*100, sfc_ta+273.15, sfc_q, units="degC")) #Calculate mixed-layer parcel indices, based on avg sfc-100 hPa AGL layer parcel. #First, find avg values for ta, p, hgt and q for ML (between the surface # and 100 hPa AGL) ml_inds = ((sfc_p_3d <= ps[t]) & (sfc_p_3d >= (ps[t] - 100))) ml_p3d_avg = ( np.ma.masked_where(~ml_inds, sfc_p_3d).min(axis=0) + np.ma.masked_where(~ml_inds, sfc_p_3d).max(axis=0) ) / 2. ml_hgt_avg = ( np.ma.masked_where(~ml_inds, sfc_hgt).min(axis=0) + np.ma.masked_where(~ml_inds, sfc_hgt).max(axis=0) ) / 2. ml_ta_avg = trapz_int3d(sfc_ta, sfc_p_3d, ml_inds ).astype(np.float32) ml_q_avg = trapz_int3d(sfc_q, sfc_p_3d, ml_inds ).astype(np.float32) #Insert the mean values into the bottom of the 3d arrays pressure-level arrays ml_ta_arr = np.insert(sfc_ta,0,ml_ta_avg,axis=0) ml_q_arr = np.insert(sfc_q,0,ml_q_avg,axis=0) ml_hgt_arr = np.insert(sfc_hgt,0,ml_hgt_avg,axis=0) ml_p3d_arr = np.insert(sfc_p_3d,0,ml_p3d_avg,axis=0) #Sort by ascending p a,temp1,temp2 = np.meshgrid(np.arange(ml_p3d_arr.shape[0]) ,\ np.arange(ml_p3d_arr.shape[1]), np.arange(ml_p3d_arr.shape[2])) sort_inds = np.flipud(np.lexsort([np.swapaxes(a,1,0),ml_p3d_arr],axis=0)) ml_ta_arr = np.take_along_axis(ml_ta_arr, sort_inds, axis=0) ml_p3d_arr = np.take_along_axis(ml_p3d_arr, sort_inds, axis=0) ml_hgt_arr = np.take_along_axis(ml_hgt_arr, sort_inds, axis=0) ml_q_arr = np.take_along_axis(ml_q_arr, sort_inds, axis=0) #Calculate CAPE using wrf-python. cape3d_mlavg = wrf.cape_3d(ml_p3d_arr.astype(np.float64),\ (ml_ta_arr + 273.15).astype(np.float64),\ ml_q_arr.astype(np.float64),\ ml_hgt_arr.astype(np.float64),terrain.astype(np.float64),\ ps[t].astype(np.float64),False,meta=False, missing=0) ml_cape = np.ma.masked_where(~((ml_ta_arr==ml_ta_avg) & (ml_p3d_arr==ml_p3d_avg)),\ cape3d_mlavg.data[0]).max(axis=0).filled(0) ml_cin = np.ma.masked_where(~((ml_ta_arr==ml_ta_avg) & (ml_p3d_arr==ml_p3d_avg)),\ cape3d_mlavg.data[1]).max(axis=0).filled(0) ml_lfc = np.ma.masked_where(~((ml_ta_arr==ml_ta_avg) & (ml_p3d_arr==ml_p3d_avg)),\ cape3d_mlavg.data[2]).max(axis=0).filled(0) ml_lcl = np.ma.masked_where(~((ml_ta_arr==ml_ta_avg) & (ml_p3d_arr==ml_p3d_avg)),\ cape3d_mlavg.data[3]).max(axis=0).filled(0) ml_el = np.ma.masked_where(~((ml_ta_arr==ml_ta_avg) & (ml_p3d_arr==ml_p3d_avg)),\ cape3d_mlavg.data[4]).max(axis=0).filled(0) #Now get most-unstable CAPE (max CAPE in vertical, ensuring parcels used are AGL) cape3d = wrf.cape_3d(sfc_p_3d,sfc_ta+273.15,\ sfc_q,sfc_hgt,\ terrain,ps[t],\ True,meta=False, missing=0) cape = cape3d.data[0] cin = cape3d.data[1] lfc = cape3d.data[2] lcl = cape3d.data[3] el = cape3d.data[4] #Mask values which are below the surface and above 500 hPa AGL cape[(sfc_p_3d > ps[t]) | (sfc_p_3d<(ps[t]-500))] = np.nan cin[(sfc_p_3d > ps[t]) | (sfc_p_3d<(ps[t]-500))] = np.nan lfc[(sfc_p_3d > ps[t]) | (sfc_p_3d<(ps[t]-500))] = np.nan lcl[(sfc_p_3d > ps[t]) | (sfc_p_3d<(ps[t]-500))] = np.nan el[(sfc_p_3d > ps[t]) | (sfc_p_3d<(ps[t]-500))] = np.nan #Get maximum (in the vertical), and get cin, lfc, lcl for the same parcel mu_cape_inds = np.tile(np.nanargmax(cape,axis=0), (cape.shape[0],1,1)) mu_cape = np.take_along_axis(cape, mu_cape_inds, 0)[0] mu_cin = np.take_along_axis(cin, mu_cape_inds, 0)[0] mu_lfc = np.take_along_axis(lfc, mu_cape_inds, 0)[0] mu_lcl = np.take_along_axis(lcl, mu_cape_inds, 0)[0] mu_el = np.take_along_axis(el, mu_cape_inds, 0)[0] muq = np.take_along_axis(sfc_q, mu_cape_inds, 0)[0] #Now get surface based CAPE. Simply the CAPE defined by parcel #with surface properties sb_cape = np.ma.masked_where(~((sfc_p_3d==ps[t])),\ cape).max(axis=0).filled(0) sb_cin = np.ma.masked_where(~((sfc_p_3d==ps[t])),\ cin).max(axis=0).filled(0) sb_lfc = np.ma.masked_where(~((sfc_p_3d==ps[t])),\ lfc).max(axis=0).filled(0) sb_lcl = np.ma.masked_where(~((sfc_p_3d==ps[t])),\ lcl).max(axis=0).filled(0) sb_el = np.ma.masked_where(~((sfc_p_3d==ps[t])),\ el).max(axis=0).filled(0) #Now get the effective-inflow layer parcel CAPE. Layer defined as a parcel with # the mass-wegithted average conditions of the inflow layer; the layer # between when the profile has CAPE > 100 and cin < 250. #If no effective layer, effective layer CAPE is zero. #Only levels below 500 hPa AGL are considered #EDITS (23/01/2020) #Do not get surface-based values when eff_cape is not defined. Just leave as zero. #If an effective layer is only one level, the pacel is defined with quantities at # that level. Previously, quantites were defined as zero, becuase of the averaging # routine (i.e. bc pressure difference between the top of the effective layer and the # bottom is zero). I assume this would result in zero CAPE (given q would be zero) eff_cape, eff_cin, eff_lfc, eff_lcl, eff_el, eff_hgt, eff_avg_hgt = get_eff_cape(\ cape, cin, sfc_p_3d, sfc_ta, sfc_hgt, sfc_q, ps[t], terrain) eff_cape = np.where(np.isnan(eff_cape), 0, eff_cape) eff_cin = np.where(np.isnan(eff_cin), 0, eff_cin) eff_lfc = np.where(np.isnan(eff_lfc), 0, eff_lfc) eff_lcl = np.where(np.isnan(eff_lcl), 0, eff_lcl) eff_el = np.where(np.isnan(eff_el), 0, eff_el) #Calculate other parameters #Thermo thermo_start = dt.datetime.now() lr01 = get_lr_hgt(sfc_ta,np.copy(sfc_hgt),0,1000,terrain) lr03 = get_lr_hgt(sfc_ta,np.copy(sfc_hgt),0,3000,terrain) lr13 = get_lr_hgt(sfc_ta,np.copy(sfc_hgt),1000,3000,terrain) lr24 = get_lr_hgt(sfc_ta,np.copy(sfc_hgt),2000,4000,terrain) lr36 = get_lr_hgt(sfc_ta,np.copy(sfc_hgt),3000,6000,terrain) lr_freezing = get_lr_hgt(sfc_ta,np.copy(sfc_hgt),0,"freezing",terrain) lr_subcloud = get_lr_hgt(sfc_ta,np.copy(sfc_hgt),0,ml_lcl,terrain) lr850_670 = get_lr_p(ta[t], p_3d, hgt[t], 850, 670) lr750_500 = get_lr_p(ta[t], p_3d, hgt[t], 750, 500) lr700_500 = get_lr_p(ta[t], p_3d, hgt[t], 700, 500) melting_hgt = get_t_hgt(sfc_ta,np.copy(sfc_hgt),0,terrain) hwb0 = get_var_hgt(np.flipud(sfc_wb),np.flipud(np.copy(sfc_hgt)),0,terrain) rhmean01 = get_mean_var_hgt(np.copy(sfc_hur),np.copy(sfc_hgt),0,1000,terrain,True,np.copy(sfc_p_3d)) rhmean03 = get_mean_var_hgt(np.copy(sfc_hur),np.copy(sfc_hgt),0,3000,terrain,True,np.copy(sfc_p_3d)) rhmean06 = get_mean_var_hgt(np.copy(sfc_hur),np.copy(sfc_hgt),0,6000,terrain,True,np.copy(sfc_p_3d)) rhmean13 = get_mean_var_hgt(np.copy(sfc_hur),np.copy(sfc_hgt),1000,3000,terrain,True,np.copy(sfc_p_3d)) rhmean36 = get_mean_var_hgt(np.copy(sfc_hur),np.copy(sfc_hgt),3000,6000,terrain,True,np.copy(sfc_p_3d)) rhmeansubcloud = get_mean_var_hgt(np.copy(sfc_hur),np.copy(sfc_hgt),0,ml_lcl,terrain,True,np.copy(sfc_p_3d)) qmean01 = get_mean_var_hgt(np.copy(sfc_q),np.copy(sfc_hgt),0,1000,terrain,True,np.copy(sfc_p_3d)) * 1000 qmean03 = get_mean_var_hgt(np.copy(sfc_q),np.copy(sfc_hgt),0,3000,terrain,True,np.copy(sfc_p_3d)) * 1000 qmean06 = get_mean_var_hgt(np.copy(sfc_q),np.copy(sfc_hgt),0,6000,terrain,True,np.copy(sfc_p_3d)) * 1000 qmean13 = get_mean_var_hgt(np.copy(sfc_q),np.copy(sfc_hgt),1000,3000,terrain,True,np.copy(sfc_p_3d)) * 1000 qmean36 = get_mean_var_hgt(np.copy(sfc_q),np.copy(sfc_hgt),3000,6000,terrain,True,np.copy(sfc_p_3d)) * 1000 qmeansubcloud = get_mean_var_hgt(np.copy(sfc_q),np.copy(sfc_hgt),0,ml_lcl,terrain,True,np.copy(sfc_p_3d)) * 1000 q_melting = get_var_hgt_lvl(np.copy(sfc_q), np.copy(sfc_hgt), melting_hgt, terrain) * 1000 q1 = get_var_hgt_lvl(np.copy(sfc_q), np.copy(sfc_hgt), 1000, terrain) * 1000 q3 = get_var_hgt_lvl(np.copy(sfc_q), np.copy(sfc_hgt), 3000, terrain) * 1000 q6 = get_var_hgt_lvl(np.copy(sfc_q), np.copy(sfc_hgt), 6000, terrain) * 1000 sfc_thetae = get_var_hgt_lvl(np.array(sfc_thetae_unit), np.copy(sfc_hgt), 0, terrain) rhmin01 = get_min_var_hgt(np.copy(sfc_hur), np.copy(sfc_hgt), 0, 1000, terrain) rhmin03 = get_min_var_hgt(np.copy(sfc_hur), np.copy(sfc_hgt), 0, 3000, terrain) rhmin06 = get_min_var_hgt(np.copy(sfc_hur), np.copy(sfc_hgt), 0, 6000, terrain) rhmin13 = get_min_var_hgt(np.copy(sfc_hur), np.copy(sfc_hgt), 1000, 3000, terrain) rhmin36 = get_min_var_hgt(np.copy(sfc_hur), np.copy(sfc_hgt), 3000, 6000, terrain) rhminsubcloud = get_min_var_hgt(np.copy(sfc_hur), np.copy(sfc_hgt), 0, ml_lcl, terrain) v_totals = get_var_p_lvl(np.copy(sfc_ta), sfc_p_3d, 850) - \ get_var_p_lvl(np.copy(sfc_ta), sfc_p_3d, 500) c_totals = get_var_p_lvl(np.copy(sfc_dp), sfc_p_3d, 850) - \ get_var_p_lvl(np.copy(sfc_ta), sfc_p_3d, 500) t_totals = v_totals + c_totals pwat = get_pwat(sfc_q, np.copy(sfc_p_3d)) if model != "era5": maxtevv = maxtevv_fn(np.array(sfc_thetae_unit), np.copy(sfc_wap), np.copy(sfc_hgt), terrain) te_diff = thetae_diff(np.array(sfc_thetae_unit), np.copy(sfc_hgt), terrain) tei = tei_fn(np.array(sfc_thetae_unit), sfc_p_3d, ps[t], np.copy(sfc_hgt), terrain) dpd850 = get_var_p_lvl(np.copy(sfc_ta), sfc_p_3d, 850) - \ get_var_p_lvl(np.copy(sfc_dp), sfc_p_3d, 850) dpd700 = get_var_p_lvl(np.copy(sfc_ta), sfc_p_3d, 700) - \ get_var_p_lvl(np.copy(sfc_dp), sfc_p_3d, 700) dpd670 = get_var_p_lvl(np.copy(sfc_ta), sfc_p_3d, 670) - \ get_var_p_lvl(np.copy(sfc_dp), sfc_p_3d, 670) dpd500 = get_var_p_lvl(np.copy(sfc_ta), sfc_p_3d, 500) - \ get_var_p_lvl(np.copy(sfc_dp), sfc_p_3d, 500) if (int(is_dcape) == 1) & (ps[t].max() > 0): #Define DCAPE as the area between the moist adiabat of a descending parcel # and the environmental temperature (w/o virtual temperature correction). #Starting parcel chosen by the pressure level with minimum thetae below # 400 hPa AGL if mdl_lvl: sfc_thetae300 = np.copy(sfc_thetae_unit) sfc_thetae300[(ps[t] - sfc_p_3d) > 400] = np.nan sfc_thetae300[(sfc_p_3d > ps[t])] = np.nan dcape, ddraft_temp = get_dcape( sfc_p_3d, sfc_ta, sfc_q, sfc_hgt,\ ps[t], p_lvl=False, \ minthetae_inds=np.argmin(sfc_thetae300, axis=0)) else: #Get 3d DCAPE for every point below 300 hPa, and then mask points above 400 hPa AGL #For each lat/lon point, calculate the minimum thetae, and use # DCAPE for that point dcape, ddraft_temp = get_dcape(\ np.array(sfc_p_3d[np.concatenate([[1100], \ p]) >= 300]), \ sfc_ta[np.concatenate([[1100], p]) >= 300], \ sfc_q[np.concatenate([[1100], p]) >= 300], \ sfc_hgt[np.concatenate([[1100], p]) >= 300], \ ps[t], p=np.array(p[p>=300])) sfc_thetae300 = np.array(sfc_thetae_unit[np.concatenate([[1100], \ p]) >= 300]) sfc_p300 = sfc_p_3d[np.concatenate([[1100], p]) >= 300] sfc_thetae300[(ps[t] - sfc_p300) > 400] = np.nan sfc_thetae300[(sfc_p300 > ps[t])] = np.nan dcape_inds = np.tile(np.nanargmin(sfc_thetae300, axis=0), \ (sfc_thetae300.shape[0],1,1) ) dcape = np.take_along_axis(dcape, dcape_inds, 0)[0] ddraft_temp = tas[t] - \ np.take_along_axis(ddraft_temp, dcape_inds, 0)[0] ddraft_temp[(ddraft_temp<0) | (np.isnan(ddraft_temp))] = 0 else: ddraft_temp = np.zeros(dpd500.shape) dcape = np.zeros(dpd500.shape) #Winds winds_start = dt.datetime.now() umeanwindinf = get_mean_var_hgt(sfc_ua, np.copy(sfc_hgt), np.nanmin(eff_hgt,axis=0), \ np.nanmax(eff_hgt,axis=0),0,False,sfc_p_3d) vmeanwindinf = get_mean_var_hgt(sfc_va, np.copy(sfc_hgt), np.nanmin(eff_hgt,axis=0),\ np.nanmax(eff_hgt,axis=0),0,False,sfc_p_3d) umean01 = get_mean_var_hgt(sfc_ua, np.copy(sfc_hgt), 0, 1000, terrain, mass_weighted=True, p3d=np.copy(sfc_p_3d)) vmean01 = get_mean_var_hgt(sfc_va, np.copy(sfc_hgt), 0, 1000, terrain, mass_weighted=True, p3d=np.copy(sfc_p_3d)) umean03 = get_mean_var_hgt(sfc_ua, np.copy(sfc_hgt), 0, 3000, terrain, mass_weighted=True, p3d=np.copy(sfc_p_3d)) vmean03 = get_mean_var_hgt(sfc_va, np.copy(sfc_hgt), 0, 3000, terrain, mass_weighted=True, p3d=np.copy(sfc_p_3d)) umean06 = get_mean_var_hgt(sfc_ua, np.copy(sfc_hgt), 0, 6000, terrain, mass_weighted=True, p3d=np.copy(sfc_p_3d)) vmean06 = get_mean_var_hgt(sfc_va, np.copy(sfc_hgt), 0, 6000, terrain, mass_weighted=True, p3d=np.copy(sfc_p_3d)) umean800_600 = get_mean_var_p(ua[t], p_3d, 800, 600, ps[t], mass_weighted=True) vmean800_600 = get_mean_var_p(va[t], p_3d, 800, 600, ps[t], mass_weighted=True) Umeanwindinf = np.sqrt( (umeanwindinf**2) + (vmeanwindinf**2) ) Umean01 = np.sqrt( (umean01**2) + (vmean01**2) ) Umean03 = np.sqrt( (umean03**2) + (vmean03**2) ) Umean06 = np.sqrt( (umean06**2) + (vmean06**2) ) Umean800_600 = np.sqrt( (umean800_600**2) + (vmean800_600**2) ) uwindinf = get_var_hgt_lvl(sfc_ua, np.copy(sfc_hgt), eff_avg_hgt, terrain) vwindinf = get_var_hgt_lvl(sfc_va, np.copy(sfc_hgt), eff_avg_hgt, terrain) u10 = get_var_hgt_lvl(sfc_ua, np.copy(sfc_hgt), 10, terrain) v10 = get_var_hgt_lvl(sfc_va, np.copy(sfc_hgt), 10, terrain) u500 = get_var_p_lvl(np.copy(sfc_ua), sfc_p_3d, 500) v500 = get_var_p_lvl(np.copy(sfc_va), sfc_p_3d, 500) u1 = get_var_hgt_lvl(sfc_ua, np.copy(sfc_hgt), 1000, terrain) v1 = get_var_hgt_lvl(sfc_va, np.copy(sfc_hgt), 1000, terrain) u3 = get_var_hgt_lvl(sfc_ua, np.copy(sfc_hgt), 3000, terrain) v3 = get_var_hgt_lvl(sfc_va, np.copy(sfc_hgt), 3000, terrain) u6 = get_var_hgt_lvl(sfc_ua, np.copy(sfc_hgt), 6000, terrain) v6 = get_var_hgt_lvl(sfc_va, np.copy(sfc_hgt), 6000, terrain) Uwindinf = np.sqrt( (uwindinf**2) + (vwindinf**2) ) U500 = np.sqrt( (u500**2) + (v500**2) ) U10 = np.sqrt( (u10**2) + (v10**2) ) U1 = np.sqrt( (u1**2) + (v1**2) ) U3 = np.sqrt( (u3**2) + (v3**2) ) U6 = np.sqrt( (u6**2) + (v6**2) ) scld = get_shear_hgt(sfc_ua, sfc_va, np.copy(sfc_hgt), ml_lcl, 0.5*mu_el, terrain) s01 = get_shear_hgt(sfc_ua, sfc_va, np.copy(sfc_hgt), 0, 1000, terrain) s03 = get_shear_hgt(sfc_ua, sfc_va, np.copy(sfc_hgt), 0, 3000, terrain) s06 = get_shear_hgt(sfc_ua, sfc_va, np.copy(sfc_hgt), 0, 6000, terrain) s010 = get_shear_hgt(sfc_ua, sfc_va, np.copy(sfc_hgt), 0, 10000, terrain) s13 = get_shear_hgt(sfc_ua, sfc_va, np.copy(sfc_hgt), 1000, 3000, terrain) s36 = get_shear_hgt(sfc_ua, sfc_va, np.copy(sfc_hgt), 3000, 6000, terrain) ebwd = get_shear_hgt(sfc_ua, sfc_va, np.copy(sfc_hgt), np.nanmin(eff_hgt,axis=0),\ (mu_el * 0.5), terrain) srh01_left, srh01_right = get_srh(sfc_ua, sfc_va, np.copy(sfc_hgt), 0, 1000, terrain) srh03_left, srh03_right = get_srh(sfc_ua, sfc_va, np.copy(sfc_hgt), 0, 3000, terrain) srh06_left, srh06_right = get_srh(sfc_ua, sfc_va, np.copy(sfc_hgt), 0, 6000, terrain) srhe_left, srhe_right = get_srh(sfc_ua, sfc_va, np.copy(sfc_hgt), \ np.nanmin(eff_hgt,axis=0), np.nanmax(eff_hgt,axis=0), terrain) ust_right, vst_right, ust_left, vst_left = \ get_storm_motion(sfc_ua, sfc_va, np.copy(sfc_hgt), terrain) sru01_right = umean01 - ust_right srv01_right = vmean01 - vst_right sru03_right = umean03 - ust_right srv03_right = vmean03 - vst_right sru06_right = umean06 - ust_right srv06_right = vmean06 - vst_right sru01_left = umean01 - ust_left srv01_left = vmean01 - vst_left sru03_left = umean03 - ust_left srv03_left = vmean03 - vst_left sru06_left = umean06 - ust_left srv06_left = vmean06 - vst_left Ust_right = np.sqrt( ust_right**2 + vst_right**2) Ust_left = np.sqrt( ust_left**2 + vst_left**2) Usr01_right = np.sqrt( sru01_right**2 + srv01_right**2) Usr03_right = np.sqrt( sru03_right**2 + srv03_right**2) Usr06_right = np.sqrt( sru06_right**2 + srv06_right**2) Usr01_left = np.sqrt( sru01_left**2 + srv01_left**2) Usr03_left = np.sqrt( sru03_left**2 + srv03_left**2) Usr06_left = np.sqrt( sru06_left**2 + srv06_left**2) if model != "era5": omega01 = get_mean_var_hgt(wap[t], hgt[t], 0, 1000, terrain, True, np.copy(p_3d)) omega03 = get_mean_var_hgt(wap[t], hgt[t], 0, 3000, terrain, True, np.copy(p_3d)) omega06 = get_mean_var_hgt(wap[t], hgt[t], 0, 6000, terrain, True, np.copy(p_3d)) #Kinematic kinematic_start = dt.datetime.now() x, y = np.meshgrid(lon,lat) dx, dy = mpcalc.lat_lon_grid_deltas(x,y) thetae10 = get_var_hgt_lvl(np.array(sfc_thetae_unit), np.copy(sfc_hgt), 10, terrain) thetae01 = get_mean_var_hgt(np.array(sfc_thetae_unit), np.copy(sfc_hgt), 0, 1000, terrain, True, np.copy(sfc_p_3d)) thetae03 = get_mean_var_hgt(np.array(sfc_thetae_unit), np.copy(sfc_hgt), 0, 3000, terrain, True, np.copy(sfc_p_3d)) F10, Fn10, Fs10, icon10, vgt10, conv10, vo10 = \ kinematics(u10, v10, thetae10, dx, dy, y) F01, Fn01, Fs01, icon01, vgt01, conv01, vo01 = \ kinematics(umean01, vmean01, thetae01, dx, dy, y) F03, Fn03, Fs03, icon03, vgt03, conv03, vo03 = \ kinematics(umean03, vmean03, thetae03, dx, dy, y) #Composites Rq = qmean01 / 12. windex = 5. * np.power( (melting_hgt/1000.) * Rq * (np.power( lr_freezing,2) - 30. + \ qmean01 - 2. * q_melting), 0.5) windex[np.isnan(windex)] = 0 gustex = (0.5 * windex) + (0.5 * Umean06) hmi = lr850_670 + dpd850 - dpd670 wmsi_ml = (ml_cape * te_diff) / 1000 dmi = lr750_500 + dpd700 - dpd500 mwpi_ml = (ml_cape / 100.) + (lr850_670 + dpd850 - dpd670) wmpi = np.sqrt( np.power(melting_hgt,2) * (lr_freezing / 1000. - 5.5e-3) + \ melting_hgt * (q1 - 1.5*q_melting) / 3.) /5. dmi[dmi<0] = 0 hmi[hmi<0] = 0 wmsi_ml[wmsi_ml<0] = 0 mwpi_ml[wmsi_ml<0] = 0 stp_fixed_left, stp_cin_left = get_tornado_pot( np.copy(ml_cin), np.copy(ml_lcl)\ , np.copy(sb_lcl), np.copy(s06), np.copy(ebwd), \ np.copy(sb_cape), np.copy(ml_cape), np.copy(srh01_left), \ np.copy(srhe_left)) if model != "era5": moshe = ((lr03 - 4.)/4.) * ((s01 - 8)/10.) * \ ((ebwd - 8)/10.) * ((maxtevv + 10.)/9.) moshe[moshe<0] = 0 mosh = ((lr03 - 4.)/4.) * ((s01 - 8)/10.) * ((maxtevv + 10.)/9.) mosh[mosh<0] = 0 ship = get_ship(np.copy(mu_cape), np.copy(muq), np.copy(s06), np.copy(lr700_500), \ get_var_p_lvl(sfc_ta, sfc_p_3d, 500), np.copy(melting_hgt) ) scp, scp_fixed = get_supercell_pot(mu_cape, np.copy(srhe_left), np.copy(srh01_left), np.copy(ebwd),\ np.copy(s06) ) sherb, eff_sherb = get_sherb(np.copy(s03), np.copy(ebwd), np.copy(lr03), np.copy(lr700_500)) k_index = get_var_p_lvl(np.copy(sfc_ta), sfc_p_3d, 850) \ - get_var_p_lvl(np.copy(sfc_ta), sfc_p_3d, 500) \ + get_var_p_lvl(np.copy(sfc_dp), sfc_p_3d, 850) - (dpd700) k_index[k_index<0] = 0 mlcs6 = ml_cape * np.power(s06, 1.67) mucs6 = mu_cape * np.power(s06, 1.67) sbcs6 = sb_cape * np.power(s06, 1.67) effcs6 = eff_cape * np.power(s06, 1.67) if model == "erai": cs6 = mod_cape[t] * np.power(s06, 1.67) wndg = get_wndg(np.copy(ml_cape), np.copy(ml_cin), np.copy(lr03), sfc_ua, sfc_va, np.copy(sfc_hgt), terrain,\ np.copy(sfc_p_3d)) sweat = get_sweat(np.copy(sfc_p_3d), np.copy(sfc_dp), np.copy(t_totals), sfc_ua, sfc_va) mmp = get_mmp(sfc_ua, sfc_va, np.copy(mu_cape), sfc_ta, np.copy(sfc_hgt), terrain, np.copy(sfc_p_3d)) dmgwind = (dcape/800.) * (Uwindinf / 8.) dmgwind_fixed = (dcape/800.) * (Umean800_600 / 8.) mburst = get_mburst(np.copy(sb_cape), np.copy(lr03), np.copy(v_totals), \ np.copy(dcape), np.copy(pwat), np.copy(tei), \ np.array(sfc_thetae_unit), \ np.copy(sfc_hgt), terrain) mburst[mburst<0] = 0 convgust_wet = np.sqrt( (Umean800_600**2) + (np.sqrt(2*dcape))**2 ) convgust_dry = np.sqrt( (Umean800_600**2) + (np.sqrt(dcape))**2 ) dcp = (dcape / 980.) * (mu_cape / 2000.) * (s06 / 20.) * (Umean06 / 16.) #Fill output output = fill_output(output, t, param, ps, "ml_cape", ml_cape) output = fill_output(output, t, param, ps, "mu_cape", mu_cape) output = fill_output(output, t, param, ps, "eff_cape", eff_cape) output = fill_output(output, t, param, ps, "sb_cape", sb_cape) output = fill_output(output, t, param, ps, "ml_cin", ml_cin) output = fill_output(output, t, param, ps, "mu_cin", mu_cin) output = fill_output(output, t, param, ps, "eff_cin", eff_cin) output = fill_output(output, t, param, ps, "sb_cin", sb_cin) output = fill_output(output, t, param, ps, "ml_lcl", ml_lcl) output = fill_output(output, t, param, ps, "mu_lcl", mu_lcl) output = fill_output(output, t, param, ps, "eff_lcl", eff_lcl) output = fill_output(output, t, param, ps, "sb_lcl", sb_lcl) output = fill_output(output, t, param, ps, "ml_el", ml_el) output = fill_output(output, t, param, ps, "mu_el", mu_el) output = fill_output(output, t, param, ps, "eff_el", eff_el) output = fill_output(output, t, param, ps, "sb_el", sb_el) output = fill_output(output, t, param, ps, "lr36", lr36) output = fill_output(output, t, param, ps, "lr_freezing", lr_freezing) output = fill_output(output, t, param, ps, "lr_subcloud", lr_subcloud) output = fill_output(output, t, param, ps, "qmean01", qmean01) output = fill_output(output, t, param, ps, "qmeansubcloud", qmeansubcloud) output = fill_output(output, t, param, ps, "mhgt", melting_hgt) output = fill_output(output, t, param, ps, "pwat", pwat) output = fill_output(output, t, param, ps, "dcape", dcape) output = fill_output(output, t, param, ps, "srh03_left", srh03_left) output = fill_output(output, t, param, ps, "srhe_left", srhe_left) output = fill_output(output, t, param, ps, "s03", s03) output = fill_output(output, t, param, ps, "s06", s06) output = fill_output(output, t, param, ps, "ebwd", ebwd) output = fill_output(output, t, param, ps, "Umean06", Umean06) output = fill_output(output, t, param, ps, "Umean800_600", Umean800_600) output = fill_output(output, t, param, ps, "wg10", wg10[t]) output = fill_output(output, t, param, ps, "U10", U10) output = fill_output(output, t, param, ps, "stp_cin_left", stp_cin_left) output = fill_output(output, t, param, ps, "stp_fixed_left", stp_fixed_left) output = fill_output(output, t, param, ps, "windex", windex) output = fill_output(output, t, param, ps, "gustex", gustex) output = fill_output(output, t, param, ps, "ship", ship) output = fill_output(output, t, param, ps, "scp", scp) output = fill_output(output, t, param, ps, "scp_fixed", scp_fixed) output = fill_output(output, t, param, ps, "k_index", k_index) output = fill_output(output, t, param, ps, "mlcape*s06", mlcs6) output = fill_output(output, t, param, ps, "mucape*s06", mucs6) output = fill_output(output, t, param, ps, "sbcape*s06", sbcs6) output = fill_output(output, t, param, ps, "effcape*s06", effcs6) output = fill_output(output, t, param, ps, "wndg", wndg) output = fill_output(output, t, param, ps, "sweat", sweat) output = fill_output(output, t, param, ps, "mmp", mmp) output = fill_output(output, t, param, ps, "convgust_wet", convgust_wet) output = fill_output(output, t, param, ps, "convgust_dry", convgust_dry) output = fill_output(output, t, param, ps, "dcp", dcp) output = fill_output(output, t, param, ps, "dmgwind", dmgwind) output = fill_output(output, t, param, ps, "dmgwind_fixed", dmgwind_fixed) output = fill_output(output, t, param, ps, "t_totals", t_totals) if full_params: if model == "erai": output = fill_output(output, t, param, ps, "cape*s06", cs6) if (model == "erai") | (model == "era5"): output = fill_output(output, t, param, ps, "cp", cp[t]) if model == "erai": output = fill_output(output, t, param, ps, "cape", mod_cape[t]) output = fill_output(output, t, param, ps, "lr01", lr01) output = fill_output(output, t, param, ps, "lr03", lr03) output = fill_output(output, t, param, ps, "lr13", lr13) output = fill_output(output, t, param, ps, "lr24", lr24) output = fill_output(output, t, param, ps, "wbz", hwb0) output = fill_output(output, t, param, ps, "qmean03", qmean03) output = fill_output(output, t, param, ps, "qmean06", qmean06) output = fill_output(output, t, param, ps, "q_melting", q_melting) output = fill_output(output, t, param, ps, "q1", q1) output = fill_output(output, t, param, ps, "q3", q3) output = fill_output(output, t, param, ps, "q6", q6) output = fill_output(output, t, param, ps, "sfc_thetae", sfc_thetae) output = fill_output(output, t, param, ps, "rhmin01", rhmin01) output = fill_output(output, t, param, ps, "rhmin03", rhmin03) output = fill_output(output, t, param, ps, "rhmin13", rhmin13) output = fill_output(output, t, param, ps, "rhminsubcloud", rhminsubcloud) output = fill_output(output, t, param, ps, "v_totals", v_totals) output = fill_output(output, t, param, ps, "c_totals", c_totals) output = fill_output(output, t, param, ps, "te_diff", te_diff) output = fill_output(output, t, param, ps, "tei", tei) output = fill_output(output, t, param, ps, "dpd700", dpd700) output = fill_output(output, t, param, ps, "dpd850", dpd850) output = fill_output(output, t, param, ps, "ddraft_temp", ddraft_temp) output = fill_output(output, t, param, ps, "Umeanwindinf", Umeanwindinf) output = fill_output(output, t, param, ps, "Umean01", Umean01) output = fill_output(output, t, param, ps, "Umean03", Umean03) output = fill_output(output, t, param, ps, "Uwindinf", Uwindinf) output = fill_output(output, t, param, ps, "U500", U500) output = fill_output(output, t, param, ps, "U1", U1) output = fill_output(output, t, param, ps, "U3", U3) output = fill_output(output, t, param, ps, "U6", U6) output = fill_output(output, t, param, ps, "Ust_left", Ust_left) output = fill_output(output, t, param, ps, "Usr01_left", Usr01_left) output = fill_output(output, t, param, ps, "Usr03_left", Usr03_left) output = fill_output(output, t, param, ps, "Usr06_left", Usr06_left) output = fill_output(output, t, param, ps, "scld", scld) output = fill_output(output, t, param, ps, "s01", s01) output = fill_output(output, t, param, ps, "s010", s010) output = fill_output(output, t, param, ps, "s13", s13) output = fill_output(output, t, param, ps, "s36", s36) output = fill_output(output, t, param, ps, "srh01_left", srh01_left) output = fill_output(output, t, param, ps, "srh06_left", srh06_left) output = fill_output(output, t, param, ps, "F10", F10) output = fill_output(output, t, param, ps, "Fn10", Fn10) output = fill_output(output, t, param, ps, "Fs10", Fs10) output = fill_output(output, t, param, ps, "icon10", icon10) output = fill_output(output, t, param, ps, "vgt10", vgt10) output = fill_output(output, t, param, ps, "conv10", conv10) output = fill_output(output, t, param, ps, "vo10", vo10) output = fill_output(output, t, param, ps, "hmi", hmi) output = fill_output(output, t, param, ps, "wmsi_ml", wmsi_ml) output = fill_output(output, t, param, ps, "dmi", dmi) output = fill_output(output, t, param, ps, "mwpi_ml", mwpi_ml) output = fill_output(output, t, param, ps, "wmpi", wmpi) output = fill_output(output, t, param, ps, "eff_sherb", eff_sherb) output = fill_output(output, t, param, ps, "sherb", sherb) if model == "erai": output = fill_output(output, t, param, ps, "cape*s06", cs6) output = fill_output(output, t, param, ps, "mburst", mburst) if model != "era5": output = fill_output(output, t, param, ps, "mosh", mosh) output = fill_output(output, t, param, ps, "moshe", moshe) output = fill_output(output, t, param, ps, "maxtevv", maxtevv) output = fill_output(output, t, param, ps, "omega01", omega01) output = fill_output(output, t, param, ps, "omega03", omega03) output = fill_output(output, t, param, ps, "omega06", omega06) output_data[t] = output print("SAVING DATA...") param_out = [] for param_name in param: temp_data = output_data[:,:,:,np.where(param==param_name)[0][0]] param_out.append(temp_data) #If the mhgt variable is zero everywhere, then it is likely that data has not been read. #In this case, all values are missing, set to zero. for t in np.arange(param_out[0].shape[0]): if param_out[np.where(param=="mhgt")[0][0]][t].max() == 0: for p in np.arange(len(param_out)): param_out[p][t] = np.nan if issave: save_netcdf(region, model, out_name, date_list, lat, lon, param, param_out, \ out_dtype = "f4", compress=True) print(dt.datetime.now() - tot_start)