Create a new simulation object, the "sim" object. This object is implemented using an environment where all objects and functions are placed. Since environments in R are pass by reference, "putting" objects in the sim object does no actual copy. The simList also stores all parameters, and other important simulation information, such as times, paths, modules, and module load order. See more details below.

This may allow for more efficient Caching. This passes all arguments to simInit, then the created simList is passed to spades

simInit(times, params, modules, objects, paths, inputs, outputs, loadOrder,
  notOlderThan = NULL)


  # S4 method for list,list,list,list,list,data.frame,data.frame,character
simInit(times,
  params, modules, objects, paths, inputs, outputs, loadOrder,
  notOlderThan = NULL)

# S4 method for ANY,ANY,ANY,character,ANY,ANY,ANY,ANY
simInit(times, params,
  modules, objects, paths, inputs, outputs, loadOrder, notOlderThan = NULL)

# S4 method for ANY,ANY,character,ANY,ANY,ANY,ANY,ANY
simInit(times, params,
  modules, objects, paths, inputs, outputs, loadOrder, notOlderThan = NULL)

# S4 method for ANY,ANY,ANY,ANY,ANY,ANY,ANY,ANY
simInit(times, params, modules,
  objects, paths, inputs, outputs, loadOrder, notOlderThan = NULL)

simInitAndSpades(...)

Arguments

times

A named list of numeric simulation start and end times (e.g., times = list(start = 0.0, end = 10.0)).

params

A list of lists of the form list(moduleName=list(param1=value, param2=value)). See details.

modules

A named list of character strings specifying the names of modules to be loaded for the simulation. Note: the module name should correspond to the R source file from which the module is loaded. Example: a module named "caribou" will be sourced form the file caribou.R, located at the specified modulePath(simList) (see below).

objects

(optional) A vector of object names (naming objects that are in the calling environment of the simInit, which is often the .GlobalEnv unless used programmatically -- NOTE: this mechanism will fail if object name is in a package dependency), or a named list of data objects to be passed into the simList (more reliable). These objects will be accessible from the simList as a normal list, e.g,. mySim$obj.

paths

An optional named list with up to 4 named elements, modulePath, inputPath, outputPath, and cachePath. See details.

inputs

A data.frame. Can specify from 1 to 6 columns with following column names: objectName (character, required), file (character), fun (character), package (character), interval (numeric), loadTime (numeric). See inputs and vignette("ii-modules") section about inputs.

outputs

A data.frame. Can specify from 1 to 5 columns with following column names: objectName (character, required), file (character), fun (character), package (character), saveTime (numeric). See outputs and vignette("ii-modules") section about outputs.

loadOrder

An optional list of module names specifying the order in which to load the modules. If not specified, the module load order will be determined automatically.

notOlderThan

A time, as in from Sys.time(). This is passed into the Cache function that wraps .inputObjects. If the module uses the .useCache parameter and it is set to TRUE or ".inputObjects", then the .inputObjects will be cached. Setting notOlderThan = Sys.time() will cause the cached versions of .inputObjects to be refreshed, i.e., rerun.

...

Passed to simInit

Value

A simList simulation object, pre-initialized from values specified in the arguments supplied.

Details

Calling this simInit function does the following:

