Beispiel #1
0
    def test_constant_bed(self):

        models = [FluxBasedModel, MUSCLSuperBeeModel]

        lens = []
        surface_h = []
        volume = []
        yrs = np.arange(1, 300, 2)
        for model in models:
            fls = dummy_constant_bed()
            mb = LinearMassBalance(2600.)

            model = model(fls, mb_model=mb, y0=0., glen_a=self.glen_a,
                          fs=self.fs, fixed_dt=10 * SEC_IN_DAY)

            length = yrs * 0.
            vol = yrs * 0.
            for i, y in enumerate(yrs):
                model.run_until(y)
                assert model.yr == y
                length[i] = fls[-1].length_m
                vol[i] = fls[-1].volume_km3
            lens.append(length)
            volume.append(vol)
            surface_h.append(fls[-1].surface_h.copy())

        assert_allclose(lens[0][-1], lens[1][-1], atol=101)
        assert_allclose(volume[0][-1], volume[1][-1], atol=3e-3)

        assert rmsd(lens[0], lens[1]) < 50.
        assert rmsd(volume[0], volume[1]) < 2e-3
        assert rmsd(surface_h[0], surface_h[1]) < 1.0
Beispiel #2
0
    def test_adaptive_ts(self):

        models = [KarthausModel, FluxBasedModel, MUSCLSuperBeeModel]
        steps = [31 * SEC_IN_DAY, None, None]
        lens = []
        surface_h = []
        volume = []
        yrs = np.arange(1, 500, 2)
        for model, step in zip(models, steps):
            fls = dummy_constant_bed()
            mb = LinearMassBalance(2600.)

            model = model(fls, mb_model=mb, glen_a=self.glen_a, fixed_dt=step)

            length = yrs * 0.
            vol = yrs * 0.
            for i, y in enumerate(yrs):
                model.run_until(y)
                length[i] = fls[-1].length_m
                vol[i] = fls[-1].volume_km3
            lens.append(length)
            volume.append(vol)
            surface_h.append(fls[-1].surface_h.copy())

        np.testing.assert_almost_equal(lens[0][-1], lens[1][-1])
        np.testing.assert_allclose(volume[0][-1], volume[1][-1], atol=1e-2)
        np.testing.assert_allclose(volume[0][-1], volume[2][-1], atol=1e-2)

        self.assertTrue(utils.rmsd(lens[0], lens[1]) < 50.)
        self.assertTrue(utils.rmsd(volume[2], volume[1]) < 1e-3)
        self.assertTrue(utils.rmsd(surface_h[0], surface_h[1]) < 5)
        self.assertTrue(utils.rmsd(surface_h[1], surface_h[2]) < 5)
Beispiel #3
0
    def test_adaptive_ts(self):

        models = [
            flowline.KarthausModel, flowline.FluxBasedModel,
            flowline.MUSCLSuperBeeModel
        ]
        steps = [SEC_IN_MONTH, None, None]
        lens = []
        surface_h = []
        volume = []
        yrs = np.arange(1, 500, 2)
        for model, step in zip(models, steps):
            fls = dummy_constant_bed()
            mb = ConstantBalanceModel(2600.)

            model = model(fls, mb_model=mb, glen_a=self.glen_a, fixed_dt=step)

            length = yrs * 0.
            vol = yrs * 0.
            for i, y in enumerate(yrs):
                model.run_until(y)
                length[i] = fls[-1].length_m
                vol[i] = fls[-1].volume_km3
            lens.append(length)
            volume.append(vol)
            surface_h.append(fls[-1].surface_h.copy())

        np.testing.assert_almost_equal(lens[0][-1], lens[1][-1])
        np.testing.assert_allclose(volume[0][-1], volume[1][-1], atol=1e-2)
        np.testing.assert_allclose(volume[0][-1], volume[2][-1], atol=1e-2)

        self.assertTrue(utils.rmsd(lens[0], lens[1]) < 50.)
        self.assertTrue(utils.rmsd(volume[0], volume[1]) < 1e-3)
        self.assertTrue(utils.rmsd(surface_h[0], surface_h[1]) < 5)
        self.assertTrue(utils.rmsd(surface_h[0], surface_h[2]) < 5)
Beispiel #4
0
    def test_init_present_time_glacier(self):

        gdirs = up_to_inversion()

        # Inversion Results
        cfg.PARAMS['invert_with_sliding'] = True
        cfg.PARAMS['optimize_thick'] = True
        workflow.inversion_tasks(gdirs)

        fpath = os.path.join(cfg.PATHS['working_dir'],
                             'inversion_optim_results.csv')
        df = pd.read_csv(fpath, index_col=0)
        r1 = rmsd(df['ref_volume_km3'], df['oggm_volume_km3'])
        r2 = rmsd(df['ref_volume_km3'], df['vas_volume_km3'])
        self.assertTrue(r1 < r2)

        cfg.PARAMS['invert_with_sliding'] = False
        cfg.PARAMS['optimize_thick'] = False
        workflow.inversion_tasks(gdirs)

        fpath = os.path.join(cfg.PATHS['working_dir'],
                             'inversion_optim_results.csv')
        df = pd.read_csv(fpath, index_col=0)
        r1 = rmsd(df['ref_volume_km3'], df['oggm_volume_km3'])
        r2 = rmsd(df['ref_volume_km3'], df['vas_volume_km3'])
        self.assertTrue(r1 < r2)

        # Init glacier
        d = gdirs[0].read_pickle('inversion_params')
        fs = d['fs']
        glen_a = d['glen_a']
        maxs = cfg.PARAMS['max_shape_param']
        for gdir in gdirs:
            flowline.init_present_time_glacier(gdir)
            mb_mod = massbalance.ConstantMassBalanceModel(gdir)
            fls = gdir.read_pickle('model_flowlines')
            model = flowline.FluxBasedModel(fls, mb_model=mb_mod, y0=0.,
                                            fs=fs, glen_a=glen_a)
            _vol = model.volume_km3
            _area = model.area_km2
            if gdir.rgi_id in df.index:
                gldf = df.loc[gdir.rgi_id]
                # TODO: broken but should work
                # assert_allclose(gldf['oggm_volume_km3'], _vol, rtol=0.03)
                # assert_allclose(gldf['ref_area_km2'], _area, rtol=0.03)
                maxo = max([fl.order for fl in model.fls])
                for fl in model.fls:
                    self.assertTrue(np.all(fl.bed_shape > 0))
                    self.assertTrue(np.all(fl.bed_shape <= maxs))
                    if len(model.fls) > 1:
                        if fl.order == (maxo-1):
                            self.assertTrue(fl.flows_to is fls[-1])

        # Test the glacier charac
        dfc = utils.glacier_characteristics(gdirs)
        self.assertTrue(np.all(dfc.terminus_type == 'Land-terminating'))
        cc = dfc[['dem_mean_elev', 'clim_temp_avgh']].corr().values[0, 1]
        self.assertTrue(cc > 0.4)
Beispiel #5
0
    def test_set_width(self):
        entity = gpd.read_file(self.rgi_file).iloc[0]

        gdir = oggm.GlacierDirectory(entity, base_dir=self.testdir)
        gis.define_glacier_region(gdir)
        gis.glacier_masks(gdir)
        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)

        # Test that area and area-altitude elev is fine
        with utils.ncDataset(gdir.get_filepath('gridded_data')) as nc:
            mask = nc.variables['glacier_mask'][:]
            topo = nc.variables['topo_smoothed'][:]
        rhgt = topo[np.where(mask)][:]

        fls = gdir.read_pickle('inversion_flowlines')
        hgt, widths = gdir.get_inversion_flowline_hw()

        bs = 100
        bins = np.arange(utils.nicenumber(np.min(hgt), bs, lower=True),
                         utils.nicenumber(np.max(hgt), bs) + 1,
                         bs)
        h1, b = np.histogram(hgt, weights=widths, density=True, bins=bins)
        h2, b = np.histogram(rhgt, density=True, bins=bins)
        h1 = h1 / np.sum(h1)
        h2 = h2 / np.sum(h2)
        assert utils.rmsd(h1, h2) < 0.02  # less than 2% error
        new_area = np.sum(widths * fls[-1].dx * gdir.grid.dx)
        np.testing.assert_allclose(new_area, gdir.rgi_area_m2)

        centerlines.terminus_width_correction(gdir, new_width=714)

        fls = gdir.read_pickle('inversion_flowlines')
        hgt, widths = gdir.get_inversion_flowline_hw()

        # Check that the width is ok
        np.testing.assert_allclose(fls[-1].widths[-1] * gdir.grid.dx, 714)

        # Check for area distrib
        bins = np.arange(utils.nicenumber(np.min(hgt), bs, lower=True),
                         utils.nicenumber(np.max(hgt), bs) + 1,
                         bs)
        h1, b = np.histogram(hgt, weights=widths, density=True, bins=bins)
        h2, b = np.histogram(rhgt, density=True, bins=bins)
        h1 = h1 / np.sum(h1)
        h2 = h2 / np.sum(h2)
        assert utils.rmsd(h1, h2) < 0.02  # less than 2% error
        new_area = np.sum(widths * fls[-1].dx * gdir.grid.dx)
        np.testing.assert_allclose(new_area, gdir.rgi_area_m2)
Beispiel #6
0
    def test_set_width(self):
        entity = gpd.read_file(self.rgi_file).iloc[0]

        gdir = oggm.GlacierDirectory(entity, base_dir=self.testdir)
        gis.define_glacier_region(gdir, entity=entity)
        gis.glacier_masks(gdir)
        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)

        # Test that area and area-altitude elev is fine
        with utils.ncDataset(gdir.get_filepath('gridded_data')) as nc:
            mask = nc.variables['glacier_mask'][:]
            topo = nc.variables['topo_smoothed'][:]
        rhgt = topo[np.where(mask)][:]

        fls = gdir.read_pickle('inversion_flowlines')
        hgt, widths = gdir.get_inversion_flowline_hw()

        bs = 100
        bins = np.arange(utils.nicenumber(np.min(hgt), bs, lower=True),
                         utils.nicenumber(np.max(hgt), bs) + 1,
                         bs)
        h1, b = np.histogram(hgt, weights=widths, density=True, bins=bins)
        h2, b = np.histogram(rhgt, density=True, bins=bins)
        h1 = h1 / np.sum(h1)
        h2 = h2 / np.sum(h2)
        assert utils.rmsd(h1, h2) < 0.02  # less than 2% error
        new_area = np.sum(widths * fls[-1].dx * gdir.grid.dx)
        np.testing.assert_allclose(new_area, gdir.rgi_area_m2)

        centerlines.terminus_width_correction(gdir, new_width=714)

        fls = gdir.read_pickle('inversion_flowlines')
        hgt, widths = gdir.get_inversion_flowline_hw()

        # Check that the width is ok
        np.testing.assert_allclose(fls[-1].widths[-1] * gdir.grid.dx, 714)

        # Check for area distrib
        bins = np.arange(utils.nicenumber(np.min(hgt), bs, lower=True),
                         utils.nicenumber(np.max(hgt), bs) + 1,
                         bs)
        h1, b = np.histogram(hgt, weights=widths, density=True, bins=bins)
        h2, b = np.histogram(rhgt, density=True, bins=bins)
        h1 = h1 / np.sum(h1)
        h2 = h2 / np.sum(h2)
        assert utils.rmsd(h1, h2) < 0.02  # less than 2% error
        new_area = np.sum(widths * fls[-1].dx * gdir.grid.dx)
        np.testing.assert_allclose(new_area, gdir.rgi_area_m2)
Beispiel #7
0
def optimize_inversion_params(gdirs):
    """Optimizes fs and fd"""

    log.info('Compute the reference fs and fd parameters.')

    # Get test glaciers (all glaciers with thickness data)
    dfids = cfg.paths['glathida_rgi_links']
    gtd_df = pd.read_csv(dfids).sort_values(by=['RGI_ID'])
    dfids = gtd_df['RGI_ID'].values

    ref_gdirs = [gdir for gdir in gdirs if gdir.rgi_id in dfids]

    # Account for area differences between glathida and rgi
    ref_area_km2 = gtd_df.RGI_AREA.values
    ref_cs = gtd_df.VOLUME.values / (gtd_df.GTD_AREA.values**1.375)
    ref_volume_km3 = ref_cs * ref_area_km2**1.375
    ref_thickness_m = ref_volume_km3 / ref_area_km2 * 1000.

    # Optimize
    def to_optimize(x):
        tmp_vols = np.zeros(len(ref_gdirs))
        fd = 1.9e-24 * x[0]
        fs = 5.7e-20 * x[1]
        for i, gdir in enumerate(ref_gdirs):
            v, _ = inversion_parabolic_point_slope(gdir, fs=fs, fd=fd)
            tmp_vols[i] = v * 1e-9
        return utils.rmsd(tmp_vols, ref_volume_km3)

    out = optimization.minimize(to_optimize, [1., 1.],
                                bounds=((0.01, 1), (0.01, 1)),
                                tol=1.e-3)

    # Check results and save.
    fd = 1.9e-24 * out['x'][0]
    fs = 5.7e-20 * out['x'][1]

    tmp_vols = np.zeros(len(ref_gdirs))
    for i, gdir in enumerate(ref_gdirs):
        v, _ = inversion_parabolic_point_slope(gdir, fs=fs, fd=fd)
        tmp_vols[i] = v * 1e-9

    d = dict()
    d['fs'] = fs
    d['fd'] = fd
    d['vol_rmsd'] = utils.rmsd(tmp_vols, ref_volume_km3)
    d['thick_rmsd'] = utils.rmsd(tmp_vols / ref_area_km2 / 1000.,
                                 ref_thickness_m)
    log.info('Optimized fs={fs} and fd={fd} for a volume RMSD of '
             '{vol_rmsd}'.format(**d))

    df = pd.DataFrame(d, index=[0])
    file = os.path.join(cfg.paths['working_dir'], 'inversion_params.csv')
    df.to_csv(file)

    return fs, fd
