def path_s_levels(self,time,x,y,rw='r',**kargs): inds=kargs.get('inds',None) xr,yr,h,m=self.grid.vars() zeta=self.use('zeta',SEARCHtime=time) if inds: i0,i1=inds['xi'] j0,j1=inds['eta'] xr=xr[j0:j1,i0:i1] yr=yr[j0:j1,i0:i1] h=h[j0:j1,i0:i1] m=m[j0:j1,i0:i1] zeta= zeta[j0:j1,i0:i1] if np.ma.isMA(zeta): h=np.ma.masked_where(zeta.mask,h) else:# probably a clm/ini file. Mask maskc point (pygridgen complex grid): if 'maskc' in netcdf.varnames(self.grid.nc): mc=self.grid.use('maskc') if inds: mc=mc[j0:j1,i0:i1] h=np.ma.masked_where(mc==0,h) zeta=np.ma.masked_where(mc==0,zeta) h = calc.griddata(xr,yr,h,x,y,extrap=False) zeta = calc.griddata(xr,yr,zeta,x,y,extrap=False) z=rt.s_levels(h,zeta,self.s_params,rw=rw) z=np.squeeze(z) return np.ma.masked_where(np.isnan(z),z)
def slicez(self, varname, ind, time=0, plot=False, **opts): x, y, z, v = [[]] * 4 savename = False retMsg = False surf_nans = True if "savename" in opts.keys(): savename = opts["savename"] if "msg" in opts.keys(): retMsg = opts["msg"] if "surf_nans" in opts.keys(): surf_nans = opts["surf_nans"] if varname not in netcdf.varnames(self.name): msg = ":: variable %s not found" % varname if retMsg: return x, y, z, v, msg else: print msg return x, y, z, v if self.hast(varname) and time >= self.TIME: msg = "t = %d exceeds TIME dimension (%d)" % (time, self.TIME) if retMsg: return x, y, z, v, msg else: print msg return x, y, z, v 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) if len(v.shape) == 2: # no vertical comp if retMsg: return x, y, ind + np.zeros(v.shape), np.ma.masked_where(m == 0, v), "" else: return x, y, ind + np.zeros(v.shape), np.ma.masked_where(m == 0, v) v, mask = rt.slicez(v, m, h, zeta, self.s_params, ind, surf_nans) v = np.ma.masked_where(mask, v) if plot: p = self.grid.plot(bathy=None, **opts) xm, ym = p(x, y) pch = pylab.pcolor(xm, ym, v, shading="flat") pylab.colorbar(pch, shrink=0.7) pylab.axis([p.xmin, p.xmax, p.ymin, p.ymax]) if savename: pylab.savefig(savename, dpi=pylab.gcf().dpi) pylab.close(pylab.gcf()) if retMsg: return x, y, ind + np.zeros(v.shape), v, "" else: return x, y, ind + np.zeros(v.shape), v
def slicell(self,varname,X,Y,time=0,plot=False,**opts): x,y,z,v,m=[[]]*5 data = opts.get('data',False) dist = opts.get('dist',False) extrap = opts.get('extrap',False) varOnly = opts.get('retv',False) maskLimit = opts.get('lmask',0.5) # points where interpolated mask are above # this value are considered as mask! # Most strict value is 0 X=np.array(X) Y=np.array(Y) if X.ndim>1: X=np.squeeze(X) if Y.ndim>1: Y=np.squeeze(X) if varname not in netcdf.varnames(self.name): print(':: variable %s not found' % varname) return x,y,z,v,m if time>=self.TIME: print('t = %d exceeds TIME dimension (%d)' % (time,self.TIME)) return x,y,z,v,m if data is False: v=self.use(varname,SEARCHtime=time) else: v=data x,y,h,m=self.grid.vars(ruvp=self.var_at(varname)) if v.ndim==3: V=calc.griddata(x,y,v,X,Y,extrap=extrap,mask2d=m==0, keepMaskVal=maskLimit) elif v.ndim==2: V=calc.griddata(x,y,np.ma.masked_where(m==0,v),X,Y,extrap=extrap, keepMaskVal=maskLimit) if varOnly: return V # Z: if v.ndim==3: Z=self.path_s_levels(time,X,Y,rw=varname[0]) else: Z=0.*X # X, Y, dist: if dist: Dist=calc.distance(X,Y) if v.ndim==3: Dist=np.tile(Dist,(v.shape[0],1)) else: if v.ndim==3: X=np.tile(X,(v.shape[0],1)) Y=np.tile(Y,(v.shape[0],1)) if dist: return Dist,Z,V else: return X,Y,Z,V
def slicez(self, varname, ind, time=0, plot=False, **opts): x, y, z, v = [[]] * 4 savename = False retMsg = False surf_nans = True if 'savename' in opts.keys(): savename = opts['savename'] if 'msg' in opts.keys(): retMsg = opts['msg'] if 'surf_nans' in opts.keys(): surf_nans = opts['surf_nans'] if varname not in netcdf.varnames(self.name): msg = ':: variable %s not found' % varname if retMsg: return x, y, z, v, msg else: print(msg) return x, y, z, v if self.hast(varname) and time >= self.TIME: msg = 't = %d exceeds TIME dimension (%d)' % (time, self.TIME) if retMsg: return x, y, z, v, msg else: print(msg) return x, y, z, v 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) if len(v.shape) == 2: # no vertical comp if retMsg: return x, y, ind + np.zeros(v.shape), np.ma.masked_where( m == 0, v), '' else: return x, y, ind + np.zeros(v.shape), np.ma.masked_where( m == 0, v) v, mask = rt.slicez(v, m, h, zeta, self.s_params, ind, surf_nans) v = np.ma.masked_where(mask, v) if plot: p = self.grid.plot(bathy=None, **opts) xm, ym = p(x, y) pch = pylab.pcolor(xm, ym, v, shading='flat') pylab.colorbar(pch, shrink=.7) pylab.axis([p.xmin, p.xmax, p.ymin, p.ymax]) if savename: pylab.savefig(savename, dpi=pylab.gcf().dpi) pylab.close(pylab.gcf()) if retMsg: return x, y, ind + np.zeros(v.shape), v, '' else: return x, y, ind + np.zeros(v.shape), v
def path_s_levels(self,time,x,y,rw='r'): xr,yr,h,m=self.grid.vars() zeta=self.use('zeta',SEARCHtime=time) if np.ma.isMA(zeta): h=np.ma.masked_where(zeta.mask,h) else:# probably a clm/ini file. Mask maskc point (pygridgen complex grid): if 'maskc' in netcdf.varnames(self.grid.name): mc=self.grid.use('maskc') h=np.ma.masked_where(mc==0,h) zeta=np.ma.masked_where(mc==0,zeta) h = calc.griddata(xr,yr,h,x,y,extrap=False) zeta = calc.griddata(xr,yr,zeta,x,y,extrap=False) z=rt.s_levels(h,zeta,self.s_params,rw=rw) z=np.squeeze(z) return np.ma.masked_where(np.isnan(z),z)
def path_s_levels(self, time, x, y, rw='r'): xr, yr, h, m = self.grid.vars() zeta = self.use('zeta', SEARCHtime=time) if np.ma.isMA(zeta): h = np.ma.masked_where(zeta.mask, h) else: # probably a clm/ini file. Mask maskc point (pygridgen complex grid): if 'maskc' in netcdf.varnames(self.grid.name): mc = self.grid.use('maskc') h = np.ma.masked_where(mc == 0, h) zeta = np.ma.masked_where(mc == 0, zeta) h = calc.griddata(xr, yr, h, x, y, extrap=False) zeta = calc.griddata(xr, yr, zeta, x, y, extrap=False) z = rt.s_levels(h, zeta, self.s_params, rw=rw) z = np.squeeze(z) return np.ma.masked_where(np.isnan(z), z)
def check_slice(self,varname,**dims): msg='' # check varname: if varname not in netcdf.varnames(self.nc): return ':: variable %s not found' % varname isU=varname in ('u','ubar') isV=varname in ('v','vbar') isW=varname=='w' for dim,ind in dims.items(): # check time: if dim=='t': if self.hast(varname) and ind>=self.TIME: msg='t = %d exceeds TIME dimension (%d)' % (ind,self.TIME) # check dim k: elif dim=='k': if self.hasz(varname): if isW: s='S_W' else: s='S_RHO' indMax=getattr(self,s) if ind >= indMax: msg='k = %d exceeds %s dimension (%d)' % (ind,s,indMax) # check dim i: elif dim=='i': xi='XI_RHO' if isU: xi='XI_U' elif isV and hasattr(self,'XI_V'): xi='XI_V' # needed for roms-agrif indMax=getattr(self,xi) if ind >= indMax: msg='i = %d exceeds %s dimension (%d)' % (ind,xi,indMax) # check dim j: elif dim=='j': eta='ETA_RHO' if isU and hasattr(self,'ETA_U'): eta='ETA_U' # needed for roms-agrif elif isV: eta='ETA_V' indMax=getattr(self,eta) if ind >= indMax: msg='j = %d exceeds %s dimension (%d)' % (ind,eta,indMax) return msg
def check_slice(self,varname,**dims): msg='' # check varname: if varname not in netcdf.varnames(self.nc): return ':: variable %s not found' % varname isU=varname in ('u','ubar') isV=varname in ('v','vbar') isW=varname=='w' for dim,ind in dims.items(): # check time: if dim=='t': if 't' in self.vaxes(varname) and ind>=self.TIME: msg='t = %d exceeds TIME dimension (%d)' % (ind,self.TIME) # check dim k: elif dim=='k': if 'z' in self.vaxes(varname): if isW: s='S_W' else: s='S_RHO' indMax=getattr(self,s) if ind >= indMax: msg='k = %d exceeds %s dimension (%d)' % (ind,s,indMax) # check dim i: elif dim=='i': xi='XI_RHO' if isU: xi='XI_U' elif isV and hasattr(self,'XI_V'): xi='XI_V' # needed for roms-agrif indMax=getattr(self,xi) if ind >= indMax: msg='i = %d exceeds %s dimension (%d)' % (ind,xi,indMax) # check dim j: elif dim=='j': eta='ETA_RHO' if isU and hasattr(self,'ETA_U'): eta='ETA_U' # needed for roms-agrif elif isV: eta='ETA_V' indMax=getattr(self,eta) if ind >= indMax: msg='j = %d exceeds %s dimension (%d)' % (ind,eta,indMax) return msg
def path_s_levels(self,time,x,y,rw='r',**kargs): inds=kargs.get('inds',None) xr,yr,h,m=self.grid.vars() zeta=self.use('zeta',SEARCHtime=time) if inds: i0,i1=inds['xi'] j0,j1=inds['eta'] xr=xr[j0:j1,i0:i1] yr=yr[j0:j1,i0:i1] h=h[j0:j1,i0:i1] m=m[j0:j1,i0:i1] zeta= zeta[j0:j1,i0:i1] if np.ma.is_masked(zeta): # h=np.ma.masked_where(zeta.mask,h) # comment above in order to keep right depth inside the domain # on masked regions pass else:# probably a clm/ini file. Mask maskc point (pygridgen complex grid): if 'maskc' in netcdf.varnames(self.grid.nc): mc=self.grid.use('maskc') if inds: mc=mc[j0:j1,i0:i1] h=np.ma.masked_where(mc==0,h) zeta=np.ma.masked_where(mc==0,zeta) h = calc.griddata(xr,yr,h,x,y,extrap=False) zeta = calc.griddata(xr,yr,zeta,x,y,extrap=False) # better interpolate the gaps, otherwise s_levels will use default # values for zeta and h: X=np.arange(h.size) if np.ma.is_masked(h): h=np.interp(X,X[~h.mask],h[~h.mask]) if np.ma.is_masked(zeta): zeta=np.interp(X,X[~zeta.mask],zeta[~zeta.mask]) ### return h,zeta,self.s_params,rw return rt.s_levels(h,zeta,self.s_params,rw=rw)
def cordex_file_data(f,lims=False,quiet=False): ''' CORDEX data for ROMS No accumulated variables are considered ''' out={} # time, x, y: if not quiet: print(' reading time,x,y') out['time']=netcdf.nctime(f,'time') x=netcdf.use(f,'lon') y=netcdf.use(f,'lat') x[x>180]=x[x>180]-360 if x.ndim==1 and y.ndim==1: x,y=np.meshgrid(x,y) if np.ma.isMA(x): x=x.data if np.ma.isMA(y): y=y.data if lims: from okean import calc xlim,ylim=lims i1,i2,j1,j2=calc.ij_limits(x,y,xlim,ylim,margin=3) else: i0=0 j0=0 j1,i1=x.shape I=range(i1,i2) J=range(j1,j2) x=x[j1:j2,i1:i2] y=y[j1:j2,i1:i2] # tair [K-->C] if not quiet: print(' --> T air') vname='tair' tair=netcdf.use(f,vname,lon=I,lat=J)-273.15 out['tair']=Data(x,y,tair,'Celsius') # R humidity [0--1] if not quiet: print(' --> R humidity (from specific humidity)') vname='humid' q=netcdf.use(f,vname,lon=I,lat=J) # specific humidity rhum=q/air_sea.qsat(tair) rhum[rhum>1]=1 out['rhum']=Data(x,y,rhum,'0--1') # surface pressure [Pa] if not quiet: print(' --> Surface pressure') vname='press' pres=netcdf.use(f,vname,lon=I,lat=J) out['pres']=Data(x,y,pres,'Pa') # P rate [kg m-2 s-1 -> cm/d] if not quiet: print(' --> P rate') vname='rain' prate=netcdf.use(f,vname,lon=I,lat=J) prate=prate*86400*100/1000. prate[prate<0]=0 out['prate']=Data(x,y,prate,'cm/d') # Net shortwave flux [W m-2] if not quiet: print(' --> Net shortwave flux') if not quiet: print(' SW down') sw_down=netcdf.use(f,'sw_down',lon=I,lat=J) if not quiet: print(' SW up') sw_up=netcdf.use(f,'sw_up',lon=I,lat=J) sw_net=sw_down-sw_up out['radsw']=Data(x,y,sw_net,'W m-2',info='positive downward') # Net longwave flux [W m-2] if not quiet: print(' --> Net longwave flux') if not quiet: print(' LW down') lw_down=netcdf.use(f,'lw_down',lon=I,lat=J) if not quiet: print(' LW up') lw_up=netcdf.use(f,'lw_up',lon=I,lat=J) lw_net=lw_down-lw_up out['radlw']=Data(x,y,-lw_net,'W m-2',info='positive upward') # downward lw: out['dlwrf']=Data(x,y,-lw_down,'W m-2',info='negative... downward') # signs convention is better explained in wrf.py # U and V wind speed 10m if not quiet: print(' --> U and V wind') uwnd=netcdf.use(f,'u',lon=I,lat=J) vwnd=netcdf.use(f,'v',lon=I,lat=J) if not quiet: print(' --> calc wind speed and stress') speed = np.sqrt(uwnd**2+vwnd**2) taux,tauy=air_sea.wind_stress(uwnd,vwnd) out['wspd']=Data(x,y,speed,'m s-1') out['uwnd']=Data(x,y,uwnd,'m s-1') out['vwnd']=Data(x,y,vwnd,'m s-1') out['sustr']=Data(x,y,taux,'Pa') out['svstr']=Data(x,y,tauy,'Pa') # Cloud cover [0--100 --> 0--1]: if not quiet: print(' --> Cloud cover') if 'clouds' in netcdf.varnames(f): clouds=netcdf.use(f,'clouds',lon=I,lat=J)/100. out['cloud']=Data(x,y,clouds,'fraction (0--1)') else: print('==> clouds not present!') return fill_extremes(out,quiet)
def varfile(var): for f in files: if var in netcdf.varnames(f): return f
def cfsr_file_data(files,quiet=False): ''' Returns bulk data from one CFRS files ''' def load_time(f): time=np.array((),datetime.datetime) ff=glob.glob(f) ff.sort() for f in ff: time=np.append(time,netcdf.nctime(f,'time')) return time def load_time_main(f): time=load_time(f) # I want 0,6,12,... after 2006 results may be 3,9,15, ... if time[0].hour in [3,9,15,21]: time=time+datetime.timedelta(hours=3) # for 2011 1st time is not 0! if time[0].hour==6: time=np.hstack((time[0].replace(hour=0),time)) return time def fix_time(t,var,t0,t1): # convert 1h, 7h, ... to 0h, 6h, ... if t[0].hour in [1,7,13,19]: # not all! sp analysis starts at 0, 6,...! print(' 1,7,... to 0,6,...') var=(var[1:]*5+var[:-1]*1)/6. t=t[1:]-datetime.timedelta(hours=1) elif t[0].hour in [3,9,15,21]: print(' 3,9,... to 0,6,...') var=(var[1:]*3+var[:-1]*3)/6. t=t[1:]-datetime.timedelta(hours=3) cond=(t>=t0)&(t<=t1) t=t[cond] var=var[cond] if t[0]>t0: dt=t[0]-t0 dt=dt.days*24+dt.seconds/3600. # hours print('missing data at start: %.2d h missing --> repeating 1st data'%dt) v=np.zeros((var.shape[0]+1,)+var.shape[1:],var.dtype) v[1:]=var v[0]=var[0] var=v t_=np.zeros((t.shape[0]+1,)+t.shape[1:],t.dtype) t_[1:]=t t_[0]=t0 t=t_ if t[-1]<t1: dt=t1-t[-1] dt=dt.days*24+dt.seconds/3600. # hours print('missing data at end: %.2d h missing --> repeating last data'%dt) v=np.zeros((var.shape[0]+1,)+var.shape[1:],var.dtype) v[:-1]=var v[-1]=var[-1] var=v t_=np.zeros((t.shape[0]+1,)+t.shape[1:],t.dtype) t_[:-1]=t t_[-1]=t1 t=t_ return var,t out={} # time: if 0: time=netcdf.nctime(files['cc'],'time') # files have diff units !! so, cannot load all times at once! # these result will use only units of 1st file!! else: time=load_time_main(files['cc']) out['time']=time # T air [K->C] if not quiet: print(' --> T air') f=files['st'] tair=netcdf.use(f,'TMP_L103') tair=tair-273.15 x=netcdf.use(f,'lon'); x[x>180]=x[x>180]-360 y=netcdf.use(f,'lat') x,y=np.meshgrid(x,y) # check time: ttmp=load_time(f) if ttmp.size==time.size and np.all(ttmp==time): print(' time ok') else: print(' time differs !!!!',) tair,tfix=fix_time(ttmp,tair,time[0],time[-1]) if tfix.size==time.size and np.all(tfix==time): print(' ...fixed!') else: print('time is NOT OK. Please check !!') return out['tair']=Data(x,y,tair,'C') # R humidity [%-->0--1] if not quiet: print(' --> R humidity') f=files['rh'] rhum=netcdf.use(f,'R_H_L103') rhum=rhum/100. x=netcdf.use(f,'lon'); x[x>180]=x[x>180]-360 y=netcdf.use(f,'lat') x,y=np.meshgrid(x,y) # check time: ttmp=load_time(f) if ttmp.size==time.size and np.all(ttmp==time): print(' time ok') else: print(' time differs !!!!'), # should use end=' ' for python3 print continuation rhum,tfix=fix_time(ttmp,rhum,time[0],time[-1]) if tfix.size==time.size and np.all(tfix==time): print(' ...fixed!') else: print('time is NOT OK. Please check !!') return out['rhum']=Data(x,y,rhum,'0--1') # surface pressure [Pa] if not quiet: print(' --> Surface pressure') f=files['sp'] pres=netcdf.use(f,'PRES_L1') x=netcdf.use(f,'lon'); x[x>180]=x[x>180]-360 y=netcdf.use(f,'lat') x,y=np.meshgrid(x,y) # check time: ttmp=load_time(f) if ttmp.size==time.size and np.all(ttmp==time): print(' time ok') else: print(' time differs !!!!'), pres,tfix=fix_time(ttmp,pres,time[0],time[-1]) if tfix.size==time.size and np.all(tfix==time): print(' ...fixed!') else: print('time is NOT OK. Please check !!') return out['pres']=Data(x,y,pres,'Pa') # P rate [kg m-2 s-1 -> cm/d] if not quiet: print(' --> P rate') f=files['pr'] if 'PRATE_L1' in netcdf.varnames(f): prate=netcdf.use(f,'PRATE_L1') else: prate=netcdf.use(f,'PRATE_L1_Avg_1') x=netcdf.use(f,'lon'); x[x>180]=x[x>180]-360 y=netcdf.use(f,'lat') x,y=np.meshgrid(x,y) # Conversion kg m^-2 s^-1 to cm/day prate=prate*86400*100/1000. prate=np.where(abs(prate)<1.e-4,0,prate) # check time: ttmp=load_time(f) if ttmp.size==time.size and np.all(ttmp==time): print(' time ok') else: print(' time differs !!!!'), prate,tfix=fix_time(ttmp,prate,time[0],time[-1]) if tfix.size==time.size and np.all(tfix==time): print(' ...fixed!') else: print('time is NOT OK. Please check !!') return out['prate']=Data(x,y,prate,'cm/d') # Net shortwave flux [W/m^2] if not quiet: print(' --> Net shortwave flux') if not quiet: print(' SW down') f=files['rad'] sw_down=netcdf.use(f,'DSWRF_L1_Avg_1') x=netcdf.use(f,'lon'); x[x>180]=x[x>180]-360 y=netcdf.use(f,'lat') x,y=np.meshgrid(x,y) if not quiet: print(' SW up') sw_up=netcdf.use(f,'USWRF_L1_Avg_1') sw_net=sw_down-sw_up sw_net=np.where(sw_net<1.e-10,0,sw_net) # check time: ttmp=load_time(f) if ttmp.size==time.size and np.all(ttmp==time): print(' time ok') else: print(' time differs !!!!'), sw_net,tfix=fix_time(ttmp,sw_net,time[0],time[-1]) if tfix.size==time.size and np.all(tfix==time): print(' ...fixed!') else: print('time is NOT OK. Please check !!') return out['radsw']=Data(x,y,sw_net,'W m-2',info='positive downward') # Net longwave flux [W/m^2] if not quiet: print(' --> Net longwave flux') if not quiet: print(' LW down') f=files['rad'] lw_down=netcdf.use(f,'DLWRF_L1_Avg_1') x=netcdf.use(f,'lon'); x[x>180]=x[x>180]-360 y=netcdf.use(f,'lat') x,y=np.meshgrid(x,y) if not quiet: print(' LW up') lw_up=netcdf.use(f,'ULWRF_L1_Avg_1') lw_net=lw_down-lw_up lw_net=np.where(np.abs(lw_net)<1.e-10,0,lw_net) # check time: ttmp=load_time(f) if ttmp.size==time.size and np.all(ttmp==time): print(' time ok') else: print(' time differs !!!!'), lw_net,tfix1=fix_time(ttmp,lw_net,time[0],time[-1]) lw_down,tfix2=fix_time(ttmp,lw_down,time[0],time[-1]) if tfix1.size==tfix2.size==time.size and np.all((tfix1==time)&(tfix2==time)): print(' ...fixed!') else: print('time is NOT OK. Please check !!') return # ROMS (agrif, used to be!) convention: positive upward out['radlw']=Data(x,y,-lw_net,'W m-2',info='positive upward') # downward lw: out['dlwrf']=Data(x,y,-lw_down,'W m-2',info='negative... downward') # signs convention is better explained in wrf.py # U and V wind speed 10m if not quiet: print(' --> U and V wind') f=files['uv'] uwnd=netcdf.use(f,'U_GRD_L103') vwnd=netcdf.use(f,'V_GRD_L103') x=netcdf.use(f,'lon'); x[x>180]=x[x>180]-360 y=netcdf.use(f,'lat') x,y=np.meshgrid(x,y) # check time: ttmp=load_time(f) if ttmp.size==time.size and np.all(ttmp==time): print(' time ok') else: print(' time differs !!!!'), uwnd,tfix1=fix_time(ttmp,uwnd,time[0],time[-1]) vwnd,tfix2=fix_time(ttmp,vwnd,time[0],time[-1]) if tfix1.size==tfix2.size==time.size and np.all((tfix1==time)&(tfix2==time)): print(' ...fixed!') else: print('time is NOT OK. Please check !!') return # if not quiet: print(' --> calc wind speed and stress') speed = np.sqrt(uwnd**2+vwnd**2) taux,tauy=air_sea.wind_stress(uwnd,vwnd) out['wspd']=Data(x,y,speed,'m s-1') out['uwnd']=Data(x,y,uwnd,'m s-1') out['vwnd']=Data(x,y,vwnd,'m s-1') out['sustr']=Data(x,y,taux,'Pa') out['svstr']=Data(x,y,tauy,'Pa') # Cloud cover [0--100 --> 0--1]: if not quiet: print(' --> Cloud cover') f=files['cc'] if 'T_CDC_L200' in netcdf.varnames(f): clouds=netcdf.use(f,'T_CDC_L200') else: clouds=netcdf.use(f,'T_CDC_L200_Avg_1') x=netcdf.use(f,'lon'); x[x>180]=x[x>180]-360 y=netcdf.use(f,'lat') x,y=np.meshgrid(x,y) clouds=clouds/100. # check time: ttmp=load_time(f) if ttmp.size==time.size and np.all(ttmp==time): print(' time ok') else: print(' time differs !!!!'), clouds,tfix=fix_time(ttmp,clouds,time[0],time[-1]) if tfix.size==time.size and np.all(tfix==time): print(' ...fixed!') else: print('time is NOT OK. Please check !!') return out['cloud']=Data(x,y,clouds,'fraction (0--1)') # rhum has different resolution (0.5, just like dew point!) # so, i can edit surface.py or just interpolate here rhum to # other vars resolution: if out['rhum'].data.shape!=out['uwnd'].data.shape: from okean import calc print('rhum shape differs!! --> interp:') nt,ny,nx=out['uwnd'].data.shape x,y=out['uwnd'].x,out['uwnd'].y rhum=np.zeros((nt,ny,nx), out['rhum'].data.dtype) for it in range(nt): if it%100==0: print(' %d of %d'%(it,nt)) rhum[it]=calc.griddata(out['rhum'].x,out['rhum'].y,out['rhum'].data[it],x,y) out['rhum']=Data(x,y,rhum,'0--1') return out
def cfsr_file_data(files, quiet=False): ''' Returns bulk data from one CFRS files ''' def load_time(f): time = np.array((), datetime.datetime) ff = glob.glob(f) ff.sort() for f in ff: time = np.append(time, netcdf.nctime(f, 'time')) return time def load_time_main(f): time = load_time(f) # I want 0,6,12,... after 2006 results may be 3,9,15, ... if time[0].hour in [3, 9, 15, 21]: time = time + datetime.timedelta(hours=3) # for 2011 1st time is not 0! if time[0].hour == 6: time = np.hstack((time[0].replace(hour=0), time)) return time def fix_time(t, var, t0, t1): # convert 1h, 7h, ... to 0h, 6h, ... if t[0].hour in [1, 7, 13, 19]: # not all! sp analysis starts at 0, 6,...! print(' 1,7,... to 0,6,...') var = (var[1:] * 5 + var[:-1] * 1) / 6. t = t[1:] - datetime.timedelta(hours=1) elif t[0].hour in [3, 9, 15, 21]: print(' 3,9,... to 0,6,...') var = (var[1:] * 3 + var[:-1] * 3) / 6. t = t[1:] - datetime.timedelta(hours=3) cond = (t >= t0) & (t <= t1) t = t[cond] var = var[cond] if t[0] > t0: dt = t[0] - t0 dt = dt.days * 24 + dt.seconds / 3600. # hours print( 'missing data at start: %.2d h missing --> repeating 1st data' % dt) v = np.zeros((var.shape[0] + 1, ) + var.shape[1:], var.dtype) v[1:] = var v[0] = var[0] var = v t_ = np.zeros((t.shape[0] + 1, ) + t.shape[1:], t.dtype) t_[1:] = t t_[0] = t0 t = t_ if t[-1] < t1: dt = t1 - t[-1] dt = dt.days * 24 + dt.seconds / 3600. # hours print( 'missing data at end: %.2d h missing --> repeating last data' % dt) v = np.zeros((var.shape[0] + 1, ) + var.shape[1:], var.dtype) v[:-1] = var v[-1] = var[-1] var = v t_ = np.zeros((t.shape[0] + 1, ) + t.shape[1:], t.dtype) t_[:-1] = t t_[-1] = t1 t = t_ return var, t out = {} # time: if 0: time = netcdf.nctime(files['cc'], 'time') # files have diff units !! so, cannot load all times at once! # these result will use only units of 1st file!! else: time = load_time_main(files['cc']) out['time'] = time # T air [K->C] if not quiet: print(' --> T air') f = files['st'] tair = netcdf.use(f, 'TMP_L103') tair = tair - 273.15 x = netcdf.use(f, 'lon') x[x > 180] = x[x > 180] - 360 y = netcdf.use(f, 'lat') x, y = np.meshgrid(x, y) # check time: ttmp = load_time(f) if ttmp.size == time.size and np.all(ttmp == time): print(' time ok') else: print(' time differs !!!!', ) tair, tfix = fix_time(ttmp, tair, time[0], time[-1]) if tfix.size == time.size and np.all(tfix == time): print(' ...fixed!') else: print('time is NOT OK. Please check !!') return out['tair'] = Data(x, y, tair, 'C') # R humidity [%-->0--1] if not quiet: print(' --> R humidity') f = files['rh'] rhum = netcdf.use(f, 'R_H_L103') rhum = rhum / 100. x = netcdf.use(f, 'lon') x[x > 180] = x[x > 180] - 360 y = netcdf.use(f, 'lat') x, y = np.meshgrid(x, y) # check time: ttmp = load_time(f) if ttmp.size == time.size and np.all(ttmp == time): print(' time ok') else: print(' time differs !!!!' ), # should use end=' ' for python3 print continuation rhum, tfix = fix_time(ttmp, rhum, time[0], time[-1]) if tfix.size == time.size and np.all(tfix == time): print(' ...fixed!') else: print('time is NOT OK. Please check !!') return out['rhum'] = Data(x, y, rhum, '0--1') # surface pressure [Pa] if not quiet: print(' --> Surface pressure') f = files['sp'] pres = netcdf.use(f, 'PRES_L1') x = netcdf.use(f, 'lon') x[x > 180] = x[x > 180] - 360 y = netcdf.use(f, 'lat') x, y = np.meshgrid(x, y) # check time: ttmp = load_time(f) if ttmp.size == time.size and np.all(ttmp == time): print(' time ok') else: print(' time differs !!!!'), pres, tfix = fix_time(ttmp, pres, time[0], time[-1]) if tfix.size == time.size and np.all(tfix == time): print(' ...fixed!') else: print('time is NOT OK. Please check !!') return out['pres'] = Data(x, y, pres, 'Pa') # P rate [kg m-2 s-1 -> cm/d] if not quiet: print(' --> P rate') f = files['pr'] if 'PRATE_L1' in netcdf.varnames(f): prate = netcdf.use(f, 'PRATE_L1') else: prate = netcdf.use(f, 'PRATE_L1_Avg_1') x = netcdf.use(f, 'lon') x[x > 180] = x[x > 180] - 360 y = netcdf.use(f, 'lat') x, y = np.meshgrid(x, y) # Conversion kg m^-2 s^-1 to cm/day prate = prate * 86400 * 100 / 1000. prate = np.where(abs(prate) < 1.e-4, 0, prate) # check time: ttmp = load_time(f) if ttmp.size == time.size and np.all(ttmp == time): print(' time ok') else: print(' time differs !!!!'), prate, tfix = fix_time(ttmp, prate, time[0], time[-1]) if tfix.size == time.size and np.all(tfix == time): print(' ...fixed!') else: print('time is NOT OK. Please check !!') return out['prate'] = Data(x, y, prate, 'cm/d') # Net shortwave flux [W/m^2] if not quiet: print(' --> Net shortwave flux') if not quiet: print(' SW down') f = files['rad'] sw_down = netcdf.use(f, 'DSWRF_L1_Avg_1') x = netcdf.use(f, 'lon') x[x > 180] = x[x > 180] - 360 y = netcdf.use(f, 'lat') x, y = np.meshgrid(x, y) if not quiet: print(' SW up') sw_up = netcdf.use(f, 'USWRF_L1_Avg_1') sw_net = sw_down - sw_up sw_net = np.where(sw_net < 1.e-10, 0, sw_net) # check time: ttmp = load_time(f) if ttmp.size == time.size and np.all(ttmp == time): print(' time ok') else: print(' time differs !!!!'), sw_net, tfix = fix_time(ttmp, sw_net, time[0], time[-1]) if tfix.size == time.size and np.all(tfix == time): print(' ...fixed!') else: print('time is NOT OK. Please check !!') return out['radsw'] = Data(x, y, sw_net, 'W m-2', info='positive downward') # Net longwave flux [W/m^2] if not quiet: print(' --> Net longwave flux') if not quiet: print(' LW down') f = files['rad'] lw_down = netcdf.use(f, 'DLWRF_L1_Avg_1') x = netcdf.use(f, 'lon') x[x > 180] = x[x > 180] - 360 y = netcdf.use(f, 'lat') x, y = np.meshgrid(x, y) if not quiet: print(' LW up') lw_up = netcdf.use(f, 'ULWRF_L1_Avg_1') lw_net = lw_down - lw_up lw_net = np.where(np.abs(lw_net) < 1.e-10, 0, lw_net) # check time: ttmp = load_time(f) if ttmp.size == time.size and np.all(ttmp == time): print(' time ok') else: print(' time differs !!!!'), lw_net, tfix1 = fix_time(ttmp, lw_net, time[0], time[-1]) lw_down, tfix2 = fix_time(ttmp, lw_down, time[0], time[-1]) if tfix1.size == tfix2.size == time.size and np.all((tfix1 == time) & (tfix2 == time)): print(' ...fixed!') else: print('time is NOT OK. Please check !!') return # ROMS (agrif, used to be!) convention: positive upward out['radlw'] = Data(x, y, -lw_net, 'W m-2', info='positive upward') # downward lw: out['dlwrf'] = Data(x, y, -lw_down, 'W m-2', info='negative... downward') # signs convention is better explained in wrf.py # U and V wind speed 10m if not quiet: print(' --> U and V wind') f = files['uv'] uwnd = netcdf.use(f, 'U_GRD_L103') vwnd = netcdf.use(f, 'V_GRD_L103') x = netcdf.use(f, 'lon') x[x > 180] = x[x > 180] - 360 y = netcdf.use(f, 'lat') x, y = np.meshgrid(x, y) # check time: ttmp = load_time(f) if ttmp.size == time.size and np.all(ttmp == time): print(' time ok') else: print(' time differs !!!!'), uwnd, tfix1 = fix_time(ttmp, uwnd, time[0], time[-1]) vwnd, tfix2 = fix_time(ttmp, vwnd, time[0], time[-1]) if tfix1.size == tfix2.size == time.size and np.all((tfix1 == time) & (tfix2 == time)): print(' ...fixed!') else: print('time is NOT OK. Please check !!') return # if not quiet: print(' --> calc wind speed and stress') speed = np.sqrt(uwnd**2 + vwnd**2) taux, tauy = air_sea.wind_stress(uwnd, vwnd) out['wspd'] = Data(x, y, speed, 'm s-1') out['uwnd'] = Data(x, y, uwnd, 'm s-1') out['vwnd'] = Data(x, y, vwnd, 'm s-1') out['sustr'] = Data(x, y, taux, 'Pa') out['svstr'] = Data(x, y, tauy, 'Pa') # Cloud cover [0--100 --> 0--1]: if not quiet: print(' --> Cloud cover') f = files['cc'] if 'T_CDC_L200' in netcdf.varnames(f): clouds = netcdf.use(f, 'T_CDC_L200') else: clouds = netcdf.use(f, 'T_CDC_L200_Avg_1') x = netcdf.use(f, 'lon') x[x > 180] = x[x > 180] - 360 y = netcdf.use(f, 'lat') x, y = np.meshgrid(x, y) clouds = clouds / 100. # check time: ttmp = load_time(f) if ttmp.size == time.size and np.all(ttmp == time): print(' time ok') else: print(' time differs !!!!'), clouds, tfix = fix_time(ttmp, clouds, time[0], time[-1]) if tfix.size == time.size and np.all(tfix == time): print(' ...fixed!') else: print('time is NOT OK. Please check !!') return out['cloud'] = Data(x, y, clouds, 'fraction (0--1)') # rhum has different resolution (0.5, just like dew point!) # so, i can edit surface.py or just interpolate here rhum to # other vars resolution: if out['rhum'].data.shape != out['uwnd'].data.shape: from okean import calc print('rhum shape differs!! --> interp:') nt, ny, nx = out['uwnd'].data.shape x, y = out['uwnd'].x, out['uwnd'].y rhum = np.zeros((nt, ny, nx), out['rhum'].data.dtype) for it in range(nt): if it % 100 == 0: print(' %d of %d' % (it, nt)) rhum[it] = calc.griddata(out['rhum'].x, out['rhum'].y, out['rhum'].data[it], x, y) out['rhum'] = Data(x, y, rhum, '0--1') return out
ttmp = load_time(f) if ttmp.size == time.size and np.all(ttmp == time): print ' time ok' else: print ' time differs !!!!', pres, tfix = fix_time(ttmp, pres, time[0], time[-1]) if tfix.size == time.size and np.all(tfix == time): print ' ...fixed!' else: print 'time is NOT OK. Please check !!' return out['pres'] = Data(x, y, pres, 'Pa') # P rate [kg m-2 s-1 -> cm/d] if not quiet: print ' --> P rate' f = files['pr'] if 'PRATE_L1' in netcdf.varnames(f): prate = netcdf.use(f, 'PRATE_L1') else: prate = netcdf.use(f, 'PRATE_L1_Avg_1') x = netcdf.use(f, 'lon') x[x > 180] = x[x > 180] - 360 y = netcdf.use(f, 'lat') x, y = np.meshgrid(x, y) # Conversion kg m^-2 s^-1 to cm/day prate = prate * 86400 * 100 / 1000. prate = np.where(abs(prate) < 1.e-4, 0, prate) # check time: ttmp = load_time(f) if ttmp.size == time.size and np.all(ttmp == time): print ' time ok' else: print ' time differs !!!!',
def slicej(self,varname,ind,time=0,dist=1,plot=False,**opts): savename=False if 'savename' in opts.keys(): savename=opts['savename'] d,x,y,z,v=[[]]*5 if varname not in netcdf.varnames(self.name): print(':: variable %s not found' % varname) if dist: return d,z,v else: return x,y,z,v isU=varname=='u' isV=varname=='v' if isU: if hasattr(self,'ETA_U'): ETA= self.ETA_U eta='ETA_U' else: # this happens in current roms-agrif ETA= self.ETA_RHO eta='ETA_RHO' elif isV: ETA= self.ETA_V eta='ETA_V' else: ETA= self.ETA_RHO eta='ETA_RHO' if ind >= ETA: print('j = %d exceeds %s dimension (%d)' % (ind,eta,ETA)) if dist: return d,z,v else: return x,y,z,v x,y,h,m=self.grid.vars(ruvp=self.var_at(varname),j=ind) karg={'SEARCHtime':time,eta.lower(): ind} v=self.use(varname,**karg) if v.ndim==2: z=self.s_levels(time=time,ruvpw=self.var_at(varname),j=ind) elif v.ndim==1: z=[] N=v.shape[0] if dist: d=calc.distance(x,y) if plot: pylab.figure() if v.ndim==2: pylab.pcolor(np.tile(d,(N,1)),z,np.ma.masked_where(np.tile(m,(N,1))==0,v),shading='flat') pylab.plot(d,-h) pylab.colorbar(shrink=.7) elif v.ndim==1: pylab.plot(d,v) if savename: pylab.savefig(savename,dpi=pylab.gcf().dpi) pylab.close(pylab.gcf()) if v.ndim==2: return np.tile(d,(N,1)),z,v elif v.ndim==1: return d,z,v #np.ma.masked_where(m==0,v) else: if plot: pylab.figure() if v.ndim==2: pylab.pcolor(tile(x,(N,1)),z,ma.masked_where(tile(m,(N,1))==0,v),shading='flat') pylab.colorbar(shrink=.7) pylab.plot(x,-h) elif v.ndim==1: pylab.plot(x,v) if savename: pylab.savefig(savename,dpi=pylab.gcf().dpi) pylab.close(pylab.gcf()) if v.ndim==2: m=np.tile(m,(N,1))==0 return np.tile(x,(N,1)),np.tile(y,(N,1)),z,v #np.ma.masked_where(m,v) elif v.ndim==1: return x,y,z,v #np.ma.masked_where(m==0,v)
def wrf_file_data(file, quiet=False): ''' WRF data for ROMS ''' out = {} # time: if not quiet: print ' --> get time' time = read_time(file) out['time'] = time # lon,lat: if not quiet: print ' --> reading x,y' x = netcdf.use(file, 'XLONG', **{'0': 0}) y = netcdf.use(file, 'XLAT', **{'0': 0}) # tair [K-->C] if not quiet: print ' --> T air' tair = netcdf.use(file, 'T2') - 273.15 out['tair'] = Data(x, y, tair, 'Celsius') # R humidity [kg/kg --> 0--1] if not quiet: print ' --> R humidity from QV at 2m' wv = netcdf.use(file, 'Q2') # water vapor mixing ratio at 2m rhum = wv / air_sea.qsat(tair) rhum[rhum > 1] = 1 out['rhum'] = Data(x, y, rhum, '0--1') # surface pressure [Pa] if not quiet: print ' --> Surface pressure' pres = netcdf.use(file, 'PSFC') out['pres'] = Data(x, y, pres, 'Pa') # P rate [mm --> cm day-1] if not quiet: print ' --> P rate (rainc+rainnc)' rainc = netcdf.use(file, 'RAINC') rainnc = netcdf.use(file, 'RAINNC') prate = rainc + rainnc if not quiet: print ' accum2avg...' prate = accum2avg(prate, dt=time[1] - time[0]) # mm s-1 conv = 0.1 * 86400 # from mm s-1 --> cm day-1 prate = prate * conv # cm day-1 prate[prate < 0] = 0 # interpolation errors may result in negative rain! out['prate'] = Data(x, y, prate, 'cm day-1') # LW, SW, latent, sensible signs: # positive (downward flux, heating) or negative (upward flux, cooling) #https://www.myroms.org/forum/viewtopic.php?f=1&t=2621 # Net shortwave flux [W m-2] if not quiet: print ' --> Net shortwave flux' sw_down = netcdf.use(file, 'SWDOWN') albedo = netcdf.use(file, 'ALBEDO') sw_net = sw_down * (1 - albedo) out['radsw'] = Data(x, y, sw_net, 'W m-2', info='positive downward') # Net longwave flux [W m-2] if not quiet: print ' --> Net longwave flux' lw_down = netcdf.use(file, 'GLW') # positive # sst needed: if not quiet: print ' --> SST for LW up' sst = netcdf.use(file, 'SST') # K lw_net = air_sea.lwhf(sst, lw_down) # positive down # here vars have roms-agrif signs --> radlw is positive upward! #conversion to ROMS is done in surface.py out['radlw'] = Data(x, y, -lw_net, 'W m-2', info='positive upward') out['dlwrf'] = Data(x, y, -lw_down, 'W m-2', info='positive upward') # U and V wind speed 10m if not quiet: print ' --> U and V wind' uwnd = netcdf.use(file, 'U10') vwnd = netcdf.use(file, 'V10') if not quiet: print ' --> calc wind speed and stress' speed = np.sqrt(uwnd**2 + vwnd**2) taux, tauy = air_sea.wind_stress(uwnd, vwnd) out['wspd'] = Data(x, y, speed, 'm s-1') out['uwnd'] = Data(x, y, uwnd, 'm s-1') out['vwnd'] = Data(x, y, vwnd, 'm s-1') out['sustr'] = Data(x, y, taux, 'Pa') out['svstr'] = Data(x, y, tauy, 'Pa') # Cloud cover [0--1]: if not quiet: print ' --> Cloud cover for LONGWAVE. Use LONGWAVE_OUT instead...' if 'CLDFRA' in netcdf.varnames(file): clouds = netcdf.use(file, 'CLDFRA').sum(-3) clouds = np.where(clouds > 1, 1, clouds) else: if not quiet: print 'CLDFRA not found!! Using SST and air_sea.clouds' sst = netcdf.use(f, 'SST') clouds = air_sea.clouds(lw_net, sst, tair, rhum, Wtype='net') out['cloud'] = Data(x, y, clouds, 'fraction (0--1)') return out
def wrf_file_data(file,quiet=False): ''' WRF data for ROMS ''' out={} # time: if not quiet: print ' --> get time' time=read_time(file) out['time']=time # lon,lat: if not quiet: print ' --> reading x,y' x=netcdf.use(file,'XLONG',**{'0': 0}) y=netcdf.use(file,'XLAT',**{'0': 0}) # tair [K-->C] if not quiet: print ' --> T air' tair=netcdf.use(file,'T2')-273.15 out['tair']=Data(x,y,tair,'Celsius') # R humidity [kg/kg --> 0--1] if not quiet: print ' --> R humidity from QV at 2m' wv=netcdf.use(file,'Q2') # water vapor mixing ratio at 2m rhum=wv/air_sea.qsat(tair) rhum[rhum>1]=1 out['rhum']=Data(x,y,rhum,'0--1') # surface pressure [Pa] if not quiet: print ' --> Surface pressure' pres=netcdf.use(file,'PSFC') out['pres']=Data(x,y,pres,'Pa') # P rate [mm --> cm day-1] if not quiet: print ' --> P rate (rainc+rainnc)' rainc = netcdf.use(file,'RAINC') rainnc = netcdf.use(file,'RAINNC') prate=rainc+rainnc if not quiet: print ' accum2avg...' prate=accum2avg(prate,dt=time[1]-time[0]) # mm s-1 conv= 0.1*86400 # from mm s-1 --> cm day-1 prate=prate*conv # cm day-1 prate[prate<0]=0 # interpolation errors may result in negative rain! out['prate']=Data(x,y,prate,'cm day-1') # LW, SW, latent, sensible signs: # positive (downward flux, heating) or negative (upward flux, cooling) #https://www.myroms.org/forum/viewtopic.php?f=1&t=2621 # Net shortwave flux [W m-2] if not quiet: print ' --> Net shortwave flux' sw_down=netcdf.use(file,'SWDOWN') albedo=netcdf.use(file,'ALBEDO') sw_net=sw_down*(1-albedo) out['radsw']=Data(x,y,sw_net,'W m-2',info='positive downward') # Net longwave flux [W m-2] if not quiet: print ' --> Net longwave flux' lw_down=netcdf.use(file,'GLW') # positive # sst needed: if not quiet: print ' --> SST for LW up' sst=netcdf.use(file,'SST') # K lw_net = air_sea.lwhf(sst,lw_down) # positive down # here vars have roms-agrif signs --> radlw is positive upward! #conversion to ROMS is done in surface.py out['radlw']=Data(x,y,-lw_net,'W m-2',info='positive upward') out['dlwrf']=Data(x,y,-lw_down,'W m-2',info='positive upward') # U and V wind speed 10m if not quiet: print ' --> U and V wind' uwnd=netcdf.use(file,'U10') vwnd=netcdf.use(file,'V10') if not quiet: print ' --> calc wind speed and stress' speed = np.sqrt(uwnd**2+vwnd**2) taux,tauy=air_sea.wind_stress(uwnd,vwnd) out['wspd']=Data(x,y,speed,'m s-1') out['uwnd']=Data(x,y,uwnd,'m s-1') out['vwnd']=Data(x,y,vwnd,'m s-1') out['sustr']=Data(x,y,taux,'Pa') out['svstr']=Data(x,y,tauy,'Pa') # Cloud cover [0--1]: if not quiet: print ' --> Cloud cover for LONGWAVE. Use LONGWAVE_OUT instead...' if 'CLDFRA' in netcdf.varnames(file): clouds=netcdf.use(file,'CLDFRA').sum(-3) clouds=np.where(clouds>1,1,clouds) else: if not quiet: print 'CLDFRA not found!! Using SST and air_sea.clouds' sst=netcdf.use(f,'SST') clouds=air_sea.clouds(lw_net,sst,tair,rhum,Wtype='net') out['cloud']=Data(x,y,clouds,'fraction (0--1)') return out
def slicej(self, varname, ind, time=0, dist=1, plot=False, **opts): savename = False if 'savename' in opts.keys(): savename = opts['savename'] d, x, y, z, v = [[]] * 5 if varname not in netcdf.varnames(self.name): print(':: variable %s not found' % varname) if dist: return d, z, v else: return x, y, z, v isU = varname == 'u' isV = varname == 'v' if isU: if hasattr(self, 'ETA_U'): ETA = self.ETA_U eta = 'ETA_U' else: # this happens in current roms-agrif ETA = self.ETA_RHO eta = 'ETA_RHO' elif isV: ETA = self.ETA_V eta = 'ETA_V' else: ETA = self.ETA_RHO eta = 'ETA_RHO' if ind >= ETA: print('j = %d exceeds %s dimension (%d)' % (ind, eta, ETA)) if dist: return d, z, v else: return x, y, z, v x, y, h, m = self.grid.vars(ruvp=self.var_at(varname), j=ind) karg = {'SEARCHtime': time, eta.lower(): ind} v = self.use(varname, **karg) if v.ndim == 2: z = self.s_levels(time=time, ruvpw=self.var_at(varname), j=ind) elif v.ndim == 1: z = [] N = v.shape[0] if dist: d = calc.distance(x, y) if plot: pylab.figure() if v.ndim == 2: pylab.pcolor(np.tile(d, (N, 1)), z, np.ma.masked_where( np.tile(m, (N, 1)) == 0, v), shading='flat') pylab.plot(d, -h) pylab.colorbar(shrink=.7) elif v.ndim == 1: pylab.plot(d, v) if savename: pylab.savefig(savename, dpi=pylab.gcf().dpi) pylab.close(pylab.gcf()) if v.ndim == 2: return np.tile(d, (N, 1)), z, v elif v.ndim == 1: return d, z, v #np.ma.masked_where(m==0,v) else: if plot: pylab.figure() if v.ndim == 2: pylab.pcolor(tile(x, (N, 1)), z, ma.masked_where(tile(m, (N, 1)) == 0, v), shading='flat') pylab.colorbar(shrink=.7) pylab.plot(x, -h) elif v.ndim == 1: pylab.plot(x, v) if savename: pylab.savefig(savename, dpi=pylab.gcf().dpi) pylab.close(pylab.gcf()) if v.ndim == 2: m = np.tile(m, (N, 1)) == 0 return np.tile(x, (N, 1)), np.tile( y, (N, 1)), z, v #np.ma.masked_where(m,v) elif v.ndim == 1: return x, y, z, v #np.ma.masked_where(m==0,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 plt_hslice(conf, plconf, date, FA='a', nest=0, **kargs): err = '' fig = False info = {} type = 'avg' var = 'temp' slice = 'z' ind = -10 time = -1 currents = False dcurr = (3, 3) scurr = 3 lcurr = 0.2 ifig = 0 # closefig = True clim = False quiet = False outStoragePath = False cmap = None norm = None useBar = True # currents are barotropic for 2D vars (like zeta) keys = kargs.keys() if 'type' in keys: type = kargs['type'] if 'var' in keys: var = kargs['var'] if 'slice' in keys: slice = kargs['slice'] if 'ind' in keys: ind = kargs['ind'] if 'time' in keys: time = kargs['time'] if 'currents' in keys: currents = kargs['currents'] if 'dcurr' in keys: dcurr = kargs['dcurr'] if 'scurr' in keys: scurr = kargs['scurr'] if 'lcurr' in keys: lcurr = kargs['lcurr'] if 'ifig' in keys: ifig = kargs['ifig'] if 'closefig' in keys: closefig = kargs['closefig'] if 'clim' in keys: clim = kargs['clim'] if 'quiet' in keys: quiet = kargs['quiet'] if 'ostorage' in keys: outStoragePath = kargs['ostorage'] if 'cmap' in keys: cmap = kargs['cmap'] if 'usebar' in keys: useBar = kargs['usebar'] if 'norm' in keys: norm = kargs['norm'] date = dateu.parse_date(date) # find input files: args = { 'cf': conf, 'date': date, 'FA': FA, 'nest': nest, 'ostorage': outStoragePath } his = opt.nameof('out', type, **args) clm = opt.nameof('in', 'clm', **args) grd = opt.nameof('in', 'grd', **args) if not os.path.isfile(his): err = 'Main file not found (%s)' % his return err, fig, info if not os.path.isfile(grd): err = 'Grid file not found (%s)' % grd return err, fig, info r = roms.His(his, grd) # plot grid: proj, fig, ax = plt_grid(plconf, grd, ifig) def add_colorbar(handle, **args): ax = pl.gca() Data, err = opt.get_plconf(plconf, 'AXES') cbpos = Data['cbpos'][ifig] cbbgpos = Data['cbbgpos'][ifig] cbbgc = Data['cbbgcolor'][ifig] cbbga = Data['cbbgalpha'][ifig] cblab = Data['cblabel'][ifig] # colorbar bg axes: if cbbgpos: rec = pl.axes((cbpos[0] - cbpos[2] * cbbgpos[0], cbpos[1] - cbbgpos[2] * cbpos[3], cbpos[2] * (1 + cbbgpos[0] + cbbgpos[1]), cbpos[3] * (1 + cbbgpos[2] + cbbgpos[3])), axisbg=cbbgc, frameon=1) rec.patch.set_alpha(cbbga) rec.set_xticks([]) rec.set_yticks([]) for k in rec.axes.spines.keys(): rec.axes.spines[k].set_color(cbbgc) rec.axes.spines[k].set_alpha(cbbga) # colorbar: if cbpos: cbax = fig.add_axes(cbpos) if cbpos[2] > cbpos[3]: orient = 'horizontal' else: orient = 'vertical' cb = pl.colorbar(handle, cax=cbax, orientation=orient, drawedges=0, **args) pl.axes(ax) # colorbar label: if cblab: Data, err = opt.get_plconf(plconf, 'HSLICES') varnames = Data['varnames'][ifig].split(',') vnames = Data['vnames'][ifig].split(',') lab = '' for i in range(len(varnames)): if varnames[i].strip() == var: lab = vnames[i].strip() break if lab: if r.hasz(var): if slice == 'k': if ind == 0: lab = 'Bottom ' + lab elif ind in (-1, 'surface'): lab = 'Surface ' + lab elif slice == 'z': lab = lab + ' ' + str(ind) + 'm' cb.set_label(lab) def add_currkey(handle): Data, err = opt.get_plconf(plconf, 'HSLICES') pos = Data['kcurrpos'][ifig] if pos: pl.quiverkey(handle, pos[0], pos[1], lcurr, '%s m/s' % str(lcurr), labelpos='S', coordinates='axes') # hslice: if var: if slice == 'k': metodo = r.slicek elif slice == 'z': metodo = r.slicez x, y, z, v = metodo(var, ind, time, plot=False) x, y = proj(x, y) # cmap: if isinstance(cmap, basestring): try: cmap = pl.cm.cmap_d[cmap] except: try: from okean import pl_tools cmap = pl_tools.cm.cmap_d[cmap] except: cmap = pl.cm.jet # original data from clm if slice == 'k' and ind in ( -1, ) and var + '_original' in netcdf.varnames(clm): tcurr = r.datetime[time] x_o = netcdf.use(clm, 'x_original') y_o = netcdf.use(clm, 'y_original') x_o, y_o = proj(x_o, y_o) v_o = netcdf.use(clm, 'y_original') t_o = netcdf.nctime(clm, 'clim_time') # average to current time: i0, = np.where(t_o <= tcurr)[-1] i1, = np.where(t_o > tcurr)[0] v_o0 = netcdf.use(clm, var + '_original', time=i0) v_o1 = netcdf.use(clm, var + '_original', time=i1) # avg: a = tcurr - t_o[i0] b = t_o[i1] - tcurr a = a.days * 86400 + a.seconds b = b.days * 86400 + b.seconds if a == 0: v_o = v_o0 elif b == 0: v_o = v_o1 else: v_o = (v_o0 * b + v_o1 * a) / (a + b) pch = pl.pcolormesh(x_o, y_o, v_o, shading='flat', cmap=cmap) if clim: pl.clim(clim[0], clim[1]) if norm == 'log': from matplotlib.colors import LogNorm Norm = LogNorm(vmin=clim[0], vmax=clim[1]) else: Norm = None # change hypoxia colorbar/cmap if var == 'dye_01': HypoxiaLim = 135 from okean import pl_tools cmap = pl_tools.ucmaps().gen_oxygen( v=(0, HypoxiaLim, 300.)) # default is 0,135,300 !! pch = pl.pcolormesh(x, y, v, shading='flat', cmap=cmap, norm=Norm) if clim: pl.clim(clim[0], clim[1]) # hypoxia: if var == 'dye_01' and ind == 0 and ifig == 0: cond = v < 135. cond = v < HypoxiaLim cond = (v < HypoxiaLim) & (r.grid.h > 5) pm = r.grid.use('pm') pn = r.grid.use('pn') A = (1 / pm[cond] * 1 / pn[cond] / 1e6).sum() x_, y_ = proj(-98, 29.5) pl.text(x_, y_, 'Hypoxia area = %.0f km$^2$' % A, color='r', fontweight='bold', fontname='monospace', bbox=dict(edgecolor='none', facecolor='white', alpha=0.8)) # hypoxia. # colorbar: if norm == 'log': tks = 10**np.linspace(np.log10(clim[0]), np.log10(clim[1]), 4) opts = {'ticks': tks, 'format': '%.2f'} else: opts = {'ticks': None} add_colorbar(pch, **opts) if currents: if (var and r.hasz(var)) or not useBar: uvind = ind else: uvind = 'bar' x, y, z, u, v = r.sliceuv(uvind, time) xm, ym = proj(x, y) mm = np.zeros(x.shape, 'bool') mm[::dcurr[0], ::dcurr[1]] = True Data, err = opt.get_plconf(plconf, 'HSLICES') wcurr = Data['wcurr'][ifig] acurr = Data['acurr'][ifig] qvopts = {'units': 'x', 'scale': scurr, 'width': wcurr, 'alpha': acurr} if var: q = pl.quiver(xm[mm], ym[mm], u[mm], v[mm], **qvopts) else: s = np.sqrt(u**2 + v**2) q = pl.quiver(xm[mm], ym[mm], u[mm], v[mm], s[mm], **qvopts) if clim: pl.clim(clim[0], clim[1]) add_colorbar(q) add_currkey(q) # store some info that may be required later info['hasz'] = False if var and r.hasz(var): info['hasz'] = True # logo: if ifig == 0: im = os.path.join(os.path.dirname(__file__), 'logo_INOCAR.png') i = pl.imread(im) h, w = i.shape[:2] rx = .12 W = (proj.xmax - proj.xmin) * rx H = W * h / w l = proj.xmax #pl.fill([proj.xmax-W, proj.xmax, proj.xmax, proj.xmax-W], # [proj.ymin, proj.ymin, proj.ymin+2.8*H, proj.ymin+2.8*H], # '#500000',alpha=0.25,ec='none') ax.imshow(i, extent=(proj.xmax * .98 - W, proj.xmax * .98, proj.ymin + H * .1, proj.ymin + H * 1.1), zorder=1e3) #pl.text(proj.xmax-W/2., proj.ymin+2.2*H,'OOF', # fontdict={'size':14,'family':'serif'}, # color='#500000',ha='center',weight='bold') pl.text(proj.xmax * .8, proj.ymax * (-.1), r.datetime[time].strftime("%d %b %Y"), fontdict={ 'size': 11, 'family': 'monospace' }, ha='center') if FA == 'f': s = 'Pronostico desde %s' % r.datetime[0].strftime("%d %b %Y") pl.text( proj.xmax * .8, proj.ymax * (-.15), s, #pl.text(proj.xmax-W/2., proj.ymin+1.1*H,s, fontdict={'fontsize': 10}, ha='center') # logo. # lims change in some mpl versions !! pl.gca().axis([proj.xmin, proj.xmax, proj.ymin, proj.ymax]) return err, fig, info
def 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 slicell(self, varname, X, Y, time=0, plot=False, **opts): x, y, z, v, m = [[]] * 5 data = opts.get('data', False) dist = opts.get('dist', False) extrap = opts.get('extrap', False) varOnly = opts.get('retv', False) maskLimit = opts.get('lmask', 0.5) # points where interpolated mask are above # this value are considered as mask! # Most strict value is 0 X = np.array(X) Y = np.array(Y) if X.ndim > 1: X = np.squeeze(X) if Y.ndim > 1: Y = np.squeeze(X) if varname not in netcdf.varnames(self.name): print(':: variable %s not found' % varname) return x, y, z, v, m if time >= self.TIME: print('t = %d exceeds TIME dimension (%d)' % (time, self.TIME)) return x, y, z, v, m if data is False: v = self.use(varname, SEARCHtime=time) else: v = data x, y, h, m = self.grid.vars(ruvp=self.var_at(varname)) if v.ndim == 3: V = calc.griddata(x, y, v, X, Y, extrap=extrap, mask2d=m == 0, keepMaskVal=maskLimit) elif v.ndim == 2: V = calc.griddata(x, y, np.ma.masked_where(m == 0, v), X, Y, extrap=extrap, keepMaskVal=maskLimit) if varOnly: return V # Z: if v.ndim == 3: Z = self.path_s_levels(time, X, Y, rw=varname[0]) else: Z = 0. * X # X, Y, dist: if dist: Dist = calc.distance(X, Y) if v.ndim == 3: Dist = np.tile(Dist, (v.shape[0], 1)) else: if v.ndim == 3: X = np.tile(X, (v.shape[0], 1)) Y = np.tile(Y, (v.shape[0], 1)) if dist: return Dist, Z, V else: return X, Y, Z, V
if ttmp.size==time.size and np.all(ttmp==time): print ' time ok' else: print ' time differs !!!!', pres,tfix=fix_time(ttmp,pres,time[0],time[-1]) if tfix.size==time.size and np.all(tfix==time): print ' ...fixed!' else: print 'time is NOT OK. Please check !!' return out['pres']=Data(x,y,pres,'Pa') # P rate [kg m-2 s-1 -> cm/d] if not quiet: print ' --> P rate' f=files['pr'] if 'PRATE_L1' in netcdf.varnames(f): prate=netcdf.use(f,'PRATE_L1') else: prate=netcdf.use(f,'PRATE_L1_Avg_1') x=netcdf.use(f,'lon'); x[x>180]=x[x>180]-360 y=netcdf.use(f,'lat') x,y=np.meshgrid(x,y) # Conversion kg m^-2 s^-1 to cm/day prate=prate*86400*100/1000. prate=np.where(abs(prate)<1.e-4,0,prate) # check time: ttmp=load_time(f) if ttmp.size==time.size and np.all(ttmp==time): print ' time ok' else: print ' time differs !!!!', prate,tfix=fix_time(ttmp,prate,time[0],time[-1])
def time_series(self, varname, x, y, times=False, depth=False, **opts): t, z, v = [[]] * 3 RetVarOnly = False savename = False retMsg = False nearest = True # UNIQUE case Currently plot = False if 'retvar' in opts.keys(): RetVarOnly = opts['retvar'] if 'savename' in opts.keys(): savename = opts['savename'] if 'msg' in opts.keys(): retMsg = opts['msg'] if 'nearest' in opts.keys(): nearest = opts['msg'] if 'plot' in opts.keys(): plot = opts['msg'] if varname not in netcdf.varnames(self.name): msg = ':: variable %s not found' % varname if retMsg: return t, z, v, msg else: print(msg) return t, z, v isW = varname == 'w' hasZ = self.hasz(varname) if not depth is False and hasZ: if isW and depth >= self.S_W: msg = 'k = %d exceeds S_W dimension (%d)' % (depth, self.S_W) if retMsg: return t, z, v, msg else: print(msg) return t, z, v elif depth >= self.S_RHO: msg = 'k = %d exceeds S_RHO dimension (%d)' % (depth, self.S_RHO) if retMsg: return t, z, v, msg else: print(msg) return t, z, v if times is False: times = 0, len(self.tdays) if self.hast(varname) and times[-1] > self.TIME: msg = 't = %d exceeds TIME dimension (%d)' % (times[-1], self.TIME) if retMsg: return t, z, v, msg else: print(msg) return t, z, v lon, lat, hr, mr = self.grid.vars(ruvp=self.var_at(varname)) dist = (lon - x)**2 + (lat - y)**2 i, j = np.where(dist == dist.min()) i, j = i[0], j[0] v = self.use(varname, xiSEARCH=j, etaSEARCH=i, SEARCHtime=range(times[0], times[-1])).T # time: t = self.tdays[range(times[0], times[-1])] t = t + 0. * v # depth: if hasZ: h = self.grid.h[i, j] zeta = self.use('zeta', xiSEARCH=j, etaSEARCH=i, SEARCHtime=range(times[0], times[-1])) h = h + 0 * zeta z = rt.s_levels(h, zeta, self.s_params, rw=varname) z = np.squeeze(z) if not depth is False: if depth >= 0: t = t[0, :] z = z[depth, :] v = v[depth, :] else: t0, z0 = t, z t = t[0, :] z = depth + 0. * t v = calc.griddata(t0, z0, v, t, z, extrap=False, norm_xy=True) else: # not hasZ z = 0. * t if plot: pass # TODO if RetVarOnly: return v else: if retMsg: return t, z, v, '' else: return t, z, v
def slicek(self,varname,ind,time=0,plot=False,**opts): x,y,z,v=[[]]*4 RetVarOnly=False savename=False retMsg=False if ind in ('s','surf','surface'): ind=-1 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 varname not in netcdf.varnames(self.name): msg=':: variable %s not found' % varname if retMsg: return x,y,z,v,msg else: print(msg) return x,y,z,v isW=varname=='w' hasZ=self.hasz(varname) if hasZ: if isW and ind >= self.S_W: msg='k = %d exceeds S_W dimension (%d)' % (ind,self.S_W) if retMsg: return x,y,z,v,msg else: print(msg) return x,y,z,v elif ind >= self.S_RHO: msg='k = %d exceeds S_RHO dimension (%d)' % (ind,self.S_RHO) if retMsg: return x,y,z,v,msg else: print(msg) return x,y,z,v if self.hast(varname) and time>=self.TIME: msg='t = %d exceeds TIME dimension (%d)' % (time,self.TIME) if retMsg: return x,y,z,v,msg else: print(msg) return x,y,z,v if isW: v=self.use(varname,SEARCHtime=time,s_w=ind) else: v=self.use(varname,SEARCHtime=time,s_rho=ind) x,y,h,m=self.grid.vars(ruvp=self.var_at(varname)) if hasZ: z=self.s_levels(time,k=ind,ruvpw=self.var_at(varname)) else: z=self.use('zeta',SEARCHtime=time) z=rt.rho2uvp(z,varname) if not np.ma.isMA(v): # roms agrif ... v=np.ma.masked_where(m==0,v) if plot: p=self.grid.plot(bathy=None,**opts) xm, ym = p(x,y) pch=pylab.pcolor(xm,ym,v,shading='flat') pylab.colorbar(pch,shrink=.7) pylab.axis([p.xmin, p.xmax, p.ymin, p.ymax]) if savename: pylab.savefig(savename,dpi=pylab.gcf().dpi) pylab.close(pylab.gcf()) if RetVarOnly: return v else: if retMsg: return x,y,z,v,'' else: return x,y,z,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 time_series(self,varname,x,y,times=False,depth=False,**opts): t,z,v=[[]]*3 RetVarOnly=False savename=False retMsg=False nearest=True # UNIQUE case Currently plot=False if 'retvar' in opts.keys(): RetVarOnly = opts['retvar'] if 'savename' in opts.keys(): savename = opts['savename'] if 'msg' in opts.keys(): retMsg = opts['msg'] if 'nearest' in opts.keys(): nearest = opts['msg'] if 'plot' in opts.keys(): plot = opts['msg'] if varname not in netcdf.varnames(self.name): msg=':: variable %s not found' % varname if retMsg: return t,z,v,msg else: print(msg) return t,z,v isW=varname=='w' hasZ=self.hasz(varname) if not depth is False and hasZ : if isW and depth >= self.S_W: msg='k = %d exceeds S_W dimension (%d)' % (depth,self.S_W) if retMsg: return t,z,v,msg else: print(msg) return t,z,v elif depth >= self.S_RHO: msg='k = %d exceeds S_RHO dimension (%d)' % (depth,self.S_RHO) if retMsg: return t,z,v,msg else: print(msg) return t,z,v if times is False: times=0,len(self.tdays) if self.hast(varname) and times[-1]>self.TIME: msg='t = %d exceeds TIME dimension (%d)' % (times[-1],self.TIME) if retMsg: return t,z,v,msg else: print(msg) return t,z,v lon,lat,hr,mr=self.grid.vars(ruvp=self.var_at(varname)) dist=(lon-x)**2+(lat-y)**2 i,j=np.where(dist==dist.min()) i,j=i[0],j[0] v=self.use(varname,xiSEARCH=j,etaSEARCH=i,SEARCHtime=range(times[0],times[-1])).T # time: t=self.tdays[range(times[0],times[-1])] t=t+0.*v # depth: if hasZ: h=self.grid.h[i,j] zeta=self.use('zeta',xiSEARCH=j,etaSEARCH=i,SEARCHtime=range(times[0],times[-1])) h=h+0*zeta z=rt.s_levels(h,zeta,self.s_params,rw=varname) z=np.squeeze(z) if not depth is False: if depth>=0: t=t[0,:] z=z[depth,:] v=v[depth,:] else: t0,z0=t,z t=t[0,:] z=depth+0.*t v=calc.griddata(t0,z0,v,t,z,extrap=False,norm_xy=True) else: # not hasZ z=0.*t if plot: pass # TODO if RetVarOnly: return v else: if retMsg: return t,z,v,'' else: return t,z,v
def slicei(self, varname, ind, time=0, dist=1, plot=False, **opts): savename = False if "savename" in opts.keys(): savename = opts["savename"] d, x, y, z, v = [[]] * 5 if varname not in netcdf.varnames(self.name): print ":: variable %s not found" % varname if dist: return d, z, v else: return x, y, z, v isU = varname == "u" isV = varname == "v" if isU: XI = self.XI_U xi = "XI_U" elif isV: if hasattr(self, "XI_V"): XI = self.XI_V xi = "XI_V" else: # this happens in current roms-agrif XI = self.XI_RHO xi = "XI_RHO" else: XI = self.XI_RHO xi = "XI_RHO" if ind >= XI: print "j = %d exceeds %s dimension (%d)" % (ind, xi, XI) x, y, h, m = self.grid.vars(ruvp=self.var_at(varname), i=ind) karg = {"SEARCHtime": time, xi.lower(): ind} v = self.use(varname, **karg) if v.ndim == 2: z = self.s_levels(time=time, ruvpw=self.var_at(varname), i=ind) elif v.ndim == 1: z = [] N = v.shape[0] if dist: d = calc.distance(x, y) if plot: pylab.figure() if v.ndim == 2: pylab.pcolor(np.tile(d, (N, 1)), z, np.ma.masked_where(np.tile(m, (N, 1)) == 0, v), shading="flat") pylab.plot(d, -h) pylab.colorbar(shrink=0.7) elif v.ndim == 1: pylab.plot(d, v) if savename: pylab.savefig(savename, dpi=pylab.gcf().dpi) pylab.close(pylab.gcf()) if v.ndim == 2: return np.tile(d, (N, 1)), z, v # ,np.tile(m,(N,1))==0 elif v.ndim == 1: return d, z, v # ,m==0 else: if plot: pylab.figure() if v.ndim == 2: pylab.pcolor(np.tile(y, (N, 1)), z, np.ma.masked_where(np.tile(m, (N, 1)) == 0, v), shading="flat") pylab.colorbar(shrink=0.7) pylab.plot(y, -h) elif v.ndim == 1: pylab.plot(y, v) if savename: pylab.savefig(savename, dpi=pylab.gcf().dpi) pylab.close(pylab.gcf()) if v.ndim == 2: return np.tile(x, (N, 1)), np.tile(y, (N, 1)), z, v # ,np.tile(m,(N,1))==0 elif v.ndim == 1: return x, y, z, v # ,m==0
def slicek(self, varname, ind, time=0, plot=False, **opts): x, y, z, v = [[]] * 4 RetVarOnly = False savename = False retMsg = False if ind in ('s', 'surf', 'surface'): ind = -1 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 varname not in netcdf.varnames(self.name): msg = ':: variable %s not found' % varname if retMsg: return x, y, z, v, msg else: print(msg) return x, y, z, v isW = varname == 'w' hasZ = self.hasz(varname) if hasZ: if isW and ind >= self.S_W: msg = 'k = %d exceeds S_W dimension (%d)' % (ind, self.S_W) if retMsg: return x, y, z, v, msg else: print(msg) return x, y, z, v elif ind >= self.S_RHO: msg = 'k = %d exceeds S_RHO dimension (%d)' % (ind, self.S_RHO) if retMsg: return x, y, z, v, msg else: print(msg) return x, y, z, v if self.hast(varname) and time >= self.TIME: msg = 't = %d exceeds TIME dimension (%d)' % (time, self.TIME) if retMsg: return x, y, z, v, msg else: print(msg) return x, y, z, v if isW: v = self.use(varname, SEARCHtime=time, s_w=ind) else: v = self.use(varname, SEARCHtime=time, s_rho=ind) x, y, h, m = self.grid.vars(ruvp=self.var_at(varname)) if hasZ: z = self.s_levels(time, k=ind, ruvpw=self.var_at(varname)) else: z = self.use('zeta', SEARCHtime=time) z = rt.rho2uvp(z, varname) if not np.ma.isMA(v): # roms agrif ... v = np.ma.masked_where(m == 0, v) if plot: p = self.grid.plot(bathy=None, **opts) xm, ym = p(x, y) pch = pylab.pcolor(xm, ym, v, shading='flat') pylab.colorbar(pch, shrink=.7) pylab.axis([p.xmin, p.xmax, p.ymin, p.ymax]) if savename: pylab.savefig(savename, dpi=pylab.gcf().dpi) pylab.close(pylab.gcf()) if RetVarOnly: return v else: if retMsg: return x, y, z, v, '' else: return x, y, z, v
def plt_hslice(conf,plconf,date,FA='a',nest=0,**kargs): err='' fig=False info={} type = 'avg' var = 'temp' slice = 'z' ind = -10 time = -1 currents = False dcurr = (3,3) scurr = 3 lcurr = 0.2 ifig = 0 # closefig = True clim = False quiet = False outStoragePath=False cmap = None norm = None useBar = True # currents are barotropic for 2D vars (like zeta) keys=kargs.keys() if 'type' in keys: type = kargs['type'] if 'var' in keys: var = kargs['var'] if 'slice' in keys: slice = kargs['slice'] if 'ind' in keys: ind = kargs['ind'] if 'time' in keys: time = kargs['time'] if 'currents' in keys: currents = kargs['currents'] if 'dcurr' in keys: dcurr = kargs['dcurr'] if 'scurr' in keys: scurr = kargs['scurr'] if 'lcurr' in keys: lcurr = kargs['lcurr'] if 'ifig' in keys: ifig = kargs['ifig'] if 'closefig' in keys: closefig = kargs['closefig'] if 'clim' in keys: clim = kargs['clim'] if 'quiet' in keys: quiet = kargs['quiet'] if 'ostorage' in keys: outStoragePath = kargs['ostorage'] if 'cmap' in keys: cmap = kargs['cmap'] if 'usebar' in keys: useBar = kargs['usebar'] if 'norm' in keys: norm = kargs['norm'] date=dateu.parse_date(date) # find input files: args={'cf':conf,'date':date,'FA':FA,'nest':nest,'ostorage':outStoragePath} his = opt.nameof('out',type,**args) clm = opt.nameof('in','clm',**args) grd = opt.nameof('in','grd',**args) if not os.path.isfile(his): err='Main file not found (%s)' % his return err,fig,info if not os.path.isfile(grd): err='Grid file not found (%s)' % grd return err,fig,info r=roms.His(his,grd) # plot grid: proj,fig, ax = plt_grid(plconf,grd,ifig) def add_colorbar(handle,**args): ax=pl.gca() Data,err = opt.get_plconf(plconf,'AXES') cbpos = Data['cbpos'][ifig] cbbgpos = Data['cbbgpos'][ifig] cbbgc = Data['cbbgcolor'][ifig] cbbga = Data['cbbgalpha'][ifig] cblab = Data['cblabel'][ifig] # colorbar bg axes: if cbbgpos: rec=pl.axes((cbpos[0]-cbpos[2]*cbbgpos[0],cbpos[1]-cbbgpos[2]*cbpos[3], cbpos[2]*(1+cbbgpos[0]+cbbgpos[1]),cbpos[3]*(1+cbbgpos[2]+cbbgpos[3])), axisbg=cbbgc,frameon=1) rec.patch.set_alpha(cbbga) rec.set_xticks([]) rec.set_yticks([]) for k in rec.axes.spines.keys(): rec.axes.spines[k].set_color(cbbgc) rec.axes.spines[k].set_alpha(cbbga) # colorbar: if cbpos: cbax=fig.add_axes(cbpos) if cbpos[2]>cbpos[3]: orient='horizontal' else: orient='vertical' cb=pl.colorbar(handle,cax=cbax,orientation=orient,drawedges=0,**args) pl.axes(ax) # colorbar label: if cblab: Data,err = opt.get_plconf(plconf,'HSLICES') varnames=Data['varnames'][ifig].split(',') vnames=Data['vnames'][ifig].split(',') lab='' for i in range(len(varnames)): if varnames[i].strip()==var: lab=vnames[i].strip() break if lab: if r.hasz(var): if slice=='k': if ind==0: lab = 'Bottom '+lab elif ind in (-1,'surface'): lab = 'Surface '+lab elif slice=='z': lab=lab+' '+str(ind)+'m' cb.set_label(lab) def add_currkey(handle): Data,err = opt.get_plconf(plconf,'HSLICES') pos=Data['kcurrpos'][ifig] if pos: pl.quiverkey(handle, pos[0], pos[1], lcurr, '%s m/s' % str(lcurr),labelpos='S', coordinates='axes') # hslice: if var: if slice=='k': metodo=r.slicek elif slice=='z': metodo=r.slicez x,y,z,v=metodo(var,ind,time,plot=False) x,y=proj(x,y) # cmap: if isinstance(cmap,basestring): try:cmap=pl.cm.cmap_d[cmap] except: try: from okean import pl_tools cmap=pl_tools.cm.cmap_d[cmap] except: cmap=pl.cm.jet # original data from clm if slice=='k' and ind in (-1,) and var+'_original' in netcdf.varnames(clm): tcurr= r.datetime[time] x_o=netcdf.use(clm,'x_original') y_o=netcdf.use(clm,'y_original') x_o,y_o=proj(x_o,y_o) v_o=netcdf.use(clm,'y_original') t_o=netcdf.nctime(clm,'clim_time') # average to current time: i0,=np.where(t_o<=tcurr)[-1] i1,=np.where(t_o>tcurr)[0] v_o0=netcdf.use(clm,var+'_original',time=i0) v_o1=netcdf.use(clm,var+'_original',time=i1) # avg: a=tcurr-t_o[i0] b=t_o[i1]-tcurr a=a.days*86400+a.seconds b=b.days*86400+b.seconds if a==0: v_o=v_o0 elif b==0: v_o=v_o1 else: v_o=(v_o0*b+v_o1*a)/(a+b) pch=pl.pcolormesh(x_o,y_o,v_o,shading='flat',cmap=cmap) if clim: pl.clim(clim[0],clim[1]) if norm=='log': from matplotlib.colors import LogNorm Norm=LogNorm(vmin=clim[0],vmax=clim[1]) else: Norm=None # change hypoxia colorbar/cmap if var=='dye_01': HypoxiaLim=135 from okean import pl_tools cmap=pl_tools.ucmaps().gen_oxygen(v=(0,HypoxiaLim,300.)) # default is 0,135,300 !! pch=pl.pcolormesh(x,y,v,shading='flat',cmap=cmap, norm=Norm) if clim: pl.clim(clim[0],clim[1]) # hypoxia: if var=='dye_01' and ind==0 and ifig==0: cond=v<135. cond=v<HypoxiaLim cond=(v<HypoxiaLim)&(r.grid.h>5) pm=r.grid.use('pm') pn=r.grid.use('pn') A=(1/pm[cond]*1/pn[cond]/1e6).sum() x_,y_=proj(-98,29.5) pl.text(x_,y_,'Hypoxia area = %.0f km$^2$' % A,color='r', fontweight='bold',fontname='monospace', bbox=dict(edgecolor='none',facecolor='white', alpha=0.8)) # hypoxia. # colorbar: if norm=='log': tks=10**np.linspace(np.log10(clim[0]),np.log10(clim[1]),4) opts={'ticks':tks,'format':'%.2f'} else: opts={'ticks':None} add_colorbar(pch,**opts) if currents: if (var and r.hasz(var)) or not useBar: uvind=ind else: uvind='bar' x,y,z,u,v=r.sliceuv(uvind,time) xm, ym = proj(x,y) mm=np.zeros(x.shape,'bool') mm[::dcurr[0],::dcurr[1]]=True Data,err = opt.get_plconf(plconf,'HSLICES') wcurr=Data['wcurr'][ifig] acurr=Data['acurr'][ifig] qvopts={'units':'x','scale':scurr,'width':wcurr,'alpha':acurr} if var: q=pl.quiver(xm[mm],ym[mm],u[mm],v[mm],**qvopts) else: s=np.sqrt(u**2+v**2) q=pl.quiver(xm[mm],ym[mm],u[mm],v[mm],s[mm],**qvopts) if clim: pl.clim(clim[0],clim[1]) add_colorbar(q) add_currkey(q) # store some info that may be required later info['hasz']=False if var and r.hasz(var): info['hasz']=True # logo: if ifig==0: im=os.path.join(os.path.dirname(__file__),'logo_INOCAR.png') i=pl.imread(im) h,w=i.shape[:2] rx=.12 W=(proj.xmax- proj.xmin)*rx H=W*h/w l=proj.xmax #pl.fill([proj.xmax-W, proj.xmax, proj.xmax, proj.xmax-W], # [proj.ymin, proj.ymin, proj.ymin+2.8*H, proj.ymin+2.8*H], # '#500000',alpha=0.25,ec='none') ax.imshow(i,extent=(proj.xmax*.98-W,proj.xmax*.98, proj.ymin+H*.1, proj.ymin+H*1.1),zorder=1e3) #pl.text(proj.xmax-W/2., proj.ymin+2.2*H,'OOF', # fontdict={'size':14,'family':'serif'}, # color='#500000',ha='center',weight='bold') pl.text(proj.xmax*.8, proj.ymax*(-.1),r.datetime[time].strftime("%d %b %Y"), fontdict={'size':11,'family':'monospace'},ha='center') if FA=='f': s='Pronostico desde %s' % r.datetime[0].strftime("%d %b %Y") pl.text(proj.xmax*.8, proj.ymax*(-.15),s, #pl.text(proj.xmax-W/2., proj.ymin+1.1*H,s, fontdict={'fontsize':10},ha='center') # logo. # lims change in some mpl versions !! pl.gca().axis([proj.xmin, proj.xmax, proj.ymin, proj.ymax]) return err, fig, info