Esempio n. 1
0
    def test_get_dz(self):
        mdo = self.mdo
        ds = mdo.dataset
        dz = mdo.get_dz("CWD")

        self.assertEqual(dz.name, "dz")
        self.assertEqual(dz.unit, "m")
        res2 = ds["dz"]
        self.assertTrue(np.all(dz.data == res2[:]))

        ## no layers, no grid
        mdo = self.mdos_inc[0]
        dz = mdo.get_dz("CWD")
        self.assertTrue(np.all(dz.data == np.array([1])))
        self.assertEqual(dz.unit, "1")

        ## test manually given dz variable
        mdo = self.mdo
        dz = Variable(name="dz", data=np.cumsum(np.arange(10)), unit="km")
        time = Variable(data=np.arange(10), unit="d")
        mdo_dz = ModelDataObject(
            model_structure=mdo.model_structure,
            dataset=mdo.dataset,
            dz_var_names={"dz": dz},
            nstep=mdo.nstep,
            stock_unit=mdo.stock_unit,
            time=time,
        )

        dz = mdo_dz.get_dz("CWD")
        self.assertEqual(dz.name, "dz")
        self.assertEqual(dz.unit, "km")
        res2 = np.cumsum(np.arange(10))
        self.assertTrue(np.all(dz.data == res2[:]))
Esempio n. 2
0
    def test_init(self):
        unit = "gC/m^2"
        var = Variable(data=np.arange(10), unit=unit)
        self.assertEqual(var.unit, "g/m^2")

        unit = "gC14/m^2"
        var = Variable(data=np.arange(10), unit=unit)
        self.assertEqual(var.unit, "g/m^2")
Esempio n. 3
0
    def test_data_mult(self):
        var_masked_data = np.ma.masked_array(
            data=np.arange(9).reshape(3, 3),
            mask=[[0, 0, 0], [1, 0, 0], [0, 0, 0]],
            fill_value=-1,
        )
        var = Variable(data=var_masked_data, unit="gC/m^3")

        dz_masked_data = np.ma.masked_array(
            data=np.cumsum(np.arange(3)), mask=[0, 0, 1], fill_value=-1
        )
        dz = Variable(data=dz_masked_data, unit="m")

        res = var.data_mult(dz, given_axes=0)
        res2 = np.ma.masked_array(
            data=[[0, 0, 0], [3, 4, 5], [18, 21, 25]],
            mask=[[0, 0, 0], [1, 0, 0], [1, 1, 1]],
            fill_value=-1,
        )
        self.assertTrue(np.all(res.data == res2))
        self.assertEqual(res.unit, "m-2.kg")
        self.assertTrue(np.all(res.data.filled() == res2.filled()))
        res2.mask[2, 2] = 0
        self.assertFalse(np.all(res.data.filled() == res2.filled()))

        res = var.data_mult(dz, given_axes=1)
        res2 = np.ma.masked_array(
            data=[[0, 1, 6], [0, 4, 15], [0, 7, 24]],
            mask=[[0, 0, 1], [1, 0, 1], [0, 0, 1]],
            fill_value=-1,
        )
        self.assertTrue(np.all(res.data == res2))
        self.assertEqual(res.unit, "m-2.kg")
        self.assertTrue(np.all(res.data.filled() == res2.filled()))
        res2.mask[2, 2] = 0
        self.assertFalse(np.all(res.data.filled() == res2.filled()))

        var_data = np.ma.masked_array(
            data=np.arange(12).reshape(3, 2, 2), mask=False, fill_value=-1
        )
        var = Variable(data=var_data, unit="g/m^2")
        area_data = np.ma.masked_array(
            data=np.arange(4).reshape(2, 2), mask=[[0, 0], [1, 0]], fill_value=-1
        )
        area = Variable(data=area_data, unit="km^2")
        res = var.data_mult(area, given_axes=(1, 2))
        res2 = np.ma.masked_array(
            data=np.array([[[0, 1], [4, 9]], [[0, 5], [12, 21]], [[0, 9], [20, 33]]],),
            mask=[[[0, 0], [1, 0]], [[0, 0], [1, 0]], [[0, 0], [1, 0]]],
            fill_value=-1,
        )
        self.assertTrue(np.all(res.data.filled() == res2.filled()))
        self.assertEqual(res.unit, "t")
        res2.set_fill_value(-2)
        self.assertFalse(np.all(res.data.filled() == res2.filled()))
Esempio n. 4
0
def FluxRateVariable2FluxVariable(frv, time):
    time_axis = 0
    dt_data = np.diff(time.data)
    dt = Variable(data=dt_data, unit=time.unit)
    fv = frv.data_mult(dt, time_axis)

    return fv
Esempio n. 5
0
    def test_add(self):
        masked_data = np.ma.masked_array(
            data=np.arange(3), mask=[0, 1, 0], fill_value=-1
        )
        unit = "g"
        var1 = Variable(data=masked_data, unit=unit)

        masked_data2 = np.ma.masked_array(data=[0, 2, 4], mask=[1, 0, 0], fill_value=-2)
        var2 = Variable(data=masked_data2, unit=unit)
        res = var1 + var2
        self.assertTrue(np.all(res.data.filled() == [-1, -1, 6]))
        self.assertEqual(var1.unit, res.unit)

        var3 = Variable(data=masked_data, unit="kg")
        with self.assertRaises(AssertionError):
            var1 + var3
Esempio n. 6
0
def load_parameter_set(**keywords):
    nstep = keywords.get("nstep", 1)

    parameter_set = {
        "stock_unit": "g/m^2",
        "nr_layers": 10,
        "nstep": nstep,
    }

    ## depth variable with bounds
    ds_depth = keywords['ds_depth']
    dz_var = ds_depth.variables["DZSOI"]
    dz_var_name = "dz"
    dz = Variable(
        name=dz_var_name,
        data=dz_var[:parameter_set["nr_layers"], 0],
        unit=dz_var.attrs['units'],
    )
    ds_depth.close()

    parameter_set["dz_var_name"] = dz_var_name
    parameter_set["dz_var_names"] = {dz_var_name: dz}

    parameter_set['integration_method'] = keywords.get('integration_method',
                                                       'solve_ivp')
    parameter_set['nr_nodes'] = keywords.get('nr_nodes', None)

    #    dataset = Dataset(parameter_set['ds_filename'], 'r')
    #    parameter_set['dataset']   = dataset
    #    parameter_set['calendar_src']  = dataset['time'].calendar

    return parameter_set
