diff --git a/README.md b/README.md index 722e8423cf..ad4d164be7 100644 --- a/README.md +++ b/README.md @@ -19,7 +19,7 @@ and, in particular, for - 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` - 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` - 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` -- 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` +- 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*. *Chaos, Solitons & Fractals* 199:116782. `https://doi.org/10.1016/j.chaos.2025.116782` **Getting started** diff --git a/docs/source/citation.rst b/docs/source/citation.rst index a8e0a26779..bacc2c2a5d 100644 --- a/docs/source/citation.rst +++ b/docs/source/citation.rst @@ -3,7 +3,7 @@ Citing MEmilio If you use MEmilio, please cite our work -- Kühn, Martin Joachim et al. (2025). *MEmilio - a High Performance Modular Epidemics Simulation Software (2022)*. Available at `https://github.com/SciCompMod/memilio `_ and `https://elib.dlr.de/213614/ `_. +- Bicker J, Kerkmann D, Korf S, Ploetzke L, Schmieding R, Wendler A, Zunker H et al. (2025). *MEmilio - a High Performance Modular Epidemics Simulation Software*. Available at `https://github.com/SciCompMod/memilio `_ and `https://elib.dlr.de/213614/ `_. and, in particular, for @@ -13,4 +13,5 @@ and, in particular, for - **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 `_ - **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 `_ - **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 `_ -- **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 `_ +- **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*. *Chaos, Solitons & Fractals* 199:116782. `DOI:10.1016/j.chaos.2025.116782 `_ + diff --git a/docs/source/cpp/development.rst b/docs/source/cpp/development.rst index ff19249dae..d6c7813d87 100644 --- a/docs/source/cpp/development.rst +++ b/docs/source/cpp/development.rst @@ -1,10 +1,10 @@ Development -================================= +=========== .. _performance-monitoring-cpp: Performance monitoring ---------------------------------- +---------------------- LIKWID ~~~~~~ @@ -30,11 +30,15 @@ Set the CMake variable ``MEMILIO_USE_LIKWID=ON`` to enable LIKWID support and ru For more details see the LIKWID documentation, available `here `_. Agent-based model benchmarks -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -There is a suite of benchmarks for the ABM that can be used to check performance. The suite contains setups of different sizes. If you added a new feature (i.e., you didn't just fix a bug in an existing feature), make sure the feature is actually used by the benchmark. Add it to the benchmark if necessary, then run the benchmark to see if the cost for the new feature is acceptable and as expected. +There is a suite of benchmarks for the ABM that are used to check its performance. The suite contains setups of different sizes, to check that the model maintains its linear scaling. -Most new features will add some overhead, but this needs to be limited and in proportion to the added value of the feature so runtime doesn't grow out of control. Optional features that can be disabled should only incur minimal overhead. If you did not add any new feature, just run the benchmark before and after your changes to make sure there are no performance regressions. This process will hopefully be automated soon by running benchmarks in the CI. +When you make any changes to the ABM or code used by it, run the benchmarks to check that its performance did not degrade. What exactly impacts the ABM's performance can be hard to tell (even parameter values may change its runtime), so it is best to run the bencharks on any change to the main library or the ABM specific code. + +If you added a new feature (i.e., you didn't just fix a bug in an existing feature), make sure the feature is actually used by the benchmark. Add it to the benchmark if necessary, then run the benchmark to see if the cost for the new feature is acceptable and as expected. + +Most new features will add some overhead, but this needs to be limited and in proportion to the added value of the feature so runtime doesn't grow out of control. Optional features that can be disabled should only incur minimal overhead. Always make sure there are no major performance regressions compared to the code in the current *main* branch. Build the benchmarks by defining the CMake variable ``MEMILIO_BUILD_BENCHMARKS=ON`` in the build. Make sure to use a **Release** build to test performance. @@ -91,6 +95,10 @@ However, it can be expensive because long-running benchmarks are repeated. **Suggested workflow:** -1. Run with 5–10 repetitions to check variance. -2. Increase ``benchmark_min_time`` until variance is acceptable. -3. Continue benchmarking with 1 repetition and the adjusted minimum time. \ No newline at end of file +1. Use the benchmark to check the performance of your current changes: + + 1. Run with 5–10 repetitions to check variance. + 2. Increase ``benchmark_min_time`` until variance is acceptable. + 3. Continue benchmarking with 1 repetition and the adjusted minimum time. + +2. Repeat the benchmark *on the main branch* with the same ``benchmark_min_time`` and compare the results. diff --git a/docs/source/cpp/diffusive_abm.rst b/docs/source/cpp/diffusive_abm.rst index dd2413ddcd..6d7c9c285d 100644 --- a/docs/source/cpp/diffusive_abm.rst +++ b/docs/source/cpp/diffusive_abm.rst @@ -122,7 +122,7 @@ There are no non-pharmaceutical interventions (NPIs) explicitly implemented in t .. code-block:: cpp //Reduce the transmission risk by 10% - model.get_adoption_rates().at({mio::mpm::Region(0), Status::S, Status::E}).factor *= 0.9; + model.get_adoption_rates().at({mio::regions::Region(0), Status::S, Status::E}).factor *= 0.9; Simulation ----------- diff --git a/docs/source/cpp/glct.rst b/docs/source/cpp/glct.rst index e0d1639e19..7735c457b7 100644 --- a/docs/source/cpp/glct.rst +++ b/docs/source/cpp/glct.rst @@ -1,10 +1,10 @@ Generalized Linear Chain Trick model ==================================== -MEmilio implements a SECIR-type model utilizing the Generalized Linear Chain Trick (GLCT). This is a generalization of -the LCT model and allows for phase-type distributed stay times in the compartments. Phase-type distributions are dense +MEmilio implements a SECIR-type model utilizing the Generalized Linear Chain Trick (GLCT). This is a generalization of +the LCT model. In contrast to simpler ODE models that assume (possibly unrealistic) exponentially distributed stay times, the GLCT allows for more realistic, phase-type distributed stay times in the compartments through the use of subcompartments. Phase-type distributions are dense in the field of all positive-valued distributions. Therefore, for any positive-valued distribution, a phase-type -distribution of arbitrary precision can be identified. Note that the resulting system can still be described by ODEs. +distribution of arbitrary precision can be identified. Note that the resulting system can still be described by an ordinary differential equation system. In the following, we present the general structure of the GLCT model. The particular model documentation with examples is linked at the bottom of this page. @@ -12,7 +12,7 @@ is linked at the bottom of this page. Infection states ---------------- -The model contains a list of **InfectionState**\s that define particular features of the subpopulations in the particular state. +The model contains a list of **InfectionState**s that define particular features of the subpopulations in the particular state. .. code-block:: RST @@ -43,10 +43,10 @@ a set of contact matrices of arbitrary length and which can represent the differ schools, workplaces, or homes. The matrices can be loaded or stored in the particular example. In the **ContactPatterns**, each matrix element stores baseline contact rates :math:`c_{i,j}` between sociodemographic group :math:`i` to group :math:`j`. The dimension of the matrix is automatically defined by the model initiation and it is reduced -to one value if no stratifcation is used. The values can be adjusted during the simulation, e.g., through implementing +to one value if no stratification is used. The values can be adjusted during the simulation, e.g., through implementing nonpharmaceutical interventions, see the section on :ref:`Nonpharmaceutical Interventions`. -Parameters can get accessed via ``model.parameters.get>()`` and set via either -``model.parameters.get>() = value`` or ``model.parameters.set>(value)``. +Parameters can be accessed via ``model.parameters.get>()`` and set via either +``model.parameters.set>(value)`` or ``model.parameters.get>() = value``. Initial conditions @@ -114,17 +114,6 @@ and its documentation. In the following, we give detailed explanations of the GLCT-SECIR model. -Introduction -------------- - -This model is based on the Generalized Linear Chain Trick (GLCT). - -The GLCT provides the option to use phase-type distributed stay times in the compartments through the use of subcompartments. The Generalized Linear Chain Trick is an extension of the Linear Chain Trick (as the name already suggests). Phase-type distributions are dense in the field of all positive-valued distributions. Therefore, for any positive-valued distribution, a phase-type distribution of arbitrary precision can be identified. -The normal ODE models have (possibly unrealistic) exponentially distributed stay times. -The GLCT model can still be described by an ordinary differential equation system. - - - List of models ----------------------------- diff --git a/docs/source/cpp/io.rst b/docs/source/cpp/io.rst index 325cac418a..a48b5500fb 100644 --- a/docs/source/cpp/io.rst +++ b/docs/source/cpp/io.rst @@ -6,7 +6,7 @@ This document describes utilities for reading and writing data from and to files - The serialization framework, that can be used to define the structure of data without using a specific file format. There are implementations of the framework for different formats. The framework is described in detail below, also - see the `serialization example <../../examples/serialize.cpp>`__. + see the `serialization example `__. - The command line interface, that can be used to set (and get) values of a ``ParameterSet``. @@ -101,7 +101,7 @@ The default serialization is intentionally less flexible than the serialize and - Every class member itself must be serializable, deserializable and assignable. -This feature is primarily meant to make data classes easy to (de)serialize, avoiding some repitition that is necessary +This feature is primarily meant to make data classes easy to (de)serialize, avoiding some repetition that is necessary when writing both a serialize and deserialize function. It can, however, be used for any class that should be serialized in its entirety, and that does not need to make any decisions or computations while doing so. For example, default serialization cannot be used if your class has optional members or values, or if one of its members is stored @@ -272,8 +272,8 @@ Working with the History object The History object provides a way to save data throughout the simulation process. It offers an interface where users can define the data to be saved from a given object using Loggers and the method of saving it using Writers. Afterward, the user can access this data from the History object and manipulate it. For a basic Logger use case, refer to -`this example <../../examples/history.cpp>`__. For an example demonstrating using a Logger in the ABM, refer to -`this example <../../examples/abm_history_example.cpp>`__. +`this example `__. For an example demonstrating using a Logger in the ABM, refer to +`this example `__. Loggers ~~~~~~~ @@ -293,7 +293,7 @@ functions is the same as the one given to the ``History`` member-function ``Hist Users can derive their Loggers from ``LogOnce`` or ``LogAlways`` to use a predefined ``should_log`` function. ``LogOnce`` logs only at the first call of ``Logger::log()``, while ``LogAlways`` logs every time ``log`` is called. All implemented Loggers must be default constructible/destructible. For user-defined examples in the ABM, refer to -`this file <../../models/abm/common_abm_loggers.h>`__. +`this file `__. .. code-block:: cpp @@ -324,9 +324,9 @@ user-implemented ``Writer`` must have a ``Data`` Type and implement the - ``add_record``: This manipulates the passed Data member of the ``History`` class to store the value ``t`` returned by the Loggers. It is used whenever ``History::log`` is called and ``Logger::should_log`` is true. -A predefined universal ``Writer`` called ``DataWriterToMemory`` is already implemented in `history.h `__. +A predefined universal ``Writer`` called ``DataWriterToMemory`` is already implemented in `history.h `__. This stores the data from the loggers in a tuple of vectors every time the Logger is called. Another ``Writer`` named -``TimeSeriesWriter`` can be found in `this file <../../models/abm/common_abm_loggers.h>`__, which saves data in a +``TimeSeriesWriter`` can be found in `this file `__, which saves data in a Timeseries. The according Logger has to have a suitable return type. .. code-block:: cpp @@ -354,9 +354,9 @@ For this, the lifetime of the ``History`` has to be as long as one wants to have should not be constructed in the function it is called in when data is needed later. To access data from a specific Logger, one can use ``std::get`` where x is the position of the Logger in the template -argument list of the ``History`` object. Refer to `this example <../../examples/history.cpp>`__ for a simple -implementation of a history object and `this full ABM example <../../simulation/abm.cpp>`__ for a more advanced use case +argument list of the ``History`` object. Refer to `this example `__ for a simple +implementation of a history object and `this full ABM example `__ for a more advanced use case of the History object with several History objects in use. As mentioned, if multiple Writers have to be used simultaneously, a separate History object is needed for each Writer. -For a use case of this, refer to `the ABM Simulation advance function <../../models/abm/simulation.cpp>`__. +For a use case of this, refer to `the ABM Simulation advance function `__. diff --git a/docs/source/cpp/lct.rst b/docs/source/cpp/lct.rst index c4b27dfd47..58741d5173 100644 --- a/docs/source/cpp/lct.rst +++ b/docs/source/cpp/lct.rst @@ -12,7 +12,7 @@ is linked at the bottom of this page. Infection states ---------------- -The model contains a list of **InfectionState**\s that define particular features of the subpopulations in the particular state. +The model contains a list of **InfectionState**s that define particular features of the subpopulations in the particular state. .. code-block:: RST @@ -51,9 +51,9 @@ a set of contact matrices of arbitrary length and which can represent the differ schools, workplaces, or homes. The matrices can be loaded or stored in the particular example. In the **ContactPatterns**, each matrix element stores baseline contact rates :math:`c_{i,j}` between sociodemographic group :math:`i` to group :math:`j`. The dimension of the matrix is automatically defined by the model initiation and it is reduced -to one value if no stratifcation is used. The values can be adjusted during the simulation, e.g., through implementing +to one value if no stratification is used. The values can be adjusted during the simulation, e.g., through implementing nonpharmaceutical interventions, see the section on :ref:`Nonpharmaceutical Interventions`. -Parameters can get accessed via ``model.parameters.get>()`` and set via either +Parameters can be accessed via ``model.parameters.get>()`` and set via either ``model.parameters.get>() = value`` or ``model.parameters.set>(value)``. diff --git a/docs/source/cpp/lct_creation.rst b/docs/source/cpp/lct_creation.rst index c487cc3849..4013760d0d 100644 --- a/docs/source/cpp/lct_creation.rst +++ b/docs/source/cpp/lct_creation.rst @@ -4,16 +4,16 @@ LCT model creation The mathematical model ---------------------- -Before implementing a model in MEmilio, we need to do a some math, in particular, define an initial value problem -given by a system of ordinary differential equations. In the here considered example, we consider a SIRD model where we -divide the Infectious compartment into :math`n` subcompartments. The model is defined by +Before implementing a model in MEmilio, we need to do some math, in particular, define an initial value problem +given by a system of ordinary differential equations. Here, we consider a SIRD model where we +divide the Infectious compartment into :math:`n` subcompartments. The model is defined by .. math:: \begin{aligned} - S'(t) & = -\rho\phi\ \frac{S(t)*I(t)}{N_{\perp D}} \\ - I_1'(t) & = \rho\phi\ \frac{S(t)*I(t)}{N_{\perp D}} - \frac{n}{T_I}I_1(t) \\ - I_j'(t) & = \frac{n}{T_I}I_{j-1}(t) - \frac{n}{T_I}I_j(t) \quad \text{for } j\in\{2,\dots,n}\\ + S'(t) & = -\rho\phi\ \frac{S(t)I(t)}{N_{\perp D}} \\ + I_1'(t) & = \rho\phi\ \frac{S(t)I(t)}{N_{\perp D}} - \frac{n}{T_I}I_1(t) \\ + I_j'(t) & = \frac{n}{T_I}I_{j-1}(t) - \frac{n}{T_I}I_j(t) \quad \text{for } j\in\{2,\dots,n\}\\ R'(t) & = \frac{\mu_R}{T_I}I(t) \\ D'(t) & = \frac{\mu_D}{T_I}I(t) \\ \end{aligned} @@ -21,7 +21,7 @@ divide the Infectious compartment into :math`n` subcompartments. The model is de with :math:`I(t) = \sum_{j=1}^n I_j(t)` and some initial values for :math:`t=0`. Here :math:`N_{\perp D} := S(t) + I(t) + R(t)`. This type of model belongs to the class of compartmental models because the model population is represented by discrete infection -states **S** usceptible, **I** nfectious, **R** ecovered, **D** eceased, also called compartments. +states **S**\usceptible, **I**\nfectious, **R**\ecovered, **D**\eceased, also called compartments. Infection states ~~~~~~~~~~~~~~~~ @@ -46,7 +46,7 @@ Parameters Next, we define the parameters in "parameters.h", which consist of a struct for each constant used in the mathematical model. This struct must define the data type, name and default value of the constant. For example, for the time a -person stays infectious :math:`T_I` we define a struct +person stays infectious, :math:`T_I`, we define a struct: .. code-block:: cpp @@ -65,30 +65,31 @@ person stays infectious :math:`T_I` we define a struct } }; -and for the contact rate :math:`\phi` a struct -We also define a parameter ``ContactPatterns`` determining the contacts of the different groups by +We also define a parameter ``ContactPatterns`` determining the contacts of the different groups by: .. code-block:: cpp struct ContactPatterns { - using Type = UncertainContactMatrix; + using Type = UncertainContactMatrix; - static Type get_default() - { - mio::ContactMatrixGroup contact_matrix(1, 1); - contact_matrix[0] = mio::ContactMatrix(Eigen::MatrixXd::Constant(1, 1, 10.)); - return Type(contact_matrix); - } - static std::string name() - { - return "ContactPatterns"; - } + static Type get_default() + { + mio::ContactMatrixGroup contact_matrix(1, 1); + contact_matrix[0] = mio::ContactMatrix(Eigen::MatrixXd::Constant(1, 1, 10.)); + return Type(contact_matrix); + } + static std::string name() + { + return "ContactPatterns"; + } }; -Avoid using the mathematical symbols of the constant as names for the struct. Their connection can be noted in the +Avoid using the mathematical symbol of a constant as name for the struct. Their connection can be noted down in the documentation of these structs. -Additionally, we can determine parameters influencing the infection dynamics. In the case of the LCT-SECIR model we use the parameters ``TransmissionProbabilityOnContact``, ``RelativeTransmissionNoSymptoms``, ``RiskOfInfectionFromSymptomatic``, ``StartDay`` and ``Seasonality``. For each parameter, we need to define a default value and a name as for the above parameters. +Additionally, we can determine parameters influencing the infection dynamics. In the case of the LCT-SECIR model we use +the parameters ``TransmissionProbabilityOnContact``, ``RelativeTransmissionNoSymptoms``, ``RiskOfInfectionFromSymptomatic``, ``StartDay`` and ``Seasonality``. +For each parameter, we need to define a default value and a name as for the above parameters. Finally, define a type :code:`Parameters` by listing all parameter structs as template arguments of a :code:`mio::ParameterSet`: @@ -107,14 +108,14 @@ Population ~~~~~~~~~~ The population will be stored in a vector, with a component for each subcompartment of every infection state. We define -it using the class **LctPopulations**. +it using the class ``LctPopulations``. .. code-block:: cpp template using Population = mio::LctPopulations; -where **LctStates** contains the number of subcompartments per infection state. +where ``LctStates`` contains the number of subcompartments per infection state. Importantly, this class allows further stratifying the population vector, with the most common example being adding age groups. @@ -144,25 +145,25 @@ Now we can define the model as a **CompartmentalModel** in the file model.h: const auto N = y[InfectionState::Susceptible] + y[InfectionState::Infectious] + y[InfectionState::Recovered]; - dydt[InfectionState::Susceptible] = params.template get>() * - params.template get>() * - y[InfectionState::Susceptible] * y[InfectionState::Infectious] / N; + dydt[InfectionState::Susceptible] = -params.template get>() * + params.template get>() * + y[InfectionState::Susceptible] * y[InfectionState::Infectious] / N; . . . } + }; -Note that this class has a template parameter **LctStates** that defines the number of subcompartments per infection state. -For LCT models, the class **CompartmentalModel** requires the following template arguments: +Note that this class has a template parameter ``LctStates`` that defines the number of subcompartments per infection state. +For LCT models, the class ``CompartmentalModel`` requires the following template arguments: -- type of floating point type, here **ScalarType**, -- a class **InfectionState** containing the compartments, see above, -- the class **LctPopulations** which is a class template for compartment populations of LCT models depending on the floating point type and the considered **LctStates**, -- the class **Parameters** containing all required parameters, see above. +- type of floating point type, here ``ScalarType``, +- a class ``InfectionState`` containing the compartments, see above, +- the class ``LctPopulations`` which is a class template for compartment populations of LCT models depending on the floating point type and the considered ``LctStates``, +- the class ``Parameters`` containing all required parameters, see above. The function ``get_derivatives()`` evaluates the right-hand-side of the ODE :math:`dydt = f(y, t)` that we want to solve, see above. It is also useful to implement the following methods within the model: -- A function ``calculate_compartments()`` that accumulates the TimeSeries containing simulation results that are divided -into subcompartments to a TimeSeries that conatins the simulation results according to the infection states without subcompartments. -- A function ``check_constraints()`` that checks that the model satisfies sensible constraints regarding parameters and initial conditions. \ No newline at end of file +- A function ``calculate_compartments()`` that accumulates the TimeSeries containing simulation results that are divided into subcompartments to a TimeSeries that conatins the simulation results according to the infection states without subcompartments. +- A function ``check_constraints()`` that checks that the model satisfies sensible constraints regarding parameters and initial conditions. diff --git a/docs/source/cpp/model_creation.rst b/docs/source/cpp/model_creation.rst index f6cec88541..5d4f6e1242 100644 --- a/docs/source/cpp/model_creation.rst +++ b/docs/source/cpp/model_creation.rst @@ -10,5 +10,5 @@ Here we collect information on how to create models. Ordinary differential equations Linear Chain Trick Stochastic-differential equations - Integro-differenatial equations + Integro-differential equations \ No newline at end of file diff --git a/docs/source/cpp/ode_creation.rst b/docs/source/cpp/ode_creation.rst index eacbb564b3..d71f86d0f4 100644 --- a/docs/source/cpp/ode_creation.rst +++ b/docs/source/cpp/ode_creation.rst @@ -19,12 +19,12 @@ given by a system of ordinary differential equations. For example we consider a and some initial values for :math:`t=0`. Here :math:`N_{\perp D} := S(t) + I(t) + R(t)`. This type of model is called compartmental model, because the model population is represented by discrete infection -states **S** usceptible, **I** nfectious, **R** ecovered, **D** eceased, also called compartments. +states **S**\usceptible, **I**\nfectious, **R**\ecovered, **D**\eceased, also called compartments. How to define an ODE model -------------------------- -To define an ODE model in MEmilio, there are two options. You can define a CompartmentalModel or FlowModel, which +To define an ODE model in MEmilio, there are two options. You can define a CompartmentalModel or a FlowModel, which use different methods to define the right hand side of the mathematical model above. Both classes need definitions for the infection states, population and parameters it uses. The FlowModel additionally requires a list of flows. @@ -35,9 +35,9 @@ other noteworthy features of the model in shortened form. All files in the follo Infection states ~~~~~~~~~~~~~~~~ -First we define an :code:`enum class` called InfectionState in the file "infection_state.h", which contains an entry +First we define an :code:`enum class` called ``InfectionState`` in the file "infection_state.h", which contains an entry for each infection state of the mathematical model, followed by an entry called :code:`Count`. This enumerates the -compartments starting from 0, with Count being equal to the number of compartments. For example: +compartments starting from 0, with Count being equal to the number of compartments. In our example we have: .. code-block:: cpp @@ -55,7 +55,7 @@ Parameters Next, we define the parameters in "parameters.h", which consist of a struct for each constant used in the mathematical model. This struct must define the data type, name and default value of the constant. For example, for the time a -person stays infectious :math:`T_I` we define a struct +person stays infectious, :math:`T_I`, we define a struct .. code-block:: cpp @@ -113,7 +113,7 @@ Population ~~~~~~~~~~ The population will be stored in a vector, with a component for each infection state. We define it using the class -`mio::Population`. +``mio::Population``. .. code-block:: cpp @@ -146,7 +146,7 @@ Now we can define the model: const auto N = y[InfectionState::Susceptible] + y[InfectionState::Infectious] + y[InfectionState::Recovered]; - dydt[InfectionState::Susceptible] = params.template get>() * + dydt[InfectionState::Susceptible] = -params.template get>() * params.template get>() * y[InfectionState::Susceptible] * y[InfectionState::Infectious] / N; @@ -221,4 +221,4 @@ With the flows and classes also used by the CompartmentalModel, we can define a . . . } - }; \ No newline at end of file + }; diff --git a/docs/source/cpp/smm.rst b/docs/source/cpp/smm.rst index 0fdb670adf..f1892f530f 100644 --- a/docs/source/cpp/smm.rst +++ b/docs/source/cpp/smm.rst @@ -53,9 +53,9 @@ Using the infection states from above and two regions, there are five first-orde adoption_rates.push_back({InfectionState::I, InfectionState::D, mio::regions::Region(r), 0.01 / 5., {}}); } - //Set second-order adoption rate different for the two regions + //Set second-order adoption rate different for the two regions adoption_rates.push_back({InfectionState::S, InfectionState::E, mio::regions::Region(0), 0.1, {{InfectionState::C, 1}, {InfectionState::I, 0.5}}}); - adoption_rates.push_back({InfectionState::S, InfectionState::E, mio::regions::Region(0), 0.2, {{InfectionState::C, 1}, {InfectionState::I, 0.5}}}); + adoption_rates.push_back({InfectionState::S, InfectionState::E, mio::regions::Region(1), 0.2, {{InfectionState::C, 1}, {InfectionState::I, 0.5}}}); //Initialize model parameter model.parameters.get>() = adoption_rates; @@ -95,7 +95,7 @@ These populations have the class type **Populations** and can be set via: .. code-block:: cpp - double pop = 1000, numE = 0.001 * pop, numC = 0.0001 * pop, numI = 0.0001 * pop; + double pop = 1000, numE = 0.001 * pop, numC = 0.0001 * pop, numI = 0.0001 * pop, numR = 0, numD = 0; //Population is distributed equally to the regions for (size_t r = 0; r < num_regions; ++r) { @@ -118,11 +118,11 @@ As the spatial transition rates are dependent on infection state, region changes for (size_t i = 0; i < num_regions; ++i) { for (size_t j = 0; j < num_regions; ++j) if (i != j) { - transition_rates.push_back( - {InfectionState(s), mio::regions::Region(i), mio::regions::Region(j), 0.01}); - transition_rates.push_back( - {InfectionState(s), mio::regions::Region(j), mio::regions::Region(i), 0.01}); - } + transition_rates.push_back( + {InfectionState(s), mio::regions::Region(i), mio::regions::Region(j), 0.01}); + transition_rates.push_back( + {InfectionState(s), mio::regions::Region(j), mio::regions::Region(i), 0.01}); + } } } diff --git a/docs/source/development.rst b/docs/source/development.rst index 53a96e105e..0fb2dd7e2d 100644 --- a/docs/source/development.rst +++ b/docs/source/development.rst @@ -237,6 +237,32 @@ to your corresponding ``settings.json``. Docstrings in Python should be added for every function, as detailed in the C++ coding guidelines. However, the syntax is slightly different than for C++ code. An overview and examples can be found at https://sphinx-rtd-tutorial.readthedocs.io/en/latest/docstrings.html . +Figure colors and settings +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +In order to ensure that figures in the documentation and in the code have a consistent look, we use the following settings: + +**Default color scheme** + +- For figures in the documentation, we usually use the `matplotlib `_ library. +- The default color cycle is set to the `Set1 `_ colormap. + +**Colorblind-friendly alternatives** + +For better accessibility and when creating figures with many categories, consider using colorblind-friendly alternatives: + +- Use the `tab10 `_ colormap for up to 10 distinct categories +- For sequential data, prefer `viridis `_, `plasma`, or `cividis` colormaps +- For diverging data, use `RdBu `_ or `RdYlBu` colormaps +- Avoid using red-green color combinations without additional visual cues (patterns, shapes, etc.) + +**General figure guidelines** + +- Use consistent font sizes across all figures (typically 10-12pt for labels, 8-10pt for tick labels) +- Ensure sufficient contrast between colors and background +- Add appropriate legends and axis labels with units +- For line plots with multiple series, vary both color and line style (solid, dashed, dotted) for better distinction +- When possible, test figures with a colorblind simulator to ensure accessibility Git workflow ---------------------- diff --git a/docs/source/getting_started.rst b/docs/source/getting_started.rst index 364a3192c5..cce7cf2fa5 100644 --- a/docs/source/getting_started.rst +++ b/docs/source/getting_started.rst @@ -7,21 +7,23 @@ Overview .. note:: This project is under active development. -MEmilio is an extensive framework for tasks around infectious disease modelling. It supports various :ref:`model ` types +MEmilio is an extensive framework for tasks around infectious disease modeling. It supports a multitude of :ref:`model ` types including :doc:`equation-based`, :doc:`agent-based `, -and :doc:`hybrid graph-ODE-based models ` as well as data integration and visualizations. +and :doc:`hybrid graph-ODE-based models `. It furthermore provides ready-to-use tools for data integration and visualizations. Among the equation-based models, we provide models based on :doc:`ordinary differential equations `, -:doc:`the linear chain trick, ` and its :doc:`generalisation `, :doc:`integro-differential equations ` -and :doc:`stochastic differential equations `. The MEmilio framework is written in two languages: C++ and Python. +:doc:`the linear chain trick (LCT), ` and a recent :doc:`generalized LCT `, :doc:`integro-differential equations ` +and :doc:`stochastic differential equations `. With simple definitions, models can be spatially or demographically resolved. -- The C++ backend powers the model and simulation components for optimal efficiency. -- Data acquisition, plotting, and machine-learning models are handled via Python. +The MEmilio framework is written in two languages: C++ and Python. -For more details on the C++ implementation, see the sections on :doc:`model usage ` if you are interested -in using or applying our models and :doc:`model creation ` if you want to write new models inside our framework. +- The C++ backend contains efficient and optimized model implementations that further use parallelization to speed up execution and reduce waiting times. +- Python is used for data acquisition, plotting, and machine-learning models. +- We, furthermore, provide Python interfaces to selected models (implemented in C++) to allow the use and study of advanced models by users less experience in programming or computer science. -If you prefer using Python, you can use our :doc:`memilio-simulation ` package to run simulations -in our C++ backend; this package uses ``pybind11`` to bind our C++ model code. +For more details on using models implemented in C++ directly, see the sections on :doc:`model usage `. +For more details on implementing new infection dynamics models that could then be combined with, e.g., our mobility patterns, see :doc:`model creation `. + +If you prefer using Python to call or run our models, you can use our :doc:`memilio-simulation ` package to run simulations. The :doc:`memilio-epidata ` package provides tools to download and structure important data such as infection or mobility data. More about this and our other Python packages can be found in the :doc:`Python Interface Section ` of this documentation. @@ -37,43 +39,140 @@ Usage .. _installation: Installation -~~~~~~~~~~~~~ +~~~~~~~~~~~~ + +There are two main ways to set up MEmilio on your computer or on a remote cluster or supercomputer, depending on what you want to do: + +1. **Using the Python packages:** This is the recommended path for many users not familiar with C++. Here, you can run simulations using python bindings. +2. **Directly building the C++ Core:** This is for developers who want to modify the functionality, contribute new models etc. by running C++ code directly. + +In addition, we provide several Python packages to download epidemiological data or create plots from Python. + +Below, we will give you a step-by-step guide for both methods. If you are new to MEmilio and more familiar with Python, Julia, or R than with C++, we recommend starting with the Python packages, +as they provide an easy access to simulate infection dynamics models from and collect experiences with MEmilio. + +Required Tools +***************** + +Before you can install MEmilio, you need to install some common development tools. + +* **Git:** This is a version control system used to download the project's source code. + + * **Windows:** By default, Git is not installed. Download and install it from `git-scm.com `_. + * **macOS & Linux:** Git is usually preinstalled. You can check by opening a terminal and typing ``git --version``. + +* **Python:** Required for the Python packages. + + * MEmilio is tested daily with Python 3.8 and 3.11. While other versions might also work, we recommend installing the latest version tested daily from the official website `python.org `_. + +* **C++ Compiler and CMake:** + + * **Windows:** The easiest way is to install **Visual Studio Community**. This includes a C++ compiler, CMake, and Git all in one. + * **macOS:** One option is installing the **Xcode Command Line Tools** by running ``xcode-select --install`` in your terminal. + * **Linux:** On Linux, essential build tools and CMake might be preinstalled. Otherwise, on Debian/Ubuntu, you could execute the installation by running ``sudo apt-get install cmake gcc g++`` in your terminal. -You can download the latest code version of MEmilio from our `github repository `_ -in a Linux terminal via: +Step 1: Download the MEmilio Source Code +***************************************** + +Once the required tools are installed, open a terminal and download the MEmilio code with this command: .. code-block:: console git clone https://github.com/SciCompMod/memilio.git -You can now build the C++ code: +This command copies the entire MEmilio project into a new folder named ``memilio`` on your computer. -.. code-block:: console +.. note:: A Quick Note on HTTPS vs. SSH - cd memilio/cpp - mkdir build && cd build - cmake .. - cmake --build . + The ``git clone`` command above uses an **HTTPS** URL. This is the simplest method and works perfectly for downloading the code. -For details on the possible compile flags, help with errors and general a more detailed instruction, see the -:doc:`C++-interface ` section of this documentation. + However, if you plan to contribute code back to the project (i.e., "push" your changes), we recommend using **SSH**. To set this up, you can follow `GitHub's official guide on adding an SSH key `_. -For the installation of Python packages, e.g. ``memilio-epidata``, do + +Now, navigate into that folder: .. code-block:: console - - cd memilio/pycode - cd memilio-epidata - pip install . - -For more information, we refere to the :ref:`Python Interace Part ` of this documentation. + cd memilio + +From here, choose one of the following options. + +Option A: Installing the Python Packages (Recommended for nonexperienced users or for data download and visualizations) +**************************************************** + +You can run simulations, download data, or create plots, by only installing our Python packages. + +1. Navigate to the directory containing our Python code: + + .. code-block:: console + + cd pycode + +2. To install the simulation package ``memilio-simulation``, from here you can do: + + .. code-block:: console + + cd memilio-simulation + pip install -e . + +3. For afterwards installing the ``memilio-epidata`` package for data downloading and handling, run: + + .. code-block:: console + + cd .. # Go back to the pycode directory + cd memilio-epidata + pip install -e . + +.. tip:: For Contributors: Installing development packages + + The ``-e`` flag installs the package in a mode, which links the installation to your local source code folder. + + If you plan to contribute to MEmilio, you can also install all the necessary development dependencies by adding ``[dev]`` to the command: + + .. code-block:: console + + pip install -e .[dev] + + For regular use, the simple ``pip install -e .`` is sufficient. + +To install other packages, see the items below *Python Interface* in the menu on the left hand side. + +Option B: Building the C++ Core (Advanced) +**************************************** + +For experienced developers and C++ programmers, we offer the C++ backend to fully benefit from all functionality and parallel performance. + +1. Navigate to the C++ source code directory: + + .. code-block:: console + + cd cpp + +2. Create a separate directory for the build files. + + .. code-block:: console + + mkdir build && cd build + +3. Run CMake. This tool prepares the project for compilation on your specific system. + + .. code-block:: console + + cmake .. + +4. Compile the code and create the executables. + + .. code-block:: console + + cmake --build . + +For more detailed instructions, help with errors, and a list of compile options, please see the full :doc:`C++ Installation Guide `. Running simulations ~~~~~~~~~~~~~~~~~~~~~ You can run simulations either via the C++ interface where they are originally implemented or via the python bindings. -For the C++ Interface you can find explanations of the models as well as guides on their usage in the :doc:`C++ model usage ` section. -In short, the executables for different model instatiations are build as described above and can be run via +For the C++ Interface, you can find explanations of the models as well as guides on their usage in the :doc:`C++ model usage ` section. +In short, the executables for different model instantiations are build as described above and can be run via .. code-block:: console @@ -84,10 +183,6 @@ Out of the box this works for all examples in the ``cpp/examples`` folder of our that do not depend on user-provided external libraries. Additional explanations for our models are linked at the corresponding sites of this documentation. -For the Python interface, you can find a short introduction in the :doc:`Python Interface ` section. - -Additionally we provide a python package for :doc:`surrogate models `, which can be used to c -reate fast approximations of our models. Loading data ~~~~~~~~~~~~~~~~~~~~~ @@ -106,10 +201,10 @@ the :doc:`C++ model creation ` section of this documentation Visualizations ~~~~~~~~~~~~~~~~~~~~~ -For visualizations we first of all recommend our :doc:`python package `. Apart from that we have +For visualizations, we provide our :doc:`python package MEmilio-plot `. Apart from that, we have collected some scripts that we used for visualizations in the `tools folder in our github repository `_. -For the latter we don't take any responsibilities! +For the latter, no regular testing is conducted. If you encounter errors, please `contact us `. Further questions ~~~~~~~~~~~~~~~~~~~~~ -If you have any further questions, please take a look at our :doc:`faq` and feel free to contact us via `github `_. \ No newline at end of file +If you have any further questions, please take a look at our :doc:`faq` and feel free to contact us via `e-mail ` or open an issue or discusion on `github ` diff --git a/docs/source/python/memilio_epidata.rst b/docs/source/python/memilio_epidata.rst index fe9d484f77..ca8874f22d 100644 --- a/docs/source/python/memilio_epidata.rst +++ b/docs/source/python/memilio_epidata.rst @@ -46,15 +46,16 @@ Usage ----- After installation the following functions are available: - * getcasedata: Downloads SARS-CoV-2 case data from Robert Koch-Institut (RKI-C). - * getpopuldata: Downloads population data for German federal states and counties from various public sources (P). - * getjhdata: Downloads COVID-19 case data from John Hopkins University (JH). - * getdividata: Downloads ICU data from German DIVI Intensivregister (DIVI). - * getsimdata: Downloads all data required for a simulation with the graph-metapopulation model which are SARS-CoV-2 case data(RKI-C), population data (P), ICU data (DIVI) and COVID-19 vaccination data from Robert Koch-Institut (RKI-V). - * getcommutermobility: Downloads data about commuter mobility from German Federal Employment Agency (BAA). - * gettestingdata: Downloads data about SARS-CoV-2 PCR tests from Robert Koch-Institut (RKI-T). - * gethospitalizationdata: Downloads data about COVID-19 hospitalizations data from Robert Koch-Institut (RKI-H) - * cleandata: Deletes all data files generated by the MEmilio Epidata package. + +* ``getcasedata``: Downloads SARS-CoV-2 case data from Robert Koch-Institut (RKI-C). +* ``getpopuldata``: Downloads population data for German federal states and counties from various public sources (P). +* ``getjhdata``: Downloads COVID-19 case data from John Hopkins University (JH). +* ``getdividata``: Downloads ICU data from German DIVI Intensivregister (DIVI). +* ``getsimdata``: Downloads all data required for a simulation with the graph-metapopulation model which are SARS-CoV-2 case data(RKI-C), population data (P), ICU data (DIVI) and COVID-19 vaccination data from Robert Koch-Institut (RKI-V). +* ``getcommutermobility``: Downloads data about commuter mobility from German Federal Employment Agency (BAA). +* ``gettestingdata``: Downloads data about SARS-CoV-2 PCR tests from Robert Koch-Institut (RKI-T). +* ``gethospitalizationdata``: Downloads data about COVID-19 hospitalizations data from Robert Koch-Institut (RKI-H) +* ``cleandata``: Deletes all data files generated by the MEmilio Epidata package. For a detailed description of the run options and the resulting data files written see the `epidata subfolder `_. diff --git a/docs/source/python/memilio_generation.rst b/docs/source/python/memilio_generation.rst index 83fae181c7..09b0177389 100644 --- a/docs/source/python/memilio_generation.rst +++ b/docs/source/python/memilio_generation.rst @@ -8,7 +8,7 @@ For a particular example, see the SEIR model with its files `oseir.cpp` and `ose This generating software was developed as a part of the Bachelor thesis `Automatische Codegenerierung für nutzerfreundliche mathematisch-epidemiologische Modelle `_. The following figure from Chapter 5 outlines the workflow of the generator. Blue boxes represent parts of the code generator and orange ones the input and output. Rectangular boxes contain classes with logic, the rest represent data. -.. image:: https://github.com/SciCompMod/memilio/main/blob/pycode/memilio-generation/generator_workflow.png +.. image:: ../../../pycode/memilio-generation/generator_workflow.png :alt: tikzGeneratorWorkflow Dependencies @@ -32,24 +32,25 @@ During the installation the package creates a compilation database (compile_comm The package provides an example script on how to use it in `memilio/tools`. The example uses the ode_seir model. Before running the example you have to do these steps of setup: + * Change `config.json.txt `_. -* Check if the parameters set in __post_init__() of the [ScannerConfig class](./memilio/generation/scanner_config.py) match with the cpp-class names. +* Check if the parameters set in ``__post_init__()`` of the `ScannerConfig class `_ match with the cpp-class names. Example: -After processing as described in the previous paragraph, run the example with the command (path according to the current folder): +After processing as described in the previous paragraph, run the example with the command (adjust the path according to your current folder): .. code-block:: console python memilio/tools/example_oseir.py -When working on a new model you can copy the example script and add an additional segment to the config.json.txt. The setup works similar to the example. Additionaly you can print the AST of your model into a file (Usefull for development/debugging). +When working on a new model, you can copy the example script and add an additional segment to the config.json.txt. The setup works similar to the example. Additionaly, you can print the AST of your model into a file for development or debugging. Testing ------- -The package provides a test suite in `memilio/generation_test `_. -To run the tests, simply run the following command: +The package provides a test suite in `memilio/generation_test `_. +To run the tests, simply use the following command: .. code-block:: console @@ -60,11 +61,12 @@ Development ----------- When implementing new model features you can follow these steps: + * Add necessary configurations to `config.json.txt `_ and add corresponding attributes to the ``ScannerConfig``. * For the features you want to implement, find the nodes in the abstract syntax tree (AST) (use method Scanner.output_ast_file(); see the example in tools/). -* Add the extraction of those features. Therefore you need to change the "check_..."-methods corresponding to the ``CursorKind`` of your nodes in the ``Scanner``. If there is no corresponding "check_..."-method you need to write a new one and add it to the switch-method (scanner.switch_node_kind()). +* Add the extraction of those features. Therefore you need to change the "check_..."-methods corresponding to the ``CursorKind`` of your nodes in the ``Scanner``. If there is no corresponding "check\_..."-method you need to write a new one and add it to the switch-method (``scanner.switch_node_kind()``). * Extend the ``IntermediateRepresentation`` for the new model features. -* Adjust the `cpp-template `_ and the `string-template-methods `_. If needed, use new identifiers and write new string-template-methods for them. +* Adjust the `cpp-template `_ and the `string-template-methods `_. If needed, use new identifiers and write new string-template-methods for them. * Adjust the substitution dictionaries in the ``Generator``. -* Write new/Adjust script in the `tool folder `_ for the model and try to run. +* Write new/Adjust scripts in the `tool folder `_ for the model and try to run. * Update tests. \ No newline at end of file diff --git a/docs/source/python/memilio_simulation.rst b/docs/source/python/memilio_simulation.rst index ff37112e6b..f917330d03 100644 --- a/docs/source/python/memilio_simulation.rst +++ b/docs/source/python/memilio_simulation.rst @@ -13,8 +13,8 @@ Required Python packages: * scikit-build -For a succesful build, the development libraries for Python need to be installed, i.e. python3.x-dev. -Additionally, as this packages builds upon the MEmilio C++ library, +For a successful build, the development libraries for Python need to be installed, i.e. python3.x-dev. +Additionally, as this package builds upon the MEmilio C++ library, all dependencies of the main library need to be met. Read more about the C++ dependencies at :doc:`cpp <../getting_started>`. diff --git a/docs/source/references.rst b/docs/source/references.rst index aeef0f97c7..eb19c550a0 100644 --- a/docs/source/references.rst +++ b/docs/source/references.rst @@ -1,15 +1,14 @@ References =========== +The following gives an overview on (peer-reviewed) publications extending or using MEmilio. If you would like to add a publication, `contact us `. + Recently Submitted Publications -------------------------------------- -- 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 `_ - 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 `_ - 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 `_ -- 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 `_ - 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 `_ -- Schmid N, Bicker J, Hofmann AF, Wallrafen-Sam K, Kerkmann D, et al. (2024). *Integrative Modeling of the Spread of Serious Infectious Diseases and Corresponding Wastewater Dynamics*. medRxiv. `DOI:10.1101/2024.11.10.24317057 `_ Peer-Reviewed Publications @@ -17,6 +16,14 @@ Peer-Reviewed Publications **2025** +- 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*. *Chaos, Solitons & Fractals* 199:116782. `DOI:10.1016/j.chaos.2025.116782 `_ + +- Schmid N, Bicker J , Hofmann AF, Wallrafen-Sam K, Kerkmann D, Wieser A, Kühn MJ, Hasenauer J (2025). *Integrative Modeling of the Spread of Serious Infectious Diseases and Corresponding Wastewater Dynamics*. *Epidemics* 51:100836. `DOI:10.1016/j.epidem.2025.100836 `_ + +- Kerkmann D, Korf S, Nguyen K, Abele D, Schengen A, Gerstein C, Göbbert JH, Basermann A, Kühn MJ, Meyer-Hermann M (2025). *Agent-based modeling for realistic reproduction of human mobility and contact behavior to evaluate test and isolation strategies in epidemic infectious disease spread*. *Computers in Biology and Medicine* 193:110269. `DOI:10.1016/j.compbiomed.2025.110269 `_ + +- Diallo D, Schoenfeld J, Schmieding R, Korf S, Kühn MJ, Hecking T (2025). *Integrating Human Mobility Models with Epidemic Modeling: A Framework for Generating Synthetic Temporal Contact Networks*. *Entropy* 27(5), 507. `DOI:10.3390/e27050507 `_ + - 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 `_ **2024**