Пример #1
0
    def _set_up_VAS_model(self):
        """Avoiding a chunk of code duplicate. Set's up a running volume/area
        scaling model, including all needed prepo tasks.
        """

        # read the Hintereisferner DEM
        hef_file = get_demo_file('Hintereisferner_RGI6.shp')
        entity = gpd.read_file(hef_file).iloc[0]

        # initialize the GlacierDirectory
        gdir = oggm.GlacierDirectory(entity, base_dir=self.testdir)
        # define the local grid and glacier mask
        gis.define_glacier_region(gdir, entity=entity)
        gis.glacier_masks(gdir)

        # process the given climate file
        climate.process_custom_climate_data(gdir)

        # run center line preprocessing tasks
        centerlines.compute_centerlines(gdir)
        centerlines.initialize_flowlines(gdir)
        centerlines.catchment_area(gdir)
        centerlines.catchment_intersections(gdir)
        centerlines.catchment_width_geom(gdir)
        centerlines.catchment_width_correction(gdir)

        # read reference glacier mass balance data
        mbdf = gdir.get_ref_mb_data()
        # compute the reference t* for the glacier
        # given the reference of mass balance measurements
        res = climate.t_star_from_refmb(gdir, mbdf=mbdf['ANNUAL_BALANCE'])
        t_star, bias = res['t_star'], res['bias']

        # --------------------
        #  MASS BALANCE TASKS
        # --------------------

        # compute local t* and the corresponding mu*
        vascaling.local_t_star(gdir, tstar=t_star, bias=bias)

        # instance the mass balance models
        mbmod = vascaling.VAScalingMassBalance(gdir)

        # ----------------
        #  DYNAMICAL PART
        # ----------------
        # get reference area
        a0 = gdir.rgi_area_m2
        # get reference year
        y0 = gdir.get_climate_info()['baseline_hydro_yr_0']
        # get min and max glacier surface elevation
        h0, h1 = vascaling.get_min_max_elevation(gdir)

        model = vascaling.VAScalingModel(year_0=y0,
                                         area_m2_0=a0,
                                         min_hgt=h0,
                                         max_hgt=h1,
                                         mb_model=mbmod)
        return gdir, model
Пример #2
0
    def _setup_mb_test(self):
        """Avoiding a chunk of code duplicate. Performs needed prepo tasks and
        returns the oggm.GlacierDirectory.
        """

        # read the Hintereisferner DEM
        hef_file = get_demo_file('Hintereisferner_RGI6.shp')
        entity = gpd.read_file(hef_file).iloc[0]
        # initialize the GlacierDirectory
        gdir = oggm.GlacierDirectory(entity, base_dir=self.testdir)
        # define the local grid and the glacier mask
        gis.define_glacier_region(gdir, entity=entity)
        gis.glacier_masks(gdir)

        # process the given climate file
        climate.process_custom_climate_data(gdir)

        # run centerline prepro tasks
        centerlines.compute_centerlines(gdir)
        centerlines.initialize_flowlines(gdir)
        centerlines.catchment_area(gdir)
        centerlines.catchment_intersections(gdir)
        centerlines.catchment_width_geom(gdir)
        centerlines.catchment_width_correction(gdir)

        # read reference glacier mass balance data
        mbdf = gdir.get_ref_mb_data()
        # compute the reference t* for the glacier
        # given the reference of mass balance measurements
        res = vascaling.t_star_from_refmb(gdir, mbdf=mbdf['ANNUAL_BALANCE'])
        t_star, bias = res['t_star'], res['bias']

        # compute local t* and the corresponding mu*
        vascaling.local_t_star(gdir, tstar=t_star, bias=bias)

        # run OGGM mu* calibration
        climate.local_t_star(gdir, tstar=t_star, bias=bias)
        climate.mu_star_calibration(gdir)

        # pass the GlacierDirectory
        return gdir
