Line data Source code
1 : /*
2 : * Copyright (C) 2020-2024 MEmilio
3 : *
4 : * Authors: Daniel Abele, Khoa Nguyen
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 ABM_ANALYZE_RESULT_H
21 : #define ABM_ANALYZE_RESULT_H
22 :
23 : #include "abm/parameters.h"
24 :
25 : #include <vector>
26 :
27 : namespace mio
28 : {
29 : namespace abm
30 : {
31 : /**
32 : * @brief computes the p percentile of the parameters for each node.
33 : * @param ensemble_result graph of multiple simulation runs
34 : * @param p percentile value in open interval (0, 1)
35 : * @return p percentile of the parameters over all runs
36 : */
37 : template <class Model>
38 14 : std::vector<Model> ensemble_params_percentile(const std::vector<std::vector<Model>>& ensemble_params, double p)
39 : {
40 14 : assert(p > 0.0 && p < 1.0 && "Invalid percentile value.");
41 :
42 14 : auto num_runs = ensemble_params.size();
43 14 : auto num_nodes = ensemble_params[0].size();
44 28 : std::vector<double> single_element_ensemble(num_runs);
45 14 : auto num_groups = (size_t)ensemble_params[0][0].parameters.get_num_groups();
46 :
47 : // Lambda function that calculates the percentile of a single parameter
48 42 : std::vector<Model> percentile(num_nodes, Model((int)num_groups));
49 60438 : auto param_percentil = [&ensemble_params, p, num_runs, &percentile](auto n, auto get_param) mutable {
50 13944 : std::vector<double> single_element(num_runs);
51 18592 : for (size_t run = 0; run < num_runs; run++) {
52 18592 : auto const& params = ensemble_params[run][n];
53 9296 : single_element[run] = get_param(params);
54 : }
55 4648 : std::sort(single_element.begin(), single_element.end());
56 9296 : auto& new_params = get_param(percentile[n]);
57 9296 : new_params = single_element[static_cast<size_t>(num_runs * p)];
58 4648 : };
59 :
60 42 : for (size_t node = 0; node < num_nodes; node++) {
61 196 : for (auto age_group = AgeGroup(0); age_group < AgeGroup(num_groups); age_group++) {
62 336 : for (auto virus_variant = VirusVariant(0); virus_variant < VirusVariant::Count;
63 168 : virus_variant = static_cast<VirusVariant>((uint32_t)virus_variant + 1)) {
64 : // Global infection parameters
65 672 : param_percentil(node, [age_group, virus_variant](auto&& model) -> auto& {
66 1008 : return model.parameters.template get<IncubationPeriod>()[{virus_variant, age_group}];
67 : });
68 672 : param_percentil(node, [age_group, virus_variant](auto&& model) -> auto& {
69 1008 : return model.parameters.template get<InfectedNoSymptomsToSymptoms>()[{virus_variant, age_group}];
70 : });
71 672 : param_percentil(node, [age_group, virus_variant](auto&& model) -> auto& {
72 1008 : return model.parameters.template get<InfectedNoSymptomsToRecovered>()[{virus_variant, age_group}];
73 : });
74 672 : param_percentil(node, [age_group, virus_variant](auto&& model) -> auto& {
75 1008 : return model.parameters.template get<InfectedSymptomsToRecovered>()[{virus_variant, age_group}];
76 : });
77 672 : param_percentil(node, [age_group, virus_variant](auto&& model) -> auto& {
78 1008 : return model.parameters.template get<InfectedSymptomsToSevere>()[{virus_variant, age_group}];
79 : });
80 672 : param_percentil(node, [age_group, virus_variant](auto&& model) -> auto& {
81 1008 : return model.parameters.template get<SevereToCritical>()[{virus_variant, age_group}];
82 : });
83 672 : param_percentil(node, [age_group, virus_variant](auto&& model) -> auto& {
84 1008 : return model.parameters.template get<SevereToRecovered>()[{virus_variant, age_group}];
85 : });
86 672 : param_percentil(node, [age_group, virus_variant](auto&& model) -> auto& {
87 1008 : return model.parameters.template get<CriticalToDead>()[{virus_variant, age_group}];
88 : });
89 672 : param_percentil(node, [age_group, virus_variant](auto&& model) -> auto& {
90 1008 : return model.parameters.template get<CriticalToRecovered>()[{virus_variant, age_group}];
91 : });
92 672 : param_percentil(node, [age_group, virus_variant](auto&& model) -> auto& {
93 1008 : return model.parameters.template get<RecoveredToSusceptible>()[{virus_variant, age_group}];
94 : });
95 672 : param_percentil(node, [age_group, virus_variant](auto&& model) -> auto& {
96 1008 : return model.parameters.template get<DetectInfection>()[{virus_variant, age_group}];
97 : });
98 182 : param_percentil(node, [age_group, virus_variant](auto&& model) -> auto& {
99 518 : static auto result =
100 42 : model.parameters.template get<ViralLoadDistributions>()[{virus_variant, age_group}]
101 : .viral_load_incline.params.a();
102 504 : return result;
103 : });
104 182 : param_percentil(node, [age_group, virus_variant](auto&& model) -> auto& {
105 518 : static auto result =
106 42 : model.parameters.template get<ViralLoadDistributions>()[{virus_variant, age_group}]
107 : .viral_load_incline.params.b();
108 504 : return result;
109 : });
110 182 : param_percentil(node, [age_group, virus_variant](auto&& model) -> auto& {
111 518 : static auto result =
112 42 : model.parameters.template get<ViralLoadDistributions>()[{virus_variant, age_group}]
113 : .viral_load_decline.params.a();
114 504 : return result;
115 : });
116 182 : param_percentil(node, [age_group, virus_variant](auto&& model) -> auto& {
117 518 : static auto result =
118 42 : model.parameters.template get<ViralLoadDistributions>()[{virus_variant, age_group}]
119 : .viral_load_decline.params.b();
120 504 : return result;
121 : });
122 182 : param_percentil(node, [age_group, virus_variant](auto&& model) -> auto& {
123 518 : static auto result =
124 42 : model.parameters.template get<ViralLoadDistributions>()[{virus_variant, age_group}]
125 : .viral_load_peak.params.a();
126 504 : return result;
127 : });
128 182 : param_percentil(node, [age_group, virus_variant](auto&& model) -> auto& {
129 518 : static auto result =
130 42 : model.parameters.template get<ViralLoadDistributions>()[{virus_variant, age_group}]
131 : .viral_load_peak.params.b();
132 504 : return result;
133 : });
134 182 : param_percentil(node, [age_group, virus_variant](auto&& model) -> auto& {
135 518 : static auto result =
136 42 : model.parameters.template get<InfectivityDistributions>()[{virus_variant, age_group}]
137 : .infectivity_alpha.params.a();
138 504 : return result;
139 : });
140 182 : param_percentil(node, [age_group, virus_variant](auto&& model) -> auto& {
141 518 : static auto result =
142 42 : model.parameters.template get<InfectivityDistributions>()[{virus_variant, age_group}]
143 : .infectivity_alpha.params.b();
144 504 : return result;
145 : });
146 182 : param_percentil(node, [age_group, virus_variant](auto&& model) -> auto& {
147 518 : static auto result =
148 42 : model.parameters.template get<InfectivityDistributions>()[{virus_variant, age_group}]
149 : .infectivity_beta.params.a();
150 504 : return result;
151 : });
152 182 : param_percentil(node, [age_group, virus_variant](auto&& model) -> auto& {
153 518 : static auto result =
154 42 : model.parameters.template get<InfectivityDistributions>()[{virus_variant, age_group}]
155 : .infectivity_beta.params.b();
156 504 : return result;
157 : });
158 672 : param_percentil(node, [virus_variant](auto&& model) -> auto& {
159 1008 : return model.parameters.template get<AerosolTransmissionRates>()[{virus_variant}];
160 : });
161 : }
162 672 : param_percentil(node, [age_group](auto&& model) -> auto& {
163 504 : return model.parameters.template get<BasicShoppingRate>()[{age_group}];
164 : });
165 672 : param_percentil(node, [age_group](auto&& model) -> auto& {
166 504 : static auto result = model.parameters.template get<GotoWorkTimeMinimum>()[{age_group}].hours();
167 504 : return result;
168 : });
169 672 : param_percentil(node, [age_group](auto&& model) -> auto& {
170 504 : static auto result = model.parameters.template get<GotoWorkTimeMaximum>()[{age_group}].hours();
171 504 : return result;
172 : });
173 672 : param_percentil(node, [age_group](auto&& model) -> auto& {
174 504 : static auto result = model.parameters.template get<GotoSchoolTimeMinimum>()[{age_group}].hours();
175 504 : return result;
176 : });
177 672 : param_percentil(node, [age_group](auto&& model) -> auto& {
178 504 : static auto result = model.parameters.template get<GotoSchoolTimeMaximum>()[{age_group}].hours();
179 504 : return result;
180 : });
181 : }
182 112 : param_percentil(node, [](auto&& model) -> auto& {
183 84 : return model.parameters.template get<MaskProtection>()[MaskType::Community];
184 : });
185 112 : param_percentil(node, [](auto&& model) -> auto& {
186 84 : return model.parameters.template get<MaskProtection>()[MaskType::FFP2];
187 : });
188 112 : param_percentil(node, [](auto&& model) -> auto& {
189 84 : return model.parameters.template get<MaskProtection>()[MaskType::Surgical];
190 : });
191 112 : param_percentil(node, [](auto&& model) -> auto& {
192 84 : static auto result = model.parameters.template get<LockdownDate>().days();
193 84 : return result;
194 : });
195 : }
196 :
197 28 : return percentile;
198 14 : }
199 :
200 : } // namespace abm
201 : } // namespace mio
202 :
203 : #endif
|