20 #ifndef MIO_ODE_SECIRTS_PARAMETERS_IO_H
21 #define MIO_ODE_SECIRTS_PARAMETERS_IO_H
25 #ifdef MEMILIO_HAS_JSONCPP
73 template <
typename FP,
class Model>
74 IOResult<void> compute_confirmed_cases_data(
75 const std::vector<ConfirmedCasesDataEntry>& case_data, std::vector<std::vector<FP>>& vnum_Exposed,
76 std::vector<std::vector<FP>>& vnum_InfectedNoSymptoms, std::vector<std::vector<FP>>& vnum_InfectedSymptoms,
77 std::vector<std::vector<FP>>& vnum_InfectedSevere, std::vector<std::vector<FP>>& vnum_icu,
78 std::vector<std::vector<FP>>& vnum_death, std::vector<std::vector<FP>>& vnum_timm_i,
79 std::vector<int>
const& vregion, Date date,
const std::vector<Model>& model,
80 const std::vector<FP>& scaling_factor_inf,
const size_t layer)
82 auto max_date_entry = std::max_element(case_data.begin(), case_data.end(), [](
auto&& a,
auto&& b) {
83 return a.date < b.date;
85 if (max_date_entry == case_data.end()) {
89 auto max_date = max_date_entry->date;
90 if (max_date < date) {
91 log_error(
"Specified date does not exist in case data");
99 if (days_surplus > 0) {
103 for (
auto&& entry : case_data) {
104 auto it = std::find_if(vregion.begin(), vregion.end(), [&entry](
auto r) {
105 return r == 0 || get_region_id(entry) == r;
107 if (it != vregion.end()) {
108 auto region_idx = size_t(it - vregion.begin());
110 auto params_region = model[region_idx].parameters;
111 auto& num_InfectedNoSymptoms = vnum_InfectedNoSymptoms[region_idx];
112 auto& num_InfectedSymptoms = vnum_InfectedSymptoms[region_idx];
113 auto& num_Exposed = vnum_Exposed[region_idx];
114 auto& num_InfectedSevere = vnum_InfectedSevere[region_idx];
115 auto& num_death = vnum_death[region_idx];
116 auto& num_icu = vnum_icu[region_idx];
117 auto& num_imm = vnum_timm_i[region_idx];
119 auto age = (size_t)entry.age_group;
121 const int t_exposed =
122 static_cast<int>(std::round(params_region.template
get<TimeExposed<FP>>()[entry.age_group]));
123 int t_InfectedNoSymptoms =
124 static_cast<int>(std::round(params_region.template
get<TimeInfectedNoSymptoms<FP>>()[entry.age_group]));
125 int t_InfectedSymptoms =
126 static_cast<int>(std::round(params_region.template
get<TimeInfectedSymptoms<FP>>()[entry.age_group]));
127 const int t_InfectedSevere =
128 static_cast<int>(std::round(params_region.template
get<TimeInfectedSevere<FP>>()[entry.age_group]));
129 const int t_InfectedCritical =
130 static_cast<int>(std::round(params_region.template
get<TimeInfectedCritical<FP>>()[entry.age_group]));
131 const int t_imm_interval_i =
static_cast<int>(
132 std::round(params_region.template
get<TimeTemporaryImmunityPI<FP>>()[entry.age_group]));
135 FP recoveredPerInfectedNoSymptoms =
136 params_region.template get<RecoveredPerInfectedNoSymptoms<FP>>()[entry.age_group];
137 FP severePerInfectedSymptoms = params_region.template
get<SeverePerInfectedSymptoms<FP>>()[entry.age_group];
138 FP criticalPerSevere = params_region.template get<CriticalPerSevere<FP>>()[entry.age_group];
142 t_InfectedNoSymptoms =
static_cast<int>(std::round(
143 t_InfectedNoSymptoms * params_region.template
get<ReducTimeInfectedMild<FP>>()[entry.age_group]));
144 t_InfectedSymptoms =
static_cast<int>(std::round(
145 t_InfectedSymptoms * params_region.template
get<ReducTimeInfectedMild<FP>>()[entry.age_group]));
147 const FP red_fact_exp =
148 layer == 1 ? params_region.template get<ReducExposedPartialImmunity<FP>>()[entry.age_group]
149 : params_region.template
get<ReducExposedImprovedImmunity<FP>>()[entry.age_group];
151 const FP red_fact_inf =
153 ? params_region.template get<ReducInfectedSymptomsPartialImmunity<FP>>()[entry.age_group]
154 : params_region.template
get<ReducInfectedSymptomsImprovedImmunity<FP>>()[entry.age_group];
156 const FP red_fact_sev =
159 .template get<ReducInfectedSevereCriticalDeadPartialImmunity<FP>>()[entry.age_group]
161 .template
get<ReducInfectedSevereCriticalDeadImprovedImmunity<FP>>()[entry.age_group];
163 recoveredPerInfectedNoSymptoms = 1 - red_fact_inf / red_fact_exp * (1 - recoveredPerInfectedNoSymptoms);
164 severePerInfectedSymptoms = red_fact_sev / red_fact_inf * severePerInfectedSymptoms;
168 num_InfectedSymptoms[age] += scaling_factor_inf[age] * entry.num_confirmed;
169 num_imm[age] += entry.num_confirmed;
172 num_InfectedNoSymptoms[age] +=
173 1 / (1 - recoveredPerInfectedNoSymptoms) * scaling_factor_inf[age] * entry.num_confirmed;
175 1 / (1 - recoveredPerInfectedNoSymptoms) * scaling_factor_inf[age] * entry.num_confirmed;
178 num_InfectedNoSymptoms[age] -=
179 1 / (1 - recoveredPerInfectedNoSymptoms) * scaling_factor_inf[age] * entry.num_confirmed;
181 if (entry.date ==
offset_date_by_days(date, t_exposed + t_InfectedNoSymptoms + days_surplus)) {
183 1 / (1 - recoveredPerInfectedNoSymptoms) * scaling_factor_inf[age] * entry.num_confirmed;
186 num_InfectedSymptoms[age] -= scaling_factor_inf[age] * entry.num_confirmed;
187 num_InfectedSevere[age] += severePerInfectedSymptoms * scaling_factor_inf[age] * entry.num_confirmed;
190 num_InfectedSevere[age] -= severePerInfectedSymptoms * scaling_factor_inf[age] * entry.num_confirmed;
192 severePerInfectedSymptoms * criticalPerSevere * scaling_factor_inf[age] * entry.num_confirmed;
194 if (entry.date ==
offset_date_by_days(date, -t_InfectedSymptoms - t_InfectedSevere - t_InfectedCritical)) {
195 num_death[age] += entry.num_deaths;
197 severePerInfectedSymptoms * criticalPerSevere * scaling_factor_inf[age] * entry.num_confirmed;
200 num_imm[age] -= entry.num_confirmed;
205 for (
size_t region_idx = 0; region_idx < vregion.size(); ++region_idx) {
206 auto region = vregion[region_idx];
208 auto& num_InfectedNoSymptoms = vnum_InfectedNoSymptoms[region_idx];
209 auto& num_InfectedSymptoms = vnum_InfectedSymptoms[region_idx];
210 auto& num_Exposed = vnum_Exposed[region_idx];
211 auto& num_InfectedSevere = vnum_InfectedSevere[region_idx];
212 auto& num_death = vnum_death[region_idx];
213 auto& num_icu = vnum_icu[region_idx];
214 auto& num_timm_i = vnum_timm_i[region_idx];
216 size_t num_groups = ConfirmedCasesDataEntry::age_group_names.size();
217 for (
size_t i = 0;
i < num_groups;
i++) {
218 auto try_fix_constraints = [region,
i](FP&
value, FP error,
auto str) {
223 log_error(
"{:s} for age group {:s} is {:.4f} for region {:d}, "
224 "exceeds expected negative value.",
225 str, ConfirmedCasesDataEntry::age_group_names[
i],
value, region);
228 else if (
value < 0) {
229 log_info(
"{:s} for age group {:s} is {:.4f} for region {:d}, "
230 "automatically corrected",
231 str, ConfirmedCasesDataEntry::age_group_names[
i],
value, region);
236 const FP tol_error = -1e-8;
237 try_fix_constraints(num_InfectedSymptoms[
i], tol_error,
"InfectedSymptoms");
238 try_fix_constraints(num_InfectedNoSymptoms[
i], tol_error,
"InfectedNoSymptoms");
239 try_fix_constraints(num_Exposed[
i], tol_error,
"Exposed");
240 try_fix_constraints(num_InfectedSevere[
i], tol_error,
"InfectedSevere");
241 try_fix_constraints(num_death[
i], tol_error,
"Dead");
242 try_fix_constraints(num_icu[
i], tol_error,
"InfectedCritical");
243 try_fix_constraints(num_timm_i[
i], tol_error,
"Recently Recovered or Vaccinated");
275 template <
typename FP,
class Model>
276 IOResult<void> read_confirmed_cases_data(
277 std::string
const& path, std::vector<int>
const& vregion, Date date, std::vector<std::vector<FP>>& vnum_Exposed,
278 std::vector<std::vector<FP>>& vnum_InfectedNoSymptoms, std::vector<std::vector<FP>>& vnum_InfectedSymptoms,
279 std::vector<std::vector<FP>>& vnum_InfectedSevere, std::vector<std::vector<FP>>& vnum_icu,
280 std::vector<std::vector<FP>>& vnum_death, std::vector<std::vector<FP>>& vnum_timm_i,
281 const std::vector<Model>& model,
const std::vector<FP>& scaling_factor_inf,
const size_t layer)
283 BOOST_OUTCOME_TRY(
auto&& case_data, mio::read_confirmed_cases_data(path));
284 return compute_confirmed_cases_data(case_data, vnum_Exposed, vnum_InfectedNoSymptoms, vnum_InfectedSymptoms,
285 vnum_InfectedSevere, vnum_icu, vnum_death, vnum_timm_i, vregion, date, model,
286 scaling_factor_inf, layer);
307 template <
typename FP,
class Model>
309 set_confirmed_cases_data(std::vector<Model>& model,
const std::vector<ConfirmedCasesDataEntry>& case_data,
310 std::vector<int>
const& region, Date date,
const std::vector<FP>& scaling_factor_inf,
311 const std::vector<std::vector<FP>> immunity_population)
313 auto num_age_groups = (size_t)model[0].parameters.get_num_groups();
314 assert(scaling_factor_inf.size() == num_age_groups);
315 assert(ConfirmedCasesDataEntry::age_group_names.
size() == num_age_groups);
317 std::vector<std::vector<FP>> num_InfectedSymptoms(model.size());
318 std::vector<std::vector<FP>> num_death(model.size());
319 std::vector<std::vector<FP>> num_Exposed(model.size());
320 std::vector<std::vector<FP>> num_InfectedNoSymptoms(model.size());
321 std::vector<std::vector<FP>> num_InfectedSevere(model.size());
322 std::vector<std::vector<FP>> num_icu(model.size());
323 std::vector<std::vector<FP>> num_timm1(model.size());
324 std::vector<std::vector<FP>> num_timm2(model.size());
326 std::vector<FP> denom_E(num_age_groups, 0.0);
327 std::vector<FP> denom_I_NS(num_age_groups, 0.0);
328 std::vector<FP> denom_I_Sy(num_age_groups, 0.0);
329 std::vector<FP> denom_I_Sev_Cr(num_age_groups, 0.0);
332 for (
size_t county = 0; county < model.size(); county++) {
333 num_InfectedSymptoms[county] = std::vector<FP>(num_age_groups, 0.0);
334 num_death[county] = std::vector<FP>(num_age_groups, 0.0);
335 num_Exposed[county] = std::vector<FP>(num_age_groups, 0.0);
336 num_InfectedNoSymptoms[county] = std::vector<FP>(num_age_groups, 0.0);
337 num_InfectedSevere[county] = std::vector<FP>(num_age_groups, 0.0);
338 num_icu[county] = std::vector<FP>(num_age_groups, 0.0);
339 num_timm1[county] = std::vector<FP>(num_age_groups, 0.0);
340 num_timm2[county] = std::vector<FP>(num_age_groups, 0.0);
341 for (
size_t group = 0; group < num_age_groups; group++) {
344 1 / (immunity_population[0][group] +
345 immunity_population[1][group] *
346 model[county].parameters.template get<ReducExposedPartialImmunity<FP>>()[(AgeGroup)group] +
347 immunity_population[2][group] *
348 model[county].parameters.template get<ReducExposedImprovedImmunity<FP>>()[(AgeGroup)group]);
351 1 / (immunity_population[0][group] +
352 immunity_population[1][group] *
353 model[county].parameters.template get<ReducExposedPartialImmunity<FP>>()[(AgeGroup)group] +
354 immunity_population[2][group] *
355 model[county].parameters.template get<ReducExposedImprovedImmunity<FP>>()[(AgeGroup)group]);
358 1 / (immunity_population[0][group] +
359 immunity_population[1][group] *
361 .parameters.template get<ReducInfectedSymptomsPartialImmunity<FP>>()[(AgeGroup)group] +
362 immunity_population[2][group] *
364 .parameters.template get<ReducInfectedSymptomsImprovedImmunity<FP>>()[(AgeGroup)group]);
366 denom_I_Sev_Cr[group] =
367 1 / (immunity_population[0][group] +
368 immunity_population[1][group] *
369 model[county].parameters.template get<ReducInfectedSevereCriticalDeadPartialImmunity<FP>>()[(
371 immunity_population[2][group] *
372 model[county].parameters.template get<ReducInfectedSevereCriticalDeadImprovedImmunity<FP>>()[(
377 BOOST_OUTCOME_TRY(compute_confirmed_cases_data(case_data, num_Exposed, num_InfectedNoSymptoms, num_InfectedSymptoms,
378 num_InfectedSevere, num_icu, num_death, num_timm1, region, date,
379 model, scaling_factor_inf, 0));
381 for (
size_t county = 0; county < model.size(); county++) {
382 size_t num_groups = (size_t)model[county].parameters.get_num_groups();
383 for (
size_t i = 0;
i < num_groups;
i++) {
385 immunity_population[0][
i] * denom_E[
i] * num_Exposed[county][
i];
387 immunity_population[0][
i] * denom_I_NS[
i] * num_InfectedNoSymptoms[county][
i];
390 immunity_population[0][
i] * denom_I_Sy[
i] * num_InfectedSymptoms[county][
i];
393 immunity_population[0][
i] * denom_I_Sev_Cr[
i] * num_InfectedSevere[county][
i];
395 if (!is_divi_data_available(date)) {
397 immunity_population[0][
i] * denom_I_Sev_Cr[
i] * num_icu[county][
i];
400 if (std::accumulate(num_InfectedSymptoms[county].
begin(), num_InfectedSymptoms[county].
end(), FP(0.0),
401 [](
const FP& a,
const FP& b) {
402 return evaluate_intermediate<FP>(a + b);
405 "No infections for unvaccinated reported on date {} for region {}. Population data has not been set.",
406 date, region[county]);
411 for (
size_t county = 0; county < model.size(); county++) {
412 num_InfectedSymptoms[county] = std::vector<FP>(num_age_groups, 0.0);
413 num_death[county] = std::vector<FP>(num_age_groups, 0.0);
414 num_Exposed[county] = std::vector<FP>(num_age_groups, 0.0);
415 num_InfectedNoSymptoms[county] = std::vector<FP>(num_age_groups, 0.0);
416 num_InfectedSevere[county] = std::vector<FP>(num_age_groups, 0.0);
417 num_icu[county] = std::vector<FP>(num_age_groups, 0.0);
420 BOOST_OUTCOME_TRY(compute_confirmed_cases_data(case_data, num_Exposed, num_InfectedNoSymptoms, num_InfectedSymptoms,
421 num_InfectedSevere, num_icu, num_death, num_timm1, region, date,
422 model, scaling_factor_inf, 1));
424 for (
size_t county = 0; county < model.size(); county++) {
425 size_t num_groups = (size_t)model[county].parameters.get_num_groups();
426 for (
size_t i = 0;
i < num_groups;
i++) {
428 immunity_population[1][
i] *
429 model[county].parameters.template get<ReducExposedPartialImmunity<FP>>()[(AgeGroup)
i] * denom_E[
i] *
430 num_Exposed[county][
i];
432 immunity_population[1][
i] *
433 model[county].parameters.template get<ReducExposedPartialImmunity<FP>>()[(AgeGroup)
i] * denom_I_NS[
i] *
434 num_InfectedNoSymptoms[county][
i];
437 immunity_population[1][
i] *
438 model[county].parameters.template get<ReducInfectedSymptomsPartialImmunity<FP>>()[(AgeGroup)
i] *
439 denom_I_Sy[
i] * num_InfectedSymptoms[county][
i];
442 immunity_population[1][
i] *
444 .parameters.template get<ReducInfectedSevereCriticalDeadPartialImmunity<FP>>()[(AgeGroup)
i] *
445 denom_I_Sev_Cr[
i] * num_InfectedSevere[county][
i];
447 if (!is_divi_data_available(date)) {
449 immunity_population[1][
i] *
451 .parameters.template get<ReducInfectedSevereCriticalDeadPartialImmunity<FP>>()[(AgeGroup)
i] *
452 denom_I_Sev_Cr[
i] * num_icu[county][
i];
456 immunity_population[1][
i] *
457 model[county].parameters.template get<ReducExposedPartialImmunity<FP>>()[(AgeGroup)
i] * denom_E[
i] *
458 num_timm1[county][
i];
460 if (std::accumulate(num_InfectedSymptoms[county].
begin(), num_InfectedSymptoms[county].
end(), FP(0.0),
461 [](
const FP& a,
const FP& b) {
462 return evaluate_intermediate<FP>(a + b);
465 log_warning(
"No infections for partially vaccinated reported on date {} for region {}. "
466 "Population data has not been set.",
467 date, region[county]);
472 for (
size_t county = 0; county < model.size(); county++) {
473 num_InfectedSymptoms[county] = std::vector<FP>(num_age_groups, 0.0);
474 num_death[county] = std::vector<FP>(num_age_groups, 0.0);
475 num_Exposed[county] = std::vector<FP>(num_age_groups, 0.0);
476 num_InfectedNoSymptoms[county] = std::vector<FP>(num_age_groups, 0.0);
477 num_InfectedSevere[county] = std::vector<FP>(num_age_groups, 0.0);
478 num_icu[county] = std::vector<FP>(num_age_groups, 0.0);
481 BOOST_OUTCOME_TRY(compute_confirmed_cases_data(case_data, num_Exposed, num_InfectedNoSymptoms, num_InfectedSymptoms,
482 num_InfectedSevere, num_icu, num_death, num_timm2, region, date,
483 model, scaling_factor_inf, 2));
485 for (
size_t county = 0; county < model.size(); county++) {
486 size_t num_groups = (size_t)model[county].parameters.get_num_groups();
487 for (
size_t i = 0;
i < num_groups;
i++) {
489 immunity_population[2][
i] *
490 model[county].parameters.template get<ReducExposedImprovedImmunity<FP>>()[(AgeGroup)
i] * denom_E[
i] *
491 num_Exposed[county][
i];
493 immunity_population[2][
i] *
494 model[county].parameters.template get<ReducExposedImprovedImmunity<FP>>()[(AgeGroup)
i] * denom_I_NS[
i] *
495 num_InfectedNoSymptoms[county][
i];
498 immunity_population[2][
i] *
499 model[county].parameters.template get<ReducInfectedSymptomsImprovedImmunity<FP>>()[(AgeGroup)
i] *
500 denom_I_Sy[
i] * num_InfectedSymptoms[county][
i];
503 immunity_population[2][
i] *
505 .parameters.template get<ReducInfectedSevereCriticalDeadImprovedImmunity<FP>>()[(AgeGroup)
i] *
506 denom_I_Sev_Cr[
i] * num_InfectedSevere[county][
i];
508 if (!is_divi_data_available(date)) {
510 immunity_population[2][
i] *
512 .parameters.template get<ReducInfectedSevereCriticalDeadImprovedImmunity<FP>>()[(AgeGroup)
i] *
513 denom_I_Sev_Cr[
i] * num_icu[county][
i];
518 immunity_population[2][
i] *
519 model[county].parameters.template get<ReducExposedImprovedImmunity<FP>>()[(AgeGroup)
i] * denom_E[
i] *
520 num_timm2[county][
i];
522 if (std::accumulate(num_InfectedSymptoms[county].
begin(), num_InfectedSymptoms[county].
end(), FP(0.0),
523 [](
const FP& a,
const FP& b) {
524 return evaluate_intermediate<FP>(a + b);
526 log_warning(
"No infections for vaccinated reported on date {} for region {}. "
527 "Population data has not been set.",
528 date, region[county]);
553 template <
typename FP,
class Model>
554 IOResult<void> set_confirmed_cases_data(std::vector<Model>& model,
const std::string& path,
555 std::vector<int>
const& region, Date date,
556 const std::vector<FP>& scaling_factor_inf,
557 const std::vector<std::vector<FP>> immunity_population)
559 BOOST_OUTCOME_TRY(
auto&& case_data, mio::read_confirmed_cases_data(path));
561 set_confirmed_cases_data(model, case_data, region, date, scaling_factor_inf, immunity_population));
583 template <
typename FP,
class Model>
584 IOResult<void> set_divi_data(std::vector<Model>& model,
const std::string& path,
const std::vector<int>& vregion,
585 Date date, FP scaling_factor_icu)
588 if (!is_divi_data_available(date)) {
589 log_warning(
"No DIVI data available for date: {}. "
590 "ICU compartment will be set based on Case data.",
594 std::vector<FP> sum_mu_I_U(vregion.size(), 0);
595 std::vector<std::vector<FP>> mu_I_U{model.size()};
596 for (
size_t region = 0; region < vregion.size(); region++) {
597 auto num_groups = model[region].parameters.get_num_groups();
598 for (
auto i = AgeGroup(0);
i < num_groups;
i++) {
599 sum_mu_I_U[region] += model[region].parameters.template get<CriticalPerSevere<FP>>()[
i] *
600 model[region].parameters.template
get<SeverePerInfectedSymptoms<FP>>()[
i];
601 mu_I_U[region].push_back(model[region].parameters.template
get<CriticalPerSevere<FP>>()[
i] *
602 model[region].parameters.template get<SeverePerInfectedSymptoms<FP>>()[
i]);
605 std::vector<FP> num_icu(model.size(), 0.0);
606 BOOST_OUTCOME_TRY(read_divi_data(path, vregion, date, num_icu));
608 for (
size_t region = 0; region < vregion.size(); region++) {
609 auto num_groups = model[region].parameters.get_num_groups();
610 for (
auto i = AgeGroup(0);
i < num_groups;
i++) {
612 scaling_factor_icu * num_icu[region] * mu_I_U[region][(size_t)
i] / sum_mu_I_U[region];
633 template <
typename FP,
class Model>
634 IOResult<void> set_population_data(std::vector<Model>& model,
const std::vector<std::vector<FP>>& num_population,
635 const std::vector<int>& vregion,
636 const std::vector<std::vector<FP>> immunity_population)
638 for (
size_t region = 0; region < vregion.size(); region++) {
639 if (std::accumulate(num_population[region].
begin(), num_population[region].
end(), FP(0.0),
640 [](
const FP& a,
const FP& b) {
641 return evaluate_intermediate<FP>(a + b);
643 auto num_groups = model[region].parameters.get_num_groups();
644 for (
auto i = AgeGroup(0);
i < num_groups;
i++) {
646 FP SN = num_population[region][size_t(
i)] * immunity_population[0][size_t(
i)];
647 FP SPI = num_population[region][size_t(
i)] * immunity_population[1][size_t(
i)];
648 FP SII = num_population[region][size_t(
i)] - SN - SPI;
675 model[region].populations.template set_difference_from_group_total<AgeGroup>(
679 for (
auto i = AgeGroup(0);
i < AgeGroup(6);
i++) {
681 if (model[region].populations[{
i, j}] < 0) {
682 log_warning(
"Compartment at age group {}, infection state {}, is negative: {}",
size_t(
i),
683 size_t(j), model[region].populations[{
i, j}]);
689 log_warning(
"No population data available for region " + std::to_string(region) +
690 ". Population data has not been set.");
710 template <
class Model>
711 IOResult<void> set_population_data(std::vector<Model>& model,
const std::string& path,
const std::vector<int>& vregion,
712 const std::vector<std::vector<double>> immunity_population)
714 BOOST_OUTCOME_TRY(
auto&& num_population, mio::read_population_data(path, vregion));
715 BOOST_OUTCOME_TRY(set_population_data(model, num_population, vregion, immunity_population));
733 template <
typename FP>
734 IOResult<void> set_vaccination_data(std::vector<Model<FP>>& model,
const std::vector<VaccinationDataEntry>& vacc_data,
735 Date date,
const std::vector<int>& vregion,
int num_days)
737 auto num_groups = model[0].parameters.get_num_groups();
739 auto days_until_effective_n =
740 (int)(
double)model[0].parameters.template get<DaysUntilEffectivePartialVaccination<FP>>()[AgeGroup(0)];
741 auto days_until_effective_pi =
742 (int)(
double)model[0].parameters.template get<DaysUntilEffectiveImprovedVaccination<FP>>()[AgeGroup(0)];
743 auto days_until_effective_ii =
744 (int)(
double)model[0].parameters.template get<DaysUntilEffectiveBoosterImmunity<FP>>()[AgeGroup(0)];
746 for (
size_t i = 0;
i < model.size(); ++
i) {
748 for (
auto g = AgeGroup(0); g < num_groups; ++g) {
750 model[
i].parameters.template get<DailyPartialVaccinations<FP>>().resize(SimulationDay(num_days + 1));
751 model[
i].parameters.template get<DailyFullVaccinations<FP>>().resize(SimulationDay(num_days + 1));
752 model[
i].parameters.template get<DailyBoosterVaccinations<FP>>().resize(SimulationDay(num_days + 1));
753 for (
auto d = SimulationDay(0); d < SimulationDay(num_days + 1); ++d) {
754 model[
i].parameters.template get<DailyPartialVaccinations<FP>>()[{g, d}] = 0.0;
755 model[
i].parameters.template get<DailyFullVaccinations<FP>>()[{g, d}] = 0.0;
756 model[
i].parameters.template get<DailyBoosterVaccinations<FP>>()[{g, d}] = 0.0;
761 auto max_date_entry = std::max_element(vacc_data.begin(), vacc_data.end(), [](
auto&& a,
auto&& b) {
762 return a.date < b.date;
764 if (max_date_entry == vacc_data.end()) {
767 auto max_date = max_date_entry->date;
768 auto min_date_entry = std::min_element(vacc_data.begin(), vacc_data.end(), [](
auto&& a,
auto&& b) {
769 return a.date < b.date;
771 auto min_date = min_date_entry->date;
773 log_warning(
"Vaccination data only available from {} to {}. "
774 "For days before and after, vaccinations will be set to 0.",
778 for (
auto&& vacc_data_entry : vacc_data) {
779 auto it = std::find_if(vregion.begin(), vregion.end(), [&vacc_data_entry](
auto&& r) {
780 return r == 0 || (vacc_data_entry.county_id && vacc_data_entry.county_id == regions::CountyId(r)) ||
781 (vacc_data_entry.state_id && vacc_data_entry.state_id == regions::StateId(r)) ||
782 (vacc_data_entry.district_id && vacc_data_entry.district_id == regions::DistrictId(r));
784 auto date_df = vacc_data_entry.date;
785 if (it != vregion.end()) {
786 auto region_idx = size_t(it - vregion.begin());
787 AgeGroup age = vacc_data_entry.age_group;
790 for (
size_t d = 0; d < (size_t)num_days + 1; ++d) {
792 if (max_date >= offset_first_date) {
793 if (date_df == offset_first_date) {
795 .parameters.template get<DailyPartialVaccinations<FP>>()[{age, SimulationDay(d)}] =
796 vacc_data_entry.num_vaccinations_partial;
800 if (date_df == offset_first_date) {
802 .parameters.template get<DailyPartialVaccinations<FP>>()[{age, SimulationDay(d)}] = 0;
807 if (max_date >= offset_full_date) {
808 if (date_df == offset_full_date) {
810 .parameters.template get<DailyFullVaccinations<FP>>()[{age, SimulationDay(d)}] =
811 vacc_data_entry.num_vaccinations_completed;
815 if (date_df == offset_first_date) {
817 .parameters.template get<DailyFullVaccinations<FP>>()[{age, SimulationDay(d)}] = 0;
822 if (max_date >= offset_booster_date) {
823 if (date_df == offset_booster_date) {
825 .parameters.template get<DailyBoosterVaccinations<FP>>()[{age, SimulationDay(d)}] =
826 vacc_data_entry.num_vaccinations_refreshed_first +
827 vacc_data_entry.num_vaccinations_refreshed_additional;
831 if (date_df == offset_first_date) {
833 .parameters.template get<DailyBoosterVaccinations<FP>>()[{age, SimulationDay(d)}] = 0;
858 template <
typename FP>
859 IOResult<void> set_vaccination_data(std::vector<Model<FP>>& model,
const std::string& path, Date date,
860 const std::vector<int>& vregion,
int num_days)
864 if (!is_vaccination_data_available(date, end_date)) {
865 log_warning(
"No vaccination data available in range from {} to {}. "
866 "Vaccination data will be set to 0.",
869 for (
auto& m : model) {
870 m.parameters.template get<DailyPartialVaccinations<FP>>().resize(SimulationDay(num_days + 1));
871 m.parameters.template get<DailyFullVaccinations<FP>>().resize(SimulationDay(num_days + 1));
872 m.parameters.template get<DailyBoosterVaccinations<FP>>().resize(SimulationDay(num_days + 1));
873 for (
auto d = SimulationDay(0); d < SimulationDay(num_days + 1); ++d) {
874 for (
auto a = AgeGroup(0); a < m.parameters.get_num_groups(); ++a) {
875 m.parameters.template get<DailyPartialVaccinations<FP>>()[{a, d}] = 0.0;
876 m.parameters.template get<DailyFullVaccinations<FP>>()[{a, d}] = 0.0;
877 m.parameters.template get<DailyBoosterVaccinations<FP>>()[{a, d}] = 0.0;
883 BOOST_OUTCOME_TRY(
auto&& vacc_data, read_vaccination_data(path));
884 BOOST_OUTCOME_TRY(set_vaccination_data(model, vacc_data, date, vregion, num_days));
890 #ifdef MEMILIO_HAS_HDF5
916 template <
class Model>
917 IOResult<void> export_input_data_county_timeseries(
918 std::vector<Model> models,
const std::string& results_dir,
const std::vector<int>& counties, Date date,
919 const std::vector<double>& scaling_factor_inf,
const double scaling_factor_icu,
const int num_days,
920 const std::string& divi_data_path,
const std::string& confirmed_cases_path,
const std::string& population_data_path,
921 const std::vector<std::vector<double>> immunity_population,
const std::string& vaccination_data_path =
"")
923 const auto num_groups = (size_t)models[0].parameters.get_num_groups();
924 assert(scaling_factor_inf.size() == num_groups);
925 assert(num_groups == ConfirmedCasesDataEntry::age_group_names.
size());
926 assert(models.size() == counties.size());
927 std::vector<TimeSeries<double>> extrapolated_data(
930 BOOST_OUTCOME_TRY(
auto&& case_data, read_confirmed_cases_data(confirmed_cases_path));
931 BOOST_OUTCOME_TRY(
auto&& population_data, read_population_data(population_data_path, counties));
934 std::vector<VaccinationDataEntry> vacc_data;
935 if (!vaccination_data_path.empty()) {
936 BOOST_OUTCOME_TRY(vacc_data, read_vaccination_data(vaccination_data_path));
939 for (
int t = 0; t <= num_days; ++t) {
942 if (!vaccination_data_path.empty()) {
943 BOOST_OUTCOME_TRY(details::set_vaccination_data(models, vacc_data, offset_day, counties, num_days));
948 BOOST_OUTCOME_TRY(details::set_divi_data(models, divi_data_path, counties, offset_day, scaling_factor_icu));
950 BOOST_OUTCOME_TRY(details::set_confirmed_cases_data(models, case_data, counties, offset_day, scaling_factor_inf,
951 immunity_population));
953 BOOST_OUTCOME_TRY(details::set_population_data(models, population_data, counties, immunity_population));
955 for (
size_t r = 0; r < counties.size(); r++) {
956 extrapolated_data[r][t] = models[r].get_initial_values();
959 for (
size_t age = 0; age < num_groups; age++) {
966 BOOST_OUTCOME_TRY(save_result(extrapolated_data, counties,
static_cast<int>(num_groups),
967 path_join(results_dir,
"Results_rki.h5")));
969 auto extrapolated_rki_data_sum =
sum_nodes(std::vector<std::vector<TimeSeries<double>>>{extrapolated_data});
970 BOOST_OUTCOME_TRY(save_result({extrapolated_rki_data_sum[0][0]}, {0},
static_cast<int>(num_groups),
971 path_join(results_dir,
"Results_rki_sum.h5")));
977 template <
class Model>
978 IOResult<void> export_input_data_county_timeseries(std::vector<Model>,
const std::string&,
const std::vector<int>&,
979 Date,
const std::vector<double>&,
const double,
const int,
980 const std::string&,
const std::string&,
const std::string&,
981 const std::vector<std::vector<double>>,
const std::string&)
983 mio::log_warning(
"HDF5 not available. Cannot export time series of extrapolated real data.");
1010 template <
class Model>
1011 IOResult<void> read_input_data_county(std::vector<Model>& model, Date date,
const std::vector<int>& county,
1012 const std::vector<double>& scaling_factor_inf,
double scaling_factor_icu,
1013 const std::string& pydata_dir,
int num_days,
1014 const std::vector<std::vector<double>> immunity_population,
1015 bool export_time_series =
false)
1017 BOOST_OUTCOME_TRY(details::set_vaccination_data(model,
path_join(pydata_dir,
"vacc_county_ageinf_ma7.json"), date,
1023 details::set_divi_data(model,
path_join(pydata_dir,
"county_divi_ma7.json"), county, date, scaling_factor_icu));
1025 BOOST_OUTCOME_TRY(details::set_confirmed_cases_data(model,
path_join(pydata_dir,
"cases_all_county_age_ma7.json"),
1026 county, date, scaling_factor_inf, immunity_population));
1027 BOOST_OUTCOME_TRY(details::set_population_data(model,
path_join(pydata_dir,
"county_current_population.json"),
1028 county, immunity_population));
1030 if (export_time_series) {
1034 log_info(
"Exporting time series of extrapolated real data. This may take some minutes. "
1035 "For simulation runs over the same time period, deactivate it.");
1036 BOOST_OUTCOME_TRY(export_input_data_county_timeseries(
1037 model, pydata_dir, county, date, scaling_factor_inf, scaling_factor_icu, num_days,
1038 path_join(pydata_dir,
"county_divi_ma7.json"),
path_join(pydata_dir,
"cases_all_county_age_ma7.json"),
1039 path_join(pydata_dir,
"county_current_population.json"), immunity_population,
1040 path_join(pydata_dir,
"vacc_county_ageinf_ma7.json")));
1065 template <
class Model>
1066 IOResult<void> read_input_data(std::vector<Model>& model, Date date,
const std::vector<int>& node_ids,
1067 const std::vector<double>& scaling_factor_inf,
double scaling_factor_icu,
1068 const std::string& pydata_dir,
int num_days,
1069 const std::vector<std::vector<double>> immunity_population,
1070 bool export_time_series =
false)
1074 details::set_vaccination_data(model,
path_join(pydata_dir,
"vaccination_data.json"), date, node_ids, num_days));
1078 BOOST_OUTCOME_TRY(details::set_divi_data(model,
path_join(pydata_dir,
"critical_cases.json"), node_ids, date,
1079 scaling_factor_icu));
1081 BOOST_OUTCOME_TRY(details::set_confirmed_cases_data(model,
path_join(pydata_dir,
"confirmed_cases.json"), node_ids,
1082 date, scaling_factor_inf, immunity_population));
1083 BOOST_OUTCOME_TRY(details::set_population_data(model,
path_join(pydata_dir,
"population_data.json"), node_ids,
1084 immunity_population));
1086 if (export_time_series) {
1090 log_info(
"Exporting time series of extrapolated real data. This may take some minutes. "
1091 "For simulation runs over the same time period, deactivate it.");
1092 BOOST_OUTCOME_TRY(export_input_data_county_timeseries(
1093 model, pydata_dir, node_ids, date, scaling_factor_inf, scaling_factor_icu, num_days,
1094 path_join(pydata_dir,
"critical_cases.json"),
path_join(pydata_dir,
"confirmed_cases.json"),
1095 path_join(pydata_dir,
"population_data.json"), immunity_population,
1096 path_join(pydata_dir,
"vaccination_data.json")));
static TimeSeries zero(Eigen::Index num_time_points, Eigen::Index num_elements)
constructs TimeSeries instance and initializes it with zeros
Definition: time_series.h:152
static min_max_return_type< ad::internal::active_type< AD_TAPE_REAL, DATA_HANDLER_1 >, ad::internal::active_type< AD_TAPE_REAL, DATA_HANDLER_1 > >::type max(const ad::internal::active_type< AD_TAPE_REAL, DATA_HANDLER_1 > &a, const ad::internal::active_type< AD_TAPE_REAL, DATA_HANDLER_1 > &b)
Definition: ad.hpp:2596
trait_value< T >::RETURN_TYPE & value(T &x)
Definition: ad.hpp:3308
int size(Comm comm)
Return the size of the given communicator.
Definition: miompi.cpp:75
@ ExposedImprovedImmunity
@ InfectedNoSymptomsImprovedImmunityConfirmed
@ InfectedSeverePartialImmunity
@ InfectedNoSymptomsPartialImmunityConfirmed
@ InfectedNoSymptomsNaive
@ InfectedNoSymptomsImprovedImmunity
@ InfectedSevereImprovedImmunity
@ InfectedSymptomsPartialImmunityConfirmed
@ InfectedSymptomsPartialImmunity
@ InfectedNoSymptomsNaiveConfirmed
@ SusceptiblePartialImmunity
@ InfectedSymptomsImprovedImmunityConfirmed
@ InfectedCriticalPartialImmunity
@ InfectedNoSymptomsPartialImmunity
@ TemporaryImmuneImprovedImmunity
@ SusceptibleImprovedImmunity
@ InfectedCriticalImprovedImmunity
@ InfectedSymptomsImprovedImmunity
@ InfectedSymptomsNaiveConfirmed
@ TemporaryImmunePartialImmunity
A collection of classes to simplify handling of matrix shapes in meta programming.
Definition: models/abm/analyze_result.h:30
requires details::IsElementReference< M > RowMajorIterator< M, false > end(M &m)
create a non-const end iterator for the matrix m.
Definition: eigen_util.h:449
auto failure(const IOStatus &s)
Create an object that is implicitly convertible to an error IOResult<T>.
Definition: io.h:380
auto i
Definition: io.h:809
void log_warning(spdlog::string_view_t fmt, const Args &... args)
Definition: logging.h:112
auto success()
Create an object that is implicitly convertible to a succesful IOResult<void>.
Definition: io.h:359
int get_offset_in_days(Date date1, Date date2)
Computes the offset in days given two dates: first date minus second date.
Definition: date.h:310
void log_error(spdlog::string_view_t fmt, const Args &... args)
Definition: logging.h:100
requires details::IsElementReference< M > RowMajorIterator< M, false > begin(M &m)
create a non-const iterator to first element of the matrix m.
Definition: eigen_util.h:421
Date offset_date_by_days(Date date, int offset_days)
Computes the new date corresponding to a given date and a offset in days.
Definition: date.h:242
std::string path_join(String &&base, Strings &&... app)
join one ore more strings with path separators.
Definition: stl_util.h:268
constexpr std::tuple_element< I, std::tuple< Index< CategoryTags >... > >::type & get(Index< CategoryTags... > &i) noexcept
Retrieves the Index (by reference) at the Ith position of a MultiIndex.
Definition: index.h:294
std::vector< std::vector< TimeSeries< FP > > > sum_nodes(const std::vector< std::vector< TimeSeries< FP >>> &ensemble_result)
Definition: memilio/data/analyze_result.h:268
void log_info(spdlog::string_view_t fmt, const Args &... args)
Definition: logging.h:94