def test_set_observed_state(self): # set up configuration config_dir = path.join(path.dirname(__file__), "netcdf") cfg = orchestration.YAMLConfig("atnsjoen_simulation.yaml", "atnsjoen", config_dir=config_dir, data_dir=shyftdata_dir) # get a simulator simulator = cfg.get_simulator() n_cells = simulator.region_model.size() state_repos = DefaultStateRepository(cfg.model_t, n_cells) state = state_repos.get_state(0) simulator.run(cfg.time_axis, state) simulator.region_model.get_states(state) obs_discharge = 0.0 state = simulator.discharge_adjusted_state(obs_discharge, state) self.assertAlmostEqual( 0.0, reduce(operator.add, (state[i].kirchner.q for i in range(state.size())))) simulator.region_model.get_states(state) obs_discharge = 10.0 # m3/s state = simulator.discharge_adjusted_state(obs_discharge, state) # Convert from l/h to m3/s by dividing by 3.6e6 adj_discharge = reduce( operator.add, (state[i].kirchner.q * cell.geo.area() for (i, cell) in enumerate(simulator.region_model.get_cells()) )) / (3.6e6) self.assertAlmostEqual(obs_discharge, adj_discharge)
def run_calibration(self, model_t): # set up configuration config_dir = path.join(path.dirname(__file__), "netcdf") cfg = orchestration.YAMLConfig( "atnsjoen_calibration.yaml", "atnsjoen", config_dir=config_dir, data_dir=shyftdata_dir, model_t=model_t) time_axis = cfg.time_axis # get a simulator simulator = cfg.get_simulator() n_cells = simulator.region_model.size() state_repos = DefaultStateRepository(cfg.model_t, n_cells) simulator.run(time_axis, state_repos.get_state(0)) cid = 1 target_discharge_ts = simulator.region_model.statistics.discharge([cid]) target_discharge = api.TsTransform().to_average(time_axis.time(0), time_axis.time(1)-time_axis.time(0), time_axis.size(), target_discharge_ts) # Perturb parameters param = simulator.region_model.get_region_parameter() p_vec_orig = [param.get(i) for i in range(param.size())] p_vec_min = p_vec_orig[:] p_vec_max = p_vec_orig[:] p_vec_guess = p_vec_orig[:] random.seed(0) p_names = [] for i in range(4): p_names.append(param.get_name(i)) p_vec_min[i] *= 0.5 p_vec_max[i] *= 1.5 p_vec_guess[i] = random.uniform(p_vec_min[i], p_vec_max[i]) if p_vec_min[i] > p_vec_max[i]: p_vec_min[i], p_vec_max[i] = p_vec_max[i], p_vec_min[i] p_min = simulator.region_model.parameter_t() p_max = simulator.region_model.parameter_t() p_guess = simulator.region_model.parameter_t() p_min.set(p_vec_min) p_max.set(p_vec_max) p_guess.set(p_vec_guess) # Find parameters target_spec = api.TargetSpecificationPts(target_discharge, api.IntVector([cid]), 1.0, api.KLING_GUPTA) target_spec_vec = api.TargetSpecificationVector() #([target_spec]) does not yet work target_spec_vec.append(target_spec) p_opt = simulator.optimize(time_axis, state_repos.get_state(0), target_spec_vec, p_guess, p_min, p_max) simulator.region_model.set_catchment_parameter(cid, p_opt) simulator.run(time_axis, state_repos.get_state(0)) found_discharge = simulator.region_model.statistics.discharge([cid]) t_vs = np.array([target_discharge.value(i) for i in range(target_discharge.size())]) t_ts = np.array([target_discharge.time(i) for i in range(target_discharge.size())]) f_vs = np.array([found_discharge.value(i) for i in range(found_discharge.size())]) f_ts = np.array([found_discharge.time(i) for i in range(found_discharge.size())]) self.assertTrue(np.linalg.norm(t_ts - f_ts) < 1.0e-10) self.assertTrue(np.linalg.norm(t_vs - f_vs) < 1.0e-3)
def test_run_geo_ts_data_simulator(self): # set up configuration config_dir = path.join(path.dirname(__file__), "netcdf") cfg = orchestration.YAMLConfig( "atnsjoen_simulation.yaml", "atnsjoen", config_dir=config_dir, data_dir=shyftdata_dir) # get a simulator simulator = cfg.get_simulator() n_cells = simulator.region_model.size() state_repos = DefaultStateRepository(cfg.model_t, n_cells) simulator.run(cfg.time_axis, state_repos.get_state(0)) sim_copy = simulator.copy() sim_copy.run(cfg.time_axis,state_repos.get_state(0))
def test_set_observed_state(self): # set up configuration config_dir = path.join(path.dirname(__file__), "netcdf") cfg = orchestration.YAMLConfig("atnsjoen_simulation.yaml", "atnsjoen", config_dir=config_dir, data_dir=shyftdata_dir) # get a simulator simulator = cfg.get_simulator() state_repos = DefaultStateRepository(simulator.region_model) state = state_repos.get_state(0) simulator.run( cfg.time_axis, state ) # Here we have already checked if StateIDs match with model cell ID. Further check is redundant. #simulator.region_model.get_states(state.state_vector) state = simulator.reg_model_state obs_discharge = 0.0 state = simulator.discharge_adjusted_state(obs_discharge, state) self.assertAlmostEqual( 0.0, reduce(operator.add, (state[i].state.kirchner.q for i in range(len(state))))) #simulator.region_model.get_states(state.state_vector) state = simulator.reg_model_state obs_discharge = 10.0 # m3/s state = simulator.discharge_adjusted_state(obs_discharge, state) # Convert from l/h to m3/s by dividing by 3.6e6 adj_discharge = reduce( operator.add, (state[i].state.kirchner.q * cell.geo.area() for (i, cell) in enumerate(simulator.region_model.get_cells()) )) / (3.6e6) self.assertAlmostEqual(obs_discharge, adj_discharge)
def run_calibration(self, model_t): # set up configuration config_dir = path.join(path.dirname(__file__), "netcdf") cfg = orchestration.YAMLConfig("atnsjoen_calibration.yaml", "atnsjoen", config_dir=config_dir, data_dir=shyftdata_dir, model_t=model_t) time_axis = cfg.time_axis # get a simulator simulator = cfg.get_simulator() n_cells = simulator.region_model.size() state_repos = DefaultStateRepository(cfg.model_t, n_cells) s0 = state_repos.get_state(0) param = simulator.region_model.get_region_parameter() # not needed, we auto initialize to default if not done explicitely #if model_t in [pt_hs_k.PTHSKOptModel]: # for i in range(len(s0)): # s0[i].snow.distribute(param.hs) simulator.run(time_axis, s0) cid = 1 target_discharge_ts = simulator.region_model.statistics.discharge( [cid]) target_discharge = api.TsTransform().to_average( time_axis.time(0), time_axis.time(1) - time_axis.time(0), time_axis.size(), target_discharge_ts) # Perturb parameters p_vec_orig = [param.get(i) for i in range(param.size())] p_vec_min = p_vec_orig[:] p_vec_max = p_vec_orig[:] p_vec_guess = p_vec_orig[:] random.seed(0) p_names = [] for i in range(4): p_names.append(param.get_name(i)) p_vec_min[i] *= 0.5 p_vec_max[i] *= 1.5 p_vec_guess[i] = random.uniform(p_vec_min[i], p_vec_max[i]) if p_vec_min[i] > p_vec_max[i]: p_vec_min[i], p_vec_max[i] = p_vec_max[i], p_vec_min[i] p_min = simulator.region_model.parameter_t() p_max = simulator.region_model.parameter_t() p_guess = simulator.region_model.parameter_t() p_min.set(p_vec_min) p_max.set(p_vec_max) p_guess.set(p_vec_guess) # Find parameters target_spec = api.TargetSpecificationPts(target_discharge, api.IntVector([cid]), 1.0, api.KLING_GUPTA) target_spec_vec = api.TargetSpecificationVector( ) # ([target_spec]) does not yet work target_spec_vec.append(target_spec) self.assertEqual(simulator.optimizer.trace_size, 0) # before optmize, trace_size should be 0 p_opt = simulator.optimize(time_axis, s0, target_spec_vec, p_guess, p_min, p_max) self.assertGreater(simulator.optimizer.trace_size, 0) # after opt, some trace values should be there # the trace values are in the order of appearance 0...trace_size-1 # goal_fn_values = simulator.optimizer.trace_goal_function_values.to_numpy( ) # all of them, as np array self.assertEqual(len(goal_fn_values), simulator.optimizer.trace_size) p_last = simulator.optimizer.trace_parameter( simulator.optimizer.trace_size - 1) # get out the last (not neccessary the best) self.assertIsNotNone(p_last) simulator.region_model.set_catchment_parameter(cid, p_opt) simulator.run(time_axis, s0) found_discharge = simulator.region_model.statistics.discharge([cid]) t_vs = np.array([ target_discharge.value(i) for i in range(target_discharge.size()) ]) t_ts = np.array( [target_discharge.time(i) for i in range(target_discharge.size())]) f_vs = np.array( [found_discharge.value(i) for i in range(found_discharge.size())]) f_ts = np.array( [found_discharge.time(i) for i in range(found_discharge.size())]) self.assertTrue(np.linalg.norm(t_ts - f_ts) < 1.0e-10) self.assertTrue(np.linalg.norm(t_vs - f_vs) < 1.0e-3)