simInit | R Documentation |
Create a new simulation object, the sim
object (a simList
).
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.
simInit(
times,
params,
modules,
objects,
paths,
inputs,
outputs,
loadOrder,
notOlderThan = NULL,
...
)
## S4 method for signature
## 'list,list,list,list,list,data.frame,data.frame,character'
simInit(
times,
params,
modules,
objects,
paths,
inputs,
outputs,
loadOrder,
notOlderThan = NULL,
...
)
## S4 method for signature 'ANY,ANY,ANY,character,ANY,ANY,ANY,ANY'
simInit(
times,
params,
modules,
objects,
paths,
inputs,
outputs,
loadOrder,
notOlderThan = NULL,
...
)
## S4 method for signature 'ANY,ANY,character,ANY,ANY,ANY,ANY,ANY'
simInit(
times,
params,
modules,
objects,
paths,
inputs,
outputs,
loadOrder,
notOlderThan = NULL,
...
)
## S4 method for signature 'ANY,ANY,ANY,ANY,ANY,ANY,ANY,ANY'
simInit(
times,
params,
modules,
objects,
paths,
inputs,
outputs,
loadOrder,
notOlderThan = NULL,
...
)
simInitDefaults()
times |
A named list of numeric simulation start and end times
(e.g., |
params |
A list of lists of the form |
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 |
objects |
(optional) A vector of object names (naming objects
that are in the calling environment of
the |
paths |
An optional named list with up to 4 named elements,
|
inputs |
A |
outputs |
A See |
loadOrder |
An optional character vector 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 |
... |
An alternative way to pass |
simInit
function does the following:What | Details | Argument(s) to use |
fills simList slots | places the arguments times ,
params , modules , paths into equivalently named
simList slots | times ,
params , modules , paths |
sources all module files | places 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 objects | from the global environment to the
simList environment | objects |
loads objects | from disk into the simList | inputs |
schedule object loading/copying | Objects can be loaded into the
simList at any time during a simulation | inputs |
schedule object saving | Objects 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" events | from all modules (see events() )
| automatic |
assesses module dependencies | via 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 unit | takes time units of modules and how they fit together | times or automatic |
runs .inputObjects functions | from every module in the module order as determined above | automatic |
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))
.
The params
list can contain a list (named .globals
) of named objects
e.g., .globals = list(climateURL = "https:\\something.com")
entry. Any and every
module that has a parameter with that name (in this case climateURL
) will be
overridden with this value as passed.
params
can be used to set the seed for a specific event in a module. This
is done using the normal params
argument, specifying .seed
as a list
where the elements are a numeric for the seed and the name is the event. Since
parameters must be specific to a module, this creates a module and event specific
seed e.g., params = list(moduleName = list(.seed = list(init = 123)))
will
set the init
event of module named moduleName
to 123. The RN stream
will be reset to its state prior to the set.seed
call after the event.
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("reproducible.cachePath")
;
inputPath
: getOption("spades.inputPath")
;
modulePath
: getOption("spades.modulePath")
;
outputPath
: getOption("spades.outputPath")
.
A simList
simulation object, pre-initialized from values
specified in the arguments supplied.
The simInit
function will attempt to find usage of sim$xxx
or sim[['xxx']]
on either side of the assignment (<-
) 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 undesirable in operational code.
To turn off checking (i.e., if there are too many false positives and negatives), set
options(spades.moduleCodeChecks = FALSE)
.
Using caching with SpaDES
is vital when building re-usable and reproducible content.
Please see the vignette dedicated to this topic.
Since the objects in the simList
are passed-by-reference, it is useful
to create a copy of the initialized simList
object prior to running
the simulation (e.g., mySimOut <- spades(Copy(mySim))
).
This ensures you retain access to the original objects, which would otherwise
be overwritten/modified during the simulation.
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
.
All of modules
, paths
, params
, and objects
are needed
for successful initialization.
Alex Chubaty and Eliot McIntire
Matloff, N. (2011). The Art of R Programming (ch. 7.8.3). San Francisco, CA: No Starch Press, Inc.. Retrieved from https://nostarch.com/artofr.htm
spades()
, defineModule()
to get help on metadata elements,
times()
, params()
, objs()
, paths()
,
modules()
, inputs()
, outputs()
# Tests take several seconds
if (requireNamespace("SpaDES.tools", quietly = TRUE) &&
requireNamespace("NLMR", quietly = TRUE)) {
opts <- options("spades.moduleCodeChecks" = FALSE, "spades.useRequire" = FALSE)
if (!interactive()) opts <- append(opts, options("spades.plots" = NA,
"spades.debug" = FALSE))
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 = getSampleModules(tempdir()))
)
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 = getSampleModules(tempdir()))
)
outSim <- spades(mySim)
# A little more complicated with inputs and outputs
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 = getSampleModules(tempdir()),
outputPath = tempdir()),
inputs = data.frame(
files = dir(file.path(mapPath), full.names = TRUE, pattern = "tif")[1:2],
functions = "rast",
package = "terra",
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(start = 0.0, end = 2.0, timeunit = "year"),
modules = list("randomLandscapes", "fireSpread", "caribouMovement"),
params = list(
.globals = list(stackName = "landscape", burnStats = "nPixelsBurned"),
randomLandscapes = list(nx = 10, ny = 10)
),
paths = list(
modulePath = getSampleModules(tempdir()),
outputPath = tempdir()
)
)
# add by accessor is equivalent
inputs(mySim2) <- data.frame(
files = dir(file.path(mapPath), full.names = TRUE, pattern = "tif")[1:2],
functions = "rast",
package = "terra",
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 = getSampleModules(tempdir()),
outputPath = tempdir()),
inputs = data.frame(
files = dir(file.path(mapPath), full.names = TRUE, pattern = "tif")[1:2],
functions = "rast",
package = "terra",
loadTime = 1,
stringsAsFactors = FALSE),
outputs = data.frame(
expand.grid(objectName = c("caribou","landscape"),
saveTime = 1:2,
eventPriority = c(0,10), # eventPriority 0 may give "initial" conditions
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
options(opts)
}
Add the following code to your website.
For more information on customizing the embed code, read Embedding Snippets.