def to_minimize(mu_star): mbmod = ConstantMassBalance(gdir, mu_star=mu_star, bias=0, check_calib_params=False, y0=df['t_star']) smb = mbmod.get_annual_mb(heights=topo) return np.sum(smb)**2
def test_constant_mb_model(self, hef_gdir): y0 = 2000 halfsize = 15 combine_mb_model = ConstantMassBalanceTorch(hef_gdir, y0=y0, halfsize=halfsize) oggm_mb_model = ConstantMassBalance(hef_gdir, y0=y0, halfsize=halfsize) test_height_shift = 100. combine_mb_model_shift = ConstantMassBalanceTorch( hef_gdir, y0=y0, halfsize=halfsize, height_shift=test_height_shift) fls = hef_gdir.read_pickle('model_flowlines') h = [] for fl in fls: # We use bed because of overdeepenings h = np.append(h, fl.bed_h) h = np.append(h, fl.surface_h) zminmax = np.round([np.min(h), np.max(h)]) heights = np.linspace(zminmax[0], zminmax[1], num=20) heights_torch = torch.tensor(heights, dtype=torch.double) heights_torch_shift = heights_torch + torch.tensor(test_height_shift, dtype=torch.double) # test annual oggm_annual_mbs = oggm_mb_model.get_annual_mb(heights) combine_annual_mbs = combine_mb_model.get_annual_mb(heights_torch) combine_annual_mbs_shift = \ combine_mb_model_shift.get_annual_mb(heights_torch_shift) assert np.allclose(oggm_annual_mbs, combine_annual_mbs) assert type(combine_annual_mbs) == torch.Tensor assert combine_annual_mbs.shape == heights_torch.shape assert np.allclose(combine_annual_mbs, combine_annual_mbs_shift) assert type(combine_annual_mbs_shift) == torch.Tensor assert combine_annual_mbs_shift.shape == heights_torch_shift.shape # test monthly for month in np.arange(12) + 1: yr = date_to_floatyear(0, month) oggm_monthly_mbs = oggm_mb_model.get_monthly_mb(heights, year=yr) combine_monthly_mbs = combine_mb_model.get_monthly_mb( heights_torch, year=yr) combine_monthly_mbs_shift = \ combine_mb_model_shift.get_monthly_mb(heights_torch_shift, year=yr) assert np.allclose(oggm_monthly_mbs, combine_monthly_mbs) assert type(combine_monthly_mbs) == torch.Tensor assert combine_monthly_mbs.shape == heights_torch.shape assert np.allclose(combine_monthly_mbs, combine_monthly_mbs_shift) assert type(combine_monthly_mbs_shift) == torch.Tensor assert combine_monthly_mbs_shift.shape == heights_torch_shift.shape
prcp_yr = np.mean(prcp_yr[selind]) # Average oberved mass-balance ref_mb = mbdf.ANNUAL_BALANCE.mean() mb_per_mu = prcp_yr - mu_yr_clim * temp_yr # Diff to reference diff = mb_per_mu - ref_mb pdf = pd.DataFrame() pdf[r'$\mu (t)$'] = mu_yr_clim pdf['bias'] = diff res = t_star_from_refmb(gdir, mbdf=mbdf.ANNUAL_BALANCE) # For the mass flux cl = gdir.read_pickle('inversion_input')[-1] mbmod = ConstantMassBalance(gdir) mbx = (mbmod.get_annual_mb(cl['hgt']) * cfg.SEC_IN_YEAR * cfg.PARAMS['ice_density']) fdf = pd.DataFrame(index=np.arange(len(mbx)) * cl['dx']) fdf['Flux'] = cl['flux'] fdf['Mass balance'] = mbx # For the distributed thickness tasks.mass_conservation_inversion(gdir, glen_a=2.4e-24 * 3, fs=0) tasks.distribute_thickness_per_altitude(gdir) # plot functions def example_plot_temp_ts(): d = xr.open_dataset(gdir.get_filepath('climate_historical')) temp = d.temp.resample(time='12MS').mean('time').to_series()
def test_mb(self): # This is a function to produce the MB function needed by Anna # Download the RGI file for the run # Make a new dataframe of those rgidf = gpd.read_file(get_demo_file('SouthGlacier.shp')) # Go - initialize working directories gdirs = workflow.init_glacier_regions(rgidf) # Preprocessing tasks task_list = [ tasks.glacier_masks, tasks.compute_centerlines, tasks.initialize_flowlines, tasks.catchment_area, tasks.catchment_intersections, tasks.catchment_width_geom, tasks.catchment_width_correction, ] for task in task_list: execute_entity_task(task, gdirs) # Climate tasks -- only data IO and tstar interpolation! execute_entity_task(tasks.process_cru_data, gdirs) tasks.distribute_t_stars(gdirs) execute_entity_task(tasks.apparent_mb, gdirs) mbref = salem.GeoTiff(get_demo_file('mb_SouthGlacier.tif')) demref = salem.GeoTiff(get_demo_file('dem_SouthGlacier.tif')) mbref = mbref.get_vardata() mbref[mbref == -9999] = np.NaN demref = demref.get_vardata()[np.isfinite(mbref)] mbref = mbref[np.isfinite(mbref)] * 1000 # compute the bias to make it 0 SMB on the 2D DEM mbmod = ConstantMassBalance(gdirs[0], bias=0) mymb = mbmod.get_annual_mb(demref) * cfg.SEC_IN_YEAR * cfg.RHO mbmod = ConstantMassBalance(gdirs[0], bias=np.average(mymb)) mymb = mbmod.get_annual_mb(demref) * cfg.SEC_IN_YEAR * cfg.RHO np.testing.assert_allclose(np.average(mymb), 0., atol=1e-3) # Same for ref mbref = mbref - np.average(mbref) np.testing.assert_allclose(np.average(mbref), 0., atol=1e-3) # Fit poly p = np.polyfit(demref, mbref, deg=2) poly = np.poly1d(p) myfit = poly(demref) np.testing.assert_allclose(np.average(myfit), 0., atol=1e-3) if do_plot: import matplotlib.pyplot as plt plt.scatter(mbref, demref, s=5, label='Obs (2007-2012), shifted to ' 'Avg(SMB) = 0') plt.scatter(mymb, demref, s=5, label='OGGM MB at t*') plt.scatter(myfit, demref, s=5, label='Polyfit', c='C3') plt.xlabel('MB (mm w.e yr-1)') plt.ylabel('Altidude (m)') plt.legend() plt.show()
execute_entity_task(tasks.apparent_mb, gdirs) # Recompute after the first round - this is being picky but this is # Because geometries may change after apparent_mb's filtering tasks.compute_ref_t_stars(gdirs) tasks.distribute_t_stars(gdirs) execute_entity_task(tasks.apparent_mb, gdirs) # Model validation tasks.quick_crossval_t_stars(gdirs) # for later tasks.distribute_t_stars(gdirs) # To restore after cross-val # Tests: for all glaciers, the mass-balance around tstar and the # bias with observation should be approx 0 from oggm.core.massbalance import (ConstantMassBalance, PastMassBalance) for gd in gdirs: heights, widths = gd.get_inversion_flowline_hw() mb_mod = ConstantMassBalance(gd, bias=0) # bias=0 because of calib! mb = mb_mod.get_specific_mb(heights, widths) np.testing.assert_allclose(mb, 0, atol=10) # numerical errors mb_mod = PastMassBalance(gd) # Here we need the computed bias refmb = gd.get_ref_mb_data().copy() refmb['OGGM'] = mb_mod.get_specific_mb(heights, widths, year=refmb.index) np.testing.assert_allclose(refmb.OGGM.mean(), refmb.ANNUAL_BALANCE.mean(), atol=10) # Log log.info('Calibration is done!')
def test_fluxmodel(self, hef_gdir): # define flowlines oggm_fls = hef_gdir.read_pickle('model_flowlines') fl = oggm_fls[0] combine_fls = MixedBedFlowline(line=fl.line, dx=fl.dx, map_dx=fl.map_dx, surface_h=fl.surface_h, bed_h=fl.bed_h, section=fl.section, bed_shape=fl.bed_shape, is_trapezoid=fl.is_trapezoid, lambdas=fl._lambdas, w0_m=fl._w0_m, rgi_id=fl.rgi_id, water_level=fl.water_level, torch_type=torch.double, device="cpu") # define MassBalanceModels y0 = 2000 halfsize = 15 combine_mb_model = ConstantMassBalanceTorch(hef_gdir, y0=y0, halfsize=halfsize) oggm_mb_model = ConstantMassBalance(hef_gdir, y0=y0, halfsize=halfsize) # define FluxModels oggm_model = oggm_flux_model(oggm_fls, mb_model=oggm_mb_model, y0=0, cfl_number=0.01) combine_model = combine_flux_model(combine_fls, mb_model=combine_mb_model, y0=0) # Let models run oggm_model.run_until(30.) combine_model.run_until(30.) # Compare models def compare_mdls(combine_mdl, oggm_mdl): assert np.isclose(combine_mdl.area_m2, oggm_mdl.area_m2, rtol=1e-4) assert np.isclose(combine_mdl.area_km2, oggm_mdl.area_km2, rtol=1e-4) assert np.isclose(combine_mdl.volume_m3, oggm_mdl.volume_m3, rtol=1e-3) assert np.isclose(combine_mdl.volume_km3, oggm_mdl.volume_km3, rtol=1e-3) assert np.allclose(combine_mdl.fls[0].surface_h, oggm_mdl.fls[0].surface_h, rtol=1e-4) compare_mdls(combine_model, oggm_model) # test with year as torch tensor oggm_model.run_until(40.) combine_model.run_until(torch.tensor(40., dtype=torch.double)) compare_mdls(combine_model, oggm_model) # Now run and compare in equilibrium oggm_model.run_until_equilibrium() combine_model.run_until_equilibrium() compare_mdls(combine_model, oggm_model)
# Select HEF out of all glaciers glen_a = cfg.A vol_m3, area_m3 = mass_conservation_inversion(gdir_hef, glen_a=glen_a) print('With A={}, the mean thickness of HEF is {:.1f} m'.format(glen_a, vol_m3/area_m3)) optim_resuls = tasks.optimize_inversion_params(gdirs) workflow.execute_entity_task(tasks.volume_inversion, gdirs) workflow.execute_entity_task(tasks.filter_inversion_output, gdirs) tasks.init_present_time_glacier(gdir_hef) fls = gdir_hef.read_pickle('model_flowlines') model = FluxBasedModel(fls) surface_before=model.fls[-1].surface_h today_model = ConstantMassBalance(gdir_hef, y0=1985) commit_model = FluxBasedModel(fls, mb_model=today_model, glen_a=cfg.A) pickle.dump(gdir_hef,open('gdir_hef.pkl','wb')) pickle.dump(commit_model.fls,open('hef_y0.pkl','wb')) plt.figure(0) #graphics.plot_modeloutput_section(gdir_hef, model=commit_model) print(commit_model.length_m) commit_model.run_until(100) pickle.dump(commit_model.fls,open('hef_y1.pkl','wb')) x=np.arange(model.fls[-1].nx) * model.fls[-1].dx * model.fls[-1].map_dx plt.figure(1) plt.plot(x,model.fls[-1].bed_h,'k') plt.plot(x,surface_before,color='teal', label='y0') plt.plot(x,commit_model.fls[-1].surface_h,color='tomato',label='y1')
def __init__(self, gdir, temp_bias_ts=None, prcp_fac_ts=None, mu_star=None, bias=None, y0=None, halfsize=15, filename='climate_historical', input_filesuffix='', **kwargs): """Initialize Parameters ---------- gdir : GlacierDirectory the glacier directory magicc_ts : pd.Series the GMT time series mu_star : float, optional set to the alternative value of mu* you want to use (the default is to use the calibrated value) bias : float, optional set to the alternative value of the annual bias [mm we yr-1] you want to use (the default is to use the calibrated value) y0 : int, optional, default: tstar the year at the center of the period of interest. The default is to use tstar as center. dt_per_dt : float, optional, default 1 the local climate change signal, in units of °C per °C halfsize : int, optional the half-size of the time window (window size = 2 * halfsize + 1) filename : str, optional set to a different BASENAME if you want to use alternative climate data. input_filesuffix : str the file suffix of the input climate file """ super(BiasedConstantMassBalance, self).__init__() self.mbmod = ConstantMassBalance(gdir, mu_star=mu_star, bias=bias, y0=y0, halfsize=halfsize, filename=filename, input_filesuffix=input_filesuffix, **kwargs) self.valid_bounds = self.mbmod.valid_bounds self.hemisphere = gdir.hemisphere # Set ys and ye self.ys = int(temp_bias_ts.index[0]) self.ye = int(temp_bias_ts.index[-1]) if prcp_fac_ts is None: prcp_fac_ts = temp_bias_ts * 0 self.prcp_fac_ts = self.mbmod.prcp_fac + prcp_fac_ts self.temp_bias_ts = temp_bias_ts
class BiasedConstantMassBalance(MassBalanceModel): """Time-dependant Temp and PRCP delta ConstantMassBalance model""" def __init__(self, gdir, temp_bias_ts=None, prcp_fac_ts=None, mu_star=None, bias=None, y0=None, halfsize=15, filename='climate_historical', input_filesuffix='', **kwargs): """Initialize Parameters ---------- gdir : GlacierDirectory the glacier directory magicc_ts : pd.Series the GMT time series mu_star : float, optional set to the alternative value of mu* you want to use (the default is to use the calibrated value) bias : float, optional set to the alternative value of the annual bias [mm we yr-1] you want to use (the default is to use the calibrated value) y0 : int, optional, default: tstar the year at the center of the period of interest. The default is to use tstar as center. dt_per_dt : float, optional, default 1 the local climate change signal, in units of °C per °C halfsize : int, optional the half-size of the time window (window size = 2 * halfsize + 1) filename : str, optional set to a different BASENAME if you want to use alternative climate data. input_filesuffix : str the file suffix of the input climate file """ super(BiasedConstantMassBalance, self).__init__() self.mbmod = ConstantMassBalance(gdir, mu_star=mu_star, bias=bias, y0=y0, halfsize=halfsize, filename=filename, input_filesuffix=input_filesuffix, **kwargs) self.valid_bounds = self.mbmod.valid_bounds self.hemisphere = gdir.hemisphere # Set ys and ye self.ys = int(temp_bias_ts.index[0]) self.ye = int(temp_bias_ts.index[-1]) if prcp_fac_ts is None: prcp_fac_ts = temp_bias_ts * 0 self.prcp_fac_ts = self.mbmod.prcp_fac + prcp_fac_ts self.temp_bias_ts = temp_bias_ts @property def temp_bias(self): """Temperature bias to add to the original series.""" return self.mbmod.temp_bias @temp_bias.setter def temp_bias(self, value): """Temperature bias to add to the original series.""" self.mbmod.temp_bias = value @property def prcp_fac(self): """Precipitation factor to apply to the original series.""" return self.mbmod.prcp_fac @prcp_fac.setter def prcp_fac(self, value): """Precipitation factor to apply to the original series.""" self.mbmod.prcp_fac = value @property def bias(self): """Residual bias to apply to the original series.""" return self.mbmod.bias @bias.setter def bias(self, value): """Residual bias to apply to the original series.""" self.mbmod.bias = value def _check_bias(self, year): t = np.asarray(self.temp_bias_ts.loc[int(year)]) if np.any(t != self.temp_bias): self.temp_bias = t p = np.asarray(self.prcp_fac_ts.loc[int(year)]) if np.any(p != self.prcp_fac): self.prcp_fac = p def get_monthly_mb(self, heights, year=None, **kwargs): self._check_bias(year) return self.mbmod.get_monthly_mb(heights, year=year, **kwargs) def get_annual_mb(self, heights, year=None, **kwargs): self._check_bias(year) return self.mbmod.get_annual_mb(heights, year=year, **kwargs)
def test_mb(self): # This is a function to produce the MB function needed by Anna # Download the RGI file for the run # Make a new dataframe of those rgidf = gpd.read_file(get_demo_file('SouthGlacier.shp')) # Go - initialize working directories gdirs = workflow.init_glacier_regions(rgidf) # Preprocessing tasks task_list = [ tasks.glacier_masks, tasks.compute_centerlines, tasks.initialize_flowlines, tasks.catchment_area, tasks.catchment_intersections, tasks.catchment_width_geom, tasks.catchment_width_correction, tasks.process_cru_data, tasks.local_t_star, tasks.mu_star_calibration, ] for task in task_list: execute_entity_task(task, gdirs) mbref = salem.GeoTiff(get_demo_file('mb_SouthGlacier.tif')) demref = salem.GeoTiff(get_demo_file('dem_SouthGlacier.tif')) mbref = mbref.get_vardata() mbref[mbref == -9999] = np.NaN demref = demref.get_vardata()[np.isfinite(mbref)] mbref = mbref[np.isfinite(mbref)] * 1000 # compute the bias to make it 0 SMB on the 2D DEM rho = cfg.PARAMS['ice_density'] mbmod = ConstantMassBalance(gdirs[0], bias=0) mymb = mbmod.get_annual_mb(demref) * cfg.SEC_IN_YEAR * rho mbmod = ConstantMassBalance(gdirs[0], bias=np.average(mymb)) mymb = mbmod.get_annual_mb(demref) * cfg.SEC_IN_YEAR * rho np.testing.assert_allclose(np.average(mymb), 0., atol=1e-3) # Same for ref mbref = mbref - np.average(mbref) np.testing.assert_allclose(np.average(mbref), 0., atol=1e-3) # Fit poly p = np.polyfit(demref, mbref, deg=2) poly = np.poly1d(p) myfit = poly(demref) np.testing.assert_allclose(np.average(myfit), 0., atol=1e-3) if do_plot: import matplotlib.pyplot as plt plt.scatter(mbref, demref, s=5, label='Obs (2007-2012), shifted to Avg(SMB) = 0') plt.scatter(mymb, demref, s=5, label='OGGM MB at t*') plt.scatter(myfit, demref, s=5, label='Polyfit', c='C3') plt.xlabel('MB (mm w.e yr-1)') plt.ylabel('Altidude (m)') plt.legend() plt.show()
def gridded_mb_attributes(gdir): """Adds mass-balance related attributes to the gridded data file. This could be useful for distributed ice thickness models. The raster data are added to the gridded_data file. Parameters ---------- gdir : :py:class:`oggm.GlacierDirectory` where to write the data """ from oggm.core.massbalance import LinearMassBalance, ConstantMassBalance from oggm.core.centerlines import line_inflows # Get the input data with ncDataset(gdir.get_filepath('gridded_data')) as nc: topo_2d = nc.variables['topo_smoothed'][:] glacier_mask_2d = nc.variables['glacier_mask'][:] glacier_mask_2d = glacier_mask_2d == 1 catchment_mask_2d = glacier_mask_2d * np.NaN cls = gdir.read_pickle('centerlines') # Catchment areas cis = gdir.read_pickle('geometries')['catchment_indices'] for j, ci in enumerate(cis): catchment_mask_2d[tuple(ci.T)] = j # Make everything we need flat catchment_mask = catchment_mask_2d[glacier_mask_2d].astype(int) topo = topo_2d[glacier_mask_2d] # Prepare the distributed mass-balance data rho = cfg.PARAMS['ice_density'] dx2 = gdir.grid.dx ** 2 # Linear def to_minimize(ela_h): mbmod = LinearMassBalance(ela_h[0]) smb = mbmod.get_annual_mb(heights=topo) return np.sum(smb)**2 ela_h = optimization.minimize(to_minimize, [0.], method='Powell') mbmod = LinearMassBalance(float(ela_h['x'])) lin_mb_on_z = mbmod.get_annual_mb(heights=topo) * cfg.SEC_IN_YEAR * rho if not np.isclose(np.sum(lin_mb_on_z), 0, atol=10): raise RuntimeError('Spec mass-balance should be zero but is: {}' .format(np.sum(lin_mb_on_z))) # Normal OGGM (a bit tweaked) df = gdir.read_json('local_mustar') def to_minimize(mu_star): mbmod = ConstantMassBalance(gdir, mu_star=mu_star, bias=0, check_calib_params=False, y0=df['t_star']) smb = mbmod.get_annual_mb(heights=topo) return np.sum(smb)**2 mu_star = optimization.minimize(to_minimize, [0.], method='Powell') mbmod = ConstantMassBalance(gdir, mu_star=float(mu_star['x']), bias=0, check_calib_params=False, y0=df['t_star']) oggm_mb_on_z = mbmod.get_annual_mb(heights=topo) * cfg.SEC_IN_YEAR * rho if not np.isclose(np.sum(oggm_mb_on_z), 0, atol=10): raise RuntimeError('Spec mass-balance should be zero but is: {}' .format(np.sum(oggm_mb_on_z))) # Altitude based mass balance catch_area_above_z = topo * np.NaN lin_mb_above_z = topo * np.NaN oggm_mb_above_z = topo * np.NaN for i, h in enumerate(topo): catch_area_above_z[i] = np.sum(topo >= h) * dx2 lin_mb_above_z[i] = np.sum(lin_mb_on_z[topo >= h]) * dx2 oggm_mb_above_z[i] = np.sum(oggm_mb_on_z[topo >= h]) * dx2 # Hardest part - MB per catchment catchment_area = topo * np.NaN lin_mb_above_z_on_catch = topo * np.NaN oggm_mb_above_z_on_catch = topo * np.NaN # First, find all inflows indices and min altitude per catchment inflows = [] lowest_h = [] for i, cl in enumerate(cls): lowest_h.append(np.min(topo[catchment_mask == i])) inflows.append([cls.index(l) for l in line_inflows(cl, keep=False)]) for i, (catch_id, h) in enumerate(zip(catchment_mask, topo)): if h == np.min(topo): t = 1 # Find the catchment area of the point itself by eliminating points # below the point altitude. We assume we keep all of them first, # then remove those we don't want sel_catchs = inflows[catch_id].copy() for catch in inflows[catch_id]: if h >= lowest_h[catch]: for cc in np.append(inflows[catch], catch): try: sel_catchs.remove(cc) except ValueError: pass # At the very least we need or own catchment sel_catchs.append(catch_id) # Then select all the catchment points sel_points = np.isin(catchment_mask, sel_catchs) # And keep the ones above our altitude sel_points = sel_points & (topo >= h) # Compute lin_mb_above_z_on_catch[i] = np.sum(lin_mb_on_z[sel_points]) * dx2 oggm_mb_above_z_on_catch[i] = np.sum(oggm_mb_on_z[sel_points]) * dx2 catchment_area[i] = np.sum(sel_points) * dx2 # Make 2D again def _fill_2d_like(data): out = topo_2d * np.NaN out[glacier_mask_2d] = data return out catchment_area = _fill_2d_like(catchment_area) catch_area_above_z = _fill_2d_like(catch_area_above_z) lin_mb_above_z = _fill_2d_like(lin_mb_above_z) oggm_mb_above_z = _fill_2d_like(oggm_mb_above_z) lin_mb_above_z_on_catch = _fill_2d_like(lin_mb_above_z_on_catch) oggm_mb_above_z_on_catch = _fill_2d_like(oggm_mb_above_z_on_catch) # Save to file with ncDataset(gdir.get_filepath('gridded_data'), 'a') as nc: vn = 'catchment_area' if vn in nc.variables: v = nc.variables[vn] else: v = nc.createVariable(vn, 'f4', ('y', 'x', )) v.units = 'm^2' v.long_name = 'Catchment area above point' v.description = ('This is a very crude method: just the area above ' 'the points elevation on glacier.') v[:] = catch_area_above_z vn = 'catchment_area_on_catch' if vn in nc.variables: v = nc.variables[vn] else: v = nc.createVariable(vn, 'f4', ('y', 'x',)) v.units = 'm^2' v.long_name = 'Catchment area above point on flowline catchments' v.description = ('Uses the catchments masks of the flowlines to ' 'compute the area above the altitude of the given ' 'point.') v[:] = catchment_area vn = 'lin_mb_above_z' if vn in nc.variables: v = nc.variables[vn] else: v = nc.createVariable(vn, 'f4', ('y', 'x', )) v.units = 'kg/year' v.long_name = 'MB above point from linear MB model, without catchments' v.description = ('Mass-balance cumulated above the altitude of the' 'point, hence in unit of flux. Note that it is ' 'a coarse approximation of the real flux. ' 'The mass-balance model is a simple linear function' 'of altitude.') v[:] = lin_mb_above_z vn = 'lin_mb_above_z_on_catch' if vn in nc.variables: v = nc.variables[vn] else: v = nc.createVariable(vn, 'f4', ('y', 'x', )) v.units = 'kg/year' v.long_name = 'MB above point from linear MB model, with catchments' v.description = ('Mass-balance cumulated above the altitude of the' 'point in a flowline catchment, hence in unit of ' 'flux. Note that it is a coarse approximation of the ' 'real flux. The mass-balance model is a simple ' 'linear function of altitude.') v[:] = lin_mb_above_z_on_catch vn = 'oggm_mb_above_z' if vn in nc.variables: v = nc.variables[vn] else: v = nc.createVariable(vn, 'f4', ('y', 'x', )) v.units = 'kg/year' v.long_name = 'MB above point from OGGM MB model, without catchments' v.description = ('Mass-balance cumulated above the altitude of the' 'point, hence in unit of flux. Note that it is ' 'a coarse approximation of the real flux. ' 'The mass-balance model is a calibrated temperature ' 'index model like OGGM.') v[:] = oggm_mb_above_z vn = 'oggm_mb_above_z_on_catch' if vn in nc.variables: v = nc.variables[vn] else: v = nc.createVariable(vn, 'f4', ('y', 'x', )) v.units = 'kg/year' v.long_name = 'MB above point from OGGM MB model, with catchments' v.description = ('Mass-balance cumulated above the altitude of the' 'point in a flowline catchment, hence in unit of ' 'flux. Note that it is a coarse approximation of the ' 'real flux. The mass-balance model is a calibrated ' 'temperature index model like OGGM.') v[:] = oggm_mb_above_z_on_catch
prcp_yr = np.mean(prcp_yr[selind]) # Average oberved mass-balance ref_mb = mbdf.ANNUAL_BALANCE.mean() mb_per_mu = prcp_yr - mu_yr_clim * temp_yr # Diff to reference diff = mb_per_mu - ref_mb pdf = pd.DataFrame() pdf[r'$\mu (t)$'] = mu_yr_clim pdf['bias'] = diff res = t_star_from_refmb(gdir, mbdf=mbdf.ANNUAL_BALANCE) # For the mass flux cl = gdir.read_pickle('inversion_input')[-1] mbmod = ConstantMassBalance(gdir) mbx = (mbmod.get_annual_mb(cl['hgt']) * cfg.SEC_IN_YEAR * cfg.PARAMS['ice_density']) fdf = pd.DataFrame(index=np.arange(len(mbx))*cl['dx']) fdf['Flux'] = cl['flux'] fdf['Mass balance'] = mbx # For the distributed thickness tasks.mass_conservation_inversion(gdir, glen_a=2.4e-24 * 3, fs=0) tasks.distribute_thickness_per_altitude(gdir) # plot functions def example_plot_temp_ts(): d = xr.open_dataset(gdir.get_filepath('climate_monthly')) temp = d.temp.resample(time='12MS').mean('time').to_series()