def test_add_consensus(self, class_case_dir, monkeypatch): # Init cfg.initialize() cfg.PARAMS['use_intersects'] = False cfg.PATHS['working_dir'] = class_case_dir cfg.PATHS['dem_file'] = get_demo_file('hef_srtm.tif') entity = gpd.read_file(get_demo_file('Hintereisferner_RGI5.shp')) entity['RGIId'] = 'RGI60-11.00897' gdir = workflow.init_glacier_directories(entity)[0] tasks.define_glacier_region(gdir) tasks.glacier_masks(gdir) ft = utils.get_demo_file('RGI60-11.00897_thickness.tif') monkeypatch.setattr(utils, 'file_downloader', lambda x: ft) bedtopo.add_consensus_thickness(gdir) # Check with rasterio cfg.add_to_basenames('consensus', 'consensus.tif') gis.rasterio_to_gdir(gdir, ft, 'consensus', resampling='bilinear') with xr.open_dataset(gdir.get_filepath('gridded_data')) as ds: mine = ds.consensus_ice_thickness with xr.open_rasterio(gdir.get_filepath('consensus')) as ds: ref = ds.isel(band=0) # Check area my_area = np.sum(np.isfinite(mine.data)) * gdir.grid.dx**2 np.testing.assert_allclose(my_area, gdir.rgi_area_m2, rtol=0.07) rio_area = np.sum(ref.data > 0) * gdir.grid.dx**2 np.testing.assert_allclose(rio_area, gdir.rgi_area_m2, rtol=0.15) np.testing.assert_allclose(my_area, rio_area, rtol=0.15) # They are not same: # - interpolation not 1to1 same especially at borders # - we preserve total volume np.testing.assert_allclose(mine.sum(), ref.sum(), rtol=0.01) assert utils.rmsd(ref, mine) < 2 # Check vol cdf = pd.read_hdf(utils.get_demo_file('rgi62_itmix_df.h5')) ref_vol = cdf.loc[gdir.rgi_id].vol_itmix_m3 my_vol = mine.sum() * gdir.grid.dx**2 np.testing.assert_allclose(my_vol, ref_vol) # Now check the rest of the workflow # Check that no error when var not there vn = 'consensus_ice_thickness' centerlines.elevation_band_flowline(gdir, bin_variables=[vn, 'foo']) # Check vol df = pd.read_csv(gdir.get_filepath('elevation_band_flowline'), index_col=0) my_vol = (df[vn] * df['area']).sum() np.testing.assert_allclose(my_vol, ref_vol) centerlines.fixed_dx_elevation_band_flowline(gdir, bin_variables=[vn, 'foo']) fdf = pd.read_csv(gdir.get_filepath('elevation_band_flowline', filesuffix='_fixed_dx'), index_col=0) # Check vol my_vol = (fdf[vn] * fdf['area_m2']).sum() np.testing.assert_allclose(my_vol, ref_vol)
def debris_to_gdir(gdir, debris_dir=pygem_prms.debris_fp, add_to_gridded=True, hd_max=5, hd_min=0, ed_max=10, ed_min=0): """Reproject the debris thickness and enhancement factor files to the given glacier directory Variables are exported as new files in the glacier directory. Reprojecting debris data from one map proj to another is done. We use bilinear interpolation to reproject the velocities to the local glacier map. Parameters ---------- gdir : :py:class:`oggm.GlacierDirectory` where to write the data """ assert os.path.exists( debris_dir), "Error: debris directory does not exist." hd_dir = debris_dir + 'hd_tifs/' + gdir.rgi_region + '/' ed_dir = debris_dir + 'ed_tifs/' + gdir.rgi_region + '/' glac_str_nolead = str(int( gdir.rgi_region)) + '.' + gdir.rgi_id.split('-')[1].split('.')[1] # If debris thickness data exists, then write to glacier directory if os.path.exists(hd_dir + glac_str_nolead + '_hdts_m.tif'): hd_fn = hd_dir + glac_str_nolead + '_hdts_m.tif' elif os.path.exists(hd_dir + glac_str_nolead + '_hdts_m_extrap.tif'): hd_fn = hd_dir + glac_str_nolead + '_hdts_m_extrap.tif' else: hd_fn = None if hd_fn is not None: rasterio_to_gdir(gdir, hd_fn, 'debris_hd', resampling='bilinear') if add_to_gridded and hd_fn is not None: output_fn = gdir.get_filepath('debris_hd') # append the debris data to the gridded dataset with rasterio.open(output_fn) as src: grids_file = gdir.get_filepath('gridded_data') with ncDataset(grids_file, 'a') as nc: # Mask values glacier_mask = nc['glacier_mask'][:] data = src.read(1) * glacier_mask data[data > hd_max] = 0 data[data < hd_min] = 0 # Write data vn = 'debris_hd' if vn in nc.variables: v = nc.variables[vn] else: v = nc.createVariable(vn, 'f8', ( 'y', 'x', ), zlib=True) v.units = 'm' v.long_name = 'Debris thicknness' v[:] = data # If debris enhancement factor data exists, then write to glacier directory if os.path.exists(ed_dir + glac_str_nolead + '_meltfactor.tif'): ed_fn = ed_dir + glac_str_nolead + '_meltfactor.tif' elif os.path.exists(ed_dir + glac_str_nolead + '_meltfactor_extrap.tif'): ed_fn = ed_dir + glac_str_nolead + '_meltfactor_extrap.tif' else: ed_fn = None if ed_fn is not None: rasterio_to_gdir(gdir, ed_fn, 'debris_ed', resampling='bilinear') if add_to_gridded and ed_fn is not None: output_fn = gdir.get_filepath('debris_ed') # append the debris data to the gridded dataset with rasterio.open(output_fn) as src: grids_file = gdir.get_filepath('gridded_data') with ncDataset(grids_file, 'a') as nc: # Mask values glacier_mask = nc['glacier_mask'][:] data = src.read(1) * glacier_mask data[data > ed_max] = 1 data[data < ed_min] = 1 # Write data vn = 'debris_ed' if vn in nc.variables: v = nc.variables[vn] else: v = nc.createVariable(vn, 'f8', ( 'y', 'x', ), zlib=True) v.units = '-' v.long_name = 'Debris enhancement factor' v[:] = data
def test_repro_to_glacier(self, class_case_dir, monkeypatch): # Init cfg.initialize() cfg.PATHS['working_dir'] = class_case_dir cfg.PARAMS['use_intersects'] = False cfg.PATHS['dem_file'] = get_demo_file('dem_Columbia.tif') cfg.PARAMS['border'] = 10 entity = gpd.read_file(get_demo_file('RGI60-01.10689.shp')).iloc[0] gdir = oggm.GlacierDirectory(entity) tasks.define_glacier_region(gdir) tasks.glacier_masks(gdir) # use our files region_files = { 'ALA': { 'vx': get_demo_file('crop_ALA_G0120_0000_vx.tif'), 'vy': get_demo_file('crop_ALA_G0120_0000_vy.tif') } } monkeypatch.setattr(its_live, 'region_files', region_files) monkeypatch.setattr(utils, 'file_downloader', lambda x: x) with warnings.catch_warnings(): warnings.filterwarnings("ignore", category=RuntimeWarning) its_live.velocity_to_gdir(gdir) with xr.open_dataset(gdir.get_filepath('gridded_data')) as ds: mask = ds.glacier_mask.data.astype(bool) vx = ds.obs_icevel_x.where(mask).data vy = ds.obs_icevel_y.where(mask).data vel = np.sqrt(vx**2 + vy**2) assert np.nanmax(vel) > 2900 assert np.nanmin(vel) < 2 # We reproject with rasterio and check no big diff cfg.BASENAMES['its_live_vx'] = ('its_live_vx.tif', '') cfg.BASENAMES['its_live_vy'] = ('its_live_vy.tif', '') gis.rasterio_to_gdir(gdir, region_files['ALA']['vx'], 'its_live_vx', resampling='bilinear') gis.rasterio_to_gdir(gdir, region_files['ALA']['vy'], 'its_live_vy', resampling='bilinear') with xr.open_rasterio(gdir.get_filepath('its_live_vx')) as da: _vx = da.where(mask).data.squeeze() with xr.open_rasterio(gdir.get_filepath('its_live_vy')) as da: _vy = da.where(mask).data.squeeze() _vel = np.sqrt(_vx**2 + _vy**2) np.testing.assert_allclose(utils.rmsd(vel[mask], _vel[mask]), 0, atol=40) np.testing.assert_allclose(utils.md(vel[mask], _vel[mask]), 0, atol=8) if DO_PLOT: import matplotlib.pyplot as plt smap = salem.Map(gdir.grid.center_grid, countries=False) smap.set_shapefile(gdir.read_shapefile('outlines')) with warnings.catch_warnings(): warnings.filterwarnings('ignore', category=RuntimeWarning) smap.set_topography(gdir.get_filepath('dem')) vel = np.sqrt(vx**2 + vy**2) smap.set_data(vel) smap.set_plot_params(cmap='Blues', vmin=None, vmax=None) xx, yy = gdir.grid.center_grid.xy_coordinates xx, yy = smap.grid.transform(xx, yy, crs=gdir.grid.proj) yy = yy[2::5, 2::5] xx = xx[2::5, 2::5] vx = vx[2::5, 2::5] vy = vy[2::5, 2::5] f, ax = plt.subplots() smap.visualize(ax=ax, title='ITS_LIVE velocity', cbar_title='m yr-1') ax.quiver(xx, yy, vx, vy) plt.show()
def consensus_gridded(gdir, h_consensus_fp=pygem_prms.h_consensus_fp, add_mass=True, add_to_gridded=True): """Bin consensus ice thickness and add total glacier mass to the given glacier directory Updates the 'inversion_flowlines' save file and creates new consensus_mass.pkl Parameters ---------- gdir : :py:class:`oggm.GlacierDirectory` where to write the data """ # If binned mb data exists, then write to glacier directory h_fn = h_consensus_fp + 'RGI60-' + gdir.rgi_region + '/' + gdir.rgi_id + '_thickness.tif' assert os.path.exists( h_fn ), 'Error: h_consensus_fullfn for ' + gdir.rgi_id + ' does not exist.' # open consensus ice thickness estimate h_dr = rasterio.open(h_fn, 'r', driver='GTiff') h = h_dr.read(1).astype(rasterio.float32) # Glacier mass [kg] glacier_mass_raw = (h * h_dr.res[0] * h_dr.res[1]).sum() * pygem_prms.density_ice # print(glacier_mass_raw) if add_mass: # Pickle data consensus_fn = gdir.get_filepath('consensus_mass') with open(consensus_fn, 'wb') as f: pickle.dump(glacier_mass_raw, f) if add_to_gridded: rasterio_to_gdir(gdir, h_fn, 'consensus_h', resampling='bilinear') output_fn = gdir.get_filepath('consensus_h') # append the debris data to the gridded dataset with rasterio.open(output_fn) as src: grids_file = gdir.get_filepath('gridded_data') with ncDataset(grids_file, 'a') as nc: # Mask values glacier_mask = nc['glacier_mask'][:] data = src.read(1) * glacier_mask # Pixel area pixel_m2 = abs(gdir.grid.dx * gdir.grid.dy) # Glacier mass [kg] reprojoected (may lose or gain mass depending on resampling algorithm) glacier_mass_reprojected = ( data * pixel_m2).sum() * pygem_prms.density_ice # Scale data to ensure conservation of mass during reprojection data_scaled = data * glacier_mass_raw / glacier_mass_reprojected # glacier_mass = (data_scaled * pixel_m2).sum() * pygem_prms.density_ice # print(glacier_mass) # Write data vn = 'consensus_h' if vn in nc.variables: v = nc.variables[vn] else: v = nc.createVariable(vn, 'f8', ( 'y', 'x', ), zlib=True) v.units = 'm' v.long_name = 'Consensus ice thicknness' v[:] = data_scaled