Esempio n. 7
0
    def get_stock(self, mr, pool_name, nr_layer=0, name=''):
        ms = self.model_structure
        pool_nr = ms.get_pool_nr(pool_name, nr_layer)
        soln = mr.solve()

        if name == '':
            name = ms.get_stock_var(pool_name)

        return Variable(name=name, data=soln[:, pool_nr], unit=self.stock_unit)
Esempio n. 8
0
    def get_dz(self, pool_name):
        ms = self.model_structure
        dataset = self.dataset

        for item in ms.pool_structure:
            if item["pool_name"] == pool_name:
                dz_var_name = item.get("dz_var", None)

        if dz_var_name is not None:
            dz = self.dz_var_names.get(dz_var_name, None)
            if dz is None:
                dz_var = dataset[dz_var_name]

                dz = Variable(name=dz_var_name,
                              data=dz_var[...],
                              unit=dz_var.units)
        else:
            dz = Variable(name="dz_default", data=np.array([1]), unit="1")

        return dz
Esempio n. 9
0
    def create_discrete_model_run(self, errors=False):
        out = self.load_xs_Us_Fs_Rs()
        xs, Us, Fs, Rs = out
        start_values = xs.data[0, :]

        if (xs.data.mask.sum() + Fs.data.mask.sum() + Us.data.mask.sum() +
                Rs.data.mask.sum() == 0):

            # fixme hm 2020-04-21:
            # which reconstruction version is the right choice?
            #            dmr = DMR.reconstruct_from_data(
            #                self.time_agg.data.filled(),
            #                start_values.filled(),
            #                xs.data.filled(),
            #                Fs.data.filled(),
            #                Rs.data.filled(),
            #                Us.data.filled()
            #            )

            #            dmr = DMR.reconstruct_from_fluxes_and_solution(
            dmr = DMRWGF.reconstruct_from_fluxes_and_solution(
                self.time_agg.data.filled(),
                xs.data.filled(),
                Fs.data.filled(),
                Rs.data.filled(),
                Us.data.filled(),
                Fs.data.filled(),
                Rs.data.filled(),
            )
        else:
            dmr = None

        if errors:
            soln_dmr = Variable(data=dmr.solve(), unit=self.stock_unit)
            abs_err = soln_dmr.absolute_error(xs)
            rel_err = soln_dmr.relative_error(xs)

            return dmr, abs_err, rel_err
        else:
            return dmr
Esempio n. 10
0
    def test_FluxRateVariable2FluxVariable(self):
        ds = self.mdo.dataset
        nr_layers = self.mdo.model_structure.get_nr_layers("CWD")

        frdv = readVariable(
            ReturnClass=FluxVariable,
            dataset=ds,
            variable_name="fire_CWD",
            nr_layers=nr_layers,
            data_shift=1,
        )
        dz = Variable(data=ds["dz"][:], unit=ds["dz"].units)
        frv = FluxRateDensityVariable2FluxRateVariable(frdv, dz)

        time = Variable(data=ds["time"][:], unit=ds["time"].units)
        fv = FluxRateVariable2FluxVariable(frv, time)

        self.assertTrue(isinstance(fv, FluxVariable))
        self.assertEqual(fv.unit, "m-2.kg")
        res = fv.data[3, ...]
        res2 = 86.4 * np.array([12, 26, 42])
        self.assertTrue(np.allclose(res, res2 * 1e-03))
Esempio n. 11
0
    def get_acc_gross_external_output_flux(self,
                                           mr,
                                           pool_name,
                                           nr_layer=0,
                                           name=''):
        ms = self.model_structure
        pool_nr = ms.get_pool_nr(pool_name, nr_layer)

        if name == '':
            name = ms.get_external_output_flux_var(pool_name)

        return Variable(name=name,
                        data=mr.acc_gross_external_output_vector()[:, pool_nr],
                        unit=self.stock_unit)
Esempio n. 12
0
def check_data_consistency(ds_single_site, time_step_in_days):
    ms = load_model_structure_with_vegetation()

    # data_test.py says tht for labile 31.0 is constantly right
    time = Variable(name="time",
                    data=np.arange(len(ds_single_site.time)) *
                    time_step_in_days,
                    unit="d")

    mdo = ModelDataObject(model_structure=ms,
                          dataset=ds_single_site,
                          stock_unit="gC/m2",
                          time=time)

    abs_err, rel_err = mdo.check_data_consistency()
    return abs_err, rel_err
Esempio n. 13
0
    def test_convert(self):
        masked_data = np.ma.masked_array(data=np.arange(2), mask=[1, 0], fill_value=-1)
        unit = "d"
        var = Variable(data=masked_data, unit=unit)
        tar_unit = "s"
        var.convert(tar_unit)
        self.assertTrue(np.all(var.data.filled() == [-1, 86400]))
        self.assertEqual(var.unit, "s")

        tar_unit = "m"
        with self.assertRaises(ValueError):
            var.convert(tar_unit)
Esempio n. 14
0
    def get_acc_gross_internal_flux(self,
                                    mr,
                                    pool_name_from,
                                    pool_name_to,
                                    nr_layer_from=0,
                                    nr_layer_to=0,
                                    name=''):
        ms = self.model_structure
        pool_nr_from = ms.get_pool_nr(pool_name_from, nr_layer_from)
        pool_nr_to = ms.get_pool_nr(pool_name_to, nr_layer_to)
        Fs = mr.acc_gross_internal_flux_matrix()

        if name == '':
            name = ms.get_horizontal_flux_var(pool_name_from, pool_name_to)

        return Variable(name=name,
                        data=Fs[:, pool_nr_to, pool_nr_from],
                        unit=self.stock_unit)
Esempio n. 15
0
    def test_StockDensityVariable2StockVariable(self):
        ds = self.mdo.dataset
        nr_layers = self.mdo.model_structure.get_nr_layers("CWD")

        sdv = readVariable(
            ReturnClass=StockVariable,
            dataset=ds,
            variable_name="CWDC",
            nr_layers=nr_layers,
            data_shift=0,
        )
        dz = Variable(data=ds["dz"][:], unit=ds["dz"].units)

        sv = StockDensityVariable2StockVariable(sdv, dz)
        self.assertTrue(isinstance(sv, StockVariable))
        self.assertEqual(sv.unit, "m-2.kg")
        res = sv.data[4, ...] * 1000
        res2 = np.array([12, 26, 42])
        self.assertTrue(np.allclose(res, res2))