Пример #3
0
def seek_start_area(rgi_id,
                    name,
                    show=False,
                    path='',
                    ref=np.NaN,
                    adjust_term_elev=False,
                    legend=True,
                    instant_geometry_change=False):
    """ Set up an VAS model from scratch and run/test the start area seeking
    tasks. The result is a plot showing the modeled glacier area evolution for
    different start values. The plots can be displayed and/or stored to file.

    Parameters
    ----------
    rgi_id: string
        RGI ID denoting the glacier on which to perform the tasks
    name: string
        Name og glacier, since it is not always given (or correct) in RGI
    show: bool, optional, default=False
        Flag deciding whether or not to show the created plots.
    path: string, optional, default=''
        Path under which the modeled area plot should be stored.
    ref: float, optional, default=np.NaN
        Historic (1851) reference area with which a reference model run is
        performed.

    """
    # Initialization and load default parameter file
    vascaling.initialize()

    # compute RGI region and version from RGI IDs
    # assuming they all are all the same
    rgi_region = (rgi_id.split('-')[-1]).split('.')[0]
    rgi_version = (rgi_id.split('-')[0])[-2:-1]

    # specify working directory and output directory
    working_dir = os.path.abspath('../working_directories/start_area/')
    # output_dir = os.path.abspath('./vas_run_output')
    output_dir = os.path.abspath('../data/vas_run_output')
    # create working directory
    utils.mkdir(working_dir, reset=False)
    utils.mkdir(output_dir)
    # set path to working directory
    cfg.PATHS['working_dir'] = working_dir
    # set RGI version and region
    cfg.PARAMS['rgi_version'] = rgi_version
    # define how many grid points to use around the glacier,
    # if you expect the glacier to grow large use a larger border
    cfg.PARAMS['border'] = 20
    # we use HistAlp climate data
    cfg.PARAMS['baseline_climate'] = 'HISTALP'
    # set the mb hyper parameters accordingly
    cfg.PARAMS['prcp_scaling_factor'] = 1.75
    cfg.PARAMS['temp_melt'] = -1.75
    cfg.PARAMS['run_mb_calibration'] = False

    # the bias is defined to be zero during the calibration process,
    # which is why we don't use it here to reproduce the results
    cfg.PARAMS['use_bias_for_run'] = True

    # get/downlaod the rgi entity including the outline shapefile
    rgi_df = utils.get_rgi_glacier_entities([rgi_id])
    # set name, if not delivered with RGI
    if rgi_df.loc[int(rgi_id[-5:]) - 1, 'Name'] is None:
        rgi_df.loc[int(rgi_id[-5:]) - 1, 'Name'] = name

    # get and set path to intersect shapefile
    intersects_db = utils.get_rgi_intersects_region_file(region=rgi_region)
    cfg.set_intersects_db(intersects_db)

    # initialize the GlacierDirectory
    gdir = workflow.init_glacier_directories(rgi_df)[0]

    # # DEM and GIS tasks
    # # get the path to the DEM file (will download if necessary)
    # dem = utils.get_topo_file(gdir.cenlon, gdir.cenlat)
    # print('DEM source: {}, path to DEM file: {}'.format(dem[1], dem[0][0]))
    # # set path in config file
    # cfg.PATHS['dem_file'] = dem[0][0]
    # cfg.PARAMS['border'] = 10
    # cfg.PARAMS['use_intersects'] = False

    # run GIS tasks
    gis.define_glacier_region(gdir)
    gis.glacier_masks(gdir)

    # process climate data
    climate.process_climate_data(gdir)

    #  compute local t* and the corresponding mu*
    vascaling.local_t_star(gdir)

    # create mass balance model
    mb_mod = vascaling.VAScalingMassBalance(gdir)

    # look at specific mass balance over climate data period
    min_hgt, max_hgt = vascaling.get_min_max_elevation(gdir)
    y0 = 1851
    y1 = 2014

    # run scalar minimization
    minimize_res = vascaling.find_start_area(
        gdir,
        adjust_term_elev=adjust_term_elev,
        instant_geometry_change=instant_geometry_change)
    # print(minimize_res)

    # stop script if minimization was not successful
    if minimize_res.status and False:
        sys.exit(minimize_res.status)

    # instance glacier with today's values
    model_ref = vascaling.VAScalingModel(year_0=gdir.rgi_date,
                                         area_m2_0=gdir.rgi_area_m2,
                                         min_hgt=min_hgt,
                                         max_hgt=max_hgt,
                                         mb_model=mb_mod)

    # instance guessed starting areas
    num = 9
    area_guess = np.linspace(1e6,
                             np.floor(gdir.rgi_area_m2 * 2),
                             num,
                             endpoint=True)
    # create empty containers
    area_list = list()
    volume_list = list()
    spec_mb_list = list()

    # iterate over all starting areas
    for area_ in area_guess:
        # instance iteration model
        model_guess = vascaling.VAScalingModel(year_0=gdir.rgi_date,
                                               area_m2_0=gdir.rgi_area_m2,
                                               min_hgt=min_hgt,
                                               max_hgt=max_hgt,
                                               mb_model=mb_mod)
        # set new starting values
        model_guess.create_start_glacier(area_,
                                         y0,
                                         adjust_term_elev=adjust_term_elev)
        # run model and save years and area
        best_guess_ds = model_guess.run_until_and_store(
            year_end=model_ref.year,
            instant_geometry_change=instant_geometry_change)
        # create series and store in container
        area_list.append(best_guess_ds.area_m2.to_dataframe()['area_m2'])
        volume_list.append(best_guess_ds.volume_m3.to_dataframe()['volume_m3'])
        spec_mb_list.append(best_guess_ds.spec_mb.to_dataframe()['spec_mb'])

    # create DataFrame
    area_df = pd.DataFrame(
        area_list, index=['{:.2f}'.format(a / 1e6) for a in area_guess])
    area_df.index.name = 'Start Area [km$^2$]'

    volume_df = pd.DataFrame(
        volume_list, index=['{:.2f}'.format(a / 1e6) for a in area_guess])
    volume_df.index.name = 'Start Area [km$^2$]'

    # set up model with resulted starting area
    model = vascaling.VAScalingModel(year_0=model_ref.year_0,
                                     area_m2_0=model_ref.area_m2_0,
                                     min_hgt=model_ref.min_hgt_0,
                                     max_hgt=model_ref.max_hgt,
                                     mb_model=model_ref.mb_model)
    model.create_start_glacier(minimize_res.x,
                               y0,
                               adjust_term_elev=adjust_term_elev)

    # run model with best guess initial area
    best_guess_ds = model.run_until_and_store(
        year_end=model_ref.year,
        instant_geometry_change=instant_geometry_change)
    # run model with historic reference area
    if ref:
        model.reset()
        model.create_start_glacier(ref * 1e6,
                                   y0,
                                   adjust_term_elev=adjust_term_elev)
        ref_ds = model.run_until_and_store(
            year_end=model_ref.year,
            instant_geometry_change=instant_geometry_change)

    # create figure and add axes
    fig = plt.figure(figsize=[5, 5])
    ax = fig.add_axes([0.125, 0.075, 0.85, 0.9])

    # plot model output
    ax = (area_df / 1e6).T.plot(legend=False, colormap='Spectral', ax=ax)

    # plot best guess
    ax.plot(
        best_guess_ds.time,
        best_guess_ds.area_m2 / 1e6,
        color='k',
        ls='--',
        lw=1.2,
        label=
        f'{best_guess_ds.area_m2.isel(time=0).values/1e6:.2f} km$^2$ (best result)'
    )
    # plot reference
    if ref:
        ax.plot(
            ref_ds.time,
            ref_ds.area_m2 / 1e6,
            color='k',
            ls='-.',
            lw=1.2,
            label=
            f'{ref_ds.area_m2.isel(time=0).values/1e6:.2f} km$^2$ (1850 ref.)')

    # plot 2003 reference line
    ax.axhline(
        model_ref.area_m2_0 / 1e6,
        c='k',
        ls=':',
        label=f'{model_ref.area_m2_0/1e6:.2f} km$^2$ ({gdir.rgi_date} obs.)')

    # add legend
    if legend:
        handels, labels = ax.get_legend_handles_labels()
        labels[:-3] = [r'{} km$^2$'.format(l) for l in labels[:-3]]
        leg = ax.legend(handels, labels, loc='upper right', ncol=2)
        # leg.set_title('Start area $A_0$', prop={'size': 12})

    # replot best guess estimate and reference (in case it lies below another
    # guess)
    ax.plot(best_guess_ds.time,
            best_guess_ds.area_m2 / 1e6,
            color='k',
            ls='--',
            lw=1.2)
    if ref:
        ax.plot(ref_ds.time, ref_ds.area_m2 / 1e6, color='k', ls='-.', lw=1.2)

    # labels, title
    ax.set_xlim([best_guess_ds.time.values[0], best_guess_ds.time.values[-1]])
    ax.set_xlabel('')
    ax.set_ylabel('Glacier area [km$^2$]')

    # save figure to file
    if path:
        fig.savefig(path)

    # show plot
    if show:
        plt.show()
    plt.clf()

    # plot and store volume evolution
    (volume_df / 1e9).T.plot(legend=False, colormap='viridis')
    plt.gcf().savefig(path[:-4] + '_volume.pdf')
