def ingrid(self,x,y,retInds=False): '''in polygon of region border''' xb,yb=self.border() i=calc.inpolygon(x,y,xb,yb) if retInds: return x[i!=0], y[i!=0], np.where(i)[0] else: return x[i!=0], y[i!=0]
def grid_vicinity(grid, x, y, margin=5, rect=False, retinds=False): ''' Returns True for x,y points inside roms grid boundary plus margin. Margin is the number of cells to add around the grid. if rect is True returns True for all points in the smallest 2d xy grid (usually a rectangle) around the grid. In this case,margin is the rectangle margin, ie, in units of xy, not in units of grid if retinds, in the case of rect, the rectangle j1,j2 and i1,i2 are also returned (cond,inds=grid_vicinity(....); i1,i2,j1,j2=inds) mma, TAMU 2011 ''' xg = netcdf.use(grid, 'lon_rho') yg = netcdf.use(grid, 'lat_rho') xlim = xg.min(), xg.max() ylim = yg.min(), yg.max() if x.ndim == 1 and y.ndim == 1: x, y = np.meshgrid(x, y) if rect: out = np.zeros(x.shape, 'bool') i1, i2, j1, j2 = calc.ij_limits(x, y, xlim, ylim, margin) out[j1:j2, i1:i2] = 1 else: from roms import Grid g = Grid(grid) xb, yb = g.border(margin=-margin) out = calc.inpolygon(x, y, xb, yb) if rect and retinds: return out, (i1, i2, j1, j2) else: return out
def grid_vicinity(grid,x,y,margin=5,rect=False,retinds=False): ''' Returns True for x,y points inside roms grid boundary plus margin. Margin is the number of cells to add around the grid. if rect is True returns True for all points in the smallest 2d xy grid (usually a rectangle) around the grid. In this case,margin is the rectangle margin, ie, in units of xy, not in units of grid if retinds, in the case of rect, the rectangle j1,j2 and i1,i2 are also returned (cond,inds=grid_vicinity(....); i1,i2,j1,j2=inds) mma, TAMU 2011 ''' xg=netcdf.use(grid,'lon_rho') yg=netcdf.use(grid,'lat_rho') xlim=xg.min(),xg.max() ylim=yg.min(),yg.max() if x.ndim==1 and y.ndim==1: x,y=np.meshgrid(x,y) if rect: out=np.zeros(x.shape,'bool') i1,i2,j1,j2=calc.ij_limits(x,y,xlim,ylim,margin) out[j1:j2,i1:i2]=1 else: from roms import Grid g=Grid(grid) xb,yb=g.border(margin=-margin) out=calc.inpolygon(x,y,xb,yb) if rect and retinds: return out,(i1,i2,j1,j2) else: return out
def centres(self): ''' Needed for area weighted averages ''' from okean import calc elements = [] for e in self.q.IKLE2: element = [] for n in e: element.append((self.x[n], self.y[n])) elements.append(element) elements = np.asarray(elements) X = elements[:, :, 0] Y = elements[:, :, 1] n = len(X) Cx = np.zeros(n, 'f') Cy = np.zeros(n, 'f') A = np.zeros(n, 'f') inp = np.zeros(n, 'bool') for i in range(n): A[i] = calc.poly_area(X[i], Y[i]) Cx[i], Cy[i] = calc.poly_centroid(X[i], Y[i]) # check if centre is inside polygon: inp[i] = calc.inpolygon(Cx[i], Cy[i], X[i], Y[i]) self.xc = Cx self.yc = Cy if any(~inp): A = np.ma.masked_where(~inp, A) self.area = A self.inp = inp
def centres(self): ''' Needed for area weighted averages ''' from okean import calc elements = [] for e in self.q.IKLE2: element = [] for n in e: element.append((self.x[n],self.y[n])) elements.append(element) elements=np.asarray(elements) X=elements[:,:,0] Y=elements[:,:,1] n=len(X) Cx=np.zeros(n,'f') Cy=np.zeros(n,'f') A=np.zeros(n,'f') inp=np.zeros(n,'bool') for i in range(n): A[i]=calc.poly_area(X[i],Y[i]) Cx[i],Cy[i]=calc.poly_centroid(X[i],Y[i]) # check if centre is inside polygon: inp[i]=calc.inpolygon(Cx[i],Cy[i],X[i],Y[i]) self.xc=Cx self.yc=Cy if any(~inp): A=np.ma.masked_where(~inp,A) self.area=A self.inp=inp
def ingrid(self, x, y, retInds=False): '''in polygon of region border''' xb, yb = self.border() i = calc.inpolygon(x, y, xb, yb) if retInds: return x[i != 0], y[i != 0], np.where(i)[0] else: return x[i != 0], y[i != 0]
def inside(self, x, y): '''Returns data inside the polygon x,y If len(x)==2, the polygon is the rectangle with limits x[0],x[1] and y[0],y[1] Return lon, lat, name and country -180<=x<=180; -90<=y<=90 ''' if len(x) == 2: # rectangle x = x[0], x[1], x[1], x[0] y = y[0], y[0], y[1], y[1] inp = calc.inpolygon(self.lon, self.lat, x, y) return self.lon[inp], self.lat[inp], self.name[inp], self.country[inp]
def inside(self,x,y): '''Returns data inside the polygon x,y If len(x)==2, the polygon is the rectangle with limits x[0],x[1] and y[0],y[1] Return lon, lat, name and country -180<=x<=180; -90<=y<=90 ''' if len(x)==2: # rectangle x=x[0],x[1],x[1],x[0] y=y[0],y[0],y[1],y[1] inp=calc.inpolygon(self.lon,self.lat,x,y) return self.lon[inp],self.lat[inp],self.name[inp],self.country[inp]
def locate(self,varname,quiet=1): # find points inside grid: inds=self.roms.grid.ingrid(self.x,self.y) inds=np.where(inds)[0] # lon, lat: lon,lat=self.model_lon_lat(varname) ntimes=len(self.t) V=np.ma.array(()) Iind,Jind,Tind=[],[],[] INDS=[] for c in range(ntimes): if not quiet: print(' %s %d of %d' % (self.t[c].isoformat(' '),c,ntimes)) if not c in inds: if not quiet: print(' - outside domain in time %s'%t[c].isoformat()) INDS+=[(-1,-1,-1)] continue # find time indices: if self.t[c]>=self.roms.time[0] and self.t[c]<=self.roms.time[-1]: i0=np.where(self.roms.time<=self.t[c])[0][-1] else: i0=-1 # find i,j bbox: d=(lon-self.x[c])**2+(lat-self.y[c])**2 i,j=np.where(d==d.min()) i=i[0] j=j[0] isIn=False for I in [i-1,i]: if I+1>=lon.shape[0] or I<0: continue for J in [j-1,j]: if J+1>=lon.shape[1] or J<0: continue xp=[lon[I,J],lon[I,J+1],lon[I+1,J+1],lon[I+1,J]] yp=[lat[I,J],lat[I,J+1],lat[I+1,J+1],lat[I+1,J]] if calc.inpolygon(self.x[c],self.y[c],xp,yp): i,j=I,J isIn=True break else: # Continue if the inner loop wasn't broken. continue # Inner loop was broken, break the outer. break INDS+=[(i,j,i0)] Iind+=[ i, i, i+1, i+1 ] Jind+=[ j, j+1, j+1, j ] Tind+=[i0, i0, i0, i0 ] if i0<0: ii0=i0 else: ii0=i0+1 Iind+=[ i, i, i+1, i+1 ] Jind+=[ j, j+1, j+1, j ] Tind+=[ii0, ii0, ii0, ii0 ] Iind=np.asarray(Iind) Jind=np.asarray(Jind) Tind=np.asarray(Tind) INDS=np.asarray(INDS) # deal with points at boundary ! just in case... imax,jmax=[k-1 for k in lon.shape] tmax=self.roms.time.size-1 Iind=np.where(Iind>imax,imax,Iind) Jind=np.where(Jind>jmax,jmax,Jind) Tind=np.where(Tind>tmax,tmax,Tind) inds=[(Iind[i],Jind[i],Tind[i]) for i in range(len(Iind))] uinds=np.asarray(list(frozenset(inds))) tag=self.horiz_var_type(varname) self.inds0[tag]=INDS self.uinds[tag]=uinds return INDS, uinds
def ingrid(self,x,y,**kargs):#,retInds=False): '''in polygon of region border''' xb,yb=self.border(**kargs) return calc.inpolygon(x,y,xb,yb)
def his2gnome(fname, his, grd=False, nomask=False, gshhsMask=True, xylim=False, dates=False, ij=(1, 1)): ''' Creates GNOME wind file Ex: his2gnome(out,his,grd,dates=dates,ij=(2,2)) if gshhsMask, the high res mask file mask_gshhs.npy will be created at 1st usage. Mask is based on high (h) resolution gshhs data which must be available (env variable GSHHS_MASK must be set). ''' if not grd: grd = his deta, dxi = ij dims = netcdf.fdim(his) xi, eta = dims['xi_rho'], dims['eta_rho'] xi0, eta0 = xi, eta nc0 = netcdf.ncopen(his) time = netcdf.nctime(nc0, 'ocean_time') # for roms agrif: #t=netcdf.use(nc0,'scrum_time') #time=netcdf.num2date(t,'seconds since %d-01-01' % year0) x0 = netcdf.use(grd, 'lon_rho') y0 = netcdf.use(grd, 'lat_rho') ang = netcdf.use(grd, 'angle') if not xylim is False: xlim = xylim[:2] ylim = xylim[2:] i1, i2, j1, j2 = calc.ij_limits(x0, y0, xlim, ylim) print(i1, i2, j1, j2) xi = i2 - i1 eta = j2 - j1 else: i1, i2 = 0, xi j1, j2 = 0, eta XI = '%d:%d:%d' % (i1, i2, dxi) ETA = '%d:%d:%d' % (j1, j2, deta) xi = len(range(i1, i2, dxi)) eta = len(range(j1, j2, deta)) # create file: create_uv(fname, xi, eta) nc = netcdf.ncopen(fname, 'a') for v0, v in ('lon_rho', 'lon'), ('lat_rho', 'lat'), ('mask_rho', 'mask'), ('h', 'depth'): print('filling %s with %s' % (v, v0)) nc.vars[v][:] = netcdf.use(grd, v0, xi_rho=XI, eta_rho=ETA) if nomask: print('NO MASK !!!') nc.vars['mask'][:] = 1 if gshhsMask: try: mask = np.load('mask_gshhs.npy') except: mask = 1 + 0 * netcdf.use(nc0, 'mask_rho', xi_rho=XI, eta_rho=ETA) mask = mask.astype('bool') x = netcdf.use(grd, 'lon_rho', xi_rho=XI, eta_rho=ETA) y = netcdf.use(grd, 'lat_rho', xi_rho=XI, eta_rho=ETA) from okean import gshhs axis = x.min(), x.max(), y.min(), y.max() g = gshhs.gshhs(axis, resolution='h', area_thresh=0., max_level=2, clip=True) for lon, lat, level in zip(g.lon, g.lat, g.level): if level == 1: # land print('mask ', lon.shape) i = calc.inpolygon(x, y, lon, lat) mask = mask & ~i mask.dump('mask_gshhs.npy') nc.vars['mask'][:] = mask x = x0[j1:j2:deta, i1:i2:dxi] y = y0[j1:j2:deta, i1:i2:dxi] ang = ang[j1:j2:deta, i1:i2:dxi] n = -1 for it in range(len(time)): if not dates is False: d0, d1 = dates if time[it] < d0 or time[it] >= d1: continue n += 1 U = np.zeros((eta0, xi0), 'f') V = np.zeros((eta0, xi0), 'f') nc.vars['time'][n] = netcdf.date2num(time[it], tunits) # for roms agrif: #u=netcdf.use(nc0,'u',time=it,s_rho=-1) #v=netcdf.use(nc0,'v',time=it,s_rho=-1) u = netcdf.use(nc0, 'u', ocean_time=it, s_rho=-1) v = netcdf.use(nc0, 'v', ocean_time=it, s_rho=-1) # mask extrap: print('mask extrap...') u = calc.mask_extrap(x0, y0, np.ma.masked_where(u == 0, u)) v = calc.mask_extrap(x0, y0, np.ma.masked_where(v == 0, v)) U[:, 1:-1] = 0.5 * (u[:, :-1] + u[:, 1:]) U[:, 0] = u[:, 0] U[:, -1] = u[:, -1] V[1:-1, :] = 0.5 * (v[:-1.:] + v[1:, :]) V[0, :] = v[0, :] V[-1, :] = v[-1, :] U = U[j1:j2, i1:i2] V = V[j1:j2, i1:i2] U = U[j1:j2:deta, i1:i2:dxi] V = V[j1:j2:deta, i1:i2:dxi] # rotate uv: print('rotating ...') U, V = calc.rot2d(U, V, -ang) print('filling uv', n, time[it]) nc.vars['u'][n, ...] = U nc.vars['v'][n, ...] = V nc.close() nc0.close()
def his2gnome(fname,his,grd=False,nomask=False,gshhsMask=True,xylim=False,dates=False,ij=(1,1)): ''' Creates GNOME wind file Ex: his2gnome(out,his,grd,dates=dates,ij=(2,2)) if gshhsMask, the high res mask file mask_gshhs.npy will be created at 1st usage. Mask is based on high (h) resolution gshhs data which must be available (env variable GSHHS_MASK must be set). ''' if not grd: grd=his deta,dxi=ij dims=netcdf.fdim(his) xi,eta=dims['xi_rho'],dims['eta_rho'] xi0,eta0=xi,eta nc0=netcdf.ncopen(his) time=netcdf.nctime(nc0,'ocean_time') # for roms agrif: #t=netcdf.use(nc0,'scrum_time') #time=netcdf.num2date(t,'seconds since %d-01-01' % year0) x0=netcdf.use(grd,'lon_rho') y0=netcdf.use(grd,'lat_rho') ang=netcdf.use(grd,'angle') if not xylim is False: xlim=xylim[:2] ylim=xylim[2:] i1,i2,j1,j2=calc.ij_limits(x0,y0,xlim,ylim) print i1,i2,j1,j2 xi=i2-i1 eta=j2-j1 else: i1,i2=0,xi j1,j2=0,eta XI ='%d:%d:%d' %(i1,i2,dxi) ETA ='%d:%d:%d' %(j1,j2,deta) xi=len(range(i1,i2,dxi)) eta=len(range(j1,j2,deta)) # create file: create_uv(fname,xi,eta) nc=netcdf.ncopen(fname,'a') for v0,v in ('lon_rho','lon'),('lat_rho','lat'),('mask_rho','mask'),('h','depth'): print 'filling %s with %s' % (v,v0) nc.vars[v][:]=netcdf.use(grd,v0,xi_rho=XI,eta_rho=ETA) if nomask: print 'NO MASK !!!' nc.vars['mask'][:]=1 if gshhsMask: try: mask=np.load('mask_gshhs.npy') except: mask=1+0*netcdf.use(nc0,'mask_rho',xi_rho=XI,eta_rho=ETA) mask=mask.astype('bool') x=netcdf.use(grd,'lon_rho',xi_rho=XI,eta_rho=ETA) y=netcdf.use(grd,'lat_rho',xi_rho=XI,eta_rho=ETA) from okean import gshhs axis=x.min(),x.max(),y.min(),y.max() g=gshhs.gshhs(axis, resolution='h',area_thresh=0., max_level=2,clip=True) for lon, lat, level in zip(g.lon, g.lat, g.level): if level == 1: # land print 'mask ',lon.shape i=calc.inpolygon(x,y,lon,lat) mask=mask & ~i mask.dump('mask_gshhs.npy') nc.vars['mask'][:]=mask x=x0[j1:j2:deta,i1:i2:dxi] y=y0[j1:j2:deta,i1:i2:dxi] ang=ang[j1:j2:deta,i1:i2:dxi] n=-1 for it in range(len(time)): if not dates is False: d0,d1=dates if time[it]<d0 or time[it]>=d1: continue n+=1 U=np.zeros((eta0,xi0),'f') V=np.zeros((eta0,xi0),'f') nc.vars['time'][n]=netcdf.date2num(time[it],tunits) # for roms agrif: #u=netcdf.use(nc0,'u',time=it,s_rho=-1) #v=netcdf.use(nc0,'v',time=it,s_rho=-1) u=netcdf.use(nc0,'u',ocean_time=it,s_rho=-1) v=netcdf.use(nc0,'v',ocean_time=it,s_rho=-1) # mask extrap: print 'mask extrap...' u=calc.mask_extrap(x0,y0,np.ma.masked_where(u==0,u)) v=calc.mask_extrap(x0,y0,np.ma.masked_where(v==0,v)) U[:,1:-1]=0.5*(u[:,:-1]+u[:,1:]) U[:,0]=u[:,0] U[:,-1]=u[:,-1] V[1:-1,:]=0.5*(v[:-1.:]+v[1:,:]) V[0,:]=v[0,:] V[-1,:]=v[-1,:] U=U[j1:j2,i1:i2] V=V[j1:j2,i1:i2] U=U[j1:j2:deta,i1:i2:dxi] V=V[j1:j2:deta,i1:i2:dxi] # rotate uv: print 'rotating ...' U,V=calc.rot2d(U,V,-ang) print 'filling uv', n, time[it] nc.vars['u'][n,...]=U nc.vars['v'][n,...]=V nc.close() nc0.close()
def ingrid(self,x,y):#,retInds=False): '''in polygon of region border''' xb,yb=self.border() return calc.inpolygon(x,y,xb,yb)