From ed96ce6835c89f7a3e85a3fb395a37d21fc72ec2 Mon Sep 17 00:00:00 2001 From: HenrZu <69154294+HenrZu@users.noreply.github.com> Date: Wed, 8 May 2024 14:50:20 +0200 Subject: [PATCH 01/46] short test example. Reset later --- cpp/examples/ode_secir_ageres.cpp | 48 +++++++++++++------------------ 1 file changed, 20 insertions(+), 28 deletions(-) diff --git a/cpp/examples/ode_secir_ageres.cpp b/cpp/examples/ode_secir_ageres.cpp index b10f0fbca7..8ada6cac62 100644 --- a/cpp/examples/ode_secir_ageres.cpp +++ b/cpp/examples/ode_secir_ageres.cpp @@ -18,6 +18,7 @@ * limitations under the License. */ #include "ode_secir/model.h" +#include "ode_secir/parameters_io.h" #include "memilio/utils/time_series.h" #include "memilio/utils/logging.h" #include "memilio/compartments/simulation.h" @@ -33,8 +34,6 @@ int main() mio::log_info("Simulating SECIR; t={} ... {} with dt = {}.", t0, tmax, dt); - double cont_freq = 10; // see Polymod study - double nb_total_t0 = 10000, nb_exp_t0 = 100, nb_inf_t0 = 50, nb_car_t0 = 50, nb_hosp_t0 = 20, nb_icu_t0 = 10, nb_rec_t0 = 10, nb_dead_t0 = 0; @@ -44,7 +43,7 @@ int main() // theta = theta_in; // icu per hospitalized // delta = delta_in; // deaths per ICUs - mio::osecir::Model model(3); + mio::osecir::Model model(6); auto nb_groups = model.parameters.get_num_groups(); double fact = 1.0 / (double)(size_t)nb_groups; @@ -79,38 +78,31 @@ int main() params.get()[i] = 0.25; params.get()[i] = 0.45; params.get()[i] = 0.2; - params.get()[i] = 0.25; + params.get()[i] = 0.45; params.get()[i] = 0.3; } model.apply_constraints(); - mio::ContactMatrixGroup& contact_matrix = params.get(); - contact_matrix[0] = - mio::ContactMatrix(Eigen::MatrixXd::Constant((size_t)nb_groups, (size_t)nb_groups, fact * cont_freq)); - contact_matrix.add_damping(Eigen::MatrixXd::Constant((size_t)nb_groups, (size_t)nb_groups, 0.7), - mio::SimulationTime(30.)); - - mio::TimeSeries secir = simulate(t0, tmax, dt, model); - - bool print_to_terminal = true; + // tests + const auto num_age_groups = 6; + const auto TEST_DATA_DIR = "/localdata1/code_2024/memilio/data/"; + const auto results_dir = "/localdata1/code_2024/memilio/test"; + std::vector models1 = {model}; + auto status_export = mio::osecir::export_input_data_county_timeseries( + models1, results_dir, {1001}, {2020, 12, 01}, std::vector(size_t(num_age_groups), 1.0), 1.0, 1, + mio::path_join(TEST_DATA_DIR, "pydata/Germany", "county_divi_ma7.json"), + mio::path_join(TEST_DATA_DIR, "pydata/Germany", "cases_all_county_age_ma7.json"), + mio::path_join(TEST_DATA_DIR, "pydata/Germany", "county_current_population.json")); - if (print_to_terminal) { + std::vector models2 = {model}; + auto read_result1 = mio::osecir::read_input_data_county(models2, {2020, 12, 01}, {1001}, + std::vector(size_t(num_age_groups), 1.0), 1.0, + TEST_DATA_DIR, 1, false); - std::vector vars = {"S", "E", "C", "C_confirmed", "I", "I_confirmed", "H", "U", "R", "D"}; - printf("Number of time points :%d\n", static_cast(secir.get_num_time_points())); - printf("People in\n"); + mio::TimeSeries secir = simulate(0.0, 1.0, 1.0, models2[0]); - for (size_t k = 0; k < (size_t)mio::osecir::InfectionState::Count; k++) { - double dummy = 0; + std::cout << secir.get_value(0) << std::endl; - for (size_t i = 0; i < (size_t)params.get_num_groups(); i++) { - printf("\t %s[%d]: %.0f", vars[k].c_str(), (int)i, - secir.get_last_value()[k + (size_t)mio::osecir::InfectionState::Count * (int)i]); - dummy += secir.get_last_value()[k + (size_t)mio::osecir::InfectionState::Count * (int)i]; - } - - printf("\t %s_otal: %.0f\n", vars[k].c_str(), dummy); - } - } + mio::unused(read_result1); } From 92e778b9677a0be40308cd60853e81426744d313 Mon Sep 17 00:00:00 2001 From: HenrZu <69154294+HenrZu@users.noreply.github.com> Date: Fri, 10 May 2024 10:10:46 +0200 Subject: [PATCH 02/46] extrapolate function now shorter --- cpp/models/ode_secir/parameters_io.h | 126 +++------------------------ 1 file changed, 14 insertions(+), 112 deletions(-) diff --git a/cpp/models/ode_secir/parameters_io.h b/cpp/models/ode_secir/parameters_io.h index 35279228b2..0b983ed27e 100644 --- a/cpp/models/ode_secir/parameters_io.h +++ b/cpp/models/ode_secir/parameters_io.h @@ -139,7 +139,7 @@ IOResult set_population_data(std::vector& model, const std::string& /** * @brief sets populations data from RKI into a Model with one age group -* @param model vector of objects in which the data is set +* @param model vector of models in which the data is set. Copy is made to avoid changing the original model * @param data_dir Path to RKI files * @param results_dir Path to result files * @param region vector of keys of the region of interest @@ -149,120 +149,25 @@ IOResult set_population_data(std::vector& model, const std::string& * @param scaling_factor_inf factors by which to scale the confirmed cases of rki data */ template -IOResult -export_input_data_county_timeseries(std::vector& model, const std::string& dir, std::vector const& region, - Date date, const std::vector& scaling_factor_inf, double scaling_factor_icu, - int num_days, const std::string& divi_data_path, - const std::string& confirmed_cases_path, const std::string& population_data_path) +IOResult export_input_data_county_timeseries(std::vector models, const std::string& dir, + std::vector const& region, Date date, + const std::vector& scaling_factor_inf, + double scaling_factor_icu, int num_days) { - std::vector> t_InfectedNoSymptoms{model.size()}; - std::vector> t_Exposed{model.size()}; - std::vector> t_InfectedSymptoms{model.size()}; - std::vector> t_InfectedSevere{model.size()}; - std::vector> t_InfectedCritical{model.size()}; - - std::vector> mu_C_R{model.size()}; - std::vector> mu_I_H{model.size()}; - std::vector> mu_H_U{model.size()}; - std::vector> mu_U_D{model.size()}; - - std::vector sum_mu_I_U(region.size(), 0); - std::vector> mu_I_U{model.size()}; - - const size_t num_age_groups = ConfirmedCasesDataEntry::age_group_names.size(); - - BOOST_OUTCOME_TRY(auto&& case_data, mio::read_confirmed_cases_data(confirmed_cases_path)); - - for (size_t node = 0; node < model.size(); node++) { - for (size_t group = 0; group < ConfirmedCasesDataEntry::age_group_names.size(); group++) { - - t_Exposed[node].push_back( - static_cast(std::round(model[node].parameters.template get()[AgeGroup(group)]))); - t_InfectedNoSymptoms[node].push_back(static_cast( - std::round(model[node].parameters.template get()[AgeGroup(group)]))); - t_InfectedSymptoms[node].push_back(static_cast( - std::round(model[node].parameters.template get()[AgeGroup(group)]))); - t_InfectedSevere[node].push_back(static_cast( - std::round(model[node].parameters.template get()[AgeGroup(group)]))); - t_InfectedCritical[node].push_back(static_cast( - std::round(model[node].parameters.template get()[AgeGroup(group)]))); - - mu_C_R[node].push_back( - model[node].parameters.template get()[AgeGroup(group)]); - mu_I_H[node].push_back(model[node].parameters.template get()[AgeGroup(group)]); - mu_H_U[node].push_back(model[node].parameters.template get()[AgeGroup(group)]); - mu_U_D[node].push_back(model[node].parameters.template get()[AgeGroup(group)]); - - sum_mu_I_U[node] += model[node].parameters.template get()[AgeGroup(group)] * - model[node].parameters.template get()[AgeGroup(group)]; - mu_I_U[node].push_back(model[node].parameters.template get()[AgeGroup(group)] * - model[node].parameters.template get()[AgeGroup(group)]); - } - } - + const size_t num_age_groups = scaling_factor_inf.size(); std::vector> rki_data( region.size(), TimeSeries::zero(num_days, (size_t)InfectionState::Count * num_age_groups)); for (size_t t = 0; t < static_cast(num_days); ++t) { - std::vector> num_InfectedSymptoms( - model.size(), std::vector(ConfirmedCasesDataEntry::age_group_names.size(), 0.0)); - std::vector> num_InfectedSymptomsConfirmed( - model.size(), std::vector(ConfirmedCasesDataEntry::age_group_names.size(), 0.0)); - std::vector> num_death( - model.size(), std::vector(ConfirmedCasesDataEntry::age_group_names.size(), 0.0)); - std::vector> num_rec( - model.size(), std::vector(ConfirmedCasesDataEntry::age_group_names.size(), 0.0)); - std::vector> num_Exposed( - model.size(), std::vector(ConfirmedCasesDataEntry::age_group_names.size(), 0.0)); - std::vector> num_InfectedNoSymptoms( - model.size(), std::vector(ConfirmedCasesDataEntry::age_group_names.size(), 0.0)); - std::vector> num_InfectedNoSymptomsConfirmed( - model.size(), std::vector(ConfirmedCasesDataEntry::age_group_names.size(), 0.0)); - std::vector> num_InfectedSevere( - model.size(), std::vector(ConfirmedCasesDataEntry::age_group_names.size(), 0.0)); - std::vector> dummy_icu( - model.size(), std::vector(ConfirmedCasesDataEntry::age_group_names.size(), 0.0)); - std::vector num_icu(model.size(), 0.0); - - BOOST_OUTCOME_TRY(details::read_confirmed_cases_data( - confirmed_cases_path, case_data, region, date, num_Exposed, num_InfectedNoSymptoms, num_InfectedSymptoms, - num_InfectedSevere, dummy_icu, num_death, num_rec, t_Exposed, t_InfectedNoSymptoms, t_InfectedSymptoms, - t_InfectedSevere, t_InfectedCritical, mu_C_R, mu_I_H, mu_H_U, scaling_factor_inf)); - BOOST_OUTCOME_TRY(details::read_divi_data(divi_data_path, region, date, num_icu)); - bool interpolate_rki_age_groups = num_age_groups == 1 ? true : false; - BOOST_OUTCOME_TRY(auto&& num_population, - details::read_population_data(population_data_path, region, interpolate_rki_age_groups)); + auto offset_day = offset_date_by_days(date, t); + BOOST_OUTCOME_TRY( + read_input_data_county(models, offset_day, region, scaling_factor_inf, scaling_factor_icu, dir, 0, false)); - for (size_t i = 0; i < region.size(); i++) { - for (size_t age = 0; age < num_age_groups; age++) { - rki_data[i][t]((size_t)InfectionState::Exposed + (size_t)InfectionState::Count * age) = - num_Exposed[i][age]; - rki_data[i][t]((size_t)InfectionState::InfectedNoSymptoms + (size_t)InfectionState::Count * age) = - num_InfectedNoSymptoms[i][age]; - rki_data[i][t]((size_t)InfectionState::InfectedNoSymptomsConfirmed + - (size_t)InfectionState::Count * age) = num_InfectedNoSymptomsConfirmed[i][age]; - rki_data[i][t]((size_t)InfectionState::InfectedSymptoms + (size_t)InfectionState::Count * age) = - num_InfectedSymptoms[i][age]; - rki_data[i][t]((size_t)InfectionState::InfectedSymptomsConfirmed + - (size_t)InfectionState::Count * age) = num_InfectedSymptomsConfirmed[i][age]; - rki_data[i][t]((size_t)InfectionState::InfectedSevere + (size_t)InfectionState::Count * age) = - num_InfectedSevere[i][age]; - rki_data[i][t]((size_t)InfectionState::InfectedCritical + (size_t)InfectionState::Count * age) = - scaling_factor_icu * num_icu[i] * mu_I_U[i][age] / sum_mu_I_U[i]; - rki_data[i][t]((size_t)InfectionState::Recovered + (size_t)InfectionState::Count * age) = - num_rec[i][age]; - rki_data[i][t]((size_t)InfectionState::Dead + (size_t)InfectionState::Count * age) = num_death[i][age]; - rki_data[i][t]((size_t)InfectionState::Susceptible + (size_t)InfectionState::Count * age) = - num_population[i][age] - num_Exposed[i][age] - num_InfectedNoSymptoms[i][age] - - num_InfectedNoSymptomsConfirmed[i][age] - num_InfectedSymptoms[i][age] - - num_InfectedSymptomsConfirmed[i][age] - num_InfectedSevere[i][age] - num_rec[i][age] - - num_death[i][age] - - rki_data[i][t]((size_t)InfectionState::InfectedCritical + (size_t)InfectionState::Count * age); - } + for (size_t r = 0; r < region.size(); r++) { + rki_data[r][t] = models[r].get_initial_values(); } - date = offset_date_by_days(date, 1); } - auto num_groups = (int)(size_t)model[0].parameters.get_num_groups(); + auto num_groups = (int)(size_t)models[0].parameters.get_num_groups(); BOOST_OUTCOME_TRY(save_result(rki_data, region, num_groups, path_join(dir, "Results_rki.h5"))); auto rki_data_sum = sum_nodes(std::vector>>{rki_data}); @@ -371,11 +276,8 @@ IOResult read_input_data_county(std::vector& model, Date date, cons // (This only represents the vectorization of the previous function over all simulation days...) log_warning("Exporting time series of extrapolated real data. This may take some minutes. " "For simulation runs over the same time period, deactivate it."); - BOOST_OUTCOME_TRY( - export_input_data_county_timeseries(model, dir, county, date, scaling_factor_inf, scaling_factor_icu, - num_days, path_join(dir, "pydata/Germany", "county_divi_ma7.json"), - path_join(dir, "pydata/Germany", "cases_all_county_age_ma7.json"), - path_join(dir, "pydata/Germany", "county_current_population.json"))); + BOOST_OUTCOME_TRY(export_input_data_county_timeseries(model, dir, county, date, scaling_factor_inf, + scaling_factor_icu, num_days)); } return success(); } From 65ad5092cdc48fab989205a581e850dea86d3d41 Mon Sep 17 00:00:00 2001 From: HenrZu <69154294+HenrZu@users.noreply.github.com> Date: Fri, 10 May 2024 10:33:37 +0200 Subject: [PATCH 03/46] adjust example --- cpp/examples/ode_secir_ageres.cpp | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) diff --git a/cpp/examples/ode_secir_ageres.cpp b/cpp/examples/ode_secir_ageres.cpp index 8ada6cac62..2d47fe0926 100644 --- a/cpp/examples/ode_secir_ageres.cpp +++ b/cpp/examples/ode_secir_ageres.cpp @@ -85,15 +85,12 @@ int main() model.apply_constraints(); // tests - const auto num_age_groups = 6; - const auto TEST_DATA_DIR = "/localdata1/code_2024/memilio/data/"; - const auto results_dir = "/localdata1/code_2024/memilio/test"; + const auto num_age_groups = 6; + const auto TEST_DATA_DIR = "/localdata1/code_2024/memilio/data/"; + // const auto results_dir = "/localdata1/code_2024/memilio/test"; std::vector models1 = {model}; auto status_export = mio::osecir::export_input_data_county_timeseries( - models1, results_dir, {1001}, {2020, 12, 01}, std::vector(size_t(num_age_groups), 1.0), 1.0, 1, - mio::path_join(TEST_DATA_DIR, "pydata/Germany", "county_divi_ma7.json"), - mio::path_join(TEST_DATA_DIR, "pydata/Germany", "cases_all_county_age_ma7.json"), - mio::path_join(TEST_DATA_DIR, "pydata/Germany", "county_current_population.json")); + models1, TEST_DATA_DIR, {1001}, {2020, 12, 01}, std::vector(size_t(num_age_groups), 1.0), 1.0, 1); std::vector models2 = {model}; auto read_result1 = mio::osecir::read_input_data_county(models2, {2020, 12, 01}, {1001}, From cecee21c9c3a8831c1ffe82f7f119d9f7ed42ac6 Mon Sep 17 00:00:00 2001 From: HenrZu <69154294+HenrZu@users.noreply.github.com> Date: Fri, 10 May 2024 10:43:32 +0200 Subject: [PATCH 04/46] [ci skip] set up benchmark example --- cpp/examples/ode_secir_ageres.cpp | 42 ++++++++++++++++++++++++------- 1 file changed, 33 insertions(+), 9 deletions(-) diff --git a/cpp/examples/ode_secir_ageres.cpp b/cpp/examples/ode_secir_ageres.cpp index 2d47fe0926..44bef50b7d 100644 --- a/cpp/examples/ode_secir_ageres.cpp +++ b/cpp/examples/ode_secir_ageres.cpp @@ -22,6 +22,9 @@ #include "memilio/utils/time_series.h" #include "memilio/utils/logging.h" #include "memilio/compartments/simulation.h" +#include +#include +#include int main() { @@ -89,17 +92,38 @@ int main() const auto TEST_DATA_DIR = "/localdata1/code_2024/memilio/data/"; // const auto results_dir = "/localdata1/code_2024/memilio/test"; std::vector models1 = {model}; - auto status_export = mio::osecir::export_input_data_county_timeseries( - models1, TEST_DATA_DIR, {1001}, {2020, 12, 01}, std::vector(size_t(num_age_groups), 1.0), 1.0, 1); + // auto status_export = mio::osecir::export_input_data_county_timeseries( + // models1, TEST_DATA_DIR, {1001}, {2020, 12, 01}, std::vector(size_t(num_age_groups), 1.0), 1.0, 1); + + auto vec_days = std::vector{1, 5, 10, 20}; + for (auto days : vec_days) { + auto times = std::vector(); + for (int i = 0; i < 20; ++i) { + auto start = std::chrono::high_resolution_clock::now(); + + // Call the function + auto status_export = + export_input_data_county_timeseries(models1, TEST_DATA_DIR, {1001}, {2020, 12, 01}, + std::vector(size_t(num_age_groups), 1.0), 1.0, days); + + auto end = std::chrono::high_resolution_clock::now(); + std::chrono::duration diff = end - start; + + times.push_back(diff.count()); + mio::unused(status_export); + } + double average_time = std::accumulate(times.begin(), times.end(), 0.0) / times.size(); + std::cout << "Average time to run function: " << average_time << "s for days = " << days << "\n"; + } - std::vector models2 = {model}; - auto read_result1 = mio::osecir::read_input_data_county(models2, {2020, 12, 01}, {1001}, - std::vector(size_t(num_age_groups), 1.0), 1.0, - TEST_DATA_DIR, 1, false); + // std::vector models2 = {model}; + // auto read_result1 = mio::osecir::read_input_data_county(models2, {2020, 12, 01}, {1001}, + // std::vector(size_t(num_age_groups), 1.0), 1.0, + // TEST_DATA_DIR, 1, false); - mio::TimeSeries secir = simulate(0.0, 1.0, 1.0, models2[0]); + // mio::TimeSeries secir = simulate(0.0, 1.0, 1.0, models2[0]); - std::cout << secir.get_value(0) << std::endl; + // std::cout << secir.get_value(0) << std::endl; - mio::unused(read_result1); + // mio::unused(read_result1); } From c0b43af11fa0a4bce1419f8d24799886d656910e Mon Sep 17 00:00:00 2001 From: HenrZu <69154294+HenrZu@users.noreply.github.com> Date: Mon, 24 Jun 2024 15:20:00 +0200 Subject: [PATCH 05/46] load static population data only once --- cpp/models/ode_secir/parameters_io.h | 43 +++++++++++++++++++++++----- 1 file changed, 36 insertions(+), 7 deletions(-) diff --git a/cpp/models/ode_secir/parameters_io.h b/cpp/models/ode_secir/parameters_io.h index 0b983ed27e..39e4d4f167 100644 --- a/cpp/models/ode_secir/parameters_io.h +++ b/cpp/models/ode_secir/parameters_io.h @@ -149,20 +149,46 @@ IOResult set_population_data(std::vector& model, const std::string& * @param scaling_factor_inf factors by which to scale the confirmed cases of rki data */ template -IOResult export_input_data_county_timeseries(std::vector models, const std::string& dir, - std::vector const& region, Date date, - const std::vector& scaling_factor_inf, - double scaling_factor_icu, int num_days) +IOResult +export_input_data_county_timeseries(std::vector models, const std::string& dir, std::vector const& region, + Date date, const std::vector& scaling_factor_inf, double scaling_factor_icu, + int num_days, const std::string& divi_data_path, + const std::string& confirmed_cases_path, const std::string& population_data_path) { const size_t num_age_groups = scaling_factor_inf.size(); std::vector> rki_data( region.size(), TimeSeries::zero(num_days, (size_t)InfectionState::Count * num_age_groups)); + BOOST_OUTCOME_TRY(auto&& num_population, details::read_population_data(population_data_path, region)); + for (size_t t = 0; t < static_cast(num_days); ++t) { auto offset_day = offset_date_by_days(date, t); + + if (offset_day > Date(2020, 4, 23)) { + BOOST_OUTCOME_TRY(details::set_divi_data(models, divi_data_path, region, offset_day, scaling_factor_icu)); + } + else { + log_warning("No DIVI data available for this date"); + // TODO: print specific date + } + BOOST_OUTCOME_TRY( - read_input_data_county(models, offset_day, region, scaling_factor_inf, scaling_factor_icu, dir, 0, false)); + details::set_confirmed_cases_data(models, confirmed_cases_path, region, offset_day, scaling_factor_inf)); + BOOST_OUTCOME_TRY(details::set_population_data(models, population_data_path, region, false)); + for (size_t r = 0; r < region.size(); r++) { + if (std::accumulate(num_population[r].begin(), num_population[r].end(), 0.0) > 0) { + auto num_groups = models[r].parameters.get_num_groups(); + for (auto i = AgeGroup(0); i < num_groups; i++) { + models[r].populations.template set_difference_from_group_total( + {i, InfectionState::Susceptible}, num_population[r][size_t(i)]); + } + } + else { + log_warning("No population data available for region " + std::to_string(r) + + ". Population data has not been set."); + } + } for (size_t r = 0; r < region.size(); r++) { rki_data[r][t] = models[r].get_initial_values(); } @@ -276,8 +302,11 @@ IOResult read_input_data_county(std::vector& model, Date date, cons // (This only represents the vectorization of the previous function over all simulation days...) log_warning("Exporting time series of extrapolated real data. This may take some minutes. " "For simulation runs over the same time period, deactivate it."); - BOOST_OUTCOME_TRY(export_input_data_county_timeseries(model, dir, county, date, scaling_factor_inf, - scaling_factor_icu, num_days)); + BOOST_OUTCOME_TRY( + export_input_data_county_timeseries(model, dir, county, date, scaling_factor_inf, scaling_factor_icu, + num_days, path_join(dir, "pydata/Germany", "county_divi_ma7.json"), + path_join(dir, "pydata/Germany", "cases_all_county_age_ma7.json"), + path_join(dir, "pydata/Germany", "county_current_population.json"))); } return success(); } From 9acb87360969ee201ff5dcad5fea6f262efd2e79 Mon Sep 17 00:00:00 2001 From: HenrZu <69154294+HenrZu@users.noreply.github.com> Date: Tue, 25 Jun 2024 10:40:40 +0200 Subject: [PATCH 06/46] [ci skip] tests for secir extrapolation, adapt function extrapolation --- cpp/examples/ode_secir_ageres.cpp | 12 +- cpp/tests/test_odesecir.cpp | 200 ++++++++++++++++++++++++++++-- 2 files changed, 201 insertions(+), 11 deletions(-) diff --git a/cpp/examples/ode_secir_ageres.cpp b/cpp/examples/ode_secir_ageres.cpp index 44bef50b7d..738c36f0ab 100644 --- a/cpp/examples/ode_secir_ageres.cpp +++ b/cpp/examples/ode_secir_ageres.cpp @@ -90,6 +90,12 @@ int main() // tests const auto num_age_groups = 6; const auto TEST_DATA_DIR = "/localdata1/code_2024/memilio/data/"; + // mio::path_join(TEST_DATA_DIR, "county_divi_ma7.json"), + // mio::path_join(TEST_DATA_DIR, "cases_all_county_age_ma7.json"), + // mio::path_join(TEST_DATA_DIR, "county_current_population.json"), + const auto ICU_DIR = TEST_DATA_DIR + "pydata/Germany/county_divi_ma7.json"; + const auto CASES_DIR = TEST_DATA_DIR + "pydata/Germany/cases_all_county_age_ma7.json"; + const auto POPULATION_DIR = TEST_DATA_DIR + "pydata/Germany/county_current_population.json"; // const auto results_dir = "/localdata1/code_2024/memilio/test"; std::vector models1 = {model}; // auto status_export = mio::osecir::export_input_data_county_timeseries( @@ -102,9 +108,9 @@ int main() auto start = std::chrono::high_resolution_clock::now(); // Call the function - auto status_export = - export_input_data_county_timeseries(models1, TEST_DATA_DIR, {1001}, {2020, 12, 01}, - std::vector(size_t(num_age_groups), 1.0), 1.0, days); + auto status_export = export_input_data_county_timeseries(models1, TEST_DATA_DIR, {1001}, {2020, 12, 01}, + std::vector(size_t(num_age_groups), 1.0), + 1.0, days, 1, ICU_DIR, CASES_DIR, POPULATION_DIR); auto end = std::chrono::high_resolution_clock::now(); std::chrono::duration diff = end - start; diff --git a/cpp/tests/test_odesecir.cpp b/cpp/tests/test_odesecir.cpp index 00e6372a97..93d4a611d7 100644 --- a/cpp/tests/test_odesecir.cpp +++ b/cpp/tests/test_odesecir.cpp @@ -19,6 +19,7 @@ */ #include "matchers.h" #include "load_test_data.h" +#include "temp_file_register.h" #include "ode_secir/model.h" #include "memilio/math/adapt_rk.h" #include "ode_secir/parameter_space.h" @@ -713,7 +714,7 @@ TEST(TestOdeSecir, testModelConstraints) } } -TEST(Secir, testAndTraceCapacity) +TEST(TestOdeSecir, testAndTraceCapacity) { double cont_freq = 10; @@ -763,7 +764,7 @@ TEST(Secir, testAndTraceCapacity) dydt_default[(size_t)mio::osecir::InfectionState::Exposed]); } -TEST(Secir, getInfectionsRelative) +TEST(TestOdeSecir, getInfectionsRelative) { size_t num_groups = 3; mio::osecir::Model model((int)num_groups); @@ -782,7 +783,7 @@ TEST(Secir, getInfectionsRelative) (100. + 50. + 25.) / (10'000 + 20'000 + 40'000)); } -TEST(Secir, get_reproduction_number) +TEST(TestOdeSecir, get_reproduction_number) { const size_t num_groups = 3; mio::osecir::Model model((int)num_groups); @@ -949,7 +950,7 @@ TEST(Secir, get_reproduction_number) EXPECT_TRUE(mio::osecir::get_reproduction_number((size_t)0, sim)); } -TEST(Secir, get_migration_factors) +TEST(TestOdeSecir, get_migration_factors) { auto beta = 0.25; auto max_beta = 0.5; @@ -983,7 +984,7 @@ TEST(Secir, get_migration_factors) } } -TEST(Secir, test_commuters) +TEST(TestOdeSecir, test_commuters) { auto model = mio::osecir::Model(2); auto migration_factor = 0.1; @@ -1013,7 +1014,7 @@ TEST(Secir, test_commuters) 1e-5); } -TEST(Secir, check_constraints_parameters) +TEST(TestOdeSecir, check_constraints_parameters) { auto model = mio::osecir::Model(1); ASSERT_EQ(model.parameters.check_constraints(), 0); @@ -1076,7 +1077,7 @@ TEST(Secir, check_constraints_parameters) mio::set_log_level(mio::LogLevel::warn); } -TEST(Secir, apply_constraints_parameters) +TEST(TestOdeSecir, apply_constraints_parameters) { auto model = mio::osecir::Model(1); auto indx_agegroup = mio::AgeGroup(0); @@ -1145,7 +1146,7 @@ TEST(Secir, apply_constraints_parameters) #if defined(MEMILIO_HAS_JSONCPP) -TEST(Secir, read_population_data_one_age_group) +TEST(TestOdeSecir, read_population_data_one_age_group) { std::string path = mio::path_join(TEST_DATA_DIR, "county_current_population.json"); const std::vector region{1001}; @@ -1160,4 +1161,187 @@ TEST(Secir, read_population_data_one_age_group) EXPECT_EQ(result_multiple_age_groups[0][0], 3433.0); } +#if defined(MEMILIO_HAS_HDF5) +TEST(TestOdeSecir, read_data) +{ + constexpr auto num_age_groups = 6; //reading data requires RKI data age groups + + mio::osecir::Model model(num_age_groups); + + model.parameters.set(60); + model.parameters.set(0.2); + + for (auto i = mio::AgeGroup(0); i < (mio::AgeGroup)num_age_groups; i++) { + model.parameters.get()[i] = 3.2; + model.parameters.get()[i] = 2.0; + model.parameters.get()[i] = 5.8; + model.parameters.get()[i] = 9.5; + model.parameters.get()[i] = 7.1; + + model.parameters.get()[i] = 0.05; + model.parameters.get()[i] = 0.7; + model.parameters.get()[i] = 0.09; + model.parameters.get()[i] = 0.25; + model.parameters.get()[i] = 0.45; + model.parameters.get()[i] = 0.2; + model.parameters.get()[i] = 0.25; + model.parameters.get()[i] = 0.3; + } + + model.apply_constraints(); + + auto model1 = std::vector{model}; + auto model2 = std::vector{model}; + auto model3 = std::vector{model}; + + auto read_result1 = mio::osecir::read_input_data_county( + model1, {2020, 12, 01}, {1002}, std::vector(size_t(num_age_groups), 1.0), 1.0, TEST_DATA_DIR, 10); + + auto read_result2 = mio::osecir::read_input_data( + model2, {2020, 12, 01}, {1002}, std::vector(size_t(num_age_groups), 1.0), 1.0, TEST_DATA_DIR, 10); + + auto read_result_district = + mio::osecir::read_input_data(model3, {2020, 12, 01}, {1002}, std::vector(size_t(num_age_groups), 1.0), + 1.0, mio::path_join(TEST_DATA_DIR, "pydata/District"), 10); + + ASSERT_THAT(read_result1, IsSuccess()); + ASSERT_THAT(read_result2, IsSuccess()); + ASSERT_THAT(read_result_district, IsSuccess()); + + // values were generated by the tested function; can only check stability of the implementation, not correctness + auto expected_values = + (Eigen::ArrayXd(num_age_groups * Eigen::Index(mio::osecir::InfectionState::Count)) << 10280, 2.82575, 1.25589, + 0, 5.85714, 0, 1.42857, 1.33333, 28.2857, 0, 19091.3, 6.59341, 4.23862, 0, 11, 0, 2.54286, 1.33333, 88, 0, + 73821.7, 41.9152, 21.6641, 0, 54.5714, 0, 22, 1.33333, 523.857, 0, 82533.6, 39.5604, 21.0361, 0, 51.4286, 0, + 15.1714, 1.33333, 468.571, 0, 43733.1, 8.32025, 5.18053, 0, 11.4286, 0, 4.22857, 1.33333, 158.571, 8, 15642.7, + 10.5181, 3.2967, 0, 3.28571, 0, 0.657143, 1.33333, 49.8571, 7.57143) + .finished(); + + ASSERT_THAT(print_wrap(model1[0].populations.array().cast()), + MatrixNear(print_wrap(model2[0].populations.array().cast()), 1e-5, 1e-5)); + + ASSERT_THAT(print_wrap(model1[0].populations.array().cast()), + MatrixNear(print_wrap(model3[0].populations.array().cast()), 1e-5, 1e-5)); + + ASSERT_THAT(print_wrap(model1[0].populations.array().cast()), + MatrixNear(print_wrap(expected_values), 1e-5, 1e-5)); + ASSERT_THAT(print_wrap(model2[0].populations.array().cast()), + MatrixNear(print_wrap(expected_values), 1e-5, 1e-5)); + ASSERT_THAT(print_wrap(model3[0].populations.array().cast()), + MatrixNear(print_wrap(expected_values), 1e-5, 1e-5)); +} + +TEST(TestOdeSecir, export_time_series_init) +{ + TempFileRegister temp_file_register; + auto tmp_results_dir = temp_file_register.get_unique_path(); + ASSERT_THAT(mio::create_directory(tmp_results_dir), IsSuccess()); + + constexpr auto num_age_groups = 6; //reading data requires RKI data age groups + + mio::osecir::Model model(num_age_groups); + + model.parameters.set(60); + model.parameters.set(0.2); + + for (auto i = mio::AgeGroup(0); i < (mio::AgeGroup)num_age_groups; i++) { + model.parameters.get()[i] = 3.2; + model.parameters.get()[i] = 2.0; + model.parameters.get()[i] = 5.8; + model.parameters.get()[i] = 9.5; + model.parameters.get()[i] = 7.1; + + model.parameters.get()[i] = 0.05; + model.parameters.get()[i] = 0.7; + model.parameters.get()[i] = 0.09; + model.parameters.get()[i] = 0.25; + model.parameters.get()[i] = 0.45; + model.parameters.get()[i] = 0.2; + model.parameters.get()[i] = 0.25; + model.parameters.get()[i] = 0.3; + } + + model.apply_constraints(); + + // Test exporting time series + ASSERT_THAT(mio::osecir::export_input_data_county_timeseries( + std::vector{model}, tmp_results_dir, {1002}, {2020, 12, 01}, + std::vector(size_t(num_age_groups), 1.0), 1.0, 2, + mio::path_join(TEST_DATA_DIR, "county_divi_ma7.json"), + mio::path_join(TEST_DATA_DIR, "cases_all_county_age_ma7.json"), + mio::path_join(TEST_DATA_DIR, "county_current_population.json")), + IsSuccess()); + + auto data_extrapolated = mio::read_result(mio::path_join(tmp_results_dir, "Results_rki.h5")); + ASSERT_THAT(data_extrapolated, IsSuccess()); + + // Values were generated by the tested function export_input_data_county_timeseries; + // can only check stability of the implementation, not correctness + auto expected_results = + mio::read_result(mio::path_join(TEST_DATA_DIR, "export_time_series_initialization_osecir.h5")).value(); + + ASSERT_THAT(print_wrap(data_extrapolated.value()[0].get_groups().matrix()), + MatrixNear(print_wrap(expected_results[0].get_groups().matrix()), 1e-5, 1e-5)); +} + +// // Model initialization should return same start values as export time series on that day +TEST(TestOdeSecir, model_initialization) +{ + constexpr auto num_age_groups = 6; //reading data requires RKI data age groups + + mio::osecir::Model model(num_age_groups); + + model.parameters.set(60); + model.parameters.set(0.2); + + for (auto i = mio::AgeGroup(0); i < (mio::AgeGroup)num_age_groups; i++) { + model.parameters.get()[i] = 3.2; + model.parameters.get()[i] = 2.0; + model.parameters.get()[i] = 5.8; + model.parameters.get()[i] = 9.5; + model.parameters.get()[i] = 7.1; + + model.parameters.get()[i] = 0.05; + model.parameters.get()[i] = 0.7; + model.parameters.get()[i] = 0.09; + model.parameters.get()[i] = 0.25; + model.parameters.get()[i] = 0.45; + model.parameters.get()[i] = 0.2; + model.parameters.get()[i] = 0.25; + model.parameters.get()[i] = 0.3; + } + + model.apply_constraints(); + // Vector assignment necessary as read_input_data_county changes model + auto model_vector = std::vector{model}; + + ASSERT_THAT(mio::osecir::read_input_data_county(model_vector, {2020, 12, 01}, {1002}, + std::vector(size_t(num_age_groups), 1.0), 1.0, + TEST_DATA_DIR, 2, false), + IsSuccess()); + + // Values from data/export_time_series_init_osecir.h5, for reading in comparison + // operator for return of mio::read_result and model population needed. + auto expected_values = + (Eigen::ArrayXd(num_age_groups * Eigen::Index(mio::osecir::InfectionState::Count)) << 3.46722e+06, 176.06, + 3.42799, 0.00017139, 0.00059842, 1.52355, 9.52168e-05, 0.000803518, 0, 0, 0, 7.28479, 0.000193296, 0.000551002, + 0, 0, 0, 0.0342843, 3.1805e-08, 5.37183e-07, 0.029746, 1.51045e-07, 1.04806e-06, 1340.35, 0, 0, 0, 7.74734e+06, + 220.4, 7.99917, 0.000224064, 0.000882024, 5.14232, 0.000180051, 0.00171304, 0, 0, 0, 12.1419, 0.000203391, + 0.000653659, 0, 0, 0, 0.0439275, 1.87568e-08, 3.5717e-07, 0.0297464, 8.46241e-08, 6.62006e-07, 1891.15, 0, 0, + 0, 1.92155e+07, 176.538, 47.6768, 0.00043128, 0.00187022, 24.642, 0.000278636, 0.00292033, 0, 0, 0, 65.1411, + 0.000325876, 0.0011537, 0, 0, 0, 1.24042, 1.74173e-07, 3.65358e-06, 0.0753588, 6.9234e-08, 5.96637e-07, + 1671.81, 0, 0, 0, 3.00317e+07, 184.888, 44.9988, 0.000272769, 0.00137466, 23.9279, 0.000181305, 0.00220837, 0, + 0, 0, 59.4274, 0.000205796, 0.000846734, 0, 0, 0, 3.76905, 3.67799e-07, 8.9664e-06, 0.48785, 3.00341e-07, + 3.00797e-06, 2022.51, 0, 0, 0, 1.65123e+07, 177.579, 9.4638, 0.000100211, 0.00055573, 5.89255, 7.79946e-05, + 0.00104538, 0, 0, 0, 13.5709, 7.98864e-05, 0.000361685, 0, 0, 0, 3.13496, 5.30384e-07, 1.4228e-05, 2.61772, + 2.81518e-06, 3.1025e-05, 2136.56, 0, 0, 0, 6.17983e+06, 216.328, 11.9625, 0.000412312, 0.00197908, 3.74944, + 0.00016154, 0.00187405, 0, 0, 0, 3.71387, 7.47535e-05, 0.000292941, 0, 0, 0, 0.707117, 4.15435e-07, + 9.64602e-06, 4.75937, 1.66604e-05, 0.000158922, 2253.59, 0, 0, 0) + .finished(); + + ASSERT_THAT(print_wrap(model_vector[0].populations.array().cast()), + MatrixNear(print_wrap(expected_values), 1e-5, 1e-5)); +} +#endif + #endif \ No newline at end of file From 95c3d544fd31de57005c1c6e7c6dca275e3a12b5 Mon Sep 17 00:00:00 2001 From: HenrZu <69154294+HenrZu@users.noreply.github.com> Date: Tue, 25 Jun 2024 12:25:43 +0200 Subject: [PATCH 07/46] add test data --- .../export_time_series_initialization_osecir.h5 | Bin 0 -> 6384 bytes 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 cpp/tests/data/export_time_series_initialization_osecir.h5 diff --git a/cpp/tests/data/export_time_series_initialization_osecir.h5 b/cpp/tests/data/export_time_series_initialization_osecir.h5 new file mode 100644 index 0000000000000000000000000000000000000000..c3340a399e786c8f6e13f4747fced966e739bed3 GIT binary patch literal 6384 zcmeD5aB<`1lHy_j0S*oZ76t(@6Gr@pf)5f95f~pPp8#brLg@}Dy@CnCU}OM61_r2h z20^I#=;}g(TwNJ}Dq-fsXsB@v4_F~A4w%3wJ)%Ou!__eWw&0>jY2 zzzD>KrAH5#1er9h^y|S4F)#y~E(xVy3uwZ1Ak!VA+J<%rpr>D0y6k|aADHh#GILWw zZ1+KhoAB)=pv2dEF0?qT^O*w5bul!jsDrUEqG!qlOs zW0*TeY19y4WMG4YEi~X5p*0#KBSZjJ48dq-pgc%MP{AG=_6`gt+zclFq2bR86a~pM zF)@J+;DDOP%-FyQu^ASF5S|d!6p&((_Np`nh6;$p0FjV%#Q|?EGzj8%2(12}AcS9? z0#tf|Fn)C!Q0WaK_|+Ler4NYWS7!m0z95EQ9V{Pdu;W+f0F{0qj$a+R?CKqt_A-hb zaS*5~?Nyk~=8z!J`Cdlii#<$T%&(l=+j7MnVEiVQJKJ(^f3pt@1%a>jcSSrWsd(DJ z(XgG@l%zY5~Fu44e ztn??2K=USaKM{JmPtxIn?ChrL!3gsr^i_c#QirQQ@OPq$=Oh*fnERp(fYO}^^L~i7 zblqb8ljy5(ZaQO*#!03(kg7YIxUM=8zr3ZK4%gsRR?jp>aRkF=#QPfk1fWD}2-xn)5G`KTe zzq>;Ou7AOWTR;aQ;x_4r<{MT%y0qjrV`NL;E(7$gz9A1Id$vFhdn8f7 z6X-mnL^%J$c3^&Ec6R_*0t^Zc)B1t_pEAXvG#C^P`VK+s%I62X;&s$C(f+AY65~*@ z;2xhja{yd_P8U#}3&OlZl>zLf0WkAq92RZ``uFP;2eHWQK!!eCAHygZ4S~@R81N9l zY*%W4-NXoK7BaxvlaK)#V0#hjVi=$NcIE_VJ97a_7+|(DGf?Dd%^A4xFn|W>Xn26) zn3?gyXm|j_0nslj;0A>Y1H%F^2_r^sei7h-gu!TdfWm>9al>eM0K);1UjleR;WF6r F3joC*?6d#? literal 0 HcmV?d00001 From bbb897d06b060a690c6dd3d3c729e1cf7ee25d38 Mon Sep 17 00:00:00 2001 From: HenrZu <69154294+HenrZu@users.noreply.github.com> Date: Tue, 25 Jun 2024 12:32:35 +0200 Subject: [PATCH 08/46] [ci skip] benchmark example --- cpp/examples/ode_secir_ageres.cpp | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/cpp/examples/ode_secir_ageres.cpp b/cpp/examples/ode_secir_ageres.cpp index 74308c6396..7233e3be9a 100644 --- a/cpp/examples/ode_secir_ageres.cpp +++ b/cpp/examples/ode_secir_ageres.cpp @@ -46,7 +46,7 @@ int main() // theta = theta_in; // icu per hospitalized // delta = delta_in; // deaths per ICUs - mio::osecir::Model model(6); + mio::osecir::Model model(6); auto nb_groups = model.parameters.get_num_groups(); double fact = 1.0 / (double)(size_t)nb_groups; @@ -75,21 +75,21 @@ int main() model.populations.set_difference_from_group_total({i, mio::osecir::InfectionState::Susceptible}, fact * nb_total_t0); - params.get()[i] = 0.05; - params.get()[i] = 0.7; - params.get()[i] = 0.09; - params.get()[i] = 0.25; - params.get()[i] = 0.45; - params.get()[i] = 0.2; - params.get()[i] = 0.45; - params.get()[i] = 0.3; + params.get>()[i] = 0.05; + params.get>()[i] = 0.7; + params.get>()[i] = 0.09; + params.get>()[i] = 0.25; + params.get>()[i] = 0.45; + params.get>()[i] = 0.2; + params.get>()[i] = 0.45; + params.get>()[i] = 0.3; } model.apply_constraints(); // tests - const auto num_age_groups = 6; - const auto TEST_DATA_DIR = "/localdata1/code_2024/memilio/data/"; + const auto num_age_groups = 6; + const std::string TEST_DATA_DIR = "/localdata1/code_2024/memilio/data/"; // mio::path_join(TEST_DATA_DIR, "county_divi_ma7.json"), // mio::path_join(TEST_DATA_DIR, "cases_all_county_age_ma7.json"), // mio::path_join(TEST_DATA_DIR, "county_current_population.json"), @@ -97,7 +97,7 @@ int main() const auto CASES_DIR = TEST_DATA_DIR + "pydata/Germany/cases_all_county_age_ma7.json"; const auto POPULATION_DIR = TEST_DATA_DIR + "pydata/Germany/county_current_population.json"; // const auto results_dir = "/localdata1/code_2024/memilio/test"; - std::vector models1 = {model}; + std::vector> models1 = {model}; // auto status_export = mio::osecir::export_input_data_county_timeseries( // models1, TEST_DATA_DIR, {1001}, {2020, 12, 01}, std::vector(size_t(num_age_groups), 1.0), 1.0, 1); @@ -110,7 +110,7 @@ int main() // Call the function auto status_export = export_input_data_county_timeseries(models1, TEST_DATA_DIR, {1001}, {2020, 12, 01}, std::vector(size_t(num_age_groups), 1.0), - 1.0, days, 1, ICU_DIR, CASES_DIR, POPULATION_DIR); + 1.0, days, ICU_DIR, CASES_DIR, POPULATION_DIR); auto end = std::chrono::high_resolution_clock::now(); std::chrono::duration diff = end - start; From 24e580d11447d55d61faa95c51be43ae76fc2669 Mon Sep 17 00:00:00 2001 From: HenrZu <69154294+HenrZu@users.noreply.github.com> Date: Tue, 25 Jun 2024 13:55:26 +0200 Subject: [PATCH 09/46] add pop manually to load pop data only once --- cpp/models/ode_secir/parameters_io.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cpp/models/ode_secir/parameters_io.h b/cpp/models/ode_secir/parameters_io.h index c7c2e37c82..d8dbb88bf9 100644 --- a/cpp/models/ode_secir/parameters_io.h +++ b/cpp/models/ode_secir/parameters_io.h @@ -295,8 +295,8 @@ export_input_data_county_timeseries(std::vector models, const std::string BOOST_OUTCOME_TRY( details::set_confirmed_cases_data(models, confirmed_cases_path, region, offset_day, scaling_factor_inf)); - BOOST_OUTCOME_TRY(details::set_population_data(models, population_data_path, region, false)); + // set population data for (size_t r = 0; r < region.size(); r++) { if (std::accumulate(num_population[r].begin(), num_population[r].end(), 0.0) > 0) { auto num_groups = models[r].parameters.get_num_groups(); From f8d139141edd5ff955aa84d3847ba681178d2f6e Mon Sep 17 00:00:00 2001 From: HenrZu <69154294+HenrZu@users.noreply.github.com> Date: Tue, 25 Jun 2024 14:57:04 +0200 Subject: [PATCH 10/46] empty extrapolation function if no hdf5 --- cpp/models/ode_secir/parameters_io.h | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/cpp/models/ode_secir/parameters_io.h b/cpp/models/ode_secir/parameters_io.h index d8dbb88bf9..fb5cabb80b 100644 --- a/cpp/models/ode_secir/parameters_io.h +++ b/cpp/models/ode_secir/parameters_io.h @@ -324,9 +324,11 @@ export_input_data_county_timeseries(std::vector models, const std::string } #else template -IOResult export_input_data_county_timeseries(std::vector&, const std::string&, std::vector const&, - Date, const std::vector&, double, int, const std::string&, - const std::string&, const std::string&) +IOResult +export_input_data_county_timeseries(std::vector models, const std::string& dir, std::vector const& region, + Date date, const std::vector& scaling_factor_inf, double scaling_factor_icu, + int num_days, const std::string& divi_data_path, + const std::string& confirmed_cases_path, const std::string& population_data_path) { mio::log_warning("HDF5 not available. Cannot export time series of extrapolated real data."); return success(); From 8ebef3c5c5cb5da4c564156c4f6d53e022a939c3 Mon Sep 17 00:00:00 2001 From: HenrZu <69154294+HenrZu@users.noreply.github.com> Date: Wed, 26 Jun 2024 10:15:17 +0200 Subject: [PATCH 11/46] fix msvc build --- cpp/examples/ode_secir_ageres.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/cpp/examples/ode_secir_ageres.cpp b/cpp/examples/ode_secir_ageres.cpp index 7233e3be9a..06a2872325 100644 --- a/cpp/examples/ode_secir_ageres.cpp +++ b/cpp/examples/ode_secir_ageres.cpp @@ -108,9 +108,9 @@ int main() auto start = std::chrono::high_resolution_clock::now(); // Call the function - auto status_export = export_input_data_county_timeseries(models1, TEST_DATA_DIR, {1001}, {2020, 12, 01}, - std::vector(size_t(num_age_groups), 1.0), - 1.0, days, ICU_DIR, CASES_DIR, POPULATION_DIR); + auto status_export = mio::osecir::export_input_data_county_timeseries( + models1, TEST_DATA_DIR, {1001}, {2020, 12, 01}, std::vector(size_t(num_age_groups), 1.0), 1.0, + days, ICU_DIR, CASES_DIR, POPULATION_DIR); auto end = std::chrono::high_resolution_clock::now(); std::chrono::duration diff = end - start; From 0ebaf1c9133dc22190fe3669791a09ee24679f04 Mon Sep 17 00:00:00 2001 From: HenrZu <69154294+HenrZu@users.noreply.github.com> Date: Wed, 26 Jun 2024 12:29:59 +0200 Subject: [PATCH 12/46] seperating reading and processing for pop and case data --- cpp/models/ode_secir/parameters_io.h | 106 ++++++++++++++++----------- 1 file changed, 62 insertions(+), 44 deletions(-) diff --git a/cpp/models/ode_secir/parameters_io.h b/cpp/models/ode_secir/parameters_io.h index fb5cabb80b..ef6880653a 100644 --- a/cpp/models/ode_secir/parameters_io.h +++ b/cpp/models/ode_secir/parameters_io.h @@ -70,20 +70,19 @@ IOResult read_confirmed_cases_data( const std::vector& scaling_factor_inf); /** - * @brief sets populations data from json file with multiple age groups into a Model with one age group - * @tparam FP floating point data type, e.g., double - * @param[in, out] model vector of objects in which the data is set - * @param[in] path Path to confirmed cases file - * @param[in] region vector of keys of the region of interest - * @param[in] year Specifies year at which the data is read - * @param[in] month Specifies month at which the data is read - * @param[in] day Specifies day at which the data is read - * @param[in] scaling_factor_inf factors by which to scale the confirmed cases of rki data - */ + * @brief sets populations data from already read data with multiple age groups into a Model with one age group + * @tparam FP floating point data type, e.g., double + * @param[in, out] model vector of objects in which the data is set + * @param[in] path Path to confirmed cases file + * @param[in] case_data List of confirmed cases data entries + * @param[in] region vector of keys of the region of interest + * @param[in] date Date at which the data is read + * @param[in] scaling_factor_inf factors by which to scale the confirmed cases of rki data + */ template IOResult set_confirmed_cases_data(std::vector>& model, const std::string& path, - std::vector const& region, Date date, - const std::vector& scaling_factor_inf) + std::vector& case_data, const std::vector& region, + Date date, const std::vector& scaling_factor_inf) { const size_t num_age_groups = ConfirmedCasesDataEntry::age_group_names.size(); assert(scaling_factor_inf.size() == num_age_groups); @@ -99,8 +98,6 @@ IOResult set_confirmed_cases_data(std::vector>& model, const std std::vector> mu_H_U{model.size()}; std::vector> mu_U_D{model.size()}; - BOOST_OUTCOME_TRY(auto&& case_data, mio::read_confirmed_cases_data(path)); - for (size_t node = 0; node < model.size(); ++node) { for (size_t group = 0; group < num_age_groups; group++) { @@ -161,6 +158,26 @@ IOResult set_confirmed_cases_data(std::vector>& model, const std return success(); } +/** + * @brief Sets the infected population for a given model based on confirmed cases data. + * + * @tparam FP floating point data type, e.g., double + * @param model Vector of models for which the confirmed cases data will be set. + * @param path Path to the confirmed cases data file. + * @param region Vector of keys of the region of interest + * @param date Date at which the data is read + * @param scaling_factor_inf Factors by which to scale the confirmed cases of rki data + */ +template +IOResult set_confirmed_cases_data(std::vector>& model, const std::string& path, + std::vector const& region, Date date, + const std::vector& scaling_factor_inf) +{ + BOOST_OUTCOME_TRY(auto&& case_data, mio::read_confirmed_cases_data(path)); + BOOST_OUTCOME_TRY(set_confirmed_cases_data(model, path, case_data, region, date, scaling_factor_inf)); + return success(); +} + /** * @brief reads number of ICU patients from DIVI register into Parameters * @param path Path to DIVI file @@ -224,19 +241,17 @@ IOResult>> read_population_data(const std::string& path, const std::vector& vregion, bool accumulate_age_groups = false); /** - * @brief sets population data from census data - * @tparam FP floating point data type, e.g., double - * @param[in, out] model vector of objects in which the data is set - * @param[in] path Path to RKI file - * @param[in] vregion vector of keys of the regions of interest - * @param[in] accumulate_age_groups specifies whether population data sould be accumulated to one age group - */ +* @brief sets population data from census data which has been read into num_population +* @tparam FP floating point data type, e.g., double +* @param[in, out] model vector of objects in which the data is set +* @param[in] num_population vector of population data +* @param[in] vregion vector of keys of the regions of interest +*/ template -IOResult set_population_data(std::vector>& model, const std::string& path, - const std::vector& vregion, bool accumulate_age_groups = false) +IOResult set_population_data(std::vector>& model, + const std::vector>& num_population, + const std::vector& vregion) { - BOOST_OUTCOME_TRY(auto&& num_population, read_population_data(path, vregion, accumulate_age_groups)); - for (size_t region = 0; region < vregion.size(); region++) { if (std::accumulate(num_population[region].begin(), num_population[region].end(), 0.0) > 0) { auto num_groups = model[region].parameters.get_num_groups(); @@ -246,11 +261,27 @@ IOResult set_population_data(std::vector>& model, const std::str } } else { - log_warning("No population data available for region " + std::to_string(region) + - ". Population data has not been set."); + return failure(StatusCode::OutOfRange, "No population data available for region " + std::to_string(region) + + ". Population data has not been set."); } } + return success(); +} +/** +* @brief sets population data from census data into a Model +* @tparam FP floating point data type, e.g., double +* @param[in, out] model vector of objects in which the data is set +* @param[in] path Path to RKI file containing population data +* @param[in] vregion vector of keys of the regions of interest +* @param[in] accumulate_age_groups specifies whether population data sould be accumulated to one age group +*/ +template +IOResult set_population_data(std::vector>& model, const std::string& path, + const std::vector& vregion, bool accumulate_age_groups = false) +{ + BOOST_OUTCOME_TRY(const auto&& num_population, read_population_data(path, vregion, accumulate_age_groups)); + BOOST_OUTCOME_TRY(set_population_data(model, num_population, vregion)); return success(); } @@ -281,6 +312,7 @@ export_input_data_county_timeseries(std::vector models, const std::string region.size(), TimeSeries::zero(num_days, (size_t)InfectionState::Count * num_age_groups)); BOOST_OUTCOME_TRY(auto&& num_population, details::read_population_data(population_data_path, region)); + BOOST_OUTCOME_TRY(auto&& case_data, mio::read_confirmed_cases_data(confirmed_cases_path)); for (size_t t = 0; t < static_cast(num_days); ++t) { auto offset_day = offset_date_by_days(date, t); @@ -293,23 +325,9 @@ export_input_data_county_timeseries(std::vector models, const std::string // TODO: print specific date } - BOOST_OUTCOME_TRY( - details::set_confirmed_cases_data(models, confirmed_cases_path, region, offset_day, scaling_factor_inf)); - - // set population data - for (size_t r = 0; r < region.size(); r++) { - if (std::accumulate(num_population[r].begin(), num_population[r].end(), 0.0) > 0) { - auto num_groups = models[r].parameters.get_num_groups(); - for (auto i = AgeGroup(0); i < num_groups; i++) { - models[r].populations.template set_difference_from_group_total( - {i, InfectionState::Susceptible}, num_population[r][size_t(i)]); - } - } - else { - log_warning("No population data available for region " + std::to_string(r) + - ". Population data has not been set."); - } - } + BOOST_OUTCOME_TRY(details::set_confirmed_cases_data(models, confirmed_cases_path, case_data, region, offset_day, + scaling_factor_inf)); + BOOST_OUTCOME_TRY(details::set_population_data(models, num_population, region)); for (size_t r = 0; r < region.size(); r++) { rki_data[r][t] = models[r].get_initial_values(); } From ddb112274dfd99bfde4f55b8d4182816c91a227b Mon Sep 17 00:00:00 2001 From: HenrZu <69154294+HenrZu@users.noreply.github.com> Date: Wed, 26 Jun 2024 12:56:47 +0200 Subject: [PATCH 13/46] size_t -> int --- cpp/models/ode_secir/parameters_io.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/cpp/models/ode_secir/parameters_io.h b/cpp/models/ode_secir/parameters_io.h index ef6880653a..1ec4e264d3 100644 --- a/cpp/models/ode_secir/parameters_io.h +++ b/cpp/models/ode_secir/parameters_io.h @@ -314,15 +314,15 @@ export_input_data_county_timeseries(std::vector models, const std::string BOOST_OUTCOME_TRY(auto&& num_population, details::read_population_data(population_data_path, region)); BOOST_OUTCOME_TRY(auto&& case_data, mio::read_confirmed_cases_data(confirmed_cases_path)); - for (size_t t = 0; t < static_cast(num_days); ++t) { + for (int t = 0; t < num_days; ++t) { auto offset_day = offset_date_by_days(date, t); if (offset_day > Date(2020, 4, 23)) { BOOST_OUTCOME_TRY(details::set_divi_data(models, divi_data_path, region, offset_day, scaling_factor_icu)); } else { - log_warning("No DIVI data available for this date"); - // TODO: print specific date + log_warning("No DIVI data available for date " + std::to_string(offset_day.year) + "-" + + std::to_string(offset_day.month) + "-" + std::to_string(offset_day.day)); } BOOST_OUTCOME_TRY(details::set_confirmed_cases_data(models, confirmed_cases_path, case_data, region, offset_day, From 2d751149038a287c6c19c9d0cbda223d9772b052 Mon Sep 17 00:00:00 2001 From: HenrZu <69154294+HenrZu@users.noreply.github.com> Date: Wed, 26 Jun 2024 15:30:57 +0200 Subject: [PATCH 14/46] secir for num_days + 1. More general naming --- cpp/models/ode_secir/parameters_io.h | 20 ++++++++++-------- ...xport_time_series_initialization_osecir.h5 | Bin 6384 -> 6384 bytes 2 files changed, 11 insertions(+), 9 deletions(-) diff --git a/cpp/models/ode_secir/parameters_io.h b/cpp/models/ode_secir/parameters_io.h index 1ec4e264d3..c393cbaa2f 100644 --- a/cpp/models/ode_secir/parameters_io.h +++ b/cpp/models/ode_secir/parameters_io.h @@ -307,35 +307,37 @@ export_input_data_county_timeseries(std::vector models, const std::string int num_days, const std::string& divi_data_path, const std::string& confirmed_cases_path, const std::string& population_data_path) { - const size_t num_age_groups = scaling_factor_inf.size(); - std::vector> rki_data( - region.size(), TimeSeries::zero(num_days, (size_t)InfectionState::Count * num_age_groups)); + const auto num_age_groups = (size_t)models[0].parameters.get_num_groups(); + assert(scaling_factor_inf.size() == num_age_groups); + assert(num_age_groups == ConfirmedCasesDataEntry::age_group_names.size()); + assert(models.size() == region.size()); + std::vector> extrapolated_data( + region.size(), TimeSeries::zero(num_days + 1, (size_t)InfectionState::Count * num_age_groups)); BOOST_OUTCOME_TRY(auto&& num_population, details::read_population_data(population_data_path, region)); BOOST_OUTCOME_TRY(auto&& case_data, mio::read_confirmed_cases_data(confirmed_cases_path)); - for (int t = 0; t < num_days; ++t) { + for (int t = 0; t <= num_days; ++t) { auto offset_day = offset_date_by_days(date, t); if (offset_day > Date(2020, 4, 23)) { BOOST_OUTCOME_TRY(details::set_divi_data(models, divi_data_path, region, offset_day, scaling_factor_icu)); } else { - log_warning("No DIVI data available for date " + std::to_string(offset_day.year) + "-" + - std::to_string(offset_day.month) + "-" + std::to_string(offset_day.day)); + log_warning("No DIVI data available for date: {}-{}-{}", offset_day.day, offset_day.month, offset_day.year); } BOOST_OUTCOME_TRY(details::set_confirmed_cases_data(models, confirmed_cases_path, case_data, region, offset_day, scaling_factor_inf)); BOOST_OUTCOME_TRY(details::set_population_data(models, num_population, region)); for (size_t r = 0; r < region.size(); r++) { - rki_data[r][t] = models[r].get_initial_values(); + extrapolated_data[r][t] = models[r].get_initial_values(); } } auto num_groups = (int)(size_t)models[0].parameters.get_num_groups(); - BOOST_OUTCOME_TRY(save_result(rki_data, region, num_groups, path_join(dir, "Results_rki.h5"))); + BOOST_OUTCOME_TRY(save_result(extrapolated_data, region, num_groups, path_join(dir, "Results_rki.h5"))); - auto rki_data_sum = sum_nodes(std::vector>>{rki_data}); + auto rki_data_sum = sum_nodes(std::vector>>{extrapolated_data}); BOOST_OUTCOME_TRY(save_result({rki_data_sum[0][0]}, {0}, num_groups, path_join(dir, "Results_rki_sum.h5"))); return success(); diff --git a/cpp/tests/data/export_time_series_initialization_osecir.h5 b/cpp/tests/data/export_time_series_initialization_osecir.h5 index c3340a399e786c8f6e13f4747fced966e739bed3..34fe8bb25adb05a3418cbcc6e250f7b448491ecc 100644 GIT binary patch delta 940 zcmexh_`z_42RkP-0|YQn4rKRal$bo5U6Or+cug7uL&e06wVN$CA{Zwg;FvstbAfy1 z-u}!j!bcngs!DqmX0tgQxagU#t@6(vY662qWOc5Ufj5*mJ?AaHyGsezJH5qc|vRXiuDsKd?r@S3eOfSuI= zX4bOvK(oJv!R3EWzQ{E{ups5;EfXgqKT*y7&y;A+DZm-H02Zy9m9#b6`hlaF<1EuCxa8)-%fKK&9 zn400cqSUS?PBvg=Nd@$fphoZ;trAIU?tf5L*rmOEI`v6V?FL z-qwKgUpTV^{VfPLYmO4ouFMpNU7A2ECrw_*vna66EZMlM!S>A^%_SI`+)H(K+`< zjKjG&qyH;;gW#rIN(VVK5zepL`AB}Ce7OmfPMYda3XVtvhm9K}7$-Lf zDhR?792Zz20|WEqje?$>GdLmK51<6d3`~HN<%K5VP}>33N{reHZsN_&;2~aZ1TXPw OJ@|-MYr&7Hwh#bTU=IBN delta 453 zcmexh_`z_42RkPd0|YQl4rKRa6qr1lU6Ng-y(*1?pwj{(#uQuJIPLr(!W>24F?AzjY~GV}!SV%k#(00OQ_U;qFB From 09ff7b627db3de54af9dfeaeb0dbfaac6b3f7aef Mon Sep 17 00:00:00 2001 From: HenrZu <69154294+HenrZu@users.noreply.github.com> Date: Wed, 26 Jun 2024 21:08:16 +0200 Subject: [PATCH 15/46] same for secir vvs code --- cpp/models/ode_secirvvs/parameters_io.h | 776 +++++------------------- 1 file changed, 156 insertions(+), 620 deletions(-) diff --git a/cpp/models/ode_secirvvs/parameters_io.h b/cpp/models/ode_secirvvs/parameters_io.h index c6233ae368..7cc377d732 100644 --- a/cpp/models/ode_secirvvs/parameters_io.h +++ b/cpp/models/ode_secirvvs/parameters_io.h @@ -94,23 +94,22 @@ IOResult read_confirmed_cases_data_fix_recovered(std::string const& path, /** * @brief sets populations data from a transformed RKI cases file into a Model. * @param model vector of objects in which the data is set - * @param path Path to transformed RKI cases file + * @param case_data vector of case data. Each inner vector represents a different region * @param region vector of keys of the region of interest * @param date Date for which the arrays are initialized * @param scaling_factor_inf factors by which to scale the confirmed cases of * rki data */ template -IOResult set_confirmed_cases_data(std::vector& model, const std::string& path, +IOResult set_confirmed_cases_data(std::vector& model, + const std::vector& case_data, std::vector const& region, Date date, - const std::vector& scaling_factor_inf) + const std::vector& scaling_factor_inf, bool set_death) { auto num_age_groups = (size_t)model[0].parameters.get_num_groups(); assert(scaling_factor_inf.size() == num_age_groups); //TODO: allow vector or scalar valued scaling factors assert(ConfirmedCasesDataEntry::age_group_names.size() == num_age_groups); - BOOST_OUTCOME_TRY(auto&& rki_data, mio::read_confirmed_cases_data(path)); - std::vector> t_Exposed{model.size()}; std::vector> t_InfectedNoSymptoms{model.size()}; std::vector> t_InfectedSymptoms{model.size()}; @@ -160,7 +159,7 @@ IOResult set_confirmed_cases_data(std::vector& model, const std::st } } - BOOST_OUTCOME_TRY(read_confirmed_cases_data(rki_data, region, date, num_Exposed, num_InfectedNoSymptoms, + BOOST_OUTCOME_TRY(read_confirmed_cases_data(case_data, region, date, num_Exposed, num_InfectedNoSymptoms, num_InfectedSymptoms, num_InfectedSevere, num_icu, num_death, num_rec, t_Exposed, t_InfectedNoSymptoms, t_InfectedSymptoms, t_InfectedSevere, t_InfectedCritical, mu_C_R, mu_I_H, mu_H_U, scaling_factor_inf)); @@ -179,6 +178,16 @@ IOResult set_confirmed_cases_data(std::vector& model, const std::st model[county].populations[{AgeGroup(i), InfectionState::InfectedSevereNaive}] = num_InfectedSevere[county][i]; model[county].populations[{AgeGroup(i), InfectionState::SusceptibleImprovedImmunity}] = num_rec[county][i]; + if (set_death) { + // in set_confirmed_cases_data initilization, deaths are now set to 0. In order to visualize + // the extrapolated real number of deaths, they have to be set here. In the comparison of data + // it has to be paid attention to the fact, the the simulation starts with deaths=0 + // while this method starts with deaths=number of reported deaths so far... + // Additionally, we set the number of reported deaths to DeadNaive since no information on that is + // available here. + // Do only add deaths after substraction. + model[county].populations[{AgeGroup(i), InfectionState::DeadNaive}] = num_death[county][i]; + } } // } @@ -245,7 +254,7 @@ IOResult set_confirmed_cases_data(std::vector& model, const std::st } } - BOOST_OUTCOME_TRY(read_confirmed_cases_data(rki_data, region, date, num_Exposed, num_InfectedNoSymptoms, + BOOST_OUTCOME_TRY(read_confirmed_cases_data(case_data, region, date, num_Exposed, num_InfectedNoSymptoms, num_InfectedSymptoms, num_InfectedSevere, num_icu, num_death, num_rec, t_Exposed, t_InfectedNoSymptoms, t_InfectedSymptoms, t_InfectedSevere, t_InfectedCritical, mu_C_R, mu_I_H, mu_H_U, scaling_factor_inf)); @@ -328,7 +337,7 @@ IOResult set_confirmed_cases_data(std::vector& model, const std::st } } - BOOST_OUTCOME_TRY(read_confirmed_cases_data(rki_data, region, date, num_Exposed, num_InfectedNoSymptoms, + BOOST_OUTCOME_TRY(read_confirmed_cases_data(case_data, region, date, num_Exposed, num_InfectedNoSymptoms, num_InfectedSymptoms, num_InfectedSevere, num_icu, num_death, num_rec, t_Exposed, t_InfectedNoSymptoms, t_InfectedSymptoms, t_InfectedSevere, t_InfectedCritical, mu_C_R, mu_I_H, mu_H_U, scaling_factor_inf)); @@ -354,6 +363,26 @@ IOResult set_confirmed_cases_data(std::vector& model, const std::st std::to_string(region[county]) + ". Population data has not been set."); } } + + return success(); +} + +/** + * @brief sets populations data from a transformed RKI cases file into a Model. + * @param model vector of objects in which the data is set + * @param path Path to transformed RKI cases file + * @param region vector of keys of the region of interest + * @param date Date for which the arrays are initialized + * @param scaling_factor_inf factors by which to scale the confirmed cases of + * rki data + */ +template +IOResult set_confirmed_cases_data(std::vector& model, const std::string& path, + std::vector const& region, Date date, + const std::vector& scaling_factor_inf, bool set_death = false) +{ + BOOST_OUTCOME_TRY(auto&& case_data, mio::read_confirmed_cases_data(path)); + BOOST_OUTCOME_TRY(set_confirmed_cases_data(model, case_data, region, date, scaling_factor_inf, set_death)); return success(); } @@ -422,16 +451,23 @@ IOResult>> read_population_data(const std::vecto const std::vector& vregion); /**@}*/ +/** +* @brief sets population data from census data which has been read into num_population +* @param[in, out] model vector of objects in which the data is set +* @param[in] num_population vector of population data +* @param[in] case_data vector of case data. Each inner vector represents a different region +* @param[in] vregion vector of keys of the regions of interest +* @param[in] date Date for which the arrays are initialized +*/ template -IOResult set_population_data(std::vector& model, const std::string& path, const std::string& path_rki, +IOResult set_population_data(std::vector& model, const std::vector>& num_population, + const std::vector& case_data, const std::vector& vregion, Date date) { - BOOST_OUTCOME_TRY(auto&& num_population, read_population_data(path, vregion)); - auto num_age_groups = ConfirmedCasesDataEntry::age_group_names.size(); - std::vector> num_rec(model.size(), std::vector(num_age_groups, 0.0)); + std::vector> vnum_rec(model.size(), std::vector(num_age_groups, 0.0)); - BOOST_OUTCOME_TRY(read_confirmed_cases_data_fix_recovered(path_rki, vregion, date, num_rec, 14.)); + BOOST_OUTCOME_TRY(read_confirmed_cases_data_fix_recovered(case_data, vregion, date, vnum_rec, 14.)); for (size_t region = 0; region < vregion.size(); region++) { if (std::accumulate(num_population[region].begin(), num_population[region].end(), 0.0) > 0) { @@ -440,7 +476,7 @@ IOResult set_population_data(std::vector& model, const std::string& double S_v = std::min( model[region].parameters.template get>()[{i, SimulationDay(0)}] + - num_rec[region][size_t(i)], + vnum_rec[region][size_t(i)], num_population[region][size_t(i)]); double S_pv = std::max( model[region].parameters.template get>()[{i, SimulationDay(0)}] - @@ -606,12 +642,39 @@ IOResult set_population_data(std::vector& model, const std::string& return success(); } -template -IOResult set_vaccination_data(std::vector>& model, const std::string& path, Date date, - const std::vector& vregion, int num_days) +/** +* @brief sets population data from census data which has been read into num_population +* @param[in, out] model vector of objects in which the data is set +* @param[in] path Path to population data file +* @param[in] path_rki Path to RKI cases data file +* @param[in] vregion vector of keys of the regions of interest +* @param[in] date Date for which the arrays are initialized +*/ +template +IOResult set_population_data(std::vector& model, const std::string& path, const std::string& path_rki, + const std::vector& vregion, Date date) { - BOOST_OUTCOME_TRY(auto&& vacc_data, read_vaccination_data(path)); + BOOST_OUTCOME_TRY(auto&& num_population, details::read_population_data(path, vregion)); + BOOST_OUTCOME_TRY(auto&& rki_data, mio::read_confirmed_cases_data(path_rki)); + + BOOST_OUTCOME_TRY(set_population_data(model, num_population, rki_data, vregion, date)); + return success(); +} +/** + * @brief Sets vaccination data for models stored in a vector + * + * @tparam FP Floating point type used in the Model objects + * @param model Vector of Model objects in which the vaccination data is set + * @param vacc_data Vector of VaccinationDataEntry objects containing the vaccination data + * @param date Start date for the simulation + * @param vregion Vector of region identifiers + * @param num_days Number of days for which the simulation is run + */ +template +IOResult set_vaccination_data(std::vector>& model, const std::vector& vacc_data, + Date date, const std::vector& vregion, int num_days) +{ auto num_groups = model[0].parameters.get_num_groups(); auto days_until_effective1 = @@ -733,6 +796,25 @@ IOResult set_vaccination_data(std::vector>& model, const std::st return success(); } +/** + * @brief Sets vaccination data for models stored in a vector + * + * @tparam FP Floating point type used in the Model objects + * @param model Vector of Model objects in which the vaccination data is set + * @param path Path to vaccination data file + * @param date Start date for the simulation + * @param vregion Vector of region identifiers + * @param num_days Number of days for which the simulation is run + */ +template +IOResult set_vaccination_data(std::vector>& model, const std::string& path, Date date, + const std::vector& vregion, int num_days) +{ + BOOST_OUTCOME_TRY(auto&& vacc_data, read_vaccination_data(path)); + BOOST_OUTCOME_TRY(set_vaccination_data(model, vacc_data, date, vregion, num_days)); + return success(); +} + } // namespace details #ifdef MEMILIO_HAS_HDF5 @@ -753,622 +835,75 @@ IOResult set_vaccination_data(std::vector>& model, const std::st * @param divi_data_path path to divi data file * @param confirmed_cases_path path to confirmed cases file * @param population_data_path path to population data file + * @param set_vaccination_data boolean to set vaccination data + * @param vaccination_data_path path to vaccination data file */ template IOResult export_input_data_county_timeseries( - const std::vector& model, const std::string& dir, std::vector const& region, Date start_date, - const std::vector& scaling_factor_inf, double scaling_factor_icu, int num_days, - const std::string& divi_data_path, const std::string& confirmed_cases_path, const std::string& population_data_path) + std::vector models, const std::string& dir, const std::vector& counties, Date date, + const std::vector& scaling_factor_inf, const double scaling_factor_icu, const int num_days, + const std::string& divi_data_path, const std::string& confirmed_cases_path, const std::string& population_data_path, + bool set_vaccination_data, const std::string& vaccination_data_path) { - auto num_age_groups = (size_t)model[0].parameters.get_num_groups(); - assert(scaling_factor_inf.size() == num_age_groups); - assert(num_age_groups == ConfirmedCasesDataEntry::age_group_names.size()); - assert(model.size() == region.size()); - - BOOST_OUTCOME_TRY(auto&& rki_data, read_confirmed_cases_data(confirmed_cases_path)); - BOOST_OUTCOME_TRY(auto&& population_data, read_population_data(population_data_path)); - BOOST_OUTCOME_TRY(auto&& divi_data, read_divi_data(divi_data_path)); - - /* functionality copy from set_confirmed_cases_data() here splitted in params */ - /* which do not need to be reset for each day and compartments sizes that are */ - /* set later for each day */ - /*----------- UNVACCINATED -----------*/ - // data needs to be int, because access to data-specific confirmed cases - // is done with these parameters. TODO: Rounding instead - // of casting to int should be introduced in the future. - std::vector> t_InfectedNoSymptoms_uv{model.size()}; - std::vector> t_Exposed_uv{model.size()}; - std::vector> t_InfectedSymptoms_uv{model.size()}; - std::vector> t_InfectedSevere_uv{model.size()}; - std::vector> t_InfectedCritical_uv{model.size()}; - - std::vector> mu_C_R_uv{model.size()}; - std::vector> mu_I_H_uv{model.size()}; - std::vector> mu_H_U_uv{model.size()}; - // ICU data is not age-resolved. Use a partition of unity defined by - // the age-dependent probability I->H->U divided by the sum over all - // age groups of all of these probabilities. - std::vector sum_mu_I_U_uv(model.size(), 0); - std::vector> mu_I_U_uv{model.size()}; - - for (size_t county = 0; county < model.size(); county++) { - for (size_t group = 0; group < num_age_groups; group++) { - t_Exposed_uv[county].push_back(static_cast( - std::round(model[county].parameters.template get>()[(AgeGroup)group]))); - t_InfectedNoSymptoms_uv[county].push_back(static_cast( - std::round(model[county].parameters.template get>()[(AgeGroup)group]))); - t_InfectedSymptoms_uv[county].push_back(static_cast( - std::round(model[county].parameters.template get>()[(AgeGroup)group]))); - t_InfectedSevere_uv[county].push_back(static_cast( - std::round(model[county].parameters.template get>()[(AgeGroup)group]))); - t_InfectedCritical_uv[county].push_back(static_cast( - std::round(model[county].parameters.template get>()[(AgeGroup)group]))); - - mu_C_R_uv[county].push_back( - model[county].parameters.template get>()[(AgeGroup)group]); - mu_I_H_uv[county].push_back( - model[county].parameters.template get>()[(AgeGroup)group]); - mu_H_U_uv[county].push_back( - model[county].parameters.template get>()[(AgeGroup)group]); - - /* begin: NOT in set_confirmed_cases_data() */ - sum_mu_I_U_uv[county] += - model[county].parameters.template get>()[AgeGroup(group)] * - model[county].parameters.template get>()[AgeGroup(group)]; - mu_I_U_uv[county].push_back( - model[county].parameters.template get>()[AgeGroup(group)] * - model[county].parameters.template get>()[AgeGroup(group)]); - /* end: NOT in set_confirmed_cases_data() */ - } + const auto num_groups = (size_t)models[0].parameters.get_num_groups(); + assert(scaling_factor_inf.size() == num_groups); + assert(num_groups == ConfirmedCasesDataEntry::age_group_names.size()); + assert(models.size() == counties.size()); + std::vector> extrapolated_data( + models.size(), TimeSeries::zero(num_days + 1, (size_t)InfectionState::Count * num_groups)); + + BOOST_OUTCOME_TRY(auto&& case_data, read_confirmed_cases_data(confirmed_cases_path)); + BOOST_OUTCOME_TRY(auto&& population_data, details::read_population_data(population_data_path, counties)); + + // empty vector if set_vaccination_data is false + std::vector vacc_data; + if (set_vaccination_data) { + BOOST_OUTCOME_TRY(vacc_data, read_vaccination_data(vaccination_data_path)); } - /*----------- PARTIALLY VACCINATED -----------*/ - // data needs to be int, because access to data-specific confirmed cases - // is done with these parameters. TODO: Rounding instead - // of casting to int should be introduced in the future. - std::vector> t_InfectedNoSymptoms_pv{model.size()}; - std::vector> t_Exposed_pv{model.size()}; - std::vector> t_InfectedSymptoms_pv{model.size()}; - std::vector> t_InfectedSevere_pv{model.size()}; - std::vector> t_InfectedCritical_pv{model.size()}; - - std::vector> mu_C_R_pv{model.size()}; - std::vector> mu_I_H_pv{model.size()}; - std::vector> mu_H_U_pv{model.size()}; - - // ICU data is not age-resolved. Use a partition of unity defined by - // the age-dependent probability I->H->U divided by the sum over all - // age groups of all of these probabilities. - std::vector sum_mu_I_U_pv(model.size(), 0); - std::vector> mu_I_U_pv{model.size()}; - for (size_t county = 0; county < model.size(); county++) { - for (size_t group = 0; group < num_age_groups; group++) { - double reduc_t = model[0].parameters.template get>()[(AgeGroup)group]; - t_Exposed_pv[county].push_back(static_cast( - std::round(model[county].parameters.template get>()[(AgeGroup)group]))); - t_InfectedNoSymptoms_pv[county].push_back(static_cast(std::round( - model[county].parameters.template get>()[(AgeGroup)group] * reduc_t))); - t_InfectedSymptoms_pv[county].push_back(static_cast(std::round( - model[county].parameters.template get>()[(AgeGroup)group] * reduc_t))); - t_InfectedSevere_pv[county].push_back(static_cast( - std::round(model[county].parameters.template get>()[(AgeGroup)group]))); - t_InfectedCritical_pv[county].push_back(static_cast( - std::round(model[county].parameters.template get>()[(AgeGroup)group]))); - - double exp_fact_part_immune = - model[county].parameters.template get>()[(AgeGroup)group]; - double inf_fact_part_immune = - model[county].parameters.template get>()[(AgeGroup)group]; - double hosp_fact_part_immune = - model[county] - .parameters.template get>()[(AgeGroup)group]; - double icu_fact_part_immune = - model[county] - .parameters.template get>()[(AgeGroup)group]; - mu_C_R_pv[county].push_back(( - 1 - inf_fact_part_immune / exp_fact_part_immune * - (1 - model[county] - .parameters.template get>()[(AgeGroup)group]))); - mu_I_H_pv[county].push_back( - hosp_fact_part_immune / inf_fact_part_immune * - model[county].parameters.template get>()[(AgeGroup)group]); - // transfer from H to U, D unchanged. - mu_H_U_pv[county].push_back( - icu_fact_part_immune / hosp_fact_part_immune * - model[county].parameters.template get>()[(AgeGroup)group]); + for (int t = 0; t <= num_days; ++t) { + auto offset_day = offset_date_by_days(date, t); - sum_mu_I_U_pv[county] += - icu_fact_part_immune / hosp_fact_part_immune * - model[county].parameters.template get>()[AgeGroup(group)] * - hosp_fact_part_immune / inf_fact_part_immune * - model[county].parameters.template get>()[AgeGroup(group)]; - mu_I_U_pv[county].push_back( - icu_fact_part_immune / hosp_fact_part_immune * - model[county].parameters.template get>()[AgeGroup(group)] * - hosp_fact_part_immune / inf_fact_part_immune * - model[county].parameters.template get>()[AgeGroup(group)]); + if (set_vaccination_data) { + BOOST_OUTCOME_TRY(details::set_vaccination_data(models, vacc_data, offset_day, counties, num_days)); } - } - - /*----------- FULLY VACCINATED -----------*/ - // data needs to be int, because access to data-specific confirmed cases - // is done with these parameters. TODO: Rounding instead - // of casting to int should be introduced in the future. - std::vector> t_InfectedNoSymptoms_fv{model.size()}; - std::vector> t_Exposed_fv{model.size()}; - std::vector> t_InfectedSymptoms_fv{model.size()}; - std::vector> t_InfectedSevere_fv{model.size()}; - std::vector> t_InfectedCritical_fv{model.size()}; - - std::vector> mu_C_R_fv{model.size()}; - std::vector> mu_I_H_fv{model.size()}; - std::vector> mu_H_U_fv{model.size()}; - // ICU data is not age-resolved. Use a partition of unity defined by - // the age-dependent probability I->H->U divided by the sum over all - // age groups of all of these probabilities. - std::vector sum_mu_I_U_fv(model.size(), 0); - std::vector> mu_I_U_fv{model.size()}; - for (size_t county = 0; county < model.size(); county++) { - for (size_t group = 0; group < num_age_groups; group++) { - double reduc_t = model[0].parameters.template get>()[(AgeGroup)group]; - t_Exposed_fv[county].push_back(static_cast( - std::round(model[county].parameters.template get>()[(AgeGroup)group]))); - t_InfectedNoSymptoms_fv[county].push_back(static_cast(std::round( - model[county].parameters.template get>()[(AgeGroup)group] * reduc_t))); - t_InfectedSymptoms_fv[county].push_back(static_cast(std::round( - model[county].parameters.template get>()[(AgeGroup)group] * reduc_t))); - t_InfectedSevere_fv[county].push_back(static_cast( - std::round(model[county].parameters.template get>()[(AgeGroup)group]))); - t_InfectedCritical_fv[county].push_back(static_cast( - std::round(model[county].parameters.template get>()[(AgeGroup)group]))); - - double reduc_immune_exp = - model[county].parameters.template get>()[(AgeGroup)group]; - double reduc_immune_inf = - model[county].parameters.template get>()[(AgeGroup)group]; - double reduc_immune_hosp = - model[county].parameters.template get>()[( - AgeGroup)group]; - double reduc_immune_icu = - model[county].parameters.template get>()[( - AgeGroup)group]; - mu_C_R_fv[county].push_back(( - 1 - reduc_immune_inf / reduc_immune_exp * - (1 - model[county] - .parameters.template get>()[(AgeGroup)group]))); - mu_I_H_fv[county].push_back( - reduc_immune_hosp / reduc_immune_inf * - model[county].parameters.template get>()[(AgeGroup)group]); - // transfer from H to U, D unchanged. - mu_H_U_fv[county].push_back( - reduc_immune_icu / reduc_immune_hosp * - model[county].parameters.template get>()[(AgeGroup)group]); - sum_mu_I_U_fv[county] += - reduc_immune_icu / reduc_immune_hosp * - model[county].parameters.template get>()[AgeGroup(group)] * - reduc_immune_hosp / reduc_immune_inf * - model[county].parameters.template get>()[AgeGroup(group)]; - mu_I_U_fv[county].push_back( - reduc_immune_icu / reduc_immune_hosp * - model[county].parameters.template get>()[AgeGroup(group)] * - reduc_immune_hosp / reduc_immune_inf * - model[county].parameters.template get>()[AgeGroup(group)]); + // TODO: Reuse more code, e.g., set_divi_data (in secir) and a set_divi_data (here) only need a different ModelType. + // TODO: add option to set ICU data from confirmed cases if DIVI or other data is not available. + if (offset_day > Date(2020, 4, 23)) { + BOOST_OUTCOME_TRY(details::set_divi_data(models, divi_data_path, counties, offset_day, scaling_factor_icu)); } - } - std::vector> extrapolated_rki( - model.size(), TimeSeries::zero(num_days + 1, (size_t)InfectionState::Count * num_age_groups)); - - for (size_t day = 0; day <= static_cast(num_days); day++) { - auto date = offset_date_by_days(start_date, int(day)); - - // unvaccinated - std::vector> num_Exposed_uv(model.size(), std::vector(num_age_groups, 0.0)); - std::vector> num_InfectedNoSymptoms_uv(model.size(), - std::vector(num_age_groups, 0.0)); - std::vector> num_InfectedSymptoms_uv(model.size(), - std::vector(num_age_groups, 0.0)); - // potential TODO: these confirmed are only confirmed by commuting, set to zero here. Adapt if generalized! - std::vector> num_InfectedNoSymptomsConfirmed_uv(model.size(), - std::vector(num_age_groups, 0.0)); - std::vector> num_InfectedSymptomsConfirmed_uv(model.size(), - std::vector(num_age_groups, 0.0)); - // end TODO - std::vector> num_rec_uv(model.size(), std::vector(num_age_groups, 0.0)); - std::vector> num_InfectedSevere_uv(model.size(), std::vector(num_age_groups, 0.0)); - std::vector> num_death_uv(model.size(), std::vector(num_age_groups, 0.0)); - std::vector> dummy_icu(model.size(), std::vector(num_age_groups, 0.0)); - BOOST_OUTCOME_TRY(details::read_confirmed_cases_data( - rki_data, region, date, num_Exposed_uv, num_InfectedNoSymptoms_uv, num_InfectedSymptoms_uv, - num_InfectedSevere_uv, dummy_icu, num_death_uv, num_rec_uv, t_Exposed_uv, t_InfectedNoSymptoms_uv, - t_InfectedSymptoms_uv, t_InfectedSevere_uv, t_InfectedCritical_uv, mu_C_R_uv, mu_I_H_uv, mu_H_U_uv, - scaling_factor_inf)); - - // partially vaccinated - std::vector> num_Exposed_pv(model.size(), std::vector(num_age_groups, 0.0)); - std::vector> num_InfectedNoSymptoms_pv(model.size(), - std::vector(num_age_groups, 0.0)); - std::vector> num_InfectedSymptoms_pv(model.size(), - std::vector(num_age_groups, 0.0)); - std::vector> num_InfectedSevere_pv(model.size(), std::vector(num_age_groups, 0.0)); - // potential TODO: these confirmed are only confirmed by commuting, set to zero here. Adapt if generalized! - std::vector> num_InfectedNoSymptomsConfirmed_pv(model.size(), - std::vector(num_age_groups, 0.0)); - std::vector> num_InfectedSymptomsConfirmed_pv(model.size(), - std::vector(num_age_groups, 0.0)); - // end TODO - std::vector> dummy_death(model.size(), std::vector(num_age_groups, 0.0)); - std::vector> dummy_rec(model.size(), std::vector(num_age_groups, 0.0)); - for (size_t county = 0; county < model.size(); county++) { - dummy_death[county] = std::vector(num_age_groups, 0.0); - dummy_icu[county] = std::vector(num_age_groups, 0.0); - } - BOOST_OUTCOME_TRY(details::read_confirmed_cases_data( - rki_data, region, date, num_Exposed_pv, num_InfectedNoSymptoms_pv, num_InfectedSymptoms_pv, - num_InfectedSevere_pv, dummy_icu, dummy_death, dummy_rec, t_Exposed_pv, t_InfectedNoSymptoms_pv, - t_InfectedSymptoms_pv, t_InfectedSevere_pv, t_InfectedCritical_pv, mu_C_R_pv, mu_I_H_pv, mu_H_U_pv, - scaling_factor_inf)); - - // fully vaccinated - std::vector> num_Exposed_fv(model.size(), std::vector(num_age_groups, 0.0)); - std::vector> num_InfectedNoSymptoms_fv(model.size(), - std::vector(num_age_groups, 0.0)); - std::vector> num_InfectedSymptoms_fv(model.size(), - std::vector(num_age_groups, 0.0)); - // potential TODO: these confirmed are only confirmed by commuting, set to zero here. Adapt if generalized! - std::vector> num_InfectedNoSymptomsConfirmed_fv(model.size(), - std::vector(num_age_groups, 0.0)); - std::vector> num_InfectedSymptomsConfirmed_fv(model.size(), - std::vector(num_age_groups, 0.0)); - // end TODO - std::vector> num_InfectedSevere_fv(model.size(), std::vector(num_age_groups, 0.0)); - for (size_t county = 0; county < model.size(); county++) { - dummy_rec[county] = std::vector(num_age_groups, 0.0); - dummy_death[county] = std::vector(num_age_groups, 0.0); - dummy_icu[county] = std::vector(num_age_groups, 0.0); - } - BOOST_OUTCOME_TRY(details::read_confirmed_cases_data( - rki_data, region, date, num_Exposed_fv, num_InfectedNoSymptoms_fv, num_InfectedSymptoms_fv, - num_InfectedSevere_fv, dummy_icu, dummy_death, dummy_rec, t_Exposed_fv, t_InfectedNoSymptoms_fv, - t_InfectedSymptoms_fv, t_InfectedSevere_fv, t_InfectedCritical_fv, mu_C_R_fv, mu_I_H_fv, mu_H_U_fv, - scaling_factor_inf)); - - // ICU only read for compartment InfectionState::InfectedCritical and then distributed later - std::vector dummy_icu2(model.size(), 0.0); - BOOST_OUTCOME_TRY(details::read_divi_data(divi_data, region, date, dummy_icu2)); - - std::vector> num_icu(model.size(), std::vector(num_age_groups, 0.0)); - for (size_t county = 0; county < region.size(); county++) { - for (size_t age = 0; age < num_age_groups; age++) { - num_icu[county][age] = - scaling_factor_icu * dummy_icu2[county] * mu_I_U_uv[county][age] / sum_mu_I_U_uv[county]; - } + else { + log_warning("No DIVI data available for for date: {}-{}-{}", offset_day.day, offset_day.month, + offset_day.year); } - // read population basics - BOOST_OUTCOME_TRY(auto&& num_population, details::read_population_data(population_data, region)); - - std::vector> num_rec(model.size(), std::vector(num_age_groups, 0.0)); - BOOST_OUTCOME_TRY(details::read_confirmed_cases_data_fix_recovered(rki_data, region, date, num_rec, 14.)); - - for (size_t county = 0; county < region.size(); county++) { - if (std::accumulate(num_population[county].begin(), num_population[county].end(), 0.0) > 0) { - for (size_t age = 0; age < num_age_groups; age++) { - - auto age_group_offset = age * (size_t)InfectionState::Count; - double S_v = std::min(model[county].parameters.template get>()[{ - AgeGroup(age), SimulationDay(day)}] + - num_rec[county][age], - num_population[county][age]); - double S_pv = std::max(model[county].parameters.template get>()[{ - AgeGroup(age), SimulationDay(day)}] - - model[county].parameters.template get>()[{ - AgeGroup(age), SimulationDay(day)}], - 0.0); // use std::max with 0 - double S; - if (num_population[county][age] - S_pv - S_v < 0.0) { - log_warning("Number of vaccinated greater than population at county {}, age group {}: {} + " - "{} > {}.", - county, age, S_pv, S_v, num_population[county][age]); - S = 0.0; - S_v = num_population[county][age] - S_pv; - } - else { - S = num_population[county][age] - S_pv - S_v; - } - - double denom_E = - 1 / (S + - S_pv * model[county] - .parameters.template get>()[AgeGroup(age)] + - S_v * model[county] - .parameters.template get>()[AgeGroup(age)]); - double denom_C = - 1 / (S + - S_pv * model[county] - .parameters.template get>()[AgeGroup(age)] + - S_v * model[county] - .parameters.template get>()[AgeGroup(age)]); - double denom_I = - 1 / (S + - S_pv * model[county] - .parameters - .template get>()[AgeGroup(age)] + - S_v * model[county] - .parameters - .template get>()[AgeGroup(age)]); - double denom_HU = - 1 / (S + - S_pv * model[county] - .parameters.template get< - ReducInfectedSevereCriticalDeadPartialImmunity>()[AgeGroup(age)] + - S_v * model[county] - .parameters.template get< - ReducInfectedSevereCriticalDeadImprovedImmunity>()[AgeGroup(age)]); - - extrapolated_rki[county][day]((size_t)InfectionState::ExposedNaive + age_group_offset) = - S * denom_E * num_Exposed_uv[county][age]; - extrapolated_rki[county][day]((size_t)InfectionState::ExposedPartialImmunity + age_group_offset) = - S_pv * - model[county].parameters.template get>()[AgeGroup(age)] * - denom_E * num_Exposed_pv[county][age]; - extrapolated_rki[county][day]((size_t)InfectionState::ExposedImprovedImmunity + age_group_offset) = - S_v * - model[county].parameters.template get>()[AgeGroup(age)] * - denom_E * num_Exposed_fv[county][age]; - - extrapolated_rki[county][day]((size_t)InfectionState::InfectedNoSymptomsNaive + age_group_offset) = - S * denom_C * num_InfectedNoSymptoms_uv[county][age]; - extrapolated_rki[county][day]((size_t)InfectionState::InfectedNoSymptomsPartialImmunity + - age_group_offset) = - S_pv * denom_C * num_InfectedNoSymptoms_pv[county][age]; - extrapolated_rki[county][day]((size_t)InfectionState::InfectedNoSymptomsImprovedImmunity + - age_group_offset) = - S_v * denom_C * num_InfectedNoSymptoms_fv[county][age]; - - extrapolated_rki[county][day]((size_t)InfectionState::InfectedNoSymptomsNaiveConfirmed + - age_group_offset) = - S * denom_C * num_InfectedNoSymptomsConfirmed_uv[county][age]; - extrapolated_rki[county][day]((size_t)InfectionState::InfectedNoSymptomsPartialImmunityConfirmed + - age_group_offset) = - S_pv * denom_C * num_InfectedNoSymptomsConfirmed_pv[county][age]; - extrapolated_rki[county][day]((size_t)InfectionState::InfectedNoSymptomsImprovedImmunityConfirmed + - age_group_offset) = - S_v * denom_C * num_InfectedNoSymptomsConfirmed_fv[county][age]; - - extrapolated_rki[county][day]((size_t)InfectionState::InfectedSymptomsNaive + age_group_offset) = - S * denom_I * num_InfectedSymptoms_uv[county][age]; - extrapolated_rki[county][day]((size_t)InfectionState::InfectedSymptomsPartialImmunity + - age_group_offset) = - S_pv * - model[county] - .parameters.template get>()[AgeGroup(age)] * - denom_I * num_InfectedSymptoms_pv[county][age]; - extrapolated_rki[county][day]((size_t)InfectionState::InfectedSymptomsImprovedImmunity + - age_group_offset) = - S_v * - model[county] - .parameters.template get>()[AgeGroup(age)] * - denom_I * num_InfectedSymptoms_fv[county][age]; - - extrapolated_rki[county][day]((size_t)InfectionState::InfectedSymptomsNaiveConfirmed + - age_group_offset) = - S * denom_I * num_InfectedSymptomsConfirmed_uv[county][age]; - extrapolated_rki[county][day]((size_t)InfectionState::InfectedSymptomsPartialImmunityConfirmed + - age_group_offset) = - S_pv * - model[county] - .parameters.template get>()[AgeGroup(age)] * - denom_I * num_InfectedSymptomsConfirmed_pv[county][age]; - extrapolated_rki[county][day]((size_t)InfectionState::InfectedSymptomsImprovedImmunityConfirmed + - age_group_offset) = - S_v * - model[county] - .parameters.template get>()[AgeGroup(age)] * - denom_I * num_InfectedSymptomsConfirmed_fv[county][age]; - - extrapolated_rki[county][day]((size_t)InfectionState::InfectedSevereNaive + age_group_offset) = - S * denom_HU * num_InfectedSevere_uv[county][age]; - extrapolated_rki[county][day]((size_t)InfectionState::InfectedSeverePartialImmunity + - age_group_offset) = - S_pv * - model[county] - .parameters - .template get>()[AgeGroup(age)] * - denom_HU * num_InfectedSevere_pv[county][age]; - extrapolated_rki[county][day]((size_t)InfectionState::InfectedSevereImprovedImmunity + - age_group_offset) = - S_v * - model[county] - .parameters - .template get>()[AgeGroup(age)] * - denom_HU * num_InfectedSevere_fv[county][age]; - - extrapolated_rki[county][day]((size_t)InfectionState::InfectedCriticalNaive + age_group_offset) = - S * denom_HU * num_icu[county][age]; - extrapolated_rki[county][day]((size_t)InfectionState::InfectedCriticalPartialImmunity + - age_group_offset) = - S_pv * - model[county] - .parameters - .template get>()[AgeGroup(age)] * - denom_HU * num_icu[county][age]; - extrapolated_rki[county][day]((size_t)InfectionState::InfectedCriticalImprovedImmunity + - age_group_offset) = - S_v * - model[county] - .parameters - .template get>()[AgeGroup(age)] * - denom_HU * num_icu[county][age]; - - extrapolated_rki[county][day]((size_t)InfectionState::SusceptibleImprovedImmunity + - age_group_offset) = - model[county].parameters.template get>()[{AgeGroup(age), - SimulationDay(day)}] + - num_rec_uv[county][age] - - (extrapolated_rki[county][day]((size_t)InfectionState::InfectedSymptomsNaive + - age_group_offset) + - extrapolated_rki[county][day]((size_t)InfectionState::InfectedSymptomsPartialImmunity + - age_group_offset) + - extrapolated_rki[county][day]((size_t)InfectionState::InfectedSymptomsImprovedImmunity + - age_group_offset) + - extrapolated_rki[county][day]((size_t)InfectionState::InfectedSymptomsNaiveConfirmed + - age_group_offset) + - extrapolated_rki[county][day]( - (size_t)InfectionState::InfectedSymptomsPartialImmunityConfirmed + age_group_offset) + - extrapolated_rki[county][day]( - (size_t)InfectionState::InfectedSymptomsImprovedImmunityConfirmed + age_group_offset) + - extrapolated_rki[county][day]((size_t)InfectionState::InfectedSevereNaive + age_group_offset) + - extrapolated_rki[county][day]((size_t)InfectionState::InfectedSeverePartialImmunity + - age_group_offset) + - extrapolated_rki[county][day]((size_t)InfectionState::InfectedSevereImprovedImmunity + - age_group_offset) + - extrapolated_rki[county][day]((size_t)InfectionState::InfectedCriticalNaive + - age_group_offset) + - extrapolated_rki[county][day]((size_t)InfectionState::InfectedCriticalPartialImmunity + - age_group_offset) + - extrapolated_rki[county][day]((size_t)InfectionState::InfectedCriticalImprovedImmunity + - age_group_offset) + - extrapolated_rki[county][day]((size_t)InfectionState::DeadNaive + age_group_offset) + - extrapolated_rki[county][day]((size_t)InfectionState::DeadPartialImmunity + age_group_offset) + - extrapolated_rki[county][day]((size_t)InfectionState::DeadImprovedImmunity + - age_group_offset)); - - extrapolated_rki[county][day]((size_t)InfectionState::SusceptibleImprovedImmunity + - age_group_offset) = - std::min( - S_v - - extrapolated_rki[county][day]((size_t)InfectionState::ExposedImprovedImmunity + - age_group_offset) - - extrapolated_rki[county][day]( - (size_t)InfectionState::InfectedNoSymptomsImprovedImmunity + age_group_offset) - - extrapolated_rki[county][day]( - (size_t)InfectionState::InfectedNoSymptomsImprovedImmunityConfirmed + - age_group_offset) - - extrapolated_rki[county][day]((size_t)InfectionState::InfectedSymptomsImprovedImmunity + - age_group_offset) - - extrapolated_rki[county][day]( - (size_t)InfectionState::InfectedSymptomsImprovedImmunityConfirmed + - age_group_offset) - - extrapolated_rki[county][day]((size_t)InfectionState::InfectedSevereImprovedImmunity + - age_group_offset) - - extrapolated_rki[county][day]((size_t)InfectionState::InfectedCriticalImprovedImmunity + - age_group_offset) - - extrapolated_rki[county][day]((size_t)InfectionState::DeadImprovedImmunity + - age_group_offset), - std::max(0.0, - double(extrapolated_rki[county][day]( - (size_t)InfectionState::SusceptibleImprovedImmunity + age_group_offset)))); - - extrapolated_rki[county][day]((size_t)InfectionState::SusceptiblePartialImmunity + - age_group_offset) = - std::max(0.0, - S_pv - - extrapolated_rki[county][day]((size_t)InfectionState::ExposedPartialImmunity + - age_group_offset) - - extrapolated_rki[county][day]( - (size_t)InfectionState::InfectedNoSymptomsPartialImmunity + age_group_offset) - - extrapolated_rki[county][day]( - (size_t)InfectionState::InfectedNoSymptomsPartialImmunityConfirmed + - age_group_offset) - - extrapolated_rki[county][day]( - (size_t)InfectionState::InfectedSymptomsPartialImmunity + age_group_offset) - - extrapolated_rki[county][day]( - (size_t)InfectionState::InfectedSymptomsPartialImmunityConfirmed + - age_group_offset) - - extrapolated_rki[county][day]( - (size_t)InfectionState::InfectedSeverePartialImmunity + age_group_offset) - - extrapolated_rki[county][day]( - (size_t)InfectionState::InfectedCriticalPartialImmunity + age_group_offset) - - extrapolated_rki[county][day]((size_t)InfectionState::DeadPartialImmunity + - age_group_offset)); - - extrapolated_rki[county][day]((size_t)InfectionState::SusceptibleNaive + age_group_offset) = - num_population[county][age] - - (extrapolated_rki[county][day]((size_t)InfectionState::SusceptiblePartialImmunity + - age_group_offset) + - extrapolated_rki[county][day]((size_t)InfectionState::SusceptibleImprovedImmunity + - age_group_offset) + - extrapolated_rki[county][day]((size_t)InfectionState::ExposedNaive + age_group_offset) + - extrapolated_rki[county][day]((size_t)InfectionState::ExposedPartialImmunity + - age_group_offset) + - extrapolated_rki[county][day]((size_t)InfectionState::ExposedImprovedImmunity + - age_group_offset) + - extrapolated_rki[county][day]((size_t)InfectionState::InfectedNoSymptomsNaive + - age_group_offset) + - extrapolated_rki[county][day]((size_t)InfectionState::InfectedNoSymptomsPartialImmunity + - age_group_offset) + - extrapolated_rki[county][day]((size_t)InfectionState::InfectedNoSymptomsImprovedImmunity + - age_group_offset) + - extrapolated_rki[county][day]((size_t)InfectionState::InfectedSymptomsNaive + - age_group_offset) + - extrapolated_rki[county][day]((size_t)InfectionState::InfectedSymptomsPartialImmunity + - age_group_offset) + - extrapolated_rki[county][day]((size_t)InfectionState::InfectedSymptomsImprovedImmunity + - age_group_offset) + - extrapolated_rki[county][day]((size_t)InfectionState::InfectedSevereNaive + age_group_offset) + - extrapolated_rki[county][day]((size_t)InfectionState::InfectedSeverePartialImmunity + - age_group_offset) + - extrapolated_rki[county][day]((size_t)InfectionState::InfectedSevereImprovedImmunity + - age_group_offset) + - extrapolated_rki[county][day]((size_t)InfectionState::InfectedCriticalNaive + - age_group_offset) + - extrapolated_rki[county][day]((size_t)InfectionState::InfectedCriticalPartialImmunity + - age_group_offset) + - extrapolated_rki[county][day]((size_t)InfectionState::InfectedCriticalImprovedImmunity + - age_group_offset) + - extrapolated_rki[county][day]((size_t)InfectionState::DeadNaive + age_group_offset) + - extrapolated_rki[county][day]((size_t)InfectionState::DeadPartialImmunity + age_group_offset) + - extrapolated_rki[county][day]((size_t)InfectionState::DeadImprovedImmunity + - age_group_offset)); - - // in set_confirmed_cases_data initilization, deaths are now set to 0. In order to visualize - // the extrapolated real number of deaths, they have to be set here. In the comparison of data - // it has to be paid attention to the fact, the the simulation starts with deaths=0 - // while this method starts with deaths=number of reported deaths so far... - // Additionally, we set the number of reported deaths to DeadNaive since no information on that is - // available here. - // Do only add deaths after substraction. - extrapolated_rki[county][day]((size_t)InfectionState::DeadNaive + age_group_offset) = - num_death_uv[county][age]; - } - } - else { - log_warning("No population data available for region " + std::to_string(county) + - ". Population data has not been set."); + BOOST_OUTCOME_TRY( + details::set_confirmed_cases_data(models, case_data, counties, offset_day, scaling_factor_inf, true)); + BOOST_OUTCOME_TRY(details::set_population_data(models, population_data, case_data, counties, offset_day)); + + // in set_population_data werden die Anzahl an TOten noch von SusceptibleImprovedImmunity subtrahiert. Da wir egal, + // ob wir diese betrachten oder nicht, addieren wir sie hier wieder hinzu bevor wir die Daten speichern. + for (size_t r = 0; r < counties.size(); r++) { + extrapolated_data[r][t] = models[r].get_initial_values(); + // in set_population_data the number of death individuals is subtracted from the SusceptibleImprovedImmunity compartment. + // Since we should be independent whether we consider them or not, we add them back here before we save the data. + for (size_t age = 0; age < num_groups; age++) { + // extrapolated_rki[county][day]((size_t)InfectionState::DeadNaive + age_group_offset) + extrapolated_data[r][t][(size_t)InfectionState::SusceptibleImprovedImmunity + + age * (size_t)InfectionState::Count] += + extrapolated_data[r][t][(size_t)InfectionState::DeadNaive + age * (size_t)InfectionState::Count]; } } - log_info("extrapolated real data for date: {}-{}-{}", date.day, date.month, date.year); } - /* end: similar functionality in set_confirmed_cases_data(), here only for vector of TimeSeries */ - auto num_groups = (int)(size_t)model[0].parameters.get_num_groups(); - BOOST_OUTCOME_TRY(save_result(extrapolated_rki, region, num_groups, path_join(dir, "Results_rki.h5"))); + BOOST_OUTCOME_TRY(save_result(extrapolated_data, counties, num_groups, path_join(dir, "Results_rki.h5"))); - auto extrapolated_rki_data_sum = sum_nodes(std::vector>>{extrapolated_rki}); + auto extrapolated_rki_data_sum = sum_nodes(std::vector>>{extrapolated_data}); BOOST_OUTCOME_TRY( save_result({extrapolated_rki_data_sum[0][0]}, {0}, num_groups, path_join(dir, "Results_rki_sum.h5"))); return success(); } - -template -IOResult -export_input_data_county_timeseries(std::vector&& model, const std::string& dir, std::vector const& region, - Date date, const std::vector& scaling_factor_inf, double scaling_factor_icu, - int num_days, const std::string& divi_data_path, - const std::string& confirmed_cases_path, const std::string& population_data_path, - bool set_vaccination_data, const std::string& vaccination_data_path) -{ - if (set_vaccination_data) { - BOOST_OUTCOME_TRY(details::set_vaccination_data(model, vaccination_data_path, date, region, num_days)); - } - - BOOST_OUTCOME_TRY(export_input_data_county_timeseries(model, dir, region, date, scaling_factor_inf, - scaling_factor_icu, num_days, divi_data_path, - confirmed_cases_path, population_data_path)); - - return success(); -} #else template IOResult export_input_data_county_timeseries(std::vector&, const std::string&, std::vector const&, @@ -1434,11 +969,12 @@ IOResult read_input_data_county(std::vector& model, Date date, cons // (This only represents the vectorization of the previous function over all simulation days...) log_warning("Exporting time series of extrapolated real data. This may take some minutes. " "For simulation runs over the same time period, deactivate it."); - BOOST_OUTCOME_TRY( - export_input_data_county_timeseries(model, dir, county, date, scaling_factor_inf, scaling_factor_icu, - num_days, path_join(dir, "pydata/Germany", "county_divi_ma7.json"), - path_join(dir, "pydata/Germany", "cases_all_county_age_ma7.json"), - path_join(dir, "pydata/Germany", "county_current_population.json"))); + BOOST_OUTCOME_TRY(export_input_data_county_timeseries( + model, dir, county, date, scaling_factor_inf, scaling_factor_icu, num_days, + path_join(dir, "pydata/Germany", "county_divi_ma7.json"), + path_join(dir, "pydata/Germany", "cases_all_county_age_ma7.json"), + path_join(dir, "pydata/Germany", "county_current_population.json"), true, + path_join(dir, "pydata/Germany", "all_county_ageinf_vacc_ma7.json"))); } return success(); @@ -1490,8 +1026,8 @@ IOResult read_input_data(std::vector& model, Date date, const std:: "For simulation runs over the same time period, deactivate it."); BOOST_OUTCOME_TRY(export_input_data_county_timeseries( model, data_dir, node_ids, date, scaling_factor_inf, scaling_factor_icu, num_days, - path_join(data_dir, "critical_cases.json"), path_join(data_dir, "confirmed_cases.json"), - path_join(data_dir, "population_data.json"))); + path_join(data_dir, "divi_data.json"), path_join(data_dir, "confirmed_cases.json"), + path_join(data_dir, "population_data.json"), true, path_join(data_dir, "vaccination_data.json"))); } return success(); From 99ea23d8282f24b9ee8492c4ec6bd6aeab1f5281 Mon Sep 17 00:00:00 2001 From: HenrZu <69154294+HenrZu@users.noreply.github.com> Date: Wed, 26 Jun 2024 23:05:44 +0200 Subject: [PATCH 16/46] [ci skip] size_t to int cast for msvc --- cpp/models/ode_secirvvs/parameters_io.h | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/cpp/models/ode_secirvvs/parameters_io.h b/cpp/models/ode_secirvvs/parameters_io.h index 7cc377d732..d8338a71df 100644 --- a/cpp/models/ode_secirvvs/parameters_io.h +++ b/cpp/models/ode_secirvvs/parameters_io.h @@ -896,11 +896,12 @@ IOResult export_input_data_county_timeseries( } } } - BOOST_OUTCOME_TRY(save_result(extrapolated_data, counties, num_groups, path_join(dir, "Results_rki.h5"))); + BOOST_OUTCOME_TRY( + save_result(extrapolated_data, counties, static_cast(num_groups), path_join(dir, "Results_rki.h5"))); auto extrapolated_rki_data_sum = sum_nodes(std::vector>>{extrapolated_data}); - BOOST_OUTCOME_TRY( - save_result({extrapolated_rki_data_sum[0][0]}, {0}, num_groups, path_join(dir, "Results_rki_sum.h5"))); + BOOST_OUTCOME_TRY(save_result({extrapolated_rki_data_sum[0][0]}, {0}, static_cast(num_groups), + path_join(dir, "Results_rki_sum.h5"))); return success(); } From 8f378001290c8dbd59e9cc5e23e0b3206c604259 Mon Sep 17 00:00:00 2001 From: HenrZu <69154294+HenrZu@users.noreply.github.com> Date: Thu, 27 Jun 2024 13:11:10 +0200 Subject: [PATCH 17/46] reset secir ageres example --- cpp/examples/ode_secir_ageres.cpp | 74 +++++++++++-------------------- 1 file changed, 27 insertions(+), 47 deletions(-) diff --git a/cpp/examples/ode_secir_ageres.cpp b/cpp/examples/ode_secir_ageres.cpp index 06a2872325..0d9293212c 100644 --- a/cpp/examples/ode_secir_ageres.cpp +++ b/cpp/examples/ode_secir_ageres.cpp @@ -18,13 +18,9 @@ * limitations under the License. */ #include "ode_secir/model.h" -#include "ode_secir/parameters_io.h" #include "memilio/utils/time_series.h" #include "memilio/utils/logging.h" #include "memilio/compartments/simulation.h" -#include -#include -#include int main() { @@ -37,6 +33,8 @@ int main() mio::log_info("Simulating SECIR; t={} ... {} with dt = {}.", t0, tmax, dt); + double cont_freq = 10; // see Polymod study + double nb_total_t0 = 10000, nb_exp_t0 = 100, nb_inf_t0 = 50, nb_car_t0 = 50, nb_hosp_t0 = 20, nb_icu_t0 = 10, nb_rec_t0 = 10, nb_dead_t0 = 0; @@ -46,7 +44,7 @@ int main() // theta = theta_in; // icu per hospitalized // delta = delta_in; // deaths per ICUs - mio::osecir::Model model(6); + mio::osecir::Model model(3); auto nb_groups = model.parameters.get_num_groups(); double fact = 1.0 / (double)(size_t)nb_groups; @@ -81,55 +79,37 @@ int main() params.get>()[i] = 0.25; params.get>()[i] = 0.45; params.get>()[i] = 0.2; - params.get>()[i] = 0.45; + params.get>()[i] = 0.25; params.get>()[i] = 0.3; } model.apply_constraints(); - // tests - const auto num_age_groups = 6; - const std::string TEST_DATA_DIR = "/localdata1/code_2024/memilio/data/"; - // mio::path_join(TEST_DATA_DIR, "county_divi_ma7.json"), - // mio::path_join(TEST_DATA_DIR, "cases_all_county_age_ma7.json"), - // mio::path_join(TEST_DATA_DIR, "county_current_population.json"), - const auto ICU_DIR = TEST_DATA_DIR + "pydata/Germany/county_divi_ma7.json"; - const auto CASES_DIR = TEST_DATA_DIR + "pydata/Germany/cases_all_county_age_ma7.json"; - const auto POPULATION_DIR = TEST_DATA_DIR + "pydata/Germany/county_current_population.json"; - // const auto results_dir = "/localdata1/code_2024/memilio/test"; - std::vector> models1 = {model}; - // auto status_export = mio::osecir::export_input_data_county_timeseries( - // models1, TEST_DATA_DIR, {1001}, {2020, 12, 01}, std::vector(size_t(num_age_groups), 1.0), 1.0, 1); - - auto vec_days = std::vector{1, 5, 10, 20}; - for (auto days : vec_days) { - auto times = std::vector(); - for (int i = 0; i < 20; ++i) { - auto start = std::chrono::high_resolution_clock::now(); - - // Call the function - auto status_export = mio::osecir::export_input_data_county_timeseries( - models1, TEST_DATA_DIR, {1001}, {2020, 12, 01}, std::vector(size_t(num_age_groups), 1.0), 1.0, - days, ICU_DIR, CASES_DIR, POPULATION_DIR); - - auto end = std::chrono::high_resolution_clock::now(); - std::chrono::duration diff = end - start; - - times.push_back(diff.count()); - mio::unused(status_export); - } - double average_time = std::accumulate(times.begin(), times.end(), 0.0) / times.size(); - std::cout << "Average time to run function: " << average_time << "s for days = " << days << "\n"; - } + mio::ContactMatrixGroup& contact_matrix = params.get>(); + contact_matrix[0] = + mio::ContactMatrix(Eigen::MatrixXd::Constant((size_t)nb_groups, (size_t)nb_groups, fact * cont_freq)); + contact_matrix.add_damping(Eigen::MatrixXd::Constant((size_t)nb_groups, (size_t)nb_groups, 0.7), + mio::SimulationTime(30.)); + + mio::TimeSeries secir = mio::simulate>(t0, tmax, dt, model); + bool print_to_terminal = true; - // std::vector models2 = {model}; - // auto read_result1 = mio::osecir::read_input_data_county(models2, {2020, 12, 01}, {1001}, - // std::vector(size_t(num_age_groups), 1.0), 1.0, - // TEST_DATA_DIR, 1, false); + if (print_to_terminal) { - // mio::TimeSeries secir = simulate(0.0, 1.0, 1.0, models2[0]); + std::vector vars = {"S", "E", "C", "C_confirmed", "I", "I_confirmed", "H", "U", "R", "D"}; + printf("Number of time points :%d\n", static_cast(secir.get_num_time_points())); + printf("People in\n"); - // std::cout << secir.get_value(0) << std::endl; + for (size_t k = 0; k < (size_t)mio::osecir::InfectionState::Count; k++) { + double dummy = 0; - // mio::unused(read_result1); + for (size_t i = 0; i < (size_t)params.get_num_groups(); i++) { + printf("\t %s[%d]: %.0f", vars[k].c_str(), (int)i, + secir.get_last_value()[k + (size_t)mio::osecir::InfectionState::Count * (int)i]); + dummy += secir.get_last_value()[k + (size_t)mio::osecir::InfectionState::Count * (int)i]; + } + + printf("\t %s_otal: %.0f\n", vars[k].c_str(), dummy); + } + } } From 92cffab4fb4b284b829ba0f661930b2b081fe53d Mon Sep 17 00:00:00 2001 From: HenrZu <69154294+HenrZu@users.noreply.github.com> Date: Thu, 27 Jun 2024 14:24:24 +0200 Subject: [PATCH 18/46] delete old function --- cpp/models/ode_secirvvs/parameters_io.h | 16 ++++------------ 1 file changed, 4 insertions(+), 12 deletions(-) diff --git a/cpp/models/ode_secirvvs/parameters_io.h b/cpp/models/ode_secirvvs/parameters_io.h index d8338a71df..f33ca6a0d6 100644 --- a/cpp/models/ode_secirvvs/parameters_io.h +++ b/cpp/models/ode_secirvvs/parameters_io.h @@ -907,18 +907,10 @@ IOResult export_input_data_county_timeseries( } #else template -IOResult export_input_data_county_timeseries(std::vector&, const std::string&, std::vector const&, - Date, const std::vector&, double, int, const std::string&, - const std::string&, const std::string&) -{ - mio::log_warning("HDF5 not available. Cannot export time series of extrapolated real data."); - return success(); -} - -template -IOResult export_input_data_county_timeseries(std::vector&&, const std::string&, std::vector const&, - Date, const std::vector&, double, int, const std::string&, - const std::string&, const std::string&, bool, const std::string&) +IOResult export_input_data_county_timeseries(std::vector, const std::string&, const std::vector&, + Date, const std::vector&, const double, const int, + const std::string&, const std::string&, const std::string&, bool, + const std::string&) { mio::log_warning("HDF5 not available. Cannot export time series of extrapolated real data."); return success(); From 113c02426b3822080f821a7cd9e16e47f566d65c Mon Sep 17 00:00:00 2001 From: HenrZu <69154294+HenrZu@users.noreply.github.com> Date: Thu, 27 Jun 2024 15:38:58 +0200 Subject: [PATCH 19/46] add more tests for input data with old date --- cpp/tests/test_odesecir.cpp | 32 +++++++++++++++++++++++++++++++ cpp/tests/test_odesecirvvs.cpp | 35 ++++++++++++++++++++++++++++++++++ 2 files changed, 67 insertions(+) diff --git a/cpp/tests/test_odesecir.cpp b/cpp/tests/test_odesecir.cpp index e517568eb5..97fdc31b6a 100644 --- a/cpp/tests/test_odesecir.cpp +++ b/cpp/tests/test_odesecir.cpp @@ -1312,5 +1312,37 @@ TEST(TestOdeSecir, model_initialization) ASSERT_THAT(print_wrap(model_vector[0].populations.array().cast()), MatrixNear(print_wrap(expected_values), 1e-5, 1e-5)); } + +TEST(TestOdeSecir, model_initialization_old_date) +{ + constexpr auto num_age_groups = 6; //reading data requires RKI data age groups + mio::osecir::Model model(make_model(num_age_groups)); + + // Vector assignment necessary as read_input_data_county changes model + auto model_vector = std::vector>{model}; + + ASSERT_THAT(mio::osecir::read_input_data_county(model_vector, {1000, 12, 01}, {1002}, + std::vector(size_t(num_age_groups), 1.0), 1.0, + TEST_DATA_DIR, 2, false), + IsSuccess()); + + // if we enter an old date, the model only should be initialized with the population data. + // read population data + std::string path = mio::path_join(TEST_DATA_DIR, "county_current_population.json"); + const std::vector region{1002}; + auto result_one_age_group = mio::osecir::details::read_population_data(path, region, false).value(); + + // So, the expected values are the population data in the susceptible compartments and zeros in the other compartments. + auto expected_values = + (Eigen::ArrayXd(num_age_groups * Eigen::Index(mio::osecir::InfectionState::Count)) + << result_one_age_group[0][0], + 0, 0, 0, 0, 0, 0, 0, 0, 0, result_one_age_group[0][1], 0, 0, 0, 0, 0, 0, 0, 0, 0, result_one_age_group[0][2], + 0, 0, 0, 0, 0, 0, 0, 0, 0, result_one_age_group[0][3], 0, 0, 0, 0, 0, 0, 0, 0, 0, result_one_age_group[0][4], + 0, 0, 0, 0, 0, 0, 0, 0, 0, result_one_age_group[0][5], 0, 0, 0, 0, 0, 0, 0, 0, 0) + .finished(); + + ASSERT_THAT(print_wrap(model_vector[0].populations.array().cast()), + MatrixNear(print_wrap(expected_values), 1e-5, 1e-5)); +} #endif #endif diff --git a/cpp/tests/test_odesecirvvs.cpp b/cpp/tests/test_odesecirvvs.cpp index 14708e7f5c..1e7e2416e4 100644 --- a/cpp/tests/test_odesecirvvs.cpp +++ b/cpp/tests/test_odesecirvvs.cpp @@ -795,6 +795,41 @@ TEST(TestOdeSECIRVVS, model_initialization) MatrixNear(print_wrap(expected_values), 1e-5, 1e-5)); } +TEST(TestOdeSECIRVVS, model_initialization_old_date) +{ + constexpr auto num_age_groups = 6; // Data to be read requires RKI confirmed cases data age groups + auto model = make_model(num_age_groups); + // Vector assignment necessary as read_input_data_county changes model + auto model_vector = std::vector>{model}; + + ASSERT_THAT(mio::osecirvvs::read_input_data_county(model_vector, {100, 12, 01}, {0}, + std::vector(size_t(num_age_groups), 1.0), 1.0, + TEST_DATA_DIR, 2, false), + IsSuccess()); + + // if we enter an old date, the model only should be initialized with the population data. + // read population data + std::string path = mio::path_join(TEST_DATA_DIR, "county_current_population.json"); + const std::vector region{1002}; + auto result_one_age_group = mio::osecirvvs::details::read_population_data(path, region).value(); + + // So, the expected values are the population data in the susceptible compartments and zeros in the other compartments. + auto expected_values = + (Eigen::ArrayXd(num_age_groups * Eigen::Index(mio::osecirvvs::InfectionState::Count)) << 3468740.0, 0.0, 0.0, + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 3.0, 0.0, 0.0, 0.0, 0.0, + 0.0, 0.0, 7749470.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, + 0.0, 3.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 19217500.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 3.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 30034000.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 3.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 16514700.0, + 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 3.0, 0.0, 0.0, + 0.0, 0.0, 0.0, 0.0, 6182330.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, + 0.0, 0.0, 0.0, 3.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0) + .finished(); + + ASSERT_THAT(print_wrap(model_vector[0].populations.array().cast()), + MatrixNear(print_wrap(expected_values), 1e-5, 1e-5)); +} + TEST(TestOdeSECIRVVS, run_simulation) { auto num_age_groups = 3; From 5b81f94228e7312adb8c0ee7d53b67105aa7748a Mon Sep 17 00:00:00 2001 From: HenrZu <69154294+HenrZu@users.noreply.github.com> Date: Fri, 28 Jun 2024 13:31:27 +0200 Subject: [PATCH 20/46] some assertions and test old dates --- cpp/models/ode_secir/parameters_io.h | 17 +++---- cpp/tests/test_odesecir.cpp | 49 +++++++++++++++--- cpp/tests/test_odesecirvvs.cpp | 76 ++++++++++++++++++++++------ 3 files changed, 109 insertions(+), 33 deletions(-) diff --git a/cpp/models/ode_secir/parameters_io.h b/cpp/models/ode_secir/parameters_io.h index c393cbaa2f..3aceb0ec9c 100644 --- a/cpp/models/ode_secir/parameters_io.h +++ b/cpp/models/ode_secir/parameters_io.h @@ -21,6 +21,7 @@ #define ODESECIR_PARAMETERS_IO_H #include "memilio/config.h" +#include #ifdef MEMILIO_HAS_JSONCPP @@ -252,17 +253,13 @@ IOResult set_population_data(std::vector>& model, const std::vector>& num_population, const std::vector& vregion) { + assert(num_population.size() == vregion.size()); + assert(model.size() == vregion.size()); for (size_t region = 0; region < vregion.size(); region++) { - if (std::accumulate(num_population[region].begin(), num_population[region].end(), 0.0) > 0) { - auto num_groups = model[region].parameters.get_num_groups(); - for (auto i = AgeGroup(0); i < num_groups; i++) { - model[region].populations.template set_difference_from_group_total( - {i, InfectionState::Susceptible}, num_population[region][size_t(i)]); - } - } - else { - return failure(StatusCode::OutOfRange, "No population data available for region " + std::to_string(region) + - ". Population data has not been set."); + auto num_groups = model[region].parameters.get_num_groups(); + for (auto i = AgeGroup(0); i < num_groups; i++) { + model[region].populations.template set_difference_from_group_total( + {i, InfectionState::Susceptible}, num_population[region][size_t(i)]); } } return success(); diff --git a/cpp/tests/test_odesecir.cpp b/cpp/tests/test_odesecir.cpp index 97fdc31b6a..53521a8df9 100644 --- a/cpp/tests/test_odesecir.cpp +++ b/cpp/tests/test_odesecir.cpp @@ -1285,6 +1285,42 @@ TEST(TestOdeSecir, export_time_series_init) MatrixNear(print_wrap(expected_results[0].get_groups().matrix()), 1e-5, 1e-5)); } +TEST(TestOdeSecir, export_time_series_init_old_date) +{ + TempFileRegister temp_file_register; + auto tmp_results_dir = temp_file_register.get_unique_path(); + ASSERT_THAT(mio::create_directory(tmp_results_dir), IsSuccess()); + + constexpr auto num_age_groups = 6; //reading data requires RKI data age groups + mio::osecir::Model model(make_model(num_age_groups)); + + // Test exporting time series + std::vector> models{model}; + ASSERT_THAT(mio::osecir::export_input_data_county_timeseries( + models, tmp_results_dir, {1002}, {1000, 12, 01}, std::vector(size_t(num_age_groups), 1.0), + 1.0, 0, mio::path_join(TEST_DATA_DIR, "county_divi_ma7.json"), + mio::path_join(TEST_DATA_DIR, "cases_all_county_age_ma7.json"), + mio::path_join(TEST_DATA_DIR, "county_current_population.json")), + IsSuccess()); + + auto data_extrapolated = mio::read_result(mio::path_join(tmp_results_dir, "Results_rki.h5")); + ASSERT_THAT(data_extrapolated, IsSuccess()); + auto results_extrapolated = data_extrapolated.value()[0].get_groups().get_value(0); + + // if we enter an old date, the model only should be initialized with the population data. + // read population data + std::string path = mio::path_join(TEST_DATA_DIR, "county_current_population.json"); + const std::vector region{1002}; + auto population_data = mio::osecir::details::read_population_data(path, region, false).value(); + + // So, the expected values are the population data in the susceptible compartments and zeros in the other compartments. + for (auto i = 0; i < num_age_groups; i++) { + EXPECT_EQ(results_extrapolated(i * Eigen::Index(mio::osecir::InfectionState::Count)), population_data[0][i]); + } + // sum of all compartments should be equal to the population + EXPECT_EQ(results_extrapolated.sum(), std::accumulate(population_data[0].begin(), population_data[0].end(), 0.0)); +} + // // Model initialization should return same start values as export time series on that day TEST(TestOdeSecir, model_initialization) { @@ -1323,22 +1359,21 @@ TEST(TestOdeSecir, model_initialization_old_date) ASSERT_THAT(mio::osecir::read_input_data_county(model_vector, {1000, 12, 01}, {1002}, std::vector(size_t(num_age_groups), 1.0), 1.0, - TEST_DATA_DIR, 2, false), + TEST_DATA_DIR, 0, false), IsSuccess()); // if we enter an old date, the model only should be initialized with the population data. // read population data std::string path = mio::path_join(TEST_DATA_DIR, "county_current_population.json"); const std::vector region{1002}; - auto result_one_age_group = mio::osecir::details::read_population_data(path, region, false).value(); + auto population_data = mio::osecir::details::read_population_data(path, region, false).value(); // So, the expected values are the population data in the susceptible compartments and zeros in the other compartments. auto expected_values = - (Eigen::ArrayXd(num_age_groups * Eigen::Index(mio::osecir::InfectionState::Count)) - << result_one_age_group[0][0], - 0, 0, 0, 0, 0, 0, 0, 0, 0, result_one_age_group[0][1], 0, 0, 0, 0, 0, 0, 0, 0, 0, result_one_age_group[0][2], - 0, 0, 0, 0, 0, 0, 0, 0, 0, result_one_age_group[0][3], 0, 0, 0, 0, 0, 0, 0, 0, 0, result_one_age_group[0][4], - 0, 0, 0, 0, 0, 0, 0, 0, 0, result_one_age_group[0][5], 0, 0, 0, 0, 0, 0, 0, 0, 0) + (Eigen::ArrayXd(num_age_groups * Eigen::Index(mio::osecir::InfectionState::Count)) << population_data[0][0], 0, + 0, 0, 0, 0, 0, 0, 0, 0, population_data[0][1], 0, 0, 0, 0, 0, 0, 0, 0, 0, population_data[0][2], 0, 0, 0, 0, 0, + 0, 0, 0, 0, population_data[0][3], 0, 0, 0, 0, 0, 0, 0, 0, 0, population_data[0][4], 0, 0, 0, 0, 0, 0, 0, 0, 0, + population_data[0][5], 0, 0, 0, 0, 0, 0, 0, 0, 0) .finished(); ASSERT_THAT(print_wrap(model_vector[0].populations.array().cast()), diff --git a/cpp/tests/test_odesecirvvs.cpp b/cpp/tests/test_odesecirvvs.cpp index 1e7e2416e4..6621441a77 100644 --- a/cpp/tests/test_odesecirvvs.cpp +++ b/cpp/tests/test_odesecirvvs.cpp @@ -759,6 +759,50 @@ TEST(TestOdeSECIRVVS, export_time_series_init) MatrixNear(print_wrap(expected_results[0].get_groups().matrix()), 1e-5, 1e-5)); } +TEST(TestOdeSECIRVVS, export_time_series_init_old_date) +{ + TempFileRegister temp_file_register; + auto tmp_results_dir = temp_file_register.get_unique_path(); + ASSERT_THAT(mio::create_directory(tmp_results_dir), IsSuccess()); + + auto num_age_groups = 6; // Data to be read requires RKI confirmed cases data age groups + auto model = make_model(num_age_groups); + + // set vaccinations to zero + model.parameters.get>().array().setConstant(0); + model.parameters.get>().array().setConstant(0); + // set all compartments to zero + model.populations.array().setConstant(0.0); + + // Test exporting time series + ASSERT_THAT(mio::osecirvvs::export_input_data_county_timeseries( + std::vector>{model}, tmp_results_dir, {0}, {20, 12, 01}, + std::vector(size_t(num_age_groups), 1.0), 1.0, 0, + mio::path_join(TEST_DATA_DIR, "county_divi_ma7.json"), + mio::path_join(TEST_DATA_DIR, "cases_all_county_age_ma7.json"), + mio::path_join(TEST_DATA_DIR, "county_current_population.json"), true, + mio::path_join(TEST_DATA_DIR, "vacc_county_ageinf_ma7.json")), + IsSuccess()); + + auto data_extrapolated = mio::read_result(mio::path_join(tmp_results_dir, "Results_rki.h5")); + ASSERT_THAT(data_extrapolated, IsSuccess()); + auto results_extrapolated = data_extrapolated.value()[0].get_groups().get_value(0); + + // if we enter an old date, the model only should be initialized with the population data. + // read population data + std::string path = mio::path_join(TEST_DATA_DIR, "county_current_population.json"); + const std::vector region{0}; + auto population_data = mio::osecirvvs::details::read_population_data(path, region).value(); + + // So, the expected values are the population data in the susceptible compartments and zeros in the other compartments. + for (auto i = 0; i < num_age_groups; i++) { + EXPECT_EQ(results_extrapolated(i * Eigen::Index(mio::osecirvvs::InfectionState::Count)), population_data[0][i]); + } + // sum of all compartments should be equal to the population + EXPECT_NEAR(results_extrapolated.sum(), std::accumulate(population_data[0].begin(), population_data[0].end(), 0.0), + 1e-5); +} + // Model initialization should return same start values as export time series on that day TEST(TestOdeSECIRVVS, model_initialization) { @@ -799,35 +843,35 @@ TEST(TestOdeSECIRVVS, model_initialization_old_date) { constexpr auto num_age_groups = 6; // Data to be read requires RKI confirmed cases data age groups auto model = make_model(num_age_groups); + // set vaccinations to zero + model.parameters.get>().array().setConstant(0); + model.parameters.get>().array().setConstant(0); + // set all compartments to zero + model.populations.array().setConstant(0.0); // Vector assignment necessary as read_input_data_county changes model auto model_vector = std::vector>{model}; ASSERT_THAT(mio::osecirvvs::read_input_data_county(model_vector, {100, 12, 01}, {0}, std::vector(size_t(num_age_groups), 1.0), 1.0, - TEST_DATA_DIR, 2, false), + TEST_DATA_DIR, 0, false), IsSuccess()); // if we enter an old date, the model only should be initialized with the population data. // read population data std::string path = mio::path_join(TEST_DATA_DIR, "county_current_population.json"); - const std::vector region{1002}; - auto result_one_age_group = mio::osecirvvs::details::read_population_data(path, region).value(); + const std::vector region{0}; + auto population_data = mio::osecirvvs::details::read_population_data(path, region).value(); // So, the expected values are the population data in the susceptible compartments and zeros in the other compartments. - auto expected_values = - (Eigen::ArrayXd(num_age_groups * Eigen::Index(mio::osecirvvs::InfectionState::Count)) << 3468740.0, 0.0, 0.0, - 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 3.0, 0.0, 0.0, 0.0, 0.0, - 0.0, 0.0, 7749470.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, - 0.0, 3.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 19217500.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, - 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 3.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 30034000.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, - 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 3.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 16514700.0, - 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 3.0, 0.0, 0.0, - 0.0, 0.0, 0.0, 0.0, 6182330.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, - 0.0, 0.0, 0.0, 3.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0) - .finished(); + for (auto i = 0; i < num_age_groups; i++) { + EXPECT_NEAR( + model_vector[0].populations.array().cast()(i * Eigen::Index(mio::osecirvvs::InfectionState::Count)), + population_data[0][i], 1e-5); + } - ASSERT_THAT(print_wrap(model_vector[0].populations.array().cast()), - MatrixNear(print_wrap(expected_values), 1e-5, 1e-5)); + // sum of all compartments should be equal to the population + EXPECT_NEAR(model_vector[0].populations.array().cast().sum(), + std::accumulate(population_data[0].begin(), population_data[0].end(), 0.0), 1e-5); } TEST(TestOdeSECIRVVS, run_simulation) From 563965d9e6ae7b8bfe9c5e1f2eb23668f1c878af Mon Sep 17 00:00:00 2001 From: HenrZu <69154294+HenrZu@users.noreply.github.com> Date: Fri, 28 Jun 2024 16:07:08 +0200 Subject: [PATCH 21/46] mock that export data is called --- cpp/tests/test_odesecirvvs.cpp | 67 ++++++++++++++++++++++++++++++++++ 1 file changed, 67 insertions(+) diff --git a/cpp/tests/test_odesecirvvs.cpp b/cpp/tests/test_odesecirvvs.cpp index 6621441a77..c78aae7d50 100644 --- a/cpp/tests/test_odesecirvvs.cpp +++ b/cpp/tests/test_odesecirvvs.cpp @@ -874,6 +874,73 @@ TEST(TestOdeSECIRVVS, model_initialization_old_date) std::accumulate(population_data[0].begin(), population_data[0].end(), 0.0), 1e-5); } +namespace mio +{ +namespace osecirvvs +{ +class Mock +{ +public: + MOCK_METHOD(mio::IOResult, export_input_data_county_timeseries, + (const std::vector>&, const std::string&, const std::vector&, + mio::Date, const std::vector&, double, int, const std::string&, const std::string&, + const std::string&, bool, const std::string&), + (const)); +}; + +Mock* mock_export_function = nullptr; + +mio::IOResult export_input_data_county_timeseries(const std::vector>& model, + const std::string& dir, const std::vector& county, + mio::Date date, const std::vector& scaling_factor_inf, + double scaling_factor_icu, int num_days, + const std::string& divi_path, const std::string& cases_path, + const std::string& population_path, bool set_vaccination_data, + const std::string& vaccination_path) +{ + if (mock_export_function) { + return mock_export_function->export_input_data_county_timeseries( + model, dir, county, date, scaling_factor_inf, scaling_factor_icu, num_days, divi_path, cases_path, + population_path, set_vaccination_data, vaccination_path); + } + return mio::success(); +} +} // namespace osecirvvs +} // namespace mio + +class TestOdeSECIRVVSExportData : public ::testing::Test +{ +protected: + void SetUp() override + { + mio::osecirvvs::mock_export_function = &m_mock_export_function; + } + + void TearDown() override + { + mio::osecirvvs::mock_export_function = nullptr; + } + + mio::osecirvvs::Mock m_mock_export_function; +}; + +TEST_F(TestOdeSECIRVVSExportData, ExportFunctionCalled) +{ + auto num_age_groups = 6; //reading data requires RKI data age groups + auto model1 = std::vector>({make_model(num_age_groups)}); + + EXPECT_CALL(m_mock_export_function, + export_input_data_county_timeseries(::testing::_, ::testing::_, ::testing::_, ::testing::_, + ::testing::_, ::testing::_, ::testing::_, ::testing::_, + ::testing::_, ::testing::_, ::testing::_, ::testing::_)) + .Times(1) + .WillOnce(::testing::Return(mio::success())); + + auto result = mio::osecirvvs::read_input_data_county( + model1, {2020, 12, 01}, {1002}, std::vector(size_t(num_age_groups), 1.0), 1.0, TEST_DATA_DIR, 10, true); + ASSERT_TRUE(result.has_value()); +} + TEST(TestOdeSECIRVVS, run_simulation) { auto num_age_groups = 3; From 94771dfb7b527f64481660d477a068988d8389c0 Mon Sep 17 00:00:00 2001 From: HenrZu <69154294+HenrZu@users.noreply.github.com> Date: Mon, 1 Jul 2024 10:56:41 +0200 Subject: [PATCH 22/46] rm include --- cpp/tests/test_odesecirvvs.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/cpp/tests/test_odesecirvvs.cpp b/cpp/tests/test_odesecirvvs.cpp index c78aae7d50..668f34781c 100644 --- a/cpp/tests/test_odesecirvvs.cpp +++ b/cpp/tests/test_odesecirvvs.cpp @@ -45,7 +45,6 @@ #include "ode_secirvvs/analyze_result.h" #include "gtest/gtest.h" -#include "gmock/gmock-matchers.h" #include #include #include From 36ce480cafd02ea4a077524821c85a263b989cdc Mon Sep 17 00:00:00 2001 From: HenrZu <69154294+HenrZu@users.noreply.github.com> Date: Mon, 1 Jul 2024 13:14:59 +0200 Subject: [PATCH 23/46] include gmock --- cpp/tests/test_odesecirvvs.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/cpp/tests/test_odesecirvvs.cpp b/cpp/tests/test_odesecirvvs.cpp index 668f34781c..4dead7e98d 100644 --- a/cpp/tests/test_odesecirvvs.cpp +++ b/cpp/tests/test_odesecirvvs.cpp @@ -45,6 +45,7 @@ #include "ode_secirvvs/analyze_result.h" #include "gtest/gtest.h" +#include "gmock/gmock.h" #include #include #include From 7c48cd4137b8c0c79b8dd91aba729ea5b1b422ff Mon Sep 17 00:00:00 2001 From: HenrZu <69154294+HenrZu@users.noreply.github.com> Date: Tue, 2 Jul 2024 16:28:03 +0200 Subject: [PATCH 24/46] rm gmock include --- cpp/tests/test_odesecirvvs.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/cpp/tests/test_odesecirvvs.cpp b/cpp/tests/test_odesecirvvs.cpp index 4dead7e98d..668f34781c 100644 --- a/cpp/tests/test_odesecirvvs.cpp +++ b/cpp/tests/test_odesecirvvs.cpp @@ -45,7 +45,6 @@ #include "ode_secirvvs/analyze_result.h" #include "gtest/gtest.h" -#include "gmock/gmock.h" #include #include #include From d624fad480737e1fa17cfeaa0c0c89c04fde3f24 Mon Sep 17 00:00:00 2001 From: HenrZu <69154294+HenrZu@users.noreply.github.com> Date: Wed, 3 Jul 2024 13:34:06 +0200 Subject: [PATCH 25/46] comment out mock functions --- cpp/tests/test_odesecirvvs.cpp | 133 +++++++++++++++++---------------- 1 file changed, 67 insertions(+), 66 deletions(-) diff --git a/cpp/tests/test_odesecirvvs.cpp b/cpp/tests/test_odesecirvvs.cpp index 668f34781c..4a8d2f7d47 100644 --- a/cpp/tests/test_odesecirvvs.cpp +++ b/cpp/tests/test_odesecirvvs.cpp @@ -45,6 +45,7 @@ #include "ode_secirvvs/analyze_result.h" #include "gtest/gtest.h" +#include "gmock/gmock.h" #include #include #include @@ -873,72 +874,72 @@ TEST(TestOdeSECIRVVS, model_initialization_old_date) std::accumulate(population_data[0].begin(), population_data[0].end(), 0.0), 1e-5); } -namespace mio -{ -namespace osecirvvs -{ -class Mock -{ -public: - MOCK_METHOD(mio::IOResult, export_input_data_county_timeseries, - (const std::vector>&, const std::string&, const std::vector&, - mio::Date, const std::vector&, double, int, const std::string&, const std::string&, - const std::string&, bool, const std::string&), - (const)); -}; - -Mock* mock_export_function = nullptr; - -mio::IOResult export_input_data_county_timeseries(const std::vector>& model, - const std::string& dir, const std::vector& county, - mio::Date date, const std::vector& scaling_factor_inf, - double scaling_factor_icu, int num_days, - const std::string& divi_path, const std::string& cases_path, - const std::string& population_path, bool set_vaccination_data, - const std::string& vaccination_path) -{ - if (mock_export_function) { - return mock_export_function->export_input_data_county_timeseries( - model, dir, county, date, scaling_factor_inf, scaling_factor_icu, num_days, divi_path, cases_path, - population_path, set_vaccination_data, vaccination_path); - } - return mio::success(); -} -} // namespace osecirvvs -} // namespace mio - -class TestOdeSECIRVVSExportData : public ::testing::Test -{ -protected: - void SetUp() override - { - mio::osecirvvs::mock_export_function = &m_mock_export_function; - } - - void TearDown() override - { - mio::osecirvvs::mock_export_function = nullptr; - } - - mio::osecirvvs::Mock m_mock_export_function; -}; - -TEST_F(TestOdeSECIRVVSExportData, ExportFunctionCalled) -{ - auto num_age_groups = 6; //reading data requires RKI data age groups - auto model1 = std::vector>({make_model(num_age_groups)}); - - EXPECT_CALL(m_mock_export_function, - export_input_data_county_timeseries(::testing::_, ::testing::_, ::testing::_, ::testing::_, - ::testing::_, ::testing::_, ::testing::_, ::testing::_, - ::testing::_, ::testing::_, ::testing::_, ::testing::_)) - .Times(1) - .WillOnce(::testing::Return(mio::success())); - - auto result = mio::osecirvvs::read_input_data_county( - model1, {2020, 12, 01}, {1002}, std::vector(size_t(num_age_groups), 1.0), 1.0, TEST_DATA_DIR, 10, true); - ASSERT_TRUE(result.has_value()); -} +// namespace mio +// { +// namespace osecirvvs +// { +// class MockExtrapolation +// { +// public: +// MOCK_METHOD(mio::IOResult, export_input_data_county_timeseries, +// (const std::vector>&, const std::string&, const std::vector&, +// mio::Date, const std::vector&, double, int, const std::string&, const std::string&, +// const std::string&, bool, const std::string&), +// (const)); +// }; + +// MockExtrapolation* mock_export_function = nullptr; + +// mio::IOResult export_input_data_county_timeseries(const std::vector>& model, +// const std::string& dir, const std::vector& county, +// mio::Date date, const std::vector& scaling_factor_inf, +// double scaling_factor_icu, int num_days, +// const std::string& divi_path, const std::string& cases_path, +// const std::string& population_path, bool set_vaccination_data, +// const std::string& vaccination_path) +// { +// if (mock_export_function) { +// return mock_export_function->export_input_data_county_timeseries( +// model, dir, county, date, scaling_factor_inf, scaling_factor_icu, num_days, divi_path, cases_path, +// population_path, set_vaccination_data, vaccination_path); +// } +// return mio::success(); +// } +// } // namespace osecirvvs +// } // namespace mio + +// class TestOdeSECIRVVSExportData : public ::testing::Test +// { +// protected: +// void SetUp() override +// { +// mio::osecirvvs::mock_export_function = &m_mock_export_function; +// } + +// void TearDown() override +// { +// mio::osecirvvs::mock_export_function = nullptr; +// } + +// mio::osecirvvs::MockExtrapolation m_mock_export_function; +// }; + +// TEST_F(TestOdeSECIRVVSExportData, ExportFunctionCalled) +// { +// auto num_age_groups = 6; //reading data requires RKI data age groups +// auto model1 = std::vector>({make_model(num_age_groups)}); + +// EXPECT_CALL(m_mock_export_function, +// export_input_data_county_timeseries(::testing::_, ::testing::_, ::testing::_, ::testing::_, +// ::testing::_, ::testing::_, ::testing::_, ::testing::_, +// ::testing::_, ::testing::_, ::testing::_, ::testing::_)) +// .Times(1) +// .WillOnce(::testing::Return(mio::success())); + +// auto result = mio::osecirvvs::read_input_data_county( +// model1, {2020, 12, 01}, {1002}, std::vector(size_t(num_age_groups), 1.0), 1.0, TEST_DATA_DIR, 10, true); +// ASSERT_TRUE(result.has_value()); +// } TEST(TestOdeSECIRVVS, run_simulation) { From 236b74174703a881f4e94aa4d6b38445663975af Mon Sep 17 00:00:00 2001 From: HenrZu <69154294+HenrZu@users.noreply.github.com> Date: Wed, 3 Jul 2024 14:17:07 +0200 Subject: [PATCH 26/46] remove comments from mock class --- cpp/tests/test_odesecirvvs.cpp | 66 +++++++++++++++++----------------- 1 file changed, 33 insertions(+), 33 deletions(-) diff --git a/cpp/tests/test_odesecirvvs.cpp b/cpp/tests/test_odesecirvvs.cpp index 4a8d2f7d47..5a221f58e1 100644 --- a/cpp/tests/test_odesecirvvs.cpp +++ b/cpp/tests/test_odesecirvvs.cpp @@ -874,39 +874,39 @@ TEST(TestOdeSECIRVVS, model_initialization_old_date) std::accumulate(population_data[0].begin(), population_data[0].end(), 0.0), 1e-5); } -// namespace mio -// { -// namespace osecirvvs -// { -// class MockExtrapolation -// { -// public: -// MOCK_METHOD(mio::IOResult, export_input_data_county_timeseries, -// (const std::vector>&, const std::string&, const std::vector&, -// mio::Date, const std::vector&, double, int, const std::string&, const std::string&, -// const std::string&, bool, const std::string&), -// (const)); -// }; - -// MockExtrapolation* mock_export_function = nullptr; - -// mio::IOResult export_input_data_county_timeseries(const std::vector>& model, -// const std::string& dir, const std::vector& county, -// mio::Date date, const std::vector& scaling_factor_inf, -// double scaling_factor_icu, int num_days, -// const std::string& divi_path, const std::string& cases_path, -// const std::string& population_path, bool set_vaccination_data, -// const std::string& vaccination_path) -// { -// if (mock_export_function) { -// return mock_export_function->export_input_data_county_timeseries( -// model, dir, county, date, scaling_factor_inf, scaling_factor_icu, num_days, divi_path, cases_path, -// population_path, set_vaccination_data, vaccination_path); -// } -// return mio::success(); -// } -// } // namespace osecirvvs -// } // namespace mio +namespace mio +{ +namespace osecirvvs +{ +class MockExtrapolation +{ +public: + MOCK_METHOD(mio::IOResult, export_input_data_county_timeseries, + (const std::vector>&, const std::string&, const std::vector&, + mio::Date, const std::vector&, double, int, const std::string&, const std::string&, + const std::string&, bool, const std::string&), + (const)); +}; + +MockExtrapolation* mock_export_function = nullptr; + +mio::IOResult export_input_data_county_timeseries(const std::vector>& model, + const std::string& dir, const std::vector& county, + mio::Date date, const std::vector& scaling_factor_inf, + double scaling_factor_icu, int num_days, + const std::string& divi_path, const std::string& cases_path, + const std::string& population_path, bool set_vaccination_data, + const std::string& vaccination_path) +{ + if (mock_export_function) { + return mock_export_function->export_input_data_county_timeseries( + model, dir, county, date, scaling_factor_inf, scaling_factor_icu, num_days, divi_path, cases_path, + population_path, set_vaccination_data, vaccination_path); + } + return mio::success(); +} +} // namespace osecirvvs +} // namespace mio // class TestOdeSECIRVVSExportData : public ::testing::Test // { From a1b00379631b7c859a22ca2b3ca392aeb14544a4 Mon Sep 17 00:00:00 2001 From: HenrZu <69154294+HenrZu@users.noreply.github.com> Date: Wed, 3 Jul 2024 14:33:42 +0200 Subject: [PATCH 27/46] just mock_method --- cpp/tests/test_odesecirvvs.cpp | 34 +++++++++++++++++----------------- 1 file changed, 17 insertions(+), 17 deletions(-) diff --git a/cpp/tests/test_odesecirvvs.cpp b/cpp/tests/test_odesecirvvs.cpp index 5a221f58e1..3279f4768e 100644 --- a/cpp/tests/test_odesecirvvs.cpp +++ b/cpp/tests/test_odesecirvvs.cpp @@ -888,23 +888,23 @@ class MockExtrapolation (const)); }; -MockExtrapolation* mock_export_function = nullptr; - -mio::IOResult export_input_data_county_timeseries(const std::vector>& model, - const std::string& dir, const std::vector& county, - mio::Date date, const std::vector& scaling_factor_inf, - double scaling_factor_icu, int num_days, - const std::string& divi_path, const std::string& cases_path, - const std::string& population_path, bool set_vaccination_data, - const std::string& vaccination_path) -{ - if (mock_export_function) { - return mock_export_function->export_input_data_county_timeseries( - model, dir, county, date, scaling_factor_inf, scaling_factor_icu, num_days, divi_path, cases_path, - population_path, set_vaccination_data, vaccination_path); - } - return mio::success(); -} +// MockExtrapolation* mock_export_function = nullptr; + +// mio::IOResult export_input_data_county_timeseries(const std::vector>& model, +// const std::string& dir, const std::vector& county, +// mio::Date date, const std::vector& scaling_factor_inf, +// double scaling_factor_icu, int num_days, +// const std::string& divi_path, const std::string& cases_path, +// const std::string& population_path, bool set_vaccination_data, +// const std::string& vaccination_path) +// { +// if (mock_export_function) { +// return mock_export_function->export_input_data_county_timeseries( +// model, dir, county, date, scaling_factor_inf, scaling_factor_icu, num_days, divi_path, cases_path, +// population_path, set_vaccination_data, vaccination_path); +// } +// return mio::success(); +// } } // namespace osecirvvs } // namespace mio From 411f4524a5241d59a76763daa17055adfa4b2824 Mon Sep 17 00:00:00 2001 From: HenrZu <69154294+HenrZu@users.noreply.github.com> Date: Wed, 3 Jul 2024 15:06:52 +0200 Subject: [PATCH 28/46] add pointer --- cpp/tests/test_odesecirvvs.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/cpp/tests/test_odesecirvvs.cpp b/cpp/tests/test_odesecirvvs.cpp index 3279f4768e..fa4687c4c8 100644 --- a/cpp/tests/test_odesecirvvs.cpp +++ b/cpp/tests/test_odesecirvvs.cpp @@ -888,7 +888,7 @@ class MockExtrapolation (const)); }; -// MockExtrapolation* mock_export_function = nullptr; +std::shared_ptr mock_export_function = nullptr; // mio::IOResult export_input_data_county_timeseries(const std::vector>& model, // const std::string& dir, const std::vector& county, @@ -913,12 +913,12 @@ class MockExtrapolation // protected: // void SetUp() override // { -// mio::osecirvvs::mock_export_function = &m_mock_export_function; +// mio::osecirvvs::mock_export_function = std::make_shared(); // } // void TearDown() override // { -// mio::osecirvvs::mock_export_function = nullptr; +// mio::osecirvvs::mock_export_function.reset(); // } // mio::osecirvvs::MockExtrapolation m_mock_export_function; From 9ec95505fbe3dafd0d7a48d56da3d384bcb19104 Mon Sep 17 00:00:00 2001 From: HenrZu <69154294+HenrZu@users.noreply.github.com> Date: Wed, 3 Jul 2024 15:27:05 +0200 Subject: [PATCH 29/46] overwrite export function --- cpp/tests/test_odesecirvvs.cpp | 30 +++++++++++++++--------------- 1 file changed, 15 insertions(+), 15 deletions(-) diff --git a/cpp/tests/test_odesecirvvs.cpp b/cpp/tests/test_odesecirvvs.cpp index fa4687c4c8..e7c5e2947a 100644 --- a/cpp/tests/test_odesecirvvs.cpp +++ b/cpp/tests/test_odesecirvvs.cpp @@ -890,21 +890,21 @@ class MockExtrapolation std::shared_ptr mock_export_function = nullptr; -// mio::IOResult export_input_data_county_timeseries(const std::vector>& model, -// const std::string& dir, const std::vector& county, -// mio::Date date, const std::vector& scaling_factor_inf, -// double scaling_factor_icu, int num_days, -// const std::string& divi_path, const std::string& cases_path, -// const std::string& population_path, bool set_vaccination_data, -// const std::string& vaccination_path) -// { -// if (mock_export_function) { -// return mock_export_function->export_input_data_county_timeseries( -// model, dir, county, date, scaling_factor_inf, scaling_factor_icu, num_days, divi_path, cases_path, -// population_path, set_vaccination_data, vaccination_path); -// } -// return mio::success(); -// } +mio::IOResult export_input_data_county_timeseries(const std::vector>& model, + const std::string& dir, const std::vector& county, + mio::Date date, const std::vector& scaling_factor_inf, + double scaling_factor_icu, int num_days, + const std::string& divi_path, const std::string& cases_path, + const std::string& population_path, bool set_vaccination_data, + const std::string& vaccination_path) +{ + if (mock_export_function) { + return mock_export_function->export_input_data_county_timeseries( + model, dir, county, date, scaling_factor_inf, scaling_factor_icu, num_days, divi_path, cases_path, + population_path, set_vaccination_data, vaccination_path); + } + return mio::success(); +} } // namespace osecirvvs } // namespace mio From 14c63b3518076bf8010aadfbcc5ea2311ed90725 Mon Sep 17 00:00:00 2001 From: HenrZu <69154294+HenrZu@users.noreply.github.com> Date: Wed, 3 Jul 2024 15:54:51 +0200 Subject: [PATCH 30/46] rm comments --- cpp/tests/test_odesecirvvs.cpp | 63 +++++++++++++++++----------------- 1 file changed, 31 insertions(+), 32 deletions(-) diff --git a/cpp/tests/test_odesecirvvs.cpp b/cpp/tests/test_odesecirvvs.cpp index e7c5e2947a..0ddb018deb 100644 --- a/cpp/tests/test_odesecirvvs.cpp +++ b/cpp/tests/test_odesecirvvs.cpp @@ -908,39 +908,38 @@ mio::IOResult export_input_data_county_timeseries(const std::vector(); -// } - -// void TearDown() override -// { -// mio::osecirvvs::mock_export_function.reset(); -// } - -// mio::osecirvvs::MockExtrapolation m_mock_export_function; -// }; - -// TEST_F(TestOdeSECIRVVSExportData, ExportFunctionCalled) -// { -// auto num_age_groups = 6; //reading data requires RKI data age groups -// auto model1 = std::vector>({make_model(num_age_groups)}); - -// EXPECT_CALL(m_mock_export_function, -// export_input_data_county_timeseries(::testing::_, ::testing::_, ::testing::_, ::testing::_, -// ::testing::_, ::testing::_, ::testing::_, ::testing::_, -// ::testing::_, ::testing::_, ::testing::_, ::testing::_)) -// .Times(1) -// .WillOnce(::testing::Return(mio::success())); - -// auto result = mio::osecirvvs::read_input_data_county( -// model1, {2020, 12, 01}, {1002}, std::vector(size_t(num_age_groups), 1.0), 1.0, TEST_DATA_DIR, 10, true); -// ASSERT_TRUE(result.has_value()); -// } +class TestOdeSECIRVVSExportData : public ::testing::Test +{ +protected: + void SetUp() override + { + mio::osecirvvs::mock_export_function = std::make_shared(); + } + + void TearDown() override + { + mio::osecirvvs::mock_export_function.reset(); + } + + mio::osecirvvs::MockExtrapolation m_mock_export_function; +}; +TEST_F(TestOdeSECIRVVSExportData, ExportFunctionCalled) +{ + auto num_age_groups = 6; //reading data requires RKI data age groups + auto model1 = std::vector>({make_model(num_age_groups)}); + + EXPECT_CALL(*mio::osecirvvs::mock_export_function, + export_input_data_county_timeseries(::testing::_, ::testing::_, ::testing::_, ::testing::_, + ::testing::_, ::testing::_, ::testing::_, ::testing::_, + ::testing::_, ::testing::_, ::testing::_, ::testing::_)) + .Times(1) + .WillOnce(::testing::Return(mio::success())); + + auto result = mio::osecirvvs::read_input_data_county( + model1, {2020, 12, 01}, {1002}, std::vector(size_t(num_age_groups), 1.0), 1.0, TEST_DATA_DIR, 10, true); + ASSERT_TRUE(result.has_value()); +} TEST(TestOdeSECIRVVS, run_simulation) { auto num_age_groups = 3; From 2731b392aeb62966e96c68a34752bbf436b736f7 Mon Sep 17 00:00:00 2001 From: HenrZu <69154294+HenrZu@users.noreply.github.com> Date: Thu, 4 Jul 2024 11:51:13 +0200 Subject: [PATCH 31/46] comment out test function --- cpp/tests/test_odesecirvvs.cpp | 31 ++++++++++++++++--------------- 1 file changed, 16 insertions(+), 15 deletions(-) diff --git a/cpp/tests/test_odesecirvvs.cpp b/cpp/tests/test_odesecirvvs.cpp index 0ddb018deb..fb6d2e2d94 100644 --- a/cpp/tests/test_odesecirvvs.cpp +++ b/cpp/tests/test_odesecirvvs.cpp @@ -924,22 +924,23 @@ class TestOdeSECIRVVSExportData : public ::testing::Test mio::osecirvvs::MockExtrapolation m_mock_export_function; }; -TEST_F(TestOdeSECIRVVSExportData, ExportFunctionCalled) -{ - auto num_age_groups = 6; //reading data requires RKI data age groups - auto model1 = std::vector>({make_model(num_age_groups)}); +// TEST_F(TestOdeSECIRVVSExportData, ExportFunctionCalled) +// { +// auto num_age_groups = 6; //reading data requires RKI data age groups +// auto model1 = std::vector>({make_model(num_age_groups)}); + +// EXPECT_CALL(*mio::osecirvvs::mock_export_function, +// export_input_data_county_timeseries(::testing::_, ::testing::_, ::testing::_, ::testing::_, +// ::testing::_, ::testing::_, ::testing::_, ::testing::_, +// ::testing::_, ::testing::_, ::testing::_, ::testing::_)) +// .Times(1) +// .WillOnce(::testing::Return(mio::success())); + +// auto result = mio::osecirvvs::read_input_data_county( +// model1, {2020, 12, 01}, {1002}, std::vector(size_t(num_age_groups), 1.0), 1.0, TEST_DATA_DIR, 10, true); +// ASSERT_TRUE(result.has_value()); +// } - EXPECT_CALL(*mio::osecirvvs::mock_export_function, - export_input_data_county_timeseries(::testing::_, ::testing::_, ::testing::_, ::testing::_, - ::testing::_, ::testing::_, ::testing::_, ::testing::_, - ::testing::_, ::testing::_, ::testing::_, ::testing::_)) - .Times(1) - .WillOnce(::testing::Return(mio::success())); - - auto result = mio::osecirvvs::read_input_data_county( - model1, {2020, 12, 01}, {1002}, std::vector(size_t(num_age_groups), 1.0), 1.0, TEST_DATA_DIR, 10, true); - ASSERT_TRUE(result.has_value()); -} TEST(TestOdeSECIRVVS, run_simulation) { auto num_age_groups = 3; From b89683980f80b4b1ab5f96d8a603fe275a602582 Mon Sep 17 00:00:00 2001 From: HenrZu <69154294+HenrZu@users.noreply.github.com> Date: Thu, 4 Jul 2024 13:26:23 +0200 Subject: [PATCH 32/46] comment setup --- cpp/tests/test_odesecirvvs.cpp | 30 +++++++++++++++--------------- 1 file changed, 15 insertions(+), 15 deletions(-) diff --git a/cpp/tests/test_odesecirvvs.cpp b/cpp/tests/test_odesecirvvs.cpp index fb6d2e2d94..aae6f8d757 100644 --- a/cpp/tests/test_odesecirvvs.cpp +++ b/cpp/tests/test_odesecirvvs.cpp @@ -908,21 +908,21 @@ mio::IOResult export_input_data_county_timeseries(const std::vector(); - } - - void TearDown() override - { - mio::osecirvvs::mock_export_function.reset(); - } - - mio::osecirvvs::MockExtrapolation m_mock_export_function; -}; +// class TestOdeSECIRVVSExportData : public ::testing::Test +// { +// protected: +// void SetUp() override +// { +// mio::osecirvvs::mock_export_function = std::make_shared(); +// } + +// void TearDown() override +// { +// mio::osecirvvs::mock_export_function.reset(); +// } + +// mio::osecirvvs::MockExtrapolation m_mock_export_function; +// }; // TEST_F(TestOdeSECIRVVSExportData, ExportFunctionCalled) // { From 586454f82eb567ec24965f46923bc3da6c40e959 Mon Sep 17 00:00:00 2001 From: HenrZu <69154294+HenrZu@users.noreply.github.com> Date: Thu, 4 Jul 2024 14:32:36 +0200 Subject: [PATCH 33/46] comment overwrite function --- cpp/tests/test_odesecirvvs.cpp | 30 +++++++++++++++--------------- 1 file changed, 15 insertions(+), 15 deletions(-) diff --git a/cpp/tests/test_odesecirvvs.cpp b/cpp/tests/test_odesecirvvs.cpp index aae6f8d757..d30ff50f37 100644 --- a/cpp/tests/test_odesecirvvs.cpp +++ b/cpp/tests/test_odesecirvvs.cpp @@ -890,21 +890,21 @@ class MockExtrapolation std::shared_ptr mock_export_function = nullptr; -mio::IOResult export_input_data_county_timeseries(const std::vector>& model, - const std::string& dir, const std::vector& county, - mio::Date date, const std::vector& scaling_factor_inf, - double scaling_factor_icu, int num_days, - const std::string& divi_path, const std::string& cases_path, - const std::string& population_path, bool set_vaccination_data, - const std::string& vaccination_path) -{ - if (mock_export_function) { - return mock_export_function->export_input_data_county_timeseries( - model, dir, county, date, scaling_factor_inf, scaling_factor_icu, num_days, divi_path, cases_path, - population_path, set_vaccination_data, vaccination_path); - } - return mio::success(); -} +// mio::IOResult export_input_data_county_timeseries(const std::vector>& model, +// const std::string& dir, const std::vector& county, +// mio::Date date, const std::vector& scaling_factor_inf, +// double scaling_factor_icu, int num_days, +// const std::string& divi_path, const std::string& cases_path, +// const std::string& population_path, bool set_vaccination_data, +// const std::string& vaccination_path) +// { +// if (mock_export_function) { +// return mock_export_function->export_input_data_county_timeseries( +// model, dir, county, date, scaling_factor_inf, scaling_factor_icu, num_days, divi_path, cases_path, +// population_path, set_vaccination_data, vaccination_path); +// } +// return mio::success(); +// } } // namespace osecirvvs } // namespace mio From eb5876c98692235264ceb7e2d3a5ab3e3f58657c Mon Sep 17 00:00:00 2001 From: HenrZu <69154294+HenrZu@users.noreply.github.com> Date: Fri, 5 Jul 2024 09:46:48 +0200 Subject: [PATCH 34/46] rm mock test because of msvc --- cpp/tests/test_odesecirvvs.cpp | 104 ++++++++++++--------------------- 1 file changed, 36 insertions(+), 68 deletions(-) diff --git a/cpp/tests/test_odesecirvvs.cpp b/cpp/tests/test_odesecirvvs.cpp index d30ff50f37..df8652d641 100644 --- a/cpp/tests/test_odesecirvvs.cpp +++ b/cpp/tests/test_odesecirvvs.cpp @@ -848,7 +848,42 @@ TEST(TestOdeSECIRVVS, model_initialization_old_date) model.parameters.get>().array().setConstant(0); // set all compartments to zero model.populations.array().setConstant(0.0); - // Vector assignment necessary as read_input_data_county changes model + + auto model_vector = std::vector>{model}; + + ASSERT_THAT(mio::osecirvvs::read_input_data(model_vector, {100, 12, 01}, {0}, + std::vector(size_t(num_age_groups), 1.0), 1.0, TEST_DATA_DIR, 0, + false), + IsSuccess()); + + // if we enter an old date, the model only should be initialized with the population data. + // read population data + std::string path = mio::path_join(TEST_DATA_DIR, "county_current_population.json"); + const std::vector region{0}; + auto population_data = mio::osecirvvs::details::read_population_data(path, region).value(); + + // So, the expected values are the population data in the susceptible compartments and zeros in the other compartments. + for (auto i = 0; i < num_age_groups; i++) { + EXPECT_NEAR( + model_vector[0].populations.array().cast()(i * Eigen::Index(mio::osecirvvs::InfectionState::Count)), + population_data[0][i], 1e-5); + } + + // sum of all compartments should be equal to the population + EXPECT_NEAR(model_vector[0].populations.array().cast().sum(), + std::accumulate(population_data[0].begin(), population_data[0].end(), 0.0), 1e-5); +} + +TEST(TestOdeSECIRVVS, model_initialization_old_date_county) +{ + constexpr auto num_age_groups = 6; // Data to be read requires RKI confirmed cases data age groups + auto model = make_model(num_age_groups); + // set vaccinations to zero + model.parameters.get>().array().setConstant(0); + model.parameters.get>().array().setConstant(0); + // set all compartments to zero + model.populations.array().setConstant(0.0); + auto model_vector = std::vector>{model}; ASSERT_THAT(mio::osecirvvs::read_input_data_county(model_vector, {100, 12, 01}, {0}, @@ -874,73 +909,6 @@ TEST(TestOdeSECIRVVS, model_initialization_old_date) std::accumulate(population_data[0].begin(), population_data[0].end(), 0.0), 1e-5); } -namespace mio -{ -namespace osecirvvs -{ -class MockExtrapolation -{ -public: - MOCK_METHOD(mio::IOResult, export_input_data_county_timeseries, - (const std::vector>&, const std::string&, const std::vector&, - mio::Date, const std::vector&, double, int, const std::string&, const std::string&, - const std::string&, bool, const std::string&), - (const)); -}; - -std::shared_ptr mock_export_function = nullptr; - -// mio::IOResult export_input_data_county_timeseries(const std::vector>& model, -// const std::string& dir, const std::vector& county, -// mio::Date date, const std::vector& scaling_factor_inf, -// double scaling_factor_icu, int num_days, -// const std::string& divi_path, const std::string& cases_path, -// const std::string& population_path, bool set_vaccination_data, -// const std::string& vaccination_path) -// { -// if (mock_export_function) { -// return mock_export_function->export_input_data_county_timeseries( -// model, dir, county, date, scaling_factor_inf, scaling_factor_icu, num_days, divi_path, cases_path, -// population_path, set_vaccination_data, vaccination_path); -// } -// return mio::success(); -// } -} // namespace osecirvvs -} // namespace mio - -// class TestOdeSECIRVVSExportData : public ::testing::Test -// { -// protected: -// void SetUp() override -// { -// mio::osecirvvs::mock_export_function = std::make_shared(); -// } - -// void TearDown() override -// { -// mio::osecirvvs::mock_export_function.reset(); -// } - -// mio::osecirvvs::MockExtrapolation m_mock_export_function; -// }; - -// TEST_F(TestOdeSECIRVVSExportData, ExportFunctionCalled) -// { -// auto num_age_groups = 6; //reading data requires RKI data age groups -// auto model1 = std::vector>({make_model(num_age_groups)}); - -// EXPECT_CALL(*mio::osecirvvs::mock_export_function, -// export_input_data_county_timeseries(::testing::_, ::testing::_, ::testing::_, ::testing::_, -// ::testing::_, ::testing::_, ::testing::_, ::testing::_, -// ::testing::_, ::testing::_, ::testing::_, ::testing::_)) -// .Times(1) -// .WillOnce(::testing::Return(mio::success())); - -// auto result = mio::osecirvvs::read_input_data_county( -// model1, {2020, 12, 01}, {1002}, std::vector(size_t(num_age_groups), 1.0), 1.0, TEST_DATA_DIR, 10, true); -// ASSERT_TRUE(result.has_value()); -// } - TEST(TestOdeSECIRVVS, run_simulation) { auto num_age_groups = 3; From 58e7cea95a1dfcbce616bb6aefab41113d20fcd0 Mon Sep 17 00:00:00 2001 From: HenrZu <69154294+HenrZu@users.noreply.github.com> Date: Fri, 5 Jul 2024 14:24:39 +0200 Subject: [PATCH 35/46] test for set_population_data overflow of vacccinated individuals --- cpp/tests/test_odesecirvvs.cpp | 41 ++++++++++++++++++++++++++++++++++ 1 file changed, 41 insertions(+) diff --git a/cpp/tests/test_odesecirvvs.cpp b/cpp/tests/test_odesecirvvs.cpp index df8652d641..a122ac60ee 100644 --- a/cpp/tests/test_odesecirvvs.cpp +++ b/cpp/tests/test_odesecirvvs.cpp @@ -909,6 +909,47 @@ TEST(TestOdeSECIRVVS, model_initialization_old_date_county) std::accumulate(population_data[0].begin(), population_data[0].end(), 0.0), 1e-5); } +TEST(TestOdeSECIRVVS, set_population_data_overflow_vacc) +{ + auto num_age_groups = 6; // Data to be read requires RKI confirmed cases data age groups + auto model = make_model(num_age_groups); + // set all compartments to zero + model.populations.array().setConstant(0.0); + + // if the number of vaccinated individuals is greater than the population, we must limit the number of vaccinated. + model.parameters + .template get>()[{mio::AgeGroup(0), mio::SimulationDay(0)}] = + 1e7 + 1; + + model.parameters + .template get>()[{mio::AgeGroup(0), mio::SimulationDay(0)}] = 1e7; + + // Vector assignment necessary as read_input_data_county changes model + auto model_vector = std::vector>{model}; + + std::string path_pop_data = mio::path_join(TEST_DATA_DIR, "county_current_population.json"); + const std::vector region{0}; + auto population_data = mio::osecirvvs::details::read_population_data(path_pop_data, region).value(); + + // we choose the date so that no case data is available + ASSERT_THAT(mio::osecirvvs::details::set_population_data( + model_vector, path_pop_data, mio::path_join(TEST_DATA_DIR, "cases_all_county_age_ma7.json"), {0}, + {1000, 12, 01}), + IsSuccess()); + + EXPECT_NEAR( + double(model_vector[0].populations[{mio::AgeGroup(0), mio::osecirvvs::InfectionState::SusceptibleNaive}]), 0.0, + 1e-10); + EXPECT_NEAR(double(model_vector[0].populations[{mio::AgeGroup(0), + mio::osecirvvs::InfectionState::SusceptiblePartialImmunity}]), + 1, 1e-10); + EXPECT_NEAR(double(model_vector[0].populations[{mio::AgeGroup(0), + mio::osecirvvs::InfectionState::SusceptibleImprovedImmunity}]), + population_data[0][0] - 1, 1e-10); + + EXPECT_NEAR(model_vector[0].populations.get_group_total(mio::AgeGroup(0)), population_data[0][0], 1e-9); +} + TEST(TestOdeSECIRVVS, run_simulation) { auto num_age_groups = 3; From 5a708e0ee44e48f02dedca553ab10c75d89cb920 Mon Sep 17 00:00:00 2001 From: HenrZu <69154294+HenrZu@users.noreply.github.com> Date: Wed, 10 Jul 2024 17:07:20 +0200 Subject: [PATCH 36/46] one more test with no pop data avail --- cpp/tests/test_odesecirvvs.cpp | 30 ++++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) diff --git a/cpp/tests/test_odesecirvvs.cpp b/cpp/tests/test_odesecirvvs.cpp index a122ac60ee..c73aa94e0c 100644 --- a/cpp/tests/test_odesecirvvs.cpp +++ b/cpp/tests/test_odesecirvvs.cpp @@ -950,6 +950,36 @@ TEST(TestOdeSECIRVVS, set_population_data_overflow_vacc) EXPECT_NEAR(model_vector[0].populations.get_group_total(mio::AgeGroup(0)), population_data[0][0], 1e-9); } +TEST(TestOdeSECIRVVS, set_population_data_no_data_avail) +{ + auto num_age_groups = 6; // Data to be read requires RKI confirmed cases data age groups + auto model = make_model(num_age_groups); + // set all compartments to zero + model.populations.array().setConstant(0.0); + + // if the number of vaccinated individuals is greater than the population, we must limit the number of vaccinated. + model.parameters + .template get>()[{mio::AgeGroup(0), mio::SimulationDay(0)}] = 0; + + model.parameters + .template get>()[{mio::AgeGroup(0), mio::SimulationDay(0)}] = 0; + + // Vector assignment necessary as read_input_data_county changes model + auto model_vector = std::vector>{model}; + + std::string path_pop_data = mio::path_join(TEST_DATA_DIR, "county_current_population.json"); + const std::vector region{0}; + auto population_data = mio::osecirvvs::details::read_population_data(path_pop_data, region).value(); + + // we choose the date so that no case data is available + ASSERT_THAT(mio::osecirvvs::details::set_population_data( + model_vector, path_pop_data, mio::path_join(TEST_DATA_DIR, "cases_all_county_age_ma7.json"), {200}, + {1000, 12, 01}), + IsSuccess()); + + EXPECT_NEAR(model.populations.get_total(), 0.0, 1e-10); +} + TEST(TestOdeSECIRVVS, run_simulation) { auto num_age_groups = 3; From d899aa9882b7e5e9c1899f2781ae254a35ba688e Mon Sep 17 00:00:00 2001 From: Henrik Zunker Date: Thu, 15 Aug 2024 10:33:55 +0200 Subject: [PATCH 37/46] mainly update documentation --- cpp/models/ode_secir/parameters_io.cpp | 8 +- cpp/models/ode_secir/parameters_io.h | 209 ++++++++++++------------ cpp/models/ode_secirvvs/parameters_io.h | 123 +++++++------- 3 files changed, 170 insertions(+), 170 deletions(-) diff --git a/cpp/models/ode_secir/parameters_io.cpp b/cpp/models/ode_secir/parameters_io.cpp index 7fe6fa6fa6..68923adb90 100644 --- a/cpp/models/ode_secir/parameters_io.cpp +++ b/cpp/models/ode_secir/parameters_io.cpp @@ -58,7 +58,7 @@ int get_region_id(int id) } IOResult read_confirmed_cases_data( - std::string const& path, std::vector& rki_data, std::vector const& vregion, Date date, + std::vector& rki_data, std::vector const& vregion, Date date, std::vector>& vnum_Exposed, std::vector>& vnum_InfectedNoSymptoms, std::vector>& vnum_InfectedSymptoms, std::vector>& vnum_InfectedSevere, std::vector>& vnum_icu, std::vector>& vnum_death, @@ -74,12 +74,12 @@ IOResult read_confirmed_cases_data( }); if (max_date_entry == rki_data.end()) { log_error("RKI data file is empty."); - return failure(StatusCode::InvalidFileFormat, path + ", file is empty."); + return failure(StatusCode::InvalidFileFormat, "RKI file is empty."); } auto max_date = max_date_entry->date; if (max_date < date) { log_error("Specified date does not exist in RKI data"); - return failure(StatusCode::OutOfRange, path + ", specified date does not exist in RKI data."); + return failure(StatusCode::OutOfRange, "Specified date does not exist in RKI data."); } auto days_surplus = std::min(get_offset_in_days(max_date, date) - 6, 0); @@ -277,4 +277,4 @@ read_population_data(const std::string& path, const std::vector& vregion, b #endif // MEMILIO_HAS_JSONCPP -GCC_CLANG_DIAGNOSTIC(pop) \ No newline at end of file +GCC_CLANG_DIAGNOSTIC(pop) diff --git a/cpp/models/ode_secir/parameters_io.h b/cpp/models/ode_secir/parameters_io.h index 3aceb0ec9c..ee3dd1597c 100644 --- a/cpp/models/ode_secir/parameters_io.h +++ b/cpp/models/ode_secir/parameters_io.h @@ -38,28 +38,27 @@ namespace osecir namespace details { /** - * @brief interpolates age_ranges to param_ranges and saves ratios in interpolation - * @param age_ranges original age ranges of the data - * @param interpolation vector of ratios that are aplied to the data of age_ranges - * @param carry_over boolean vector which indicates whether there is an overflow from one age group to the next while interpolating data + * @brief Interpolates age_ranges to param_ranges and saves ratios in interpolation. + * @param age_ranges Original age ranges of the data. + * @param interpolation Vector of ratios that are aplied to the data of age_ranges. + * @param carry_over Boolean vector which indicates whether there is an overflow from one age group to the next while interpolating data. */ void interpolate_ages(const std::vector& age_ranges, std::vector>& interpolation, std::vector& carry_over); /** - * @brief reads populations data from RKI - * @param[in] path Path to RKI file - * @param[in] rki_data Vector of ConfirmedCasesDataEntry%s - * @param[in] region vector of keys of the region of interest - * @param[in] year Specifies year at which the data is read - * @param[in] month Specifies month at which the data is read - * @param[in] day Specifies day at which the data is read - * @param[in, out] num_* output vector for number of people in the corresponding compartement - * @param[in] t_* vector average time it takes to get from one compartement to another for each age group - * @param[in] mu_* vector probabilities to get from one compartement to another for each age group + * @brief reads populations data from RKI. + * @param[in] rki_data Vector of ConfirmedCasesDataEntry%s. + * @param[in] region Vector of keys of the region of interest. + * @param[in] year Specifies year at which the data is read. + * @param[in] month Specifies month at which the data is read. + * @param[in] day Specifies day at which the data is read. + * @param[in, out] num_* Output vector for number of people in the corresponding compartement. + * @param[in] t_* vector Average time it takes to get from one compartement to another for each age group. + * @param[in] mu_* vector Probabilities to get from one compartement to another for each age group. */ IOResult read_confirmed_cases_data( - std::string const& path, std::vector& rki_data, std::vector const& vregion, Date date, + std::vector& rki_data, std::vector const& vregion, Date date, std::vector>& vnum_Exposed, std::vector>& vnum_InfectedNoSymptoms, std::vector>& vnum_InfectedSymptoms, std::vector>& vnum_InfectedSevere, std::vector>& vnum_icu, std::vector>& vnum_death, @@ -71,19 +70,18 @@ IOResult read_confirmed_cases_data( const std::vector& scaling_factor_inf); /** - * @brief sets populations data from already read data with multiple age groups into a Model with one age group - * @tparam FP floating point data type, e.g., double - * @param[in, out] model vector of objects in which the data is set - * @param[in] path Path to confirmed cases file - * @param[in] case_data List of confirmed cases data entries - * @param[in] region vector of keys of the region of interest - * @param[in] date Date at which the data is read - * @param[in] scaling_factor_inf factors by which to scale the confirmed cases of rki data + * @brief Sets populations data from already read case data with multiple age groups into a Model with one age group. + * @tparam FP Floating point data type, e.g., double. + * @param[in, out] model Vector of models in which the data is set. + * @param[in] case_data List of confirmed cases data entries. + * @param[in] region Vector of keys of the region of interest. + * @param[in] date Date at which the data is read. + * @param[in] scaling_factor_inf Factors by which to scale the confirmed cases of rki data. */ template -IOResult set_confirmed_cases_data(std::vector>& model, const std::string& path, - std::vector& case_data, const std::vector& region, - Date date, const std::vector& scaling_factor_inf) +IOResult set_confirmed_cases_data(std::vector>& model, std::vector& case_data, + const std::vector& region, Date date, + const std::vector& scaling_factor_inf) { const size_t num_age_groups = ConfirmedCasesDataEntry::age_group_names.size(); assert(scaling_factor_inf.size() == num_age_groups); @@ -129,7 +127,7 @@ IOResult set_confirmed_cases_data(std::vector>& model, const std std::vector> num_InfectedSevere(model.size(), std::vector(num_age_groups, 0.0)); std::vector> num_icu(model.size(), std::vector(num_age_groups, 0.0)); - BOOST_OUTCOME_TRY(read_confirmed_cases_data(path, case_data, region, date, num_Exposed, num_InfectedNoSymptoms, + BOOST_OUTCOME_TRY(read_confirmed_cases_data(case_data, region, date, num_Exposed, num_InfectedNoSymptoms, num_InfectedSymptoms, num_InfectedSevere, num_icu, num_death, num_rec, t_Exposed, t_InfectedNoSymptoms, t_InfectedSymptoms, t_InfectedSevere, t_InfectedCritical, mu_C_R, mu_I_H, mu_H_U, scaling_factor_inf)); @@ -160,9 +158,9 @@ IOResult set_confirmed_cases_data(std::vector>& model, const std } /** - * @brief Sets the infected population for a given model based on confirmed cases data. - * - * @tparam FP floating point data type, e.g., double + * @brief Sets the infected population for a given model based on confirmed cases data. Here, we + * read the case data from a file. + * @tparam FP Floating point data type, e.g., double. * @param model Vector of models for which the confirmed cases data will be set. * @param path Path to the confirmed cases data file. * @param region Vector of keys of the region of interest @@ -175,32 +173,32 @@ IOResult set_confirmed_cases_data(std::vector>& model, const std const std::vector& scaling_factor_inf) { BOOST_OUTCOME_TRY(auto&& case_data, mio::read_confirmed_cases_data(path)); - BOOST_OUTCOME_TRY(set_confirmed_cases_data(model, path, case_data, region, date, scaling_factor_inf)); + BOOST_OUTCOME_TRY(set_confirmed_cases_data(model, case_data, region, date, scaling_factor_inf)); return success(); } /** - * @brief reads number of ICU patients from DIVI register into Parameters - * @param path Path to DIVI file - * @param vregion Keys of the region of interest - * @param year Specifies year at which the data is read - * @param month Specifies month at which the data is read - * @param day Specifies day at which the data is read - * @param vnum_icu number of ICU patients + * @brief Reads number of ICU patients from DIVI register into Parameters. + * @param path Path to DIVI file. + * @param vregion Keys of the region of interest. + * @param year Specifies year at which the data is read. + * @param month Specifies month at which the data is read. + * @param day Specifies day at which the data is read. + * @param vnum_icu Number of ICU patients. */ IOResult read_divi_data(const std::string& path, const std::vector& vregion, Date date, std::vector& vnum_icu); /** - * @brief sets populations data from DIVI register into Model - * @tparam FP floating point data type, e.g., double - * @param model vector of objects in which the data is set - * @param path Path to DIVI file - * @param vregion vector of keys of the regions of interest - * @param year Specifies year at which the data is read - * @param month Specifies month at which the data is read - * @param day Specifies day at which the data is read - * @param scaling_factor_icu factor by which to scale the icu cases of divi data + * @brief Sets populations data from DIVI register into Model. + * @tparam FP floating point data type, e.g., double. + * @param model Vector of models in which the data is set. + * @param path Path to DIVI file. + * @param vregion Vector of keys of the regions of interest. + * @param year Specifies year at which the data is read. + * @param month Specifies month at which the data is read. + * @param day Specifies day at which the data is read. + * @param scaling_factor_icu factor by which to scale the icu cases of divi data. */ template IOResult set_divi_data(std::vector>& model, const std::string& path, const std::vector& vregion, @@ -232,21 +230,21 @@ IOResult set_divi_data(std::vector>& model, const std::string& p } /** - * @brief Reads population data from census data - * @tparam FP floating point data type, e.g., double - * @param[in] path Path to RKI file - * @param[in] vregion Vector of keys of the regions of interest - * @param[in] accumulate_age_groups Specifies whether population data sould be accumulated to one age group + * @brief Reads population data from census data. + * @tparam FP floating point data type, e.g., double. + * @param[in] path Path to RKI file. + * @param[in] vregion Vector of keys of the regions of interest. + * @param[in] accumulate_age_groups Specifies whether population data should be accumulated to one age group. */ IOResult>> read_population_data(const std::string& path, const std::vector& vregion, bool accumulate_age_groups = false); /** -* @brief sets population data from census data which has been read into num_population -* @tparam FP floating point data type, e.g., double -* @param[in, out] model vector of objects in which the data is set -* @param[in] num_population vector of population data -* @param[in] vregion vector of keys of the regions of interest +* @brief Sets population data from census data which has been read into num_population. +* @tparam FP floating point data type, e.g., double. +* @param[in, out] model Vector of models in which the data is set. There should be one model per region. +* @param[in] num_population Vector of population data. The size should be the same as vregion and model. +* @param[in] vregion Vector of keys of the regions of interest. */ template IOResult set_population_data(std::vector>& model, @@ -266,12 +264,12 @@ IOResult set_population_data(std::vector>& model, } /** -* @brief sets population data from census data into a Model -* @tparam FP floating point data type, e.g., double -* @param[in, out] model vector of objects in which the data is set -* @param[in] path Path to RKI file containing population data -* @param[in] vregion vector of keys of the regions of interest -* @param[in] accumulate_age_groups specifies whether population data sould be accumulated to one age group +* @brief Sets population data from census data into a Model. +* @tparam FP Floating point data type, e.g., double. +* @param[in, out] model Vector of models in which the data is set. +* @param[in] path Path to RKI file containing population data. +* @param[in] vregion Vector of keys of the regions of interest. +* @param[in] accumulate_age_groups Specifies whether population data should be accumulated to one age group. */ template IOResult set_population_data(std::vector>& model, const std::string& path, @@ -287,22 +285,26 @@ IOResult set_population_data(std::vector>& model, const std::str #ifdef MEMILIO_HAS_HDF5 /** -* @brief sets populations data from RKI into a Model with one age group -* @param model vector of models in which the data is set. Copy is made to avoid changing the original model -* @param data_dir Path to RKI files -* @param results_dir Path to result files -* @param region vector of keys of the region of interest -* @param year Specifies year at which the data is read -* @param month Specifies month at which the data is read -* @param day Specifies day at which the data is read -* @param scaling_factor_inf factors by which to scale the confirmed cases of rki data +* @brief Uses the initialisation method, which uses the reported data to set the initial conditions for the model for a given day. +* The initialisation is applied for a predefined number of days and finally saved in a timeseries for each region. In the end, +* we save the files "Results_rki.h5" and "Results_rki_sum.h5" in the results_dir. +* Results_rki.h5 contains a time series for each region and Results_rki_sum.h5 contains the sum of all regions. +* @param models Vector of models in which the data is set. Copy is made to avoid changing the original model. +* @param results_dir Path to result files. +* @param region Vector of keys of the region of interest. +* @param date Date for which the data should be read. +* @param scaling_factor_inf Factors by which to scale the confirmed cases of rki data. +* @param scaling_factor_icu Factor by which to scale the icu cases of divi data. +* @param num_days Number of days to be simulated/initialized. +* @param divi_data_path Path to DIVI file. +* @param confirmed_cases_path Path to confirmed cases file. +* @param population_data_path Path to population data file. */ template -IOResult -export_input_data_county_timeseries(std::vector models, const std::string& dir, std::vector const& region, - Date date, const std::vector& scaling_factor_inf, double scaling_factor_icu, - int num_days, const std::string& divi_data_path, - const std::string& confirmed_cases_path, const std::string& population_data_path) +IOResult export_input_data_county_timeseries( + std::vector models, const std::string& results_dir, std::vector const& region, Date date, + const std::vector& scaling_factor_inf, double scaling_factor_icu, int num_days, + const std::string& divi_data_path, const std::string& confirmed_cases_path, const std::string& population_data_path) { const auto num_age_groups = (size_t)models[0].parameters.get_num_groups(); assert(scaling_factor_inf.size() == num_age_groups); @@ -324,18 +326,19 @@ export_input_data_county_timeseries(std::vector models, const std::string log_warning("No DIVI data available for date: {}-{}-{}", offset_day.day, offset_day.month, offset_day.year); } - BOOST_OUTCOME_TRY(details::set_confirmed_cases_data(models, confirmed_cases_path, case_data, region, offset_day, - scaling_factor_inf)); + BOOST_OUTCOME_TRY(details::set_confirmed_cases_data(models, case_data, region, offset_day, scaling_factor_inf)); BOOST_OUTCOME_TRY(details::set_population_data(models, num_population, region)); for (size_t r = 0; r < region.size(); r++) { extrapolated_data[r][t] = models[r].get_initial_values(); } } - auto num_groups = (int)(size_t)models[0].parameters.get_num_groups(); - BOOST_OUTCOME_TRY(save_result(extrapolated_data, region, num_groups, path_join(dir, "Results_rki.h5"))); + + BOOST_OUTCOME_TRY( + save_result(extrapolated_data, region, (int)num_age_groups, path_join(results_dir, "Results_rki.h5"))); auto rki_data_sum = sum_nodes(std::vector>>{extrapolated_data}); - BOOST_OUTCOME_TRY(save_result({rki_data_sum[0][0]}, {0}, num_groups, path_join(dir, "Results_rki_sum.h5"))); + BOOST_OUTCOME_TRY( + save_result({rki_data_sum[0][0]}, {0}, (int)num_age_groups, path_join(results_dir, "Results_rki_sum.h5"))); return success(); } @@ -353,12 +356,12 @@ export_input_data_county_timeseries(std::vector models, const std::string #endif // MEMILIO_HAS_HDF5 /** - * @brief reads population data from population files for the whole country - * @param model vector of model in which the data is set - * @param date Date for which the data should be read - * @param scaling_factor_inf factors by which to scale the confirmed cases of rki data - * @param scaling_factor_icu factor by which to scale the icu cases of divi data - * @param dir directory of files + * @brief Reads population data from population files for the whole country. + * @param model Vector of model in which the data is set. + * @param date Date for which the data should be read. + * @param scaling_factor_inf Factors by which to scale the confirmed cases of rki data. + * @param scaling_factor_icu Factor by which to scale the icu cases of divi data. + * @param dir Directory of files. */ template IOResult read_input_data_germany(std::vector& model, Date date, @@ -380,13 +383,13 @@ IOResult read_input_data_germany(std::vector& model, Date date, } /** - * @brief reads population data from population files for the specefied state - * @param model vector of model in which the data is set - * @param date Date for which the data should be read - * @param state vector of region keys of states of interest - * @param scaling_factor_inf factors by which to scale the confirmed cases of rki data - * @param scaling_factor_icu factor by which to scale the icu cases of divi data - * @param dir directory of files + * @brief Reads population data from population files for the specefied state. + * @param model Vector of model in which the data is set. + * @param date Date for which the data should be read. + * @param state Vector of region keys of states of interest. + * @param scaling_factor_inf Factors by which to scale the confirmed cases of rki data. + * @param scaling_factor_icu Factor by which to scale the icu cases of divi data. + * @param dir Directory of files. */ template IOResult read_input_data_state(std::vector& model, Date date, std::vector& state, @@ -409,14 +412,14 @@ IOResult read_input_data_state(std::vector& model, Date date, std:: } /** - * @brief reads population data from population files for the specefied county - * @param model vector of model in which the data is set - * @param date Date for which the data should be read - * @param county vector of region keys of counties of interest - * @param scaling_factor_inf factors by which to scale the confirmed cases of rki data - * @param scaling_factor_icu factor by which to scale the icu cases of divi data - * @param dir directory of files - * @param num_days [Default: 0] Number of days to be simulated; required to extrapolate real data + * @brief Reads population data from population files for the specefied county. + * @param model Vector of model in which the data is set. + * @param date Date for which the data should be read. + * @param county Vector of region keys of counties of interest. + * @param scaling_factor_inf Factors by which to scale the confirmed cases of rki data. + * @param scaling_factor_icu Factor by which to scale the icu cases of divi data. + * @param dir Directory of files. + * @param num_days [Default: 0] Number of days to be simulated; required to extrapolate real data. * @param export_time_series [Default: false] If true, reads data for each day of simulation and writes it in the same directory as the input files. */ template diff --git a/cpp/models/ode_secirvvs/parameters_io.h b/cpp/models/ode_secirvvs/parameters_io.h index f33ca6a0d6..8a014c0959 100644 --- a/cpp/models/ode_secirvvs/parameters_io.h +++ b/cpp/models/ode_secirvvs/parameters_io.h @@ -41,11 +41,11 @@ namespace details /** * @brief Reads subpopulations of infection states from transformed RKI cases file. * @param path Path to transformed RKI cases file. - * @param vregion vector of keys of the region of interest - * @param date Date for which the arrays are initialized - * @param num_* output vector for number of people in the corresponding compartement - * @param t_* average time it takes to get from one compartement to another (vector with one element per age group) - * @param mu_* probabilities to get from one compartement to another (vector with one element per age group) + * @param vregion Vector of keys of the region of interest. + * @param date Date for which the arrays are initialized. + * @param num_* Output vector for number of people in the corresponding compartement. + * @param t_* Average time it takes to get from one compartement to another (vector with one element per age group). + * @param mu_* Probabilities to get from one compartement to another (vector with one element per age group). * @param scaling_factor_inf Factor for scaling the confirmed cases to account for estimated undetected cases. * @see mio::read_confirmed_cases_data * @{ @@ -74,12 +74,12 @@ IOResult read_confirmed_cases_data( /**@}*/ /** - * @brief Reads confirmed cases data and translates data of day t0-delay to recovered compartment, + * @brief Reads confirmed cases data and translates data of day t0-delay to recovered compartment. * @param path Path to RKI confirmed cases file. - * @param vregion vector of keys of the region of interest - * @param date Date for which the arrays are initialized - * @param num_rec output vector for number of people in the compartement recovered - * @param delay number of days in the past the are used to set recovered compartment. + * @param vregion Vector of keys of the region of interest. + * @param date Date for which the arrays are initialized. + * @param num_rec Output vector for number of people in the compartement recovered. + * @param delay Number of days in the past the are used to set recovered compartment. * @see mio::read_confirmed_cases_data * @{ */ @@ -92,19 +92,19 @@ IOResult read_confirmed_cases_data_fix_recovered(std::string const& path, /**@}*/ /** - * @brief sets populations data from a transformed RKI cases file into a Model. - * @param model vector of objects in which the data is set - * @param case_data vector of case data. Each inner vector represents a different region - * @param region vector of keys of the region of interest - * @param date Date for which the arrays are initialized - * @param scaling_factor_inf factors by which to scale the confirmed cases of - * rki data + * @brief Sets the confirmed cases data for a vector of models based on input data. + * @param model Vector of objects in which the data is set. + * @param case_data Vector of case data. Each inner vector represents a different region. + * @param region Vector of keys of the region of interest. + * @param date Date for which the arrays are initialized. + * @param scaling_factor_inf Factors by which to scale the confirmed cases of RKI data. + * @param set_death If true, set the number of deaths. */ template IOResult set_confirmed_cases_data(std::vector& model, const std::vector& case_data, std::vector const& region, Date date, - const std::vector& scaling_factor_inf, bool set_death) + const std::vector& scaling_factor_inf, bool set_death = false) { auto num_age_groups = (size_t)model[0].parameters.get_num_groups(); assert(scaling_factor_inf.size() == num_age_groups); //TODO: allow vector or scalar valued scaling factors @@ -375,6 +375,7 @@ IOResult set_confirmed_cases_data(std::vector& model, * @param date Date for which the arrays are initialized * @param scaling_factor_inf factors by which to scale the confirmed cases of * rki data + * @param set_death If true, set the number of deaths. */ template IOResult set_confirmed_cases_data(std::vector& model, const std::string& path, @@ -643,12 +644,12 @@ IOResult set_population_data(std::vector& model, const std::vector< } /** -* @brief sets population data from census data which has been read into num_population -* @param[in, out] model vector of objects in which the data is set -* @param[in] path Path to population data file -* @param[in] path_rki Path to RKI cases data file -* @param[in] vregion vector of keys of the regions of interest -* @param[in] date Date for which the arrays are initialized +* @brief Sets population data from census data which has been read into num_population. +* @param[in, out] model Vector of objects in which the data is set. +* @param[in] path Path to population data file. +* @param[in] path_rki Path to RKI cases data file. +* @param[in] vregion Vector of keys of the regions of interest. +* @param[in] date Date for which the arrays are initialized. */ template IOResult set_population_data(std::vector& model, const std::string& path, const std::string& path_rki, @@ -662,14 +663,14 @@ IOResult set_population_data(std::vector& model, const std::string& } /** - * @brief Sets vaccination data for models stored in a vector + * @brief Sets vaccination data for models stored in a vector. * - * @tparam FP Floating point type used in the Model objects - * @param model Vector of Model objects in which the vaccination data is set - * @param vacc_data Vector of VaccinationDataEntry objects containing the vaccination data - * @param date Start date for the simulation - * @param vregion Vector of region identifiers - * @param num_days Number of days for which the simulation is run + * @tparam FP Floating point type used in the Model objects. + * @param model Vector of Model objects in which the vaccination data is set. + * @param vacc_data Vector of VaccinationDataEntry objects containing the vaccination data. + * @param date Start date for the simulation. + * @param vregion Vector of region identifiers. + * @param num_days Number of days for which the simulation is run. */ template IOResult set_vaccination_data(std::vector>& model, const std::vector& vacc_data, @@ -797,14 +798,14 @@ IOResult set_vaccination_data(std::vector>& model, const std::ve } /** - * @brief Sets vaccination data for models stored in a vector + * @brief Reads vaccination data from a file and sets it for each model. * - * @tparam FP Floating point type used in the Model objects - * @param model Vector of Model objects in which the vaccination data is set - * @param path Path to vaccination data file - * @param date Start date for the simulation - * @param vregion Vector of region identifiers - * @param num_days Number of days for which the simulation is run + * @tparam FP Floating point type used in the Model objects. + * @param model Vector of Model objects in which the vaccination data is set. + * @param path Path to vaccination data file. + * @param date Start date for the simulation. + * @param vregion Vector of region identifiers. + * @param num_days Number of days for which the simulation is run. */ template IOResult set_vaccination_data(std::vector>& model, const std::string& path, Date date, @@ -820,27 +821,26 @@ IOResult set_vaccination_data(std::vector>& model, const std::st #ifdef MEMILIO_HAS_HDF5 /** - * @brief Exports the time series of extrapolated real data according to - * the extrapolation / approximation method used to initialize the model from - * real world data. - (This is the vector-valued functionality of set_confirmed_cases_data()) - * @param model vector of objects in which the data is set - * @param data_dir Path to transformed RKI cases files - * @param results_dir Path to result files - * @param start_date Start date of the time series to be exported. - * @param region vector of keys of the region of interest - * @param scaling_factor_inf Factor for scaling the confirmed cases to account for an estimated number of undetected cases. - * @param scaling_factor_icu Factor for scaling the reported ICU cases to account for possibly unreported ICU cases. - * @param num_days Number of days for which the time series is exported. - * @param divi_data_path path to divi data file - * @param confirmed_cases_path path to confirmed cases file - * @param population_data_path path to population data file - * @param set_vaccination_data boolean to set vaccination data - * @param vaccination_data_path path to vaccination data file - */ +* @brief Uses the initialisation method, which uses the reported data to set the initial conditions for the model for a given day. +* The initialisation is applied for a predefined number of days and finally saved in a timeseries for each region. In the end, +* we save the files "Results_rki.h5" and "Results_rki_sum.h5" in the results_dir. +* Results_rki.h5 contains a time series for each region and Results_rki_sum.h5 contains the sum of all regions. +* @param models Vector of models in which the data is set. Copy is made to avoid changing the original model. +* @param results_dir Path to result files. +* @param counties Vector of keys of the counties of interest. +* @param date Date for which the data should be read. +* @param scaling_factor_inf Factors by which to scale the confirmed cases of rki data. +* @param scaling_factor_icu Factor by which to scale the icu cases of divi data. +* @param num_days Number of days to be simulated/initialized. +* @param divi_data_path Path to DIVI file. +* @param confirmed_cases_path Path to confirmed cases file. +* @param population_data_path Path to population data file. +* @param set_vaccination_data Boolean to set vaccination data. +* @param vaccination_data_path Path to vaccination data file. +*/ template IOResult export_input_data_county_timeseries( - std::vector models, const std::string& dir, const std::vector& counties, Date date, + std::vector models, const std::string& results_dir, const std::vector& counties, Date date, const std::vector& scaling_factor_inf, const double scaling_factor_icu, const int num_days, const std::string& divi_data_path, const std::string& confirmed_cases_path, const std::string& population_data_path, bool set_vaccination_data, const std::string& vaccination_data_path) @@ -882,26 +882,23 @@ IOResult export_input_data_county_timeseries( details::set_confirmed_cases_data(models, case_data, counties, offset_day, scaling_factor_inf, true)); BOOST_OUTCOME_TRY(details::set_population_data(models, population_data, case_data, counties, offset_day)); - // in set_population_data werden die Anzahl an TOten noch von SusceptibleImprovedImmunity subtrahiert. Da wir egal, - // ob wir diese betrachten oder nicht, addieren wir sie hier wieder hinzu bevor wir die Daten speichern. for (size_t r = 0; r < counties.size(); r++) { extrapolated_data[r][t] = models[r].get_initial_values(); // in set_population_data the number of death individuals is subtracted from the SusceptibleImprovedImmunity compartment. // Since we should be independent whether we consider them or not, we add them back here before we save the data. for (size_t age = 0; age < num_groups; age++) { - // extrapolated_rki[county][day]((size_t)InfectionState::DeadNaive + age_group_offset) extrapolated_data[r][t][(size_t)InfectionState::SusceptibleImprovedImmunity + age * (size_t)InfectionState::Count] += extrapolated_data[r][t][(size_t)InfectionState::DeadNaive + age * (size_t)InfectionState::Count]; } } } - BOOST_OUTCOME_TRY( - save_result(extrapolated_data, counties, static_cast(num_groups), path_join(dir, "Results_rki.h5"))); + BOOST_OUTCOME_TRY(save_result(extrapolated_data, counties, static_cast(num_groups), + path_join(results_dir, "Results_rki.h5"))); auto extrapolated_rki_data_sum = sum_nodes(std::vector>>{extrapolated_data}); BOOST_OUTCOME_TRY(save_result({extrapolated_rki_data_sum[0][0]}, {0}, static_cast(num_groups), - path_join(dir, "Results_rki_sum.h5"))); + path_join(results_dir, "Results_rki_sum.h5"))); return success(); } From 6a3385bdf03ccbb6b4c71ec67c2c0d3a4b199914 Mon Sep 17 00:00:00 2001 From: Henrik Zunker Date: Fri, 16 Aug 2024 11:22:09 +0200 Subject: [PATCH 38/46] rm accumulate age_groups --- cpp/models/ode_secir/parameters_io.h | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/cpp/models/ode_secir/parameters_io.h b/cpp/models/ode_secir/parameters_io.h index ee3dd1597c..68a5d16192 100644 --- a/cpp/models/ode_secir/parameters_io.h +++ b/cpp/models/ode_secir/parameters_io.h @@ -269,13 +269,14 @@ IOResult set_population_data(std::vector>& model, * @param[in, out] model Vector of models in which the data is set. * @param[in] path Path to RKI file containing population data. * @param[in] vregion Vector of keys of the regions of interest. -* @param[in] accumulate_age_groups Specifies whether population data should be accumulated to one age group. */ template IOResult set_population_data(std::vector>& model, const std::string& path, - const std::vector& vregion, bool accumulate_age_groups = false) + const std::vector& vregion) { - BOOST_OUTCOME_TRY(const auto&& num_population, read_population_data(path, vregion, accumulate_age_groups)); + // Specifies whether population data should be accumulated to one age group. + const bool multiple_age_groups = model[0].parameters.get_num_groups() > 1; + BOOST_OUTCOME_TRY(const auto&& num_population, read_population_data(path, vregion, multiple_age_groups)); BOOST_OUTCOME_TRY(set_population_data(model, num_population, vregion)); return success(); } From 75a71aff1044a5cc57d3347c6b1b3b0b70d6d899 Mon Sep 17 00:00:00 2001 From: Henrik Zunker Date: Tue, 20 Aug 2024 15:57:45 +0200 Subject: [PATCH 39/46] explicit casting, naming --- cpp/models/ode_secir/parameters_io.h | 16 ++++++---------- cpp/models/ode_secirvvs/parameters_io.h | 12 +++++++----- 2 files changed, 13 insertions(+), 15 deletions(-) diff --git a/cpp/models/ode_secir/parameters_io.h b/cpp/models/ode_secir/parameters_io.h index 68a5d16192..297c428059 100644 --- a/cpp/models/ode_secir/parameters_io.h +++ b/cpp/models/ode_secir/parameters_io.h @@ -275,8 +275,8 @@ IOResult set_population_data(std::vector>& model, const std::str const std::vector& vregion) { // Specifies whether population data should be accumulated to one age group. - const bool multiple_age_groups = model[0].parameters.get_num_groups() > 1; - BOOST_OUTCOME_TRY(const auto&& num_population, read_population_data(path, vregion, multiple_age_groups)); + const bool is_single_age_group = static_cast(model[0].parameters.get_num_groups()) == 1; + BOOST_OUTCOME_TRY(const auto&& num_population, read_population_data(path, vregion, is_single_age_group)); BOOST_OUTCOME_TRY(set_population_data(model, num_population, vregion)); return success(); } @@ -378,8 +378,7 @@ IOResult read_input_data_germany(std::vector& model, Date date, } BOOST_OUTCOME_TRY(details::set_confirmed_cases_data(model, path_join(dir, "cases_all_age_ma7.json"), {0}, date, scaling_factor_inf)); - BOOST_OUTCOME_TRY( - details::set_population_data(model, path_join(dir, "county_current_population.json"), {0}, false)); + BOOST_OUTCOME_TRY(details::set_population_data(model, path_join(dir, "county_current_population.json"), {0})); return success(); } @@ -407,8 +406,7 @@ IOResult read_input_data_state(std::vector& model, Date date, std:: BOOST_OUTCOME_TRY(details::set_confirmed_cases_data(model, path_join(dir, "cases_all_state_age_ma7.json"), state, date, scaling_factor_inf)); - BOOST_OUTCOME_TRY( - details::set_population_data(model, path_join(dir, "county_current_population.json"), state, false)); + BOOST_OUTCOME_TRY(details::set_population_data(model, path_join(dir, "county_current_population.json"), state)); return success(); } @@ -438,7 +436,7 @@ IOResult read_input_data_county(std::vector& model, Date date, cons BOOST_OUTCOME_TRY(details::set_confirmed_cases_data( model, path_join(dir, "pydata/Germany", "cases_all_county_age_ma7.json"), county, date, scaling_factor_inf)); BOOST_OUTCOME_TRY(details::set_population_data( - model, path_join(dir, "pydata/Germany", "county_current_population.json"), county, false)); + model, path_join(dir, "pydata/Germany", "county_current_population.json"), county)); if (export_time_series) { // Use only if extrapolated real data is needed for comparison. EXPENSIVE ! @@ -479,9 +477,7 @@ IOResult read_input_data(std::vector& model, Date date, const std:: } BOOST_OUTCOME_TRY(details::set_confirmed_cases_data(model, path_join(data_dir, "confirmed_cases.json"), node_ids, date, scaling_factor_inf)); - bool single_age_group = scaling_factor_inf.size() == 1 ? true : false; - BOOST_OUTCOME_TRY( - details::set_population_data(model, path_join(data_dir, "population_data.json"), node_ids, single_age_group)); + BOOST_OUTCOME_TRY(details::set_population_data(model, path_join(data_dir, "population_data.json"), node_ids)); if (export_time_series) { // Use only if extrapolated real data is needed for comparison. EXPENSIVE ! diff --git a/cpp/models/ode_secirvvs/parameters_io.h b/cpp/models/ode_secirvvs/parameters_io.h index 8a014c0959..33bcbe39cd 100644 --- a/cpp/models/ode_secirvvs/parameters_io.h +++ b/cpp/models/ode_secirvvs/parameters_io.h @@ -678,11 +678,13 @@ IOResult set_vaccination_data(std::vector>& model, const std::ve { auto num_groups = model[0].parameters.get_num_groups(); - auto days_until_effective1 = - (int)(double)model[0].parameters.template get>()[AgeGroup(0)]; - auto days_until_effective2 = - (int)(double)model[0].parameters.template get>()[AgeGroup(0)]; - auto vaccination_distance = (int)(double)model[0].parameters.template get>()[AgeGroup(0)]; + // type conversion from UncertainValue -> FP -> int + auto days_until_effective1 = static_cast( + static_cast(model[0].parameters.template get>()[AgeGroup(0)])); + auto days_until_effective2 = static_cast( + static_cast(model[0].parameters.template get>()[AgeGroup(0)])); + auto vaccination_distance = + static_cast(static_cast(model[0].parameters.template get>()[AgeGroup(0)])); // iterate over regions (e.g., counties) for (size_t i = 0; i < model.size(); ++i) { From a43a6ea9543314be1efa976dadfa05698446b621 Mon Sep 17 00:00:00 2001 From: Henrik Zunker Date: Tue, 20 Aug 2024 16:03:18 +0200 Subject: [PATCH 40/46] rm boolean set_vaccination_data --- cpp/models/ode_secirvvs/parameters_io.h | 25 ++++++++++++------------- cpp/tests/test_odesecirvvs.cpp | 4 ++-- 2 files changed, 14 insertions(+), 15 deletions(-) diff --git a/cpp/models/ode_secirvvs/parameters_io.h b/cpp/models/ode_secirvvs/parameters_io.h index 33bcbe39cd..0272834122 100644 --- a/cpp/models/ode_secirvvs/parameters_io.h +++ b/cpp/models/ode_secirvvs/parameters_io.h @@ -837,7 +837,6 @@ IOResult set_vaccination_data(std::vector>& model, const std::st * @param divi_data_path Path to DIVI file. * @param confirmed_cases_path Path to confirmed cases file. * @param population_data_path Path to population data file. -* @param set_vaccination_data Boolean to set vaccination data. * @param vaccination_data_path Path to vaccination data file. */ template @@ -845,7 +844,7 @@ IOResult export_input_data_county_timeseries( std::vector models, const std::string& results_dir, const std::vector& counties, Date date, const std::vector& scaling_factor_inf, const double scaling_factor_icu, const int num_days, const std::string& divi_data_path, const std::string& confirmed_cases_path, const std::string& population_data_path, - bool set_vaccination_data, const std::string& vaccination_data_path) + const std::string& vaccination_data_path = "") { const auto num_groups = (size_t)models[0].parameters.get_num_groups(); assert(scaling_factor_inf.size() == num_groups); @@ -857,16 +856,16 @@ IOResult export_input_data_county_timeseries( BOOST_OUTCOME_TRY(auto&& case_data, read_confirmed_cases_data(confirmed_cases_path)); BOOST_OUTCOME_TRY(auto&& population_data, details::read_population_data(population_data_path, counties)); - // empty vector if set_vaccination_data is false + // empty vector if set_vaccination_data is not set std::vector vacc_data; - if (set_vaccination_data) { + if (!vaccination_data_path.empty()) { BOOST_OUTCOME_TRY(vacc_data, read_vaccination_data(vaccination_data_path)); } for (int t = 0; t <= num_days; ++t) { auto offset_day = offset_date_by_days(date, t); - if (set_vaccination_data) { + if (!vaccination_data_path.empty()) { BOOST_OUTCOME_TRY(details::set_vaccination_data(models, vacc_data, offset_day, counties, num_days)); } @@ -908,7 +907,7 @@ IOResult export_input_data_county_timeseries( template IOResult export_input_data_county_timeseries(std::vector, const std::string&, const std::vector&, Date, const std::vector&, const double, const int, - const std::string&, const std::string&, const std::string&, bool, + const std::string&, const std::string&, const std::string&, const std::string&) { mio::log_warning("HDF5 not available. Cannot export time series of extrapolated real data."); @@ -961,12 +960,12 @@ IOResult read_input_data_county(std::vector& model, Date date, cons // (This only represents the vectorization of the previous function over all simulation days...) log_warning("Exporting time series of extrapolated real data. This may take some minutes. " "For simulation runs over the same time period, deactivate it."); - BOOST_OUTCOME_TRY(export_input_data_county_timeseries( - model, dir, county, date, scaling_factor_inf, scaling_factor_icu, num_days, - path_join(dir, "pydata/Germany", "county_divi_ma7.json"), - path_join(dir, "pydata/Germany", "cases_all_county_age_ma7.json"), - path_join(dir, "pydata/Germany", "county_current_population.json"), true, - path_join(dir, "pydata/Germany", "all_county_ageinf_vacc_ma7.json"))); + BOOST_OUTCOME_TRY( + export_input_data_county_timeseries(model, dir, county, date, scaling_factor_inf, scaling_factor_icu, + num_days, path_join(dir, "pydata/Germany", "county_divi_ma7.json"), + path_join(dir, "pydata/Germany", "cases_all_county_age_ma7.json"), + path_join(dir, "pydata/Germany", "county_current_population.json"), + path_join(dir, "pydata/Germany", "all_county_ageinf_vacc_ma7.json"))); } return success(); @@ -1019,7 +1018,7 @@ IOResult read_input_data(std::vector& model, Date date, const std:: BOOST_OUTCOME_TRY(export_input_data_county_timeseries( model, data_dir, node_ids, date, scaling_factor_inf, scaling_factor_icu, num_days, path_join(data_dir, "divi_data.json"), path_join(data_dir, "confirmed_cases.json"), - path_join(data_dir, "population_data.json"), true, path_join(data_dir, "vaccination_data.json"))); + path_join(data_dir, "population_data.json"), path_join(data_dir, "vaccination_data.json"))); } return success(); diff --git a/cpp/tests/test_odesecirvvs.cpp b/cpp/tests/test_odesecirvvs.cpp index c73aa94e0c..66da229199 100644 --- a/cpp/tests/test_odesecirvvs.cpp +++ b/cpp/tests/test_odesecirvvs.cpp @@ -743,7 +743,7 @@ TEST(TestOdeSECIRVVS, export_time_series_init) std::vector(size_t(num_age_groups), 1.0), 1.0, 2, mio::path_join(TEST_DATA_DIR, "county_divi_ma7.json"), mio::path_join(TEST_DATA_DIR, "cases_all_county_age_ma7.json"), - mio::path_join(TEST_DATA_DIR, "county_current_population.json"), true, + mio::path_join(TEST_DATA_DIR, "county_current_population.json"), mio::path_join(TEST_DATA_DIR, "vacc_county_ageinf_ma7.json")), IsSuccess()); @@ -780,7 +780,7 @@ TEST(TestOdeSECIRVVS, export_time_series_init_old_date) std::vector(size_t(num_age_groups), 1.0), 1.0, 0, mio::path_join(TEST_DATA_DIR, "county_divi_ma7.json"), mio::path_join(TEST_DATA_DIR, "cases_all_county_age_ma7.json"), - mio::path_join(TEST_DATA_DIR, "county_current_population.json"), true, + mio::path_join(TEST_DATA_DIR, "county_current_population.json"), mio::path_join(TEST_DATA_DIR, "vacc_county_ageinf_ma7.json")), IsSuccess()); From 7976337495ceb96f8a344c1c3315b3c2a9d84263 Mon Sep 17 00:00:00 2001 From: Henrik Zunker Date: Wed, 21 Aug 2024 12:33:55 +0200 Subject: [PATCH 41/46] Test_F in test secir, log level --- cpp/tests/test_odesecir.cpp | 131 ++++++++++++++++----------------- cpp/tests/test_odesecirvvs.cpp | 9 ++- 2 files changed, 70 insertions(+), 70 deletions(-) diff --git a/cpp/tests/test_odesecir.cpp b/cpp/tests/test_odesecir.cpp index 53521a8df9..a82c47cb26 100644 --- a/cpp/tests/test_odesecir.cpp +++ b/cpp/tests/test_odesecir.cpp @@ -1180,40 +1180,47 @@ TEST(TestOdeSecir, read_population_data_one_age_group) } #if defined(MEMILIO_HAS_HDF5) -mio::osecir::Model make_model(int num_age_groups) +class ModelTestOdeSecir : public testing::Test { - mio::osecir::Model model(num_age_groups); - model.parameters.set(60); - model.parameters.set>(0.2); - - for (auto i = mio::AgeGroup(0); i < (mio::AgeGroup)num_age_groups; i++) { - model.parameters.get>()[i] = 3.2; - model.parameters.get>()[i] = 2.0; - model.parameters.get>()[i] = 5.8; - model.parameters.get>()[i] = 9.5; - model.parameters.get>()[i] = 7.1; - - model.parameters.get>()[i] = 0.05; - model.parameters.get>()[i] = 0.7; - model.parameters.get>()[i] = 0.09; - model.parameters.get>()[i] = 0.25; - model.parameters.get>()[i] = 0.45; - model.parameters.get>()[i] = 0.2; - model.parameters.get>()[i] = 0.25; - model.parameters.get>()[i] = 0.3; +public: + ModelTestOdeSecir() + : model(6) + , num_age_groups(6) + { } + size_t num_age_groups; + mio::osecir::Model model; - model.apply_constraints(); - - return model; -} +protected: + void SetUp() override + { + model.parameters.set(60); + model.parameters.set>(0.2); + + for (auto i = mio::AgeGroup(0); i < (mio::AgeGroup)num_age_groups; i++) { + model.parameters.get>()[i] = 3.2; + model.parameters.get>()[i] = 2.0; + model.parameters.get>()[i] = 5.8; + model.parameters.get>()[i] = 9.5; + model.parameters.get>()[i] = 7.1; + + model.parameters.get>()[i] = 0.05; + model.parameters.get>()[i] = 0.7; + model.parameters.get>()[i] = 0.09; + model.parameters.get>()[i] = 0.25; + model.parameters.get>()[i] = 0.45; + model.parameters.get>()[i] = 0.2; + model.parameters.get>()[i] = 0.25; + model.parameters.get>()[i] = 0.3; + } + model.apply_constraints(); + } +}; -TEST(TestOdeSecir, read_data) +// Initialize model with data frrom external reported data. Check if the model is initialized correctly. +TEST_F(ModelTestOdeSecir, read_input_data) { - constexpr auto num_age_groups = 6; //reading data requires RKI data age groups - mio::osecir::Model model(make_model(num_age_groups)); - auto model1 = std::vector>{model}; auto model2 = std::vector>{model}; auto model3 = std::vector>{model}; @@ -1228,9 +1235,9 @@ TEST(TestOdeSecir, read_data) mio::osecir::read_input_data(model3, {2020, 12, 01}, {1002}, std::vector(size_t(num_age_groups), 1.0), 1.0, mio::path_join(TEST_DATA_DIR, "pydata/District"), 10); - ASSERT_THAT(read_result1, IsSuccess()); - ASSERT_THAT(read_result2, IsSuccess()); - ASSERT_THAT(read_result_district, IsSuccess()); + EXPECT_THAT(read_result1, IsSuccess()); + EXPECT_THAT(read_result2, IsSuccess()); + EXPECT_THAT(read_result_district, IsSuccess()); // values were generated by the tested function; can only check stability of the implementation, not correctness auto expected_values = @@ -1241,32 +1248,24 @@ TEST(TestOdeSecir, read_data) 10.5181, 3.2967, 0, 3.28571, 0, 0.657143, 1.33333, 49.8571, 7.57143) .finished(); - ASSERT_THAT(print_wrap(model1[0].populations.array().cast()), - MatrixNear(print_wrap(model2[0].populations.array().cast()), 1e-5, 1e-5)); - - ASSERT_THAT(print_wrap(model1[0].populations.array().cast()), - MatrixNear(print_wrap(model3[0].populations.array().cast()), 1e-5, 1e-5)); - - ASSERT_THAT(print_wrap(model1[0].populations.array().cast()), + EXPECT_THAT(print_wrap(model1[0].populations.array().cast()), MatrixNear(print_wrap(expected_values), 1e-5, 1e-5)); - ASSERT_THAT(print_wrap(model2[0].populations.array().cast()), + EXPECT_THAT(print_wrap(model2[0].populations.array().cast()), MatrixNear(print_wrap(expected_values), 1e-5, 1e-5)); - ASSERT_THAT(print_wrap(model3[0].populations.array().cast()), + EXPECT_THAT(print_wrap(model3[0].populations.array().cast()), MatrixNear(print_wrap(expected_values), 1e-5, 1e-5)); } -TEST(TestOdeSecir, export_time_series_init) +// Test if the export of the time series is called not failing and results are the same as the initialization. +TEST_F(ModelTestOdeSecir, export_time_series_init) { TempFileRegister temp_file_register; auto tmp_results_dir = temp_file_register.get_unique_path(); - ASSERT_THAT(mio::create_directory(tmp_results_dir), IsSuccess()); - - constexpr auto num_age_groups = 6; //reading data requires RKI data age groups - mio::osecir::Model model(make_model(num_age_groups)); + EXPECT_THAT(mio::create_directory(tmp_results_dir), IsSuccess()); // Test exporting time series std::vector> models{model}; - ASSERT_THAT(mio::osecir::export_input_data_county_timeseries( + EXPECT_THAT(mio::osecir::export_input_data_county_timeseries( models, tmp_results_dir, {1002}, {2020, 12, 01}, std::vector(size_t(num_age_groups), 1.0), 1.0, 2, mio::path_join(TEST_DATA_DIR, "county_divi_ma7.json"), mio::path_join(TEST_DATA_DIR, "cases_all_county_age_ma7.json"), @@ -1274,29 +1273,28 @@ TEST(TestOdeSecir, export_time_series_init) IsSuccess()); auto data_extrapolated = mio::read_result(mio::path_join(tmp_results_dir, "Results_rki.h5")); - ASSERT_THAT(data_extrapolated, IsSuccess()); + EXPECT_THAT(data_extrapolated, IsSuccess()); // Values were generated by the tested function export_input_data_county_timeseries; // can only check stability of the implementation, not correctness auto expected_results = mio::read_result(mio::path_join(TEST_DATA_DIR, "export_time_series_initialization_osecir.h5")).value(); - ASSERT_THAT(print_wrap(data_extrapolated.value()[0].get_groups().matrix()), + EXPECT_THAT(print_wrap(data_extrapolated.value()[0].get_groups().matrix()), MatrixNear(print_wrap(expected_results[0].get_groups().matrix()), 1e-5, 1e-5)); } -TEST(TestOdeSecir, export_time_series_init_old_date) +// Test the output of the function for a day way in the past. The model should be initialized with the population data since no Case data is available there. +TEST_F(ModelTestOdeSecir, export_time_series_init_old_date) { + mio::set_log_level(mio::LogLevel::off); TempFileRegister temp_file_register; auto tmp_results_dir = temp_file_register.get_unique_path(); - ASSERT_THAT(mio::create_directory(tmp_results_dir), IsSuccess()); - - constexpr auto num_age_groups = 6; //reading data requires RKI data age groups - mio::osecir::Model model(make_model(num_age_groups)); + EXPECT_THAT(mio::create_directory(tmp_results_dir), IsSuccess()); // Test exporting time series std::vector> models{model}; - ASSERT_THAT(mio::osecir::export_input_data_county_timeseries( + EXPECT_THAT(mio::osecir::export_input_data_county_timeseries( models, tmp_results_dir, {1002}, {1000, 12, 01}, std::vector(size_t(num_age_groups), 1.0), 1.0, 0, mio::path_join(TEST_DATA_DIR, "county_divi_ma7.json"), mio::path_join(TEST_DATA_DIR, "cases_all_county_age_ma7.json"), @@ -1304,7 +1302,7 @@ TEST(TestOdeSecir, export_time_series_init_old_date) IsSuccess()); auto data_extrapolated = mio::read_result(mio::path_join(tmp_results_dir, "Results_rki.h5")); - ASSERT_THAT(data_extrapolated, IsSuccess()); + EXPECT_THAT(data_extrapolated, IsSuccess()); auto results_extrapolated = data_extrapolated.value()[0].get_groups().get_value(0); // if we enter an old date, the model only should be initialized with the population data. @@ -1319,18 +1317,16 @@ TEST(TestOdeSecir, export_time_series_init_old_date) } // sum of all compartments should be equal to the population EXPECT_EQ(results_extrapolated.sum(), std::accumulate(population_data[0].begin(), population_data[0].end(), 0.0)); + mio::set_log_level(mio::LogLevel::warn); } // // Model initialization should return same start values as export time series on that day -TEST(TestOdeSecir, model_initialization) +TEST_F(ModelTestOdeSecir, model_initialization) { - constexpr auto num_age_groups = 6; //reading data requires RKI data age groups - mio::osecir::Model model(make_model(num_age_groups)); - // Vector assignment necessary as read_input_data_county changes model auto model_vector = std::vector>{model}; - ASSERT_THAT(mio::osecir::read_input_data_county(model_vector, {2020, 12, 01}, {1002}, + EXPECT_THAT(mio::osecir::read_input_data_county(model_vector, {2020, 12, 01}, {1002}, std::vector(size_t(num_age_groups), 1.0), 1.0, TEST_DATA_DIR, 2, false), IsSuccess()); @@ -1345,19 +1341,18 @@ TEST(TestOdeSecir, model_initialization) 10.5181, 3.2967, 0, 3.28571, 0, 0.657143, 1.33333, 49.8571, 7.57143) .finished(); - ASSERT_THAT(print_wrap(model_vector[0].populations.array().cast()), + EXPECT_THAT(print_wrap(model_vector[0].populations.array().cast()), MatrixNear(print_wrap(expected_values), 1e-5, 1e-5)); } -TEST(TestOdeSecir, model_initialization_old_date) +// Calling the model initialization with a date way in the past should only initialize the model with the population data. +TEST_F(ModelTestOdeSecir, model_initialization_old_date) { - constexpr auto num_age_groups = 6; //reading data requires RKI data age groups - mio::osecir::Model model(make_model(num_age_groups)); - + mio::set_log_level(mio::LogLevel::off); // Vector assignment necessary as read_input_data_county changes model auto model_vector = std::vector>{model}; - ASSERT_THAT(mio::osecir::read_input_data_county(model_vector, {1000, 12, 01}, {1002}, + EXPECT_THAT(mio::osecir::read_input_data_county(model_vector, {1000, 12, 01}, {1002}, std::vector(size_t(num_age_groups), 1.0), 1.0, TEST_DATA_DIR, 0, false), IsSuccess()); @@ -1376,8 +1371,10 @@ TEST(TestOdeSecir, model_initialization_old_date) population_data[0][5], 0, 0, 0, 0, 0, 0, 0, 0, 0) .finished(); - ASSERT_THAT(print_wrap(model_vector[0].populations.array().cast()), + EXPECT_THAT(print_wrap(model_vector[0].populations.array().cast()), MatrixNear(print_wrap(expected_values), 1e-5, 1e-5)); + mio::set_log_level(mio::LogLevel::warn); } + #endif #endif diff --git a/cpp/tests/test_odesecirvvs.cpp b/cpp/tests/test_odesecirvvs.cpp index 66da229199..986efd11a5 100644 --- a/cpp/tests/test_odesecirvvs.cpp +++ b/cpp/tests/test_odesecirvvs.cpp @@ -761,6 +761,7 @@ TEST(TestOdeSECIRVVS, export_time_series_init) TEST(TestOdeSECIRVVS, export_time_series_init_old_date) { + mio::set_log_level(mio::LogLevel::off); TempFileRegister temp_file_register; auto tmp_results_dir = temp_file_register.get_unique_path(); ASSERT_THAT(mio::create_directory(tmp_results_dir), IsSuccess()); @@ -801,6 +802,7 @@ TEST(TestOdeSECIRVVS, export_time_series_init_old_date) // sum of all compartments should be equal to the population EXPECT_NEAR(results_extrapolated.sum(), std::accumulate(population_data[0].begin(), population_data[0].end(), 0.0), 1e-5); + mio::set_log_level(mio::LogLevel::warn); } // Model initialization should return same start values as export time series on that day @@ -841,6 +843,7 @@ TEST(TestOdeSECIRVVS, model_initialization) TEST(TestOdeSECIRVVS, model_initialization_old_date) { + mio::set_log_level(mio::LogLevel::off); constexpr auto num_age_groups = 6; // Data to be read requires RKI confirmed cases data age groups auto model = make_model(num_age_groups); // set vaccinations to zero @@ -872,10 +875,12 @@ TEST(TestOdeSECIRVVS, model_initialization_old_date) // sum of all compartments should be equal to the population EXPECT_NEAR(model_vector[0].populations.array().cast().sum(), std::accumulate(population_data[0].begin(), population_data[0].end(), 0.0), 1e-5); + mio::set_log_level(mio::LogLevel::warn); } TEST(TestOdeSECIRVVS, model_initialization_old_date_county) { + mio::set_log_level(mio::LogLevel::off); constexpr auto num_age_groups = 6; // Data to be read requires RKI confirmed cases data age groups auto model = make_model(num_age_groups); // set vaccinations to zero @@ -907,6 +912,7 @@ TEST(TestOdeSECIRVVS, model_initialization_old_date_county) // sum of all compartments should be equal to the population EXPECT_NEAR(model_vector[0].populations.array().cast().sum(), std::accumulate(population_data[0].begin(), population_data[0].end(), 0.0), 1e-5); + mio::set_log_level(mio::LogLevel::warn); } TEST(TestOdeSECIRVVS, set_population_data_overflow_vacc) @@ -916,7 +922,6 @@ TEST(TestOdeSECIRVVS, set_population_data_overflow_vacc) // set all compartments to zero model.populations.array().setConstant(0.0); - // if the number of vaccinated individuals is greater than the population, we must limit the number of vaccinated. model.parameters .template get>()[{mio::AgeGroup(0), mio::SimulationDay(0)}] = 1e7 + 1; @@ -924,7 +929,6 @@ TEST(TestOdeSECIRVVS, set_population_data_overflow_vacc) model.parameters .template get>()[{mio::AgeGroup(0), mio::SimulationDay(0)}] = 1e7; - // Vector assignment necessary as read_input_data_county changes model auto model_vector = std::vector>{model}; std::string path_pop_data = mio::path_join(TEST_DATA_DIR, "county_current_population.json"); @@ -964,7 +968,6 @@ TEST(TestOdeSECIRVVS, set_population_data_no_data_avail) model.parameters .template get>()[{mio::AgeGroup(0), mio::SimulationDay(0)}] = 0; - // Vector assignment necessary as read_input_data_county changes model auto model_vector = std::vector>{model}; std::string path_pop_data = mio::path_join(TEST_DATA_DIR, "county_current_population.json"); From ba9442f543172694e4b7493fea28a02026e42562 Mon Sep 17 00:00:00 2001 From: Henrik Zunker Date: Wed, 21 Aug 2024 13:13:06 +0200 Subject: [PATCH 42/46] test value for elegant --- cpp/tests/test_odesecir.cpp | 9 +++++++-- cpp/tests/test_odesecirvvs.cpp | 3 ++- 2 files changed, 9 insertions(+), 3 deletions(-) diff --git a/cpp/tests/test_odesecir.cpp b/cpp/tests/test_odesecir.cpp index a82c47cb26..1e26c02566 100644 --- a/cpp/tests/test_odesecir.cpp +++ b/cpp/tests/test_odesecir.cpp @@ -1371,8 +1371,13 @@ TEST_F(ModelTestOdeSecir, model_initialization_old_date) population_data[0][5], 0, 0, 0, 0, 0, 0, 0, 0, 0) .finished(); - EXPECT_THAT(print_wrap(model_vector[0].populations.array().cast()), - MatrixNear(print_wrap(expected_values), 1e-5, 1e-5)); + auto results_extrapolated = model_vector[0].populations.array().cast(); + + for (auto i = 0; i < num_age_groups; i++) { + EXPECT_EQ(results_extrapolated(i * Eigen::Index(mio::osecir::InfectionState::Count)), population_data[0][i]); + } + // sum of all compartments should be equal to the population + EXPECT_EQ(results_extrapolated.sum(), std::accumulate(population_data[0].begin(), population_data[0].end(), 0.0)); mio::set_log_level(mio::LogLevel::warn); } diff --git a/cpp/tests/test_odesecirvvs.cpp b/cpp/tests/test_odesecirvvs.cpp index 986efd11a5..b9a62ff248 100644 --- a/cpp/tests/test_odesecirvvs.cpp +++ b/cpp/tests/test_odesecirvvs.cpp @@ -797,7 +797,8 @@ TEST(TestOdeSECIRVVS, export_time_series_init_old_date) // So, the expected values are the population data in the susceptible compartments and zeros in the other compartments. for (auto i = 0; i < num_age_groups; i++) { - EXPECT_EQ(results_extrapolated(i * Eigen::Index(mio::osecirvvs::InfectionState::Count)), population_data[0][i]); + EXPECT_NEAR(results_extrapolated(i * Eigen::Index(mio::osecirvvs::InfectionState::Count)), + population_data[0][i], 1e-10); } // sum of all compartments should be equal to the population EXPECT_NEAR(results_extrapolated.sum(), std::accumulate(population_data[0].begin(), population_data[0].end(), 0.0), From 86203d94cbbc2eab5b48348d806f4c80f9dbae5f Mon Sep 17 00:00:00 2001 From: HenrZu <69154294+HenrZu@users.noreply.github.com> Date: Wed, 28 Aug 2024 11:38:31 +0200 Subject: [PATCH 43/46] type conversation --- cpp/tests/test_odesecir.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/cpp/tests/test_odesecir.cpp b/cpp/tests/test_odesecir.cpp index 569a1593fd..cb133d06bb 100644 --- a/cpp/tests/test_odesecir.cpp +++ b/cpp/tests/test_odesecir.cpp @@ -1214,8 +1214,8 @@ class ModelTestOdeSecir : public testing::Test , num_age_groups(6) { } - size_t num_age_groups; mio::osecir::Model model; + size_t num_age_groups; protected: void SetUp() override @@ -1337,7 +1337,7 @@ TEST_F(ModelTestOdeSecir, export_time_series_init_old_date) auto population_data = mio::osecir::details::read_population_data(path, region, false).value(); // So, the expected values are the population data in the susceptible compartments and zeros in the other compartments. - for (auto i = 0; i < num_age_groups; i++) { + for (size_t i = 0; i < num_age_groups; i++) { EXPECT_EQ(results_extrapolated(i * Eigen::Index(mio::osecir::InfectionState::Count)), population_data[0][i]); } // sum of all compartments should be equal to the population @@ -1398,7 +1398,7 @@ TEST_F(ModelTestOdeSecir, model_initialization_old_date) auto results_extrapolated = model_vector[0].populations.array().cast(); - for (auto i = 0; i < num_age_groups; i++) { + for (size_t i = 0; i < num_age_groups; i++) { EXPECT_EQ(results_extrapolated(i * Eigen::Index(mio::osecir::InfectionState::Count)), population_data[0][i]); } // sum of all compartments should be equal to the population From 1db2103dc0b0b0d08542509cfabc9b201a709624 Mon Sep 17 00:00:00 2001 From: Henrik Zunker <69154294+HenrZu@users.noreply.github.com> Date: Tue, 3 Sep 2024 14:41:26 +0200 Subject: [PATCH 44/46] Update cpp/models/ode_secir/parameters_io.h Co-authored-by: lenaploetzke <70579874+lenaploetzke@users.noreply.github.com> --- cpp/models/ode_secir/parameters_io.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cpp/models/ode_secir/parameters_io.h b/cpp/models/ode_secir/parameters_io.h index 297c428059..d5b1865756 100644 --- a/cpp/models/ode_secir/parameters_io.h +++ b/cpp/models/ode_secir/parameters_io.h @@ -49,7 +49,7 @@ void interpolate_ages(const std::vector& age_ranges, std::vector Date: Tue, 3 Sep 2024 15:06:07 +0200 Subject: [PATCH 45/46] some fixes for doc, [in] and [out], del function interpolate_ages --- cpp/models/ode_secir/parameters_io.h | 116 +++++++++---------- cpp/models/ode_secirvvs/parameters_io.h | 144 ++++++++++++------------ 2 files changed, 124 insertions(+), 136 deletions(-) diff --git a/cpp/models/ode_secir/parameters_io.h b/cpp/models/ode_secir/parameters_io.h index d5b1865756..a77722ebf1 100644 --- a/cpp/models/ode_secir/parameters_io.h +++ b/cpp/models/ode_secir/parameters_io.h @@ -37,25 +37,15 @@ namespace osecir namespace details { -/** - * @brief Interpolates age_ranges to param_ranges and saves ratios in interpolation. - * @param age_ranges Original age ranges of the data. - * @param interpolation Vector of ratios that are aplied to the data of age_ranges. - * @param carry_over Boolean vector which indicates whether there is an overflow from one age group to the next while interpolating data. - */ -void interpolate_ages(const std::vector& age_ranges, std::vector>& interpolation, - std::vector& carry_over); - /** * @brief reads populations data from RKI. * @param[in] rki_data Vector of ConfirmedCasesDataEntry%s. * @param[in] vregion Vector of keys of the region of interest. - * @param[in] year Specifies year at which the data is read. - * @param[in] month Specifies month at which the data is read. - * @param[in] day Specifies day at which the data is read. - * @param[in, out] num_* Output vector for number of people in the corresponding compartement. - * @param[in] t_* vector Average time it takes to get from one compartement to another for each age group. - * @param[in] mu_* vector Probabilities to get from one compartement to another for each age group. + * @param[in] date Date at which the data is read. + * @param[in, out] vnum_* Output vector for number of people in the corresponding compartement. + * @param[in] vt_* vector Average time it takes to get from one compartement to another for each age group. + * @param[in] vmu_* vector Probabilities to get from one compartement to another for each age group. + * @param[in] scaling_factor_inf Factors by which to scale the confirmed cases of rki data. */ IOResult read_confirmed_cases_data( std::vector& rki_data, std::vector const& vregion, Date date, @@ -161,11 +151,11 @@ IOResult set_confirmed_cases_data(std::vector>& model, std::vect * @brief Sets the infected population for a given model based on confirmed cases data. Here, we * read the case data from a file. * @tparam FP Floating point data type, e.g., double. - * @param model Vector of models for which the confirmed cases data will be set. - * @param path Path to the confirmed cases data file. - * @param region Vector of keys of the region of interest - * @param date Date at which the data is read - * @param scaling_factor_inf Factors by which to scale the confirmed cases of rki data + * @param[in, out] Vector of models for which the confirmed cases data will be set. + * @param[in] path Path to the confirmed cases data file. + * @param[in] region Vector of keys of the region of interest + * @param[in] date Date at which the data is read + * @param[in] scaling_factor_inf Factors by which to scale the confirmed cases of rki data */ template IOResult set_confirmed_cases_data(std::vector>& model, const std::string& path, @@ -179,7 +169,7 @@ IOResult set_confirmed_cases_data(std::vector>& model, const std /** * @brief Reads number of ICU patients from DIVI register into Parameters. - * @param path Path to DIVI file. + * @param[out] path Path to DIVI file. * @param vregion Keys of the region of interest. * @param year Specifies year at which the data is read. * @param month Specifies month at which the data is read. @@ -192,13 +182,11 @@ IOResult read_divi_data(const std::string& path, const std::vector& v /** * @brief Sets populations data from DIVI register into Model. * @tparam FP floating point data type, e.g., double. - * @param model Vector of models in which the data is set. - * @param path Path to DIVI file. - * @param vregion Vector of keys of the regions of interest. - * @param year Specifies year at which the data is read. - * @param month Specifies month at which the data is read. - * @param day Specifies day at which the data is read. - * @param scaling_factor_icu factor by which to scale the icu cases of divi data. + * @param[in, out] model Vector of models in which the data is set. + * @param[in] path Path to DIVI file. + * @param[in] vregion Vector of keys of the regions of interest. + * @param[in] date Date for which the arrays are initialized. + * @param[in]scaling_factor_icu factor by which to scale the icu cases of divi data. */ template IOResult set_divi_data(std::vector>& model, const std::string& path, const std::vector& vregion, @@ -290,16 +278,16 @@ IOResult set_population_data(std::vector>& model, const std::str * The initialisation is applied for a predefined number of days and finally saved in a timeseries for each region. In the end, * we save the files "Results_rki.h5" and "Results_rki_sum.h5" in the results_dir. * Results_rki.h5 contains a time series for each region and Results_rki_sum.h5 contains the sum of all regions. -* @param models Vector of models in which the data is set. Copy is made to avoid changing the original model. -* @param results_dir Path to result files. -* @param region Vector of keys of the region of interest. -* @param date Date for which the data should be read. -* @param scaling_factor_inf Factors by which to scale the confirmed cases of rki data. -* @param scaling_factor_icu Factor by which to scale the icu cases of divi data. -* @param num_days Number of days to be simulated/initialized. -* @param divi_data_path Path to DIVI file. -* @param confirmed_cases_path Path to confirmed cases file. -* @param population_data_path Path to population data file. +* @param[in] models Vector of models in which the data is set. Copy is made to avoid changing the original model. +* @param[in] results_dir Path to result files. +* @param[in] region Vector of keys of the region of interest. +* @param[in] date Date for which the data should be read. +* @param[in] scaling_factor_inf Factors by which to scale the confirmed cases of rki data. +* @param[in] scaling_factor_icu Factor by which to scale the icu cases of divi data. +* @param[in] num_days Number of days to be simulated/initialized. +* @param[in] divi_data_path Path to DIVI file. +* @param[in] confirmed_cases_path Path to confirmed cases file. +* @param[in] population_data_path Path to population data file. */ template IOResult export_input_data_county_timeseries( @@ -358,11 +346,11 @@ export_input_data_county_timeseries(std::vector models, const std::string /** * @brief Reads population data from population files for the whole country. - * @param model Vector of model in which the data is set. - * @param date Date for which the data should be read. - * @param scaling_factor_inf Factors by which to scale the confirmed cases of rki data. - * @param scaling_factor_icu Factor by which to scale the icu cases of divi data. - * @param dir Directory of files. + * @param[in, out] model Vector of model in which the data is set. + * @param[in] date Date for which the data should be read. + * @param[in] scaling_factor_inf Factors by which to scale the confirmed cases of rki data. + * @param[in] scaling_factor_icu Factor by which to scale the icu cases of divi data. + * @param[in] dir Directory of files. */ template IOResult read_input_data_germany(std::vector& model, Date date, @@ -384,12 +372,12 @@ IOResult read_input_data_germany(std::vector& model, Date date, /** * @brief Reads population data from population files for the specefied state. - * @param model Vector of model in which the data is set. - * @param date Date for which the data should be read. - * @param state Vector of region keys of states of interest. - * @param scaling_factor_inf Factors by which to scale the confirmed cases of rki data. - * @param scaling_factor_icu Factor by which to scale the icu cases of divi data. - * @param dir Directory of files. + * @param[in, out] model Vector of model in which the data is set. + * @param[in] date Date for which the data should be read. + * @param[in] state Vector of region keys of states of interest. + * @param[in] scaling_factor_inf Factors by which to scale the confirmed cases of rki data. + * @param[in] scaling_factor_icu Factor by which to scale the icu cases of divi data. + * @param[in] dir Directory of files. */ template IOResult read_input_data_state(std::vector& model, Date date, std::vector& state, @@ -412,14 +400,14 @@ IOResult read_input_data_state(std::vector& model, Date date, std:: /** * @brief Reads population data from population files for the specefied county. - * @param model Vector of model in which the data is set. - * @param date Date for which the data should be read. - * @param county Vector of region keys of counties of interest. - * @param scaling_factor_inf Factors by which to scale the confirmed cases of rki data. - * @param scaling_factor_icu Factor by which to scale the icu cases of divi data. - * @param dir Directory of files. - * @param num_days [Default: 0] Number of days to be simulated; required to extrapolate real data. - * @param export_time_series [Default: false] If true, reads data for each day of simulation and writes it in the same directory as the input files. + * @param[in, out] model Vector of model in which the data is set. + * @param[in] date Date for which the data should be read. + * @param[in] county Vector of region keys of counties of interest. + * @param[in] scaling_factor_inf Factors by which to scale the confirmed cases of rki data. + * @param[in] scaling_factor_icu Factor by which to scale the icu cases of divi data. + * @param[in] dir Directory of files. + * @param[in] num_days [Default: 0] Number of days to be simulated; required to extrapolate real data. + * @param[in] export_time_series [Default: false] If true, reads data for each day of simulation and writes it in the same directory as the input files. */ template IOResult read_input_data_county(std::vector& model, Date date, const std::vector& county, @@ -455,13 +443,13 @@ IOResult read_input_data_county(std::vector& model, Date date, cons /** * @brief reads population data from population files for the specified nodes - * @param model vector of model in which the data is set - * @param date Date for which the data should be read - * @param county vector of region keys of interest - * @param scaling_factor_inf factors by which to scale the confirmed cases of rki data - * @param scaling_factor_icu factor by which to scale the icu cases of divi data - * @param dir directory of files - * @param age_group_names strings specifying age group names + * @param[in, out] model vector of model in which the data is set + * @param[in] date Date for which the data should be read + * @param[in] county vector of region keys of interest + * @param[in] scaling_factor_inf factors by which to scale the confirmed cases of rki data + * @param[in] scaling_factor_icu factor by which to scale the icu cases of divi data + * @param[in] dir directory of files + * @param[in] age_group_names strings specifying age group names */ template IOResult read_input_data(std::vector& model, Date date, const std::vector& node_ids, diff --git a/cpp/models/ode_secirvvs/parameters_io.h b/cpp/models/ode_secirvvs/parameters_io.h index 0272834122..89cfd4d3d7 100644 --- a/cpp/models/ode_secirvvs/parameters_io.h +++ b/cpp/models/ode_secirvvs/parameters_io.h @@ -40,13 +40,13 @@ namespace details { /** * @brief Reads subpopulations of infection states from transformed RKI cases file. - * @param path Path to transformed RKI cases file. - * @param vregion Vector of keys of the region of interest. - * @param date Date for which the arrays are initialized. - * @param num_* Output vector for number of people in the corresponding compartement. - * @param t_* Average time it takes to get from one compartement to another (vector with one element per age group). - * @param mu_* Probabilities to get from one compartement to another (vector with one element per age group). - * @param scaling_factor_inf Factor for scaling the confirmed cases to account for estimated undetected cases. + * @param[in] path Path to transformed RKI cases file. + * @param[in] vregion Vector of keys of the region of interest. + * @param[in] date Date for which the arrays are initialized. + * @param[in, out] num_* Output vector for number of people in the corresponding compartement. + * @param[in] vt_* Average time it takes to get from one compartement to another (vector with one element per age group). + * @param[in] vmu_* Probabilities to get from one compartement to another (vector with one element per age group). + * @param[in] scaling_factor_inf Factor for scaling the confirmed cases to account for estimated undetected cases. * @see mio::read_confirmed_cases_data * @{ */ @@ -75,11 +75,11 @@ IOResult read_confirmed_cases_data( /** * @brief Reads confirmed cases data and translates data of day t0-delay to recovered compartment. - * @param path Path to RKI confirmed cases file. - * @param vregion Vector of keys of the region of interest. - * @param date Date for which the arrays are initialized. - * @param num_rec Output vector for number of people in the compartement recovered. - * @param delay Number of days in the past the are used to set recovered compartment. + * @param[in] path Path to RKI confirmed cases file. + * @param[in] vregion Vector of keys of the region of interest. + * @param[in] date Date for which the arrays are initialized. + * @param[in, out] num_rec Output vector for number of people in the compartement recovered. + * @param[in] delay Number of days in the past the are used to set recovered compartment. * @see mio::read_confirmed_cases_data * @{ */ @@ -93,12 +93,12 @@ IOResult read_confirmed_cases_data_fix_recovered(std::string const& path, /** * @brief Sets the confirmed cases data for a vector of models based on input data. - * @param model Vector of objects in which the data is set. - * @param case_data Vector of case data. Each inner vector represents a different region. - * @param region Vector of keys of the region of interest. - * @param date Date for which the arrays are initialized. - * @param scaling_factor_inf Factors by which to scale the confirmed cases of RKI data. - * @param set_death If true, set the number of deaths. + * @param[in, out] model Vector of objects in which the data is set. + * @param[in] case_data Vector of case data. Each inner vector represents a different region. + * @param[in] region Vector of keys of the region of interest. + * @param[in] date Date for which the arrays are initialized. + * @param[in] scaling_factor_inf Factors by which to scale the confirmed cases of RKI data. + * @param[in] set_death If true, set the number of deaths. */ template IOResult set_confirmed_cases_data(std::vector& model, @@ -369,13 +369,13 @@ IOResult set_confirmed_cases_data(std::vector& model, /** * @brief sets populations data from a transformed RKI cases file into a Model. - * @param model vector of objects in which the data is set - * @param path Path to transformed RKI cases file - * @param region vector of keys of the region of interest - * @param date Date for which the arrays are initialized - * @param scaling_factor_inf factors by which to scale the confirmed cases of + * @param[in, out] model vector of objects in which the data is set + * @param[in] path Path to transformed RKI cases file + * @param[in] region vector of keys of the region of interest + * @param[in] date Date for which the arrays are initialized + * @param[in] scaling_factor_inf factors by which to scale the confirmed cases of * rki data - * @param set_death If true, set the number of deaths. + * @param set_death[in] If true, set the number of deaths. */ template IOResult set_confirmed_cases_data(std::vector& model, const std::string& path, @@ -389,10 +389,10 @@ IOResult set_confirmed_cases_data(std::vector& model, const std::st /** * @brief reads number of ICU patients from DIVI register into Parameters - * @param path Path to transformed DIVI file - * @param vregion Keys of the region of interest - * @param date Date for which the arrays are initialized - * @param vnum_icu number of ICU patients + * @param[in] path Path to transformed DIVI file + * @param[in] vregion Keys of the region of interest + * @param[in] date Date for which the arrays are initialized + * @param[in, out] vnum_icu number of ICU patients * @see mio::read_divi_data * @{ */ @@ -404,11 +404,11 @@ IOResult read_divi_data(const std::vector& divi_data, const std /** * @brief sets populations data from DIVI register into Model - * @param model vector of objects in which the data is set - * @param path Path to transformed DIVI file - * @param vregion vector of keys of the regions of interest - * @param date Date for which the arrays are initialized - * @param scaling_factor_icu factor by which to scale the icu cases of divi data + * @param[in, out] model vector of objects in which the data is set + * @param[in] path Path to transformed DIVI file + * @param[in] vregion vector of keys of the regions of interest + * @param[in] date Date for which the arrays are initialized + * @param[in] scaling_factor_icu factor by which to scale the icu cases of divi data */ template IOResult set_divi_data(std::vector& model, const std::string& path, const std::vector& vregion, @@ -441,8 +441,8 @@ IOResult set_divi_data(std::vector& model, const std::string& path, /** * @brief reads population data from census data. - * @param path Path to population data file. - * @param vregion vector of keys of the regions of interest + * @param[in] path Path to population data file. + * @param[in] vregion vector of keys of the regions of interest * @see mio::read_population_data * @{ */ @@ -666,11 +666,11 @@ IOResult set_population_data(std::vector& model, const std::string& * @brief Sets vaccination data for models stored in a vector. * * @tparam FP Floating point type used in the Model objects. - * @param model Vector of Model objects in which the vaccination data is set. - * @param vacc_data Vector of VaccinationDataEntry objects containing the vaccination data. - * @param date Start date for the simulation. - * @param vregion Vector of region identifiers. - * @param num_days Number of days for which the simulation is run. + * @param[in, out] model Vector of Model objects in which the vaccination data is set. + * @param[in] vacc_data Vector of VaccinationDataEntry objects containing the vaccination data. + * @param[in] date Start date for the simulation. + * @param[in] vregion Vector of region identifiers. + * @param[in] num_days Number of days for which the simulation is run. */ template IOResult set_vaccination_data(std::vector>& model, const std::vector& vacc_data, @@ -803,11 +803,11 @@ IOResult set_vaccination_data(std::vector>& model, const std::ve * @brief Reads vaccination data from a file and sets it for each model. * * @tparam FP Floating point type used in the Model objects. - * @param model Vector of Model objects in which the vaccination data is set. - * @param path Path to vaccination data file. - * @param date Start date for the simulation. - * @param vregion Vector of region identifiers. - * @param num_days Number of days for which the simulation is run. + * @param[in, out] model Vector of Model objects in which the vaccination data is set. + * @param[in] path Path to vaccination data file. + * @param[in] date Start date for the simulation. + * @param[in] vregion Vector of region identifiers. + * @param[in] num_days Number of days for which the simulation is run. */ template IOResult set_vaccination_data(std::vector>& model, const std::string& path, Date date, @@ -827,17 +827,17 @@ IOResult set_vaccination_data(std::vector>& model, const std::st * The initialisation is applied for a predefined number of days and finally saved in a timeseries for each region. In the end, * we save the files "Results_rki.h5" and "Results_rki_sum.h5" in the results_dir. * Results_rki.h5 contains a time series for each region and Results_rki_sum.h5 contains the sum of all regions. -* @param models Vector of models in which the data is set. Copy is made to avoid changing the original model. -* @param results_dir Path to result files. -* @param counties Vector of keys of the counties of interest. -* @param date Date for which the data should be read. -* @param scaling_factor_inf Factors by which to scale the confirmed cases of rki data. -* @param scaling_factor_icu Factor by which to scale the icu cases of divi data. -* @param num_days Number of days to be simulated/initialized. -* @param divi_data_path Path to DIVI file. -* @param confirmed_cases_path Path to confirmed cases file. -* @param population_data_path Path to population data file. -* @param vaccination_data_path Path to vaccination data file. +* @param[in] models Vector of models in which the data is set. Copy is made to avoid changing the original model. +* @param[in] results_dir Path to result files. +* @param[in] counties Vector of keys of the counties of interest. +* @param[in] date Date for which the data should be read. +* @param[in] scaling_factor_inf Factors by which to scale the confirmed cases of rki data. +* @param[in] scaling_factor_icu Factor by which to scale the icu cases of divi data. +* @param[in] num_days Number of days to be simulated/initialized. +* @param[in] divi_data_path Path to DIVI file. +* @param[in] confirmed_cases_path Path to confirmed cases file. +* @param[in] population_data_path Path to population data file. +* @param[in] vaccination_data_path Path to vaccination data file. */ template IOResult export_input_data_county_timeseries( @@ -921,14 +921,14 @@ IOResult export_input_data_county_timeseries(std::vector, const std * Estimates all compartments from available data using the model parameters, so the * model parameters must be set before calling this function. * Uses data files that contain centered 7-day moving average. - * @param model Vector of SECIRVVS models, one per county. - * @param date Date for which the data should be read. - * @param county Ids of the counties. - * @param scaling_factor_inf Factor of confirmed cases to account for undetected cases in each county. - * @param scaling_factor_icu Factor of ICU cases to account for underreporting. - * @param dir Directory that contains the data files. - * @param num_days Number of days to be simulated; required to load data for vaccinations during the simulation. - * @param export_time_series If true, reads data for each day of simulation and writes it in the same directory as the input files. + * @param[in, out] model Vector of SECIRVVS models, one per county. + * @param[in] date Date for which the data should be read. + * @param[in] county Ids of the counties. + * @param[in] scaling_factor_inf Factor of confirmed cases to account for undetected cases in each county. + * @param[in] scaling_factor_icu Factor of ICU cases to account for underreporting. + * @param[in] dir Directory that contains the data files. + * @param[in] num_days Number of days to be simulated; required to load data for vaccinations during the simulation. + * @param[in] export_time_series If true, reads data for each day of simulation and writes it in the same directory as the input files. */ template IOResult read_input_data_county(std::vector& model, Date date, const std::vector& county, @@ -976,14 +976,14 @@ IOResult read_input_data_county(std::vector& model, Date date, cons * Estimates all compartments from available data using the model parameters, so the * model parameters must be set before calling this function. * Uses data files that contain centered 7-day moving average. - * @param model Vector of SECIRVVS models, one per county. - * @param date Date for which the data should be read. - * @param county Ids of the counties. - * @param scaling_factor_inf Factor of confirmed cases to account for undetected cases in each county. - * @param scaling_factor_icu Factor of ICU cases to account for underreporting. - * @param dir Directory that contains the data files. - * @param num_days Number of days to be simulated; required to load data for vaccinations during the simulation. - * @param export_time_series If true, reads data for each day of simulation and writes it in the same directory as the input files. + * @param[in, out] model Vector of SECIRVVS models, one per county. + * @param[in] date Date for which the data should be read. + * @param[in] node_ids Ids of the nodes. + * @param[in] scaling_factor_inf Factor of confirmed cases to account for undetected cases in each county. + * @param[in] scaling_factor_icu Factor of ICU cases to account for underreporting. + * @param[in] dir Directory that contains the data files. + * @param[in] num_days Number of days to be simulated; required to load data for vaccinations during the simulation. + * @param[in] export_time_series If true, reads data for each day of simulation and writes it in the same directory as the input files. */ template IOResult read_input_data(std::vector& model, Date date, const std::vector& node_ids, From 49de11609f0282a006d5e3c32cf85d205c05d3c2 Mon Sep 17 00:00:00 2001 From: HenrZu <69154294+HenrZu@users.noreply.github.com> Date: Tue, 3 Sep 2024 16:00:18 +0200 Subject: [PATCH 46/46] additional doc --- cpp/models/ode_secir/parameters_io.h | 16 +++++++--------- 1 file changed, 7 insertions(+), 9 deletions(-) diff --git a/cpp/models/ode_secir/parameters_io.h b/cpp/models/ode_secir/parameters_io.h index a77722ebf1..7713232ce4 100644 --- a/cpp/models/ode_secir/parameters_io.h +++ b/cpp/models/ode_secir/parameters_io.h @@ -153,9 +153,9 @@ IOResult set_confirmed_cases_data(std::vector>& model, std::vect * @tparam FP Floating point data type, e.g., double. * @param[in, out] Vector of models for which the confirmed cases data will be set. * @param[in] path Path to the confirmed cases data file. - * @param[in] region Vector of keys of the region of interest - * @param[in] date Date at which the data is read - * @param[in] scaling_factor_inf Factors by which to scale the confirmed cases of rki data + * @param[in] region Vector of keys of the region of interest. + * @param[in] date Date at which the data is read. + * @param[in] scaling_factor_inf Factors by which to scale the confirmed cases of rki data. */ template IOResult set_confirmed_cases_data(std::vector>& model, const std::string& path, @@ -169,11 +169,9 @@ IOResult set_confirmed_cases_data(std::vector>& model, const std /** * @brief Reads number of ICU patients from DIVI register into Parameters. - * @param[out] path Path to DIVI file. - * @param vregion Keys of the region of interest. - * @param year Specifies year at which the data is read. - * @param month Specifies month at which the data is read. - * @param day Specifies day at which the data is read. + * @param[in] path Path to DIVI file. + * @param[in] vregion Keys of the region of interest. + * @param date Date for which we initialize. * @param vnum_icu Number of ICU patients. */ IOResult read_divi_data(const std::string& path, const std::vector& vregion, Date date, @@ -186,7 +184,7 @@ IOResult read_divi_data(const std::string& path, const std::vector& v * @param[in] path Path to DIVI file. * @param[in] vregion Vector of keys of the regions of interest. * @param[in] date Date for which the arrays are initialized. - * @param[in]scaling_factor_icu factor by which to scale the icu cases of divi data. + * @param[in] scaling_factor_icu factor by which to scale the icu cases of divi data. */ template IOResult set_divi_data(std::vector>& model, const std::string& path, const std::vector& vregion,