def synth_apparent_mb(gdir, tstar=None, bias=None): """Compute local mustar and apparent mb from tstar. Parameters ---------- gdir : oggm.GlacierDirectory tstar: int the year where the glacier should be equilibrium bias: int the associated reference bias """ # Ok. Looping over divides for div_id in list(gdir.divide_ids): log.info('%s: apparent mb synth') # For each flowline compute the apparent MB fls = gdir.read_pickle('inversion_flowlines', div_id=div_id) # Reset flux for fl in fls: fl.flux = np.zeros(len(fl.surface_h)) n_g = gdir.rgi_id searchf = os.path.join(DATA_DIR, 'itmix', 'glaciers_synth', '*') searchf = os.path.join(searchf, '04_mb_' + n_g + '*.asc') for dem_f in glob.glob(searchf): pass ds_mb = salem.EsriITMIX(dem_f) mb = ds_mb.get_vardata() * 1000. mb = np.where(mb < -9998, np.NaN, mb) f = os.path.join(DATA_DIR, 'itmix', 'glaciers_synth', '01_margin_' + n_g + '_0000_UTM00.shp') ds_mb.set_roi(f) mb = np.where(ds_mb.roi, mb, np.NaN) searchf = os.path.join(DATA_DIR, 'itmix', 'glaciers_synth', '*') searchf = os.path.join(searchf, '02_*_' + n_g + '*.asc') for dem_f in glob.glob(searchf): pass ds_dem = salem.EsriITMIX(dem_f) dem = ds_dem.get_vardata() from scipy import stats pok = np.where(np.isfinite(mb) & (mb > 0)) slope_p, _, _, _, _ = stats.linregress(dem[pok], mb[pok]) pok = np.where(np.isfinite(mb) & (mb < 0)) slope_m, _, _, _, _ = stats.linregress(dem[pok], mb[pok]) def ela_mb_grad(ela_h, h): return np.where(h < ela_h, slope_m * (h - ela_h), slope_p * (h - ela_h)) # Get all my hs hs = [] ws = [] for fl in fls: hs = np.append(hs, fl.surface_h) ws = np.append(ws, fl.widths) # find ela for zero mb def to_optim(x): tot_mb = np.average(ela_mb_grad(x[0], hs), weights=ws) return tot_mb**2 opti = optimization.minimize(to_optim, [1000.], bounds=((0., 10000), ), tol=1e-6) # Check results and save. final_elah = opti['x'][0] # print(final_elah) # pok = np.where(np.isfinite(mb)) # plt.plot(dem[pok], mb[pok], 'o') # plt.plot(hs, ela_mb_grad(final_elah, hs), 'o') # plt.show() # Flowlines in order to be sure # TODO: here it would be possible to test for a minimum mb gradient # and change prcp factor if judged useful for fl in fls: mb_on_h = ela_mb_grad(final_elah, fl.surface_h) fl.set_apparent_mb(mb_on_h) # Check if div_id >= 1: if not np.allclose(fls[-1].flux[-1], 0., atol=0.01): log.warning('%s: flux should be zero, but is: %.2f', gdir.rgi_id, fls[-1].flux[-1]) # Overwrite gdir.write_pickle(fls, 'inversion_flowlines', div_id=div_id)
def write_itmix_ascii(gdir, version): """Write the results""" gname = gdir.name.replace('I:', '') real = gname gname = gname.replace('_A', '') gname = gname.replace('_B', '') log.info('Write ITMIX ' + real) # Get the data grids_file = gdir.get_filepath('gridded_data', div_id=0) with netCDF4.Dataset(grids_file) as nc: thick = nc.variables['thickness'][:] vol = np.nansum(thick * gdir.grid.dx**2) # Transform to output grid try: ifile = find_path(os.path.join(DATA_DIR, 'itmix', 'glaciers_sorted'), '02_surface_' + gname + '*.asc') except AssertionError: gname = gdir.rgi_id searchf = os.path.join(DATA_DIR, 'itmix', 'glaciers_synth') ifile = find_path(searchf, '02_surface_' + gname + '*.asc') itmix = salem.EsriITMIX(ifile) thick = itmix.grid.map_gridded_data(thick, gdir.grid, interp='linear') # Mask out itmix.set_roi(shape=gdir.get_filepath('outlines')) omask = itmix.roi thick[np.nonzero(omask == 0)] = np.nan # Output path bname = os.path.basename(ifile).split('.')[0] pok = bname.find('UTM') zone = bname[pok:] ofile = os.path.join(ITMIX_ODIR, gname) if not os.path.exists(ofile): os.mkdir(ofile) fname = 'Maussion_' + real + '_bedrock_v{}_'.format( version) + zone + '.asc' ofile = os.path.join(ofile, fname) # Write out with rasterio.drivers(): with rasterio.open(ifile) as src: topo = src.read(1).astype(np.float) topo = np.where(topo < -999., np.NaN, topo) # Also for ours thick = np.where(topo < -999., np.NaN, thick) # Be sure volume is conserved thick *= vol / np.nansum(thick * itmix.grid.dx**2) assert np.isclose(np.nansum(thick * itmix.grid.dx**2), vol) # convert topo -= thick with rasterio.open(ofile, 'w', driver=src.driver, width=src.width, height=src.height, transform=src.transform, count=1, dtype=np.float, nodata=np.NaN) as dst: dst.write_band(1, topo) # Check with rasterio.open(ifile) as src: topo = src.read(1).astype(np.float) topo = np.where(topo < -9999., np.NaN, topo) with rasterio.open(ofile) as src: mtopo = src.read(1).astype(np.float) mtopo = np.where(mtopo < -9999., np.NaN, mtopo) if not np.allclose(np.nanmax(topo - mtopo), np.nanmax(thick), atol=5): print(np.nanmax(topo - mtopo), np.nanmax(thick)) f, (ax1, ax2, ax3, ax4) = plt.subplots(1, 4) ax1.imshow(topo - mtopo) ax2.imshow(thick) ax3.imshow(topo - mtopo - thick) ax4.imshow(~np.isclose(topo - mtopo, thick, atol=1, equal_nan=True)) plt.show()
import salem from .itmix import find_path from .itmix_cfg import DATA_DIR, ITMIX_ODIR, PLOTS_DIR pdir = os.path.join(PLOTS_DIR, 'submitted') + '/' if not os.path.exists(pdir): os.mkdir(pdir) for dgn in glob.glob(os.path.join(ITMIX_ODIR, '*')): gname = os.path.basename(dgn) print(gname) ifile = find_path(os.path.join(DATA_DIR, 'itmix', 'glaciers_sorted'), '02_surface_' + gname + '*.asc') ds = salem.EsriITMIX(ifile) itmix_topo = ds.get_vardata() ifiles = find_path(ITMIX_ODIR, '*' + gname + '*.asc', allow_more=True) for ifile in ifiles: ds2 = salem.EsriITMIX(ifile) oggm_topo = ds2.get_vardata() thick = itmix_topo - oggm_topo cm = salem.Map(ds.grid) cm.set_plot_params(nlevels=256) cm.set_cmap(plt.get_cmap('viridis')) cm.set_data(thick) cm.visualize()