This app explores how one should implement ID control measures for a scenario with multiple consecutive outbreaks. Read about the model in the “Model” tab. Then do the tasks described in the “What to do” tab. Before going through this app, you should go through the Reproductive Number apps first. This app closely follows a model and analysis described in (Handel, Longini, and Antia 2007), see the “Further Information” tab for this and other related references.
For this app, we’ll use the basic compartmental SIR model. We include 3 different stages/compartments:
For this app, we specify the following processes/flows:
The flow diagram and the set of equations which are used to implement this model are as follows:
Flow diagram for this model.
\[\dot S = -(1-f) b SI\] \[\dot I = (1-f)b S I\] \[\dot R = g I\]
The simulation for this app also has one more (mostly invisible) feature. In previous apps, you learned that an unrealistic feature of models implemented by ordinary differential equations (ODE) is that the number of individuals can drop below 1, i.e., there could be a fraction of infected. For this app, the underlying code is such that if the number of infected drops below 1, it is set to 0. This is in some way a bit of a “hack” to deal with this issue. When you work through the stochastic apps, you will learn better ways of handling this. The advantage of using the “hack” is that we can keep using the ODE model formulation, without stochasticity, which makes things easy.
This app assumes knowledge of the reproductive number concept. If you are not familiar with it, please go through the ‘Reproductive Number’ apps first.
The tasks below are described in a way that assumes everything is in units of days (rate parameters, therefore, have units of inverse days). If any quantity is not given in those units, you need to convert it first.
We’ll start with an outbreak in the absence of control. Set the model to 1000 initial susceptible, 1 infected, no recovered. Set the recovery rate, g, such that it corresponds to an infectiousness duration of 5 days. Set the infectiousness rate b such that the model has a reproductive number, R0, of 4. Keep the intervention level, f, at 0 for now. Set tmax and tnew to 100. Values for tstart and tend do not matter since f is 0. Run the simulation. You should get an outbreak with around 20 susceptibles left at the end.
Record
First without running the simulation and using what you know about R0 and how it relates to the susceptible population size, figure out what the number of susceptibles is (assuming every other parameter stays the same) at which you do not get an outbreak anymore. Now test your expectation by trying different values for S. You might have to adjust the simulation time to see this better. This value for S provides a threshold below which we don’t get an outbreak. This threshold value is often called the herd immunity or community/population immunity level. It corresponds to the threshold value of R0=1 which you learned about previously.
Record
In the previous task, you found the threshold/population immunity value for the number of susceptible needed to prevent an outbreak. In the 1st task, you also saw that at the end of the outbreak, there are much fewer susceptible left than the population immunity level. The outbreak overshoots by depleting more susceptibles than the threshold value. Compute the additional number of susceptible that became infected during the outbreak compared to the value that would have prevented an outbreak. Why is there such a difference? Think about what the value for the reproductive number is during the outbreak at the moment the number of susceptible has dropped to population level immunity. Does the outbreak stop immediately? Why not?
Record
For a single outbreak, more control is better. We looked at at that in the Basics of ID Control app, where we assumed some type of control lowered the transmission rate. We can repeat that here. Set parameters as in task 1. Set tmax and tnew to 200 (so we can see slow outbreaks if they happen). Set control to start at time 0 (tstart) and end at 200 (tend). That basically means the control is active for the whole duration of the simulation. Slowly increase control, f (e.g. in steps of 0.05). Run the simulation for each value of f. As f increases, you should see smaller outbreaks until you hit a value of f for which you don’t see outbreaks anymore. Understand how this value of f relates to the reproductive number. You should be able to figure out the exact value for f at which no outbreak happens anymore based on your knowledge of the reproductive number, and how a reduction in transmission (which is what f does) affects it.
Record
Total/cumulative number of infected at end of simulation for f=0.5 (you need to compute this)
Minimum value for f at which no outbreak is possible
The idea that more control is better also applies if control is only applied during a certain period of the outbreak. Let’s explore that by repeating the previous task, but now with control starting 10 days after the beginning of the outbreak and ending 120 days later (tend=130). Slowly increase control, in steps of 0.1, starting at 0. Run the simulation for each value of f. Since you don’t start control at the beginning, you will always see an outbreak starting, but it will be reduced once control starts, with a higher reduction as f increases.
Record
Doing the previous tasks, you will have noticed that timing of the outbreak matters, the earlier you start the better. Play around a bit with different start and end time for the control and different strengths to explore how they impact the size of the outbreaks you get and how much overshoot you get, i.e. by how much the final number of susceptible is below the herd immunity level.
Record
As you explored different start- and end-times and strengths for control in the previous task, you might have noticed that occasionally you can get the infected numbers to come back up once control is stopped. Let’s explore a bit more how to apply optimal control if there is a chance of multiple outbreaks, either because the pathogen did not get completely wiped out in a specific community, or there are ongoing re-introduction of the pathogen from the outside. Set control to start at time 10 and end at 50. Assume no new infected persons enter the population by setting both total simulation time and tmax and tend to 200 days. All of the other settings as in the previous task. Slowly increase control, f and run the simulation for the different values of f. Initially, things look as before. But once you reach a certain level of control, you will see that a second outbreak occurs and the total number of susceptibles drops again. To explore this in more detail, set f=0.6 and f=0.8 and try to understand why in one case you only get a single outbreak and in the other you get 2. To get the values for susceptible at t=50 it is easiest to switch to a plotly plot and read them off. Try to figure out how the number of susceptible when control is stopped relates to R0 and how that relates to the fact that you do or don’t see another outbreak.
Record
Number of susceptible at end of control (t=50) for f=0.6
Number of susceptible at end of simulation for f=0.6
Number of susceptible at end of control (t=50) for f=0.8
Number of susceptible at end of simulation for f=0.8
Run the simulation with the previous settings for f going from 0.5 to 0.7 in steps of 0.025. For each control level, record the number of susceptibles left at the end of the simulation. Based on that, what do you conclude about the impact of different levels of control on the outcome? What seems to be the best level of control, and why?
Record
In the previous task, control ends while there are still a few infected around, which can lead to a second outbreak. An alternative scenario is one where control ends after infected are gone, but then a newly infected person enters the population. We can explore this scenario, as well. Using parameter settings as previously, change control to start at time 10 (tstart) and end at 110 (tend). Set tmax and tnew to 400. Run the simulation for control strength f=0.8. You should see a single outbreak with around 475 susceptibles left. You learned above that this value of is not low enough for herd immunity, thus you can get a second outbreak. This is not happening here since the infected dropped to 0, so when control is ended, there is no chance a new outbreak can start. However, that changes if newly infected enter the population. To simulate this, set tnew=50, then run the simulation again. A new infected person is no introduced every 50 days. At times 50 and 100, control is still in effect, so they have no impact. But at day 150, there is no control, so this person can spark a new outbreak, which is what you see.
Record
Number of susceptible at end of control (t=110)
Number of susceptible at end of simulation
Open exploration: In a setting like this, where multiple outbreaks are possible and one cannot apply control for a long enough time to drive the disease extinct (or get a vaccine or some other new intervention), the best one can do is implement control to get the susceptible to drop to herd immunity while minimizing the overshoot, i.e. the excess drop of susceptible below herd immunity. This can be accomplished in different ways. Play around with start- and end-times for control and control strength to explore ways you can minimize the outbreak. You can also alter transmission or recovery rate to change R0 and see how that changes results. An option that is not possible with this simulation but could be done in real life is adaptive control by changing the control strength. You could mimic it by running a simulation with control at some level, then use the end values of the simulation as starting values with new control, etc. That’s a bit tedious to do through the graphical interface but would not be too hard if you interacted with the simulation function directly through code.
Record
simulate_idcontrolmultioutbreak_ode
. You can call them directly, without going through the shiny app. Use the help()
command for more information on how to use the functions directly. If you go that route, you need to use the results returned from this function and produce useful output (such as a plot) yourself.vignette('DSAIDE')
into the R console.