Пример #4
0
    def test_run_constant_climate(self):
        """ Test the run_constant_climate task for a climate based on the
        equilibrium period centred around t*. Additionally a positive and a
        negative temperature bias are tested.

        """
        # let's not use the mass balance bias since we want to reproduce
        # results from mass balance calibration
        cfg.PARAMS['use_bias_for_run'] = False

        # read the Hintereisferner DEM
        hef_file = get_demo_file('Hintereisferner_RGI6.shp')
        entity = gpd.read_file(hef_file).iloc[0]

        # initialize the GlacierDirectory
        gdir = oggm.GlacierDirectory(entity, base_dir=self.testdir)
        # define the local grid and glacier mask
        gis.define_glacier_region(gdir, entity=entity)
        gis.glacier_masks(gdir)

        # process the given climate file
        climate.process_custom_climate_data(gdir)
        # compute mass balance parameters
        fn = 'vas_ref_tstars_rgi6_histalp.csv'
        fp = vascaling.get_ref_tstars_filepath(fn)
        ref_df = pd.read_csv(fp)
        vascaling.local_t_star(gdir, ref_df=ref_df)

        # define some parameters for the constant climate model
        nyears = 500
        temp_bias = 0.5
        _ = vascaling.run_constant_climate(gdir,
                                           nyears=nyears,
                                           output_filesuffix='')
        _ = vascaling.run_constant_climate(gdir,
                                           nyears=nyears,
                                           temperature_bias=+temp_bias,
                                           output_filesuffix='_bias_p')
        _ = vascaling.run_constant_climate(gdir,
                                           nyears=nyears,
                                           temperature_bias=-temp_bias,
                                           output_filesuffix='_bias_n')

        # compile run outputs
        ds = utils.compile_run_output([gdir], input_filesuffix='')
        ds_p = utils.compile_run_output([gdir], input_filesuffix='_bias_p')
        ds_n = utils.compile_run_output([gdir], input_filesuffix='_bias_n')

        # the glacier should not change under a constant climate
        # based on the equilibirum period centered around t*
        assert abs(1 - ds.volume.mean() / ds.volume[0]) < 1e-7
        # higher temperatures should result in a smaller glacier
        assert ds.volume.mean() > ds_p.volume.mean()
        # lower temperatures should result in a larger glacier
        assert ds.volume.mean() < ds_n.volume.mean()

        # compute volume change from one year to the next
        dV_p = (ds_p.volume[1:].values - ds_p.volume[:-1].values).flatten()
        dV_n = (ds_n.volume[1:].values - ds_n.volume[:-1].values).flatten()
        # compute relative volume change, with respect to the final volume
        rate_p = abs(dV_p / float(ds_p.volume.values[-1]))
        rate_n = abs(dV_n / float(ds_n.volume.values[-1]))
        # the glacier should be in a new equilibirum for last 300 years
        assert max(rate_p[-300:]) < 0.001
        assert max(rate_n[-300:]) < 0.001
