def add_grid_bounds(self,lon_p=None,lat_p=None): """Generate grid cell boundaries either by sub-sampling lon and lat or from input arguments Parameters ---------- lon_p,lat_p : 2D arrays, optional lon,lat axes of grid cell boundaries Attributes added ---------------- lon_p,lat_p : lon,lat axes of p vertices (u boundaries) """ if lon_p is None or lat_p is None: lo,la = geo.waypoints_segments(self.lon,self.lat,n=2) self.lon_p = lo[1:len(lo):2] self.lat_p = la[1:len(la):2] else: self.lon_p = lon_p[self.j,self.ii] self.lat_p = lat_p[self.j,self.ii]
def __init__(self, longrid, latgrid, lat0, lonw=None, lone=None, add_bounds=False): self.lat0 = lat0 # take care of NaN masks latgrid = np.ma.masked_invalid(latgrid) longrid = np.ma.masked_invalid(longrid) longrid = np.mod(longrid[:], 360) # mask the latgrid for mean taking if lonw is None or lone is None: latgrid_masked = latgrid else: self.lone = np.mod(lone, 360) or 360 self.lonw = np.mod(lonw, 360) or 360 # limit the selectable region zonally if self.lonw <= self.lone: latgrid_masked = np.ma.masked_where( ((longrid >= self.lonw) & (longrid <= self.lone)),latgrid[:]) else: latgrid_masked = np.ma.masked_where( ((longrid >= self.lonw) | (longrid <= self.lone)),latgrid[:]) # find position of best fitting zonal section latmean = np.mean(latgrid_masked, axis=1) self.j = j = np.argmin(np.abs(latmean-lat0)) # find the zonal boundaries of the section lonband = longrid[j,:] if lonw is None or lone is None: regmask = ~np.ma.getmaskarray(latgrid_masked[j,:]) if regmask.all(): # nothing masked iw,ie = 0,len(lonband)-1 elif regmask[[0,-1]].all(): # region wraps around # find largest connected region of False cr = np.cumsum(regmask) regmask_largest = cr == np.argmax(np.bincount(cr)) ie,iw = np.where(regmask_largest)[0][[0,-1]] ; ie+=1 else: iw,ie = np.where(regmask)[0][[0,-1]] else: iw = np.argmin(np.abs(lonband-self.lonw)) ie = np.argmin(np.abs(lonband-self.lone)) if iw > ie: ii = np.concatenate([np.arange(iw,len(lonband)),np.arange(0,ie+1)]) else: ii = np.arange(iw,ie+1) self.ii = ii if add_bounds: iipad = np.concatenate(([ii[0]-1], ii, [ii[-1]+1])) iipad = np.mod(iipad, len(lonband)) else: iipad = ii # make sure longitude axis is monotonically increasing lontmp = geo.make_lon_continuous(np.ma.getdata(longrid[j,iipad])) lattmp = np.ma.getdata(latgrid[j,iipad]) if add_bounds: self.lon_p, self.lat_p = geo.waypoints_segments(lontmp, lattmp, f=0.5) self.lon_p = geo.make_lon_continuous(self.lon_p) self.lon = lontmp[1:-1] self.lat = lattmp[1:-1] else: self.lon = lontmp self.lat = lattmp self.ii = ii self.jj = np.ones(len(ii), 'i4') * j # latitude axis self.meanlat = np.mean(self.lat) # add descriptions self.desc = 'zonal transect around {:.2f} N'.format(self.meanlat) self.lat0str = '{:.0f}S'.format(-lat0) if lat0 < 0 else '{:.0f}N'.format(lat0) self.meanlatstr = '{:.2f}S'.format(-self.meanlat) if lat0 < 0 else '{:.2f}N'.format(self.meanlat)