Beispiel #8
0
    def test_init_present_time_glacier(self):

        gdirs = up_to_inversion()

        # Inversion Results
        cfg.PARAMS['invert_with_sliding'] = True
        cfg.PARAMS['optimize_thick'] = True
        workflow.inversion_tasks(gdirs)

        fpath = os.path.join(cfg.PATHS['working_dir'],
                             'inversion_optim_results.csv')
        df = pd.read_csv(fpath, index_col=0)
        r1 = rmsd(df['ref_volume_km3'], df['oggm_volume_km3'])
        assert r1 < 0.1

        cfg.PARAMS['invert_with_sliding'] = False
        cfg.PARAMS['optimize_thick'] = False
        workflow.inversion_tasks(gdirs)

        fpath = os.path.join(cfg.PATHS['working_dir'],
                             'inversion_optim_results.csv')
        df = pd.read_csv(fpath, index_col=0)
        r1 = rmsd(df['ref_volume_km3'], df['oggm_volume_km3'])
        assert r1 < 0.12

        # Init glacier
        d = gdirs[0].read_pickle('inversion_params')
        fs = d['fs']
        glen_a = d['glen_a']
        for gdir in gdirs:
            flowline.init_present_time_glacier(gdir)
            mb_mod = massbalance.ConstantMassBalance(gdir)
            fls = gdir.read_pickle('model_flowlines')
            model = flowline.FluxBasedModel(fls, mb_model=mb_mod, y0=0.,
                                            fs=fs, glen_a=glen_a)
            _vol = model.volume_km3
            _area = model.area_km2
            if gdir.rgi_id in df.index:
                gldf = df.loc[gdir.rgi_id]
                assert_allclose(gldf['oggm_volume_km3'], _vol, rtol=0.05)
                assert_allclose(gldf['ref_area_km2'], _area, rtol=0.05)
                maxo = max([fl.order for fl in model.fls])
                for fl in model.fls:
                    if len(model.fls) > 1:
                        if fl.order == (maxo-1):
                            self.assertTrue(fl.flows_to is fls[-1])

        # Test the glacier charac
        dfc = utils.glacier_characteristics(gdirs)
        self.assertTrue(np.all(dfc.terminus_type == 'Land-terminating'))
        cc = dfc[['flowline_mean_elev',
                  'tstar_avg_temp_mean_elev']].corr().values[0, 1]
        assert cc < -0.8
        assert np.all(dfc.t_star > 1900)
        assert np.all(dfc.tstar_aar.mean() > 0.5)
Beispiel #9
0
    def test_init_present_time_glacier(self):

        gdirs = up_to_inversion()

        # Inversion Results
        cfg.PARAMS['invert_with_sliding'] = True
        cfg.PARAMS['optimize_thick'] = True
        workflow.inversion_tasks(gdirs)

        fpath = os.path.join(cfg.PATHS['working_dir'],
                             'inversion_optim_results.csv')
        df = pd.read_csv(fpath, index_col=0)
        r1 = rmsd(df['ref_volume_km3'], df['oggm_volume_km3'])
        r2 = rmsd(df['ref_volume_km3'], df['vas_volume_km3'])
        self.assertTrue(r1 < r2)

        cfg.PARAMS['invert_with_sliding'] = False
        cfg.PARAMS['optimize_thick'] = False
        workflow.inversion_tasks(gdirs)

        fpath = os.path.join(cfg.PATHS['working_dir'],
                             'inversion_optim_results.csv')
        df = pd.read_csv(fpath, index_col=0)
        r1 = rmsd(df['ref_volume_km3'], df['oggm_volume_km3'])
        r2 = rmsd(df['ref_volume_km3'], df['vas_volume_km3'])
        self.assertTrue(r1 < r2)

        # Init glacier
        d = gdirs[0].read_pickle('inversion_params')
        fs = d['fs']
        glen_a = d['glen_a']
        maxs = cfg.PARAMS['max_shape_param']
        for gdir in gdirs:
            flowline.init_present_time_glacier(gdir)
            mb_mod = massbalance.ConstantMassBalanceModel(gdir)
            fls = gdir.read_pickle('model_flowlines')
            model = flowline.FluxBasedModel(fls,
                                            mb_model=mb_mod,
                                            y0=0.,
                                            fs=fs,
                                            glen_a=glen_a)
            _vol = model.volume_km3
            _area = model.area_km2
            gldf = df.loc[gdir.rgi_id]
            assert_allclose(gldf['oggm_volume_km3'], _vol, rtol=0.03)
            assert_allclose(gldf['ref_area_km2'], _area, rtol=0.03)
            maxo = max([fl.order for fl in model.fls])
            for fl in model.fls:
                self.assertTrue(np.all(fl.bed_shape > 0))
                self.assertTrue(np.all(fl.bed_shape <= maxs))
                if len(model.fls) > 1:
                    if fl.order == (maxo - 1):
                        self.assertTrue(fl.flows_to is fls[-1])
Beispiel #10
0
    def test_tributary(self):

        models = [KarthausModel, FluxBasedModel]
        steps = [15 * SEC_IN_DAY, None]
        flss = [dummy_width_bed(), dummy_width_bed_tributary()]
        lens = []
        surface_h = []
        volume = []
        yrs = np.arange(1, 500, 2)
        for model, step, fls in zip(models, steps, flss):
            mb = LinearMassBalance(2600.)

            model = model(fls,
                          mb_model=mb,
                          fs=self.fs_old,
                          glen_a=self.aglen_old,
                          fixed_dt=step)

            length = yrs * 0.
            vol = yrs * 0.
            for i, y in enumerate(yrs):
                model.run_until(y)
                assert model.yr == y
                length[i] = fls[-1].length_m
                vol[i] = np.sum([f.volume_km3 for f in fls])
            lens.append(length)
            volume.append(vol)
            surface_h.append(fls[-1].surface_h.copy())

        np.testing.assert_allclose(lens[0][-1], lens[1][-1], atol=101)
        np.testing.assert_allclose(volume[0][-1], volume[1][-1], atol=2e-2)

        np.testing.assert_allclose(utils.rmsd(lens[0], lens[1]), 0., atol=70)
        np.testing.assert_allclose(utils.rmsd(volume[0], volume[1]),
                                   0.,
                                   atol=6e-3)
        np.testing.assert_allclose(utils.rmsd(surface_h[0], surface_h[1]),
                                   0.,
                                   atol=5)

        if do_plot:  # pragma: no cover
            plt.plot(lens[0], 'r')
            plt.plot(lens[1], 'b')
            plt.show()

            plt.plot(volume[0], 'r')
            plt.plot(volume[1], 'b')
            plt.show()

            plt.plot(fls[-1].bed_h, 'k')
            plt.plot(surface_h[0], 'r')
            plt.plot(surface_h[1], 'b')
            plt.show()
Beispiel #11
0
    def test_init_present_time_glacier(self):

        gdirs = up_to_inversion()

        # Inversion Results
        cfg.PARAMS['invert_with_sliding'] = True
        cfg.PARAMS['optimize_thick'] = True
        workflow.inversion_tasks(gdirs)

        fpath = os.path.join(cfg.PATHS['working_dir'],
                             'inversion_optim_results.csv')
        df = pd.read_csv(fpath, index_col=0)
        r1 = rmsd(df['ref_volume_km3'], df['oggm_volume_km3'])
        r2 = rmsd(df['ref_volume_km3'], df['vas_volume_km3'])
        self.assertTrue(r1 < r2)

        cfg.PARAMS['invert_with_sliding'] = False
        cfg.PARAMS['optimize_thick'] = False
        workflow.inversion_tasks(gdirs)

        fpath = os.path.join(cfg.PATHS['working_dir'],
                             'inversion_optim_results.csv')
        df = pd.read_csv(fpath, index_col=0)
        r1 = rmsd(df['ref_volume_km3'], df['oggm_volume_km3'])
        r2 = rmsd(df['ref_volume_km3'], df['vas_volume_km3'])
        self.assertTrue(r1 < r2)

        # Init glacier
        d = gdirs[0].read_pickle('inversion_params')
        fs = d['fs']
        glen_a = d['glen_a']
        maxs = cfg.PARAMS['max_shape_param']
        for gdir in gdirs:
            flowline.init_present_time_glacier(gdir)
            mb_mod = massbalance.TstarMassBalanceModel(gdir)
            fls = gdir.read_pickle('model_flowlines')
            model = flowline.FluxBasedModel(fls, mb_model=mb_mod, y0=0.,
                                            fs=fs, glen_a=glen_a)
            _vol = model.volume_km3
            _area = model.area_km2
            gldf = df.loc[gdir.rgi_id]
            assert_allclose(gldf['oggm_volume_km3'], _vol, rtol=0.03)
            assert_allclose(gldf['ref_area_km2'], _area, rtol=0.03)
            maxo = max([fl.order for fl in model.fls])
            for fl in model.fls:
                self.assertTrue(np.all(fl.bed_shape > 0))
                self.assertTrue(np.all(fl.bed_shape <= maxs))
                if len(model.fls) > 1:
                    if fl.order == (maxo-1):
                        self.assertTrue(fl.flows_to is fls[-1])
Beispiel #12
0
    def test_tributary(self):

        models = [KarthausModel, FluxBasedModel]
        steps = [15 * SEC_IN_DAY, None]
        flss = [dummy_width_bed(), dummy_width_bed_tributary()]
        lens = []
        surface_h = []
        volume = []
        yrs = np.arange(1, 500, 2)
        for model, step, fls in zip(models, steps, flss):
            mb = LinearMassBalance(2600.)

            model = model(fls, mb_model=mb, fs=self.fs_old,
                          glen_a=self.aglen_old,
                          fixed_dt=step)

            length = yrs * 0.
            vol = yrs * 0.
            for i, y in enumerate(yrs):
                model.run_until(y)
                length[i] = fls[-1].length_m
                vol[i] = np.sum([f.volume_km3 for f in fls])
            lens.append(length)
            volume.append(vol)
            surface_h.append(fls[-1].surface_h.copy())

        np.testing.assert_allclose(lens[0][-1], lens[1][-1], atol=101)
        np.testing.assert_allclose(volume[0][-1], volume[1][-1], atol=2e-2)

        np.testing.assert_allclose(utils.rmsd(lens[0], lens[1]), 0., atol=70)
        np.testing.assert_allclose(utils.rmsd(volume[0], volume[1]), 0.,
                                   atol=6e-3)
        np.testing.assert_allclose(utils.rmsd(surface_h[0], surface_h[1]), 0.,
                                   atol=5)

        if do_plot:  # pragma: no cover
            plt.plot(lens[0], 'r')
            plt.plot(lens[1], 'b')
            plt.show()

            plt.plot(volume[0], 'r')
            plt.plot(volume[1], 'b')
            plt.show()

            plt.plot(fls[-1].bed_h, 'k')
            plt.plot(surface_h[0], 'r')
            plt.plot(surface_h[1], 'b')
            plt.show()
Beispiel #13
0
 def to_optimize(x):
     tmp_ = np.zeros(len(ref_gdirs))
     glen_a = cfg.A * x[0]
     for i, gdir in enumerate(ref_gdirs):
         v, a = invert_parabolic_bed(gdir, glen_a=glen_a, fs=0.0, write=False)
         tmp_[i] = v / a
     return utils.rmsd(tmp_, ref_thickness_m)
Beispiel #14
0
def test_find_t0(self):

    from oggm.tests.funcs import init_hef
    from oggm.core import flowline
    import pandas as pd
    import matplotlib.pyplot as plt
    do_plot = True

    gdir = init_hef(border=80, invert_with_sliding=False)

    flowline.init_present_time_glacier(gdir)
    glacier = gdir.read_pickle('model_flowlines')
    df = pd.read_csv(utils.get_demo_file('hef_lengths.csv'), index_col=0)
    df.columns = ['Leclercq']
    df = df.loc[1950:]

    vol_ref = flowline.FlowlineModel(glacier).volume_km3

    init_bias = 94.  # so that "went too far" comes once on travis
    rtol = 0.005

    flowline.iterative_initial_glacier_search(gdir,
                                              y0=df.index[0],
                                              init_bias=init_bias,
                                              rtol=rtol,
                                              write_steps=True)

    past_model = flowline.FileModel(gdir.get_filepath('model_run'))

    vol_start = past_model.volume_km3
    bef_fls = copy.deepcopy(past_model.fls)

    mylen = past_model.length_m_ts()
    df['oggm'] = mylen[12::12].values
    df = df - df.iloc[-1]

    past_model.run_until(2003)

    vol_end = past_model.volume_km3
    np.testing.assert_allclose(vol_ref, vol_end, rtol=0.05)

    rmsd = utils.rmsd(df.Leclercq, df.oggm)
    self.assertTrue(rmsd < 1000.)

    if do_plot:  # pragma: no cover
        df.plot()
        plt.ylabel('Glacier length (relative to 2003)')
        plt.show()
        fig = plt.figure()
        lab = 'ref (vol={:.2f}km3)'.format(vol_ref)
        plt.plot(glacier[-1].surface_h, 'k', label=lab)
        lab = 'oggm start (vol={:.2f}km3)'.format(vol_start)
        plt.plot(bef_fls[-1].surface_h, 'b', label=lab)
        lab = 'oggm end (vol={:.2f}km3)'.format(vol_end)
        plt.plot(past_model.fls[-1].surface_h, 'r', label=lab)

        plt.plot(glacier[-1].bed_h, 'gray', linewidth=2)
        plt.legend(loc='best')
        plt.show()
Beispiel #15
0
 def to_optimize(x):
     tmp_vols = np.zeros(len(ref_gdirs))
     glen_a = cfg.A * x[0]
     for i, gdir in enumerate(ref_gdirs):
         v, _ = invert_parabolic_bed(gdir, glen_a=glen_a,
                                     fs=0., write=False)
         tmp_vols[i] = v * 1e-9
     return utils.rmsd(tmp_vols, ref_volume_km3)
Beispiel #16
0
 def to_optimize(x):
     tmp_ = np.zeros(len(ref_gdirs))
     glen_a = cfg.A * x[0]
     for i, gdir in enumerate(ref_gdirs):
         v, a = mass_conservation_inversion(gdir, glen_a=glen_a,
                                            fs=0., write=False)
         tmp_[i] = v / a
     return utils.rmsd(tmp_, ref_thickness_m)
Beispiel #17
0
 def to_optimize(x):
     tmp_vols = np.zeros(len(ref_gdirs))
     fd = 1.9e-24 * x[0]
     fs = 5.7e-20 * x[1]
     for i, gdir in enumerate(ref_gdirs):
         v, _ = inversion_parabolic_point_slope(gdir, fs=fs, fd=fd)
         tmp_vols[i] = v * 1e-9
     return utils.rmsd(tmp_vols, ref_volume_km3)
Beispiel #18
0
 def to_optimize(x):
     tmp_vols = np.zeros(len(ref_gdirs))
     glen_a = cfg.A * x[0]
     for i, gdir in enumerate(ref_gdirs):
         v, _ = invert_parabolic_bed(gdir, glen_a=glen_a,
                                     fs=0., write=False)
         tmp_vols[i] = v * 1e-9
     return utils.rmsd(tmp_vols, ref_volume_km3)
