Type: | Package |
Title: | Core Utilities for Developing and Running Spatially Explicit Discrete Event Models |
Description: | Provides the core framework for a discrete event system to implement a complete data-to-decisions, reproducible workflow. The core components facilitate the development of modular pieces, and enable the user to include additional functionality by running user-built modules. Includes conditional scheduling, restart after interruption, packaging of reusable modules, tools for developing arbitrary automated workflows, automated interweaving of modules of different temporal resolution, and tools for visualizing and understanding the within-project dependencies. The suggested package 'NLMR' can be installed from the repository (https://PredictiveEcology.r-universe.dev). |
URL: | https://spades-core.predictiveecology.org/, https://github.com/PredictiveEcology/SpaDES.core |
Date: | 2024-05-29 |
Version: | 2.1.0 |
Depends: | R (≥ 4.2), quickPlot (≥ 1.0.2), reproducible (≥ 2.1.0) |
Imports: | cli, data.table (≥ 1.11.0), fs, igraph (≥ 1.0.1), lobstr, methods, qs (≥ 0.21.1), Require (≥ 0.3.1), stats, terra (≥ 1.7-46), tools, utils, whisker |
Suggests: | archive, CircStats, codetools, covr, DiagrammeR (≥ 0.8.2), future, future.callr, ggplot2, ggplotify, httr, knitr, lattice, logging, magrittr, NLMR (≥ 1.1.1), pkgload, png, RColorBrewer (≥ 1.1-2), raster (≥ 2.5-8), rmarkdown, roxygen2, RSQLite, rstudioapi, sp, SpaDES.tools (≥ 2.0.0), tcltk, testthat (≥ 1.0.2), withr |
Additional_repositories: | https://predictiveecology.r-universe.dev/ |
Encoding: | UTF-8 |
Language: | en-CA |
License: | GPL-3 |
VignetteBuilder: | knitr, rmarkdown |
BugReports: | https://github.com/PredictiveEcology/SpaDES.core/issues |
ByteCompile: | yes |
Collate: | 'module-dependencies-class.R' 'misc-methods.R' 'environment.R' 'helpers.R' 'simList-class.R' 'times.R' 'simList-accessors.R' 'Plots.R' 'cache.R' 'check.R' 'priority.R' 'checkpoint.R' 'code-checking.R' 'convertToPackage.R' 'copy.R' 'debugging.R' 'downloadData.R' 'simulation-parseModule.R' 'simulation-simInit.R' 'load.R' 'memory-leaks.R' 'memory.R' 'modActiveBinding.R' 'module-define.R' 'module-dependencies-methods.R' 'module-param-check.R' 'module-repository.R' 'module-template.R' 'moduleCoverage.R' 'moduleMetadata.R' 'objectSynonyms.R' 'options.R' 'paths.R' 'plotting-diagrams.R' 'plotting.R' 'progress.R' 'project-template.R' 'reexports.R' 'restart.R' 'save.R' 'saveLoadSimList.R' 'simulation-spades.R' 'spades-classes.R' 'spades-core-deprecated.R' 'spades-core-package.R' 'suppliedElsewhere.R' 'zzz.R' |
RoxygenNote: | 7.3.1 |
NeedsCompilation: | no |
Packaged: | 2024-05-30 19:32:31 UTC; achubaty |
Author: | Alex M Chubaty |
Maintainer: | Eliot J B McIntire <eliot.mcintire@canada.ca> |
Repository: | CRAN |
Date/Publication: | 2024-06-02 11:02:47 UTC |
Categorized overview of the SpaDES.core
package
Description
This package allows implementation a variety of simulation-type models, with a focus on spatially explicit models. The core simulation components are built upon a discrete event simulation framework that facilitates modularity, and easily enables the user to include additional functionality by running user-built simulation modules. Included are numerous tools to visualize various spatial data formats, as well as non-spatial data. Much work has been done to speed up the core of the DES, with current benchmarking as low as 56 microseconds overhead for each event (including scheduling, sorting event queue, spawning event etc.) or 38 microseconds if there is no sorting (i.e., no sorting occurs under simple conditions). Under most event conditions, therefore, the DES itself will contribute very minimally compared to the content of the events, which may often be milliseconds to many seconds each event.
Bug reports: https://github.com/PredictiveEcology/SpaDES.core/issues
Module repository: https://github.com/PredictiveEcology/SpaDES-modules
Wiki: https://github.com/PredictiveEcology/SpaDES/wiki
Details
1 Spatial discrete event simulation (SpaDES
)
A collection of top-level functions for doing spatial discrete event simulation.
1.1 Simulations
There are two workhorse functions that initialize and run a simulation, and third function for doing multiple spades runs:
simInit() | Initialize a new simulation |
spades() | Run a discrete event simulation |
experiment | In SpaDES.experiment package.
Run multiple spades() calls |
experiment2 | In SpaDES.experiment package.
Run multiple spades() calls |
1.2 Events
Within a module, important simulation functions include:
scheduleEvent() | Schedule a simulation event |
scheduleConditionalEvent() | Schedule a conditional simulation event |
removeEvent | Remove an event from the simulation queue (not yet implemented) |
2 The simList
object class
The principle exported object class is the simList
.
All SpaDES
simulations operate on this object class.
simList() | The simList class |
3 simList
methods
Collections of commonly used functions to retrieve or set slots (and their elements)
of a simList()
object are summarized further below.
3.1 Simulation parameters
globals() | List of global simulation parameters. |
params() | Nested list of all simulation parameter. |
P() | Namespaced version of params()
(i.e., do not have to specify module name). |
3.2 loading from disk, saving to disk
inputs() | List of loaded objects used in simulation. (advanced) |
outputs() | List of objects to save during simulation. (advanced) |
3.3 objects in the simList
ls() , objects() | Names of objects referenced by the simulation environment. |
ls.str() | List the structure of the simList objects. |
objs() | List of objects referenced by the simulation environment. |
3.4 Simulation paths
Accessor functions for the paths
slot and its elements.
cachePath() | Global simulation cache path. |
modulePath() | Global simulation module path. |
inputPath() | Global simulation input path. |
outputPath() | Global simulation output path. |
rasterPath() | Global simulation temporary raster path. |
paths() | Global simulation paths (cache, modules, inputs, outputs, rasters). |
3.5 Simulation times
Accessor functions for the simtimes
slot and its elements.
time() | Current simulation time, in units of longest module. |
start() | Simulation start time, in units of longest module. |
end() | Simulation end time, in units of longest module. |
times() | List of all simulation times (current, start, end), in units of longest module.. |
3.6 Simulation event queues
Accessor functions for the events
and completed
slots.
By default, the event lists are shown when the simList
object is printed,
thus most users will not require direct use of these methods.
events() | Scheduled simulation events (the event queue). (advanced) |
current() | Currently executing event. (advanced) |
completed() | Completed simulation events. (advanced) |
elapsedTime() | The amount of clock time that modules & events use |
3.7 Modules, dependencies, packages
Accessor functions for the depends
, modules
, and .loadOrder
slots.
These are included for advanced users.
depends() | List of simulation module dependencies. (advanced) |
modules() | List of simulation modules to be loaded. (advanced) |
packages() | Vector of required R libraries of all modules. (advanced) |
3.8 simList
environment
The simList()
has a slot called .xData
which is an environment.
All objects in the simList
are actually in this environment,
i.e., the simList
is not a list
.
In R, environments use pass-by-reference semantics, which means that copying
a simList
object using normal R assignment operation (e.g., sim2 <- sim1
),
will not copy the objects contained within the .xData
slot.
The two objects (sim1
and sim2
) will share identical objects
within that slot. Sometimes, this not desired, and a true copy is required.
envir() | Access the environment of the simList directly (advanced) |
copy() | Deep copy of a simList. (advanced) |
3.9 Checkpointing
Accessor method | Module | Description |
checkpointFile() | checkpoint | Name of the checkpoint file. (advanced) |
checkpointInterval() | checkpoint | The simulation checkpoint interval. (advanced) |
3.10 Progress Bar
progressType() | .progress | Type of graphical progress bar used. (advanced) |
progressInterval() | .progress | Interval for the progress bar. (advanced) |
4 Module operations
4.1 Creating, distributing, and downloading modules
Modules are the basic unit of SpaDES
.
These are generally created and stored locally, or are downloaded from remote
repositories, including our
SpaDES-modules
repository on GitHub.
checksums() | Verify (and optionally write) checksums for a module's data files. |
downloadModule() | Open all modules nested within a base directory. |
getModuleVersion() | Get the latest module version # from module repository. |
newModule() | Create new module from template. |
newModuleDocumentation() | Create empty documentation for a new module. |
openModules() | Open all modules nested within a base directory. |
moduleMetadata() | Shows the module metadata. |
zipModule() | Zip a module and its associated files. |
4.2 Module metadata
Each module requires several items to be defined.
These comprise the metadata for that module (including default parameter
specifications, inputs and outputs), and are currently written at the top of
the module's .R
file.
defineModule() | Define the module metadata |
defineParameter() | Specify a parameter's name, value and set a default |
expectsInput() | Specify an input object's name, class, description, sourceURL and other specifications |
createsOutput() | Specify an output object's name, class, description and other specifications |
There are also accessors for many of the metadata entries:
timeunit() | Accesses metadata of same name |
citation() | Accesses metadata of same name |
documentation() | Accesses metadata of same name |
reqdPkgs() | Accesses metadata of same name |
inputObjects() | Accesses metadata of same name |
outputObjects() | Accesses metadata of same name |
4.3 Module dependencies
Once a set of modules have been chosen, the dependency information is automatically
calculated once simInit
is run. There are several functions to assist with dependency
information:
depsEdgeList() | Build edge list for module dependency graph |
depsGraph() | Build a module dependency graph using igraph |
5 Module functions
A collection of functions that help with making modules can be found in
the suggested SpaDES.tools
package, and are summarized below.
5.1 Spatial spreading/distances methods
Spatial contagion is a key phenomenon for spatially explicit simulation models.
Contagion can be modelled using discrete approaches or continuous approaches.
Several SpaDES.tools
functions assist with these:
SpaDES.tools::adj() | An optimized (i.e., faster) version of terra::adjacent() |
SpaDES.tools::cir() | Identify pixels in a circle around a SpatialPoints*() object |
directionFromEachPoint() | Fast calculation of direction and distance surfaces |
SpaDES.tools::distanceFromEachPoint() | Fast calculation of distance surfaces |
SpaDES.tools::rings() | Identify rings around focal cells (e.g., buffers and donuts) |
SpaDES.tools::spokes() | Identify outward radiating spokes from initial points |
SpaDES.tools::spread() | Contagious cellular automata |
SpaDES.tools::spread2() | Contagious cellular automata, different algorithm, more robust |
SpaDES.tools::wrap() | Create a torus from a grid |
5.2 Spatial agent methods
Agents have several methods and functions specific to them:
SpaDES.tools::crw() | Simple correlated random walk function |
SpaDES.tools::heading() | Determines the heading between SpatialPoints* |
quickPlot::makeLines() | Makes SpatialLines object for, e.g., drawing arrows |
move() | A meta function that can currently only take "crw" |
specificNumPerPatch() | Initiate a specific number of agents per patch |
5.3 GIS operations
In addition to the vast amount of GIS operations available in R (mostly from
contributed packages such as sf
, terra
, (also sp
, raster
), maps
, maptools
and many others), we provide the following GIS-related functions:
equalExtent() | Assess whether a list of extents are all equal |
5.4 'Map-reduce'–type operations
These functions convert between reduced and mapped representations of the same data. This allows compact representation of, e.g., rasters that have many individual pixels that share identical information.
SpaDES.tools::rasterizeReduced() | Convert reduced representation to full raster. |
5.5 Colours in Raster*
objects
We likely will not want the default colours for every map.
Here are several helper functions to add to, set and get colours of Raster*
objects:
setColors() | Set colours for plotting Raster* objects |
getColors() | Get colours in a Raster* objects |
divergentColors() | Create a colour palette with diverging colours around a middle |
5.6 Random Map Generation
It is often useful to build dummy maps with which to build simulation models before all data are available. These dummy maps can later be replaced with actual data maps.
SpaDES.tools::neutralLandscapeMap() | Creates a random map using Gaussian random fields |
SpaDES.tools::randomPolygons() | Creates a random polygon with specified number of classes |
5.7 Checking for the existence of objects
SpaDES
modules will often require the existence of objects in the simList
.
These are helpers for assessing this:
checkObject() | Check for a existence of an object within a simList |
reproducible::checkPath() | Checks the specified filepath for formatting consistencies |
5.8 SELES-type approach to simulation
These functions are essentially skeletons and are not fully implemented. They are intended to make translations from SELES (https://www.gowlland.ca/). You must know how to use SELES for these to be useful:
agentLocation() | Agent location |
SpaDES.tools::initiateAgents() | Initiate agents into a SpatialPointsDataFrame |
numAgents() | Number of agents |
probInit() | Probability of initiating an agent or event |
transitions() | Transition probability |
5.9 Miscellaneous
Functions that may be useful within a SpaDES
context:
SpaDES.tools::inRange() | Test whether a number lies within range [a,b] |
layerNames() | Get layer names for numerous object classes |
numLayers() | Return number of layers |
paddedFloatToChar() | Wrapper for padding (e.g., zeros) floating numbers to character |
6 Caching simulations and simulation components
Simulation caching uses the reproducible
package.
Caching can be done in a variety of ways, most of which are up to the module developer. However, the one most common usage would be to cache a simulation run. This might be useful if a simulation is very long, has been run once, and the goal is just to retrieve final results. This would be an alternative to manually saving the outputs.
See example in spades()
, achieved by using cache = TRUE
argument.
reproducible::Cache() | Caches a function, but often accessed as argument in spades() |
reproducible::showCache() | Shows information about the objects in the cache |
reproducible::clearCache() | Removes objects from the cache |
reproducible::keepCache() | Keeps only the objects described |
A module developer can build caching into their module by creating cached versions of their functions.
7 Plotting
Much of the underlying plotting functionality is provided by quickPlot.
There are several user-accessible plotting functions that are optimized for modularity and speed of plotting:
Commonly used:
Plot() | The workhorse plotting function |
Simulation diagrams:
eventDiagram() | Gantt chart representing the events in a completed simulation. |
moduleDiagram() | Network diagram of simplified module (object) dependencies. |
objectDiagram() | Sequence diagram of detailed object dependencies. |
Other useful plotting functions:
clearPlot() | Helpful for resolving many errors |
clickValues() | Extract values from a raster object at the mouse click location(s) |
clickExtent() | Zoom into a raster or polygon map that was plotted with Plot() |
clickCoordinates() | Get the coordinates, in map units, under mouse click |
dev() | Specify which device to plot on, making a non-RStudio one as default |
newPlot() | Open a new default plotting device |
rePlot() | Re-plots all elements of device for refreshing or moving plot |
8 File operations
In addition to R's file operations, we have added several here to aid in bulk loading and saving of files for simulation purposes:
loadFiles() | Load simulation objects according to a file list |
rasterToMemory() | Read a raster from file to RAM |
saveFiles() | Save simulation objects according to outputs and parameters |
9 Sample modules included in package
Several dummy modules are included for testing of functionality.
These can be found with file.path(find.package("SpaDES.core"), "sampleModules")
.
randomLandscapes | Imports, updates, and plots several raster map layers |
caribouMovement | A simple agent-based (a.k.a., individual-based) model |
fireSpread | A simple model of a spatial spread process |
10 Package options
SpaDES
packages use the following options()
to configure behaviour:
-
spades.browserOnError
: IfTRUE
, the default, then any error rerun the same event withdebugonce
called on it to allow editing to be done. When that browser is continued (e.g., with 'c'), then it will save it reparse it into thesimList
and rerun the edited version. This may allow a spades call to be recovered on error, though in many cases that may not be the correct behaviour. For example, if thesimList
gets updated inside that event in an iterative manner, then each run through the event will cause that iteration to occur. When this option isTRUE
, then the event will be run at least 3 times: the first time makes the error, the second time hasdebugonce
and the third time is after the error is addressed.TRUE
is likely somewhat slower. -
reproducible.cachePath
: The default local directory in which to cache simulation outputs. Default is a temporary directory (typically/tmp/RtmpXXX/SpaDES/cache
). -
spades.inputPath
: The default local directory in which to look for simulation inputs. Default is a temporary directory (typically/tmp/RtmpXXX/SpaDES/inputs
). -
spades.debug
: The default debugging valuedebug
argument inspades()
. Default isTRUE
. -
spades.lowMemory
: If true, some functions will use more memory efficient (but slower) algorithms. DefaultFALSE
. -
spades.moduleCodeChecks
: Should the various code checks be run duringsimInit
. These are passed tocodetools::checkUsage()
. Default is given by the function, plus these :list(suppressParamUnused = FALSE, suppressUndefined = TRUE, suppressPartialMatchArgs = FALSE, suppressNoLocalFun = TRUE, skipWith = TRUE)
. -
spades.modulePath
: The default local directory where modules and data will be downloaded and stored. Default is a temporary directory (typically/tmp/RtmpXXX/SpaDES/modules
). -
spades.moduleRepo
: The default GitHub repository to use when downloading modules viadownloadModule
. Default"PredictiveEcology/SpaDES-modules"
. -
spades.nCompleted
: The maximum number of completed events to retain in thecompleted
event queue. Default1000L
. -
spades.outputPath
: The default local directory in which to save simulation outputs. Default is a temporary directory (typically/tmp/RtmpXXX/SpaDES/outputs
). -
spades.recoveryMode
: If this a numeric greater than 0 or TRUE, then the discrete event simulator will take a snapshot of the objects in thesimList
that might change (based on metadataoutputObjects
for that module), prior to initiating every event. This will allow the user to be able to recover in case of an error or manual interruption (e.g.,Esc
). If this is numeric, a copy of that number of "most recent events" will be maintained so that the user can recover and restart more than one event in the past, i.e., redo some of the "completed" events. Default isTRUE
, i.e., it will keep the state of thesimList
at the start of the current event. This can be recovered withrestartSpades
and the differences can be seen in a hidden object in the stashedsimList.
There is a message which describes how to find that. -
spades.switchPkgNamespaces
: Should the search path be modified to ensure a module's required packages are listed first? DefaultFALSE
to keep computational overhead down. IfTRUE
, there should be no name conflicts among package objects, but it is much slower, especially if the events are themselves fast. -
spades.tolerance
: The default tolerance value used for floating point number comparisons. Default.Machine$double.eps^0.5
. -
spades.useragent
: The default user agent to use for downloading modules from GitHub.com. Default"https://github.com/PredictiveEcology/SpaDES"
.
Author(s)
Maintainer: Eliot J B McIntire eliot.mcintire@canada.ca (ORCID)
Authors:
Alex M Chubaty achubaty@for-cast.ca (ORCID)
Other contributors:
Yong Luo Yong.Luo@gov.bc.ca [contributor]
Steve Cumming Steve.Cumming@sbf.ulaval.ca [contributor]
Ceres Barros ceres.barros@ubc.ca (ORCID) [contributor]
His Majesty the King in Right of Canada, as represented by the Minister of Natural Resources Canada [copyright holder]
See Also
Create an empty data.frame
object for use with inputObjects
or
outputObjects
Description
Internal function.
Usage
._inputObjectsDF(x)
## S4 method for signature 'missing'
._inputObjectsDF()
._outputObjectsDF(x)
## S4 method for signature 'missing'
._outputObjectsDF()
Arguments
x |
Not used. Should be missing. |
Value
A data.frame
object.
Author(s)
Alex Chubaty
See Also
.addChangedAttr
for simList
objects
Description
This will evaluate which elements in the simList
object changed following
this Cached function call. It will add a named character string as an
attribute attr(x, ".Cache")$changed
, indicating which ones changed.
When this function is subsequently called again, only these changed objects
will be returned. All other simList
objects will remain unchanged.
Usage
## S4 method for signature 'simList'
.addChangedAttr(object, preDigest, origArguments, ...)
Arguments
object |
Any R object returned from a function |
preDigest |
The full, element by element hash of the input arguments to that same function,
e.g., from |
origArguments |
These are the actual arguments (i.e., the values, not the names) that
were the source for |
... |
Anything passed to methods. |
Value
returns the object with attribute added
See Also
Add simulation dependencies
Description
Internal function.
Adds a .moduleDeps
object to the simulation dependency list.
Usage
.addDepends(sim, x)
## S4 method for signature 'simList,.moduleDeps'
.addDepends(sim, x)
Arguments
sim |
A |
x |
A named list containing the parameters used to construct a new
|
Value
A simList
object.
Author(s)
Alex Chubaty
See Also
Other functions to access elements of a 'simList' object:
checkpointFile()
,
envir()
,
events()
,
globals()
,
inputs()
,
modules()
,
objs()
,
packages()
,
params()
,
paths()
,
progressInterval()
,
times()
.addTagsToOutput
for simList
objects
Description
See reproducible::.addTagsToOutput()
.
Usage
## S4 method for signature 'simList'
.addTagsToOutput(object, outputObjects, FUN, preDigestByClass)
Arguments
object |
Any R object returned from a function |
outputObjects |
Optional character vector indicating which objects to return. This is only relevant for list, environment (or similar) objects |
FUN |
A function |
preDigestByClass |
A list, usually from |
Value
modified object
, with attributes added
Author(s)
Eliot McIntire
.cacheMessage
for simList
objects
Description
See reproducible::.cacheMessage()
.
Usage
## S4 method for signature 'simList'
.cacheMessage(
object,
functionName,
fromMemoise = getOption("reproducible.useMemoise", TRUE),
verbose = getOption("reproducible.verbose")
)
Arguments
object |
Any R object returned from a function |
functionName |
A character string indicating the function name |
fromMemoise |
Logical. If |
verbose |
Numeric, -1 silent (where possible), 0 being very quiet,
1 showing more messaging, 2 being more messaging, etc.
Default is 1. Above 3 will output much more information about the internals of
Caching, which may help diagnose Caching challenges. Can set globally with an
option, e.g., |
See Also
Namespacing within SpaDES
Description
This will only return the module name if it is inside a spades
call,
i.e., it will return NULL
if used in interactive mode.
The related function currentModule
is simply a rapid accessor for the
current module name. This latter will return the module that is in the current
event queue, which will never be NULL
.
Usage
.callingModuleName(sim)
## S4 method for signature 'simList'
.callingModuleName(sim)
currentModule(sim)
## S4 method for signature 'simList'
currentModule(sim)
.callingFrameTimeunit(x)
Arguments
sim |
A |
x |
A |
Value
.callingModuleName
returns the name of the module that is currently
the active module calling functions like scheduleEvent
.
Author(s)
Eliot McIntire
.checkCacheRepo
for simList
objects
Description
See reproducible::.checkCacheRepo()
.
Usage
## S4 method for signature 'list'
.checkCacheRepo(object, create = FALSE)
Arguments
object |
Any R object returned from a function |
create |
Logical. If TRUE, then it will create the path for cache. |
Value
character string representing a directory path to the cache repo
See Also
strip GitHub repo info from vector of packages
Description
strip GitHub repo info from vector of packages
Usage
.cleanPkgs(pkgs)
Named list of core SpaDES
modules
Description
Internal function.
Usage
.coreModules()
Value
Returns a named list of the core modules.
Author(s)
Alex Chubaty
Determine module load order
Description
Internal function. Checks module dependencies and attempts to ensure that cyclic dependencies can be resolved, checking objects in the global environment, and finally, attempts to determine the load order for modules in the simulation.
Usage
.depsLoadOrder(sim, simGraph)
## S4 method for signature 'simList,igraph'
.depsLoadOrder(sim, simGraph)
Arguments
sim |
A |
simGraph |
An |
Details
Uses igraph::topo_sort()
to try to find a load order satisfying
all module object dependencies.
Value
Character vector of module names, sorted in correct load order.
Author(s)
Alex Chubaty
Prune edges to remove cycles in module dependencies
Description
Internal function. Attempts to identify cycles in the dependency graph and remove edges representing object dependencies which are provided by other modules in the simulation.
Usage
.depsPruneEdges(simEdgeList)
## S4 method for signature 'data.table'
.depsPruneEdges(simEdgeList)
Arguments
simEdgeList |
An edge list ( |
Value
An updated edge list object.
Author(s)
Alex Chubaty
Default (empty) metadata
Description
Internal use only. Default values to use for metadata elements when not otherwise supplied.
Usage
.emptyMetadata(x)
## S4 method for signature 'missing'
.emptyMetadata()
Arguments
x |
Not used. Should be missing. |
Author(s)
Alex Chubaty
Open a file for editing
Description
RStudio's file.edit
behaves differently than utils::file.edit
.
The workaround is to have the user manually open the file if they are using RStudio.
Usage
.fileEdit(file)
Arguments
file |
Character string giving the file path to open. |
Value
Invoked for its side effect of opening a file for editing.
Author(s)
Alex Chubaty
File extensions map
Description
How to load various types of files in R.
This function has two roles:
to proceed with the loading of files that are in a
simList
; oras a shortcut to
simInit(inputs = filelist)
.
A data.frame
with information on how to load various types of files in R,
containing the columns:
-
exts
: the file extension; -
fun
: the function to use for files with this file extension; -
package
: the package from which to loadfun
.
Usage
.fileExtensions()
loadFiles(sim, filelist, ...)
## S4 method for signature 'simList,missing'
loadFiles(sim, filelist, ...)
## S4 method for signature 'missing,ANY'
loadFiles(sim, filelist, ...)
## S4 method for signature 'missing,missing'
loadFiles(sim, filelist, ...)
.saveFileExtensions()
Arguments
sim |
|
filelist |
|
... |
Additional arguments. |
Value
data.frame
of file extension, package, and function mappings
the modified sim
, invisibly.
data.frame
Note
Generally not intended to be used by users.
Author(s)
Eliot McIntire and Alex Chubaty
See Also
Examples
library(SpaDES.core)
# Load random maps included with package
filelist <- data.frame(
files = dir(getMapPath(tempdir()), full.names = TRUE),
functions = "rasterToMemory",
package = "SpaDES.core"
)
sim1 <- loadFiles(filelist = filelist) # loads all the maps to sim1 simList
# Second, more sophisticated. All maps loaded at time = 0, and the last one is reloaded
# at time = 10 and 20 (via "intervals").
# Also, pass the single argument as a list to all functions...
# specifically, when add "native = TRUE" as an argument to the raster function
files <- dir(getMapPath(tempdir()), full.names = TRUE)
arguments <- I(rep(list(lyrs = 1), length(files)))
filelist <- data.frame(
files = files,
functions = "terra::rast",
objectName = NA,
arguments = arguments,
loadTime = 0,
intervals = c(rep(NA, length(files)-1), 10)
)
sim2 <- loadFiles(filelist = filelist) # only does the time = 0 loading; see next
end(sim2) <- 10
sim2 <- spades(sim2) # loads the object at time 10
# if we extend the end time and continue running, it will load an object scheduled
# at time = 10, and it will also schedule a new object loading at 20 because
# interval = 10
end(sim2) <- 20
sim2 <- spades(sim2) # loads the percentPine map 2 more times, once at 10, once at 20
Create empty fileTable
for inputs and outputs
Description
Internal functions.
Returns an empty fileTable
to be used with inputs and outputs.
Usage
.fileTableIn(x)
## S4 method for signature 'missing'
.fileTableIn()
.fileTableInCols
.fileTableInDF
.fileTableOut(x)
## S4 method for signature 'missing'
.fileTableOut()
.fileTableOutCols
.fileTableOutDF
Arguments
x |
Not used (should be missing) |
Format
An object of class character
of length 8.
An object of class data.frame
with 0 rows and 8 columns.
An object of class character
of length 7.
An object of class data.frame
with 0 rows and 7 columns.
Value
An empty data.frame with structure needed for input/output fileTable.
An internal function for coercing a data.frame to inputs()
Description
An internal function for coercing a data.frame to inputs()
Usage
.fillInputRows(inputDF, startTime)
Arguments
inputDF |
A data.frame with partial columns to pass to |
startTime |
Numeric time. The |
An internal function for coercing a data.frame to outputs()
Description
An internal function for coercing a data.frame to outputs()
Usage
.fillOutputRows(outputDF, endTime)
Arguments
outputDF |
A data.frame with partial columns to pass to |
endTime |
Numeric time. The |
Find all references to sim$
Description
Find all references to sim$
.parsingSim
will pull out the various ways to use sim
, e.g.,
sim$xxx
, sim[["xxx"]]
, sim[[P(sim)$xxx]]
Usage
.findElementsInEnv(
envToFindSim = parent.frame(),
moduleEnv = parent.frame(),
type
)
.findElement(x, type)
.parsingSim(x, type)
Arguments
envToFindSim |
An environment where |
moduleEnv |
The environment where the module functions are. |
type |
Either "get", "assign", or "globals". See details. |
x |
A call in which to search for |
Details
.findElementsInEnv
is a wrapper around .findElements
.
It will convert function code to a call, and then pass it to .findElements
.
It also does some cleaning for duplications, NA
values, and cases where the element
inside a sim[["xxx"]]
is a variable that should be evaluated, rather than
simply taken verbatim (e.g., sim[[P(sim)$stackName]])
.
When type = "get"
, the function scans for sim$xxx
or sim[["xxx"]]]
on
the RHS of an assignment operator or when there is no assignment. When
type = "assign"
, the function scans for sim$xxx
or sim[["xxx"]]
on the
LHS of an assignment operator. When type = "globals"
, the function
scans for all functions (i.e., "globals") being used.
This is similar to codetools::findGlobals()
, but faster.
.findElement
will omit whatever it finds inside a is.null()
, when type = "assign"
.
Usually this is a test of existence of that object, in order to assign to that object.
It is only reading it to determine whether or not it should write to it.
Value
A character string with all sim
objects found.
Author(s)
Eliot McIntire
Identify module names up to a given recursive level
Description
With children, parents, grandparents, etc.; there can be several "layers" of recursion. Some functions need to evaluate the outer level for a value, if found, they don't need to proceed further. If not found, increment one more level of recursion, etc.
Usage
.findModuleName(modList, recursive = 0)
Arguments
modList |
(Nested) Named list of module names |
recursive |
Numeric. The depth of recursion, where 0 is only top level, 1 is 1 level in etc. |
Value
Character vector of modules names
Find objects if passed as character strings
Description
Objects are passed into simList
via simInit
call or objects(simList)
assignment. This function is an internal helper to find those objects from their
environments by searching the call stack.
Usage
.findObjects(objects, functionCall = "simInit")
Arguments
objects |
A character vector of object names |
functionCall |
A character string identifying the function name to be
searched in the call stack. Default is |
Author(s)
Eliot McIntire
Find simList
in a nested list
Description
This is recursive, so it will find the all simList
s even if they are deeply nested.
Usage
.findSimList(x)
Arguments
x |
any object, used here only when it is a list with at least one
|
Extract the user-defined .inputObjects
function from a module
Description
Extract the user-defined .inputObjects
function from a module
Usage
.getModuleInputObjects(sim, m)
A slightly modified version of getOption()
Description
This can take x
as a character string or as a function that returns a character string.
Usage
.getOption(x, default = NULL)
Arguments
x |
a character string holding an option name. |
default |
if the specified option is not set in the options list, this value is returned. This facilitates retrieving an option and checking whether it is set and setting it separately if not. |
Guess package of a function
Description
Guess package of a function
Usage
.guessPkgFun(bsf)
Arguments
bsf |
character. A function name |
Value
character. The package and function name as "pkg::bsf"
Identify child modules from a recursive list
Description
There can be parents, grandparents, etc
Usage
.identifyChildModules(sim, modules)
Arguments
sim |
a |
modules |
List of module names |
Value
list of modules
will flat named list of all module names (children, parents etc.) and
childModules
a non-flat named list of only the childModule
names.
Check is module uses module namespacing
Description
Older modules may not have their functions etc. namespaced in the simList
.
Usage
.isNamespaced(sim, m)
Attach missing attributes from x
to y
Description
This is an internal helper.
Usage
.keepAttrs(x, y, omitAttrs = c(".envir", ".list", ".xData", ".Data"))
Arguments
x |
an object with attributes |
y |
an object with attributes |
Reserved module parameter names
Description
These are common parameter names that are reserved for specific use within modules.
Usage
.knownDotParams
Format
An object of class character
of length 7.
Details
-
.plotInitialTime
: the initial time for plotting; -
.plotInterval
: the interval between plots; -
.plots
: the types of plots to create (seetypes
argument inPlots()
); -
.saveInitialTime
: the initial time for saving; -
.saveInterval
: the interval between saves; -
.useCache
: whether to use caching, or which events to cache; -
.useParallel
: whether to use parallel processing, or the number of parallel cores to use;
Modify package order in search path
Description
Intended for internal use only. It modifies the search path (i.e., search()
)
such that the packages required by the current module are placed first in the
search path. Note, several "core" packages are not touched; or more specifically,
they will remain in the search path, but may move down if packages are rearranged.
The current set of these core packages used by SpaDES can be found here:
SpaDES.core:::.corePackages
Usage
.modifySearchPath(
pkgs,
removeOthers = FALSE,
skipNamespacing = !getOption("spades.switchPkgNamespaces")
)
Arguments
pkgs |
The packages that are to be placed at the beginning of the search path, |
removeOthers |
Logical. If |
skipNamespacing |
Logical. If |
Value
Nothing. This is used for its side effects, which are "severe".
Author(s)
Eliot McIntire
The .moduleDeps
class
Description
Descriptor object for specifying SpaDES module dependencies.
Slots
name
Name of the module as a character string.
description
Description of the module as a character string.
keywords
Character vector containing a module's keywords.
authors
The author(s) of the module as a
person()
object.childModules
A character vector of child module names. Modules listed here will be loaded with this module.
version
The module version as a
numeric_version
. Semantic versioning is assumed https://semver.org/.spatialExtent
Specifies the module's spatial extent as an
Raster::Extent
orterra::SpatExtent
object. Default isNA
.timeframe
Specifies the valid timeframe for which the module was designed to simulate. Must be a
POSIXt()
object of length 2, specifying the start and end times (e.g.,as.POSIXlt(c("1990-01-01 00:00:00", "2100-12-31 11:59:59"))
). Can be specified asNA
usingas.POSIXlt(c(NA, NA))
.timeunit
Describes the time (in seconds) corresponding to 1.0 simulation time units. Default is
NA
.citation
A list of citations for the module, each as character strings. Alternatively, list of filenames of
.bib
or similar files. Defaults toNA_character_
.documentation
List of filenames referring to module documentation sources.
loadOrder
An optional list of up to 2 named character vectors, named "before" and "after". If specified, then SpaDES.core will use this information to help disentangle ambiguous module load order estimation. Any module that is specified in the "before" element will have its "init" event scheduled before this module; any module specified in the "after" element will have its "init" event scheduled after this module.
reqdPkgs
Character vector of R package names to be loaded. Defaults to
NA_character_
.parameters
A
data.frame
specifying the object dependencies of the module, with columnsparamName
,paramClass
, anddefault
, whose values are of typecharacter
,character
, andANY
, respectively. Default values may be overridden by the user by passing a list of parameters tosimInit()
.inputObjects
A
data.frame
specifying the object dependencies of the module, with columnsobjectName
,objectClass
, andother
. For objects that are used within the module as both an input and an output, add the object to each of thesedata.frame
s.outputObjects
A
data.frame
specifying the objects output by the module, following the format ofinputObjects
.
Author(s)
Alex Chubaty
See Also
.simDeps
, spadesClasses()
.parseElems
for simList
class objects
Description
Usage
## S4 method for signature 'simList'
.parseElems(tmp, elems, envir)
Arguments
tmp |
A evaluated object |
elems |
A character string to be parsed |
envir |
An environment |
Value
An object, parsed from a character string and an environment.
See Also
Prepend module name to a message
Description
Also makes it blue.
Usage
.parseMessage(m, problem, message)
Arguments
m |
module name |
message |
rest of message |
Value
returns TRUE
; invoked for side effect of generating message with that starts with
paste0(m, ":", message)
.
Parse and initialize a module
Description
Internal function, used during simInit()
.
Usage
.parseModulePartial(sim, modules, filename, defineModuleElement, envir = NULL)
## S4 method for signature 'missing,missing,character,character'
.parseModulePartial(filename, defineModuleElement, envir)
## S4 method for signature 'simList,list,missing,character'
.parseModulePartial(sim, modules, defineModuleElement, envir = NULL)
.parseModule(
sim,
modules,
userSuppliedObjNames = NULL,
envir = NULL,
notOlderThan,
...
)
## S4 method for signature 'simList,list'
.parseModule(
sim,
modules,
userSuppliedObjNames = NULL,
envir = NULL,
notOlderThan,
...
)
Arguments
sim |
A |
modules |
A list of modules with a logical attribute "parsed". |
filename |
The filename of the module to be parsed. |
defineModuleElement |
Character string indicating which of the list
elements in |
envir |
Optional environment in which to store parsed code. This may be
useful if the same file is being parsed multiple times. This
function will check in that environment for the parsed file before
parsing again. If the |
userSuppliedObjNames |
Character string (or |
notOlderThan |
Passed to |
... |
All |
Value
.parseModulePartial
extracts just the individual element
requested from the module. This can be useful if parsing the whole module
would cause an error.
A simList
simulation object.
Author(s)
Eliot McIntire
Alex Chubaty and Eliot McIntire
The SpaDES.core
package environment
Description
Environment used internally to store internal package objects and methods.
Usage
.pkgEnv
Format
An object of class environment
of length 7.
Pre-digesting method for simList
Description
Takes a snapshot of simList
objects.
Usage
## S4 method for signature 'simList'
.preDigestByClass(object)
Arguments
object |
Any R object returned from a function |
Details
See reproducible::.preDigestByClass()
.
Value
character vector corresponding to the names of objects stored in the .xData
slot
Author(s)
Eliot McIntire
See Also
reproducible::.preDigestByClass
.prepareOutput
for simList
objects
Description
See reproducible::.prepareOutput()
.
Usage
## S4 method for signature 'simList'
.prepareOutput(object, cachePath, ...)
Arguments
object |
Any R object returned from a function |
cachePath |
A repository used for storing cached objects.
This is optional if |
... |
Anything passed to methods. |
Value
the modified object
See Also
The SpaDES.core
variable to switch between quick and robust checking
Description
A variable that can be use by module developers and model users to switch between
a quick check of functions like downloadData
, Cache.
The module developer must actually use this in their code.
Usage
.quickCheck
Format
An object of class logical
of length 1.
Generate random strings
Description
Generate a vector of random alphanumeric strings each of an arbitrary length.
Usage
.rndstr(n = 1, len = 8)
rndstr(n, len, characterFirst)
## S4 method for signature 'numeric,numeric,logical'
rndstr(n, len, characterFirst)
## S4 method for signature 'numeric,numeric,missing'
rndstr(n, len)
## S4 method for signature 'numeric,missing,logical'
rndstr(n, characterFirst)
## S4 method for signature 'missing,numeric,logical'
rndstr(len, characterFirst)
## S4 method for signature 'numeric,missing,missing'
rndstr(n)
## S4 method for signature 'missing,numeric,missing'
rndstr(len)
## S4 method for signature 'missing,missing,logical'
rndstr(characterFirst)
## S4 method for signature 'missing,missing,missing'
rndstr(n, len, characterFirst)
Arguments
n |
Number of strings to generate (default 1). Will attempt to coerce to integer value. |
len |
Length of strings to generate (default 8). Will attempt to coerce to integer value. |
characterFirst |
Logical, if |
Value
Character vector of random strings.
Author(s)
Alex Chubaty and Eliot McIntire
Examples
set.seed(11)
rndstr()
rndstr(len = 10)
rndstr(characterFirst = FALSE)
rndstr(n = 5, len = 10)
rndstr(n = 5)
rndstr(n = 5, characterFirst = TRUE)
rndstr(len = 10, characterFirst = TRUE)
rndstr(n = 5, len = 10, characterFirst = TRUE)
.robustDigest
for simList
objects
Description
This is intended to be used within the Cache
function, but can be used to evaluate what
a simList
would look like once it is converted to a repeatably digestible object.
Usage
## S4 method for signature 'simList'
.robustDigest(object, .objects, length, algo, quick, classOptions)
Arguments
object |
an object to digest. |
.objects |
Character vector of objects to be digested. This is only applicable if there is a list, environment (or similar) with named objects within it. Only this/these objects will be considered for caching, i.e., only use a subset of the list, environment or similar objects. In the case of nested list-type objects, this will only be applied outermost first. |
length |
Numeric. If the element passed to Cache is a |
algo |
The algorithms to be used; currently available choices are
|
quick |
Logical or character. If |
classOptions |
Optional list. This will pass into |
Details
See reproducible::.robustDigest()
.
This method strips out stuff from a simList
class object that would make it otherwise not
reproducibly digestible between sessions, operating systems, or machines.
This will likely still not allow identical digest results across R versions.
Author(s)
Eliot McIntire
See Also
Runs a series of code checks during simInit()
Description
This uses custom tools and some optional tools in the codetools
package to check for function
collisions with known, common function collisions (raster::stack
, raster::scale
).
All outputs will be sent as messages.
Usage
.runCodeChecks(sim, m, k, hadPrevMessage = FALSE)
Arguments
sim |
a |
m |
module name |
k |
numeric index of module name in sim@depends@dependencies, should align with |
hadPrevMessage |
Value
NULL (invisibly); invoked for side effect of generating message with that starts with
paste0(m, ":", message)
.
Run module's .inputObjects
Description
Run .inputObjects()
from each module file from each module, one at a time,
and remove it from the simList
so next module won't rerun it.
Usage
.runModuleInputObjects(sim, m, objects, notOlderThan)
sim2gantt
Description
Internal function to convert the completed events list of a simList
object to a list of data.frame
s suitable to pass to a call to
DiagrammeR::mermaid
to make a Gantt chart representing the
events in a completed simulation.
Usage
.sim2gantt(sim, n, startDate, width)
## S4 method for signature 'simList,numeric,character,numeric'
.sim2gantt(sim, n, startDate, width)
Arguments
sim |
A |
n |
The number of most recently completed events to plot. |
startDate |
A character representation of date in |
width |
Numeric. Passed to determine scale of vertical bars. |
Value
A list of data.frames
Author(s)
Alex Chubaty
The .simDeps
class
Description
Defines all simulation dependencies for all modules within a SpaDES simulation.
Slots
dependencies
List of
.moduleDeps()
dependency objects.
Author(s)
Alex Chubaty
See Also
.moduleDeps()
, spadesClasses()
.tagsByClass
for simList
objects
Description
See reproducible::.tagsByClass()
. Adds current moduleName
,
eventType
, eventTime
, and function:spades
as userTags
.
Usage
## S4 method for signature 'simList'
.tagsByClass(object)
Arguments
object |
Any R object returned from a function |
Author(s)
Eliot McIntire
See Also
tryCatch
that keeps warnings, errors and value (result)
Description
From https://stackoverflow.com/a/24569739/3890027
Usage
.tryCatch(expr)
Determine which modules in a list are unparsed
Description
Internal function, used during simInit()
.
Usage
.unparsed(modules)
## S4 method for signature 'list'
.unparsed(modules)
Arguments
modules |
A character vector specifying the modules to parse. |
Value
The ids of the unparsed list elements.
Author(s)
Alex Chubaty
Chose verb conjugation for "to be"
Description
Chose verb conjugation for "to be"
Usage
.verb(item)
Arguments
item |
The item to accord conjugation with. If length 1, then "is" else "are". |
Value
character string "is" or "are".
Methods for .wrap
and .unwrap
Description
Methods for .wrap
and .unwrap
Usage
## S3 method for class 'simList'
.wrap(
obj,
cachePath,
preDigest,
drv = getOption("reproducible.drv", NULL),
conn = getOption("reproducible.conn", NULL),
verbose = getOption("reproducible.verbose"),
outputObjects = NULL,
...
)
## S3 method for class 'simList'
.unwrap(
obj,
cachePath,
cacheId,
drv = getOption("reproducible.drv", NULL),
conn = getOption("reproducible.conn", NULL),
...
)
Arguments
obj |
Any arbitrary R object. |
cachePath |
A repository used for storing cached objects.
This is optional if |
preDigest |
The list of |
drv |
an object that inherits from |
conn |
A |
verbose |
Numeric, -1 silent (where possible), 0 being very quiet,
1 showing more messaging, 2 being more messaging, etc.
Default is 1. Above 3 will output much more information about the internals of
Caching, which may help diagnose Caching challenges. Can set globally with an
option, e.g., |
outputObjects |
Optional character vector indicating which objects to return. This is only relevant for list, environment (or similar) objects |
... |
Other arguments. Can be in the form of |
cacheId |
An optional character vector describing the |
Value
The same object as passed into the function, but dealt with so that it can be saved to disk.
Copy for simList
class objects
Description
Because a simList
works with an environment to hold all objects,
all objects within that slot are pass-by-reference.
That means it is not possible to simply copy an object with an assignment operator:
the two objects will share the same objects.
As one simList
object changes so will the other.
When this is not the desired behaviour, use this function.
Usage
## S4 method for signature 'simList'
Copy(object, objects, queues, modules, ...)
Arguments
object |
An R object (likely containing environments) or an environment. |
objects |
Whether the objects contained within the |
queues |
Logical. Should the events queues ( |
modules |
Logical. Should list of modules be copied. |
... |
Only used for custom Methods |
Details
simList
objects can contain a lot of information, much of which could be
in pass-by-reference objects (e.g., data.table
class), and objects that are
file-backed, such as some Raster*
-class objects. For all the objects that
are file-backed, it is likely very important to give unique file-backed
directories. This should be passed here, which gets passed on to the many methods
of Copy
in reproducible
.
Value
a copy of object
Note
uses capital C, to limit confusion with e.g., data.table::copy()
.
Author(s)
Eliot McIntire
See Also
Plot method for simList
objects
Description
Extends quickPlot::Plot
for simList
objects.
Usage
## S4 method for signature 'simList'
Plot(
...,
new = FALSE,
addTo = NULL,
gp = gpar(),
gpText = gpar(),
gpAxis = gpar(),
axes = FALSE,
speedup = 1,
size = 5,
cols = NULL,
col = NULL,
zoomExtent = NULL,
visualSqueeze = NULL,
legend = TRUE,
legendRange = NULL,
legendText = NULL,
pch = 19,
title = NULL,
na.color = "#FFFFFF00",
zero.color = NULL,
length = NULL,
arr = NULL,
plotFn = "plot",
verbose = getOption("quickPlot.verbose")
)
Arguments
... |
A combination of |
new |
Logical. If |
addTo |
Character vector, with same length as |
gp |
A |
gpText |
A |
gpAxis |
A |
axes |
Logical or |
speedup |
Numeric. The factor by which the number of pixels is divided by to plot rasters. See Details. |
size |
Numeric. The size, in points, for |
cols |
(also |
col |
(also |
zoomExtent |
An |
visualSqueeze |
Numeric. The proportion of the white space to be used for plots. Default is 0.75. |
legend |
Logical indicating whether a legend should be drawn.
Default is |
legendRange |
Numeric vector giving values that, representing the lower
and upper bounds of a legend (i.e., |
legendText |
Character vector of legend value labels.
Defaults to |
pch |
see |
title |
Logical or character string. If logical, it
indicates whether to print the object name as the title
above the plot. If a character string, it will print this
above the plot. NOTE: the object name is used with |
na.color |
Character string indicating the colour for |
zero.color |
Character string indicating the colour for zero values, when zero is the minimum value, otherwise, zero is treated as any other colour. Default transparent. |
length |
Numeric. Optional length, in inches, of the arrow head. |
arr |
A vector of length 2 indicating a desired arrangement of plot areas indicating number of rows, number of columns. Default NULL, meaning let Plot function do it automatically. |
plotFn |
An optional function name to do the plotting internally, e.g., "barplot" to get a barplot() call. Default "plot". |
verbose |
Numeric or logical. If |
Details
See quickPlot::Plot
.
This method strips out stuff from a simList
class object that would make it otherwise not
reproducibly digestible between sessions, operating systems, or machines.
This will likely still not allow identical digest results across R versions.
Value
invoked for side effect of plotting
See Also
quickPlot::Plot
Plot
wrapper intended for use in a SpaDES module
Description
This is a single function call that allows a user to change which format in which
the plots will occur.
Specifically, the two common formats would be to "screen"
or to disk as an image file,
such as "png"
.
This has currently been tested with ggplot2
, RasterLayer
, and tmap
objects.
The default (or change with e.g., fn = "print", usePlot = FALSE
) uses
Plot
internally, so individual plots may be rearranged. When saved to
disk (e.g., via type = 'png'
), then Plot
will not be used and the single object
that is the result of this Plots
call will be saved to disk.
This function requires at least 2 things: a plotting function and arguments passed
to that function (which could include data
, but commonly would simply be named
arguments required by fn
).
See below and examples.
Usage
Plots(
data,
fn,
filename,
types = quote(params(sim)[[currentModule(sim)]]$.plots),
path = quote(figurePath(sim)),
.plotInitialTime = quote(params(sim)[[currentModule(sim)]]$.plotInitialTime),
ggsaveArgs = list(),
usePlot = getOption("spades.PlotsUsePlot", FALSE),
deviceArgs = list(),
...
)
Arguments
data |
An (optional) arbitrary data object. If supplied, it will be passed as
the first argument to |
fn |
An arbitrary plotting function. If not provided, defaults to using |
filename |
A name that will be the base for the files that will be saved, i.e,
do not supply the file extension, as this will be determined based on |
types |
Character vector, zero or more of types. If used within a module, this
will be deduced from the |
path |
Currently a single path for the saved objects on disk. If |
.plotInitialTime |
A numeric. If |
ggsaveArgs |
An optional list of arguments passed to |
usePlot |
Logical. If |
deviceArgs |
An optional list of arguments passed to one of |
... |
Anything needed by |
Details
-
type
-
"screen"
– Will plot to the current device, normally a plot window -
"object"
– Will save the plot object, e.g.,ggplot
object -
"raw"
– Will save the raw data prior to plotting, e.g., the data argument -
"png"
– or any other type save-able withggsave
-
Value
Called for its side effect of plot creation.
Recording of files saved
In cases where files are saved, and where Plots
is used within a SpaDES module,
the file(s) that is/are saved will be appended to the outputs
slot of the
simList
of the module. This will, therefore, keep a record of figures saved
within the simList
Note
This is still experimental and could change in the next release.
Plots
now has experimental support for "just a Plot
call", but with types
specified.
See examples.
The devices to save on disk will have some different behaviours to the screen representation,
since "wiping" an individual plot on a device doesn't exist for a file device.
This offers up to 4 different actions for a given plot:
To screen device
To disk as raw data (limited testing)
To disk as a saved plot object (limited testing)
To disk as a ‘.png’ or other image file, e.g., ‘.pdf’
To turn off plotting both to screen and disk, set both
.plotInititalTime = NA
and .plots = NA
or any other
value that will not trigger a TRUE with a grepl
with the types
argument (e.g., ""
will omit all saving).
Examples
# Note: if this is used inside a SpaDES module, do not define this
# function inside another function. Put it outside in a normal
# module script. Otherwise, it will cause a memory leak.
if (requireNamespace("ggplot2")) {
fn <- function(d)
ggplot2::ggplot(d, ggplot2::aes(a)) +
ggplot2::geom_histogram()
sim <- simInit()
sim$something <- data.frame(a = sample(1:10, replace = TRUE))
Plots(data = sim$something, fn = fn,
types = c("png"),
path = file.path("figures"),
filename = tempfile(),
.plotInitialTime = 1
)
# plot to active device and to png
Plots(data = sim$something, fn = fn,
types = c("png", "screen"),
path = file.path("figures"),
filename = tempfile(),
.plotInitialTime = 1
)
# Can also be used like quickPlot::Plot, but with control over output type
r <- terra::rast(terra::ext(0,10,0,10), vals = sample(1:3, size = 100, replace = TRUE))
Plots(r, types = c("screen", "png"), deviceArgs = list(width = 700, height = 500),
usePlot = TRUE)
# with ggplotify, Plots can also be used to plot/save
# non-ggplot objects:
if (require("ggplotify")) {
if (!require("lattice")) stop("please install lattice")
plotFile <- tempfile()
p1 <- densityplot(~mpg|cyl, data=mtcars)
Plots(data = p1, fn = as.ggplot, filename = plotFile,
ggsaveArgs = list(width = 5, height = 4, dpi = 300, bg = "white", units = "in"),
types = c("screen", "png"), .plotInitialTime = 1)
}
} # end ggplot
# end of dontrun
Extract an intact simList
but with subset of objects
Description
This is copies the non-object components of a simList
(e.g., events, etc.)
then selects only the objects listed in i
using Copy(mget(i, envir(sim)))
and adds them to the returned simList
.
Usage
## S4 method for signature 'simList,character,ANY'
x[i, j, ..., drop = TRUE]
Arguments
x |
A |
i |
A character vector of objects to select. |
j |
Not used. |
... |
Not used. |
drop |
Not used. |
Value
The [
method returns a complete simList
class with all the slots
copied from the original, but only the named objects in i
are returned.
Author(s)
Eliot McIntire
Examples
s <- simInit()
s$a <- 1
s$b <- 2
s$d <- 3
s[c("a", "d")] # a simList with only 2 objects
All equal method for simList
objects
Description
This function removes a few attributes that are added internally
by SpaDES.core and are not relevant to the all.equal
.
One key element removed is any time stamps, as these are guaranteed to be different.
A possibly very important argument to pass to the ...
is check.attributes = FALSE
which will allow successful comparisons of many objects that might have pointers.
Usage
## S3 method for class 'equal.simList'
all(target, current, ...)
Arguments
target |
R object. |
current |
other R object, to be compared with |
... |
further arguments for different methods, notably the following two, for numerical comparison: |
Value
Test whether there should be any plotting from .plots
module parameter
Description
This will do all the various tests needed to determine whether
plotting of one sort or another will occur.
Testing any of the types as listed in Plots()
argument types
.
Only the first 3 letters of the type are required.
Usage
anyPlotting(.plots)
Arguments
.plots |
Usually will be the |
Value
logical of length 1
Append attributes
Description
Ordinary base lists and vectors do not retain their attributes when subsetted or appended. This function appends items to a list while preserving the attributes of items in the list (but not of the list itself).
Usage
append_attr(x, y)
## S4 method for signature 'list,list'
append_attr(x, y)
Arguments
x , y |
A |
Details
Similar to updateList
but does not require named lists.
Value
An updated list
with attributes.
Author(s)
Alex Chubaty and Eliot McIntire
Examples
tmp1 <- list("apple", "banana")
tmp1 <- lapply(tmp1, `attributes<-`, list(type = "fruit"))
tmp2 <- list("carrot")
tmp2 <- lapply(tmp2, `attributes<-`, list(type = "vegetable"))
append_attr(tmp1, tmp2)
rm(tmp1, tmp2)
Simple wrapper around data.table::rbindlist
Description
This simply sets defaults to fill = TRUE
, and use.names = TRUE
.
Usage
bindrows(...)
Arguments
... |
one or more |
Value
a data.table
object
Check for the existence of a remote module
Description
Looks in the remote repo
for a module named name
.
Usage
checkModule(name, repo)
## S4 method for signature 'character,character'
checkModule(name, repo)
## S4 method for signature 'character,missing'
checkModule(name)
Arguments
name |
Character string giving the module name. |
repo |
GitHub repository name.
Default is |
Value
a character vector of module file paths (invisibly).
Author(s)
Eliot McIntire and Alex Chubaty
Check for the existence of a module locally
Description
Looks the module path for a module named name
, and checks for existence
of all essential module files listed below.
Usage
checkModuleLocal(name, path, version)
## S4 method for signature 'character,character,character'
checkModuleLocal(name, path, version)
## S4 method for signature 'character,ANY,ANY'
checkModuleLocal(name, path, version)
Arguments
name |
Character string giving the module name. |
path |
Local path to modules directory.
Default is specified by the global option |
version |
Character specifying the desired module version. |
Details
-
‘data/CHECKSUMS.txt’
-
‘name.R’
Value
Logical indicating presence of the module (invisibly).
Author(s)
Alex Chubaty
Check for existence of object(s) referenced by a objects
slot of a
simList
object
Description
Check that a named object exists in the provide simList
environment slot,
and optionally has desired attributes.
Usage
checkObject(sim, name, object, layer, ...)
## S4 method for signature 'simList,ANY,ANY'
checkObject(sim, name, object, layer, ...)
## S4 method for signature 'simList,character,missing'
checkObject(sim, name, object, layer, ...)
## S4 method for signature 'missing,ANY,ANY'
checkObject(sim, name, object, layer, ...)
Arguments
sim |
A |
name |
A character string specifying the name of an object to be checked. |
object |
An object. This is mostly used internally, or with layer, because it will fail if the object does not exist. |
layer |
Character string, specifying a layer name in a Raster, if the
|
... |
Additional arguments. Not implemented. |
Value
Invisibly return TRUE
indicating object exists; FALSE
if not.
Author(s)
Alex Chubaty and Eliot McIntire
See Also
Examples
sim <- simInit()
sim$a <- 1
sim$b <- list(d = 1)
sim$r <- terra::rast(terra::ext(0,2,0,2), res = 1, vals = 2)
sim$s <- c(sim$r, terra::rast(terra::ext(0,2,0,2), res = 1, vals = 3))
names(sim$s) <- c("r1", "r2") # give layer names
(checkObject(sim, name = "a")) # TRUE
(checkObject(sim, name = "b", layer = "d")) # TRUE
(checkObject(sim, name = "d")) # FALSE
(checkObject(sim, name = "r")) # TRUE
(checkObject(sim, object = sim$s)) # TRUE
(checkObject(sim, object = sim$s, layer = "r1")) # TRUE
Check use and existence of parameters passed to simulation.
Description
Checks that all parameters passed are used in a module, and that all parameters used in a module are passed.
Usage
checkParams(sim, coreParams, ...)
## S4 method for signature 'simList,list'
checkParams(sim, coreParams, ...)
Arguments
sim |
A |
coreParams |
List of default core parameters. |
... |
Additional arguments. Not implemented. |
Value
Invisibly return TRUE
indicating object exists; FALSE
if not.
Sensible messages are produced identifying missing parameters.
Author(s)
Alex Chubaty
Simulation checkpoints
Description
Save and reload the current state of the simulation, including the state of the random number generator, by scheduling checkpoint events.
Usage
checkpointFile(sim)
## S4 method for signature 'simList'
checkpointFile(sim)
checkpointFile(sim) <- value
## S4 replacement method for signature 'simList'
checkpointFile(sim) <- value
checkpointInterval(sim)
## S4 method for signature 'simList'
checkpointInterval(sim)
checkpointInterval(sim) <- value
## S4 replacement method for signature 'simList'
checkpointInterval(sim) <- value
doEvent.checkpoint(sim, eventTime, eventType, debug = FALSE)
checkpointLoad(file)
.checkpointSave(sim, file)
Arguments
sim |
A |
value |
The parameter value to be set (in the corresponding |
eventTime |
A numeric specifying the time of the next event. |
eventType |
A character string specifying the type of event: one of
either |
debug |
Optional logical flag determines whether |
file |
The checkpoint file. |
Value
Returns the modified simList
object.
Note
Checkpoint files are intended to be used locally, and do not invoke the simulation archiving tools to bundle and subsequently extract simulation files (e.g., file-backed rasters).
RNG save code adapted from: http://www.cookbook-r.com/Numbers/Saving_the_state_of_the_random_number_generator/ and https://stackoverflow.com/q/13997444/1380598
Author(s)
Alex Chubaty
See Also
Other functions to access elements of a 'simList' object:
.addDepends()
,
envir()
,
events()
,
globals()
,
inputs()
,
modules()
,
objs()
,
packages()
,
params()
,
paths()
,
progressInterval()
,
times()
Calculate checksum for a module's data files
Description
Verify (and optionally write) checksums for data files in a module's
‘data/’ subdirectory. The file ‘data/CHECKSUMS.txt’ contains the
expected checksums for each data file.
Checksums are computed using reproducible:::.digest
, which is simply a
wrapper around digest::digest
.
Usage
checksums(module, path, ...)
Arguments
module |
Character string giving the name of the module. |
path |
Character string giving the path to the module directory. |
... |
Passed to |
Details
Modules may require data that for various reasons cannot be distributed with the module source code. In these cases, the module developer should ensure that the module downloads and extracts the data required. It is useful to not only check that the data files exist locally but that their checksums match those expected.
Note
In version 1.2.0 and earlier, two checksums per file were required because of differences in the checksum hash values on Windows and Unix-like platforms. Recent versions use a different (faster) algorithm and only require one checksum value per file. To update your ‘CHECKSUMS.txt’ files using the new algorithm:
specify your module (
moduleName <- "my_module"
);use a temporary location to ensure all modules get fresh copies of the data (
tmpdir <- file.path(tempdir(), "SpaDES_modules")
);download your module's data to the temp dir (
downloadData(moduleName, tmpdir)
);initialize a dummy simulation to ensure any 'data prep' steps in the
.inputObjects
section are run (simInit(modules = moduleName)
);recalculate your checksums and overwrite the file (
checksums(moduleName, tmpdir, write = TRUE)
);copy the new checksums file to your working module directory (the one not in the temp dir) (
file.copy(from = file.path(tmpdir, moduleName, 'data', 'CHECKSUMS.txt'), to = file.path('path/to/my/moduleDir', moduleName, 'data', 'CHECKSUMS.txt'), overwrite = TRUE)
).
A citation method for SpaDES
modules
Description
This is a wrapper around utils::citation()
for cases with package
is a
character
string. Otherwise, it takes a simList
.
Usage
citation(package, lib.loc = NULL, auto = NULL, module = character())
## S4 method for signature 'simList'
citation(package, lib.loc = NULL, auto = NULL, module = character())
## S4 method for signature 'character'
citation(package, lib.loc = NULL, auto = NULL, module = character())
Arguments
package |
For compatibility with |
lib.loc |
a character vector with path names of R libraries, or
the directory containing the source for |
auto |
a logical indicating whether the default citation
auto-generated from the package ‘DESCRIPTION’ metadata should
be used or not, or |
module |
Optional character string indicating which module params should come from. |
Value
The citation information for a SpaDES module.
Filter objects by class
Description
Based on https://stackoverflow.com/a/5158978/1380598.
Usage
classFilter(x, include, exclude, envir)
## S4 method for signature 'character,character,character,environment'
classFilter(x, include, exclude, envir)
## S4 method for signature 'character,character,character,missing'
classFilter(x, include, exclude)
## S4 method for signature 'character,character,missing,environment'
classFilter(x, include, envir)
## S4 method for signature 'character,character,missing,missing'
classFilter(x, include)
Arguments
x |
Character vector of object names to filter, possibly from |
include |
Class(es) to include, as a character vector. |
exclude |
Optional class(es) to exclude, as a character vector. |
envir |
The environment ins which to search for objects. Default is the calling environment. |
Value
Vector of object names matching the class filter.
Note
inherits()
is used internally to check the object class,
which can, in some cases, return results inconsistent with is
.
See https://stackoverflow.com/a/27923346/1380598.
These (known) cases are checked manually and corrected.
Author(s)
Alex Chubaty
Examples
## from local (e.g., function) environment
local({
e <- environment()
a <- list(1:10) # class `list`
b <- letters # class `character`
d <- stats::runif(10) # class `numeric`
f <- sample(1L:10L) # class `numeric`, `integer`
g <- lm( jitter(d) ~ d ) # class `lm`
h <- glm( jitter(d) ~ d ) # class `lm`, `glm`
classFilter(ls(), include=c("character", "list"), envir = e)
classFilter(ls(), include = "numeric", envir = e)
classFilter(ls(), include = "numeric", exclude = "integer", envir = e)
classFilter(ls(), include = "lm", envir = e)
classFilter(ls(), include = "lm", exclude = "glm", envir = e)
rm(a, b, d, e, f, g, h)
})
## from another environment (can be omitted if .GlobalEnv)
e = new.env(parent = emptyenv())
e$a <- list(1:10) # class `list`
e$b <- letters # class `character`
e$d <- stats::runif(10) # class `numeric`
e$f <- sample(1L:10L) # class `numeric`, `integer`
e$g <- lm( jitter(e$d) ~ e$d ) # class `lm`
e$h <- glm( jitter(e$d) ~ e$d ) # class `lm`, `glm`
classFilter(ls(e), include=c("character", "list"), envir = e)
classFilter(ls(e), include = "numeric", envir = e)
classFilter(ls(e), include = "numeric", exclude = "integer", envir = e)
classFilter(ls(e), include = "lm", envir = e)
classFilter(ls(e), include = "lm", exclude = "glm", envir = e)
rm(a, b, d, f, g, h, envir = e)
rm(e)
clearCache
for simList
objects
Description
This will take the cachePath(object)
and pass
Usage
## S4 method for signature 'simList'
clearCache(
x,
userTags = character(),
after = NULL,
before = NULL,
fun = NULL,
cacheId = NULL,
ask = getOption("reproducible.ask"),
useCloud = FALSE,
cloudFolderID = getOption("reproducible.cloudFolderID", NULL),
drv = getDrv(getOption("reproducible.drv", NULL)),
conn = getOption("reproducible.conn", NULL),
verbose = getOption("reproducible.verbose"),
...
)
## S4 method for signature 'simList'
showCache(
x,
userTags = character(),
after = NULL,
before = NULL,
fun = NULL,
cacheId = NULL,
drv = getDrv(getOption("reproducible.drv", NULL)),
conn = getOption("reproducible.conn", NULL),
verbose = getOption("reproducible.verbose"),
...
)
## S4 method for signature 'simList'
keepCache(
x,
userTags = character(),
after = NULL,
before = NULL,
ask = getOption("reproducible.ask"),
drv = getDrv(getOption("reproducible.drv", NULL)),
conn = getOption("reproducible.conn", NULL),
verbose = getOption("reproducible.verbose"),
...
)
Arguments
x |
A simList or a directory containing a valid Cache repository. Note:
For compatibility with |
userTags |
Character vector. If used, this will be used in place of the
|
after |
A time (POSIX, character understandable by data.table). Objects cached after this time will be shown or deleted. |
before |
A time (POSIX, character understandable by data.table). Objects cached before this time will be shown or deleted. |
fun |
An optional character vector describing the function name to extract. Only functions with this/these functions will be returned. |
cacheId |
An optional character vector describing the |
ask |
Logical. If |
useCloud |
Logical. If |
cloudFolderID |
A googledrive dribble of a folder, e.g., using |
drv |
an object that inherits from |
conn |
A |
verbose |
Numeric, -1 silent (where possible), 0 being very quiet,
1 showing more messaging, 2 being more messaging, etc.
Default is 1. Above 3 will output much more information about the internals of
Caching, which may help diagnose Caching challenges. Can set globally with an
option, e.g., |
... |
Other arguments. Can be in the form of |
Value
A data.table
object showing the subset of items in the cache, located at cachePath
of the sim
object, if sim
is provided, or located in cachePath
.
For clearCache
(invoked for its side effect of clearing objects matching userTags
, or those
between after
or before
), the returned data.table
shows the removed items (invisibly).
Convert standard module code into an R package
Description
EXPERIMENTAL – USE WITH CAUTION. This function attempts to convert a
SpaDES module to the closest rendition of the same functionality, but in an
R package. The main change is that instead of SpaDES.core
parsing the functions
using custom parsing tools, it will use pkgload::load_all
on the package functions.
These
Usage
convertToPackage(
module = NULL,
path = getOption("spades.modulePath"),
buildDocuments = TRUE
)
Arguments
module |
Character string of module name, without path |
path |
Character string of |
buildDocuments |
A logical. If |
Details
convertToPackage
will:
move any functions that were defined within the main module file (
moduleName.R
) into the R folder, with the same name, but ending withFns.R
;keep the
defineModule(...)
function call with all the metadata in the same file,moduleName.R
, but with all other content removed, i.e., only thedefineModule(...)
will be here.build documentation from all the roxygen2 tags
places one roxygen2 tag,
@export
in front of thedoEvent.moduleName
function, so that the function can be found bySpaDES.core
All other functions will be kept "private", i.e., not exported, unless the user manually adds
@export
, as per a normal packagewill make a
DESCRIPTION
file from the SpaDES module metadatawill make a
NAMESPACE
file from the roxygen2 tags (e.g.,@export
)
A user can continue to use the module code as before, i.e., by editing it and
putting browser()
etc. It will be parsed during simInit
. Because the functions
are "in a package", they are automatically namespaced with each other, so that
when you want to use a function from that package, there is no need to put a
prefix with the package name.
This function does not install anything (e.g., devtools::install
). After
running this function, simInit
will automatically detect that this is now
a package and will load the functions (via pkgload::load_all
) from the source files.
This will have the effect that it emulates the "non-package" behaviour of a
SpaDES module exactly. After running this function, current tests show no
impact on module behaviour, other than event-level and module-level Caching will show
changes and will be rerun. Function-level Caching appears unaffected.
In other words, this should cause no changes to running the module code via
simInit
and spades
.
This function will create
and fill a minimal DESCRIPTION
file. This will leave the defineModule
function call as the only code in the main module file. This defineModule
and a doEvent.xxx
are the only 2 elements that are required for an R
package to be considered a SpaDES module. With these changes, the module should
still function normally, but will be able to act like an
R package, e.g., for writing function documentation with roxygen2
,
using the testthat
infrastructure, etc.
This function is intended to be run once for a module that was created using
the "standard" SpaDES module structure (e.g., from a newModule
call). There
is currently no way to "revert" the changes from R (though it can be done using
version control utilities if all files are under version control, e.g., GitHub).
Currently SpaDES.core
identifies a module as being a package if it has
a DESCRIPTION
file, or if it has been installed to the .libPaths()
e.g., via devtools::install
or the like. So one can simply remove the
package from .libPaths
and delete the DESCRIPTION
file and
SpaDES.core
will treat it as a normal module.
Value
Invoked for its side effects. There will be a new or modified
DESCRIPTION
file in the root directory of the module. Any functions that
were in the main module script (i.e., the .R file whose filename is the name of
the module and is in the root directory of the module) will be moved to individual
.R
files in the R
folder. Any function with a dot prefix will have the
dot removed in its respective filename, but the function name is unaffected.
Currently, SpaDES.core
does not install the package under any circumstances.
It will load it via pkgdown::load_all
, and optionally (option("spades.moduleDocument" = TRUE)
)
build documentation via roxygen2::roxygenise
within the simInit
call.
This means that any modifications to source code
will be read in during the simInit
call, as is the practice when a module
is not a package.
invoked for the side effect of converting a module to a package
Reverting
Currently, this is not a reversible process. We recommend trying one module at
a time, running your code. If all seems to work, then great. Commit the changes.
If things don't seem to work, then revert the changes and continue on as before.
Ideally, file a bug report on the SpaDES.core
GitHub.com pages.
Currently
Exported functions
The only function that will be exported by default is the doEvent.xxx
,
where xxx
is the module name. If any other module is to be exported, it must
be explicitly exported with e.g., @export
, and then building the NAMESPACE
file, e.g., via devtools::document(moduleRootPath)
. NOTE: as long as all
the functions are being used inside each other, and they all can be traced back
to a call in doEvent.xxx
, then there is no need to export anything else.
DESCRIPTION
The DESCRIPTION
file that is created (destroying any existing DESCRIPTION
file) with this function will have
several elements that a user may wish to change. Notably, all packages that were
in reqdPkgs
in the SpaDES module metadata will be in the Imports
section of the DESCRIPTION
. To accommodate the need to see these functions,
a new R script, imports.R
will be created with @import
for each
package in reqdPkgs
of the module metadata. However, if a module already has used
@importFrom
for importing a function from a package, then the generic
@import
will be omitted for that (those) package(s).
So, a user should likely follow standard R package
best practices and use @importFrom
to identify the specific functions that
are required within external packages, thereby limiting function name collisions
(and the warnings that come with them).
Other elements of a standard DESCRIPTION
file that will be missing or possibly
inappropriately short are Title
, Description
, URL
,
BugReports
.
Installing as a package
There is no need to "install" the source code as a package because simInit
will load it on the fly. But, there may be reasons to install it, e.g., to have
access to individual functions, help manual, running tests etc. To do this,
simply use the devtools::install(pathToModuleRoot)
. Even if it is installed,
simInit
will nevertheless run pkgload::load_all
to ensure the
spades
call will be using the current source code.
Examples
if (requireNamespace("ggplot2") && requireNamespace("pkgload") ) {
tmpdir <- tempdir2()
newModule("test", tmpdir, open = FALSE)
convertToPackage("test", path = tmpdir)
pkgload::load_all(file.path(tmpdir, "test"))
pkgload::unload("test")
}
Create a copy of an existing module
Description
Create a copy of an existing module
Usage
copyModule(from, to, path, ...)
## S4 method for signature 'character,character,character'
copyModule(from, to, path, ...)
## S4 method for signature 'character,character,missing'
copyModule(from, to, path, ...)
Arguments
from |
The name of the module to copy. |
to |
The name of the copy. |
path |
The path to a local module directory. Defaults to the path set by
the |
... |
Additional arguments to |
Value
Invisible logical indicating success (TRUE
) or failure (FALSE
).
Author(s)
Alex Chubaty
Define an output object of a module
Description
Used to specify an output object's name, class, description and other specifications.
Usage
createsOutput(objectName, objectClass, desc, ...)
## S4 method for signature 'ANY,ANY,ANY'
createsOutput(objectName, objectClass, desc, ...)
## S4 method for signature 'character,character,character'
createsOutput(objectName, objectClass, desc, ...)
Arguments
objectName |
Character string to define the output object's name. |
objectClass |
Character string to specify the output object's class. |
desc |
Text string providing a brief description of the output object.
If there are extra spaces or carriage returns, these will be stripped,
allowing for multi-line character strings without using |
... |
Other specifications of the output object. |
Value
A data.frame
suitable to be passed to outputObjects
in
a module's metadata.
Author(s)
Yong Luo
Examples
outputObjects <- bindrows(
createsOutput(objectName = "outputObject1", objectClass = "character",
desc = "this is for example"),
createsOutput(objectName = "outputObject2", objectClass = "numeric",
desc = "this is for example",
otherInformation = "I am the second output object")
)
Alternative way to define events in SpaDES.core
Description
There are two ways to define what occurs during an event: defining a function
called doEvent.moduleName
, where moduleName
is the actual module name.
This approach is the original approach used in SpaDES.core, and it must have an
explicit switch
statement branching on eventType
.
The newer approach (still experimental) uses defineEvent()
.
Instead of creating, doEvent.moduleName()
, it creates one function
for each event, each with the name doEvent.moduleName.eventName
.
This may be a little bit cleaner, but both with still work.
Usage
defineEvent(
sim,
eventName = "init",
code,
moduleName = NULL,
envir = parent.frame()
)
Arguments
sim |
A |
eventName |
Character string of the desired event name to define. Default is "init" |
code |
An expression that defines the code to execute during the event. This will
be captured, and pasted into a new function ( |
moduleName |
Character string of the name of the module. If this function is used within a module, then it will try to find the module name. |
envir |
An optional environment to specify where to put the resulting function.
The default will place a function called |
See Also
defineModule()
, simInit()
, scheduleEvent()
Examples
sim <- simInit()
# these put the functions in the parent.frame() which is .GlobalEnv for an interactive user
defineEvent(sim, "init", moduleName = "thisTestModule", code = {
sim <- Init(sim) # initialize
# Now schedule some different event for "current time", i.e., will
# be put in the event queue to run *after* this current event is finished
sim <- scheduleEvent(sim, time(sim), "thisTestModule", "grow")
}, envir = envir(sim))
defineEvent(sim, "grow", moduleName = "thisTestModule", code = {
sim <- grow(sim) # grow
# Now schedule this same event for "current time plus 1", i.e., a "loop"
sim <- scheduleEvent(sim, time(sim) + 1, "thisTestModule", "grow") # for "time plus 1"
})
Init <- function(sim) {
sim$messageToWorld <- "Now the sim has an object in it that can be accessed"
sim$size <- 1 # initializes the size object --> this can be anything, Raster, list, whatever
message(sim$messageToWorld)
return(sim) # returns all the things you added to sim as they are in the simList
}
grow <- function(sim) {
sim$size <- sim$size + 1 # increments the size
message(sim$size)
return(sim)
}
# schedule that first "init" event
sim <- scheduleEvent(sim, 0, "thisTestModule", "init")
# Look at event queue
events(sim) # shows the "init" we just added
# this is skipped when running in automated tests; it is fine in interactive use
out <- spades(sim)
Define a new module.
Description
Specify a new module's metadata as well as object and package dependencies. Packages are loaded during this call. Any or all of these can be missing, with missing values set to defaults
Usage
defineModule(sim, x)
## S4 method for signature 'simList,list'
defineModule(sim, x)
Arguments
sim |
A |
x |
A list with a number of named elements, referred to as the metadata. See details. |
Value
Updated simList
object.
Required metadata elements
name | Module name. Must match the filename (without the .R extension).
This is currently not parsed by SpaDES;
it is for human readers only. |
description | Brief description of the module. This is currently not parsed by SpaDES; it is for human readers only. |
keywords | Author-supplied keywords. This is currently not parsed by SpaDES; it is for human readers only. |
childModules | If this contains any character vector, then it will
be treated as a parent module. If this is a parent module,
then only this list entry will be read. For normal,
i.e., 'child modules', this should be character(0) or
NA .
If a character vector is provided, then these must be the
names of the modules located in the same file path as this
parent module that will be loaded during the simInit . |
authors | Module author information (as a vector of person()
objects. This is currently not parsed by SpaDES;
it is for human readers only. |
version | Module version number (will be coerced to numeric_version()
if a character or numeric are supplied).
The module developer should update manually this with each change
that is made to the module. See https://semver.org/
for a widely accepted standard for version numbering. |
spatialExtent | The spatial extent of the module supplied via
terra::ext . This is currently unimplemented.
Once implemented, this should define what spatial region this
module is scientifically reasonable to be used in. |
timeframe | Vector (length 2) of POSIXt dates specifying the temporal extent
of the module. Currently unimplemented.
Once implemented, this should define what time frame this
module is scientifically reasonable to be used for. |
timeunit | Time scale of the module (e.g., "day", "year"). If this is
not specified, then .timeunitDefault() will be used.
It indicates what '1' unit of time
means for this module. SpaDES interprets this
and if modules have different timeunit values
then it will correctly schedule each module, using the
smallest (currently the default) timeunit as the
'model' timeunit in the spades call. |
citation | List of character strings specifying module citation information.
Alternatively, a list of filenames of .bib or similar files.
This is currently not parsed by SpaDES;
it is for human readers only. |
documentation | List of filenames referring to module documentation sources. This is currently not parsed by SpaDES; it is for human readers only. |
loadOrder | Named list of length 0, 1, or 2, with names being after and before .
Each element should be a character string/vector naming 1 or more
modules that this module must be after or before .
after and before are used from the current module's
perspective. So, list(after = c("Biomass_core")) means that
this module must come after "Biomass_core" . This should only
be used when there are cyclic dependencies (2 or more modules
have 1 or more objects that is in both inputObjects and
outputObjects of both/all modules) between this module
and other modules. In cases where the dependencies are not cyclic,
SpaDES is able to resolve the order correctly. |
reqdPkgs | List of R package names required by the module. These
packages will be loaded when simInit is called.
Require::Require() will be used internally
to load if available, and install if not available.
Because Require::Require() can also download from
GitHub.com, these packages can specify package names stored
on GitHub, e.g., "PredictiveEcology/SpaDES.core@development" . |
parameters | A data.frame specifying the parameters used in the module.
Usually produced by rbind -ing the outputs of multiple
defineParameter() calls. These parameters indicate
the default values that will be used unless a module user
overrides them with the params argument in the
simInit() call. The minimum and maximum are
currently used by the SpaDES.shiny::shine function and the
POM function, and they should indicate the range
of values that are reasonable scientifically. |
inputObjects | A data.frame specifying the data objects expected as
inputs to the module,
with columns objectName (class character ),
objectClass (class character ),
sourceURL (class character ), and other
(currently spades does nothing with this column).
This data.frame identifies the objects that are expected,
but does not do any loading of that object into the simList .
The sourceURL gives the developer the opportunity
to identify the source of a data file that can be used
with the model. This URL will be
used if the user calls downloadData (or
downloadModule(..., data = TRUE) . If the raw data
must be modified, the developer can use create a
function called .inputObjects in their module. That
function will be run during the simInit call. The
developer should ensure that if the object is supplied
by the module user as an argument in the simInit , then
the .inputObjects should not be run, i.e., use an
(is.null(sim$xxx))) . |
outputObjects | A data.frame specifying the data objects output by
the module, with columns identical to those in
inputObjects . Like inputObjects above,
this only identifies the objects that this module will output
into the simList .
The module developer must create the necessary functions
that will cause these objects to be put into the
simList . |
Author(s)
Alex Chubaty
See Also
moduleDefaults()
, defineEvent()
Examples
## a default version of the defineModule is created with a call to newModule
newModule("test", path = tempdir(), open = FALSE)
## view the resulting module file
if (interactive()) file.edit(file.path(tempdir(), "test", "test.R"))
Define a parameter used in a module
Description
Used to specify a parameter's name, value, and set a default. The min
and
max
arguments are ignored by simInit
or spades
; they
are for human use only. To ensure that a user cannot set parameters outside of
a range of values, the module developer should use assertions in their module
code.
Usage
defineParameter(name, class, default, min, max, desc, ...)
Arguments
name |
Character string giving the parameter name. |
class |
Character string giving the parameter class. |
default |
The default value to use when none is specified by the user. Non-standard evaluation is used for the expression. |
min |
With |
max |
With |
desc |
Text string providing a brief description of the parameter.
If there are extra spaces or carriage returns, these will be stripped,
allowing for multi-line character strings without using |
... |
A convenience that allows writing a long |
Value
a data.frame
Note
Be sure to use the correct NA type: logical (NA
), integer (NA_integer_
),
real (NA_real_
), complex (NA_complex_
), or character (NA_character_
).
See NA()
.
Author(s)
Alex Chubaty and Eliot McIntire
See Also
P()
, params()
for accessing these parameters in a module.
Examples
parameters = rbind(
defineParameter("lambda", "numeric", 1.23, desc = "intrinsic rate of increase"),
defineParameter("P", "numeric", 0.2, 0, 1, "probability of attack"),
# multi-line desc without quotes on each line -- spaces and carriage returns are stripped
defineParameter("rate", "numeric", 0.2, 0, 1,
"rate of arrival. This is in individuals
per day. This can be modified
by the user"),
# multi-line desc with quotes on each line
defineParameter("times", "numeric", 0.2, 0, 1,
desc = "The times during the year ",
"that events will occur ",
"with possibility of random arrival times")
)
# Create a new module, then access parameters using `P`
tmpdir <- file.path(tempdir(), "test")
checkPath(tmpdir, create = TRUE)
# creates a new, "empty" module -- it has defaults for everything that is required
newModule("testModule", tmpdir, open = FALSE)
# Look at new module code -- see defineParameter
if (interactive()) file.edit(file.path(tmpdir, "testModule", "testModule.R"))
# initialize the simList
if (requireNamespace("ggplot2", quietly = TRUE)) {
# Some things not necessary in this example, if not interactive (like plotting)
opts <- if (interactive()) list() else
options(spades.plot = NA, spades.useRequire = FALSE,
spades.moduleCodeChecks = FALSE)
mySim <- simInit(modules = "testModule",
paths = list(modulePath = tmpdir))
# Access one of the parameters -- because this line is not inside a module
# function, we must specify the module name. If used within a module,
# we can omit the module name
P(mySim, module = "testModule") # gets all params in a module
P(mySim, ".useCache", "testModule") # just one param
options(opts)
}
unlink(tmpdir, recursive = TRUE)
Build edge list for module dependency graph
Description
Build edge list for module dependency graph
Usage
depsEdgeList(sim, plot)
## S4 method for signature 'simList,logical'
depsEdgeList(sim, plot)
## S4 method for signature 'simList,missing'
depsEdgeList(sim, plot)
Arguments
sim |
A |
plot |
Logical indicating whether the edgelist (and subsequent graph)
will be used for plotting. If |
Value
A data.table
whose first two columns give a list of edges
and remaining columns the attributes of the dependency objects
(object name, class, etc.).
Author(s)
Alex Chubaty
Build a module dependency graph
Description
Build a module dependency graph
Usage
depsGraph(sim, plot)
## S4 method for signature 'simList,logical'
depsGraph(sim, plot)
## S4 method for signature 'simList,missing'
depsGraph(sim)
Arguments
sim |
A |
plot |
Logical indicating whether the edgelist (and subsequent graph)
will be used for plotting. If |
Value
An igraph()
object.
Author(s)
Alex Chubaty
SpaDES time units
Description
SpaDES
modules commonly use approximate durations that divide with no
remainder among themselves.
For example, models that simulate based on a "week" timestep, will likely
want to fall in lock step with a second module that is a "year" timestep.
Since, weeks, months, years don't really have this behaviour because of:
leap years, leap seconds, not quite 52 weeks in a year, months that are of
different duration, etc.
We have generated a set of units that work well together that are based on
the astronomical or "Julian" year.
In an astronomical year, leap years are added within each year with an extra
1/4 day, (i.e., 1 year == 365.25 days); months are defined as year/12, and
weeks as year/52.
Usage
dhour(x)
dmin(x)
dday(x)
dyears(x)
## S4 method for signature 'numeric'
dyears(x)
dmonths(x)
## S4 method for signature 'numeric'
dmonths(x)
dweeks(x)
## S4 method for signature 'numeric'
dweeks(x)
dweek(x)
dmonth(x)
dyear(x)
dsecond(x)
dNA(x)
## S4 method for signature 'ANY'
dNA(x)
Arguments
x |
numeric. Number of the desired units |
Details
When these units are not correct, a module developer can create their own
time unit, and create a function to calculate the number of seconds
in that unit using the "d" prefix (for duration), following the
lubridate
package standard:
ddecade <- function(x) lubridate::duration(dyear(10))
.
Then the module developer can use "decade" as the module's time unit.
Value
Number of seconds within each unit
Author(s)
Eliot McIntire
Process a simulation event
Description
Internal function called from spades
.
Usage
doEvent(
sim,
debug = FALSE,
notOlderThan,
useFuture = getOption("spades.futureEvents", FALSE),
events = NULL,
...
)
Arguments
sim |
Character string for the |
debug |
Optional tools for invoking debugging. Supplying a |
notOlderThan |
Date or time. Passed to |
useFuture |
Experimental use of future::future package. Not fully implemented. |
events |
A character vector or a named list of character vectors. If specified,
the simulations will only do the events indicated here. If a named list, the names
must correspond to the modules and the character vectors can be specific events within
each of the named modules. With the |
... |
Any. Can be used to make a unique cache identity, such as "replicate = 1".
This will be included in the |
Details
Calls the module corresponding to the event call, and executes the event.
Here, we implement a simulation in a more modular fashion so it's easier to add submodules to the simulation. We use S4 classes and methods.
Value
Returns the modified simList
object.
Author(s)
Alex Chubaty
References
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
Download module data
Description
Download external data for a module if not already present in the module directory, or if there is a checksum mismatch indicating that the file is not the correct one.
Usage
downloadData(
module,
path,
quiet,
quickCheck = FALSE,
overwrite = FALSE,
files = NULL,
checked = NULL,
urls = NULL,
children = NULL,
...
)
## S4 method for signature 'character,character,logical'
downloadData(
module,
path,
quiet,
quickCheck = FALSE,
overwrite = FALSE,
files = NULL,
checked = NULL,
urls = NULL,
children = NULL,
...
)
## S4 method for signature 'character,missing,missing'
downloadData(module, quickCheck, overwrite, files, checked, urls, children)
## S4 method for signature 'character,missing,logical'
downloadData(
module,
quiet,
quickCheck,
overwrite,
files,
checked,
urls,
children
)
## S4 method for signature 'character,character,missing'
downloadData(
module,
path,
quickCheck,
overwrite,
files,
checked,
urls,
children
)
Arguments
module |
Character string giving the name of the module. |
path |
Character string giving the path to the module directory. |
quiet |
Logical. This is passed to |
quickCheck |
Logical. If |
overwrite |
Logical. Should local data files be overwritten in case they exist?
Default is |
files |
A character vector of length 1 or more if only a subset of files should be checked in the ‘CHECKSUMS.txt’ file. |
checked |
The result of a previous |
urls |
Character vector of urls from which to get the data. This is automatically
found from module metadata when this function invoked with
|
children |
The character vector of child modules (without path) to also
run |
... |
Passed to |
Details
downloadData
requires a checksums file to work, as it will only download
the files specified therein. Hence, module developers should make sure they
have manually downloaded all the necessary data and ran checksums
to
build a checksums file.
There is an experimental attempt to use the googledrive package to download
data from a shared (publicly or with individual users) file.
To try this, put the Google Drive URL in sourceURL
argument of
expectsInputs
in the module metadata, and put the filename once downloaded
in the objectName
argument.
If using RStudio Server, you may need to use "out of band" authentication by
setting options(httr_oob_default = TRUE)
.
To avoid caching of Oauth credentials, set options(httr_oauth_cache = TRUE)
.
There is also an experimental option for the user to make a new ‘CHECKSUMS.txt’
file if there is a sourceURL
but no entry for that file.
This is experimental and should be used with caution.
Value
Invisibly, a list of downloaded files.
Author(s)
Alex Chubaty & Eliot McIntire
See Also
prepInputs()
, checksums()
, and downloadModule()
for downloading modules and building a checksums file.
Examples
# In metadata, each expectsInput has a sourceURL; downloadData will look for
# that and download if it defined; however this sample module has all
# NAs for sourceURL, so nothing to download
modulePath <- getSampleModules(tempdir())
downloadData("caribouMovement", path = modulePath)
Download a module from a SpaDES module GitHub repository
Description
Download a .zip file of the module and extract (unzip) it to a user-specified location.
Usage
downloadModule(
name,
path,
version,
repo,
data,
quiet,
quickCheck = FALSE,
overwrite = FALSE
)
## S4 method for signature
## 'character,character,character,character,logical,logical,ANY,logical'
downloadModule(
name,
path,
version,
repo,
data,
quiet,
quickCheck = FALSE,
overwrite = FALSE
)
## S4 method for signature
## 'character,missing,missing,missing,missing,missing,ANY,ANY'
downloadModule(name, quickCheck, overwrite)
## S4 method for signature 'character,ANY,ANY,ANY,ANY,ANY,ANY,ANY'
downloadModule(
name,
path,
version,
repo,
data,
quiet,
quickCheck = FALSE,
overwrite = FALSE
)
Arguments
name |
Character string giving the module name. |
path |
Character string giving the location in which to save the downloaded module. |
version |
The module version to download. (If not specified, or |
repo |
GitHub repository name, specified as |
data |
Logical. If |
quiet |
Logical. This is passed to |
quickCheck |
Logical. If |
overwrite |
Logical. Should local module files be overwritten in case they exist?
Default |
Details
Currently only works with GitHub repositories where modules are located in
a modules
directory in the root tree on the master
branch.
Module .zip files' names should contain the version number and be inside their
respective module folders (see zipModule()
for zip compression of modules).
Value
A list of length 2. The first element is a character vector containing
a character vector of extracted files for the module. The second element is
a tbl
with details about the data that is relevant for the function,
including whether it was downloaded or not, and whether it was renamed
(because there was a local copy that had the wrong file name).
Note
downloadModule
uses the GITHUB_PAT
environment variable
if a value is set. This alleviates 403 errors caused by too-frequent downloads.
Generate a GitHub personal access token with no additional permissions at
https://github.com/settings/tokens, and add this key to ‘.Renviron’
as GITHUB_PAT=<your-github-pat-here>
.
The default is to overwrite any existing files in the case of a conflict.
Author(s)
Alex Chubaty
See Also
zipModule()
for creating module .zip folders.
Blank (template) event list
Description
Internal function called from spades
, returning an empty event list.
Usage
.emptyEventListDT
.singleEventListDT
.emptyEventList(eventTime, moduleName, eventType, eventPriority)
## S4 method for signature 'numeric,character,character,numeric'
.emptyEventList(eventTime, moduleName, eventType, eventPriority)
## S4 method for signature 'missing,missing,missing,missing'
.emptyEventList()
.emptyEventListCols
Arguments
eventTime |
The time the event is to occur. |
moduleName |
The module from which the event is taken. |
eventType |
A character string for the programmer-defined event type. |
eventPriority |
The priority given to the event. |
Format
An object of class data.table
(inherits from data.frame
) with 0 rows and 4 columns.
An object of class data.table
(inherits from data.frame
) with 1 rows and 4 columns.
An object of class character
of length 4.
Details
Event lists are sorted (keyed) first by time, second by priority.
Each event is represented by a data.table()
row consisting of:
eventTime | The time the event is to occur. |
moduleName | The module from which the event is taken. |
eventType | A character string for the programmer-defined event type. |
eventPriority | The priority given to the event. |
Value
Returns an empty event list.
Author(s)
Alex Chubaty
Simulation environment
Description
Accessor functions for the .xData
slot, which is the default virtual
slot for an S4 class object that inherits from an S3 object (specifically,
the simList
inherits from environment
) in a simList
object.
These are included for advanced users.
Usage
envir(sim)
## S4 method for signature 'simList'
envir(sim)
envir(sim) <- value
## S4 replacement method for signature 'simList'
envir(sim) <- value
Arguments
sim |
A |
value |
The object to be stored at the slot. |
Details
Currently, only get and set methods are defined. Subset methods are not.
Value
Returns or sets the value of the slot from the simList
object.
Author(s)
Alex Chubaty
See Also
SpaDES.core-package, specifically the section 1.2.8 on simList
environment.
Other functions to access elements of a 'simList' object:
.addDepends()
,
checkpointFile()
,
events()
,
globals()
,
inputs()
,
modules()
,
objs()
,
packages()
,
params()
,
paths()
,
progressInterval()
,
times()
Simulation event diagram
Description
Create a Gantt Chart representing the events in a completed simulation.
This event diagram is constructed using the completed event list
To change the number of events shown, provide an n
argument.
Usage
eventDiagram(sim, n, startDate, ...)
## S4 method for signature 'simList,numeric,character'
eventDiagram(sim, n, startDate, ...)
## S4 method for signature 'simList,missing,character'
eventDiagram(sim, n, startDate, ...)
## S4 method for signature 'simList,missing,missing'
eventDiagram(sim, n, startDate, ...)
Arguments
sim |
A |
n |
The number of most recently completed events to plot. |
startDate |
A character representation of date in |
... |
Additional arguments passed to |
Details
Simulation time is presented on the x-axis, starting at date startDate
.
Each module appears in a colour-coded row, within which each event for that
module is displayed corresponding to the sequence of events for that module.
Note that only the start time of the event is meaningful is these figures:
the width of the bar associated with a particular module's event DOES NOT
correspond to an event's "duration".
Based on this Stack Overflow answer: https://stackoverflow.com/a/29999300/1380598.
Value
Plots an event diagram as Gantt Chart, invisibly returning a mermaid
object.
Note
A red vertical line corresponding to the current date may appear on the figure. This is useful for Gantt Charts generally but can be considered a 'bug' here.
Author(s)
Alex Chubaty
See Also
DiagrammeR::mermaid
.
Simulation event lists
Description
Accessor functions for the events
and completed
slots of a
simList
object. These path functions will extract the values that were
provided to the simInit
function in the path
argument.
Usage
events(sim, unit)
## S4 method for signature 'simList,character'
events(sim, unit)
## S4 method for signature 'simList,missing'
events(sim, unit)
events(sim) <- value
## S4 replacement method for signature 'simList'
events(sim) <- value
conditionalEvents(sim, unit)
## S4 method for signature 'simList,character'
conditionalEvents(sim, unit)
## S4 method for signature 'simList,missing'
conditionalEvents(sim, unit)
current(sim, unit)
## S4 method for signature 'simList,character'
current(sim, unit)
## S4 method for signature 'simList,missing'
current(sim, unit)
current(sim) <- value
## S4 replacement method for signature 'simList'
current(sim) <- value
completed(sim, unit, times = TRUE)
## S4 method for signature 'simList,character'
completed(sim, unit, times = TRUE)
## S4 method for signature 'simList,missing'
completed(sim, unit, times = TRUE)
completed(sim) <- value
## S4 replacement method for signature 'simList'
completed(sim) <- value
Arguments
sim |
A |
unit |
Character. One of the time units used in |
value |
The object to be stored at the slot. |
times |
Logical. Should this function report the |
Details
By default, the event lists are shown when the simList
object is printed,
thus most users will not require direct use of these methods.
events | Scheduled simulation events (the event queue). |
completed | Completed simulation events. |
Currently, only get and set methods are defined. Subset methods are not.
Value
Returns or sets the value of the slot from the simList
object.
Note
Each event is represented by a data.table()
row consisting of:
-
eventTime
: The time the event is to occur. -
moduleName
: The module from which the event is taken. -
eventType
: A character string for the programmer-defined event type.
See Also
SpaDES.core-package, specifically the section 1.2.6 on Simulation event queues.
Other functions to access elements of a 'simList' object:
.addDepends()
,
checkpointFile()
,
envir()
,
globals()
,
inputs()
,
modules()
,
objs()
,
packages()
,
params()
,
paths()
,
progressInterval()
,
times()
Define an input object that the module expects.
Description
Used to specify an input object's name, class, description, source url and other specifications.
Usage
expectsInput(objectName, objectClass, desc, sourceURL, ...)
## S4 method for signature 'ANY,ANY,ANY,ANY'
expectsInput(objectName, objectClass, desc, sourceURL, ...)
## S4 method for signature 'character,character,character,character'
expectsInput(objectName, objectClass, desc, sourceURL, ...)
## S4 method for signature 'character,character,character,missing'
expectsInput(objectName, objectClass, desc, sourceURL, ...)
Arguments
objectName |
Character string to define the input object's name. |
objectClass |
Character string to specify the input object's class. |
desc |
Text string providing a brief description of the input object.
If there are extra spaces or carriage returns, these will be stripped,
allowing for multi-line character strings without using |
sourceURL |
Character string to specify an URL to reach the input object,
default is |
... |
Other specifications of the input object. |
Value
A data.frame
suitable to be passed to inputObjects
in a module's metadata.
Author(s)
Yong Luo
Examples
inputObjects <- bindrows(
expectsInput(objectName = "inputObject1", objectClass = "character",
desc = "this is for example", sourceURL = "not available"),
expectsInput(objectName = "inputObject2", objectClass = "numeric",
desc = "this is for example", sourceURL = "not available",
otherInformation = "I am the second input object")
)
Extract a url from module metadata
Description
This will get the sourceURL
for the object named.
Usage
extractURL(objectName, sim, module)
## S4 method for signature 'character,missing'
extractURL(objectName, sim, module)
## S4 method for signature 'character,simList'
extractURL(objectName, sim, module)
Arguments
objectName |
A character string of the object name in the metadata. |
sim |
A |
module |
An optional character string of the module name whose metadata is
to be used. If omitted, the function will use the |
Value
The url.
Author(s)
Eliot McIntire
Extract filename (without extension) of a file
Description
Extract filename (without extension) of a file
Usage
fileName(x)
Arguments
x |
List or character vector |
Value
A character vector.
Author(s)
Eliot McIntire
ganttStatus
Description
Internal function assign the "status" of each event to be passed to DiagrammeR::mermaid()
to make a Gantt chart representing the events in a completed simulation.
init
events are set as "done"; plot
events as "critical"; and all others as "active".
Usage
ganttStatus(eventType)
## S4 method for signature 'character'
ganttStatus(eventType)
Arguments
eventType |
Character vector of events. |
Value
A character vector.
Author(s)
Alex Chubaty
Get copies of sample files for examples and tests
Description
Get copies of sample files for examples and tests
Usage
getMapPath(tmpdir)
getSampleModules(tmpdir)
Arguments
tmpdir |
character specifying the path to a temporary directory (e.g., |
Value
character vector of filepaths to the copied files
Find the latest module version from a SpaDES module repository
Description
Modified from https://stackoverflow.com/a/25485782/1380598.
Usage
getModuleVersion(name, repo)
## S4 method for signature 'character,character'
getModuleVersion(name, repo)
## S4 method for signature 'character,missing'
getModuleVersion(name)
Arguments
name |
Character string giving the module name. |
repo |
GitHub repository name, specified as |
Details
getModuleVersion
extracts a module's most recent version by
looking at the module ‘.zip’ files contained in the module directory.
It takes the most recent version, based on the name of the zip file.
See the modules vignette for details of module directory structure (https://spades-core.predictiveecology.org/articles/ii-modules.html#module-directory-structure-modulename), and see our SpaDES-modules repo for details of module repository structure (https://github.com/PredictiveEcology/SpaDES-modules).
Value
numeric_version
Author(s)
Alex Chubaty
See Also
zipModule()
for creating module ‘.zip’ folders.
Get and set global simulation parameters
Description
globals
, and the alias G
, accesses or sets the "globals"
in the simList
. This currently is not an explicit slot in the simList
,
but it is a .globals
element in the params
slot of the simList
.
Usage
globals(sim)
## S4 method for signature 'simList'
globals(sim)
globals(sim) <- value
## S4 replacement method for signature 'simList'
globals(sim) <- value
G(sim)
## S4 method for signature 'simList'
G(sim)
G(sim) <- value
## S4 replacement method for signature 'simList'
G(sim) <- value
Arguments
sim |
A |
value |
The parameter value to be set (in the corresponding |
See Also
SpaDES.core-package, specifically the section 1.2.1 on Simulation Parameters.
Other functions to access elements of a 'simList' object:
.addDepends()
,
checkpointFile()
,
envir()
,
events()
,
inputs()
,
modules()
,
objs()
,
packages()
,
params()
,
paths()
,
progressInterval()
,
times()
Convert time units
Description
Current pre-defined units are found within the spadesTimes()
function.
The user can define a new unit.
The unit name can be anything, but the function definition must be of the
form "dunitName"
, e.g., dyear
or dfortnight
.
The unit name is the part without the d
and the function name
definition includes the d
.
This new function, e.g., dfortnight <- function(x) lubridate::duration(dday(14))
can be placed anywhere in the search path or in a module
(you will need to declare "lubridate"
in your pkgDeps
in the metadata).
This function takes a numeric with a "unit" attribute and converts it to
another numeric with a different time attribute.
If the units passed to argument units
are the same as
attr(time, "unit")
, then it simply returns input time
.
Usage
inSeconds(unit, envir, skipChecks = FALSE)
convertTimeunit(time, unit, envir, skipChecks = FALSE)
.spadesTimes
spadesTimes()
checkTimeunit(unit, envir)
## S4 method for signature 'character,missing'
checkTimeunit(unit, envir)
## S4 method for signature 'character,environment'
checkTimeunit(unit, envir)
Arguments
unit |
Character. One of the time units used in |
envir |
An environment. This is where to look up the function definition for the time unit. See details. |
skipChecks |
For speed, the internal checks for classes and missingness can be skipped.
Default |
time |
Numeric. With a unit attribute, indicating the time unit of the input numeric. See Details. |
Format
An object of class character
of length 12.
Details
Because of R scoping, if envir
is a simList
environment, then
this function will search there first, then up the current search()
path.
Thus, it will find a user defined or module defined unit before a SpaDES unit.
This means that a user can override the dyear
given in SpaDES, for example,
which is 365.25 days, with dyear <- function(x) lubridate::duration(dday(365))
.
If time
has no unit
attribute, then it is assumed to be
seconds.
Value
A numeric vector of length 1, with unit
attribute set to "seconds".
Author(s)
Alex Chubaty & Eliot McIntire
Eliot McIntire
Generate a simList
object
Description
Given the name or the definition of a class, plus optionally data to be
included in the object, new
returns an object from that class.
Given the name or the definition of a class, plus optionally data to be
included in the object, new
returns an object from that class.
Usage
## S4 method for signature 'simList'
initialize(.Object, ...)
## S4 method for signature 'simList_'
initialize(.Object, ...)
Arguments
.Object |
A |
... |
Optional Values passed to any or all slot |
Metadata accessors
Description
These accessors extract the metadata for a module (if specified) or all modules
in a simList
if not specified.
Usage
inputObjects(sim, module, path)
## S4 method for signature 'simList'
inputObjects(sim, module, path)
## S4 method for signature 'missing'
inputObjects(sim, module, path)
outputObjects(sim, module, path)
## S4 method for signature 'simList'
outputObjects(sim, module, path)
## S4 method for signature 'missing'
outputObjects(sim, module, path)
outputObjectNames(sim, module)
## S4 method for signature 'simList'
outputObjectNames(sim, module)
reqdPkgs(sim, module, modulePath)
## S4 method for signature 'simList'
reqdPkgs(sim, module, modulePath)
## S4 method for signature 'missing'
reqdPkgs(sim, module, modulePath)
documentation(sim, module)
## S4 method for signature 'simList'
documentation(sim, module)
sessInfo(sim)
## S4 method for signature 'simList'
sessInfo(sim)
Arguments
sim |
A |
module |
Character vector of module name(s) |
path |
The path to the module., i.e., the |
modulePath |
That path where |
Examples
# set modulePath
setPaths(modulePath = getSampleModules(tempdir()))
# use Require and reqdPkgs
pkgs <- reqdPkgs(module = c("caribouMovement", "randomLandscapes", "fireSpread"))
Simulation inputs
Description
Accessor functions for the inputs
slots in a simList
object.
Usage
inputs(sim)
## S4 method for signature 'simList'
inputs(sim)
inputs(sim) <- value
## S4 replacement method for signature 'simList'
inputs(sim) <- value
inputArgs(sim)
## S4 method for signature 'simList'
inputArgs(sim)
inputArgs(sim) <- value
## S4 replacement method for signature 'simList'
inputArgs(sim) <- value
Arguments
sim |
A |
value |
The object to be stored at the slot. See Details. |
Details
These functions are one of three mechanisms to add the information about which input files
to load in a spades
call.
As arguments to a
simInit
call. Specifically,inputs
oroutputs
. See?simInit
.With the
outputs(simList)
function call.By adding a function called
.inputObjects
inside a module, which will be executed during thesimInit
call. This last way is the most "modular" way to create default data sets for your model.
See below for more details.
Value
Returns or sets the value(s) of the input
or output
slots
in the simList
object.
inputs function or argument in simInit
inputs
accepts a data.frame, with up to 7 columns.
Columns are:
file | required, a character string indicating the file path. There is no default. |
objectName | optional, character string indicating the name of the object
that the loaded file will be assigned to in the simList . This object
can therefore be accessed with sim$xxx in any module, where
objectName = "xxx" . Defaults to the filename without file extension or
directory information. |
fun | optional, a character string indicating the function to use to
load that file. Defaults to the known extensions in SpaDES (found by
examining .fileExtensions() ). The package and fun can be
jointly specified here as "packageName::functionName" , e.g.,
"terra::rast" . |
package | optional character string indicating the package in
which to find the fun ); |
loadTime | optional numeric, indicating when in simulation time the file
should be loaded. The default is the highest priority at start(sim) ,
i.e., at the very start. |
interval | optional numeric, indicating at what interval should this same
exact file be reloaded from disk, e.g,. 10 would mean every 10 time units. The
default is NA or no interval, i.e, load the file only once as described in
loadTime |
arguments | is a list of lists of named arguments, one list for each
fun . For example, if fun="raster" , arguments = list(native = TRUE)
will pass the argument "native = TRUE" to raster. If there is only one list,
then it is assumed to apply to all files and will be recycled as per normal R
rules of recycling for each fun . |
Currently, only file
is required. All others will be filled with defaults
if not specified.
See the modules vignette for more details (browseVignettes("SpaDES.core")
).
.inputObjects
function placed inside module
Any code placed inside a function called .inputObjects
will be run during
simInit()
for the purpose of creating any objects required by this module,
i.e., objects identified in the inputObjects
element of defineModule
.
This is useful if there is something required before simulation to produce the module
object dependencies, including such things as downloading default datasets, e.g.,
downloadData('LCC2005', modulePath(sim))
.
Nothing should be created here that does not create an named object in inputObjects
.
Any other initiation procedures should be put in the "init" eventType
of the doEvent
function.
Note: the module developer can use sim$.userSuppliedObjNames
inside the function to
selectively skip unnecessary steps because the user has provided those inputObjects
in the
simInit
call. e.g., the following code would look to see if the user had passed defaultColor
into during simInit
. If the user had done this, then this function would not override
that value with 'red'. If the user has not passed in a value for defaultColor
, then
the module will get it here:
if (!('defaultColor' %in% sim$.userSuppliedObjNames)) {
sim$defaultColor <- 'red'
}
See Also
SpaDES.core-package, specifically the section 1.2.2 on loading and saving.
Other functions to access elements of a 'simList' object:
.addDepends()
,
checkpointFile()
,
envir()
,
events()
,
globals()
,
modules()
,
objs()
,
packages()
,
params()
,
paths()
,
progressInterval()
,
times()
Examples
#######################
# inputs
#######################
# Start with a basic empty simList
sim <- simInit()
test <- 1:10
tmpdir <- file.path(tempdir(), "inputs") |> checkPath(create = TRUE)
tmpFile <- file.path(tmpdir, "test.rds")
saveRDS(test, file = tmpFile)
inputs(sim) <- data.frame(file = tmpFile) # using only required column, "file"
inputs(sim) # see that it is not yet loaded, but when it is scheduled to be loaded
simOut <- spades(sim)
inputs(simOut) # confirm it was loaded
simOut$test
# can put data.frame for inputs directly inside simInit call
allTifs <- dir(getMapPath(tempdir()), full.names = TRUE)
# next: .objectNames are taken from the filenames (without the extension)
# This will load all 5 tifs in the SpaDES sample directory, using
# the rast fuction in the terra package, all at time = 0
sim <- simInit(
inputs = data.frame(
files = allTifs,
functions = "rast",
package = "terra",
loadTime = 0,
stringsAsFactors = FALSE)
)
##############################
# A fully described inputs object, including arguments:
files <- dir(getMapPath(tempdir()), full.names = TRUE)
# arguments must be a list of lists. This may require I() to keep it as a list
# once it gets coerced into the data.frame.
# arguments = I(rep(list(native = TRUE), length(files)))
filelist <- data.frame(
objectName = paste0("Maps", 1:5),
files = files,
functions = "terra::rast",
# arguments = arguments,
loadTime = 0,
intervals = c(rep(NA, length(files) - 1), 10)
)
inputs(sim) <- filelist
spades(sim)
# Example showing loading multiple objects from global environment onto the
# same object in the simList, but at different load times
a1 <- 1
a2 <- 2
# Note arguments must be a list of NROW(inputs), with each element itself being a list,
# which is passed to do.call(fun[x], arguments[[x]]), where x is row number, one at a time
args <- lapply(1:2, function(x) {
list(x = paste0("a", x),
envir = environment()) # may be necessary to specify in which envir a1, a2
# are located, if not in an interactive session
})
inputs <- data.frame(objectName = "a", loadTime = 1:2, fun = "base::get", arguments = I(args))
a <- simInit(inputs = inputs, times = list(start = 0, end = 1))
a <- spades(a)
identical(a1, a$a)
end(a) <- 3
a <- spades(a) # different object (a2) loaded onto a$a
identical(a2, a$a)
# Clean up after
unlink(tmpdir, recursive = TRUE)
Load a saved simList
and ancillary files
Description
Loading a simList
from file can be problematic as there are non-standard
objects that must be rebuilt. See description in saveSimList()
for details.
unzipSimList
is a convenience wrapper around unzip
and loadSimList
where
all the files are correctly identified and passed to
loadSimList(..., otherFiles = xxx)
. See zipSimList for details.
Usage
loadSimList(
filename,
projectPath = getwd(),
tempPath = tempdir(),
paths = NULL,
otherFiles = "",
verbose = getOption("reproducible.verbose")
)
unzipSimList(zipfile, load = TRUE, paths = getPaths(), ...)
Arguments
filename |
Character giving the name of a saved simulation file.
Currently, only file types |
projectPath |
An optional path for the project within which the |
tempPath |
A character string specifying the new base directory for the
temporary paths maintained in a |
paths |
A list of character vectors for all the |
otherFiles |
A character vector of (absolute) file names locating each of the
existing file-backed |
verbose |
Numeric, -1 silent (where possible), 0 being very quiet,
1 showing more messaging, 2 being more messaging, etc.
Default is 1. Above 3 will output much more information about the internals of
Caching, which may help diagnose Caching challenges. Can set globally with an
option, e.g., |
zipfile |
Filename of a zipped |
load |
Logical. If |
... |
passed to |
Details
If cache
is used, it is likely that it should be trimmed before
zipping, to include only cache elements that are relevant.
Value
For loadSimList()
, a simList
object.
For unzipSimList()
, either a character vector of file names unzipped
(if load = FALSE
), or a simList
object.
See Also
Make simList
correctly work with memoise
Description
Because of the environment slot, simList
objects don't correctly
memoise a simList
.
This method for simList
converts the object to a simList_
first.
Usage
## S3 method for class 'simList'
makeMemoisable(x)
## S3 method for class 'simList_'
unmakeMemoisable(x)
Arguments
x |
An object to make memoisable. See individual methods in other packages. |
Value
A simList_
object or a simList
, in the case of unmakeMemoisable
.
See Also
reproducible::makeMemoisable()
Determine the largest timestep unit in a simulation
Description
Determine the largest timestep unit in a simulation
Usage
maxTimeunit(sim)
## S4 method for signature 'simList'
maxTimeunit(sim)
Arguments
sim |
A |
Value
The timeunit as a character string. This defaults to NA
if
none of the modules has explicit units.
Author(s)
Eliot McIntire and Alex Chubaty
Estimate memory used with system("ps")
Description
This will give a slightly different estimate than pryr::mem_used
, which uses gc()
internally.
The purpose of this function is to allow continuous monitoring, external to the R session.
Normally, this is run in a different session.
This will only work if the user has specified before running the spades
call,
set the interval, in seconds, that ps
is run.
E.g., options("spades.memoryUseInterval" = 0.5)
, will assess memory use every 0.5 seconds.
The default is 0
, meaning no interval, "off".
Usage
memoryUseThisSession(thisPid)
memoryUse(sim, max = TRUE)
Arguments
thisPid |
Numeric or integer, the |
sim |
A completed |
max |
Logical. If TRUE, then it the return value will be summarized by
module/event, showing the maximum memory used. If |
Value
estimated memory use in MiB
data.table
summarizing the estimated memory use (in MiB) for each event type,
for each module, during the simulation.
Note
The suggested future
and future.callr
packages must be available.
See Also
The vignette("iv-modules")
Determine the smallest timeunit in a simulation
Description
When modules have different timeunit, SpaDES automatically takes the smallest (e.g., "second") as the unit for a simulation.
Usage
minTimeunit(sim)
## S4 method for signature 'simList'
minTimeunit(sim)
## S4 method for signature 'list'
minTimeunit(sim)
Arguments
sim |
A |
Value
The timeunit as a character string. This defaults to "second" if none of the modules has explicit units.
Author(s)
Eliot McIntire
Extract the full file paths for R source code
Description
This can be used e.g., for Caching, to identify which files have changed.
Usage
moduleCodeFiles(paths, modules)
Arguments
paths |
An optional named list with up to 4 named elements,
|
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 |
Value
character vector of file paths.
Calculate module coverage of unit tests
Description
Calculate the test coverage by unit tests for the module and its functions.
Usage
moduleCoverage(mod, modulePath = "..")
Arguments
mod |
Character string. The module's name. Default is |
modulePath |
Character string. The path to the module directory (default is "..", i.e., one level up from working directory). |
Value
Return a list of two coverage objects and two data.table objects.
The two coverage objects are named moduleCoverage
and functionCoverage
.
The moduleCoverage
object contains the percent value of unit test coverage
for the module.
The functionCoverage
object contains percentage values for unit test
coverage for each function defined in the module.
Please use covr::report()
to view the coverage information.
Two data.tables give the information of all the tested and untested functions
in the module.
Note
When running this function, the test files must be strictly placed in
the ‘tests/testthat/’ directory under module path.
To automatically generate this folder, please set unitTests = TRUE
when creating a new module using newModule()
.
To accurately test your module, the test filename must follow the format
test-functionName.R
.
Author(s)
Yong Luo
See Also
Defaults values used in defineModule
Description
Where individual elements are missing in defineModule
, these defaults will be used.
Usage
moduleDefaults
Format
An object of class list
of length 13.
Value
named list of default module metadata
Simulation module dependency diagram
Description
Create a network diagram illustrating the simplified module dependencies of a
simulation. Offers a less detailed view of specific objects than does
plotting the depsEdgeList
directly with objectDiagram()
.
Usage
moduleDiagram(sim, type, showParents = TRUE, ...)
## S4 method for signature 'simList,character,logical'
moduleDiagram(sim, type = "plot", showParents = TRUE, ...)
## S4 method for signature 'simList,ANY,ANY'
moduleDiagram(sim, type, showParents = TRUE, ...)
Arguments
sim |
A |
type |
Character string, either |
showParents |
Logical. If TRUE, then any children that are grouped into parent
modules will be grouped together by coloured blobs. Internally,
this is calling |
... |
Additional arguments passed to plotting function specified by |
Value
invoked for its side effect of plotting the module dependency diagram.
Author(s)
Alex Chubaty
See Also
igraph()
, moduleGraph()
for a version that accounts for
parent and children module structure.
Examples
if (requireNamespace("SpaDES.tools", quietly = TRUE) &&
requireNamespace("NLMR", quietly = TRUE)) {
library(igraph)
times <- list(start = 0, end = 6, "month")
parameters <- list(
.globals = list(stackName = "landscape"),
caribouMovement = list(
.saveObjects = "caribou",
.saveInitialTime = 1, .saveInterval = 1
),
randomLandscapes = list(.plotInitialTime = NA, nx = 20, ny = 20))
modules <- list("randomLandscapes", "caribouMovement")
paths <- list(
modulePath = getSampleModules(tempdir())
)
# Set some options so example runs faster
opts <- options(spades.moduleCodeChecks = FALSE, spades.loadReqdPkgs = FALSE)
sim <- simInit(times = times, params = parameters, modules = modules,
paths = paths)
options(opts)
moduleDiagram(sim)
# Can also use default base::plot
modDia <- depsGraph(sim, plot = TRUE)
# See ?plot.igraph
plot(modDia, layout = layout_as_star)
# Or for more control - here, change the label "_INPUT_" to "DATA"
edgeList <- depsEdgeList(sim)
edgeList <- edgeList[, list(from, to)]
edgeList[from == "_INPUT_", from := "Data"]
edgeList[to == "_INPUT_", to := "Data"]
edgeList <- unique(edgeList)
ig <- graph_from_data_frame(edgeList[, list(from, to)])
plot(ig)
}
Build a module dependency graph
Description
This is still experimental, but this will show the hierarchical structure of
parent and children modules and return a list with an igraph
object
and an igraph
communities object, showing the groups.
Currently only tested with relatively simple structures.
Usage
moduleGraph(sim, plot, ...)
## S4 method for signature 'simList,logical'
moduleGraph(sim, plot, ...)
## S4 method for signature 'simList,missing'
moduleGraph(sim, plot, ...)
Arguments
sim |
A |
plot |
Logical indicating whether the edgelist (and subsequent graph)
will be used for plotting. If |
... |
Arguments passed to |
Value
A list with 2 elements, an igraph()
object and an igraph
communities object.
Author(s)
Eliot McIntire
See Also
Parse and extract module metadata
Description
Parse and extract module metadata
Usage
moduleMetadata(
sim,
module,
path = getOption("spades.modulePath", NULL),
defineModuleListItems = c("name", "description", "keywords", "childModules", "authors",
"version", "spatialExtent", "timeframe", "timeunit", "citation", "documentation",
"reqdPkgs", "parameters", "inputObjects", "outputObjects")
)
## S4 method for signature 'missing,character,character'
moduleMetadata(module, path, defineModuleListItems)
## S4 method for signature 'missing,character,missing'
moduleMetadata(module, defineModuleListItems)
## S4 method for signature 'ANY,ANY,ANY'
moduleMetadata(
sim,
module,
path = getOption("spades.modulePath", NULL),
defineModuleListItems = c("name", "description", "keywords", "childModules", "authors",
"version", "spatialExtent", "timeframe", "timeunit", "citation", "documentation",
"reqdPkgs", "parameters", "inputObjects", "outputObjects")
)
Arguments
sim |
A |
module |
Character string. Your module's name. |
path |
Character string specifying the file path to modules directory.
Default is to use the |
defineModuleListItems |
A vector of metadata entries to return values about. |
Value
A list of module metadata, matching the structure in defineModule()
.
Author(s)
Alex Chubaty
See Also
Examples
## turn off code checking -- don't need it here
opts <- options("spades.moduleCodeChecks" = FALSE,
"spades.useRequire" = FALSE)
path <- getSampleModules(tempdir())
sampleModules <- dir(path)
x <- moduleMetadata(sampleModules[3], path = path)
## using simList
if (require("SpaDES.tools", quietly = TRUE)) {
mySim <- simInit(
times = list(start = 2000.0, end = 2001.0, timeunit = "year"),
params = list(
.globals = list(stackName = "landscape")
),
modules = list("caribouMovement"),
paths = list(modulePath = path)
)
moduleMetadata(sim = mySim)
}
# turn code checking back on -- don't need it here
options(opts)
Extract a module's parameters, inputs, or outputs
Description
These are more or less wrappers around moduleMetadata
, with the exception
that extraneous spaces and End-Of-Line characters will be removed from the
desc
arguments in defineParameters
, defineInputs
, and
defineOutputs
Usage
moduleParams(module, path)
## S4 method for signature 'character,character'
moduleParams(module, path)
moduleInputs(module, path)
## S4 method for signature 'character,character'
moduleInputs(module, path)
moduleOutputs(module, path)
## S4 method for signature 'character,character'
moduleOutputs(module, path)
Arguments
module |
Character string. Your module's name. |
path |
Character string specifying the file path to modules directory.
Default is to use the |
Value
data.frame
Author(s)
Alex Chubaty
See Also
Examples
## easily include these tables in Rmd files using knitr
path <- getSampleModules(tempdir())
sampleModules <- dir(path)
p <- moduleParams(sampleModules[3], path = path)
i <- moduleInputs(sampleModules[3], path = path)
o <- moduleOutputs(sampleModules[3], path = path)
knitr::kable(p)
knitr::kable(i)
knitr::kable(o)
Parse and extract a module's version
Description
Parse and extract a module's version
Usage
moduleVersion(module, path, sim, envir = NULL)
## S4 method for signature 'character,character,missing'
moduleVersion(module, path, envir)
## S4 method for signature 'character,missing,missing'
moduleVersion(module, envir)
## S4 method for signature 'character,missing,simList'
moduleVersion(module, sim, envir)
Arguments
module |
Character string. Your module's name. |
path |
Character string specifying the file path to modules directory.
Default is to use the |
sim |
A |
envir |
Optional environment in which to store parsed code. This may be
useful if the same file is being parsed multiple times. This
function will check in that environment for the parsed file before
parsing again. If the |
Value
numeric_version
indicating the module's version.
Author(s)
Alex Chubaty
See Also
Examples
# using filepath
path <- getSampleModules(tempdir())
moduleVersion("caribouMovement", path)
# using simList
options("spades.useRequire" = FALSE)
if (require("SpaDES.tools", quietly = TRUE)) {
mySim <- simInit(
times = list(start = 2000.0, end = 2002.0, timeunit = "year"),
params = list(
.globals = list(stackName = "landscape", burnStats = "nPixelsBurned")
),
modules = list("caribouMovement"),
paths = list(modulePath = path)
)
moduleVersion("caribouMovement", sim = mySim)
}
Simulation modules and dependencies
Description
Accessor functions for the depends
and modules
slots in a simList
object.
These are included for advanced users.
depends() | List of simulation module dependencies. (advanced) |
modules() | List of simulation modules to be loaded. (advanced) |
inputs() | List of loaded objects used in simulation. (advanced) |
Usage
modules(sim, hidden = FALSE)
## S4 method for signature 'simList'
modules(sim, hidden = FALSE)
modules(sim) <- value
## S4 replacement method for signature 'simList'
modules(sim) <- value
depends(sim)
## S4 method for signature 'simList'
depends(sim)
depends(sim) <- value
## S4 replacement method for signature 'simList'
depends(sim) <- value
Arguments
sim |
A |
Logical. If TRUE, show the default core modules. | |
value |
The object to be stored at the slot. |
Details
Currently, only get and set methods are defined. Subset methods are not.
Value
Returns or sets the value of the slot from the simList
object.
Author(s)
Alex Chubaty
See Also
SpaDES.core-package, specifically the section 1.2.7 on Modules and dependencies.
Other functions to access elements of a 'simList' object:
.addDepends()
,
checkpointFile()
,
envir()
,
events()
,
globals()
,
inputs()
,
objs()
,
packages()
,
params()
,
paths()
,
progressInterval()
,
times()
Create new module from template
Description
Generate a skeleton for a new SpaDES module, a template for a
documentation file, a citation file, a license file, a ‘README.md’ file,
and a folder that contains unit tests information.
The newModuleDocumentation
will not generate the module file, but will
create the other files.
Usage
newModule(name, path, ..., events, envir = parent.frame())
## S4 method for signature 'character,character'
newModule(name, path, ..., events, envir = parent.frame())
## S4 method for signature 'character,missing'
newModule(name, path, ..., events, envir = parent.frame())
Arguments
name |
Character string specifying the name of the new module. |
path |
Character string. Subdirectory in which to place the new module code file. The default is the current working directory. |
... |
Additional arguments. Currently, these can be either named
function definitions (which will be added to the
|
events |
A list of named expressions, each of which is surrounded by |
envir |
An environment where objects being passed to |
Details
All files will be created within a subdirectory named name
within the path
:
<path>/ |_ <name>/ |_ R/ # contains additional module R scripts |_ data/ # directory for all included data |_ CHECKSUMS.txt # contains checksums for data files |_ tests/ # contains unit tests for module code |_ citation.bib # bibtex citation for the module |_ LICENSE # describes module's legal usage |_ README.md # provide overview of key aspects |_ <name>.R # module code file (incl. metadata) |_ <name>.Rmd # documentation, usage info, etc.
Value
NULL (invisibly). The new module file is created at ‘path/name.R’, as well as ancillary files for documentation, citation, ‘LICENSE’, ‘README’, and ‘tests’ directory.
Note
On Windows there is currently a bug in RStudio that prevents the editor
from opening when file.edit
is called.
Similarly, in RStudio on macOS, there is an issue opening files where they
are opened in an overlaid window rather than a new tab.
file.edit
does work if the user types it at the command prompt.
A message with the correct lines to copy and paste is provided.
Author(s)
Alex Chubaty and Eliot McIntire
See Also
Other module creation helpers:
newModuleCode()
,
newModuleDocumentation()
,
newModuleTests()
Examples
tmpdir <- tempdir2("exampleNewModule")
## create a "myModule" module in the "modules" subdirectory.
newModule("myModule", tmpdir)
## create a new parent module in the "modules" subdirectory.
newModule("myParentModule", tmpdir, type = "parent", children = c("child1", "child2"))
unlink(tmpdir, recursive = TRUE)
Create new module code file
Description
Create new module code file
Usage
newModuleCode(name, path, ..., events)
## S4 method for signature 'character,character'
newModuleCode(name, path, ..., events)
Arguments
name |
Character string specifying the name of the new module. |
path |
Character string. Subdirectory in which to place the new module code file. The default is the current working directory. |
... |
Additional arguments. Currently, these can be either named
function definitions (which will be added to the
|
events |
A list of named expressions, each of which is surrounded by |
Value
NULL (invisibly). Invoked for its side effect of creating new module code files.
Author(s)
Eliot McIntire and Alex Chubaty
See Also
Other module creation helpers:
newModule()
,
newModuleDocumentation()
,
newModuleTests()
Create new module documentation
Description
Create new module documentation
Usage
newModuleDocumentation(name, path, ...)
## S4 method for signature 'character,character'
newModuleDocumentation(name, path, ...)
## S4 method for signature 'character,missing'
newModuleDocumentation(name, path, ...)
Arguments
name |
Character string specifying the name of the new module. |
path |
Character string. Subdirectory in which to place the new module code file. The default is the current working directory. |
... |
Additional arguments. Currently, these can be either named
function definitions (which will be added to the
|
Value
NULL (invisibly). Invoked for its side effect of creating new module code files.
Author(s)
Eliot McIntire and Alex Chubaty
See Also
Other module creation helpers:
newModule()
,
newModuleCode()
,
newModuleTests()
Create template testing structures for new modules
Description
Create template testing structures for new modules
Usage
newModuleTests(name, path, open, useGitHub)
## S4 method for signature 'character,character,logical,logical'
newModuleTests(name, path, open, useGitHub)
Arguments
name |
Character string specifying the name of the new module. |
path |
Character string. Subdirectory in which to place the new module code file. The default is the current working directory. |
open |
Logical. Should the new module file be opened after creation?
Default |
useGitHub |
Logical indicating whether GitHub will be used.
If |
Value
NULL (invisibly). Invoked for its side effect of creating new module test files.
Author(s)
Eliot McIntire and Alex Chubaty
See Also
Other module creation helpers:
newModule()
,
newModuleCode()
,
newModuleDocumentation()
Show which objects were first created in a simInit
or spades
call
Description
This does an rbindlist(sim$._objectsCreated)
.
This object in the sim
records the yellow message that reports on when objects are created.
Usage
newObjectsCreated(sim)
Arguments
sim |
A |
Value
The data.table
of the objects created, alongside the current(sim)
at each moment of creation.
Progress bar
Description
Shows a progress bar that is scaled to simulation end time.
Usage
newProgressBar(sim)
setProgressBar(sim)
Arguments
sim |
A |
Details
The progress bar object is stored in a separate environment, #' .pkgEnv
.
Value
invoked for side effect of creating progress bar
Author(s)
Alex Chubaty and Eliot McIntire
Create new SpaDES project
Description
Initialize a project with subdirectories ‘cache/’, ‘modules/’,
‘inputs/’, ‘outputs/’, and setPaths
accordingly.
If invoked from Rstudio, will also create a new Rstudio project file.
Usage
newProject(name, path, open)
## S4 method for signature 'character,character,logical'
newProject(name, path, open)
## S4 method for signature 'character,character,missing'
newProject(name, path, open)
Arguments
name |
project name (name of project directory) |
path |
path to directory in which to create the project directory |
open |
Logical. Should the new project file be opened after creation?
Default |
Value
invoked for side effect of project file creation
Examples
myProjDir <- newProject("myProject", tempdir())
dir.exists(file.path(myProjDir, "cache"))
dir.exists(file.path(myProjDir, "inputs"))
dir.exists(file.path(myProjDir, "modules"))
dir.exists(file.path(myProjDir, "outputs"))
unlink(myProjDir, recursive = TRUE) ## cleanup
Create new module code file
Description
Create new module code file
Usage
newProjectCode(name, path, open)
## S4 method for signature 'character,character,logical'
newProjectCode(name, path, open = interactive())
Arguments
name |
project name (name of project directory) |
path |
path to directory in which to create the project directory |
open |
Logical. Should the new project file be opened after creation?
Default |
Value
invoked for side effect of project file creation
Author(s)
Alex Chubaty
Text for no event with that name
Description
Provides the text to be sent to warning
in each module as the default switch
case.
Usage
noEventWarning(sim)
Arguments
sim |
A |
Value
A text string specifying the event name and module for which there is no event
Object size for simList
Description
Recursively, runs reproducible::objSize()
on the simList
environment,
so it estimates the correct size of functions stored there (e.g., with their enclosing
environments) plus, it adds all other "normal" elements of the simList
, e.g.,
objSize(completed(sim))
.
The output is structured into 2 elements: the sim
environment and all its objects,
and the other slots in the simList
(e.g., events, completed, modules, etc.).
The returned object also has an attribute, "total", which shows the total size.
Usage
## S3 method for class 'simList'
objSize(x, quick = TRUE, ...)
Arguments
x |
An object |
quick |
Logical. If |
... |
Additional arguments (currently unused), enables backwards compatible use. |
Value
an estimate of the size of the object, in bytes.
Examples
a <- simInit(objects = list(d = 1:10, b = 2:20))
objSize(a)
utils::object.size(a)
Simulation object dependency diagram
Description
Create a sequence diagram illustrating the data object dependencies of a
simulation. Offers a more detailed view of specific objects than does
plotting the depsEdgeList
directly with moduleDiagram()
.
Usage
objectDiagram(sim, ...)
## S4 method for signature 'simList'
objectDiagram(sim, ...)
Arguments
sim |
A |
... |
Additional arguments passed to |
Value
Plots a sequence diagram, invisibly returning a DiagrammeR::mermaid
object.
Author(s)
Alex Chubaty
See Also
DiagrammeR::mermaid
.
Examples
if (requireNamespace("DiagrammeR", quietly = TRUE)) {
sim <- simInit()
objectDiagram(sim)
# if there are lots of objects, may need to increase width and/or height
objectDiagram(sim, height = 3000, width = 3000)
}
Identify synonyms in a simList
Description
This will create active bindings amongst the synonyms. To minimize copying,
the first one that exists in the character vector will become the "canonical"
object. All others named in the character vector will be activeBindings
to
that canonical one. This synonym list will be assigned to the envir
,
as an object named objectSynonyms
. That object will have an attribute
called, bindings
indicating which one is the canonical one and which
is/are the activeBindings.
EXPERIMENTAL: If the objects are removed during a
spades
call by, say, a module, then at the end of the event, the
spades
call will replace the bindings. In other words, if a module
deletes the object, it will "come back". This may not always be desired.
Usage
objectSynonyms(envir, synonyms)
Arguments
envir |
An environment, which in the context of SpaDES.core is usually
a |
synonyms |
A list of synonym character vectors, such as
|
Details
This is very experimental and only has minimal tests. Please report if this is not working, and under what circumstances (e.g., please submit a reproducible example to our issues tracker)
This function will append any new objectSynonym
to any pre-existing
objectSynonym
in the envir
. Similarly, this function assumes
transitivity, i.e., if age
and ageMap
are synonyms, and ageMap
and timeSinceFire
are synonyms, then age
and timeSinceFire
must be synonyms.
Value
Active bindings in the envir
so that all synonyms point to the same
canonical object, e.g., they would be at envir[[synonym[[1]][1]]]
and
envir[[synonym[[1]][2]]]
, if a list of length one is passed into
synonyms
, with a character vector of length two. See examples.
Examples
sim <- simInit()
sim$age <- 1:10;
sim <- objectSynonyms(sim, list(c("age", "ageMap")))
identical(sim$ageMap, sim$age)
sim$age <- 4
identical(sim$ageMap, sim$age)
sim$ageMap <- 2:5
sim$ageMap[3] <- 11
identical(sim$ageMap, sim$age)
# Also works to pass it in as an object
objectSynonyms <- list(c("age", "ageMap"))
sim <- simInit(objects = list(objectSynonyms = objectSynonyms))
identical(sim$ageMap, sim$age) # they are NULL at this point
sim$age <- 1:10
identical(sim$ageMap, sim$age) # they are not NULL at this point
## More complicated, with 'updating' i.e., you can add new synonyms to previous
sim <- simInit()
os <- list(c("age", "ageMap"), c("vegMap", "veg"), c("studyArea", "studyArea2"))
os2 <- list(c("ageMap", "timeSinceFire", "tsf"),
c("systime", "systime2"),
c("vegMap", "veg"))
sim <- objectSynonyms(sim, os)
sim <- objectSynonyms(sim, os2)
# check
sim$objectSynonyms
Extract or replace an object from the simulation environment
Description
The [[
and $
operators provide "shortcuts" for accessing
objects in the simulation environment.
I.e., instead of using envir(sim)$object
or envir(sim)[["object"]]
,
one can simply use sim$object
or sim[["object"]]
.
Usage
objs(sim, ...)
## S4 method for signature 'simList'
objs(sim, ...)
objs(sim) <- value
## S4 replacement method for signature 'simList'
objs(sim) <- value
moduleObjects(sim, module, path)
findObjects(objects, sim, module, path)
Arguments
sim |
A |
... |
passed to |
value |
objects to assign to the |
module |
Character vector of module name(s) |
path |
The path to the module., i.e., the |
objects |
A character vector of length >= 1 with name(s) of objects to look
for in the metadata. This is used in a |
Details
objs
can take ...
arguments passed to ls
,
allowing, e.g. all.names=TRUE
objs<-
requires takes a named list of values to be assigned in
the simulation environment.
Value
Returns or sets a list of objects in the simList
environment.
moduleObjects
returns a data.table with 4 columns, module
, objectName
, type
, and desc
,
pulled directly from the object metadata in the createsOutputs
and expectsInputs
. These
will be determined either from a simList
or from the module source code.
findObjects
returns a data.table similar to moduleObjects
, but with only the
objects provided by objects
.
See Also
SpaDES.core-package, specifically the section 1.2.1 on Simulation Parameters.
Other functions to access elements of a 'simList' object:
.addDepends()
,
checkpointFile()
,
envir()
,
events()
,
globals()
,
inputs()
,
modules()
,
packages()
,
params()
,
paths()
,
progressInterval()
,
times()
Examples
# findObjects
path <- getSampleModules(tempdir())
findObjects(path = path, module = dir(path), objects = "caribou")
Open all modules nested within a base directory
Description
This is just a convenience wrapper for opening several modules at once, recursively.
A module is defined as any file that ends in .R
or .r
and has a
directory name identical to its filename. Thus, this must be case sensitive.
Usage
openModules(name, path)
## S4 method for signature 'character,character'
openModules(name, path)
## S4 method for signature 'missing,missing'
openModules()
## S4 method for signature 'missing,character'
openModules(path)
## S4 method for signature 'character,missing'
openModules(name)
## S4 method for signature 'simList,missing'
openModules(name)
Arguments
name |
Character vector with names of modules to open. If missing, then all modules will be opened within the base directory. |
path |
Character string of length 1. The base directory within which there are only module subdirectories. |
Value
NULL (invisibly). All file are open via file.edit
.
Note
On Windows there is currently a bug in RStudio that prevents the editor
from opening when file.edit
is called. file.edit
does work if the
user types it at the command prompt. A message with the correct lines to copy
and paste is provided.
Author(s)
Eliot McIntire
Examples
if (interactive())
openModules("modules")
Simulation outputs
Description
Accessor functions for the outputs
slots in a simList
object.
If a module saves a file to disk during events, it can be useful to keep track
of the files that are saved e.g., for saveSimList()
so that all files can
be added to the archive. In addition to setting outputs
at the simInit
stage, a module developer can also put this in a using any saving mechanism that
is relevant (e.g., qs::qsave
, saveRDS
etc.). When a module event does this
it can be useful to register that saved file. registerOutputs
offers an additional
mechanism to do this. See examples.
Usage
outputs(sim)
## S4 method for signature 'simList'
outputs(sim)
outputs(sim) <- value
## S4 replacement method for signature 'simList'
outputs(sim) <- value
registerOutputs(filename, sim, ...)
outputArgs(sim)
## S4 method for signature 'simList'
outputArgs(sim)
outputArgs(sim) <- value
## S4 replacement method for signature 'simList'
outputArgs(sim) <- value
Arguments
sim |
A |
value |
The object to be stored at the slot. See Details. |
filename |
The filename to register in the |
... |
Not used. |
Details
These functions are one of three mechanisms to add information about which output files to save.
As arguments to a
simInit
call. Specifically,inputs
oroutputs
. See?simInit
.With the
outputs(simList)
function call.By adding a function called
.inputObjects
inside a module, which will be executed during thesimInit
call. This last way is the most "modular" way to create default data sets for your model.
See below for more details.
Note using registerOutputs
: a user can pass any other
arguments to registerOutputs
that are in the
outputs(sim)
data.frame, such as objectName
, fun
, package
, though these
will not be used to save the files as this function is only about
registering an output that has already been saved.
Value
A simList
which will be the sim
passed in with a new object registered
in the outputs(sim)
outputs function or argument in simInit
outputs
accepts a data.frame similar to the inputs
data.frame, but
with up to 6 columns.
objectName | required, character string indicating the name of the object
in the simList that will be saved to disk (without the sim$ prefix). |
file | optional, a character string indicating the file path to save to.
The default is to concatenate objectName with the model timeunit and
saveTime , separated by underscore, '_ '. So a default filename would be
"Fires_year1.rds" . |
fun | optional, a character string indicating the function to use to
save that file. The default is saveRDS() |
package | optional character string indicating the package in
which to find the fun ); |
saveTime | optional numeric, indicating when in simulation time the file
should be saved. The default is the lowest priority at end(sim) ,
i.e., at the very end. |
arguments | is a list of lists of named arguments, one list for each
fun . For example, if fun = "write.csv" ,
arguments = list(row.names = TRUE) will pass the argument
row.names = TRUE to write.csv If there is only one list,
then it is assumed to apply to all files and will be recycled as per normal R
rules of recycling for each fun . |
See the modules vignette for more details (browseVignettes("SpaDES.core")
).
Note
The automatic file type handling only adds the correct extension from a given
fun
and package
. It does not do the inverse, from a given extension find the
correct fun
and package
.
See Also
registerOutputs()
which enables files that are saved to be added to
the simList
using the outputs(sim)
mechanism, so the files that are saved
during a module event can be tracked at the simList
level. saveSimList()
which will optionally add all the outputs that are tracked into an archive.
Examples
#######################
# outputs
#######################
tmpdir <- file.path(tempdir(), "outputs") |> checkPath(create = TRUE)
tmpFile <- file.path(tmpdir, "temp.rds")
tempObj <- 1:10
# Can add data.frame of outputs directly into simInit call
sim <- simInit(objects = c("tempObj"),
outputs = data.frame(objectName = "tempObj"),
paths = list(outputPath = tmpdir))
outputs(sim) # To see what will be saved, when, what filename
sim <- spades(sim)
outputs(sim) # To see that it was saved, when, what filename
# Also can add using assignment after a simList object has been made
sim <- simInit(objects = c("tempObj"), paths = list(outputPath = tmpdir))
outputs(sim) <- data.frame(objectName = "tempObj", saveTime = 1:10)
sim <- spades(sim)
outputs(sim) # To see that it was saved, when, what filename.
# can do highly variable saving
tempObj2 <- paste("val", 1:10)
df1 <- data.frame(col1 = tempObj, col2 = tempObj2)
sim <- simInit(objects = c("tempObj", "tempObj2", "df1"),
paths = list(outputPath = tmpdir))
outputs(sim) <- data.frame(
objectName = c(rep("tempObj", 2), rep("tempObj2", 3), "df1"),
saveTime = c(c(1, 4), c(2, 6, 7), end(sim)),
fun = c(rep("saveRDS", 5), "write.csv"),
package = c(rep("base", 5), "utils"),
stringsAsFactors = FALSE)
# since write.csv has a default of adding a column, x, with rownames, must add additional
# argument for 6th row in data.frame (corresponding to the write.csv function)
outputArgs(sim)[[6]] <- list(row.names = FALSE)
sim <- spades(sim)
outputs(sim)
# read one back in just to test it all worked as planned
newObj <- read.csv(dir(tmpdir, pattern = "year10.csv", full.name = TRUE))
newObj
# using saving with SpaDES-aware methods
# To see current ones SpaDES can do
.saveFileExtensions()
library(terra)
ras <- rast(ncol = 4, nrow = 5)
ras[] <- 1:20
sim <- simInit(objects = c("ras"), paths = list(outputPath = tmpdir))
outputs(sim) <- data.frame(
file = "test",
fun = "writeRaster",
package = "terra",
objectName = "ras",
stringsAsFactors = FALSE)
simOut <- spades(sim)
outputs(simOut)
newRas <- rast(dir(tmpdir, full.name = TRUE, pattern = ".tif")[1])
all.equal(newRas, ras) # Should be TRUE
# Clean up after
unlink(tmpdir, recursive = TRUE)
# For `registerOutputs`
sim <- simInit()
# This would normally be a save call, e.g., `writeRaster`
tf <- reproducible::tempfile2(fileext = ".tif")
sim <- registerOutputs(sim, filename = tf)
# Using a pipe
tf <- reproducible::tempfile2(fileext = ".rds")
sim$a <- 1
sim <- saveRDS(sim$a, tf) |> registerOutputs()
# confirm:
outputs(sim) # has object --> saved = TRUE
Get module or simulation package dependencies
Description
Get module or simulation package dependencies
Usage
packages(sim, modules, paths, filenames, envir, clean = FALSE, ...)
## S4 method for signature 'ANY'
packages(sim, modules, paths, filenames, envir, clean = FALSE, ...)
Arguments
sim |
A |
modules |
Character vector, specifying the name or vector of names of module(s) |
paths |
Character vector, specifying the name or vector of names of paths(s) for
those modules. If path not specified, it will be taken from
|
filenames |
Character vector specifying filenames of modules (i.e.
combined path & module. If this is specified, then |
envir |
Optional environment in which to store parsed code. This may be
useful if the same file is being parsed multiple times. This
function will check in that environment for the parsed file before
parsing again. If the |
clean |
Optional logical. If |
... |
All |
Value
A sorted character vector of package names.
Author(s)
Alex Chubaty & Eliot McIntire
See Also
Other functions to access elements of a 'simList' object:
.addDepends()
,
checkpointFile()
,
envir()
,
events()
,
globals()
,
inputs()
,
modules()
,
objs()
,
params()
,
paths()
,
progressInterval()
,
times()
Test and update a parameter against same parameter in other modules
Description
This function is intended to be part of module code and will test whether
the value of a parameter within the current module matches the value of the
same parameter in other modules. This is a test for parameters that might expect
to be part of a params = list(.globals = list(someParam = "test"))
passed to simInit()
.
Usage
paramCheckOtherMods(
sim,
paramToCheck,
moduleToUse = "all",
ifSetButDifferent = c("error", "warning", "message", "silent"),
verbose = getOption("reproducible.verbose")
)
Arguments
sim |
A |
paramToCheck |
A character string, length one, of a parameter name to check and compare between the current module and one or more or all others |
moduleToUse |
A character vector of module names to check against. This can be
|
ifSetButDifferent |
A character string indicating whether to |
verbose |
Logical or Numeric, follows |
Details
It is considered a "fail" under several conditions:
current module has a value that is not
NULL
or"default"
and another module has a different value;there is more than one value for the
paramToCheck
in the other modules, so it is ambiguous which one to return.
Either the current module is different than other modules, unless it is "default" or NULL.
Value
If the value of the paramToCheck
in the current module is either NULL
or
"default"
, and there is only one other value across all modules named in moduleToUse
,
then this will return a character string with the value of the single parameter value
in the other module(s).
It will return the current value if there are no other modules with the same parameter.
Get and set simulation parameters
Description
params
, P
and Par
(an active binding, like "mod") access the parameter
slot in the simList
.
params
has a replace method, so can be used to update a parameter value.
Usage
params(sim)
## S4 method for signature 'simList'
params(sim)
params(sim) <- value
## S4 replacement method for signature 'simList'
params(sim) <- value
P(sim, param, module)
P(sim, param, module) <- value
parameters(sim, asDF = FALSE)
## S4 method for signature 'simList'
parameters(sim, asDF = FALSE)
Arguments
sim |
A |
value |
The parameter value to be set (in the corresponding |
param |
Optional character string indicating which parameter to choose. |
module |
Optional character string indicating which module params should come from. |
asDF |
Logical. For |
Details
parameters
will extract only the metadata with the metadata defaults,
NOT the current values that may be overwritten by a user. See examples.
Value
Returns or sets the value of the slot from the simList
object.
Note
The differences between P()
, params()
and being explicit with passing arguments
are mostly a question of speed and code compactness.
The computationally fastest way to get a parameter is to specify moduleName
and parameter name,
as in: P(sim, "paramName", "moduleName")
(replacing moduleName
and paramName
with your
specific module and parameter names), but it is more verbose than P(sim)$paramName
.
Note: the important part for speed (e.g., 2-4x faster) is specifying the moduleName
.
Specifying the parameter name is <5% faster.
See Also
SpaDES.core-package, specifically the section 1.2.1 on Simulation parameters.
Other functions to access elements of a 'simList' object:
.addDepends()
,
checkpointFile()
,
envir()
,
events()
,
globals()
,
inputs()
,
modules()
,
objs()
,
packages()
,
paths()
,
progressInterval()
,
times()
Examples
s <- simInit()
# add a parameter to tmp module
params(s)$tmp <- list(a = 1)
# Only work inside a module, inside a function with `sim` is an argument
# P(s, "a") # get "a" parameter inside the current module
# Par$a # same. Get "a" parameter inside the current module
if (requireNamespace("NLMR", quietly = TRUE) &&
requireNamespace("SpaDES.tools", quietly = TRUE)) {
opts <- options("spades.moduleCodeChecks" = FALSE) # not necessary for example
modules <- list("randomLandscapes")
paths <- list(modulePath = getSampleModules(tempdir()))
mySim <- simInit(modules = modules, paths = paths,
params = list(.globals = list(stackName = "landscape")))
# update some parameters using assignment -- currently only params will work
params(mySim)$randomLandscapes$nx <- 200
params(mySim)$randomLandscapes$ny <- 200
parameters(mySim) # Does not contain these user overridden values
# These next 2 are same here because they are not within a module
P(mySim) # Does contain the user overridden values
params(mySim) # Does contain the user overridden values
# NOTE -- deleting a parameter will affect params and P, not parameters
params(mySim)$randomLandscapes$nx <- NULL
params(mySim)$randomLandscapes$ny <- NULL
parameters(mySim) # Shows nx and ny
# These next 2 are same here because they are not within a module
P(mySim) # nx and ny are Gone
params(mySim) # nx and ny are Gone
options(opts) # reset
}
Specify paths for modules, inputs, outputs, and temporary rasters
Description
Accessor functions for the paths
slot in a simList
object.
dataPath
will return file.path(modulePath(sim), currentModule(sim), "data")
.
dataPath
, like currentModule
,is namespaced. This means that when
it is used inside a module, then it will return that model-specific information.
For instance, if used inside a module called "movingAgent"
,
then currentModule(sim)
will return "movingAgent"
, and dataPath(sim)
will return
file.path(modulePath(sim), "movingAgent", "data")
Usage
paths(sim)
## S4 method for signature 'simList'
paths(sim)
paths(sim) <- value
## S4 replacement method for signature 'simList'
paths(sim) <- value
cachePath(sim)
## S4 method for signature 'simList'
cachePath(sim)
cachePath(sim) <- value
## S4 replacement method for signature 'simList'
cachePath(sim) <- value
inputPath(sim)
## S4 method for signature 'simList'
inputPath(sim)
inputPath(sim) <- value
## S4 replacement method for signature 'simList'
inputPath(sim) <- value
outputPath(sim)
## S4 method for signature 'simList'
outputPath(sim)
outputPath(sim) <- value
## S4 replacement method for signature 'simList'
outputPath(sim) <- value
figurePath(sim)
## S4 method for signature 'simList'
figurePath(sim)
logPath(sim)
## S4 method for signature 'simList'
logPath(sim)
modulePath(sim, module)
## S4 method for signature 'simList'
modulePath(sim, module)
modulePath(sim) <- value
## S4 replacement method for signature 'simList'
modulePath(sim) <- value
scratchPath(sim)
## S4 method for signature 'simList'
scratchPath(sim)
scratchPath(sim) <- value
## S4 replacement method for signature 'simList'
scratchPath(sim) <- value
rasterPath(sim)
## S4 method for signature 'simList'
rasterPath(sim)
rasterPath(sim) <- value
## S4 replacement method for signature 'simList'
rasterPath(sim) <- value
terraPath(sim)
## S4 method for signature 'simList'
terraPath(sim)
terraPath(sim) <- value
## S4 replacement method for signature 'simList'
terraPath(sim) <- value
dataPath(sim)
## S4 method for signature 'simList'
dataPath(sim)
Arguments
sim |
A |
value |
The parameter value to be set (in the corresponding |
module |
The optional character string of the module(s) whose paths are desired. If omitted, will return all module paths, if more than one exist. |
Details
These are ways to add or access the file paths used by spades()
.
There are five file paths: cachePath
, modulePath
,
inputPath
, outputPath
, and rasterPath
.
Each has a function to get or set the value in a simList
object.
If no paths are specified, the defaults are as follows:
-
cachePath
:getOption("reproducible.cachePath")
; -
inputPath
:getOption("spades.modulePath")
; -
modulePath
:getOption("spades.inputPath")
; -
outputPath
:getOption("spades.outputPath")
; -
rasterPath
:file.path(getOption("spades.scratchPath"), "raster")
; -
scratchPath
:getOption("spades.scratchPath")
; -
terraPath
:file.path(getOption("spades.scratchPath"), "terra")
Value
Returns or sets the value of the slot from the simList
object.
See Also
SpaDES.core-package, specifically the section 1.2.4 on Simulation Paths.
Other functions to access elements of a 'simList' object:
.addDepends()
,
checkpointFile()
,
envir()
,
events()
,
globals()
,
inputs()
,
modules()
,
objs()
,
packages()
,
params()
,
progressInterval()
,
times()
Event priority
Description
Preset event priorities: 1 = first (highest); 5 = normal; 10 = last (lowest).
Usage
.first()
.highest()
.last()
.lowest()
.normal()
Value
numeric of length 1.
Author(s)
Alex Chubaty
Get and set simulation progress bar details
Description
The progress bar can be set in two ways in SpaDES. First, by setting values
in the .progress
list element in the params list element passed to simInit()
.
Second, at the spades()
call itself, which can be simpler. See examples.
Usage
progressInterval(sim)
## S4 method for signature 'simList'
progressInterval(sim)
progressInterval(sim) <- value
## S4 replacement method for signature 'simList'
progressInterval(sim) <- value
progressType(sim)
## S4 method for signature 'simList'
progressType(sim)
progressType(sim) <- value
## S4 replacement method for signature 'simList'
progressType(sim) <- value
Arguments
sim |
A |
value |
The parameter value to be set (in the corresponding |
Details
Progress Bar:
Progress type can be one of "text"
, "graphical"
, or "shiny"
.
Progress interval can be a numeric.
These both can get set by passing a
.progress = list(type = "graphical", interval = 1)
into the simInit
call.
See examples.
Value
for progressInterval
, a numeric corresponding to the progress update interval;
for progressInterval<-
, an updated simList
object.
See Also
Other functions to access elements of a 'simList' object:
.addDepends()
,
checkpointFile()
,
envir()
,
events()
,
globals()
,
inputs()
,
modules()
,
objs()
,
packages()
,
params()
,
paths()
,
times()
Examples
if (requireNamespace("SpaDES.tools", quietly = TRUE) &&
requireNamespace("NLMR", quietly = TRUE)) {
opts <- options("spades.moduleCodeChecks" = FALSE) # not necessary for example
mySim <- simInit(
times = list(start=0.0, end=100.0),
params = list(.globals = list(stackName = "landscape"),
.progress = list(type = "text", interval = 10),
checkpoint = list(interval = 10, file = "chkpnt.RData")),
modules = list("randomLandscapes"),
paths = list(modulePath = getSampleModules(tempdir()))
)
# progress bar
progressType(mySim) # "text"
progressInterval(mySim) # 10
# parameters
params(mySim) # returns all parameters in all modules
# including .global, .progress, checkpoint
globals(mySim) # returns only global parameters
# checkpoint
checkpointFile(mySim) # returns the name of the checkpoint file
# In this example, "chkpnt.RData"
checkpointInterval(mySim) # 10
options(opts) # reset
}
Simple wrapper to load any Raster*
object
Description
This wraps either raster::raster
, raster::stack
, raster::brick
, or terra::rast
,
allowing a single function to be used to create a new object of the same class as a template.
This works for all Raster*
and SpatRaster
class templates.
Usage
rasterCreate(x, ...)
## Default S3 method:
rasterCreate(x, ...)
Arguments
x |
An object, notably a |
... |
Passed to |
Value
a new (empty) object of same class as the original.
Methods (by class)
-
rasterCreate(default)
: Simply passes through argument with no effect
Read raster to memory
Description
Wrapper to the raster
function, that creates the raster object in
memory, even if it was read in from file. There is the default method which is
just a pass through, so this can be safely used on large complex objects,
recursively, e.g., a simList
.
Usage
rasterToMemory(x, ...)
## S4 method for signature 'list'
rasterToMemory(x, ...)
## S4 method for signature 'character'
rasterToMemory(x, ...)
## S4 method for signature 'ANY'
rasterToMemory(x, ...)
## S4 method for signature 'simList'
rasterToMemory(x, ...)
Arguments
x |
An object passed directly to the function raster (e.g., character string of a filename). |
... |
Additional arguments to |
Value
A raster object whose values are stored in memory.
Author(s)
Eliot McIntire and Alex Chubaty
See Also
raster()
, terra::rast()
.
Objects exported from other packages
Description
These objects are imported from other packages. Follow the links below to see their documentation.
- reproducible
Determine the size of a remotely hosted file
Description
Defunct. Will be removed by mid-2023.
Usage
remoteFileSize(url)
Arguments
url |
The url of the remote file. |
Value
A numeric indicating the size of the remote file in bytes.
Author(s)
Eliot McIntire and Alex Chubaty
Restart R programmatically
Description
This will attempt to restart the R session, reloading all packages, and
saving and reloading the simList
.
Currently, this is not intended for general use: it has many specialized
pieces for using inside a spades
call.
The main purpose for doing this is to clear memory leaks (possibly deep
in R https://github.com/r-lib/fastmap) that are not fully diagnosed.
This is still very experimental.
This should only be used if there are RAM limitations being hit with long running simulations.
It has been tested to work Linux within Rstudio and at a terminal R session.
The way to initiate restarting of R is simply setting the spades.restartRInterval
or
setting the equivalent parameter in the restartR
core module via:
simInit(..., params = list(.restartR = list(.restartRInterval = 1)), ...)
greater than 0, which is the default,
e.g., options("spades.restartRInterval" = 100)
.
This is only intended to restart a simulation in exactly the same place as it was
(i.e., cannot change machines), and because of the restart, the assignment of the spades
call will be either to sim
or the user must make such an assignment manually,
e.g., sim <- savedSimEnv()$.sim
, or perhaps, the safer sim <- Copy(savedSimEnv()$.sim)
.
This is stated in a message.
Usage
restartR(
sim,
reloadPkgs = TRUE,
.First = NULL,
.RDataFile = getOption("spades.restartR.RDataFilename"),
restartDir = getOption("spades.restartR.restartDir", NULL)
)
Arguments
sim |
Required. A |
reloadPkgs |
Logical. If |
.First |
A function to save to ‘~/.qs’ which will
be loaded at restart from ‘~/.qs’ and run. Default is |
.RDataFile |
A filename for saving the |
restartDir |
A character string indicating root directory to
save |
Details
The process responds to several options. Though under most cases,
the default behaviour should suffice. These are of 3 types: restartRInterval
the arguments to restartR
and the arguments to saveSimList
, these latter two
using a dot to separate the function name and its argument. The defaults for
two key options are: options("spades.restartR.restartDir" = NULL
, meaning
use file.path(restartDir, "restartR", paste0(sim$._startClockTime, "_", .rndString))
and options("spades.saveSimList.fileBackend" = 0)
, which means don't do anything
with raster-backed files.
See specific functions for defaults and argument meanings.
The only difference from the default function values is with saveSimList
argument
fileBackend = FALSE
during restartR
by default, because it is assumed that
the file backends will still be intact after a restart, so no need to move them all to memory.
Value
invoked for side effect of restarting the R session
Note
Because of the restarting, the object name of the original assignment of the
spades
call can not be preserved. The spades
call will be
assigned to sim
in the .GlobalEnv
.
Because this function is focused on restarting during a spades
call,
it will remove all objects in the .GlobalEnv
, emulating q("no")
.
If the user wants to keep those objects, then they should be saved to disk
immediately before the spades
call.
This can then be recovered immediately after the return from the spades
call.
To keep the saved simList
, use options("spades.restartR.clearFiles" = TRUE)
.
The default is to treat these files as temporary files and so will be removed.
Restart an interrupted simulation
Description
This is very experimental and has not been thoroughly tested. Use with caution.
This function will re-parse a single module (currently) into the simList
where its source code should reside, and then optionally restart a simulation
that stopped on an error, presumably after the developer has modified the
source code of the module that caused the break.
This will restart the simulation at the next event in the event queue
(i.e., returned by events(sim)
). Because of this, this function will
not do anything if the event queue is empty.
Usage
restartSpades(sim = NULL, module = NULL, numEvents = Inf, restart = TRUE, ...)
Arguments
sim |
A |
module |
A character string length one naming the module that caused the error and
whose source code was fixed. This module will be re-parsed and placed into the |
numEvents |
Numeric. Default is Inf (i.e., all available). In the |
restart |
Logical. If |
... |
Passed to |
Details
This will only parse the source code from the named module. It will not affect any
objects that are in the mod
or sim
.
The random number seed will be reset to the state it was at the start of the earliest event recovered, thereby returning to the exact stochastic simulation trajectory.
Value
A simList
as if spades
had been called on a simList
.
Note
This will only work reliably
if the simList
was not modified yet during the event which caused the error.
The simList
will be in the state it was at the time of the error.
Examples
# options("spades.recoveryMode" = 1) # now the default
s <- simInit()
s <- spades(s) # if this is interrupted or fails
# the following line will not work if the previous line didn't fail
s <- restartSpades(s) # don't need to specify `sim` if previous line fails
# will take from savedSimEnv()$.sim automatically
Save objects using .saveObjects
in params
slot of simInit
Description
In the simInit()
call, a parameter called .saveObjects
can be provided in
each module.
This must be a character string vector of all object names to save. These objects will
then be saved whenever a call to saveFiles
is made.
Usage
saveFiles(sim)
Arguments
sim |
A |
Details
The file names will be equal to the object name plus time(sim)
is
appended at the end.
The files are saved as .rds
files, meaning, only one object gets
saved per file.
For objects saved using this function, the module developer must create save
events that schedule a call to saveFiles
.
If this function is used outside of a module, it will save all files in the
outputs(sim)
that are scheduled to be saved at the current time in the simList.
There are several ways to save objects using SpaDES
.
Value
(invisibly) the modified sim
object.
invoked for side effect of saving the simulation to file.
Model-level saving
Using the outputs
slot in the simInit()
call.
See example in simInit()
.
This can be convenient because it gives overall control of many modules at a
time, and it gets automatically scheduled during the simInit()
call.
Module-level saving
Using the saveFiles
function inside a module.
This must be accompanied by a .saveObjects
vector or list element in the
params
slot in the simList()
.
Usually a module developer will create this method for future users of their module.
Custom saving
A module developer can save any object at any time inside their module, using
standard R functions for saving R objects (e.g., save
or saveRDS
).
This is the least modular approach, as it will happen whether a module user
wants it or not.
Note
It is not possible to schedule separate saving events for each object
that is listed in the .saveObjects
.
Author(s)
Eliot McIntire and Alex Chubaty
Examples
if (requireNamespace("SpaDES.tools", quietly = TRUE) &&
requireNamespace("NLMR", quietly = TRUE)) {
## This will save the "caribou" object at the save interval of 1 unit of time
## in the outputPath location
outputPath <- file.path(tempdir(), "test_save")
times <- list(start = 0, end = 1, "month")
modules <- list("randomLandscapes", "caribouMovement")
paths <- list(
modulePath = getSampleModules(tempdir()),
outputPath = outputPath
)
opts <- options("spades.moduleCodeChecks" = FALSE,
"spades.useRequire" = FALSE) # not necessary for example
## save multiple outputs
parameters <- list(
.globals = list(stackName = "landscape"),
caribouMovement = list(
.saveObjects = c("caribou", "habitatQuality"),
.saveInitialTime = 1, .saveInterval = 1
),
randomLandscapes = list(.plots = NA, nx = 20, ny = 20))
mySim <- simInit(times = times, params = parameters, modules = modules,
paths = paths)
spades(mySim, .plotInitialTime = NA) # plotting not relevant for this example
dir(outputPath)
# remove the files
file.remove(dir(outputPath, full.names = TRUE))
options(opts) # clean up
}
Save a whole simList
object to disk
Description
Saving a simList
may not work using the standard approaches
(e.g., save
, saveRDS
, and qs::qsave
).
There are 2 primary reasons why this doesn't work as expected:
the activeBindings
that are in place within modules
(these allow the mod
and Par
to exist), and file-backed objects,
such as SpatRaster
and Raster*
.
Because of these, a user should use saveSimList
and loadSimList
.
These will save the object and recover the object using the filename
supplied,
if there are no file-backed objects.
If there are file-backed objects, then it will save an archive
(default is .tar.gz
using the archive
package for non-Windows and zip()
if using Windows, as there is currently an unidentified bug in archive*
on Windows).
The user does not need to specify the filename any differently,
as the code will search based on the filename without the file extension.
Usage
saveSimList(
sim,
filename,
projectPath = getwd(),
outputs = TRUE,
inputs = TRUE,
cache = FALSE,
envir,
...
)
Arguments
sim |
Either a |
filename |
Character string with the path for saving |
projectPath |
Should be the "top level" or project path for the |
outputs |
Logical. If |
inputs |
Logical. If |
cache |
Logical. Not yet implemented. If |
envir |
If |
... |
Additional arguments. See Details. |
Details
There is a family of 2 functions that are mutually useful for saving and
loading simList
objects and their associated files (e.g., file-backed
Raster*
, inputs
, outputs
, cache
) saveSimList()
, loadSimList()
.
Additional arguments may be passed via ...
, including:
-
files
: logical indicating whether files should be included in the archive. ifFALSE
, will overridecache
,inputs
,outputs
, setting them toFALSE
. -
symlinks
: a named list of paths corresponding to symlinks, which will be used to substitute normalized absolute paths of files. Names should correspond to the names inpaths()
; values should be project-relative paths. E.g.,list(cachePath = "cache", inputPath = "inputs", outputPath = "outputs")
.
Value
Invoked for side effects of saving both a .qs
(or .rds
) file,
and a compressed archive (one of .tar.gz
if using non-Windows OS or .zip
on Windows).
See Also
Retrieve environment for saving interrupted simulations
Description
If the user sets options(reproducible.memoisePersist = TRUE)
,
the global environment will be used, otherwise, a package environment.
Usage
savedSimEnv(envir = .GlobalEnv)
Arguments
envir |
an environment to use to store the |
Schedule a conditional simulation event
Description
Adds a new event to the simulation's conditional event queue,
updating the simulation object by creating or appending to
sim$._conditionalEvents
.
This is very experimental. Use with caution.
Usage
scheduleConditionalEvent(
sim,
condition,
moduleName,
eventType,
eventPriority = .normal(),
minEventTime = start(sim),
maxEventTime = end(sim)
)
Arguments
sim |
A |
condition |
A string, call or expression that will be assessed for |
moduleName |
A character string specifying the module from which to
call the event. If missing, it will use
|
eventType |
A character string specifying the type of event from within the module. |
eventPriority |
A numeric specifying the priority of the event.
Lower number means higher priority. As a best practice, it is
recommended that decimal values are conceptual
grouped by their integer values (e.g., 4.0, 4.25, 4.5 are conceptually
similar).
See |
minEventTime |
A numeric specifying the time before which the event should not occur,
even if the condition is met. Defaults to |
maxEventTime |
A numeric specifying the time after which the event should not occur,
even if the condition is met. Defaults to |
Details
This conditional event queue will be assessed at every single event in the normal event
queue. If there are no conditional events, then spades
will proceed as normal.
As conditional event conditions are found to be true, then it will trigger a call to
scheduleEvent(...)
with the current time passed to eventTime
and
it will remove the conditional event from the conditional queue.
If the user would like the triggered conditional event to occur as the very next event,
then a possible strategy would be to set eventPriority
of the conditional event
to very low or even negative to ensure it gets inserted at the top of the event queue.
Value
Returns the modified simList
object, i.e., sim$._conditionalEvents
.
Author(s)
Eliot McIntire
References
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
See Also
scheduleEvent()
, conditionalEvents()
Examples
sim <- simInit(times = list(start = 0, end = 2))
condition <- "sim$age > 1" # provide as string
condition <- quote(sim$age > 1) # provide as a call
condition <- expression(sim$age > 1) # provide as an expression
sim <- scheduleConditionalEvent(sim, condition, "firemodule", "burn")
conditionalEvents(sim)
sim <- spades(sim) # no changes to sim$age, i.e., it is absent
events(sim) # nothing scheduled
sim$age <- 2 # change the value
sim <- spades(sim) # Run spades, the condition is now true, so event is
# scheduled at current time
events(sim) # now scheduled in the normal event queue
Schedule a simulation event
Description
Adds a new event to the simulation's event queue, updating the simulation object.
Usage
scheduleEvent(
sim,
eventTime,
moduleName,
eventType,
eventPriority = .pkgEnv$.normalVal,
.skipChecks = FALSE
)
Arguments
sim |
A |
eventTime |
A numeric specifying the time of the next event. |
moduleName |
A character string specifying the module from which to
call the event. If missing, it will use
|
eventType |
A character string specifying the type of event from within the module. |
eventPriority |
A numeric specifying the priority of the event.
Lower number means higher priority. As a best practice, it is
recommended that decimal values are conceptual
grouped by their integer values (e.g., 4.0, 4.25, 4.5 are conceptually
similar).
See |
.skipChecks |
Logical. If |
Details
Here, we implement a simulation in a more modular fashion so it's easier to add
submodules to the simulation. We use S4 classes and methods, and use data.table
instead of data.frame
to implement the event queue (because it is much faster).
Value
Returns the modified simList
object.
Author(s)
Alex Chubaty
References
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
See Also
priority()
, scheduleConditionalEvent()
Examples
sim <- simInit()
sim <- scheduleEvent(sim, time(sim) + 1.0, "fireSpread", "burn") # default priority
sim <- scheduleEvent(sim, time(sim) + 1.0, "fireSpread", "burn", .normal()) # default priority
sim <- scheduleEvent(sim, time(sim) + 1.0, "fireSpread", "burn", .normal()-1) # higher priority
sim <- scheduleEvent(sim, time(sim) + 1.0, "fireSpread", "burn", .normal()+1) # lower priority
sim <- scheduleEvent(sim, time(sim) + 1.0, "fireSpread", "burn", .highest()) # highest priority
sim <- scheduleEvent(sim, time(sim) + 1.0, "fireSpread", "burn", .lowest()) # lowest priority
events(sim) # shows all scheduled events, with eventTime and priority
Get and set default working directories
Description
Wrapper functions to access the packages options for default working directories.
Note: there is an active binding made to Paths
, so a user can use
Paths$cachePath
for example instead of getPaths()$cachePath
Usage
.paths()
getPaths()
Paths
setPaths(
cachePath,
inputPath,
modulePath,
outputPath,
rasterPath,
scratchPath,
terraPath,
silent = FALSE
)
Arguments
cachePath |
The default local directory in which to cache simulation outputs.
If not specified, defaults to |
inputPath |
The default local directory in which to look for simulation inputs
If not specified, defaults to |
modulePath |
The default local directory where modules and data will be
downloaded and stored.
If not specified, defaults to |
outputPath |
The default local directory in which to save simulation outputs.
If not specified, defaults to |
rasterPath |
The default local directory in which to save transient raster files.
If not specified, defaults to
|
scratchPath |
The default local directory in which to save transient files.
If not specified, defaults to |
terraPath |
The default local directory in which to save transient |
silent |
Logical. Should the messaging occur. |
Format
An object of class list
of length 7.
Value
getPaths
returns a named list of the user's default working directories.
setPaths
is invoked for the side effect of setting these directories.
Author(s)
Alex Chubaty
Examples
getPaths() ## returns the current default working paths
## set individual custom paths
setPaths(cachePath = file.path(tempdir(), "cache"))
setPaths(inputPath = file.path(tempdir(), "inputs"))
setPaths(modulePath = file.path(tempdir(), "modules"))
setPaths(outputPath = file.path(tempdir(), "outputs"))
setPaths(scratchPath = file.path(tempdir(), "scratch"))
# NOTE: on loading and attaching SpaDES.core,
# an active binding is made to "Paths"
getPaths()
Paths ## same as getPaths() above
setPaths(outputPath = tempdir())
Paths # shows change
Show an Object
Description
Show an Object
Usage
## S4 method for signature 'simList'
show(object)
Arguments
object |
|
Author(s)
Alex Chubaty
Generate simulation file name
Description
Assists with saving and retrieving simulations (e.g., with saveSimList
and loadSimList
).
Usage
simFile(name, path, time = NULL, ext = "rds")
Arguments
name |
Object name (e.g., |
path |
Directory location in where the file will be located (e.g., an |
time |
Optional simulation time to use as filename suffix. Default |
ext |
The file extension to use (default |
Value
character string giving a file path for a simulation file
Initialize a new simulation
Description
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.
Usage
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()
Arguments
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 |
Details
Calling this 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")
.
Value
A simList
simulation object, pre-initialized from values
specified in the arguments supplied.
Parsing and Checking Code
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)
.
Caching
Using caching with SpaDES
is vital when building re-usable and reproducible content.
Please see the vignette dedicated to this topic.
Note
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.
Author(s)
Alex Chubaty and Eliot McIntire
References
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
See Also
spades()
, defineModule()
to get help on metadata elements,
times()
, params()
, objs()
, paths()
,
modules()
, inputs()
, outputs()
Examples
# 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)
}
Call simInit
and spades
together
Description
These functions are convenience wrappers that may allow for more efficient caching.
Passes all arguments to simInit()
, then passes the created simList
to spades()
.
Usage
simInitAndSpades(
times,
params,
modules,
objects,
paths,
inputs,
outputs,
loadOrder,
notOlderThan,
debug,
progress,
cache,
.plots,
.plotInitialTime,
.saveInitialTime,
events,
...
)
Arguments
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 |
debug |
Optional tools for invoking debugging. Supplying a |
progress |
Logical ( |
cache |
Logical. If |
.plots |
Character. Sets the parameter of this name in all modules.
See |
.plotInitialTime |
Numeric. Temporarily override the |
.saveInitialTime |
Numeric. Temporarily override the |
events |
A character vector or a named list of character vectors. If specified,
the simulations will only do the events indicated here. If a named list, the names
must correspond to the modules and the character vectors can be specific events within
each of the named modules. With the |
... |
Arguments passed to |
Value
Same as spades()
(a simList
) or
See Also
The simList
class
Description
Contains the minimum components of a SpaDES
simulation.
Various slot accessor methods (i.e., get and set functions) are provided
(see 'Accessor Methods' below).
Details
Based on code from chapter 7.8.3 of Matloff (2011): "Discrete event simulation".
Here, we implement a discrete event simulation in a more modular fashion so
it's easier to add simulation components (i.e., "simulation modules").
We use S4 classes and methods, and use data.table()
instead of
data.frame()
to implement the event queue (because it is much
more efficient).
Slots
modules
List of character names specifying which modules to load.
params
Named list of potentially other lists specifying simulation parameters.
events
The list of scheduled events (i.e., event queue), which can be converted to a sorted
data.table
withevents(sim)
. See 'Event Lists' for more information.current
The current event, as a
data.table
. See 'Event Lists' for more information..completed
An environment consisting of completed events, with each object named a character representation of the order of events. This was converted from a previous version which was a list. This was changed because the list became slow as number of events increased. See 'Event Lists' for more information. It is kept as an environment of individual events for speed. The
completed
method converts it to a sorteddata.table
.depends
A
.simDeps
list of.moduleDeps()
objects containing module object dependency information.simtimes
List of numerical values describing the simulation start and end times; as well as the current simulation time.
inputs
a
data.frame
ordata.table
of files and metadataoutputs
a
data.frame
ordata.table
of files and metadatapaths
Named list of paths. See
?.paths
. Partial matching is performed..xData
Environment referencing the objects used in the simulation. Several "shortcuts" to accessing objects referenced by this environment are provided, and can be used on the
simList
object directly instead of specifying the.xData
slot:$
,[[
,ls
,ls.str
,objs
. See examples..envir
Deprecated. Please do not use any more.
Accessor Methods
Several slot (and sub-slot) accessor methods are provided for use, and categorized into separate help pages:
simList-accessors-envir() | Simulation environment. |
simList-accessors-events() | Scheduled and completed events. |
simList-accessors-inout() | Passing data in to / out of simulations. |
simList-accessors-modules() | Modules loaded and used; module dependencies. |
simList-accessors-objects() | Accessing objects used in the simulation. |
simList-accessors-params() | Global and module-specific parameters. |
simList-accessors-paths() | File paths for modules, inputs, and outputs. |
simList-accessors-times() | Simulation times. |
Event Lists
The main event list is a sorted data.table
(keyed) on eventTime
, and eventPriority.
The completed event list is an ordered list in the exact order that the events were executed.
Each event is represented by a data.table()
row consisting of:
eventTime | The time the event is to occur. |
moduleName | The module from which the event is taken. |
eventType | A character string for the programmer-defined event type. |
eventPriority | The priority given to the event. |
Note
The simList
class extends the environment
, by adding
several slots that provide information about the metadata for a discrete
event simulation. The environment slot, if accessed directly is .xData
and this is where input and output objects from modules are placed.
The simList_()
class is similar, but it extends the list
class. All other slots are the same.
Thus, simList
is identical to simList_
, except that the former
uses an environment for objects and the latter uses a list.
The class simList_
is only used internally when saving/loading, because
saving/loading a list behaves more reliably than saving/loading an environment.
Author(s)
Alex Chubaty and Eliot McIntire
References
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
Run a spatial discrete event simulation
Description
Here, we implement a simulation in a more modular fashion so it's easier to add
submodules to the simulation. We use S4 classes and methods, and use data.table
instead of data.frame
to implement the event queue (because it is much faster).
Usage
spades(
sim,
debug = getOption("spades.debug"),
progress = NA,
cache,
.plotInitialTime = NULL,
.saveInitialTime = NULL,
notOlderThan = NULL,
events = NULL,
.plots = getOption("spades.plots", NULL),
...
)
## S4 method for signature 'simList,ANY,ANY,missing'
spades(
sim,
debug = getOption("spades.debug"),
progress = NA,
cache,
.plotInitialTime = NULL,
.saveInitialTime = NULL,
notOlderThan = NULL,
events = NULL,
.plots = getOption("spades.plots", NULL),
...
)
## S4 method for signature 'ANY,ANY,ANY,logical'
spades(
sim,
debug = getOption("spades.debug"),
progress = NA,
cache,
.plotInitialTime = NULL,
.saveInitialTime = NULL,
notOlderThan = NULL,
events = NULL,
.plots = getOption("spades.plots", NULL),
...
)
Arguments
sim |
A |
debug |
Optional tools for invoking debugging. Supplying a |
progress |
Logical ( |
cache |
Logical. If |
.plotInitialTime |
Numeric. Temporarily override the |
.saveInitialTime |
Numeric. Temporarily override the |
notOlderThan |
Date or time. Passed to |
events |
A character vector or a named list of character vectors. If specified,
the simulations will only do the events indicated here. If a named list, the names
must correspond to the modules and the character vectors can be specific events within
each of the named modules. With the |
.plots |
Character. Sets the parameter of this name in all modules.
See |
... |
Any. Can be used to make a unique cache identity, such as "replicate = 1".
This will be included in the |
Details
The is the workhorse function in the SpaDES package. It runs simulations by
implementing the rules outlined in the simList
.
This function gives simple access to two sets of module parameters:
.plotInitialTime
and with .plotInitialTime
. The primary use of
these arguments is to temporarily turn off plotting and saving. "Temporary"
means that the simList
is not changed, so it can be used again with
the simList
values reinstated. To turn off plotting and saving, use
.plotInitialTime = NA
or .saveInitialTime = NA
. NOTE: if a
module did not use .plotInitialTime
or .saveInitialTime
, then
these arguments will not do anything.
Value
Invisibly returns the modified simList
object.
Caching with SpaDES
There are numerous ways in which Caching can be used within SpaDES. Please
see the vignette
https://spades-core.predictiveecology.org/articles/iii-cache.html
for many examples. Briefly, functions, events, modules, entire spades calls or
experiment calls (see https://github.com/PredictiveEcology/SpaDES.experiment)
can be cached and mixtures of all of these will work. For functions, simply
wrap the call with Cache
, moving the original function name into
the first argument of Cache. For events or modules, set the module parameters
,
.useCache
, e.g.,
simInit(..., parameters = list(myModule = list(.useCache = "init")))
.
This can be set to an event name, which will cache that event, or a logical,
which will cache every event in that module. Event and module caching
makes most sense when the event or module only runs once, such as an initialization
or data preparation event/module. Caching an entire simulation is actually just
a function call to simInitAndSpades
, for example. So, simply writing
Cache(simInitAndSpades, modules = ...)
will effectively cache a whole simulation.
Finally for experiments, it is just like a function call:
Cache(simInitandExperiment, ...)
. The final way Caching can be done is in
experiment
or spades
, by setting the cache
argument.
If cache
is TRUE, this allows for a seamless way to "save" results
of a simulation. The user does not have to intentionally do any saving manually.
Instead, upon a call to spades
in which the simList
is identical,
the function will simply return the result that would have come if it had
been rerun. Use this with caution, as it will return exactly the result from
a previous run, even if there is stochasticity internally.
Caching is only based on the input simList.
See also the vignette on caching for examples.
debug
The most powerful way to use debug is to invoke the logging
R package. To invoke this, debug
must be a list with up to 3
named elements:
console
, file
, and debug
. Each of these list elements
must be a list (including empty list()
for defaults) with the
sub-list elements here:
console | level | The level , see below, of information shown |
file | append | Logical. If TRUE , the default, then
log entries are appended to file, if it exists |
file | A filename. Defaults to log.txt |
|
level | The level , see below, of information shown |
|
debug | See possible values below | |
level
can be a number from 0 to 100 or a character string matching one
of the values in logging::loglevels
. These are hierarchical levels of
information passed to the console. Set a lower number for more information and a
higher number for less information. Errors in code will be shown if level
is set to "ERROR"
or 40
or above; warnings in code will be shown if
level
is set to "WARN"
or 30
or above;
normal messages in code will
be shown if level
is set to "INFO"
or 20
or above. For
consistency with base R messaging, if default level is used, then normal
messaging via message
will be shown; this means that suppressMessages
will work to suppress messaging only when level is set to "INFO"
or 20
.
Some functions in the SpaDES ecosystem may have information at the lower levels,
but currently, there are few to none.
debug
is specified as a non-list argument to spades
or as
list(debug = ...)
, then it can be a logical, a quoted call, a character vector
or a numeric scalar (currently 1 or 2) or a list of any of these to get multiple
outputs. This will be run at the start of every event. The following options for debug
are available. Each of these can also be in a list to get multiple outputs:
TRUE | current(sim) will be printed at the start of each event as
it runs |
a function name (as character string) | If a function, then it will be run on the
simList , e.g., "time" will run
time(sim) at each event. |
moduleName (as character string) | All calls to that module will be entered interactively |
eventName (as character string) | All calls that have that event name (in any module) will be entered interactively |
c(<moduleName>, <eventName>) | Only the event in that specified module will be entered into. |
Any other R expression expressed as a character string or quoted call |
Will be evaluated with access to the simList as sim .
If this is more than one character string, then all will
be printed to the screen in their sequence. |
A numeric scalar, currently 1 or 2 (maybe others) | This will print out alternative forms of event information that users may find useful |
If not specified in the function call, the package
option spades.debug
is used.
If options("spades.browserOnError" = TRUE)
(experimental still) if
there is an error, it will attempt to open a browser
in the event where the error occurred. You can edit, and then press c
to continue
or Q
to quit, plus all other normal interactive browser tools.
c
will trigger a reparse and events will continue as scheduled, starting
with the one just edited. There may be some unexpected consequences if the
simList
objects had already been changed before the error occurred.
Note
The debug option is primarily intended to facilitate building simulation
models by the user.
Will print additional outputs informing the user of updates to the values of
various simList
slot components.
See https://github.com/PredictiveEcology/SpaDES/wiki/Debugging for details.
Author(s)
Alex Chubaty and Eliot McIntire
References
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
See Also
SpaDES.core-package()
,
simInit()
, and the caching vignette (very important for reproducibility):
https://spades-core.predictiveecology.org/articles/iii-cache.html which
uses reproducible::Cache()
.
vignettes
Examples
if (requireNamespace("SpaDES.tools", quietly = TRUE) &&
requireNamespace("NLMR", quietly = TRUE)) {
# some options are not necessary when not interactive
opts <- options("spades.moduleCodeChecks" = FALSE, "spades.useRequire" = FALSE)
if (!interactive()) opts <- append(opts, options("spades.plots" = NA))
mySim <- simInit(
times = list(start = 0.0, end = 1.0, timeunit = "year"),
params = list(
randomLandscapes = list(nx = 10, ny = 10),
.globals = list(stackName = "landscape", burnStats = "nPixelsBurned",
.plots = NA) # plotting off --> not relevant for example
),
modules = list("randomLandscapes", "fireSpread", "caribouMovement"),
paths = list(modulePath = getSampleModules(tempdir()))
)
spades(mySim)
options(opts) # reset options
}
Classes defined in SpaDES
Description
These S4 classes are defined within SpaDES
. "dot" classes are not exported and
are therefore intended for internal use only.
Simulation classes
simList() | The simList class |
.moduleDeps() | Descriptor object for specifying SpaDES module dependencies |
.simDeps() | Defines all simulation dependencies for all modules within a SpaDES simulation |
--------------------------- | ------------------------------------------------------------------------------------------ |
Author(s)
Eliot McIntire and Alex Chubaty
See Also
SpaDES.core
options
Description
These provide top-level, powerful settings for a comprehensive SpaDES workflow.
To see defaults, run spadesOptions()
.
See Details below.
Usage
spadesOptions()
Details
Below are options that can be set with options("spades.xxx" = newValue)
,
where xxx
is one of the values below, and newValue
is a new value to
give the option. Sometimes these options can be placed in the user's .Rprofile
file so they persist between sessions.
The following options are likely of interest to most users
OPTION | DEFAULT VALUE | DESCRIPTION |
spades.allowInitDuringSimInit | FALSE
| New feature as of SpaDES.core > 1.1.1.9001 ; If set to TRUE ,
simInit will evaluate the dependencies in the metadata objects and determine whether
there are modules whose init events can be run safely prior to
the .inputObjects of other modules, i.e., if a module's expectsInput
is not being supplied by any other module's createsOutput . |
spades.browserOnError | FALSE | If TRUE , the default, then any
error rerun the same event with debugonce called on it to allow editing
to be done. When that browser is continued (e.g., with 'c'), then it will save it
re-parse it into the simList and rerun the edited version.
This may allow a spades() call to be recovered on error,
though in many cases that may not be the correct behaviour.
For example, if the simList gets updated inside that event in an iterative
manner, then each run through the event will cause that iteration to occur.
When this option is TRUE , then the event will be run at least 3 times: the
first time makes the error, the second time has debugonce and the third time
is after the error is addressed. TRUE is likely somewhat slower. |
reproducible.cachePath | getOption('reproducible.cachePath')
| The default local directory in which to cache simulation outputs.
Default is a temporary directory (typically /tmp/RtmpXXX/SpaDES/cache ). |
spades.debug | TRUE
| The default debugging value debug argument in spades() |
spades.dotInputObjects | TRUE
| This is used in simInit ; if set to TRUE then the .inputObjects
function will be run; if FALSE , then it will be skipped. |
spades.DTthreads | 1L
| The default number of data.table threads to use.
See also ?data.table::setDTthreads . |
spades.futureEvents | FALSE
| If set to TRUE , the event simulator will attempt to spawn events
whose outputs are not needed (by other events in the simList ) into a future.
In some cases, this will speed up simulations, by running some events in parallel.
Still VERY experimental. Use cautiously. |
spades.logPath
| Defaults to a subdirectory (logs/ ) of the simulation output directory.
| The default local directory in which to look for simulation inputs. |
spades.inputPath
| Default is a temporary directory (typically /tmp/RtmpXXX/SpaDES/inputs )
| The default local directory in which to look for simulation inputs. |
spades.loadReqdPkgs
| Default is TRUE meaning that any reqdPkgs will be loaded via Require
or require . If FALSE , no package loading will occur. This will mean that
modules must prefix every function call from a package with that package name
with double colon (::). |
|
spades.lowMemory | FALSE
| If true, some functions will use more memory efficient (but slower) algorithms. |
spades.memoryUseInterval | FALSE
| A numeric in seconds indicating how often sample the memory use. This will
be run in a separate "future" process so it can monitor the main process.
To access the resulting memory use table, use memoryUse(sim) after the simulation
has terminated. |
spades.messagingNumCharsModule | 21
| The number of characters to use for the messaging preamble on each line of the messaging during spades calls. |
spades.moduleCodeChecks
| list(suppressParamUnused = FALSE, suppressUndefined = TRUE, suppressPartialMatchArgs = FALSE, suppressNoLocalFun = TRUE, skipWith = TRUE)
| Should the various code checks be run
during simInit . These are passed to codetools::checkUsage() .
Default is given by the function, plus these: |
spades.moduleDocument | TRUE
| When a module is an R package e.g., via convertToPackage ,
it will, by default, rebuild documentation and reparse during simInit .
Since rebuilding documentation (from the roxygen2 tags) can be time consuming,
a user may wish to prevent this from happening each simInit call. If so,
set this option to FALSE |
spades.modulePath | file.path(tempdir(), "SpaDES", "modules") )
| The default local directory where modules and data will be downloaded and stored. Default is a temporary directory |
spades.moduleRepo | "PredictiveEcology/SpaDES-modules"
| The default GitHub repository to use when
downloading modules via downloadModule |
spades.nCompleted | 1000L | The maximum number of completed events to
retain in the completed event queue. |
spades.outputPath
| file.path(tempdir(), "SpaDES", "outputs")
| The default local directory in which to save simulation outputs. |
spades.plots
| The value of this will passed to .plots within every module; it will thus
override all module parameter values for .plots . This can, e.g., be used
to turn off all plotting.
| The default is NULL, meaning accept the module-level parameter |
spades.recoveryMode | 1L |
If this is a numeric greater than 0 or TRUE, then the
discrete event simulator will take a snapshot of the objects in the simList
that might change (based on metadata outputObjects for that module), prior to
initiating every event. This will allow the
user to be able to recover in case of an error or manual interruption (e.g., Esc ).
If this is numeric, a copy of that number of "most
recent events" will be maintained so that the user can recover and restart
more than one event in the past, i.e., redo some of the "completed" events.
Default is TRUE , i.e., it will keep the state of the simList
at the start of the current event. This can be recovered with restartSpades
and the differences can be seen in a hidden object in the stashed simList .
There is a message which describes how to find that. |
spades.saveFileExtensions | NULL |
a data.frame with 3 columns, exts , fun , and package indicating which
file extension, and which function from which package will be used when
using the outputs mechanism for saving files during a spades call. e.g.,
options(spades.saveFileExtensions = data.frame(exts = "shp", fun = "st_write", package = "sf") .
Then specify e.g.,
simInit(outputs = data.frame(objectName = "caribou", fun = "st_write", package = "sf"))
|
spades.scratchPath | file.path(tempdir(), "SpaDES", "scratch") )
| The default local directory where transient files from modules and data will written.
This includes temporary raster and terra files, as well as SpaDES recovery mode files.
Default is a temporary directory. |
spades.sessionInfo | TRUE )
| Assigns the utils::sessionInfo() to the simList during simInit with
the name sim$._sessionInfo . This takes about 75 milliseconds, which may be
undesirable for some situations where speed is critical. If FALSE , then
this is not assigned to the simList . |
spades.switchPkgNamespaces | FALSE to keep computational
overhead down. | Should the search path be modified
to ensure a module's required packages are listed first?
If TRUE , there should be no name conflicts among package objects,
but it is much slower, especially if the events are themselves fast. |
spades.testMemoryLeaks | TRUE .
| There is a very easy way to create a memory leak with R and SpaDES,
by adding formulas or functions to sim$ when the enclosing environment
of the formula or function contained a large object, most relevant here is
the sim object. SpaDES.core now tests for likely culprits for this
and suggests alternatives with a warning |
spades.tolerance | .Machine$double.eps^0.5 .
| The default tolerance value used for floating point number comparisons. |
spades.useragent | "https://github.com/PredictiveEcology/SpaDES" .
| : The default user agent to use for downloading modules from GitHub. |
spades.useRequire | !tolower(Sys.getenv("SPADES_USE_REQUIRE")) %in% "false"
| : The default for that environment variable is unset, so this returns
TRUE . If this is TRUE , then during the simInit call, when packages are
identified as being required, these will be installed if missing, only if
spades.useRequire option is TRUE , otherwise, simInit will fail because
packages are not available. |
Value
named list of the default package options.
Assess whether an object has or will be supplied from elsewhere
Description
When loading objects into a simList
, especially during the
simInit
call, and inside the .inputObjects
functions of modules,
it is often useful to know if an object in question will or has been
by the user via the inputs
or objects
arguments, or by another
module's .inputObjects
while preparing its expected inputs (via
expectsInputs
in metadata), or if it will be supplied by another
module during its "init"
event. In all these cases, it may not
be necessary for a given module to load any default value for its expectsInputs
.
This function can be used as a check to determine whether the module needs
to proceed in getting and assigning its default value.
Usage
suppliedElsewhere(
object,
sim,
where = c("sim", "user", "initEvent"),
returnWhere = FALSE
)
Arguments
object |
Character vector |
sim |
A |
where |
Character vector with one to three of |
returnWhere |
Logical, default |
Details
where
indicates which of three places to search, either "sim"
i.e.,
the simList
, which would be equivalent to is.null(sim\$objName)
, or
"user"
which would be supplied by the user in the simInit
function
call via outputs
or inputs
(equivalent to
(!('defaultColor' \%in\% sim$.userSuppliedObjNames))
),
or "initEvent"
, which would test whether a module that gets loaded before
the present one will create it as part of its outputs (i.e., as indicated by
createsOutputs
in that module's metadata). There is a caveat to this test,
however; if that other event also has the object as an expectsInput
, then
it would fail this test, as it also needs it as an input.
This final one ("initEvent"
) does not explicitly test that the object will be created
in the "init" event, only that it is in the outputs of that module, and that it is a module
that is loaded prior to this one.
Value
logical
Examples
mySim <- simInit()
suppliedElsewhere("test", mySim) # FALSE
# supplied in the simList
mySim$test <- 1
suppliedElsewhere("test", mySim) # TRUE
test <- 1
# supplied from user at simInit time -- note, this object would eventually get into the simList
# but the user supplied values come *after* the module's .inputObjects, so
# a basic is.null(sim$test) would return TRUE even though the user supplied test
mySim <- simInit(objects = list("test" = test))
suppliedElsewhere("test", mySim) # TRUE
# Example with prepInputs
# Put chunks like this in your .inputObjects
if (!suppliedElsewhere("test", mySim))
sim$test <- Cache(prepInputs, "raster.tif", "downloadedArchive.zip",
destinationPath = dataPath(sim), studyArea = sim$studyArea,
rasterToMatch = sim$otherRasterTemplate, overwrite = TRUE)
Time usage in SpaDES
Description
Functions for the simtimes
slot of a simList
object
and its elements. To maintain modularity, the behaviour of these functions depends
on where they are used. In other words, different modules can have their own
timeunit. SpaDES
converts these to seconds when running a simulation, but
shows the user time in the units of the model as shown with timeunit(sim)
Usage
times(x, ...)
## S4 method for signature 'simList'
times(x)
times(x) <- value
## S4 replacement method for signature 'simList'
times(x) <- value
## S3 method for class 'simList'
time(x, unit, ...)
time(x) <- value
## S4 replacement method for signature 'simList'
time(x) <- value
end(x, ...)
## S3 method for class 'simList'
end(x, unit, ...)
end(x) <- value
## S4 replacement method for signature 'simList'
end(x) <- value
start(x, ...)
## S3 method for class 'simList'
start(x, unit = NULL, ...)
start(x) <- value
## S4 replacement method for signature 'simList'
start(x) <- value
timeunit(x)
## S4 method for signature 'simList'
timeunit(x)
timeunit(x) <- value
## S4 replacement method for signature 'simList'
timeunit(x) <- value
timeunits(x)
## S4 method for signature 'simList'
timeunits(x)
elapsedTime(x, ...)
## S3 method for class 'simList'
elapsedTime(x, byEvent = TRUE, units = "auto", ...)
Arguments
x |
A |
... |
Additional parameters. |
value |
A time, given as a numeric, optionally with a unit attribute, but this will be deduced from the model time units or module time units (if used within a module). |
unit |
Character. One of the time units used in |
byEvent |
Logical. If |
units |
character string. Units in which the results are desired. Can be abbreviated. |
Details
timeunit
will extract the current units of the time used in a
simulation (i.e., within a spades
call).
If it is set within a simInit
, e.g.,
times=list(start=0, end=52, timeunit = "week")
, it will set the
units for that simulation.
By default, a simInit
call will use the smallest unit contained within
the metadata for the modules being used. If there are parent modules, then the
parent module timeunit will be used even if one of its children is a smaller timeunit.
If all modules, including parents, are set to NA
, timeunit
defaults to seconds.
If parents are set to NA
, then the set of modules defined by that parent module
will be given the smallest units of the children.
Currently, available units are "second", "hours", day", "week", "month", and "year" can be used in the metadata of a module.
The user can also define a new unit. The unit name can be anything, but the
function definition must be of the form dunitName
, e.g., dyear
or dfortnight
.
The unit name is the part without the d
and the function name definition
includes the d
. This new function, e.g.,
dfortnight <- function(x) lubridate::duration(dday(14))
can be placed anywhere in the search path or in a module.
timeunits
will extract the current units of the time of all
modules used in a simulation.
This is different from timeunit
because it is not necessarily
associated with a spades
call.
In many cases, the "simpler" use of each of these functions may be slower
computationally. For instance, it is much faster to use time(sim, "year")
than time(sim)
. So as a module developer, it is advantageous to
write out the longer one, minimizing the looking up that R must do.
Value
Returns or sets the value of the slot from the simList
object.
Note
These have default behaviour that is based on the calling frame timeunit. When used inside a module, then the time is in the units of the module. If used in an interactive mode, then the time will be in the units of the simulation.
Additional methods are provided to access the current, start, and end times of the simulation:
time | Current simulation time. |
start | Simulation start time. |
end | Simulation end time. |
timeunit | Simulation timeunit. |
timeunits | Module timeunits. |
times | List of all simulation times (current, start, end, timeunit). |
Author(s)
Alex Chubaty and Eliot McIntire
See Also
SpaDES.core-package, specifically the section 1.2.5 on Simulation times;
elapsedTime()
,
Other functions to access elements of a 'simList' object:
.addDepends()
,
checkpointFile()
,
envir()
,
events()
,
globals()
,
inputs()
,
modules()
,
objs()
,
packages()
,
params()
,
paths()
,
progressInterval()
Examples
# Elapsed Time
s1 <- simInit()
s2 <- spades(s1)
elapsedTime(s2)
elapsedTime(s2, units = "mins")
Update elements of a named list with elements of a second named list
Description
Defunct. Use utils::modifyList()
(which can not handle NULL) or
Require::modifyList2()
for case with >2 lists and can handle NULL lists.
Usage
updateList(x, y)
Arguments
x , y |
a named list |
Value
A named list, with elements sorted by name.
The values of matching elements in list y
replace the values in list x
.
Author(s)
Alex Chubaty
Use GitHub actions for automated module checking
Description
See corresponding vignette for more information.
Usage
use_gha(name, path)
Arguments
name |
module name |
path |
module path |
Value
Invoked for its side effect of creating new GitHub Actions workflow files.
Write simulation event info to file
Description
Useful for debugging.
Usage
writeEventInfo(sim, file = "events.txt", append = FALSE)
Arguments
sim |
A |
file |
Character specifying the file name (default ‘"events.txt"’). |
append |
Logical indicating whether to append to the file (default |
Value
Nothing returned. Invoked for its side effect of writing to file.
Author(s)
Alex Chubaty
Write RNG state info to file
Description
Useful for debugging and ensuring reproducibility.
Usage
writeRNGInfo(file = "seed.txt", append = FALSE)
Arguments
file |
Character specifying the filename (default |
append |
Logical indicating whether to append to the file (default |
Value
Nothing returned. Invoked for its side effect of writing to file.
Author(s)
Alex Chubaty
Create a zip archive of a module subdirectory
Description
The most common use of this would be from a "modules" directory, rather than inside a given module.
Usage
zipModule(name, path, version, data = FALSE, ...)
## S4 method for signature 'character,character,character'
zipModule(name, path, version, data = FALSE, ...)
## S4 method for signature 'character,missing,character'
zipModule(name, path, version, data = FALSE, ...)
## S4 method for signature 'character,missing,missing'
zipModule(name, path, version, data = FALSE, ...)
## S4 method for signature 'character,character,missing'
zipModule(name, path, version, data = FALSE, ...)
Arguments
name |
Character string giving the module name. |
path |
A file path to a directory containing the module subdirectory. |
version |
The module version. |
data |
Logical. If |
... |
Additional arguments to |
Value
NULL (invisibly). Invoked for its side effect of zipping module files.
Author(s)
Eliot McIntire and Alex Chubaty
Zip a simList
and various files
Description
zipSimList
will save the simList
and file-backed Raster*
objects, plus,
optionally, files identified in outputs(sim)
and inputs(sim)
.
This uses Copy
under the hood, to not affect the original simList
.
These functions have been moved to other packages.
Usage
zipSimList(sim, zipfile, ..., outputs = TRUE, inputs = TRUE, cache = FALSE)
experiment(...)
experiment2(...)
POM(...)
simInitAndExperiment(...)
loadPackages(...)
Arguments
sim |
Either a |
zipfile |
A character string indicating the filename for the zip file. Passed to |
... |
Unused. |
outputs |
Logical. If |
inputs |
Logical. If |
cache |
Logical. Not yet implemented. If |