WhatDetailsArgument(s) to use
fills simList slotsplaces the arguments times, params, modules, paths into equivalently named simList slotstimes, params, modules, paths
sources all module filesplaces all function definitions in the simList, specifically, into a sub-environment of the main simList environment: e.g., sim$<moduleName>$function1 (see section on Scoping)modules
copies objectsfrom the global environment to the simList environmentobjects
loads objectsfrom disk into the simListinputs
schedule object loading/copyingObjects can be loaded into the simList at any time during a simulationinputs
schedule object savingObjects can be saved to disk at any arbitrary time during the simulation. If specified here, this will be in addition to any saving due code inside a module (i.e., a module may manually run write.table(...)outputs
schedules "init" eventsfrom all modules (see events)automatic
assesses module dependenciesvia the inputs and outputs identified in their metadata. This gives the order of the .inputObjects and init events. This can be overridden by loadOrder.automatic
determines time unittakes time units of modules and how they fit togethertimes or automatic
runs .inputObjects functionsfrom every module in the module order as determined aboveautomatic
WhatDetails

params can only contain updates to any parameters that are defined in the metadata of modules. Take the example of a module named, Fire, which has a parameter named .plotInitialTime. In the metadata of that module, it says TRUE. Here we can override that default with: list(Fire=list(.plotInitialTime=NA)), effectively turning off plotting. Since this is a list of lists, one can override the module defaults for multiple parameters from multiple modules all at once, with say: list(Fire = list(.plotInitialTime = NA, .plotInterval = 2), caribouModule = list(N = 1000)).

We implement a discrete event simulation in a more modular fashion so it is easier to add modules to the simulation. We use S4 classes and methods, and fast lists to manage the event queue.

paths specifies the location of the module source files, the data input files, and the saving output files. If no paths are specified the defaults are as follows:

  • cachePath: getOption("spades.cachePath");

  • inputPath: getOption("spades.modulePath");

  • modulePath: getOption("spades.inputPath");

  • inputPath: getOption("spades.outputPath").

Note

The user can opt to run a simpler simInit call without inputs, outputs, and times. These can be added later with the accessor methods (See example). These are not required for initializing the simulation via simInit. modules, paths, params, and objects are all needed for successful initialization.

Parsing and Checking Code

The simInit function will attempt to find usage of sim$xxx or sim[['xxx']] on either side of the assignement "<-" operator. It will compare these to the module metadata, specifically inputObjects for cases where objects or "gotten" from the simList and outputObjects for cases where objects are assigned to the simList.

It will also attempt to find potential, common function name conflicts with things like scale and stack (both in base and raster), and Plot (in quickPlot and some modules).

This code checking is young and may get false positives and false negatives -- i.e., miss things. It also takes computational time, which may be undesireable in operational code. To turn off checking (i.e., if there are too many false positives and negatives), set the option spades.moduleCodeChecks to FALSE, e.g., options(spades.moduleCodeChecks = FALSE)

Caching

Using caching with SpaDES is vital when building re-useable and reproducible content. Please see the vignette dedicated to this topic. See https://CRAN.R-project.org/package=SpaDES/vignettes/iii-cache.html

References

Matloff, N. (2011). The Art of R Programming (ch. 7.8.3). San Fransisco, CA: No Starch Press, Inc.. Retrieved from https://www.nostarch.com/artofr.htm

See also

Examples

# NOT RUN {
mySim <- simInit(
 times = list(start = 0.0, end = 2.0, timeunit = "year"),
 params = list(
   .globals = list(stackName = "landscape", burnStats = "nPixelsBurned")
 ),
 modules = list("randomLandscapes", "fireSpread", "caribouMovement"),
 paths = list(modulePath = system.file("sampleModules", package = "SpaDES.core"))
)
spades(mySim) # shows plotting

# Change more parameters, removing plotting
mySim <- simInit(
 times = list(start = 0.0, end = 2.0, timeunit = "year"),
 params = list(
   .globals = list(stackName = "landscape", burnStats = "nPixelsBurned"),
   fireSpread = list(.plotInitialTime = NA)
 ),
 modules = list("randomLandscapes", "fireSpread", "caribouMovement"),
 paths = list(modulePath = system.file("sampleModules", package = "SpaDES.core"))
)
outSim <- spades(mySim)

# A little more complicated with inputs and outputs
if (require(rgdal)) {
 mapPath <- system.file("maps", package = "quickPlot")
 mySim <- simInit(
   times = list(start = 0.0, end = 2.0, timeunit = "year"),
   params = list(
     .globals = list(stackName = "landscape", burnStats = "nPixelsBurned")
   ),
   modules = list("randomLandscapes", "fireSpread", "caribouMovement"),
   paths = list(modulePath = system.file("sampleModules", package = "SpaDES.core"),
                outputPath = tempdir()),
   inputs = data.frame(
     files = dir(file.path(mapPath), full.names = TRUE, pattern = "tif")[1:2],
     functions = "raster",
     package = "raster",
     loadTime = 1,
     stringsAsFactors = FALSE),
   outputs = data.frame(
     expand.grid(objectName = c("caribou","landscape"),
     saveTime = 1:2,
     stringsAsFactors = FALSE))
 )

 # Use accessors for inputs, outputs
 mySim2 <- simInit(
   times = list(current = 0, start = 0.0, end = 2.0, timeunit = "year"),
   modules = list("randomLandscapes", "fireSpread", "caribouMovement"),
   params = list(.globals = list(stackName = "landscape", burnStats = "nPixelsBurned")),
   paths = list(
     modulePath = system.file("sampleModules", package = "SpaDES.core"),
     outputPath = tempdir()
   )
 )

 # add by accessor is equivalent
 inputs(mySim2) <- data.frame(
     files = dir(file.path(mapPath), full.names = TRUE, pattern = "tif")[1:2],
     functions = "raster",
     package = "raster",
     loadTime = 1,
     stringsAsFactors = FALSE)
 outputs(mySim2) <- data.frame(
     expand.grid(objectName = c("caribou", "landscape"),
     saveTime = 1:2,
     stringsAsFactors = FALSE))
 all.equal(mySim, mySim2) # TRUE

 # Use accessors for times -- does not work as desired because times are
 #   adjusted to the input timeunit during simInit
 mySim2 <- simInit(
   params = list(
     .globals = list(stackName = "landscape", burnStats = "nPixelsBurned")
   ),
   modules = list("randomLandscapes", "fireSpread", "caribouMovement"),
   paths = list(modulePath = system.file("sampleModules", package = "SpaDES.core"),
                outputPath = tempdir()),
   inputs = data.frame(
     files = dir(file.path(mapPath), full.names = TRUE, pattern = "tif")[1:2],
     functions = "raster",
     package = "raster",
     loadTime = 1,
     stringsAsFactors = FALSE),
   outputs = data.frame(
     expand.grid(objectName = c("caribou","landscape"),
     saveTime = 1:2,
     stringsAsFactors = FALSE))
 )

 # add times by accessor fails all.equal test because "year" was not
 #   declared during module loading, so month became the default
 times(mySim2) <- list(current = 0, start = 0.0, end = 2.0, timeunit = "year")
 all.equal(mySim, mySim2) # fails because time units are all different, so
                          # several parameters that have time units in
                          # "months" because they were loaded that way
 params(mySim)$fireSpread$.plotInitialTime
 params(mySim2)$fireSpread$.plotInitialTime
 events(mySim) # load event is at time 1 year
 events(mySim2) # load event is at time 1 month, reported in years because of
                #   update to times above
}
# }