Beispiel #19
0
 def to_optimize(x):
     tmp_ = np.zeros(len(ref_gdirs))
     glen_a = cfg.A * x[0]
     for i, gdir in enumerate(ref_gdirs):
         v, a = invert_parabolic_bed(gdir, glen_a=glen_a,
                                     fs=0., write=False)
         tmp_[i] = v / a
     return utils.rmsd(tmp_, ref_thickness_m)
Beispiel #20
0
    def test_ideal_glacier(self):

        # we are making a
        glen_a = cfg.A * 1
        from oggm.core.models import flowline, massbalance

        gdir = utils.GlacierDirectory(self.rgin, base_dir=self.testdir)

        fls = self._parabolic_bed()
        mbmod = massbalance.ConstantBalanceModel(2800.)
        model = flowline.FluxBasedModel(fls, mb_model=mbmod, glen_a=glen_a)
        model.run_until_equilibrium()

        # from dummy bed
        map_dx = 100.
        towrite = []
        for fl in model.fls:
            # Distance between two points
            dx = fl.dx * map_dx
            # Widths
            widths = fl.widths * map_dx
            # Heights
            hgt = fl.surface_h
            # Flux
            mb = mbmod.get_mb(hgt) * cfg.SEC_IN_YEAR * cfg.RHO
            fl.flux = np.zeros(len(fl.surface_h))
            fl.set_apparent_mb(mb)
            flux = fl.flux * (map_dx**2) / cfg.SEC_IN_YEAR / cfg.RHO
            pok = np.nonzero(widths > 10.)
            widths = widths[pok]
            hgt = hgt[pok]
            flux = flux[pok]
            angle = np.arctan(-np.gradient(hgt, dx))  # beware the minus sign
            # Clip flux to 0
            assert not np.any(flux < -0.1)
            # add to output
            cl_dic = dict(dx=dx,
                          flux=flux,
                          width=widths,
                          hgt=hgt,
                          slope_angle=angle,
                          is_last=True)
            towrite.append(cl_dic)

        # Write out
        gdir.write_pickle(towrite, 'inversion_input', div_id=1)
        v, a = inversion.invert_parabolic_bed(gdir, glen_a=glen_a)
        v_km3 = v * 1e-9
        a_km2 = np.sum(widths * dx) * 1e-6
        v_vas = 0.034 * (a_km2**1.375)

        np.testing.assert_allclose(v, model.volume_m3, rtol=0.01)

        cl = gdir.read_pickle('inversion_output', div_id=1)[0]
        assert utils.rmsd(cl['thick'],
                          model.fls[0].thick[:len(cl['thick'])]) < 10.
Beispiel #21
0
 def to_optimize(x):
     tmp_ = np.zeros(len(ref_gdirs))
     glen_a = cfg.A * x[0]
     for i, gdir in enumerate(ref_gdirs):
         v, a = mass_conservation_inversion(gdir,
                                            glen_a=glen_a,
                                            fs=0.,
                                            write=False)
         tmp_[i] = v / a
     return utils.rmsd(tmp_, ref_thickness_m)
Beispiel #22
0
 def to_optimize(x):
     tmp_ref = np.zeros(len(ref_gdirs))
     glen_a = cfg.A * x[0]
     for i, gdir in enumerate(ref_gdirs):
         v, a = mass_conservation_inversion(gdir, glen_a=glen_a,
                                            fs=0., write=False)
         if optim_t:
             tmp_ref[i] = v / a
         else:
             tmp_ref[i] = v * 1e-9
     return utils.rmsd(tmp_ref, ref_data)
Beispiel #23
0
 def to_optimize(x):
     tmp_ref = np.zeros(len(ref_gdirs))
     glen_a = cfg.A * x[0]
     for i, gdir in enumerate(ref_gdirs):
         v, a = invert_parabolic_bed(gdir, glen_a=glen_a,
                                     fs=0., write=False)
         if optim_t:
             tmp_ref[i] = v / a
         else:
             tmp_ref[i] = v * 1e-9
     return utils.rmsd(tmp_ref, ref_data)
Beispiel #24
0
 def to_optimize(x):
     tmp_ref = np.zeros(len(ref_gdirs))
     glen_a = cfg.A * x[0]
     for i, gdir in enumerate(ref_gdirs):
         v, a = invert_parabolic_bed(gdir, glen_a=glen_a,
                                     fs=0., write=False)
         if optim_t:
             tmp_ref[i] = v / a
         else:
             tmp_ref[i] = v * 1e-9
     return utils.rmsd(tmp_ref, ref_data)
Beispiel #25
0
 def to_optimize(x):
     tmp_ref = np.zeros(len(ref_gdirs))
     glen_a = cfg.A * x[0]
     for i, gdir in enumerate(ref_gdirs):
         v, a = mass_conservation_inversion(gdir, glen_a=glen_a,
                                            fs=0., write=False)
         if optim_t:
             tmp_ref[i] = v / a
         else:
             tmp_ref[i] = v * 1e-9
     return utils.rmsd(tmp_ref, ref_data)
Beispiel #26
0
    def test_find_t0(self):

        gdir = init_hef(border=DOM_BORDER, invert_with_sliding=False)

        flowline.init_present_time_glacier(gdir)
        glacier = gdir.read_pickle('model_flowlines')
        df = pd.read_csv(utils.get_demo_file('hef_lengths.csv'), index_col=0)
        df.columns = ['Leclercq']
        df = df.loc[1950:]

        vol_ref = flowline.FlowlineModel(glacier).volume_km3

        init_bias = 100.  # 100 so that "went too far" comes once on travis
        rtol = 0.005

        flowline.find_inital_glacier(gdir,
                                     y0=df.index[0],
                                     init_bias=init_bias,
                                     rtol=rtol,
                                     write_steps=False)

        past_model = gdir.read_pickle('past_model')

        vol_start = past_model.volume_km3
        bef_fls = copy.deepcopy(past_model.fls)

        mylen = []
        for y in df.index:
            past_model.run_until(y)
            mylen.append(past_model.fls[-1].length_m)
        df['oggm'] = mylen
        df = df - df.iloc[-1]

        vol_end = past_model.volume_km3
        np.testing.assert_allclose(vol_ref, vol_end, rtol=0.05)

        rmsd = utils.rmsd(df.Leclercq, df.oggm)
        self.assertTrue(rmsd < 1000.)

        if do_plot:  # pragma: no cover
            df.plot()
            plt.ylabel('Glacier length (relative to 2003)')
            plt.show()
            fig = plt.figure()
            lab = 'ref (vol={:.2f}km3)'.format(vol_ref)
            plt.plot(glacier[-1].surface_h, 'k', label=lab)
            lab = 'oggm start (vol={:.2f}km3)'.format(vol_start)
            plt.plot(bef_fls[-1].surface_h, 'b', label=lab)
            lab = 'oggm end (vol={:.2f}km3)'.format(vol_end)
            plt.plot(past_model.fls[-1].surface_h, 'r', label=lab)

            plt.plot(glacier[-1].bed_h, 'gray', linewidth=2)
            plt.legend(loc='best')
            plt.show()
Beispiel #27
0
    def test_ideal_glacier(self):

        # we are making a
        glen_a = cfg.A * 1
        from oggm.core.models import flowline, massbalance

        gdir = utils.GlacierDirectory(self.rgin, base_dir=self.testdir)

        fls = self._parabolic_bed()
        mbmod = massbalance.ConstantBalanceModel(2800.)
        model = flowline.FluxBasedModel(fls, mb_model=mbmod, glen_a=glen_a)
        model.run_until_equilibrium()

        # from dummy bed
        map_dx = 100.
        towrite = []
        for fl in model.fls:
            # Distance between two points
            dx = fl.dx * map_dx
            # Widths
            widths = fl.widths * map_dx
            # Heights
            hgt = fl.surface_h
            # Flux
            mb = mbmod.get_mb(hgt) * cfg.SEC_IN_YEAR * cfg.RHO
            fl.flux = np.zeros(len(fl.surface_h))
            fl.set_apparent_mb(mb)
            flux = fl.flux * (map_dx**2) / cfg.SEC_IN_YEAR / cfg.RHO
            pok = np.nonzero(widths > 10.)
            widths = widths[pok]
            hgt = hgt[pok]
            flux = flux[pok]
            angle = np.arctan(-np.gradient(hgt, dx))  # beware the minus sign
            # Clip flux to 0
            assert not np.any(flux < -0.1)
            # add to output
            cl_dic = dict(dx=dx, flux=flux, width=widths, hgt=hgt,
                          slope_angle=angle, is_last=True)
            towrite.append(cl_dic)

        # Write out
        gdir.write_pickle(towrite, 'inversion_input', div_id=1)
        v, a = inversion.invert_parabolic_bed(gdir, glen_a=glen_a)
        v_km3 = v * 1e-9
        a_km2 = np.sum(widths * dx) * 1e-6
        v_vas = 0.034*(a_km2**1.375)

        np.testing.assert_allclose(v, model.volume_m3, rtol=0.01)

        cl = gdir.read_pickle('inversion_output', div_id=1)[0]
        assert utils.rmsd(cl['thick'], model.fls[0].thick[:len(cl['thick'])]) < 10.
Beispiel #28
0
    def test_find_t0(self):

        gdir = init_hef(border=DOM_BORDER, invert_with_sliding=False)

        flowline.init_present_time_glacier(gdir)
        glacier = gdir.read_pickle('model_flowlines')
        df = pd.read_csv(utils.get_demo_file('hef_lengths.csv'), index_col=0)
        df.columns = ['Leclercq']
        df = df.loc[1950:]

        vol_ref = flowline.FlowlineModel(glacier).volume_km3

        init_bias = 100.  # 100 so that "went too far" comes once on travis
        rtol = 0.005

        flowline.find_inital_glacier(gdir, y0=df.index[0], init_bias=init_bias,
                                     rtol=rtol, write_steps=False)

        past_model = gdir.read_pickle('past_model')

        vol_start = past_model.volume_km3
        bef_fls = copy.deepcopy(past_model.fls)

        mylen = []
        for y in df.index:
            past_model.run_until(y)
            mylen.append(past_model.fls[-1].length_m)
        df['oggm'] = mylen
        df = df-df.iloc[-1]

        vol_end = past_model.volume_km3
        np.testing.assert_allclose(vol_ref, vol_end, rtol=0.05)

        rmsd = utils.rmsd(df.Leclercq, df.oggm)
        self.assertTrue(rmsd < 1000.)

        if do_plot:  # pragma: no cover
            df.plot()
            plt.ylabel('Glacier length (relative to 2003)')
            plt.show()
            fig = plt.figure()
            lab = 'ref (vol={:.2f}km3)'.format(vol_ref)
            plt.plot(glacier[-1].surface_h, 'k', label=lab)
            lab = 'oggm start (vol={:.2f}km3)'.format(vol_start)
            plt.plot(bef_fls[-1].surface_h, 'b', label=lab)
            lab = 'oggm end (vol={:.2f}km3)'.format(vol_end)
            plt.plot(past_model.fls[-1].surface_h, 'r', label=lab)

            plt.plot(glacier[-1].bed_h, 'gray', linewidth=2)
            plt.legend(loc='best')
            plt.show()
Beispiel #29
0
    def test_width(self):

        hef_file = get_demo_file('Hintereisferner.shp')
        rgidf = gpd.GeoDataFrame.from_file(hef_file)

        # loop because for some reason indexing wont work
        for index, entity in rgidf.iterrows():
            gdir = oggm.GlacierDirectory(entity, base_dir=self.testdir)
            gis.define_glacier_region(gdir, entity=entity)
            gis.glacier_masks(gdir)
            centerlines.compute_centerlines(gdir)
            geometry.initialize_flowlines(gdir)
            geometry.catchment_area(gdir)
            geometry.catchment_width_geom(gdir)
            geometry.catchment_width_correction(gdir)

        area = 0.
        otherarea = 0.
        hgt = []
        harea = []
        for i in gdir.divide_ids:
            cls = gdir.read_pickle('inversion_flowlines', div_id=i)
            for cl in cls:
                harea.extend(list(cl.widths * cl.dx))
                hgt.extend(list(cl.surface_h))
                area += np.sum(cl.widths * cl.dx)
            nc = netCDF4.Dataset(gdir.get_filepath('gridded_data', div_id=i))
            otherarea += np.sum(nc.variables['glacier_mask'][:])
            nc.close()

        nc = netCDF4.Dataset(gdir.get_filepath('gridded_data', div_id=0))
        mask = nc.variables['glacier_mask'][:]
        topo = nc.variables['topo_smoothed'][:]
        nc.close()
        rhgt = topo[np.where(mask)][:]

        tdf = gpd.GeoDataFrame.from_file(gdir.get_filepath('outlines'))
        np.testing.assert_allclose(area, otherarea, rtol=0.1)
        area *= (gdir.grid.dx)**2
        otherarea *= (gdir.grid.dx)**2
        np.testing.assert_allclose(area * 10**-6,
                                   np.float(tdf['AREA']),
                                   rtol=1e-4)

        # Check for area distrib
        bins = np.arange(utils.nicenumber(np.min(hgt), 50, lower=True),
                         utils.nicenumber(np.max(hgt), 50) + 1, 50.)
        h1, b = np.histogram(hgt, weights=harea, density=True, bins=bins)
        h2, b = np.histogram(rhgt, density=True, bins=bins)
        self.assertTrue(utils.rmsd(h1 * 100 * 50, h2 * 100 * 50) < 1)