Esempio n. 16
0
def _load_mdo(ds_dict, time_step_in_days, check_units=True): # time step in days
    ms = load_model_structure()

    # no unit support for dictionary version
    time = Variable(
        name="time",
        data=np.arange(len(ds_dict['time'])) * time_step_in_days,
        unit="d"
#        unit="1"
    )

    mdo = ModelDataObject(
        model_structure=ms,
        dataset=ds_dict, 
        stock_unit="gC/m2", 
#        stock_unit="1", 
        time=time,
        check_units=check_units
    )

    return mdo
Esempio n. 17
0
def load_mdo(ds, parameter_set):
    nstep = parameter_set.get("nstep", 1)
    stock_unit = parameter_set["stock_unit"]
    nr_layers = parameter_set["nr_layers"]
    dz_var_name = parameter_set["dz_var_name"]
    dz_var_names = parameter_set["dz_var_names"]

    ms = load_model_structure(nr_layers, dz_var_name)

    time = Variable(name="time", data=np.arange(len(ds.time)), unit="d")

    mdo = ModelDataObject(
        model_structure=ms,
        dataset=ds,
        nstep=nstep,
        stock_unit=stock_unit,
        time=time,
        dz_var_names=dz_var_names,
    )

    return mdo
Esempio n. 18
0
def load_mdo(ds):
    #    days_per_month = np.array(np.diff(ds.time), dtype='timedelta64[D]').astype(float)

    ms = load_model_structure()

    # bring fluxes from gC/m2/day to gC/m2/month

    ## all months are supposed to comprise 365.25/12 days
    days_per_month = 365.25 / 12.0

    time = Variable(
        name="time",
        data=np.arange(len(ds.time)) * days_per_month,
        unit="d"
    )

    mdo = ModelDataObject(
        model_structure=ms,
        dataset=ds, 
        stock_unit="gC/m2", 
        time=time
    )
    return mdo
Esempio n. 19
0
    def test_absolute_and_relative_error(self):
        v_right = Variable(data=np.arange(10).reshape(2, 5), unit="m")
        v_wrong = Variable(data=np.arange(10).reshape(2, 5) + 1, unit="m")
        abs_err = v_wrong.absolute_error(v_right)
        self.assertTrue(np.all(abs_err.data == np.ones(10).reshape(2, 5)))
        self.assertEqual(abs_err.unit, "m")
        rel_err = v_wrong.relative_error(v_right)
        res = 100 / np.ma.arange(10).reshape(2, 5)
        self.assertTrue(np.all(rel_err.data == res.data))
        self.assertEqual(rel_err.unit, "%")

        ## convertible units
        v_right = Variable(data=np.arange(10).reshape(2, 5) * 1000, unit="m")
        v_wrong = Variable(data=np.arange(10).reshape(2, 5) + 1, unit="km")
        abs_err = v_wrong.absolute_error(v_right)
        self.assertTrue(np.all(abs_err.data == np.ones(10).reshape(2, 5) * 1000))
        self.assertEqual(abs_err.unit, "m")
        rel_err = v_wrong.relative_error(v_right)
        res = 100 / np.ma.arange(10).reshape(2, 5)
        self.assertTrue(np.all(rel_err.data == res.data))
        self.assertEqual(rel_err.unit, "%")

        ## unconvertible units
        v_right = Variable(data=np.arange(10).reshape(2, 5) * 1000, unit="m")
        v_wrong = Variable(data=np.arange(10).reshape(2, 5) + 1, unit="km/s")
        with self.assertRaises(ValueError):
            abs_err = v_wrong.absolute_error(v_right)
        with self.assertRaises(ValueError):
            rel_err = v_wrong.relative_error(v_right)

        ## incompatible shapes
        v_right = Variable(data=np.arange(10) * 1000, unit="m")
        v_wrong = Variable(data=np.arange(10).reshape(2, 5) + 1, unit="km/s")
        with self.assertRaises(AssertionError):
            abs_err = v_wrong.absolute_error(v_right)
        with self.assertRaises(AssertionError):
            rel_err = v_wrong.relative_error(v_right)
Esempio n. 20
0
def MDO_3pools_nolayers_nogrid():
    ## set up test model strcture

    pool_structure = [
        {
            "pool_name": "CWD",
            "stock_var": "CWDC",
        },
        {
            "pool_name": "Litter",
            "stock_var": "LITRC",
        },
        {
            "pool_name": "Soil",
            "stock_var": "SOILC",
        },
    ]

    external_input_structure = {
        "CWD": ["fire_CWD"],
    }

    horizontal_structure = {
        ("CWD", "Litter"): ["CWD_TO_LITR"],
    }

    external_output_structure = {
        "CWD": ["CWD_HR"],
    }

    model_structure = ModelStructure(
        pool_structure=pool_structure,
        external_input_structure=external_input_structure,
        horizontal_structure=horizontal_structure,
        external_output_structure=external_output_structure,
    )

    ## set up a test dataset
    time = np.arange(10)

    ds = Dataset("test_dataset2.nc", "w", diskless=True, persist=False)
    ds.createDimension("time", len(time))

    time_var = ds.createVariable("time", "f8", ("time", ))
    time_var[:] = time
    time_var.units = "d"

    ## introduce some test variables to test dataset

    ## stocks
    var = ds.createVariable("CWDC", "f8", ("time", ))
    data = np.arange(len(time))
    var[...] = data
    var.units = "gC/m^2"
    var.cell_methods = "time: instantaneous"

    var = ds.createVariable("LITRC", "f8", ("time", ))
    data = np.arange(len(time)) + 0.1
    var[...] = data
    var.units = "gC/m^2"
    var.cell_methods = "time: instantaneous"

    var = ds.createVariable("SOILC", "f8", ("time", ))
    data = np.arange(len(time)) + 0.2
    var[...] = data.copy()
    var.units = "gC/m^2"
    var.cell_methods = "time: instantaneous"

    ## external input fluxes
    var = ds.createVariable("fire_CWD", "f8", ("time", ))
    data = np.arange(len(time)) * 1e-03
    var[...] = data
    var.units = "gC/m^2/s"
    var.cell_methods = "time: mean"

    ## horizontal fluxes
    var = ds.createVariable("CWD_TO_LITR", "f8", ("time", ))
    data = np.arange(len(time)) * 1e-03
    var[...] = data
    var.units = "gC/m^2/s"
    var.cell_methods = "time: mean"

    ## external_output_fluxes
    var = ds.createVariable("CWD_HR", "f8", ("time", ))
    data = np.arange(len(time))
    var[...] = data
    var.units = "gC/m^2/s"
    var.cell_methods = "time: mean"

    ## set up a ModelDataObject
    nstep = 2
    stock_unit = "g/m^2"
    #    cftime_unit_src  = 'days since 1850-01-01 00:00:00'
    #    calendar_src     = 'noleap'
    #    max_time         = 8

    time = Variable(data=time, unit="d")
    mdo = ModelDataObject(
        model_structure=model_structure,
        dataset=ds,
        nstep=nstep,
        stock_unit=stock_unit,
        time=time
        #        cftime_unit_src = cftime_unit_src,
        #        calendar_src    = calendar_src,
        #        max_time        = max_time
    )
    return mdo
