def narr_file_data(fname,xlim=False,ylim=False,quiet=False): ''' Returns bulk data from one NARR file ''' out={} # loading grid: if 0: if not quiet: print(' reading lon,lat from file %s' % grd) nc=netcdf.ncopen(grd) x=nc.vars['East_longitude_0-360'][0,...]-360. y=nc.vars['Latitude_-90_to_+90'][0,...] # time always 1 !! nc.close() else: if not quiet: print(' reading lon,lat from file %s' % grdTxt) x,y=load_grid() #x=x-360. x=-x ny,nx=x.shape if (xlim,ylim)==(False,False):i0,i1,j0,j1=0,nx,0,ny else: i0,i1,j0,j1=calc.ij_limits(x, y, xlim, ylim, margin=0) x=x[j0:j1,i0:i1] y=y[j0:j1,i0:i1] try: nc=netcdf.ncopen(fname) except: return {} xx=str(i0)+':'+str(i1) yy=str(j0)+':'+str(j1) tdim=netcdf.fdim(nc,'time1') if tdim!=1: print('WARNING: tdim !=1 !!!!!!') # T surface [K->C] if not quiet: print(' --> T air') tair=netcdf.use(nc,'Temperature_surface',time1=0,x=xx,y=yy) tair=tair-273.15 out['tair']=cb.Data(x,y,tair,'C') # R humidity [% -> 0--1] if not quiet: print(' --> R humidity') rhum=netcdf.use(nc,'Relative_humidity',time1=0,x=xx,y=yy) out['rhum']=cb.Data(x,y,rhum/100.,'0--1') # surface pressure [Pa] if not quiet: print(' --> Surface pressure') pres=netcdf.use(nc,'Pressure_surface',time1=0,x=xx,y=yy) out['pres']=cb.Data(x,y,pres,'Pa') # P rate [kg m-2 s-1 -> cm/d] if not quiet: print(' --> P rate') prate=netcdf.use(nc,'Precipitation_rate',time1=0,x=xx,y=yy) prate=prate*86400*100/1000. out['prate']=cb.Data(x,y,prate,'cm/d') # Net shortwave flux [ W m-2] if not quiet: print(' --> Net shortwave flux') if not quiet: print(' SW down') sw_down=netcdf.use(nc,'Downward_shortwave_radiation_flux',time1=0,x=xx,y=yy) if not quiet: print(' SW up') sw_up=netcdf.use(nc,'Upward_short_wave_radiation_flux_surface',time1=0,x=xx,y=yy) sw_net=sw_down-sw_up out['radsw']=cb.Data(x,y,sw_net,'W m-2',info='positive downward') # Net longwave flux [W/m^2] if not quiet: print(' --> Net longwave flux') if not quiet: print(' LW down') lw_down=netcdf.use(nc,'Downward_longwave_radiation_flux',time1=0,x=xx,y=yy) if not quiet: print(' LW up') lw_up=netcdf.use(nc,'Upward_long_wave_radiation_flux_surface',time1=0,x=xx,y=yy) lw_net=lw_down-lw_up out['radlw']=cb.Data(x,y,-lw_net,'W m-2',info='positive upward') # downward lw: out['dlwrf']=cb.Data(x,y,-lw_down,'W m-2',info='negative... downward') # U and V wind speed 10m if not quiet: print(' --> U and V wind') # vertical dim is height_above_ground1: 10 and 30 m uwnd=netcdf.use(nc,'u_wind_height_above_ground',height_above_ground1=0,time1=0,x=xx,y=yy) vwnd=netcdf.use(nc,'v_wind_height_above_ground',height_above_ground1=0,time1=0,x=xx,y=yy) if not quiet: print(' --> calc wind speed and stress') speed = np.sqrt(uwnd**2+vwnd**2) taux,tauy=air_sea.wind_stress(uwnd,vwnd) out['wspd']=cb.Data(x,y,speed,'m s-1') out['uwnd']=cb.Data(x,y,uwnd,'m s-1') out['vwnd']=cb.Data(x,y,vwnd,'m s-1') out['sustr']=cb.Data(x,y,taux,'Pa') out['svstr']=cb.Data(x,y,tauy,'Pa') # Cloud cover [0--100 --> 0--1]: if not quiet: print(' --> Cloud cover') clouds=netcdf.use(nc,'Total_cloud_cover',time1=0,x=xx,y=yy) out['cloud']=cb.Data(x,y,clouds/100.,'fraction (0--1)') nc.close() return out
def cordex_file_data(f,lims=False,quiet=False): ''' CORDEX data for ROMS No accumulated variables are considered ''' out={} # time, x, y: if not quiet: print(' reading time,x,y') out['time']=netcdf.nctime(f,'time') x=netcdf.use(f,'lon') y=netcdf.use(f,'lat') x[x>180]=x[x>180]-360 if x.ndim==1 and y.ndim==1: x,y=np.meshgrid(x,y) if np.ma.isMA(x): x=x.data if np.ma.isMA(y): y=y.data if lims: from okean import calc xlim,ylim=lims i1,i2,j1,j2=calc.ij_limits(x,y,xlim,ylim,margin=3) else: i0=0 j0=0 j1,i1=x.shape I=range(i1,i2) J=range(j1,j2) x=x[j1:j2,i1:i2] y=y[j1:j2,i1:i2] # tair [K-->C] if not quiet: print(' --> T air') vname='tair' tair=netcdf.use(f,vname,lon=I,lat=J)-273.15 out['tair']=Data(x,y,tair,'Celsius') # R humidity [0--1] if not quiet: print(' --> R humidity (from specific humidity)') vname='humid' q=netcdf.use(f,vname,lon=I,lat=J) # specific humidity rhum=q/air_sea.qsat(tair) rhum[rhum>1]=1 out['rhum']=Data(x,y,rhum,'0--1') # surface pressure [Pa] if not quiet: print(' --> Surface pressure') vname='press' pres=netcdf.use(f,vname,lon=I,lat=J) out['pres']=Data(x,y,pres,'Pa') # P rate [kg m-2 s-1 -> cm/d] if not quiet: print(' --> P rate') vname='rain' prate=netcdf.use(f,vname,lon=I,lat=J) prate=prate*86400*100/1000. prate[prate<0]=0 out['prate']=Data(x,y,prate,'cm/d') # Net shortwave flux [W m-2] if not quiet: print(' --> Net shortwave flux') if not quiet: print(' SW down') sw_down=netcdf.use(f,'sw_down',lon=I,lat=J) if not quiet: print(' SW up') sw_up=netcdf.use(f,'sw_up',lon=I,lat=J) sw_net=sw_down-sw_up out['radsw']=Data(x,y,sw_net,'W m-2',info='positive downward') # Net longwave flux [W m-2] if not quiet: print(' --> Net longwave flux') if not quiet: print(' LW down') lw_down=netcdf.use(f,'lw_down',lon=I,lat=J) if not quiet: print(' LW up') lw_up=netcdf.use(f,'lw_up',lon=I,lat=J) lw_net=lw_down-lw_up out['radlw']=Data(x,y,-lw_net,'W m-2',info='positive upward') # downward lw: out['dlwrf']=Data(x,y,-lw_down,'W m-2',info='negative... downward') # signs convention is better explained in wrf.py # U and V wind speed 10m if not quiet: print(' --> U and V wind') uwnd=netcdf.use(f,'u',lon=I,lat=J) vwnd=netcdf.use(f,'v',lon=I,lat=J) if not quiet: print(' --> calc wind speed and stress') speed = np.sqrt(uwnd**2+vwnd**2) taux,tauy=air_sea.wind_stress(uwnd,vwnd) out['wspd']=Data(x,y,speed,'m s-1') out['uwnd']=Data(x,y,uwnd,'m s-1') out['vwnd']=Data(x,y,vwnd,'m s-1') out['sustr']=Data(x,y,taux,'Pa') out['svstr']=Data(x,y,tauy,'Pa') # Cloud cover [0--100 --> 0--1]: if not quiet: print(' --> Cloud cover') if 'clouds' in netcdf.varnames(f): clouds=netcdf.use(f,'clouds',lon=I,lat=J)/100. out['cloud']=Data(x,y,clouds,'fraction (0--1)') else: print('==> clouds not present!') return fill_extremes(out,quiet)
def interim_file_data(files,quiet=False): ''' ECMWF ERA INTERIM data for ROMS To be used with data obtained from the new server: http://apps.ecmwf.int/datasets/ and not the old one (http://data-portal.ecmwf.int/data/d/interim_daily/) To deal with data from old server use module interim_past => forecast vars: time=00h, 12h step=3,6,9,12 --> n forec steps=4 needed (suggestion): - Surface net solar radiation (ssr) - Surface thermal radiation (str) - Total precipitation (tp) others: - Surface thermal radiation downwards (strd) - Evaporation (e) - ... =>analysis+forec vars: (interim analysis starts every 6h; forecast starts every 12h !!) time=00h,6h,12h,18h step=0,3,9 (3 and 9 are for the forecast 00h and 12h) needed (suggestion): - Surface pressure (sp) - Total cloud cover (tcc) - 10 metre U wind component (v10u or u10) - 10 metre V wind component (v10v or v10) - 2 metre temperature (v2t or t2m) - 2 metre dewpoint temperature (v2d or d2m) Accumulated vars (rad SW, LW and precipitation are converted to averages by acum2avg ''' # some variables may have different names! Vars={} Vars['v10u']='v10u','u10' Vars['v10v']='v10v','v10' Vars['v2t']='v2t','t2m' Vars['v2d']='v2d','d2m' def find_v(name): if name in Vars.keys(): for v in Vars[name]: if varfile(v): return v else: return name def varfile(var): for f in files: if var in netcdf.varnames(f): return f def check_var_type(var): # new interim dataserver provides forec+analysis vars with extra dim # 'type', 0 or 1 if var.ndim==4: if not quiet: print(' dealing with var type... '), v=np.zeros(var.shape[1:],var.dtype) v[::2]=var[0,::2,...] v[1::2]=var[1,1::2,...] var=v if not quiet: print('done.') return var out={} # time: # all times from analysis file, except last ind which will be # the last time of forecast file aFile=varfile(find_v('v2t')) # air temp, for instance fFile=varfile(find_v('ssr')) # sw rad, for instance if not quiet: print(' reading "analysis" time from file %s' % aFile) aTime=netcdf.nctime(aFile,'time') aTime.sort() # analysis+forecast files may not have time sorted!! if not quiet: print(' reading "forecast" time from file %s' % fFile) fTime=netcdf.nctime(fFile,'time') fTime.sort() # this one should be sorted... time=np.append(aTime,fTime[-1]) out['time']=time # calc number of forecast steps stored,nforec (used by accum2avg) if [fTime[i].hour for i in range(8)]==range(3,22,3)+[0]: nforec=4 elif [fTime[i].hour for i in range(4)]==range(6,19,6)+[0]: nforec=2 else: if not quiet: print('INTERIM WRONG TIME: cannot n forec steps') return if not quiet: print(' ==> n forecast steps = %d' % nforec) # x,y: if not quiet: print(' reading x,y from file %s' % files[0]) x=netcdf.use(files[0],'longitude') y=netcdf.use(files[0],'latitude') x[x>180]=x[x>180]-360 if x.ndim==1 and y.ndim==1: x,y=np.meshgrid(x,y) # tair [K-->C] if not quiet: print(' --> T air') vname=find_v('v2t') f=varfile(vname) # time may not be monotonically increasing !! # when using mix of analysis and forecast variables and steps sortInds=np.argsort(netcdf.use(f,'time')) tair=netcdf.use(f,vname,time=sortInds)-273.15 tair=check_var_type(tair) if not quiet and np.any(sortInds!=range(len(sortInds))): print(' sort DONE') if not quiet: print(' fill_tend...') tair=fill_tend(tair) out['tair']=Data(x,y,tair,'Celsius') # R humidity [0--1] if not quiet: print(' --> R humidity (from T dew)') vname=find_v('v2d') f=varfile(vname) sortInds=np.argsort(netcdf.use(f,'time')) Td=netcdf.use(f,vname,time=sortInds)-273.15 Td=check_var_type(Td) if not quiet and np.any(sortInds!=range(len(sortInds))): print(' sort DONE') if not quiet: print(' fill_tend... (T dew)') Td=fill_tend(Td) T=tair rhum=air_sea.relative_humidity(T,Td) ## rhum=((112-0.1*T+Td)/(112+0.9*T))**8 rhum[rhum>1]=1 out['rhum']=Data(x,y,rhum,'0--1') # surface pressure [Pa] if not quiet: print(' --> Surface pressure') vname=find_v('sp') f=varfile(vname) sortInds=np.argsort(netcdf.use(f,'time')) pres=netcdf.use(f,vname,time=sortInds) pres=check_var_type(pres) if not quiet and np.any(sortInds!=range(len(sortInds))): print(' sort DONE') if not quiet: print(' fill_tend...') pres=fill_tend(pres) out['pres']=Data(x,y,pres,'Pa') # P rate [m --> cm day-1] if not quiet: print(' --> P rate') vname=find_v('tp') f=varfile(vname) sortInds=np.argsort(netcdf.use(f,'time')) prate=netcdf.use(f,vname,time=sortInds) prate=check_var_type(prate) if not quiet and np.any(sortInds!=range(len(sortInds))): print(' sort DONE') if not quiet: print(' accum2avg...') prate=accum2avg(prate,nforec) conv= 100*86400 # from m s-1 --> cm day-1 #conv= 100*86400/1000. # from kg m-2 s-1 --> cm day-1 prate=prate*conv # cm day-1 if not quiet: print(' fill_t0...') prate=fill_t0(prate) prate[prate<0]=0 out['prate']=Data(x,y,prate,'cm day-1') # Net shortwave flux [W m-2 s+1 --> W m-2] if not quiet: print(' --> Net shortwave flux') vname=find_v('ssr') f=varfile(vname) sortInds=np.argsort(netcdf.use(f,'time')) sw_net=netcdf.use(f,vname,time=sortInds) sw_net=check_var_type(sw_net) if not quiet and np.any(sortInds!=range(len(sortInds))): print(' sort DONE') if not quiet: print(' accum2avg...') sw_net=accum2avg(sw_net,nforec) if not quiet: print(' fill_t0...') sw_net=fill_t0(sw_net) out['radsw']=Data(x,y,sw_net,'W m-2',info='positive downward') # Net longwave flux [W m-2 s+1 --> W m-2] if not quiet: print(' --> Net longwave flux') vname=find_v('str') f=varfile(vname) sortInds=np.argsort(netcdf.use(f,'time')) lw_net=netcdf.use(f,vname,time=sortInds)*-1 # let us consider positive upward (*-1) lw_net=check_var_type(lw_net) if not quiet and np.any(sortInds!=range(len(sortInds))): print(' sort DONE') if not quiet: print(' accum2avg...') lw_net=accum2avg(lw_net,nforec) if not quiet: print(' fill_t0...') lw_net=fill_t0(lw_net) out['radlw']=Data(x,y,lw_net,'W m-2',info='positive upward') # longwave down: # can be obtained from clouds!! if not quiet: print(' --> Down longwave flux') vname=find_v('strd') f=varfile(vname) if f: sortInds=np.argsort(netcdf.use(f,'time')) lw_down=netcdf.use(f,vname,time=sortInds)*-1 # let us consider positive upward (*-1) lw_down=check_var_type(lw_down) if not quiet and np.any(sortInds!=range(len(sortInds))): print(' sort DONE') if not quiet: print(' accum2avg...') lw_down=accum2avg(lw_down,nforec) if not quiet: print(' fill_t0...') lw_down=fill_t0(lw_down) out['dlwrf']=Data(x,y,lw_down,'W m-2',info='negative... downward') else: print('down long wave CANNOT BE USED') # U and V wind speed 10m if not quiet: print(' --> U and V wind') vname=find_v('v10u') f=varfile(vname) sortInds=np.argsort(netcdf.use(f,'time')) uwnd=netcdf.use(f,vname,time=sortInds) uwnd=check_var_type(uwnd) if not quiet and np.any(sortInds!=range(len(sortInds))): print(' sort DONE') if not quiet: print(' fill_tend...') uwnd=fill_tend(uwnd) vname=find_v('v10v') f=varfile(vname) sortInds=np.argsort(netcdf.use(f,'time')) vwnd=netcdf.use(f,vname,time=sortInds) vwnd=check_var_type(vwnd) if not quiet and np.any(sortInds!=range(len(sortInds))): print(' sort DONE') if not quiet: print(' fill_tend...') vwnd=fill_tend(vwnd) if not quiet: print(' --> calc wind speed and stress') speed = np.sqrt(uwnd**2+vwnd**2) taux,tauy=air_sea.wind_stress(uwnd,vwnd) out['wspd']=Data(x,y,speed,'m s-1') out['uwnd']=Data(x,y,uwnd,'m s-1') out['vwnd']=Data(x,y,vwnd,'m s-1') out['sustr']=Data(x,y,taux,'Pa') out['svstr']=Data(x,y,tauy,'Pa') # Cloud cover [0--1]: if not quiet: print(' --> Cloud cover') vname=find_v('tcc') f=varfile(vname) sortInds=np.argsort(netcdf.use(f,'time')) clouds=netcdf.use(f,vname,time=sortInds) clouds=check_var_type(clouds) if not quiet and np.any(sortInds!=range(len(sortInds))): print(' sort DONE') if not quiet: print(' fill_tend...') clouds=fill_tend(clouds) out['cloud']=Data(x,y,clouds,'fraction (0--1)') return out
def interim_file_data(files, quiet=False): ''' ECMWF ERA INTERIM data for ROMS To be used with data obtained from the new server: http://apps.ecmwf.int/datasets/ and not the old one (http://data-portal.ecmwf.int/data/d/interim_daily/) To deal with data from old server use module interim_past => forecast vars: time=00h, 12h step=3,6,9,12 --> n forec steps=4 needed (suggestion): - Surface net solar radiation (ssr) - Surface thermal radiation (str) - Total precipitation (tp) others: - Surface thermal radiation downwards (strd) - Evaporation (e) - ... =>analysis+forec vars: (interim analysis starts every 6h; forecast starts every 12h !!) time=00h,6h,12h,18h step=0,3,9 (3 and 9 are for the forecast 00h and 12h) needed (suggestion): - Surface pressure (sp) - Total cloud cover (tcc) - 10 metre U wind component (v10u or u10) - 10 metre V wind component (v10v or v10) - 2 metre temperature (v2t or t2m) - 2 metre dewpoint temperature (v2d or d2m) Accumulated vars (rad SW, LW and precipitation are converted to averages by acum2avg ''' # some variables may have different names! Vars = {} Vars['v10u'] = 'v10u', 'u10' Vars['v10v'] = 'v10v', 'v10' Vars['v2t'] = 'v2t', 't2m' Vars['v2d'] = 'v2d', 'd2m' def find_v(name): if name in Vars.keys(): for v in Vars[name]: if varfile(v): return v else: return name def varfile(var): for f in files: if var in netcdf.varnames(f): return f def check_var_type(var): # new interim dataserver provides forec+analysis vars with extra dim # 'type', 0 or 1 if var.ndim == 4: if not quiet: print(' dealing with var type... '), v = np.zeros(var.shape[1:], var.dtype) v[::2] = var[0, ::2, ...] v[1::2] = var[1, 1::2, ...] var = v if not quiet: print('done.') return var out = {} # time: # all times from analysis file, except last ind which will be # the last time of forecast file aFile = varfile(find_v('v2t')) # air temp, for instance fFile = varfile(find_v('ssr')) # sw rad, for instance if not quiet: print(' reading "analysis" time from file %s' % aFile) aTime = netcdf.nctime(aFile, 'time') aTime.sort() # analysis+forecast files may not have time sorted!! if not quiet: print(' reading "forecast" time from file %s' % fFile) fTime = netcdf.nctime(fFile, 'time') fTime.sort() # this one should be sorted... time = np.append(aTime, fTime[-1]) out['time'] = time # calc number of forecast steps stored,nforec (used by accum2avg) if [fTime[i].hour for i in range(8)] == range(3, 22, 3) + [0]: nforec = 4 elif [fTime[i].hour for i in range(4)] == range(6, 19, 6) + [0]: nforec = 2 else: if not quiet: print('INTERIM WRONG TIME: cannot n forec steps') return if not quiet: print(' ==> n forecast steps = %d' % nforec) # x,y: if not quiet: print(' reading x,y from file %s' % files[0]) x = netcdf.use(files[0], 'longitude') y = netcdf.use(files[0], 'latitude') x[x > 180] = x[x > 180] - 360 if x.ndim == 1 and y.ndim == 1: x, y = np.meshgrid(x, y) # tair [K-->C] if not quiet: print(' --> T air') vname = find_v('v2t') f = varfile(vname) # time may not be monotonically increasing !! # when using mix of analysis and forecast variables and steps sortInds = np.argsort(netcdf.use(f, 'time')) tair = netcdf.use(f, vname, time=sortInds) - 273.15 tair = check_var_type(tair) if not quiet and np.any(sortInds != range(len(sortInds))): print(' sort DONE') if not quiet: print(' fill_tend...') tair = fill_tend(tair) out['tair'] = Data(x, y, tair, 'Celsius') # R humidity [0--1] if not quiet: print(' --> R humidity (from T dew)') vname = find_v('v2d') f = varfile(vname) sortInds = np.argsort(netcdf.use(f, 'time')) Td = netcdf.use(f, vname, time=sortInds) - 273.15 Td = check_var_type(Td) if not quiet and np.any(sortInds != range(len(sortInds))): print(' sort DONE') if not quiet: print(' fill_tend... (T dew)') Td = fill_tend(Td) T = tair rhum = relative_humidity(T, Td) ## rhum=((112-0.1*T+Td)/(112+0.9*T))**8 rhum[rhum > 1] = 1 out['rhum'] = Data(x, y, rhum, '0--1') # surface pressure [Pa] if not quiet: print(' --> Surface pressure') vname = find_v('sp') f = varfile(vname) sortInds = np.argsort(netcdf.use(f, 'time')) pres = netcdf.use(f, vname, time=sortInds) pres = check_var_type(pres) if not quiet and np.any(sortInds != range(len(sortInds))): print(' sort DONE') if not quiet: print(' fill_tend...') pres = fill_tend(pres) out['pres'] = Data(x, y, pres, 'Pa') # P rate [m --> cm day-1] if not quiet: print(' --> P rate') vname = find_v('tp') f = varfile(vname) sortInds = np.argsort(netcdf.use(f, 'time')) prate = netcdf.use(f, vname, time=sortInds) prate = check_var_type(prate) if not quiet and np.any(sortInds != range(len(sortInds))): print(' sort DONE') if not quiet: print(' accum2avg...') prate = accum2avg(prate, nforec) conv = 100 * 86400 # from m s-1 --> cm day-1 #conv= 100*86400/1000. # from kg m-2 s-1 --> cm day-1 prate = prate * conv # cm day-1 if not quiet: print(' fill_t0...') prate = fill_t0(prate) prate[prate < 0] = 0 out['prate'] = Data(x, y, prate, 'cm day-1') # Net shortwave flux [W m-2 s+1 --> W m-2] if not quiet: print(' --> Net shortwave flux') vname = find_v('ssr') f = varfile(vname) sortInds = np.argsort(netcdf.use(f, 'time')) sw_net = netcdf.use(f, vname, time=sortInds) sw_net = check_var_type(sw_net) if not quiet and np.any(sortInds != range(len(sortInds))): print(' sort DONE') if not quiet: print(' accum2avg...') sw_net = accum2avg(sw_net, nforec) if not quiet: print(' fill_t0...') sw_net = fill_t0(sw_net) out['radsw'] = Data(x, y, sw_net, 'W m-2', info='positive downward') # Net longwave flux [W m-2 s+1 --> W m-2] if not quiet: print(' --> Net longwave flux') vname = find_v('str') f = varfile(vname) sortInds = np.argsort(netcdf.use(f, 'time')) lw_net = netcdf.use( f, vname, time=sortInds) * -1 # let us consider positive upward (*-1) lw_net = check_var_type(lw_net) if not quiet and np.any(sortInds != range(len(sortInds))): print(' sort DONE') if not quiet: print(' accum2avg...') lw_net = accum2avg(lw_net, nforec) if not quiet: print(' fill_t0...') lw_net = fill_t0(lw_net) out['radlw'] = Data(x, y, lw_net, 'W m-2', info='positive upward') # longwave down: # can be obtained from clouds!! if not quiet: print(' --> Down longwave flux') vname = find_v('strd') f = varfile(vname) if f: sortInds = np.argsort(netcdf.use(f, 'time')) lw_down = netcdf.use( f, vname, time=sortInds) * -1 # let us consider positive upward (*-1) lw_down = check_var_type(lw_down) if not quiet and np.any(sortInds != range(len(sortInds))): print(' sort DONE') if not quiet: print(' accum2avg...') lw_down = accum2avg(lw_down, nforec) if not quiet: print(' fill_t0...') lw_down = fill_t0(lw_down) out['dlwrf'] = Data(x, y, lw_down, 'W m-2', info='negative... downward') else: print('down long wave CANNOT BE USED') # U and V wind speed 10m if not quiet: print(' --> U and V wind') vname = find_v('v10u') f = varfile(vname) sortInds = np.argsort(netcdf.use(f, 'time')) uwnd = netcdf.use(f, vname, time=sortInds) uwnd = check_var_type(uwnd) if not quiet and np.any(sortInds != range(len(sortInds))): print(' sort DONE') if not quiet: print(' fill_tend...') uwnd = fill_tend(uwnd) vname = find_v('v10v') f = varfile(vname) sortInds = np.argsort(netcdf.use(f, 'time')) vwnd = netcdf.use(f, vname, time=sortInds) vwnd = check_var_type(vwnd) if not quiet and np.any(sortInds != range(len(sortInds))): print(' sort DONE') if not quiet: print(' fill_tend...') vwnd = fill_tend(vwnd) if not quiet: print(' --> calc wind speed and stress') speed = np.sqrt(uwnd**2 + vwnd**2) taux, tauy = air_sea.wind_stress(uwnd, vwnd) out['wspd'] = Data(x, y, speed, 'm s-1') out['uwnd'] = Data(x, y, uwnd, 'm s-1') out['vwnd'] = Data(x, y, vwnd, 'm s-1') out['sustr'] = Data(x, y, taux, 'Pa') out['svstr'] = Data(x, y, tauy, 'Pa') # Cloud cover [0--1]: if not quiet: print(' --> Cloud cover') vname = find_v('tcc') f = varfile(vname) sortInds = np.argsort(netcdf.use(f, 'time')) clouds = netcdf.use(f, vname, time=sortInds) clouds = check_var_type(clouds) if not quiet and np.any(sortInds != range(len(sortInds))): print(' sort DONE') if not quiet: print(' fill_tend...') clouds = fill_tend(clouds) out['cloud'] = Data(x, y, clouds, 'fraction (0--1)') return out
def cfsr_file_data(files, quiet=False): ''' Returns bulk data from one CFRS files ''' def load_time(f): time = np.array((), datetime.datetime) ff = glob.glob(f) ff.sort() for f in ff: time = np.append(time, netcdf.nctime(f, 'time')) return time def load_time_main(f): time = load_time(f) # I want 0,6,12,... after 2006 results may be 3,9,15, ... if time[0].hour in [3, 9, 15, 21]: time = time + datetime.timedelta(hours=3) # for 2011 1st time is not 0! if time[0].hour == 6: time = np.hstack((time[0].replace(hour=0), time)) return time def fix_time(t, var, t0, t1): # convert 1h, 7h, ... to 0h, 6h, ... if t[0].hour in [1, 7, 13, 19]: # not all! sp analysis starts at 0, 6,...! print(' 1,7,... to 0,6,...') var = (var[1:] * 5 + var[:-1] * 1) / 6. t = t[1:] - datetime.timedelta(hours=1) elif t[0].hour in [3, 9, 15, 21]: print(' 3,9,... to 0,6,...') var = (var[1:] * 3 + var[:-1] * 3) / 6. t = t[1:] - datetime.timedelta(hours=3) cond = (t >= t0) & (t <= t1) t = t[cond] var = var[cond] if t[0] > t0: dt = t[0] - t0 dt = dt.days * 24 + dt.seconds / 3600. # hours print( 'missing data at start: %.2d h missing --> repeating 1st data' % dt) v = np.zeros((var.shape[0] + 1, ) + var.shape[1:], var.dtype) v[1:] = var v[0] = var[0] var = v t_ = np.zeros((t.shape[0] + 1, ) + t.shape[1:], t.dtype) t_[1:] = t t_[0] = t0 t = t_ if t[-1] < t1: dt = t1 - t[-1] dt = dt.days * 24 + dt.seconds / 3600. # hours print( 'missing data at end: %.2d h missing --> repeating last data' % dt) v = np.zeros((var.shape[0] + 1, ) + var.shape[1:], var.dtype) v[:-1] = var v[-1] = var[-1] var = v t_ = np.zeros((t.shape[0] + 1, ) + t.shape[1:], t.dtype) t_[:-1] = t t_[-1] = t1 t = t_ return var, t out = {} # time: if 0: time = netcdf.nctime(files['cc'], 'time') # files have diff units !! so, cannot load all times at once! # these result will use only units of 1st file!! else: time = load_time_main(files['cc']) out['time'] = time # T air [K->C] if not quiet: print(' --> T air') f = files['st'] tair = netcdf.use(f, 'TMP_L103') tair = tair - 273.15 x = netcdf.use(f, 'lon') x[x > 180] = x[x > 180] - 360 y = netcdf.use(f, 'lat') x, y = np.meshgrid(x, y) # check time: ttmp = load_time(f) if ttmp.size == time.size and np.all(ttmp == time): print(' time ok') else: print(' time differs !!!!', ) tair, tfix = fix_time(ttmp, tair, time[0], time[-1]) if tfix.size == time.size and np.all(tfix == time): print(' ...fixed!') else: print('time is NOT OK. Please check !!') return out['tair'] = Data(x, y, tair, 'C') # R humidity [%-->0--1] if not quiet: print(' --> R humidity') f = files['rh'] rhum = netcdf.use(f, 'R_H_L103') rhum = rhum / 100. x = netcdf.use(f, 'lon') x[x > 180] = x[x > 180] - 360 y = netcdf.use(f, 'lat') x, y = np.meshgrid(x, y) # check time: ttmp = load_time(f) if ttmp.size == time.size and np.all(ttmp == time): print(' time ok') else: print(' time differs !!!!' ), # should use end=' ' for python3 print continuation rhum, tfix = fix_time(ttmp, rhum, time[0], time[-1]) if tfix.size == time.size and np.all(tfix == time): print(' ...fixed!') else: print('time is NOT OK. Please check !!') return out['rhum'] = Data(x, y, rhum, '0--1') # surface pressure [Pa] if not quiet: print(' --> Surface pressure') f = files['sp'] pres = netcdf.use(f, 'PRES_L1') x = netcdf.use(f, 'lon') x[x > 180] = x[x > 180] - 360 y = netcdf.use(f, 'lat') x, y = np.meshgrid(x, y) # check time: ttmp = load_time(f) if ttmp.size == time.size and np.all(ttmp == time): print(' time ok') else: print(' time differs !!!!'), pres, tfix = fix_time(ttmp, pres, time[0], time[-1]) if tfix.size == time.size and np.all(tfix == time): print(' ...fixed!') else: print('time is NOT OK. Please check !!') return out['pres'] = Data(x, y, pres, 'Pa') # P rate [kg m-2 s-1 -> cm/d] if not quiet: print(' --> P rate') f = files['pr'] if 'PRATE_L1' in netcdf.varnames(f): prate = netcdf.use(f, 'PRATE_L1') else: prate = netcdf.use(f, 'PRATE_L1_Avg_1') x = netcdf.use(f, 'lon') x[x > 180] = x[x > 180] - 360 y = netcdf.use(f, 'lat') x, y = np.meshgrid(x, y) # Conversion kg m^-2 s^-1 to cm/day prate = prate * 86400 * 100 / 1000. prate = np.where(abs(prate) < 1.e-4, 0, prate) # check time: ttmp = load_time(f) if ttmp.size == time.size and np.all(ttmp == time): print(' time ok') else: print(' time differs !!!!'), prate, tfix = fix_time(ttmp, prate, time[0], time[-1]) if tfix.size == time.size and np.all(tfix == time): print(' ...fixed!') else: print('time is NOT OK. Please check !!') return out['prate'] = Data(x, y, prate, 'cm/d') # Net shortwave flux [W/m^2] if not quiet: print(' --> Net shortwave flux') if not quiet: print(' SW down') f = files['rad'] sw_down = netcdf.use(f, 'DSWRF_L1_Avg_1') x = netcdf.use(f, 'lon') x[x > 180] = x[x > 180] - 360 y = netcdf.use(f, 'lat') x, y = np.meshgrid(x, y) if not quiet: print(' SW up') sw_up = netcdf.use(f, 'USWRF_L1_Avg_1') sw_net = sw_down - sw_up sw_net = np.where(sw_net < 1.e-10, 0, sw_net) # check time: ttmp = load_time(f) if ttmp.size == time.size and np.all(ttmp == time): print(' time ok') else: print(' time differs !!!!'), sw_net, tfix = fix_time(ttmp, sw_net, time[0], time[-1]) if tfix.size == time.size and np.all(tfix == time): print(' ...fixed!') else: print('time is NOT OK. Please check !!') return out['radsw'] = Data(x, y, sw_net, 'W m-2', info='positive downward') # Net longwave flux [W/m^2] if not quiet: print(' --> Net longwave flux') if not quiet: print(' LW down') f = files['rad'] lw_down = netcdf.use(f, 'DLWRF_L1_Avg_1') x = netcdf.use(f, 'lon') x[x > 180] = x[x > 180] - 360 y = netcdf.use(f, 'lat') x, y = np.meshgrid(x, y) if not quiet: print(' LW up') lw_up = netcdf.use(f, 'ULWRF_L1_Avg_1') lw_net = lw_down - lw_up lw_net = np.where(np.abs(lw_net) < 1.e-10, 0, lw_net) # check time: ttmp = load_time(f) if ttmp.size == time.size and np.all(ttmp == time): print(' time ok') else: print(' time differs !!!!'), lw_net, tfix1 = fix_time(ttmp, lw_net, time[0], time[-1]) lw_down, tfix2 = fix_time(ttmp, lw_down, time[0], time[-1]) if tfix1.size == tfix2.size == time.size and np.all((tfix1 == time) & (tfix2 == time)): print(' ...fixed!') else: print('time is NOT OK. Please check !!') return # ROMS (agrif, used to be!) convention: positive upward out['radlw'] = Data(x, y, -lw_net, 'W m-2', info='positive upward') # downward lw: out['dlwrf'] = Data(x, y, -lw_down, 'W m-2', info='negative... downward') # signs convention is better explained in wrf.py # U and V wind speed 10m if not quiet: print(' --> U and V wind') f = files['uv'] uwnd = netcdf.use(f, 'U_GRD_L103') vwnd = netcdf.use(f, 'V_GRD_L103') x = netcdf.use(f, 'lon') x[x > 180] = x[x > 180] - 360 y = netcdf.use(f, 'lat') x, y = np.meshgrid(x, y) # check time: ttmp = load_time(f) if ttmp.size == time.size and np.all(ttmp == time): print(' time ok') else: print(' time differs !!!!'), uwnd, tfix1 = fix_time(ttmp, uwnd, time[0], time[-1]) vwnd, tfix2 = fix_time(ttmp, vwnd, time[0], time[-1]) if tfix1.size == tfix2.size == time.size and np.all((tfix1 == time) & (tfix2 == time)): print(' ...fixed!') else: print('time is NOT OK. Please check !!') return # if not quiet: print(' --> calc wind speed and stress') speed = np.sqrt(uwnd**2 + vwnd**2) taux, tauy = air_sea.wind_stress(uwnd, vwnd) out['wspd'] = Data(x, y, speed, 'm s-1') out['uwnd'] = Data(x, y, uwnd, 'm s-1') out['vwnd'] = Data(x, y, vwnd, 'm s-1') out['sustr'] = Data(x, y, taux, 'Pa') out['svstr'] = Data(x, y, tauy, 'Pa') # Cloud cover [0--100 --> 0--1]: if not quiet: print(' --> Cloud cover') f = files['cc'] if 'T_CDC_L200' in netcdf.varnames(f): clouds = netcdf.use(f, 'T_CDC_L200') else: clouds = netcdf.use(f, 'T_CDC_L200_Avg_1') x = netcdf.use(f, 'lon') x[x > 180] = x[x > 180] - 360 y = netcdf.use(f, 'lat') x, y = np.meshgrid(x, y) clouds = clouds / 100. # check time: ttmp = load_time(f) if ttmp.size == time.size and np.all(ttmp == time): print(' time ok') else: print(' time differs !!!!'), clouds, tfix = fix_time(ttmp, clouds, time[0], time[-1]) if tfix.size == time.size and np.all(tfix == time): print(' ...fixed!') else: print('time is NOT OK. Please check !!') return out['cloud'] = Data(x, y, clouds, 'fraction (0--1)') # rhum has different resolution (0.5, just like dew point!) # so, i can edit surface.py or just interpolate here rhum to # other vars resolution: if out['rhum'].data.shape != out['uwnd'].data.shape: from okean import calc print('rhum shape differs!! --> interp:') nt, ny, nx = out['uwnd'].data.shape x, y = out['uwnd'].x, out['uwnd'].y rhum = np.zeros((nt, ny, nx), out['rhum'].data.dtype) for it in range(nt): if it % 100 == 0: print(' %d of %d' % (it, nt)) rhum[it] = calc.griddata(out['rhum'].x, out['rhum'].y, out['rhum'].data[it], x, y) out['rhum'] = Data(x, y, rhum, '0--1') return out
def gfs_file_data(fname,xlim=False,ylim=False,quiet=False): ''' Returns bulk data from one GFS file ''' # the way to ectract differes if using pygrib or grib2 ! so check first: try: import pygrib isPygrib=True except: isPygrib=False out={} # T air 2m [K->C] if not quiet: print(' --> T air') if isPygrib: #x,y,tair=gribu.getvar(fname,'temperature',tags=(':2 metre',),lons=xlim,lats=ylim) #newest gribu: x,y,tair=gribu.getvar(fname,'2t',lons=xlim,lats=ylim) else: x,y,tair=gribu.getvar(fname,'temperature',tags=(':2 m','TMP'),lons=xlim,lats=ylim) tair=tair-273.15 out['tair']=Data(x,y,tair,'C') # R humidity 2m [%-->0--1] if not quiet: print(' --> R humidity') if 0: # kg/kg x,y,rhum=gribu.getvar(fname,'humidity',tags=(':2 m','kg'),lons=xlim,lats=ylim) rhum=rhum/air_sea.qsat(tair) rhum=np.where(rhum>1.0,1.0,rhum) else: # % #x,y,rhum=gribu.getvar(fname,'humidity',tags=('2 m','%'),lons=xlim,lats=ylim) x,y,rhum=gribu.getvar(fname,'2r',lons=xlim,lats=ylim) rhum=rhum/100. out['rhum']=Data(x,y,rhum,'0--1') # surface pressure [Pa] if not quiet: print(' --> Surface pressure') #x,y,pres=gribu.getvar(fname,'pressure',tags='surface',lons=xlim,lats=ylim) x,y,pres=gribu.getvar(fname,'sp',lons=xlim,lats=ylim) out['pres']=Data(x,y,pres,'Pa') # P rate [kg m-2 s-1 -> cm/d] if not quiet: print(' --> P rate') #x,y,prate=gribu.getvar(fname,'precipitation rate',lons=xlim,lats=ylim) x,y,prate=gribu.getvar(fname,'prate',lons=xlim,lats=ylim) # Conversion kg m^-2 s^-1 to cm/day prate=prate*86400*100/1000. prate=np.where(abs(prate)<1.e-4,0,prate) out['prate']=Data(x,y,prate,'cm/d') # Net shortwave flux [W/m^2] if not quiet: print(' --> Net shortwave flux') if not quiet: print(' SW down') if isPygrib: #x,y,sw_down = gribu.getvar(fname,'',tags='Downward short-wave radiation flux',lons=xlim,lats=ylim) x,y,sw_down = gribu.getvar(fname,'dswrf',lons=xlim,lats=ylim) else: x,y,sw_down = gribu.getvar(fname,'downward short-wave',lons=xlim,lats=ylim) if not quiet: print(' SW up') #x,y,sw_up = gribu.getvar(fname,'',tags='Upward short-wave radiation flux',lons=xlim,lats=ylim) x,y,sw_up = gribu.getvar(fname,'uswrf',lons=xlim,lats=ylim) if sw_up is False: if not quiet: print(' SW up not found: using albedo') #x,y,albedo = gribu.getvar(fname,'albedo',lons=xlim,lats=ylim) x,y,albedo = gribu.getvar(fname,'al',lons=xlim,lats=ylim) albedo=albedo/100. sw_net=sw_down*(1-albedo) else: sw_net=sw_down-sw_up sw_net=np.where(sw_net<1.e-10,0,sw_net) out['radsw']=Data(x,y,sw_net,'W m-2',info='positive downward') # Net longwave flux [W/m^2] if not quiet: print(' --> Net longwave flux') if not quiet: print(' LW down') if isPygrib: #x,y,lw_down = gribu.getvar(fname,'',tags='Downward long-wave radiation flux',lons=xlim,lats=ylim) x,y,lw_down = gribu.getvar(fname,'dlwrf',lons=xlim,lats=ylim) else: x,y,lw_down = gribu.getvar(fname,'downward long-wave',lons=xlim,lats=ylim) if not quiet: print(' LW up') #x,y,lw_up = gribu.getvar(fname,'',tags='Upward long-wave radiation flux',lons=xlim,lats=ylim) x,y,lw_up = gribu.getvar(fname,'ulwrf',lons=xlim,lats=ylim) if lw_up is False: if not quiet: print(' LW up not found: using sst') if isPygrib: #x,y,sst=gribu.getvar(fname,'temperature',tags='surface',lons=xlim,lats=ylim) # K x,y,sst=gribu.getvar(fname,'t',lons=xlim,lats=ylim) # K else: x,y,sst=gribu.getvar(fname,'temperature',tags='water surface',lons=xlim,lats=ylim) # K lw_net=air_sea.lwhf(sst,lw_down) lw_up=lw_down-lw_net else: lw_net=lw_down-lw_up # ROMS convention: positive upward # GFS convention: positive downward --> * (-1) lw_net=np.where(np.abs(lw_net)<1.e-10,0,lw_net) out['radlw']=Data(x,y,-lw_net,'W m-2',info='positive upward') # downward lw: out['dlwrf']=Data(x,y,-lw_down,'W m-2',info='negative... downward') # U and V wind speed 10m if not quiet: print(' --> U and V wind') #x,y,uwnd = gribu.getvar(fname,'u',tags=':10 m',lons=xlim,lats=ylim) #x,y,vwnd = gribu.getvar(fname,'v',tags=':10 m',lons=xlim,lats=ylim) x,y,uwnd = gribu.getvar(fname,'10u',lons=xlim,lats=ylim) x,y,vwnd = gribu.getvar(fname,'10v',lons=xlim,lats=ylim) if not quiet: print(' --> calc wind speed and stress') speed = np.sqrt(uwnd**2+vwnd**2) taux,tauy=air_sea.wind_stress(uwnd,vwnd) out['wspd']=Data(x,y,speed,'m s-1') out['uwnd']=Data(x,y,uwnd,'m s-1') out['vwnd']=Data(x,y,vwnd,'m s-1') out['sustr']=Data(x,y,taux,'Pa') out['svstr']=Data(x,y,tauy,'Pa') # Cloud cover [0--100 --> 0--1]: if not quiet: print(' --> Cloud cover') #x,y,clouds = gribu.getvar(fname,'cloud cover',lons=xlim,lats=ylim) x,y,clouds = gribu.getvar(fname,'tcc',lons=xlim,lats=ylim) if clouds is False: if not quiet: print('CALC clouds from LW,TAIR,TSEA and RH') # first get sst (maybe already done to calc lw_up) try: sst except: if not quiet: print(' get TSEA') if isPygrib: #x,y,sst=gribu.getvar(fname,'temperature',tags='surface',lons=xlim,lats=ylim) # K x,y,sst=gribu.getvar(fname,'t',lons=xlim,lats=ylim) # K else: x,y,sst=gribu.getvar(fname,'temperature',tags='water surface',lons=xlim,lats=ylim) # K clouds=air_sea.cloud(lw_net,sst-273.15,tair,rhum,'net') else: clouds=clouds/100. out['cloud']=Data(x,y,clouds,'fraction (0--1)') return out
def update_wind(fname, data, new_wind_info, **kargs): ''' new_wind_info will be added to fname as global attribute (ex: 'new wind from database xxx') ''' quiet = False Margin = 4 # for griddata and for original data to keep grd = False keepOriginal = 2 for k in kargs.keys(): if k == 'quiet': quiet = kargs[k] elif k == 'margin': Margin = kargs[k] elif k == 'grid': grd = kargs[k] elif k.lower().startswith('keepor'): keepOriginal = kargs[k] if not grd: grd = netcdf.fatt(fname, 'grd_file') g = roms.Grid(grd) x0 = data['x'] y0 = data['y'] if x0.ndim == 1: x0, y0 = np.meshgrid(x0, y0) dates = data.keys()[:] dates.remove('x') dates.remove('y') dates = np.array(dates) # interp in time: time = netcdf.nctime(fname, 'time') cond = False tind = -1 fob = gennc.GenBlk(fname, grd) for t in time: newWind = {} tind += 1 I, = np.where(dates == t) if I.size: I = I[0] uv = data[dates[I]] if not quiet: print(t, dates[I]) else: i1, = np.where(dates > t) i0, = np.where(dates < t) if i0.size and i1.size: i1 = i1[0] i0 = i0[-1] d0 = t - dates[i0] d1 = dates[i1] - t d0 = d0.days + d0.seconds / 86400. d1 = d1.days + d1.seconds / 86400. uv = (data[dates[i0]] * d1 + data[dates[i1]] * d0) / (d0 + d1) if not quiet: print(t, dates[i0], dates[i1], d0, d1) elif not i1.size: uv = data[dates[-1]] if not quiet: print(t, dates[-1]) elif not i0.size: uv = data[dates[0]] if not quiet: print(t, dates[0]) # interp to grid: if cond is False: cond, inds = rt.grid_vicinity(grd, x0, y0, margin=Margin, rect=True, retinds=True) i1, i2, j1, j2 = inds if not quiet: print(' --> inter uv %s' % t.isoformat(' ')) u = calc.griddata(x0[cond], y0[cond], uv.real[cond], g.lon, g.lat, extrap=True) v = calc.griddata(x0[cond], y0[cond], uv.imag[cond], g.lon, g.lat, extrap=True) # rotate wind, calc stress: if not quiet: print(' --> rot U,V wind and U,V wind stress') wspd = np.sqrt(u**2 + v**2) sustr, svstr = air_sea.wind_stress(u, v) angle = g.use('angle') uwnd, vwnd = calc.rot2d(u, v, angle) sustr, svstr = calc.rot2d(sustr, svstr, angle) sustr = rt.rho2uvp(sustr, 'u') svstr = rt.rho2uvp(svstr, 'v') # update wind data: newWind['date'] = t newWind['uwnd'] = uwnd newWind['vwnd'] = vwnd newWind['sustr'] = sustr newWind['svstr'] = svstr newWind['wspd'] = wspd # original xy: if tind == 0: newWind['attr'] = {'new_wind_info': new_wind_info} if not quiet: print(' --> original xy') if keepOriginal == 1: newWind['x_wind'] = x0 newWind['y_wind'] = y0 elif keepOriginal == 2: newWind['x_wind'] = x0[j1:j2, i1:i2] newWind['y_wind'] = y0[j1:j2, i1:i2] # add to file: if not quiet: print(' --> adding to file') fob.update_wind(newWind, quiet=quiet) if not quiet: print('')
def update_wind(fname,data,new_wind_info,**kargs): ''' new_wind_info will be added to fname as global attribute (ex: 'new wind from database xxx') ''' quiet = False Margin = 4 # for griddata and for original data to keep grd = False keepOriginal = 2 for k in kargs.keys(): if k=='quiet': quiet=kargs[k] elif k=='margin': Margin=kargs[k] elif k=='grid': grd=kargs[k] elif k.lower().startswith('keepor'): keepOriginal=kargs[k] if not grd: grd=netcdf.fatt(fname,'grd_file') g=roms.Grid(grd) x0=data['x'] y0=data['y'] if x0.ndim==1: x0,y0=np.meshgrid(x0,y0) dates=data.keys()[:] dates.remove('x') dates.remove('y') dates=np.array(dates) # interp in time: time=netcdf.nctime(fname,'time') cond=False tind=-1 fob=gennc.GenBlk(fname,grd) for t in time: newWind={} tind+=1 I,=np.where(dates==t) if I.size: I=I[0] uv=data[dates[I]] if not quiet: print(t,dates[I]) else: i1,=np.where(dates>t) i0,=np.where(dates<t) if i0.size and i1.size: i1=i1[0] i0=i0[-1] d0=t-dates[i0] d1=dates[i1]-t d0=d0.days+d0.seconds/86400. d1=d1.days+d1.seconds/86400. uv=(data[dates[i0]]*d1+data[dates[i1]]*d0)/(d0+d1) if not quiet: print(t,dates[i0],dates[i1], d0,d1) elif not i1.size: uv=data[dates[-1]] if not quiet: print(t,dates[-1]) elif not i0.size: uv=data[dates[0]] if not quiet: print(t,dates[0]) # interp to grid: if cond is False: cond,inds=rt.grid_vicinity(grd,x0,y0,margin=Margin,rect=True,retinds=True) i1,i2,j1,j2=inds if not quiet: print(' --> inter uv %s' % t.isoformat(' ')) u=calc.griddata(x0[cond],y0[cond],uv.real[cond],g.lon,g.lat,extrap=True) v=calc.griddata(x0[cond],y0[cond],uv.imag[cond],g.lon,g.lat,extrap=True) # rotate wind, calc stress: if not quiet: print(' --> rot U,V wind and U,V wind stress') wspd=np.sqrt(u**2+v**2) sustr,svstr=air_sea.wind_stress(u,v) angle=g.use('angle') uwnd,vwnd=calc.rot2d(u,v,angle) sustr,svstr=calc.rot2d(sustr,svstr,angle) sustr=rt.rho2uvp(sustr,'u') svstr=rt.rho2uvp(svstr,'v') # update wind data: newWind['date'] = t newWind['uwnd'] = uwnd newWind['vwnd'] = vwnd newWind['sustr'] = sustr newWind['svstr'] = svstr newWind['wspd'] = wspd # original xy: if tind==0: newWind['attr']={'new_wind_info':new_wind_info} if not quiet: print(' --> original xy') if keepOriginal==1: newWind['x_wind']=x0 newWind['y_wind']=y0 elif keepOriginal==2: newWind['x_wind']=x0[j1:j2,i1:i2] newWind['y_wind']=y0[j1:j2,i1:i2] # add to file: if not quiet: print(' --> adding to file') fob.update_wind(newWind,quiet=quiet) if not quiet: print('')
def gfs_file_data(fname, xlim=False, ylim=False, quiet=False): ''' Returns bulk data from one GFS file ''' # the way to ectract differes if using pygrib or grib2 ! so check first: try: import pygrib isPygrib = True except: isPygrib = False out = {} # T air 2m [K->C] if not quiet: print(' --> T air') if isPygrib: #x,y,tair=gribu.getvar(fname,'temperature',tags=(':2 metre',),lons=xlim,lats=ylim) #newest gribu: x, y, tair = gribu.getvar(fname, '2t', lons=xlim, lats=ylim) else: x, y, tair = gribu.getvar(fname, 'temperature', tags=(':2 m', 'TMP'), lons=xlim, lats=ylim) tair = tair - 273.15 out['tair'] = Data(x, y, tair, 'C') # R humidity 2m [%-->0--1] if not quiet: print(' --> R humidity') if 0: # kg/kg x, y, rhum = gribu.getvar(fname, 'humidity', tags=(':2 m', 'kg'), lons=xlim, lats=ylim) rhum = rhum / air_sea.qsat(tair) rhum = np.where(rhum > 1.0, 1.0, rhum) else: # % #x,y,rhum=gribu.getvar(fname,'humidity',tags=('2 m','%'),lons=xlim,lats=ylim) x, y, rhum = gribu.getvar(fname, '2r', lons=xlim, lats=ylim) rhum = rhum / 100. out['rhum'] = Data(x, y, rhum, '0--1') # surface pressure [Pa] if not quiet: print(' --> Surface pressure') #x,y,pres=gribu.getvar(fname,'pressure',tags='surface',lons=xlim,lats=ylim) x, y, pres = gribu.getvar(fname, 'sp', lons=xlim, lats=ylim) out['pres'] = Data(x, y, pres, 'Pa') # P rate [kg m-2 s-1 -> cm/d] if not quiet: print(' --> P rate') #x,y,prate=gribu.getvar(fname,'precipitation rate',lons=xlim,lats=ylim) x, y, prate = gribu.getvar(fname, 'prate', lons=xlim, lats=ylim) # Conversion kg m^-2 s^-1 to cm/day prate = prate * 86400 * 100 / 1000. prate = np.where(abs(prate) < 1.e-4, 0, prate) out['prate'] = Data(x, y, prate, 'cm/d') # Net shortwave flux [W/m^2] if not quiet: print(' --> Net shortwave flux') if not quiet: print(' SW down') if isPygrib: #x,y,sw_down = gribu.getvar(fname,'',tags='Downward short-wave radiation flux',lons=xlim,lats=ylim) x, y, sw_down = gribu.getvar(fname, 'dswrf', lons=xlim, lats=ylim) else: x, y, sw_down = gribu.getvar(fname, 'downward short-wave', lons=xlim, lats=ylim) if not quiet: print(' SW up') #x,y,sw_up = gribu.getvar(fname,'',tags='Upward short-wave radiation flux',lons=xlim,lats=ylim) x, y, sw_up = gribu.getvar(fname, 'uswrf', lons=xlim, lats=ylim) if sw_up is False: if not quiet: print(' SW up not found: using albedo') #x,y,albedo = gribu.getvar(fname,'albedo',lons=xlim,lats=ylim) x, y, albedo = gribu.getvar(fname, 'al', lons=xlim, lats=ylim) albedo = albedo / 100. sw_net = sw_down * (1 - albedo) else: sw_net = sw_down - sw_up sw_net = np.where(sw_net < 1.e-10, 0, sw_net) out['radsw'] = Data(x, y, sw_net, 'W m-2', info='positive downward') # Net longwave flux [W/m^2] if not quiet: print(' --> Net longwave flux') if not quiet: print(' LW down') if isPygrib: #x,y,lw_down = gribu.getvar(fname,'',tags='Downward long-wave radiation flux',lons=xlim,lats=ylim) x, y, lw_down = gribu.getvar(fname, 'dlwrf', lons=xlim, lats=ylim) else: x, y, lw_down = gribu.getvar(fname, 'downward long-wave', lons=xlim, lats=ylim) if not quiet: print(' LW up') #x,y,lw_up = gribu.getvar(fname,'',tags='Upward long-wave radiation flux',lons=xlim,lats=ylim) x, y, lw_up = gribu.getvar(fname, 'ulwrf', lons=xlim, lats=ylim) if lw_up is False: if not quiet: print(' LW up not found: using sst') if isPygrib: #x,y,sst=gribu.getvar(fname,'temperature',tags='surface',lons=xlim,lats=ylim) # K x, y, sst = gribu.getvar(fname, 't', lons=xlim, lats=ylim) # K else: x, y, sst = gribu.getvar(fname, 'temperature', tags='water surface', lons=xlim, lats=ylim) # K lw_net = air_sea.lwhf(sst, lw_down) lw_up = lw_down - lw_net else: lw_net = lw_down - lw_up # ROMS convention: positive upward # GFS convention: positive downward --> * (-1) lw_net = np.where(np.abs(lw_net) < 1.e-10, 0, lw_net) out['radlw'] = Data(x, y, -lw_net, 'W m-2', info='positive upward') # downward lw: out['dlwrf'] = Data(x, y, -lw_down, 'W m-2', info='negative... downward') # U and V wind speed 10m if not quiet: print(' --> U and V wind') #x,y,uwnd = gribu.getvar(fname,'u',tags=':10 m',lons=xlim,lats=ylim) #x,y,vwnd = gribu.getvar(fname,'v',tags=':10 m',lons=xlim,lats=ylim) x, y, uwnd = gribu.getvar(fname, '10u', lons=xlim, lats=ylim) x, y, vwnd = gribu.getvar(fname, '10v', lons=xlim, lats=ylim) if not quiet: print(' --> calc wind speed and stress') speed = np.sqrt(uwnd**2 + vwnd**2) taux, tauy = air_sea.wind_stress(uwnd, vwnd) out['wspd'] = Data(x, y, speed, 'm s-1') out['uwnd'] = Data(x, y, uwnd, 'm s-1') out['vwnd'] = Data(x, y, vwnd, 'm s-1') out['sustr'] = Data(x, y, taux, 'Pa') out['svstr'] = Data(x, y, tauy, 'Pa') # Cloud cover [0--100 --> 0--1]: if not quiet: print(' --> Cloud cover') #x,y,clouds = gribu.getvar(fname,'cloud cover',lons=xlim,lats=ylim) x, y, clouds = gribu.getvar(fname, 'tcc', lons=xlim, lats=ylim) if clouds is False: if not quiet: print('CALC clouds from LW,TAIR,TSEA and RH') # first get sst (maybe already done to calc lw_up) try: sst except: if not quiet: print(' get TSEA') if isPygrib: #x,y,sst=gribu.getvar(fname,'temperature',tags='surface',lons=xlim,lats=ylim) # K x, y, sst = gribu.getvar(fname, 't', lons=xlim, lats=ylim) # K else: x, y, sst = gribu.getvar(fname, 'temperature', tags='water surface', lons=xlim, lats=ylim) # K clouds = air_sea.cloud(lw_net, sst - 273.15, tair, rhum, 'net') else: clouds = clouds / 100. out['cloud'] = Data(x, y, clouds, 'fraction (0--1)') return out
def update_wind(fname, data, new_wind_info, **kargs): """ new_wind_info will be added to fname as global attribute (ex: 'new wind from database xxx') """ quiet = False Margin = 4 # for griddata and for original data to keep grd = False keepOriginal = 2 for k in kargs.keys(): if k == "quiet": quiet = kargs[k] elif k == "margin": Margin = kargs[k] elif k == "grid": grd = kargs[k] elif k.lower().startswith("keepor"): keepOriginal = kargs[k] if not grd: grd = netcdf.fatt(fname, "grd_file") g = roms.Grid(grd) x0 = data["x"] y0 = data["y"] if x0.ndim == 1: x0, y0 = np.meshgrid(x0, y0) dates = data.keys()[:] dates.remove("x") dates.remove("y") dates = np.array(dates) # interp in time: time = netcdf.nctime(fname, "time") cond = False tind = -1 fob = gennc.GenBlk(fname, grd) for t in time: newWind = {} tind += 1 I, = np.where(dates == t) if I.size: I = I[0] uv = data[dates[I]] if not quiet: print t, dates[I] else: i1, = np.where(dates > t) i0, = np.where(dates < t) if i0.size and i1.size: i1 = i1[0] i0 = i0[-1] d0 = t - dates[i0] d1 = dates[i1] - t d0 = d0.days + d0.seconds / 86400.0 d1 = d1.days + d1.seconds / 86400.0 uv = (data[dates[i0]] * d1 + data[dates[i1]] * d0) / (d0 + d1) if not quiet: print t, dates[i0], dates[i1], d0, d1 elif not i1.size: uv = data[dates[-1]] if not quiet: print t, dates[-1] elif not i0.size: uv = data[dates[0]] if not quiet: print t, dates[0] # interp to grid: if cond is False: cond, inds = rt.grid_vicinity(grd, x0, y0, margin=Margin, rect=True, retinds=True) i1, i2, j1, j2 = inds if not quiet: print " --> inter uv %s" % t.isoformat(" ") u = calc.griddata(x0[cond], y0[cond], uv.real[cond], g.lon, g.lat, extrap=True) v = calc.griddata(x0[cond], y0[cond], uv.imag[cond], g.lon, g.lat, extrap=True) # rotate wind, calc stress: if not quiet: print " --> rot U,V wind and U,V wind stress" wspd = np.sqrt(u ** 2 + v ** 2) sustr, svstr = air_sea.wind_stress(u, v) angle = g.use("angle") uwnd, vwnd = calc.rot2d(u, v, angle) sustr, svstr = calc.rot2d(sustr, svstr, angle) sustr = rt.rho2uvp(sustr, "u") svstr = rt.rho2uvp(svstr, "v") # update wind data: newWind["date"] = t newWind["uwnd"] = uwnd newWind["vwnd"] = vwnd newWind["sustr"] = sustr newWind["svstr"] = svstr newWind["wspd"] = wspd # original xy: if tind == 0: newWind["attr"] = {"new_wind_info": new_wind_info} if not quiet: print " --> original xy" if keepOriginal == 1: newWind["x_wind"] = x0 newWind["y_wind"] = y0 elif keepOriginal == 2: newWind["x_wind"] = x0[j1:j2, i1:i2] newWind["y_wind"] = y0[j1:j2, i1:i2] # add to file: if not quiet: print " --> adding to file" fob.update_wind(newWind, quiet=quiet) if not quiet: print ""
def wrf_file_data(file,quiet=False): ''' WRF data for ROMS ''' out={} # time: if not quiet: print ' --> get time' time=read_time(file) out['time']=time # lon,lat: if not quiet: print ' --> reading x,y' x=netcdf.use(file,'XLONG',**{'0': 0}) y=netcdf.use(file,'XLAT',**{'0': 0}) # tair [K-->C] if not quiet: print ' --> T air' tair=netcdf.use(file,'T2')-273.15 out['tair']=Data(x,y,tair,'Celsius') # R humidity [kg/kg --> 0--1] if not quiet: print ' --> R humidity from QV at 2m' wv=netcdf.use(file,'Q2') # water vapor mixing ratio at 2m rhum=wv/air_sea.qsat(tair) rhum[rhum>1]=1 out['rhum']=Data(x,y,rhum,'0--1') # surface pressure [Pa] if not quiet: print ' --> Surface pressure' pres=netcdf.use(file,'PSFC') out['pres']=Data(x,y,pres,'Pa') # P rate [mm --> cm day-1] if not quiet: print ' --> P rate (rainc+rainnc)' rainc = netcdf.use(file,'RAINC') rainnc = netcdf.use(file,'RAINNC') prate=rainc+rainnc if not quiet: print ' accum2avg...' prate=accum2avg(prate,dt=time[1]-time[0]) # mm s-1 conv= 0.1*86400 # from mm s-1 --> cm day-1 prate=prate*conv # cm day-1 prate[prate<0]=0 # interpolation errors may result in negative rain! out['prate']=Data(x,y,prate,'cm day-1') # LW, SW, latent, sensible signs: # positive (downward flux, heating) or negative (upward flux, cooling) #https://www.myroms.org/forum/viewtopic.php?f=1&t=2621 # Net shortwave flux [W m-2] if not quiet: print ' --> Net shortwave flux' sw_down=netcdf.use(file,'SWDOWN') albedo=netcdf.use(file,'ALBEDO') sw_net=sw_down*(1-albedo) out['radsw']=Data(x,y,sw_net,'W m-2',info='positive downward') # Net longwave flux [W m-2] if not quiet: print ' --> Net longwave flux' lw_down=netcdf.use(file,'GLW') # positive # sst needed: if not quiet: print ' --> SST for LW up' sst=netcdf.use(file,'SST') # K lw_net = air_sea.lwhf(sst,lw_down) # positive down # here vars have roms-agrif signs --> radlw is positive upward! #conversion to ROMS is done in surface.py out['radlw']=Data(x,y,-lw_net,'W m-2',info='positive upward') out['dlwrf']=Data(x,y,-lw_down,'W m-2',info='positive upward') # U and V wind speed 10m if not quiet: print ' --> U and V wind' uwnd=netcdf.use(file,'U10') vwnd=netcdf.use(file,'V10') if not quiet: print ' --> calc wind speed and stress' speed = np.sqrt(uwnd**2+vwnd**2) taux,tauy=air_sea.wind_stress(uwnd,vwnd) out['wspd']=Data(x,y,speed,'m s-1') out['uwnd']=Data(x,y,uwnd,'m s-1') out['vwnd']=Data(x,y,vwnd,'m s-1') out['sustr']=Data(x,y,taux,'Pa') out['svstr']=Data(x,y,tauy,'Pa') # Cloud cover [0--1]: if not quiet: print ' --> Cloud cover for LONGWAVE. Use LONGWAVE_OUT instead...' if 'CLDFRA' in netcdf.varnames(file): clouds=netcdf.use(file,'CLDFRA').sum(-3) clouds=np.where(clouds>1,1,clouds) else: if not quiet: print 'CLDFRA not found!! Using SST and air_sea.clouds' sst=netcdf.use(f,'SST') clouds=air_sea.clouds(lw_net,sst,tair,rhum,Wtype='net') out['cloud']=Data(x,y,clouds,'fraction (0--1)') return out
def cfsr_file_data(files,quiet=False): ''' Returns bulk data from one CFRS files ''' def load_time(f): time=np.array((),datetime.datetime) ff=glob.glob(f) ff.sort() for f in ff: time=np.append(time,netcdf.nctime(f,'time')) return time def load_time_main(f): time=load_time(f) # I want 0,6,12,... after 2006 results may be 3,9,15, ... if time[0].hour in [3,9,15,21]: time=time+datetime.timedelta(hours=3) # for 2011 1st time is not 0! if time[0].hour==6: time=np.hstack((time[0].replace(hour=0),time)) return time def fix_time(t,var,t0,t1): # convert 1h, 7h, ... to 0h, 6h, ... if t[0].hour in [1,7,13,19]: # not all! sp analysis starts at 0, 6,...! print(' 1,7,... to 0,6,...') var=(var[1:]*5+var[:-1]*1)/6. t=t[1:]-datetime.timedelta(hours=1) elif t[0].hour in [3,9,15,21]: print(' 3,9,... to 0,6,...') var=(var[1:]*3+var[:-1]*3)/6. t=t[1:]-datetime.timedelta(hours=3) cond=(t>=t0)&(t<=t1) t=t[cond] var=var[cond] if t[0]>t0: dt=t[0]-t0 dt=dt.days*24+dt.seconds/3600. # hours print('missing data at start: %.2d h missing --> repeating 1st data'%dt) v=np.zeros((var.shape[0]+1,)+var.shape[1:],var.dtype) v[1:]=var v[0]=var[0] var=v t_=np.zeros((t.shape[0]+1,)+t.shape[1:],t.dtype) t_[1:]=t t_[0]=t0 t=t_ if t[-1]<t1: dt=t1-t[-1] dt=dt.days*24+dt.seconds/3600. # hours print('missing data at end: %.2d h missing --> repeating last data'%dt) v=np.zeros((var.shape[0]+1,)+var.shape[1:],var.dtype) v[:-1]=var v[-1]=var[-1] var=v t_=np.zeros((t.shape[0]+1,)+t.shape[1:],t.dtype) t_[:-1]=t t_[-1]=t1 t=t_ return var,t out={} # time: if 0: time=netcdf.nctime(files['cc'],'time') # files have diff units !! so, cannot load all times at once! # these result will use only units of 1st file!! else: time=load_time_main(files['cc']) out['time']=time # T air [K->C] if not quiet: print(' --> T air') f=files['st'] tair=netcdf.use(f,'TMP_L103') tair=tair-273.15 x=netcdf.use(f,'lon'); x[x>180]=x[x>180]-360 y=netcdf.use(f,'lat') x,y=np.meshgrid(x,y) # check time: ttmp=load_time(f) if ttmp.size==time.size and np.all(ttmp==time): print(' time ok') else: print(' time differs !!!!',) tair,tfix=fix_time(ttmp,tair,time[0],time[-1]) if tfix.size==time.size and np.all(tfix==time): print(' ...fixed!') else: print('time is NOT OK. Please check !!') return out['tair']=Data(x,y,tair,'C') # R humidity [%-->0--1] if not quiet: print(' --> R humidity') f=files['rh'] rhum=netcdf.use(f,'R_H_L103') rhum=rhum/100. x=netcdf.use(f,'lon'); x[x>180]=x[x>180]-360 y=netcdf.use(f,'lat') x,y=np.meshgrid(x,y) # check time: ttmp=load_time(f) if ttmp.size==time.size and np.all(ttmp==time): print(' time ok') else: print(' time differs !!!!'), # should use end=' ' for python3 print continuation rhum,tfix=fix_time(ttmp,rhum,time[0],time[-1]) if tfix.size==time.size and np.all(tfix==time): print(' ...fixed!') else: print('time is NOT OK. Please check !!') return out['rhum']=Data(x,y,rhum,'0--1') # surface pressure [Pa] if not quiet: print(' --> Surface pressure') f=files['sp'] pres=netcdf.use(f,'PRES_L1') x=netcdf.use(f,'lon'); x[x>180]=x[x>180]-360 y=netcdf.use(f,'lat') x,y=np.meshgrid(x,y) # check time: ttmp=load_time(f) if ttmp.size==time.size and np.all(ttmp==time): print(' time ok') else: print(' time differs !!!!'), pres,tfix=fix_time(ttmp,pres,time[0],time[-1]) if tfix.size==time.size and np.all(tfix==time): print(' ...fixed!') else: print('time is NOT OK. Please check !!') return out['pres']=Data(x,y,pres,'Pa') # P rate [kg m-2 s-1 -> cm/d] if not quiet: print(' --> P rate') f=files['pr'] if 'PRATE_L1' in netcdf.varnames(f): prate=netcdf.use(f,'PRATE_L1') else: prate=netcdf.use(f,'PRATE_L1_Avg_1') x=netcdf.use(f,'lon'); x[x>180]=x[x>180]-360 y=netcdf.use(f,'lat') x,y=np.meshgrid(x,y) # Conversion kg m^-2 s^-1 to cm/day prate=prate*86400*100/1000. prate=np.where(abs(prate)<1.e-4,0,prate) # check time: ttmp=load_time(f) if ttmp.size==time.size and np.all(ttmp==time): print(' time ok') else: print(' time differs !!!!'), prate,tfix=fix_time(ttmp,prate,time[0],time[-1]) if tfix.size==time.size and np.all(tfix==time): print(' ...fixed!') else: print('time is NOT OK. Please check !!') return out['prate']=Data(x,y,prate,'cm/d') # Net shortwave flux [W/m^2] if not quiet: print(' --> Net shortwave flux') if not quiet: print(' SW down') f=files['rad'] sw_down=netcdf.use(f,'DSWRF_L1_Avg_1') x=netcdf.use(f,'lon'); x[x>180]=x[x>180]-360 y=netcdf.use(f,'lat') x,y=np.meshgrid(x,y) if not quiet: print(' SW up') sw_up=netcdf.use(f,'USWRF_L1_Avg_1') sw_net=sw_down-sw_up sw_net=np.where(sw_net<1.e-10,0,sw_net) # check time: ttmp=load_time(f) if ttmp.size==time.size and np.all(ttmp==time): print(' time ok') else: print(' time differs !!!!'), sw_net,tfix=fix_time(ttmp,sw_net,time[0],time[-1]) if tfix.size==time.size and np.all(tfix==time): print(' ...fixed!') else: print('time is NOT OK. Please check !!') return out['radsw']=Data(x,y,sw_net,'W m-2',info='positive downward') # Net longwave flux [W/m^2] if not quiet: print(' --> Net longwave flux') if not quiet: print(' LW down') f=files['rad'] lw_down=netcdf.use(f,'DLWRF_L1_Avg_1') x=netcdf.use(f,'lon'); x[x>180]=x[x>180]-360 y=netcdf.use(f,'lat') x,y=np.meshgrid(x,y) if not quiet: print(' LW up') lw_up=netcdf.use(f,'ULWRF_L1_Avg_1') lw_net=lw_down-lw_up lw_net=np.where(np.abs(lw_net)<1.e-10,0,lw_net) # check time: ttmp=load_time(f) if ttmp.size==time.size and np.all(ttmp==time): print(' time ok') else: print(' time differs !!!!'), lw_net,tfix1=fix_time(ttmp,lw_net,time[0],time[-1]) lw_down,tfix2=fix_time(ttmp,lw_down,time[0],time[-1]) if tfix1.size==tfix2.size==time.size and np.all((tfix1==time)&(tfix2==time)): print(' ...fixed!') else: print('time is NOT OK. Please check !!') return # ROMS (agrif, used to be!) convention: positive upward out['radlw']=Data(x,y,-lw_net,'W m-2',info='positive upward') # downward lw: out['dlwrf']=Data(x,y,-lw_down,'W m-2',info='negative... downward') # signs convention is better explained in wrf.py # U and V wind speed 10m if not quiet: print(' --> U and V wind') f=files['uv'] uwnd=netcdf.use(f,'U_GRD_L103') vwnd=netcdf.use(f,'V_GRD_L103') x=netcdf.use(f,'lon'); x[x>180]=x[x>180]-360 y=netcdf.use(f,'lat') x,y=np.meshgrid(x,y) # check time: ttmp=load_time(f) if ttmp.size==time.size and np.all(ttmp==time): print(' time ok') else: print(' time differs !!!!'), uwnd,tfix1=fix_time(ttmp,uwnd,time[0],time[-1]) vwnd,tfix2=fix_time(ttmp,vwnd,time[0],time[-1]) if tfix1.size==tfix2.size==time.size and np.all((tfix1==time)&(tfix2==time)): print(' ...fixed!') else: print('time is NOT OK. Please check !!') return # if not quiet: print(' --> calc wind speed and stress') speed = np.sqrt(uwnd**2+vwnd**2) taux,tauy=air_sea.wind_stress(uwnd,vwnd) out['wspd']=Data(x,y,speed,'m s-1') out['uwnd']=Data(x,y,uwnd,'m s-1') out['vwnd']=Data(x,y,vwnd,'m s-1') out['sustr']=Data(x,y,taux,'Pa') out['svstr']=Data(x,y,tauy,'Pa') # Cloud cover [0--100 --> 0--1]: if not quiet: print(' --> Cloud cover') f=files['cc'] if 'T_CDC_L200' in netcdf.varnames(f): clouds=netcdf.use(f,'T_CDC_L200') else: clouds=netcdf.use(f,'T_CDC_L200_Avg_1') x=netcdf.use(f,'lon'); x[x>180]=x[x>180]-360 y=netcdf.use(f,'lat') x,y=np.meshgrid(x,y) clouds=clouds/100. # check time: ttmp=load_time(f) if ttmp.size==time.size and np.all(ttmp==time): print(' time ok') else: print(' time differs !!!!'), clouds,tfix=fix_time(ttmp,clouds,time[0],time[-1]) if tfix.size==time.size and np.all(tfix==time): print(' ...fixed!') else: print('time is NOT OK. Please check !!') return out['cloud']=Data(x,y,clouds,'fraction (0--1)') # rhum has different resolution (0.5, just like dew point!) # so, i can edit surface.py or just interpolate here rhum to # other vars resolution: if out['rhum'].data.shape!=out['uwnd'].data.shape: from okean import calc print('rhum shape differs!! --> interp:') nt,ny,nx=out['uwnd'].data.shape x,y=out['uwnd'].x,out['uwnd'].y rhum=np.zeros((nt,ny,nx), out['rhum'].data.dtype) for it in range(nt): if it%100==0: print(' %d of %d'%(it,nt)) rhum[it]=calc.griddata(out['rhum'].x,out['rhum'].y,out['rhum'].data[it],x,y) out['rhum']=Data(x,y,rhum,'0--1') return out
ttmp = load_time(f) if ttmp.size == time.size and np.all(ttmp == time): print ' time ok' else: print ' time differs !!!!', uwnd, tfix1 = fix_time(ttmp, uwnd, time[0], time[-1]) vwnd, tfix2 = fix_time(ttmp, vwnd, time[0], time[-1]) if tfix1.size == tfix2.size == time.size and np.all((tfix1 == time) & (tfix2 == time)): print ' ...fixed!' else: print 'time is NOT OK. Please check !!' return # if not quiet: print ' --> calc wind speed and stress' speed = np.sqrt(uwnd**2 + vwnd**2) taux, tauy = air_sea.wind_stress(uwnd, vwnd) out['wspd'] = Data(x, y, speed, 'm s-1') out['uwnd'] = Data(x, y, uwnd, 'm s-1') out['vwnd'] = Data(x, y, vwnd, 'm s-1') out['sustr'] = Data(x, y, taux, 'Pa') out['svstr'] = Data(x, y, tauy, 'Pa') # Cloud cover [0--100 --> 0--1]: if not quiet: print ' --> Cloud cover' f = files['cc'] if 'T_CDC_L200' in netcdf.varnames(f): clouds = netcdf.use(f, 'T_CDC_L200') else: clouds = netcdf.use(f, 'T_CDC_L200_Avg_1') x = netcdf.use(f, 'lon')
def narr_file_data(fname, xlim=False, ylim=False, quiet=False): ''' Returns bulk data from one NARR file ''' out = {} # loading grid: if 0: if not quiet: print ' reading lon,lat from file %s' % grd nc = netcdf.ncopen(grd) x = nc.vars['East_longitude_0-360'][0, ...] - 360. y = nc.vars['Latitude_-90_to_+90'][0, ...] # time always 1 !! nc.close() else: if not quiet: print ' reading lon,lat from file %s' % grdTxt x, y = load_grid() #x=x-360. x = -x ny, nx = x.shape if (xlim, ylim) == (False, False): i0, i1, j0, j1 = 0, nx, 0, ny else: i0, i1, j0, j1 = calc.ij_limits(x, y, xlim, ylim, margin=0) x = x[j0:j1, i0:i1] y = y[j0:j1, i0:i1] try: nc = netcdf.ncopen(fname) except: return {} xx = str(i0) + ':' + str(i1) yy = str(j0) + ':' + str(j1) tdim = netcdf.fdim(nc, 'time1') if tdim != 1: print 'WARNING: tdim !=1 !!!!!!' # T surface [K->C] if not quiet: print ' --> T air' tair = netcdf.use(nc, 'Temperature_surface', time1=0, x=xx, y=yy) tair = tair - 273.15 out['tair'] = cb.Data(x, y, tair, 'C') # R humidity [% -> 0--1] if not quiet: print ' --> R humidity' rhum = netcdf.use(nc, 'Relative_humidity', time1=0, x=xx, y=yy) out['rhum'] = cb.Data(x, y, rhum / 100., '0--1') # surface pressure [Pa] if not quiet: print ' --> Surface pressure' pres = netcdf.use(nc, 'Pressure_surface', time1=0, x=xx, y=yy) out['pres'] = cb.Data(x, y, pres, 'Pa') # P rate [kg m-2 s-1 -> cm/d] if not quiet: print ' --> P rate' prate = netcdf.use(nc, 'Precipitation_rate', time1=0, x=xx, y=yy) prate = prate * 86400 * 100 / 1000. out['prate'] = cb.Data(x, y, prate, 'cm/d') # Net shortwave flux [ W m-2] if not quiet: print ' --> Net shortwave flux' if not quiet: print ' SW down' sw_down = netcdf.use(nc, 'Downward_shortwave_radiation_flux', time1=0, x=xx, y=yy) if not quiet: print ' SW up' sw_up = netcdf.use(nc, 'Upward_short_wave_radiation_flux_surface', time1=0, x=xx, y=yy) sw_net = sw_down - sw_up out['radsw'] = cb.Data(x, y, sw_net, 'W m-2', info='positive downward') # Net longwave flux [W/m^2] if not quiet: print ' --> Net longwave flux' if not quiet: print ' LW down' lw_down = netcdf.use(nc, 'Downward_longwave_radiation_flux', time1=0, x=xx, y=yy) if not quiet: print ' LW up' lw_up = netcdf.use(nc, 'Upward_long_wave_radiation_flux_surface', time1=0, x=xx, y=yy) lw_net = lw_down - lw_up out['radlw'] = cb.Data(x, y, -lw_net, 'W m-2', info='positive upward') # downward lw: out['dlwrf'] = cb.Data(x, y, -lw_down, 'W m-2', info='negative... downward') # U and V wind speed 10m if not quiet: print ' --> U and V wind' # vertical dim is height_above_ground1: 10 and 30 m uwnd = netcdf.use(nc, 'u_wind_height_above_ground', height_above_ground1=0, time1=0, x=xx, y=yy) vwnd = netcdf.use(nc, 'v_wind_height_above_ground', height_above_ground1=0, time1=0, x=xx, y=yy) if not quiet: print ' --> calc wind speed and stress' speed = np.sqrt(uwnd**2 + vwnd**2) taux, tauy = air_sea.wind_stress(uwnd, vwnd) out['wspd'] = cb.Data(x, y, speed, 'm s-1') out['uwnd'] = cb.Data(x, y, uwnd, 'm s-1') out['vwnd'] = cb.Data(x, y, vwnd, 'm s-1') out['sustr'] = cb.Data(x, y, taux, 'Pa') out['svstr'] = cb.Data(x, y, tauy, 'Pa') # Cloud cover [0--100 --> 0--1]: if not quiet: print ' --> Cloud cover' clouds = netcdf.use(nc, 'Total_cloud_cover', time1=0, x=xx, y=yy) out['cloud'] = cb.Data(x, y, clouds / 100., 'fraction (0--1)') nc.close() return out
vwnd=netcdf.use(f,'V_GRD_L103') x=netcdf.use(f,'lon'); x[x>180]=x[x>180]-360 y=netcdf.use(f,'lat') x,y=np.meshgrid(x,y) # check time: ttmp=load_time(f) if ttmp.size==time.size and np.all(ttmp==time): print ' time ok' else: print ' time differs !!!!', uwnd=fix_time(ttmp,uwnd,time[0],time[-1]) vwnd=fix_time(ttmp,vwnd,time[0],time[-1]) print ' ...fixed!' # if not quiet: print ' --> calc wind speed and stress' speed = np.sqrt(uwnd**2+vwnd**2) taux,tauy=air_sea.wind_stress(uwnd,vwnd) out['wspd']=Data(x,y,speed,'m s-1') out['uwnd']=Data(x,y,uwnd,'m s-1') out['vwnd']=Data(x,y,vwnd,'m s-1') out['sustr']=Data(x,y,taux,'Pa') out['svstr']=Data(x,y,tauy,'Pa') # Cloud cover [0--100 --> 0--1]: if not quiet: print ' --> Cloud cover' f=files['cc'] clouds=netcdf.use(f,'T_CDC_L200') x=netcdf.use(f,'lon'); x[x>180]=x[x>180]-360 y=netcdf.use(f,'lat') x,y=np.meshgrid(x,y)
def wrf_file_data(file, quiet=False): ''' WRF data for ROMS ''' out = {} # time: if not quiet: print(' --> get time') time = read_time(file) out['time'] = time # lon,lat: if not quiet: print(' --> reading x,y') x = netcdf.use(file, 'XLONG', Time=0) #**{'0': 0}) y = netcdf.use(file, 'XLAT', Time=0) #**{'0': 0}) # tair [K-->C] if not quiet: print(' --> T air') tair = netcdf.use(file, 'T2') - 273.15 out['tair'] = Data(x, y, tair, 'Celsius') # R humidity [kg/kg --> 0--1] if not quiet: print(' --> R humidity from QV at 2m') wv = netcdf.use(file, 'Q2') # water vapor mixing ratio at 2m rhum = wv / air_sea.qsat(tair) rhum[rhum > 1] = 1 out['rhum'] = Data(x, y, rhum, '0--1') # surface pressure [Pa] if not quiet: print(' --> Surface pressure') pres = netcdf.use(file, 'PSFC') out['pres'] = Data(x, y, pres, 'Pa') # P rate [mm --> cm day-1] if not quiet: print(' --> P rate (rainc+rainnc)') rainc = netcdf.use(file, 'RAINC') rainnc = netcdf.use(file, 'RAINNC') prate = rainc + rainnc if not quiet: print(' accum2avg...') prate = accum2avg(prate, dt=time[1] - time[0]) # mm s-1 conv = 0.1 * 86400 # from mm s-1 --> cm day-1 prate = prate * conv # cm day-1 prate[prate < 0] = 0 # interpolation errors may result in negative rain! out['prate'] = Data(x, y, prate, 'cm day-1') # LW, SW, latent, sensible signs: # positive (downward flux, heating) or negative (upward flux, cooling) #https://www.myroms.org/forum/viewtopic.php?f=1&t=2621 # Net shortwave flux [W m-2] if not quiet: print(' --> Net shortwave flux') sw_down = netcdf.use(file, 'SWDOWN') albedo = netcdf.use(file, 'ALBEDO') sw_net = sw_down * (1 - albedo) out['radsw'] = Data(x, y, sw_net, 'W m-2', info='positive downward') # Net longwave flux [W m-2] if not quiet: print(' --> Net longwave flux') lw_down = netcdf.use(file, 'GLW') # positive # sst needed: if not quiet: print(' --> SST for LW up') sst = netcdf.use(file, 'SST') # K lw_net = air_sea.lwhf(sst, lw_down) # positive down # here vars have roms-agrif signs --> radlw is positive upward! #conversion to ROMS is done in surface.py out['radlw'] = Data(x, y, -lw_net, 'W m-2', info='positive upward') out['dlwrf'] = Data(x, y, -lw_down, 'W m-2', info='positive upward') # U and V wind speed 10m if not quiet: print(' --> U and V wind') uwnd = netcdf.use(file, 'U10') vwnd = netcdf.use(file, 'V10') if not quiet: print(' --> calc wind speed and stress') speed = np.sqrt(uwnd**2 + vwnd**2) taux, tauy = air_sea.wind_stress(uwnd, vwnd) out['wspd'] = Data(x, y, speed, 'm s-1') out['uwnd'] = Data(x, y, uwnd, 'm s-1') out['vwnd'] = Data(x, y, vwnd, 'm s-1') out['sustr'] = Data(x, y, taux, 'Pa') out['svstr'] = Data(x, y, tauy, 'Pa') # Cloud cover [0--1]: if not quiet: print(' --> Cloud cover for LONGWAVE. Use LONGWAVE_OUT instead...') if 0: pass # next code is wrong! If cloud cover is really needed, it needs to be calculated using wrfpost. # See http://www2.mmm.ucar.edu/wrf/users/docs/user_guide/users_guide_chap8.html#_ARWpost_1 # # if 'CLDFRA' in netcdf.varnames(file): # clouds=netcdf.use(file,'CLDFRA').sum(-3) # clouds=np.where(clouds>1,1,clouds) else: if not quiet: print('CLDFRA not found!! Using SST and air_sea.cloud_fraction') sst = netcdf.use(file, 'SST') - 273.15 clouds = air_sea.cloud_fraction(lw_net, sst, tair, rhum, Wtype='net') clouds[clouds < 0] = 0 clouds[clouds > 1] = 1 out['cloud'] = Data(x, y, clouds, 'fraction (0--1)') return out
def era5_file_data(files, quiet=False): ''' ECMWF ERA5 data for ROMS variables: # radiation: msdwlwrf - mean_surface_downward_long_wave_radiation_flux #msdwswrf - mean_surface_downward_short_wave_radiation_flux -- not needed msnlwrf - mean_surface_net_long_wave_radiation_flux msnswrf - mean_surface_net_short_wave_radiation_flux # rain: mtpr - mean_total_precipitation_rate # wind: u10 - 10m_u_component_of_wind v10 - 10m_v_component_of_wind # temp: t2m - 2m_temperature d2m - 2m_dewpoint_temperature (for relative humidity) # pres: sp - surface_pressure # clouds: tcc - 'total_cloud_cover ''' ### # some variables may have different names! ### Vars={} ### Vars['v10u']='v10u','u10' ### Vars['v10v']='v10v','v10' ### Vars['v2t']='v2t','t2m' ### Vars['v2d']='v2d','d2m' ### #### def find_v(name): ### if name in Vars.keys(): ### for v in Vars[name]: ### if varfile(v): return v ### else: return name def varfile(var): for f in files: if var in netcdf.varnames(f): return f ##3 def check_var_type(var): ### # new interim dataserver provides forec+analysis vars with extra dim ### # 'type', 0 or 1 ### if var.ndim==4: ### if not quiet: print(' dealing with var type... '), ### v=np.zeros(var.shape[1:],var.dtype) ### v[::2]=var[0,::2,...] ### v[1::2]=var[1,1::2,...] ### var=v ### if not quiet: print('done.') ### ### return var out = {} # time: File = varfile('t2m') # air temp, for instance if not quiet: print(' reading time from file %s' % File) time = netcdf.nctime(File, 'time') # check if last time at 00h: if time[-1].hour != 0: dateEnd = datetime.datetime(time[-1].year, time[-1].month, time[-1].day) + datetime.timedelta(days=1) time = np.append(time, dateEnd) else: dateEnd = 0 out['time'] = time ### # all times from analysis file, except last ind which will be ###### # the last time of forecast file ### aFile=varfile(find_v('v2t')) # air temp, for instance ###### fFile=varfile(find_v('ssr')) # sw rad, for instance ### if not quiet: print(' reading "analysis" time from file %s' % aFile) ### aTime=netcdf.nctime(aFile,'time') ### aTime.sort() # analysis+forecast files may not have time sorted!! ### if not quiet: print(' reading "forecast" time from file %s' % fFile) ### fTime=netcdf.nctime(fFile,'time') ### fTime.sort() # this one should be sorted... ### time=np.append(aTime,fTime[-1]) ### out['time']=time ## # # calc number of forecast steps stored,nforec (used by accum2avg) # if [fTime[i].hour for i in range(8)]==range(3,22,3)+[0]: nforec=4 # elif [fTime[i].hour for i in range(4)]==range(6,19,6)+[0]: nforec=2 # else: # if not quiet: print('INTERIM WRONG TIME: cannot n forec steps') # return # ### if not quiet: print(' ==> n forecast steps = %d' % nforec) # x,y: if not quiet: print(' reading x,y from file %s' % File) x = netcdf.use(File, 'longitude') y = netcdf.use(File, 'latitude') x[x > 180] = x[x > 180] - 360 if x.ndim == 1 and y.ndim == 1: x, y = np.meshgrid(x, y) # tair [K-->C] if not quiet: print(' --> T air') vname = 't2m' f = varfile(vname) tair = netcdf.use(f, vname) - 273.15 if dateEnd: if not quiet: print(' fill_tend...') tair = fill_tend(tair) out['tair'] = Data(x, y, tair, 'Celsius') # R humidity [0--1] if not quiet: print(' --> R humidity (from T dew)') vname = 'd2m' f = varfile(vname) Td = netcdf.use(f, vname) - 273.15 if dateEnd: if not quiet: print(' fill_tend... (T dew)') Td = fill_tend(Td) T = tair rhum = air_sea.relative_humidity(T, Td) rhum[rhum > 1] = 1 out['rhum'] = Data(x, y, rhum, '0--1') # surface pressure [Pa] if not quiet: print(' --> Surface pressure') vname = 'sp' f = varfile(vname) pres = netcdf.use(f, vname) if dateEnd: if not quiet: print(' fill_tend...') pres = fill_tend(pres) out['pres'] = Data(x, y, pres, 'Pa') def avg_fix_time(v, DT): '''Fix data to right time in avg rate fields (ie, prev half hour to now) See: https://confluence.ecmwf.int/display/CKB/ERA5+data+documentation#ERA5datadocumentation-Meanratesandaccumulations ''' DTstep = 1 a = DTstep / 2. b = DT - a u = np.zeros_like(v) u[:-1] = (v[:-1] * b + v[1:] * a) / (a + b) # last one lost, use prev value (from 30 min before) u[-1] = v[-1] return u DT = (time[1] - time[0]).total_seconds() / 3600. # hours # P rate [kg m-2 s-1 --> cm day-1] if not quiet: print(' --> P rate') vname = 'mtpr' f = varfile(vname) prate = netcdf.use(f, vname) if not quiet: print(' avg_fix_time - DTstep=1h - DT=%.2f h' % DT) prate = avg_fix_time(prate, DT) if dateEnd: if not quiet: print(' fill_tend...') prate = fill_tend(prate) conv = 100 * 86400 / 1000. # from kg m-2 s-1 --> cm day-1 prate = prate * conv # cm day-1 prate[prate < 0] = 0 out['prate'] = Data(x, y, prate, 'cm day-1') # dt=(TIMe[1]-time[0]).total_seconds()/3600. # if not quiet: print(' accum to avg at correct time - DTstep=1h - DT=%.2f h'%DT) # prate2=accum2avg(prate,DT) # prate2=prate2*1000 # return prate,prate2 # prate=check_var_type(prate) # if not quiet and np.any(sortInds!=range(len(sortInds))): print(' sort DONE') # if not quiet: print(' accum2avg...') # prate=accum2avg(prate,nforec) # conv= 100*86400 # from m s-1 --> cm day-1 # #conv= 100*86400/1000. # from kg m-2 s-1 --> cm day-1 # prate=prate*conv # cm day-1 # if not quiet: print(' fill_t0...') # prate=fill_t0(prate) # prate[prate<0]=0 # out['prate']=Data(x,y,prate,'cm day-1') # # return out # Net shortwave flux [W m-2 --> W m-2] if not quiet: print(' --> Net shortwave flux') vname = 'msnswrf' f = varfile(vname) sw_net = netcdf.use(f, vname) if not quiet: print(' avg_fix_time - DTstep=1h - DT=%.2f h' % DT) sw_net = avg_fix_time(sw_net, DT) if dateEnd: if not quiet: print(' fill_tend...') sw_net = fill_tend(sw_net) out['radsw'] = Data(x, y, sw_net, 'W m-2', info='positive downward') # Net longwave flux [W m-2 --> W m-2] if not quiet: print(' --> Net longwave flux') vname = 'msnlwrf' f = varfile(vname) lw_net = netcdf.use(f, vname) * -1 # positive upward (*-1) # here vars have roms-agrif signs --> radlw is positive upward! # conversion to ROMS is done in surface.py if not quiet: print(' avg_fix_time - DTstep=1h - DT=%.2f h' % DT) lw_net = avg_fix_time(lw_net, DT) if dateEnd: if not quiet: print(' fill_tend...') lw_net = fill_tend(lw_net) out['radlw'] = Data(x, y, lw_net, 'W m-2', info='positive upward') # longwave down: if not quiet: print(' --> Down longwave flux') vname = 'msdwlwrf' f = varfile(vname) lw_down = netcdf.use(f, vname) * -1 # positive upward (*-1) if not quiet: print(' avg_fix_time - DTstep=1h - DT=%.2f h' % DT) lw_down = avg_fix_time(lw_down, DT) if dateEnd: if not quiet: print(' fill_tend...') lw_down = fill_tend(lw_down) out['dlwrf'] = Data(x, y, lw_down, 'W m-2', info='positive upward') # U and V wind speed 10m if not quiet: print(' --> U and V wind') vname = 'u10' f = varfile(vname) uwnd = netcdf.use(f, vname) vname = 'v10' f = varfile(vname) vwnd = netcdf.use(f, vname) if dateEnd: if not quiet: print(' fill_tend...') uwnd = fill_tend(uwnd) vwnd = fill_tend(vwnd) out['uwnd'] = Data(x, y, uwnd, 'm s-1') out['vwnd'] = Data(x, y, vwnd, 'm s-1') # speed and stress: if 0: if not quiet: print(' --> calc wind speed and stress') speed = np.sqrt(uwnd**2 + vwnd**2) taux, tauy = air_sea.wind_stress(uwnd, vwnd) out['wspd'] = Data(x, y, speed, 'm s-1') out['sustr'] = Data(x, y, taux, 'Pa') out['svstr'] = Data(x, y, tauy, 'Pa') # Cloud cover [0--1]: if not quiet: print(' --> Cloud cover') vname = 'tcc' f = varfile(vname) clouds = netcdf.use(f, vname) if dateEnd: if not quiet: print(' fill_tend...') clouds = fill_tend(clouds) out['cloud'] = Data(x, y, clouds, 'fraction (0--1)') return out