Beispiel #30
0
    def test_width(self):

        hef_file = get_demo_file('Hintereisferner.shp')
        rgidf = gpd.GeoDataFrame.from_file(hef_file)

        # loop because for some reason indexing wont work
        for index, entity in rgidf.iterrows():
            gdir = cfg.GlacierDir(entity, base_dir=self.testdir)
            gis.define_glacier_region(gdir, entity)
            gis.glacier_masks(gdir)
            centerlines.compute_centerlines(gdir)
            geometry.initialize_flowlines(gdir)
            geometry.catchment_area(gdir)
            geometry.catchment_width_geom(gdir)
            geometry.catchment_width_correction(gdir)

        area = 0.
        otherarea = 0.
        hgt = []
        harea = []
        for i in gdir.divide_ids:
            cls = gdir.read_pickle('inversion_flowlines', div_id=i)
            for cl in cls:
                harea.extend(list(cl.widths * cl.dx))
                hgt.extend(list(cl.surface_h))
                area += np.sum(cl.widths * cl.dx)
            nc = netCDF4.Dataset(gdir.get_filepath('grids', div_id=i))
            otherarea += np.sum(nc.variables['glacier_mask'][:])
            nc.close()

        nc = netCDF4.Dataset(gdir.get_filepath('grids', div_id=0))
        mask = nc.variables['glacier_mask'][:]
        topo = nc.variables['topo_smoothed'][:]
        nc.close()
        rhgt = topo[np.where(mask)][:]

        tdf = gpd.GeoDataFrame.from_file(gdir.get_filepath('outlines'))
        np.testing.assert_allclose(area, otherarea, rtol=0.1)
        area *= (gdir.grid.dx) ** 2
        otherarea *= (gdir.grid.dx) ** 2
        np.testing.assert_allclose(area * 10**-6, np.float(tdf['AREA']), rtol=1e-4)

        # Check for area distrib
        bins = np.arange(utils.nicenumber(np.min(hgt), 50, lower=True),
                         utils.nicenumber(np.max(hgt), 50)+1,
                         50.)
        h1, b = np.histogram(hgt, weights=harea, density=True, bins=bins)
        h2, b = np.histogram(rhgt, density=True, bins=bins)
        self.assertTrue(utils.rmsd(h1*100*50, h2*100*50) < 1)
Beispiel #31
0
    def test_width(self):

        hef_file = get_demo_file("Hintereisferner.shp")
        entity = gpd.GeoDataFrame.from_file(hef_file).iloc[0]

        gdir = oggm.GlacierDirectory(entity, base_dir=self.testdir)
        gis.define_glacier_region(gdir, entity=entity)
        gis.glacier_masks(gdir)
        centerlines.compute_centerlines(gdir)
        geometry.initialize_flowlines(gdir)
        geometry.catchment_area(gdir)
        geometry.catchment_width_geom(gdir)
        geometry.catchment_width_correction(gdir)

        area = 0.0
        otherarea = 0.0
        hgt = []
        harea = []
        for i in gdir.divide_ids:
            cls = gdir.read_pickle("inversion_flowlines", div_id=i)
            for cl in cls:
                harea.extend(list(cl.widths * cl.dx))
                hgt.extend(list(cl.surface_h))
                area += np.sum(cl.widths * cl.dx)
            with netCDF4.Dataset(gdir.get_filepath("gridded_data", div_id=i)) as nc:
                otherarea += np.sum(nc.variables["glacier_mask"][:])

        with netCDF4.Dataset(gdir.get_filepath("gridded_data", div_id=0)) as nc:
            mask = nc.variables["glacier_mask"][:]
            topo = nc.variables["topo_smoothed"][:]
        rhgt = topo[np.where(mask)][:]

        tdf = gpd.GeoDataFrame.from_file(gdir.get_filepath("outlines"))
        np.testing.assert_allclose(area, otherarea, rtol=0.1)
        area *= (gdir.grid.dx) ** 2
        otherarea *= (gdir.grid.dx) ** 2
        np.testing.assert_allclose(area * 10 ** -6, np.float(tdf["AREA"]), rtol=1e-4)

        # Check for area distrib
        bins = np.arange(utils.nicenumber(np.min(hgt), 50, lower=True), utils.nicenumber(np.max(hgt), 50) + 1, 50.0)
        h1, b = np.histogram(hgt, weights=harea, density=True, bins=bins)
        h2, b = np.histogram(rhgt, density=True, bins=bins)
        self.assertTrue(utils.rmsd(h1 * 100 * 50, h2 * 100 * 50) < 1)
Beispiel #32
0
    def test_noisy_bed(self):

        models = [
            flowline.KarthausModel, flowline.FluxBasedModel,
            flowline.MUSCLSuperBeeModel
        ]
        steps = [15 * SEC_IN_DAY, None, None]
        lens = []
        surface_h = []
        volume = []
        yrs = np.arange(1, 500, 2)
        fls_orig = dummy_noisy_bed()
        for model, step in zip(models, steps):
            fls = copy.deepcopy(fls_orig)
            mb = ConstantBalanceModel(2600.)

            model = model(fls, mb_model=mb, glen_a=self.glen_a, fixed_dt=step)

            length = yrs * 0.
            vol = yrs * 0.
            for i, y in enumerate(yrs):
                model.run_until(y)
                length[i] = fls[-1].length_m
                vol[i] = fls[-1].volume_km3
            lens.append(length)
            volume.append(vol)
            surface_h.append(fls[-1].surface_h.copy())

        if do_plot:  # pragma: no cover
            plt.figure()
            plt.plot(yrs, lens[0], 'r')
            plt.plot(yrs, lens[1], 'b')
            plt.plot(yrs, lens[2], 'g')
            plt.title('Compare Length')
            plt.xlabel('years')
            plt.ylabel('[m]')
            plt.legend(['Karthaus', 'Flux', 'MUSCL-SuperBee'], loc=2)

            plt.figure()
            plt.plot(yrs, volume[0], 'r')
            plt.plot(yrs, volume[1], 'b')
            plt.plot(yrs, volume[2], 'g')
            plt.title('Compare Volume')
            plt.xlabel('years')
            plt.ylabel('[km^3]')
            plt.legend(['Karthaus', 'Flux', 'MUSCL-SuperBee'], loc=2)

            plt.figure()
            plt.plot(fls[-1].bed_h, 'k')
            plt.plot(surface_h[0], 'r')
            plt.plot(surface_h[1], 'b')
            plt.plot(surface_h[2], 'g')
            plt.title('Compare Shape')
            plt.xlabel('[m]')
            plt.ylabel('Elevation [m]')
            plt.legend(['Bed', 'Karthaus', 'Flux', 'MUSCL-SuperBee'], loc=3)
            plt.show()

        np.testing.assert_allclose(lens[0][-1], lens[1][-1], atol=101)
        np.testing.assert_allclose(volume[0][-1], volume[1][-1], atol=1e-2)
        np.testing.assert_allclose(volume[0][-1], volume[2][-1], atol=1e-2)

        self.assertTrue(utils.rmsd(lens[0], lens[1]) < 100.)
        self.assertTrue(utils.rmsd(volume[0], volume[1]) < 1e-1)
        self.assertTrue(utils.rmsd(volume[0], volume[2]) < 1e-1)
        self.assertTrue(utils.rmsd(surface_h[0], surface_h[1]) < 10)
        self.assertTrue(utils.rmsd(surface_h[0], surface_h[2]) < 10)
Beispiel #33
0
    def test_varying_width(self):
        """This test is for a flowline glacier of variying width, i.e with an
         accumulation area twice as wide as the tongue."""

        # TODO: @alexjarosch here we should have a look at MUSCLSuperBeeModel
        # set do_plot = True to see the plots

        models = [
            flowline.KarthausModel, flowline.FluxBasedModel,
            flowline.MUSCLSuperBeeModel
        ]
        steps = [15 * SEC_IN_DAY, None, None]
        lens = []
        surface_h = []
        volume = []
        yrs = np.arange(1, 500, 2)
        for model, step in zip(models, steps):
            fls = dummy_width_bed()
            mb = ConstantBalanceModel(2600.)

            model = model(fls, mb_model=mb, glen_a=self.glen_a, fixed_dt=step)

            length = yrs * 0.
            vol = yrs * 0.
            for i, y in enumerate(yrs):
                model.run_until(y)
                length[i] = fls[-1].length_m
                vol[i] = fls[-1].volume_km3
            lens.append(length)
            volume.append(vol)
            surface_h.append(fls[-1].surface_h.copy())

        if do_plot:  # pragma: no cover
            plt.figure()
            plt.plot(yrs, lens[0], 'r')
            plt.plot(yrs, lens[1], 'b')
            plt.plot(yrs, lens[2], 'g')
            plt.title('Compare Length')
            plt.xlabel('years')
            plt.ylabel('[m]')
            plt.legend(['Karthaus', 'Flux', 'MUSCL-SuperBee'], loc=2)

            plt.figure()
            plt.plot(yrs, volume[0], 'r')
            plt.plot(yrs, volume[1], 'b')
            plt.plot(yrs, volume[2], 'g')
            plt.title('Compare Volume')
            plt.xlabel('years')
            plt.ylabel('[km^3]')
            plt.legend(['Karthaus', 'Flux', 'MUSCL-SuperBee'], loc=2)

            plt.figure()
            plt.plot(fls[-1].bed_h, 'k')
            plt.plot(surface_h[0], 'r')
            plt.plot(surface_h[1], 'b')
            plt.plot(surface_h[2], 'g')
            plt.title('Compare Shape')
            plt.xlabel('[m]')
            plt.ylabel('Elevation [m]')
            plt.legend(['Bed', 'Karthaus', 'Flux', 'MUSCL-SuperBee'], loc=3)
            plt.show()

        np.testing.assert_almost_equal(lens[0][-1], lens[1][-1])
        np.testing.assert_allclose(volume[0][-1], volume[1][-1], atol=1e-2)

        np.testing.assert_allclose(utils.rmsd(lens[0], lens[1]), 0., atol=50)
        np.testing.assert_allclose(utils.rmsd(volume[0], volume[1]),
                                   0.,
                                   atol=3e-3)
        np.testing.assert_allclose(utils.rmsd(surface_h[0], surface_h[1]),
                                   0.,
                                   atol=5)
Beispiel #34
0
    def test_constant_bed(self):

        map_dx = 100.
        yrs = np.arange(1, 200, 5)
        lens = []
        volume = []
        areas = []
        surface_h = []

        # Flowline case
        fls = dummy_constant_bed(hmax=3000., hmin=1000., nx=200, map_dx=map_dx,
                                 widths=1.)
        mb = LinearMassBalance(2600.)

        flmodel = FluxBasedModel(fls, mb_model=mb, y0=0.)

        length = yrs * 0.
        vol = yrs * 0.
        area = yrs * 0
        for i, y in enumerate(yrs):
            flmodel.run_until(y)
            assert flmodel.yr == y
            length[i] = fls[-1].length_m
            vol[i] = fls[-1].volume_km3
            area[i] = fls[-1].area_km2

        lens.append(length)
        volume.append(vol)
        areas.append(area)
        surface_h.append(fls[-1].surface_h.copy())

        # Make a 2D bed out of the 1D
        bed_2d = np.repeat(fls[-1].bed_h, 3).reshape((fls[-1].nx, 3))

        sdmodel = Upstream2D(bed_2d, dx=map_dx, mb_model=mb, y0=0.,
                             ice_thick_filter=None)

        length = yrs * 0.
        vol = yrs * 0.
        area = yrs * 0
        for i, y in enumerate(yrs):
            sdmodel.run_until(y)
            assert sdmodel.yr == y
            surf_1d = sdmodel.ice_thick[:, 1]
            length[i] = np.sum(surf_1d > 0) * sdmodel.dx
            vol[i] = sdmodel.volume_km3 / 3
            area[i] = sdmodel.area_km2 / 3

        lens.append(length)
        volume.append(vol)
        areas.append(area)
        surface_h.append(sdmodel.surface_h[:, 1])

        assert_allclose(lens[0][-1], lens[1][-1], atol=101)
        assert_allclose(volume[0][-1], volume[1][-1], atol=3e-3)

        assert rmsd(lens[0], lens[1]) < 50.
        assert rmsd(volume[0], volume[1]) < 2e-3
        assert rmsd(areas[0], areas[1]) < 2e-3
        assert rmsd(surface_h[0], surface_h[1]) < 1.0

        # Store
        run_ds = sdmodel.run_until_and_store(sdmodel.yr+50)
        assert 'ice_thickness' in run_ds

        # Other direction
        bed_2d = np.repeat(fls[-1].bed_h, 3).reshape((fls[-1].nx, 3)).T

        sdmodel = Upstream2D(bed_2d, dx=map_dx, mb_model=mb, y0=0.,
                             ice_thick_filter=None)

        length = yrs * 0.
        vol = yrs * 0.
        area = yrs * 0
        for i, y in enumerate(yrs):
            sdmodel.run_until(y)
            assert sdmodel.yr == y
            surf_1d = sdmodel.ice_thick[1, :]
            length[i] = np.sum(surf_1d > 0) * sdmodel.dx
            vol[i] = sdmodel.volume_km3 / 3
            area[i] = sdmodel.area_km2 / 3

        lens.append(length)
        volume.append(vol)
        areas.append(area)
        surface_h.append(sdmodel.surface_h[:, 1])

        assert_allclose(lens[0][-1], lens[1][-1], atol=101)
        assert_allclose(volume[0][-1], volume[1][-1], atol=3e-3)

        assert rmsd(lens[0], lens[1]) < 50.
        assert rmsd(volume[0], volume[1]) < 2e-3
        assert rmsd(areas[0], areas[1]) < 2e-3
        assert rmsd(surface_h[0], surface_h[1]) < 1.0
Beispiel #35
0
    def test_first_shot(self):

        df = up_to_inversion()
        self.assertTrue(rmsd(df['ref_vol'], df['oggm_vol']) < rmsd(df['ref_vol'], df['vas_vol']))
Beispiel #36
0
    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)
