def acab_epsg3413(args, nc_racmo, nc_bamber, nc_base, base, proj_epsg3413, proj_eigen_gl04c): bamber = projections.DataGrid() bamber.y = nc_bamber.variables['projection_y_coordinate'] bamber.x = nc_bamber.variables['projection_x_coordinate'] bamber.ny = bamber.y[:].shape[0] bamber.nx = bamber.x[:].shape[0] bamber.make_grid() speak.verbose(args, ' Interpolating smb to acab in base grid.') sys.stdout.write(" [%-60s] %d%%" % ('=' * 0, 0.)) sys.stdout.flush() racmo_data = nc_racmo.variables['smb'][:, ::-1].transpose() / 910. racmo_data = np.ma.masked_invalid( racmo_data) # find invalid data and create a mask racmo_data = racmo_data.filled(0.) # fill invalid data with zeros base2bamber = projections.transform(base, proj_epsg3413, proj_eigen_gl04c) racmo_interp = scipy.interpolate.RectBivariateSpline( bamber.y[:], bamber.x[:], racmo_data, kx=1, ky=1, s=0) # regular 2d linear interp. but faster base_bamber = np.zeros(base.dims) for ii in range(0, base.nx): ctr = (ii * 60) / base.nx sys.stdout.write("\r [%-60s] %d%%" % ('=' * ctr, ctr / 60. * 100.)) sys.stdout.flush() base_bamber[:, ii] = racmo_interp.ev(base2bamber.y_grid[:, ii], base2bamber.x_grid[:, ii]) sys.stdout.write("\r [%-60s] %d%%\n" % ('=' * 60, 100.)) sys.stdout.flush() #NOTE: RectBivariateSpline extrapolates data outside the convex hull # (constant value), so, we need to create a mask for values outisde # the IceBridge convex hull... base_y_mask = np.ma.masked_outside(base2bamber.y_grid, bamber.y[0], bamber.y[-1]) base_x_mask = np.ma.masked_outside(base2bamber.x_grid, bamber.x[0], bamber.x[-1]) base_masked = np.ma.masked_array(base_bamber, mask=np.logical_or( base_y_mask.mask, base_x_mask.mask)) base.var = nc_base.createVariable('acab', 'f4', ( 'y', 'x', )) base.var[:] = base_masked.filled(0.) base.var.long_name = 'Water Equivalent Surface Mass Balance' base.var.standard_name = 'land_ice_lwe_surface_specific_mass_balance' base.var.units = 'mm/year' base.var.grid_mapping = 'epsg_3413' base.var.coordinates = 'lon lat' base.var.source = 'Ian Howat' base.var.comments = '1961--1990 mean surface mass balance from RACMO 2.0 '
def velocity_epsg3413(args, nc_insar, nc_base, base): insar = projections.DataGrid() insar.y = nc_insar.variables['y'] insar.x = nc_insar.variables['x'] insar.ny = insar.y[:].shape[0] insar.nx = insar.x[:].shape[0] insar.make_grid() for var in ['vy', 'vx', 'ey', 'ex']: speak.verbose(args, ' Interpolating ' + var + ' and writing to base.') sys.stdout.write(" [%-60s] %d%%" % ('=' * 0, 0.)) sys.stdout.flush() insar_data = np.ma.masked_values(nc_insar.variables[var][:, :], -2.e9) data_min = insar_data.min() data_max = insar_data.max() insar_to_base = scipy.interpolate.RectBivariateSpline( insar.y[:], insar.x[:], insar_data, kx=1, ky=1, s=0) # regular 2d linear interp. but faster base_data = np.zeros(base.dims) for ii in range(0, base.nx): ctr = (ii * 60) / base.nx sys.stdout.write("\r [%-60s] %d%%" % ('=' * ctr, ctr / 60. * 100.)) sys.stdout.flush() base_data[:, ii] = insar_to_base.ev(base.y_grid[:, ii], base.x_grid[:, ii]) sys.stdout.write("\r [%-60s] %d%%\n" % ('=' * 60, 100.)) sys.stdout.flush() base_data[base_data < data_min] = -2.e9 base_data[base_data > data_max] = -2.e9 base.var = nc_base.createVariable(var, 'f4', ( 'y', 'x', )) base.var[:] = base_data[:] copy_atts(nc_insar.variables[var], base.var) base.var.grid_mapping = 'epsg_3413' base.var.coordinates = 'lon lat'
def main(args): #FIXME: Pick projection based on input file! proj_epsg3413, proj_eigen_gl04c = projections.greenland() if args.projection == 'epsg': proj = proj_epsg3413 scrip_title = "CISM EPSG:3413 Grid" elif args.projection == 'bamber': proj = proj_eigen_gl04c scrip_title = "CISM Bamber Grid" # load the dataset nc_base = Dataset(args.input, 'r') base = projections.DataGrid() base.y = nc_base.variables[args.dims[0]] base.x = nc_base.variables[args.dims[1]] base.dy = base.y[1]-base.y[0] base.dx = base.x[1]-base.x[0] base.ny = base.y[:].shape[0] base.nx = base.x[:].shape[0] base.N = base.ny*base.nx base.make_grid() lon_grid, lat_grid = proj(base.x_grid.ravel(), base.y_grid.ravel(), inverse=True) lon_grid.shape = base.x_grid.shape lat_grid.shape = base.x_grid.shape base.lon_grid = lon_grid base.lat_grid = lat_grid base.ll_y = base.y_grid.flatten(order='C') - base.dy/2. base.ll_x = base.x_grid.flatten(order='C') - base.dx/2. base.lr_y = base.y_grid.flatten(order='C') - base.dy/2. base.lr_x = base.x_grid.flatten(order='C') + base.dx/2. base.ur_y = base.y_grid.flatten(order='C') + base.dy/2. base.ur_x = base.x_grid.flatten(order='C') + base.dx/2. base.ul_y = base.y_grid.flatten(order='C') + base.dy/2. base.ul_x = base.x_grid.flatten(order='C') - base.dx/2. base.ll_lon, base.ll_lat = proj(base.ll_x, base.ll_y, inverse=True) base.lr_lon, base.lr_lat = proj(base.lr_x, base.lr_y, inverse=True) base.ur_lon, base.ur_lat = proj(base.ur_x, base.ur_y, inverse=True) base.ul_lon, base.ul_lat = proj(base.ul_x, base.ul_y, inverse=True) base.corner_lat = numpy.column_stack((base.ll_lat, base.lr_lat, base.ur_lat, base.ul_lat)) base.corner_lon = numpy.column_stack((base.ll_lon, base.lr_lon, base.ur_lon, base.ul_lon)) min_lat = numpy.amin(base.corner_lat) max_lat = numpy.amax(base.corner_lat) min_lon = numpy.amin(base.corner_lon) max_lon = numpy.amax(base.corner_lon) proj_aea = projections.equal_area(min_lat, max_lat, (max_lon+min_lon)/2.) # get the area for each grid cell sys.stdout.write(" [%-60s] %d%%" % ('='*0, 0.)) sys.stdout.flush() base.area = numpy.zeros(base.N) for ii in range(base.N): ctr = (ii*60)/base.N if not (ii % 100): sys.stdout.write("\r [%-60s] %d%%" % ('='*ctr, ctr/60.*100.)) sys.stdout.flush() lat = base.corner_lat[ii,:] lon = base.corner_lon[ii,:] x, y = proj_aea(lon, lat) points = {'type':'polygon', 'coordinates':[zip(x,y)]} base.area[ii] = shape(points).area #m^2 sys.stdout.write("\r [%-60s] %d%%\n" % ('='*60, 100.)) path_scrip, name_scrip = os.path.split(args.input) lc_scrip = os.path.join(path_scrip, 'SCRIPgrid_'+name_scrip) nc_scrip = Dataset(lc_scrip, 'w', format='NETCDF4') nc_scrip.createDimension('grid_size', base.N) nc_scrip.createDimension('grid_corners', 4) nc_scrip.createDimension('grid_rank', 2) nc_scrip.title = scrip_title nc_scrip.source = 'Joseph H. Kennedy, ORNL' scrip = projections.DataGrid() scrip.dims = nc_scrip.createVariable('grid_dims','i4', ('grid_rank')) #NOTE: SCRIP is a Fortran program and as such assumes data is stored in column-major order. # Because (1) netCDF stores data 'C-style' with row-major order and (2) the scrip grid # formate uses flattened arrays, it's easiest to flatten the data 'C-syle', which is the # default for numpy, and flip the dimensions. SCRIP will then read in the array structure # correctly, and the expected ordering within the netCDF file we are creating will be # maintained. #scrip.dims[:] = numpy.array(base.dims)[::-1] #NOTE: Now dumping everything 'F-style' (column-major) order. #scrip.dims[:] = numpy.array(base.dims)[::] #NOTE: I don't freaking know man; just do it normal like. scrip.dims[:] = numpy.array(base.dims)[:] scrip.imask = nc_scrip.createVariable('grid_imask','i4', ('grid_size')) scrip.imask[:] = numpy.ones(base.N) scrip.imask.units = 'unitless' scrip.center_lat = nc_scrip.createVariable('grid_center_lat','f4', ('grid_size')) scrip.center_lat[:] = base.lat_grid[:,:].flatten(order='C') scrip.center_lat.setncattr('units', 'degrees') scrip.center_lon = nc_scrip.createVariable('grid_center_lon','f4', ('grid_size')) scrip.center_lon[:] = base.lon_grid[:,:].flatten(order='C') scrip.center_lon.setncattr('units', 'degrees') scrip.corner_lat = nc_scrip.createVariable('grid_corner_lat','f4', ('grid_size','grid_corners',)) scrip.corner_lat[:,:] = base.corner_lat[:,:] scrip.corner_lat.units = 'degrees' scrip.corner_lon = nc_scrip.createVariable('grid_corner_lon','f4', ('grid_size','grid_corners',)) scrip.corner_lon[:,:] = base.corner_lon[:,:] scrip.corner_lon.units = 'degrees' scrip.area = nc_scrip.createVariable('grid_area','f4', ('grid_size',)) scrip.area[:] = (base.area[:]/SURFACE_AREA_EARTH)*SQR_DEG_ON_SPHERE scrip.area.units = 'square degrees' nc_base.close() nc_scrip.close() os.chmod(lc_scrip, 0o644) # uses an octal number!
action="store_true") volume.add_argument("-q", "--quiet", help="Run silently", action="store_true") args = parser.parse_args() # get the projections proj_epsg3413, proj_eigen_gl04c = projections.greenland() surface_area_earth = 510065621724000.0 # unit: m^2 #source: http://home.vikenfiber.no/humrum/WGS84_Eng.html sqr_deg_on_sphere = 41252.96 # unit: deg^2 sqr_rad_on_sphere = 4. * math.pi # unit rad^2 # load the dataset nc_base = Dataset(args.input, 'r') base = projections.DataGrid() base.y = nc_base.variables['y1'] base.x = nc_base.variables['x1'] base.dy = base.y[1] - base.y[0] base.dx = base.x[1] - base.x[0] base.ny = base.y[:].shape[0] base.nx = base.x[:].shape[0] base.N = base.ny * base.nx base.make_grid() #FIXME: Pick projection based on input file! lon_grid, lat_grid = proj_eigen_gl04c(base.x_grid.ravel(), base.y_grid.ravel(), inverse=True) lon_grid.shape = base.x_grid.shape lat_grid.shape = base.x_grid.shape
def bheatflx_artm_epsg3413(args, nc_seaRise, nc_base, base, proj_epsg3413, proj_eigen_gl04c): seaRise = projections.DataGrid() seaRise.y = nc_seaRise.variables['y'] seaRise.x = nc_seaRise.variables['x'] seaRise.ny = seaRise.y[:].shape[0] seaRise.nx = seaRise.x[:].shape[0] seaRise.make_grid() base_vars = {'bheatflx': 'bheatflx', 'artm': 'presartm'} for base_var, sea_var in base_vars.iteritems(): speak.verbose( args, ' Interpolating ' + sea_var + ' to ' + base_var + ' in base grid.') sys.stdout.write(" [%-60s] %d%%" % ('=' * 0, 0.)) sys.stdout.flush() sea_data = nc_seaRise.variables[sea_var][0, :, :] base2bamber = projections.transform(base, proj_epsg3413, proj_eigen_gl04c) seaRise_interp = scipy.interpolate.RectBivariateSpline( seaRise.y[:], seaRise.x[:], sea_data, kx=1, ky=1, s=0) # regular 2d linear interp. but faster base_bamber = np.zeros(base.dims) for ii in range(0, base.nx): ctr = (ii * 60) / base.nx sys.stdout.write("\r [%-60s] %d%%" % ('=' * ctr, ctr / 60. * 100.)) sys.stdout.flush() base_bamber[:, ii] = seaRise_interp.ev(base2bamber.y_grid[:, ii], base2bamber.x_grid[:, ii]) sys.stdout.write("\r [%-60s] %d%%\n" % ('=' * 60, 100.)) sys.stdout.flush() #NOTE: RectBivariateSpline extrapolates data outside the convex hull # (constant value), so, we need to create a mask for values outisde # the IceBridge convex hull... base_y_mask = np.ma.masked_outside(base2bamber.y_grid, seaRise.y[0], seaRise.y[-1]) base_x_mask = np.ma.masked_outside(base2bamber.x_grid, seaRise.x[0], seaRise.x[-1]) base_masked = np.ma.masked_array(base_bamber, mask=np.logical_or( base_y_mask.mask, base_x_mask.mask)) if base_var != 'bheatflx': base_bamber[base_masked.mask] = -9999. base.var = nc_base.createVariable(base_var, 'f4', ( 'y', 'x', )) if base_var == 'bheatflx': base.var[:] = -base_bamber[:] # invert sign! else: base.var[:] = base_bamber[:] copy_atts_add_fill(nc_seaRise.variables[sea_var], base.var, -9999.) base.var.grid_mapping = 'epsg_3413' base.var.coordinates = 'lon lat'
def mcb_epsg3413(args, nc_massCon, nc_bamber, nc_base, base, proj_epsg3413, proj_eigen_gl04c): """The mass conserving bed data on CISM's ESPG:3413 grid. This function pulls in the `thickness` variable from the mass conserving bed dataset, interpolates it to CISM's EPSG:3413 grid, and writes it to the base dataset as `thk`. NetCDF attributes are mostly preserved, but the data is changed from type short to type float. """ massCon = projections.DataGrid() massCon.y = nc_massCon.variables['y'] massCon.x = nc_massCon.variables['x'] massCon.ny = massCon.y[:].shape[0] massCon.nx = massCon.x[:].shape[0] massCon.make_grid_flip_y() massCon.thickness = nc_massCon.variables['thickness'] massCon.thk = np.ndarray(massCon.dims) massCon.thk[:, :] = massCon.thickness[::-1, :] # y fliped bamber = projections.DataGrid() bamber.y = nc_bamber.variables['projection_y_coordinate'] bamber.x = nc_bamber.variables['projection_x_coordinate'] bamber.ny = bamber.y[:].shape[0] bamber.nx = bamber.x[:].shape[0] bamber.make_grid() speak.verbose(args, " Interpolating thickness and writing to base.") sys.stdout.write(" [%-60s] %d%%" % ('=' * 0, 0.)) sys.stdout.flush() massCon_to_base = scipy.interpolate.RectBivariateSpline( massCon.y[::-1], massCon.x[:], massCon.thk, kx=1, ky=1, s=0) # regular 2d linear interp. but faster base.thk = nc_base.createVariable('thk', 'f4', ( 'y', 'x', )) base.thk[:] = np.zeros(base.dims) for ii in range(0, base.nx): ctr = (ii * 60) / base.nx sys.stdout.write("\r [%-60s] %d%%" % ('=' * ctr, ctr / 60. * 100.)) sys.stdout.flush() base.thk[:, ii] = massCon_to_base.ev(base.y_grid[:, ii], base.x_grid[:, ii]) sys.stdout.write("\r [%-60s] %d%%\n" % ('=' * 60, 100.)) sys.stdout.flush() copy_atts_bad_fill(massCon.thickness, base.thk, -9999.) base.thk.grid_mapping = 'epsg_3413' base.thk.coordinates = 'lon lat' base.thk.reference = 'M. Morlighem, E. Rignot, J. Mouginot, H. Seroussi and E. Larour, Deeply incised submarine glacial valleys beneath the Greenland Ice Sheet, Nat. Geosci., 7, 418-422, 2014, doi:10.1038/ngeo2167, http://www.nature.com/ngeo/journal/vaop/ncurrent/full/ngeo2167.html' speak.verbose(args, " Interpolating, with priority, topg and topgerr.") speak.verbose(args, " Primary Data [IceBridge]: bed and errbed.") speak.verbose( args, " Secondary Data [BamberDEM]: BedrockElevation and BedrockError." ) #base_vars = {'topg':['bed','BedrockElevation']} #NOTE: topgerr accounts for ~10 min. of the runtime. base_vars = { 'topg': ['bed', 'BedrockElevation'], 'topgerr': ['errbed', 'BedrockError'] } for var, var_list in base_vars.iteritems(): speak.verbose(args, '\n Begin ' + var + ':') pri_data = np.ma.masked_equal( nc_massCon.variables[var_list[0]][::-1, :], -9999) sec_data = np.ma.masked_values(nc_bamber.variables[var_list[1]][:, :], -9999.) pri_range = [pri_data.min(), pri_data.max()] rng = [sec_data.min(), sec_data.max()] if pri_range[0] < rng[0]: rng[0] = pri_range[0] if pri_range[1] > rng[1]: rng[1] = pri_range[1] # fill in missing data values in the IceBridge data with the Bamber DEM speak.verbose(args, " Combining IceBridge and Bamber DEMs.") sys.stdout.write(" [%-60s] %d%%" % ('=' * 0, 0.)) sys.stdout.flush() massCon2bamber = projections.transform(massCon, proj_epsg3413, proj_eigen_gl04c) sec_interp = scipy.interpolate.RectBivariateSpline( bamber.y[::], bamber.x[:], sec_data, kx=1, ky=1, s=0) # regular 2d linear interp. but faster massCon_bamber = np.zeros(massCon.dims) for ii in range(0, massCon.nx): ctr = (ii * 60) / massCon.nx sys.stdout.write("\r [%-60s] %d%%" % ('=' * ctr, ctr / 60. * 100.)) sys.stdout.flush() massCon_bamber[:, ii] = sec_interp.ev(massCon2bamber.y_grid[:, ii], massCon2bamber.x_grid[:, ii]) sys.stdout.write("\r [%-60s] %d%%\n" % ('=' * 60, 100.)) sys.stdout.flush() pri_data.unshare_mask() pri_data[pri_data.mask] = massCon_bamber[pri_data.mask] # interpolate the Bamber DEM data to the base grid speak.verbose( args, " Interpolating extended Bamber DEM to base grid.") sys.stdout.write(" [%-60s] %d%%" % ('=' * 0, 0.)) sys.stdout.flush() base2bamber = projections.transform(base, proj_epsg3413, proj_eigen_gl04c) base_bamber = np.zeros(base.dims) for ii in range(0, base.nx): ctr = (ii * 60) / base.nx sys.stdout.write("\r [%-60s] %d%%" % ('=' * ctr, ctr / 60. * 100.)) sys.stdout.flush() base_bamber[:, ii] = sec_interp.ev(base2bamber.y_grid[:, ii], base2bamber.x_grid[:, ii]) sys.stdout.write("\r [%-60s] %d%%\n" % ('=' * 60, 100.)) sys.stdout.flush() # interpolate the filled IceBridge data to the base grid speak.verbose(args, " Interpolating combined dataset to base grid.") sys.stdout.write(" [%-60s] %d%%" % ('=' * 0, 0.)) sys.stdout.flush() pri_interp = scipy.interpolate.RectBivariateSpline( massCon.y[::-1], massCon.x[:], pri_data, kx=1, ky=1, s=0) # regular 2d linear interp. but faster base_mcb = np.zeros(base.dims) for ii in range(0, base.nx): ctr = (ii * 60) / base.nx sys.stdout.write("\r [%-60s] %d%%" % ('=' * ctr, ctr / 60. * 100.)) sys.stdout.flush() base_mcb[:, ii] = pri_interp.ev(base.y_grid[:, ii], base.x_grid[:, ii]) sys.stdout.write("\r [%-60s] %d%%\n" % ('=' * 60, 100.)) sys.stdout.flush() #NOTE: RectBivariateSpline extrapolates data outside the convex hull # (constant value), so, we need to create a mask for values outisde # the IceBridge convex hull... base_y_mask = np.ma.masked_outside(base.y_grid, massCon.y[0], massCon.y[-1]) base_x_mask = np.ma.masked_outside(base.x_grid, massCon.x[0], massCon.x[-1]) base_mcb_masked = np.ma.masked_array(base_mcb, mask=np.logical_or( base_y_mask.mask, base_x_mask.mask)) base_bamber[~base_mcb_masked.mask] = base_mcb_masked[~base_mcb_masked. mask] bamx = [ bamber.x[0], bamber.x[-1], bamber.x[-1], bamber.x[0], bamber.x[0] ] bamy = [ bamber.y[0], bamber.y[0], bamber.y[-1], bamber.y[-1], bamber.y[0] ] bam_shape = shape({ 'type': 'polygon', 'coordinates': [zip(bamx, bamy)] }) base_pts_in_bamber = zip(base2bamber.x_grid.flatten(), base2bamber.y_grid.flatten()) msk = np.ones(base2bamber.x_grid.size, dtype=bool) for ii in range(msk.size): msk[ii] = Point(base_pts_in_bamber[ii]).within(bam_shape) msk.shape = base2bamber.x_grid.shape #from pprint import pprint as pp #print(msk.size) #pp(msk) base_bamber[~msk] = -9999. #NOTE: Make sure all values fall within a reasonable range as # RectBivariateSpine interps using the missing values base_bamber[base_bamber < rng[0]] = -9999. base_bamber[base_bamber > rng[1]] = -9999. base.var = nc_base.createVariable(var, 'f4', ( 'y', 'x', )) base.var[:] = base_bamber[:] copy_atts_bad_fill(nc_massCon.variables[var_list[0]], base.var, -9999.) base.var.grid_mapping = 'epsg_3413' base.var.coordinates = 'lon lat' base.var.reference = 'M. Morlighem, E. Rignot, J. Mouginot, H. Seroussi and E. Larour, Deeply incised submarine glacial valleys beneath the Greenland Ice Sheet, Nat. Geosci., 7, 418-422, 2014, doi:10.1038/ngeo2167, http://www.nature.com/ngeo/journal/vaop/ncurrent/full/ngeo2167.html'
def mcb_bamber(args, nc_massCon, nc_bamber, nc_base, base, trans, proj_eigen_gl04c, proj_epsg3413): """The mass conserving bed data in the bamber projection. This function pulls in the `thickness` variable from the mass conserving bed dataset, interpolates it to the Bamber DEM, and writes it to the base dataset as `thk`. NetCDF attributes are mostly preserved, but the data is changed from type short to type float. This function then pulls in the `bed` and `errbed` variables from the mass conserving bed dataset, and the `bedrockElevation` and `bedrockError` variables from the Bamber dataset. Prioritizing the mass conserving bed data, the bedrock elevation and error is interpolated to the Bamber DEM and written as `topg` and `topgerr` respectively. Data attributes are taken from the mass conserving bed data, and the data is written as a float. Parameters ---------- args : Namespace() object holding parsed command line arguments. nc_massCon : An opened netCDF Dataset containing the Sea Rise data. nc_bamber : An opened netCDF Dataset containing the Sea Rise data. nc_base : The created netCDF Dataset that will contain the base data. base : A DataGrid() class instance that holds the base data grid information. trans : A DataGrid() class instance that holds the base data grid transformed to EPSG:3413. proj_eigen_gl04c : A proj class instance that holds the Bamber DEM projection. proj_epsg3413 : A proj class instance that holds the EPSG:3413 projection. """ massCon = projections.DataGrid() massCon.y = nc_massCon.variables['y'] massCon.x = nc_massCon.variables['x'] massCon.ny = massCon.y[:].shape[0] massCon.nx = massCon.x[:].shape[0] massCon.make_grid_flip_y() massCon.yx = np.ndarray((len(massCon.y_grid.ravel()), 2)) massCon.yx[:, 0] = massCon.y_grid.ravel() massCon.yx[:, 1] = massCon.x_grid.ravel() massCon.tree = scipy.spatial.cKDTree(massCon.yx) trans.yx = np.ndarray((len(trans.y_grid.ravel()), 2)) trans.yx[:, 0] = trans.y_grid.ravel() trans.yx[:, 1] = trans.x_grid.ravel() trans.qd, trans.qi = massCon.tree.query( trans.yx, k=1) # nearest neighbor in massCon for transformed base grid massCon.thickness = nc_massCon.variables['thickness'] massCon.thk = np.ndarray(massCon.dims) massCon.thk[:, :] = massCon.thickness[:: -1, :] # y fliped when compaired to Bamber speak.verbose(args, " Interpolating thickness.") massCon_to_base = scipy.interpolate.RectBivariateSpline( massCon.y[::-1], massCon.x[:], massCon.thk, kx=1, ky=1, s=0) # regular 2d linear interp. but faster trans.thk = np.zeros(trans.dims) for ii in range(0, base.nx): trans.thk[:, ii] = massCon_to_base.ev(trans.y_grid[:, ii], trans.x_grid[:, ii]) speak.verbose(args, " Writing thk to base.") base.thk = nc_base.createVariable('thk', 'f4', ( 'y', 'x', )) base.thk[:, :] = trans.thk[:, :] copy_atts_bad_fill(massCon.thickness, base.thk, -9999.) speak.verbose(args, " Interpolating, with priority, topg and topgerr.") speak.verbose(args, " Primary Data [IceBridge]: bed and errbed.") speak.verbose( args, " Secondary Data [BamberDEM]: BedrockElevation and BedrockError." ) pri_data = np.ma.masked_equal(nc_massCon.variables['bed'][::-1, :], -9999) sec_data = np.ma.masked_values( nc_bamber.variables['BedrockElevation'][:, :], -9999.) new_data = np.ma.array(np.zeros(base.dims), mask=np.zeros(base.dims)) pri_err = np.ma.masked_equal(nc_massCon.variables['errbed'][::-1, :], -9999) sec_err = np.ma.masked_values(nc_bamber.variables['BedrockError'][:, :], -9999.) new_err = np.ma.array(np.zeros(base.dims), mask=np.zeros(base.dims)) for ii in range(0, base.ny): for jj in range(0, base.nx): # make sure inside priority grid (massCon) if (trans.y_grid[ii, jj] < massCon.y_grid[0, 0] or trans.y_grid[ii, jj] > massCon.y_grid[-1, 0]): # outside y range if sec_data.mask[ii, jj]: new_data.mask[ii, jj] = True new_err.mask[ii, jj] = True continue else: tx, ty, td = pyproj.transform(proj_eigen_gl04c, proj_epsg3413, base.x_grid[ii, jj], base.y_grid[ii, jj], sec_data[ii, jj]) new_data[ii, jj] = td new_err[ii, jj] = sec_err[ii, jj] continue if (trans.x_grid[ii, jj] < massCon.x_grid[0, 0] or trans.x_grid[ii, jj] > massCon.x_grid[0, -1]): # outside x range if sec_data.mask[ii, jj]: new_data.mask[ii, jj] = True new_err.mask[ii, jj] = True continue else: tx, ty, td = pyproj.transform(proj_eigen_gl04c, proj_epsg3413, base.x_grid[ii, jj], base.y_grid[ii, jj], sec_data[ii, jj]) new_data[ii, jj] = td new_err[ii, jj] = sec_err[ii, jj] continue indx = np.ravel_multi_index((ii, jj), base.dims) # nearest neighbor indices nn_ii, nn_jj = np.unravel_index(trans.qi[indx], massCon.dims) # to find nearest neighbors quadrent i_s = -1 j_s = -1 # find quadrent point lies in if trans.y_grid[ii, jj] >= massCon.y_grid[nn_ii, nn_jj]: i_s = +1 if trans.x_grid[ii, jj] >= massCon.x_grid[nn_ii, nn_jj]: j_s = +1 # check for missing priority data! # NOTE: points are ordered as such: # # 0: (ii , jj ) # 1: (ii , jj+j_s) # 2: (ii+i_s, jj+j_s) # 3: (ii+i_s, jj ) # # Which, for an upper-right quadrent looks like: # # 3 ---- 2 # | | # | | # 0 ---- 1 # # Numbering in other quadrents is the reflection through the axis or axes # with negitive skip values (i_s or j_s). missing_points, interp_dict = interp.check_missing( pri_data, (nn_ii, nn_jj), i_s, j_s) missing_err_pts, err_dict = interp.check_missing( pri_err, (nn_ii, nn_jj), i_s, j_s) # get secondary data! if not missing_points: pass elif not sec_data.mask[ii, jj]: tx, ty, td = pyproj.transform(proj_eigen_gl04c, proj_epsg3413, base.x_grid[ii, jj], base.y_grid[ii, jj], sec_data[ii, jj]) if len(missing_points) <= 3: for point in missing_points: # use secondary data at (ii,jj) for missing points, but keep same interp weight! interp_dict[point] = td err_dict[point] = sec_err[ii, jj] else: new_data[ii, jj] = td new_err[ii, jj] = sec_err[ii, jj] continue else: new_data.mask[ii, jj] = True new_err.mask[ii, jj] = True continue # interpolate! alpha = (trans.y_grid[ii, jj] - massCon.y_grid[nn_ii, nn_jj]) / (massCon.dy * i_s) beta = (trans.x_grid[ii, jj] - massCon.x_grid[nn_ii, nn_jj]) / (massCon.dx * j_s) w = interp.linear_weights(alpha, beta) new_data[ii,jj] = interp_dict[ (nn_ii, nn_jj ) ]*w[0] \ +interp_dict[ (nn_ii, nn_jj+j_s) ]*w[1] \ +interp_dict[ (nn_ii+i_s,nn_jj+j_s) ]*w[2] \ +interp_dict[ (nn_ii+i_s,nn_jj ) ]*w[3] new_err[ii,jj] = err_dict[ (nn_ii, nn_jj ) ]*w[0] \ +err_dict[ (nn_ii, nn_jj+j_s) ]*w[1] \ +err_dict[ (nn_ii+i_s,nn_jj+j_s) ]*w[2] \ +err_dict[ (nn_ii+i_s,nn_jj ) ]*w[3] missing_points = None interp_dict = None err_dict = None # now transform new data back to bamber grid. temp_x_grid, temp_y_grid, temp_data = pyproj.transform( proj_epsg3413, proj_eigen_gl04c, trans.x_grid.flatten(), trans.y_grid.flatten(), new_data.flatten()) new_data[:, :] = temp_data.reshape(base.dims)[:, :] speak.verbose(args, " Writing topg topgerr to base.") base.topg = nc_base.createVariable('topg', 'f4', ( 'y', 'x', )) base.topg[:, :] = new_data.filled(-9999.)[:, :] copy_atts_bad_fill(nc_massCon.variables['bed'], base.topg, -9999.) base.topgerr = nc_base.createVariable('topgerr', 'f4', ( 'y', 'x', )) base.topgerr[:, :] = new_err.filled(-9999.)[:, :] copy_atts_bad_fill(nc_massCon.variables['errbed'], base.topgerr, -9999.)
def main(args): if args.write: nc_base = get_nc_file(args.input,'r+') else: nc_base = get_nc_file(args.input,'r') base = projections.DataGrid() base.y = nc_base.variables['y'] base.x = nc_base.variables['x'] base.ny = base.y[:].shape[0] base.nx = base.x[:].shape[0] base.make_grid() base.topg = nc_base.variables['topg'] base.thk = nc_base.variables['thk'] topg = base.topg[::-1,:].filled() ice = base.thk[::-1,:] islands = np.greater(topg, args.altitude) segments, ids = ndimage.label(islands) #sgmt = ndimage.measurements.find_objects(segments) speak.verbose(args, ' Number of distinct shallow regions found: {}'.format(ids)) mask = np.array(segments * -1.) # Set ocean mask[np.equal(mask,0)] = 1 labeled = np.copy(mask) # For viewing #NOTE: nx = 2480, ny = 2975; -1 for index gl_x = [1200, 1990, 1990, 1625, 1320, 720, 440, 440, 359, 540, 586, 618, 710, 774, 819, 878, 969, 1200] gl_y = [ 60, 344, 1680, 2225, 2940, 2940, 1995, 1168, 767, 523, 507, 493, 416, 391, 346, 305, 273, 60] shape_gl = shape({'type':'polygon', 'coordinates':[zip(gl_y, gl_x)]}) ei_x = [960, 773, 140, 140, 158, 122, 144, 115, 84, 65, 45, 34, 44, 60, 76, 183, 207, 359, 540, 586, 618, 710, 774, 819, 878, 969, 960] ei_y = [ 84, 24, 24, 200, 290, 377, 431, 503, 505, 495, 501, 536, 558, 594, 652, 737, 855, 767, 523, 507, 493, 416, 391, 346, 305, 273, 84] shape_ei = shape({'type':'polygon', 'coordinates':[zip(ei_y, ei_x)]}) for ii in range(mask.shape[0]): speak.progress(args, ii, mask.shape[0], width=60, char='=', indent=4) for jj in range(mask.shape[1]): if topg[ii,jj] == -9999.: mask[ii,jj] = 0 elif Point((ii,jj)).within(shape_gl): if ice[ii,jj] > 0: if ice[ii,jj] >= -1*topg[ii,jj]/R_RHO: mask[ii,jj] = 3 else: mask[ii,jj] = 4 elif topg[ii,jj] > 0: mask[ii,jj] = 2 else: mask[ii,jj] = 1 elif mask[ii,jj] == 1: continue elif Point((ii,jj)).within(shape_ei): if topg[ii,jj] > 0: mask[ii,jj] = -2 else: mask[ii,jj] = -1 else: mask[ii,jj] = -3 speak.progress(args, mask.shape[0], mask.shape[0], width=60, char='=', indent=4) if args.write: base.mask = nc_base.createVariable('mask', 'i4', ('y','x',) ) base.mask[:,:] = mask[::-1,:] base.mask.long_name = 'location type mask' base.mask.grid_mapping = 'epsg_3413' base.mask.coordinates = 'lon lat' base.source = 'Joseph H. Kennedy, ORNL' base.comment = 'Mask values: -3, shallow ocean or land outside paleo domain; '+ \ '-2, bare paleo land; '+ \ '-1, shallow paleo ocean; '+ \ '0, missing topg data; '+ \ '1, ocean; '+ \ '2, bare land; '+ \ '3, grounded ice; '+ \ '4, floating ice.' fig, ((ax1, ax2, ax3), (ax4, ax5, ax6)) = plt.subplots(2,3, figsize=(12,10), dpi=150) plt.rc('text', usetex=True) plt.rc('font', family='serif') ax1.imshow(topg, cmap='spectral', interpolation='nearest') ax1.set_title('Topography') ax2.imshow(islands, cmap='spectral', interpolation='nearest') ax2.set_title('Shallow regions') ax3.imshow(labeled, cmap='spectral', interpolation='nearest') ax3.set_title('Labeled regions') ax4.imshow(ice, cmap='spectral', interpolation='nearest') ax4.set_title('Ice thickness') ax5.imshow(mask, cmap='spectral', interpolation='nearest') ax5.set_title('Mask') ax6.imshow(mask, cmap='spectral', interpolation='nearest') ax6.autoscale(False) ax6.plot(gl_x, gl_y, '-ro') ax6.plot(ei_x, ei_y, '-bx') ax6.set_title('Mask with shapes') plt.tight_layout() plt.savefig('segments.png', bbox_inches='tight') if args.show: plt.show() nc_base.close()
args = parser.parse_args() # get the projections proj_epsg3413, proj_eigen_gl04c = projections.greenland() #FIXME: Pick projection based on input file! if args.projection == 'epsg': proj = proj_epsg3413 scrip_title = "CISM EPSG:3413 Grid" elif args.projection == 'bamber': proj = proj_eigen_gl04c scrip_title = "CISM Bamber Grid" # load the dataset nc_base = Dataset(args.input, 'r') base = projections.DataGrid() base.y = nc_base.variables['y1'] base.x = nc_base.variables['x1'] base.dy = base.y[1] - base.y[0] base.dx = base.x[1] - base.x[0] base.ny = base.y[:].shape[0] base.nx = base.x[:].shape[0] base.make_grid() base.y0 = (base.y[:-1] + base.y[1:]) / 2. base.x0 = (base.x[:-1] + base.x[1:]) / 2. base.y0_grid, base.x0_grid = scipy.meshgrid(base.y0[:], base.x0[:], indexing='ij') base.dim0 = (base.ny - 1, base.nx - 1)
# load in datasets #================== speak.notquiet(args, "Loading the datasets.") nc_template = get_nc_file(lc_template, 'r') nc_base = get_nc_file(lc_base, 'r') speak.verbose(args, " Found Bamber DEM") speak.verbose(args, "\n All data files found!") #===== Bamber DEM ====== # this is a 1km dataset #======================= speak.notquiet(args, "\nCreating the 1 km Bamber template grid."), template = projections.DataGrid() template.y = nc_template.variables['projection_y_coordinate'] template.x = nc_template.variables['projection_x_coordinate'] template.ny = template.y[:].shape[0] template.nx = template.x[:].shape[0] template.make_grid() speak.notquiet(args, " Done!") speak.notquiet(args, "\nCreating the 1 km Bamber grid."), base = projections.DataGrid() base.y = nc_base.variables['y1'] base.x = nc_base.variables['x1'] base.ny = base.y[:].shape[0] base.nx = base.x[:].shape[0] base.make_grid()