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 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 sliceuv(self,ind,time=0,**opts):#plot=False,**opts): ### plot= opts.pop('plot',False) ### opts['plot']=False ### ax = opts.get('ax',None) coords=opts.get('coords',self._default_coords('sliceuv')).split(',') #### out=Data() #### # savename=opts.pop('savename',False) # retMsg=opts.pop('msg',False) if ind=='bar': slc,uname,vname,ind = self.slicek, 'ubar','vbar', 9999 elif ind in ('s','surf','surface'): slc,uname,vname,ind = self.slicek, 'u','v', -1 elif ind>=0: slc,uname,vname,ind = self.slicek, 'u','v', ind elif ind <0: isK=False slc,uname,vname,ind = self.slicez, 'u','v', ind ## if isK: # xu,yu,zu,u,msg1=self.slicek(uname,ind,time,msg=True,**opts) # xv,yv,zv,v,msg2=self.slicek(vname,ind,time,msg=True,**opts) ## u,auxu=slc(uname,ind,time,**opts) ## v,auxv=slc(vname,ind,time,**opts) outu=slc(uname,ind,time,**opts) outv=slc(vname,ind,time,**opts) if outu.msg: return outu##None,None,auxu elif outv.msg: return outv##None,None,auxv # at psi: u,v=outu.v,outv.v u=( u[1:,:]+ u[:-1,:])/2. v=( v[:,1:]+ v[:,:-1])/2. # rotate uv: ang=rt.rho2uvp(self.grid.angle,'p') u,v=calc.rot2d(u,v,-ang) ## else: ## xu,yu,zu,u,msg1=self.slicez(uname,ind,time,msg=True,**opts) ## xv,yv,zv,v,msg2=self.slicez(vname,ind,time,msg=True,**opts) ## ## if msg1: msg=msg1+' and '+msg2 ## else: msg=msg2 out=outu out.v=u,v out.info['v']['name']=uname+vname if 'z' in coords: out.z=(out.z[1:,:]+out.z[:-1,:])/2. if 'x' in coords: out.x=(out.x[1:,:]+out.x[:-1,:])/2. if 'y' in coords: out.y=(out.y[1:,:]+out.y[:-1,:])/2. out.coordsReq=','.join(sorted(coords)) return out###u,v,aux
def seta(anchor='start'): # anchor: start or center t1=35*np.pi/180 t2=80*np.pi/180 # t0..90 w=0.1 h=0.2 s=(u**2+v**2)**0.5 h=min(h,s/3) w=min(w,s/5) P0=np.array([0,0]) P1=np.array([0,w/2]) w1=np.tan(t1)*h-w/2 h1=w1/np.tan(t2) P2=np.array([s-h+h1,w/2]) P3=np.array([s-h,w/2+w1]) P4=np.array([s,0]) P5=np.array([P3[0],-P3[1]]) P6=np.array([P2[0],-P2[1]]) P7=np.array([P1[0],-P1[1]]) x=P1[0],P2[0],P3[0],P4[0],P5[0],P6[0],P7[0],P1[0] y=P1[1],P2[1],P3[1],P4[1],P5[1],P6[1],P7[1],P1[1] x=np.asarray(x) y=np.asarray(y) ang=np.arctan2(v,u) x,y=calc.rot2d(x,y,-ang) pl.plot(x,y)
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 sliceuv(self,ind,time=0,plot=False,**opts): savename=False if savename in opts.keys(): savename=opts['savename'] if ind=='bar': isK,uname,vname,ind = True, 'ubar','vbar', 9999 elif ind in ('s','surf','surface'): isK,uname,vname,ind = True, 'u','v', -1 elif ind>=0: isK,uname,vname,ind = True, 'u','v', ind elif ind <0: isK=False isK,uname,vname,ind = False, 'u','v', ind if isK: xu,yu,zu,u=self.slicek(uname,ind,time) xv,yv,zv,v=self.slicek(vname,ind,time) else: xu,yu,zu,u=self.slicez(uname,ind,time) xv,yv,zv,v=self.slicez(vname,ind,time) z=(zu[1:,:]+zu[:-1,:])/2. u=( u[1:,:]+ u[:-1,:])/2. v=( v[:,1:]+ v[:,:-1])/2. x=self.grid.lonp y=self.grid.latp # rotate uv: ang=rt.rho2uvp(self.grid.angle,'p') u,v=calc.rot2d(u,v,-ang) if plot: p=self.grid.plot(bathy=None) xm, ym = p(x,y) mm=0*m mm[::3,::3]=1 mm=mm*m==1 s=np.sqrt(u**2+v**2) q=pylab.quiver(xm[mm],ym[mm],u[mm],v[mm],s[mm]) pylab.colorbar(shrink=.7) pylab.axis([p.xmin, p.xmax, p.ymin, p.ymax]) qk = pylab.quiverkey(q, .05, .01, 0.2, '0.2 m/s',labelpos='E', coordinates='axes') if savename: pylab.savefig(savename,dpi=pylab.gcf().dpi) pylab.close(pylab.gcf()) return x,y,z,u,v
def sliceuv(self, ind, time=0, plot=False, **opts): savename = False if savename in opts.keys(): savename = opts["savename"] if ind == "bar": isK, uname, vname, ind = True, "ubar", "vbar", 9999 elif ind in ("s", "surf", "surface"): isK, uname, vname, ind = True, "u", "v", -1 elif ind >= 0: isK, uname, vname, ind = True, "u", "v", ind elif ind < 0: isK = False isK, uname, vname, ind = False, "u", "v", ind if isK: xu, yu, zu, u = self.slicek(uname, ind, time) xv, yv, zv, v = self.slicek(vname, ind, time) else: xu, yu, zu, u = self.slicez(uname, ind, time) xv, yv, zv, v = self.slicez(vname, ind, time) z = (zu[1:, :] + zu[:-1, :]) / 2.0 u = (u[1:, :] + u[:-1, :]) / 2.0 v = (v[:, 1:] + v[:, :-1]) / 2.0 x = self.grid.lonp y = self.grid.latp # rotate uv: ang = rt.rho2uvp(self.grid.angle, "p") u, v = calc.rot2d(u, v, -ang) if plot: p = self.grid.plot(bathy=None) xm, ym = p(x, y) mm = 0 * m mm[::3, ::3] = 1 mm = mm * m == 1 s = np.sqrt(u ** 2 + v ** 2) q = pylab.quiver(xm[mm], ym[mm], u[mm], v[mm], s[mm]) pylab.colorbar(shrink=0.7) pylab.axis([p.xmin, p.xmax, p.ymin, p.ymax]) qk = pylab.quiverkey(q, 0.05, 0.01, 0.2, "0.2 m/s", labelpos="E", coordinates="axes") if savename: pylab.savefig(savename, dpi=pylab.gcf().dpi) pylab.close(pylab.gcf()) return x, y, z, u, v
def sliceuv(self,ind,time=0,**opts):#plot=False,**opts): coords=opts.get('coords',self._default_coords('sliceuv')).split(',') if ind=='bar': slc,uname,vname,ind = self.slicek, 'ubar','vbar', 9999 elif ind in ('s','surf','surface'): slc,uname,vname,ind = self.slicek, 'u','v', -1 elif ind>=0: slc,uname,vname,ind = self.slicek, 'u','v', ind elif ind <0: slc,uname,vname,ind = self.slicez, 'u','v', ind outu=slc(uname,ind,time,**opts) outv=slc(vname,ind,time,**opts) if outu.msg: return outu elif outv.msg: return outv # at psi: u,v=outu.v,outv.v u=( u[1:,:]+ u[:-1,:])/2. v=( v[:,1:]+ v[:,:-1])/2. # rotate uv: if 0: ang=rt.rho2uvp(self.grid.angle,'p') else: ang=np.cos(self.grid.angle)+1j*np.sin(self.grid.angle) ang=np.angle(rt.rho2uvp(ang,'p')) u,v=calc.rot2d(u,v,-ang) out=outu out.label=out.label+'_uv' out.v=u+1j*v out.info['v']['name']=uname+vname if 'z' in coords: out.z=(out.z[1:,:]+out.z[:-1,:])/2. if 'x' in coords: out.x=(out.x[1:,:]+out.x[:-1,:])/2. if 'y' in coords: out.y=(out.y[1:,:]+out.y[:-1,:])/2. out.coordsReq=','.join(sorted(coords)) return out
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(self, what, **kargs): time = False day = False quiet = True keys = kargs.keys() if "time" in keys: time = kargs["time"] if "day" in keys: day = kargs["day"] if "quiet" in keys: quiet = kargs["quiet"] if what == "wind_ts": if "xi" in kargs.keys() and "eta" in kargs.keys(): xi = kargs["xi"] eta = kargs["eta"] elif "lon" in kargs.keys() and "lat" in kargs.keys(): d = (self.grid.lon - kargs["lon"]) ** 2 + (self.grid.lat - kargs["lat"]) ** 2 i, j = np.where(d == d.min()) eta = i[0] xi = j[0] u = self.use("uwnd", xi_rho=xi, eta_rho=eta) v = self.use("vwnd", xi_rho=xi, eta_rho=eta) ang = self.grid.angle[eta, xi] * np.ones(u.shape) u, v = calc.rot2d(u, v, -ang) tdays = self.tdays if not day is False: ndays = self.tdays[-1] - self.tdays[0] n = int(86400 / self.dt) u = u[day * n : (day + 1) * n] v = v[day * n : (day + 1) * n] tdays = tdays[day * n : (day + 1) * n] return tdays, u, v elif what == "wind": if "uwnd" in netcdf.varnames(self.name): u = self.use("uwnd") v = self.use("vwnd") else: u = self.use("Uwind") v = self.use("Vwind") if time == "mean" and u.ndim == 3: u = u.mean(0) v = v.mean(0) elif time == "dailyMean" and u.ndim == 3: ndays = self.tdays[-1] - self.tdays[0] n = int(86400 / self.dt) if not day is False: if day == -1: day = ndays - 1 # this is wrong if there is data missing! u = u[day * n : (day + 1) * n, ...].mean(0) v = v[day * n : (day + 1) * n, ...].mean(0) else: U = range(ndays) V = range(ndays) for i in range(ndays): U[i] = u[i * n : (i + 1) * n, ...].mean(0) V[i] = v[i * n : (i + 1) * n, ...].mean(0) u = U v = V elif not time is False and isinstance(time, int) and u.ndim == 3: u = u[time, ...] v = v[time, ...] if isinstance(u, list): for i in range(len(u)): u[i], v[i] = calc.rot2d(u[i], v[i], -self.grid.angle) else: if u.ndim == 3: for i in range(u.shape[0]): u[i, ...], v[i, ...] = calc.rot2d(u[i, ...], v[i, ...], -self.grid.angle) elif u.ndim == 2: u, v = calc.rot2d(u, v, -self.grid.angle) if self.grid: x = self.grid.lon y = self.grid.lat m = self.grid.mask return x, y, u, v, m else: return u, v elif what == "data": out = {} args = {} if not time is False: args["bulk_time"] = time if not quiet: print "loading Blk data time=", time print "* * * * * * * * * * * *." if not quiet: print "*", out["tair"] = self.use("tair", **args) if not quiet: print "*", out["rhum"] = self.use("rhum", **args) if not quiet: print "*", out["pres"] = self.use("pres", **args) if not quiet: print "*", out["prate"] = self.use("prate", **args) if not quiet: print "*", out["radsw"] = self.use("radsw", **args) if not quiet: print "*", out["radlw"] = self.use("radlw", **args) if not quiet: print "*", out["dlwrf"] = self.use("dlwrf", **args) if not quiet: print "*", out["uwnd"] = self.use("uwnd", **args) if not quiet: print "*", out["vwnd"] = self.use("vwnd", **args) if not quiet: print "*", out["sustr"] = self.use("sustr", **args) if not quiet: print "*", out["svstr"] = self.use("svstr", **args) if not quiet: print "*." out["wspd"] = self.use("wspd", **args) blktime = self.use("bulk_time", **args) t0 = self.atts["t0"] return out, blktime, t0
def get(self, what, **kargs): time = False day = False quiet = True keys = kargs.keys() if 'time' in keys: time = kargs['time'] if 'day' in keys: day = kargs['day'] if 'quiet' in keys: quiet = kargs['quiet'] if what == 'wind_ts': if 'xi' in kargs.keys() and 'eta' in kargs.keys(): xi = kargs['xi'] eta = kargs['eta'] elif 'lon' in kargs.keys() and 'lat' in kargs.keys(): d = (self.grid.lon - kargs['lon'])**2 + (self.grid.lat - kargs['lat'])**2 i, j = np.where(d == d.min()) eta = i[0] xi = j[0] u = self.use('uwnd', xi_rho=xi, eta_rho=eta) v = self.use('vwnd', xi_rho=xi, eta_rho=eta) ang = self.grid.angle[eta, xi] * np.ones(u.shape) u, v = calc.rot2d(u, v, -ang) tdays = self.tdays if not day is False: ndays = self.tdays[-1] - self.tdays[0] n = int(86400 / self.dt) u = u[day * n:(day + 1) * n] v = v[day * n:(day + 1) * n] tdays = tdays[day * n:(day + 1) * n] return tdays, u, v elif what == 'wind': if 'uwnd' in netcdf.varnames(self.name): u = self.use('uwnd') v = self.use('vwnd') else: u = self.use('Uwind') v = self.use('Vwind') if time == 'mean' and u.ndim == 3: u = u.mean(0) v = v.mean(0) elif time == 'dailyMean' and u.ndim == 3: ndays = self.tdays[-1] - self.tdays[0] n = int(86400 / self.dt) if not day is False: if day == -1: day = ndays - 1 # this is wrong if there is data missing! u = u[day * n:(day + 1) * n, ...].mean(0) v = v[day * n:(day + 1) * n, ...].mean(0) else: U = range(ndays) V = range(ndays) for i in range(ndays): U[i] = u[i * n:(i + 1) * n, ...].mean(0) V[i] = v[i * n:(i + 1) * n, ...].mean(0) u = U v = V elif not time is False and isinstance(time, int) and u.ndim == 3: u = u[time, ...] v = v[time, ...] if isinstance(u, list): for i in range(len(u)): u[i], v[i] = calc.rot2d(u[i], v[i], -self.grid.angle) else: if u.ndim == 3: for i in range(u.shape[0]): u[i, ...], v[i, ...] = calc.rot2d(u[i, ...], v[i, ...], -self.grid.angle) elif u.ndim == 2: u, v = calc.rot2d(u, v, -self.grid.angle) if self.grid: x = self.grid.lon y = self.grid.lat m = self.grid.mask return x, y, u, v, m else: return u, v elif what == 'data': out = {} args = {} if not time is False: args['bulk_time'] = time if not quiet: print('loading Blk data time=', time) print('* * * * * * * * * * * *.') if not quiet: print('*'), out['tair'] = self.use('tair', **args) if not quiet: print('*'), out['rhum'] = self.use('rhum', **args) if not quiet: print('*'), out['pres'] = self.use('pres', **args) if not quiet: print('*'), out['prate'] = self.use('prate', **args) if not quiet: print('*'), out['radsw'] = self.use('radsw', **args) if not quiet: print('*'), out['radlw'] = self.use('radlw', **args) if not quiet: print('*'), out['dlwrf'] = self.use('dlwrf', **args) if not quiet: print('*'), out['uwnd'] = self.use('uwnd', **args) if not quiet: print('*'), out['vwnd'] = self.use('vwnd', **args) if not quiet: print('*'), out['sustr'] = self.use('sustr', **args) if not quiet: print('*'), out['svstr'] = self.use('svstr', **args) if not quiet: print('*.') out['wspd'] = self.use('wspd', **args) blktime = self.use('bulk_time', **args) t0 = self.atts['t0'] return out, blktime, t0
def frc2gnome(fname, frc, grd, xylim=False, dates=False, ij=(1, 1), **kargs): ''' Creates GNOME wind file kargs: t[u,v]var t[u,v]dim x[y,ang]var Ex: .frc2gnome(out,frc,grd,ij=(10,10),dates=dates,**{'tdim':'Time'}) ''' deta, dxi = ij tvar = 'time' uvar = 'Uwind' vvar = 'Vwind' #tvar='bulk_time' #uvar='uwnd' #vvar='vwnd' tdim = 'time' #tdim='bulk_time' xdim = 'xi_rho' ydim = 'eta_rho' xvar = 'lon_rho' yvar = 'lat_rho' angvar = 'angle' if 'tvar' in kargs.keys(): tvar = kargs['tvar'] if 'uvar' in kargs.keys(): uvar = kargs['uvar'] if 'vvar' in kargs.keys(): vvar = kargs['vvar'] if 'tdim' in kargs.keys(): tdim = kargs['tdim'] if 'xdim' in kargs.keys(): xdim = kargs['xdim'] if 'ydim' in kargs.keys(): ydim = kargs['ydim'] if 'xvar' in kargs.keys(): xvar = kargs['xvar'] if 'yvar' in kargs.keys(): yvar = kargs['yvar'] if 'angvar' in kargs.keys(): angvar = kargs['angvar'] dims = netcdf.fdim(grd) xi, eta = dims[xdim], dims[ydim] xi0, eta0 = xi, eta ncg = netcdf.ncopen(grd) nc0 = netcdf.ncopen(frc) try: t = netcdf.nctime(nc0, tvar) except: t = netcdf.use(nc0, tvar) t = netcdf.num2date(t, 'days since %d-01-01' % year0) time = netcdf.date2num(t, tunits) x0 = netcdf.use(grd, xvar) y0 = netcdf.use(grd, yvar) if x0.ndim == 1: x0, y0 = np.meshgrid(x0, y0) if angvar: ang = netcdf.use(grd, angvar) if not xylim is False: xlim = xylim[:2] ylim = xylim[2:] i1, i2, j1, j2 = calc.ij_limits(x0, y0, xlim, ylim) xi = i2 - i1 eta = j2 - j1 else: i1, i2 = 0, xi j1, j2 = 0, eta XI = '%d:%d:%d' % (i1, i2, dxi) ETA = '%d:%d:%d' % (j1, j2, deta) xi = len(range(i1, i2, dxi)) eta = len(range(j1, j2, deta)) # create file: create_wind(fname, xi, eta) nc = netcdf.ncopen(fname, 'a') x = x0[j1:j2:deta, i1:i2:dxi] y = y0[j1:j2:deta, i1:i2:dxi] nc.vars['lon'][:] = x nc.vars['lat'][:] = y if angvar: ang = ang[j1:j2:deta, i1:i2:dxi] n = -1 for it in range(len(time)): if not dates is False: d0, d1 = dates if t[it] < d0 or t[it] >= d1: continue n += 1 u = netcdf.use(nc0, uvar, **{xdim: XI, ydim: ETA, tdim: it}) v = netcdf.use(nc0, vvar, **{xdim: XI, ydim: ETA, tdim: it}) # rotate uv: if angvar: print('rotating ...') u, v = calc.rot2d(u, v, -ang) nc.vars['time'][n] = time[it] print('filling uv', n, t[it]) nc.vars['air_u'][n, ...] = u nc.vars['air_v'][n, ...] = v nc.close() nc0.close() ncg.close()
def his2gnome(fname, his, grd=False, nomask=False, gshhsMask=True, xylim=False, dates=False, ij=(1, 1)): ''' Creates GNOME wind file Ex: his2gnome(out,his,grd,dates=dates,ij=(2,2)) if gshhsMask, the high res mask file mask_gshhs.npy will be created at 1st usage. Mask is based on high (h) resolution gshhs data which must be available (env variable GSHHS_MASK must be set). ''' if not grd: grd = his deta, dxi = ij dims = netcdf.fdim(his) xi, eta = dims['xi_rho'], dims['eta_rho'] xi0, eta0 = xi, eta nc0 = netcdf.ncopen(his) time = netcdf.nctime(nc0, 'ocean_time') # for roms agrif: #t=netcdf.use(nc0,'scrum_time') #time=netcdf.num2date(t,'seconds since %d-01-01' % year0) x0 = netcdf.use(grd, 'lon_rho') y0 = netcdf.use(grd, 'lat_rho') ang = netcdf.use(grd, 'angle') if not xylim is False: xlim = xylim[:2] ylim = xylim[2:] i1, i2, j1, j2 = calc.ij_limits(x0, y0, xlim, ylim) print(i1, i2, j1, j2) xi = i2 - i1 eta = j2 - j1 else: i1, i2 = 0, xi j1, j2 = 0, eta XI = '%d:%d:%d' % (i1, i2, dxi) ETA = '%d:%d:%d' % (j1, j2, deta) xi = len(range(i1, i2, dxi)) eta = len(range(j1, j2, deta)) # create file: create_uv(fname, xi, eta) nc = netcdf.ncopen(fname, 'a') for v0, v in ('lon_rho', 'lon'), ('lat_rho', 'lat'), ('mask_rho', 'mask'), ('h', 'depth'): print('filling %s with %s' % (v, v0)) nc.vars[v][:] = netcdf.use(grd, v0, xi_rho=XI, eta_rho=ETA) if nomask: print('NO MASK !!!') nc.vars['mask'][:] = 1 if gshhsMask: try: mask = np.load('mask_gshhs.npy') except: mask = 1 + 0 * netcdf.use(nc0, 'mask_rho', xi_rho=XI, eta_rho=ETA) mask = mask.astype('bool') x = netcdf.use(grd, 'lon_rho', xi_rho=XI, eta_rho=ETA) y = netcdf.use(grd, 'lat_rho', xi_rho=XI, eta_rho=ETA) from okean import gshhs axis = x.min(), x.max(), y.min(), y.max() g = gshhs.gshhs(axis, resolution='h', area_thresh=0., max_level=2, clip=True) for lon, lat, level in zip(g.lon, g.lat, g.level): if level == 1: # land print('mask ', lon.shape) i = calc.inpolygon(x, y, lon, lat) mask = mask & ~i mask.dump('mask_gshhs.npy') nc.vars['mask'][:] = mask x = x0[j1:j2:deta, i1:i2:dxi] y = y0[j1:j2:deta, i1:i2:dxi] ang = ang[j1:j2:deta, i1:i2:dxi] n = -1 for it in range(len(time)): if not dates is False: d0, d1 = dates if time[it] < d0 or time[it] >= d1: continue n += 1 U = np.zeros((eta0, xi0), 'f') V = np.zeros((eta0, xi0), 'f') nc.vars['time'][n] = netcdf.date2num(time[it], tunits) # for roms agrif: #u=netcdf.use(nc0,'u',time=it,s_rho=-1) #v=netcdf.use(nc0,'v',time=it,s_rho=-1) u = netcdf.use(nc0, 'u', ocean_time=it, s_rho=-1) v = netcdf.use(nc0, 'v', ocean_time=it, s_rho=-1) # mask extrap: print('mask extrap...') u = calc.mask_extrap(x0, y0, np.ma.masked_where(u == 0, u)) v = calc.mask_extrap(x0, y0, np.ma.masked_where(v == 0, v)) U[:, 1:-1] = 0.5 * (u[:, :-1] + u[:, 1:]) U[:, 0] = u[:, 0] U[:, -1] = u[:, -1] V[1:-1, :] = 0.5 * (v[:-1.:] + v[1:, :]) V[0, :] = v[0, :] V[-1, :] = v[-1, :] U = U[j1:j2, i1:i2] V = V[j1:j2, i1:i2] U = U[j1:j2:deta, i1:i2:dxi] V = V[j1:j2:deta, i1:i2:dxi] # rotate uv: print('rotating ...') U, V = calc.rot2d(U, V, -ang) print('filling uv', n, time[it]) nc.vars['u'][n, ...] = U nc.vars['v'][n, ...] = V nc.close() nc0.close()
def roms2roms(f0,grd,sparams,tind=0,**kargs): ''' tind: ind or datetime **kargs: grd0 sparams0 tunits0 quiet ''' grd0 = False sparams0 = False quiet = False tunits0 = False Z='auto' ij='i' for k in kargs.keys(): if k=='grd0': grd0 = kargs[k] elif k=='sparams0': sparams0 = kargs['sparams0'] elif k=='quiet': quiet = kargs['quiet'] elif k=='tunits0': tunits0 = kargs['tunits0'] elif k=='Z': Z = kargs['Z'] elif k=='ij': ij = kargs['ij'] r0=roms.His(f0,grd=grd0) g0=r0.grid g1=roms.Grid(grd) if sparams0 is False: sparams0=r0.s_params # load data: F0={} for i in ('temp','salt','u','v','ssh','time','misc'): F0[i]=f0 F0['xy']=g0.name if tind=='all': times=range(r0.TIME) else: times=[tind] xlim=g1.lon.min(),g1.lon.max() ylim=g1.lat.min(),g1.lat.max() inds={} outdata={} outdatab={} for tind in times: inds[sett.tdim]=tind data,msg=prognostic.load_data(F0,quiet=quiet,settings=sett,inds=inds,t_units=tunits0) # z3d: data['z3d']=r0.s_levels(tind) # u,v at rho: print ' u,v at rho ...' u=np.ma.zeros((data['NZ'],data['NY'],data['NX']),data['u'].dtype) v=np.ma.zeros((data['NZ'],data['NY'],data['NX']),data['v'].dtype) u[:,:,1:-1]=(data['u'][:,:,:-1]+data['u'][:,:,1:])/2. u[:,:,0]=data['u'][:,:,0] u[:,:,-1]=data['u'][:,:,-1] v[:,1:-1,:]=(data['v'][:,:-1,:]+data['v'][:,1:,:])/2. v[:,0,:]=data['v'][:,0,:] v[:,-1,:]=data['v'][:,-1,:] print 'rot 2d from original grid' for k in range(v.shape[0]): u[k],v[k]=calc.rot2d(u[k],v[k],-g0.angle) data['u']=u data['v']=v # simplify data: print ' simplify data...' i0,i1,j0,j1=calc.ij_limits(g0.lon,g0.lat,xlim,ylim,margin=3) for v in 'z3d','temp','salt','u','v': data[v]=data[v][:,j0:j1,i0:i1] for v in 'ssh','lon','lat': data[v]=data[v][j0:j1,i0:i1] data['NZ'],data['NY'],data['NX']=data['temp'].shape # interp depths: if Z is 'auto': h=-g0.h Z=np.concatenate((np.arange(data['ssh'].max(),-2,-.05),np.arange(-2,-5,.2),np.arange(-5,-20,-1),np.arange(-20,-100,-2), np.arange(-100,-500,-5),np.arange(-500,-1000,-20),np.arange(-1000,h.min()-100,-100))) Z=Z[::3] if Z[-1]>h.min(): Z[-1]=h.min() data['depth']=Z for v in 'temp','salt','u','v','ssh': print ' %-6s %6.3f %6.3f'%(v,data[v].min(), data[v].max()) # to z levels: Data=prognostic.data2z(data,quiet=quiet,ij=ij) for v in 'temp','salt','u','v','ssh': print ' %-6s %6.3f %6.3f'%(v,Data[v].min(), Data[v].max()) # clm: data,HA=prognostic.data2roms(Data,grd,sparams,quiet=quiet,horizAux=True,ij=ij) for v in 'temp','salt','u','v','zeta': print ' %-6s %6.3f %6.3f'%(v,data[v].min(), data[v].max()) # bry: datab=prognostic.data2romsbry(Data,grd,sparams,quiet=quiet,horizAux=HA) outdata[tind] = data outdatab[tind] = datab if len(times)==1: return outdata[tind],outdatab[tind] else: return outdata,outdatab
def frc2gnome(fname,frc,grd,xylim=False,dates=False,ij=(1,1),**kargs): ''' Creates GNOME wind file kargs: t[u,v]var t[u,v]dim x[y,ang]var Ex: .frc2gnome(out,frc,grd,ij=(10,10),dates=dates,**{'tdim':'Time'}) ''' deta,dxi=ij tvar='time' uvar='Uwind' vvar='Vwind' #tvar='bulk_time' #uvar='uwnd' #vvar='vwnd' tdim='time' #tdim='bulk_time' xdim='xi_rho' ydim='eta_rho' xvar='lon_rho' yvar='lat_rho' angvar='angle' if 'tvar' in kargs.keys(): tvar=kargs['tvar'] if 'uvar' in kargs.keys(): uvar=kargs['uvar'] if 'vvar' in kargs.keys(): vvar=kargs['vvar'] if 'tdim' in kargs.keys(): tdim=kargs['tdim'] if 'xdim' in kargs.keys(): xdim=kargs['xdim'] if 'ydim' in kargs.keys(): ydim=kargs['ydim'] if 'xvar' in kargs.keys(): xvar=kargs['xvar'] if 'yvar' in kargs.keys(): yvar=kargs['yvar'] if 'angvar' in kargs.keys(): angvar=kargs['angvar'] dims=netcdf.fdim(grd) xi,eta=dims[xdim],dims[ydim] xi0,eta0=xi,eta ncg=netcdf.ncopen(grd) nc0=netcdf.ncopen(frc) try: t=netcdf.nctime(nc0,tvar) except: t=netcdf.use(nc0,tvar) t=netcdf.num2date(t,'days since %d-01-01' % year0) time=netcdf.date2num(t,tunits) x0=netcdf.use(grd,xvar) y0=netcdf.use(grd,yvar) if x0.ndim==1: x0,y0=np.meshgrid(x0,y0) if angvar: ang=netcdf.use(grd,angvar) if not xylim is False: xlim=xylim[:2] ylim=xylim[2:] i1,i2,j1,j2=calc.ij_limits(x0,y0,xlim,ylim) xi=i2-i1 eta=j2-j1 else: i1,i2=0,xi j1,j2=0,eta XI ='%d:%d:%d' %(i1,i2,dxi) ETA ='%d:%d:%d' %(j1,j2,deta) xi=len(range(i1,i2,dxi)) eta=len(range(j1,j2,deta)) # create file: create_wind(fname,xi,eta) nc=netcdf.ncopen(fname,'a') x=x0[j1:j2:deta,i1:i2:dxi] y=y0[j1:j2:deta,i1:i2:dxi] nc.vars['lon'][:]=x nc.vars['lat'][:]=y if angvar: ang=ang[j1:j2:deta,i1:i2:dxi] n=-1 for it in range(len(time)): if not dates is False: d0,d1=dates if t[it]<d0 or t[it]>=d1: continue n+=1 u=netcdf.use(nc0,uvar,**{xdim:XI,ydim:ETA,tdim:it}) v=netcdf.use(nc0,vvar,**{xdim:XI,ydim:ETA,tdim:it}) # rotate uv: if angvar: print 'rotating ...' u,v=calc.rot2d(u,v,-ang) nc.vars['time'][n]=time[it] print 'filling uv',n,t[it] nc.vars['air_u'][n,...]=u nc.vars['air_v'][n,...]=v nc.close() nc0.close() ncg.close()
def get(self,what,**kargs): time=False day=False quiet=True keys=kargs.keys() if 'time' in keys: time = kargs['time'] if 'day' in keys: day = kargs['day'] if 'quiet' in keys: quiet = kargs['quiet'] if what=='wind_ts': if 'xi' in kargs.keys() and 'eta' in kargs.keys(): xi=kargs['xi'] eta=kargs['eta'] elif 'lon' in kargs.keys() and 'lat' in kargs.keys(): d=(self.grid.lon-kargs['lon'])**2+(self.grid.lat-kargs['lat'])**2 i,j=np.where(d==d.min()) eta=i[0] xi=j[0] u=self.use('uwnd',xi_rho=xi,eta_rho=eta) v=self.use('vwnd',xi_rho=xi,eta_rho=eta) ang=self.grid.angle[eta,xi]*np.ones(u.shape) u,v=calc.rot2d(u,v,-ang) tdays=self.tdays if not day is False: ndays=self.tdays[-1]-self.tdays[0] n=int(86400/self.dt) u=u[day*n:(day+1)*n] v=v[day*n:(day+1)*n] tdays=tdays[day*n:(day+1)*n] return tdays,u,v elif what=='wind': if 'uwnd' in netcdf.varnames(self.name): u=self.use('uwnd') v=self.use('vwnd') else: u=self.use('Uwind') v=self.use('Vwind') if time=='mean' and u.ndim==3: u=u.mean(0) v=v.mean(0) elif time=='dailyMean' and u.ndim==3: ndays=self.tdays[-1]-self.tdays[0] n=int(86400/self.dt) if not day is False: if day==-1: day=ndays-1 # this is wrong if there is data missing! u=u[day*n:(day+1)*n,...].mean(0) v=v[day*n:(day+1)*n,...].mean(0) else: U=range(ndays) V=range(ndays) for i in range(ndays): U[i]=u[i*n:(i+1)*n,...].mean(0) V[i]=v[i*n:(i+1)*n,...].mean(0) u=U v=V elif not time is False and isinstance(time,int) and u.ndim==3: u=u[time,...] v=v[time,...] if isinstance(u,list): for i in range(len(u)): u[i],v[i]=calc.rot2d(u[i],v[i],-self.grid.angle) else: if u.ndim==3: for i in range(u.shape[0]): u[i,...],v[i,...]=calc.rot2d(u[i,...],v[i,...],-self.grid.angle) elif u.ndim==2: u,v=calc.rot2d(u,v,-self.grid.angle) if self.grid: x=self.grid.lon y=self.grid.lat m=self.grid.mask return x,y,u,v,m else: return u,v elif what=='data': out={} args={} if not time is False: args['bulk_time']=time if not quiet: print('loading Blk data time=',time) print('* * * * * * * * * * * *.') if not quiet: print('*'), out['tair'] = self.use('tair', **args) if not quiet: print('*'), out['rhum'] = self.use('rhum', **args) if not quiet: print('*'), out['pres'] = self.use('pres', **args) if not quiet: print('*'), out['prate'] = self.use('prate', **args) if not quiet: print('*'), out['radsw'] = self.use('radsw', **args) if not quiet: print('*'), out['radlw'] = self.use('radlw', **args) if not quiet: print('*'), out['dlwrf'] = self.use('dlwrf', **args) if not quiet: print('*'), out['uwnd'] = self.use('uwnd', **args) if not quiet: print('*'), out['vwnd'] = self.use('vwnd', **args) if not quiet: print('*'), out['sustr'] = self.use('sustr', **args) if not quiet: print('*'), out['svstr'] = self.use('svstr', **args) if not quiet: print('*.') out['wspd'] = self.use('wspd', **args) blktime=self.use('bulk_time',**args) t0=self.atts['t0'] return out,blktime,t0
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 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 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 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 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 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 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 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 his2gnome(fname,his,grd=False,nomask=False,gshhsMask=True,xylim=False,dates=False,ij=(1,1)): ''' Creates GNOME wind file Ex: his2gnome(out,his,grd,dates=dates,ij=(2,2)) if gshhsMask, the high res mask file mask_gshhs.npy will be created at 1st usage. Mask is based on high (h) resolution gshhs data which must be available (env variable GSHHS_MASK must be set). ''' if not grd: grd=his deta,dxi=ij dims=netcdf.fdim(his) xi,eta=dims['xi_rho'],dims['eta_rho'] xi0,eta0=xi,eta nc0=netcdf.ncopen(his) time=netcdf.nctime(nc0,'ocean_time') # for roms agrif: #t=netcdf.use(nc0,'scrum_time') #time=netcdf.num2date(t,'seconds since %d-01-01' % year0) x0=netcdf.use(grd,'lon_rho') y0=netcdf.use(grd,'lat_rho') ang=netcdf.use(grd,'angle') if not xylim is False: xlim=xylim[:2] ylim=xylim[2:] i1,i2,j1,j2=calc.ij_limits(x0,y0,xlim,ylim) print i1,i2,j1,j2 xi=i2-i1 eta=j2-j1 else: i1,i2=0,xi j1,j2=0,eta XI ='%d:%d:%d' %(i1,i2,dxi) ETA ='%d:%d:%d' %(j1,j2,deta) xi=len(range(i1,i2,dxi)) eta=len(range(j1,j2,deta)) # create file: create_uv(fname,xi,eta) nc=netcdf.ncopen(fname,'a') for v0,v in ('lon_rho','lon'),('lat_rho','lat'),('mask_rho','mask'),('h','depth'): print 'filling %s with %s' % (v,v0) nc.vars[v][:]=netcdf.use(grd,v0,xi_rho=XI,eta_rho=ETA) if nomask: print 'NO MASK !!!' nc.vars['mask'][:]=1 if gshhsMask: try: mask=np.load('mask_gshhs.npy') except: mask=1+0*netcdf.use(nc0,'mask_rho',xi_rho=XI,eta_rho=ETA) mask=mask.astype('bool') x=netcdf.use(grd,'lon_rho',xi_rho=XI,eta_rho=ETA) y=netcdf.use(grd,'lat_rho',xi_rho=XI,eta_rho=ETA) from okean import gshhs axis=x.min(),x.max(),y.min(),y.max() g=gshhs.gshhs(axis, resolution='h',area_thresh=0., max_level=2,clip=True) for lon, lat, level in zip(g.lon, g.lat, g.level): if level == 1: # land print 'mask ',lon.shape i=calc.inpolygon(x,y,lon,lat) mask=mask & ~i mask.dump('mask_gshhs.npy') nc.vars['mask'][:]=mask x=x0[j1:j2:deta,i1:i2:dxi] y=y0[j1:j2:deta,i1:i2:dxi] ang=ang[j1:j2:deta,i1:i2:dxi] n=-1 for it in range(len(time)): if not dates is False: d0,d1=dates if time[it]<d0 or time[it]>=d1: continue n+=1 U=np.zeros((eta0,xi0),'f') V=np.zeros((eta0,xi0),'f') nc.vars['time'][n]=netcdf.date2num(time[it],tunits) # for roms agrif: #u=netcdf.use(nc0,'u',time=it,s_rho=-1) #v=netcdf.use(nc0,'v',time=it,s_rho=-1) u=netcdf.use(nc0,'u',ocean_time=it,s_rho=-1) v=netcdf.use(nc0,'v',ocean_time=it,s_rho=-1) # mask extrap: print 'mask extrap...' u=calc.mask_extrap(x0,y0,np.ma.masked_where(u==0,u)) v=calc.mask_extrap(x0,y0,np.ma.masked_where(v==0,v)) U[:,1:-1]=0.5*(u[:,:-1]+u[:,1:]) U[:,0]=u[:,0] U[:,-1]=u[:,-1] V[1:-1,:]=0.5*(v[:-1.:]+v[1:,:]) V[0,:]=v[0,:] V[-1,:]=v[-1,:] U=U[j1:j2,i1:i2] V=V[j1:j2,i1:i2] U=U[j1:j2:deta,i1:i2:dxi] V=V[j1:j2:deta,i1:i2:dxi] # rotate uv: print 'rotating ...' U,V=calc.rot2d(U,V,-ang) print 'filling uv', n, time[it] nc.vars['u'][n,...]=U nc.vars['v'][n,...]=V nc.close() nc0.close()
def extract(self,varname,method='fast',nfast=1,quiet=1): if not self.roms.hast(varname): method,nfast='fast',1 tag=self.horiz_var_type(varname) if tag in self.uinds.keys(): inds0=self.inds0[tag] uinds=self.uinds[tag] else: inds0,uinds=self.locate(varname,quiet) J,I,T = uinds.T J0,I0,T0 = inds0.T if not self.roms.hast(varname): no_time=True else: no_time=False if method=='fast': # faster but will download more data than needed! II=range(I.min(),I.max()+1) JJ=range(J.min(),J.max()+1) TT=range(T[T>=0].min(),T.max()+1) if not calc.isiterable(nfast) and nfast==1: if not quiet: print('loading %s : ijt= %d %d %d'%(varname,len(II),len(JJ),len(TT))) v=netcdf.use(self.nc,varname,xiSEARCH=II,etaSEARCH=JJ,ocean_time=TT) else: v=False if not calc.isiterable(nfast): nfast=min(nfast,len(TT)-1) tmp=range(TT[0],TT[-1]+2,(TT[-1]-TT[0])/nfast) if tmp[-1]<TT[-1]+1: tmp+=[TT[-1]+1] else: tmp=nfast for k in range(len(tmp)-1): tt=range(tmp[k],tmp[k+1]) if not quiet: print('loading %s : ijt= %d %d %d (t %d to %d)'%(varname,len(II),len(JJ),len(tt), tt[0],tt[-1])) vtmp=netcdf.use(self.nc,varname,xiSEARCH=II,etaSEARCH=JJ,ocean_time=tt) if not v is False: if vtmp.ndim<v.ndim: vtmp=vtmp[np.newaxis,:] # if len of last tt is 1 ! v=np.vstack((v,vtmp)) else: v=vtmp if v.ndim>3: V=np.ma.zeros((I.size,v.shape[1]),'f') else: V=np.ma.zeros(I.size,'f') for i in range(I.size): xi = I[i]-I.min() eta = J[i]-J.min() if T[i]>=0: tind = T[i]-T[T>=0].min() else: tind=T[i] # negative means data ouside model time if v.ndim==4: V[i]=v[tind,:,eta,xi] elif v.ndim==3: V[i]=v[tind,eta,xi] elif v.ndim==2: V[i]=v[eta,xi] else: V=False for i in range(len(I)): if T[i]<0: continue if not quiet: print('loading %s (%d of %d): ijt= %d %d %d'%(varname,i,len(I),I[i],J[i],T[i])) v=netcdf.use(self.nc,varname,xiSEARCH=I[i],etaSEARCH=J[i],ocean_time=T[i]) if V is False: if v.ndim>1: shape=(len(I),)+v.shape else: shape=len(I) V=np.ma.zeros(shape,'f') V[i]=v lon,lat=self.model_lon_lat(varname) U=np.array(()) for i in range(len(self.t)): xi = I0[i] eta = J0[i] tind = T0[i] if tind<0: continue # data outside model time # rotate cell before interp: xp=np.asarray([lon[eta,xi],lon[eta,xi+1],lon[eta+1,xi+1],lon[eta+1,xi],self.x[i]]) yp=np.asarray([lat[eta,xi],lat[eta,xi+1],lat[eta+1,xi+1],lat[eta+1,xi],self.y[i]]) xp,yp=calc.rot2d(xp,yp,self.roms.grid.angle[eta,xi]) x=xp[:-1].min(),xp[-1],xp[:-1].max() y=yp[:-1].min(),yp[-1],yp[:-1].max() A = x[1]-x[0] a = x[2]-x[1] B = y[1]-y[0] b = y[2]-y[1] tcond=(T==tind)#|(tind<0) tcond1=(T==tind+1)#|(tind+1<0) j0=np.where((I==xi)&(J==eta)&tcond)[0][0] j1=np.where((I==xi+1)&(J==eta)&tcond)[0][0] j2=np.where((I==xi+1)&(J==eta+1)&tcond)[0][0] j3=np.where((I==xi)&(J==eta+1)&tcond)[0][0] u0=(V[j0]*a*b+V[j1]*A*b+V[j2]*A*B+V[j3]*a*B)/(a*b+A*b+A*B+a*B) if not no_time: dt0=self.t[i]-self.roms.time[tind] dt1=self.roms.time[tind+1]-self.t[i] dt0=dt0.days*86400+dt0.seconds dt1=dt1.days*86400+dt1.seconds k0=np.where((I==xi)&(J==eta)&tcond1)[0][0] k1=np.where((I==xi+1)&(J==eta)&tcond1)[0][0] k2=np.where((I==xi+1)&(J==eta+1)&tcond1)[0][0] k3=np.where((I==xi)&(J==eta+1)&tcond1)[0][0] u1=(V[k0]*a*b+V[k1]*A*b+V[k2]*A*B+V[k3]*a*B)/(a*b+A*b+A*B+a*B) u=(u0*dt1+u1*dt0)/(dt1+dt0) else: u=u0 if not U.size: U=np.ma.zeros((len(self.t),u.size),'f') U=np.ma.masked_where(U==0,U) U[i]=u U=np.squeeze(U) return U
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