Beispiel #37
0
def optimize_inversion_params(gdirs):
    """Optimizes fs and fd based on GlaThiDa thicknesses.

    We use the glacier averaged thicknesses provided by GlaThiDa and correct
    them for differences in area with RGI, using a glacier specific volume-area
    scaling formula.

    Parameters
    ----------
    gdirs: list of oggm.GlacierDirectory objects
    """

    # Do we even need to do this?
    if not cfg.PARAMS['optimize_inversion_params']:
        log.info('User did not want to optimize the inversion params')
        return

    # Get test glaciers (all glaciers with thickness data)
    fpath = utils.get_glathida_file()
    try:
        gtd_df = pd.read_csv(fpath).sort_values(by=['RGI_ID'])
    except AttributeError:
        gtd_df = pd.read_csv(fpath).sort(columns=['RGI_ID'])
    dfids = gtd_df['RGI_ID'].values

    ref_gdirs = [gdir for gdir in gdirs if gdir.rgi_id in dfids]
    ref_rgiids = [gdir.rgi_id for gdir in ref_gdirs]
    gtd_df = gtd_df.set_index('RGI_ID').loc[ref_rgiids]

    # Account for area differences between glathida and rgi
    gtd_df['RGI_AREA'] = [gdir.rgi_area_km2 for gdir in ref_gdirs]
    ref_area_km2 = gtd_df.RGI_AREA.values
    gtd_df.VOLUME = gtd_df.MEAN_THICKNESS * gtd_df.GTD_AREA * 1e-3
    ref_cs = gtd_df.VOLUME.values / (gtd_df.GTD_AREA.values**1.375)
    ref_volume_km3 = ref_cs * ref_area_km2**1.375
    ref_thickness_m = ref_volume_km3 / ref_area_km2 * 1000.

    # Minimize volume or thick RMSD?
    optim_t = cfg.PARAMS['optimize_thick']
    if optim_t:
        ref_data = ref_thickness_m
        tol = 0.1
    else:
        ref_data = ref_volume_km3
        tol = 1.e-4

    if cfg.PARAMS['invert_with_sliding']:
        # Optimize with both params
        log.info('Compute the inversion parameters.')

        def to_optimize(x):
            tmp_ref = np.zeros(len(ref_gdirs))
            glen_a = cfg.A * x[0]
            fs = cfg.FS * x[1]
            for i, gdir in enumerate(ref_gdirs):
                v, a = invert_parabolic_bed(gdir, glen_a=glen_a,
                                            fs=fs, write=False)
                if optim_t:
                    tmp_ref[i] = v / a
                else:
                    tmp_ref[i] = v * 1e-9
            return utils.rmsd(tmp_ref, ref_data)

        opti = optimization.minimize(to_optimize, [1., 1.],
                                    bounds=((0.01, 10), (0.01, 10)),
                                    tol=tol)
        # Check results and save.
        glen_a = cfg.A * opti['x'][0]
        fs = cfg.FS * opti['x'][1]
    else:
        # Optimize without sliding
        log.info('Compute the inversion parameter.')

        def to_optimize(x):
            tmp_ref = np.zeros(len(ref_gdirs))
            glen_a = cfg.A * x[0]
            for i, gdir in enumerate(ref_gdirs):
                v, a = invert_parabolic_bed(gdir, glen_a=glen_a,
                                            fs=0., write=False)
                if optim_t:
                    tmp_ref[i] = v / a
                else:
                    tmp_ref[i] = v * 1e-9
            return utils.rmsd(tmp_ref, ref_data)
        opti = optimization.minimize(to_optimize, [1.],
                                    bounds=((0.01, 10), ),
                                    tol=tol)
        # Check results and save.
        glen_a = cfg.A * opti['x'][0]
        fs = 0.

    # This is for the stats
    oggm_volume_m3 = np.zeros(len(ref_gdirs))
    rgi_area_m2 = np.zeros(len(ref_gdirs))
    for i, gdir in enumerate(ref_gdirs):
        v, a = invert_parabolic_bed(gdir, glen_a=glen_a, fs=fs,
                                    write=False)
        oggm_volume_m3[i] = v
        rgi_area_m2[i] = a
    assert np.allclose(rgi_area_m2 * 1e-6, ref_area_km2)

    # This is for each glacier
    out = dict()
    out['glen_a'] = glen_a
    out['fs'] = fs
    out['factor_glen_a'] = opti['x'][0]
    try:
        out['factor_fs'] = opti['x'][1]
    except IndexError:
        out['factor_fs'] = 0.
    for gdir in gdirs:
        gdir.write_pickle(out, 'inversion_params')

    # This is for the working dir
    # Simple stats
    out['vol_rmsd'] = utils.rmsd(oggm_volume_m3 * 1e-9, ref_volume_km3)
    out['thick_rmsd'] = utils.rmsd(oggm_volume_m3 * 1e-9 / ref_area_km2 / 1000,
                                   ref_thickness_m)

    log.info('Optimized glen_a and fs with a factor {factor_glen_a:.2f} and '
             '{factor_fs:.2f} for a thick RMSD of '
             '{thick_rmsd:.1f} and a volume RMSD of '
             '{vol_rmsd:.3f}'.format(**out))

    df = pd.DataFrame(out, index=[0])
    fpath = os.path.join(cfg.PATHS['working_dir'],
                         'inversion_optim_params.csv')
    df.to_csv(fpath)

    # All results
    df = dict()
    df['ref_area_km2'] = ref_area_km2
    df['ref_volume_km3'] = ref_volume_km3
    df['oggm_volume_km3'] = oggm_volume_m3 * 1e-9
    df['vas_volume_km3'] = 0.034*(df['ref_area_km2']**1.375)

    rgi_id = [gdir.rgi_id for gdir in ref_gdirs]
    df = pd.DataFrame(df, index=rgi_id)
    fpath = os.path.join(cfg.PATHS['working_dir'],
                         'inversion_optim_results.csv')
    df.to_csv(fpath)

    # return value for tests
    return out
Beispiel #38
0
print('Area % coverage where we find a k value with racmo data',
      area_with_cal_result_racmo / study_area * 100)

#Uncomment for paper information
# ids_negative = df_racmo_negative.RGIId.values
# keep_ids_negative = [(i in ids_negative) for i in rgidf.RGIId]
# rgidf_racmo_negative = rgidf.iloc[keep_ids_negative]
#
# area_racmo_negative = rgidf_racmo_negative.Area.sum()
#
# print('Area % coverage where racmo data is negative',
#       area_racmo_negative/ study_area * 100)
#
# negative_percet = np.round(area_racmo_negative/ study_area * 100)

RMSD = utils.rmsd(df_vel_result.u_obs, df_vel_result.u_surf)
print('RMSD between observations and oggm', RMSD)
mean_dev = utils.md(df_vel_result.u_obs, df_vel_result.u_surf)
print('mean difference between observations and oggm', mean_dev)

slope, intercept, r_value, p_value, std_err = stats.linregress(
    df_vel_result.u_obs, df_vel_result.u_surf)

Num = area_with_cal_result / study_area * 100

print('N = ', Num)
print('bo = ', slope)
print(intercept)
print(r_value)
print(p_value)
print(mean_dev)
Beispiel #39
0
    def test_varying_width(self):
        """This test is for a flowline glacier of variying width, i.e with an
         accumulation area twice as wide as the tongue."""

        # TODO: @alexjarosch here we should have a look at MUSCLSuperBeeModel
        # set do_plot = True to see the plots

        models = [KarthausModel, FluxBasedModel, MUSCLSuperBeeModel]
        steps = [15 * SEC_IN_DAY, None, None]
        lens = []
        surface_h = []
        volume = []
        yrs = np.arange(1, 500, 2)
        for model, step in zip(models, steps):
            fls = dummy_width_bed()
            mb = LinearMassBalance(2600.)

            model = model(fls, mb_model=mb, glen_a=self.glen_a, fixed_dt=step)

            length = yrs * 0.
            vol = yrs * 0.
            for i, y in enumerate(yrs):
                model.run_until(y)
                length[i] = fls[-1].length_m
                vol[i] = fls[-1].volume_km3
            lens.append(length)
            volume.append(vol)
            surface_h.append(fls[-1].surface_h.copy())

        if do_plot:  # pragma: no cover
            plt.figure()
            plt.plot(yrs, lens[0], 'r')
            plt.plot(yrs, lens[1], 'b')
            plt.plot(yrs, lens[2], 'g')
            plt.title('Compare Length')
            plt.xlabel('years')
            plt.ylabel('[m]')
            plt.legend(['Karthaus', 'Flux', 'MUSCL-SuperBee'], loc=2)

            plt.figure()
            plt.plot(yrs, volume[0], 'r')
            plt.plot(yrs, volume[1], 'b')
            plt.plot(yrs, volume[2], 'g')
            plt.title('Compare Volume')
            plt.xlabel('years')
            plt.ylabel('[km^3]')
            plt.legend(['Karthaus', 'Flux', 'MUSCL-SuperBee'], loc=2)

            plt.figure()
            plt.plot(fls[-1].bed_h, 'k')
            plt.plot(surface_h[0], 'r')
            plt.plot(surface_h[1], 'b')
            plt.plot(surface_h[2], 'g')
            plt.title('Compare Shape')
            plt.xlabel('[m]')
            plt.ylabel('Elevation [m]')
            plt.legend(['Bed', 'Karthaus', 'Flux', 'MUSCL-SuperBee'], loc=3)
            plt.show()

        np.testing.assert_almost_equal(lens[0][-1], lens[1][-1])
        np.testing.assert_allclose(volume[0][-1], volume[1][-1], atol=2e-2)

        np.testing.assert_allclose(utils.rmsd(lens[0], lens[1]), 0., atol=70)
        np.testing.assert_allclose(utils.rmsd(volume[0], volume[1]), 0.,
                                   atol=1e-2)
        np.testing.assert_allclose(utils.rmsd(surface_h[0], surface_h[1]), 0.,
                                   atol=5)
Beispiel #40
0
    def test_min_slope(self):
        """ Check what is the min slope a flowline model can produce
        """

        models = [KarthausModel, FluxBasedModel, MUSCLSuperBeeModel]
        kwargs = [{'fixed_dt': 3 * SEC_IN_DAY}, {}, {}]
        lens = []
        surface_h = []
        volume = []
        min_slope = []
        yrs = np.arange(1, 700, 2)
        for model, kw in zip(models, kwargs):
            fls = dummy_constant_bed_obstacle()
            mb = LinearMassBalance(2600.)

            model = model(fls, mb_model=mb, y0=0., glen_a=self.glen_a, **kw)

            length = yrs * 0.
            vol = yrs * 0.
            slope = yrs * 0.
            for i, y in enumerate(yrs):
                model.run_until(y)
                fl = fls[-1]
                length[i] = fl.length_m
                vol[i] = fl.volume_km3

                hgt = np.where(fl.thick > 0, fl.surface_h, np.NaN)
                sl = np.arctan(-np.gradient(hgt, fl.dx_meter))
                slope[i] = np.rad2deg(np.nanmin(sl))

            lens.append(length)
            volume.append(vol)
            min_slope.append(slope)
            surface_h.append(fls[-1].surface_h.copy())

        np.testing.assert_allclose(lens[0][-1], lens[1][-1], atol=101)
        np.testing.assert_allclose(volume[0][-1], volume[2][-1], atol=2e-3)
        np.testing.assert_allclose(volume[1][-1], volume[2][-1], atol=5e-3)

        self.assertTrue(utils.rmsd(volume[0], volume[2]) < 1e-2)
        self.assertTrue(utils.rmsd(volume[1], volume[2]) < 1e-2)

        if do_plot:  # pragma: no cover
            plt.figure()
            plt.plot(yrs, lens[0], 'r')
            plt.plot(yrs, lens[1], 'b')
            plt.plot(yrs, lens[2], 'g')
            plt.title('Compare Length')
            plt.xlabel('years')
            plt.ylabel('[m]')
            plt.legend(['Karthaus', 'Flux', 'MUSCL-SuperBee'], loc=2)

            plt.figure()
            plt.plot(yrs, volume[0], 'r')
            plt.plot(yrs, volume[1], 'b')
            plt.plot(yrs, volume[2], 'g')
            plt.title('Compare Volume')
            plt.xlabel('years')
            plt.ylabel('[km^3]')
            plt.legend(['Karthaus', 'Flux', 'MUSCL-SuperBee'], loc=2)

            plt.figure()
            plt.plot(yrs, min_slope[0], 'r')
            plt.plot(yrs, min_slope[1], 'b')
            plt.plot(yrs, min_slope[2], 'g')
            plt.title('Compare min slope')
            plt.xlabel('years')
            plt.ylabel('[degrees]')
            plt.legend(['Karthaus', 'Flux', 'MUSCL-SuperBee'], loc=2)

            plt.figure()
            plt.plot(fls[-1].bed_h, 'k')
            plt.plot(surface_h[0], 'r')
            plt.plot(surface_h[1], 'b')
            plt.plot(surface_h[2], 'g')
            plt.title('Compare Shape')
            plt.xlabel('[m]')
            plt.ylabel('Elevation [m]')
            plt.legend(['Bed', 'Karthaus', 'Flux', 'MUSCL-SuperBee'], loc=3)
            plt.show()
Beispiel #41
0
    def test_constant_bed(self):

        map_dx = 100.
        yrs = np.arange(1, 400, 5)
        lens = []
        volume = []
        areas = []
        surface_h = []

        # Flowline case
        fls = dummy_constant_bed(hmax=3000.,
                                 hmin=1000.,
                                 nx=200,
                                 map_dx=map_dx,
                                 widths=1.)
        mb = LinearMassBalance(2600.)

        flmodel = FluxBasedModel(fls, mb_model=mb, y0=0.)

        length = yrs * 0.
        vol = yrs * 0.
        area = yrs * 0
        for i, y in enumerate(yrs):
            flmodel.run_until(y)
            length[i] = fls[-1].length_m
            vol[i] = fls[-1].volume_km3
            area[i] = fls[-1].area_km2

        lens.append(length)
        volume.append(vol)
        areas.append(area)
        surface_h.append(fls[-1].surface_h.copy())

        # Make a 2D bed out of the 1D
        bed_2d = np.repeat(fls[-1].bed_h, 3).reshape((fls[-1].nx, 3))

        sdmodel = Upstream2D(bed_2d,
                             dx=map_dx,
                             mb_model=mb,
                             y0=0.,
                             ice_thick_filter=None)

        length = yrs * 0.
        vol = yrs * 0.
        area = yrs * 0
        for i, y in enumerate(yrs):
            sdmodel.run_until(y)
            surf_1d = sdmodel.ice_thick[:, 1]
            length[i] = np.sum(surf_1d > 0) * sdmodel.dx
            vol[i] = sdmodel.volume_km3 / 3
            area[i] = sdmodel.area_km2 / 3

        lens.append(length)
        volume.append(vol)
        areas.append(area)
        surface_h.append(sdmodel.surface_h[:, 1])

        if do_plot:
            plt.figure()
            plt.plot(yrs, lens[0], 'r')
            plt.plot(yrs, lens[1], 'b')
            plt.title('Compare Length')
            plt.xlabel('years')
            plt.ylabel('[m]')
            plt.legend(['Flowline', '2D'], loc=2)

            plt.figure()
            plt.plot(yrs, volume[0], 'r')
            plt.plot(yrs, volume[1], 'b')
            plt.title('Compare Volume')
            plt.xlabel('years')
            plt.ylabel('[km^3]')
            plt.legend(['Flowline', '2D'], loc=2)

            plt.figure()
            plt.plot(fls[-1].bed_h, 'k')
            plt.plot(surface_h[0], 'r')
            plt.plot(surface_h[1], 'b')
            plt.title('Compare Shape')
            plt.xlabel('[m]')
            plt.ylabel('Elevation [m]')
            plt.legend(['Bed', 'Flowline', '2D'], loc=2)
            plt.show()

        np.testing.assert_almost_equal(lens[0][-1], lens[1][-1])
        np.testing.assert_allclose(volume[0][-1], volume[1][-1], atol=3e-3)

        self.assertTrue(utils.rmsd(lens[0], lens[1]) < 50.)
        self.assertTrue(utils.rmsd(volume[0], volume[1]) < 2e-3)
        self.assertTrue(utils.rmsd(areas[0], areas[1]) < 2e-3)
        self.assertTrue(utils.rmsd(surface_h[0], surface_h[1]) < 1.0)

        # Equilibrium
        sdmodel.run_until_equilibrium()
        flmodel.run_until_equilibrium()
        assert_allclose(sdmodel.volume_km3 / 3, flmodel.volume_km3, atol=2e-3)
        assert_allclose(sdmodel.area_km2 / 3, flmodel.area_km2, atol=2e-3)

        # Store
        run_ds = sdmodel.run_until_and_store(sdmodel.yr + 50)
        ts = run_ds['ice_thickness'].mean(dim=['y', 'x'])
        assert_allclose(ts, ts.values[0], atol=1)

        # Other direction
        bed_2d = np.repeat(fls[-1].bed_h, 3).reshape((fls[-1].nx, 3)).T

        sdmodel = Upstream2D(bed_2d,
                             dx=map_dx,
                             mb_model=mb,
                             y0=0.,
                             ice_thick_filter=None)

        length = yrs * 0.
        vol = yrs * 0.
        area = yrs * 0
        for i, y in enumerate(yrs):
            sdmodel.run_until(y)
            surf_1d = sdmodel.ice_thick[1, :]
            length[i] = np.sum(surf_1d > 0) * sdmodel.dx
            vol[i] = sdmodel.volume_km3 / 3
            area[i] = sdmodel.area_km2 / 3

        lens.append(length)
        volume.append(vol)
        areas.append(area)
        surface_h.append(sdmodel.surface_h[:, 1])

        np.testing.assert_almost_equal(lens[0][-1], lens[1][-1])
        np.testing.assert_allclose(volume[0][-1], volume[1][-1], atol=3e-3)

        self.assertTrue(utils.rmsd(lens[0], lens[1]) < 50.)
        self.assertTrue(utils.rmsd(volume[0], volume[1]) < 2e-3)
        self.assertTrue(utils.rmsd(areas[0], areas[1]) < 2e-3)
        self.assertTrue(utils.rmsd(surface_h[0], surface_h[1]) < 1.0)

        # Equilibrium
        sdmodel.run_until_equilibrium()
        assert_allclose(sdmodel.volume_km3 / 3, flmodel.volume_km3, atol=2e-3)
        assert_allclose(sdmodel.area_km2 / 3, flmodel.area_km2, atol=2e-3)
