Line data Source code
1 : /*
2 : * Copyright (C) 2020-2024 MEmilio
3 : *
4 : * Authors: Daniel Abele, Elisabeth Kluth, 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 MIO_ABM_PARAMETERS_H
21 : #define MIO_ABM_PARAMETERS_H
22 :
23 : #include "abm/mask_type.h"
24 : #include "abm/time.h"
25 : #include "abm/virus_variant.h"
26 : #include "abm/protection_event.h"
27 : #include "abm/test_type.h"
28 : #include "memilio/config.h"
29 : #include "memilio/io/default_serialize.h"
30 : #include "memilio/io/io.h"
31 : #include "memilio/math/time_series_functor.h"
32 : #include "memilio/utils/custom_index_array.h"
33 : #include "memilio/utils/uncertain_value.h"
34 : #include "memilio/utils/parameter_set.h"
35 : #include "memilio/epidemiology/age_group.h"
36 : #include "memilio/epidemiology/damping.h"
37 : #include "memilio/epidemiology/contact_matrix.h"
38 :
39 : #include <algorithm>
40 : #include <limits>
41 : #include <string>
42 :
43 : namespace mio
44 : {
45 : namespace abm
46 : {
47 :
48 : /**
49 : * @brief Time that a Person is infected but not yet infectious.
50 : */
51 : struct IncubationPeriod {
52 : using Type = CustomIndexArray<UncertainValue<>, VirusVariant, AgeGroup>;
53 883 : static Type get_default(AgeGroup size)
54 : {
55 883 : return Type({VirusVariant::Count, size}, 1.);
56 : }
57 27 : static std::string name()
58 : {
59 27 : return "IncubationPeriod";
60 : }
61 : };
62 :
63 : struct InfectedNoSymptomsToSymptoms {
64 : using Type = CustomIndexArray<UncertainValue<>, VirusVariant, AgeGroup>;
65 883 : static Type get_default(AgeGroup size)
66 : {
67 883 : return Type({VirusVariant::Count, size}, 1.);
68 : }
69 27 : static std::string name()
70 : {
71 27 : return "InfectedNoSymptomsToSymptoms";
72 : }
73 : };
74 :
75 : struct InfectedNoSymptomsToRecovered {
76 : using Type = CustomIndexArray<UncertainValue<>, VirusVariant, AgeGroup>;
77 883 : static Type get_default(AgeGroup size)
78 : {
79 883 : return Type({VirusVariant::Count, size}, 1.);
80 : }
81 27 : static std::string name()
82 : {
83 27 : return "InfectedNoSymptomsToRecovered";
84 : }
85 : };
86 :
87 : struct InfectedSymptomsToRecovered {
88 : using Type = CustomIndexArray<UncertainValue<>, VirusVariant, AgeGroup>;
89 883 : static Type get_default(AgeGroup size)
90 : {
91 883 : return Type({VirusVariant::Count, size}, 1.);
92 : }
93 27 : static std::string name()
94 : {
95 27 : return "InfectedSymptomsToRecovered";
96 : }
97 : };
98 :
99 : struct InfectedSymptomsToSevere {
100 : using Type = CustomIndexArray<UncertainValue<>, VirusVariant, AgeGroup>;
101 883 : static Type get_default(AgeGroup size)
102 : {
103 883 : return Type({VirusVariant::Count, size}, 1.);
104 : }
105 27 : static std::string name()
106 : {
107 27 : return "InfectedSymptomsToSevere";
108 : }
109 : };
110 :
111 : struct SevereToCritical {
112 : using Type = CustomIndexArray<UncertainValue<>, VirusVariant, AgeGroup>;
113 883 : static Type get_default(AgeGroup size)
114 : {
115 883 : return Type({VirusVariant::Count, size}, 1.);
116 : }
117 27 : static std::string name()
118 : {
119 27 : return "SevereToCritical";
120 : }
121 : };
122 :
123 : struct SevereToRecovered {
124 : using Type = CustomIndexArray<UncertainValue<>, VirusVariant, AgeGroup>;
125 883 : static Type get_default(AgeGroup size)
126 : {
127 883 : return Type({VirusVariant::Count, size}, 1.);
128 : }
129 27 : static std::string name()
130 : {
131 27 : return "SevereToRecovered";
132 : }
133 : };
134 :
135 : struct CriticalToRecovered {
136 : using Type = CustomIndexArray<UncertainValue<>, VirusVariant, AgeGroup>;
137 883 : static Type get_default(AgeGroup size)
138 : {
139 883 : return Type({VirusVariant::Count, size}, 1.);
140 : }
141 27 : static std::string name()
142 : {
143 27 : return "CriticalToRecovered";
144 : }
145 : };
146 :
147 : struct CriticalToDead {
148 : using Type = CustomIndexArray<UncertainValue<>, VirusVariant, AgeGroup>;
149 883 : static Type get_default(AgeGroup size)
150 : {
151 883 : return Type({VirusVariant::Count, size}, 1.);
152 : }
153 27 : static std::string name()
154 : {
155 27 : return "CriticalToDead";
156 : }
157 : };
158 :
159 : struct RecoveredToSusceptible {
160 : using Type = CustomIndexArray<UncertainValue<>, VirusVariant, AgeGroup>;
161 883 : static Type get_default(AgeGroup size)
162 : {
163 883 : return Type({VirusVariant::Count, size}, 1.);
164 : }
165 27 : static std::string name()
166 : {
167 27 : return "RecoveredToSusceptible";
168 : }
169 : };
170 : /**
171 : * @brief Parameters for the ViralLoad course. Default values taken as constant values from the average from
172 : * https://github.com/VirologyCharite/SARS-CoV-2-VL-paper/tree/main
173 : * Section 3.3.1 or see also supplementary materials Fig. S5.
174 : */
175 : struct ViralLoadDistributionsParameters {
176 : UniformDistribution<double>::ParamType viral_load_peak;
177 : UniformDistribution<double>::ParamType viral_load_incline;
178 : UniformDistribution<double>::ParamType viral_load_decline;
179 :
180 : /// This method is used by the default serialization feature.
181 27 : auto default_serialize()
182 : {
183 54 : return Members("ViralLoadDistributionsParameters")
184 81 : .add("viral_load_peak", viral_load_peak)
185 81 : .add("viral_load_incline", viral_load_incline)
186 81 : .add("viral_load_decline", viral_load_decline);
187 : }
188 : };
189 :
190 : struct ViralLoadDistributions {
191 : using Type = CustomIndexArray<ViralLoadDistributionsParameters, VirusVariant, AgeGroup>;
192 892 : static Type get_default(AgeGroup size)
193 : {
194 892 : Type default_val({VirusVariant::Count, size},
195 892 : ViralLoadDistributionsParameters{{8.1, 8.1}, {2., 2.}, {-0.17, -0.17}});
196 1784 : return default_val;
197 892 : }
198 27 : static std::string name()
199 : {
200 27 : return "ViralLoadDistributions";
201 : }
202 : };
203 :
204 : /**
205 : * @brief Parameters for the Infectivity. Default values taken as constant values that match the graph 2C from
206 : * https://github.com/VirologyCharite/SARS-CoV-2-VL-paper/tree/main
207 : */
208 : struct InfectivityDistributionsParameters {
209 : UniformDistribution<double>::ParamType infectivity_alpha;
210 : UniformDistribution<double>::ParamType infectivity_beta;
211 :
212 : /// This method is used by the default serialization feature.
213 27 : auto default_serialize()
214 : {
215 54 : return Members("InfectivityDistributionsParameters")
216 81 : .add("infectivity_alpha", infectivity_alpha)
217 81 : .add("infectivity_beta", infectivity_beta);
218 : }
219 : };
220 :
221 : struct InfectivityDistributions {
222 : using Type = CustomIndexArray<InfectivityDistributionsParameters, VirusVariant, AgeGroup>;
223 892 : static Type get_default(AgeGroup size)
224 : {
225 892 : Type default_val({VirusVariant::Count, size}, InfectivityDistributionsParameters{{-7., -7.}, {1., 1.}});
226 1784 : return default_val;
227 892 : }
228 27 : static std::string name()
229 : {
230 27 : return "InfectivityDistributions";
231 : }
232 : };
233 :
234 : /**
235 : * @brief Probability that an Infection is detected.
236 : */
237 : struct DetectInfection {
238 : using Type = CustomIndexArray<UncertainValue<>, VirusVariant, AgeGroup>;
239 883 : static Type get_default(AgeGroup size)
240 : {
241 883 : return Type({VirusVariant::Count, size}, 1.);
242 : }
243 27 : static std::string name()
244 : {
245 27 : return "DetectInfection";
246 : }
247 : };
248 :
249 : /**
250 : * @brief Effectiveness of a Mask of a certain MaskType% against an Infection%.
251 : */
252 : struct MaskProtection {
253 : using Type = CustomIndexArray<UncertainValue<>, MaskType>;
254 883 : static Type get_default(AgeGroup /*size*/)
255 : {
256 883 : Type defaut_value = Type(MaskType::Count, 0.0);
257 : // Initial values according to http://dx.doi.org/10.15585/mmwr.mm7106e1
258 883 : defaut_value[MaskType::FFP2] = 0.83;
259 883 : defaut_value[MaskType::Surgical] = 0.66;
260 883 : defaut_value[MaskType::Community] = 0.56;
261 1766 : return defaut_value;
262 883 : }
263 27 : static std::string name()
264 : {
265 27 : return "MaskProtection";
266 : }
267 : };
268 :
269 : /**
270 : * @brief Aerosol transmission rates.
271 : */
272 : struct AerosolTransmissionRates {
273 : using Type = CustomIndexArray<ScalarType, VirusVariant>;
274 883 : static Type get_default(AgeGroup /*size*/)
275 : {
276 883 : return Type({VirusVariant::Count}, 1.0);
277 : }
278 27 : static std::string name()
279 : {
280 27 : return "AerosolTransmissionRates";
281 : }
282 : };
283 :
284 : /**
285 : * @brief Personal protection factor against #Infection% after #Infection and vaccination, which depends on #ProtectionType,
286 : * #AgeGroup and #VirusVariant. Its value is between 0 and 1.
287 : */
288 : struct InfectionProtectionFactor {
289 : using Type = CustomIndexArray<TimeSeriesFunctor<ScalarType>, ProtectionType, AgeGroup, VirusVariant>;
290 883 : static auto get_default(AgeGroup size)
291 : {
292 883 : return Type({ProtectionType::Count, size, VirusVariant::Count}, TimeSeriesFunctor<ScalarType>());
293 : }
294 27 : static std::string name()
295 : {
296 27 : return "InfectionProtectionFactor";
297 : }
298 : };
299 :
300 : /**
301 : * @brief Personal protective factor against severe symptoms after #Infection and vaccination, which depends on #ProtectionType,
302 : * #AgeGroup and #VirusVariant. Its value is between 0 and 1.
303 : */
304 : struct SeverityProtectionFactor {
305 : using Type = CustomIndexArray<TimeSeriesFunctor<ScalarType>, ProtectionType, AgeGroup, VirusVariant>;
306 883 : static auto get_default(AgeGroup size)
307 : {
308 883 : return Type({ProtectionType::Count, size, VirusVariant::Count}, TimeSeriesFunctor<ScalarType>());
309 : }
310 27 : static std::string name()
311 : {
312 27 : return "SeverityProtectionFactor";
313 : }
314 : };
315 :
316 : /**
317 : * @brief Personal protective factor against high viral load, which depends on #ProtectionType,
318 : * #AgeGroup and #VirusVariant. Its value is between 0 and 1.
319 : */
320 : struct HighViralLoadProtectionFactor {
321 : using Type = CustomIndexArray<TimeSeriesFunctor<ScalarType>, ProtectionType, AgeGroup, VirusVariant>;
322 883 : static auto get_default(AgeGroup size)
323 : {
324 883 : return Type({ProtectionType::Count, size, VirusVariant::Count}, TimeSeriesFunctor<ScalarType>());
325 : }
326 27 : static std::string name()
327 : {
328 27 : return "HighViralLoadProtectionFactor";
329 : }
330 : };
331 :
332 : /**
333 : * @brief Parameters that describe the reliability of a test.
334 : */
335 : struct TestParameters {
336 : UncertainValue<> sensitivity;
337 : UncertainValue<> specificity;
338 : TimeSpan required_time;
339 : TestType type;
340 :
341 : /// This method is used by the default serialization feature.
342 99 : auto default_serialize()
343 : {
344 198 : return Members("TestParameters")
345 297 : .add("sensitivity", sensitivity)
346 297 : .add("specificity", specificity)
347 297 : .add("required_time", required_time)
348 297 : .add("test_type", type);
349 : }
350 : };
351 :
352 : /**
353 : * @brief Store a map from the TestTypes to their TestParameters.
354 : */
355 : struct TestData {
356 : using Type = CustomIndexArray<TestParameters, TestType>;
357 883 : static auto get_default(AgeGroup /*size*/)
358 : {
359 883 : Type default_val = Type({TestType::Count});
360 883 : default_val[{TestType::Generic}] = TestParameters{0.9, 0.99, hours(48), TestType::Generic};
361 883 : default_val[{TestType::Antigen}] = TestParameters{0.8, 0.88, minutes(30), TestType::Antigen};
362 883 : default_val[{TestType::PCR}] = TestParameters{0.9, 0.99, hours(48), TestType::PCR};
363 1766 : return default_val;
364 883 : }
365 27 : static std::string name()
366 : {
367 27 : return "TestData";
368 : }
369 : };
370 :
371 : /**
372 : * @brief Starting date of interventions.
373 : */
374 : struct LockdownDate {
375 : using Type = TimePoint;
376 883 : static auto get_default(AgeGroup /*size*/)
377 : {
378 883 : return TimePoint(std::numeric_limits<int>::max());
379 : }
380 27 : static std::string name()
381 : {
382 27 : return "LockdownDate";
383 : }
384 : };
385 :
386 : /**
387 : * @brief Duration of quarantine.
388 : */
389 : struct QuarantineDuration {
390 : using Type = TimeSpan;
391 883 : static auto get_default(AgeGroup /*size*/)
392 : {
393 883 : return days(10);
394 : }
395 27 : static std::string name()
396 : {
397 27 : return "QuarantineDuration";
398 : }
399 : };
400 :
401 : /**
402 : * @brief Parameter for the exponential distribution to decide if a Person goes shopping.
403 : */
404 : struct BasicShoppingRate {
405 : using Type = CustomIndexArray<UncertainValue<>, AgeGroup>;
406 883 : static auto get_default(AgeGroup size)
407 : {
408 1766 : return Type({size}, 1.0);
409 : }
410 27 : static std::string name()
411 : {
412 27 : return "BasicShoppingRate";
413 : }
414 : };
415 :
416 : /**
417 : * @brief Percentage of Person%s of the respective age going to work.
418 : */
419 : struct WorkRatio {
420 : using Type = DampingMatrixExpression<Dampings<Damping<ColumnVectorShape>>>;
421 883 : static auto get_default(AgeGroup /*size*/)
422 : {
423 1766 : return Type(Eigen::VectorXd::Constant(1, 1.0));
424 : }
425 27 : static std::string name()
426 : {
427 27 : return "WorkRatio";
428 : }
429 : };
430 :
431 : /**
432 : * @brief Percentage of Person%s of the respective age going to school.
433 : */
434 : struct SchoolRatio {
435 : using Type = DampingMatrixExpression<Dampings<Damping<ColumnVectorShape>>>;
436 883 : static auto get_default(AgeGroup /*size*/)
437 : {
438 1766 : return Type(Eigen::VectorXd::Constant(1, 1.0));
439 : }
440 27 : static std::string name()
441 : {
442 27 : return "SchoolRatio";
443 : }
444 : };
445 :
446 : /**
447 : * @brief Parameter for the exponential distribution to decide if a Person goes to a social event.
448 : */
449 : struct SocialEventRate {
450 : using Type = DampingMatrixExpression<Dampings<Damping<ColumnVectorShape>>>;
451 883 : static auto get_default(AgeGroup size)
452 : {
453 1766 : return Type(Eigen::VectorXd::Constant((size_t)size, 1.0));
454 : }
455 27 : static std::string name()
456 : {
457 27 : return "SocialEventRate";
458 : }
459 : };
460 :
461 : /**
462 : * @brief Earliest time that a Person can go to work.
463 : */
464 : struct GotoWorkTimeMinimum {
465 : using Type = CustomIndexArray<TimeSpan, AgeGroup>;
466 883 : static auto get_default(AgeGroup size)
467 : {
468 1766 : return CustomIndexArray<TimeSpan, AgeGroup>(size, hours(6));
469 : }
470 27 : static std::string name()
471 : {
472 27 : return "GotoWorkTimeMinimum";
473 : }
474 : };
475 :
476 : /**
477 : * @brief Latest time that a Person can go to work.
478 : */
479 : struct GotoWorkTimeMaximum {
480 : using Type = CustomIndexArray<TimeSpan, AgeGroup>;
481 883 : static auto get_default(AgeGroup size)
482 : {
483 1766 : return CustomIndexArray<TimeSpan, AgeGroup>(size, hours(9));
484 : }
485 27 : static std::string name()
486 : {
487 27 : return "GotoWorkTimeMaximum";
488 : }
489 : };
490 :
491 : /**
492 : * @brief Earliest time that a Person can go to school.
493 : */
494 : struct GotoSchoolTimeMinimum {
495 : using Type = CustomIndexArray<TimeSpan, AgeGroup>;
496 883 : static auto get_default(AgeGroup size)
497 : {
498 1766 : return CustomIndexArray<TimeSpan, AgeGroup>(size, hours(6));
499 : }
500 27 : static std::string name()
501 : {
502 27 : return "GotoSchoolTimeMinimum";
503 : }
504 : };
505 :
506 : /**
507 : * @brief Latest time that a Person can go to school.
508 : */
509 : struct GotoSchoolTimeMaximum {
510 : using Type = CustomIndexArray<TimeSpan, AgeGroup>;
511 883 : static auto get_default(AgeGroup size)
512 : {
513 1766 : return CustomIndexArray<TimeSpan, AgeGroup>(size, hours(9));
514 : }
515 27 : static std::string name()
516 : {
517 27 : return "GotoSchoolTimeMaximum";
518 : }
519 : };
520 :
521 : /**
522 : * @brief The set of AgeGroups that can go to school.
523 : */
524 : struct AgeGroupGotoSchool {
525 : using Type = CustomIndexArray<bool, AgeGroup>;
526 883 : static Type get_default(AgeGroup num_agegroups)
527 : {
528 883 : return Type(num_agegroups, false);
529 : }
530 27 : static std::string name()
531 : {
532 27 : return "AgeGroupGotoSchool";
533 : }
534 : };
535 :
536 : /**
537 : * @brief The set of AgeGroups that can go to work.
538 : */
539 : struct AgeGroupGotoWork {
540 : using Type = CustomIndexArray<bool, AgeGroup>;
541 883 : static Type get_default(AgeGroup num_agegroups)
542 : {
543 883 : return Type(num_agegroups, false);
544 : }
545 27 : static std::string name()
546 : {
547 27 : return "AgeGroupGotoWork";
548 : }
549 : };
550 :
551 : using ParametersBase =
552 : ParameterSet<IncubationPeriod, InfectedNoSymptomsToSymptoms, InfectedNoSymptomsToRecovered,
553 : InfectedSymptomsToRecovered, InfectedSymptomsToSevere, SevereToCritical, SevereToRecovered,
554 : CriticalToDead, CriticalToRecovered, RecoveredToSusceptible, ViralLoadDistributions,
555 : InfectivityDistributions, DetectInfection, MaskProtection, AerosolTransmissionRates, LockdownDate,
556 : QuarantineDuration, SocialEventRate, BasicShoppingRate, WorkRatio, SchoolRatio, GotoWorkTimeMinimum,
557 : GotoWorkTimeMaximum, GotoSchoolTimeMinimum, GotoSchoolTimeMaximum, AgeGroupGotoSchool,
558 : AgeGroupGotoWork, InfectionProtectionFactor, SeverityProtectionFactor, HighViralLoadProtectionFactor,
559 : TestData>;
560 :
561 : /**
562 : * @brief Maximum number of Person%s an infectious Person can infect at the respective Location.
563 : */
564 : struct MaximumContacts {
565 : using Type = ScalarType;
566 1360 : static Type get_default(AgeGroup /*size*/)
567 : {
568 1360 : return std::numeric_limits<ScalarType>::max();
569 : }
570 18 : static std::string name()
571 : {
572 18 : return "MaximumContacts";
573 : }
574 : };
575 :
576 : /**
577 : * contact rates
578 : */
579 : struct ContactRates {
580 : using Type = CustomIndexArray<ScalarType, AgeGroup, AgeGroup>;
581 1369 : static Type get_default(AgeGroup size)
582 : {
583 : return Type({size, size},
584 1369 : 1.0); // amount of contacts from AgeGroup a to AgeGroup b per day
585 : }
586 18 : static std::string name()
587 : {
588 18 : return "ContactRates";
589 : }
590 : };
591 :
592 : // If true, consider the capacity of the Cell%s of this Location for the computation of relative transmission risk.
593 : struct UseLocationCapacityForTransmissions {
594 : using Type = bool;
595 1360 : static Type get_default(AgeGroup)
596 : {
597 1360 : return false;
598 : }
599 18 : static std::string name()
600 : {
601 18 : return "UseLocationCapacityForTransmissions";
602 : }
603 : };
604 :
605 : /**
606 : * @brief Parameters of the Infection that depend on the Location.
607 : */
608 : using LocalInfectionParameters = ParameterSet<MaximumContacts, ContactRates, UseLocationCapacityForTransmissions>;
609 :
610 : /**
611 : * @brief Parameters of the simulation that are the same everywhere within the Model.
612 : */
613 : class Parameters : public ParametersBase
614 : {
615 : public:
616 883 : Parameters(size_t num_agegroups)
617 1766 : : ParametersBase(AgeGroup(num_agegroups))
618 2649 : , m_num_groups(num_agegroups)
619 : {
620 883 : }
621 :
622 : private:
623 9 : Parameters(ParametersBase&& base)
624 9 : : ParametersBase(std::move(base))
625 18 : , m_num_groups(this->get<AgeGroupGotoWork>().size<AgeGroup>().get())
626 : {
627 9 : }
628 :
629 : public:
630 : /**
631 : * @brief Get the number of the age groups.
632 : */
633 8286 : size_t get_num_groups() const
634 : {
635 8286 : return m_num_groups;
636 : }
637 :
638 : /**
639 : * @brief Checks whether all Parameters satisfy their corresponding constraints and logs an error
640 : * if constraints are not satisfied.
641 : * @return Returns true if one (or more) constraint(s) are not satisfied, otherwise false.
642 : */
643 180 : bool check_constraints() const
644 : {
645 504 : for (auto i = AgeGroup(0); i < AgeGroup(m_num_groups); ++i) {
646 :
647 459 : if (this->get<IncubationPeriod>()[{VirusVariant::Wildtype, i}] < 0) {
648 18 : log_error("Constraint check: Parameter IncubationPeriod of age group {:.0f} smaller than {:.4f}",
649 18 : (size_t)i, 0);
650 9 : return true;
651 : }
652 :
653 450 : if (this->get<InfectedNoSymptomsToSymptoms>()[{VirusVariant::Wildtype, i}] < 0.0) {
654 18 : log_error("Constraint check: Parameter InfectedNoSymptomsToSymptoms of age group {:.0f} smaller "
655 : "than {:d}",
656 18 : (size_t)i, 0);
657 9 : return true;
658 : }
659 :
660 441 : if (this->get<InfectedNoSymptomsToRecovered>()[{VirusVariant::Wildtype, i}] < 0.0) {
661 18 : log_error("Constraint check: Parameter InfectedNoSymptomsToRecovered of age group {:.0f} smaller "
662 : "than {:d}",
663 18 : (size_t)i, 0);
664 9 : return true;
665 : }
666 :
667 432 : if (this->get<InfectedSymptomsToRecovered>()[{VirusVariant::Wildtype, i}] < 0.0) {
668 18 : log_error(
669 : "Constraint check: Parameter InfectedSymptomsToRecovered of age group {:.0f} smaller than {:d}",
670 18 : (size_t)i, 0);
671 9 : return true;
672 : }
673 :
674 423 : if (this->get<InfectedSymptomsToSevere>()[{VirusVariant::Wildtype, i}] < 0.0) {
675 18 : log_error("Constraint check: Parameter InfectedSymptomsToSevere of age group {:.0f} smaller than {:d}",
676 18 : (size_t)i, 0);
677 9 : return true;
678 : }
679 :
680 414 : if (this->get<SevereToCritical>()[{VirusVariant::Wildtype, i}] < 0.0) {
681 18 : log_error("Constraint check: Parameter SevereToCritical of age group {:.0f} smaller than {:d}",
682 18 : (size_t)i, 0);
683 9 : return true;
684 : }
685 :
686 405 : if (this->get<SevereToRecovered>()[{VirusVariant::Wildtype, i}] < 0.0) {
687 18 : log_error("Constraint check: Parameter SevereToRecovered of age group {:.0f} smaller than {:d}",
688 18 : (size_t)i, 0);
689 9 : return true;
690 : }
691 :
692 396 : if (this->get<CriticalToDead>()[{VirusVariant::Wildtype, i}] < 0.0) {
693 18 : log_error("Constraint check: Parameter CriticalToDead of age group {:.0f} smaller than {:d}", (size_t)i,
694 18 : 0);
695 9 : return true;
696 : }
697 :
698 387 : if (this->get<CriticalToRecovered>()[{VirusVariant::Wildtype, i}] < 0.0) {
699 18 : log_error("Constraint check: Parameter CriticalToRecovered of age group {:.0f} smaller than {:d}",
700 18 : (size_t)i, 0);
701 9 : return true;
702 : }
703 :
704 378 : if (this->get<RecoveredToSusceptible>()[{VirusVariant::Wildtype, i}] < 0.0) {
705 18 : log_error("Constraint check: Parameter RecoveredToSusceptible of age group {:.0f} smaller than {:d}",
706 18 : (size_t)i, 0);
707 9 : return true;
708 : }
709 :
710 1107 : if (this->get<DetectInfection>()[{VirusVariant::Wildtype, i}] < 0.0 ||
711 738 : this->get<DetectInfection>()[{VirusVariant::Wildtype, i}] > 1.0) {
712 18 : log_error("Constraint check: Parameter DetectInfection of age group {:.0f} smaller than {:d} or "
713 : "larger than {:d}",
714 18 : (size_t)i, 0, 1);
715 9 : return true;
716 : }
717 :
718 720 : if (this->get<GotoWorkTimeMinimum>()[i].seconds() < 0.0 ||
719 360 : this->get<GotoWorkTimeMinimum>()[i].seconds() > this->get<GotoWorkTimeMaximum>()[i].seconds()) {
720 18 : log_error("Constraint check: Parameter GotoWorkTimeMinimum of age group {:.0f} smaller {:d} or "
721 : "larger {:d}",
722 18 : (size_t)i, 0, this->get<GotoWorkTimeMaximum>()[i].seconds());
723 9 : return true;
724 : }
725 :
726 1404 : if (this->get<GotoWorkTimeMaximum>()[i].seconds() < this->get<GotoWorkTimeMinimum>()[i].seconds() ||
727 1053 : this->get<GotoWorkTimeMaximum>()[i] > days(1)) {
728 18 : log_error("Constraint check: Parameter GotoWorkTimeMaximum of age group {:.0f} smaller {:d} or larger "
729 : "than one day time span",
730 18 : (size_t)i, this->get<GotoWorkTimeMinimum>()[i].seconds());
731 9 : return true;
732 : }
733 :
734 684 : if (this->get<GotoSchoolTimeMinimum>()[i].seconds() < 0.0 ||
735 342 : this->get<GotoSchoolTimeMinimum>()[i].seconds() > this->get<GotoSchoolTimeMaximum>()[i].seconds()) {
736 18 : log_error("Constraint check: Parameter GotoSchoolTimeMinimum of age group {:.0f} smaller {:d} or "
737 : "larger {:d}",
738 18 : (size_t)i, 0, this->get<GotoWorkTimeMaximum>()[i].seconds());
739 9 : return true;
740 : }
741 :
742 1332 : if (this->get<GotoSchoolTimeMaximum>()[i].seconds() < this->get<GotoSchoolTimeMinimum>()[i].seconds() ||
743 999 : this->get<GotoSchoolTimeMaximum>()[i] > days(1)) {
744 18 : log_error("Constraint check: Parameter GotoWorkTimeMaximum of age group {:.0f} smaller {:d} or larger "
745 : "than one day time span",
746 18 : (size_t)i, this->get<GotoSchoolTimeMinimum>()[i].seconds());
747 9 : return true;
748 : }
749 : }
750 :
751 135 : if (this->get<MaskProtection>()[MaskType::Community] < 0.0 ||
752 90 : this->get<MaskProtection>()[MaskType::Community] > 1.0) {
753 18 : log_error(
754 18 : "Constraint check: Parameter MaskProtection for MaskType Community is smaller {:d} or larger {:d}", 0,
755 18 : 1);
756 9 : return true;
757 : }
758 :
759 36 : if (this->get<MaskProtection>()[MaskType::FFP2] < 0.0 || this->get<MaskProtection>()[MaskType::FFP2] > 1.0) {
760 18 : log_error("Constraint check: Parameter MaskProtection for MaskType FFP2 is smaller {:d} or larger {:d}", 0,
761 18 : 1);
762 9 : return true;
763 : }
764 :
765 81 : if (this->get<MaskProtection>()[MaskType::Surgical] < 0.0 ||
766 54 : this->get<MaskProtection>()[MaskType::Surgical] > 1.0) {
767 18 : log_error("Constraint check: Parameter MaskProtection for MaskType Surgical smaller {:d} or larger {:d}", 0,
768 18 : 1);
769 9 : return true;
770 : }
771 :
772 18 : if (this->get<LockdownDate>().seconds() < 0.0) {
773 18 : log_error("Constraint check: Parameter LockdownDate smaller {:d}", 0);
774 9 : return true;
775 : }
776 :
777 9 : return false;
778 : }
779 :
780 : /**
781 : * deserialize an object of this class.
782 : * @see epi::deserialize
783 : */
784 : template <class IOContext>
785 9 : static IOResult<Parameters> deserialize(IOContext& io)
786 : {
787 9 : BOOST_OUTCOME_TRY(auto&& base, ParametersBase::deserialize(io));
788 9 : return success(Parameters(std::move(base)));
789 9 : }
790 :
791 : private:
792 : size_t m_num_groups;
793 : };
794 :
795 : } // namespace abm
796 : } // namespace mio
797 : #endif
|