Esempio n. 21
0
    def create_model_run(self, errors=False):
        out = self.load_xs_Us_Fs_Rs()
        xs, Us, Fs, Rs = out
        # print(self.time_agg.data)
        # print(xs.data)
        # print(Fs.data)
        # print(Rs.data)
        # print(Us.data)
        # input()

        times = self.time_agg.data.filled()
        # times = np.arange(len(self.time_agg.data))
        if (xs.data.mask.sum() + Fs.data.mask.sum() + Us.data.mask.sum() +
                Rs.data.mask.sum() == 0):
            pwc_mr_fd = PWCMRFD.from_gross_fluxes(
                symbols("t"),
                times,
                xs.data.filled()[0],
                # xs.data.filled(),
                Us.data.filled(),
                Fs.data.filled(),
                Rs.data.filled(),
                #                xs.data.filled()
            )
        else:
            pwc_mr_fd = None

        if errors:
            err_dict = {}

            soln = pwc_mr_fd.solve()
            soln_pwc_mr_fd = Variable(data=soln, unit=self.stock_unit)
            abs_err = soln_pwc_mr_fd.absolute_error(xs)
            rel_err = soln_pwc_mr_fd.relative_error(xs)
            err_dict["stocks"] = {"abs_err": abs_err, "rel_err": rel_err}

            Us_pwc_mr_fd = Variable(
                name="acc_gross_external_input_vector",
                data=pwc_mr_fd.acc_gross_external_input_vector(),
                unit=self.stock_unit,
            )
            abs_err = Us_pwc_mr_fd.absolute_error(Us)
            rel_err = Us_pwc_mr_fd.relative_error(Us)
            err_dict["acc_gross_external_inputs"] = {
                "abs_err": abs_err,
                "rel_err": rel_err,
            }

            Rs_pwc_mr_fd = Variable(
                name="acc_gross_external_output_vector",
                data=pwc_mr_fd.acc_gross_external_output_vector(),
                unit=self.stock_unit,
            )
            abs_err = Rs_pwc_mr_fd.absolute_error(Rs)
            rel_err = Rs_pwc_mr_fd.relative_error(Rs)
            err_dict["acc_gross_external_outputs"] = {
                "abs_err": abs_err,
                "rel_err": rel_err,
            }

            Fs_pwc_mr_fd = Variable(
                name="acc_gross_internal_flux_matrix",
                data=pwc_mr_fd.acc_gross_internal_flux_matrix(),
                unit=self.stock_unit,
            )
            abs_err = Fs_pwc_mr_fd.absolute_error(Fs)
            rel_err = Fs_pwc_mr_fd.relative_error(Fs)
            err_dict["acc_gross_internal_fluxes"] = {
                "abs_err": abs_err,
                "rel_err": rel_err,
            }

            return pwc_mr_fd, err_dict
        else:
            return pwc_mr_fd
Esempio n. 22
0
def MDO_3pools_3layers_nogrid():
    ## set up test model strcture

    nr_layers = 3
    dz_var_name = "dz"

    pool_structure = [
        {
            "pool_name": "CWD",
            "stock_var": "CWDC",
            "nr_layers": nr_layers,
            "dz_var": dz_var_name,
        },
        {
            "pool_name": "Litter",
            "stock_var": "LITRC",
            "nr_layers": nr_layers,
            "dz_var": dz_var_name,
        },
        {
            "pool_name": "Soil",
            "stock_var": "SOILC",
            "nr_layers": nr_layers,
            "dz_var": dz_var_name,
        },
    ]

    external_input_structure = {
        "CWD": ["fire_CWD"],
    }

    horizontal_structure = {("CWD", "Litter"): ["CWD_TO_LITR"]}

    external_output_structure = {
        "CWD": ["CWD_HR"],
    }

    model_structure = ModelStructure(
        pool_structure=pool_structure,
        external_input_structure=external_input_structure,
        horizontal_structure=horizontal_structure,
        external_output_structure=external_output_structure,
    )

    ## set up a test dataset
    time = np.arange(10)
    dz = np.arange(nr_layers) + 1

    ds = Dataset("test_dataset4.nc", "w", diskless=True, persist=False)
    ds.createDimension("time", len(time))
    ds.createDimension("level", nr_layers)

    time_var = ds.createVariable("time", "f8", ("time", ))
    time_var[:] = time
    time_var.units = "d"

    dz_var = ds.createVariable("dz", "f4", ("level"))
    dz_var[:] = dz
    dz_var.units = "m"

    ## introduce some test variables to test dataset

    ## stocks
    var = ds.createVariable("CWDC", "f8", ("time", "level"))
    data = np.arange(len(time) * nr_layers)
    var[...] = data.reshape(len(time), nr_layers)
    var.units = "gC14/m^3"
    var.cell_methods = "time: instantaneous"

    var = ds.createVariable("LITRC", "f8", ("time", "level"))
    data = np.arange(len(time) * nr_layers) + 0.1
    var[...] = data.reshape(len(time), nr_layers)
    var.units = "gC14/m^3"
    var.cell_methods = "time: instantaneous"

    var = ds.createVariable("SOILC", "f8", ("time", "level"))
    data = np.arange(len(time) * nr_layers) + 0.2
    var[...] = data.reshape(len(time), nr_layers)
    var.units = "gC14/m^3"
    var.cell_methods = "time: instantaneous"

    ## external input fluxes
    var = ds.createVariable("fire_CWD", "f8", ("time", "level"))
    masked_data = np.ma.masked_array(
        data=np.arange(len(time) * nr_layers) * 1e-03,
        mask=np.zeros(len(time) * nr_layers),
    )
    masked_data.mask[21] = 1
    var[...] = masked_data.reshape(len(time), nr_layers)
    var.units = "gC14/m^3/s"
    var.cell_methods = "time: mean"

    ## horizontal fluxes
    var = ds.createVariable("CWD_TO_LITR", "f8", ("time", "level"))
    data = np.arange(len(time) * nr_layers) * 1e-03
    var[...] = data.reshape(len(time), nr_layers)
    var.units = "gC14/m^3/s"
    var.cell_methods = "time: mean"

    ## external_output_fluxes
    var = ds.createVariable("CWD_HR", "f8", ("time", "level"))
    data = np.arange(len(time) * nr_layers)
    var[...] = data.reshape(len(time), nr_layers)
    var.units = "gC14/m^3/s"
    var.cell_methods = "time: mean"

    ## set up a ModelDataObject
    nstep = 2
    stock_unit = "g/m^2"
    #    cftime_unit_src  = 'days since 1900-01-01 00:00:00'
    #    calendar_src     = 'noleap'
    #    max_time         = 8

    time = Variable(data=time, unit="d")
    mdo = ModelDataObject(
        model_structure=model_structure,
        dataset=ds,
        nstep=nstep,
        stock_unit=stock_unit,
        time=time
        #        cftime_unit_src = cftime_unit_src,
        #        calendar_src    = calendar_src,
        #        max_time        = max_time
    )
    return mdo
