The hardware and bandwidth for this mirror is donated by dogado GmbH, the Webhosting and Full Service-Cloud Provider. Check out our Wordpress Tutorial.
If you wish to report a bug, or if you are interested in having us mirror your free-software or open-source project, please feel free to contact us at mirror[@]dogado.de.
SpaDES useSpaDES useThis vignette covers tools that become useful once you are building
or maintaining a substantial SpaDES workflow: monitoring
memory use across events, and statically checking that a module’s code
agrees with its declared metadata.
profvis::profvis is great for digging into R internals,
but it doesn’t fit the discrete-event pattern very well. Often the
question is simpler: which event uses the most memory, and how much?
That number sets how many parallel runs you can fit on a machine.
SpaDES.core ships a small background sampler. Turn it on
by setting the option spades.memoryUseInterval to a
sampling interval in seconds (e.g., 0.2). If
future and future.callr are installed, each
spades() call will then:
future (parallel) R session that runs
system('ps') once per interval, keeping only the row for
the main R process;spades() returns, read the file into
sim@.xData$.memoryUse$obj and delete the file;if (requireNamespace("future", quietly = TRUE) &&
requireNamespace("future.callr", quietly = TRUE)) {
options(spades.memoryUseInterval = 0.5)
# sim <- simInit(...)
# sim <- spades(sim)
memoryUse(sim, max = TRUE) # peak memory by event type (summarised across times)
memoryUse(sim, max = FALSE) # peak memory for every individual event
}[memoryUseThisSession()] returns the memory currently used by the running R session; useful as a quick sanity check between events.
simInit() parses your module’s source and statically
checks that the code agrees with the metadata: every read of
sim$x should have x listed in
expectsInput() or createsOutput(), every
parameter access (Par$y, P(sim)$y,
params(sim)$mod$y) should match a
defineParameter() entry, every doEvent.*
function should return sim, and so on. Mismatches are
reported as a structured table with file/line/column locations.
The checks are controlled by two options:
options(spades.moduleCodeChecks = TRUE) # turn checking on/off
options(spades.codeCheckEngine = "v2") # "v1" (legacy) or "v2" (new, structured)You can also run the checks on a module on disk, without going
through simInit(). This is handy while authoring or
refactoring a module:
# returns a data.frame of findings; also prints a grouped report
findings <- codeCheckModule("path/to/myModule")
# subset by severity or rule id
findings[findings$severity == "warning", ]
findings[findings$id == "param_used_undeclared", ]A finding has columns id, severity,
module, where, name,
fn, file, line, col,
message, suggestion. The suggestion is a
plain-language fix (e.g., “add
defineParameter('coverThresh', ...) to parameters”). When
simInit() runs the checks, the same data.frame is stashed
at sim@.xData$.codeCheck[[moduleName]].
Typical findings the checker flags:
| id | what it catches |
|---|---|
out_declared_unused |
output declared in metadata, never assigned in code |
out_used_undeclared |
sim$x <- ... for x not in
createsOutput() |
in_declared_unused |
input declared, never read |
in_used_undeclared |
sim$x read for x not in
expectsInput() |
param_declared_unused |
defineParameter("x", ...) but no Par$x in
the code |
param_used_undeclared |
Par$x / P(sim)$x for x not
declared |
unresolved_accessor |
sim[[expr]] or get(var, envir=envir(sim))
— can’t be checked statically |
must_return_sim |
doEvent.* not ending with
return(invisible(sim)) |
must_assign_to_sim |
scheduleEvent(...) or saveFiles(...) not
assigned back to sim |
module_named_object |
sim$<moduleName> <- ... (forbidden) |
conflicting_fn_unqualified |
bare levels/scale/which.max
(ambiguous with raster::) |
See [codeCheckModule()] for details.
These binaries (installable software) and packages are in development.
They may not be fully stable and should be used with caution. We make no claims about them.
Health stats visible at Monitor.