Пример #5
0
    def test_run_random_climate(self):
        """ Test the run_random_climate task for a climate based on the
        equilibrium period centred around t*. Additionally a positive and a
        negative temperature bias are tested.

        Returns
        -------

        """
        # let's not use the mass balance bias since we want to reproduce
        # results from mass balance calibration
        cfg.PARAMS['use_bias_for_run'] = False

        # read the Hintereisferner DEM
        hef_file = get_demo_file('Hintereisferner_RGI6.shp')
        entity = gpd.read_file(hef_file).iloc[0]

        # initialize the GlacierDirectory
        gdir = oggm.GlacierDirectory(entity, base_dir=self.testdir)
        # define the local grid and glacier mask
        gis.define_glacier_region(gdir, entity=entity)
        gis.glacier_masks(gdir)

        # process the given climate file
        climate.process_custom_climate_data(gdir)
        # compute mass balance parameters
        fn = 'vas_ref_tstars_rgi6_histalp.csv'
        fp = vascaling.get_ref_tstars_filepath(fn)
        ref_df = pd.read_csv(fp)
        vascaling.local_t_star(gdir, ref_df=ref_df)

        # define some parameters for the random climate model
        nyears = 300
        seed = 1
        temp_bias = 0.5
        # read the equilibirum year used for the mass balance calibration
        t_star = gdir.read_json('vascaling_mustar')['t_star']
        # run model with random climate
        _ = vascaling.run_random_climate(gdir,
                                         nyears=nyears,
                                         y0=t_star,
                                         seed=seed)
        # run model with positive temperature bias
        _ = vascaling.run_random_climate(gdir,
                                         nyears=nyears,
                                         y0=t_star,
                                         seed=seed,
                                         temperature_bias=temp_bias,
                                         output_filesuffix='_bias_p')
        # run model with negative temperature bias
        _ = vascaling.run_random_climate(gdir,
                                         nyears=nyears,
                                         y0=t_star,
                                         seed=seed,
                                         temperature_bias=-temp_bias,
                                         output_filesuffix='_bias_n')

        # compile run outputs
        ds = utils.compile_run_output([gdir], input_filesuffix='')
        ds_p = utils.compile_run_output([gdir], input_filesuffix='_bias_p')
        ds_n = utils.compile_run_output([gdir], input_filesuffix='_bias_n')

        # the glacier should not change much under a random climate
        # based on the equilibirum period centered around t*
        assert abs(1 - ds.volume.mean() / ds.volume[0]) < 0.015
        # higher temperatures should result in a smaller glacier
        assert ds.volume.mean() > ds_p.volume.mean()
        # lower temperatures should result in a larger glacier
        assert ds.volume.mean() < ds_n.volume.mean()