Esempio n. 23
0
def MDO_3pools_3layers_discretizable():
    ## set up test model strcture
    nr_layers = 3
    dz_var_name = "dz"

    pool_structure = [
        {
            "pool_name": "CWD",
            "stock_var": "CWDC",
            "nr_layers": nr_layers,
            "dz_var": dz_var_name,
        },
        {
            "pool_name": "Litter",
            "stock_var": "LITRC",
            "nr_layers": nr_layers,
            "dz_var": dz_var_name,
        },
        {
            "pool_name": "Soil",
            "stock_var": "SOILC",
            "nr_layers": nr_layers,
            "dz_var": dz_var_name,
        },
    ]

    external_input_structure = {"CWD": ["input_CWD"], "Litter": ["input_LITR"]}

    horizontal_structure = {
        ("CWD", "Litter"): ["CWD_TO_LITR"],
        ("Litter", "Soil"): ["LITR_TO_SOIL"],
    }

    external_output_structure = {
        "CWD": ["CWD_HR"],
        "Litter": ["LITR_HR"],
        "Soil": ["SOIL_HR"],
    }

    model_structure = ModelStructure(
        pool_structure=pool_structure,
        external_input_structure=external_input_structure,
        horizontal_structure=horizontal_structure,
        #        vertical_structure        = vertical_structure,
        external_output_structure=external_output_structure,
    )

    ## set up a test dataset
    time = np.arange(10)
    dz = np.arange(nr_layers) + 1

    ds = Dataset("test_dataset_discretizable1.nc",
                 "w",
                 diskless=True,
                 persist=False)
    ds.createDimension("time", len(time))
    ds.createDimension("level", nr_layers)

    time_var = ds.createVariable("time", "f8", ("time", ))
    time_var[:] = time
    time_var.units = "d"

    dz_var = ds.createVariable("dz", "f4", ("level"))
    dz_var[:] = dz
    dz_var.units = "m"

    ## introduce some test variables to test dataset

    ## stocks
    var = ds.createVariable("CWDC", "f8", ("time", "level"))
    data = np.ones((len(time), nr_layers)) * 1e05
    var[...] = data
    var.units = "gC/m^3"
    var.cell_methods = "time: instantaneous"

    var = ds.createVariable("LITRC", "f8", ("time", "level"))
    data = np.ones((len(time), nr_layers)) * 1e05
    var[...] = data
    var.units = "gC/m^3"
    var.cell_methods = "time: instantaneous"

    var = ds.createVariable("SOILC", "f8", ("time", "level"))
    data = np.ones((
        len(time),
        nr_layers,
    )) * 1e05
    var[...] = data.copy()
    var.units = "gC/m^3"
    var.cell_methods = "time: instantaneous"

    ## external input fluxes
    var = ds.createVariable("input_CWD", "f8", ("time", "level"))
    data = np.ones((len(time), nr_layers)) * 1e-02
    var[...] = data
    var.units = "gC/m^3/s"
    var.cell_methods = "time: mean"

    var = ds.createVariable("input_LITR", "f8", ("time", "level"))
    data = np.ones((len(time), nr_layers)) * 1e-02
    var[...] = data
    var.units = "gC/m^3/s"
    var.cell_methods = "time: mean"

    ## horizontal fluxes
    var = ds.createVariable("CWD_TO_LITR", "f8", ("time", "level"))
    data = np.ones((len(time), nr_layers)) * 1e-03
    var[...] = data
    var.units = "gC/m^3/s"
    var.cell_methods = "time: mean"

    var = ds.createVariable("LITR_TO_SOIL", "f8", ("time", "level"))
    data = np.ones((len(time), nr_layers)) * 1e-03
    var[...] = data
    var.units = "gC/m^3/s"
    var.cell_methods = "time: mean"

    ## external_output_fluxes
    var = ds.createVariable("CWD_HR", "f8", ("time", "level"))
    data = np.ones((len(time), nr_layers)) * 2 * 1e-03
    var[...] = data
    var.units = "gC/m^3/s"
    var.cell_methods = "time: mean"

    var = ds.createVariable("LITR_HR", "f8", ("time", "level"))
    data = np.ones((len(time), nr_layers)) * 2 * 1e-03
    var[...] = data
    var.units = "gC/m^3/s"
    var.cell_methods = "time: mean"

    var = ds.createVariable("SOIL_HR", "f8", ("time", "level"))
    data = np.ones((len(time), nr_layers)) * 2 * 1e-03
    var[...] = data
    var.units = "gC/m^3/s"
    var.cell_methods = "time: mean"

    ## set up a ModelDataObject
    nstep = 2
    stock_unit = "g/m^2"
    #    cftime_unit_src  = 'days since 1850-01-01 00:00:00'
    #    calendar_src     = 'noleap'
    #    max_time         = 8

    time = Variable(data=time, unit="d")
    mdo = ModelDataObject(
        model_structure=model_structure,
        dataset=ds,
        nstep=nstep,
        stock_unit=stock_unit,
        time=time
        #        cftime_unit_src = cftime_unit_src,
        #        calendar_src    = calendar_src,
        #        max_time        = max_time
    )
    return mdo
