---
title: Vector Borne Transmission 
output:
  html_document:
    theme: null
    highlight: null
    fig_retina: null
    fig_caption: true
    mathjax: default 
    keep_md: false
bibliography: dsaide_references.bib
---

```{r, include = FALSE}
#*************************************
#general setup to define package and get path locations
#all paths are inside the package and retrieved with system.file
packagename = "DSAIDE"
helperdir = "helperfunctions"
mbmodeldir = "mbmodels"
figuredir = "media"
appdocdir = "appinformation" 
#*************************************
#Note: for this to process/knit, several helper functions need to be available (sourced) first
#those are in the inst/helperfunctions folder
#Note: in general, the "processing-script.R" in the docsfordevelopers should be used to produce the html docs
#manual knitting of each doc only during development/testing
#*************************************
files_to_source = list.files(system.file(helperdir,package = packagename),full.names=TRUE)
sapply(files_to_source, source) #sourcing needs to happen inside each Rmd file since knitr starts a new environment
#load the settings file for the current app 
#so we can automatically include figure, list the functions in the further information section
#and use other information specific to the current app for the task table generation
currentrmdfile = knitr::current_input() 
appsettings = get_settings(currentrmdfile,appdocdir,packagename)
```


## Overview {#shinytab1}
This app allows you to explore a simple model for vector-borne transmission. Read about the model in the "Model" tab. Then do the tasks described in the "What to do" tab.


### Learning Objectives

* Know about important IDs that are vector-borne
* Understand the implications of vector-borne transmission on ID dynamics
* Understand how vector-borne transmission influences potential ID control strategies.


## The Model {#shinytab2}

### Model Overview

This is a simple 2 species (hosts and vectors) model, using the basic SIR framework as follows.

The model has the following compartments:  

* **Sh** - uninfected and susceptible host 
* **Ih** - infected/infectious hosts
* **Rh** - recovered/removed hosts
* **Sv** - susceptible vectors
* **Iv** - infected/infectious vectors

We assume that once a vector is infected, it stays infected until it dies. Therefore, recovered vectors are not included in the model.


The processes being modeled are:

* Susceptible host can become infected by contact with infected vectors at rate _b~1~_ 
* Susceptible vectors can become infected by contact with infected hosts at rate _b~2~_ 
* Infected hosts recover after some time (specified by the rate _g_). 
* New susceptible vectors are born at a rate _n_. Susceptible and infected vectors die at rate _m_. The inverse of this rate is the average lifespan. 
* Recovered hosts lose their immunity at rate _w_.

We envision hosts to be humans and vectors to be e.g. mosquitoes. We further assume the time scale for the model is short enough that we can ignore births and deaths for human hosts but not vectors. This is likely a decent approximation as long as our simulation time is only a few years.


### Model Implementation
The flow diagram and the set of ordinary differential equations (ODE) which are used to implement this model are as follows:

```{r modeldiagram,  fig.cap='Model Diagram',  echo=FALSE, out.width = "70%"}
knitr::include_graphics(here::here('inst/media',appsettings$modelfigname))
```


The model equations are:



$$\dot S_h = - b_1 S_h I_v + w R_h $$ 
$$\dot I_h =  b_1 S_h I_v  - g I_h $$ 
$$\dot R_h = g I_h - w R_h $$
$$\dot S_v = n - b_2 S_v I_h - m S_v $$ 
$$\dot I_v =  b_2 S_v I_h - m I_v$$ 





## What to do {#shinytab3}

**The tasks below are described in a way that assumes everything is in units of months (rate parameters, therefore, have units of inverse months). If any quantity is not given in those units, you need to convert it first (e.g. if it says a year, you need to convert it to 12 months).**