Пример #6
0
    def test_run_until_and_store(self):
        """Test the volume/area scaling model against the oggm.FluxBasedModel.

        Both models run the Hintereisferner over the entire HistAlp climate
        period, initialized with the 2003 RGI outline without spin up.

        The following two parameters for length, area and volume are tested:
            - correlation coefficient
            - relative RMSE, i.e. RMSE/mean(OGGM). Whereby the results from the
                VAS model are offset with the average differences to the OGGM
                results.
       """

        # read the Hintereisferner DEM
        hef_file = get_demo_file('Hintereisferner_RGI6.shp')
        entity = gpd.read_file(hef_file).iloc[0]

        # initialize the GlacierDirectory
        gdir = oggm.GlacierDirectory(entity, base_dir=self.testdir)
        # define the local grid and glacier mask
        gis.define_glacier_region(gdir, entity=entity)
        gis.glacier_masks(gdir)

        # process the given climate file
        climate.process_custom_climate_data(gdir)

        # run center line preprocessing tasks
        centerlines.compute_centerlines(gdir)
        centerlines.initialize_flowlines(gdir)
        centerlines.compute_downstream_line(gdir)
        centerlines.compute_downstream_bedshape(gdir)
        centerlines.catchment_area(gdir)
        centerlines.catchment_intersections(gdir)
        centerlines.catchment_width_geom(gdir)
        centerlines.catchment_width_correction(gdir)

        # read reference glacier mass balance data
        mbdf = gdir.get_ref_mb_data()
        # compute the reference t* for the glacier
        # given the reference of mass balance measurements
        res = climate.t_star_from_refmb(gdir, mbdf=mbdf['ANNUAL_BALANCE'])
        t_star, bias = res['t_star'], res['bias']

        # --------------------
        #  SCALING MODEL
        # --------------------

        # compute local t* and the corresponding mu*
        vascaling.local_t_star(gdir, tstar=t_star, bias=bias)

        # instance the mass balance models
        vas_mbmod = vascaling.VAScalingMassBalance(gdir)

        # get reference area
        a0 = gdir.rgi_area_m2
        # get reference year
        y0 = gdir.get_climate_info()['baseline_hydro_yr_0']
        # get min and max glacier surface elevation
        h0, h1 = vascaling.get_min_max_elevation(gdir)

        vas_model = vascaling.VAScalingModel(year_0=y0,
                                             area_m2_0=a0,
                                             min_hgt=h0,
                                             max_hgt=h1,
                                             mb_model=vas_mbmod)

        # let model run over entire HistAlp climate period
        vas_ds = vas_model.run_until_and_store(2003)

        # ------
        #  OGGM
        # ------

        # compute local t* and the corresponding mu*
        climate.local_t_star(gdir, tstar=t_star, bias=bias)
        climate.mu_star_calibration(gdir)

        # instance the mass balance models
        mb_mod = massbalance.PastMassBalance(gdir)

        # perform ice thickness inversion
        inversion.prepare_for_inversion(gdir)
        inversion.mass_conservation_inversion(gdir)
        inversion.filter_inversion_output(gdir)

        # initialize present time glacier
        flowline.init_present_time_glacier(gdir)

        # instance flowline model
        fls = gdir.read_pickle('model_flowlines')
        y0 = gdir.get_climate_info()['baseline_hydro_yr_0']
        fl_mod = flowline.FluxBasedModel(flowlines=fls, mb_model=mb_mod, y0=y0)

        # run model and store output as xarray data set
        _, oggm_ds = fl_mod.run_until_and_store(2003)

        # temporal indices must be equal
        assert (vas_ds.time == oggm_ds.time).all()

        # specify which parameters to compare and their respective correlation
        # coefficients and rmsd values
        params = ['length_m', 'area_m2', 'volume_m3']
        corr_coeffs = np.array([0.7, 0.7, 0.7])
        rmsds = np.array([0.43e3, 0.25e6, 0.05e9])

        # compare given parameters
        for param, cc, rmsd in zip(params, corr_coeffs, rmsds):
            # correlation coefficient
            assert corrcoef(oggm_ds[param].values, vas_ds[param].values) >= cc
            # root mean squared deviation
            rmsd_an = rmsd_bc(oggm_ds[param].values, vas_ds[param].values)
            assert rmsd_an <= rmsd