Esempio n. 24
0
def MDO_3pools_3layers():
    ## set up test model strcture
    nr_layers = 3
    dz_var_name = "dz"

    pool_structure = [
        {
            "pool_name": "CWD",
            "stock_var": "CWDC",
            "nr_layers": nr_layers,
            "dz_var": dz_var_name,
        },
        {
            "pool_name": "Litter",
            "stock_var": "LITRC",
            "nr_layers": nr_layers,
            "dz_var": dz_var_name,
        },
        {
            "pool_name": "Soil",
            "stock_var": "SOILC",
            "nr_layers": nr_layers,
            "dz_var": dz_var_name,
        },
    ]

    external_input_structure = {
        "CWD": ["fire_CWD", "gap_CWD", "harvest_CWD"],
        "Litter": ["gap_LITR", "harvest_LITR", "m_c_LITR", "phenology_LITR"],
    }

    horizontal_structure = {
        ("CWD", "Litter"): ["CWD_TO_LITR"],
        ("Litter", "Soil"): ["LITR_TO_SOIL"],
    }

    vertical_structure = {
        "Litter": {
            "to_below": ["LITR_flux_down_tb"],
            "from_below": ["LITR_flux_up_fb"],
            "to_above": [],
            "from_above": [],
        },
        "Soil": {
            "to_below": [],
            "from_below": [],
            "to_above": ["SOIL_flux_up_ta"],
            "from_above": ["SOIL_flux_down_fa"],
        },
    }

    external_output_structure = {
        "CWD": ["CWD_HR1", "CWD_HR2"],
        "Litter": ["LITR_HR"],
        "Soil": ["SOIL_HR1", "SOIL_HR2"],
    }

    model_structure = ModelStructure(
        pool_structure=pool_structure,
        external_input_structure=external_input_structure,
        horizontal_structure=horizontal_structure,
        vertical_structure=vertical_structure,
        external_output_structure=external_output_structure,
    )

    ## set up a test dataset
    time = np.arange(10)
    dz = np.arange(nr_layers) + 1

    ds = Dataset("test_dataset.nc", "w", diskless=True, persist=False)
    ds.createDimension("time", len(time))
    ds.createDimension("level", nr_layers)

    time_var = ds.createVariable("time", "f8", ("time", ))
    time_var[:] = time
    time_var.units = "d"

    dz_var = ds.createVariable("dz", "f4", ("level"))
    dz_var[:] = dz
    dz_var.units = "m"

    ## introduce some test variables to test dataset

    ## stocks
    var = ds.createVariable("CWDC", "f8", ("time", "level"))
    data = np.arange(len(time) * nr_layers).reshape((len(time), nr_layers))
    var[...] = data
    var.units = "gC/m^3"
    var.cell_methods = "time: instantaneous"

    var = ds.createVariable("LITRC", "f8", ("time", "level"))
    data = (np.arange(len(time) * nr_layers) + 0.1).reshape(
        (len(time), nr_layers))
    var[...] = data
    var.units = "gC/m^3"
    var.cell_methods = "time: instantaneous"

    var = ds.createVariable("SOILC", "f8", ("time", "level"))
    data = (np.arange(len(time) * nr_layers) + 0.2).reshape(
        (len(time), nr_layers))
    var[...] = data.copy()
    var.units = "gC/m^3"
    var.cell_methods = "time: instantaneous"

    ## external input fluxes
    var = ds.createVariable("fire_CWD", "f8", ("time", "level"))
    data = np.arange(len(time) * nr_layers).reshape(
        (len(time), nr_layers)) * 1e-03
    var[...] = data
    var.units = "gC/m^3/s"
    var.cell_methods = "time: mean"

    var = ds.createVariable("gap_CWD", "f8", ("time", "level"))
    data = (np.arange(len(time) * nr_layers) + 0.01).reshape(
        (len(time), nr_layers)) * 1e-03
    var[...] = data
    var.units = "gC/m^3/s"
    var.cell_methods = "time: mean"

    var = ds.createVariable("harvest_CWD", "f8", ("time", "level"))
    data = (np.arange(len(time) * nr_layers) + 0.02).reshape(
        (len(time), nr_layers)) * 1e-03
    var[...] = data
    var.units = "gC/m^3/s"
    var.cell_methods = "time: mean"

    var = ds.createVariable("gap_LITR", "f8", ("time", "level"))
    data = (np.arange(len(time) * nr_layers) + 0.10).reshape(
        (len(time), nr_layers)) * 1e-03
    var[...] = data
    var.units = "gC/m^3/s"
    var.cell_methods = "time: mean"

    var = ds.createVariable("harvest_LITR", "f8", ("time", "level"))
    data = (np.arange(len(time) * nr_layers) + 0.11).reshape(
        (len(time), nr_layers)) * 1e-03
    var[...] = data
    var.units = "gC/m^3/s"
    var.cell_methods = "time: mean"

    var = ds.createVariable("m_c_LITR", "f8", ("time", "level"))
    data = (np.arange(len(time) * nr_layers) + 0.12).reshape(
        (len(time), nr_layers)) * 1e-03
    var[...] = data
    var.units = "gC/m^3/s"
    var.cell_methods = "time: mean"

    var = ds.createVariable("phenology_LITR", "f8", ("time", "level"))
    data = (np.arange(len(time) * nr_layers) + 0.13).reshape(
        (len(time), nr_layers)) * 1e-03
    var[...] = data
    var.units = "gC/m^3/s"
    var.cell_methods = "time: mean"

    ## horizontal fluxes
    var = ds.createVariable("CWD_TO_LITR", "f8", ("time", "level"))
    data = np.arange(len(time) * nr_layers).reshape(
        (len(time), nr_layers)) * 1e-03
    var[...] = data
    var.units = "gC/m^3/s"
    var.cell_methods = "time: mean"

    var = ds.createVariable("LITR_TO_SOIL", "f8", ("time", "level"))
    data = (np.arange(len(time) * nr_layers) + 0.1).reshape(
        (len(time), nr_layers)) * 1e-03
    var[...] = data
    var.units = "gC/m^3/s"
    var.cell_methods = "time: mean"

    ## vertical fluxes
    var = ds.createVariable("LITR_flux_down_tb", "f8", ("time", "level"))
    data = np.arange(len(time) * nr_layers).reshape(
        (len(time), nr_layers)) * 1e-03
    var[...] = data
    var.units = "gC/m^2/s"
    var.cell_methods = "time: mean"

    var = ds.createVariable("LITR_flux_up_fb", "f8", ("time", "level"))
    data = np.arange(len(time) * nr_layers).reshape(
        (len(time), nr_layers)) * 1e-04
    var[...] = data
    var.units = "gC/m^2/s"
    var.cell_methods = "time: mean"

    var = ds.createVariable("SOIL_flux_down_fa", "f8", ("time", "level"))
    data = np.arange(len(time) * nr_layers).reshape(
        (len(time), nr_layers)) * 1e-03
    var[...] = data
    var.units = "gC/m^2/s"
    var.cell_methods = "time: mean"

    var = ds.createVariable("SOIL_flux_up_ta", "f8", ("time", "level"))
    data = np.arange(len(time) * nr_layers).reshape(
        (len(time), nr_layers)) * 1e-04
    var[...] = data
    var.units = "gC/m^2/s"
    var.cell_methods = "time: mean"

    ## external_output_fluxes
    var = ds.createVariable("CWD_HR1", "f8", ("time", "level"))
    data = np.arange(len(time) * nr_layers).reshape(
        (len(time), nr_layers)) * 1e-03
    var[...] = data
    var.units = "gC/m^3/s"
    var.cell_methods = "time: mean"

    var = ds.createVariable("CWD_HR2", "f8", ("time", "level"))
    data = (np.arange(len(time) * nr_layers) + 0.01).reshape(
        (len(time), nr_layers)) * 1e-03
    var[...] = data
    var.units = "gC/m^3/s"
    var.cell_methods = "time: mean"

    var = ds.createVariable("LITR_HR", "f8", ("time", "level"))
    data = (np.arange(len(time) * nr_layers) + 0.10).reshape(
        (len(time), nr_layers)) * 1e-03
    var[...] = data
    var.units = "gC/m^3/s"
    var.cell_methods = "time: mean"

    var = ds.createVariable("SOIL_HR1", "f8", ("time", "level"))
    data = (np.arange(len(time) * nr_layers) + 0.20).reshape(
        (len(time), nr_layers)) * 1e-03
    var[...] = data
    var.units = "gC/m^3/s"
    var.cell_methods = "time: mean"

    var = ds.createVariable("SOIL_HR2", "f8", ("time", "level"))
    data = (np.arange(len(time) * nr_layers) + 0.21).reshape(
        (len(time), nr_layers)) * 1e-03
    var[...] = data
    var.units = "gC/m^3/s"
    var.cell_methods = "time: mean"

    ## set up a ModelDataObject
    nstep = 2
    stock_unit = "g/m^2"
    #    cftime_unit_src  = 'days since 1851-01-01 00:00:00'
    #    calendar_src     = 'noleap'
    #    time_shift       = 5
    #    max_time         = 8

    time = Variable(data=time, unit="d")
    mdo = ModelDataObject(
        model_structure=model_structure,
        dataset=ds,
        nstep=nstep,
        stock_unit=stock_unit,
        time=time
        #        cftime_unit_src = cftime_unit_src,
        #        calendar_src    = calendar_src,
        #        time_shift      = time_shift,
        #        max_time        = max_time
    )
    return mdo
