def hxmdaz(jdbeg,jdend,outfile,comb,attr_in,nifiles,infile_h,infile_t,*,avg_hr=8,rank=4,lyyyyjjj=True,tzone=None,l2uam=False,lnew_mda8=False,tmpoutf=None): # Include functions from CAMxtools.combine.combine import combine import netCDF4 as ncdf4 from PseudoNetCDF.camxfiles.Memmaps import uamiv from CAMxtools.write.set_attr import set_attr from CAMxtools.tzone.scan_timezones import scan_timezones from CAMxtools.tzone.get_local_hrs import get_mda1s from CAMxtools.tzone.get_local_hrs import get_mda8s from CAMxtools.tzone.get_local_hrs import get_mda8s_a0 from CAMxtools._cnvt._data2fin import _data2fin from CAMxtools.write.wrt_ioapi import wrt_ioapi from CAMxtools.write.wrt_uamiv import wrt_uamiv import numpy as np # Check arguments l1tzone = False if tzone != None: l1tzone = True # If users specify a specific time zone, MATS MDA8 O3 is calculated based on the time zone. # Scan time zone over the domain tzfile = None dum, tzone_stlji = scan_timezones(tzfile, attr_in, loutf = False) tzone_ji = tzone_stlji[0,0,0,:,:].astype(np.int) tzones = np.unique(tzone_ji) if l1tzone: print("A SINGLE TIMEZONE, {} will be applied".format(tzone)) if tzone in tzones: ny = attr_in['NROWS'] nx = attr_in['NCOLS'] tzone_ji = np.zeros((ny,nx)).astype(np.int) + tzone tzones = [tzone] else: exit("YOUR TIMEZONE SPECIFIED IS OUT OF DOMAIN") # Get attribute nx = attr_in['NCOLS'] ny = attr_in['NROWS'] # Set a variable name spec = "O3" # Daily loop print (" 1. PROCESSING COMBINE") jdate = jdbeg while (jdate <= jdend): print ("Processing {}".format(jdate)) gdate = int(datetime.datetime.strptime(str(jdate),"%Y%j").strftime("%Y%m%d")) infile = [] for ifile in range(0,nifiles): if lyyyyjjj: infile.append(infile_h[ifile]+'.'+str(jdate)+'.'+infile_t[ifile]) else: infile.append(infile_h[ifile]+'.'+str(gdate)+'.'+infile_t[ifile]) tracernames, indata, ovarunits = combine(None,comb,nifiles,infile,lverbose=False,loutf=False,lovarunits=True) s = tracernames.index(spec) if jdate == jdbeg : conc_hrs_utc = indata[s,:,0,:,:] if jdate > jdbeg : conc_hrs_utc = np.append(conc_hrs_utc,indata[s,:,0,:,:],axis=0) #As len(s) = 1, the 2nd dimension, nt is axis=0 jdate = int((datetime.datetime.strptime(str(jdate),"%Y%j") + datetime.timedelta(days=1)).strftime("%Y%j")) del indata print (" 2. PROCESSING MDA{} FOR ALL DAYS".format(avg_hr)) nd = jdend - jdbeg if avg_hr == 1: mdaz = get_mda1s(conc_hrs_utc, tzone_ji, nd, nx, ny) elif avg_hr == 8: if lnew_mda8: mdaz = get_mda8s_a0(conc_hrs_utc, tzone_ji, nd, nx, ny) else: mdaz = get_mda8s(conc_hrs_utc, tzone_ji, nd, nx, ny) else: exit("avg_hr must be either 1 or 8.") # Prepare MDAZ if asked lout_mdaz = False if not tmpoutf == None: lout_mdaz = True if lout_mdaz: data2sav = np.zeros((1,nd,1,ny,nx)) data2sav[0,:,0,:,:] = mdaz # Write a binary file for MDAZ attr_in['TSTEP']=240000 fout = _data2fin(data2sav, tracernames, attr_in) if l2uam: wrt_uamiv(tmpoutf, fout, lsurf = True, ounits = ovarunits) else: wrt_ioapi(tmpoutf, fout, lsurf = True, ounits = ovarunits) # Find X highest if rank == 1: rank_name = "FIRST" elif rank == 4: rank_name = "FOURTH" else: exit("rank must be either 1 or 4.") print (" 3. PROCESSING {} HIGHEST".format(rank_name)) data2sav = np.zeros((1,1,1,ny,nx)) data2sav[0,0,0,:,:] = np.sort(mdaz,axis=0)[mdaz.shape[0]-rank,...] #data2sav[nspc,nt,nz,ny,nx] # Write a binary file for HXMDAZ fout = _data2fin(data2sav, tracernames, attr_in) if l2uam: wrt_uamiv(outfile, fout, lsurf = True, ounits = ovarunits) else: wrt_ioapi(outfile, fout, lsurf = True, ounits = ovarunits)
def hxmdaz_naaqs(jdbeg, jdend, outfile, csvfile, comb, attr_in, nifiles, infile_h, infile_t, *, avg_hr=8, rank=4, lyyyyjjj=True, tzone=None, l2uam=False, lnew_mda8=False, tmpoutf=None): # Include functions from CAMxtools.combine.combine import combine import netCDF4 as ncdf4 from PseudoNetCDF.camxfiles.Memmaps import uamiv from CAMxtools.write.set_attr import set_attr from CAMxtools.tzone.scan_timezones import scan_timezones from CAMxtools.tzone.get_local_hrs import get_mda1s from CAMxtools.tzone.get_local_hrs import get_mda8 from CAMxtools._cnvt._data2fin import _data2fin from CAMxtools.write.wrt_ioapi import wrt_ioapi from CAMxtools.write.wrt_uamiv import wrt_uamiv from CAMxtools.write.wrt_uamiv import wrt_uamiv from CAMxtools.write.wrt_uamiv import wrt_uamiv from CAMxtools.write.wrt_uamiv import wrt_uamiv from CAMxtools.write.wrt_uamiv import wrt_uamiv from CAMxtools.naaqs.wrt_csv_for_naaqs import wrt_csv_for_naaqs import numpy as np import gc # Check arguments l1tzone = False if tzone != None: l1tzone = True # If users specify a specific time zone, MATS MDA8 O3 is calculated based on the time zone. # Scan time zone over the domain tzfile = None dum, tzone_stlji = scan_timezones(tzfile, attr_in, loutf=False) tzone_ji = tzone_stlji[0, 0, 0, :, :].astype(np.int) tzones = np.unique(tzone_ji) if l1tzone: print("A SINGLE TIMEZONE, {} will be applied".format(tzone)) if tzone in tzones: ny = attr_in['NROWS'] nx = attr_in['NCOLS'] tzone_ji = np.zeros((ny, nx)).astype(np.int) + tzone tzones = [tzone] else: exit("YOUR TIMEZONE SPECIFIED IS OUT OF DOMAIN") # Get attribute nx = attr_in['NCOLS'] ny = attr_in['NROWS'] # Set a variable name spec = "O3" # Daily loop jdate = jdbeg while (jdate <= jdend): print("Processing {}".format(jdate)) gdate = int( datetime.datetime.strptime(str(jdate), "%Y%j").strftime("%Y%m%d")) infile = [] for ifile in range(0, nifiles): if lyyyyjjj: infile.append(infile_h[ifile] + '.' + str(jdate) + '.' + infile_t[ifile]) else: infile.append(infile_h[ifile] + '.' + str(gdate) + '.' + infile_t[ifile]) print(" 1. PROCESSING COMBINE") tracernames, indata2, ovarunits = combine(None, comb, nifiles, infile, lverbose=False, loutf=False, lovarunits=True) if (jdate > jdbeg): # One time execution - Check 'O3' is the first output species and index output trcnames which excludes O3 from tracernames if jdate == jdbeg + 1: s = tracernames.index(spec) if s != 0: exit('O3 must be the first species in combine spec_def') ntracers = len(tracernames) trcnames = tracernames[1:] print(" 2. PROCESSING METRICS FOR PREVIOUS DAY") concs_48_utc = np.append(indata1[:, :, 0, :, :], indata2[:, :, 0, :, :], axis=1) conc_o3_48_utc = concs_48_utc[ np.newaxis, s, :, :, :] #concs_48_utc[nspc,nt,ny,nx], conc_o3_48_utc[1,nt,ny,nx] if avg_hr == 1: dmdaz_1day, dind_hr_1day = get_mda1( conc_o3_48_utc, tzone_ji, nx, ny) # dmda1_1day[1,ny,nx], dind_hr_1day[1,ny,nx] elif avg_hr == 8: dmdaz_1day, dind_hr_1day = get_mda8( conc_o3_48_utc, tzone_ji, nx, ny, lnew_mda8=lnew_mda8 ) # dmda1_1day[1,ny,nx], dind_hr_1day[1,ny,nx] else: exit("avg_hr must be either 1 or 8.") # Set trcs_dmdaz_1day trcs_dmdaz_1day = np.zeros((ntracers - 1, ny, nx)) for i in range(nx): for j in range(ny): if avg_hr == 1: trcs_dmdaz_1day[:, j, i] = concs_48_utc[ 1:, np.squeeze(dind_hr_1day)[j, i], j, i] elif avg_hr == 8: trcs_daz_1day_1cell = np.apply_along_axis( np.convolve, axis=1, arr=concs_48_utc[1:, tzone_ji[j, i]:tzone_ji[j, i] + 31, j, i], v=[1 / 8.] * 8, mode='valid') #trcs_daz_1day_1cell[nspc-1,24] trcs_dmdaz_1day[:, j, i] = trcs_daz_1day_1cell[:, np.squeeze( dind_hr_1day )[j, i]] else: exit("avg_hr must be either 1 or 8.") gc.collect() if jdate == jdbeg + 1: dmdazs = dmdaz_1day #dmdazs[nd,ny,nx] dind_hrs = dind_hr_1day #dind_hrs[nd,ny,nx] trcs_dmdazs = np.array([trcs_dmdaz_1day ]) #trcs_dmdazs[nd,nspc-1,ny,nx] if jdate > jdbeg + 1: dmdazs = np.append(dmdazs, dmdaz_1day, axis=0) dind_hrs = np.append(dind_hrs, dind_hr_1day, axis=0) trcs_dmdazs = np.append(trcs_dmdazs, np.array([trcs_dmdaz_1day]), axis=0) indata1 = indata2 jdate = int((datetime.datetime.strptime(str(jdate), "%Y%j") + datetime.timedelta(days=1)).strftime("%Y%j")) gc.collect() del indata2 del indata1 gc.collect() # Prepare MDAZ if asked lout_mdaz = False if not tmpoutf == None: lout_mdaz = True if lout_mdaz: nd = jdend - jdbeg data2sav = np.zeros((ntracers, nd, 1, ny, nx)) data2sav[0, :, 0, :, :] = dmdazs data2sav[1:, :, 0, :, :] = np.einsum('jikl->ijkl', trcs_dmdazs) # Write a binary file for MDAZ attr_in['TSTEP'] = 240000 fout = _data2fin(data2sav, tracernames, attr_in) if l2uam: wrt_uamiv(tmpoutf, fout, lsurf=True, ounits=ovarunits) else: wrt_ioapi(tmpoutf, fout, lsurf=True, ounits=ovarunits) gc.collect() # Find X highest if rank == 1: rank_name = "FIRST" elif rank == 4: rank_name = "FOURTH" elif rank == 0: rank_name = "AVERAGE" else: exit("rank must be either 1 or 4 or 0.") if rank == 0: print(" 3. PROCESSING AVERAGE") else: print(" 3. PROCESSING {} HIGHEST".format(rank_name)) data2sav = np.zeros((ntracers, 1, 1, ny, nx)) nd = jdend - jdbeg if (nd < rank): print('Your no. of days is less than the rank you specified.') print('No. of days from input files = {}'.format(nd)) print('Rank you select is = {}'.format(rank)) exit( 'Either reduce your rank or increase no. of days from input files') if rank == 0: data2sav[0, 0, 0, :, :] = np.mean( dmdazs, axis=0) #data2sav[nspc,nt,nz,ny,nx], dmdazs[nd,ny,nx] data2sav[1:, 0, 0, :, :] = np.mean(trcs_dmdazs, axis=0) #trcs_dmdazs[nd,nspc-1,ny,nx] else: ind = np.argsort(dmdazs, axis=0)[nd - rank, ...] #dmdazs[nd,ny,nx], ind[ny,nx] gr = np.ogrid[0:dmdazs.shape[0], 0:dmdazs.shape[1], 0:dmdazs.shape[2]] gr[0] = ind data2sav[0, 0, 0, :, :] = dmdazs[gr] #data2sav[nspc,nt,nz,ny,nx] for i in range(nx): for j in range(ny): data2sav[1:, 0, 0, j, i] = trcs_dmdazs[ind[j, i], :, j, i] # Write a csv file if rank == 0: jdays = np.zeros( (ny, nx)) + attr_in['SDATE'] # Average of MDAZ, set the beginning date hours = np.zeros((ny, nx)) # Average of MDAZ, set zeros. else: jdays = attr_in['SDATE'] + ind[:, :] hours = np.zeros( (ny, nx)) + dind_hrs[gr][0, :, :] #dind_hrs[gr].shape = (1,ny,nx) data2csv = np.zeros((ntracers, ny, nx)) data2csv = data2sav[:, 0, 0, :, :] wrt_csv_for_naaqs(csvfile, tracernames, data2csv, jdays, hours) gc.collect() # Write a binary file for HXMDAZ fout = _data2fin(data2sav, tracernames, attr_in) if l2uam: wrt_uamiv(outfile, fout, lsurf=True, ounits=ovarunits) else: wrt_ioapi(outfile, fout, lsurf=True, ounits=ovarunits) gc.collect()
def psd_pm10_2nddavg_annavg(jdbeg, jdend, out_anndavg, out_2nddavg, csv_anndavg, csv_2nddavg, comb, attr_in, nifiles, infile_h, infile_t, *, lyyyyjjj=True, tzone=None, l2uam=False, tmpoutf=None): # Include functions from CAMxtools.combine.combine import combine import netCDF4 as ncdf4 from PseudoNetCDF.camxfiles.Memmaps import uamiv from CAMxtools.write.set_attr import set_attr from CAMxtools.tzone.scan_timezones import scan_timezones from CAMxtools.tzone.get_local_hrs import get_davg from CAMxtools._cnvt._data2fin import _data2fin from CAMxtools.write.wrt_ioapi import wrt_ioapi from CAMxtools.write.wrt_uamiv import wrt_uamiv from CAMxtools.psd.wrt_csv_for_psd import wrt_csv_for_psd import numpy as np # Check arguments l1tzone = False if tzone != None: l1tzone = True # If users specify a specific time zone, MATS MDA8 O3 is calculated based on the time zone. # Scan time zone over the domain tzfile = None dum, tzone_stlji = scan_timezones(tzfile, attr_in, loutf=False) tzone_ji = tzone_stlji[0, 0, 0, :, :].astype(np.int) tzones = np.unique(tzone_ji) if l1tzone: print("A SINGLE TIMEZONE, {} will be applied".format(tzone)) if tzone in tzones: ny = attr_in['NROWS'] nx = attr_in['NCOLS'] tzone_ji = np.zeros((ny, nx)).astype(np.int) + tzone tzones = [tzone] else: exit("YOUR TIMEZONE SPECIFIED IS OUT OF DOMAIN") # Get attribute nx = attr_in['NCOLS'] ny = attr_in['NROWS'] # Daily loop jdate = jdbeg while (jdate <= jdend): print("Processing {}".format(jdate)) gdate = int( datetime.datetime.strptime(str(jdate), "%Y%j").strftime("%Y%m%d")) infile = [] for ifile in range(0, nifiles): if lyyyyjjj: infile.append(infile_h[ifile] + '.' + str(jdate) + '.' + infile_t[ifile]) else: infile.append(infile_h[ifile] + '.' + str(gdate) + '.' + infile_t[ifile]) print(" 1. PROCESSING COMBINE") tracernames, indata2, ovarunits = combine(None, comb, nifiles, infile, lverbose=False, loutf=False, lovarunits=True) if (jdate > jdbeg): print(" 2. PROCESSING DAILY AVERAGE FOR PREVIOUS DAY") concs_48_utc = np.append(indata1[:, :, 0, :, :], indata2[:, :, 0, :, :], axis=1) davg_1day = get_davg(concs_48_utc, tzone_ji, nx, ny) if jdate == jdbeg + 1: davgs = np.array([davg_1day]) #davgs[nd,nspc,ny,nx] if jdate > jdbeg + 1: davgs = np.append(davgs, np.array([davg_1day]), axis=0) indata1 = indata2 jdate = int((datetime.datetime.strptime(str(jdate), "%Y%j") + datetime.timedelta(days=1)).strftime("%Y%j")) del indata2 del indata1 # Prepare DAVG if asked nspc = len(tracernames) lout_davg = False if not tmpoutf == None: lout_davg = True if lout_davg: nd = jdend - jdbeg data2sav = np.zeros((nspc, nd, 1, ny, nx)) for ispc in range(nspc): data2sav[ispc, :, 0, :, :] = davgs[:, ispc, :, :] # Write a binary file for DAVG attr_in['TSTEP'] = 240000 fout = _data2fin(data2sav, tracernames, attr_in) if l2uam: wrt_uamiv(tmpoutf, fout, lsurf=True, ounits=ovarunits) else: wrt_ioapi(tmpoutf, fout, lsurf=True, ounits=ovarunits) # Calculate 2nd highest daily average print(" 3. PROCESSING 2ND HIGHEST DAILY AVERAGE") data2sav = np.zeros((nspc, 1, 1, ny, nx)) rank = 2 #data2sav[:,0,0,:,:] = np.sort(davgs,axis=0)[davgs.shape[0]-rank,...] #data2sav[nspc,nt,nz,ny,nx], davgs[nd,nspc,ny,nx] ind = np.argsort(davgs, axis=0)[ davgs.shape[0] - rank, ...] #data2sav[nspc,nt,nz,ny,nx], davgs[nd,nspc,ny,nx], ind[nsp,ny,nx] gr = np.ogrid[0:davgs.shape[0], 0:davgs.shape[1], 0:davgs.shape[2], 0:davgs.shape[3]] gr[0] = ind data2sav[:, 0, 0, :, :] = davgs[gr] #data2sav[:,0,0,:,:] = np.mean(davgs,axis=0) #data2sav[nspc,nt,nz,ny,nx], davgs[nd,nspc,ny,nx] # Write a csv file jdays = attr_in['SDATE'] + ind[ 0, :, :] # Annual average, set the beginning date hours = np.zeros((ny, nx)) # daily average, set zeros data2csv = np.zeros((nspc, ny, nx)) data2csv = data2sav[:, 0, 0, :, :] wrt_csv_for_psd(csv_2nddavg, tracernames, data2csv, jdays, hours) # Write a binary file fout = _data2fin(data2sav, tracernames, attr_in) if l2uam: wrt_uamiv(out_2nddavg, fout, lsurf=True, ounits=ovarunits) else: wrt_ioapi(out_2nddavg, fout, lsurf=True, ounits=ovarunits) # Calculate grand average print(" 4. PROCESSING GRAND AVERAGE") data2sav = np.zeros((nspc, 1, 1, ny, nx)) data2sav[:, 0, 0, :, :] = np.mean( davgs, axis=0) #data2sav[nspc,nt,nz,ny,nx], davgs[nd,nspc,ny,nx] # Write a csv file jdays = np.zeros( (ny, nx)) + attr_in['SDATE'] # Annual average, set the beginning date hours = np.zeros((ny, nx)) # Annual average, set zeros data2csv = np.zeros((nspc, ny, nx)) data2csv = data2sav[:, 0, 0, :, :] wrt_csv_for_psd(csv_anndavg, tracernames, data2csv, jdays, hours) # Write a binary file fout = _data2fin(data2sav, tracernames, attr_in) if l2uam: wrt_uamiv(out_anndavg, fout, lsurf=True, ounits=ovarunits) else: wrt_ioapi(out_anndavg, fout, lsurf=True, ounits=ovarunits)
def prep_pm_mats(jdbeg,jdend,outfile,comb,attr_in,nifiles,infile_h,infile_t,*,lyyyyjjj=True,tzone=None,lno_edges=True,convfac=1.): # Include functions from CAMxtools.combine.combine import combine import netCDF4 as ncdf4 from PseudoNetCDF.camxfiles.Memmaps import uamiv from CAMxtools.write.set_attr import set_attr from CAMxtools.tzone.scan_timezones import get_lcc from CAMxtools.regrid.projection import ll2latlon from CAMxtools.regrid.projection import lcp2latlon from CAMxtools.tzone.scan_timezones import scan_timezones from CAMxtools.tzone.get_local_hrs import get_davg from CAMxtools.MATS.wrt_csv_for_pm_mats import wrt_csv_for_pm_mats import numpy as np # Check arguments l1tzone = False if tzone != None: l1tzone = True # If users specify a specific time zone, MATS MDA8 O3 is calculated based on the time zone. # Scan time zone over the domain tzfile = None dum, tzone_stlji = scan_timezones(tzfile, attr_in, loutf = False) tzone_ji = tzone_stlji[0,0,0,:,:].astype(np.int) tzones = np.unique(tzone_ji) if l1tzone: print("A SINGLE TIMEZONE, {} will be applied".format(tzone)) if tzone in tzones: ny = attr_in['NROWS'] nx = attr_in['NCOLS'] tzone_ji = np.zeros((ny,nx)).astype(np.int) + tzone tzones = [tzone] else: exit("YOUR TIMEZONE SPECIFIED IS OUT OF DOMAIN") # Get attribute dxy = attr_in['XCELL'] nx = attr_in['NCOLS'] ny = attr_in['NROWS'] x0 = attr_in['XORIG'] y0 = attr_in['YORIG'] # Get lat and lon at the center of grid cells if attr_in['GDTYP'] == 1: lats, lons = ll2latlon (x0, y0, dxy, nx, ny, lno_edges = lno_edges) elif attr_in['GDTYP'] == 2: lcc = get_lcc(attr_in) lats, lons = lcp2latlon (lcc, dxy, nx, ny, lno_edges = lno_edges) else: print("Your GDTYP is {}".format(attr_in['GDTYP'])) exit("This program currently supports LATLON (GDTYP = 1) and LCP (GDTYP = 2) only.") # Daily loop jdays = [] jdate = jdbeg while (jdate <= jdend): jdays.append(jdate) print ("Processing {}".format(jdate)) gdate = int(datetime.datetime.strptime(str(jdate),"%Y%j").strftime("%Y%m%d")) infile = [] for ifile in range(0,nifiles): if lyyyyjjj: infile.append(infile_h[ifile]+'.'+str(jdate)+'.'+infile_t[ifile]) else: infile.append(infile_h[ifile]+'.'+str(gdate)+'.'+infile_t[ifile]) print (" 1. PROCESSING COMBINE") tracernames, indata2 = combine(None,comb,nifiles,infile,lverbose=False,loutf=False) if (jdate > jdbeg): print (" 2. PROCESSING DAILY AVERAGE FOR PREVIOUS DAY") concs_48_utc = np.append(indata1[:,:,0,:,:],indata2[:,:,0,:,:],axis=1) davg_1day = get_davg(concs_48_utc, tzone_ji, nx, ny) if jdate == jdbeg + 1: davgs = np.array([davg_1day]) #davgs[nd,nspc,ny,nx] if jdate > jdbeg + 1: davgs = np.append(davgs,np.array([davg_1day]),axis=0) indata1 = indata2 jdate = int((datetime.datetime.strptime(str(jdate),"%Y%j") + datetime.timedelta(days=1)).strftime("%Y%j")) del indata2 del indata1 # Exclude buffer cells if needed if lno_edges: davgs_chked = davgs[:,:,1:-1,1:-1] else: davgs_chked = davgs # Write csv file wrt_csv_for_pm_mats(outfile,davgs_chked,jdays,lats,lons,tracernames,convfac)
def regrid(outfile, project, utmzon, plon, plat, tlat1, tlat2, xorg, yorg, dxy_out, nx_out, ny_out, comb, attr_in, nstep, nifiles, infile, *, lno_edges=True, l2uam=False, lnearest=False, ijfile=None): # Include functions from CAMxtools.combine.combine import combine import netCDF4 as ncdf4 from PseudoNetCDF.camxfiles.Memmaps import uamiv from CAMxtools.write.set_attr import set_attr from CAMxtools.tzone.scan_timezones import get_lcc from CAMxtools.regrid.projection import ll2latlon from CAMxtools.regrid.projection import lcp2latlon from CAMxtools.regrid.projection import ll2lcp from CAMxtools._cnvt._data2fin import _data2fin from CAMxtools.write.wrt_ioapi import wrt_ioapi from CAMxtools.write.wrt_uamiv import wrt_uamiv import numpy as np import csv # 1. COMBINE print(" 1. PROCESSING COMBINE") tracernames, indata, ovarunits = combine(None, comb, nifiles, infile, lsurf=False, lverbose=False, loutf=False, lovarunits=True) # 2. REGRID print(" 2. PROCESSING REGRID") # 2.1 Set attributes of output file if l2uam: NA_val = 0. else: NA_val = -9.999E36 attr_out = {} for key, value in attr_in.items(): if key == 'XCELL': attr_out[key] = dxy_out elif key == 'YCELL': attr_out[key] = dxy_out elif key == 'XORIG': attr_out[key] = xorg elif key == 'YORIG': attr_out[key] = yorg elif key == 'NCOLS': attr_out[key] = nx_out elif key == 'NROWS': attr_out[key] = ny_out elif key == 'GDTYP': if project == 'LATLON': attr_out[key] = 1 elif project == 'LAMBERT': attr_out[key] = 2 else: exit() elif key == 'P_ALP': if project == 'LATLON': attr_out[key] = NA_val elif project == 'LAMBERT': attr_out[key] = tlat1 else: exit() elif key == 'P_BET': if project == 'LATLON': attr_out[key] = NA_val elif project == 'LAMBERT': attr_out[key] = tlat2 else: exit() elif key == 'P_GAM': if project == 'LATLON': attr_out[key] = NA_val elif project == 'LAMBERT': attr_out[key] = plon else: exit() elif key == 'XCENT': if project == 'LATLON': attr_out[key] = NA_val elif project == 'LAMBERT': attr_out[key] = plon else: exit() elif key == 'YCENT': if project == 'LATLON': attr_out[key] = NA_val elif project == 'LAMBERT': attr_out[key] = plat else: exit() else: attr_out[key] = value if ijfile == None: # 2.2a.1 Get lat and lon at center of grid cells for output if attr_out['GDTYP'] == 1: lats_out, lons_out = ll2latlon(xorg, yorg, dxy_out, nx_out, ny_out, lno_edges=False) elif attr_out['GDTYP'] == 2: lcc_out = get_lcc(attr_out) lats_out, lons_out = lcp2latlon(lcc_out, dxy_out, nx_out, ny_out, lno_edges=False) else: print("Your GDTYP is {}".format(attr_in['GDTYP'])) exit( "This program currently supports LATLON (GDTYP = 1) and LCP (GDTYP = 2) only." ) # 2.2a.2 Get x and y values of input file corresponding to each output grid cell if attr_in['GDTYP'] == 1: xpos = lons_out ypos = lats_out elif attr_in['GDTYP'] == 2: x0_in = attr_in['XORIG'] y0_in = attr_in['YORIG'] lcc_in = get_lcc(attr_in) xpos, ypos = ll2lcp(lons_out, lats_out, lcc_in, ny_out, nx_out, x0_in, y0_in) else: print("Your GDTYP is {}".format(attr_in['GDTYP'])) exit( "This program currently supports LATLON (GDTYP = 1) and LCP (GDTYP = 2) only." ) # 2.2a.3 Get grid index of input file corresponding to each output grid cell dxy_in = attr_in['XCELL'] x0 = attr_in['XORIG'] y0 = attr_in['YORIG'] nx_in = attr_in['NCOLS'] ny_in = attr_in['NROWS'] if lnearest: if attr_in['GDTYP'] == 1: lats_in, lons_in = ll2latlon(x0, y0, dxy_in, nx_in, ny_in, lno_edges=False) elif attr_in['GDTYP'] == 2: lats_in, lons_in = lcp2latlon(lcc_in, dxy_in, nx_in, ny_in, lno_edges=False) else: print("Your GDTYP is {}".format(attr_in['GDTYP'])) exit( "This program currently supports LATLON (GDTYP = 1) and LCP (GDTYP = 2) only." ) iloc, jloc = find_ij(dxy_in, x0, y0, nx_in, ny_in, nx_out, ny_out, xpos, ypos, lno_edges=True, lnearest=lnearest, lats_in=lats_in, lons_in=lons_in, lats_out=lats_out, lons_out=lons_out) else: iloc, jloc = find_ij(dxy_in, x0, y0, nx_in, ny_in, nx_out, ny_out, xpos, ypos, lno_edges=True) else: # 2.2b Read index mapping from ijfile iloc = np.zeros((ny_out, nx_out), dtype=int) jloc = np.zeros((ny_out, nx_out), dtype=int) with open(ijfile) as csvfile: lines = csv.reader(csvfile, delimiter=',', quotechar='|') # skip the first header line for line in lines: if line[0][0] == 'i': continue # skip the first header line i = int(line[0].split()[0]) j = int(line[1].split()[0]) iloc[j, i] = int(line[2].split()[0]) jloc[j, i] = int(line[3].split()[0]) # 2.5 Mapping and prepare data to save nspc = len(tracernames) nz = attr_out['NLAYS'] data2sav = np.zeros((nspc, nstep, nz, ny_out, nx_out)) for j in range(ny_out): for i in range(nx_out): data2sav[:, :, :, j, i] = indata[:, :, :, jloc[j, i], iloc[j, i]] del indata # 3. WRITE A BINARY FILE fout = _data2fin(data2sav, tracernames, attr_out) if l2uam: wrt_uamiv(outfile, fout, lsurf=False, ounits=ovarunits) else: wrt_ioapi(outfile, fout, lsurf=False, ounits=ovarunits)
def prep_o3_mats(jdbeg, jdend, outfile, comb, attr_in, nifiles, infile_h, infile_t, *, lyyyyjjj=True, tzone=None, lno_edges=True, convfac=1000., lnew_mda8=False): # Include functions from CAMxtools.combine.combine import combine import netCDF4 as ncdf4 from PseudoNetCDF.camxfiles.Memmaps import uamiv from CAMxtools.write.set_attr import set_attr from CAMxtools.tzone.scan_timezones import get_lcc from CAMxtools.regrid.projection import ll2latlon from CAMxtools.regrid.projection import lcp2latlon from CAMxtools.tzone.scan_timezones import scan_timezones from CAMxtools.tzone.get_local_hrs import get_mda8s from CAMxtools.tzone.get_local_hrs import get_mda8s_a0 from CAMxtools.MATS.wrt_csv_for_o3_mats import wrt_csv_for_o3_mats import numpy as np # Check arguments l1tzone = False if tzone != None: l1tzone = True # If users specify a specific time zone, MATS MDA8 O3 is calculated based on the time zone. # Scan time zone over the domain tzfile = None dum, tzone_stlji = scan_timezones(tzfile, attr_in, loutf=False) tzone_ji = tzone_stlji[0, 0, 0, :, :].astype(np.int) tzones = np.unique(tzone_ji) if l1tzone: print("A SINGLE TIMEZONE, {} will be applied".format(tzone)) if tzone in tzones: ny = attr_in['NROWS'] nx = attr_in['NCOLS'] tzone_ji = np.zeros((ny, nx)).astype(np.int) + tzone tzones = [tzone] else: exit("YOUR TIMEZONE SPECIFIED IS OUT OF DOMAIN") # Get attribute dxy = attr_in['XCELL'] nx = attr_in['NCOLS'] ny = attr_in['NROWS'] x0 = attr_in['XORIG'] y0 = attr_in['YORIG'] # Get lat and lon at the center of grid cells if attr_in['GDTYP'] == 1: lats, lons = ll2latlon(x0, y0, dxy, nx, ny, lno_edges=lno_edges) elif attr_in['GDTYP'] == 2: lcc = get_lcc(attr_in) lats, lons = lcp2latlon(lcc, dxy, nx, ny, lno_edges=lno_edges) else: print("Your GDTYP is {}".format(attr_in['GDTYP'])) exit( "This program currently supports LATLON (GDTYP = 1) and LCP (GDTYP = 2) only." ) # Set a variable name spec = "O3" # Daily loop print(" 1. PROCESSING COMBINE") jdays = [] jdate = jdbeg while (jdate <= jdend): jdays.append(jdate) print("Processing {}".format(jdate)) gdate = int( datetime.datetime.strptime(str(jdate), "%Y%j").strftime("%Y%m%d")) infile = [] for ifile in range(0, nifiles): if lyyyyjjj: infile.append(infile_h[ifile] + '.' + str(jdate) + '.' + infile_t[ifile]) else: infile.append(infile_h[ifile] + '.' + str(gdate) + '.' + infile_t[ifile]) tracernames, indata = combine(None, comb, nifiles, infile, lverbose=False, loutf=False) s = tracernames.index(spec) if jdate == jdbeg: conc_hrs_utc = indata[s, :, 0, :, :] if jdate > jdbeg: conc_hrs_utc = np.append( conc_hrs_utc, indata[s, :, 0, :, :], axis=0) #As len(s) = 1, the 2nd dimension, nt is axis=0 jdate = int((datetime.datetime.strptime(str(jdate), "%Y%j") + datetime.timedelta(days=1)).strftime("%Y%j")) del indata print(" 2. PROCESSING MDA8 FOR ALL DAYS") nd = jdend - jdbeg if lnew_mda8: mda8 = get_mda8s_a0(conc_hrs_utc, tzone_ji, nd, nx, ny) else: mda8 = get_mda8s(conc_hrs_utc, tzone_ji, nd, nx, ny) # Exclude buffer cells if needed if lno_edges: mda8_chked = mda8[:, 1:-1, 1:-1] else: mda8_chked = mda8 # Write csv file wrt_csv_for_o3_mats(outfile, mda8_chked, jdays, lats, lons, convfac)
def day_loop_for_vis(jdbeg, jdend, outfile, xref, comb, nifiles, infile_h, infile_t, class_lst, *, lyyyyjjj=True, tzone=None): # Include functions from CAMxtools.combine.combine import combine from CAMxtools.vis.calc_dv import calc_dv from CAMxtools.avg.get_davg_at_cells import get_davg_at_cells import numpy as np # Begin the script jdate = jdbeg if Path(outfile).exists(): os.remove(outfile) fout = open(outfile, 'a') while (jdate <= jdend): print("Processing {}".format(jdate)) gdate = int( datetime.datetime.strptime(str(jdate), "%Y%j").strftime("%Y%m%d")) infile = [] for ifile in range(0, nifiles): if lyyyyjjj: infile.append(infile_h[ifile] + '.' + str(jdate) + '.' + infile_t[ifile]) else: infile.append(infile_h[ifile] + '.' + str(gdate) + '.' + infile_t[ifile]) print(" 1. PROCESSING COMBINE") tracernames, indata2 = combine(None, comb, nifiles, infile, lverbose=False, loutf=False) jdatem1 = int((datetime.datetime.strptime(str(jdate), "%Y%j") + datetime.timedelta(days=-1)).strftime("%Y%j")) tmp_davg_outf = "tmp_davg_out.csv" tmp_dv_outf = "tmp_dv_out.csv" if (jdate > jdbeg): print(" 2. PROCESSING DAILY AVERAGE FOR PREVIOUS DAY") indata = np.append(indata1, indata2, axis=1) get_davg_at_cells(tracernames, indata, tmp_davg_outf, xref, jdatem1, tzone=tzone) print(" 3. PROCESSING DECI-VIEW FOR PREVIOUS DAY") calc_dv(tmp_davg_outf, tmp_dv_outf, class_lst) os.remove(tmp_davg_outf) print(" 4. APPENDING PREVIOUS DAY DECI-VIEW") fin = open(tmp_dv_outf, 'r') header = fin.readline() # no. of header lines is one. if jdate == (jdbeg + 1): fout.write('%s' % (str(header))) for line in fin: fout.write('%s' % (str(line))) fin.close() os.remove(tmp_dv_outf) indata1 = indata2 jdate = int((datetime.datetime.strptime(str(jdate), "%Y%j") + datetime.timedelta(days=1)).strftime("%Y%j")) del indata2 del indata1 del indata fout.close()