Line data Source code
1 : /*
2 : * Copyright (C) 2020-2024 MEmilio
3 : *
4 : * Authors: Wadim Koslow, Daniel Abele, Martin J. Kuehn, Lena Ploetzke
5 : *
6 : * Contact: Martin J. Kuehn <Martin.Kuehn@DLR.de>
7 : *
8 : * Licensed under the Apache License, Version 2.0 (the "License");
9 : * you may not use this file except in compliance with the License.
10 : * You may obtain a copy of the License at
11 : *
12 : * http://www.apache.org/licenses/LICENSE-2.0
13 : *
14 : * Unless required by applicable law or agreed to in writing, software
15 : * distributed under the License is distributed on an "AS IS" BASIS,
16 : * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17 : * See the License for the specific language governing permissions and
18 : * limitations under the License.
19 : */
20 : #ifndef ODESECIR_PARAMETERS_IO_H
21 : #define ODESECIR_PARAMETERS_IO_H
22 :
23 : #include "memilio/config.h"
24 : #include <cassert>
25 :
26 : #ifdef MEMILIO_HAS_JSONCPP
27 :
28 : #include "ode_secir/model.h"
29 : #include "memilio/io/epi_data.h"
30 : #include "memilio/io/result_io.h"
31 :
32 : namespace mio
33 : {
34 :
35 : namespace osecir
36 : {
37 :
38 : namespace details
39 : {
40 : /**
41 : * @brief reads populations data from RKI.
42 : * @param[in] rki_data Vector of ConfirmedCasesDataEntry%s.
43 : * @param[in] vregion Vector of keys of the region of interest.
44 : * @param[in] date Date at which the data is read.
45 : * @param[in, out] vnum_* Output vector for number of people in the corresponding compartement.
46 : * @param[in] vt_* vector Average time it takes to get from one compartement to another for each age group.
47 : * @param[in] vmu_* vector Probabilities to get from one compartement to another for each age group.
48 : * @param[in] scaling_factor_inf Factors by which to scale the confirmed cases of rki data.
49 : */
50 : IOResult<void> read_confirmed_cases_data(
51 : std::vector<ConfirmedCasesDataEntry>& rki_data, std::vector<int> const& vregion, Date date,
52 : std::vector<std::vector<double>>& vnum_Exposed, std::vector<std::vector<double>>& vnum_InfectedNoSymptoms,
53 : std::vector<std::vector<double>>& vnum_InfectedSymptoms, std::vector<std::vector<double>>& vnum_InfectedSevere,
54 : std::vector<std::vector<double>>& vnum_icu, std::vector<std::vector<double>>& vnum_death,
55 : std::vector<std::vector<double>>& vnum_rec, const std::vector<std::vector<int>>& vt_Exposed,
56 : const std::vector<std::vector<int>>& vt_InfectedNoSymptoms,
57 : const std::vector<std::vector<int>>& vt_InfectedSymptoms, const std::vector<std::vector<int>>& vt_InfectedSevere,
58 : const std::vector<std::vector<int>>& vt_InfectedCritical, const std::vector<std::vector<double>>& vmu_C_R,
59 : const std::vector<std::vector<double>>& vmu_I_H, const std::vector<std::vector<double>>& vmu_H_U,
60 : const std::vector<double>& scaling_factor_inf);
61 :
62 : /**
63 : * @brief Sets populations data from already read case data with multiple age groups into a Model with one age group.
64 : * @tparam FP Floating point data type, e.g., double.
65 : * @param[in, out] model Vector of models in which the data is set.
66 : * @param[in] case_data List of confirmed cases data entries.
67 : * @param[in] region Vector of keys of the region of interest.
68 : * @param[in] date Date at which the data is read.
69 : * @param[in] scaling_factor_inf Factors by which to scale the confirmed cases of rki data.
70 : */
71 : template <typename FP = double>
72 88 : IOResult<void> set_confirmed_cases_data(std::vector<Model<FP>>& model, std::vector<ConfirmedCasesDataEntry>& case_data,
73 : const std::vector<int>& region, Date date,
74 : const std::vector<double>& scaling_factor_inf)
75 : {
76 88 : const size_t num_age_groups = ConfirmedCasesDataEntry::age_group_names.size();
77 88 : assert(scaling_factor_inf.size() == num_age_groups);
78 :
79 176 : std::vector<std::vector<int>> t_InfectedNoSymptoms{model.size()};
80 176 : std::vector<std::vector<int>> t_Exposed{model.size()};
81 176 : std::vector<std::vector<int>> t_InfectedSymptoms{model.size()};
82 176 : std::vector<std::vector<int>> t_InfectedSevere{model.size()};
83 176 : std::vector<std::vector<int>> t_InfectedCritical{model.size()};
84 :
85 176 : std::vector<std::vector<double>> mu_C_R{model.size()};
86 176 : std::vector<std::vector<double>> mu_I_H{model.size()};
87 176 : std::vector<std::vector<double>> mu_H_U{model.size()};
88 176 : std::vector<std::vector<double>> mu_U_D{model.size()};
89 :
90 176 : for (size_t node = 0; node < model.size(); ++node) {
91 616 : for (size_t group = 0; group < num_age_groups; group++) {
92 :
93 1056 : t_Exposed[node].push_back(
94 1056 : static_cast<int>(std::round(model[node].parameters.template get<TimeExposed<FP>>()[(AgeGroup)group])));
95 1056 : t_InfectedNoSymptoms[node].push_back(static_cast<int>(
96 1056 : std::round(model[node].parameters.template get<TimeInfectedNoSymptoms<FP>>()[(AgeGroup)group])));
97 1056 : t_InfectedSymptoms[node].push_back(static_cast<int>(
98 1056 : std::round(model[node].parameters.template get<TimeInfectedSymptoms<FP>>()[(AgeGroup)group])));
99 1056 : t_InfectedSevere[node].push_back(static_cast<int>(
100 1056 : std::round(model[node].parameters.template get<TimeInfectedSevere<FP>>()[(AgeGroup)group])));
101 1056 : t_InfectedCritical[node].push_back(static_cast<int>(
102 1056 : std::round(model[node].parameters.template get<TimeInfectedCritical<FP>>()[(AgeGroup)group])));
103 :
104 1056 : mu_C_R[node].push_back(
105 1056 : model[node].parameters.template get<RecoveredPerInfectedNoSymptoms<FP>>()[(AgeGroup)group]);
106 1056 : mu_I_H[node].push_back(
107 1056 : model[node].parameters.template get<SeverePerInfectedSymptoms<FP>>()[(AgeGroup)group]);
108 528 : mu_H_U[node].push_back(model[node].parameters.template get<CriticalPerSevere<FP>>()[(AgeGroup)group]);
109 528 : mu_U_D[node].push_back(model[node].parameters.template get<DeathsPerCritical<FP>>()[(AgeGroup)group]);
110 : }
111 : }
112 352 : std::vector<std::vector<double>> num_InfectedSymptoms(model.size(), std::vector<double>(num_age_groups, 0.0));
113 352 : std::vector<std::vector<double>> num_death(model.size(), std::vector<double>(num_age_groups, 0.0));
114 352 : std::vector<std::vector<double>> num_rec(model.size(), std::vector<double>(num_age_groups, 0.0));
115 352 : std::vector<std::vector<double>> num_Exposed(model.size(), std::vector<double>(num_age_groups, 0.0));
116 352 : std::vector<std::vector<double>> num_InfectedNoSymptoms(model.size(), std::vector<double>(num_age_groups, 0.0));
117 352 : std::vector<std::vector<double>> num_InfectedSevere(model.size(), std::vector<double>(num_age_groups, 0.0));
118 352 : std::vector<std::vector<double>> num_icu(model.size(), std::vector<double>(num_age_groups, 0.0));
119 :
120 88 : BOOST_OUTCOME_TRY(read_confirmed_cases_data(case_data, region, date, num_Exposed, num_InfectedNoSymptoms,
121 : num_InfectedSymptoms, num_InfectedSevere, num_icu, num_death, num_rec,
122 : t_Exposed, t_InfectedNoSymptoms, t_InfectedSymptoms, t_InfectedSevere,
123 : t_InfectedCritical, mu_C_R, mu_I_H, mu_H_U, scaling_factor_inf));
124 :
125 176 : for (size_t node = 0; node < model.size(); node++) {
126 88 : if (std::accumulate(num_InfectedSymptoms[node].begin(), num_InfectedSymptoms[node].end(), 0.0) > 0) {
127 70 : size_t num_groups = (size_t)model[node].parameters.get_num_groups();
128 490 : for (size_t i = 0; i < num_groups; i++) {
129 420 : model[node].populations[{AgeGroup(i), InfectionState::Exposed}] = num_Exposed[node][i];
130 420 : model[node].populations[{AgeGroup(i), InfectionState::InfectedNoSymptoms}] =
131 : num_InfectedNoSymptoms[node][i];
132 420 : model[node].populations[{AgeGroup(i), InfectionState::InfectedNoSymptomsConfirmed}] = 0;
133 420 : model[node].populations[{AgeGroup(i), InfectionState::InfectedSymptoms}] =
134 : num_InfectedSymptoms[node][i];
135 420 : model[node].populations[{AgeGroup(i), InfectionState::InfectedSymptomsConfirmed}] = 0;
136 420 : model[node].populations[{AgeGroup(i), InfectionState::InfectedSevere}] = num_InfectedSevere[node][i];
137 420 : model[node].populations[{AgeGroup(i), InfectionState::Dead}] = num_death[node][i];
138 420 : model[node].populations[{AgeGroup(i), InfectionState::Recovered}] = num_rec[node][i];
139 : }
140 : }
141 : else {
142 36 : log_warning("No infections reported on date " + std::to_string(date.year) + "-" +
143 : std::to_string(date.month) + "-" + std::to_string(date.day) + " for region " +
144 18 : std::to_string(region[node]) + ". Population data has not been set.");
145 : }
146 : }
147 176 : return success();
148 88 : }
149 :
150 : /**
151 : * @brief Sets the infected population for a given model based on confirmed cases data. Here, we
152 : * read the case data from a file.
153 : * @tparam FP Floating point data type, e.g., double.
154 : * @param[in, out] Vector of models for which the confirmed cases data will be set.
155 : * @param[in] path Path to the confirmed cases data file.
156 : * @param[in] region Vector of keys of the region of interest.
157 : * @param[in] date Date at which the data is read.
158 : * @param[in] scaling_factor_inf Factors by which to scale the confirmed cases of rki data.
159 : */
160 : template <typename FP = double>
161 50 : IOResult<void> set_confirmed_cases_data(std::vector<Model<FP>>& model, const std::string& path,
162 : std::vector<int> const& region, Date date,
163 : const std::vector<double>& scaling_factor_inf)
164 : {
165 50 : BOOST_OUTCOME_TRY(auto&& case_data, mio::read_confirmed_cases_data(path));
166 50 : BOOST_OUTCOME_TRY(set_confirmed_cases_data(model, case_data, region, date, scaling_factor_inf));
167 100 : return success();
168 50 : }
169 :
170 : /**
171 : * @brief Reads number of ICU patients from DIVI register into Parameters.
172 : * @param[in] path Path to DIVI file.
173 : * @param[in] vregion Keys of the region of interest.
174 : * @param date Date for which we initialize.
175 : * @param vnum_icu Number of ICU patients.
176 : */
177 : IOResult<void> read_divi_data(const std::string& path, const std::vector<int>& vregion, Date date,
178 : std::vector<double>& vnum_icu);
179 :
180 : /**
181 : * @brief Sets populations data from DIVI register into Model.
182 : * @tparam FP floating point data type, e.g., double.
183 : * @param[in, out] model Vector of models in which the data is set.
184 : * @param[in] path Path to DIVI file.
185 : * @param[in] vregion Vector of keys of the regions of interest.
186 : * @param[in] date Date for which the arrays are initialized.
187 : * @param[in] scaling_factor_icu factor by which to scale the icu cases of divi data.
188 : */
189 : template <typename FP = double>
190 70 : IOResult<void> set_divi_data(std::vector<Model<FP>>& model, const std::string& path, const std::vector<int>& vregion,
191 : Date date, double scaling_factor_icu)
192 : {
193 140 : std::vector<double> sum_mu_I_U(vregion.size(), 0);
194 140 : std::vector<std::vector<double>> mu_I_U{model.size()};
195 140 : for (size_t region = 0; region < vregion.size(); region++) {
196 70 : auto num_groups = model[region].parameters.get_num_groups();
197 490 : for (auto i = AgeGroup(0); i < num_groups; i++) {
198 840 : sum_mu_I_U[region] += model[region].parameters.template get<CriticalPerSevere<FP>>()[i] *
199 420 : model[region].parameters.template get<SeverePerInfectedSymptoms<FP>>()[i];
200 840 : mu_I_U[region].push_back(model[region].parameters.template get<CriticalPerSevere<FP>>()[i] *
201 420 : model[region].parameters.template get<SeverePerInfectedSymptoms<FP>>()[i]);
202 : }
203 : }
204 140 : std::vector<double> num_icu(model.size(), 0.0);
205 70 : BOOST_OUTCOME_TRY(read_divi_data(path, vregion, date, num_icu));
206 :
207 140 : for (size_t region = 0; region < vregion.size(); region++) {
208 70 : auto num_groups = model[region].parameters.get_num_groups();
209 490 : for (auto i = AgeGroup(0); i < num_groups; i++) {
210 420 : model[region].populations[{i, InfectionState::InfectedCritical}] =
211 420 : scaling_factor_icu * num_icu[region] * mu_I_U[region][(size_t)i] / sum_mu_I_U[region];
212 : }
213 : }
214 :
215 140 : return success();
216 70 : }
217 :
218 : /**
219 : * @brief Reads population data from census data.
220 : * @tparam FP floating point data type, e.g., double.
221 : * @param[in] path Path to RKI file.
222 : * @param[in] vregion Vector of keys of the regions of interest.
223 : * @param[in] accumulate_age_groups Specifies whether population data should be accumulated to one age group.
224 : */
225 : IOResult<std::vector<std::vector<double>>>
226 : read_population_data(const std::string& path, const std::vector<int>& vregion, bool accumulate_age_groups = false);
227 :
228 : /**
229 : * @brief Sets population data from census data which has been read into num_population.
230 : * @tparam FP floating point data type, e.g., double.
231 : * @param[in, out] model Vector of models in which the data is set. There should be one model per region.
232 : * @param[in] num_population Vector of population data. The size should be the same as vregion and model.
233 : * @param[in] vregion Vector of keys of the regions of interest.
234 : */
235 : template <typename FP = double>
236 88 : IOResult<void> set_population_data(std::vector<Model<FP>>& model,
237 : const std::vector<std::vector<double>>& num_population,
238 : const std::vector<int>& vregion)
239 : {
240 88 : assert(num_population.size() == vregion.size());
241 88 : assert(model.size() == vregion.size());
242 176 : for (size_t region = 0; region < vregion.size(); region++) {
243 88 : auto num_groups = model[region].parameters.get_num_groups();
244 616 : for (auto i = AgeGroup(0); i < num_groups; i++) {
245 528 : model[region].populations.template set_difference_from_group_total<AgeGroup>(
246 : {i, InfectionState::Susceptible}, num_population[region][size_t(i)]);
247 : }
248 : }
249 176 : return success();
250 : }
251 :
252 : /**
253 : * @brief Sets population data from census data into a Model.
254 : * @tparam FP Floating point data type, e.g., double.
255 : * @param[in, out] model Vector of models in which the data is set.
256 : * @param[in] path Path to RKI file containing population data.
257 : * @param[in] vregion Vector of keys of the regions of interest.
258 : */
259 : template <typename FP = double>
260 50 : IOResult<void> set_population_data(std::vector<Model<FP>>& model, const std::string& path,
261 : const std::vector<int>& vregion)
262 : {
263 : // Specifies whether population data should be accumulated to one age group.
264 50 : const bool is_single_age_group = static_cast<size_t>(model[0].parameters.get_num_groups()) == 1;
265 50 : BOOST_OUTCOME_TRY(const auto&& num_population, read_population_data(path, vregion, is_single_age_group));
266 50 : BOOST_OUTCOME_TRY(set_population_data(model, num_population, vregion));
267 100 : return success();
268 50 : }
269 :
270 : } //namespace details
271 :
272 : #ifdef MEMILIO_HAS_HDF5
273 :
274 : /**
275 : * @brief Uses the initialisation method, which uses the reported data to set the initial conditions for the model for a given day.
276 : * The initialisation is applied for a predefined number of days and finally saved in a timeseries for each region. In the end,
277 : * we save the files "Results_rki.h5" and "Results_rki_sum.h5" in the results_dir.
278 : * Results_rki.h5 contains a time series for each region and Results_rki_sum.h5 contains the sum of all regions.
279 : * @param[in] models Vector of models in which the data is set. Copy is made to avoid changing the original model.
280 : * @param[in] results_dir Path to result files.
281 : * @param[in] region Vector of keys of the region of interest.
282 : * @param[in] date Date for which the data should be read.
283 : * @param[in] scaling_factor_inf Factors by which to scale the confirmed cases of rki data.
284 : * @param[in] scaling_factor_icu Factor by which to scale the icu cases of divi data.
285 : * @param[in] num_days Number of days to be simulated/initialized.
286 : * @param[in] divi_data_path Path to DIVI file.
287 : * @param[in] confirmed_cases_path Path to confirmed cases file.
288 : * @param[in] population_data_path Path to population data file.
289 : */
290 : template <class Model>
291 19 : IOResult<void> export_input_data_county_timeseries(
292 : std::vector<Model> models, const std::string& results_dir, std::vector<int> const& region, Date date,
293 : const std::vector<double>& scaling_factor_inf, double scaling_factor_icu, int num_days,
294 : const std::string& divi_data_path, const std::string& confirmed_cases_path, const std::string& population_data_path)
295 : {
296 19 : const auto num_age_groups = (size_t)models[0].parameters.get_num_groups();
297 19 : assert(scaling_factor_inf.size() == num_age_groups);
298 19 : assert(num_age_groups == ConfirmedCasesDataEntry::age_group_names.size());
299 19 : assert(models.size() == region.size());
300 95 : std::vector<TimeSeries<double>> extrapolated_data(
301 38 : region.size(), TimeSeries<double>::zero(num_days + 1, (size_t)InfectionState::Count * num_age_groups));
302 :
303 19 : BOOST_OUTCOME_TRY(auto&& num_population, details::read_population_data(population_data_path, region));
304 19 : BOOST_OUTCOME_TRY(auto&& case_data, mio::read_confirmed_cases_data(confirmed_cases_path));
305 :
306 95 : for (int t = 0; t <= num_days; ++t) {
307 38 : auto offset_day = offset_date_by_days(date, t);
308 :
309 38 : if (offset_day > Date(2020, 4, 23)) {
310 29 : BOOST_OUTCOME_TRY(details::set_divi_data(models, divi_data_path, region, offset_day, scaling_factor_icu));
311 29 : }
312 : else {
313 18 : log_warning("No DIVI data available for date: {}-{}-{}", offset_day.day, offset_day.month, offset_day.year);
314 : }
315 :
316 38 : BOOST_OUTCOME_TRY(details::set_confirmed_cases_data(models, case_data, region, offset_day, scaling_factor_inf));
317 38 : BOOST_OUTCOME_TRY(details::set_population_data(models, num_population, region));
318 76 : for (size_t r = 0; r < region.size(); r++) {
319 38 : extrapolated_data[r][t] = models[r].get_initial_values();
320 : }
321 : }
322 :
323 38 : BOOST_OUTCOME_TRY(
324 : save_result(extrapolated_data, region, (int)num_age_groups, path_join(results_dir, "Results_rki.h5")));
325 :
326 95 : auto rki_data_sum = sum_nodes(std::vector<std::vector<TimeSeries<double>>>{extrapolated_data});
327 152 : BOOST_OUTCOME_TRY(
328 : save_result({rki_data_sum[0][0]}, {0}, (int)num_age_groups, path_join(results_dir, "Results_rki_sum.h5")));
329 :
330 38 : return success();
331 19 : }
332 : #else
333 : template <class Model>
334 : IOResult<void>
335 : export_input_data_county_timeseries(std::vector<Model> models, const std::string& dir, std::vector<int> const& region,
336 : Date date, const std::vector<double>& scaling_factor_inf, double scaling_factor_icu,
337 : int num_days, const std::string& divi_data_path,
338 : const std::string& confirmed_cases_path, const std::string& population_data_path)
339 : {
340 : mio::log_warning("HDF5 not available. Cannot export time series of extrapolated real data.");
341 : return success();
342 : }
343 : #endif // MEMILIO_HAS_HDF5
344 :
345 : /**
346 : * @brief Reads population data from population files for the whole country.
347 : * @param[in, out] model Vector of model in which the data is set.
348 : * @param[in] date Date for which the data should be read.
349 : * @param[in] scaling_factor_inf Factors by which to scale the confirmed cases of rki data.
350 : * @param[in] scaling_factor_icu Factor by which to scale the icu cases of divi data.
351 : * @param[in] dir Directory of files.
352 : */
353 : template <class Model>
354 1 : IOResult<void> read_input_data_germany(std::vector<Model>& model, Date date,
355 : const std::vector<double>& scaling_factor_inf, double scaling_factor_icu,
356 : const std::string& dir)
357 : {
358 1 : if (date > Date(2020, 4, 23)) {
359 4 : BOOST_OUTCOME_TRY(
360 : details::set_divi_data(model, path_join(dir, "germany_divi.json"), {0}, date, scaling_factor_icu));
361 1 : }
362 : else {
363 0 : log_warning("No DIVI data available for this date");
364 : }
365 4 : BOOST_OUTCOME_TRY(details::set_confirmed_cases_data(model, path_join(dir, "cases_all_age_ma7.json"), {0}, date,
366 : scaling_factor_inf));
367 4 : BOOST_OUTCOME_TRY(details::set_population_data(model, path_join(dir, "county_current_population.json"), {0}));
368 2 : return success();
369 1 : }
370 :
371 : /**
372 : * @brief Reads population data from population files for the specefied state.
373 : * @param[in, out] model Vector of model in which the data is set.
374 : * @param[in] date Date for which the data should be read.
375 : * @param[in] state Vector of region keys of states of interest.
376 : * @param[in] scaling_factor_inf Factors by which to scale the confirmed cases of rki data.
377 : * @param[in] scaling_factor_icu Factor by which to scale the icu cases of divi data.
378 : * @param[in] dir Directory of files.
379 : */
380 : template <class Model>
381 1 : IOResult<void> read_input_data_state(std::vector<Model>& model, Date date, std::vector<int>& state,
382 : const std::vector<double>& scaling_factor_inf, double scaling_factor_icu,
383 : const std::string& dir)
384 : {
385 1 : if (date > Date(2020, 4, 23)) {
386 2 : BOOST_OUTCOME_TRY(
387 : details::set_divi_data(model, path_join(dir, "state_divi.json"), state, date, scaling_factor_icu));
388 1 : }
389 : else {
390 0 : log_warning("No DIVI data available for this date");
391 : }
392 :
393 2 : BOOST_OUTCOME_TRY(details::set_confirmed_cases_data(model, path_join(dir, "cases_all_state_age_ma7.json"), state,
394 : date, scaling_factor_inf));
395 2 : BOOST_OUTCOME_TRY(details::set_population_data(model, path_join(dir, "county_current_population.json"), state));
396 2 : return success();
397 1 : }
398 :
399 : /**
400 : * @brief Reads population data from population files for the specefied county.
401 : * @param[in, out] model Vector of model in which the data is set.
402 : * @param[in] date Date for which the data should be read.
403 : * @param[in] county Vector of region keys of counties of interest.
404 : * @param[in] scaling_factor_inf Factors by which to scale the confirmed cases of rki data.
405 : * @param[in] scaling_factor_icu Factor by which to scale the icu cases of divi data.
406 : * @param[in] dir Directory of files.
407 : * @param[in] num_days [Default: 0] Number of days to be simulated; required to extrapolate real data.
408 : * @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.
409 : */
410 : template <class Model>
411 28 : IOResult<void> read_input_data_county(std::vector<Model>& model, Date date, const std::vector<int>& county,
412 : const std::vector<double>& scaling_factor_inf, double scaling_factor_icu,
413 : const std::string& dir, int num_days = 0, bool export_time_series = false)
414 : {
415 28 : if (date > Date(2020, 4, 23)) {
416 38 : BOOST_OUTCOME_TRY(details::set_divi_data(model, path_join(dir, "pydata/Germany", "county_divi_ma7.json"),
417 : county, date, scaling_factor_icu));
418 19 : }
419 : else {
420 18 : log_warning("No DIVI data available for this date");
421 : }
422 56 : BOOST_OUTCOME_TRY(details::set_confirmed_cases_data(
423 : model, path_join(dir, "pydata/Germany", "cases_all_county_age_ma7.json"), county, date, scaling_factor_inf));
424 56 : BOOST_OUTCOME_TRY(details::set_population_data(
425 : model, path_join(dir, "pydata/Germany", "county_current_population.json"), county));
426 :
427 28 : if (export_time_series) {
428 : // Use only if extrapolated real data is needed for comparison. EXPENSIVE !
429 : // Run time equals run time of the previous functions times the num_days !
430 : // (This only represents the vectorization of the previous function over all simulation days...)
431 0 : log_warning("Exporting time series of extrapolated real data. This may take some minutes. "
432 : "For simulation runs over the same time period, deactivate it.");
433 0 : BOOST_OUTCOME_TRY(
434 : export_input_data_county_timeseries(model, dir, county, date, scaling_factor_inf, scaling_factor_icu,
435 : num_days, path_join(dir, "pydata/Germany", "county_divi_ma7.json"),
436 : path_join(dir, "pydata/Germany", "cases_all_county_age_ma7.json"),
437 : path_join(dir, "pydata/Germany", "county_current_population.json")));
438 0 : }
439 56 : return success();
440 28 : }
441 :
442 : /**
443 : * @brief reads population data from population files for the specified nodes
444 : * @param[in, out] model vector of model in which the data is set
445 : * @param[in] date Date for which the data should be read
446 : * @param[in] county vector of region keys of interest
447 : * @param[in] scaling_factor_inf factors by which to scale the confirmed cases of rki data
448 : * @param[in] scaling_factor_icu factor by which to scale the icu cases of divi data
449 : * @param[in] dir directory of files
450 : * @param[in] age_group_names strings specifying age group names
451 : */
452 : template <class Model>
453 20 : IOResult<void> read_input_data(std::vector<Model>& model, Date date, const std::vector<int>& node_ids,
454 : const std::vector<double>& scaling_factor_inf, double scaling_factor_icu,
455 : const std::string& data_dir, int num_days = 0, bool export_time_series = false)
456 : {
457 20 : if (date > Date(2020, 4, 23)) {
458 40 : BOOST_OUTCOME_TRY(details::set_divi_data(model, path_join(data_dir, "critical_cases.json"), node_ids, date,
459 : scaling_factor_icu));
460 20 : }
461 : else {
462 0 : log_warning("No DIVI data available for this date");
463 : }
464 40 : BOOST_OUTCOME_TRY(details::set_confirmed_cases_data(model, path_join(data_dir, "confirmed_cases.json"), node_ids,
465 : date, scaling_factor_inf));
466 40 : BOOST_OUTCOME_TRY(details::set_population_data(model, path_join(data_dir, "population_data.json"), node_ids));
467 :
468 20 : if (export_time_series) {
469 : // Use only if extrapolated real data is needed for comparison. EXPENSIVE !
470 : // Run time equals run time of the previous functions times the num_days !
471 : // (This only represents the vectorization of the previous function over all simulation days...)
472 0 : log_warning("Exporting time series of extrapolated real data. This may take some minutes. "
473 : "For simulation runs over the same time period, deactivate it.");
474 0 : BOOST_OUTCOME_TRY(export_input_data_county_timeseries(
475 : model, data_dir, node_ids, date, scaling_factor_inf, scaling_factor_icu, num_days,
476 : path_join(data_dir, "critical_cases.json"), path_join(data_dir, "confirmed_cases.json"),
477 : path_join(data_dir, "population_data.json")));
478 0 : }
479 40 : return success();
480 20 : }
481 :
482 : } // namespace osecir
483 : } // namespace mio
484 :
485 : #endif // MEMILIO_HAS_JSONCPP
486 :
487 : #endif // ODESECIR_PARAMETERS_IO_H
|