Esempio n. 25
0
def create_Daelta_14C_dataset(mdo, ds, mr, mr_14C):
    alpha = 1.18e-12
    t_conv = lambda t: 2001 + (15 + t) / 365.25
    F_Delta_14C = lambda C12, C14: (C14 / C12 / alpha - 1) * 1000
    ms = mdo.model_structure

    ## create 14C dataset
    data_vars = {}

    ## save stocks
    for pool_nr, pool_name in enumerate(ms.pool_names):
        var_name_ds = pool_name
        soln = mr.solve()
        soln_14C = mr_14C.solve()

        new_var = Variable(
            data=F_Delta_14C(soln[:, pool_nr], soln_14C[:, pool_nr]),
            unit=mdo.stock_unit,
        )
        add_variable(ds, data_vars, var_name_ds, new_var)

    ## save external input fluxes

    # insert np.nan at time t0
    #    raise(Exception('check units and values, use acc variants'))
    Us_monthly = Variable(
        data=np.concatenate(
            [
                np.nan * np.ones((1, len(ms.pool_names))),
                mr.acc_gross_external_input_vector(),
            ],
            axis=0,
        ),
        unit="g/(365.25/12 d)",
    )
    print(mr, Us_monthly)
    Us_monthly_14C = Variable(
        data=np.concatenate(
            [
                np.nan * np.ones((1, len(ms.pool_names))),
                mr_14C.acc_gross_external_input_vector(),
            ],
            axis=0,
        ),
        unit="g/(365.25/12 d)",
    )

    # convert to daily flux rates
    us = Us_monthly.convert("g/d")
    us_14C = Us_monthly_14C.convert("g/d")
    for pool_nr, pool_name in enumerate(ms.pool_names):
        var_name_ds = "NPP_to_" + pool_name
        new_var = Variable(
            data=F_Delta_14C(us.data[:, pool_nr], us_14C.data[:, pool_nr]), unit=us.unit
        )
        add_variable(ds, data_vars, var_name_ds, new_var)

    ## save internal fluxes

    # insert np.nan at time t0
    Fs_monthly = Variable(
        data=np.concatenate(
            [
                np.nan * np.ones((1, len(ms.pool_names), len(ms.pool_names))),
                mr.acc_gross_internal_flux_matrix(),
            ],
            axis=0,
        ),
        unit="g/(365.25/12 d)",
    )
    Fs_monthly_14C = Variable(
        data=np.concatenate(
            [
                np.nan * np.ones((1, len(ms.pool_names), len(ms.pool_names))),
                mr_14C.acc_gross_internal_flux_matrix(),
            ],
            axis=0,
        ),
        unit="g/(365.25/12 d)",
    )

    # convert to daily flux rates
    fs = Fs_monthly.convert("g/d")
    fs_14C = Fs_monthly_14C.convert("g/d")
    for pnr_from, pn_from in enumerate(ms.pool_names):
        for pnr_to, pn_to in enumerate(ms.pool_names):
            var_name_ds = pn_from + "_to_" + pn_to
            new_var = Variable(
                data=F_Delta_14C(
                    fs.data[:, pnr_to, pnr_from], fs_14C.data[:, pnr_to, pnr_from]
                ),
                unit=fs.unit,
            )
            add_variable(ds, data_vars, var_name_ds, new_var)

    ## save external output fluxes

    # insert np.nan at time t0
    Rs_monthly = Variable(
        data=np.concatenate(
            [
                np.nan * np.ones((1, len(ms.pool_names))),
                mr.acc_gross_external_output_vector(),
            ],
            axis=0,
        ),
        unit="g/(365.25/12 d)",
    )
    Rs_monthly_14C = Variable(
        data=np.concatenate(
            [
                np.nan * np.ones((1, len(ms.pool_names))),
                mr_14C.acc_gross_external_output_vector(),
            ],
            axis=0,
        ),
        unit="g/(365.25/12 d)",
    )

    # convert to daily flux rates
    rs = Rs_monthly.convert("g/d")
    rs_14C = Rs_monthly_14C.convert("g/d")
    for pool_nr, pool_name in enumerate(ms.pool_names):
        var_name_ds = pool_name + "_to_RH"
        new_var = Variable(
            data=F_Delta_14C(rs.data[:, pool_nr], rs_14C.data[:, pool_nr]), unit=rs.unit
        )
        add_variable(ds, data_vars, var_name_ds, new_var)

    ds_Delta_14C = xr.Dataset(data_vars=data_vars, coords=ds.coords, attrs=ds.attrs)

    return ds_Delta_14C
