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[:]))
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")
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()))
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
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
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
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)
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
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
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))
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)
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
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)
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)
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))
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
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
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
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)
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
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
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
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
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
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
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))
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()