Пример #7
0
    def test_local_t_star(self):

        # set parameters for climate file and mass balance calibration
        cfg.PARAMS['baseline_climate'] = 'CUSTOM'
        cfg.PATHS['climate_file'] = get_demo_file('histalp_merged_hef.nc')
        cfg.PARAMS['run_mb_calibration'] = False

        # read the Hintereisferner
        hef_file = get_demo_file('Hintereisferner_RGI6.shp')
        entity = gpd.read_file(hef_file).iloc[0]

        # initialize the GlacierDirectory
        gdir = oggm.GlacierDirectory(entity, base_dir=self.testdir)
        # define the local grid and the glacier mask
        gis.define_glacier_region(gdir, entity=entity)
        gis.glacier_masks(gdir)
        # run centerline prepro tasks
        centerlines.compute_centerlines(gdir)
        centerlines.initialize_flowlines(gdir)
        centerlines.catchment_area(gdir)
        centerlines.catchment_intersections(gdir)
        centerlines.catchment_width_geom(gdir)
        centerlines.catchment_width_correction(gdir)
        # process the given climate file
        climate.process_custom_climate_data(gdir)

        # compute the reference t* for the glacier
        # given the reference of mass balance measurements
        res = vascaling.t_star_from_refmb(gdir)
        t_star, bias = res['t_star'], res['bias']
        # compute local t* and the corresponding mu*
        vascaling.local_t_star(gdir, tstar=t_star, bias=bias)
        # read calibration results
        vas_mustar_refmb = gdir.read_json('vascaling_mustar')

        # get reference t* list
        fn = 'vas_ref_tstars_rgi6_histalp.csv'
        fp = vascaling.get_ref_tstars_filepath(fn)
        ref_df = pd.read_csv(fp)

        # compute local t* and the corresponding mu*
        vascaling.local_t_star(gdir, ref_df=ref_df)
        # read calibration results
        vas_mustar_refdf = gdir.read_json('vascaling_mustar')

        # compute local t* and the corresponding mu*
        vascaling.local_t_star(gdir)
        # read calibration results
        vas_mustar = gdir.read_json('vascaling_mustar')

        # compare with each other
        assert vas_mustar_refdf == vas_mustar
        # TODO: this test is currently failing, since the bias computed
        # via `t_start_from_refmb` does not align with the reference tstar list
        # np.testing.assert_allclose(vas_mustar_refmb['bias'],
        #                            vas_mustar_refdf['bias'], atol=1)
        vas_mustar_refdf.pop('bias')
        vas_mustar_refmb.pop('bias')
        # end of workaround
        assert vas_mustar_refdf == vas_mustar_refmb
        # compare with know values
        assert vas_mustar['t_star'] == 1885
        assert abs(vas_mustar['mu_star'] - 82.73) <= 0.1
        assert abs(vas_mustar['bias'] - -6.47) <= 0.1
