Skip to content

Commit a5cbb91

Browse files
793 add seasonality to ide model (#972)
- Functionality to simulate the IDE model with a seasonality has been added. - The test for the function check_constraints() of the Parameters class was rewritten. The use of the class Model made the test unnecessarily complicated. Co-authored-by: reneSchm <[email protected]>
1 parent 4886fcf commit a5cbb91

File tree

6 files changed

+138
-117
lines changed

6 files changed

+138
-117
lines changed

cpp/examples/ide_secir.cpp

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -91,11 +91,14 @@ int main()
9191
model.parameters.set<mio::isecir::TransmissionProbabilityOnContact>(prob);
9292
model.parameters.set<mio::isecir::RelativeTransmissionNoSymptoms>(prob);
9393
model.parameters.set<mio::isecir::RiskOfInfectionFromSymptomatic>(prob);
94+
model.parameters.set<mio::isecir::Seasonality>(0.1);
95+
// Start the simulation on the 40th day of a year (i.e. in February).
96+
model.parameters.set<mio::isecir::StartDay>(40);
9497

9598
model.check_constraints(dt);
9699

97100
// Carry out simulation.
98-
mio::isecir::Simulation sim(model, 0, dt);
101+
mio::isecir::Simulation sim(model, dt);
99102
sim.advance(tmax);
100103

101104
auto interpolated_results = mio::interpolate_simulation_result(sim.get_result(), dt / 2);

cpp/models/ide_secir/model.cpp

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -275,9 +275,12 @@ void Model::update_forceofinfection(ScalarType dt, bool initialization)
275275
for (Eigen::Index i = num_time_points - 1 - calc_time_index; i < num_time_points - 1; i++) {
276276

277277
ScalarType state_age = (num_time_points - 1 - i) * dt;
278-
278+
ScalarType season_val =
279+
1 +
280+
parameters.get<Seasonality>() *
281+
sin(3.141592653589793 * (std::fmod((parameters.get<StartDay>() + current_time), 365.0) / 182.5 + 0.5));
279282
m_forceofinfection +=
280-
parameters.get<TransmissionProbabilityOnContact>().eval(state_age) *
283+
season_val * parameters.get<TransmissionProbabilityOnContact>().eval(state_age) *
281284
parameters.get<ContactPatterns>().get_cont_freq_mat().get_matrix_at(current_time)(0, 0) *
282285
((parameters
283286
.get<TransitionProbabilities>()[(int)InfectionTransition::InfectedNoSymptomsToInfectedSymptoms] *

cpp/models/ide_secir/parameters.h

Lines changed: 46 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -150,10 +150,48 @@ struct RiskOfInfectionFromSymptomatic {
150150
}
151151
};
152152

153-
// Define Parameterset for IDE SECIR model.
153+
/**
154+
* @brief Sets the day in a year at which a simulation with an IDE-SECIR model is started.
155+
*
156+
* The value 0.0 corresponds to the 1st of January at 0:00 am, 31.25 is the 1st of February at 6:00 am, and so on.
157+
* The start day defines in which season the simulation is started.
158+
* If the start day is 180 and simulation takes place from t0=0 to
159+
* tmax=100 the days 180 to 280 of the year are simulated.
160+
* The parameter is used in the formula of the seasonality in the model.
161+
*/
162+
struct StartDay {
163+
using Type = ScalarType;
164+
static Type get_default()
165+
{
166+
return 0.;
167+
}
168+
static std::string name()
169+
{
170+
return "StartDay";
171+
}
172+
};
173+
174+
/**
175+
* @brief The seasonality parameter k in the IDE-SECIR model.
176+
* The formula for the seasonality used in the model is given as (1+k*sin()) where the sine
177+
* curve is below one in summer and above one in winter.
178+
*/
179+
struct Seasonality {
180+
using Type = ScalarType;
181+
static Type get_default()
182+
{
183+
return Type(0.);
184+
}
185+
static std::string name()
186+
{
187+
return "Seasonality";
188+
}
189+
};
190+
191+
// Define Parameterset for IDE-SECIR model.
154192
using ParametersBase =
155193
ParameterSet<TransitionDistributions, TransitionProbabilities, ContactPatterns, TransmissionProbabilityOnContact,
156-
RelativeTransmissionNoSymptoms, RiskOfInfectionFromSymptomatic>;
194+
RelativeTransmissionNoSymptoms, RiskOfInfectionFromSymptomatic, StartDay, Seasonality>;
157195

158196
/**
159197
* @brief Parameters of an age-resolved SECIR/SECIHURD model.
@@ -269,6 +307,7 @@ class Parameters : public ParametersBase
269307
1);
270308
return true;
271309
}
310+
272311
/* The first entry of TransitionDistributions is not checked because the distribution S->E is never used
273312
(and it makes no sense to use the distribution). The support does not need to be valid.*/
274313
for (size_t i = 1; i < (int)InfectionTransition::Count; i++) {
@@ -278,6 +317,11 @@ class Parameters : public ParametersBase
278317
}
279318
}
280319

320+
if (this->get<Seasonality>() < 0.0 || this->get<Seasonality>() > 0.5) {
321+
log_warning("Constraint check: Parameter Seasonality should lie between {:0.4f} and {:.4f}", 0.0, 0.5);
322+
return true;
323+
}
324+
281325
return false;
282326
}
283327

cpp/models/ide_secir/simulation.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -59,10 +59,10 @@ void Simulation::advance(ScalarType tmax)
5959
}
6060
}
6161

