Line data Source code
1 : /*
2 : * Copyright (C) 2020-2025 MEmilio
3 : *
4 : * Authors: David Kerkmann, Sascha Korf, 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_INFECTION_H
21 : #define MIO_ABM_INFECTION_H
22 :
23 : #include "abm/personal_rng.h"
24 : #include "memilio/io/default_serialize.h"
25 : #include "abm/time.h"
26 : #include "abm/infection_state.h"
27 : #include "abm/virus_variant.h"
28 : #include "abm/parameters.h"
29 :
30 : #include <vector>
31 :
32 : namespace mio
33 : {
34 : namespace abm
35 : {
36 :
37 : /**
38 : * @brief Models the ViralLoad for an Infection, modelled on a log_10 scale.
39 : * Based on https://www.science.org/doi/full/10.1126/science.abi5273
40 : * Examplary ViralLoad courses can be seen for example in Fig. 4 B.
41 : */
42 : struct ViralLoad {
43 : TimePoint start_date; ///< Start date of the ViralLoad concentration in the Person.
44 : TimePoint end_date; ///< End date of the ViralLoad concentration in the Person.
45 : ScalarType peak; ///< Peak amplitude of the ViralLoad.
46 : ScalarType incline; ///< Incline of the ViralLoad during incline phase in log_10 scale per day (always positive).
47 : ScalarType decline; ///< Decline of the ViralLoad during decline phase in log_10 scale per day (always negative).
48 :
49 : /// This method is used by the default serialization feature.
50 18 : auto default_serialize()
51 : {
52 36 : return Members("ViralLoad")
53 54 : .add("start_date", start_date)
54 54 : .add("end_date", end_date)
55 54 : .add("peak", peak)
56 54 : .add("incline", incline)
57 54 : .add("decline", decline);
58 : }
59 : };
60 :
61 : class Infection
62 : {
63 : public:
64 : /**
65 : * @brief Create an Infection for a single Person.
66 : * Draws a random infection course.
67 : * @param[inout] rng PersonalRandomNumberGenerator of the Person.
68 : * @param[in] virus Virus type of the Infection.
69 : * @param[in] age AgeGroup to determine the ViralLoad course.
70 : * @param[in] params Parameters of the Model.
71 : * @param[in] init_date Date of initializing the Infection.
72 : * @param[in] init_state [Default: InfectionState::Exposed] #InfectionState at time of initializing the Infection.
73 : * @param[in] latest_protection [Default: {ProtectionType::NoProtection, TimePoint(0)}] The pair value of last ProtectionType (previous Infection/Vaccination) and TimePoint of that protection.
74 : * @param[in] detected [Default: false] If the Infection is detected.
75 : */
76 : Infection(PersonalRandomNumberGenerator& rng, VirusVariant virus, AgeGroup age, const Parameters& params,
77 : TimePoint start_date, InfectionState start_state = InfectionState::Exposed,
78 : ProtectionEvent latest_protection = {ProtectionType::NoProtection, TimePoint(0)}, bool detected = false);
79 :
80 : /**
81 : * @brief Gets the ViralLoad of the Infection at a given TimePoint.
82 : * @param[in] t TimePoint of querry.
83 : */
84 : ScalarType get_viral_load(TimePoint t) const;
85 :
86 : /**
87 : * @brief Get infectivity at a given time.
88 : * Computed depending on current ViralLoad and individual invlogit function of each Person
89 : * corresponding to https://www.science.org/doi/full/10.1126/science.abi5273
90 : * The mapping corresponds to Fig. 2 C.
91 : * Formula of invlogit function can be found here:
92 : * https://github.com/VirologyCharite/SARS-CoV-2-VL-paper/tree/main
93 : * in ExtendedMethods.html, Section 3.1.2.1.
94 : * @param[in] t TimePoint of the querry.
95 : * @return Infectivity at given TimePoint.
96 : */
97 : ScalarType get_infectivity(TimePoint t) const;
98 :
99 : /**
100 : * @brief: Get VirusVariant.
101 : * @return VirusVariant of the Infection.
102 : */
103 : VirusVariant get_virus_variant() const;
104 :
105 : /**
106 : * @brief Get the #InfectionState of the Infection.
107 : * @param[in] t TimePoint of the querry.
108 : * @return #InfectionState at the given TimePoint.
109 : */
110 : InfectionState get_infection_state(TimePoint t) const;
111 :
112 : /**
113 : * @brief Set the Infection to detected.
114 : */
115 : void set_detected();
116 :
117 : /**
118 : * @return Get the detected state.
119 : */
120 : bool is_detected() const;
121 :
122 : /**
123 : * @returns Get the start date of the infection.
124 : */
125 : TimePoint get_start_date() const;
126 :
127 : /// This method is used by the default serialization feature.
128 18 : auto default_serialize()
129 : {
130 36 : return Members("Infection")
131 54 : .add("infection_course", m_infection_course)
132 54 : .add("virus_variant", m_virus_variant)
133 54 : .add("viral_load", m_viral_load)
134 54 : .add("log_norm_alpha", m_log_norm_alpha)
135 54 : .add("log_norm_beta", m_log_norm_beta)
136 54 : .add("detected", m_detected);
137 : }
138 :
139 : private:
140 : friend DefaultFactory<Infection>;
141 9 : Infection() = default;
142 :
143 : /**
144 : * @brief Determine Infection course based on #InfectionState init_state.
145 : * Calls draw_infection_course_backward for all #InfectionState%s prior and draw_infection_course_forward for all
146 : * subsequent #InfectionState%s.
147 : * @param[inout] rng PersonalRandomNumberGenerator of the Person.
148 : * @param[in] age AgeGroup of the Person.
149 : * @param[in] params Parameters of the Model.
150 : * @param[in] init_date Date of initializing the Infection.
151 : * @param[in] init_state #InfectionState at time of initializing the Infection.
152 : * @param[in] latest_protection Latest protection against Infection, has an influence on transition probabilities.
153 : * @return The starting date of the Infection.
154 : */
155 : TimePoint draw_infection_course(PersonalRandomNumberGenerator& rng, AgeGroup age, const Parameters& params,
156 : TimePoint init_date, InfectionState start_state, ProtectionEvent latest_protection);
157 :
158 : /**
159 : * @brief Determine Infection course subsequent to the given #InfectionState start_state.
160 : * From the start_state, a random path through the #InfectionState tree is chosen, that is
161 : * Susceptible -> InfectedNoSymptoms,
162 : * InfectedNoSymptoms -> InfectedSymptoms or InfectedNoSymptoms -> Recovered,
163 : * InfectedSymptoms -> Infected_Severe or InfectedSymptoms -> Recovered,
164 : * InfectedSevere -> InfectedCritical or InfectedSevere -> Recovered or InfectedSevere -> Dead,
165 : * InfectedCritical -> Recovered or InfectedCritical -> Dead,
166 : * with artifical, hardcoded probabilites, until either Recoverd or Dead is reached.
167 : * This is subject to change when parameter distributions for these transitions are implemented.
168 : * The duration in each #InfectionState is taken from the respective parameter.
169 : * @param[inout] rng PersonalRandomNumberGenerator of the Person.
170 : * @param[in] age AgeGroup of the Person.
171 : * @param[in] params Parameters of the Model.
172 : * @param[in] init_date Date of initializing the Infection.
173 : * @param[in] init_state #InfectionState at time of initializing the Infection.
174 : * @param[in] latest_protection Latest protection against Infection, has an influence on transition probabilities.
175 : */
176 : void draw_infection_course_forward(PersonalRandomNumberGenerator& rng, AgeGroup age, const Parameters& params,
177 : TimePoint init_date, InfectionState init_state,
178 : ProtectionEvent latest_protection);
179 :
180 : /**
181 : * @brief Determine Infection course prior to the given #InfectionState start_state.
182 : * From the start_state, a random path through the #InfectionState tree is chosen backwards, until Susceptible is reached.
183 : * For more detailed information, refer to draw_infection_course_forward.
184 : * @param[inout] rng PersonalRandomNumberGenerator of the Person.
185 : * @param[in] age AgeGroup of the person.
186 : * @param[in] params Parameters of the Model.
187 : * @param[in] init_date Date of initializing the Infection.
188 : * @param[in] init_state InfectionState at time of initializing the Infection.
189 : * @return The starting date of the Infection.
190 : */
191 : TimePoint draw_infection_course_backward(PersonalRandomNumberGenerator& rng, AgeGroup age, const Parameters& params,
192 : TimePoint init_date, InfectionState init_state);
193 :
194 : std::vector<std::pair<TimePoint, InfectionState>> m_infection_course; ///< Start date of each #InfectionState.
195 : VirusVariant m_virus_variant; ///< Variant of the Infection.
196 : ViralLoad m_viral_load; ///< ViralLoad of the Infection.
197 : ScalarType m_log_norm_alpha,
198 : m_log_norm_beta; ///< Parameters for the infectivity mapping, which is modelled through an invlogit function.
199 : bool m_detected; ///< Whether an Infection is detected or not.
200 : };
201 :
202 : } // namespace abm
203 : } // namespace mio
204 :
205 : #endif
|