Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

1191 Initialization of ICU compartments after July 2024 #1192

Merged
10 changes: 2 additions & 8 deletions cpp/models/ode_secir/parameters_io.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -123,8 +123,6 @@ IOResult<void> read_confirmed_cases_data(
auto date_df = region_entry.date;
auto age = size_t(region_entry.age_group);

bool read_icu = false; //params.populations.get({age, SecirCompartments::U}) == 0;

HenrZu marked this conversation as resolved.
Show resolved Hide resolved
if (date_df == offset_date_by_days(date, 0)) {
num_InfectedSymptoms[age] += scaling_factor_inf[age] * region_entry.num_confirmed;
num_rec[age] += region_entry.num_confirmed;
Expand All @@ -147,16 +145,12 @@ IOResult<void> read_confirmed_cases_data(
}
if (date_df == offset_date_by_days(date, -t_InfectedSymptoms[age] - t_InfectedSevere[age])) {
num_InfectedSevere[age] -= mu_I_H[age] * scaling_factor_inf[age] * region_entry.num_confirmed;
if (read_icu) {
num_icu[age] += mu_I_H[age] * mu_H_U[age] * scaling_factor_inf[age] * region_entry.num_confirmed;
}
num_icu[age] += mu_I_H[age] * mu_H_U[age] * scaling_factor_inf[age] * region_entry.num_confirmed;
}
if (date_df ==
offset_date_by_days(date, -t_InfectedSymptoms[age] - t_InfectedSevere[age] - t_InfectedCritical[age])) {
num_death[age] += region_entry.num_deaths;
if (read_icu) {
num_icu[age] -= mu_I_H[age] * mu_H_U[age] * scaling_factor_inf[age] * region_entry.num_confirmed;
}
num_icu[age] -= mu_I_H[age] * mu_H_U[age] * scaling_factor_inf[age] * region_entry.num_confirmed;
}
}
}
Expand Down
58 changes: 21 additions & 37 deletions cpp/models/ode_secir/parameters_io.h
Original file line number Diff line number Diff line change
Expand Up @@ -134,8 +134,12 @@ IOResult<void> set_confirmed_cases_data(std::vector<Model<FP>>& model, std::vect
num_InfectedSymptoms[node][i];
model[node].populations[{AgeGroup(i), InfectionState::InfectedSymptomsConfirmed}] = 0;
model[node].populations[{AgeGroup(i), InfectionState::InfectedSevere}] = num_InfectedSevere[node][i];
model[node].populations[{AgeGroup(i), InfectionState::Dead}] = num_death[node][i];
model[node].populations[{AgeGroup(i), InfectionState::Recovered}] = num_rec[node][i];
// Only set the number of ICU patients here, if the date is not available in the data.
if (date <= Date(2020, 4, 23) || date >= Date(2024, 7, 21)) {
model[node].populations[{AgeGroup(i), InfectionState::InfectedCritical}] = num_icu[node][i];
}
model[node].populations[{AgeGroup(i), InfectionState::Dead}] = num_death[node][i];
model[node].populations[{AgeGroup(i), InfectionState::Recovered}] = num_rec[node][i];
}
}
else {
Expand Down Expand Up @@ -190,6 +194,12 @@ template <typename FP = double>
IOResult<void> set_divi_data(std::vector<Model<FP>>& model, const std::string& path, const std::vector<int>& vregion,
Date date, double scaling_factor_icu)
{
// DIVI dataset will no longer be updated from CW29 2024 on.
if (date <= Date(2020, 4, 23) || date >= Date(2024, 7, 21)) {
HenrZu marked this conversation as resolved.
Show resolved Hide resolved
log_warning("No DIVI data available for date: {}-{}-{}", date.day, date.month, date.year,
". ICU compartment will be set based on Case data.");
HenrZu marked this conversation as resolved.
Show resolved Hide resolved
return success();
}
std::vector<double> sum_mu_I_U(vregion.size(), 0);
std::vector<std::vector<double>> mu_I_U{model.size()};
for (size_t region = 0; region < vregion.size(); region++) {
Expand Down Expand Up @@ -306,13 +316,7 @@ IOResult<void> export_input_data_county_timeseries(
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: {}-{}-{}", offset_day.day, offset_day.month, offset_day.year);
}

BOOST_OUTCOME_TRY(details::set_divi_data(models, divi_data_path, region, offset_day, scaling_factor_icu));
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++) {
Expand Down Expand Up @@ -355,13 +359,8 @@ IOResult<void> read_input_data_germany(std::vector<Model>& model, Date date,
const std::vector<double>& scaling_factor_inf, double scaling_factor_icu,
const std::string& dir)
{
if (date > Date(2020, 4, 23)) {
BOOST_OUTCOME_TRY(
details::set_divi_data(model, path_join(dir, "germany_divi.json"), {0}, date, scaling_factor_icu));
}
else {
log_warning("No DIVI data available for this date");
}
BOOST_OUTCOME_TRY(
details::set_divi_data(model, path_join(dir, "germany_divi.json"), {0}, date, scaling_factor_icu));
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}));
Expand All @@ -382,14 +381,9 @@ IOResult<void> read_input_data_state(std::vector<Model>& model, Date date, std::
const std::vector<double>& scaling_factor_inf, double scaling_factor_icu,
const std::string& dir)
{
if (date > Date(2020, 4, 23)) {
BOOST_OUTCOME_TRY(
details::set_divi_data(model, path_join(dir, "state_divi.json"), state, date, scaling_factor_icu));
}
else {
log_warning("No DIVI data available for this date");
}

BOOST_OUTCOME_TRY(
details::set_divi_data(model, path_join(dir, "state_divi.json"), state, date, scaling_factor_icu));
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));
Expand All @@ -412,13 +406,8 @@ IOResult<void> read_input_data_county(std::vector<Model>& model, Date date, cons
const std::vector<double>& scaling_factor_inf, double scaling_factor_icu,
const std::string& dir, int num_days = 0, bool export_time_series = false)
{
if (date > Date(2020, 4, 23)) {
BOOST_OUTCOME_TRY(details::set_divi_data(model, path_join(dir, "pydata/Germany", "county_divi_ma7.json"),
county, date, scaling_factor_icu));
}
else {
log_warning("No DIVI data available for this date");
}
BOOST_OUTCOME_TRY(details::set_divi_data(model, path_join(dir, "pydata/Germany", "county_divi_ma7.json"), county,
date, scaling_factor_icu));
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(
Expand Down Expand Up @@ -454,13 +443,8 @@ IOResult<void> read_input_data(std::vector<Model>& model, Date date, const std::
const std::vector<double>& scaling_factor_inf, double scaling_factor_icu,
const std::string& data_dir, int num_days = 0, bool export_time_series = false)
{
if (date > Date(2020, 4, 23)) {
BOOST_OUTCOME_TRY(details::set_divi_data(model, path_join(data_dir, "critical_cases.json"), node_ids, date,
scaling_factor_icu));
}
else {
log_warning("No DIVI data available for this date");
}
BOOST_OUTCOME_TRY(
details::set_divi_data(model, path_join(data_dir, "critical_cases.json"), node_ids, date, scaling_factor_icu));
BOOST_OUTCOME_TRY(details::set_confirmed_cases_data(model, path_join(data_dir, "confirmed_cases.json"), node_ids,
date, scaling_factor_inf));
BOOST_OUTCOME_TRY(details::set_population_data(model, path_join(data_dir, "population_data.json"), node_ids));
Expand Down
83 changes: 45 additions & 38 deletions cpp/models/ode_secirts/parameters_io.h
Original file line number Diff line number Diff line change
Expand Up @@ -100,7 +100,7 @@ IOResult<void> compute_confirmed_cases_data(
std::vector<std::vector<FP>>& vnum_InfectedSevere, std::vector<std::vector<FP>>& vnum_icu,
std::vector<std::vector<FP>>& vnum_death, std::vector<std::vector<FP>>& vnum_timm_i,
std::vector<int> const& vregion, Date date, const std::vector<Model>& model,
const std::vector<FP>& scaling_factor_inf, const size_t layer, bool read_icu = false)
const std::vector<FP>& scaling_factor_inf, const size_t layer)
{
auto max_date_entry = std::max_element(case_data.begin(), case_data.end(), [](auto&& a, auto&& b) {
return a.date < b.date;
Expand Down Expand Up @@ -211,17 +211,13 @@ IOResult<void> compute_confirmed_cases_data(
}
if (entry.date == offset_date_by_days(date, -t_InfectedSymptoms - t_InfectedSevere)) {
num_InfectedSevere[age] -= severePerInfectedSymptoms * scaling_factor_inf[age] * entry.num_confirmed;
if (read_icu) {
num_icu[age] +=
severePerInfectedSymptoms * criticalPerSevere * scaling_factor_inf[age] * entry.num_confirmed;
}
num_icu[age] +=
severePerInfectedSymptoms * criticalPerSevere * scaling_factor_inf[age] * entry.num_confirmed;
}
if (entry.date == offset_date_by_days(date, -t_InfectedSymptoms - t_InfectedSevere - t_InfectedCritical)) {
num_death[age] += entry.num_deaths;
if (read_icu) {
num_icu[age] -=
severePerInfectedSymptoms * criticalPerSevere * scaling_factor_inf[age] * entry.num_confirmed;
}
num_icu[age] -=
severePerInfectedSymptoms * criticalPerSevere * scaling_factor_inf[age] * entry.num_confirmed;
}
if (entry.date == offset_date_by_days(date, 0 - t_imm_interval_i)) {
num_imm[age] -= entry.num_confirmed;
Expand Down Expand Up @@ -305,13 +301,12 @@ IOResult<void> read_confirmed_cases_data(
std::vector<std::vector<FP>>& vnum_InfectedNoSymptoms, std::vector<std::vector<FP>>& vnum_InfectedSymptoms,
std::vector<std::vector<FP>>& vnum_InfectedSevere, std::vector<std::vector<FP>>& vnum_icu,
std::vector<std::vector<FP>>& vnum_death, std::vector<std::vector<FP>>& vnum_timm_i,
const std::vector<Model>& model, const std::vector<FP>& scaling_factor_inf, const size_t layer,
bool read_icu = false)
const std::vector<Model>& model, const std::vector<FP>& scaling_factor_inf, const size_t layer)
{
BOOST_OUTCOME_TRY(auto&& case_data, mio::read_confirmed_cases_data(path));
return compute_confirmed_cases_data(case_data, vnum_Exposed, vnum_InfectedNoSymptoms, vnum_InfectedSymptoms,
vnum_InfectedSevere, vnum_icu, vnum_death, vnum_timm_i, vregion, date, model,
scaling_factor_inf, layer, read_icu);
scaling_factor_inf, layer);
}

/**
Expand Down Expand Up @@ -354,7 +349,7 @@ set_confirmed_cases_data(std::vector<Model>& model, const std::vector<ConfirmedC
std::vector<FP> denom_E(num_age_groups, 0.0);
std::vector<FP> denom_I_NS(num_age_groups, 0.0);
std::vector<FP> denom_I_Sy(num_age_groups, 0.0);
std::vector<FP> denom_I_Sev(num_age_groups, 0.0);
std::vector<FP> denom_I_Sev_Cr(num_age_groups, 0.0);

/*----------- Naive immunity -----------*/
for (size_t county = 0; county < model.size(); county++) {
Expand Down Expand Up @@ -391,7 +386,7 @@ set_confirmed_cases_data(std::vector<Model>& model, const std::vector<ConfirmedC
model[county]
.parameters.template get<ReducInfectedSymptomsImprovedImmunity<FP>>()[(AgeGroup)group]);

denom_I_Sev[group] =
denom_I_Sev_Cr[group] =
1 / (immunity_population[0][group] +
immunity_population[1][group] *
model[county].parameters.template get<ReducInfectedSevereCriticalDeadPartialImmunity<FP>>()[(
Expand All @@ -418,7 +413,12 @@ set_confirmed_cases_data(std::vector<Model>& model, const std::vector<ConfirmedC
immunity_population[0][i] * denom_I_Sy[i] * num_InfectedSymptoms[county][i];
model[county].populations[{AgeGroup(i), InfectionState::InfectedSymptomsNaiveConfirmed}] = 0;
model[county].populations[{AgeGroup(i), InfectionState::InfectedSevereNaive}] =
immunity_population[0][i] * denom_I_Sev[i] * num_InfectedSevere[county][i];
immunity_population[0][i] * denom_I_Sev_Cr[i] * num_InfectedSevere[county][i];
// Only set the number of ICU patients here, if the date is not available in the data.
if (date <= Date(2020, 4, 23) || date >= Date(2024, 7, 21)) {
model[county].populations[{AgeGroup(i), InfectionState::InfectedCriticalNaive}] =
immunity_population[0][i] * denom_I_Sev_Cr[i] * num_icu[county][i];
}
HenrZu marked this conversation as resolved.
Show resolved Hide resolved
}
if (std::accumulate(num_InfectedSymptoms[county].begin(), num_InfectedSymptoms[county].end(), 0.0) == 0) {
log_warning("No infections for unvaccinated reported on date " + std::to_string(date.year) + "-" +
Expand Down Expand Up @@ -462,7 +462,15 @@ set_confirmed_cases_data(std::vector<Model>& model, const std::vector<ConfirmedC
immunity_population[1][i] *
model[county]
.parameters.template get<ReducInfectedSevereCriticalDeadPartialImmunity<FP>>()[(AgeGroup)i] *
denom_I_Sev[i] * num_InfectedSevere[county][i];
denom_I_Sev_Cr[i] * num_InfectedSevere[county][i];
// Only set the number of ICU patients here, if the date is not available in the data.
if (date <= Date(2020, 4, 23) || date >= Date(2024, 7, 21)) {
model[county].populations[{AgeGroup(i), InfectionState::InfectedCriticalPartialImmunity}] =
immunity_population[1][i] *
model[county]
.parameters.template get<ReducInfectedSevereCriticalDeadPartialImmunity<FP>>()[(AgeGroup)i] *
denom_I_Sev_Cr[i] * num_icu[county][i];
}
// the += is necessary because we already set the previous vaccinated individuals
model[county].populations[{AgeGroup(i), InfectionState::TemporaryImmunePartialImmunity}] +=
immunity_population[1][i] *
Expand Down Expand Up @@ -511,7 +519,16 @@ set_confirmed_cases_data(std::vector<Model>& model, const std::vector<ConfirmedC
immunity_population[2][i] *
model[county]
.parameters.template get<ReducInfectedSevereCriticalDeadImprovedImmunity<FP>>()[(AgeGroup)i] *
denom_I_Sev[i] * num_InfectedSevere[county][i];
denom_I_Sev_Cr[i] * num_InfectedSevere[county][i];
// Only set the number of ICU patients here, if the date is not available in the data.
if (date <= Date(2020, 4, 23) || date >= Date(2024, 7, 21)) {
model[county].populations[{AgeGroup(i), InfectionState::InfectedCriticalImprovedImmunity}] =
immunity_population[2][i] *
model[county]
.parameters.template get<ReducInfectedSevereCriticalDeadImprovedImmunity<FP>>()[(AgeGroup)i] *
denom_I_Sev_Cr[i] * num_icu[county][i];
}

// the += is necessary because we already set the previous vaccinated individuals
model[county].populations[{AgeGroup(i), InfectionState::TemporaryImmuneImprovedImmunity}] +=
immunity_population[2][i] *
Expand Down Expand Up @@ -644,6 +661,12 @@ template <class Model, typename FP = double>
IOResult<void> set_divi_data(std::vector<Model>& model, const std::string& path, const std::vector<int>& vregion,
Date date, FP scaling_factor_icu)
{
// DIVI dataset will no longer be updated from CW29 2024 on.
if (date <= Date(2020, 4, 23) || date >= Date(2024, 7, 21)) {
log_warning("No DIVI data available for date: {}-{}-{}", date.day, date.month, date.year,
". ICU compartment will be set based on Case data.");
return success();
}
std::vector<FP> sum_mu_I_U(vregion.size(), 0);
std::vector<std::vector<FP>> mu_I_U{model.size()};
for (size_t region = 0; region < vregion.size(); region++) {
Expand Down Expand Up @@ -993,13 +1016,7 @@ IOResult<void> export_input_data_county_timeseries(

// 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));
}
else {
log_warning("No DIVI data available for for date: {}-{}-{}", offset_day.day, offset_day.month,
offset_day.year);
}
BOOST_OUTCOME_TRY(details::set_divi_data(models, divi_data_path, counties, offset_day, scaling_factor_icu));

BOOST_OUTCOME_TRY(details::set_confirmed_cases_data(models, case_data, counties, offset_day, scaling_factor_inf,
immunity_population));
Expand Down Expand Up @@ -1073,13 +1090,8 @@ IOResult<void> read_input_data_county(std::vector<Model>& model, Date date, cons

// 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 (date > Date(2020, 4, 23)) {
BOOST_OUTCOME_TRY(details::set_divi_data(model, path_join(dir, "pydata/Germany", "county_divi_ma7.json"),
county, date, scaling_factor_icu));
}
else {
log_warning("No DIVI data available for this date");
}
BOOST_OUTCOME_TRY(details::set_divi_data(model, path_join(dir, "pydata/Germany", "county_divi_ma7.json"), county,
date, scaling_factor_icu));

BOOST_OUTCOME_TRY(
details::set_confirmed_cases_data(model, path_join(dir, "pydata/Germany", "cases_all_county_age_ma7.json"),
Expand Down Expand Up @@ -1136,13 +1148,8 @@ IOResult<void> read_input_data(std::vector<Model>& model, Date date, const std::

// 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 (date > Date(2020, 4, 23)) {
BOOST_OUTCOME_TRY(details::set_divi_data(model, path_join(data_dir, "critical_cases.json"), node_ids, date,
scaling_factor_icu));
}
else {
log_warning("No DIVI data available for this date");
}
BOOST_OUTCOME_TRY(
details::set_divi_data(model, path_join(data_dir, "critical_cases.json"), node_ids, date, scaling_factor_icu));

BOOST_OUTCOME_TRY(details::set_confirmed_cases_data(model, path_join(data_dir, "confirmed_cases.json"), node_ids,
date, scaling_factor_inf, immunity_population));
Expand Down
Loading