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
# 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() temp.index = temp.index.year
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()
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()
# 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() del temp.index.name