Beispiel #1
0
    def test_annual_mb(self):
        """Test the routine computing the annual mass balance."""
        # run all needed prepro tasks
        gdir = self._setup_mb_test()

        # get relevant glacier surface elevation
        min_hgt, max_hgt = vascaling.get_min_max_elevation(gdir)

        # define temporal range
        year = 1975
        years = np.array([year, year])

        # get mass balance relevant climate data
        _, temp, prcp = vascaling.get_yearly_mb_temp_prcp(gdir,
                                                          year_range=years)
        temp = temp[0]
        prcp = prcp[0]

        # read mu* and bias from vascaling_mustar
        vascaling_mustar = gdir.read_json('vascaling_mustar')
        mu_star = vascaling_mustar['mu_star']
        bias = vascaling_mustar['bias']

        # specify scaling factor for SI units [kg s-1]
        fac_SI = cfg.SEC_IN_YEAR * cfg.PARAMS['ice_density']

        # compute mass balance 'by hand'
        mb_ref = (prcp - mu_star * temp - bias) / fac_SI
        # compute mb using the VAS mass balance model
        mb_mod = vascaling.VAScalingMassBalance(gdir).get_annual_mb(min_hgt,
                                                                    max_hgt,
                                                                    year)
        # compare mass balances with bias
        np.testing.assert_allclose(mb_ref, mb_mod, rtol=1e-3)

        # compute mass balance 'by hand'
        mb_ref = (prcp - mu_star * temp) / fac_SI
        # compute mb 'by model'
        mb_mod = vascaling.VAScalingMassBalance(gdir, bias=0). \
            get_annual_mb(min_hgt, max_hgt, year)
        # compare mass balances without bias
        np.testing.assert_allclose(mb_ref, mb_mod, rtol=1e-3)
Beispiel #2
0
    def test_yearly_mb_temp_prcp(self):
        """Test the routine which returns the yearly mass balance relevant
        climate parameters, i.e. positive melting temperature and solid
        precipitation. The testing target is the output of the corresponding
        OGGM routine `get_yearly_mb_climate_on_glacier(gdir)`.
        """

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

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

        # get yearly sums of terminus temperature and solid precipitation
        years, temp, prcp = vascaling.get_yearly_mb_temp_prcp(gdir)

        # use the OGGM methode to get the mass balance
        # relevant climate parameters
        years_oggm, temp_oggm, prcp_oggm = \
            climate.mb_yearly_climate_on_glacier(gdir)

        # the energy input at the glacier terminus must be greater than (or
        # equal to) the glacier wide average, since the air temperature drops
        # with elevation, i.e. the mean deviation must be positive, using the
        # OGGM data as reference
        assert md(temp_oggm, temp) >= 0
        # consequentially, the average mass input must be less than (or equal
        # to) the mass input integrated over the whole glacier surface, i.e.
        # the mean deviation must be negative, using the OGGM data as reference
        # TODO: does it actually?! And if so, why?! @ASK
        assert md(prcp_oggm, prcp) <= 0

        # correlation must be higher than set threshold
        assert corrcoef(temp, temp_oggm) >= 0.94
        assert corrcoef(prcp, prcp_oggm) >= 0.98

        # get terminus temperature using the OGGM routine
        fpath = gdir.get_filepath('gridded_data')
        with ncDataset(fpath) as nc:
            mask = nc.variables['glacier_mask'][:]
            topo = nc.variables['topo'][:]
        heights = np.array([np.min(topo[np.where(mask == 1)])])
        years_height, temp_height, _ = \
            climate.mb_yearly_climate_on_height(gdir, heights, flatten=False)
        temp_height = temp_height[0]
        # both time series must be equal
        np.testing.assert_array_equal(temp, temp_height)

        # get solid precipitation averaged over the glacier
        # (not weighted with widths)
        fls = gdir.read_pickle('inversion_flowlines')
        heights = np.array([])
        for fl in fls:
            heights = np.append(heights, fl.surface_h)
        years_height, _, prcp_height = \
            climate.mb_yearly_climate_on_height(gdir, heights, flatten=True)
        # correlation must be higher than set threshold
        assert corrcoef(prcp, prcp_height) >= 0.99

        # TODO: assert absolute values (or differences) of precipitation @ASK

        # test exception handling of out of bounds time/year range
        with self.assertRaises(climate.MassBalanceCalibrationError):
            # start year out of bounds
            year_range = [1500, 1980]
            _, _, _ = vascaling.get_yearly_mb_temp_prcp(gdir,
                                                        year_range=year_range)
        with self.assertRaises(climate.MassBalanceCalibrationError):
            # end year oud of bounds
            year_range = [1980, 3000]
            _, _, _ = vascaling.get_yearly_mb_temp_prcp(gdir,
                                                        year_range=year_range)
        with self.assertRaises(ValueError):
            # get not N full years
            t0 = datetime.datetime(1980, 1, 1)
            t1 = datetime.datetime(1980, 3, 1)
            time_range = [t0, t1]
            _, _, _ = vascaling.get_yearly_mb_temp_prcp(gdir,
                                                        time_range=time_range)

        # TODO: assert gradient in climate file?!

        pass