```{r, echo=FALSE, eval=TRUE}
#this is the running counter for the records which starts at 1 
rc=1

#empty object, will hold all outcomes
alloutcomes = NULL

############
# Task 1
############
tid = 1
tasktext = "Set the model parameters so that there are 1000 initially susceptible for both hosts and vectors, 1 initially infected host, no infected vectors, and no recovered hosts. Simulation duration 10 years (convert to months). Set the transmission rates, _b~1~_=0, and _b~2~_ = 0.004. Assume that the duration of the infectious period in hosts is half a month (about 2 weeks) long. Assume that vectors live for half a month. Set the birth rate such that in the absence of the ID, you get a steady population of 1000 vectors. You have learned the relation between births, deaths and steady state susceptibles in the _Patterns of ID_ app. If you don't remember, revisit that app or you can figure it out by trying different values for the birth rate (with no infected hosts or vectors present). Turn off waning immunity for now. Run the simulation, observe what you get. You should not see any outbreak happening. Make sure you know why."
nrec = 1 # number of items to record
out_records = c("Nothing")
out_types = rep("None",nrec)
out_notes = c("")
outcomes = data.frame( TaskID = rep(tid,nrec),
                       TaskText = rep(tasktext,nrec),
                      RecordID = paste0('T',tid,'R',(1:nrec)),
                      Record = out_records, 
                      Type = out_types, 
                      Note = out_notes)
alloutcomes = rbind(alloutcomes,outcomes)
rc = rc + nrec #increment record counter by number of outcomes to record for this task 


############
# Task 2
############
tid = 2
tasktext = "In the previous task, there was no outbreak because while infected hosts were able to transmit to the vectors (_b~2~_>0), the vectors where not able to pass the pathogen back to the hosts (_b~1~_=0), thus no sustained transmission and no outbreak. Now set _b~1~_ = 0.002 and _b~2~_ = 0.004, and rerun the simulation. Since this now _closes the loop_ and allows for sustained transmission from hosts to vectors and back, you should seen an outbreak. Run the simulation and confirm that you get an outbreak with around 251 susceptible hosts left. Also check that it doesn't matter if you start with an infected host or an infected vector (and none of the other), you'll get essentially the same results."
nrec = 1 # number of items to record
out_records = c("Maximum/Peak number of infected human hosts")
out_types = rep("Rounded_Integer",nrec)
out_notes = rep("Report the rounded integer",nrec)
outcomes = data.frame( TaskID = rep(tid,nrec),
                       TaskText = rep(tasktext,nrec),
                      RecordID = paste0('T',tid,'R',(1:nrec)),
                      Record = out_records, 
                      Type = out_types, 
                      Note = out_notes)
alloutcomes = rbind(alloutcomes,outcomes)
rc = rc + nrec #increment record counter by number of outcomes to record for this task 



############
# Task 3
############
tid = 3
tasktext = "Recall from the _Environmental Transmission_ app that the definition of the reproductive number always goes from an infectious compartment of one type back to that compartment. Here, that means we can compute how many new infectious human hosts are produced (via vectors) by one infectious host. Completely equivalently, we can determine the number of new infectious vectors produced (via hosts) by one infectious vector. One infectious human is infectious for duration _1/g_ and during that time infects vectors at rate _b~2~_, for a total of _b~2~/g_ infected vectors. Similarly, each vector transmits at rate _b~1~_, for a duration of _1/m_, for a total of _b~1~/m_ new infected hosts. To go from one type of infected back to the same time, one multiplies the two quantities, and multiplying by the initial susceptibles of each type gives the basic reproductive number, _R~0~=b~1~*b~2~*Sh~0~*Sv~0~/(g*m)_ . Let's explore this equation with the simulation. Compute _R~0~_ for the model settings from the previous task."
nrec = 1 # number of items to record
out_records = c("Value of R0")
out_types = rep("Rounded_Integer",nrec)
out_notes = rep("Report the rounded integer",nrec)
outcomes = data.frame( TaskID = rep(tid,nrec),
                       TaskText = rep(tasktext,nrec),
                      RecordID = paste0('T',tid,'R',(1:nrec)),
                      Record = out_records, 
                      Type = out_types, 
                      Note = out_notes)
alloutcomes = rbind(alloutcomes,outcomes)
rc = rc + nrec #increment record counter by number of outcomes to record for this task 


############
# Task 4
############
tid = 4
tasktext = "Run the simulation for _b~1~ = 0.003_ and _b~2~ = 0.004_, everything else as in task 1. Compute _R~0~_ and compute the outbreak size among hosts (total/cumulative number infected, which you need to compute from the output)."
nrec = 2 # number of items to record
out_records = c("Value of R0",
                "Total (cumulative) number of infected hosts")
out_types = rep("Rounded_Integer",nrec)
out_notes = rep("Report the rounded integer",nrec)
outcomes = data.frame( TaskID = rep(tid,nrec),
                       TaskText = rep(tasktext,nrec),
                      RecordID = paste0('T',tid,'R',(1:nrec)),
                      Record = out_records, 
                      Type = out_types, 
                      Note = out_notes)
alloutcomes = rbind(alloutcomes,outcomes)
rc = rc + nrec #increment record counter by number of outcomes to record for this task 

############
# Task 5
############
tid = 5
tasktext = "Repeat the previous task, now for _b~1~ = 0.006_ and _b~2~ = 0.002_. Compare the values for _R~0~_ and the outbreak size between the two settings. Are you surprised? Can you explain/guess why you see what you see?"
nrec = 2 # number of items to record
out_records = c("Value of R0",
                "Total (cumulative) number of infected hosts")
out_types = rep("Rounded_Integer",nrec)
out_notes = rep("Report the rounded integer",nrec)
outcomes = data.frame( TaskID = rep(tid,nrec),
                       TaskText = rep(tasktext,nrec),
                      RecordID = paste0('T',tid,'R',(1:nrec)),
                      Record = out_records, 
                      Type = out_types, 
                      Note = out_notes)
alloutcomes = rbind(alloutcomes,outcomes)
rc = rc + nrec #increment record counter by number of outcomes to record for this task 

############
# Task 6
############
tid = 6
tasktext = "You might have expected to see the same size outbreaks in the previous two tasks. The reason why you don't is that here we do not have a closed population, instead vectors are born and die, and their changing populations can affect the result. To test that, we can make vector dynamics so fast that they are essentially fixed. That is not biologically realistic, but we can do it just to explore model behavior and see if our intuition of why we see different outbreak sizes is correct. To do so, set the vector death rate to an (biologically unreasonable) rate of _m = 200_ and adjust birth rate so that vector population size (in absence of disease) remains at 1000. Now run simulations again for the settings from the last 2 tasks. Before you do that, we also need to adjust transmission rate for the vectors to keep _R~0~_ as before. Do so by increasing _b~1~_ by a factor of 100. compared to the values in the previous two tasks. You should see that the vector population remains pretty much constant and that the number susceptible left at the end of the outbreak is almost the same for the two scenarios. Use the final size equation to compute _R~0~_ and compare with the value from the equation given earlier."
nrec = 1 # number of items to record
out_records = c("Value of R0 from final size equation")
out_types = rep("Rounded_Integer",nrec)
out_notes = rep("Report the rounded integer",nrec)
outcomes = data.frame( TaskID = rep(tid,nrec),
                       TaskText = rep(tasktext,nrec),
                      RecordID = paste0('T',tid,'R',(1:nrec)),
                      Record = out_records, 
                      Type = out_types, 
                      Note = out_notes)
alloutcomes = rbind(alloutcomes,outcomes)
rc = rc + nrec #increment record counter by number of outcomes to record for this task 


############
# Task 7
############
tid = 7
tasktext = "While we have played around with the transmission rates, we haven't really given much thought as to how those could map to real biological quantities. Each infection requires an interaction between a host and a vector. This interaction is often a bite, especially if we think about mosquitoes. If the vectors have a fixed rate of biting (call it _r_), no matter how many hosts there are, then the rate at which a vector bites any one of the hosts in a population of size _N_ is _rb_/_N_. If there is some chance of transmission per bite from infected vector to human (call it _q~1~_) and similarly a chance of transmission per bite from infected human to vector (_q~2~_), then the transmission parameters in our model are _b~1~_= _rq~1~/N_ and _b~2~_ = _rq~2~/N_. At the beginning of an outbreak, if we assume everyone is susceptible, we can replace _N_ with _S_. If we stick these quantities into the _R~0~_ equation, we find _R~0~_=_r^2*q~1~*q~2~*Sv~0~/(g*m*Sh~0~)_. This produces two potentially interesting insights. First, the reproductive number, and thus outbreak size, is proportional to the square of the biting rate. Reducing that rate is thus an important target. Further, we find that while a larger vector number leads to a higher _R~0~_, it turns out an increase in the host population _reduces_ _R~0~_. The reason for that is that if there are many hosts, two bites of the same host (which is required for ongoing transmission) becomes less likely. For more on that, see e.g. [@keeling08]."
nrec = 1 # number of items to record
out_records = c("Nothing")
out_types = rep("None",nrec)
out_notes = c("")
outcomes = data.frame( TaskID = rep(tid,nrec),
                       TaskText = rep(tasktext,nrec),
                      RecordID = paste0('T',tid,'R',(1:nrec)),
                      Record = out_records, 
                      Type = out_types, 
                      Note = out_notes)
alloutcomes = rbind(alloutcomes,outcomes)
rc = rc + nrec #increment record counter by number of outcomes to record for this task 


############
# Task 8
############
tid = 8
tasktext = "In the _ID Patterns_ app, we discussed the concept of resource replenishment and that it is a requirement for multiple outbreaks. Here, we have a model that includes births of new vectors, yet we still only get a single outbreak. Think about it for a moment to figure out why. Then play with the model inputs and see if you can get settings for which you have more than one outbreak."
nrec = 1 # number of items to record
out_records = c("Nothing")
out_types = rep("None",nrec)
out_notes = c("")
outcomes = data.frame( TaskID = rep(tid,nrec),
                       TaskText = rep(tasktext,nrec),
                      RecordID = paste0('T',tid,'R',(1:nrec)),
                      Record = out_records, 
                      Type = out_types, 
                      Note = out_notes)
alloutcomes = rbind(alloutcomes,outcomes)
rc = rc + nrec #increment record counter by number of outcomes to record for this task 


############
# Task 9
############
tid = 9
tasktext = "In the previous task, you hopefully realized that replenishment is needed for _both_ hosts and vectors to get multiple outbreaks, and that you can accomplish that by turning on waning immunity for hosts. Set parameters to values as in task 2 and assume that immunity wanes on average in 10 months. Run the simulation. You should see a few consecutively smaller outbreaks and the system settling down at a steady state of about 523 susceptible hosts."
nrec = 1 # number of items to record
out_records = c("Final number of susceptible vectors at steady state")
out_types = rep("Rounded_Integer",nrec)
out_notes = rep("Report the rounded integer",nrec)
outcomes = data.frame( TaskID = rep(tid,nrec),
                       TaskText = rep(tasktext,nrec),
                      RecordID = paste0('T',tid,'R',(1:nrec)),
                      Record = out_records, 
                      Type = out_types, 
                      Note = out_notes)
alloutcomes = rbind(alloutcomes,outcomes)
rc = rc + nrec #increment record counter by number of outcomes to record for this task 

############
# Task 10
############
tid = 10

tasktext = "Keep exploring. One feature you might notice is that while you can get a few outbreaks and a steady state, you won't be able to produce sustained cycles/oscillations. This would require seasonality in the model, which this model does not include. Many vector-borne pathogens show strong seasonality, thus for a _real_ model that is built to study a specific vector-borne disease, seasonality - and likely other details - will need to be included."
nrec = 1 # number of items to record
out_records = c("Nothing")
out_types = rep("None",nrec)
out_notes = c("")
outcomes = data.frame( TaskID = rep(tid,nrec),
                       TaskText = rep(tasktext,nrec),
                      RecordID = paste0('T',tid,'R',(1:nrec)),
                      Record = out_records, 
                      Type = out_types, 
                      Note = out_notes)
alloutcomes = rbind(alloutcomes,outcomes)
rc = rc + nrec #increment record counter by number of outcomes to record for this task 
```