Beispiel #42
0
 def to_optimize(x):
     glen_a = cfg.A * x[0]
     v, a = invert_parabolic_bed(gdir, glen_a=glen_a, fs=0.,
                                 write=False)
     return utils.rmsd(v / a, gtd_df['ref_thickness_m'].loc[gdir.rgi_id])
Beispiel #43
0
def optimize_inversion_params(gdirs):
    """Optimizes fs and fd based on GlaThiDa thicknesses.

    We use the glacier averaged thicknesses provided by GlaThiDa and correct
    them for differences in area with RGI, using a glacier specific volume-area
    scaling formula.

    Parameters
    ----------
    gdirs: list of oggm.GlacierDirectory objects
    """

    # Do we even need to do this?
    if not cfg.PARAMS['optimize_inversion_params']:
        log.info('User did not want to optimize the inversion params')
        return

    # Get test glaciers (all glaciers with thickness data)
    fpath = utils.get_glathida_file()
    try:
        gtd_df = pd.read_csv(fpath).sort_values(by=['RGI_ID'])
    except AttributeError:
        gtd_df = pd.read_csv(fpath).sort(columns=['RGI_ID'])

    dfids = gtd_df['RGI_ID'].values

    ref_gdirs = [gdir for gdir in gdirs if gdir.rgi_id in dfids]
    if len(ref_gdirs) == 0:
        raise RuntimeError('No reference GlaThiDa glaciers. Maybe something '
                           'went wrong with the link list?')
    ref_rgiids = [gdir.rgi_id for gdir in ref_gdirs]
    gtd_df = gtd_df.set_index('RGI_ID').loc[ref_rgiids]

    # Account for area differences between glathida and rgi
    gtd_df['RGI_AREA'] = [gdir.rgi_area_km2 for gdir in ref_gdirs]
    ref_area_km2 = gtd_df.RGI_AREA.values
    ref_area_m2 = ref_area_km2 * 1e6
    gtd_df.VOLUME = gtd_df.MEAN_THICKNESS * gtd_df.GTD_AREA * 1e-3
    ref_cs = gtd_df.VOLUME.values / (gtd_df.GTD_AREA.values**1.375)
    ref_volume_km3 = ref_cs * ref_area_km2**1.375
    ref_thickness_m = ref_volume_km3 / ref_area_km2 * 1000.

    # Minimize volume or thick RMSD?
    optim_t = cfg.PARAMS['optimize_thick']
    if optim_t:
        ref_data = ref_thickness_m
        tol = 0.1
    else:
        ref_data = ref_volume_km3
        tol = 1.e-4

    if cfg.PARAMS['invert_with_sliding']:
        # Optimize with both params
        log.info('Compute the inversion parameters.')

        def to_optimize(x):
            tmp_ref = np.zeros(len(ref_gdirs))
            glen_a = cfg.A * x[0]
            fs = cfg.FS * x[1]
            for i, gdir in enumerate(ref_gdirs):
                v, a = mass_conservation_inversion(gdir, glen_a=glen_a,
                                                   fs=fs, write=False)
                if optim_t:
                    tmp_ref[i] = v / a
                else:
                    tmp_ref[i] = v * 1e-9
            return utils.rmsd(tmp_ref, ref_data)

        opti = optimization.minimize(to_optimize, [1., 1.],
                                    bounds=((0.01, 10), (0.01, 10)),
                                    tol=tol)
        # Check results and save.
        glen_a = cfg.A * opti['x'][0]
        fs = cfg.FS * opti['x'][1]
    else:
        # Optimize without sliding
        log.info('Compute the inversion parameter.')

        def to_optimize(x):
            tmp_ref = np.zeros(len(ref_gdirs))
            glen_a = cfg.A * x[0]
            for i, gdir in enumerate(ref_gdirs):
                v, a = mass_conservation_inversion(gdir, glen_a=glen_a,
                                                   fs=0., write=False)
                if optim_t:
                    tmp_ref[i] = v / a
                else:
                    tmp_ref[i] = v * 1e-9
            return utils.rmsd(tmp_ref, ref_data)
        opti = optimization.minimize(to_optimize, [1.],
                                     bounds=((0.01, 10),),
                                     tol=tol)
        # Check results and save.
        glen_a = cfg.A * opti['x'][0]
        fs = 0.

    # This is for the stats
    oggm_volume_m3 = np.zeros(len(ref_gdirs))
    rgi_area_m2 = np.zeros(len(ref_gdirs))
    for i, gdir in enumerate(ref_gdirs):
        v, a = mass_conservation_inversion(gdir, glen_a=glen_a, fs=fs,
                                           write=False)
        oggm_volume_m3[i] = v
        rgi_area_m2[i] = a
    assert np.allclose(rgi_area_m2 * 1e-6, ref_area_km2)

    # This is for each glacier
    out = dict()
    out['glen_a'] = glen_a
    out['fs'] = fs
    out['factor_glen_a'] = opti['x'][0]
    try:
        out['factor_fs'] = opti['x'][1]
    except IndexError:
        out['factor_fs'] = 0.
    for gdir in gdirs:
        gdir.write_pickle(out, 'inversion_params')

    # This is for the working dir
    # Simple stats
    out['vol_rmsd'] = utils.rmsd(oggm_volume_m3 * 1e-9, ref_volume_km3)
    out['thick_rmsd'] = utils.rmsd(oggm_volume_m3 / ref_area_m2,
                                   ref_thickness_m)

    log.info('Optimized glen_a and fs with a factor {factor_glen_a:.2f} and '
             '{factor_fs:.2f} for a thick RMSD of '
             '{thick_rmsd:.1f} m and a volume RMSD of '
             '{vol_rmsd:.3f} km3'.format(**out))

    df = pd.DataFrame(out, index=[0])
    fpath = os.path.join(cfg.PATHS['working_dir'],
                         'inversion_optim_params.csv')
    df.to_csv(fpath)

    # All results
    df = dict()
    df['ref_area_km2'] = ref_area_km2
    df['ref_volume_km3'] = ref_volume_km3
    df['oggm_volume_km3'] = oggm_volume_m3 * 1e-9
    df['vas_volume_km3'] = 0.034*(df['ref_area_km2']**1.375)

    rgi_id = [gdir.rgi_id for gdir in ref_gdirs]
    df = pd.DataFrame(df, index=rgi_id)
    fpath = os.path.join(cfg.PATHS['working_dir'],
                         'inversion_optim_results.csv')
    df.to_csv(fpath)

    # return value for tests
    return out
Beispiel #44
0
    def test_min_slope(self):
        """ Check what is the min slope a flowline model can produce
        """

        models = [KarthausModel, FluxBasedModel, MUSCLSuperBeeModel]
        kwargs = [{'fixed_dt': 3*SEC_IN_DAY}, {}, {}]
        lens = []
        surface_h = []
        volume = []
        min_slope = []
        yrs = np.arange(1, 700, 2)
        for model, kw in zip(models, kwargs):
            fls = dummy_constant_bed_obstacle()
            mb = LinearMassBalance(2600.)

            model = model(fls, mb_model=mb, y0=0., glen_a=self.glen_a,
                          **kw)

            length = yrs * 0.
            vol = yrs * 0.
            slope = yrs * 0.
            for i, y in enumerate(yrs):
                model.run_until(y)
                fl = fls[-1]
                length[i] = fl.length_m
                vol[i] = fl.volume_km3

                hgt = np.where(fl.thick > 0, fl.surface_h, np.NaN)
                sl = np.arctan(-np.gradient(hgt, fl.dx_meter))
                slope[i] = np.rad2deg(np.nanmin(sl))

            lens.append(length)
            volume.append(vol)
            min_slope.append(slope)
            surface_h.append(fls[-1].surface_h.copy())

        np.testing.assert_allclose(lens[0][-1], lens[1][-1], atol=101)
        np.testing.assert_allclose(volume[0][-1], volume[2][-1], atol=2e-3)
        np.testing.assert_allclose(volume[1][-1], volume[2][-1], atol=5e-3)

        self.assertTrue(utils.rmsd(volume[0], volume[2]) < 1e-2)
        self.assertTrue(utils.rmsd(volume[1], volume[2]) < 1e-2)

        if do_plot:  # pragma: no cover
            plt.figure()
            plt.plot(yrs, lens[0], 'r')
            plt.plot(yrs, lens[1], 'b')
            plt.plot(yrs, lens[2], 'g')
            plt.title('Compare Length')
            plt.xlabel('years')
            plt.ylabel('[m]')
            plt.legend(['Karthaus', 'Flux', 'MUSCL-SuperBee'], loc=2)

            plt.figure()
            plt.plot(yrs, volume[0], 'r')
            plt.plot(yrs, volume[1], 'b')
            plt.plot(yrs, volume[2], 'g')
            plt.title('Compare Volume')
            plt.xlabel('years')
            plt.ylabel('[km^3]')
            plt.legend(['Karthaus', 'Flux', 'MUSCL-SuperBee'], loc=2)

            plt.figure()
            plt.plot(yrs, min_slope[0], 'r')
            plt.plot(yrs, min_slope[1], 'b')
            plt.plot(yrs, min_slope[2], 'g')
            plt.title('Compare min slope')
            plt.xlabel('years')
            plt.ylabel('[degrees]')
            plt.legend(['Karthaus', 'Flux', 'MUSCL-SuperBee'], loc=2)

            plt.figure()
            plt.plot(fls[-1].bed_h, 'k')
            plt.plot(surface_h[0], 'r')
            plt.plot(surface_h[1], 'b')
            plt.plot(surface_h[2], 'g')
            plt.title('Compare Shape')
            plt.xlabel('[m]')
            plt.ylabel('Elevation [m]')
            plt.legend(['Bed', 'Karthaus', 'Flux', 'MUSCL-SuperBee'], loc=3)
            plt.show()
Beispiel #45
0
def optimize_distribute_thickness_single_glacier(gdir):
    """Tests many things

    Parameters
    ----------
    """

    # Get the ref data
    i, j, lon, lat, ref_thick = get_ref_gtd_data(gdir)
    grids_file = gdir.get_filepath('gridded_data')
    with netCDF4.Dataset(grids_file) as nc:
        glacier_mask = nc.variables['glacier_mask'][:]
    pok = np.nonzero(glacier_mask[j, i])
    assert len(pok[0]) > 0
    i, j, ref_thick = i[pok], j[pok], ref_thick[pok]

    # Make the parameter space
    fac_slope = np.linspace(0, 1, 11)
    fac_dis = np.linspace(0, 1, 11)
    fac_c = 0.027 + np.arange(13) * 0.001

    # Make the point matrix
    out_mat = np.full(
        (len(ref_thick), len(fac_c), len(fac_slope), len(fac_dis)), np.NaN)

    out = pd.DataFrame()
    t = 0
    for zi, fc in enumerate(fac_c):
        for yi, fs in enumerate(fac_slope):
            for xi, fd in enumerate(fac_dis):
                if (fs + fd) > 1:
                    continue
                thick = distribute_thickness_vas(gdir,
                                                 reset=True,
                                                 vas_c=fc,
                                                 slope_factor=fs,
                                                 dis_factor=fd,
                                                 print_log=False)
                thick = thick[j, i]
                assert np.all(np.isfinite(thick))
                out.loc[t, 'vas_c'] = fc
                out.loc[t, 'fac_slope'] = fs
                out.loc[t, 'fac_dis'] = fd
                out.loc[t, 'fac_topo'] = 1 - fs - fd
                out.loc[t, 'bias'] = np.mean(thick[pok] - ref_thick[pok])
                out.loc[t, 'mad'] = utils.mad(ref_thick[pok], thick[pok])
                out.loc[t, 'rmsd'] = utils.rmsd(ref_thick[pok], thick[pok])
                out.loc[t, 'n_ref'] = len(ref_thick[pok])
                out_mat[:, zi, yi, xi] = thick
                t += 1

    fs = os.path.join(gdir.dir, 'distribute_optim.csv')
    out.to_csv(fs)

    fs = os.path.join(gdir.dir, 'point_thick.nc')
    dims = ['points', 'fac_c', 'fac_slope', 'fac_dis']
    coords = {
        'points': np.arange(len(ref_thick)),
        'fac_c': fac_c,
        'fac_slope': fac_slope,
        'fac_dis': fac_dis
    }
    out_mat = xr.DataArray(out_mat, dims=dims, coords=coords)
    out_mat = out_mat.to_dataset(name='thick')
    out_mat['ref_thick'] = (('points', ), ref_thick)
    out_mat.to_netcdf(fs)
    return out, out_mat
