Converting R code to a `SpaDES` module - seed establishment
Alex M Chubaty & Eliot McIntire
December 7, 2016
knitr::opts_chunk$set(cache = TRUE, echo = TRUE, eval = FALSE)
Converting R code to SpaDES module
An "establishment" model
We can imagine a set of sources (e.g., trees with seeds) and a map of "quality" which will affect whether the things (e.g., seeds) will land and establish.
This code does a few things:
- Load libraries that are required.
- Defines some parameters that will be used .
- Creates 2 default maps... could be loading default initial maps from files instead, if we had these.
- "Source" locations.
- A "quality" map.
- Determines "distance" from source map.
- Multiplies the "distance from source" by the quality to determine whether there is successful establishment.
- Plot it all.
# Load some libraries library(raster) library(SpaDES) set.seed(321) # so we can compare amongst ourselves # Parameters Nsource <- 20 establishThresh <- 0.1 # Initial Map of Quality -- make a dummy one quality <- raster(extent(0, 100, 0, 100), res = c(1, 1)) %>% gaussMap(speedup = 1) # SpaDES function to generate a random map quality <- scale(quality, center = maxValue(quality), # rescales from 0 to 1 scale = minValue(quality) - maxValue(quality)) # Initial Map of sources (e.g., seed trees maybe) sourceLocations = initiateAgents(quality, Nsource) # SpaDES function # Create a distance from source map distFromSource <- distanceFromPoints(quality, sourceLocations) # raster function # Create establishment map, a function of inverse distance and quality, # Actual establishment is determined with a threshold parameter establish <- (1/distFromSource * quality) > establishThresh clearPlot() Plot(distFromSource, title = "Distance from source") Plot(establish, title = "Establishment successful") Plot(sourceLocations, addTo = "establish", title = "Establishment successful")
Convert this to a SpaDES module
newModule()to create a blank template.
- Open the
.Rfile that shows up.
- Fill in metadata:
- Indicate libraries that are needed
- Indicate parameters, with defaults
- Indicate object(s) that is/are expected as an input, and object(s) that is/are created as output(s)
- Fill in
.inputObjectssection to create the needed inputs.
- Put all the code that creates the
establishin the "init" event.
- Put Plot stuff in
Build a controller for this module.
- Open the
.Rmdfile that we will use.
- Run one line at a time, confirming that it will run your model. You will likely need to update the module path so it knows where to find the module on your computer.
Advanced -- Add time
So far, this only calculates the "establish" map once.
What if we had another module that updates "sourceLocation" every year.
So, we have to run
establish every year.
There are 2 options for this: add it all in this module, or make a new module that would generate the sourceLocations.
Option 1 - just build "sourceLocations" into this module
Move the 3 lines that make new
sourceLocation, make new
distFromSource, and make
establishinto an event called "annualEstablishment". You can delete it from the "init" event, or keep it there
within the "init" block, scheduling the "annualEstablishment" event in this ("establishment") module. We can schedule it for "the beginning", which would be start(sim).
within the "annualEstablishment" block that will schedule the "plot" event, "now". That way, it will plot immediately after this event.
within the "annualEstablishment" block, scheduling the "annualEstablishment" event in this ("establishment") module. We can schedule it for "now" + 1, which would be
time(sim) + 1. This creates the time sequence.
Option 2 - make a simple module called "sourceLocations"
This is "better" because it emulates how the normal situation would be, but it takes a few more steps. But, as we get more agile with modules, this step would take 3 minutes. Basically all the steps are the same as above, but in a different module, rather than within this module.
This solution follows Option 1.