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 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 path_s_levels(self,time,x,y,rw='r',**kargs): inds=kargs.get('inds',None) xr,yr,h,m=self.grid.vars() zeta=self.use('zeta',SEARCHtime=time) if inds: i0,i1=inds['xi'] j0,j1=inds['eta'] xr=xr[j0:j1,i0:i1] yr=yr[j0:j1,i0:i1] h=h[j0:j1,i0:i1] m=m[j0:j1,i0:i1] zeta= zeta[j0:j1,i0:i1] if np.ma.isMA(zeta): h=np.ma.masked_where(zeta.mask,h) else:# probably a clm/ini file. Mask maskc point (pygridgen complex grid): if 'maskc' in netcdf.varnames(self.grid.nc): mc=self.grid.use('maskc') if inds: mc=mc[j0:j1,i0:i1] h=np.ma.masked_where(mc==0,h) zeta=np.ma.masked_where(mc==0,zeta) h = calc.griddata(xr,yr,h,x,y,extrap=False) zeta = calc.griddata(xr,yr,zeta,x,y,extrap=False) z=rt.s_levels(h,zeta,self.s_params,rw=rw) z=np.squeeze(z) return np.ma.masked_where(np.isnan(z),z)
def path_s_levels(self,time,x,y,rw='r'): xr,yr,h,m=self.grid.vars() zeta=self.use('zeta',SEARCHtime=time) h = calc.griddata(xr,yr,h,x,y,extrap=False) zeta = calc.griddata(xr,yr,zeta,x,y,extrap=False) z=rt.s_levels(h,zeta,self.s_params,rw=rw) z=np.squeeze(z) return np.ma.masked_where(np.isnan(z),z)
def slicell(self,varname,X,Y,time=0,plot=False,**opts): x,y,z,v,m=[[]]*5 data = opts.get('data',False) dist = opts.get('dist',False) extrap = opts.get('extrap',False) varOnly = opts.get('retv',False) maskLimit = opts.get('lmask',0.5) # points where interpolated mask are above # this value are considered as mask! # Most strict value is 0 X=np.array(X) Y=np.array(Y) if X.ndim>1: X=np.squeeze(X) if Y.ndim>1: Y=np.squeeze(X) if varname not in netcdf.varnames(self.name): print(':: variable %s not found' % varname) return x,y,z,v,m if time>=self.TIME: print('t = %d exceeds TIME dimension (%d)' % (time,self.TIME)) return x,y,z,v,m if data is False: v=self.use(varname,SEARCHtime=time) else: v=data x,y,h,m=self.grid.vars(ruvp=self.var_at(varname)) if v.ndim==3: V=calc.griddata(x,y,v,X,Y,extrap=extrap,mask2d=m==0, keepMaskVal=maskLimit) elif v.ndim==2: V=calc.griddata(x,y,np.ma.masked_where(m==0,v),X,Y,extrap=extrap, keepMaskVal=maskLimit) if varOnly: return V # Z: if v.ndim==3: Z=self.path_s_levels(time,X,Y,rw=varname[0]) else: Z=0.*X # X, Y, dist: if dist: Dist=calc.distance(X,Y) if v.ndim==3: Dist=np.tile(Dist,(v.shape[0],1)) else: if v.ndim==3: X=np.tile(X,(v.shape[0],1)) Y=np.tile(Y,(v.shape[0],1)) if dist: return Dist,Z,V else: return X,Y,Z,V
def data2romsblk(data, grd, **kargs): quiet = True keepOriginal = 2 # if 2, will keep data only inside rt.grid_vicinity rectange # if 1, all original data is kept Margin = 4 # for griddata and for original data to keep for k in kargs.keys(): if k == "quiet": quiet = kargs[k] elif k.lower().startswith("keepor"): keepOriginal = kargs[k] elif k == "margin": Margin = kargs[k] g = roms.Grid(grd) cond = False out = {} for vname in data.keys(): if vname.startswith("INFO") or vname in "xy": continue # vnames starting with INFO are an info key, without data if not quiet: print " interp %s" % vname if cond is False: cond, inds = rt.grid_vicinity(grd, data["x"], data["y"], margin=Margin, rect=True, retinds=True) i1, i2, j1, j2 = inds out[vname] = calc.griddata(data["x"][cond], data["y"][cond], data[vname][cond], g.lon, g.lat, extrap=True) if keepOriginal: # keep original data: if keepOriginal == 1: out[vname + "_original"] = data[vname] # keep all original data elif keepOriginal == 2: out[vname + "_original"] = data[vname][j1:j2, i1:i2] # keep data only inside vicinity rectangle if not out.has_key("x_original"): if keepOriginal == 1: out["x_original"] = data["x"] out["y_original"] = data["y"] elif keepOriginal == 2: out["x_original"] = data["x"][j1:j2, i1:i2] out["y_original"] = data["y"][j1:j2, i1:i2] # about wind: if not quiet: print " --> rot U,V wind and U,V wind stress" angle = g.use("angle") out["uwnd"], out["vwnd"] = calc.rot2d(out["uwnd"], out["vwnd"], angle) out["sustr"], out["svstr"] = calc.rot2d(out["sustr"], out["svstr"], angle) out["sustr"] = rt.rho2uvp(out["sustr"], "u") out["svstr"] = rt.rho2uvp(out["svstr"], "v") return out
def path_s_levels(self, time, x, y, rw='r'): xr, yr, h, m = self.grid.vars() zeta = self.use('zeta', SEARCHtime=time) if np.ma.isMA(zeta): h = np.ma.masked_where(zeta.mask, h) else: # probably a clm/ini file. Mask maskc point (pygridgen complex grid): if 'maskc' in netcdf.varnames(self.grid.name): mc = self.grid.use('maskc') h = np.ma.masked_where(mc == 0, h) zeta = np.ma.masked_where(mc == 0, zeta) h = calc.griddata(xr, yr, h, x, y, extrap=False) zeta = calc.griddata(xr, yr, zeta, x, y, extrap=False) z = rt.s_levels(h, zeta, self.s_params, rw=rw) z = np.squeeze(z) return np.ma.masked_where(np.isnan(z), z)
def path_s_levels(self,time,x,y,rw='r'): xr,yr,h,m=self.grid.vars() zeta=self.use('zeta',SEARCHtime=time) if np.ma.isMA(zeta): h=np.ma.masked_where(zeta.mask,h) else:# probably a clm/ini file. Mask maskc point (pygridgen complex grid): if 'maskc' in netcdf.varnames(self.grid.name): mc=self.grid.use('maskc') h=np.ma.masked_where(mc==0,h) zeta=np.ma.masked_where(mc==0,zeta) h = calc.griddata(xr,yr,h,x,y,extrap=False) zeta = calc.griddata(xr,yr,zeta,x,y,extrap=False) z=rt.s_levels(h,zeta,self.s_params,rw=rw) z=np.squeeze(z) return np.ma.masked_where(np.isnan(z),z)
def data2romsblk(data,grd,**kargs): quiet = True keepOriginal = 2 # if 2, will keep data only inside rt.grid_vicinity rectange # if 1, all original data is kept Margin = 4 # for griddata and for original data to keep for k in kargs.keys(): if k=='quiet': quiet=kargs[k] elif k.lower().startswith('keepor'): keepOriginal=kargs[k] elif k=='margin': Margin=kargs[k] g=roms.Grid(grd) cond=False out={} for vname in data.keys(): if vname.startswith('INFO') or vname in 'xy': continue # vnames starting with INFO are an info key, without data if not quiet: print ' interp %s' % vname if cond is False: cond,inds=rt.grid_vicinity(grd,data['x'],data['y'], margin=Margin,rect=True,retinds=True) i1,i2,j1,j2=inds out[vname]=calc.griddata(data['x'][cond],data['y'][cond], data[vname][cond],g.lon,g.lat,extrap=True) if keepOriginal: # keep original data: if keepOriginal==1: out[vname+'_original']=data[vname] # kepp all original data elif keepOriginal==2: out[vname+'_original']=data[vname][j1:j2,i1:i2] # keep data only inside vicinity rectangle if not out.has_key('x_original'): if keepOriginal==1: out['x_original']=data['x'] out['y_original']=data['y'] elif keepOriginal==2: out['x_original']=data['x'][j1:j2,i1:i2] out['y_original']=data['y'][j1:j2,i1:i2] # about wind: if not quiet: print ' --> rot U,V wind and U,V wind stress' angle=g.use('angle') out['uwnd'],out['vwnd']=calc.rot2d(out['uwnd'],out['vwnd'],angle) out['sustr'],out['svstr']=calc.rot2d(out['sustr'],out['svstr'],angle) out['sustr']=rt.rho2uvp(out['sustr'],'u') out['svstr']=rt.rho2uvp(out['svstr'],'v') return out
def path_s_levels(self,time,x,y,rw='r',**kargs): inds=kargs.get('inds',None) xr,yr,h,m=self.grid.vars() zeta=self.use('zeta',SEARCHtime=time) if inds: i0,i1=inds['xi'] j0,j1=inds['eta'] xr=xr[j0:j1,i0:i1] yr=yr[j0:j1,i0:i1] h=h[j0:j1,i0:i1] m=m[j0:j1,i0:i1] zeta= zeta[j0:j1,i0:i1] if np.ma.is_masked(zeta): # h=np.ma.masked_where(zeta.mask,h) # comment above in order to keep right depth inside the domain # on masked regions pass else:# probably a clm/ini file. Mask maskc point (pygridgen complex grid): if 'maskc' in netcdf.varnames(self.grid.nc): mc=self.grid.use('maskc') if inds: mc=mc[j0:j1,i0:i1] h=np.ma.masked_where(mc==0,h) zeta=np.ma.masked_where(mc==0,zeta) h = calc.griddata(xr,yr,h,x,y,extrap=False) zeta = calc.griddata(xr,yr,zeta,x,y,extrap=False) # better interpolate the gaps, otherwise s_levels will use default # values for zeta and h: X=np.arange(h.size) if np.ma.is_masked(h): h=np.interp(X,X[~h.mask],h[~h.mask]) if np.ma.is_masked(zeta): zeta=np.interp(X,X[~zeta.mask],zeta[~zeta.mask]) ### return h,zeta,self.s_params,rw return rt.s_levels(h,zeta,self.s_params,rw=rw)
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 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 get_depth(x,y,all=False): bat_in = 'data/nri_regional_grd_roms_v2.nc' tnc = netCDF4.Dataset(bat_in) tvars = tnc.variables xb = tnc.variables['x_rho'][:] yb = tnc.variables['y_rho'][:] bat = tnc.variables['h'][:] bat = np.ma.masked_where(bat==-10.0,bat) if False: dep = calc.griddata(xb[~bat.mask], yb[~bat.mask],bat[~bat.mask] , x, y,extrap=True) else: import octant.csa as csa csa_interp = csa.CSA(xb[~bat.mask], yb[~bat.mask],bat[~bat.mask]) dep = csa_interp(x,y) if all: return dep,xb,yb,bat else: return dep
def time_series(self,varname,x,y,times=None,depth=None,**opts): coords=opts.get('coords',self._default_coords('time_series')).split(',') if times is None: times=range(0,self.time.size) # depth or s_level: check if is float or if is negative! isDepth=False if not depth is None: if calc.isiterable(depth): depth=np.asarray(depth) if calc.isarray(depth): isDepth=np.any(depth<0) or depth.kind!='i' else: isDepth=depth<0 or np.asarray(depth).dtype.kind!='i' out=vis.Data() out.label='time_series' if not depth is None and not isDepth: out.msg=self.check_slice(varname,t=np.max(times),k=depth) else: out.msg=self.check_slice(varname,t=np.max(times)) if out.msg: return out # find nearest point: ### lon,lat,hr,mr=self.grid.vars(ruvp=self.var_at(varname)) lon,lat,hr,mr=self.grid.vars(ruvp=self.vloc(varname)) dist=(lon-x)**2+(lat-y)**2 i,j=np.where(dist==dist.min()) i,j=i[0],j[0] if not depth is None and not isDepth: arg={'s_SEARCH':depth} else: arg={} v=self.use(varname,xiSEARCH=j,etaSEARCH=i,SEARCHtime=times,**arg).T # calculate depths: ### if self.hasz(varname): if 'z' in self.vaxes(varname): h=self.grid.h[i,j] zeta=self.use('zeta',xiSEARCH=j,etaSEARCH=i,SEARCHtime=times) h=h+0*zeta #### z=rt.s_levels(h,zeta,self.s_params,rw=varname) ### z=rt.s_levels(h,zeta,self.s_params,rw=self.var_at(varname)[1]) z=rt.s_levels(h,zeta,self.s_params,rw=self.vloc(varname)[1]) z=np.squeeze(z) # depth slice: ### if isDepth and self.hasz(varname): if isDepth and 'z' in self.vaxes(varname): if v.ndim==2: # could use calc.griddata, but better use slicez cos data at # different times may be independent! if 0: from matplotlib.dates import date2num t=np.tile(date2num(self.time[times]),(v.shape[0],1)) v=calc.griddata(t,z,v,t[0],depth+np.zeros(t[0].shape), extrap=opts.get('extrap',False),norm_xy=opts.get('norm_xy',False)) # norm_xy True may be needed! # extrap also may be needed cos the 1st and last value may be masked! else: nt=len(times) land_mask=np.ones((nt,1),dtype=v.dtype) # needed for slicez... not used here! v=rt.slicez(v[...,np.newaxis],land_mask, self.grid.h[i,j]*np.ones((nt,1),dtype=v.dtype), # bottom depth zeta[:,np.newaxis],self.s_params,depth, surface_masked=opts.get('surf_mask',True), spline=opts.get('spline',True))[...,0] else: # one time only v=np.interp(depth,z,v,left=np.nan,right=np.nan) v=np.ma.masked_where(np.isnan(v),v) out.v=v out.info['v']['name']=varname out.info['v']['slice']='time series' try: out.info['v']['units']=netcdf.vatt(self.nc,varname,'units') except: pass # coords ######### if 't' in coords and self.hast(varname): if 't' in coords and 't' in self.vaxes(varname): if v.ndim==2: out.t=np.tile(self.time[times],(v.shape[0],1)) from matplotlib.dates import date2num out.tnum=np.tile(date2num(self.time[times]),(v.shape[0],1)) else: out.t=self.time[times] out.info['t']['name']='Time' out.info['tnum']=dict(name='Time',units=self.var_as['time']['units']) ### if 'z' in coords and self.hasz(varname): if 'z' in coords and 'z' in self.vaxes(varname): if not depth is None: if not isDepth: out.z=z[depth,...] else: out.z=depth+0*v else: out.z=z out.info['z']=dict(name='Depth',units='m') if 'x' in coords: out.x=lon[i,j] if self.grid.spherical: out.info['x']=dict(name='Longitude',units=r'$\^o$E') else: out.x=x/1000. out.info['x']=dict(name='X-position',units='km') if 'y' in coords: out.y=lat[i,j] if self.grid.spherical: out.info['y']=dict(name='Latitude',units=r'$\^o$N') else: out.y=y/1000. out.info['y']=dict(name='Y-position',units='km') out.coordsReq=','.join(sorted(coords)) return out
def time_series(self,varname,x,y,times=False,depth=False,**opts): t,z,v=[[]]*3 RetVarOnly=False savename=False retMsg=False nearest=True # UNIQUE case Currently plot=False if 'retvar' in opts.keys(): RetVarOnly = opts['retvar'] if 'savename' in opts.keys(): savename = opts['savename'] if 'msg' in opts.keys(): retMsg = opts['msg'] if 'nearest' in opts.keys(): nearest = opts['msg'] if 'plot' in opts.keys(): plot = opts['msg'] if varname not in netcdf.varnames(self.name): msg=':: variable %s not found' % varname if retMsg: return t,z,v,msg else: print(msg) return t,z,v isW=varname=='w' hasZ=self.hasz(varname) if not depth is False and hasZ : if isW and depth >= self.S_W: msg='k = %d exceeds S_W dimension (%d)' % (depth,self.S_W) if retMsg: return t,z,v,msg else: print(msg) return t,z,v elif depth >= self.S_RHO: msg='k = %d exceeds S_RHO dimension (%d)' % (depth,self.S_RHO) if retMsg: return t,z,v,msg else: print(msg) return t,z,v if times is False: times=0,len(self.tdays) if self.hast(varname) and times[-1]>self.TIME: msg='t = %d exceeds TIME dimension (%d)' % (times[-1],self.TIME) if retMsg: return t,z,v,msg else: print(msg) return t,z,v lon,lat,hr,mr=self.grid.vars(ruvp=self.var_at(varname)) dist=(lon-x)**2+(lat-y)**2 i,j=np.where(dist==dist.min()) i,j=i[0],j[0] v=self.use(varname,xiSEARCH=j,etaSEARCH=i,SEARCHtime=range(times[0],times[-1])).T # time: t=self.tdays[range(times[0],times[-1])] t=t+0.*v # depth: if hasZ: h=self.grid.h[i,j] zeta=self.use('zeta',xiSEARCH=j,etaSEARCH=i,SEARCHtime=range(times[0],times[-1])) h=h+0*zeta z=rt.s_levels(h,zeta,self.s_params,rw=varname) z=np.squeeze(z) if not depth is False: if depth>=0: t=t[0,:] z=z[depth,:] v=v[depth,:] else: t0,z0=t,z t=t[0,:] z=depth+0.*t v=calc.griddata(t0,z0,v,t,z,extrap=False,norm_xy=True) else: # not hasZ z=0.*t if plot: pass # TODO if RetVarOnly: return v else: if retMsg: return t,z,v,'' else: return t,z,v
def ww3gb_2TPAR(datafolder,date0,date1,romsgrid,nseg=(10,10),addxy=(0.001,0.001),dspr=20,path='',name='TPAR'): '''dspr, directional spreading; see https://www.myroms.org/forum/viewtopic.php?f=14&t=2335 ''' g=roms.Grid(romsgrid) # loading data: xlim=g.lon.min()-2,g.lon.max()+2 ylim=g.lat.min()-2,g.lat.max()+2 lon,lat,Time,Res=WW3Data(datafolder).data(date0,date1,xlim,ylim) # calc spec points: xy,ij=ww3_specpoints(romsgrid,nseg,addxy) # interpolate data at initial point of each segment: x=xy[:,0] y=xy[:,1] nt=len(Time) nv=len(Res) nx=xy.shape[0] TPAR=np.zeros((nt,nv,nx),'f') vnames='hs','tp','dp' # Significant_height_of_combined_wind_waves_and_swell # Primary_wave_mean_period # Primary_wave_direction for it in range(nt): if it%10==0: print 'time %03d of %03d : %s'%(it,nt,Time[it].isoformat(' ')) for iv in range(nv): vname=vnames[iv] #print ' -- %s'%vname v=Res[vname][it,...] # 1st extrap masked data: v=calc.mask_extrap(lon,lat,v) TPAR[it,iv,:]=calc.griddata(lon,lat,v,x,y) # create TPAR files: for i in range(nx): fname=name+'_seg%03d.txt'%i j=open(fname,'w') j.write('TPAR\n') for it in range(nt): # time as YYYYMMDD.HHMMSS tiso=Time[it].strftime('%Y%m%d.%H%M%S') j.write('%s %6.2f %6.2f %6.2f %6.2f\n'%(tiso,TPAR[it,0,i],TPAR[it,1,i],TPAR[it,2,i],dspr)) j.close() print 'created tpar file %s'%fname x1=xy[:,2] y1=xy[:,3] # add to swan INPUT: # BOUND SHAPESPEC JONSWAP PEAK DSPR DEGREES # BOUNDSPEC SEGMENT XY -54.3906 33.1171 -55.5271 35.8094 VARIABLE FILE 0 './forcings/TPAR2.txt' print '\n' print 'BOUND SHAPESPEC JONSWAP PEAK DSPR DEGREES' for i in range(nx): fname=os.path.join(path,name+'_seg%03d.txt'%i) print 'BOUNDSPEC SEGMENT XY %8.4f %8.4f %8.4f %8.4f VARIABLE FILE 0 \'%s\''%(x[i],y[i],x1[i],y1[i],fname) print '\n' i0=ij[:,0] j0=ij[:,1] i1=ij[:,2] j1=ij[:,3] for i in range(nx): fname=os.path.join(path,name+'_seg%03d.txt'%i) print 'BOUNDSPEC SEGMENT IJ %3d %3d %3d %3d VARIABLE FILE 0 \'%s\''%(i0[i],j0[i],i1[i],j1[i],fname) print '\n'
# 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 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 data2roms(data,grd,sparams,**kargs): ''' Interpolates data to roms 3D grid. The dict data must contain the prognostic variables temp, salt, u, v (3d) and ssh (zeta, 2d), as well as lon, lat (2d), depth (1d) and time/date info: date (data date), date0 (reference date) and time (difference between date and date0). The input data can be provided by load_data. Parameters ---------- data : dict with prognostic variables grd : ROMS netcdf grid file sparams : s-coordinates parameters, theta_s,theta_b, hc and NLevels **kargs: ij : axis for vertical interpolations (*i,j) ij_ind : list of i or j index for vertical interpolation, all by default (ij_ind=False) horizAux : if True, the original data horizontally interpolated is returned and can be used for next data2roms call with this same karg quiet : output messages flag (false by default) ''' ij='j' ij_ind=False horizAux=False quiet=False if 'ij' in kargs.keys(): ij = kargs['ij'] if 'ij_ind' in kargs.keys(): ij_ind = kargs['ij_ind'] if 'horizAux' in kargs.keys(): horizAux = kargs['horizAux'] if 'quiet' in kargs.keys(): quiet = kargs['quiet'] if not quiet: print 'using grid %s' % grd g=roms.Grid(grd) xr,yr,hr,mr=g.vars('r') xu,yu,hu,mu=g.vars('u') xv,yv,hv,mv=g.vars('v') ny,nx=hr.shape nz=sparams[3] NX=data['NX'] NY=data['NY'] NZ=data['NZ'] if not quiet: print 'calc s levels...' sshr=calc.griddata(data['lon'],data['lat'],data['ssh'],xr,yr,extrap=True) Zr = g.s_levels(sparams,sshr,hr,'r') Zu = g.s_levels(sparams,sshr,hr,'u') Zv = g.s_levels(sparams,sshr,hr,'v') # interp horiz: retHorizAux=horizAux is True if horizAux in (True,False): TEMP = np.ma.masked_all((NZ,ny,nx),data['temp'].dtype) SALT = np.ma.masked_all((NZ,ny,nx),data['salt'].dtype) U = np.ma.masked_all((NZ,ny,nx),data['u'].dtype) V = np.ma.masked_all((NZ,ny,nx),data['v'].dtype) if not quiet: print 'horizontal interpolation:' for i in range(NZ): if not quiet and i%10==0: print ' lev %d of %d' % (i,NZ) #import pylab #pylab.figure() #pylab.pcolormesh(data['lon'],data['lat'],data['temp'][i,...]) try: TEMP[i,...] = calc.griddata(data['lon'],data['lat'],data['temp'][i,...],xr,yr,extrap=True) except: pass try: SALT[i,...] = calc.griddata(data['lon'],data['lat'],data['salt'][i,...],xr,yr,extrap=True) except: pass try: U[i,...] = calc.griddata(data['lon'],data['lat'],data['u'][i,...],xr,yr,extrap=True) except: pass try: V[i,...] = calc.griddata(data['lon'],data['lat'],data['v'][i,...],xr,yr,extrap=True) except: pass # rotate U,V: if not quiet: print 'rotating U,V to grid angle' angle=g.use('angle') # rad U,V=calc.rot2d(U,V,angle) U=rt.rho2uvp3d(U,'u') V=rt.rho2uvp3d(V,'v') horizAux={} horizAux['TEMP'] = TEMP horizAux['SALT'] = SALT horizAux['U'] = U horizAux['V'] = V else: TEMP = horizAux['TEMP'] SALT = horizAux['SALT'] U = horizAux['U'] V = horizAux['V'] # interp vert: nxu=nx-1 nyv=ny-1 #> ----------------------------------------------------------------- useInd=not ij_ind is False if ij_ind is False: if ij=='j': ij_ind=range(ny) elif ij=='i': ij_ind=range(nx) else: try: iter(ij_ind) except: ij_ind=[ij_ind] if ij=='j': ny=nyv=len(ij_ind) elif ij=='i': nx=nxu=len(ij_ind) # -----------------------------------------------------------------< Temp = np.zeros((nz,ny ,nx ),data['temp'].dtype) Salt = np.zeros((nz,ny ,nx ),data['salt'].dtype) Uvel = np.zeros((nz,ny ,nxu),data['u'].dtype) Vvel = np.zeros((nz,nyv,nx ),data['v'].dtype) jslice=lambda x,ind: x[:,ind,:] islice=lambda x,ind: x[:,:,ind] ZZr = np.tile(data['depth'],(nx,ny,1)).T ZZu = np.tile(data['depth'],(nxu,ny,1)).T ZZv = np.tile(data['depth'],(nx,nyv,1)).T if not useInd is False: #>------------------------------------------ if ij=='j': slice=jslice sshr=sshr[ij_ind,:] hr =hr[ij_ind,:] elif ij=='i': slice=islice sshr=sshr[:,ij_ind] hr =hr[:,ij_ind] Zr,Zu,Zv,TEMP,SALT,U,V=[slice(k,ij_ind) for k in [Zr,Zu,Zv,TEMP,SALT,U,V]] # -----------------------------------------------------------------< if useInd: # then store distances for a possible bry file dtype=Temp.dtype distr=np.zeros((nz,ny, nx ),dtype) distu=np.zeros((nz,ny, nxu),dtype) distv=np.zeros((nz,nyv,nx ),dtype) if not quiet: print 'vertical interpolation:' if ij=='j': for j in range(ny): if not quiet and (ny<10 or (ny>=10 and j%10==0)): print ' j=%3d of %3d' % (j,ny) ind=ij_ind[j] dr=np.tile(calc.distance(xr[ind,:],yr[ind,:]),(nz,1)) du=np.tile(calc.distance(xu[ind,:],yu[ind,:]),(nz,1)) Dr=np.tile(calc.distance(xr[ind,:],yr[ind,:]),(NZ,1)) Du=np.tile(calc.distance(xu[ind,:],yu[ind,:]),(NZ,1)) if useInd: distr[:,j,:]=dr; distu[:,j,:]=du; Temp[:,j,:] = calc.griddata(Dr,ZZr[:,j,:],TEMP[:,j,:],dr,Zr[:,j,:],extrap=True) Salt[:,j,:] = calc.griddata(Dr,ZZr[:,j,:],SALT[:,j,:],dr,Zr[:,j,:],extrap=True) if 0 and j%10==0: print Dr.shape, ZZr[:,j,:].shape import pylab as pl pl.figure(1) pl.clf() pl.pcolormesh(Dr,ZZr[:,j,:],SALT[:,j,:]) pl.colorbar() clim=pl.gci().get_clim() pl.figure(2) pl.clf() pl.pcolormesh(dr,Zr[:,j,:],Salt[:,j,:]) pl.clim(clim) pl.colorbar() raw_input() Uvel[:,j,:] = calc.griddata(Du,ZZu[:,j,:],U[:,j,:], du,Zu[:,j,:],extrap=True) if j<Vvel.shape[1]: dv=np.tile(calc.distance(xv[ind,:],yv[ind,:]),(nz,1)) Dv=np.tile(calc.distance(xv[ind,:],yv[ind,:]),(NZ,1)) Vvel[:,j,:] = calc.griddata(Dv,ZZv[:,j,:],V[:,j,:], dv,Zv[:,j,:],extrap=True) if useInd: distv[:,j,:]=dv if np.any(np.isnan(Temp[:,j,:])): print 'found nan in temp',j if np.any(np.isnan(Salt[:,j,:])): print 'found nan in salt',j if np.any(np.isnan(Uvel[:,j,:])): print 'found nan in u',j if j<Vvel.shape[1] and np.any(np.isnan(Vvel[:,j,:])): print 'found nan in v',j elif ij=='i': for i in range(nx): if not quiet and (nx<10 or (nx>=10 and i%10==0)): print ' i=%3d of %3d' % (i,nx) ind=ij_ind[i] dr=np.tile(calc.distance(xr[:,ind],yr[:,ind]),(nz,1)) dv=np.tile(calc.distance(xv[:,ind],yv[:,ind]),(nz,1)) Dr=np.tile(calc.distance(xr[:,ind],yr[:,ind]),(NZ,1)) Dv=np.tile(calc.distance(xv[:,ind],yv[:,ind]),(NZ,1)) if useInd: distr[:,:,i]=dr; distv[:,:,i]=dv; Temp[:,:,i] = calc.griddata(Dr,ZZr[:,:,i],TEMP[:,:,i],dr,Zr[:,:,i],extrap=True) Salt[:,:,i] = calc.griddata(Dr,ZZr[:,:,i],SALT[:,:,i],dr,Zr[:,:,i],extrap=True) Vvel[:,:,i] = calc.griddata(Dv,ZZv[:,:,i],V[:,:,i], dv,Zv[:,:,i],extrap=True) if i<Uvel.shape[2]: du=np.tile(calc.distance(xu[:,ind],yu[:,ind]),(nz,1)) Du=np.tile(calc.distance(xu[:,ind],yu[:,ind]),(NZ,1)) Uvel[:,:,i] = calc.griddata(Du,ZZu[:,:,i],U[:,:,i], du,Zu[:,:,i],extrap=True) if useInd: distu[:,:,i]=du # uv bar: if not quiet: print 'calc uvbar' if useInd is False: ubar,vbar=rt.uvbar(Uvel,Vvel,sshr,hr,sparams) else: #>------------------------------------------------------------ sshu=calc.griddata(data['lon'],data['lat'],data['ssh'],xu,yu,extrap=True) sshv=calc.griddata(data['lon'],data['lat'],data['ssh'],xv,yv,extrap=True) if ij=='j': sshu=sshu[ij_ind,:] sshv=sshv[ij_ind,:] hu =hu[ij_ind,:] hv =hv[ij_ind,:] elif ij=='i': sshu=sshu[:,ij_ind] sshv=sshv[:,ij_ind] hu =hu[:,ij_ind] hv =hv[:,ij_ind] ubar=rt.barotropic(Uvel,sshu,hu,sparams) vbar=rt.barotropic(Vvel,sshv,hv,sparams) # -----------------------------------------------------------------< Vars=cb.odict() Vars['temp'] = Temp Vars['salt'] = Salt Vars['u'] = Uvel Vars['v'] = Vvel Vars['zeta'] = sshr Vars['ubar'] = ubar Vars['vbar'] = vbar Vars['date'] = data['date'] if not useInd is False: #>------------------------------------------ Vars['depth'] = Zr Vars['depthu'] = Zu Vars['depthv'] = Zv Vars['dist'] = distr Vars['distu'] = distu Vars['distv'] = distv # -----------------------------------------------------------------< if retHorizAux: return Vars, horizAux else: return Vars
def data2roms(data, grd, sparams, **kargs): ''' Interpolates data to roms 3D grid. The dict data must contain the prognostic variables temp, salt, u, v (3d) and ssh (zeta, 2d), as well as lon, lat (2d), depth (1d) and time/date info: date (data date), date0 (reference date) and time (difference between date and date0). The input data can be provided by load_data. Parameters ---------- data : dict with prognostic variables grd : ROMS netcdf grid file sparams : s-coordinates parameters, theta_s,theta_b, hc and NLevels **kargs: ij : axis for vertical interpolations (*i,j) ij_ind : list of i or j index for vertical interpolation, all by default (ij_ind=False) horizAux : if True, the original data horizontally interpolated is returned and can be used for next data2roms call with this same karg quiet : output messages flag (false by default) ''' ij = 'j' ij_ind = False horizAux = False quiet = False if 'ij' in kargs.keys(): ij = kargs['ij'] if 'ij_ind' in kargs.keys(): ij_ind = kargs['ij_ind'] if 'horizAux' in kargs.keys(): horizAux = kargs['horizAux'] if 'quiet' in kargs.keys(): quiet = kargs['quiet'] if not quiet: print 'using grid %s' % grd g = roms.Grid(grd) xr, yr, hr, mr = g.vars('r') xu, yu, hu, mu = g.vars('u') xv, yv, hv, mv = g.vars('v') ny, nx = hr.shape nz = sparams[3] NX = data['NX'] NY = data['NY'] NZ = data['NZ'] if not quiet: print 'calc s levels...' sshr = calc.griddata(data['lon'], data['lat'], data['ssh'], xr, yr, extrap=True) Zr = g.s_levels(sparams, sshr, hr, 'r') Zu = g.s_levels(sparams, sshr, hr, 'u') Zv = g.s_levels(sparams, sshr, hr, 'v') # interp horiz: retHorizAux = horizAux is True if horizAux in (True, False): TEMP = np.ma.masked_all((NZ, ny, nx), data['temp'].dtype) SALT = np.ma.masked_all((NZ, ny, nx), data['salt'].dtype) U = np.ma.masked_all((NZ, ny, nx), data['u'].dtype) V = np.ma.masked_all((NZ, ny, nx), data['v'].dtype) if not quiet: print 'horizontal interpolation:' for i in range(NZ): if not quiet and i % 10 == 0: print ' lev %d of %d' % (i, NZ) #import pylab #pylab.figure() #pylab.pcolormesh(data['lon'],data['lat'],data['temp'][i,...]) try: TEMP[i, ...] = calc.griddata(data['lon'], data['lat'], data['temp'][i, ...], xr, yr, extrap=True) except: pass try: SALT[i, ...] = calc.griddata(data['lon'], data['lat'], data['salt'][i, ...], xr, yr, extrap=True) except: pass try: U[i, ...] = calc.griddata(data['lon'], data['lat'], data['u'][i, ...], xr, yr, extrap=True) except: pass try: V[i, ...] = calc.griddata(data['lon'], data['lat'], data['v'][i, ...], xr, yr, extrap=True) except: pass # rotate U,V: if not quiet: print 'rotating U,V to grid angle' angle = g.use('angle') # rad U, V = calc.rot2d(U, V, angle) U = rt.rho2uvp3d(U, 'u') V = rt.rho2uvp3d(V, 'v') horizAux = {} horizAux['TEMP'] = TEMP horizAux['SALT'] = SALT horizAux['U'] = U horizAux['V'] = V else: TEMP = horizAux['TEMP'] SALT = horizAux['SALT'] U = horizAux['U'] V = horizAux['V'] # interp vert: nxu = nx - 1 nyv = ny - 1 #> ----------------------------------------------------------------- useInd = not ij_ind is False if ij_ind is False: if ij == 'j': ij_ind = range(ny) elif ij == 'i': ij_ind = range(nx) else: try: iter(ij_ind) except: ij_ind = [ij_ind] if ij == 'j': ny = nyv = len(ij_ind) elif ij == 'i': nx = nxu = len(ij_ind) # -----------------------------------------------------------------< Temp = np.zeros((nz, ny, nx), data['temp'].dtype) Salt = np.zeros((nz, ny, nx), data['salt'].dtype) Uvel = np.zeros((nz, ny, nxu), data['u'].dtype) Vvel = np.zeros((nz, nyv, nx), data['v'].dtype) jslice = lambda x, ind: x[:, ind, :] islice = lambda x, ind: x[:, :, ind] ZZr = np.tile(data['depth'], (nx, ny, 1)).T ZZu = np.tile(data['depth'], (nxu, ny, 1)).T ZZv = np.tile(data['depth'], (nx, nyv, 1)).T if not useInd is False: #>------------------------------------------ if ij == 'j': slice = jslice sshr = sshr[ij_ind, :] hr = hr[ij_ind, :] elif ij == 'i': slice = islice sshr = sshr[:, ij_ind] hr = hr[:, ij_ind] Zr, Zu, Zv, TEMP, SALT, U, V = [ slice(k, ij_ind) for k in [Zr, Zu, Zv, TEMP, SALT, U, V] ] # -----------------------------------------------------------------< if useInd: # then store distances for a possible bry file dtype = Temp.dtype distr = np.zeros((nz, ny, nx), dtype) distu = np.zeros((nz, ny, nxu), dtype) distv = np.zeros((nz, nyv, nx), dtype) if not quiet: print 'vertical interpolation:' if ij == 'j': for j in range(ny): if not quiet and (ny < 10 or (ny >= 10 and j % 10 == 0)): print ' j=%3d of %3d' % (j, ny) ind = ij_ind[j] dr = np.tile(calc.distance(xr[ind, :], yr[ind, :]), (nz, 1)) du = np.tile(calc.distance(xu[ind, :], yu[ind, :]), (nz, 1)) Dr = np.tile(calc.distance(xr[ind, :], yr[ind, :]), (NZ, 1)) Du = np.tile(calc.distance(xu[ind, :], yu[ind, :]), (NZ, 1)) if useInd: distr[:, j, :] = dr distu[:, j, :] = du Temp[:, j, :] = calc.griddata(Dr, ZZr[:, j, :], TEMP[:, j, :], dr, Zr[:, j, :], extrap=True) Salt[:, j, :] = calc.griddata(Dr, ZZr[:, j, :], SALT[:, j, :], dr, Zr[:, j, :], extrap=True) if 0 and j % 10 == 0: print Dr.shape, ZZr[:, j, :].shape import pylab as pl pl.figure(1) pl.clf() pl.pcolormesh(Dr, ZZr[:, j, :], SALT[:, j, :]) pl.colorbar() clim = pl.gci().get_clim() pl.figure(2) pl.clf() pl.pcolormesh(dr, Zr[:, j, :], Salt[:, j, :]) pl.clim(clim) pl.colorbar() raw_input() Uvel[:, j, :] = calc.griddata(Du, ZZu[:, j, :], U[:, j, :], du, Zu[:, j, :], extrap=True) if j < Vvel.shape[1]: dv = np.tile(calc.distance(xv[ind, :], yv[ind, :]), (nz, 1)) Dv = np.tile(calc.distance(xv[ind, :], yv[ind, :]), (NZ, 1)) Vvel[:, j, :] = calc.griddata(Dv, ZZv[:, j, :], V[:, j, :], dv, Zv[:, j, :], extrap=True) if useInd: distv[:, j, :] = dv if np.any(np.isnan(Temp[:, j, :])): print 'found nan in temp', j if np.any(np.isnan(Salt[:, j, :])): print 'found nan in salt', j if np.any(np.isnan(Uvel[:, j, :])): print 'found nan in u', j if j < Vvel.shape[1] and np.any(np.isnan(Vvel[:, j, :])): print 'found nan in v', j elif ij == 'i': for i in range(nx): if not quiet and (nx < 10 or (nx >= 10 and i % 10 == 0)): print ' i=%3d of %3d' % (i, nx) ind = ij_ind[i] dr = np.tile(calc.distance(xr[:, ind], yr[:, ind]), (nz, 1)) dv = np.tile(calc.distance(xv[:, ind], yv[:, ind]), (nz, 1)) Dr = np.tile(calc.distance(xr[:, ind], yr[:, ind]), (NZ, 1)) Dv = np.tile(calc.distance(xv[:, ind], yv[:, ind]), (NZ, 1)) if useInd: distr[:, :, i] = dr distv[:, :, i] = dv Temp[:, :, i] = calc.griddata(Dr, ZZr[:, :, i], TEMP[:, :, i], dr, Zr[:, :, i], extrap=True) Salt[:, :, i] = calc.griddata(Dr, ZZr[:, :, i], SALT[:, :, i], dr, Zr[:, :, i], extrap=True) Vvel[:, :, i] = calc.griddata(Dv, ZZv[:, :, i], V[:, :, i], dv, Zv[:, :, i], extrap=True) if i < Uvel.shape[2]: du = np.tile(calc.distance(xu[:, ind], yu[:, ind]), (nz, 1)) Du = np.tile(calc.distance(xu[:, ind], yu[:, ind]), (NZ, 1)) Uvel[:, :, i] = calc.griddata(Du, ZZu[:, :, i], U[:, :, i], du, Zu[:, :, i], extrap=True) if useInd: distu[:, :, i] = du # uv bar: if not quiet: print 'calc uvbar' if useInd is False: ubar, vbar = rt.uvbar(Uvel, Vvel, sshr, hr, sparams) else: #>------------------------------------------------------------ sshu = calc.griddata(data['lon'], data['lat'], data['ssh'], xu, yu, extrap=True) sshv = calc.griddata(data['lon'], data['lat'], data['ssh'], xv, yv, extrap=True) if ij == 'j': sshu = sshu[ij_ind, :] sshv = sshv[ij_ind, :] hu = hu[ij_ind, :] hv = hv[ij_ind, :] elif ij == 'i': sshu = sshu[:, ij_ind] sshv = sshv[:, ij_ind] hu = hu[:, ij_ind] hv = hv[:, ij_ind] ubar = rt.barotropic(Uvel, sshu, hu, sparams) vbar = rt.barotropic(Vvel, sshv, hv, sparams) # -----------------------------------------------------------------< Vars = cb.odict() Vars['temp'] = Temp Vars['salt'] = Salt Vars['u'] = Uvel Vars['v'] = Vvel Vars['zeta'] = sshr Vars['ubar'] = ubar Vars['vbar'] = vbar Vars['date'] = data['date'] if not useInd is False: #>------------------------------------------ Vars['depth'] = Zr Vars['depthu'] = Zu Vars['depthv'] = Zv Vars['dist'] = distr Vars['distu'] = distu Vars['distv'] = distv # -----------------------------------------------------------------< if retHorizAux: return Vars, horizAux else: return Vars
def data2roms(data,grd,sparams,**kargs): ''' Interpolates data to roms 3D grid. The dict data must contain the prognostic variables temp, salt, u, v (3d) and ssh (zeta, 2d), as well as lon, lat (2d), depth (1d) and time/date info: date (data date), date0 (reference date) and time (difference between date and date0). The input data can be provided by load_data. Parameters ---------- data : dict with prognostic variables grd : ROMS netcdf grid file sparams : s-coordinates parameters, theta_s,theta_b, hc and NLevels **kargs: ij : axis for vertical interpolations (*i,j) ij_ind : list of i or j index for vertical interpolation, all by default (ij_ind=False) horizAux : if True, the original data horizontally interpolated is returned and can be used for next data2roms call with this same karg quiet : output messages flag (false by default) proj : projection - False, *auto* (use default grid projection) or basemap proj if False, horizontal interpolations will use lonxlat instead of distances interp_opts: options for griddata rep_surf: repeat surface level (new upper level) - If surface variables are present rep_surf must be True and for each variable (ex temp) will be used the surface variable (if present, ex ss_temp) instead of the upper layer. ''' ij = kargs.get('ij','j') ij_ind = kargs.get('ij_ind',False) horizAux = kargs.get('horizAux',False) quiet = kargs.get('quiet',False) proj = kargs.get('proj','auto') # lonxlat to distance before # horizontal interpolation interp_opts = kargs.get('interp_opts',{}) rep_surf = kargs.get('rep_surf',True) # create a surface upper level # before interpolation if not quiet: print('using grid %s' % grd) g=roms.Grid(grd) xr,yr,hr,mr=g.vars('r') xu,yu,hu,mu=g.vars('u') xv,yv,hv,mv=g.vars('v') ny,nx=hr.shape ny0,nx0=hr.shape nz=sparams[3] if proj=='auto': proj=g.get_projection() if proj: print('projecting coordinates...') xr,yr=proj(xr,yr) xu,yu=proj(xu,yu) xv,yv=proj(xv,yv) dlon,dlat=proj(data['lon'],data['lat']) Rdz=1/100. # distance to depth ratio (300km vs 3000m) distance=lambda x,y: np.append(0.,np.sqrt(np.diff(x)**2+np.diff(y)**2).cumsum()) else: dlon,dlat=data['lon'],data['lat'] Rdz=1. distance=calc.distance # needed for s_levels and for rep_surf! sshr=calc.griddata(dlon,dlat,data['ssh'],xr,yr,extrap=True,**interp_opts) # repeat surface: any_ssvar=False if rep_surf: # copy data cos dont want to change the original dataset: import copy data=copy.deepcopy(data) for vname in ['temp','salt','u','v','depth']: if data[vname].ndim==1: # depth ! if np.ma.isMA(data[vname]): vstack=np.ma.hstack else: vstack=np.hstack else: if np.ma.isMA(data[vname]): vstack=np.ma.vstack else: vstack=np.vstack ss_vname='ss_'+vname if ss_vname in data and not quiet: any_ssvar=True print('- using surface variable %s'%ss_vname) if data['depth'][0]>data['depth'][1]: # surf at ind 0 if ss_vname in data: data[vname]=vstack((data[ss_vname][np.newaxis],data[vname])) else: data[vname]=vstack((data[vname][0][np.newaxis],data[vname])) if vname=='depth': data[vname][0]=sshr.max() surf_ind=0 else: if ss_vname in data: data[vname]=vstack((data[vname],data[ss_vname][np.newaxis])) else: data[vname]=vstack((data[vname],data[vname][-1][np.newaxis])) if vname=='depth': data[vname][-1]=sshr.max() surf_ind=-1 data['NZ']=data['NZ']+1 NX=data['NX'] NY=data['NY'] NZ=data['NZ'] if not quiet: print('calc s levels...') Zr = g.s_levels(sparams,sshr,hr,'rr') Zu = g.s_levels(sparams,sshr,hr,'ur') Zv = g.s_levels(sparams,sshr,hr,'vr') # interp horiz: retHorizAux=horizAux is True if horizAux in (True,False): TEMP = np.ma.masked_all((NZ,ny,nx),data['temp'].dtype) SALT = np.ma.masked_all((NZ,ny,nx),data['salt'].dtype) U = np.ma.masked_all((NZ,ny,nx),data['u'].dtype) V = np.ma.masked_all((NZ,ny,nx),data['v'].dtype) if not quiet: print('horizontal interpolation:') for i in range(NZ): if not quiet and i%10==0: print(' lev %d of %d' % (i,NZ)) #import pylab #pylab.figure() #pylab.pcolormesh(data['lon'],data['lat'],data['temp'][i,...]) try: TEMP[i,...] = calc.griddata(dlon,dlat,data['temp'][i,...],xr,yr,extrap=True,**interp_opts) except: pass try: SALT[i,...] = calc.griddata(dlon,dlat,data['salt'][i,...],xr,yr,extrap=True,**interp_opts) except: pass try: U[i,...] = calc.griddata(dlon,dlat,data['u'][i,...],xr,yr,extrap=True,**interp_opts) except: pass try: V[i,...] = calc.griddata(dlon,dlat,data['v'][i,...],xr,yr,extrap=True,**interp_opts) except: pass # rotate U,V: if not quiet: print('rotating U,V to grid angle') U,V=calc.rot2d(U,V,g.angle) # g.angle in rad U=rt.rho2uvp3d(U,'u') V=rt.rho2uvp3d(V,'v') horizAux={} horizAux['TEMP'] = TEMP horizAux['SALT'] = SALT horizAux['U'] = U horizAux['V'] = V else: TEMP = horizAux['TEMP'] SALT = horizAux['SALT'] U = horizAux['U'] V = horizAux['V'] # interp vert: nxu=nx-1 nyv=ny-1 #> ----------------------------------------------------------------- useInd=not ij_ind is False if ij_ind is False: if ij=='j': ij_ind=range(ny) elif ij=='i': ij_ind=range(nx) else: try: iter(ij_ind) except: ij_ind=[ij_ind] if ij=='j': ny=nyv=len(ij_ind) elif ij=='i': nx=nxu=len(ij_ind) # -----------------------------------------------------------------< Temp = np.zeros((nz,ny ,nx ),data['temp'].dtype) Salt = np.zeros((nz,ny ,nx ),data['salt'].dtype) Uvel = np.zeros((nz,ny ,nxu),data['u'].dtype) Vvel = np.zeros((nz,nyv,nx ),data['v'].dtype) jslice=lambda x,ind: x[:,ind,:] islice=lambda x,ind: x[:,:,ind] if any_ssvar: ZZr = np.tile(data['depth'],(nx0,ny0,1)).T ZZu = np.tile(data['depth'],(nx0-1,ny0,1)).T ZZv = np.tile(data['depth'],(nx0,ny0-1,1)).T # replace 1st level by sea surface height! # instead of sshr.max(). This is at least slightly more correct, # and should be no problem for variables without surface counterpart. ZZr[surf_ind]=sshr ZZu[surf_ind]=(sshr[:,1:]+sshr[:,:-1])/2. ZZv[surf_ind]=(sshr[1:]+sshr[:-1])/2. else: ZZr = np.tile(data['depth'],(nx,ny,1)).T ZZu = np.tile(data['depth'],(nxu,ny,1)).T ZZv = np.tile(data['depth'],(nx,nyv,1)).T if not useInd is False: #>------------------------------------------ if ij=='j': slice=jslice sshr=sshr[ij_ind,:] hr =hr[ij_ind,:] elif ij=='i': slice=islice sshr=sshr[:,ij_ind] hr =hr[:,ij_ind] Zr,Zu,Zv,TEMP,SALT,U,V=[slice(k,ij_ind) for k in [Zr,Zu,Zv,TEMP,SALT,U,V]] if any_ssvar: ZZr,ZZu,ZZv=[slice(k,ij_ind) for k in [ZZr,ZZu,ZZv]] # -----------------------------------------------------------------< if useInd: # then store distances for a possible bry file dtype=Temp.dtype distr=np.zeros((nz,ny, nx ),dtype) distu=np.zeros((nz,ny, nxu),dtype) distv=np.zeros((nz,nyv,nx ),dtype) if not quiet: print('vertical interpolation:') if ij=='j': for j in range(ny): if not quiet and (ny<20 or (ny>=20 and j%20==0)): print(' j=%3d of %3d' % (j,ny)) ind=ij_ind[j] dr=np.tile(distance(xr[ind,:],yr[ind,:]),(nz,1)) du=np.tile(distance(xu[ind,:],yu[ind,:]),(nz,1)) Dr=np.tile(distance(xr[ind,:],yr[ind,:]),(NZ,1)) Du=np.tile(distance(xu[ind,:],yu[ind,:]),(NZ,1)) if useInd: distr[:,j,:]=dr; distu[:,j,:]=du; Temp[:,j,:] = calc.griddata(Rdz*Dr,ZZr[:,j,:],TEMP[:,j,:],Rdz*dr,Zr[:,j,:],extrap=True,**interp_opts) Salt[:,j,:] = calc.griddata(Rdz*Dr,ZZr[:,j,:],SALT[:,j,:],Rdz*dr,Zr[:,j,:],extrap=True,**interp_opts) if 0 and j%10==0: print(Dr.shape, ZZr[:,j,:].shape) import pylab as pl pl.figure(1) pl.clf() pl.pcolormesh(Dr,ZZr[:,j,:],TEMP[:,j,:]) pl.colorbar() clim=pl.gci().get_clim() pl.figure(2) pl.clf() pl.pcolormesh(dr,Zr[:,j,:],Temp[:,j,:]) pl.clim(clim) pl.colorbar() try: raw_input() except: input() # python 3 Uvel[:,j,:] = calc.griddata(Rdz*Du,ZZu[:,j,:],U[:,j,:], Rdz*du,Zu[:,j,:],extrap=True,**interp_opts) if j<Vvel.shape[1]: dv=np.tile(distance(xv[ind,:],yv[ind,:]),(nz,1)) Dv=np.tile(distance(xv[ind,:],yv[ind,:]),(NZ,1)) Vvel[:,j,:] = calc.griddata(Rdz*Dv,ZZv[:,j,:],V[:,j,:], Rdz*dv,Zv[:,j,:],extrap=True,**interp_opts) if useInd: distv[:,j,:]=dv if np.any(np.isnan(Temp[:,j,:])): print('found nan in temp',j) if np.any(np.isnan(Salt[:,j,:])): print('found nan in salt',j) if np.any(np.isnan(Uvel[:,j,:])): print('found nan in u',j) if j<Vvel.shape[1] and np.any(np.isnan(Vvel[:,j,:])): print('found nan in v',j) elif ij=='i': for i in range(nx): if not quiet and (nx<20 or (nx>=20 and i%20==0)): print(' i=%3d of %3d' % (i,nx)) ind=ij_ind[i] dr=np.tile(distance(xr[:,ind],yr[:,ind]),(nz,1)) dv=np.tile(distance(xv[:,ind],yv[:,ind]),(nz,1)) Dr=np.tile(distance(xr[:,ind],yr[:,ind]),(NZ,1)) Dv=np.tile(distance(xv[:,ind],yv[:,ind]),(NZ,1)) if useInd: distr[:,:,i]=dr; distv[:,:,i]=dv; Temp[:,:,i] = calc.griddata(Rdz*Dr,ZZr[:,:,i],TEMP[:,:,i],Rdz*dr,Zr[:,:,i],extrap=True,**interp_opts) Salt[:,:,i] = calc.griddata(Rdz*Dr,ZZr[:,:,i],SALT[:,:,i],Rdz*dr,Zr[:,:,i],extrap=True,**interp_opts) Vvel[:,:,i] = calc.griddata(Rdz*Dv,ZZv[:,:,i],V[:,:,i], Rdz*dv,Zv[:,:,i],extrap=True,**interp_opts) if i<Uvel.shape[2]: du=np.tile(distance(xu[:,ind],yu[:,ind]),(nz,1)) Du=np.tile(distance(xu[:,ind],yu[:,ind]),(NZ,1)) Uvel[:,:,i] = calc.griddata(Rdz*Du,ZZu[:,:,i],U[:,:,i], Rdz*du,Zu[:,:,i],extrap=True,**interp_opts) if useInd: distu[:,:,i]=du # uv bar: if not quiet: print('calc uvbar') if useInd is False: ubar,vbar=rt.uvbar(Uvel,Vvel,sshr,hr,sparams) else: #>------------------------------------------------------------ sshu=calc.griddata(dlon,dlat,data['ssh'],xu,yu,extrap=True,**interp_opts) sshv=calc.griddata(dlon,dlat,data['ssh'],xv,yv,extrap=True,**interp_opts) if ij=='j': sshu=sshu[ij_ind,:] sshv=sshv[ij_ind,:] hu =hu[ij_ind,:] hv =hv[ij_ind,:] elif ij=='i': sshu=sshu[:,ij_ind] sshv=sshv[:,ij_ind] hu =hu[:,ij_ind] hv =hv[:,ij_ind] ubar=rt.barotropic(Uvel,sshu,hu,sparams) vbar=rt.barotropic(Vvel,sshv,hv,sparams) # -----------------------------------------------------------------< #Vars=cb.odict() Vars=OrderedDict() Vars['temp'] = Temp Vars['salt'] = Salt Vars['u'] = Uvel Vars['v'] = Vvel Vars['zeta'] = sshr Vars['ubar'] = ubar Vars['vbar'] = vbar Vars['date'] = data['date'] if not useInd is False: #>------------------------------------------ Vars['depth'] = Zr Vars['depthu'] = Zu Vars['depthv'] = Zv Vars['dist'] = distr Vars['distu'] = distu Vars['distv'] = distv # -----------------------------------------------------------------< if retHorizAux: return Vars, horizAux else: return Vars
def data2z(data,**kargs): ''' Interpolates data dict defined at 3D vertical coordinate (like sigma levels or s-levels, for instance) to 1D depths (layers of z constant) data must contain all the fileds from load_data, z3d and the new depth, ie, data['depth'].ndim==1 **kargs: ij : axis for vertical interpolations (*i,j) quiet : output messages flag (True by default) rep_surf: repeat surface level, ie, add a new surface level with same data as the old surface. This will ensure extrapolations in vertical slices do not occur horizontally, ie, misture will occur in the vertical not along the slice (True by default) interp_opts: options for griddata ''' ij=kargs.get('ij','j') quiet=kargs.get('quiet',True) rep_surf=kargs.get('rep_surf',True) interp_opts=kargs.get('interp_opts',{}) # repeat surface: if rep_surf: for vname in ['z3d','temp','salt','u','v']: if np.ma.isMA(data[vname]): data[vname]=np.ma.vstack((data[vname],data[vname][-1][np.newaxis,...])) else: data[vname]=np.vstack((data[vname],data[vname][-1][np.newaxis,...])) data['z3d'][-1]=data['z3d'].max()+1 data['NZ']=data['NZ']+1 Z = data['depth'] # new depths 1D z = data['z3d'] # 3D depths nZ=len(Z) nz=data['NZ'] nx=data['NX'] ny=data['NY'] # lon, lat 2d: x0=data['lon'] y0=data['lat'] if x0.ndim==1:x0,y0 = np.meshgrid(x0,y0) # lon,lat 3d: x = np.tile(x0,(nz,1,1)) y = np.tile(y0,(nz,1,1)) xx = np.tile(x0,(nZ,1,1)) yy = np.tile(y0,(nZ,1,1)) # new z 3d: zz=np.tile(Z[:,np.newaxis,np.newaxis],(ny,nx)) # new data vars: Temp = np.ma.masked_all((nZ,ny,nx),data['temp'].dtype) Salt = np.ma.masked_all((nZ,ny,nx),data['salt'].dtype) U = np.ma.masked_all((nZ,ny,nx),data['u'].dtype) V = np.ma.masked_all((nZ,ny,nx),data['v'].dtype) if ij=='j': for j in range(ny): if not quiet and j%10==0: print('z interp (%d z levels) j=%d of %d' % (nZ,j,ny)) v=data['temp'][:,j,:] v=np.ma.masked_where(v==0,v) Temp[:,j,:]=calc.griddata(x[:,j,:],z[:,j,:],v,xx[:,j,:],zz[:,j,:],extrap=True,**interp_opts) v=data['salt'][:,j,:] v=np.ma.masked_where(v==0,v) Salt[:,j,:]=calc.griddata(x[:,j,:],z[:,j,:],v,xx[:,j,:],zz[:,j,:],extrap=True,**interp_opts) v=data['u'][:,j,:] v=np.ma.masked_where(v==0,v) U[:,j,:]=calc.griddata(x[:,j,:],z[:,j,:],v,xx[:,j,:],zz[:,j,:],extrap=True,**interp_opts) v=data['v'][:,j,:] v=np.ma.masked_where(v==0,v) V[:,j,:]=calc.griddata(x[:,j,:],z[:,j,:],v,xx[:,j,:],zz[:,j,:],extrap=True,**interp_opts) elif ij=='i': for i in range(nx): if not quiet and i%10==0: print('z interp (%d z levels) i=%d of %d' % (nZ,i,nx)) v=data['temp'][:,:,i] v=np.ma.masked_where(v==0,v) Temp[:,:,i]=calc.griddata(y[:,:,i],z[:,:,i],v,yy[:,:,i],zz[:,:,i],extrap=True,**interp_opts) v=data['salt'][:,:,i] v=np.ma.masked_where(v==0,v) Salt[:,:,i]=calc.griddata(y[:,:,i],z[:,:,i],v,yy[:,:,i],zz[:,:,i],extrap=True,**interp_opts) v=data['u'][:,:,i] v=np.ma.masked_where(v==0,v) U[:,:,i]=calc.griddata(y[:,:,i],z[:,:,i],v,yy[:,:,i],zz[:,:,i],extrap=True,**interp_opts) v=data['v'][:,:,i] v=np.ma.masked_where(v==0,v) V[:,:,i]=calc.griddata(y[:,:,i],z[:,:,i],v,yy[:,:,i],zz[:,:,i],extrap=True,**interp_opts) res = data.copy() res['temp'] = Temp res['salt'] = Salt res['u'] = U res['v'] = V res['NZ'] = nZ res.pop('z3d') return res
def slicell(self,varname,X,Y,time=0,**opts): coords=opts.get('coords',self._default_coords('slicell')).split(',') data = opts.get('data',False) extrap = opts.get('extrap',False) maskLimit = opts.get('lmask',0.5) # points where interpolated mask are above # this value are considered as mask! # Most strict value is 0 out=Data() out.msg=self.check_slice(varname,t=time) if out.msg: return out#None,aux X=np.asarray(X) Y=np.asarray(Y) if X.ndim>1: X=np.squeeze(X) if Y.ndim>1: Y=np.squeeze(X) x,y,h,m=self.grid.vars(ruvp=self.var_at(varname)[0]) if True: # extrat only portion of data needed: i0,i1,j0,j1=calc.ij_limits(x, y, (X.min(),X.max()),(Y.min(),Y.max()), margin=1) xi='%d:%d'%(i0,i1) eta='%d:%d'%(j0,j1) if data is False: V=self.use(varname,SEARCHtime=time,xi_SEARCH=xi,eta_SEARCH=eta) else: v=data[...,j0:j1,i0:i1] x=x[j0:j1,i0:i1] y=y[j0:j1,i0:i1] #h=h[j0:j1,i0:i1] # not used m=m[j0:j1,i0:i1] else: if data is False: V=self.use(varname,SEARCHtime=time) else: v=data if V.ndim==3: v=calc.griddata(x,y,V,X,Y,extrap=extrap,mask2d=m==0, keepMaskVal=maskLimit) elif V.ndim==2: v=calc.griddata(x,y,np.ma.masked_where(m==0,V),X,Y,extrap=extrap, keepMaskVal=maskLimit) out.v=v out.info['v']['name']=varname out.info['v']['slice']='path npts=%d'%X.size try: out.info['v']['units']=netcdf.vatt(self.nc,varname,'units') except: pass # coords: if 'z' in coords and V.ndim==3: inds=dict(xi=(i0,i1),eta=(j0,j1)) ######### out.z=self.path_s_levels(time,X,Y,rw=varname[0],inds=inds) out.z=self.path_s_levels(time,X,Y,rw=self.var_at(varname)[1],inds=inds) if 'd' in coords: d=calc.distance(X,Y) if v.ndim==2: d=np.tile(d,(v.shape[0],1)) out.d=d if 'x' in coords: if v.ndim==2: X=np.tile(X,(v.shape[0],1)) out.x=X if 'y' in coords: if v.ndim==2: Y=np.tile(Y,(v.shape[0],1)) out.y=Y if 't' in coords and self.hast(varname): out.t=self.time[time] out.coordsReq=','.join(sorted(coords)) return out
def cfsr_file_data(files,quiet=False): ''' Returns bulk data from one CFRS files ''' def load_time(f): time=np.array((),datetime.datetime) ff=glob.glob(f) ff.sort() for f in ff: time=np.append(time,netcdf.nctime(f,'time')) return time def load_time_main(f): time=load_time(f) # I want 0,6,12,... after 2006 results may be 3,9,15, ... if time[0].hour in [3,9,15,21]: time=time+datetime.timedelta(hours=3) # for 2011 1st time is not 0! if time[0].hour==6: time=np.hstack((time[0].replace(hour=0),time)) return time def fix_time(t,var,t0,t1): # convert 1h, 7h, ... to 0h, 6h, ... if t[0].hour in [1,7,13,19]: # not all! sp analysis starts at 0, 6,...! print(' 1,7,... to 0,6,...') var=(var[1:]*5+var[:-1]*1)/6. t=t[1:]-datetime.timedelta(hours=1) elif t[0].hour in [3,9,15,21]: print(' 3,9,... to 0,6,...') var=(var[1:]*3+var[:-1]*3)/6. t=t[1:]-datetime.timedelta(hours=3) cond=(t>=t0)&(t<=t1) t=t[cond] var=var[cond] if t[0]>t0: dt=t[0]-t0 dt=dt.days*24+dt.seconds/3600. # hours print('missing data at start: %.2d h missing --> repeating 1st data'%dt) v=np.zeros((var.shape[0]+1,)+var.shape[1:],var.dtype) v[1:]=var v[0]=var[0] var=v t_=np.zeros((t.shape[0]+1,)+t.shape[1:],t.dtype) t_[1:]=t t_[0]=t0 t=t_ if t[-1]<t1: dt=t1-t[-1] dt=dt.days*24+dt.seconds/3600. # hours print('missing data at end: %.2d h missing --> repeating last data'%dt) v=np.zeros((var.shape[0]+1,)+var.shape[1:],var.dtype) v[:-1]=var v[-1]=var[-1] var=v t_=np.zeros((t.shape[0]+1,)+t.shape[1:],t.dtype) t_[:-1]=t t_[-1]=t1 t=t_ return var,t out={} # time: if 0: time=netcdf.nctime(files['cc'],'time') # files have diff units !! so, cannot load all times at once! # these result will use only units of 1st file!! else: time=load_time_main(files['cc']) out['time']=time # T air [K->C] if not quiet: print(' --> T air') f=files['st'] tair=netcdf.use(f,'TMP_L103') tair=tair-273.15 x=netcdf.use(f,'lon'); x[x>180]=x[x>180]-360 y=netcdf.use(f,'lat') x,y=np.meshgrid(x,y) # check time: ttmp=load_time(f) if ttmp.size==time.size and np.all(ttmp==time): print(' time ok') else: print(' time differs !!!!',) tair,tfix=fix_time(ttmp,tair,time[0],time[-1]) if tfix.size==time.size and np.all(tfix==time): print(' ...fixed!') else: print('time is NOT OK. Please check !!') return out['tair']=Data(x,y,tair,'C') # R humidity [%-->0--1] if not quiet: print(' --> R humidity') f=files['rh'] rhum=netcdf.use(f,'R_H_L103') rhum=rhum/100. x=netcdf.use(f,'lon'); x[x>180]=x[x>180]-360 y=netcdf.use(f,'lat') x,y=np.meshgrid(x,y) # check time: ttmp=load_time(f) if ttmp.size==time.size and np.all(ttmp==time): print(' time ok') else: print(' time differs !!!!'), # should use end=' ' for python3 print continuation rhum,tfix=fix_time(ttmp,rhum,time[0],time[-1]) if tfix.size==time.size and np.all(tfix==time): print(' ...fixed!') else: print('time is NOT OK. Please check !!') return out['rhum']=Data(x,y,rhum,'0--1') # surface pressure [Pa] if not quiet: print(' --> Surface pressure') f=files['sp'] pres=netcdf.use(f,'PRES_L1') x=netcdf.use(f,'lon'); x[x>180]=x[x>180]-360 y=netcdf.use(f,'lat') x,y=np.meshgrid(x,y) # check time: ttmp=load_time(f) if ttmp.size==time.size and np.all(ttmp==time): print(' time ok') else: print(' time differs !!!!'), pres,tfix=fix_time(ttmp,pres,time[0],time[-1]) if tfix.size==time.size and np.all(tfix==time): print(' ...fixed!') else: print('time is NOT OK. Please check !!') return out['pres']=Data(x,y,pres,'Pa') # P rate [kg m-2 s-1 -> cm/d] if not quiet: print(' --> P rate') f=files['pr'] if 'PRATE_L1' in netcdf.varnames(f): prate=netcdf.use(f,'PRATE_L1') else: prate=netcdf.use(f,'PRATE_L1_Avg_1') x=netcdf.use(f,'lon'); x[x>180]=x[x>180]-360 y=netcdf.use(f,'lat') x,y=np.meshgrid(x,y) # Conversion kg m^-2 s^-1 to cm/day prate=prate*86400*100/1000. prate=np.where(abs(prate)<1.e-4,0,prate) # check time: ttmp=load_time(f) if ttmp.size==time.size and np.all(ttmp==time): print(' time ok') else: print(' time differs !!!!'), prate,tfix=fix_time(ttmp,prate,time[0],time[-1]) if tfix.size==time.size and np.all(tfix==time): print(' ...fixed!') else: print('time is NOT OK. Please check !!') return out['prate']=Data(x,y,prate,'cm/d') # Net shortwave flux [W/m^2] if not quiet: print(' --> Net shortwave flux') if not quiet: print(' SW down') f=files['rad'] sw_down=netcdf.use(f,'DSWRF_L1_Avg_1') x=netcdf.use(f,'lon'); x[x>180]=x[x>180]-360 y=netcdf.use(f,'lat') x,y=np.meshgrid(x,y) if not quiet: print(' SW up') sw_up=netcdf.use(f,'USWRF_L1_Avg_1') sw_net=sw_down-sw_up sw_net=np.where(sw_net<1.e-10,0,sw_net) # check time: ttmp=load_time(f) if ttmp.size==time.size and np.all(ttmp==time): print(' time ok') else: print(' time differs !!!!'), sw_net,tfix=fix_time(ttmp,sw_net,time[0],time[-1]) if tfix.size==time.size and np.all(tfix==time): print(' ...fixed!') else: print('time is NOT OK. Please check !!') return out['radsw']=Data(x,y,sw_net,'W m-2',info='positive downward') # Net longwave flux [W/m^2] if not quiet: print(' --> Net longwave flux') if not quiet: print(' LW down') f=files['rad'] lw_down=netcdf.use(f,'DLWRF_L1_Avg_1') x=netcdf.use(f,'lon'); x[x>180]=x[x>180]-360 y=netcdf.use(f,'lat') x,y=np.meshgrid(x,y) if not quiet: print(' LW up') lw_up=netcdf.use(f,'ULWRF_L1_Avg_1') lw_net=lw_down-lw_up lw_net=np.where(np.abs(lw_net)<1.e-10,0,lw_net) # check time: ttmp=load_time(f) if ttmp.size==time.size and np.all(ttmp==time): print(' time ok') else: print(' time differs !!!!'), lw_net,tfix1=fix_time(ttmp,lw_net,time[0],time[-1]) lw_down,tfix2=fix_time(ttmp,lw_down,time[0],time[-1]) if tfix1.size==tfix2.size==time.size and np.all((tfix1==time)&(tfix2==time)): print(' ...fixed!') else: print('time is NOT OK. Please check !!') return # ROMS (agrif, used to be!) convention: positive upward out['radlw']=Data(x,y,-lw_net,'W m-2',info='positive upward') # downward lw: out['dlwrf']=Data(x,y,-lw_down,'W m-2',info='negative... downward') # signs convention is better explained in wrf.py # U and V wind speed 10m if not quiet: print(' --> U and V wind') f=files['uv'] uwnd=netcdf.use(f,'U_GRD_L103') vwnd=netcdf.use(f,'V_GRD_L103') x=netcdf.use(f,'lon'); x[x>180]=x[x>180]-360 y=netcdf.use(f,'lat') x,y=np.meshgrid(x,y) # check time: ttmp=load_time(f) if ttmp.size==time.size and np.all(ttmp==time): print(' time ok') else: print(' time differs !!!!'), uwnd,tfix1=fix_time(ttmp,uwnd,time[0],time[-1]) vwnd,tfix2=fix_time(ttmp,vwnd,time[0],time[-1]) if tfix1.size==tfix2.size==time.size and np.all((tfix1==time)&(tfix2==time)): print(' ...fixed!') else: print('time is NOT OK. Please check !!') return # if not quiet: print(' --> calc wind speed and stress') speed = np.sqrt(uwnd**2+vwnd**2) taux,tauy=air_sea.wind_stress(uwnd,vwnd) out['wspd']=Data(x,y,speed,'m s-1') out['uwnd']=Data(x,y,uwnd,'m s-1') out['vwnd']=Data(x,y,vwnd,'m s-1') out['sustr']=Data(x,y,taux,'Pa') out['svstr']=Data(x,y,tauy,'Pa') # Cloud cover [0--100 --> 0--1]: if not quiet: print(' --> Cloud cover') f=files['cc'] if 'T_CDC_L200' in netcdf.varnames(f): clouds=netcdf.use(f,'T_CDC_L200') else: clouds=netcdf.use(f,'T_CDC_L200_Avg_1') x=netcdf.use(f,'lon'); x[x>180]=x[x>180]-360 y=netcdf.use(f,'lat') x,y=np.meshgrid(x,y) clouds=clouds/100. # check time: ttmp=load_time(f) if ttmp.size==time.size and np.all(ttmp==time): print(' time ok') else: print(' time differs !!!!'), clouds,tfix=fix_time(ttmp,clouds,time[0],time[-1]) if tfix.size==time.size and np.all(tfix==time): print(' ...fixed!') else: print('time is NOT OK. Please check !!') return out['cloud']=Data(x,y,clouds,'fraction (0--1)') # rhum has different resolution (0.5, just like dew point!) # so, i can edit surface.py or just interpolate here rhum to # other vars resolution: if out['rhum'].data.shape!=out['uwnd'].data.shape: from okean import calc print('rhum shape differs!! --> interp:') nt,ny,nx=out['uwnd'].data.shape x,y=out['uwnd'].x,out['uwnd'].y rhum=np.zeros((nt,ny,nx), out['rhum'].data.dtype) for it in range(nt): if it%100==0: print(' %d of %d'%(it,nt)) rhum[it]=calc.griddata(out['rhum'].x,out['rhum'].y,out['rhum'].data[it],x,y) out['rhum']=Data(x,y,rhum,'0--1') return out
def data2roms(data, grd, sparams, **kargs): ''' Interpolates data to roms 3D grid. The dict data must contain the prognostic variables temp, salt, u, v (3d) and ssh (zeta, 2d), as well as lon, lat (2d), depth (1d) and time/date info: date (data date), date0 (reference date) and time (difference between date and date0). The input data can be provided by load_data. Parameters ---------- data : dict with prognostic variables grd : ROMS netcdf grid file sparams : s-coordinates parameters, theta_s,theta_b, hc and NLevels **kargs: ij : axis for vertical interpolations (*i,j) ij_ind : list of i or j index for vertical interpolation, all by default (ij_ind=False) horizAux : if True, the original data horizontally interpolated is returned and can be used for next data2roms call with this same karg quiet : output messages flag (false by default) proj : projection - False, name or basemap proj - lcc by default if False, horizontal interpolations will use lonxlat instead of distances interp_opts: options for griddata rep_surf: repeat surface level (new upper level) ''' ij = kargs.get('ij', 'j') ij_ind = kargs.get('ij_ind', False) horizAux = kargs.get('horizAux', False) quiet = kargs.get('quiet', False) proj = kargs.get('proj', 'lcc') # lonxlat to distance before # horizontal interpolation interp_opts = kargs.get('interp_opts', {}) rep_surf = kargs.get('rep_surf', True) # create a surface upper level # before interpolation if not quiet: print 'using grid %s' % grd g = roms.Grid(grd) xr, yr, hr, mr = g.vars('r') xu, yu, hu, mu = g.vars('u') xv, yv, hv, mv = g.vars('v') ny, nx = hr.shape nz = sparams[3] if proj: print 'projecting coordinates...' if isinstance(proj, basestring): lonc = (xr.max() + xr.min()) / 2. latc = (yr.max() + yr.min()) / 2. from mpl_toolkits.basemap import Basemap proj = Basemap(projection=proj, width=1, height=1, resolution=None, lon_0=lonc, lat_0=latc, lat_1=latc) xr, yr = proj(xr, yr) xu, yu = proj(xu, yu) xv, yv = proj(xv, yv) dlon, dlat = proj(data['lon'], data['lat']) Rdz = 1 / 100. # distance to depth ratio (300km vs 3000m) distance = lambda x, y: np.append( 0., np.sqrt(np.diff(x)**2 + np.diff(y)**2).cumsum()) else: dlon, dlat = data['lon'], data['lat'] distance = calc.distance # needed for s_levels and for rep_surf! sshr = calc.griddata(dlon, dlat, data['ssh'], xr, yr, extrap=True, **interp_opts) # repeat surface: if rep_surf: # copy data cos dont want to change the original dataset: import copy data = copy.deepcopy(data) for vname in ['temp', 'salt', 'u', 'v', 'depth']: if data[vname].ndim == 1: # depth ! if np.ma.isMA(data[vname]): vstack = np.ma.hstack else: vstack = np.hstack else: if np.ma.isMA(data[vname]): vstack = np.ma.vstack else: vstack = np.vstack if data['depth'][0] > data['depth'][1]: # surf at ind 0 data[vname] = vstack((data[vname][0][np.newaxis], data[vname])) if vname == 'depth': data[vname][0] = sshr.max() else: data[vname] = vstack( (data[vname], data[vname][-1][np.newaxis])) if vname == 'depth': data[vname][-1] = sshr.max() data['NZ'] = data['NZ'] + 1 NX = data['NX'] NY = data['NY'] NZ = data['NZ'] if not quiet: print 'calc s levels...' Zr = g.s_levels(sparams, sshr, hr, 'r') Zu = g.s_levels(sparams, sshr, hr, 'u') Zv = g.s_levels(sparams, sshr, hr, 'v') # interp horiz: retHorizAux = horizAux is True if horizAux in (True, False): TEMP = np.ma.masked_all((NZ, ny, nx), data['temp'].dtype) SALT = np.ma.masked_all((NZ, ny, nx), data['salt'].dtype) U = np.ma.masked_all((NZ, ny, nx), data['u'].dtype) V = np.ma.masked_all((NZ, ny, nx), data['v'].dtype) if not quiet: print 'horizontal interpolation:' for i in range(NZ): if not quiet and i % 10 == 0: print ' lev %d of %d' % (i, NZ) #import pylab #pylab.figure() #pylab.pcolormesh(data['lon'],data['lat'],data['temp'][i,...]) try: TEMP[i, ...] = calc.griddata(dlon, dlat, data['temp'][i, ...], xr, yr, extrap=True, **interp_opts) except: pass try: SALT[i, ...] = calc.griddata(dlon, dlat, data['salt'][i, ...], xr, yr, extrap=True, **interp_opts) except: pass try: U[i, ...] = calc.griddata(dlon, dlat, data['u'][i, ...], xr, yr, extrap=True, **interp_opts) except: pass try: V[i, ...] = calc.griddata(dlon, dlat, data['v'][i, ...], xr, yr, extrap=True, **interp_opts) except: pass # rotate U,V: if not quiet: print 'rotating U,V to grid angle' angle = g.use('angle') # rad U, V = calc.rot2d(U, V, angle) U = rt.rho2uvp3d(U, 'u') V = rt.rho2uvp3d(V, 'v') horizAux = {} horizAux['TEMP'] = TEMP horizAux['SALT'] = SALT horizAux['U'] = U horizAux['V'] = V else: TEMP = horizAux['TEMP'] SALT = horizAux['SALT'] U = horizAux['U'] V = horizAux['V'] # interp vert: nxu = nx - 1 nyv = ny - 1 #> ----------------------------------------------------------------- useInd = not ij_ind is False if ij_ind is False: if ij == 'j': ij_ind = range(ny) elif ij == 'i': ij_ind = range(nx) else: try: iter(ij_ind) except: ij_ind = [ij_ind] if ij == 'j': ny = nyv = len(ij_ind) elif ij == 'i': nx = nxu = len(ij_ind) # -----------------------------------------------------------------< Temp = np.zeros((nz, ny, nx), data['temp'].dtype) Salt = np.zeros((nz, ny, nx), data['salt'].dtype) Uvel = np.zeros((nz, ny, nxu), data['u'].dtype) Vvel = np.zeros((nz, nyv, nx), data['v'].dtype) jslice = lambda x, ind: x[:, ind, :] islice = lambda x, ind: x[:, :, ind] ZZr = np.tile(data['depth'], (nx, ny, 1)).T ZZu = np.tile(data['depth'], (nxu, ny, 1)).T ZZv = np.tile(data['depth'], (nx, nyv, 1)).T if not useInd is False: #>------------------------------------------ if ij == 'j': slice = jslice sshr = sshr[ij_ind, :] hr = hr[ij_ind, :] elif ij == 'i': slice = islice sshr = sshr[:, ij_ind] hr = hr[:, ij_ind] Zr, Zu, Zv, TEMP, SALT, U, V = [ slice(k, ij_ind) for k in [Zr, Zu, Zv, TEMP, SALT, U, V] ] # -----------------------------------------------------------------< if useInd: # then store distances for a possible bry file dtype = Temp.dtype distr = np.zeros((nz, ny, nx), dtype) distu = np.zeros((nz, ny, nxu), dtype) distv = np.zeros((nz, nyv, nx), dtype) if not quiet: print 'vertical interpolation:' if ij == 'j': for j in range(ny): if not quiet and (ny < 10 or (ny >= 10 and j % 10 == 0)): print ' j=%3d of %3d' % (j, ny) ind = ij_ind[j] dr = np.tile(distance(xr[ind, :], yr[ind, :]), (nz, 1)) du = np.tile(distance(xu[ind, :], yu[ind, :]), (nz, 1)) Dr = np.tile(distance(xr[ind, :], yr[ind, :]), (NZ, 1)) Du = np.tile(distance(xu[ind, :], yu[ind, :]), (NZ, 1)) if useInd: distr[:, j, :] = dr distu[:, j, :] = du Temp[:, j, :] = calc.griddata(Rdz * Dr, ZZr[:, j, :], TEMP[:, j, :], Rdz * dr, Zr[:, j, :], extrap=True, **interp_opts) Salt[:, j, :] = calc.griddata(Rdz * Dr, ZZr[:, j, :], SALT[:, j, :], Rdz * dr, Zr[:, j, :], extrap=True, **interp_opts) if 0 and j % 10 == 0: print Dr.shape, ZZr[:, j, :].shape import pylab as pl pl.figure(1) pl.clf() pl.pcolormesh(Dr, ZZr[:, j, :], SALT[:, j, :]) pl.colorbar() clim = pl.gci().get_clim() pl.figure(2) pl.clf() pl.pcolormesh(dr, Zr[:, j, :], Salt[:, j, :]) pl.clim(clim) pl.colorbar() raw_input() Uvel[:, j, :] = calc.griddata(Rdz * Du, ZZu[:, j, :], U[:, j, :], Rdz * du, Zu[:, j, :], extrap=True, **interp_opts) if j < Vvel.shape[1]: dv = np.tile(distance(xv[ind, :], yv[ind, :]), (nz, 1)) Dv = np.tile(distance(xv[ind, :], yv[ind, :]), (NZ, 1)) Vvel[:, j, :] = calc.griddata(Rdz * Dv, ZZv[:, j, :], V[:, j, :], Rdz * dv, Zv[:, j, :], extrap=True, **interp_opts) if useInd: distv[:, j, :] = dv if np.any(np.isnan(Temp[:, j, :])): print 'found nan in temp', j if np.any(np.isnan(Salt[:, j, :])): print 'found nan in salt', j if np.any(np.isnan(Uvel[:, j, :])): print 'found nan in u', j if j < Vvel.shape[1] and np.any(np.isnan(Vvel[:, j, :])): print 'found nan in v', j elif ij == 'i': for i in range(nx): if not quiet and (nx < 10 or (nx >= 10 and i % 10 == 0)): print ' i=%3d of %3d' % (i, nx) ind = ij_ind[i] dr = np.tile(distance(xr[:, ind], yr[:, ind]), (nz, 1)) dv = np.tile(distance(xv[:, ind], yv[:, ind]), (nz, 1)) Dr = np.tile(distance(xr[:, ind], yr[:, ind]), (NZ, 1)) Dv = np.tile(distance(xv[:, ind], yv[:, ind]), (NZ, 1)) if useInd: distr[:, :, i] = dr distv[:, :, i] = dv Temp[:, :, i] = calc.griddata(Rdz * Dr, ZZr[:, :, i], TEMP[:, :, i], Rdz * dr, Zr[:, :, i], extrap=True, **interp_opts) Salt[:, :, i] = calc.griddata(Rdz * Dr, ZZr[:, :, i], SALT[:, :, i], Rdz * dr, Zr[:, :, i], extrap=True, **interp_opts) Vvel[:, :, i] = calc.griddata(Rdz * Dv, ZZv[:, :, i], V[:, :, i], Rdz * dv, Zv[:, :, i], extrap=True, **interp_opts) if i < Uvel.shape[2]: du = np.tile(distance(xu[:, ind], yu[:, ind]), (nz, 1)) Du = np.tile(distance(xu[:, ind], yu[:, ind]), (NZ, 1)) Uvel[:, :, i] = calc.griddata(Rdz * Du, ZZu[:, :, i], U[:, :, i], Rdz * du, Zu[:, :, i], extrap=True, **interp_opts) if useInd: distu[:, :, i] = du # uv bar: if not quiet: print 'calc uvbar' if useInd is False: ubar, vbar = rt.uvbar(Uvel, Vvel, sshr, hr, sparams) else: #>------------------------------------------------------------ sshu = calc.griddata(dlon, dlat, data['ssh'], xu, yu, extrap=True, **interp_opts) sshv = calc.griddata(dlon, dlat, data['ssh'], xv, yv, extrap=True, **interp_opts) if ij == 'j': sshu = sshu[ij_ind, :] sshv = sshv[ij_ind, :] hu = hu[ij_ind, :] hv = hv[ij_ind, :] elif ij == 'i': sshu = sshu[:, ij_ind] sshv = sshv[:, ij_ind] hu = hu[:, ij_ind] hv = hv[:, ij_ind] ubar = rt.barotropic(Uvel, sshu, hu, sparams) vbar = rt.barotropic(Vvel, sshv, hv, sparams) # -----------------------------------------------------------------< Vars = cb.odict() Vars['temp'] = Temp Vars['salt'] = Salt Vars['u'] = Uvel Vars['v'] = Vvel Vars['zeta'] = sshr Vars['ubar'] = ubar Vars['vbar'] = vbar Vars['date'] = data['date'] if not useInd is False: #>------------------------------------------ Vars['depth'] = Zr Vars['depthu'] = Zu Vars['depthv'] = Zv Vars['dist'] = distr Vars['distu'] = distu Vars['distv'] = distv # -----------------------------------------------------------------< if retHorizAux: return Vars, horizAux else: return Vars
def data2z(data, **kargs): ''' Interpolates data dict defined at 3D vertical coordinate (like sigma levels or s-levels, for instance) to 1D depths (layers of z constant) data must contain all the fileds from load_data, z3d and the new depth, ie, data['depth'].ndim==1 **kargs: ij : axis for vertical interpolations (*i,j) quiet : output messages flag (True by default) rep_surf: repeat surface level, ie, add a new surface level with same data as the old surface. This will ensure extrapolations in vertical slices do not occur horizontally, ie, misture will occur in the vertical not along the slice (True by default) interp_opts: options for griddata ''' ij = kargs.get('ij', 'j') quiet = kargs.get('quiet', True) rep_surf = kargs.get('rep_surf', True) interp_opts = kargs.get('interp_opts', {}) # repeat surface: if rep_surf: for vname in ['z3d', 'temp', 'salt', 'u', 'v']: if np.ma.isMA(data[vname]): data[vname] = np.ma.vstack( (data[vname], data[vname][-1][np.newaxis, ...])) else: data[vname] = np.vstack( (data[vname], data[vname][-1][np.newaxis, ...])) data['z3d'][-1] = data['z3d'].max() + 1 data['NZ'] = data['NZ'] + 1 Z = data['depth'] # new depths 1D z = data['z3d'] # 3D depths nZ = len(Z) nz = data['NZ'] nx = data['NX'] ny = data['NY'] # lon, lat 2d: x0 = data['lon'] y0 = data['lat'] if x0.ndim == 1: x0, y0 = np.meshgrid(x0, y0) # lon,lat 3d: x = np.tile(x0, (nz, 1, 1)) y = np.tile(y0, (nz, 1, 1)) xx = np.tile(x0, (nZ, 1, 1)) yy = np.tile(y0, (nZ, 1, 1)) # new z 3d: zz = np.tile(Z[:, np.newaxis, np.newaxis], (ny, nx)) # new data vars: Temp = np.ma.masked_all((nZ, ny, nx), data['temp'].dtype) Salt = np.ma.masked_all((nZ, ny, nx), data['salt'].dtype) U = np.ma.masked_all((nZ, ny, nx), data['u'].dtype) V = np.ma.masked_all((nZ, ny, nx), data['v'].dtype) if ij == 'j': for j in range(ny): if not quiet and j % 10 == 0: print 'z interp (%d z levels) j=%d of %d' % (nZ, j, ny) v = data['temp'][:, j, :] v = np.ma.masked_where(v == 0, v) Temp[:, j, :] = calc.griddata(x[:, j, :], z[:, j, :], v, xx[:, j, :], zz[:, j, :], extrap=True, **interp_opts) v = data['salt'][:, j, :] v = np.ma.masked_where(v == 0, v) Salt[:, j, :] = calc.griddata(x[:, j, :], z[:, j, :], v, xx[:, j, :], zz[:, j, :], extrap=True, **interp_opts) v = data['u'][:, j, :] v = np.ma.masked_where(v == 0, v) U[:, j, :] = calc.griddata(x[:, j, :], z[:, j, :], v, xx[:, j, :], zz[:, j, :], extrap=True, **interp_opts) v = data['v'][:, j, :] v = np.ma.masked_where(v == 0, v) V[:, j, :] = calc.griddata(x[:, j, :], z[:, j, :], v, xx[:, j, :], zz[:, j, :], extrap=True, **interp_opts) elif ij == 'i': for i in range(nx): if not quiet and i % 10 == 0: print 'z interp (%d z levels) i=%d of %d' % (nZ, i, nx) v = data['temp'][:, :, i] v = np.ma.masked_where(v == 0, v) Temp[:, :, i] = calc.griddata(y[:, :, i], z[:, :, i], v, yy[:, :, i], zz[:, :, i], extrap=True, **interp_opts) v = data['salt'][:, :, i] v = np.ma.masked_where(v == 0, v) Salt[:, :, i] = calc.griddata(y[:, :, i], z[:, :, i], v, yy[:, :, i], zz[:, :, i], extrap=True, **interp_opts) v = data['u'][:, :, i] v = np.ma.masked_where(v == 0, v) U[:, :, i] = calc.griddata(y[:, :, i], z[:, :, i], v, yy[:, :, i], zz[:, :, i], extrap=True, **interp_opts) v = data['v'][:, :, i] v = np.ma.masked_where(v == 0, v) V[:, :, i] = calc.griddata(y[:, :, i], z[:, :, i], v, yy[:, :, i], zz[:, :, i], extrap=True, **interp_opts) res = data.copy() res['temp'] = Temp res['salt'] = Salt res['u'] = U res['v'] = V res['NZ'] = nZ res.pop('z3d') return res
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 data2z(data,**kargs): ''' Interpolates data dict defined at 3D vertical coordinate (like sigma levels or s-levels, for instance) to 1D depths (layers of z constant) data must contain all the fileds from load_data, z3d and the new depth, ie, data['depth'].ndim==1 **kargs: ij : axis for vertical interpolations (*i,j) quiet : output messages flag (True by default) ''' ij='j' quiet=True if 'ij' in kargs.keys(): ij = kargs['ij'] if 'quiet' in kargs.keys(): quiet = kargs['quiet'] Z = data['depth'] # new depths 1D z = data['z3d'] # 3D depths nZ=len(Z) nz=data['NZ'] nx=data['NX'] ny=data['NY'] # lon, lat 2d: x0=data['lon'] y0=data['lat'] if x0.ndim==1:x0,y0 = np.meshgrid(x0,y0) # lon,lat 3d: x = np.tile(x0,(nz,1,1)) y = np.tile(y0,(nz,1,1)) xx = np.tile(x0,(nZ,1,1)) yy = np.tile(y0,(nZ,1,1)) # new z 3d: zz=np.tile(Z[:,np.newaxis,np.newaxis],(ny,nx)) # new data vars: Temp = np.ma.masked_all((nZ,ny,nx),data['temp'].dtype) Salt = np.ma.masked_all((nZ,ny,nx),data['salt'].dtype) U = np.ma.masked_all((nZ,ny,nx),data['u'].dtype) V = np.ma.masked_all((nZ,ny,nx),data['v'].dtype) if ij=='j': for j in range(ny): if not quiet and j%10==0: print 'z interp (%d z levels) j=%d of %d' % (nZ,j,ny) v=data['temp'][:,j,:] v=np.ma.masked_where(v==0,v) Temp[:,j,:]=calc.griddata(x[:,j,:],z[:,j,:],v,xx[:,j,:],zz[:,j,:],extrap=True) v=data['salt'][:,j,:] v=np.ma.masked_where(v==0,v) Salt[:,j,:]=calc.griddata(x[:,j,:],z[:,j,:],v,xx[:,j,:],zz[:,j,:],extrap=True) v=data['u'][:,j,:] v=np.ma.masked_where(v==0,v) U[:,j,:]=calc.griddata(x[:,j,:],z[:,j,:],v,xx[:,j,:],zz[:,j,:],extrap=True) v=data['v'][:,j,:] v=np.ma.masked_where(v==0,v) V[:,j,:]=calc.griddata(x[:,j,:],z[:,j,:],v,xx[:,j,:],zz[:,j,:],extrap=True) elif ij=='i': for i in range(nx): if not quiet and i%10==0: print 'z interp (%d z levels) i=%d of %d' % (nZ,i,nx) v=data['temp'][:,:,i] v=np.ma.masked_where(v==0,v) Temp[:,:,i]=calc.griddata(y[:,:,i],z[:,:,i],v,yy[:,:,i],zz[:,:,i],extrap=True) v=data['salt'][:,:,i] v=np.ma.masked_where(v==0,v) Salt[:,:,i]=calc.griddata(y[:,:,i],z[:,:,i],v,yy[:,:,i],zz[:,:,i],extrap=True) v=data['u'][:,:,i] v=np.ma.masked_where(v==0,v) U[:,:,i]=calc.griddata(y[:,:,i],z[:,:,i],v,yy[:,:,i],zz[:,:,i],extrap=True) v=data['v'][:,:,i] v=np.ma.masked_where(v==0,v) V[:,:,i]=calc.griddata(y[:,:,i],z[:,:,i],v,yy[:,:,i],zz[:,:,i],extrap=True) res = data.copy() res['temp'] = Temp res['salt'] = Salt res['u'] = U res['v'] = V res['NZ'] = nZ res.pop('z3d') return res
def data2romsblk(data, grd, **kargs): quiet = True keepOriginal = 2 # if 2, will keep data only inside rt.grid_vicinity rectange # if 1, all original data is kept Margin = 4 # for griddata and for original data to keep for k in kargs.keys(): if k == 'quiet': quiet = kargs[k] elif k.lower().startswith('keepor'): keepOriginal = kargs[k] elif k == 'margin': Margin = kargs[k] g = roms.Grid(grd) cond = False out = {} for vname in data.keys(): if vname.startswith('INFO') or vname in 'xy': continue # vnames starting with INFO are an info key, without data if not quiet: print(' interp %s' % vname) if cond is False: cond, inds = rt.grid_vicinity(grd, data['x'], data['y'], margin=Margin, rect=True, retinds=True) i1, i2, j1, j2 = inds out[vname] = calc.griddata(data['x'][cond], data['y'][cond], data[vname][cond], g.lon, g.lat, extrap=True) if keepOriginal: # keep original data: if keepOriginal == 1: out[vname + '_original'] = data[vname] # keep all original data elif keepOriginal == 2: out[vname + '_original'] = data[vname][ j1:j2, i1:i2] # keep data only inside vicinity rectangle if not out.has_key('x_original'): if keepOriginal == 1: out['x_original'] = data['x'] out['y_original'] = data['y'] elif keepOriginal == 2: out['x_original'] = data['x'][j1:j2, i1:i2] out['y_original'] = data['y'][j1:j2, i1:i2] # about wind: if not quiet: print(' --> rot U,V wind and U,V wind stress') angle = g.use('angle') out['uwnd'], out['vwnd'] = calc.rot2d(out['uwnd'], out['vwnd'], angle) out['sustr'], out['svstr'] = calc.rot2d(out['sustr'], out['svstr'], angle) out['sustr'] = rt.rho2uvp(out['sustr'], 'u') out['svstr'] = rt.rho2uvp(out['svstr'], 'v') return out
def slicell(self, varname, X, Y, time=0, plot=False, **opts): x, y, z, v, m = [[]] * 5 data = opts.get('data', False) dist = opts.get('dist', False) extrap = opts.get('extrap', False) varOnly = opts.get('retv', False) maskLimit = opts.get('lmask', 0.5) # points where interpolated mask are above # this value are considered as mask! # Most strict value is 0 X = np.array(X) Y = np.array(Y) if X.ndim > 1: X = np.squeeze(X) if Y.ndim > 1: Y = np.squeeze(X) if varname not in netcdf.varnames(self.name): print(':: variable %s not found' % varname) return x, y, z, v, m if time >= self.TIME: print('t = %d exceeds TIME dimension (%d)' % (time, self.TIME)) return x, y, z, v, m if data is False: v = self.use(varname, SEARCHtime=time) else: v = data x, y, h, m = self.grid.vars(ruvp=self.var_at(varname)) if v.ndim == 3: V = calc.griddata(x, y, v, X, Y, extrap=extrap, mask2d=m == 0, keepMaskVal=maskLimit) elif v.ndim == 2: V = calc.griddata(x, y, np.ma.masked_where(m == 0, v), X, Y, extrap=extrap, keepMaskVal=maskLimit) if varOnly: return V # Z: if v.ndim == 3: Z = self.path_s_levels(time, X, Y, rw=varname[0]) else: Z = 0. * X # X, Y, dist: if dist: Dist = calc.distance(X, Y) if v.ndim == 3: Dist = np.tile(Dist, (v.shape[0], 1)) else: if v.ndim == 3: X = np.tile(X, (v.shape[0], 1)) Y = np.tile(Y, (v.shape[0], 1)) if dist: return Dist, Z, V else: return X, Y, Z, V
def ww3gb_2TPAR(datafolder, date0, date1, romsgrid, nseg=(10, 10), addxy=(0.001, 0.001), dspr=20, path='', name='TPAR'): '''dspr, directional spreading; see https://www.myroms.org/forum/viewtopic.php?f=14&t=2335 ''' g = roms.Grid(romsgrid) # loading data: xlim = g.lon.min() - 2, g.lon.max() + 2 ylim = g.lat.min() - 2, g.lat.max() + 2 lon, lat, Time, Res = WW3Data(datafolder).data(date0, date1, xlim, ylim) # calc spec points: xy, ij = ww3_specpoints(romsgrid, nseg, addxy) # interpolate data at initial point of each segment: x = xy[:, 0] y = xy[:, 1] nt = len(Time) nv = len(Res) nx = xy.shape[0] TPAR = np.zeros((nt, nv, nx), 'f') vnames = 'hs', 'tp', 'dp' # Significant_height_of_combined_wind_waves_and_swell # Primary_wave_mean_period # Primary_wave_direction for it in range(nt): if it % 10 == 0: print 'time %03d of %03d : %s' % (it, nt, Time[it].isoformat(' ')) for iv in range(nv): vname = vnames[iv] #print ' -- %s'%vname v = Res[vname][it, ...] # 1st extrap masked data: v = calc.mask_extrap(lon, lat, v) TPAR[it, iv, :] = calc.griddata(lon, lat, v, x, y) # create TPAR files: for i in range(nx): fname = name + '_seg%03d.txt' % i j = open(fname, 'w') j.write('TPAR\n') for it in range(nt): # time as YYYYMMDD.HHMMSS tiso = Time[it].strftime('%Y%m%d.%H%M%S') j.write( '%s %6.2f %6.2f %6.2f %6.2f\n' % (tiso, TPAR[it, 0, i], TPAR[it, 1, i], TPAR[it, 2, i], dspr)) j.close() print 'created tpar file %s' % fname x1 = xy[:, 2] y1 = xy[:, 3] # add to swan INPUT: # BOUND SHAPESPEC JONSWAP PEAK DSPR DEGREES # BOUNDSPEC SEGMENT XY -54.3906 33.1171 -55.5271 35.8094 VARIABLE FILE 0 './forcings/TPAR2.txt' print '\n' print 'BOUND SHAPESPEC JONSWAP PEAK DSPR DEGREES' for i in range(nx): fname = os.path.join(path, name + '_seg%03d.txt' % i) print 'BOUNDSPEC SEGMENT XY %8.4f %8.4f %8.4f %8.4f VARIABLE FILE 0 \'%s\'' % ( x[i], y[i], x1[i], y1[i], fname) print '\n' i0 = ij[:, 0] j0 = ij[:, 1] i1 = ij[:, 2] j1 = ij[:, 3] for i in range(nx): fname = os.path.join(path, name + '_seg%03d.txt' % i) print 'BOUNDSPEC SEGMENT IJ %3d %3d %3d %3d VARIABLE FILE 0 \'%s\'' % ( i0[i], j0[i], i1[i], j1[i], fname) print '\n'
def slicell(self,varname,X,Y,time=0,**opts): # x,y,z,v,m=[[]]*5 ######## plot= opts.get('plot',False) ######### ax = opts.get('ax',None) coords=opts.get('coords',self._default_coords('slicell')).split(',') data = opts.get('data',False) # dist = opts.get('dist',False) extrap = opts.get('extrap',False) # varOnly = opts.get('retv',False) maskLimit = opts.get('lmask',0.5) # points where interpolated mask are above # this value are considered as mask! # Most strict value is 0 out=Data() out.msg=self.check_slice(varname,t=time) if out.msg: return out#None,aux X=np.asarray(X) Y=np.asarray(Y) if X.ndim>1: X=np.squeeze(X) if Y.ndim>1: Y=np.squeeze(X) # if varname not in netcdf.varnames(self.name): # print ':: variable %s not found' % varname # return x,y,z,v,m # # if time>=self.TIME: # print 't = %d exceeds TIME dimension (%d)' % (time,self.TIME) # return x,y,z,v,m x,y,h,m=self.grid.vars(ruvp=self.var_at(varname)) if True: # extrat only portion of data needed: ## print 'start', x.shape,y.shape,X.shape i0,i1,j0,j1=calc.ij_limits(x, y, (X.min(),X.max()),(Y.min(),Y.max()), margin=1) ## print 'end' xi='%d:%d'%(i0,i1) eta='%d:%d'%(j0,j1) if data is False: V=self.use(varname,SEARCHtime=time,xi_SEARCH=xi,eta_SEARCH=eta) else: v=data[...,j0:j1,i0:i1] x=x[j0:j1,i0:i1] y=y[j0:j1,i0:i1] h=h[j0:j1,i0:i1] m=m[j0:j1,i0:i1] else: if data is False: V=self.use(varname,SEARCHtime=time) else: v=data if V.ndim==3: v=calc.griddata(x,y,V,X,Y,extrap=extrap,mask2d=m==0, keepMaskVal=maskLimit) elif V.ndim==2: v=calc.griddata(x,y,np.ma.masked_where(m==0,V),X,Y,extrap=extrap, keepMaskVal=maskLimit) # coords: if 'z' in coords and V.ndim==3: out.z=self.path_s_levels(time,X,Y,rw=varname[0]) if 'd' in coords: d=calc.distance(X,Y) if v.ndim==2: d=np.tile(d,(v.shape[0],1)) out.d=d if 'x' in coords: if v.ndim==2: X=np.tile(X,(v.shape[0],1)) out.x=X if 'y' in coords: if v.ndim==2: Y=np.tile(Y,(v.shape[0],1)) out.y=Y if 't' in coords: out.t=self.time[time] # # X, Y, dist: # if dist: # Dist=calc.distance(X,Y) # if v.ndim==3: # Dist=np.tile(Dist,(v.shape[0],1)) # else: # if v.ndim==3: # X=np.tile(X,(v.shape[0],1)) # Y=np.tile(Y,(v.shape[0],1)) # # if dist: # return Dist,Z,V # else: # return X,Y,Z,V # # if plot: # if not ax: ax=pl.gca() # if v.ndim==2: # if 'x' in coords: # p=ax.pcolormesh(out.x,out.z,v) ### ax.plot(aux.x[0],-h) # elif 'y' in coords: # p=ax.pcolormesh(out.y,out.z,v) ### ax.plot(aux.y[0],-h) # else: # p=ax.pcolormesh(out.d,out.z,v) #### ax.plot(aux.d[0],-h) ## # pl.colorbar(p,shrink=.7) ## elif v.ndim==1: # if 'x' in coords: # ax.plot(out.x,v) # elif 'y' in coords: # ax.plot(out.y,v) # else: # ax.plot(out.d,v) # out.v=v out.coordsReq=','.join(sorted(coords)) return out###v,aux
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 time_series(self, varname, x, y, times=False, depth=False, **opts): t, z, v = [[]] * 3 RetVarOnly = False savename = False retMsg = False nearest = True # UNIQUE case Currently plot = False if 'retvar' in opts.keys(): RetVarOnly = opts['retvar'] if 'savename' in opts.keys(): savename = opts['savename'] if 'msg' in opts.keys(): retMsg = opts['msg'] if 'nearest' in opts.keys(): nearest = opts['msg'] if 'plot' in opts.keys(): plot = opts['msg'] if varname not in netcdf.varnames(self.name): msg = ':: variable %s not found' % varname if retMsg: return t, z, v, msg else: print(msg) return t, z, v isW = varname == 'w' hasZ = self.hasz(varname) if not depth is False and hasZ: if isW and depth >= self.S_W: msg = 'k = %d exceeds S_W dimension (%d)' % (depth, self.S_W) if retMsg: return t, z, v, msg else: print(msg) return t, z, v elif depth >= self.S_RHO: msg = 'k = %d exceeds S_RHO dimension (%d)' % (depth, self.S_RHO) if retMsg: return t, z, v, msg else: print(msg) return t, z, v if times is False: times = 0, len(self.tdays) if self.hast(varname) and times[-1] > self.TIME: msg = 't = %d exceeds TIME dimension (%d)' % (times[-1], self.TIME) if retMsg: return t, z, v, msg else: print(msg) return t, z, v lon, lat, hr, mr = self.grid.vars(ruvp=self.var_at(varname)) dist = (lon - x)**2 + (lat - y)**2 i, j = np.where(dist == dist.min()) i, j = i[0], j[0] v = self.use(varname, xiSEARCH=j, etaSEARCH=i, SEARCHtime=range(times[0], times[-1])).T # time: t = self.tdays[range(times[0], times[-1])] t = t + 0. * v # depth: if hasZ: h = self.grid.h[i, j] zeta = self.use('zeta', xiSEARCH=j, etaSEARCH=i, SEARCHtime=range(times[0], times[-1])) h = h + 0 * zeta z = rt.s_levels(h, zeta, self.s_params, rw=varname) z = np.squeeze(z) if not depth is False: if depth >= 0: t = t[0, :] z = z[depth, :] v = v[depth, :] else: t0, z0 = t, z t = t[0, :] z = depth + 0. * t v = calc.griddata(t0, z0, v, t, z, extrap=False, norm_xy=True) else: # not hasZ z = 0. * t if plot: pass # TODO if RetVarOnly: return v else: if retMsg: return t, z, v, '' else: return t, z, v
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 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 data2romsblk(data, grd, **kargs): quiet = kargs.get('quiet', True) Margin = kargs.get('margin', 4) # for griddata and for original data to keep # if margin is 'no calc', no extraction of # a domain portion is done # about projection: # - if auto will use grid default projection # - if False, no projection is used # - any Basemap projection can be used proj = kargs.get('proj', 'auto') # about origina data to keep: # - if 2, will keep data only inside rt.grid_vicinity rectange # - if 1, all original data is kept keepOriginal = 2 for k in kargs: if k.lower().startswith('keepor'): keepOriginal = kargs[k] if cb.isstr(grd): g = roms.Grid(grd) else: g = grd if proj == 'auto': proj = g.get_projection() if proj: data_x, data_y = proj(data['x'], data['y']) grd_x, grd_y = proj(g.lon, g.lat) else: data_x, data_y = data['x'], data['y'] grd_x, grd_y = g.lon, g.lat cond = False out = {} for vname in data: if vname.startswith('INFO') or vname in 'xy': continue # vnames starting with INFO are an info key, without data if not quiet: print(' interp %s' % vname) if cond is False: if Margin == 'no calc': cond = np.ones_like(data['x'], 'bool') i1, i1 = 0, 0 j2, i2 = data['x'].shape else: cond, inds = rt.grid_vicinity(grd, data['x'], data['y'], margin=Margin, rect=True, retinds=True) i1, i2, j1, j2 = inds out[vname] = calc.griddata(data_x[cond], data_y[cond], data[vname][cond], grd_x, grd_y, extrap=True) if keepOriginal: # keep original data: if keepOriginal == 1: out[vname + '_original'] = data[vname] # keep all original data elif keepOriginal == 2: out[vname + '_original'] = data[vname][ j1:j2, i1:i2] # keep data only inside vicinity rectangle if 'x_original' not in out: if keepOriginal == 1: out['x_original'] = data['x'] out['y_original'] = data['y'] elif keepOriginal == 2: out['x_original'] = data['x'][j1:j2, i1:i2] out['y_original'] = data['y'][j1:j2, i1:i2] # about wind: if not quiet: print(' --> rot U,V wind and U,V wind stress') out['uwnd'], out['vwnd'] = calc.rot2d(out['uwnd'], out['vwnd'], g.angle) out['sustr'], out['svstr'] = calc.rot2d(out['sustr'], out['svstr'], g.angle) out['sustr'] = rt.rho2uvp(out['sustr'], 'u') out['svstr'] = rt.rho2uvp(out['svstr'], 'v') return out
def time_series(self,varname,x,y,times=None,depth=None,**opts): ######## plot= opts.get('plot',False) ######## ax = opts.get('ax',None) coords=opts.get('coords',self._default_coords('sliceiso')).split(',') if times is None: times=range(0,self.time.size) out=Data() out.msg=self.check_slice(varname,t=np.max(times),k=depth) if out.msg: return out###None,aux ## t,z,v=[[]]*3 # # RetVarOnly=False # savename=False # retMsg=False # nearest=True # UNIQUE case Currently # plot=False # # if 'retvar' in opts.keys(): RetVarOnly = opts['retvar'] # if 'savename' in opts.keys(): savename = opts['savename'] # if 'msg' in opts.keys(): retMsg = opts['msg'] # if 'nearest' in opts.keys(): nearest = opts['msg'] # if 'plot' in opts.keys(): plot = opts['msg'] # # # if varname not in netcdf.varnames(self.name): # msg=':: variable %s not found' % varname # if retMsg: return t,z,v,msg # else: # print msg # return t,z,v # # isW=varname=='w' # hasZ=self.hasz(varname) # # if not depth is False and hasZ : # if isW and depth >= self.S_W: # msg='k = %d exceeds S_W dimension (%d)' % (depth,self.S_W) # if retMsg: return t,z,v,msg # else: # print msg # return t,z,v # # elif depth >= self.S_RHO: # msg='k = %d exceeds S_RHO dimension (%d)' % (depth,self.S_RHO) # if retMsg: return t,z,v,msg # else: # print msg # return t,z,v # # if times is False: # times=0,len(self.tdays) # # if self.hast(varname) and times[-1]>self.TIME: # msg='t = %d exceeds TIME dimension (%d)' % (times[-1],self.TIME) # if retMsg: return t,z,v,msg # else: # print msg # return t,z,v # # find nearest point: lon,lat,hr,mr=self.grid.vars(ruvp=self.var_at(varname)) dist=(lon-x)**2+(lat-y)**2 i,j=np.where(dist==dist.min()) i,j=i[0],j[0] if depth>=0: arg={'s_SEARCH':depth} else: arg={} v=self.use(varname,xiSEARCH=j,etaSEARCH=i,SEARCHtime=times,**arg).T # calculate depths: if self.hasz(varname): h=self.grid.h[i,j] zeta=self.use('zeta',xiSEARCH=j,etaSEARCH=i,SEARCHtime=times) h=h+0*zeta z=rt.s_levels(h,zeta,self.s_params,rw=varname) z=np.squeeze(z) # depth slice: if not depth is None and self.hasz(varname) and depth<0: if v.ndim==2: from matplotlib.dates import date2num t=np.tile(date2num(self.time[times]),(v.shape[0],1)) v=calc.griddata(t,z,v,t[0],depth+np.zeros(t[0].shape), extrap=opts.get('extrap',False),norm_xy=opts.get('norm_xy',False)) # norm_xy True may be needed! # extrap also may be needed cos the 1st and last value may be masked! else: # one time only v=np.interp(depth,z,v,left=np.nan,right=np.nan) v=np.ma.masked_where(np.isnan(v),v) # coords if 't' in coords: if v.ndim==2: out.t=np.tile(self.time[times],(v.shape[0],1)) from matplotlib.dates import date2num out.tnum=np.tile(date2num(self.time[times]),(v.shape[0],1)) else: out.t=self.time[times] if 'z' in coords and self.hasz(varname): if not depth is None: if depth>=0: out.z=z[depth,...] else: out.z=depth+0*v else: out.z=z if 'x' in coords: out.x=lon[i,j] if 'y' in coords: out.y=lat[i,j] ## if plot and v.ndim: ## if not ax: ## ax=pl.gca() ## opts['ax']=ax ## ## if v.ndim==2: ## p=ax.pcolormesh(out.tnum,out.z,v) ## #ax.xaxis_date() ## pl.colorbar(p,shrink=.7) ## elif v.size>1: ## if out.t.size>1: # time series: ## ax.plot(out.t,v) ## else: # vertical profile: ## ax.plot(v,out.z) out.v=v out.coordsReq=','.join(sorted(coords)) return out##v,aux
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 slicell(self,varname,X,Y,time=0,**opts): coords=opts.get('coords',self._default_coords('slicell')).split(',') data = opts.get('data',False) extrap = opts.get('extrap',False) maskLimit = opts.get('lmask',0.5) # points where interpolated mask are above # this value are considered as mask! # Most strict value is 0 out=vis.Data() out.label='slicell' out.msg=self.check_slice(varname,t=time) if out.msg: return out#None,aux X=np.asarray(X) Y=np.asarray(Y) if X.ndim>1: X=np.squeeze(X) if Y.ndim>1: Y=np.squeeze(X) ### x,y,h,m=self.grid.vars(ruvp=self.var_at(varname)[0]) x,y,h,m=self.grid.vars(ruvp=self.vloc(varname)[0]) if True: # extrat only portion of data needed: i0,i1,j0,j1=calc.ij_limits(x, y, (X.min(),X.max()),(Y.min(),Y.max()), margin=1) xi='%d:%d'%(i0,i1) eta='%d:%d'%(j0,j1) if data is False: V=self.use(varname,SEARCHtime=time,xi_SEARCH=xi,eta_SEARCH=eta) else: v=data[...,j0:j1,i0:i1] x=x[j0:j1,i0:i1] y=y[j0:j1,i0:i1] h=h[j0:j1,i0:i1] m=m[j0:j1,i0:i1] else: if data is False: V=self.use(varname,SEARCHtime=time) else: v=data if V.ndim==3: v=calc.griddata(x,y,V,X,Y,extrap=extrap,mask2d=m==0, keepMaskVal=maskLimit) elif V.ndim==2: v=calc.griddata(x,y,np.ma.masked_where(m==0,V),X,Y,extrap=extrap, keepMaskVal=maskLimit) out.v=v out.info['v']['name']=varname out.info['v']['slice']='path npts=%d'%X.size try: out.info['v']['units']=netcdf.vatt(self.nc,varname,'units') except: pass # coords: if 'z' in coords and V.ndim==3: inds=dict(xi=(i0,i1),eta=(j0,j1)) ######### out.z=self.path_s_levels(time,X,Y,rw=varname[0],inds=inds) ### out.z=self.path_s_levels(time,X,Y,rw=self.var_at(varname)[1],inds=inds) ### ####### out.z,zw=self.path_s_levels(time,X,Y,rw=False,inds=inds) ####### if self.vloc(varname)[1]=='w': out.z=zw out.z=self.path_s_levels(time,X,Y,rw=self.vloc(varname)[1],inds=inds) out.info['z']=dict(name='Depth',units='m') if 'd' in coords: d=calc.distance(X,Y) if d[-1]-d[0]>1e4: d=d/1000. dunits='km' else: dunits='m' if v.ndim==2: d=np.tile(d,(v.shape[0],1)) out.d=d out.info['d']=dict(name='Distance',units=dunits) if 'x' in coords: if v.ndim==2: X=np.tile(X,(v.shape[0],1)) out.x=X out.info['x']=dict(name='Longitude',units=r'$\^o$E') if 'y' in coords: if v.ndim==2: Y=np.tile(Y,(v.shape[0],1)) out.y=Y out.info['y']=dict(name='Latitude',units=r'$\^o$N') ####### if 't' in coords and self.hast(varname): out.t=self.time[time] if 't' in coords and 't' in self.vaxes(varname): out.t=self.time[time] if v.ndim==2: ################3 and not out.z is None: # zeta and bottom already calculated out.extra=[vis.Data()] if 'd' in coords: out.extra[0].x=out.d[0] if 'x' in coords: out.extra[0].y=out.x[0] if 'y' in coords: out.extra[0].x=out.y[0] #### #h=-zw[0] h = calc.griddata(x,y,h,X,Y,extrap=False) out.extra[0].v=-h # bottom out.extra[0].config['d1.plot']='fill_between' out.extra[0].config['d1.y0']=-h.max()-(h.max()-h.min())/20. out.extra[0].label='bottom' out.coordsReq=','.join(sorted(coords)) return out
def update_wind(fname, data, new_wind_info, **kargs): ''' new_wind_info will be added to fname as global attribute (ex: 'new wind from database xxx') ''' quiet = False Margin = 4 # for griddata and for original data to keep grd = False keepOriginal = 2 for k in kargs.keys(): if k == 'quiet': quiet = kargs[k] elif k == 'margin': Margin = kargs[k] elif k == 'grid': grd = kargs[k] elif k.lower().startswith('keepor'): keepOriginal = kargs[k] if not grd: grd = netcdf.fatt(fname, 'grd_file') g = roms.Grid(grd) x0 = data['x'] y0 = data['y'] if x0.ndim == 1: x0, y0 = np.meshgrid(x0, y0) dates = data.keys()[:] dates.remove('x') dates.remove('y') dates = np.array(dates) # interp in time: time = netcdf.nctime(fname, 'time') cond = False tind = -1 fob = gennc.GenBlk(fname, grd) for t in time: newWind = {} tind += 1 I, = np.where(dates == t) if I.size: I = I[0] uv = data[dates[I]] if not quiet: print(t, dates[I]) else: i1, = np.where(dates > t) i0, = np.where(dates < t) if i0.size and i1.size: i1 = i1[0] i0 = i0[-1] d0 = t - dates[i0] d1 = dates[i1] - t d0 = d0.days + d0.seconds / 86400. d1 = d1.days + d1.seconds / 86400. uv = (data[dates[i0]] * d1 + data[dates[i1]] * d0) / (d0 + d1) if not quiet: print(t, dates[i0], dates[i1], d0, d1) elif not i1.size: uv = data[dates[-1]] if not quiet: print(t, dates[-1]) elif not i0.size: uv = data[dates[0]] if not quiet: print(t, dates[0]) # interp to grid: if cond is False: cond, inds = rt.grid_vicinity(grd, x0, y0, margin=Margin, rect=True, retinds=True) i1, i2, j1, j2 = inds if not quiet: print(' --> inter uv %s' % t.isoformat(' ')) u = calc.griddata(x0[cond], y0[cond], uv.real[cond], g.lon, g.lat, extrap=True) v = calc.griddata(x0[cond], y0[cond], uv.imag[cond], g.lon, g.lat, extrap=True) # rotate wind, calc stress: if not quiet: print(' --> rot U,V wind and U,V wind stress') wspd = np.sqrt(u**2 + v**2) sustr, svstr = air_sea.wind_stress(u, v) angle = g.use('angle') uwnd, vwnd = calc.rot2d(u, v, angle) sustr, svstr = calc.rot2d(sustr, svstr, angle) sustr = rt.rho2uvp(sustr, 'u') svstr = rt.rho2uvp(svstr, 'v') # update wind data: newWind['date'] = t newWind['uwnd'] = uwnd newWind['vwnd'] = vwnd newWind['sustr'] = sustr newWind['svstr'] = svstr newWind['wspd'] = wspd # original xy: if tind == 0: newWind['attr'] = {'new_wind_info': new_wind_info} if not quiet: print(' --> original xy') if keepOriginal == 1: newWind['x_wind'] = x0 newWind['y_wind'] = y0 elif keepOriginal == 2: newWind['x_wind'] = x0[j1:j2, i1:i2] newWind['y_wind'] = y0[j1:j2, i1:i2] # add to file: if not quiet: print(' --> adding to file') fob.update_wind(newWind, quiet=quiet) if not quiet: print('')
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=fix_time(ttmp,clouds,time[0],time[-1]) # cc is currently used to get # time, so this step is not needed! print ' ...fixed!' 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 data2romsblk(data,grd,**kargs): quiet=kargs.get('quiet',True) Margin=kargs.get('margin',4) # for griddata and for original data to keep # if margin is 'no calc', no extraction of # a domain portion is done # about projection: # - if auto will use grid default projection # - if False, no projection is used # - any Basemap projection can be used proj=kargs.get('proj','auto') # about origina data to keep: # - if 2, will keep data only inside rt.grid_vicinity rectange # - if 1, all original data is kept keepOriginal = 2 for k in kargs: if k.lower().startswith('keepor'): keepOriginal=kargs[k] if cb.isstr(grd): g=roms.Grid(grd) else: g=grd if proj=='auto': proj=g.get_projection() if proj: data_x,data_y=proj(data['x'],data['y']) grd_x,grd_y=proj(g.lon,g.lat) else: data_x,data_y=data['x'],data['y'] grd_x,grd_y=g.lon,g.lat cond=False out={} for vname in data: if vname.startswith('INFO') or vname in 'xy': continue # vnames starting with INFO are an info key, without data if not quiet: print(' interp %s' % vname) if cond is False: if Margin=='no calc': cond=np.ones_like(data['x'],'bool') i1,i1=0,0 j2,i2=data['x'].shape else: cond,inds=rt.grid_vicinity(grd,data['x'],data['y'], margin=Margin,rect=True,retinds=True) i1,i2,j1,j2=inds out[vname]=calc.griddata(data_x[cond],data_y[cond], data[vname][cond],grd_x,grd_y,extrap=True) if keepOriginal: # keep original data: if keepOriginal==1: out[vname+'_original']=data[vname] # keep all original data elif keepOriginal==2: out[vname+'_original']=data[vname][j1:j2,i1:i2] # keep data only inside vicinity rectangle if 'x_original' not in out: if keepOriginal==1: out['x_original']=data['x'] out['y_original']=data['y'] elif keepOriginal==2: out['x_original']=data['x'][j1:j2,i1:i2] out['y_original']=data['y'][j1:j2,i1:i2] # about wind: if not quiet: print(' --> rot U,V wind and U,V wind stress') out['uwnd'],out['vwnd']=calc.rot2d(out['uwnd'],out['vwnd'],g.angle) out['sustr'],out['svstr']=calc.rot2d(out['sustr'],out['svstr'],g.angle) out['sustr']=rt.rho2uvp(out['sustr'],'u') out['svstr']=rt.rho2uvp(out['svstr'],'v') return out