def nccopyvariable(ncin,ncout,varin,varout=None,copyvalues=False,copyattr=True): ''' create a new netcdf variable with the same dimensions and attributes as the original variable. Optionally, the values itself can be copied as well ncin: input netcdf file ncout output netcdf file varin: input variable varout (optional): output variable. If None, it is equal to varin copyvalues: copy values (only possible if the dimensions of source and target variable are of the same size) ''' if varout == None: varoutdef = varin else: varoutdef = varout if varoutdef not in ncout.variables: for edimension in ncin.variables[varin].dimensions: if edimension not in ncout.dimensions: nccopydimension(ncin,ncout,edimension,copyvalues=True) #ncout.createVariable(variable,ncin.variables[variable].typecode(),ncin.variables[variable].dimensions) # workaround: functions are now considered an output to be float64: better make the function make arrays # that have the same output type!! create variable according to the output of dataouttemp!! ncout.createVariable(varoutdef,ncin.variables[varin].typecode(),ncin.variables[varin].dimensions) if copyattr: nccopyattrvar(ncin,ncout,varin=varin,varout=varoutdef) # for attr in dir(ncin.variables[varin]): # if attr not in ['assignValue', 'getValue', 'typecode']: # setattr(ncout.variables[varoutdef],attr,getattr(ncin.variables[varin],attr)) if copyvalues == True: if ncin.variables[varin].dimensions != tuple(): pcd2.pcd(lambda x: x,[],[{'file':ncin,'varname':varin}],[{'file':ncout,'varname':varoutdef}],appenddim=True)
# cdo selindexbox (Abort): Unsupported grid type! # on the contrary, this functionality now works with pynacolada.pcd(): they are no restrictions on the grid type. # example 1: crop the domain for the variable 'T' fin = NetCDF.NetCDFFile('/home/hendrik/data/belgium_aq/rcm/aq09/stage1/int2lm/laf2009010100_urb_ahf.nc','r') fout = NetCDF.NetCDFFile('/home/hendrik/data/belgium_aq/rcm/aq09/stage1/int2lm/laf2009010100_urb_ahf_sel.nc','w') func = lambda x: x[20:90,30:100] dnamsel = ['rlon','rlat'] evar='T' print ('processing variable: ',evar) datin = [{'file':fin,'varname':evar,}] datout = [{'file':fout,'varname':evar},] pcd.pcd(func,dnamsel,datin,datout,appenddim=True) fout.close();print('output file written to:',fout ) fin.close() # Unfortunatly, It not superfast. The reason is that the 'preperations' in pcd needs to be redone # for each variable. # example 2: crop the domain to all variables that involve the lat-lon grid, and just copy any other variable fin = NetCDF.NetCDFFile('/home/hendrik/data/belgium_aq/rcm/aq09/stage1/int2lm/laf2009010100_urb_ahf.nc','r') fout = NetCDF.NetCDFFile('/home/hendrik/data/belgium_aq/rcm/aq09/stage1/int2lm/laf2009010100_urb_ahf_sel2.nc','w') func = lambda x: x[20:90,30:100] dnamsel = [['rlon','srlon'],['rlat','srlat']] for evar in fin.variables: # apply the domain selection on all variables that involve these dimensions procvar = True
def avgcycle(x,n): xout = np.zeros([n+1]+list(np.shape(x)[1:])) for i in range(n): xout[i] = np.mean(x[i::n],axis=0) xout[n] = xout[0] return xout dts = dtrange(dt.datetime.strptime('2009040100','%Y%m%d%H'),dt.datetime.strptime('2009050100','%Y%m%d%H'),dt.timedelta(hours=1)) for RUN in ['aq09ec_td','aq09_td','aq09ec','aq09']: path = '/media/URB_AQ_1/data/belgium_aq/rcm/'+RUN+'/stage1/aurora/au3d/' fins = [ path+'/au3d'+time.strftime('%Y%m%d%H')+'.nc' for time in dts] fout = NetCDF.NetCDFFile('/media/URB_AQ_1/data/belgium_aq/rcm/'+RUN+'_au3d200904_diucycle.nc','w') pcd.pcd(lambda x: avgcycle(x,24),('time',),\ [{'file': fins, 'varname': 'O3', 'predim': 'time'}],\ [{'file': fout, 'varname': 'O3'}],appenddim=True) fout.close(); print('data written to: ',fout) fin = NetCDF.NetCDFFile('/media/URB_AQ_1/data/belgium_aq/rcm/'+RUN+'_au3d200904_diucycle.nc','r') fout = NetCDF.NetCDFFile('/media/URB_AQ_1/data/belgium_aq/rcm/'+RUN+'_au3d200904_diucycle_spatvar.nc','w') pcd.pcd(lambda x: x - np.mean(x),('jy','kx'),\ [{'file': fin, 'varname': 'O3'}],\ [{'file': fout, 'varname': 'O3'}]) fout.close(); print('data written to: ',fout) fina = NetCDF.NetCDFFile('/media/URB_AQ_1/data/belgium_aq/rcm/aq09ec_td_au3d200904_diucycle_spatvar.nc','r') finb = NetCDF.NetCDFFile('/media/URB_AQ_1/data/belgium_aq/rcm/aq09_td_au3d200904_diucycle_spatvar.nc','r')
def avgglide(x,avlen): xout = np.zeros_like(x) xwork = np.zeros_like(x) if np.mod(avlen,2) == 0: xwork[0] = np.nan xwork[:-1] = (x[1:] + x[:-1])/2. else: xwork = x lenxout = xout.shape[0] avlen2 = int(avlen/2.) xout[:avlen2] = np.nan xout[-avlen2:] = np.nan for i in range(0,avlen,1): xout[avlen2:(-avlen+avlen2)] = xout[avlen2:(-avlen+avlen2)] + xwork[i:(-avlen+i)] return xout/avlen # now, apply weekly cycle to a netcdf file ncin = NetCDF.NetCDFFile('input.nc','r') ncglide = NetCDF.NetCDFFile('output_glide.nc','w') # we can cycle through the netcdf variables that have the 'time'-dimension for evar in ncin.variables: if ((evar not in ncin.dimensions) & ('time' in ncin.variables[evar].dimensions): pcd.pcd(lambda x: avgglide(x,168),\ ('time',),\ [{'file' : ncin, 'varname': evar}],\ [{'file' : ncglide, 'varname': evar}]) ncglide.close(); print('data written to:', ncglide) ncin.close()