Esempio n. 26
0
    def test_aggregateInTime(self):
        ## one-dimensioanl data (time-like)
        data = np.arange(10)
        unit = "kg"
        var = Variable(data=data, unit=unit)

        nstep = 1
        var_agg = var.aggregateInTime(nstep)
        res2 = np.arange(10)
        self.assertTrue(np.all(var_agg.data == res2))

        nstep = 2
        var_agg = var.aggregateInTime(nstep)
        res2 = np.array([0, 2, 4, 6, 8, 9])
        self.assertTrue(np.all(var_agg.data == res2))

        nstep = 3
        var_agg = var.aggregateInTime(nstep)
        res2 = np.array([0, 3, 6, 9])
        self.assertTrue(np.all(var_agg.data == res2))

        ## multi-dimensional
        data = np.arange(20).reshape((10, 2))
        unit = "kg"
        var = Variable(data=data, unit=unit)

        nstep = 3
        var_agg = var.aggregateInTime(nstep)
        res2 = [[0, 1], [6, 7], [12, 13], [18, 19]]
        self.assertTrue(np.all(var_agg.data == res2))

        ## test mask
        masked_data = np.ma.masked_array(
            data=np.arange(10), mask=[0, 0, 1, 1, 0, 1, 1, 0, 0, 0], fill_value=-1
        )
        var = Variable(data=masked_data, unit=unit)

        nstep = 1
        var_agg = var.aggregateInTime(nstep)
        res2 = np.ma.masked_array(
            data=np.arange(10), mask=[0, 0, 1, 1, 0, 1, 1, 0, 0, 0], fill_value=-1
        )
        self.assertTrue(np.all(var_agg.data.filled() == res2.filled()))

        nstep = 2
        var_agg = var.aggregateInTime(nstep)
        res2 = np.array([0, -1, 4, -1, 8, 9])
        self.assertTrue(np.all(var_agg.data.filled() == res2))
Esempio n. 27
0
    def create_model_run(self,
                         integration_method='solve_ivp',
                         nr_nodes=None,
                         errors=False,
                         check_success=True):
        out = self.load_xs_Us_Fs_Rs()
        xs, Us, Fs, Rs = out
        # print(self.time_agg.data)
        # print(xs.data)
        # print(Fs.data)
        # print(Rs.data)
        # print(Us.data)
        # input()

        times = self.time_agg.data.filled()
        # times = np.arange(len(self.time_agg.data))
        if (xs.data.mask.sum() + Fs.data.mask.sum() + Us.data.mask.sum() +
                Rs.data.mask.sum() == 0):
            pwc_mr_fd = PWCMRFD.from_gross_fluxes(symbols("t"), times,
                                                  xs.data.filled()[0],
                                                  Us.data.filled(),
                                                  Fs.data.filled(),
                                                  Rs.data.filled(),
                                                  xs.data.filled(),
                                                  integration_method, nr_nodes,
                                                  check_success)
        else:
            pwc_mr_fd = None

        if errors:
            #            print('Computing reconstruction errors')
            err_dict = {}

            #            print('  solution error')
            soln = pwc_mr_fd.solve()
            soln_pwc_mr_fd = Variable(name="stocks",
                                      data=soln,
                                      unit=self.stock_unit)
            abs_err = soln_pwc_mr_fd.absolute_error(xs)
            rel_err = soln_pwc_mr_fd.relative_error(xs)
            err_dict["stocks"] = {
                "abs_err": abs_err.max(),
                "rel_err": rel_err.max()
            }

            #            print('  input fluxes error')
            Us_pwc_mr_fd = Variable(
                name="acc_gross_external_input_vector",
                data=pwc_mr_fd.acc_gross_external_input_vector(),
                unit=self.stock_unit,
            )
            abs_err = Us_pwc_mr_fd.absolute_error(Us)
            rel_err = Us_pwc_mr_fd.relative_error(Us)
            err_dict["acc_gross_external_inputs"] = {
                "abs_err": abs_err.max(),
                "rel_err": rel_err.max(),
            }

            #            print('  output fluxes error')
            Rs_pwc_mr_fd = Variable(
                name="acc_gross_external_output_vector",
                data=pwc_mr_fd.acc_gross_external_output_vector(),
                unit=self.stock_unit,
            )
            abs_err = Rs_pwc_mr_fd.absolute_error(Rs)
            rel_err = Rs_pwc_mr_fd.relative_error(Rs)
            err_dict["acc_gross_external_outputs"] = {
                "abs_err": abs_err.max(),
                "rel_err": rel_err.max(),
            }

            #            print('  internal fluxes error')
            Fs_pwc_mr_fd = Variable(
                name="acc_gross_internal_flux_matrix",
                data=pwc_mr_fd.acc_gross_internal_flux_matrix(),
                unit=self.stock_unit,
            )
            abs_err = Fs_pwc_mr_fd.absolute_error(Fs)
            rel_err = Fs_pwc_mr_fd.relative_error(Fs)
            err_dict["acc_gross_internal_fluxes"] = {
                "abs_err": abs_err.max(),
                "rel_err": rel_err.max(),
            }
            abs_err.argmax()
            rel_err.argmax()

            #            print('done')
            return pwc_mr_fd, err_dict
        else:
            return pwc_mr_fd, dict()