Beispiel #46
0
    def test_constant_bed(self):

        models = [KarthausModel, FluxBasedModel, MUSCLSuperBeeModel]

        lens = []
        surface_h = []
        volume = []
        yrs = np.arange(1, 700, 2)
        for model in models:
            fls = dummy_constant_bed()
            mb = LinearMassBalance(2600.)

            model = model(fls, mb_model=mb, y0=0., glen_a=self.glen_a,
                          fs=self.fs, fixed_dt=10 * SEC_IN_DAY)

            length = yrs * 0.
            vol = yrs * 0.
            for i, y in enumerate(yrs):
                model.run_until(y)
                length[i] = fls[-1].length_m
                vol[i] = fls[-1].volume_km3
            lens.append(length)
            volume.append(vol)
            surface_h.append(fls[-1].surface_h.copy())

        if do_plot:
            plt.figure()
            plt.plot(yrs, lens[0], 'r')
            plt.plot(yrs, lens[1], 'b')
            plt.plot(yrs, lens[2], 'g')
            plt.title('Compare Length')
            plt.xlabel('years')
            plt.ylabel('[m]')
            plt.legend(['Karthaus', 'Flux', 'MUSCL-SuperBee'], loc=2)

            plt.figure()
            plt.plot(yrs, volume[0], 'r')
            plt.plot(yrs, volume[1], 'b')
            plt.plot(yrs, volume[2], 'g')
            plt.title('Compare Volume')
            plt.xlabel('years')
            plt.ylabel('[km^3]')
            plt.legend(['Karthaus', 'Flux', 'MUSCL-SuperBee'], loc=2)

            plt.figure()
            plt.plot(fls[-1].bed_h, 'k')
            plt.plot(surface_h[0], 'r')
            plt.plot(surface_h[1], 'b')
            plt.plot(surface_h[2], 'g')
            plt.title('Compare Shape')
            plt.xlabel('[m]')
            plt.ylabel('Elevation [m]')
            plt.legend(['Bed', 'Karthaus', 'Flux', 'MUSCL-SuperBee'], loc=3)
            plt.show()

        np.testing.assert_almost_equal(lens[0][-1], lens[1][-1])
        np.testing.assert_allclose(volume[0][-1], volume[2][-1], atol=3e-3)
        np.testing.assert_allclose(volume[1][-1], volume[2][-1], atol=3e-3)

        self.assertTrue(utils.rmsd(lens[0], lens[2]) < 50.)
        self.assertTrue(utils.rmsd(lens[1], lens[2]) < 50.)
        self.assertTrue(utils.rmsd(volume[0], volume[2]) < 2e-3)
        self.assertTrue(utils.rmsd(volume[1], volume[2]) < 2e-3)
        self.assertTrue(utils.rmsd(surface_h[0], surface_h[2]) < 1.0)
        self.assertTrue(utils.rmsd(surface_h[1], surface_h[2]) < 1.0)
Beispiel #47
0
def optimize_thick(gdirs):
    """Optimizes fd based on GlaThiDa thicknesses.

    We use the glacier averaged thicknesses provided by GlaThiDa and correct
    them for differences in area with RGI, using a glacier specific volume-area
    scaling formula.

    Parameters
    ----------
    gdirs: list of oggm.GlacierDirectory objects
    """

    gtd_df = _prepare_inv(gdirs)
    ref_gdirs = gtd_df['ref_gdirs']
    ref_volume_km3 = gtd_df['ref_volume_km3']
    ref_area_km2 = gtd_df['ref_area_km2']
    ref_thickness_m = gtd_df['ref_thickness_m']

    # Optimize without sliding
    log.info('Compute the inversion parameter.')

    def to_optimize(x):
        tmp_ = np.zeros(len(ref_gdirs))
        glen_a = cfg.A * x[0]
        for i, gdir in enumerate(ref_gdirs):
            v, a = mass_conservation_inversion(gdir, glen_a=glen_a,
                                               fs=0., write=False)
            tmp_[i] = v / a
        return utils.rmsd(tmp_, ref_thickness_m)
    opti = optimization.minimize(to_optimize, [1.],
                                bounds=((0.01, 10), ),
                                tol=1.e-4)
    # Check results and save.
    glen_a = cfg.A * opti['x'][0]
    fs = 0.

    # This is for the stats
    oggm_volume_m3 = np.zeros(len(ref_gdirs))
    rgi_area_m2 = np.zeros(len(ref_gdirs))
    for i, gdir in enumerate(ref_gdirs):
        v, a = mass_conservation_inversion(gdir, glen_a=glen_a, fs=fs,
                                           write=False)
        oggm_volume_m3[i] = v
        rgi_area_m2[i] = a
    assert np.allclose(rgi_area_m2 * 1e-6, ref_area_km2)

    # This is for each glacier
    out = dict()
    out['glen_a'] = glen_a
    out['fs'] = fs
    out['factor_glen_a'] = opti['x'][0]
    try:
        out['factor_fs'] = opti['x'][1]
    except IndexError:
        out['factor_fs'] = 0.
    for gdir in gdirs:
        gdir.write_pickle(out, 'inversion_params')

    # This is for the working dir
    # Simple stats
    out['vol_rmsd'] = utils.rmsd(oggm_volume_m3 * 1e-9, ref_volume_km3)
    out['thick_rmsd'] = utils.rmsd(oggm_volume_m3 / (ref_area_km2 * 1e6),
                                   ref_thickness_m)
    log.info('Optimized glen_a and fs with a factor {factor_glen_a:.2f} and '
             '{factor_fs:.2f} for a thick RMSD of {thick_rmsd:.3f}'.format(
        **out))

    df = pd.DataFrame(out, index=[0])
    fpath = os.path.join(cfg.PATHS['working_dir'],
                         'inversion_optim_params.csv')
    df.to_csv(fpath)

    # All results
    df = utils.glacier_characteristics(ref_gdirs)
    df['ref_area_km2'] = ref_area_km2
    df['ref_volume_km3'] = ref_volume_km3
    df['ref_thickness_m'] = ref_thickness_m
    df['oggm_volume_km3'] = oggm_volume_m3 * 1e-9
    df['oggm_thickness_m'] = oggm_volume_m3 / (ref_area_km2 * 1e6)
    df['vas_volume_km3'] = 0.034*(df['ref_area_km2']**1.375)
    df['vas_thickness_m'] = df['vas_volume_km3'] / ref_area_km2 * 1000

    rgi_id = [gdir.rgi_id for gdir in ref_gdirs]
    df = pd.DataFrame(df, index=rgi_id)
    fpath = os.path.join(cfg.PATHS['working_dir'],
                         'inversion_optim_results.csv')
    df.to_csv(fpath)

    # return value for tests
    return out
Beispiel #48
0
    def test_noisy_bed(self):

        models = [KarthausModel, FluxBasedModel, MUSCLSuperBeeModel]
        steps = [15 * SEC_IN_DAY, None, None]
        lens = []
        surface_h = []
        volume = []
        yrs = np.arange(1, 500, 2)
        fls_orig = dummy_noisy_bed()
        for model, step in zip(models, steps):
            fls = copy.deepcopy(fls_orig)
            mb = LinearMassBalance(2600.)

            model = model(fls, mb_model=mb, glen_a=self.glen_a, fixed_dt=step)

            length = yrs * 0.
            vol = yrs * 0.
            for i, y in enumerate(yrs):
                model.run_until(y)
                length[i] = fls[-1].length_m
                vol[i] = fls[-1].volume_km3
            lens.append(length)
            volume.append(vol)
            surface_h.append(fls[-1].surface_h.copy())

        if do_plot:  # pragma: no cover
            plt.figure()
            plt.plot(yrs, lens[0], 'r')
            plt.plot(yrs, lens[1], 'b')
            plt.plot(yrs, lens[2], 'g')
            plt.title('Compare Length')
            plt.xlabel('years')
            plt.ylabel('[m]')
            plt.legend(['Karthaus', 'Flux', 'MUSCL-SuperBee'], loc=2)

            plt.figure()
            plt.plot(yrs, volume[0], 'r')
            plt.plot(yrs, volume[1], 'b')
            plt.plot(yrs, volume[2], 'g')
            plt.title('Compare Volume')
            plt.xlabel('years')
            plt.ylabel('[km^3]')
            plt.legend(['Karthaus', 'Flux', 'MUSCL-SuperBee'], loc=2)

            plt.figure()
            plt.plot(fls[-1].bed_h, 'k')
            plt.plot(surface_h[0], 'r')
            plt.plot(surface_h[1], 'b')
            plt.plot(surface_h[2], 'g')
            plt.title('Compare Shape')
            plt.xlabel('[m]')
            plt.ylabel('Elevation [m]')
            plt.legend(['Bed', 'Karthaus', 'Flux', 'MUSCL-SuperBee'], loc=3)
            plt.show()

        np.testing.assert_allclose(lens[0][-1], lens[1][-1], atol=101)
        np.testing.assert_allclose(volume[0][-1], volume[1][-1], atol=1e-2)
        np.testing.assert_allclose(volume[0][-1], volume[2][-1], atol=1e-2)

        self.assertTrue(utils.rmsd(lens[0], lens[1]) < 100.)
        self.assertTrue(utils.rmsd(volume[0], volume[1]) < 1e-1)
        self.assertTrue(utils.rmsd(volume[0], volume[2]) < 1e-1)
        self.assertTrue(utils.rmsd(surface_h[0], surface_h[1]) < 10)
        self.assertTrue(utils.rmsd(surface_h[0], surface_h[2]) < 10)
Beispiel #49
0
    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()
Beispiel #50
0
    def test_constant_bed(self):

        models = [
            flowline.KarthausModel, flowline.FluxBasedModel,
            flowline.MUSCLSuperBeeModel
        ]

        lens = []
        surface_h = []
        volume = []
        yrs = np.arange(1, 700, 2)
        for model in models:
            fls = dummy_constant_bed()
            mb = ConstantBalanceModel(2600.)

            model = model(fls,
                          mb_model=mb,
                          y0=0.,
                          glen_a=self.glen_a,
                          fs=self.fs,
                          fixed_dt=10 * SEC_IN_DAY)

            length = yrs * 0.
            vol = yrs * 0.
            for i, y in enumerate(yrs):
                model.run_until(y)
                length[i] = fls[-1].length_m
                vol[i] = fls[-1].volume_km3
            lens.append(length)
            volume.append(vol)
            surface_h.append(fls[-1].surface_h.copy())

        if do_plot:  # pragma: no cover
            plt.figure()
            plt.plot(yrs, lens[0], 'r')
            plt.plot(yrs, lens[1], 'b')
            plt.plot(yrs, lens[2], 'g')
            plt.title('Compare Length')
            plt.xlabel('years')
            plt.ylabel('[m]')
            plt.legend(['Karthaus', 'Flux', 'MUSCL-SuperBee'], loc=2)

            plt.figure()
            plt.plot(yrs, volume[0], 'r')
            plt.plot(yrs, volume[1], 'b')
            plt.plot(yrs, volume[2], 'g')
            plt.title('Compare Volume')
            plt.xlabel('years')
            plt.ylabel('[km^3]')
            plt.legend(['Karthaus', 'Flux', 'MUSCL-SuperBee'], loc=2)

            plt.figure()
            plt.plot(fls[-1].bed_h, 'k')
            plt.plot(surface_h[0], 'r')
            plt.plot(surface_h[1], 'b')
            plt.plot(surface_h[2], 'g')
            plt.title('Compare Shape')
            plt.xlabel('[m]')
            plt.ylabel('Elevation [m]')
            plt.legend(['Bed', 'Karthaus', 'Flux', 'MUSCL-SuperBee'], loc=3)
            plt.show()

        np.testing.assert_almost_equal(lens[0][-1], lens[1][-1])
        np.testing.assert_allclose(volume[0][-1], volume[2][-1], atol=3e-3)
        np.testing.assert_allclose(volume[1][-1], volume[2][-1], atol=3e-3)

        self.assertTrue(utils.rmsd(lens[0], lens[2]) < 50.)
        self.assertTrue(utils.rmsd(lens[1], lens[2]) < 50.)
        self.assertTrue(utils.rmsd(volume[0], volume[2]) < 2e-3)
        self.assertTrue(utils.rmsd(volume[1], volume[2]) < 2e-3)
        self.assertTrue(utils.rmsd(surface_h[0], surface_h[2]) < 1.0)
        self.assertTrue(utils.rmsd(surface_h[1], surface_h[2]) < 1.0)
