def extract(self,year,level=3,version=2,lims=False): a=SMOSdownload(self.path) p=a.destination_folder(year,level,version,gen=False) files=glob.glob(os.path.join(p,'*.nc')) files.sort() res=OrderedDict() for f in files: print(' -- extracting from %s'%f) if f==files[0]: lon=netcdf.use(f,'longitude') lat=netcdf.use(f,'latitude') if lims: i0,i1,j0,j1=calc.ij_limits(lon,lat,lims[:2],lims[2:],margin=2) ii='%d:%d'%(i0,i1+1) jj='%d:%d'%(j0,j1+1) lon=netcdf.use(f,'longitude',longitude=ii) lat=netcdf.use(f,'latitude',latitude=jj) else: ii,jj=':',':' date0=netcdf.nctime(f,'date_start')[0] date1=netcdf.nctime(f,'date_stop')[0] date=netcdf.nctime(f,'time')[0] sss=netcdf.use(f,'sss',longitude=ii,latitude=jj) res[date]=date0,date1,sss return lon,lat,res
def extract(self, year, level=3, version=2, lims=False): a = SMOSdownload(self.path) p = a.destination_folder(year, level, version, gen=False) files = glob.glob(os.path.join(p, '*.nc')) files.sort() res = OrderedDict() for f in files: print(' -- extracting from %s' % f) if f == files[0]: lon = netcdf.use(f, 'longitude') lat = netcdf.use(f, 'latitude') if lims: i0, i1, j0, j1 = calc.ij_limits(lon, lat, lims[:2], lims[2:], margin=2) ii = '%d:%d' % (i0, i1 + 1) jj = '%d:%d' % (j0, j1 + 1) lon = netcdf.use(f, 'longitude', longitude=ii) lat = netcdf.use(f, 'latitude', latitude=jj) else: ii, jj = ':', ':' date0 = netcdf.nctime(f, 'date_start')[0] date1 = netcdf.nctime(f, 'date_stop')[0] date = netcdf.nctime(f, 'time')[0] sss = netcdf.use(f, 'sss', longitude=ii, latitude=jj) res[date] = date0, date1, sss return lon, lat, res
def make_frc(frcname,grd,date0,date1): g=roms.Grid(grd) if not os.path.isfile(frcname): # create file: gen_frc(frcname,grd) else: last=netcdf.nctime(frcname,'wind_time',wind_time=-1) print '-->found file %s with last time %s'%(frcname,last.isoformat()) date0=last+datetime.timedelta(1/4.) dates=[date0] while dates[-1]<date1: dates+=[dates[-1]+datetime.timedelta(1/4.)] n=-1 for d in dates: n+=1 if d==dates[0]: x,y,u,v,ij=read_wind(grd,d,ij=False) else: u,v=read_wind(grd,d,ij) U=calc.griddata(x,y,u,g.lon,g.lat) V=calc.griddata(x,y,v,g.lon,g.lat) # rotate wind, print ' --> rot U,V' angle=g.use('angle') U,V=calc.rot2d(U,V,angle) print ' filling %s'%d.isoformat(' ') fill_frc(frcname,d,U,V)
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 make_frc(frcname, grd, date0, date1): g = roms.Grid(grd) if not os.path.isfile(frcname): # create file: gen_frc(frcname, grd) else: last = netcdf.nctime(frcname, 'wind_time', wind_time=-1) print '-->found file %s with last time %s' % (frcname, last.isoformat()) date0 = last + datetime.timedelta(1.) # daily dates = [date0] while dates[-1] < date1: dates += [dates[-1] + datetime.timedelta(1.)] # daily n = -1 for d in dates: n += 1 if d == dates[0]: x, y, u, v, ij = read_wind(grd, d, ij=False) else: u, v = read_wind(grd, d, ij) U = calc.griddata(x, y, u, g.lon, g.lat, extrap=True) V = calc.griddata(x, y, v, g.lon, g.lat, extrap=True) # rotate wind, print ' --> rot U,V' angle = g.use('angle') U, V = calc.rot2d(U, V, angle) print ' filling %s' % d.isoformat(' ') fill_frc(frcname, d, U, V)
def source(date): src=glob.glob('%d/aoscat_%d_*.nc'%(date.year,date.year)) src.sort() # cant return all files cos MFDataset wont work with files # without unlimited dimension ! for s in src: t=netcdf.nctime(s,'time') if date>=t[0] and date<=t[-1]: return s
def source(date): src = glob.glob('%d/aoscat_%d_*.nc' % (date.year, date.year)) src.sort() # cant return all files cos MFDataset wont work with files # without unlimited dimension ! for s in src: t = netcdf.nctime(s, 'time') if date >= t[0] and date <= t[-1]: return s
def read_wind(grd, date, ij=False): f = source(date) print('-- reading from %s' % f) time = netcdf.nctime(f, 'time') if 0: try: i = np.where(time == date)[0][0] except: return 'date %s not found' % date.isoformat(' ') else: i = 0 returnXY = False if ij is False: returnXY = True lon = netcdf.use(f, 'longitude') # -180..180 lat = netcdf.use(f, 'latitude') g = roms.Grid(grd) xl0 = np.asarray((g.lon.min(), g.lon.max())) xl = np.asarray((g.lon.min(), g.lon.max())) if np.any(xl > 180) or np.any(xl < -180): print('ERROR: grid is supposed to be -180<x<180') print( 'Can be implemented with mpl_toolkits.basemap.shiftgrid ... TODO' ) print('(http://matplotlib.org/basemap/api/basemap_api.html)') return yl = g.lat.min(), g.lat.max() ij = calc.ij_limits(lon, lat, xl, yl, margin=1) i0, i1, j0, j1 = ij u = netcdf.use(f, 'eastward_wind', longitude='%d:%d' % (i0, i1), latitude='%d:%d' % (j0, j1), time=i) v = netcdf.use(f, 'northward_wind', longitude='%d:%d' % (i0, i1), latitude='%d:%d' % (j0, j1), time=i) if returnXY: lon = netcdf.use(f, 'longitude', longitude='%d:%d' % (i0, i1), latitude='%d:%d' % (j0, j1)) lat = netcdf.use(f, 'latitude', longitude='%d:%d' % (i0, i1), latitude='%d:%d' % (j0, j1)) lon, lat = np.meshgrid(lon, lat) #if np.all(xl0<0): lon=lon-360 # this may be wrong ... if xl is near 0, lon ay have pos and neg values !!! fix this one day ... return lon, lat, u, v, ij else: return u, v
def make_blk_wrf(wrfpath,grd,bulk,date0=False,date1=False,**kargs): ''' see make_blk_interim ''' quiet = kargs.get('quiet',0) create = kargs.get('create',1) model = kargs.get('model','roms') # or roms-agrif wrffiles=kargs.get('wrffiles','wrfout*') dt = kargs.get('dt',6) proj = kargs.get('proj','auto') data=load_blkdata_wrf(wrfpath,wrffiles,date0,date1,quiet) if not len(data): return g=roms.Grid(grd) if proj=='auto': kargs['proj']=g.get_projection() q=gennc.GenBlk(bulk,grd,**kargs) if create: # about original data, run data2romsblk once to test for x_original: tmp=data2romsblk(data[list(data.keys())[0]],g,**kargs) if 'x_original' in tmp: original=tmp['x_original'].shape else: original=False q.create(model,original) for d in data: # be sure time increases. Note that in load_blkdata_wrf # we checked if time increases in the dataset... not if dates are higher # then previous dates in file ntimes=netcdf.fdim(bulk,'time') if ntimes: tin=netcdf.nctime(bulk,'time') if tin.size and (d-tin[-1])<datetime.timedelta(hours=dt-0.1): print('-> not including %s'%d.isoformat()) continue if model=='roms': if not quiet: print(' converting units:'), conv_units(data[d],model,quiet) D=data2romsblk(data[d],g,**kargs) D['date']=d if not quiet: print(' =>filling date=%s' % d.isoformat(' ')) q.fill(D,quiet=quiet)
def make_blk_wrf(wrfpath, grd, bulk, date0=False, date1=False, **kargs): """ see make_blk_interim """ quiet = kargs.get("quiet", 0) create = kargs.get("create", 1) model = kargs.get("model", "roms") # or roms-agrif wrffiles = kargs.get("wrffiles", "wrfout*") dt = kargs.get("dt", 6) data = load_blkdata_wrf(wrfpath, wrffiles, date0, date1, quiet) if not len(data): return q = gennc.GenBlk(bulk, grd, **kargs) if create: # about original data, run data2romsblk once to test for x_original: tmp = data2romsblk(data[data.keys()[0]], grd, **kargs) if "x_original" in tmp.keys(): original = tmp["x_original"].shape else: original = False q.create(model, original) for d in data.keys(): # be sure time increases. Note that in load_blkdata_wrf # we checked if time increases in the dataset... not if dates are higher # then previous dates in file ntimes = netcdf.fdim(bulk, "time") if ntimes: tin = netcdf.nctime(bulk, "time") if tin.size and (d - tin[-1]) < datetime.timedelta(hours=dt - 0.1): print "-> not including %s" % d.isoformat() continue if model == "roms": if not quiet: print " converting units:", conv_units(data[d], model, quiet) D = data2romsblk(data[d], grd, **kargs) D["date"] = d if not quiet: print " =>filling date=%s" % d.isoformat(" ") q.fill(D, quiet=quiet)
def make_blk_wrf(wrfpath, grd, bulk, date0=False, date1=False, **kargs): ''' see make_blk_interim ''' quiet = kargs.get('quiet', 0) create = kargs.get('create', 1) model = kargs.get('model', 'roms') # or roms-agrif wrffiles = kargs.get('wrffiles', 'wrfout*') dt = kargs.get('dt', 6) proj = kargs.get('proj', 'auto') data = load_blkdata_wrf(wrfpath, wrffiles, date0, date1, quiet) if not len(data): return g = roms.Grid(grd) if proj == 'auto': kargs['proj'] = g.get_projection() q = gennc.GenBlk(bulk, grd, **kargs) if create: # about original data, run data2romsblk once to test for x_original: tmp = data2romsblk(data[list(data.keys())[0]], g, **kargs) if 'x_original' in tmp: original = tmp['x_original'].shape else: original = False q.create(model, original) for d in data: # be sure time increases. Note that in load_blkdata_wrf # we checked if time increases in the dataset... not if dates are higher # then previous dates in file ntimes = netcdf.fdim(bulk, 'time') if ntimes: tin = netcdf.nctime(bulk, 'time') if tin.size and (d - tin[-1]) < datetime.timedelta(hours=dt - 0.1): print('-> not including %s' % d.isoformat()) continue if model == 'roms': if not quiet: print(' converting units:'), conv_units(data[d], model, quiet) D = data2romsblk(data[d], g, **kargs) D['date'] = d if not quiet: print(' =>filling date=%s' % d.isoformat(' ')) q.fill(D, quiet=quiet)
def __update_wind(fname, datapath, source, **kargs): if source == 'quikscat': new_wind_info = 'wind from quikscat' from okean.datasets import quikscat a = quikscat.WINDData(datapath) elif source == 'blended': new_wind_info = 'wind from myocean blended' from okean.datasets import blended_wind a = blended_wind.WINDData(datapath) time = netcdf.nctime(fname, 'time') date0 = dts.next_date(time[0], -1) date1 = dts.next_date(time[-1], +2) data = a.data(date0, date1) update_wind(fname, data, new_wind_info, **kargs)
def __update_wind(fname,datapath,source,**kargs): if source=='quikscat': new_wind_info='wind from quikscat' from okean.datasets import quikscat a=quikscat.WINDData(datapath) elif source=='blended': new_wind_info='wind from myocean blended' from okean.datasets import blended_wind a=blended_wind.WINDData(datapath) time=netcdf.nctime(fname,'time') date0=dts.next_date(time[0],-1) date1=dts.next_date(time[-1],+2) data=a.data(date0,date1) update_wind(fname,data,new_wind_info,**kargs)
def extract(self, year, type, lims=False, date=False): a = OSTIAdownload(self.path) p = a.destination_folder(year, type) #########level,version,gen=False) files = glob.glob(os.path.join(p, '*.nc')) files.sort() res = OrderedDict() c = -1 for f in files: c += 1 print(' -- extracting from %s' % f) if c == 0: lon = netcdf.use(f, 'lon') lat = netcdf.use(f, 'lat') if lims: i0, i1, j0, j1 = calc.ij_limits(lon, lat, lims[:2], lims[2:], margin=2) ii = '%d:%d' % (i0, i1 + 1) jj = '%d:%d' % (j0, j1 + 1) lon = netcdf.use(f, 'lon', lon=ii) lat = netcdf.use(f, 'lat', lat=jj) else: ii, jj = ':', ':' date = netcdf.nctime(f, 'time')[0] u = netcdf.use(f, 'analysed_sst', lon=ii, lat=jj) if c == 0: sst = np.ma.zeros((len(files), ) + u.shape, u.dtype) time = np.zeros(len(files), datetime.datetime) sst[c] = u time[c] = date ### date0=netcdf.nctime(f,'date_start')[0] ### date1=netcdf.nctime(f,'date_stop')[0] # res[date]=sst ##### return lon,lat,res return time, lon, lat, sst
def make_frc(frcname, grd, date0, date1): g = roms.Grid(grd) if not os.path.isfile(frcname): # create file: gen_frc(frcname, grd) else: last = netcdf.nctime(frcname, 'wind_time', wind_time=-1) print('-->found file %s with last time %s' % (frcname, last.isoformat())) date0 = last + datetime.timedelta(1 / 4.) # 6h data dates = [date0] while dates[-1] < date1: dates += [dates[-1] + datetime.timedelta(1 / 4.)] # 6h data n = -1 ij = False for d in dates: n += 1 if ij is False: tmp = read_wind(grd, d, ij=False) if isinstance(tmp, basestring): continue # some error, like date not found! else: x, y, u, v, ij = tmp else: tmp = read_wind(grd, d, ij) if isinstance(tmp, basestring): continue else: u, v = tmp U = calc.griddata(x, y, u, g.lon, g.lat, extrap=True) V = calc.griddata(x, y, v, g.lon, g.lat, extrap=True) # rotate wind, print(' --> rot U,V') angle = g.use('angle') U, V = calc.rot2d(U, V, angle) print(' filling %s' % d.isoformat(' ')) fill_frc(frcname, d, U, V)
def read_wind(grd,date,ij=False): f=source(date) print '-- reading from %s'%f time=netcdf.nctime(f,'time') if 0: try: i=np.where(time==date)[0][0] except: return 'date %s not found'%date.isoformat(' ') else: i=0 returnXY=False if ij is False: returnXY=True lon=netcdf.use(f,'longitude') # -180..180 lat=netcdf.use(f,'latitude') g=roms.Grid(grd) xl0=np.asarray((g.lon.min(),g.lon.max())) xl=np.asarray((g.lon.min(),g.lon.max())) if np.any(xl>180) or np.any(xl<-180): print 'ERROR: grid is supposed to be -180<x<180' print 'Can be implemented with mpl_toolkits.basemap.shiftgrid ... TODO' print '(http://matplotlib.org/basemap/api/basemap_api.html)' return yl=g.lat.min(),g.lat.max() ij=calc.ij_limits(lon,lat,xl,yl,margin=1) i0,i1,j0,j1=ij u=netcdf.use(f,'eastward_wind',longitude='%d:%d'%(i0,i1),latitude='%d:%d'%(j0,j1),time=i) v=netcdf.use(f,'northward_wind',longitude='%d:%d'%(i0,i1),latitude='%d:%d'%(j0,j1),time=i) if returnXY: lon=netcdf.use(f,'longitude',longitude='%d:%d'%(i0,i1),latitude='%d:%d'%(j0,j1)) lat=netcdf.use(f,'latitude',longitude='%d:%d'%(i0,i1),latitude='%d:%d'%(j0,j1)) lon,lat=np.meshgrid(lon,lat) #if np.all(xl0<0): lon=lon-360 # this may be wrong ... if xl is near 0, lon ay have pos and neg values !!! fix this one day ... return lon,lat,u,v, ij else: return u,v
def make_frc(frcname,grd,date0,date1): g=roms.Grid(grd) if not os.path.isfile(frcname): # create file: gen_frc(frcname,grd) else: last=netcdf.nctime(frcname,'wind_time',wind_time=-1) print '-->found file %s with last time %s'%(frcname,last.isoformat()) date0=last+datetime.timedelta(1/4.) # 6h data dates=[date0] while dates[-1]<date1: dates+=[dates[-1]+datetime.timedelta(1/4.)] # 6h data n=-1 ij=False for d in dates: n+=1 if ij is False: tmp=read_wind(grd,d,ij=False) if isinstance(tmp,basestring): continue # some error, like date not found! else: x,y,u,v,ij=tmp else: tmp=read_wind(grd,d,ij) if isinstance(tmp,basestring): continue else: u,v=tmp U=calc.griddata(x,y,u,g.lon,g.lat,extrap=True) V=calc.griddata(x,y,v,g.lon,g.lat,extrap=True) # rotate wind, print ' --> rot U,V' angle=g.use('angle') U,V=calc.rot2d(U,V,angle) print ' filling %s'%d.isoformat(' ') fill_frc(frcname,d,U,V)
def extract(self,year,type,lims=False,date=False): a=OSTIAdownload(self.path) p=a.destination_folder(year,type)#########level,version,gen=False) files=glob.glob(os.path.join(p,'*.nc')) files.sort() res=OrderedDict() c=-1 for f in files: c+=1 print(' -- extracting from %s'%f) if c==0: lon=netcdf.use(f,'lon') lat=netcdf.use(f,'lat') if lims: i0,i1,j0,j1=calc.ij_limits(lon,lat,lims[:2],lims[2:],margin=2) ii='%d:%d'%(i0,i1+1) jj='%d:%d'%(j0,j1+1) lon=netcdf.use(f,'lon',lon=ii) lat=netcdf.use(f,'lat',lat=jj) else: ii,jj=':',':' date=netcdf.nctime(f,'time')[0] u=netcdf.use(f,'analysed_sst',lon=ii,lat=jj) if c==0: sst=np.ma.zeros((len(files),)+u.shape,u.dtype) time=np.zeros(len(files),datetime.datetime) sst[c]=u time[c]=date ### date0=netcdf.nctime(f,'date_start')[0] ### date1=netcdf.nctime(f,'date_stop')[0] # res[date]=sst ##### return lon,lat,res return time,lon,lat,sst
def read_wind(grd,date,ij=False): f=source(date) print '-- reading from %s'%f time=netcdf.nctime(f,'time') try: i=np.where(time==date)[0][0] except: return 'date %s not found'%d.isoformat(' ') returnXY=False if ij is False: returnXY=True lon=netcdf.use(f,'lon') lat=netcdf.use(f,'lat') g=roms.Grid(grd) xl0=np.asarray((g.lon.min(),g.lon.max())) xl=np.asarray((g.lon.min(),g.lon.max())) if np.all(xl<0): xl=xl+360 elif np.any(xl<0) and np.any(xl>0): print 'ERROR: zero crossing not implemented !!!' print 'can be done with mpl_toolkits.basemap.shiftgrid ... TODO' print '(http://matplotlib.org/basemap/api/basemap_api.html)' return yl=g.lat.min(),g.lat.max() ij=calc.ij_limits(lon,lat,xl,yl,margin=1) i0,i1,j0,j1=ij u=netcdf.use(f,'uwnd',lon='%d:%d'%(i0,i1),lat='%d:%d'%(j0,j1),time=i) v=netcdf.use(f,'vwnd',lon='%d:%d'%(i0,i1),lat='%d:%d'%(j0,j1),time=i) if returnXY: lon=netcdf.use(f,'lon',lon='%d:%d'%(i0,i1),lat='%d:%d'%(j0,j1)) lat=netcdf.use(f,'lat',lon='%d:%d'%(i0,i1),lat='%d:%d'%(j0,j1)) lon,lat=np.meshgrid(lon,lat) if np.all(xl0<0): lon=lon-360 # this may be wrong ... if xl is near 0, lon ay have pos and neg values !!! fix this one day ... return lon,lat,u,v, ij else: return u,v
def plt_wind(conf, plconf, date, FA='a', nest=0, **kargs): err = '' fig = False info = '' ifig = kargs.get('ifig', 0) day = kargs.get('day', 0) quiet = kargs.get('quiet', 0) time = day date = dateu.parse_date(date) # find input files: args = {'cf': conf, 'date': date, 'FA': FA, 'nest': nest} atm = opt.nameof('in', 'blk', **args) grd = opt.nameof('in', 'grd', **args) if not os.path.isfile(atm): err = 'ATM file not found (%s)' % atm return err, fig, info if not os.path.isfile(grd): err = 'Grid file not found (%s)' % grd return err, fig, info Data, err = opt.get_plconf(plconf, 'WIND') dcurr = Data['dcurr'][ifig] lcurr = Data['lcurr'][ifig] scurr = Data['scurr'][ifig] clim = Data['clim'][ifig] tind = Data['time'][ifig] x = netcdf.use(grd, 'lon_rho') y = netcdf.use(grd, 'lat_rho') wtime = netcdf.nctime(atm, 'time') cnd = (wtime >= date + datetime.timedelta(days=day)) & ( date < date + datetime.timedelta(days=day + 1)) u = netcdf.use(atm, 'Uwind', time=cnd) v = netcdf.use(atm, 'Uwind', time=cnd) if tind == 'dailyMean': u = u.mean(0) v = v.mean(0) sdate = wtime[cnd][ 0] # for title... 1st day 00h is expected to be 1st date, # or model should not run! else: # tind of some day, ex: tind 0 from forec day 3 u = u[tind] v = v[tind] sdate = wtime[cnd][tind] if day > len(u) - 1: err = 'Invalid day %d (max=%d)' % (day, len(u) - 1) return err, fig, info # plot grid: proj, fig, ax = plt_grid(plconf, grd, ifig) # no mask on land: mask = np.zeros(u.shape, 'bool') mask[::dcurr[0], ::dcurr[1]] = True xm, ym = proj(x, y) s = np.sqrt(u**2 + v**2) q = pl.quiver(xm[mask], ym[mask], u[mask], v[mask], s[mask], scale=scurr, zorder=100) pl.clim(clim[0], clim[1]) def add_colorbar(handle, **args): ax = pl.gca() Data, err = opt.get_plconf(plconf, 'AXES') cbpos = Data['cbpos'][ifig] cbbgpos = Data['cbbgpos'][ifig] cbbgc = Data['cbbgcolor'][ifig] cbbga = Data['cbbgalpha'][ifig] cblab = Data['cblabel'][ifig] # colorbar bg axes: if cbbgpos: rec = pl.axes((cbpos[0] - cbpos[2] * cbbgpos[0], cbpos[1] - cbbgpos[2] * cbpos[3], cbpos[2] * (1 + cbbgpos[0] + cbbgpos[1]), cbpos[3] * (1 + cbbgpos[2] + cbbgpos[3])), axisbg=cbbgc, frameon=1) rec.patch.set_alpha(cbbga) rec.set_xticks([]) rec.set_yticks([]) for k in rec.axes.spines.keys(): rec.axes.spines[k].set_color(cbbgc) rec.axes.spines[k].set_alpha(cbbga) # colorbar: if cbpos: cbax = fig.add_axes(cbpos) if cbpos[2] > cbpos[3]: orient = 'horizontal' else: orient = 'vertical' cb = pl.colorbar(handle, cax=cbax, orientation=orient, drawedges=0, **args) pl.axes(ax) # colorbar label: cb.set_label(r'Wind Speed [m s$^{\rm{-1}}$]') def add_currkey(handle): pos = Data['kcurrpos'][ifig] if pos: pl.quiverkey(handle, pos[0], pos[1], lcurr, '%s m/s' % str(lcurr), labelpos='S', coordinates='axes') add_colorbar(q) add_currkey(q) # tilte: Title, err = opt.get_plconf(plconf, 'AXES', 'title') if Title[ifig]: simpleTitle = 1 rdate = date.strftime('%d-%m-%Y') title = 'wind %s %s %d' % (rdate, FA, day) if simpleTitle: # simpler version of title: if FA == 'f': # forecast date: rdate = dateu.next_date(date, day) rdate = rdate.strftime('%d-%m-%Y') title = 'wind %s' % (rdate) if FA == 'f': title = title + ' (forec)' pl.title(title) # logo: if ifig == 0: im = os.path.join(os.path.dirname(__file__), 'logo_INOCAR.png') i = pl.imread(im) h, w = i.shape[:2] rx = .12 W = (proj.xmax - proj.xmin) * rx H = W * h / w l = proj.xmax #pl.fill([proj.xmax-W, proj.xmax, proj.xmax, proj.xmax-W], # [proj.ymin, proj.ymin, proj.ymin+2.8*H, proj.ymin+2.8*H], # '#500000',alpha=0.25,ec='none') ax.imshow(i, extent=(proj.xmax * .98 - W, proj.xmax * .98, proj.ymin + H * .1, proj.ymin + H * 1.1), zorder=1e3) #pl.text(proj.xmax-W/2., proj.ymin+2.2*H,'OOF', # fontdict={'size':14,'family':'serif'}, # color='#500000',ha='center',weight='bold') pl.text( proj.xmax * .8, proj.ymax * (-.1), sdate.strftime("%d %b %Y"), #pl.text(proj.xmax*.62, proj.ymax*.93,sdate.strftime("%d %b %Y"), fontdict={ 'size': 13, 'family': 'monospace' }, ha='center') # change date format if tind is not daily mean, ie, add hour, etc if FA == 'f': s = 'Pronostico desde %s' % date.strftime("%d %b %Y") pl.text( proj.xmax * .8, proj.ymax * (-.15), s, ##this is outside #pl.text(proj.xmax-W/2., proj.ymin+1.1*H,s, ##this is in the proj (inside) fontdict={'fontsize': 10}, ha='center') # logo. # lims change in some mpl versions !! pl.gca().axis([proj.xmin, proj.xmax, proj.ymin, proj.ymax]) return err, fig, info
def frc2gnome(fname,frc,grd,xylim=False,dates=False,ij=(1,1),**kargs): ''' Creates GNOME wind file kargs: t[u,v]var t[u,v]dim x[y,ang]var Ex: .frc2gnome(out,frc,grd,ij=(10,10),dates=dates,**{'tdim':'Time'}) ''' deta,dxi=ij tvar='time' uvar='Uwind' vvar='Vwind' #tvar='bulk_time' #uvar='uwnd' #vvar='vwnd' tdim='time' #tdim='bulk_time' xdim='xi_rho' ydim='eta_rho' xvar='lon_rho' yvar='lat_rho' angvar='angle' if 'tvar' in kargs.keys(): tvar=kargs['tvar'] if 'uvar' in kargs.keys(): uvar=kargs['uvar'] if 'vvar' in kargs.keys(): vvar=kargs['vvar'] if 'tdim' in kargs.keys(): tdim=kargs['tdim'] if 'xdim' in kargs.keys(): xdim=kargs['xdim'] if 'ydim' in kargs.keys(): ydim=kargs['ydim'] if 'xvar' in kargs.keys(): xvar=kargs['xvar'] if 'yvar' in kargs.keys(): yvar=kargs['yvar'] if 'angvar' in kargs.keys(): angvar=kargs['angvar'] dims=netcdf.fdim(grd) xi,eta=dims[xdim],dims[ydim] xi0,eta0=xi,eta ncg=netcdf.ncopen(grd) nc0=netcdf.ncopen(frc) try: t=netcdf.nctime(nc0,tvar) except: t=netcdf.use(nc0,tvar) t=netcdf.num2date(t,'days since %d-01-01' % year0) time=netcdf.date2num(t,tunits) x0=netcdf.use(grd,xvar) y0=netcdf.use(grd,yvar) if x0.ndim==1: x0,y0=np.meshgrid(x0,y0) if angvar: ang=netcdf.use(grd,angvar) if not xylim is False: xlim=xylim[:2] ylim=xylim[2:] i1,i2,j1,j2=calc.ij_limits(x0,y0,xlim,ylim) xi=i2-i1 eta=j2-j1 else: i1,i2=0,xi j1,j2=0,eta XI ='%d:%d:%d' %(i1,i2,dxi) ETA ='%d:%d:%d' %(j1,j2,deta) xi=len(range(i1,i2,dxi)) eta=len(range(j1,j2,deta)) # create file: create_wind(fname,xi,eta) nc=netcdf.ncopen(fname,'a') x=x0[j1:j2:deta,i1:i2:dxi] y=y0[j1:j2:deta,i1:i2:dxi] nc.vars['lon'][:]=x nc.vars['lat'][:]=y if angvar: ang=ang[j1:j2:deta,i1:i2:dxi] n=-1 for it in range(len(time)): if not dates is False: d0,d1=dates if t[it]<d0 or t[it]>=d1: continue n+=1 u=netcdf.use(nc0,uvar,**{xdim:XI,ydim:ETA,tdim:it}) v=netcdf.use(nc0,vvar,**{xdim:XI,ydim:ETA,tdim:it}) # rotate uv: if angvar: print 'rotating ...' u,v=calc.rot2d(u,v,-ang) nc.vars['time'][n]=time[it] print 'filling uv',n,t[it] nc.vars['air_u'][n,...]=u nc.vars['air_v'][n,...]=v nc.close() nc0.close() ncg.close()
def update_wind_blended2(fname, datapaths, **kargs): """ In days without blended data will try to use quikscat data """ from okean.datasets import quikscat from okean.datasets import blended_wind a = blended_wind.WINDData(datapaths[0]) b = quikscat.WINDData(datapaths[1]) time = netcdf.nctime(fname, "time") date0 = dts.next_date(time[0], -1) date1 = dts.next_date(time[-1], +2) data = a.data(date0, date1) # limit are... otherwise, quikscat interp will be very slow! grd = netcdf.fatt(fname, "grd_file") import os if not os.path.isfile(grd): grd = kargs["grd"] cond, inds = rt.grid_vicinity(grd, data["x"], data["y"], margin=5, rect=True, retinds=True) i1, i2, j1, j2 = inds for d in data.keys(): if d == "x": data[d] = data[d][i1:i2] elif d == "y": data[d] = data[d][j1:j2] else: data[d] = data[d][j1:j2, i1:i2] # check for missing days: time0 = data.keys() x0 = data["x"] y0 = data["y"] x0, y0 = np.meshgrid(x0, y0) time0.remove("x") time0.remove("y") out = cb.odict() out["x"] = x0 out["y"] = y0 info = "" qs_ij_limits_done = False for d in dts.drange(date0, date1): found = 0 for t in time0: if (t.year, t.month, t.day) == (d.year, d.month, d.day): print "==> blended : ", t out[t] = data[t] found = 1 if not found: # use quikscat: print "==> quikscat : ", d.strftime("%Y-%m-%d") tmp = b.data(d, dts.next_date(d)) if not tmp.has_key("x"): continue x, y = tmp["x"], tmp["y"] x, y = np.meshgrid(x, y) # reduce qs data: if not qs_ij_limits_done: i1, i2, j1, j2 = calc.ij_limits(x, y, [x0.min(), x0.max()], [y0.min(), y0.max()]) qs_ij_limits_done = True x = x[j1:j2, i1:i2] y = y[j1:j2, i1:i2] tmp[tmp.keys()[0]] = tmp[tmp.keys()[0]][j1:j2, i1:i2] print " griddata u" u = calc.griddata(x, y, tmp[tmp.keys()[0]].real, x0, y0) print " griddata v" v = calc.griddata(x, y, tmp[tmp.keys()[0]].imag, x0, y0) out[tmp.keys()[0]] = u + 1.0j * v info += "#" + d.strftime("%Y%m%d") new_wind_info = "blended+quikscat at days: " + info update_wind(fname, out, new_wind_info, **kargs)
def roms2swan_wind(frc,date0,date1,fname='swan_wind.dat',**kargs): tname='wind_time' uname='Uwind' vname='Vwind' grd=False # needed if wind is 1d dt=1 # hours path='' if 'tname' in kargs.keys(): tname=kargs['tname'] if 'uname' in kargs.keys(): uname=kargs['uname'] if 'vname' in kargs.keys(): vname=kargs['vname'] if 'grd' in kargs.keys(): grd =kargs['grd'] if 'dt' in kargs.keys(): dt =kargs['dt'] if 'path' in kargs.keys(): path =kargs['path'] print 'wind: loading time ...' time=netcdf.nctime(frc,tname) #time=np.load('tfile') #cond=(time>=date0)&(time<=date1) cond=(time>=date0)&(time<=date1+datetime.timedelta(days=1)) # add one day at the end, just to avoid the "repeating last" time=time[cond] d=np.diff(pl.date2num(time)) print 'current max and min dt = %6.2f %6.2f hrs = %6.2f %6.2f mins'%(d.max()*24, d.min()*24, d.max()*24*60, d.min()*24*60) # time=time[::dt] # d=np.diff(pl.date2num(time)) # print ' final max and min dt = %6.2f %6.2f hrs = %6.2f %6.2f mins'%(d.max()*24, d.min()*24, d.max()*24*60, d.min()*24*60) print 'wind: loading u ...' u,nc=netcdf.var(frc,uname) print 'wind: loading v ...' v,nc=netcdf.var(nc,uname) # u=u[cond,...][::dt,...] # v=v[cond,...][::dt,...] u=u[cond,...] v=v[cond,...] nc.close() if u.ndim==1: if not grd: print 'must provide grd karg!' return nt=u.size eta=netcdf.fdim(grd)['eta_rho'] xi=netcdf.fdim(grd)['xi_rho'] else: nt,eta,xi=u.shape # array may be too big, so do this later (for each it) # # u=np.tile(u[:,np.newaxis,np.newaxis],(1,eta,xi)) # v=np.tile(v[:,np.newaxis,np.newaxis],(1,eta,xi)) i=open(fname,'w') times=[] time0=time[0]-datetime.timedelta(hours=dt) ITs=[] for it in range(nt): time0=time0+datetime.timedelta(hours=dt) if time0>date1: break if time0>time[-1]: print 'Warning : repeating last ...', it times+=[time0] d=np.abs(time-time0) it=np.where(d==d.min())[0][0] ITs+=[it] if it%100==0: print 'saving u %s %s'%(fname,time[it].isoformat(' ')) if u[it,...].ndim==0: U=np.tile(u[it,...],(eta,xi)).flatten() else: U=u[it,...].flatten() [i.write('%8.4f\n'%uu) for uu in U] for it in ITs: if it%100==0: print 'saving v %s %s'%(fname,time[it].isoformat(' ')) if v[it,...].ndim==0: V=np.tile(v[it,...],(eta,xi)).flatten() else: V=v[it,...].flatten() [i.write('%8.4f\n'%vv) for vv in V] times=np.asarray(times) t0iso=times[0].strftime('%Y%m%d.%H%M%S') t1iso=times[-1].strftime('%Y%m%d.%H%M%S') dt=times[1]-times[0] dth=dt.days*24. + dt.seconds/60.**2 print ' -- created swan wind file %s\n'%fname # add to swan INPUT: print '\n' print 'INPGRID WIND CURVILINEAR 0 0 %d %d EXC 9.999000e+003 &'%(xi-1,eta-1) print ' NONSTATIONARY %s %.2f HR %s'%(t0iso,dth,t1iso) print 'READINP WIND 1 \'%s\' 4 0 FREE '%(os.path.join(path,fname)) print '\n'
import matplotlib.pyplot as plt from matplotlib.dates import MO, TU, WE, TH, FR, SA, SU # <markdowncell> # Lets use some ROMS-ESPRESSO output and load info from a glider: # <codecell> froms='http://tds.marine.rutgers.edu/thredds/dodsC/roms/espresso/2009_da/his' fglider='http://tds.marine.rutgers.edu/thredds/dodsC/cool/glider/mab/Gridded/20121025T000000_20121105T000000_maracoos_ru23.nc' fglider='http://tds.marine.rutgers.edu:8080/thredds/dodsC/cool/glider/all/ru23-20121025T1944.ncCFMA.nc3.nc' x=netcdf.use(fglider,'longitude') y=netcdf.use(fglider,'latitude') t=netcdf.nctime(fglider,'time') a=glider.RomsGlider(froms,x,y,t) a.plot() # <markdowncell> # Extract and plot the glider data # <codecell> z=netcdf.use(fglider,'depth') v=netcdf.use(fglider,'temperature') # <codecell>
def frc2gnome(fname, frc, grd, xylim=False, dates=False, ij=(1, 1), **kargs): ''' Creates GNOME wind file kargs: t[u,v]var t[u,v]dim x[y,ang]var Ex: .frc2gnome(out,frc,grd,ij=(10,10),dates=dates,**{'tdim':'Time'}) ''' deta, dxi = ij tvar = 'time' uvar = 'Uwind' vvar = 'Vwind' #tvar='bulk_time' #uvar='uwnd' #vvar='vwnd' tdim = 'time' #tdim='bulk_time' xdim = 'xi_rho' ydim = 'eta_rho' xvar = 'lon_rho' yvar = 'lat_rho' angvar = 'angle' if 'tvar' in kargs.keys(): tvar = kargs['tvar'] if 'uvar' in kargs.keys(): uvar = kargs['uvar'] if 'vvar' in kargs.keys(): vvar = kargs['vvar'] if 'tdim' in kargs.keys(): tdim = kargs['tdim'] if 'xdim' in kargs.keys(): xdim = kargs['xdim'] if 'ydim' in kargs.keys(): ydim = kargs['ydim'] if 'xvar' in kargs.keys(): xvar = kargs['xvar'] if 'yvar' in kargs.keys(): yvar = kargs['yvar'] if 'angvar' in kargs.keys(): angvar = kargs['angvar'] dims = netcdf.fdim(grd) xi, eta = dims[xdim], dims[ydim] xi0, eta0 = xi, eta ncg = netcdf.ncopen(grd) nc0 = netcdf.ncopen(frc) try: t = netcdf.nctime(nc0, tvar) except: t = netcdf.use(nc0, tvar) t = netcdf.num2date(t, 'days since %d-01-01' % year0) time = netcdf.date2num(t, tunits) x0 = netcdf.use(grd, xvar) y0 = netcdf.use(grd, yvar) if x0.ndim == 1: x0, y0 = np.meshgrid(x0, y0) if angvar: ang = netcdf.use(grd, angvar) if not xylim is False: xlim = xylim[:2] ylim = xylim[2:] i1, i2, j1, j2 = calc.ij_limits(x0, y0, xlim, ylim) xi = i2 - i1 eta = j2 - j1 else: i1, i2 = 0, xi j1, j2 = 0, eta XI = '%d:%d:%d' % (i1, i2, dxi) ETA = '%d:%d:%d' % (j1, j2, deta) xi = len(range(i1, i2, dxi)) eta = len(range(j1, j2, deta)) # create file: create_wind(fname, xi, eta) nc = netcdf.ncopen(fname, 'a') x = x0[j1:j2:deta, i1:i2:dxi] y = y0[j1:j2:deta, i1:i2:dxi] nc.vars['lon'][:] = x nc.vars['lat'][:] = y if angvar: ang = ang[j1:j2:deta, i1:i2:dxi] n = -1 for it in range(len(time)): if not dates is False: d0, d1 = dates if t[it] < d0 or t[it] >= d1: continue n += 1 u = netcdf.use(nc0, uvar, **{xdim: XI, ydim: ETA, tdim: it}) v = netcdf.use(nc0, vvar, **{xdim: XI, ydim: ETA, tdim: it}) # rotate uv: if angvar: print('rotating ...') u, v = calc.rot2d(u, v, -ang) nc.vars['time'][n] = time[it] print('filling uv', n, t[it]) nc.vars['air_u'][n, ...] = u nc.vars['air_v'][n, ...] = v nc.close() nc0.close() ncg.close()
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 load_data(f,quiet=0,**kargs): ''' Loads prognostic variables (temp,salt,u,v,ubar,vbar,zeta) from netcdf file or opendap server. Also loads lon,lat, depth, and time. If f is a file, it must include the 1d variables lon,lat and depth; the 2d variable ssh (zeta) and the 3d variables temp, salt, u and v; ie, each file must contain data for a simgle time. The file must also contain the variable time. If f is a opendap address, it must contain also all these variables or the ones defined in the input karg settings (DataAccess object) To deal with the case of variables in different files/opendap addresses, f can also be a dictionary with keys the variables and values the files or opendap addresses. In this case, the keys must be: - temp - salt - u - v - ssh - misc, for lon, lat, depth, time and dimensions or xy for lon,lat and x,ydim; z for depth and zdim, time for time The output data (dict) is suitable to be used by data2roms, which interpolates the data to ROMS 3d grid. Also outputs an error/status string. kargs: inds, dict with dimension names/values (where time dim can be integer or datetime) settings, DataAccess object extra, extra misc vars to load [(outKey0,fileVar0),...] t_units, units of variable time, by default the att units is used ''' sett=DataAccess() inds={} extra=[] t_units=[] if 'settings' in kargs.keys(): sett = kargs['settings'] if 'inds' in kargs.keys(): inds = kargs['inds'] if 'extra' in kargs.keys(): extra = kargs['extra'] if 't_units' in kargs.keys(): t_units = kargs['t_units'] res={} msg='' if not isinstance(f,dict) and not f.startswith('http') and not isfile(f): msg='file not found %s' % f if not quiet: print msg return res, msg # load nc files: if not isinstance(f,dict): f={'temp':f,'salt':f,'u':f,'v':f,'ssh':f,'misc':f} if not f.has_key('xy'): f['xy'] = f['misc'] if not f.has_key('z'): f['z'] = f['misc'] if not f.has_key('time'): f['time'] = f['misc'] filesUsed=[] ncUsed=[] for i in f.keys(): if not quiet: print '(%s) loading from %s' % (i.ljust(5),f[i]) if i=='temp': if f[i] in filesUsed: ncTemp=ncUsed[filesUsed.index(f[i])] else: ncTemp=netcdf.ncopen(f[i]) filesUsed+=[f[i]] ncUsed+=[ncTemp] elif i=='salt': if f[i] in filesUsed: ncSalt=ncUsed[filesUsed.index(f[i])] else: ncSalt=netcdf.ncopen(f[i]) filesUsed+=[f[i]] ncUsed+=[ncSalt] elif i=='u': if f[i] in filesUsed: ncU=ncUsed[filesUsed.index(f[i])] else: ncU=netcdf.ncopen(f[i]) filesUsed+=[f[i]] ncUsed+=[ncU] elif i=='v': if f[i] in filesUsed: ncV=ncUsed[filesUsed.index(f[i])] else: ncV=netcdf.ncopen(f[i]) filesUsed+=[f[i]] ncUsed+=[ncV] elif i=='ssh': if f[i] in filesUsed: ncSsh=ncUsed[filesUsed.index(f[i])] else: ncSsh=netcdf.ncopen(f[i]) filesUsed+=[f[i]] ncUsed+=[ncSsh] elif i=='xy': if f[i] in filesUsed: ncXy=ncUsed[filesUsed.index(f[i])] else: ncXy=netcdf.ncopen(f[i]) filesUsed+=[f[i]] ncUsed+=[ncXy] elif i=='z': if f[i] in filesUsed: ncZ=ncUsed[filesUsed.index(f[i])] else: ncZ=netcdf.ncopen(f[i]) filesUsed+=[f[i]] ncUsed+=[ncZ] elif i=='time': if f[i] in filesUsed: ncTime=ncUsed[filesUsed.index(f[i])] else: ncTime=netcdf.ncopen(f[i]) filesUsed+=[f[i]] ncUsed+=[ncTime] elif i=='misc': if f[i] in filesUsed: ncMisc=ncUsed[filesUsed.index(f[i])] else: ncMisc=netcdf.ncopen(f[i]) filesUsed+=[f[i]] ncUsed+=[ncMisc] # load dims: if not quiet: print ' loading dims...' dimsXy=netcdf.fdim(ncXy) dimsZ =netcdf.fdim(ncZ) res['NX']=dimsXy[sett.xdim] res['NY']=dimsXy[sett.ydim] ###if sett.z_name: if sett.zdim: res['NZ']=dimsZ[sett.zdim] else: res['NZ']=1 # about horizontal inds: if inds.has_key(sett.xdim) and len(inds[sett.xdim])==2 and not isinstance(inds[sett.xdim],basestring): if not quiet: print ' calc horizontal inds...' xlim=inds[sett.xdim] ylim=inds[sett.ydim] inds.pop(sett.xdim) inds.pop(sett.ydim) lon=netcdf.use(ncXy,sett.x_name,**inds) if np.any(lon>360): lon=np.mod(lon,360.) lat=netcdf.use(ncXy,sett.y_name,**inds) i0,i1,j0,j1=calc.ij_limits(lon,lat,xlim,ylim,margin=3) inds[sett.xdim]='%d:%d' % (i0,i1) inds[sett.ydim]='%d:%d' % (j0,j1) if not quiet: print ' loading lon, lat, depth...' res['lon'] = netcdf.use(ncXy,sett.x_name,**inds) if np.any(res['lon']>360): res['lon']=np.mod(res['lon'],360.) res['lat'] = netcdf.use(ncXy,sett.y_name,**inds) if sett.z_name: res['depth'] = -netcdf.use(ncZ,sett.z_name,**inds) else: res['depth']=False if res['lon'].size!=res['lat'].size: res['lon'],res['lat']=np.meshgrid(res['lon'],res['lat']) # needed for griddata, later # update nx,ny: if inds.has_key(sett.xdim): res['NY'],res['NX']=res['lon'].shape # extra misc vars: if len(extra): for outKey,fileVar in extra: if not quiet: print ' loading extra misc... %s %s' % (outKey,fileVar) res[outKey]=netcdf.use(ncMisc,fileVar,**inds) # time: # file may have one or several times. If several, time dim must be given # with kargs inds! if not quiet: print ' loading time...' if t_units: times=netcdf.use(ncTime,sett.time_name) times=netcdftime.num2date(times,t_units) else: times=netcdf.nctime(ncTime,sett.time_name) if inds.has_key(sett.tdim): try: tind=dts.parse_date(inds[sett.tdim]) except: tind=inds[sett.tdim] # is an integer, for instance if isinstance(tind,datetime.datetime): tind,=np.where(times==tind) if tind.size: tind=tind[0] inds[sett.tdim]=tind # update inds to extract other variables else: Msg='date not found' msg+='\n'+Msg return res,msg+' ERROR' date=times[tind] if not quiet: print ' tind, date= %d %s' % (tind,date.isoformat(' ')) elif times.size==1: date=times[0] if not quiet: print ' date= %s' % date.isoformat(' ') else: # must provide tind as input!! Msg='several dates in file... provice tind!' msg+='\n'+Msg return res,msg+' ERROR' res['date'] = date empty3d=np.zeros([res['NZ'],res['NY'],res['NX']]) empty2d=np.zeros([res['NY'],res['NX']]) if 'temp' in f.keys(): if not quiet: print ' loading temp...' if sett.temp_name in ncTemp.varnames: res['temp'] = netcdf.use(ncTemp,sett.temp_name,**inds) else: Msg='var %s not found' % 'temp' msg+='\n'+Msg if not quiet: print Msg res['temp']=empty3d if 'salt' in f.keys(): if not quiet: print ' loading salt...' if sett.salt_name in ncSalt.varnames: res['salt'] = netcdf.use(ncSalt,sett.salt_name,**inds) else: Msg='var %s not found' % 'salt' msg+='\n'+Msg if not quiet: print Msg res['salt']=empty3d if 'u' in f.keys(): if not quiet: print ' loading u...' if sett.u_name in ncU.varnames: res['u'] = netcdf.use(ncU,sett.u_name,**inds) else: Msg='var %s not found' % 'u' msg+='\n'+Msg if not quiet: print Msg res['u']=empty3d if 'v' in f.keys(): if not quiet: print ' loading v...' if sett.v_name in ncV.varnames: res['v'] = netcdf.use(ncV,sett.v_name,**inds) else: Msg='var %s not found' % 'v' msg+='\n'+Msg if not quiet: print Msg res['v']=empty3d if 'ssh' in f.keys(): if not quiet: print ' loading ssh...' if sett.ssh_name in ncSsh.varnames: res['ssh'] = netcdf.use(ncSsh,sett.ssh_name,**inds) else: Msg='var %s not found' % 'ssh' msg+='\n'+Msg if not quiet: print Msg res['ssh']=empty2d for nc in ncUsed: try: nc.close() except: pass return res, msg
def update_wind(self, data, keepOld=True, quiet=0): # store old at first iteration nc = netcdf.Pync(self.filename, 'w') time = netcdf.nctime(self.filename, 'time') tind, = np.where(time == data['date']) if tind.size: tind = tind[0] else: if not quiet: print('cannot find time=%s' % data['date'].isoformat(' ')) return if 'Uwind' in nc.varnames: # roms names = ('Uwind', 'uwnd'), ('Vwind', 'vwnd'), 'sustr', 'svstr', 'wspd' else: # roms-agrif names = 'uwnd', 'vwnd', 'sustr', 'svstr', 'wspd' # store old wind data: if False and tind == 0: # not using for now.... too slow! # TODO: remove keepOld form argument !? if 'x_wind' in data.keys(): if not quiet: print('adding x_wind, y_wind') nc.add_dim('x_wind_original', data['x_wind'].shape[1]) nc.add_dim('y_wind_original', data['x_wind'].shape[0]) nc.add_var('x_wind_original', data['x_wind'].dtype, ('y_wind_original', 'x_wind_original')) nc.add_var('y_wind_original', data['y_wind'].dtype, ('y_wind_original', 'x_wind_original')) nc.vars['x_wind_original'][...] = data['x_wind'] nc.vars['y_wind_original'][...] = data['y_wind'] for i in names: if isinstance(i, basestring): filev, datav = i, i else: filev, datav = i newName = filev + '_old' newType = nc.vars[filev].dtype() newDims = nc.vars[filev].dims.keys() if not quiet: print(' creating var %s' % newName) nc.add_var(newName, newType, newDims) if not quiet: print(' filling var %s' % newName) nc.vars[newName][...] = nc.vars[filev][...] # also store old original data, if present: orig = datav + '_original' if orig in nc.varnames: newName = orig + '_old' newType = nc.vars[orig].dtype() newDims = nc.vars[orig].dims.keys() if not quiet: print(' creating var %s' % newName) nc.add_var(newName, newType, newDims) if not quiet: print(' filling var %s' % newName) nc.vars[newName][...] = nc.vars[orig][...] # store new wind data: for i in names: if isinstance(i, basestring): filev, datav = i, i else: filev, datav = i if not quiet: print(' %s (%s) min=%8.3f max=%8.3f' % (filev.ljust(7), datav.ljust(7), data[datav].min(), data[datav].max())) nc.vars[filev][tind, ...] = data[datav] # also store new wind original data, if present: orig = datav + '_original' if not orig in data.keys(): continue if not quiet: print(' %s min=%8.3f max=%8.3f' % (orig.ljust(7 + 9), data[orig].min(), data[orig].max())) nc.vars[orig][tind, ...] = data[datav] # adding global atts: if 'attr' in data.keys(): for i in data['attr'].keys(): nc.add_att(i, data['attr'][i]) nc.close()
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 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 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_blended2(fname, datapaths, **kargs): ''' In days without blended data will try to use quikscat data ''' from okean.datasets import quikscat from okean.datasets import blended_wind a = blended_wind.WINDData(datapaths[0]) b = quikscat.WINDData(datapaths[1]) time = netcdf.nctime(fname, 'time') date0 = dts.next_date(time[0], -1) date1 = dts.next_date(time[-1], +2) data = a.data(date0, date1) # limit are... otherwise, quikscat interp will be very slow! grd = netcdf.fatt(fname, 'grd_file') import os if not os.path.isfile(grd): grd = kargs['grd'] cond, inds = rt.grid_vicinity(grd, data['x'], data['y'], margin=5, rect=True, retinds=True) i1, i2, j1, j2 = inds for d in data.keys(): if d == 'x': data[d] = data[d][i1:i2] elif d == 'y': data[d] = data[d][j1:j2] else: data[d] = data[d][j1:j2, i1:i2] # check for missing days: time0 = data.keys() x0 = data['x'] y0 = data['y'] x0, y0 = np.meshgrid(x0, y0) time0.remove('x') time0.remove('y') out = OrderedDict() out['x'] = x0 out['y'] = y0 info = '' qs_ij_limits_done = False for d in dts.drange(date0, date1): found = 0 for t in time0: if (t.year, t.month, t.day) == (d.year, d.month, d.day): print('==> blended : ', t) out[t] = data[t] found = 1 if not found: # use quikscat: print('==> quikscat : ', d.strftime('%Y-%m-%d')) tmp = b.data(d, dts.next_date(d)) if not tmp.has_key('x'): continue x, y = tmp['x'], tmp['y'] x, y = np.meshgrid(x, y) # reduce qs data: if not qs_ij_limits_done: i1, i2, j1, j2 = calc.ij_limits(x, y, [x0.min(), x0.max()], [y0.min(), y0.max()]) qs_ij_limits_done = True x = x[j1:j2, i1:i2] y = y[j1:j2, i1:i2] tmp[tmp.keys()[0]] = tmp[tmp.keys()[0]][j1:j2, i1:i2] print(' griddata u') u = calc.griddata(x, y, tmp[tmp.keys()[0]].real, x0, y0) print(' griddata v') v = calc.griddata(x, y, tmp[tmp.keys()[0]].imag, x0, y0) out[tmp.keys()[0]] = u + 1.j * v info += '#' + d.strftime('%Y%m%d') new_wind_info = 'blended+quikscat at days: ' + info update_wind(fname, out, new_wind_info, **kargs)
def his2gnome(fname,his,grd=False,nomask=False,gshhsMask=True,xylim=False,dates=False,ij=(1,1)): ''' Creates GNOME wind file Ex: his2gnome(out,his,grd,dates=dates,ij=(2,2)) if gshhsMask, the high res mask file mask_gshhs.npy will be created at 1st usage. Mask is based on high (h) resolution gshhs data which must be available (env variable GSHHS_MASK must be set). ''' if not grd: grd=his deta,dxi=ij dims=netcdf.fdim(his) xi,eta=dims['xi_rho'],dims['eta_rho'] xi0,eta0=xi,eta nc0=netcdf.ncopen(his) time=netcdf.nctime(nc0,'ocean_time') # for roms agrif: #t=netcdf.use(nc0,'scrum_time') #time=netcdf.num2date(t,'seconds since %d-01-01' % year0) x0=netcdf.use(grd,'lon_rho') y0=netcdf.use(grd,'lat_rho') ang=netcdf.use(grd,'angle') if not xylim is False: xlim=xylim[:2] ylim=xylim[2:] i1,i2,j1,j2=calc.ij_limits(x0,y0,xlim,ylim) print i1,i2,j1,j2 xi=i2-i1 eta=j2-j1 else: i1,i2=0,xi j1,j2=0,eta XI ='%d:%d:%d' %(i1,i2,dxi) ETA ='%d:%d:%d' %(j1,j2,deta) xi=len(range(i1,i2,dxi)) eta=len(range(j1,j2,deta)) # create file: create_uv(fname,xi,eta) nc=netcdf.ncopen(fname,'a') for v0,v in ('lon_rho','lon'),('lat_rho','lat'),('mask_rho','mask'),('h','depth'): print 'filling %s with %s' % (v,v0) nc.vars[v][:]=netcdf.use(grd,v0,xi_rho=XI,eta_rho=ETA) if nomask: print 'NO MASK !!!' nc.vars['mask'][:]=1 if gshhsMask: try: mask=np.load('mask_gshhs.npy') except: mask=1+0*netcdf.use(nc0,'mask_rho',xi_rho=XI,eta_rho=ETA) mask=mask.astype('bool') x=netcdf.use(grd,'lon_rho',xi_rho=XI,eta_rho=ETA) y=netcdf.use(grd,'lat_rho',xi_rho=XI,eta_rho=ETA) from okean import gshhs axis=x.min(),x.max(),y.min(),y.max() g=gshhs.gshhs(axis, resolution='h',area_thresh=0., max_level=2,clip=True) for lon, lat, level in zip(g.lon, g.lat, g.level): if level == 1: # land print 'mask ',lon.shape i=calc.inpolygon(x,y,lon,lat) mask=mask & ~i mask.dump('mask_gshhs.npy') nc.vars['mask'][:]=mask x=x0[j1:j2:deta,i1:i2:dxi] y=y0[j1:j2:deta,i1:i2:dxi] ang=ang[j1:j2:deta,i1:i2:dxi] n=-1 for it in range(len(time)): if not dates is False: d0,d1=dates if time[it]<d0 or time[it]>=d1: continue n+=1 U=np.zeros((eta0,xi0),'f') V=np.zeros((eta0,xi0),'f') nc.vars['time'][n]=netcdf.date2num(time[it],tunits) # for roms agrif: #u=netcdf.use(nc0,'u',time=it,s_rho=-1) #v=netcdf.use(nc0,'v',time=it,s_rho=-1) u=netcdf.use(nc0,'u',ocean_time=it,s_rho=-1) v=netcdf.use(nc0,'v',ocean_time=it,s_rho=-1) # mask extrap: print 'mask extrap...' u=calc.mask_extrap(x0,y0,np.ma.masked_where(u==0,u)) v=calc.mask_extrap(x0,y0,np.ma.masked_where(v==0,v)) U[:,1:-1]=0.5*(u[:,:-1]+u[:,1:]) U[:,0]=u[:,0] U[:,-1]=u[:,-1] V[1:-1,:]=0.5*(v[:-1.:]+v[1:,:]) V[0,:]=v[0,:] V[-1,:]=v[-1,:] U=U[j1:j2,i1:i2] V=V[j1:j2,i1:i2] U=U[j1:j2:deta,i1:i2:dxi] V=V[j1:j2:deta,i1:i2:dxi] # rotate uv: print 'rotating ...' U,V=calc.rot2d(U,V,-ang) print 'filling uv', n, time[it] nc.vars['u'][n,...]=U nc.vars['v'][n,...]=V nc.close() nc0.close()
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 plt_hslice(conf,plconf,date,FA='a',nest=0,**kargs): err='' fig=False info={} type = 'avg' var = 'temp' slice = 'z' ind = -10 time = -1 currents = False dcurr = (3,3) scurr = 3 lcurr = 0.2 ifig = 0 # closefig = True clim = False quiet = False outStoragePath=False cmap = None norm = None useBar = True # currents are barotropic for 2D vars (like zeta) keys=kargs.keys() if 'type' in keys: type = kargs['type'] if 'var' in keys: var = kargs['var'] if 'slice' in keys: slice = kargs['slice'] if 'ind' in keys: ind = kargs['ind'] if 'time' in keys: time = kargs['time'] if 'currents' in keys: currents = kargs['currents'] if 'dcurr' in keys: dcurr = kargs['dcurr'] if 'scurr' in keys: scurr = kargs['scurr'] if 'lcurr' in keys: lcurr = kargs['lcurr'] if 'ifig' in keys: ifig = kargs['ifig'] if 'closefig' in keys: closefig = kargs['closefig'] if 'clim' in keys: clim = kargs['clim'] if 'quiet' in keys: quiet = kargs['quiet'] if 'ostorage' in keys: outStoragePath = kargs['ostorage'] if 'cmap' in keys: cmap = kargs['cmap'] if 'usebar' in keys: useBar = kargs['usebar'] if 'norm' in keys: norm = kargs['norm'] date=dateu.parse_date(date) # find input files: args={'cf':conf,'date':date,'FA':FA,'nest':nest,'ostorage':outStoragePath} his = opt.nameof('out',type,**args) clm = opt.nameof('in','clm',**args) grd = opt.nameof('in','grd',**args) if not os.path.isfile(his): err='Main file not found (%s)' % his return err,fig,info if not os.path.isfile(grd): err='Grid file not found (%s)' % grd return err,fig,info r=roms.His(his,grd) # plot grid: proj,fig, ax = plt_grid(plconf,grd,ifig) def add_colorbar(handle,**args): ax=pl.gca() Data,err = opt.get_plconf(plconf,'AXES') cbpos = Data['cbpos'][ifig] cbbgpos = Data['cbbgpos'][ifig] cbbgc = Data['cbbgcolor'][ifig] cbbga = Data['cbbgalpha'][ifig] cblab = Data['cblabel'][ifig] # colorbar bg axes: if cbbgpos: rec=pl.axes((cbpos[0]-cbpos[2]*cbbgpos[0],cbpos[1]-cbbgpos[2]*cbpos[3], cbpos[2]*(1+cbbgpos[0]+cbbgpos[1]),cbpos[3]*(1+cbbgpos[2]+cbbgpos[3])), axisbg=cbbgc,frameon=1) rec.patch.set_alpha(cbbga) rec.set_xticks([]) rec.set_yticks([]) for k in rec.axes.spines.keys(): rec.axes.spines[k].set_color(cbbgc) rec.axes.spines[k].set_alpha(cbbga) # colorbar: if cbpos: cbax=fig.add_axes(cbpos) if cbpos[2]>cbpos[3]: orient='horizontal' else: orient='vertical' cb=pl.colorbar(handle,cax=cbax,orientation=orient,drawedges=0,**args) pl.axes(ax) # colorbar label: if cblab: Data,err = opt.get_plconf(plconf,'HSLICES') varnames=Data['varnames'][ifig].split(',') vnames=Data['vnames'][ifig].split(',') lab='' for i in range(len(varnames)): if varnames[i].strip()==var: lab=vnames[i].strip() break if lab: if r.hasz(var): if slice=='k': if ind==0: lab = 'Bottom '+lab elif ind in (-1,'surface'): lab = 'Surface '+lab elif slice=='z': lab=lab+' '+str(ind)+'m' cb.set_label(lab) def add_currkey(handle): Data,err = opt.get_plconf(plconf,'HSLICES') pos=Data['kcurrpos'][ifig] if pos: pl.quiverkey(handle, pos[0], pos[1], lcurr, '%s m/s' % str(lcurr),labelpos='S', coordinates='axes') # hslice: if var: if slice=='k': metodo=r.slicek elif slice=='z': metodo=r.slicez x,y,z,v=metodo(var,ind,time,plot=False) x,y=proj(x,y) # cmap: if isinstance(cmap,basestring): try:cmap=pl.cm.cmap_d[cmap] except: try: from okean import pl_tools cmap=pl_tools.cm.cmap_d[cmap] except: cmap=pl.cm.jet # original data from clm if slice=='k' and ind in (-1,) and var+'_original' in netcdf.varnames(clm): tcurr= r.datetime[time] x_o=netcdf.use(clm,'x_original') y_o=netcdf.use(clm,'y_original') x_o,y_o=proj(x_o,y_o) v_o=netcdf.use(clm,'y_original') t_o=netcdf.nctime(clm,'clim_time') # average to current time: i0,=np.where(t_o<=tcurr)[-1] i1,=np.where(t_o>tcurr)[0] v_o0=netcdf.use(clm,var+'_original',time=i0) v_o1=netcdf.use(clm,var+'_original',time=i1) # avg: a=tcurr-t_o[i0] b=t_o[i1]-tcurr a=a.days*86400+a.seconds b=b.days*86400+b.seconds if a==0: v_o=v_o0 elif b==0: v_o=v_o1 else: v_o=(v_o0*b+v_o1*a)/(a+b) pch=pl.pcolormesh(x_o,y_o,v_o,shading='flat',cmap=cmap) if clim: pl.clim(clim[0],clim[1]) if norm=='log': from matplotlib.colors import LogNorm Norm=LogNorm(vmin=clim[0],vmax=clim[1]) else: Norm=None # change hypoxia colorbar/cmap if var=='dye_01': HypoxiaLim=135 from okean import pl_tools cmap=pl_tools.ucmaps().gen_oxygen(v=(0,HypoxiaLim,300.)) # default is 0,135,300 !! pch=pl.pcolormesh(x,y,v,shading='flat',cmap=cmap, norm=Norm) if clim: pl.clim(clim[0],clim[1]) # hypoxia: if var=='dye_01' and ind==0 and ifig==0: cond=v<135. cond=v<HypoxiaLim cond=(v<HypoxiaLim)&(r.grid.h>5) pm=r.grid.use('pm') pn=r.grid.use('pn') A=(1/pm[cond]*1/pn[cond]/1e6).sum() x_,y_=proj(-98,29.5) pl.text(x_,y_,'Hypoxia area = %.0f km$^2$' % A,color='r', fontweight='bold',fontname='monospace', bbox=dict(edgecolor='none',facecolor='white', alpha=0.8)) # hypoxia. # colorbar: if norm=='log': tks=10**np.linspace(np.log10(clim[0]),np.log10(clim[1]),4) opts={'ticks':tks,'format':'%.2f'} else: opts={'ticks':None} add_colorbar(pch,**opts) if currents: if (var and r.hasz(var)) or not useBar: uvind=ind else: uvind='bar' x,y,z,u,v=r.sliceuv(uvind,time) xm, ym = proj(x,y) mm=np.zeros(x.shape,'bool') mm[::dcurr[0],::dcurr[1]]=True Data,err = opt.get_plconf(plconf,'HSLICES') wcurr=Data['wcurr'][ifig] acurr=Data['acurr'][ifig] qvopts={'units':'x','scale':scurr,'width':wcurr,'alpha':acurr} if var: q=pl.quiver(xm[mm],ym[mm],u[mm],v[mm],**qvopts) else: s=np.sqrt(u**2+v**2) q=pl.quiver(xm[mm],ym[mm],u[mm],v[mm],s[mm],**qvopts) if clim: pl.clim(clim[0],clim[1]) add_colorbar(q) add_currkey(q) # store some info that may be required later info['hasz']=False if var and r.hasz(var): info['hasz']=True # logo: if ifig==0: im=os.path.join(os.path.dirname(__file__),'logo_INOCAR.png') i=pl.imread(im) h,w=i.shape[:2] rx=.12 W=(proj.xmax- proj.xmin)*rx H=W*h/w l=proj.xmax #pl.fill([proj.xmax-W, proj.xmax, proj.xmax, proj.xmax-W], # [proj.ymin, proj.ymin, proj.ymin+2.8*H, proj.ymin+2.8*H], # '#500000',alpha=0.25,ec='none') ax.imshow(i,extent=(proj.xmax*.98-W,proj.xmax*.98, proj.ymin+H*.1, proj.ymin+H*1.1),zorder=1e3) #pl.text(proj.xmax-W/2., proj.ymin+2.2*H,'OOF', # fontdict={'size':14,'family':'serif'}, # color='#500000',ha='center',weight='bold') pl.text(proj.xmax*.8, proj.ymax*(-.1),r.datetime[time].strftime("%d %b %Y"), fontdict={'size':11,'family':'monospace'},ha='center') if FA=='f': s='Pronostico desde %s' % r.datetime[0].strftime("%d %b %Y") pl.text(proj.xmax*.8, proj.ymax*(-.15),s, #pl.text(proj.xmax-W/2., proj.ymin+1.1*H,s, fontdict={'fontsize':10},ha='center') # logo. # lims change in some mpl versions !! pl.gca().axis([proj.xmin, proj.xmax, proj.ymin, proj.ymax]) return err, fig, info
def his2gnome(fname, his, grd=False, nomask=False, gshhsMask=True, xylim=False, dates=False, ij=(1, 1)): ''' Creates GNOME wind file Ex: his2gnome(out,his,grd,dates=dates,ij=(2,2)) if gshhsMask, the high res mask file mask_gshhs.npy will be created at 1st usage. Mask is based on high (h) resolution gshhs data which must be available (env variable GSHHS_MASK must be set). ''' if not grd: grd = his deta, dxi = ij dims = netcdf.fdim(his) xi, eta = dims['xi_rho'], dims['eta_rho'] xi0, eta0 = xi, eta nc0 = netcdf.ncopen(his) time = netcdf.nctime(nc0, 'ocean_time') # for roms agrif: #t=netcdf.use(nc0,'scrum_time') #time=netcdf.num2date(t,'seconds since %d-01-01' % year0) x0 = netcdf.use(grd, 'lon_rho') y0 = netcdf.use(grd, 'lat_rho') ang = netcdf.use(grd, 'angle') if not xylim is False: xlim = xylim[:2] ylim = xylim[2:] i1, i2, j1, j2 = calc.ij_limits(x0, y0, xlim, ylim) print(i1, i2, j1, j2) xi = i2 - i1 eta = j2 - j1 else: i1, i2 = 0, xi j1, j2 = 0, eta XI = '%d:%d:%d' % (i1, i2, dxi) ETA = '%d:%d:%d' % (j1, j2, deta) xi = len(range(i1, i2, dxi)) eta = len(range(j1, j2, deta)) # create file: create_uv(fname, xi, eta) nc = netcdf.ncopen(fname, 'a') for v0, v in ('lon_rho', 'lon'), ('lat_rho', 'lat'), ('mask_rho', 'mask'), ('h', 'depth'): print('filling %s with %s' % (v, v0)) nc.vars[v][:] = netcdf.use(grd, v0, xi_rho=XI, eta_rho=ETA) if nomask: print('NO MASK !!!') nc.vars['mask'][:] = 1 if gshhsMask: try: mask = np.load('mask_gshhs.npy') except: mask = 1 + 0 * netcdf.use(nc0, 'mask_rho', xi_rho=XI, eta_rho=ETA) mask = mask.astype('bool') x = netcdf.use(grd, 'lon_rho', xi_rho=XI, eta_rho=ETA) y = netcdf.use(grd, 'lat_rho', xi_rho=XI, eta_rho=ETA) from okean import gshhs axis = x.min(), x.max(), y.min(), y.max() g = gshhs.gshhs(axis, resolution='h', area_thresh=0., max_level=2, clip=True) for lon, lat, level in zip(g.lon, g.lat, g.level): if level == 1: # land print('mask ', lon.shape) i = calc.inpolygon(x, y, lon, lat) mask = mask & ~i mask.dump('mask_gshhs.npy') nc.vars['mask'][:] = mask x = x0[j1:j2:deta, i1:i2:dxi] y = y0[j1:j2:deta, i1:i2:dxi] ang = ang[j1:j2:deta, i1:i2:dxi] n = -1 for it in range(len(time)): if not dates is False: d0, d1 = dates if time[it] < d0 or time[it] >= d1: continue n += 1 U = np.zeros((eta0, xi0), 'f') V = np.zeros((eta0, xi0), 'f') nc.vars['time'][n] = netcdf.date2num(time[it], tunits) # for roms agrif: #u=netcdf.use(nc0,'u',time=it,s_rho=-1) #v=netcdf.use(nc0,'v',time=it,s_rho=-1) u = netcdf.use(nc0, 'u', ocean_time=it, s_rho=-1) v = netcdf.use(nc0, 'v', ocean_time=it, s_rho=-1) # mask extrap: print('mask extrap...') u = calc.mask_extrap(x0, y0, np.ma.masked_where(u == 0, u)) v = calc.mask_extrap(x0, y0, np.ma.masked_where(v == 0, v)) U[:, 1:-1] = 0.5 * (u[:, :-1] + u[:, 1:]) U[:, 0] = u[:, 0] U[:, -1] = u[:, -1] V[1:-1, :] = 0.5 * (v[:-1.:] + v[1:, :]) V[0, :] = v[0, :] V[-1, :] = v[-1, :] U = U[j1:j2, i1:i2] V = V[j1:j2, i1:i2] U = U[j1:j2:deta, i1:i2:dxi] V = V[j1:j2:deta, i1:i2:dxi] # rotate uv: print('rotating ...') U, V = calc.rot2d(U, V, -ang) print('filling uv', n, time[it]) nc.vars['u'][n, ...] = U nc.vars['v'][n, ...] = V nc.close() nc0.close()
def plt_wind(conf,plconf,date,FA='a',nest=0,**kargs): err = '' fig = False info = '' ifig = kargs.get('ifig',0) day = kargs.get('day',0) quiet = kargs.get('quiet',0) time=day date=dateu.parse_date(date) # find input files: args={'cf':conf,'date':date,'FA':FA,'nest':nest} atm = opt.nameof('in','blk',**args) grd = opt.nameof('in','grd',**args) if not os.path.isfile(atm): err='ATM file not found (%s)' % atm return err,fig,info if not os.path.isfile(grd): err='Grid file not found (%s)' % grd return err,fig,info Data,err = opt.get_plconf(plconf,'WIND') dcurr=Data['dcurr'][ifig] lcurr=Data['lcurr'][ifig] scurr=Data['scurr'][ifig] clim =Data['clim'][ifig] tind = Data['time'][ifig] x=netcdf.use(grd,'lon_rho') y=netcdf.use(grd,'lat_rho') wtime=netcdf.nctime(atm,'time') cnd=(wtime>=date+datetime.timedelta(days=day))&(date<date+datetime.timedelta(days=day+1)) u=netcdf.use(atm,'Uwind',time=cnd) v=netcdf.use(atm,'Uwind',time=cnd) if tind=='dailyMean': u=u.mean(0) v=v.mean(0) sdate=wtime[cnd][0] # for title... 1st day 00h is expected to be 1st date, # or model should not run! else: # tind of some day, ex: tind 0 from forec day 3 u=u[tind] v=v[tind] sdate=wtime[cnd][tind] if day>len(u)-1: err='Invalid day %d (max=%d)' % (day,len(u)-1) return err,fig,info # plot grid: proj,fig,ax= plt_grid(plconf,grd,ifig) # no mask on land: mask=np.zeros(u.shape,'bool') mask[::dcurr[0],::dcurr[1]]=True xm, ym = proj(x,y) s=np.sqrt(u**2+v**2) q=pl.quiver(xm[mask],ym[mask],u[mask],v[mask],s[mask],scale=scurr,zorder=100) pl.clim(clim[0],clim[1]) def add_colorbar(handle,**args): ax=pl.gca() Data,err = opt.get_plconf(plconf,'AXES') cbpos = Data['cbpos'][ifig] cbbgpos = Data['cbbgpos'][ifig] cbbgc = Data['cbbgcolor'][ifig] cbbga = Data['cbbgalpha'][ifig] cblab = Data['cblabel'][ifig] # colorbar bg axes: if cbbgpos: rec=pl.axes((cbpos[0]-cbpos[2]*cbbgpos[0],cbpos[1]-cbbgpos[2]*cbpos[3], cbpos[2]*(1+cbbgpos[0]+cbbgpos[1]),cbpos[3]*(1+cbbgpos[2]+cbbgpos[3])), axisbg=cbbgc,frameon=1) rec.patch.set_alpha(cbbga) rec.set_xticks([]) rec.set_yticks([]) for k in rec.axes.spines.keys(): rec.axes.spines[k].set_color(cbbgc) rec.axes.spines[k].set_alpha(cbbga) # colorbar: if cbpos: cbax=fig.add_axes(cbpos) if cbpos[2]>cbpos[3]: orient='horizontal' else: orient='vertical' cb=pl.colorbar(handle,cax=cbax,orientation=orient,drawedges=0,**args) pl.axes(ax) # colorbar label: cb.set_label(r'Wind Speed [m s$^{\rm{-1}}$]') def add_currkey(handle): pos=Data['kcurrpos'][ifig] if pos: pl.quiverkey(handle, pos[0], pos[1], lcurr, '%s m/s' % str(lcurr),labelpos='S', coordinates='axes') add_colorbar(q) add_currkey(q) # tilte: Title,err=opt.get_plconf(plconf,'AXES','title') if Title[ifig]: simpleTitle=1 rdate=date.strftime('%d-%m-%Y') title='wind %s %s %d' % (rdate,FA,day) if simpleTitle: # simpler version of title: if FA=='f': # forecast date: rdate=dateu.next_date(date,day); rdate=rdate.strftime('%d-%m-%Y') title='wind %s' % (rdate) if FA=='f': title=title+' (forec)' pl.title(title) # logo: if ifig==0: im=os.path.join(os.path.dirname(__file__),'logo_INOCAR.png') i=pl.imread(im) h,w=i.shape[:2] rx=.12 W=(proj.xmax- proj.xmin)*rx H=W*h/w l=proj.xmax #pl.fill([proj.xmax-W, proj.xmax, proj.xmax, proj.xmax-W], # [proj.ymin, proj.ymin, proj.ymin+2.8*H, proj.ymin+2.8*H], # '#500000',alpha=0.25,ec='none') ax.imshow(i,extent=(proj.xmax*.98-W,proj.xmax*.98, proj.ymin+H*.1, proj.ymin+H*1.1),zorder=1e3) #pl.text(proj.xmax-W/2., proj.ymin+2.2*H,'OOF', # fontdict={'size':14,'family':'serif'}, # color='#500000',ha='center',weight='bold') pl.text(proj.xmax*.8, proj.ymax*(-.1),sdate.strftime("%d %b %Y"), #pl.text(proj.xmax*.62, proj.ymax*.93,sdate.strftime("%d %b %Y"), fontdict={'size':13,'family':'monospace'},ha='center') # change date format if tind is not daily mean, ie, add hour, etc if FA=='f': s='Pronostico desde %s' % date.strftime("%d %b %Y") pl.text(proj.xmax*.8, proj.ymax*(-.15),s, ##this is outside #pl.text(proj.xmax-W/2., proj.ymin+1.1*H,s, ##this is in the proj (inside) fontdict={'fontsize':10},ha='center') # logo. # lims change in some mpl versions !! pl.gca().axis([proj.xmin, proj.xmax, proj.ymin, proj.ymax]) return err,fig,info
def roms2swan_wind(frc, date0, date1, fname='swan_wind.dat', **kargs): tname = 'wind_time' uname = 'Uwind' vname = 'Vwind' grd = False # needed if wind is 1d dt = 1 # hours path = '' if 'tname' in kargs.keys(): tname = kargs['tname'] if 'uname' in kargs.keys(): uname = kargs['uname'] if 'vname' in kargs.keys(): vname = kargs['vname'] if 'grd' in kargs.keys(): grd = kargs['grd'] if 'dt' in kargs.keys(): dt = kargs['dt'] if 'path' in kargs.keys(): path = kargs['path'] print 'wind: loading time ...' time = netcdf.nctime(frc, tname) #time=np.load('tfile') #cond=(time>=date0)&(time<=date1) cond = (time >= date0) & ( time <= date1 + datetime.timedelta(days=1) ) # add one day at the end, just to avoid the "repeating last" time = time[cond] d = np.diff(pl.date2num(time)) print 'current max and min dt = %6.2f %6.2f hrs = %6.2f %6.2f mins' % ( d.max() * 24, d.min() * 24, d.max() * 24 * 60, d.min() * 24 * 60) # time=time[::dt] # d=np.diff(pl.date2num(time)) # print ' final max and min dt = %6.2f %6.2f hrs = %6.2f %6.2f mins'%(d.max()*24, d.min()*24, d.max()*24*60, d.min()*24*60) print 'wind: loading u ...' nc = netcdf.ncopen(frc) u = netcdf.var(nc, uname) print 'wind: loading v ...' v = netcdf.var(nc, uname) # u=u[cond,...][::dt,...] # v=v[cond,...][::dt,...] u = u[cond, ...] v = v[cond, ...] nc.close() if u.ndim == 1: if not grd: print 'must provide grd karg!' return nt = u.size eta = netcdf.fdim(grd)['eta_rho'] xi = netcdf.fdim(grd)['xi_rho'] else: nt, eta, xi = u.shape # array may be too big, so do this later (for each it) # # u=np.tile(u[:,np.newaxis,np.newaxis],(1,eta,xi)) # v=np.tile(v[:,np.newaxis,np.newaxis],(1,eta,xi)) i = open(fname, 'w') times = [] time0 = time[0] - datetime.timedelta(hours=dt) ITs = [] for it in range(nt): time0 = time0 + datetime.timedelta(hours=dt) if time0 > date1: break if time0 > time[-1]: print 'Warning : repeating last ...', it times += [time0] d = np.abs(time - time0) it = np.where(d == d.min())[0][0] ITs += [it] if it % 100 == 0: print 'saving u %s %s' % (fname, time[it].isoformat(' ')) if u[it, ...].ndim == 0: U = np.tile(u[it, ...], (eta, xi)).flatten() else: U = u[it, ...].flatten() [i.write('%8.4f\n' % uu) for uu in U] for it in ITs: if it % 100 == 0: print 'saving v %s %s' % (fname, time[it].isoformat(' ')) if v[it, ...].ndim == 0: V = np.tile(v[it, ...], (eta, xi)).flatten() else: V = v[it, ...].flatten() [i.write('%8.4f\n' % vv) for vv in V] times = np.asarray(times) t0iso = times[0].strftime('%Y%m%d.%H%M%S') t1iso = times[-1].strftime('%Y%m%d.%H%M%S') dt = times[1] - times[0] dth = dt.days * 24. + dt.seconds / 60.**2 print ' -- created swan wind file %s\n' % fname # add to swan INPUT: print '\n' print 'INPGRID WIND CURVILINEAR 0 0 %d %d EXC 9.999000e+003 &' % (xi - 1, eta - 1) print ' NONSTATIONARY %s %.2f HR %s' % (t0iso, dth, t1iso) print 'READINP WIND 1 \'%s\' 4 0 FREE ' % (os.path.join(path, fname)) print '\n'
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 update_wind_blended2(fname,datapaths,**kargs): ''' In days without blended data will try to use quikscat data ''' from okean.datasets import quikscat from okean.datasets import blended_wind a=blended_wind.WINDData(datapaths[0]) b=quikscat.WINDData(datapaths[1]) time=netcdf.nctime(fname,'time') date0=dts.next_date(time[0],-1) date1=dts.next_date(time[-1],+2) data=a.data(date0,date1) # limit are... otherwise, quikscat interp will be very slow! grd=netcdf.fatt(fname,'grd_file') import os if not os.path.isfile(grd): grd=kargs['grd'] cond,inds=rt.grid_vicinity(grd,data['x'],data['y'],margin=5,rect=True,retinds=True) i1,i2,j1,j2=inds for d in data.keys(): if d == 'x': data[d]=data[d][i1:i2] elif d == 'y': data[d]=data[d][j1:j2] else: data[d]=data[d][j1:j2,i1:i2] # check for missing days: time0=data.keys() x0=data['x'] y0=data['y'] x0,y0=np.meshgrid(x0,y0) time0.remove('x') time0.remove('y') out=OrderedDict() out['x']=x0 out['y']=y0 info='' qs_ij_limits_done=False for d in dts.drange(date0,date1): found=0 for t in time0: if (t.year,t.month,t.day)==(d.year,d.month,d.day): print('==> blended : ',t) out[t]=data[t] found=1 if not found: # use quikscat: print('==> quikscat : ',d.strftime('%Y-%m-%d')) tmp= b.data(d,dts.next_date(d)) if not tmp.has_key('x'): continue x,y=tmp['x'],tmp['y'] x,y=np.meshgrid(x,y) # reduce qs data: if not qs_ij_limits_done: i1,i2,j1,j2=calc.ij_limits(x,y,[x0.min(),x0.max()],[y0.min(),y0.max()]) qs_ij_limits_done=True x=x[j1:j2,i1:i2] y=y[j1:j2,i1:i2] tmp[tmp.keys()[0]]=tmp[tmp.keys()[0]][j1:j2,i1:i2] print(' griddata u') u=calc.griddata(x,y,tmp[tmp.keys()[0]].real,x0,y0) print(' griddata v') v=calc.griddata(x,y,tmp[tmp.keys()[0]].imag,x0,y0) out[tmp.keys()[0]]=u+1.j*v info+='#'+d.strftime('%Y%m%d') new_wind_info='blended+quikscat at days: '+info update_wind(fname,out,new_wind_info,**kargs)
def update_wind(self,data,keepOld=True,quiet=0): # store old at first iteration nc=netcdf.Pync(self.filename,'w') time=netcdf.nctime(self.filename,'time') tind,=np.where(time==data['date']) if tind.size: tind=tind[0] else: if not quiet: print('cannot find time=%s' % data['date'].isoformat(' ')) return if 'Uwind' in nc.varnames: # roms names=('Uwind','uwnd'),('Vwind','vwnd'),'sustr','svstr','wspd' else: # roms-agrif names='uwnd','vwnd','sustr','svstr','wspd' # store old wind data: if False and tind==0: # not using for now.... too slow! # TODO: remove keepOld form argument !? if 'x_wind' in data.keys(): if not quiet: print('adding x_wind, y_wind') nc.add_dim('x_wind_original',data['x_wind'].shape[1]) nc.add_dim('y_wind_original',data['x_wind'].shape[0]) nc.add_var('x_wind_original',data['x_wind'].dtype, ('y_wind_original','x_wind_original')) nc.add_var('y_wind_original',data['y_wind'].dtype, ('y_wind_original','x_wind_original')) nc.vars['x_wind_original'][...]=data['x_wind'] nc.vars['y_wind_original'][...]=data['y_wind'] for i in names: if isinstance(i,basestring): filev,datav=i,i else: filev,datav=i newName = filev+'_old' newType = nc.vars[filev].dtype() newDims = nc.vars[filev].dims.keys() if not quiet: print(' creating var %s' % newName) nc.add_var(newName,newType,newDims) if not quiet: print(' filling var %s' % newName) nc.vars[newName][...]=nc.vars[filev][...] # also store old original data, if present: orig=datav+'_original' if orig in nc.varnames: newName = orig+'_old' newType = nc.vars[orig].dtype() newDims = nc.vars[orig].dims.keys() if not quiet: print(' creating var %s' % newName) nc.add_var(newName,newType,newDims) if not quiet: print(' filling var %s' % newName) nc.vars[newName][...]=nc.vars[orig][...] # store new wind data: for i in names: if isinstance(i,basestring): filev,datav=i,i else: filev,datav=i if not quiet: print(' %s (%s) min=%8.3f max=%8.3f' % (filev.ljust(7),datav.ljust(7), data[datav].min(),data[datav].max())) nc.vars[filev][tind,...]=data[datav] # also store new wind original data, if present: orig=datav+'_original' if not orig in data.keys(): continue if not quiet: print(' %s min=%8.3f max=%8.3f' % (orig.ljust(7+9), data[orig].min(),data[orig].max())) nc.vars[orig][tind,...]=data[datav] # adding global atts: if 'attr' in data.keys(): for i in data['attr'].keys(): nc.add_att(i,data['attr'][i]) nc.close()
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 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 load_data(f, quiet=0, **kargs): ''' Loads prognostic variables (temp,salt,u,v,ubar,vbar,zeta) from netcdf file or opendap server. Also loads lon,lat, depth, and time. If f is a file, it must include the 1d variables lon,lat and depth; the 2d variable ssh (zeta) and the 3d variables temp, salt, u and v; ie, each file must contain data for a simgle time. The file must also contain the variable time. If f is a opendap address, it must contain also all these variables or the ones defined in the input karg settings (DataAccess object) To deal with the case of variables in different files/opendap addresses, f can also be a dictionary with keys the variables and values the files or opendap addresses. In this case, the keys must be: - temp - salt - u - v - ssh - misc, for lon, lat, depth, time and dimensions or xy for lon,lat and x,ydim; z for depth and zdim, time for time The output data (dict) is suitable to be used by data2roms, which interpolates the data to ROMS 3d grid. Also outputs an error/status string. kargs: inds, dict with dimension names/values (where time dim can be integer or datetime) settings, DataAccess object extra, extra misc vars to load [(outKey0,fileVar0),...] t_units, units of variable time, by default the att units is used ''' sett = DataAccess() inds = {} extra = [] t_units = [] if 'settings' in kargs.keys(): sett = kargs['settings'] if 'inds' in kargs.keys(): inds = kargs['inds'] if 'extra' in kargs.keys(): extra = kargs['extra'] if 't_units' in kargs.keys(): t_units = kargs['t_units'] res = {} msg = '' if not isinstance(f, dict) and not f.startswith('http') and not isfile(f): msg = 'file not found %s' % f if not quiet: print msg return res, msg # load nc files: if not isinstance(f, dict): f = {'temp': f, 'salt': f, 'u': f, 'v': f, 'ssh': f, 'misc': f} if not f.has_key('xy'): f['xy'] = f['misc'] if not f.has_key('z'): f['z'] = f['misc'] if not f.has_key('time'): f['time'] = f['misc'] filesUsed = [] ncUsed = [] for i in f.keys(): if not quiet: print '(%s) loading from %s' % (i.ljust(5), f[i]) if i == 'temp': if f[i] in filesUsed: ncTemp = ncUsed[filesUsed.index(f[i])] else: ncTemp = netcdf.ncopen(f[i]) filesUsed += [f[i]] ncUsed += [ncTemp] elif i == 'salt': if f[i] in filesUsed: ncSalt = ncUsed[filesUsed.index(f[i])] else: ncSalt = netcdf.ncopen(f[i]) filesUsed += [f[i]] ncUsed += [ncSalt] elif i == 'u': if f[i] in filesUsed: ncU = ncUsed[filesUsed.index(f[i])] else: ncU = netcdf.ncopen(f[i]) filesUsed += [f[i]] ncUsed += [ncU] elif i == 'v': if f[i] in filesUsed: ncV = ncUsed[filesUsed.index(f[i])] else: ncV = netcdf.ncopen(f[i]) filesUsed += [f[i]] ncUsed += [ncV] elif i == 'ssh': if f[i] in filesUsed: ncSsh = ncUsed[filesUsed.index(f[i])] else: ncSsh = netcdf.ncopen(f[i]) filesUsed += [f[i]] ncUsed += [ncSsh] elif i == 'xy': if f[i] in filesUsed: ncXy = ncUsed[filesUsed.index(f[i])] else: ncXy = netcdf.ncopen(f[i]) filesUsed += [f[i]] ncUsed += [ncXy] elif i == 'z': if f[i] in filesUsed: ncZ = ncUsed[filesUsed.index(f[i])] else: ncZ = netcdf.ncopen(f[i]) filesUsed += [f[i]] ncUsed += [ncZ] elif i == 'time': if f[i] in filesUsed: ncTime = ncUsed[filesUsed.index(f[i])] else: ncTime = netcdf.ncopen(f[i]) filesUsed += [f[i]] ncUsed += [ncTime] elif i == 'misc': if f[i] in filesUsed: ncMisc = ncUsed[filesUsed.index(f[i])] else: ncMisc = netcdf.ncopen(f[i]) filesUsed += [f[i]] ncUsed += [ncMisc] # load dims: if not quiet: print ' loading dims...' dimsXy = netcdf.fdim(ncXy) dimsZ = netcdf.fdim(ncZ) res['NX'] = dimsXy[sett.xdim] res['NY'] = dimsXy[sett.ydim] ###if sett.z_name: if sett.zdim: res['NZ'] = dimsZ[sett.zdim] else: res['NZ'] = 1 # about horizontal inds: if inds.has_key( sett.xdim) and len(inds[sett.xdim]) == 2 and not isinstance( inds[sett.xdim], basestring): if not quiet: print ' calc horizontal inds...' xlim = inds[sett.xdim] ylim = inds[sett.ydim] inds.pop(sett.xdim) inds.pop(sett.ydim) lon = netcdf.use(ncXy, sett.x_name, **inds) if np.any(lon > 360): lon = np.mod(lon, 360.) lat = netcdf.use(ncXy, sett.y_name, **inds) i0, i1, j0, j1 = calc.ij_limits(lon, lat, xlim, ylim, margin=3) inds[sett.xdim] = '%d:%d' % (i0, i1) inds[sett.ydim] = '%d:%d' % (j0, j1) if not quiet: print ' loading lon, lat, depth...' res['lon'] = netcdf.use(ncXy, sett.x_name, **inds) if np.any(res['lon'] > 360): res['lon'] = np.mod(res['lon'], 360.) res['lat'] = netcdf.use(ncXy, sett.y_name, **inds) if sett.z_name: res['depth'] = -netcdf.use(ncZ, sett.z_name, **inds) else: res['depth'] = False if res['lon'].size != res['lat'].size: res['lon'], res['lat'] = np.meshgrid(res['lon'], res['lat']) # needed for griddata, later # update nx,ny: if inds.has_key(sett.xdim): res['NY'], res['NX'] = res['lon'].shape # extra misc vars: if len(extra): for outKey, fileVar in extra: if not quiet: print ' loading extra misc... %s %s' % (outKey, fileVar) res[outKey] = netcdf.use(ncMisc, fileVar, **inds) # time: # file may have one or several times. If several, time dim must be given # with kargs inds! # but file may also have no time dim or time name ! if sett.time_name: if not quiet: print ' loading time...' if t_units: times = netcdf.use(ncTime, sett.time_name) times = netcdf.num2date(times, t_units) else: times = netcdf.nctime(ncTime, sett.time_name) if inds.has_key(sett.tdim): try: tind = dts.parse_date(inds[sett.tdim]) except: tind = inds[sett.tdim] # is an integer, for instance if isinstance(tind, datetime.datetime): tind, = np.where(times == tind) if tind.size: tind = tind[0] inds[sett. tdim] = tind # update inds to extract other variables else: Msg = 'date not found' msg += '\n' + Msg return res, msg + ' ERROR' date = times[tind] try: len(date) ndates = True except: ndates = False if ndates: if not quiet: print ' tind, date= len=%d: %d to %d, %s to %s' % ( len(date), tind[0], tind[-1], date[0].isoformat(' '), date[-1].isoformat(' ')) else: if not quiet: print ' tind, date= %d %s' % (tind, date.isoformat(' ')) elif times.size == 1: date = times[0] if not quiet: print ' date= %s' % date.isoformat(' ') else: # must provide tind as input!! Msg = 'several dates in file... provice tind!' msg += '\n' + Msg return res, msg + ' ERROR' res['date'] = date else: if not quiet: print ' warning: not using time !!' res['date'] = 0 empty3d = np.zeros([res['NZ'], res['NY'], res['NX']]) empty2d = np.zeros([res['NY'], res['NX']]) if 'temp' in f.keys(): if not quiet: print ' loading temp...' if sett.temp_name in ncTemp.varnames: res['temp'] = netcdf.use(ncTemp, sett.temp_name, **inds) else: Msg = 'var %s not found' % 'temp' msg += '\n' + Msg if not quiet: print Msg res['temp'] = empty3d if 'salt' in f.keys(): if not quiet: print ' loading salt...' if sett.salt_name in ncSalt.varnames: res['salt'] = netcdf.use(ncSalt, sett.salt_name, **inds) else: Msg = 'var %s not found' % 'salt' msg += '\n' + Msg if not quiet: print Msg res['salt'] = empty3d if 'u' in f.keys(): if not quiet: print ' loading u...' if sett.u_name in ncU.varnames: res['u'] = netcdf.use(ncU, sett.u_name, **inds) else: Msg = 'var %s not found' % 'u' msg += '\n' + Msg if not quiet: print Msg res['u'] = empty3d if 'v' in f.keys(): if not quiet: print ' loading v...' if sett.v_name in ncV.varnames: res['v'] = netcdf.use(ncV, sett.v_name, **inds) else: Msg = 'var %s not found' % 'v' msg += '\n' + Msg if not quiet: print Msg res['v'] = empty3d if 'ssh' in f.keys(): if not quiet: print ' loading ssh...' if sett.ssh_name in ncSsh.varnames: res['ssh'] = netcdf.use(ncSsh, sett.ssh_name, **inds) else: Msg = 'var %s not found' % 'ssh' msg += '\n' + Msg if not quiet: print Msg res['ssh'] = empty2d for nc in ncUsed: try: nc.close() except: pass return res, msg
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 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
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 'missind 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 'missind 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:
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 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) 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 'missind 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 if t[-1]<t1: dt=t1-t[-1] dt=dt.days*24+dt.seconds/3600. # hours print 'missind 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 return var out={} # time: if 0: time=netcdf.nctime(files['cc'],'time') # files have diff units !! so, cannot load all times at once! # thse result will use only units of 1st file!! else: time=load_time(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:
def plt_hslice(conf, plconf, date, FA='a', nest=0, **kargs): err = '' fig = False info = {} type = 'avg' var = 'temp' slice = 'z' ind = -10 time = -1 currents = False dcurr = (3, 3) scurr = 3 lcurr = 0.2 ifig = 0 # closefig = True clim = False quiet = False outStoragePath = False cmap = None norm = None useBar = True # currents are barotropic for 2D vars (like zeta) keys = kargs.keys() if 'type' in keys: type = kargs['type'] if 'var' in keys: var = kargs['var'] if 'slice' in keys: slice = kargs['slice'] if 'ind' in keys: ind = kargs['ind'] if 'time' in keys: time = kargs['time'] if 'currents' in keys: currents = kargs['currents'] if 'dcurr' in keys: dcurr = kargs['dcurr'] if 'scurr' in keys: scurr = kargs['scurr'] if 'lcurr' in keys: lcurr = kargs['lcurr'] if 'ifig' in keys: ifig = kargs['ifig'] if 'closefig' in keys: closefig = kargs['closefig'] if 'clim' in keys: clim = kargs['clim'] if 'quiet' in keys: quiet = kargs['quiet'] if 'ostorage' in keys: outStoragePath = kargs['ostorage'] if 'cmap' in keys: cmap = kargs['cmap'] if 'usebar' in keys: useBar = kargs['usebar'] if 'norm' in keys: norm = kargs['norm'] date = dateu.parse_date(date) # find input files: args = { 'cf': conf, 'date': date, 'FA': FA, 'nest': nest, 'ostorage': outStoragePath } his = opt.nameof('out', type, **args) clm = opt.nameof('in', 'clm', **args) grd = opt.nameof('in', 'grd', **args) if not os.path.isfile(his): err = 'Main file not found (%s)' % his return err, fig, info if not os.path.isfile(grd): err = 'Grid file not found (%s)' % grd return err, fig, info r = roms.His(his, grd) # plot grid: proj, fig, ax = plt_grid(plconf, grd, ifig) def add_colorbar(handle, **args): ax = pl.gca() Data, err = opt.get_plconf(plconf, 'AXES') cbpos = Data['cbpos'][ifig] cbbgpos = Data['cbbgpos'][ifig] cbbgc = Data['cbbgcolor'][ifig] cbbga = Data['cbbgalpha'][ifig] cblab = Data['cblabel'][ifig] # colorbar bg axes: if cbbgpos: rec = pl.axes((cbpos[0] - cbpos[2] * cbbgpos[0], cbpos[1] - cbbgpos[2] * cbpos[3], cbpos[2] * (1 + cbbgpos[0] + cbbgpos[1]), cbpos[3] * (1 + cbbgpos[2] + cbbgpos[3])), axisbg=cbbgc, frameon=1) rec.patch.set_alpha(cbbga) rec.set_xticks([]) rec.set_yticks([]) for k in rec.axes.spines.keys(): rec.axes.spines[k].set_color(cbbgc) rec.axes.spines[k].set_alpha(cbbga) # colorbar: if cbpos: cbax = fig.add_axes(cbpos) if cbpos[2] > cbpos[3]: orient = 'horizontal' else: orient = 'vertical' cb = pl.colorbar(handle, cax=cbax, orientation=orient, drawedges=0, **args) pl.axes(ax) # colorbar label: if cblab: Data, err = opt.get_plconf(plconf, 'HSLICES') varnames = Data['varnames'][ifig].split(',') vnames = Data['vnames'][ifig].split(',') lab = '' for i in range(len(varnames)): if varnames[i].strip() == var: lab = vnames[i].strip() break if lab: if r.hasz(var): if slice == 'k': if ind == 0: lab = 'Bottom ' + lab elif ind in (-1, 'surface'): lab = 'Surface ' + lab elif slice == 'z': lab = lab + ' ' + str(ind) + 'm' cb.set_label(lab) def add_currkey(handle): Data, err = opt.get_plconf(plconf, 'HSLICES') pos = Data['kcurrpos'][ifig] if pos: pl.quiverkey(handle, pos[0], pos[1], lcurr, '%s m/s' % str(lcurr), labelpos='S', coordinates='axes') # hslice: if var: if slice == 'k': metodo = r.slicek elif slice == 'z': metodo = r.slicez x, y, z, v = metodo(var, ind, time, plot=False) x, y = proj(x, y) # cmap: if isinstance(cmap, basestring): try: cmap = pl.cm.cmap_d[cmap] except: try: from okean import pl_tools cmap = pl_tools.cm.cmap_d[cmap] except: cmap = pl.cm.jet # original data from clm if slice == 'k' and ind in ( -1, ) and var + '_original' in netcdf.varnames(clm): tcurr = r.datetime[time] x_o = netcdf.use(clm, 'x_original') y_o = netcdf.use(clm, 'y_original') x_o, y_o = proj(x_o, y_o) v_o = netcdf.use(clm, 'y_original') t_o = netcdf.nctime(clm, 'clim_time') # average to current time: i0, = np.where(t_o <= tcurr)[-1] i1, = np.where(t_o > tcurr)[0] v_o0 = netcdf.use(clm, var + '_original', time=i0) v_o1 = netcdf.use(clm, var + '_original', time=i1) # avg: a = tcurr - t_o[i0] b = t_o[i1] - tcurr a = a.days * 86400 + a.seconds b = b.days * 86400 + b.seconds if a == 0: v_o = v_o0 elif b == 0: v_o = v_o1 else: v_o = (v_o0 * b + v_o1 * a) / (a + b) pch = pl.pcolormesh(x_o, y_o, v_o, shading='flat', cmap=cmap) if clim: pl.clim(clim[0], clim[1]) if norm == 'log': from matplotlib.colors import LogNorm Norm = LogNorm(vmin=clim[0], vmax=clim[1]) else: Norm = None # change hypoxia colorbar/cmap if var == 'dye_01': HypoxiaLim = 135 from okean import pl_tools cmap = pl_tools.ucmaps().gen_oxygen( v=(0, HypoxiaLim, 300.)) # default is 0,135,300 !! pch = pl.pcolormesh(x, y, v, shading='flat', cmap=cmap, norm=Norm) if clim: pl.clim(clim[0], clim[1]) # hypoxia: if var == 'dye_01' and ind == 0 and ifig == 0: cond = v < 135. cond = v < HypoxiaLim cond = (v < HypoxiaLim) & (r.grid.h > 5) pm = r.grid.use('pm') pn = r.grid.use('pn') A = (1 / pm[cond] * 1 / pn[cond] / 1e6).sum() x_, y_ = proj(-98, 29.5) pl.text(x_, y_, 'Hypoxia area = %.0f km$^2$' % A, color='r', fontweight='bold', fontname='monospace', bbox=dict(edgecolor='none', facecolor='white', alpha=0.8)) # hypoxia. # colorbar: if norm == 'log': tks = 10**np.linspace(np.log10(clim[0]), np.log10(clim[1]), 4) opts = {'ticks': tks, 'format': '%.2f'} else: opts = {'ticks': None} add_colorbar(pch, **opts) if currents: if (var and r.hasz(var)) or not useBar: uvind = ind else: uvind = 'bar' x, y, z, u, v = r.sliceuv(uvind, time) xm, ym = proj(x, y) mm = np.zeros(x.shape, 'bool') mm[::dcurr[0], ::dcurr[1]] = True Data, err = opt.get_plconf(plconf, 'HSLICES') wcurr = Data['wcurr'][ifig] acurr = Data['acurr'][ifig] qvopts = {'units': 'x', 'scale': scurr, 'width': wcurr, 'alpha': acurr} if var: q = pl.quiver(xm[mm], ym[mm], u[mm], v[mm], **qvopts) else: s = np.sqrt(u**2 + v**2) q = pl.quiver(xm[mm], ym[mm], u[mm], v[mm], s[mm], **qvopts) if clim: pl.clim(clim[0], clim[1]) add_colorbar(q) add_currkey(q) # store some info that may be required later info['hasz'] = False if var and r.hasz(var): info['hasz'] = True # logo: if ifig == 0: im = os.path.join(os.path.dirname(__file__), 'logo_INOCAR.png') i = pl.imread(im) h, w = i.shape[:2] rx = .12 W = (proj.xmax - proj.xmin) * rx H = W * h / w l = proj.xmax #pl.fill([proj.xmax-W, proj.xmax, proj.xmax, proj.xmax-W], # [proj.ymin, proj.ymin, proj.ymin+2.8*H, proj.ymin+2.8*H], # '#500000',alpha=0.25,ec='none') ax.imshow(i, extent=(proj.xmax * .98 - W, proj.xmax * .98, proj.ymin + H * .1, proj.ymin + H * 1.1), zorder=1e3) #pl.text(proj.xmax-W/2., proj.ymin+2.2*H,'OOF', # fontdict={'size':14,'family':'serif'}, # color='#500000',ha='center',weight='bold') pl.text(proj.xmax * .8, proj.ymax * (-.1), r.datetime[time].strftime("%d %b %Y"), fontdict={ 'size': 11, 'family': 'monospace' }, ha='center') if FA == 'f': s = 'Pronostico desde %s' % r.datetime[0].strftime("%d %b %Y") pl.text( proj.xmax * .8, proj.ymax * (-.15), s, #pl.text(proj.xmax-W/2., proj.ymin+1.1*H,s, fontdict={'fontsize': 10}, ha='center') # logo. # lims change in some mpl versions !! pl.gca().axis([proj.xmin, proj.xmax, proj.ymin, proj.ymax]) return err, fig, info