```{r echo=FALSE}
#save the fully filled task table to a tsv file
alloutcomes$QuizID = paste0('dsaide_',appsettings$appid)
alloutcomes$AppTitle = appsettings$apptitle
alloutcomes$AppID = appsettings$appid
alloutcomes <- alloutcomes %>% dplyr::select(QuizID,AppID,AppTitle,TaskID,TaskText,RecordID,Record,Type,Note)		
write.table(alloutcomes, paste0(appsettings$appid,"_tasktable.tsv"), append = FALSE, sep = "\t", row.names = F, col.names = TRUE)
```


```{r, echo=FALSE, results='asis'}
# Take all the text stored in the table and print the tasks and items to record
write_tasktext_new(alloutcomes)
```


## Further Information {#shinytab4}

* This app (and all others) are structured such that the Shiny part (the graphical interface you see and the server-side function that goes with it) calls an underlying R script (or several) which runs the simulation for the model of interest and returns the results.
* For this app, the underlying function(s) running the simulation are called ``r appsettings$simfunction``. 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. 
* You can also download all simulator functions and modify them for your own purposes.  Of course to modify these functions, you'll need to do some coding.
* For examples on using the simulators directly and how to modify them, read the package vignette by typing `vignette('DSAIDE')` into the R console.
* Some more information on vector-borne diseases and modeling can be found in [@kilpatrick12].


### References