Пример #8
0
    def test_run_until_equilibrium(self):
        """
        Note: the oscillating behavior makes this test almost meaningless
        Returns
        -------

        """
        # let's not use the mass balance bias since we want to reproduce
        # results from mass balance calibration
        cfg.PARAMS['use_bias_for_run'] = False

        # read the Hintereisferner DEM
        hef_file = get_demo_file('Hintereisferner_RGI6.shp')
        entity = gpd.read_file(hef_file).iloc[0]

        # initialize the GlacierDirectory
        gdir = oggm.GlacierDirectory(entity, base_dir=self.testdir)
        # define the local grid and glacier mask
        gis.define_glacier_region(gdir, entity=entity)
        gis.glacier_masks(gdir)

        # process the given climate file
        climate.process_custom_climate_data(gdir)
        # compute mass balance parameters
        fn = 'vas_ref_tstars_rgi6_histalp.csv'
        fp = vascaling.get_ref_tstars_filepath(fn)
        ref_df = pd.read_csv(fp)
        vascaling.local_t_star(gdir, ref_df=ref_df)

        # instance a constant mass balance model, centred around t*
        mb_model = vascaling.ConstantVASMassBalance(gdir)
        # add a positive temperature bias
        mb_model.temp_bias = 0.5

        # create a VAS model: start with year 0  since we are using a constant
        # massbalance model, other values are read from RGI
        min_hgt, max_hgt = vascaling.get_min_max_elevation(gdir)
        model = vascaling.VAScalingModel(year_0=0,
                                         area_m2_0=gdir.rgi_area_m2,
                                         min_hgt=min_hgt,
                                         max_hgt=max_hgt,
                                         mb_model=mb_model)

        # run glacier with new mass balance model
        model.run_until_equilibrium(rate=1e-5)

        # equilibrium should be reached after a couple of 100 years
        assert model.year <= 600
        # new equilibrium glacier should be smaller (positive temperature bias)
        assert model.volume_m3 < model.volume_m3_0

        # run glacier for another 100 years and check volume again
        v_eq = model.volume_m3
        model.run_until(model.year + 100)
        assert abs(1 - (model.volume_m3 / v_eq)) < 0.01

        # instance a random mass balance model, centred around t*
        mb_model = vascaling.RandomVASMassBalance(gdir)
        min_hgt, max_hgt = vascaling.get_min_max_elevation(gdir)
        model = vascaling.VAScalingModel(year_0=0,
                                         area_m2_0=gdir.rgi_area_m2,
                                         min_hgt=min_hgt,
                                         max_hgt=max_hgt,
                                         mb_model=mb_model)

        # run glacier with random mass balance model
        with self.assertRaises(TypeError):
            model.run_until_equilibrium(rate=1e-4)