Skip to content

Commit 049e8df

Browse files
kilianvolmerjubickerHenrZumknaranjaannawendler
authored
1224 extend read the docs documentation (#1231)
Co-authored-by: jubicker <[email protected]> Co-authored-by: HenrZu <[email protected]> Co-authored-by: Martin Joachim Kühn <[email protected]> Co-authored-by: Anna Wendler <[email protected]> Co-authored-by: MaxBetzDLR <[email protected]> Co-authored-by: Sascha Korf <[email protected]> Co-authored-by: reneSchm <[email protected]>
1 parent 004a774 commit 049e8df

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

65 files changed

+3359
-77
lines changed

README.md

+11-3
Original file line numberDiff line numberDiff line change
@@ -7,11 +7,19 @@
77

88
MEmilio implements various models for infectious disease dynamics, from simple compartmental models through Integro-Differential equation-based models to agent- or individual-based models. Its modular design allows the combination of different models with different mobility patterns. Through efficient implementation and parallelization, MEmilio brings cutting edge and compute intensive epidemiological models to a large scale, enabling a precise and high-resolution spatiotemporal infectious disease dynamics. MEmilio will be extended continuously. It is available open-source and we encourage everyone to make use of it.
99

10-
If you use MEmilio, please cite our works:
10+
If you use MEmilio, please cite our work
1111

12-
- Kühn, Martin Joachim und Abele, Daniel und Kerkmann, David und Korf, Sascha Alexander und Zunker, Henrik und Wendler, Anna Clara und Bicker, Julia und Nguyen, Dang Khoa und Klitz, Margrit und Koslow, Wadim und Siggel, Martin und Kleinert, Jan und Rack, Kathrin und Binder, Sebastian und Plötzke, Lena und Schmieding, René und Lenz, Patrick und Betz, Maximilian Franz und Lutz, Annette und Gerstein, Carlotta und Schmidt, Agatha und Meyer-Hermann, Michael und Basermann, Achim (2022) MEmilio - a high performance Modular EpideMIcs simuLatIOn software (2022). https://github.com/SciCompMod/memilio, https://elib.dlr.de/192140/.
12+
- Kühn, Martin Joachim et al. (2024). *MEmilio - a High Performance Modular Epidemics Simulation Software (2022)*. Available at `https://github.com/SciCompMod/memilio` and `https://elib.dlr.de/209739/`.
1313

14-
- Koslow W, Kühn MJ, Binder S, Klitz M, Abele D, et al. (2022) Appropriate relaxation of non-pharmaceutical interventions minimizes the risk of a resurgence in SARS-CoV-2 infections in spite of the Delta variant. PLOS Computational Biology 18(5): e1010054. https://doi.org/10.1371/journal.pcbi.1010054
14+
and, in particular, for
15+
16+
- Ordinary differential equation-based (ODE) and Graph-ODE models: Zunker H, Schmieding R, Kerkmann D, Schengen A, Diexer S, et al. (2024). *Novel travel time aware metapopulation models and multi-layer waning immunity for late-phase epidemic and endemic scenarios*. *PLOS Computational Biology* 20(12): e1012630. `https://doi.org/10.1371/journal.pcbi.1012630`
17+
- Integro-differential equation-based (IDE) models: Wendler AC, Plötzke L, Tritzschak H, Kühn MJ. (2024). *A nonstandard numerical scheme for a novel SECIR integro differential equation-based model with nonexponentially distributed stay times*. Submitted for publication. `https://arxiv.org/abs/2408.12228`
18+
- Agent-based models (ABMs): Kerkmann D, Korf S, Nguyen K, Abele D, Schengen A, et al. (2024). *Agent-based modeling for realistic reproduction of human mobility and contact behavior to evaluate test and isolation strategies in epidemic infectious disease spread*. arXiv. `https://arxiv.org/abs/2410.08050`
19+
- Hybrid agent-metapopulation-based models: Bicker J, Schmieding R, Meyer-Hermann M, Kühn MJ. (2025). *Hybrid metapopulation agent-based epidemiological models for efficient insight on the individual scale: A contribution to green computing*. *Infectious Disease Modelling* 10(2): 571-590. `https://doi.org/10.1016/j.idm.2024.12.015`
20+
- Graph Neural Networks: Schmidt A, Zunker H, Heinlein A, Kühn MJ. (2024). *Towards Graph Neural Network Surrogates Leveraging Mechanistic Expert Knowledge for Pandemic Response*. arXiv. `https://arxiv.org/abs/2411.06500`
21+
- ODE-based models with Linear Chain Trick: Plötzke L, Wendler A, Schmieding R, Kühn MJ. (2024). *Revisiting the Linear Chain Trick in epidemiological models: Implications of underlying assumptions for numerical solutions*. Submitted for publication. `https://doi.org/10.48550/arXiv.2412.09140`
22+
- Behavior-based ODE models: Zunker H, Dönges P, Lenz P, Contreras S, Kühn MJ. (2025). *Risk-mediated dynamic regulation of effective contacts de-synchronizes outbreaks in metapopulation epidemic models*. arXiv. `https://arxiv.org/abs/2502.14428`
1523

1624
**Getting started**
1725

cpp/models/sde_seirvv/model.h

+75-14
Original file line numberDiff line numberDiff line change
@@ -59,114 +59,175 @@ class Model : public FlowModel<ScalarType, InfectionState, Populations<ScalarTyp
5959
void get_flows(Eigen::Ref<const Eigen::VectorX<ScalarType>> pop, Eigen::Ref<const Eigen::VectorX<ScalarType>> y,
6060
ScalarType t, Eigen::Ref<Eigen::VectorX<ScalarType>> flows) const
6161
{
62+
std::cout << "calc flows" << std::endl;
6263
auto& params = this->parameters;
63-
params.get<ContactPatterns>().get_matrix_at(t)(0, 0);
64-
ScalarType coeffStoIV1 = params.get<ContactPatterns>().get_matrix_at(t)(0, 0) *
65-
params.get<TransmissionProbabilityOnContactV1>() / populations.get_total();
66-
ScalarType coeffStoIV2 = params.get<ContactPatterns>().get_matrix_at(t)(0, 0) *
67-
params.get<TransmissionProbabilityOnContactV2>() / populations.get_total();
6864

69-
// Normal distributed values for the stochastic part of the flows, variables are encoded
70-
// in the following way: x_y is the stochastic part for the flow from x to y. Variant
71-
// specific compartments also get an addendum v1 or v2 denoting the relevant variant.
65+
// Hole den Kontaktmuster-Wert aus der Matrix bei Zeit t
66+
ScalarType cp_val = params.get<ContactPatterns>().get_matrix_at(t)(0, 0);
67+
std::cout << "ContactPatterns value: " << cp_val << std::endl;
7268

69+
// Berechne Koeffizienten für die Transmission
70+
ScalarType coeffStoIV1 = cp_val * params.get<TransmissionProbabilityOnContactV1>() / populations.get_total();
71+
std::cout << "coeffStoIV1: " << coeffStoIV1 << std::endl;
72+
73+
ScalarType coeffStoIV2 = cp_val * params.get<TransmissionProbabilityOnContactV2>() / populations.get_total();
74+
std::cout << "coeffStoIV2: " << coeffStoIV2 << std::endl;
75+
76+
// Normalverteilte Zufallszahlen für den stochastischen Anteil der Flows
7377
ScalarType s_ev1 =
7478
mio::DistributionAdapter<std::normal_distribution<ScalarType>>::get_instance()(rng, 0.0, 1.0);
79+
std::cout << "s_ev1: " << s_ev1 << std::endl;
80+
7581
ScalarType s_ev2 =
7682
mio::DistributionAdapter<std::normal_distribution<ScalarType>>::get_instance()(rng, 0.0, 1.0);
83+
std::cout << "s_ev2: " << s_ev2 << std::endl;
84+
7785
ScalarType ev1_iv1 =
7886
mio::DistributionAdapter<std::normal_distribution<ScalarType>>::get_instance()(rng, 0.0, 1.0);
87+
std::cout << "ev1_iv1: " << ev1_iv1 << std::endl;
88+
7989
ScalarType ev2_iv2 =
8090
mio::DistributionAdapter<std::normal_distribution<ScalarType>>::get_instance()(rng, 0.0, 1.0);
91+
std::cout << "ev2_iv2: " << ev2_iv2 << std::endl;
92+
8193
ScalarType iv1_rv1 =
8294
mio::DistributionAdapter<std::normal_distribution<ScalarType>>::get_instance()(rng, 0.0, 1.0);
95+
std::cout << "iv1_rv1: " << iv1_rv1 << std::endl;
96+
8397
ScalarType iv2_rv2 =
8498
mio::DistributionAdapter<std::normal_distribution<ScalarType>>::get_instance()(rng, 0.0, 1.0);
99+
std::cout << "iv2_rv2: " << iv2_rv2 << std::endl;
100+
85101
ScalarType rv1_ev1v2 =
86102
mio::DistributionAdapter<std::normal_distribution<ScalarType>>::get_instance()(rng, 0.0, 1.0);
103+
std::cout << "rv1_ev1v2: " << rv1_ev1v2 << std::endl;
104+
87105
ScalarType ev1v2_iv1v2 =
88106
mio::DistributionAdapter<std::normal_distribution<ScalarType>>::get_instance()(rng, 0.0, 1.0);
107+
std::cout << "ev1v2_iv1v2: " << ev1v2_iv1v2 << std::endl;
108+
89109
ScalarType iv1v2_rv1v2 =
90110
mio::DistributionAdapter<std::normal_distribution<ScalarType>>::get_instance()(rng, 0.0, 1.0);
111+
std::cout << "iv1v2_rv1v2: " << iv1v2_rv1v2 << std::endl;
91112

92-
// Assuming that no person can change its InfectionState twice in a single time step,
93-
// take the minimum of the calculated flow and the source compartment, to ensure that
94-
// no compartment attains negative values.
113+
// Berechne Optimierungsgrößen
114+
ScalarType inv_step_size = 1.0 / step_size;
115+
std::cout << "inv_step_size: " << inv_step_size << std::endl;
95116

96-
// Calculate inv_step_size and inv_sqrt_step_size for optimization.
97-
ScalarType inv_step_size = 1.0 / step_size;
98117
ScalarType inv_sqrt_step_size = 1.0 / sqrt(step_size);
118+
std::cout << "inv_sqrt_step_size: " << inv_sqrt_step_size << std::endl;
99119

100-
// Two outgoing flows from S so will clamp their sum to S * inv_step_size to ensure non-negative S.
120+
// Berechne den ersten Outflow aus S
101121
const ScalarType outflow1 = std::clamp(
102122
coeffStoIV1 * y[(size_t)InfectionState::Susceptible] * pop[(size_t)InfectionState::InfectedV1] +
103123
sqrt(coeffStoIV1 * y[(size_t)InfectionState::Susceptible] * pop[(size_t)InfectionState::InfectedV1]) *
104124
inv_sqrt_step_size * s_ev1,
105125
0.0, y[(size_t)InfectionState::Susceptible] * inv_step_size);
126+
std::cout << "outflow1: " << outflow1 << std::endl;
106127

128+
// Berechne den zweiten Outflow aus S
107129
const ScalarType outflow2 =
108130
std::clamp(coeffStoIV1 * y[(size_t)InfectionState::Susceptible] *
109131
(pop[(size_t)InfectionState::InfectedV1V2] + pop[(size_t)InfectionState::InfectedV2]) +
110132
sqrt(coeffStoIV2 * y[(size_t)InfectionState::Susceptible] *
111133
(pop[(size_t)InfectionState::InfectedV1V2] + pop[(size_t)InfectionState::InfectedV2])) *
112134
inv_sqrt_step_size * s_ev2,
113135
0.0, y[(size_t)InfectionState::Susceptible] * inv_step_size);
136+
std::cout << "outflow2: " << outflow2 << std::endl;
114137

138+
// Summe der Outflows
115139
const ScalarType outflow_sum = outflow1 + outflow2;
140+
std::cout << "outflow_sum: " << outflow_sum << std::endl;
141+
116142
if (outflow_sum > 0) {
117143
const ScalarType scale =
118144
std::clamp(outflow_sum, 0.0, y[(size_t)InfectionState::Susceptible] * inv_step_size) / outflow_sum;
145+
std::cout << "scale: " << scale << std::endl;
119146
flows[get_flat_flow_index<InfectionState::Susceptible, InfectionState::ExposedV1>()] = outflow1 * scale;
147+
std::cout << "flow Sus -> ExpV1: "
148+
<< flows[get_flat_flow_index<InfectionState::Susceptible, InfectionState::ExposedV1>()]
149+
<< std::endl;
120150
flows[get_flat_flow_index<InfectionState::Susceptible, InfectionState::ExposedV2>()] = outflow2 * scale;
151+
std::cout << "flow Sus -> ExpV2: "
152+
<< flows[get_flat_flow_index<InfectionState::Susceptible, InfectionState::ExposedV2>()]
153+
<< std::endl;
121154
}
122155
else {
123156
flows[get_flat_flow_index<InfectionState::Susceptible, InfectionState::ExposedV1>()] = 0;
157+
std::cout << "flow Sus -> ExpV1 auf 0 gesetzt" << std::endl;
124158
flows[get_flat_flow_index<InfectionState::Susceptible, InfectionState::ExposedV2>()] = 0;
159+
std::cout << "flow Sus -> ExpV2 auf 0 gesetzt" << std::endl;
125160
}
126161

162+
// Fluss von ExposedV1 zu InfectedV1
127163
flows[get_flat_flow_index<InfectionState::ExposedV1, InfectionState::InfectedV1>()] =
128164
std::clamp((1.0 / params.get<TimeExposedV1>()) * y[(size_t)InfectionState::ExposedV1] +
129165
sqrt((1.0 / params.get<TimeExposedV1>()) * y[(size_t)InfectionState::ExposedV1]) *
130166
inv_sqrt_step_size * ev1_iv1,
131167
0.0, y[(size_t)InfectionState::ExposedV1] * inv_step_size);
168+
std::cout << "flow ExpV1 -> InfV1: "
169+
<< flows[get_flat_flow_index<InfectionState::ExposedV1, InfectionState::InfectedV1>()] << std::endl;
132170

171+
// Fluss von ExposedV2 zu InfectedV2
133172
flows[get_flat_flow_index<InfectionState::ExposedV2, InfectionState::InfectedV2>()] =
134173
std::clamp((1.0 / params.get<TimeExposedV2>()) * y[(size_t)InfectionState::ExposedV2] +
135174
sqrt((1.0 / params.get<TimeExposedV2>()) * y[(size_t)InfectionState::ExposedV2]) *
136175
inv_sqrt_step_size * ev2_iv2,
137176
0.0, y[(size_t)InfectionState::ExposedV2] * inv_step_size);
177+
std::cout << "flow ExpV2 -> InfV2: "
178+
<< flows[get_flat_flow_index<InfectionState::ExposedV2, InfectionState::InfectedV2>()] << std::endl;
138179

180+
// Fluss von InfectedV1 zu RecoveredV1
139181
flows[get_flat_flow_index<InfectionState::InfectedV1, InfectionState::RecoveredV1>()] =
140182
std::clamp((1.0 / params.get<TimeInfectedV1>()) * y[(size_t)InfectionState::InfectedV1] +
141183
sqrt((1.0 / params.get<TimeInfectedV1>()) * y[(size_t)InfectionState::InfectedV1]) *
142184
inv_sqrt_step_size * iv1_rv1,
143185
0.0, y[(size_t)InfectionState::InfectedV1] * inv_step_size);
186+
std::cout << "flow InfV1 -> RecV1: "
187+
<< flows[get_flat_flow_index<InfectionState::InfectedV1, InfectionState::RecoveredV1>()] << std::endl;
144188

189+
// Fluss von InfectedV2 zu RecoveredV2
145190
flows[get_flat_flow_index<InfectionState::InfectedV2, InfectionState::RecoveredV2>()] =
146191
std::clamp((1.0 / params.get<TimeInfectedV2>()) * y[(size_t)InfectionState::InfectedV2] +
147192
sqrt((1.0 / params.get<TimeInfectedV2>()) * y[(size_t)InfectionState::InfectedV2]) *
148193
inv_sqrt_step_size * iv2_rv2,
149194
0.0, y[(size_t)InfectionState::InfectedV2] * inv_step_size);
195+
std::cout << "flow InfV2 -> RecV2: "
196+
<< flows[get_flat_flow_index<InfectionState::InfectedV2, InfectionState::RecoveredV2>()] << std::endl;
150197

198+
// Fluss von RecoveredV1 zu ExposedV1V2
151199
flows[get_flat_flow_index<InfectionState::RecoveredV1, InfectionState::ExposedV1V2>()] =
152200
std::clamp(coeffStoIV2 * y[(size_t)InfectionState::RecoveredV1] *
153201
(pop[(size_t)InfectionState::InfectedV1V2] + pop[(size_t)InfectionState::InfectedV2]) +
154202
sqrt(coeffStoIV2 * y[(size_t)InfectionState::RecoveredV1] *
155203
(pop[(size_t)InfectionState::InfectedV1V2] + pop[(size_t)InfectionState::InfectedV2])) *
156204
inv_sqrt_step_size * rv1_ev1v2,
157205
0.0, y[(size_t)InfectionState::RecoveredV1] * inv_step_size);
206+
std::cout << "flow RecV1 -> ExpV1V2: "
207+
<< flows[get_flat_flow_index<InfectionState::RecoveredV1, InfectionState::ExposedV1V2>()]
208+
<< std::endl;
158209

210+
// Fluss von ExposedV1V2 zu InfectedV1V2
159211
flows[get_flat_flow_index<InfectionState::ExposedV1V2, InfectionState::InfectedV1V2>()] =
160212
std::clamp((1.0 / params.get<TimeExposedV2>()) * y[(size_t)InfectionState::ExposedV1V2] +
161213
sqrt((1.0 / params.get<TimeExposedV2>()) * y[(size_t)InfectionState::ExposedV1V2]) /
162214
sqrt(step_size) * ev1v2_iv1v2,
163215
0.0, y[(size_t)InfectionState::ExposedV1V2] * inv_step_size);
216+
std::cout << "flow ExpV1V2 -> InfV1V2: "
217+
<< flows[get_flat_flow_index<InfectionState::ExposedV1V2, InfectionState::InfectedV1V2>()]
218+
<< std::endl;
164219

220+
// Fluss von InfectedV1V2 zu RecoveredV1V2
165221
flows[get_flat_flow_index<InfectionState::InfectedV1V2, InfectionState::RecoveredV1V2>()] =
166222
std::clamp((1.0 / params.get<TimeInfectedV2>()) * y[(size_t)InfectionState::InfectedV1V2] +
167223
sqrt((1.0 / params.get<TimeInfectedV2>()) * y[(size_t)InfectionState::InfectedV1V2]) /
168224
sqrt(step_size) * iv1v2_rv1v2,
169225
0.0, y[(size_t)InfectionState::InfectedV1V2] * inv_step_size);
226+
std::cout << "flow InfV1V2 -> RecV1V2: "
227+
<< flows[get_flat_flow_index<InfectionState::InfectedV1V2, InfectionState::RecoveredV1V2>()]
228+
<< std::endl;
229+
230+
std::cout << "calc flows done" << std::endl;
170231
}
171232

172233
ScalarType step_size; ///< A step size of the model with which the stochastic process is realized.

docs/requirements.txt

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
sphinx==7.1.2
22
sphinx-rtd-theme==1.3.0rc1
3-
furo
43
sphinx-copybutton
4+
sphinx_design
55
breathe
66
sphinx-hoverxref
77
pycode/memilio-epidata

docs/source/_static/custom.css

+41
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
/* Newlines (\a) and spaces (\20) before each parameter
2+
.sig-param::before {
3+
content: "\a\20\20\20\20\20\20\20\20\20\20\20\20\20\20\20\20";
4+
white-space: pre;
5+
}
6+
7+
/* Newline after the last parameter (so the closing bracket is on a new line)
8+
dt em.sig-param:last-of-type::after {
9+
content: "\a";
10+
white-space: pre;
11+
}
12+
13+
/* To have blue background of width of the block (instead of width of content)
14+
dl.class > dt:first-of-type {
15+
display: block !important;
16+
} */
17+
18+
/* Take out pointless vertical whitespace in the signatures. */
19+
.rst-content dl .sig dl,
20+
.rst-content dl .sig dd {
21+
margin-bottom: 0;
22+
}
23+
24+
/* Make signature boxes full-width, with view-source and header links right-aligned. */
25+
.rst-content dl .sig {
26+
width: -webkit-fill-available;
27+
}
28+
.rst-content .viewcode-link {
29+
display: inline-flex;
30+
float: inline-end;
31+
margin-right: 1.5em;
32+
}
33+
.rst-content .headerlink {
34+
position: absolute;
35+
right: 0.5em;
36+
}
37+
38+
.wy-table-responsive table td,
39+
.wy-table-responsive table th {
40+
white-space: normal;
41+
}

docs/source/citation.rst

+16
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
Citing MEmilio
2+
===============
3+
4+
If you use MEmilio, please cite our work
5+
6+
- Kühn, Martin Joachim et al. (2024). *MEmilio - a High Performance Modular Epidemics Simulation Software (2022)*. Available at `https://github.com/SciCompMod/memilio <https://github.com/SciCompMod/memilio>`_ and `https://elib.dlr.de/209739/ <https://elib.dlr.de/209739/>`_.
7+
8+
and, in particular, for
9+
10+
- **Ordinary differential equation-based (ODE) and Graph-ODE models**: Zunker H, Schmieding R, Kerkmann D, Schengen A, Diexer S, et al. (2024). *Novel travel time aware metapopulation models and multi-layer waning immunity for late-phase epidemic and endemic scenarios*. *PLOS Computational Biology* 20(12): e1012630. `DOI:10.1371/journal.pcbi.1012630 <https://doi.org/10.1371/journal.pcbi.1012630>`_
11+
- **Integro-differential equation-based (IDE) models**: Wendler AC, Plötzke L, Tritzschak H, Kühn MJ. (2024). *A nonstandard numerical scheme for a novel SECIR integro differential equation-based model with nonexponentially distributed stay times*. Submitted for publication. `arXiv:2408.12228 <https://arxiv.org/abs/2408.12228>`_
12+
- **Agent-based models (ABMs)**: Kerkmann D, Korf S, Nguyen K, Abele D, Schengen A, et al. (2024). *Agent-based modeling for realistic reproduction of human mobility and contact behavior to evaluate test and isolation strategies in epidemic infectious disease spread*. arXiv. `arXiv:2410.08050 <https://arxiv.org/abs/2410.08050>`_
13+
- **Hybrid agent-metapopulation-based models**: Bicker J, Schmieding R, Meyer-Hermann M, Kühn MJ. (2025). *Hybrid metapopulation agent-based epidemiological models for efficient insight on the individual scale: A contribution to green computing*. *Infectious Disease Modelling* 10(2): 571-590. `DOI:10.1016/j.idm.2024.12.015 <https://doi.org/10.1016/j.idm.2024.12.015>`_
14+
- **Graph Neural Networks**: Schmidt A, Zunker H, Heinlein A, Kühn MJ. (2024).*Towards Graph Neural Network Surrogates Leveraging Mechanistic Expert Knowledge for Pandemic Response*. arXiv. `arXiv:2411.06500 <https://arxiv.org/abs/2411.06500>`_
15+
- **ODE-based models with Linear Chain Trick**: Plötzke L, Wendler A, Schmieding R, Kühn MJ. (2024). *Revisiting the Linear Chain Trick in epidemiological models: Implications of underlying assumptions for numerical solutions*. Submitted for publication. `DOI:10.48550/arXiv.2412.09140 <https://doi.org/10.48550/arXiv.2412.09140>`_
16+
- **Behavior-based ODE models**: Zunker H, Dönges P, Lenz P, Contreras S, Kühn MJ. (2025). *Risk-mediated dynamic regulation of effective contacts de-synchronizes outbreaks in metapopulation epidemic models*. arXiv. `arXiv:2502.14428 <https://arxiv.org/abs/2502.14428>`_

0 commit comments

Comments
 (0)