Beispiel #51
0
def optimize_thick(gdirs):
    """Optimizes fd based on GlaThiDa thicknesses.

    We use the glacier averaged thicknesses provided by GlaThiDa and correct
    them for differences in area with RGI, using a glacier specific volume-area
    scaling formula.

    Parameters
    ----------
    gdirs: list of oggm.GlacierDirectory objects
    """

    gtd_df = _prepare_inv(gdirs)
    ref_gdirs = gtd_df['ref_gdirs']
    ref_volume_km3 = gtd_df['ref_volume_km3']
    ref_area_km2 = gtd_df['ref_area_km2']
    ref_thickness_m = gtd_df['ref_thickness_m']

    # Optimize without sliding
    log.info('Compute the inversion parameter.')

    def to_optimize(x):
        tmp_ = np.zeros(len(ref_gdirs))
        glen_a = cfg.A * x[0]
        for i, gdir in enumerate(ref_gdirs):
            v, a = invert_parabolic_bed(gdir,
                                        glen_a=glen_a,
                                        fs=0.,
                                        write=False)
            tmp_[i] = v / a
        return utils.rmsd(tmp_, ref_thickness_m)

    opti = optimization.minimize(to_optimize, [1.],
                                 bounds=((0.01, 10), ),
                                 tol=1.e-4)
    # Check results and save.
    glen_a = cfg.A * opti['x'][0]
    fs = 0.

    # This is for the stats
    oggm_volume_m3 = np.zeros(len(ref_gdirs))
    rgi_area_m2 = np.zeros(len(ref_gdirs))
    for i, gdir in enumerate(ref_gdirs):
        v, a = invert_parabolic_bed(gdir, glen_a=glen_a, fs=fs, write=False)
        oggm_volume_m3[i] = v
        rgi_area_m2[i] = a
    assert np.allclose(rgi_area_m2 * 1e-6, ref_area_km2)

    # This is for each glacier
    out = dict()
    out['glen_a'] = glen_a
    out['fs'] = fs
    out['factor_glen_a'] = opti['x'][0]
    try:
        out['factor_fs'] = opti['x'][1]
    except IndexError:
        out['factor_fs'] = 0.
    for gdir in gdirs:
        gdir.write_pickle(out, 'inversion_params')

    # This is for the working dir
    # Simple stats
    out['vol_rmsd'] = utils.rmsd(oggm_volume_m3 * 1e-9, ref_volume_km3)
    out['thick_rmsd'] = utils.rmsd(oggm_volume_m3 / (ref_area_km2 * 1e6),
                                   ref_thickness_m)
    log.info(
        'Optimized glen_a and fs with a factor {factor_glen_a:.2f} and '
        '{factor_fs:.2f} for a thick RMSD of {thick_rmsd:.3f}'.format(**out))

    df = pd.DataFrame(out, index=[0])
    fpath = os.path.join(cfg.PATHS['working_dir'],
                         'inversion_optim_params.csv')
    df.to_csv(fpath)

    # All results
    df = utils.glacier_characteristics(ref_gdirs)
    df['ref_area_km2'] = ref_area_km2
    df['ref_volume_km3'] = ref_volume_km3
    df['ref_thickness_m'] = ref_thickness_m
    df['oggm_volume_km3'] = oggm_volume_m3 * 1e-9
    df['oggm_thickness_m'] = oggm_volume_m3 / (ref_area_km2 * 1e6)
    df['vas_volume_km3'] = 0.034 * (df['ref_area_km2']**1.375)
    df['vas_thickness_m'] = df['vas_volume_km3'] / ref_area_km2 * 1000

    rgi_id = [gdir.rgi_id for gdir in ref_gdirs]
    df = pd.DataFrame(df, index=rgi_id)
    fpath = os.path.join(cfg.PATHS['working_dir'],
                         'inversion_optim_results.csv')
    df.to_csv(fpath)

    # return value for tests
    return out
Beispiel #52
0
    def test_constant_bed_cliff(self):
        """ a test case for mass conservation in the flowline models
            the idea is to introduce a cliff in the sloping bed and see
            what the models do when the cliff height is changed
        """

        models = [
            flowline.KarthausModel, flowline.FluxBasedModel,
            flowline.MUSCLSuperBeeModel
        ]

        lens = []
        surface_h = []
        volume = []
        yrs = np.arange(1, 700, 2)
        for model in models:
            fls = dummy_constant_bed_cliff()
            mb = ConstantBalanceModel(2600.)

            model = model(fls,
                          mb_model=mb,
                          y0=0.,
                          glen_a=self.glen_a,
                          fs=self.fs,
                          fixed_dt=2 * SEC_IN_DAY)

            length = yrs * 0.
            vol = yrs * 0.
            for i, y in enumerate(yrs):
                model.run_until(y)
                length[i] = fls[-1].length_m
                vol[i] = fls[-1].volume_km3
            lens.append(length)
            volume.append(vol)
            surface_h.append(fls[-1].surface_h.copy())

        if do_plot:  # pragma: no cover
            plt.figure()
            plt.plot(yrs, lens[0], 'r')
            plt.plot(yrs, lens[1], 'b')
            plt.plot(yrs, lens[2], 'g')
            plt.title('Compare Length')
            plt.xlabel('years')
            plt.ylabel('[m]')
            plt.legend(['Karthaus', 'Flux', 'MUSCL-SuperBee'], loc=2)

            plt.figure()
            plt.plot(yrs, volume[0], 'r')
            plt.plot(yrs, volume[1], 'b')
            plt.plot(yrs, volume[2], 'g')
            plt.title('Compare Volume')
            plt.xlabel('years')
            plt.ylabel('[km^3]')
            plt.legend(['Karthaus', 'Flux', 'MUSCL-SuperBee'], loc=2)

            plt.figure()
            plt.plot(fls[-1].bed_h, 'k')
            plt.plot(surface_h[0], 'r')
            plt.plot(surface_h[1], 'b')
            plt.plot(surface_h[2], 'g')
            plt.title('Compare Shape')
            plt.xlabel('[m]')
            plt.ylabel('Elevation [m]')
            plt.legend(['Bed', 'Karthaus', 'Flux', 'MUSCL-SuperBee'], loc=3)
            plt.show()

        # OK, so basically, Alex's tests below show that the other models
        # are wrong and produce too much mass. There is also another more
        # more trivial issue with the computation of the length, I added a
        # "to do" in the code.

        # Unit-testing perspective:
        # verify that indeed the models are wrong of more than 50%
        self.assertTrue(volume[1][-1] > volume[2][-1] * 1.5)
        # Karthaus is even worse
        self.assertTrue(volume[0][-1] > volume[1][-1])

        if False:
            # TODO: this will always fail so ignore it for now
            np.testing.assert_almost_equal(lens[0][-1], lens[1][-1])
            np.testing.assert_allclose(volume[0][-1], volume[2][-1], atol=2e-3)
            np.testing.assert_allclose(volume[1][-1], volume[2][-1], atol=2e-3)

            self.assertTrue(utils.rmsd(lens[0], lens[2]) < 50.)
            self.assertTrue(utils.rmsd(lens[1], lens[2]) < 50.)
            self.assertTrue(utils.rmsd(volume[0], volume[2]) < 1e-3)
            self.assertTrue(utils.rmsd(volume[1], volume[2]) < 1e-3)
            self.assertTrue(utils.rmsd(surface_h[0], surface_h[2]) < 1.0)
            self.assertTrue(utils.rmsd(surface_h[1], surface_h[2]) < 1.0)
Beispiel #53
0
    def test_constant_bed(self):

        map_dx = 100.
        yrs = np.arange(1, 400, 5)
        lens = []
        volume = []
        areas = []
        surface_h = []

        # Flowline case
        fls = dummy_constant_bed(hmax=3000., hmin=1000., nx=200, map_dx=map_dx,
                                 widths=1.)
        mb = LinearMassBalance(2600.)

        flmodel = FluxBasedModel(fls, mb_model=mb, y0=0.)

        length = yrs * 0.
        vol = yrs * 0.
        area = yrs * 0
        for i, y in enumerate(yrs):
            flmodel.run_until(y)
            length[i] = fls[-1].length_m
            vol[i] = fls[-1].volume_km3
            area[i] = fls[-1].area_km2

        lens.append(length)
        volume.append(vol)
        areas.append(area)
        surface_h.append(fls[-1].surface_h.copy())

        # Make a 2D bed out of the 1D
        bed_2d = np.repeat(fls[-1].bed_h, 3).reshape((fls[-1].nx, 3))

        sdmodel = Upstream2D(bed_2d, dx=map_dx, mb_model=mb, y0=0.,
                             ice_thick_filter=None)

        length = yrs * 0.
        vol = yrs * 0.
        area = yrs * 0
        for i, y in enumerate(yrs):
            sdmodel.run_until(y)
            surf_1d = sdmodel.ice_thick[:, 1]
            length[i] = np.sum(surf_1d > 0) * sdmodel.dx
            vol[i] = sdmodel.volume_km3 / 3
            area[i] = sdmodel.area_km2 / 3

        lens.append(length)
        volume.append(vol)
        areas.append(area)
        surface_h.append(sdmodel.surface_h[:, 1])

        if do_plot:
            plt.figure()
            plt.plot(yrs, lens[0], 'r')
            plt.plot(yrs, lens[1], 'b')
            plt.title('Compare Length')
            plt.xlabel('years')
            plt.ylabel('[m]')
            plt.legend(['Flowline', '2D'], loc=2)

            plt.figure()
            plt.plot(yrs, volume[0], 'r')
            plt.plot(yrs, volume[1], 'b')
            plt.title('Compare Volume')
            plt.xlabel('years')
            plt.ylabel('[km^3]')
            plt.legend(['Flowline', '2D'], loc=2)

            plt.figure()
            plt.plot(fls[-1].bed_h, 'k')
            plt.plot(surface_h[0], 'r')
            plt.plot(surface_h[1], 'b')
            plt.title('Compare Shape')
            plt.xlabel('[m]')
            plt.ylabel('Elevation [m]')
            plt.legend(['Bed', 'Flowline', '2D'], loc=2)
            plt.show()

        np.testing.assert_almost_equal(lens[0][-1], lens[1][-1])
        np.testing.assert_allclose(volume[0][-1], volume[1][-1], atol=3e-3)

        self.assertTrue(utils.rmsd(lens[0], lens[1]) < 50.)
        self.assertTrue(utils.rmsd(volume[0], volume[1]) < 2e-3)
        self.assertTrue(utils.rmsd(areas[0], areas[1]) < 2e-3)
        self.assertTrue(utils.rmsd(surface_h[0], surface_h[1]) < 1.0)

        # Equilibrium
        sdmodel.run_until_equilibrium()
        flmodel.run_until_equilibrium()
        assert_allclose(sdmodel.volume_km3 / 3, flmodel.volume_km3, atol=2e-3)
        assert_allclose(sdmodel.area_km2 / 3, flmodel.area_km2, atol=2e-3)

        # Store
        run_ds = sdmodel.run_until_and_store(sdmodel.yr+50)
        ts = run_ds['ice_thickness'].mean(dim=['y', 'x'])
        assert_allclose(ts, ts.values[0], atol=1)

        # Other direction
        bed_2d = np.repeat(fls[-1].bed_h, 3).reshape((fls[-1].nx, 3)).T

        sdmodel = Upstream2D(bed_2d, dx=map_dx, mb_model=mb, y0=0.,
                             ice_thick_filter=None)

        length = yrs * 0.
        vol = yrs * 0.
        area = yrs * 0
        for i, y in enumerate(yrs):
            sdmodel.run_until(y)
            surf_1d = sdmodel.ice_thick[1, :]
            length[i] = np.sum(surf_1d > 0) * sdmodel.dx
            vol[i] = sdmodel.volume_km3 / 3
            area[i] = sdmodel.area_km2 / 3

        lens.append(length)
        volume.append(vol)
        areas.append(area)
        surface_h.append(sdmodel.surface_h[:, 1])

        np.testing.assert_almost_equal(lens[0][-1], lens[1][-1])
        np.testing.assert_allclose(volume[0][-1], volume[1][-1], atol=3e-3)

        self.assertTrue(utils.rmsd(lens[0], lens[1]) < 50.)
        self.assertTrue(utils.rmsd(volume[0], volume[1]) < 2e-3)
        self.assertTrue(utils.rmsd(areas[0], areas[1]) < 2e-3)
        self.assertTrue(utils.rmsd(surface_h[0], surface_h[1]) < 1.0)

        # Equilibrium
        sdmodel.run_until_equilibrium()
        assert_allclose(sdmodel.volume_km3 / 3, flmodel.volume_km3, atol=2e-3)
        assert_allclose(sdmodel.area_km2 / 3, flmodel.area_km2, atol=2e-3)
Beispiel #54
0
    def test_cliff(self):
        """ a test case for mass conservation in the flowline models
            the idea is to introduce a cliff in the sloping bed and see
            what the models do when the cliff height is changed
        """

        models = [KarthausModel, FluxBasedModel, MUSCLSuperBeeModel]

        lens = []
        surface_h = []
        volume = []
        yrs = np.arange(1, 500, 2)
        for model in models:
            fls = dummy_constant_bed_cliff()
            mb = LinearMassBalance(2600.)

            model = model(fls, mb_model=mb, y0=0., glen_a=self.glen_a,
                          fs=self.fs, fixed_dt=2*SEC_IN_DAY)

            length = yrs * 0.
            vol = yrs * 0.
            for i, y in enumerate(yrs):
                model.run_until(y)
                length[i] = fls[-1].length_m
                vol[i] = fls[-1].volume_km3
            lens.append(length)
            volume.append(vol)
            surface_h.append(fls[-1].surface_h.copy())

        if False:  # pragma: no cover
            plt.figure()
            plt.plot(yrs, lens[0], 'r')
            plt.plot(yrs, lens[1], 'b')
            plt.plot(yrs, lens[2], 'g')
            plt.title('Compare Length')
            plt.xlabel('years')
            plt.ylabel('[m]')
            plt.legend(['Karthaus', 'Flux', 'MUSCL-SuperBee'], loc=2)

            plt.figure()
            plt.plot(yrs, volume[0], 'r')
            plt.plot(yrs, volume[1], 'b')
            plt.plot(yrs, volume[2], 'g')
            plt.title('Compare Volume')
            plt.xlabel('years')
            plt.ylabel('[km^3]')
            plt.legend(['Karthaus', 'Flux', 'MUSCL-SuperBee'], loc=2)

            plt.figure()
            plt.plot(fls[-1].bed_h, 'k')
            plt.plot(surface_h[0], 'r')
            plt.plot(surface_h[1], 'b')
            plt.plot(surface_h[2], 'g')
            plt.title('Compare Shape')
            plt.xlabel('[m]')
            plt.ylabel('Elevation [m]')
            plt.legend(['Bed', 'Karthaus', 'Flux', 'MUSCL-SuperBee'], loc=3)
            plt.show()

        # OK, so basically, Alex's tests below show that the other models
        # are wrong and produce too much mass. There is also another more
        # more trivial issue with the computation of the length, I added a
        # "to do" in the code.

        # Unit-testing perspective:
        # "verify" that indeed the models are wrong of more than 50%
        self.assertTrue(volume[1][-1] > volume[2][-1] * 1.5)
        # Karthaus is even worse
        self.assertTrue(volume[0][-1] > volume[1][-1])

        if False:
            # TODO: this will always fail so ignore it for now
            np.testing.assert_almost_equal(lens[0][-1], lens[1][-1])
            np.testing.assert_allclose(volume[0][-1], volume[2][-1], atol=2e-3)
            np.testing.assert_allclose(volume[1][-1], volume[2][-1], atol=2e-3)

            self.assertTrue(utils.rmsd(lens[0], lens[2]) < 50.)
            self.assertTrue(utils.rmsd(lens[1], lens[2]) < 50.)
            self.assertTrue(utils.rmsd(volume[0], volume[2]) < 1e-3)
            self.assertTrue(utils.rmsd(volume[1], volume[2]) < 1e-3)
            self.assertTrue(utils.rmsd(surface_h[0], surface_h[2]) < 1.0)
            self.assertTrue(utils.rmsd(surface_h[1], surface_h[2]) < 1.0)