Overview
This documentation is work in progress. Potential discrepancies and omissions may exist for the time being. If you find any, contact us here.
spadesCBM is a modular, transparent, and spatially explicit implementation of the logic, pools structure, equations, and default assumptions of the Carbon Budget Model of the Canadian Forest Sector (CBM). It applies the science presented in Kurz et al. (2009) in a similar way to the simulations in Boisvenue et al. (2016) and Boisvenue et al. (2022) but calls Python functions for annual processes (see libcbm_py/examples/cbm_exn). These functions and spadesCBM are, like much of modelling-based science, continuously under development.
The collection of SpaDES modules in spadesCBM was developed to enable R&D input to the Canadian Forest Service (CFS) forest carbon reporting system, NFCMARS, the National Forest Carbon Monitoring, Accounting, and Reporting system. The CFS provides science backing for Canadian policies on national forest issues. spadesCBM is a nimble tool in which new science, data and algorithms can be tested and explored to serve policy purposes. spadesCBM development follows the PERFICT approach of McIntire et al. (2022) for ecological modelling systems, an approach that helps solve many of the complex issues in ecological modelling, supports continuous workflows, and nimble, enter operable modelling systems. The SpaDES platform is the toolkit that enables this implementation of the PERFICT principle.
Usage
Four modules need to be run in tandem for a spadesCBM simulation. The first module, CBM_defaults, reads in defaults CBM parameters for Canada. The second module, CBM_dataPrep_SK, is a data preparation SpaDES module, where input data and spatial layers are assembled and prepared for a specific study area. The CBM_dataPrep_SK module will be study-area and scenario specific. Throughout this manual we use an example simulation of forest carbon dynamics for the managed forests of Saskatchewan (SK) from 1985-2012 similarly to the simulations in Boisvenue et al. (2016), where the SK indicates the study area. In spadesCBM, as in CBM, growth curves (\(m^3/ha\)) are the main change-agent. The CBM_vol2biomass module translates user-provided stand-level growth curves (\(m^3/ha\)) into increments for specific above ground carbon pools (metric tonnes of carbon/ha) using Boudewyn et al. (2007) models (leading species specific) to which we added a smoothing algorithm to fill-in the gap between age 0 and the age at which growth curves have data. Note that CBM_vol2biomass is also study-area specific, as Boudewyn et al. (2007) parameters are dominant species and ecozone specific.
CBM_defaults, and CBM_vol2biomass have one event (init
), and need to be run only once (note that they will be cached in our example).CBM_dataPrep_SK processes most of the data in its init
event, but also has a second event where the annual disturbances are processed (readDisturbanceEvents
). This second event enables dynamic linkages to disturbance models.
These three modules provide the inputs to the CBM_core module, where carbon-transfers between pools are applied on a specified time step (in our example, yearly).
This modularity enables users to access and change default parameters, change inputs, connect dynamically to external modules that modify the landscape, and assess the impact of these changes.
We are working on various implementations of this modelling system and making these available to the community in the Preditive Ecology GitHub repository.
We hope others will do the same.
A smaller study area extent simulation of spadesCBM is available in the SpaDES training manual.
insert a moduleDiagram
Several core utilities to spadesCBM are provided by the CBMutils
package, available on GitHub. The SpaDES platform has a much broader scope then our use of it in spadesCBM. We provide some basic SpaDES definitions here so that users can perform spadesCBM simulations without having to learn all the SpaDES capacities. CBMutils
functions used in our example are listed with a brief explanation in this subsequent section. Active development in CBMutils
and all spadesCBM modules is underway.
The Carbon Budget Model in SpaDES
The Carbon Budget Model (CBM) was first developed in the early 1990s (Kurz et al. (1993)). Its implementation in a platform for model inter-operability and nimbleness such as SpaDES warrants an overview.
spadesCBM simulates forest carbon dynamics for a given study area based on Canadian-parameterization and user-provided growth and inventory information. Default Canadian parameters are read-in (CBM_defaults), matched to the user-provided information (CBM_dataPrep_SK and CBM_vol2biomass), and this information drives the carbon-transfers through the simulations (CBM_core).
Input requirements
spadesCBM simulations require study area information, age, and leading species of each stand or pixel to simulate on the landscape, and growth information for each stand or pixel. Users can provide this information in various format which is processed in CBM_dataPrep_SK and in CBM_vol2biomass. We suggest users modify the example provided to represent their study area and inventory information. Each module has a chapter in which module inputs and outputs are listed.
Pools
There are 18 internal carbon pools in spadesCBM, representing a stand or pixel (Table 1), and two pools that take carbon out of the system, Products and the Atmosphere. The carbon transfers are dictated by matrices (available in the defaults information) which specify the proportion of carbon moving from one pool (source_pool to another (sink_pools). Matrices for growth are populated with the user-provided growth information and are the main change agent in the system, providing carbon input to the stand. Default parameters for biomass and dead organic mater (DOM) turnover, decay, and soil mixing are either at the provincial/territorial, ecozone, or Canada-wide scale (see Table 1 in Kurz et al. (2009)). Note that parameters can easily be modified from their defaults in a spadesCBM simulation. Disturbances matrices representing carbon-transfers during disturbances like fire or harvesting, are available in the defaults (read-in via CBM_defaults) for all managed forests of Canada. Figure XX gives an example of transfers during a fire in SK. INSERT VINI’S DIST MATRIX TRANSFER FIGURE
Table 1: Carbon pools in spadesCBM
Pool | Description |
---|---|
Merch | Live stemwood of merchantable size |
Foliage | Live foliage |
Other | Live branches, stumps, and small trees |
CoarseRoots | Live roots ≥5 mm diameter |
FineRoots | Live roots <5 mm diameter |
AboveGroundVeryFastSoil | The L horizon comprised of foliar litter plus dead fine roots <5 mm diameter |
BelowGroundVeryFastSoil | Dead fine roots in the mineral soil <5 mm diameter |
AboveGroundFastSoil | Fine and small woody debris plus dead coarse roots in the forest floor ≥5 and <75 mm diameter |
BelowGroundFastSoil | Dead coarse roots in the mineral soil ≥5 diameter |
MediumSoil | Coarse woody debris on the ground |
AboveGroundSlowSoil | F, H, and O horizons |
BelowGroundSlowSoil | Humified organic matter in the mineral soil |
StemSnag | Dead standing stemwood of merchantable size including bark |
BranchSnag | Dead branches, stumps, and small trees including bark |
CO2 | CO2 emitted to atmosphere |
CH4 | CH4 emitted to atmosphere |
CO | CO emitted to atmosphere |
NO2 | NO2 emitted to atmosphere |
Order of operations
In simulations, disturbances occur before any other carbon-transfer. After the disturbances, half of the growth (determined by increments in the user-provided growth curve) is applied followed by the transfers representing DOM turnover, live biomass turnover, an overmature decline compensation if applicable, the 2nd half of the growth, DOM decay, slow decay and slow soil mixing. AS previously stated, carbon additions to the system come from the atmosphere (amount determined by growth via user-provided growth curves), and carbon exists the system to the atmosphere or to the forest products sector (ADD A FIGURE HERE MODIFICATION OF CBM_slide.ppt). Transfers are proportions of a source pool to sink pools and proportions add up to 1, so no carbon is lost.
MAKE A TABLE OF THESE disturbance half growth domturnover bioturnover overmaturedecline 2nd half of the growth domdecay slowdecay slowmixing
The spinup
function
The amount of carbon below ground in forests is extremely variable and consequently there are few data that can provide this information at scales greater then plot levels. To compensate for this gap in knowledge and data, prior to a simulation, CBM_core completes a process that populates below ground pools. This process is called a spinup and it is the first event in the CBM_core module. The procedure consists of growing and burning forest stand, according to the provided growth curves and default values for fire return intervals (provided in CBM_defaults) until the below ground carbon pool stabilize or reach a predefined number of simulations. The choice of a fire disturbance matches the historical forest disturbance for most forests in Canada. We consider this procedure a place holder until our knowledge of below ground carbon dynamics improves. Although it will likely be resulting in errors in absolute carbon stocks (see Boisvenue et al. (2022) Appendix 4), these should be systematic errors and we can at least simulate the trends in carbon stocks and fluxes. Research has compared below ground stocks values (Shaw (2008)) and work continues to improve parameters (Hararuk (2017) ?).
Setup
In this example, we setup the workflow using the
SpaDES.project
package and
current versions of the spadesCBM modules.
0.1 Google account needed for this example
To run the provided example, users need to access some of the data using the googledrive R package (part of the tidyverse family of R packages). During the simInit() (or simInitAndSpades) call, a function to initialize (or initialize and run) SpaDES-based simulations, R will prompt you to either choose a previously authenticated account (if you have previously used googledrive) or to open a browser window and authenticate.
Make sure you give tidyverse read/write access to your files:

0.2 Python is required for this example
The CBM_core module, which is the simulation module of spadesCBM, requires Python >=3.9 and <=3.12.7.
If a suitable version of Python does not already exist on your computer,
SpaDES.project::setupProject will use the reticulate
package to install it using the pyenv or pyenv-win.
If you are using a Windows computer with Git installed, the pyenv-win tool will be acquired and managed directly by reticulate
. If you are using a Windows computer without Git installed, you will be prompted to allow the pyenv-win tool to be downloaded directly from Github to your local user application data directory (tools::R_user_dir("r-spadesCBM")
).
If the Python installation process fails or you would prefer to manually install Python, it can be downloaded directly from python.org/downloads. The calls to Python are for functions from a package called libcbm. Python functions are only used in the CBM_core module. Details on CBM_core module and the Python functions are provided in CBM_core chapter in this manual.
Run Example Simulation
Here is the R script to run the simulation of forest carbon dynamics in the managed forests of SK from 1985 to 2012, with disturbances as presented in Boisvenue et al. (2016). Depending on your computing capacity, this may take a while, particularly the first time you run it. Subsequent simulations are much faster because of the use of the reproducible::Cache function.
# set project paths and install packages
projectPath <- "~/GitHub/spadesCBM"
repos <- unique(c("predictiveecology.r-universe.dev", getOption("repos")))
install.packages("SpaDES.project",
repos = repos)
# Set simulation period.In this example we start in 1985, and end in 2011
times <- list(start = 1985, end = 2011)
# This is our setupProject call. This creates the model's folder structure, downloads modules, installs and loads needed packages, and sets options.
out <- SpaDES.project::setupProject(
Restart = TRUE,
useGit = "PredictiveEcology", # a developer sets and keeps this = TRUE
overwrite = TRUE, # a user who wants to get latest modules sets this to TRUE
paths = list(projectPath = projectPath),
options = options(
repos = c(repos = repos),
Require.cloneFrom = Sys.getenv("R_LIBS_USER"),
reproducible.destinationPath = "inputs",
## These are for speed
reproducible.useMemoise = TRUE,
# Require.offlineMode = TRUE,
spades.moduleCodeChecks = FALSE
),
modules = c("PredictiveEcology/CBM_defaults@development",
"PredictiveEcology/CBM_dataPrep_SK@development",
"PredictiveEcology/CBM_vol2biomass@development",
"PredictiveEcology/CBM_core@development"),
times = times,
require = c("SpaDES.core", "reticulate",
"PredictiveEcology/libcbmr", "data.table"),
params = list(
CBM_defaults = list(
.useCache = TRUE
),
CBM_dataPrep_SK = list(
.useCache = TRUE
),
CBM_vol2biomass = list(
.useCache = TRUE
)
),
functions = "PredictiveEcology/CBM_core@training/R/ReticulateFindPython.R",
ret = {
reticulate::virtualenv_create(
"r-spadesCBM",
python = if (!reticulate::virtualenv_exists("r-spadesCBM")){
ReticulateFindPython(
version = ">=3.9,<=3.12.7",
versionInstall = "3.10:latest",
pyenvRoot = tools::R_user_dir("r-spadesCBM")
)
},
packages = c(
"numpy<2",
"pandas>=1.1.5",
"scipy",
"numexpr>=2.8.7",
"numba",
"pyyaml",
"mock",
"openpyxl",
"libcbm"
)
)
reticulate::use_virtualenv("r-spadesCBM")
},
#### begin manually passed inputs #########################################
## define the study area.
masterRaster = {
mr <- reproducible::prepInputs(url = "https://drive.google.com/file/d/1zUyFH8k6Ef4c_GiWMInKbwAl6m6gvLJW/view?usp=drive_link",
destinationPath = "inputs")
mr[mr[] == 0] <- NA
mr
},
disturbanceRastersURL = "https://drive.google.com/file/d/12YnuQYytjcBej0_kdodLchPg7z9LygCt",
outputs = as.data.frame(expand.grid(objectName = c("cbmPools", "NPP"),
saveTime = sort(c(times$start,
times$start +
c(1:(times$end - times$start))
)))),
)
# Run simulation
simMngedSK <- SpaDES.core::simInitAndSpades2(out)