62-
TimeSeries<ScalarType> simulate(ScalarType t0, ScalarType tmax, ScalarType dt, Model const& m_model)
62+
TimeSeries<ScalarType> simulate(ScalarType tmax, ScalarType dt, Model const& m_model)
6363
{
6464
m_model.check_constraints(dt);
65-
Simulation sim(m_model, t0, dt);
65+
Simulation sim(m_model, dt);
6666
sim.advance(tmax);
6767
return sim.get_result();
6868
}

cpp/models/ide_secir/simulation.h

Lines changed: 8 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -44,12 +44,10 @@ class Simulation
4444
/**
4545
* @brief setup the Simulation for an IDE model.
4646
* @param[in] model An instance of the IDE model.
47-
* @param[in] t0 Start time.
4847
* @param[in] dt Step size of numerical solver.
4948
*/
50-
Simulation(Model const& model, ScalarType t0 = 0., ScalarType dt = 0.1)
49+
Simulation(Model const& model, ScalarType dt = 0.1)
5150
: m_model(std::make_unique<Model>(model))
52-
, m_t0(t0)
5351
, m_dt(dt)
5452
{
5553
}
@@ -106,15 +104,6 @@ class Simulation
106104
return *m_model;
107105
}
108106

109-
/**
110-
* @brief get the starting time of the simulation.
111-
*
112-
*/
113-
ScalarType get_t0()
114-
{
115-
return m_t0;
116-
}
117-
118107
/**
119108
* @brief get the time step of the simulation.
120109
*
@@ -126,19 +115,18 @@ class Simulation
126115

127116
private:
128117
std::unique_ptr<Model> m_model; ///< Unique pointer to the Model simulated.
129-
ScalarType m_t0; ///< Start time used for simulation.
130118
ScalarType m_dt; ///< Time step used for numerical computations in simulation.
131119
};
132120

133121
/**
134-
* @brief simulates a compartmental model
135-
* @param[in] t0 start time
136-
* @param[in] tmax end time
137-
* @param[in] dt initial step size of integration
138-
* @param[in] model an instance of a compartmental model
139-
* @return a TimeSeries to represent the final simulation result
122+
* @brief Run a Simulation of an IDE-SECIR model.
123+
*
124+
* @param[in] tmax End time.
125+
* @param[in] dt Initial step size of integration.
126+
* @param[in] model An instance of an IDE-SECIR model.
127+
* @return A TimeSeries to represent the final simulation result.
140128
*/
141-
TimeSeries<ScalarType> simulate(double t0, double tmax, double dt, Model const& model);
129+
TimeSeries<ScalarType> simulate(double tmax, double dt, Model const& model);
142130

143131
} // namespace isecir
144132
} // namespace mio

0 commit comments

Comments
 (0)