def slice_derived(self,var,ind,time,**opts): plot= opts.get('plot',False) ax = opts.get('ax',None) if not isinstance(ind,dict): # slicez,k coords=opts.get('coords','x,y,t').split(',') else: # slicell coords=opts.get('coords','d,z,t').split(',') out=Data() out.msg=self.check_slice('u',t=time) # any time dependent var could be # used here! if out.msg: return out if var in ('div','divergence','diverg'): var='hdiv' if var in ('vort','vorticity','rel vort'): var='rvort' if not isinstance(ind,dict): # horizontal slices, else, slicell if var in ('speed','ke'): outuv=self.sliceuv(ind,time,**opts) if outuv.msg: return outuv if var=='speed': res=phys.speed(*outuv.v) elif var=='ke': res=phys.ke(*outuv.v) out=outuv out.v=res out.info['v']['name']=var if var=='speed': out.info['v']['units']='metre second-1' elif var=='ke': out.info['v']['units']='metre2 second-2' return out elif var in ('okubo','hdiv','rvort'): if ind>=0: slc=self.slicek else: slc=self.slicez if ind=='bar': uname,vname,ind='ubar','vbar',0 else: uname,vname='u','v' outu=slc(uname,ind,time,**opts) outv=slc(vname,ind,time,**opts) if outu.msg: return outu elif outv.msg: return outv # coords at rho needed for okubo','hdiv','rvort,so: if any([i in coords for i in 'xy']): x,y,h,m=self.grid.vars(ruvp='r') if 'x' in coords: if self.grid.use('spherical') in (1,'T'): out.x=x out.info['x']=dict(name='Longitude',units=r'$\^o$E') else: out.x=x/1000. out.info['x']=dict(name='Distance',units='km') if 'y' in coords: if self.grid.use('spherical') in (1,'T'): out.y=y out.info['y']=dict(name='Latitude',units=r'$\^o$N') else: out.y=y/1000. out.info['y']=dict(name='Distance',units='km') if 't' in coords: out.t=self.time[time] if 'z' in coords and self.hasz(uname): out.z=self.s_levels(time,k=ind,ruvpw='r') out.info['z']=dict(name='Depth',units='m') if var=='okubo': res=phys.okubo(outu.v,outv.v,self.grid.pm,self.grid.pn) out.v=res out.info['v']['name']=var out.info['v']['units']='second-2' elif var=='hdiv': res=phys.hor_div(outu.v,outv.v,self.grid.pm,self.grid.pn) out.v=res out.info['v']['name']=var out.info['v']['units']='second-1' if not out.x is None: out.x=out.x[1:-1,1:-1] if not out.y is None: out.y=out.y[1:-1,1:-1] if not out.z is None: out.z=out.z[1:-1,1:-1] elif var=='rvort': res=phys.vorticity(outu.v,outv.v,self.grid.pm,self.grid.pn) out.v=res out.info['v']['name']=var out.info['v']['units']='second-1' out.coordsReq=','.join(sorted(coords)) return out else: # slice ll: print 'TODO !!!!' return out
def slicez(self,varname,ind,time=0,**opts): if not self.hasz(varname): return self.slicek(varname,ind,time,**opts) surf_nans=opts.get('surf_nans',True) spline=opts.get('spline',True) coords=opts.get('coords',self._default_coords('slicez')).split(',') out=Data() out.msg=self.check_slice(varname,t=time) if out.msg: return out##None,au v=self.use(varname,SEARCHtime=time) x,y,h,m=self.grid.vars(ruvp=self.var_at(varname)[0]) zeta=self.use('zeta',SEARCHtime=time) zeta=rt.rho2uvp(zeta,varname) out.v=rt.slicez(v,m,h,zeta,self.s_params,ind,surf_nans,spline) out.info['v']['name']=varname if calc.isarray(ind): out.info['v']['slice']='z= array %.2f to %.2f'%(ind.min(),ind.max()) else: out.info['v']['slice']='z=%d'%ind try: out.info['v']['units']=netcdf.vatt(self.nc,varname,'units') except: pass # coords: if 'x' in coords: if self.grid.is_spherical: out.x=x out.info['x']=dict(name='Longitude',units=r'$\^o$E') else: out.x=x/1000. out.info['x']=dict(name='Distance',units='km') if 'y' in coords: if self.grid.is_spherical: out.y=y out.info['y']=dict(name='Latitude',units=r'$\^o$N') else: out.y=y/1000. out.info['y']=dict(name='Distance',units='km') if 'z' in coords: out.z=ind+np.zeros(out.v.shape) out.info['z']=dict(name='Depth',units='m') if 't' in coords and self.hast(varname): out.t=self.time[time] if v.ndim==2: out.extra=[Data()] if 'x' in coords: out.extra[0].x=out.x if 'y' in coords: out.extra[0].y=out.y out.extra[0].v=h if h.max()>1000: cvals=200.,1000. elif h.max()>200: cvals=50.,100.,200. else: cvals=3 out.extra[0].config['field.plot']='contour' out.extra[0].config['field.cvals']=cvals out.extra[0].config['field.linecolors']='k' out.extra[0].alias='bathy' out.coordsReq=','.join(sorted(coords)) return out
def slice_derived(self, var, ind, time, **opts): plot = opts.get('plot', False) ax = opts.get('ax', None) if not isinstance(ind, dict): # slicez,k coords = opts.get('coords', 'x,y,t').split(',') else: # slicell coords = opts.get('coords', 'd,z,t').split(',') out = Data() out.msg = self.check_slice('u', t=time) # any time dependent var could be # used here! if out.msg: return out if var in ('div', 'divergence', 'diverg'): var = 'hdiv' if var in ('vort', 'vorticity', 'rel vort'): var = 'rvort' if not isinstance(ind, dict): # horizontal slices, else, slicell if var in ('speed', 'ke'): outuv = self.sliceuv(ind, time, **opts) if outuv.msg: return outuv if var == 'speed': res = phys.speed(*outuv.v) elif var == 'ke': res = phys.ke(*outuv.v) out = outuv out.v = res out.info['v']['name'] = var if var == 'speed': out.info['v']['units'] = 'metre second-1' elif var == 'ke': out.info['v']['units'] = 'metre2 second-2' return out elif var in ('okubo', 'hdiv', 'rvort'): if ind >= 0: slc = self.slicek else: slc = self.slicez if ind == 'bar': uname, vname, ind = 'ubar', 'vbar', 0 else: uname, vname = 'u', 'v' outu = slc(uname, ind, time, **opts) outv = slc(vname, ind, time, **opts) if outu.msg: return outu elif outv.msg: return outv # coords at rho needed for okubo','hdiv','rvort,so: if any([i in coords for i in 'xy']): x, y, h, m = self.grid.vars(ruvp='r') if 'x' in coords: if self.grid.use('spherical') in (1, 'T'): out.x = x out.info['x'] = dict(name='Longitude', units=r'$\^o$E') else: out.x = x / 1000. out.info['x'] = dict(name='Distance', units='km') if 'y' in coords: if self.grid.use('spherical') in (1, 'T'): out.y = y out.info['y'] = dict(name='Latitude', units=r'$\^o$N') else: out.y = y / 1000. out.info['y'] = dict(name='Distance', units='km') if 't' in coords: out.t = self.time[time] if 'z' in coords and self.hasz(uname): out.z = self.s_levels(time, k=ind, ruvpw='r') out.info['z'] = dict(name='Depth', units='m') if var == 'okubo': res = phys.okubo(outu.v, outv.v, self.grid.pm, self.grid.pn) out.v = res out.info['v']['name'] = var out.info['v']['units'] = 'second-2' elif var == 'hdiv': res = phys.hor_div(outu.v, outv.v, self.grid.pm, self.grid.pn) out.v = res out.info['v']['name'] = var out.info['v']['units'] = 'second-1' if not out.x is None: out.x = out.x[1:-1, 1:-1] if not out.y is None: out.y = out.y[1:-1, 1:-1] if not out.z is None: out.z = out.z[1:-1, 1:-1] elif var == 'rvort': res = phys.vorticity(outu.v, outv.v, self.grid.pm, self.grid.pn) out.v = res out.info['v']['name'] = var out.info['v']['units'] = 'second-1' out.coordsReq = ','.join(sorted(coords)) return out else: # slice ll: print 'TODO !!!!' return out
def slicej(self,varname,ind,time=0,**opts): coords=opts.get('coords',self._default_coords('slicej')).split(',') out=Data() out.msg=self.check_slice(varname,t=time,j=ind) if out.msg: return out v=self.use(varname,SEARCHtime=time,eta_SEARCH=ind) # add mask if not masked: if not np.ma.isMA(v): m=self.grid.vars(ruvp=self.var_at(varname)[0],j=ind)[-1] if v.ndim==2: m=np.tile(m,(v.shape[0],1)) v=np.ma.masked_where(m==0,v) out.v=v out.info['v']['name']=varname out.info['v']['slice']='j=%d'%ind try: out.info['v']['units']=netcdf.vatt(self.name,varname,'units') except: pass # coords: if 'z' in coords and v.ndim==2: ###### out.z=self.s_levels(time=time,ruvpw=self.var_at(varname),j=ind) out.z=self.s_levels(time=time,loc=self.var_at(varname),j=ind) out.info['z']=dict(name='Depth',units='m') if any([i in coords for i in 'xyd']): x,y,h,m=self.grid.vars(ruvp=self.var_at(varname)[0],j=ind) 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 v.ndim==2: out.extra=[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] out.extra[0].v=-h out.extra[0].config['d1.plot']='fill_between' out.extra[0].config['d1.y0']=-h.max()-(h.max()-h.min())/20. out.extra[0].alias='bottom' out.coordsReq=','.join(sorted(coords)) return out
def slicek(self,varname,ind,time=0,**opts): coords=opts.get('coords',self._default_coords('slicek')).split(',') out=Data() out.msg=self.check_slice(varname,t=time,k=ind) if out.msg: out v=self.use(varname,SEARCHtime=time,s_SEARCH=ind) # add mask if not masked: if not np.ma.isMA(v): m=self.grid.vars(ruvp=self.var_at(varname)[0])[-1] v=np.ma.masked_where(m==0,v) out.v=v out.info['v']['name']=varname if self.hasz(varname): out.info['v']['slice']='k=%d'%ind try: out.info['v']['units']=netcdf.vatt(self.nc,varname,'units') except: pass # coords: if 'z' in coords and self.hasz(varname): ##### out.z=self.s_levels(time,k=ind,ruvpw=self.var_at(varname)) out.z=self.s_levels(time,k=ind,loc=self.var_at(varname)) out.info['z']=dict(name='Depth',units='m') if any([i in coords for i in 'xy']): x,y,h,m=self.grid.vars(ruvp=self.var_at(varname)[0]) if 'x' in coords: if self.grid.is_spherical: out.x=x out.info['x']=dict(name='Longitude',units=r'$\^o$E') else: out.x=x/1000. out.info['x']=dict(name='Distance',units='km') if 'y' in coords: if self.grid.is_spherical: out.y=y out.info['y']=dict(name='Latitude',units=r'$\^o$N') else: out.y=y/1000. out.info['y']=dict(name='Distance',units='km') if 't' in coords and self.hast(varname): out.t=self.time[time] if v.ndim==2: out.extra=[Data()] if 'x' in coords: out.extra[0].x=out.x if 'y' in coords: out.extra[0].y=out.y out.extra[0].v=h if h.max()>1000: cvals=200.,1000. elif h.max()>200: cvals=50.,100.,200. else: cvals=3 out.extra[0].config['field.plot']='contour' out.extra[0].config['field.cvals']=cvals out.extra[0].config['field.linecolors']='k' out.extra[0].alias='bathy' out.coordsReq=','.join(sorted(coords)) return out
def sliceiso(self,varname,iso,time,**opts): ''' Depths where variable, increasing/dec with depth, has some value. Output is masked where surface is higher/lower than value or where all water column is lower/higher than value. ''' coords=opts.get('coords',self._default_coords('sliceiso')).split(',') out=Data() out.msg=self.check_slice(varname,t=time) if out.msg: return out if not self.hasz(varname): out.msg='a depth dependent variable is needed for sliceiso!' return out v=self.use(varname,SEARCHtime=time) #### z=self.s_levels(time=time,ruvpw=self.var_at(varname)) z=self.s_levels(time=time,loc=self.var_at(varname)) v=rt.depthof(v,z,iso) out.v=v #out.info['v']['name']=varname out.info['v']['name']='depth' if isinstance(iso,np.ndarray) and iso.ndim==2: siso='2d' else: siso=str(iso) try: out.info['v']['slice']='%s (%s) iso=%s'%(varname,netcdf.vatt(self.nc,varname,'units'),siso) except: out.info['v']['slice']='%s iso=%s'%(varname,siso) out.info['v']['units']='metre' # coords: if any([i in coords for i in 'xy']): x,y,h=self.grid.vars(ruvp=self.var_at(varname))[:3] if 'x' in coords: if self.grid.is_spherical: out.x=x out.info['x']=dict(name='Longitude',units=r'$\^o$E') else: out.x=x/1000. out.info['x']=dict(name='Distance',units='km') if 'y' in coords: if self.grid.is_spherical: out.y=y out.info['y']=dict(name='Latitude',units=r'$\^o$N') else: out.y=y/1000. out.info['y']=dict(name='Distance',units='km') if 'z' in coords: # makes no sense... v is the depth! coords.remove('z') if 't' in coords and self.hast(varname): out.t=self.time[time] if v.ndim==2: out.extra=[Data()] if 'x' in coords: out.extra[0].x=out.x if 'y' in coords: out.extra[0].y=out.y out.extra[0].v=h if h.max()>1000: cvals=200.,1000. elif h.max()>200: cvals=50.,100.,200. else: cvals=3 out.extra[0].config['field.plot']='contour' out.extra[0].config['field.cvals']=cvals out.extra[0].config['field.linecolors']='k' out.extra[0].alias='bathy' out.coordsReq=','.join(sorted(coords)) return out
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 is 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=Data() 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)) 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): 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=np.squeeze(z) # depth slice: if isDepth and self.hasz(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,vm=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,spline=opts.get('spline',True)) v=np.ma.masked_where(vm,v) v=v[...,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 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 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.is_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.is_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 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 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 slicek(self,varname,ind,time=0,**opts): coords=opts.get('coords',self._default_coords('slicek')).split(',') out=Data() out.msg=self.check_slice(varname,t=time,k=ind) if out.msg: out v=self.use(varname,SEARCHtime=time,s_SEARCH=ind) # add mask if not masked: if not np.ma.isMA(v): m=self.grid.vars(ruvp=self.var_at(varname))[-1] v=np.ma.masked_where(m==0,v) out.v=v out.info['v']['name']=varname out.info['v']['slice']='k=%d'%ind try: out.info['v']['units']=netcdf.vatt(self.nc,varname,'units') except: pass # coords: if 'z' in coords and self.hasz(varname): out.z=self.s_levels(time,k=ind,ruvpw=self.var_at(varname)) out.info['z']=dict(name='Depth',units='m') if any([i in coords for i in 'xy']): x,y,h,m=self.grid.vars(ruvp=self.var_at(varname)) if 'x' in coords: if self.grid.is_spherical: out.x=x out.info['x']=dict(name='Longitude',units=r'$\^o$E') else: out.x=x/1000. out.info['x']=dict(name='Distance',units='km') if 'y' in coords: if self.grid.is_spherical: out.y=y out.info['y']=dict(name='Latitude',units=r'$\^o$N') else: out.y=y/1000. out.info['y']=dict(name='Distance',units='km') if 't' in coords: out.t=self.time[time] if v.ndim==2: out.extra=[Data()] if 'x' in coords: out.extra[0].x=out.x if 'y' in coords: out.extra[0].y=out.y out.extra[0].v=h if h.max()>1000: cvals=200.,1000. elif h.max()>200: cvals=50.,100.,200. else: cvals=3 out.extra[0].config['field.plot']='contour' out.extra[0].config['field.cvals']=cvals out.extra[0].config['field.linecolors']='k' out.extra[0].alias='bathy' out.coordsReq=','.join(sorted(coords)) return out
def slicez(self,varname,ind,time=0,**opts): if not self.hasz(varname): return self.slicek(varname,ind,time,**opts) surf_nans=opts.get('surf_nans',True) spline=opts.get('spline',True) coords=opts.get('coords',self._default_coords('slicez')).split(',') out=Data() out.msg=self.check_slice(varname,t=time) if out.msg: return out##None,au v=self.use(varname,SEARCHtime=time) x,y,h,m=self.grid.vars(ruvp=self.var_at(varname)) zeta=self.use('zeta',SEARCHtime=time) zeta=rt.rho2uvp(zeta,varname) v,mask=rt.slicez(v,m,h,zeta,self.s_params,ind,surf_nans,spline) v=np.ma.masked_where(mask,v) out.v=v out.info['v']['name']=varname out.info['v']['slice']='z=%d'%ind try: out.info['v']['units']=netcdf.vatt(self.nc,varname,'units') except: pass # coords: if 'x' in coords: if self.grid.is_spherical: out.x=x out.info['x']=dict(name='Longitude',units=r'$\^o$E') else: out.x=x/1000. out.info['x']=dict(name='Distance',units='km') if 'y' in coords: if self.grid.is_spherical: out.y=y out.info['y']=dict(name='Latitude',units=r'$\^o$N') else: out.y=y/1000. out.info['y']=dict(name='Distance',units='km') if 'z' in coords: out.z=ind+np.zeros(v.shape) out.info['z']=dict(name='Depth',units='m') if 't' in coords: out.t=self.time[time] if v.ndim==2: out.extra=[Data()] if 'x' in coords: out.extra[0].x=out.x if 'y' in coords: out.extra[0].y=out.y out.extra[0].v=h if h.max()>1000: cvals=200.,1000. elif h.max()>200: cvals=50.,100.,200. else: cvals=3 out.extra[0].config['field.plot']='contour' out.extra[0].config['field.cvals']=cvals out.extra[0].config['field.linecolors']='k' out.extra[0].alias='bathy' out.coordsReq=','.join(sorted(coords)) return out
def slicej(self,varname,ind,time=0,**opts): coords=opts.get('coords',self._default_coords('slicej')).split(',') out=Data() out.msg=self.check_slice(varname,t=time,j=ind) if out.msg: return out v=self.use(varname,SEARCHtime=time,eta_SEARCH=ind) # add mask if not masked: if not np.ma.isMA(v): m=self.grid.vars(ruvp=self.var_at(varname),j=ind)[-1] if v.ndim==2: m=np.tile(m,(v.shape[0],1)) v=np.ma.masked_where(m==0,v) out.v=v out.info['v']['name']=varname out.info['v']['slice']='j=%d'%ind try: out.info['v']['units']=netcdf.vatt(self.name,varname,'units') except: pass # coords: if 'z' in coords and v.ndim==2: out.z=self.s_levels(time=time,ruvpw=self.var_at(varname),j=ind) out.info['z']=dict(name='Depth',units='m') if any([i in coords for i in 'xyd']): x,y,h,m=self.grid.vars(ruvp=self.var_at(varname),j=ind) 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: out.t=self.time[time] if v.ndim==2: out.extra=[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] out.extra[0].v=-h out.extra[0].config['1d.plot']='fill_between' out.extra[0].config['1d.y0']=-h.max()-(h.max()-h.min())/20. out.extra[0].alias='bottom' out.coordsReq=','.join(sorted(coords)) 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 sliceiso(self,varname,iso,time,**opts): ''' Depths where variable, increasing/dec with depth, has some value. Output is masked where surface is higher/lower than value or where all water column is lower/higher than value. ''' coords=opts.get('coords',self._default_coords('sliceiso')).split(',') out=Data() out.msg=self.check_slice(varname,t=time) if out.msg: return out if not self.hasz(varname): out.msg='a depth dependent variable is needed for sliceiso!' return out v=self.use(varname,SEARCHtime=time) z=self.s_levels(time=time,ruvpw=self.var_at(varname)) v=rt.depthof(v,z,iso) out.v=v out.info['v']['name']=varname if isinstance(iso,np.ndarray) and iso.ndim==2: siso='2d' else: siso=str(iso) out.info['v']['slice']='iso=%s'%siso try: out.info['v']['units']=netcdf.vatt(self.nc,varname,'units') except: pass # coords: if any([i in coords for i in 'xy']): x,y,h=self.grid.vars(ruvp=self.var_at(varname))[:3] if 'x' in coords: if self.grid.is_spherical: out.x=x out.info['x']=dict(name='Longitude',units=r'$\^o$E') else: out.x=x/1000. out.info['x']=dict(name='Distance',units='km') if 'y' in coords: if self.grid.is_spherical: out.y=y out.info['y']=dict(name='Latitude',units=r'$\^o$N') else: out.y=y/1000. out.info['y']=dict(name='Distance',units='km') if 'z' in coords: # makes no sense... v is the depth! coords.remove('z') if 't' in coords: out.t=self.time[time] if v.ndim==2: out.extra=[Data()] if 'x' in coords: out.extra[0].x=out.x if 'y' in coords: out.extra[0].y=out.y out.extra[0].v=h if h.max()>1000: cvals=200.,1000. elif h.max()>200: cvals=50.,100.,200. else: cvals=3 out.extra[0].config['field.plot']='contour' out.extra[0].config['field.cvals']=cvals out.extra[0].config['field.linecolors']='k' out.extra[0].alias='bathy' out.coordsReq=','.join(sorted(coords)) return out
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 is 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=Data() 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)) 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): 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=np.squeeze(z) # depth slice: if isDepth and self.hasz(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,vm=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,spline=opts.get('spline',True)) v=np.ma.masked_where(vm,v) v=v[...,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 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 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.is_spherical: out.info['x']=dict(name='Longitude',units=r'$\^o$E') else: out.x=x#/1000. out.info['x']=dict(name='X-position',units='m') if 'y' in coords: out.y=lat[i,j] if self.grid.is_spherical: out.info['y']=dict(name='Latitude',units=r'$\^o$N') else: out.y=y#/1000. out.info['y']=dict(name='Y-position',units='m') out.coordsReq=','.join(sorted(coords)) return out