Skip to contents

EndoSim is designed in a modular fashion. Input objects are, in general, lists of functions, where each function accepts a single numeric vector input ( e.g., temperature, days after emergence) and returns a numeric vector output of the same length.

For example, in the pest() object, the argument fun_dev_apt accepts a function describing temperature-dependent development of nymphs destined to become apterae. This function should accept as its input daily temperature and return a corresponding number, ranging from 0-1. The input can be a vector of length 1:

GPA@fun_dev_apt(20)
#> [1] 0.1376906

Or a longer vector:

GPA@fun_dev_apt(c(0, 15, 20, 38))
#> [1] 0.00000000 0.09255006 0.13769057 0.00000000

For the supplied pest() object for Myzus persicae, GPA, this function is currently defined using the Wang model for development (set up using the internal function EndoSim:::fit_wang()). However, we can easily replace this with a different function. This can be done using one of the internal functions provided with the EndoSim package. For example, say we want to use a Gaussian function:

GPA@fun_dev_apt <- EndoSim:::fit_gaussian(1, 25, 3)

plot(seq(0, 50, by = 0.1), GPA@fun_dev_apt(seq(0, 50, by = 0.1)), type = "l")

The internal functions come with documentation explaining what the input arguments for each are (generally parameters defining the shape and range of the function), and what the resultant function is - i.e., what is its required input and what is the range of output values it produces. This can make it easy to set up new objects that have similar functional responses as the ones supplied with the package, but may differ in the shape or range. For example, if we want to model a different aphid pest that has narrower thermal preferences and a lower optimal temperature:

GPA@fun_dev_apt <- EndoSim:::fit_gaussian(1, 20, 2)

plot(seq(0, 50, by = 0.1), GPA@fun_dev_apt(seq(0, 50, by = 0.1)), type = "l")

Using the internal functions is not a requirement - we can also write custom functions to represent different processes. However, we strongly urge users to take caution when writing their own functions, since they could potentially return values which are nonsensical or “break” the model. For example, we could write a function where the returned development units change linearly with temperature, but not include bounds which prevent the returned values from being negative:

GPA@fun_dev_apt <- function(temp){
  output <- 0.2 * temp - 2
  
  return(output)
}

plot(seq(0, 50, by = 0.1), GPA@fun_dev_apt(seq(0, 50, by = 0.1)), type = "l")

Running a model with this function can lead to downright weird results because of nonsensical development rates:

model <- endosim(Pest = GPA,
                 Endosymbiont = Rickettsiella,
                 Crop = Canola,
                 Parasitoid = DR,
                 init = init,
                 conds = Aroonda,
                 plot = FALSE,
                 progress = FALSE,
                 imi = FALSE,
                 emi = FALSE,
                 vert_trans = TRUE,
                 hori_trans = TRUE,
                 para = TRUE)

plot(model, type = "demo")

Also note that we could, theoretically, use a function that returns a non-numeric output, or an output of different length to the input. This could simply result in the model failing to run:

GPA@fun_dev_apt <- function(temp){
  output <- "this is a text output"
  
  return(output)
}

model <- endosim(Pest = GPA,
                 Endosymbiont = Rickettsiella,
                 Crop = Canola,
                 Parasitoid = DR,
                 init = init,
                 conds = Aroonda,
                 plot = TRUE,
                 progress = FALSE,
                 imi = FALSE,
                 emi = FALSE,
                 vert_trans = TRUE,
                 hori_trans = TRUE,
                 para = TRUE)
#> Error in dev_cohorts[, c(1, 2)] + dev_apt: non-numeric argument to binary operator

Turning processes on and off

Because all objects include functions as arguments, a process can be easily turned off or fixed ( i.e., made not dependent on its input) by using the internal EndoSim:::fit_null() function. This function accepts as an input a user-determined value, and returns a function which returns this value as an output regardless of the input - but crucially, of the same length. Some examples:

my_func <- EndoSim:::fit_null(5)

my_func(10)
#> [1] 5

my_func(c(0, 5, 10, 20))
#> [1] 5 5 5 5

my_func("test")
#> [1] 5

my_func <- EndoSim:::fit_null("null")

my_func(10)
#> [1] "null"

my_func(c(0, 5, 10, 20))
#> [1] "null" "null" "null" "null"

Because the output is always of the same length, using fit_null() doesn’t break the model due to inconsistent lengths of objects.

Turning off a process is as simple as passing to it fit_null(0) or fit_null(1) - this makes sure the output for that process is always 0 or 1. Which one to choose depends on the process, and whether “turning it off” means the returned value should be 0 or 1.

For instance, disabling age-dependent mortality can be done by replacing the fun_sen_loss() function so that the returned value is 0. In this way, there is no mortality associated with the age of the cohort (senescense), since the number of aphid deaths due to senescense are always 0, and mortality is modelled as an additive process.

GPA@fun_sen_loss <- EndoSim:::fit_null(0)

model <- endosim(Pest = GPA,
                 Endosymbiont = Rickettsiella,
                 Crop = Canola,
                 Parasitoid = DR,
                 init = init,
                 conds = Aroonda,
                 plot = TRUE,
                 progress = FALSE,
                 imi = FALSE,
                 emi = FALSE,
                 vert_trans = TRUE,
                 hori_trans = TRUE,
                 para = TRUE)

On the other hand, disabling age-dependent reproduction by replacing the fun_age_fecund() function, requires a value of 1. Because the total growth rate is a multiplication of temperature-, density- and age-related contributions, fixing this value to 1 effectively removes the “contribution” of age - growth rates no longer depend on the age of the cohort.

GPA@fun_age_fecund <- EndoSim:::fit_null(1)

model <- endosim(Pest = GPA,
                 Endosymbiont = Rickettsiella,
                 Crop = Canola,
                 Parasitoid = DR,
                 init = init,
                 conds = Aroonda,
                 plot = TRUE,
                 progress = FALSE,
                 imi = FALSE,
                 emi = FALSE,
                 vert_trans = TRUE,
                 hori_trans = TRUE,
                 para = TRUE)

Again - this functionality should be used with caution since it could lead to nonsensical results.