From 56091339d687359eb9c499c1c5e48962a6090b35 Mon Sep 17 00:00:00 2001 From: Eliot McIntire Date: Wed, 2 Mar 2022 11:29:41 -0800 Subject: [PATCH 001/148] allow sppNameVector --- Biomass_core.R | 64 ++++++++++++++++++++++++-------------------------- 1 file changed, 31 insertions(+), 33 deletions(-) diff --git a/Biomass_core.R b/Biomass_core.R index b77b6c4..a52a76c 100644 --- a/Biomass_core.R +++ b/Biomass_core.R @@ -2053,46 +2053,44 @@ CohortAgeReclassification <- function(sim) { sim$sufficientLight <- data.frame(sufficientLight, stringsAsFactors = FALSE) } - if (!suppliedElsewhere("sppEquiv", sim)) { - if (!is.null(sim$sppColorVect)) - stop("If you provide sppColorVect, you MUST also provide sppEquiv") - + if (is.null(sim$sppEquiv)) { data("sppEquivalencies_CA", package = "LandR", envir = environment()) sim$sppEquiv <- as.data.table(sppEquivalencies_CA) - ## By default, Abies_las is renamed to Abies_sp - sim$sppEquiv[KNN == "Abie_Las", LandR := "Abie_sp"] - - ## check spp column to use - if (P(sim)$sppEquivCol == "Boreal") { - message(paste("There is no 'sppEquiv' table supplied;", - "will attempt to use species listed under 'Boreal'", - "in the 'LandR::sppEquivalencies_CA' table")) - } else { - if (grepl(P(sim)$sppEquivCol, names(sim$sppEquiv))) { - message(paste("There is no 'sppEquiv' table supplied,", - "will attempt to use species listed under", P(sim)$sppEquivCol, - "in the 'LandR::sppEquivalencies_CA' table")) - } else { - stop("You changed 'sppEquivCol' without providing 'sppEquiv',", - "and the column name can't be found in the default table ('LandR::sppEquivalencies_CA').", - "Please provide conforming 'sppEquivCol', 'sppEquiv' and 'sppColorVect'") - } - } + } + if (!is.null(sim$sppNameVector)) { + if (!exists("sppEquivalencies_CA", inherits = FALSE)) + message("Both sppEquiv and sppNameVector are supplied; subsetting sppEquiv with species in sppNameVector") + speciesNameConvention <- LandR::equivalentNameColumn(sim$sppNameVector, LandR::sppEquivalencies_CA) + sim$sppEquiv <- sim$sppEquiv[sim$sppEquiv[[speciesNameConvention]] %in% sim$sppNameVector,] + } - ## remove empty lines/NAs - sim$sppEquiv <- sim$sppEquiv[!"", on = P(sim)$sppEquivCol] - sim$sppEquiv <- na.omit(sim$sppEquiv, P(sim)$sppEquivCol) + ## By default, Abies_las is renamed to Abies_sp + sim$sppEquiv[KNN == "Abie_Las", LandR := "Abie_sp"] # TODO: This should be removed as a hard coded thing + ## check spp column to use + # if (P(sim)$sppEquivCol == "Boreal") { + # message(paste("There is no 'sppEquiv' table supplied;", + # "will attempt to use species listed under 'Boreal'", + # "in the 'LandR::sppEquivalencies_CA' table")) + # } else { + if (any(grepl(P(sim)$sppEquivCol, names(sim$sppEquiv)))) { + message(paste("Using species listed under", P(sim)$sppEquivCol, + "column in the 'sim$sppEquiv' table")) + } else { + stop("'P(sim)$sppEquivCol' is not a column in 'sim$sppEquiv'.", + "Please provide conforming 'sppEquivCol', 'sppEquiv' and 'sppColorVect'") + } + #} + + ## remove empty lines/NAs + sim$sppEquiv <- sim$sppEquiv[!"", on = P(sim)$sppEquivCol] + sim$sppEquiv <- na.omit(sim$sppEquiv, P(sim)$sppEquivCol) + + if (is.null(sim$sppColorVect)) { ## add default colors for species used in model sim$sppColorVect <- sppColors(sim$sppEquiv, P(sim)$sppEquivCol, newVals = "Mixed", palette = "Accent") - } else { - if (is.null(sim$sppColorVect)) { - message("'sppEquiv' is provided without a 'sppColorVect'. Running: - LandR::sppColors with column ", P(sim)$sppEquivCol) - sim$sppColorVect <- sppColors(sim$sppEquiv, P(sim)$sppEquivCol, - newVals = "Mixed", palette = "Accent") - } + message("No 'sppColorVect' provided; using default colour palette: Accent") } if (P(sim)$vegLeadingProportion > 0 & is.na(sim$sppColorVect['Mixed'])) { From 746a6b6da900c439f0fcec1c2e0609a036d7bbe4 Mon Sep 17 00:00:00 2001 From: Eliot McIntire Date: Sat, 12 Mar 2022 21:08:20 -0800 Subject: [PATCH 002/148] bugfix when cohortDefinitionCols has B (e.g., partial mortality) --- Biomass_core.R | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Biomass_core.R b/Biomass_core.R index ffa30d1..4b9c637 100644 --- a/Biomass_core.R +++ b/Biomass_core.R @@ -925,7 +925,7 @@ Init <- function(sim, verbose = getOption("LandR.verbose", TRUE)) { simulatedBiomassMap <- rasterizeReduced(pixelAll, pixelGroupMap, "uniqueSumB") } - colsToKeep <- c(P(sim)$cohortDefinitionCols, "ecoregionGroup", "B") + colsToKeep <- unique(c(P(sim)$cohortDefinitionCols, "ecoregionGroup", "B")) sim$cohortData <- cohortData[, .SD, .SDcol = colsToKeep] sim$cohortData[, c("mortality", "aNPPAct") := 0L] # sim$cohortData <- cohortData[, .(pixelGroup, ecoregionGroup, speciesCode, age, B, mortality = 0L, aNPPAct = 0L)] From 3477d238dc2f436fb84d2b2f9a3c1ec2cf6b9773 Mon Sep 17 00:00:00 2001 From: CeresBarros Date: Tue, 29 Mar 2022 10:54:06 -0700 Subject: [PATCH 003/148] minor improvement to example setup --- Biomass_core.Rmd | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/Biomass_core.Rmd b/Biomass_core.Rmd index 8fa9ce2..df93866 100644 --- a/Biomass_core.Rmd +++ b/Biomass_core.Rmd @@ -391,11 +391,9 @@ Require(c("PredictiveEcology/SpaDES.install", install_githubArgs = list(dependencies = TRUE))# In general, a module code will be controlled at one level above the source code tempDir <- tempdir() -spadesModulesDirectory <- file.path(tempDir, "modules") - paths <- list(inputPath = normPath(file.path(tempDir, "inputs")), cachePath = normPath(file.path(tempDir, "cache")), - modulePath = normPath(spadesModulesDirectory), + modulePath = normPath(file.path(tempDir, "modules")), outputPath = normPath(file.path(tempDir, "outputs"))) ``` @@ -403,14 +401,14 @@ paths <- list(inputPath = normPath(file.path(tempDir, "inputs")), We can use the `SpaDES.install::getModule` function to download the module to the module folder specified above. Alternatively, see [SpaDES-modules repository](https://github.com/PredictiveEcology/SpaDES-modules) to see how to download this and other `SpaDES` modules, or fork/clone from its [GitHub repository](https://github.com/PredictiveEcology/Biomass_core/) directly. -After downloading the module, it is important to make sure all module R package dependencies are installed in their correct version. `SpaDES.install::makeSureAllPackagesInstalled` takes care of this for this and any other module in the `spadesModulesDirectory`. +After downloading the module, it is important to make sure all module R package dependencies are installed in their correct version. `SpaDES.install::makeSureAllPackagesInstalled` takes care of this for this and any other module in the `paths$modulePath`. ```{r getModule-Biomass-core, eval=FALSE} SpaDES.install::getModule("PredictiveEcology/Biomass_core", - modulePath = spadesModulesDirectory, overwrite = TRUE) + modulePath = paths$modulePath, overwrite = TRUE) ## make sure all necessary packages are installed: -SpaDES.install::makeSureAllPackagesInstalled(spadesModulesDirectory) +SpaDES.install::makeSureAllPackagesInstalled(paths$modulePath) ``` From 94a25abcde0577a0d466c078ef494b12c68f680c Mon Sep 17 00:00:00 2001 From: CeresBarros Date: Tue, 29 Mar 2022 10:54:21 -0700 Subject: [PATCH 004/148] spell out LBSE in header --- Biomass_core.Rmd | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Biomass_core.Rmd b/Biomass_core.Rmd index df93866..b258be0 100644 --- a/Biomass_core.Rmd +++ b/Biomass_core.Rmd @@ -151,7 +151,7 @@ Intended to be used with other landscape modules, such as *LandMine*, *fireSense LandR *Biomass_core* (hereafter *Biomass_core*) a forest landscape model based on the LANDIS-II Biomass Succession Extension v.3.2.1 model [LBSE; @SchellerMiranda2015]. It is the core forest succession model of the LandR ecosystem of `SpaDES` modules. Similarly to the LBSE, *Biomass_core* simulates changes in tree cohort aboveground biomass (g/m^2^.) by calculating growth, mortality and recruitment as functions of pixel and species characteristics, competition and disturbances (Fig. \@ref(fig:fig-Biomass-core)). Specifically, growth is driven by both invariant (`growthcurve`) and spatially varying species growth traits (maximum biomass, `maxB`, and maximum annual net primary productivity, `maxANPP`), while mortality depends only on invariant species traits (`age`, `longevity` and `mortalityshape`). Disturbances (e.g., fire) can also cause cohort mortality, but are simulated in separate modules (e.g., *Biomass_regeneration* simulates the death of all cohorts immediately after a fire). The parameters `growthcurve` and `mortalityshape` directly influence the shape of species growth curves, by determining how fast they grow and how soon age mortality starts with respect to longevity. Cohort recruitment is determined by available "space" (*i.e.*, pixel shade), invariant species traits (regeneration mode, age at maturity, shade tolerance) and spatially varying traits (species establishment probability, `SEP`). The available "growing space" is calculated as species `maxB` minus the occupied biomass (summed across other cohorts and species). If there is "space", a cohort can establish from one of three recruitment modes: serotiny, resprouting and germinating. Serotiny and resprouting occur only in response to fire and are simulated in two separate, but interchangeable modules, *Biomass_regeneration* and *Biomass_regenerationPM*. Germination occurs if seeds are made available from local sources (the pixel), or via seed dispersal. Seed dispersal can be of three modes: 'no dispersal', 'universal dispersal' (only interesting for dummy case studies) or 'ward dispersal' [@SchellerMiranda2015]. The 'ward dispersal' algorithm describes a flexible kernel that calculates the probability of a species colonising a neighbour pixel as a function of distance from the source and dispersal-related (and invariant) species traits, and is used by default. We refer the reader to @SchellerMiranda2015, @SchellerDomingo2011 and @SchellerDomingo2012 for further details with respect to the mechanisms implemented in the module. -### Differences between *Biomass_core* and LBSE +### Differences between *Biomass_core* and the LANDIS-II Biomass Succession Extension (LBSE) #### Algorithm changes From f107a03ed8702d0b9f8de55f125e032ae2474f07 Mon Sep 17 00:00:00 2001 From: CeresBarros Date: Tue, 29 Mar 2022 13:05:38 -0700 Subject: [PATCH 005/148] rm dot from `P(sim)$initialB` & check value across modules --- Biomass_core.R | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/Biomass_core.R b/Biomass_core.R index 8d54a19..5f3a5ce 100644 --- a/Biomass_core.R +++ b/Biomass_core.R @@ -44,6 +44,10 @@ defineModule(sim, list( "This parameter should only be modified if additional modules are adding columns to cohortData")), defineParameter("cutpoint", "numeric", 1e10, NA, NA, desc = "A numeric scalar indicating how large each chunk of an internal data.table is, when processing by chunks"), + defineParameter("initialB", "numeric", 10, 1, NA, + desc = paste("initial biomass values of new age-1 cohorts.", + "If `NA` or `NULL`, initial biomass will be calculated as in LANDIS-II Biomass Suc. Extension", + "(see Scheller and Miranda, 2015 or `?LandR::.initiateNewCohorts`)")), defineParameter("gmcsGrowthLimits", "numeric", c(1/1.5 * 100, 1.5/1 * 100), NA, NA, paste("if using `LandR.CS` for climate-sensitive growth and mortality, a percentile", " is used to estimate the effect of climate on growth/mortality ", @@ -66,7 +70,6 @@ defineModule(sim, list( "(see `LandR.CS` for climate sensitivity equivalent functions, or leave default if this is not desired)")), defineParameter("growthInitialTime", "numeric", start(sim), NA_real_, NA_real_, desc = "Initial time for the growth event to occur"), - defineParameter("initialB", "numeric", 10, 1, NA, desc = "initial biomass values of new age-1 cohorts"), defineParameter("initialBiomassSource", "character", "cohortData", NA, NA, paste("Currently, there are three options: 'spinUp', 'cohortData', 'biomassMap'. ", "If 'spinUp', it will derive biomass by running spinup derived from Landis-II.", @@ -542,6 +545,9 @@ Init <- function(sim, verbose = getOption("LandR.verbose", TRUE)) { "Only trees that are older than successionTimestep are included in the ", "calculation of sumB, i.e., trees younger than this do not contribute ", "to competitive interactions") + + paramCheckOtherMods(sim, "initialB", ifSetButDifferent = "warning") + ############################################## ## Prepare individual objects ############################################## From 599d9a2095d8fed57c5c700620da089f93d4d431 Mon Sep 17 00:00:00 2001 From: CeresBarros Date: Wed, 6 Apr 2022 16:09:31 -0700 Subject: [PATCH 006/148] knitr cache is only logical now --- Biomass_core.Rmd | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Biomass_core.Rmd b/Biomass_core.Rmd index b258be0..0aa0bbc 100644 --- a/Biomass_core.Rmd +++ b/Biomass_core.Rmd @@ -28,7 +28,7 @@ always_allow_html: true ```{r setup-Biomass-core, include=FALSE} ## set cache.rebuild = TRUE whenever there are changes to the module code/metadata knitr::opts_chunk$set(echo = TRUE, eval = FALSE, warning = FALSE, - cache = 2, cache.rebuild = FALSE, results = "hold", dpi = 300) + cache = TRUE, cache.rebuild = FALSE, results = "hold", dpi = 300) ## get citation style if (!file.exists("citations/ecology-letters.csl")) { From 28610399eb5bf7d1bf6836b2d07f919913220ec5 Mon Sep 17 00:00:00 2001 From: CeresBarros Date: Wed, 6 Apr 2022 20:26:00 -0700 Subject: [PATCH 007/148] change pipe table to list --- Biomass_core.Rmd | 261 ++++++++++++++++++++++++++++++++--------------- 1 file changed, 177 insertions(+), 84 deletions(-) diff --git a/Biomass_core.Rmd b/Biomass_core.Rmd index 0aa0bbc..75ba6cd 100644 --- a/Biomass_core.Rmd +++ b/Biomass_core.Rmd @@ -88,7 +88,7 @@ Table \@ref(tab:moduleInputs-Biomass-core) shows a full list of input objects th df_inputs <- SpaDES.core::moduleInputs("Biomass_core", "..")[, c(1, 3)] ## name + desc only knitr::kable(df_inputs, caption = "List of (ref:Biomass-core) input objects and their description.") %>% - kableExtra::kable_styling(latex_options = "scale_down", full_width = TRUE) + kableExtra::kable_styling(latex_options = c("scale_down", "repeat_header"), full_width = TRUE) ``` Of the above, we draw particular attention to the the following inputs, which are crucial to run *Biomass_core* on a realistic setting (see [Input objects] section of the manual for further detail): @@ -107,7 +107,7 @@ Besides the above mentioned inputs, *Biomass_core* uses several other parameters df_params <- SpaDES.core::moduleParams("Biomass_core", "..")[, c(1, 6)] ## name + desc only knitr::kable(df_params, caption = "List of (ref:Biomass-core) parameters and their description.") %>% - kableExtra::kable_styling(latex_options = "scale_down", full_width = TRUE) + kableExtra::kable_styling(latex_options = c("scale_down", "repeat_header"), full_width = TRUE) ``` ### Events @@ -134,7 +134,7 @@ All `simList` objects that are changed by *Biomass_core* (*i.e.*, the definition df_outputs <- SpaDES.core::moduleOutputs("Biomass_core", "..")[, c(1, 3)] ## name + desc only knitr::kable(df_outputs, caption = "List of (ref:Biomass-core) output objects and their description.") %>% - kableExtra::kable_styling(latex_options = "scale_down", full_width = TRUE) + kableExtra::kable_styling(latex_options = c("scale_down", "repeat_header"), full_width = TRUE) ``` ### Links to other modules @@ -213,135 +213,228 @@ All of *Biomass_core*'s input objects have (theoretical) defaults that are produ df_inputs <- SpaDES.core::moduleInputs("Biomass_core", "..") knitr::kable(df_inputs, caption = "List of (ref:Biomass-core) input objects and their description.") %>% - kableExtra::kable_styling(latex_options = "scale_down", full_width = TRUE) + kableExtra::kable_styling(latex_options = c("scale_down", "repeat_header"), full_width = TRUE) ``` Of the inputs in Table \@ref(tab:moduleInputs2-Biomass-core), the following are particularly important and deserve special attention: - **Spatial layers** - - `ecoregionMap` -- a raster layer with ecolocation IDs (note that the term "ecoregion" was inherited from LBSE and kept as is for consistency with original LBSE code). Ecolocations group pixels or similar biophysical conditions using up to two levels of grouping. In many of our applications, we use the Natural Ecoregion classification of Canada as the first grouping level and a land-cover classification as the second level. The raster layer must be defined as a categorical variable, with an associated Raster Attribute Table (RAT; see, e.g., `raster::ratify`). The RAT must contain the columns: `ID` (the value in the raster layer), `ecoregion` (the first level of ecolocation grouping) and `ecoregionGroup` (the full ecolocation "name" written as \). Note that `ecoregionGroup` usually originated from combining two raster layers and, thus, the grouping level IDs are also integers. For instance, if Natural Ecoregion `2` has land-cover types `1`, `2` and `3`, the RAT will contain `ID = {1,2,3}`, `ecoregion = {2}` and `ecoregionGroup = {2_1, 2_2, 2_3}`. All ecolocations are listed in the `ecoregion` `data.table`. - - - `rasterToMatch` -- a RasterLayer, with a given resolution and projection determining the pixels (*i.e.*, non NA values) where forest dynamics will be simulated. Needs to match `studyArea`. If not supplied, *Biomass_core* attempts to produce it, using `biomassMap` as the template for spatial resolution and projection. - - - `studyArea` -- shapefile. A `SpatialPolygonsDataFrame` with a single polygon determing the where the simulation will take place. This is the only input object that **must be supplied by the user**. + - `ecoregionMap` -- a raster layer with ecolocation IDs (note that the + term "ecoregion" was inherited from LBSE and kept as is for consistency + with original LBSE code). Ecolocations group pixels or similar biophysical + conditions using up to two levels of grouping. In many of our applications, + we use the Natural Ecoregion classification of Canada as the first grouping + level and a land-cover classification as the second level. The raster layer + must be defined as a categorical variable, with an associated Raster + Attribute Table (RAT; see, e.g., `raster::ratify`). The RAT must contain + the columns: `ID` (the value in the raster layer), `ecoregion` (the first + level of ecolocation grouping) and `ecoregionGroup` (the full ecolocation + "name" written as \). Note that `ecoregionGroup` + usually originated from combining two raster layers and, thus, the grouping + level IDs are also integers. For instance, if Natural Ecoregion `2` has + land-cover types `1`, `2` and `3`, the RAT will contain `ID = {1,2,3}`, + `ecoregion = {2}` and `ecoregionGroup = {2_1, 2_2, 2_3}`. All ecolocations + are listed in the `ecoregion` `data.table`. + + - `rasterToMatch` -- a RasterLayer, with a given resolution and + projection determining the pixels (*i.e.*, non NA values) where forest + dynamics will be simulated. Needs to match `studyArea`. If not supplied, + *Biomass_core* attempts to produce it, using `biomassMap` as the template + for spatial resolution and projection. + + - `studyArea` -- shapefile. A `SpatialPolygonsDataFrame` with a single + polygon determing the where the simulation will take place. This is the + only input object that **must be supplied by the user**. - **Species traits and other parameter tables** - - `ecoregion` -- `data.table` listing all ecolocation "names" (*ecoregionGroup* column; see `ecoregionMap` above for details) and their state (active -- `yes` -- or inactive -- `no`) + - `ecoregion` -- `data.table` listing all ecolocation "names" + (*ecoregionGroup* column; see `ecoregionMap` above for details) and their + state (active -- `yes` -- or inactive -- `no`) - - `minRelativeB` -- `data.table` of minimum relative biomass values. This is a spatially variant trait used to determine the shade level in each pixel [see @SchellerMiranda2015, pp. 14], yet in our applications we often keep values constant across ecolocations. The table must contain the following columns: + - `minRelativeB` -- `data.table` of minimum relative biomass values. This + is a spatially variant trait used to determine the shade level in each + pixel [see @SchellerMiranda2015, pp. 14], yet in our applications we often + keep values constant across ecolocations. The table must contain the + following columns: - - *ecoregionGroup --* character. Ecolocation names. See `ecoregionMap` and `ecoregion` objects above. + - *ecoregionGroup --* character. Ecolocation names. See + `ecoregionMap` and `ecoregion` objects above. - - *X0-X5* -- six numeric columns, one per shade class (no-shade, 0, to maximum shade, 5), with 0 to 1 values determining the minimum threshold of biomass (relative to the species/ecolocation `maxB`) necessary to reach a given shade-level. This means that shade-levels are determined on a species by species basis [see @SchellerMiranda2015, pp. 14] + - *X0-X5* -- six numeric columns, one per shade class (no-shade, 0, + to maximum shade, 5), with 0 to 1 values determining the minimum + threshold of biomass (relative to the species/ecolocation `maxB`) + necessary to reach a given shade-level. This means that shade-levels + are determined on a species by species basis [see @SchellerMiranda2015, + pp. 14] - - `species` -- `data.table` of *invariant species traits*. There are species traits that do no vary spatially, nor temporally (e.g., longevity). The table must contain the following trait values (*i.e.*, columns) in order to run *Biomass_core* (note that columns should follow the data type indicated): + - `species` -- `data.table` of *invariant species traits*. There are + species traits that do no vary spatially, nor temporally (e.g., longevity). + The table must contain the following trait values (*i.e.*, columns) in + order to run *Biomass_core* (note that columns should follow the data type + indicated): - *speciesCode --* character. Species ID. - - *longevity --* integer. Maximum age in years [see @SchellerDomingo2011, pp. 18]. + - *longevity --* integer. Maximum age in years + [see @SchellerDomingo2011, pp. 18]. - - *sexualmature --* integer. Age at sexual maturity in years [see @SchellerDomingo2011, pp. 18]. + - *sexualmature --* integer. Age at sexual maturity in years + [see @SchellerDomingo2011, pp. 18]. - - *shadetolerance --* integer OR numeric. *Relative* shade tolerance (see [Algorithm changes]). + - *shadetolerance --* integer OR numeric. *Relative* shade tolerance + (see [Algorithm changes]). - - *seeddistance_eff --* integer. Eeffective seed distance in meters. [see @SchellerDomingo2011, pp. 18] + - *seeddistance_eff --* integer. Eeffective seed distance in meters. + [see @SchellerDomingo2011, pp. 18] - - *seeddistance_max --* integer. Maximum seed distance in meters. Note that is the pixel size is larger than the maximum seed distance, the species will not be able to disperse to neighbouring pixels [see @SchellerDomingo2011, pp. 18]. + - *seeddistance_max --* integer. Maximum seed distance in meters. + Note that is the pixel size is larger than the maximum seed distance, + the species will not be able to disperse to neighbouring pixels + [see @SchellerDomingo2011, pp. 18]. - - *mortalityshape --* integer. Shape of growth curve determining how quickly mortality begins [see @SchellerMiranda2015, pp. 15]. + - *mortalityshape --* integer. Shape of growth curve determining how + quickly mortality begins [see @SchellerMiranda2015, pp. 15]. - - *growthcurve --* numeric. Shape of growth curve determining ANPP reaches its maximum [see @SchellerMiranda2015, pp. 16]. + - *growthcurve --* numeric. Shape of growth curve determining ANPP + reaches its maximum [see @SchellerMiranda2015, pp. 16]. - - `speciesEcoregion` -- `data.table` of *spatiotemporally-varying species traits*. There are species traits vary spatially and, potentially, temporally. The table must contain the following columns in order to run *Biomass_core*: + - `speciesEcoregion` -- `data.table` of *spatiotemporally-varying species + traits*. There are species traits vary spatially and, potentially, + temporally. The table must contain the following columns in order to run + *Biomass_core*: - - *ecoregionGroup* -- character. Ecolocation names. See `ecoregionMap` and `ecoregion` objects above. + - *ecoregionGroup* -- character. Ecolocation names. See + `ecoregionMap` and `ecoregion` objects above. - *speciesCode* -- character. Species ID. - - *establishprob* -- numeric. Species establishment probability (`SEP`) for a given species in an ecolocation and, potentially year. SEP influences the success of incoming seed germination, given pixel biophysical characteristics (note that *actual* success is determined by both SEP and light conditions in the pixel) [see @SchellerMiranda2015, pp. 18]. - - - *maxB* -- integer. Maximum biomass for a given species in an ecolocation in units of g biomass / m^2^. Note that the actual maximum biomass reached by a species in a pixel may exceed `maxB` because `maxB` is applied at the cohort level an species may have several cohorts in a given pixel [see @SchellerMiranda2015, pp. 18]. - - - *maxANPP* -- numeric. Maximum aboveground net primary productivity in units of g biomass / m^2^ / year, by default it is calculated as 1/30 of `maxB` [see @SchellerMiranda2015, pp. 18] - - - *year* -- integer. Used when varying `SEP`, `maxB` and `maxANPP` values in time. Otherwise, use fill all lines with `0`. - - - `sufficientLight` -- `data.table` defining the probability of germination for a species, given its `shadetolerance` level (see `species` above) and the shade level in the pixel (see `minRelativeB` above). Must contain columns: - - - *speciesshadetolerance* -- integer. Species shade tolerance levels, from 1-5 (all levels must be present in this table). - - - *X0-X5* -- six integer columns, one per shade class (no-shade, 0, to maximum shade, 5), filled with 0s OR 1s values determining the probability of germination (or resprouting) for a species given a shade-level[see @SchellerMiranda2015, pp. 14]. Unlike LBSE, species `shadetolerance` values can take decimal values between 1-5, in which case the resulting probability of germination in a given pixel is interpolated between the corresponding lower and upper shade tolerance values. - - - `sppEquiv` -- a `data.table` of species name equivalencies between various conventions. It must contain the columns *LandR* (species IDs following in LandR format) *EN_generic_short* (short generic species names in English -- or any other language; used for plotting), *Type* (type of species, *Conifer* or *Deciduous*, as in "broadleaf") and *Leading* (same as *EN_generic_short* but with "leading" appended -- e.g., "Poplar leading") . See `?LandR::sppEquivalencies_CA` for more information. - - - `sppColorVect` -- character. A named vector of colours used to plot species dynamics. Should contain one colour per species in the `species` table and, potentially a colour for species mixtures (named "Mixed"). Vector names must follow `species$speciesCode`. + - *establishprob* -- numeric. Species establishment probability + (`SEP`) for a given species in an ecolocation and, potentially year. + SEP influences the success of incoming seed germination, given pixel + biophysical characteristics (note that *actual* success is determined + by both SEP and light conditions in the pixel) + [see @SchellerMiranda2015, pp. 18]. + + - *maxB* -- integer. Maximum biomass for a given species in an + ecolocation in units of g biomass / m^2^. Note that the actual maximum + biomass reached by a species in a pixel may exceed `maxB` because + `maxB` is applied at the cohort level an species may have several + cohorts in a given pixel [see @SchellerMiranda2015, pp. 18]. + + - *maxANPP* -- numeric. Maximum aboveground net primary productivity + in units of g biomass / m^2^ / year, by default it is calculated as + 1/30 of `maxB` [see @SchellerMiranda2015, pp. 18] + + - *year* -- integer. Used when varying `SEP`, `maxB` and `maxANPP` + values in time. Otherwise, use fill all lines with `0`. + + - `sufficientLight` -- `data.table` defining the probability of + germination for a species, given its `shadetolerance` level (see `species` + above) and the shade level in the pixel (see `minRelativeB` above). Must + contain columns: + + - *speciesshadetolerance* -- integer. Species shade tolerance levels, + from 1-5 (all levels must be present in this table). + + - *X0-X5* -- six integer columns, one per shade class (no-shade, 0, + to maximum shade, 5), filled with 0s OR 1s values determining the + probability of germination (or resprouting) for a species given a + shade-level[see @SchellerMiranda2015, pp. 14]. Unlike LBSE, species + `shadetolerance` values can take decimal values between 1-5, in which + case the resulting probability of germination in a given pixel is + interpolated between the corresponding lower and upper shade tolerance + values. + + - `sppEquiv` -- a `data.table` of species name equivalencies between + various conventions. It must contain the columns *LandR* (species IDs + following in LandR format) *EN_generic_short* (short generic species names + in English -- or any other language; used for plotting), *Type* (type of + species, *Conifer* or *Deciduous*, as in "broadleaf") and *Leading* (same + as *EN_generic_short* but with "leading" appended -- e.g., "Poplar + leading") . See `?LandR::sppEquivalencies_CA` for more + information. + + - `sppColorVect` -- character. A named vector of colours used to plot + species dynamics. Should contain one colour per species in the `species` + table and, potentially a colour for species mixtures (named "Mixed"). + Vector names must follow `species$speciesCode`. - **Cohort-simulation-related objects** - - `cohortData` -- a `data.table` containing initial cohort information per *pixelGroup* (see `pixelGroupMap` below). This table is updated during the simulation as cohort dynamics are simulated. Must contain the following columns + - `cohortData` -- a `data.table` containing initial cohort information + per *pixelGroup* (see `pixelGroupMap` below). This table is updated during + the simulation as cohort dynamics are simulated. Must contain the following + columns - - *pixelGroup* -- integer. *pixelGroup* ID. See [Hashing]. + - *pixelGroup* -- integer. *pixelGroup* ID. See [Hashing]. - - *ecoregionGroup* -- character. Ecolocation names. See `ecoregionMap` and `ecoregion` objects above. + - *ecoregionGroup* -- character. Ecolocation names. See + `ecoregionMap` and `ecoregion` objects above. - - *speciesCode* -- character. Species ID. + - *speciesCode* -- character. Species ID. - - *age* -- integer. Cohort age. + - *age* -- integer. Cohort age. - - *B* -- integer. cohort biomass in g/m^2^. + - *B* -- integer. cohort biomass in g/m^2^. - - *mortality* -- integer. cohort dead biomass in the current year in g/m^2^. Should be filled with 0s in initial conditions. + - *mortality* -- integer. cohort dead biomass in the current year in + g/m^2^. Should be filled with 0s in initial conditions. - - *aNPPAct* -- integer. Actual aboveground net primary productivity of the current year in g/m^2^. Hence *B* is the result of the previous year's *B* minus *mortality* plus *aNPPAct*. See "1.1.3 Cohort growth and ageing" section of @SchellerMiranda2015. + - *aNPPAct* -- integer. Actual aboveground net primary productivity + of the current year in g/m^2^. Hence *B* is the result of the previous + year's *B* minus *mortality* plus *aNPPAct*. See "1.1.3 Cohort growth + and ageing" section of @SchellerMiranda2015. - - `pixelGroupMap` -- a raster layer with *pixelGroup* IDs per pixel. Pixels are always grouped based on identical *ecoregionGroup*, *speciesCode*, *age* and *B* composition, even if the user supplies other initial groupings (e.g., this is possible in the *Biomass_borealDataPrep* data module). + - `pixelGroupMap` -- a raster layer with *pixelGroup* IDs per pixel. + Pixels are always grouped based on identical *ecoregionGroup*, + *speciesCode*, *age* and *B* composition, even if the user supplies other + initial groupings (e.g., this is possible in the *Biomass_borealDataPrep* + data module). #### Parameters -Table \@ref(tab:moduleParams2-Biomass-core) lists all parameters used in *Biomass_core*. Note that a few of these parameters are only relevant when simulating climate effects of cohort growth and mortality, which require also loading the `LandR.CS` R package. Like with input objects, default values are supplied for all parameters and we suggest the user becomes familiarized with them before attempting any changes. We also note that the `"spin-up"` and `"biomassMap"` options for the `initialBiomassSource` are currently deactivated, since *Biomass_core* no longer generates initial cohort biomass conditions using a spin-up based on initial stand age like LANDIS-II (`"spin-up"`), nor does it attempt to fill initial cohort biomasses using `biomassMap` (`"biomassMap"`). A list of useful parameters and their description is shown in Table \@ref(tab:tableUsefulParams). +Table \@ref(tab:moduleParams2-Biomass-core) lists all parameters used in *Biomass_core*. Note that a few of these parameters are only relevant when simulating climate effects of cohort growth and mortality, which require also loading the `LandR.CS` R package. Like with input objects, default values are supplied for all parameters and we suggest the user becomes familiarized with them before attempting any changes. We also note that the `"spin-up"` and `"biomassMap"` options for the `initialBiomassSource` are currently deactivated, since *Biomass_core* no longer generates initial cohort biomass conditions using a spin-up based on initial stand age like LANDIS-II (`"spin-up"`), nor does it attempt to fill initial cohort biomasses using `biomassMap` (`"biomassMap"`). A list of useful parameters and their description is shown below Table \@ref(tab:moduleParams2-Biomass-core). ```{r moduleParams2-Biomass-core, echo = FALSE, eval = TRUE, message = FALSE} df_params <- SpaDES.core::moduleParams("Biomass_core", "..") knitr::kable(df_params, caption = "List of (ref:Biomass-core) parameters and their description.") %>% - kableExtra::kable_styling(latex_options = "scale_down", full_width = TRUE) + kableExtra::kable_styling(latex_options = c("scale_down", "repeat_header"), full_width = TRUE) ``` -::: fullwidth -+------------------------+-------------------------------------------------------------------------------------------------+ -| Required inputs | Description | -+:=======================+:================================================================================================+ -| Plotting & saving | | -+------------------------+-------------------------------------------------------------------------------------------------+ -| `.plots` | activates/deactivates plotting and defines type fo plotting (see `?Plots`) | -+------------------------+-------------------------------------------------------------------------------------------------+ -| `.plotInitialTime` | defines when plotting starts | -+------------------------+-------------------------------------------------------------------------------------------------+ -| `.plotInterval` | defines plotting frequency | -+------------------------+-------------------------------------------------------------------------------------------------+ -| `.plotMaps` | activates/deactivates map plotting | -+------------------------+-------------------------------------------------------------------------------------------------+ -| `.saveInitialTime` | defines when saving starts | -+------------------------+-------------------------------------------------------------------------------------------------+ -| `.saveInterval` | defines saving frequency | -+------------------------+-------------------------------------------------------------------------------------------------+ -| Simulation | | -+------------------------+-------------------------------------------------------------------------------------------------+ -| `seedingAlgorithm` | dispersal type (see above) | -+------------------------+-------------------------------------------------------------------------------------------------+ -| `successionTimestep` | defines frequency of dispersal/local recruitment event (growth and mortality are always yearly) | -+------------------------+-------------------------------------------------------------------------------------------------+ -| Other | | -+------------------------+-------------------------------------------------------------------------------------------------+ -| `mixedType` | how mixed forest stands are defined | -+------------------------+-------------------------------------------------------------------------------------------------+ -| `vegLeadingProportion` | relative biomass threshold to consider a species "leading" (*i.e.*, dominant) | -+------------------------+-------------------------------------------------------------------------------------------------+ -::: - -: (#tab:tableUsefulParams) Useful *Biomass_core* parameters. + +- **Plotting & saving** + + - `.plots` -- activates/deactivates plotting and defines type fo plotting + (see `?Plots`) + + - `.plotInitialTime` -- defines when plotting starts + + - `.plotInterval` -- defines plotting frequency + + - `.plotMaps` -- activates/deactivates map plotting + + - `.saveInitialTime` -- defines when saving starts + + - `.saveInterval` -- defines saving frequency + +- **Simulation** + + - `seedingAlgorithm` -- dispersal type (see above) + + - `successionTimestep` -- defines frequency of dispersal/local + recruitment event (growth and mortality are always yearly) + +- **Other** + + - `mixedType` -- how mixed forest stands are defined + + - `vegLeadingProportion` -- relative biomass threshold to consider a + species "leading" (*i.e.*, dominant) + ### Simulation flow From 327f883f9e281f54d4c37e7ae72f6a8ef6f354cb Mon Sep 17 00:00:00 2001 From: CeresBarros Date: Wed, 6 Apr 2022 22:56:00 -0700 Subject: [PATCH 008/148] fixes for latex --- Biomass_core.Rmd | 223 +++++++++++++++++++++++++------ LBSE_LandR_comparisonTables.xlsx | Bin 0 -> 22856 bytes 2 files changed, 180 insertions(+), 43 deletions(-) create mode 100644 LBSE_LandR_comparisonTables.xlsx diff --git a/Biomass_core.Rmd b/Biomass_core.Rmd index 75ba6cd..cf39c0f 100644 --- a/Biomass_core.Rmd +++ b/Biomass_core.Rmd @@ -23,8 +23,11 @@ always_allow_html: true (ref:Biomass-core) *Biomass_core* + (ref:percent) % +(ref:sufficient-light) *sufficient light* + ```{r setup-Biomass-core, include=FALSE} ## set cache.rebuild = TRUE whenever there are changes to the module code/metadata knitr::opts_chunk$set(echo = TRUE, eval = FALSE, warning = FALSE, @@ -54,6 +57,7 @@ download.file(url = "https://img.shields.io/badge/Get%20help-Report%20issues-%3C ``` [![made-with-Markdown](figures/markdownBadge.png)](http://commonmark.org) + [![Generic badge](figures/genericBadge.png)](https://github.com/PredictiveEcology/Biomass_core/issues) @@ -88,7 +92,8 @@ Table \@ref(tab:moduleInputs-Biomass-core) shows a full list of input objects th df_inputs <- SpaDES.core::moduleInputs("Biomass_core", "..")[, c(1, 3)] ## name + desc only knitr::kable(df_inputs, caption = "List of (ref:Biomass-core) input objects and their description.") %>% - kableExtra::kable_styling(latex_options = c("scale_down", "repeat_header"), full_width = TRUE) + kableExtra::kable_styling(latex_options = c("scale_down", "repeat_header"), full_width = TRUE) %>% + kableExtra::column_spec(column = 2, width = "30em") ``` Of the above, we draw particular attention to the the following inputs, which are crucial to run *Biomass_core* on a realistic setting (see [Input objects] section of the manual for further detail): @@ -107,7 +112,8 @@ Besides the above mentioned inputs, *Biomass_core* uses several other parameters df_params <- SpaDES.core::moduleParams("Biomass_core", "..")[, c(1, 6)] ## name + desc only knitr::kable(df_params, caption = "List of (ref:Biomass-core) parameters and their description.") %>% - kableExtra::kable_styling(latex_options = c("scale_down", "repeat_header"), full_width = TRUE) + kableExtra::kable_styling(latex_options = c("scale_down", "repeat_header"), full_width = TRUE) %>% + kableExtra::column_spec(column = 2, width = "40em") ``` ### Events @@ -134,7 +140,8 @@ All `simList` objects that are changed by *Biomass_core* (*i.e.*, the definition df_outputs <- SpaDES.core::moduleOutputs("Biomass_core", "..")[, c(1, 3)] ## name + desc only knitr::kable(df_outputs, caption = "List of (ref:Biomass-core) output objects and their description.") %>% - kableExtra::kable_styling(latex_options = c("scale_down", "repeat_header"), full_width = TRUE) + kableExtra::kable_styling(latex_options = c("scale_down", "repeat_header"), full_width = TRUE) %>% + kableExtra::column_spec(column = 2, width = "40em") ``` ### Links to other modules @@ -571,52 +578,93 @@ knitr::include_graphics(normalizePath(c("figures/Biomass_coreOutPlots1.png", ### Tables -| Input order 1 | | | | Input order 2 | | | | -|:--------------|:---------|:----|:-----------|:--------------|:---------|:----|:-----------| -| Community | Input | Age | Processing | Community | Input | Age | Processing | -| | order | | order | | order | | order | -| 1 | abiebals | 20 | poputrem | 1 | pinustro | 20 | thujocci | -| 1 | acerrubr | 20 | querelli | 1 | poputrem | 20 | tiliamer | -| 1 | acersacc | 20 | pinuresi | 1 | acerrubr | 20 | querelli | -| 1 | betualle | 20 | pinustro | 1 | pinubank | 20 | querrubr | -| 1 | betupapy | 20 | tiliamer | 1 | betualle | 20 | betupapy | -| 1 | fraxamer | 20 | tsugcana | 1 | piceglau | 20 | fraxamer | -| 1 | piceglau | 20 | querrubr | 1 | pinuresi | 20 | tsugcana | -| 1 | pinubank | 20 | thujocci | 1 | acersacc | 20 | abiebals | -| 1 | pinuresi | 20 | acersacc | 1 | querelli | 20 | acerrubr | -| 1 | pinustro | 20 | betualle | 1 | querrubr | 20 | pinubank | -| 1 | poputrem | 20 | abiebals | 1 | thujocci | 20 | pinustro | -| 1 | querelli | 20 | acerrubr | 1 | tiliamer | 20 | poputrem | -| 1 | querrubr | 20 | piceglau | 1 | tsugcana | 20 | pinuresi | -| 1 | thujocci | 20 | pinubank | 1 | abiebals | 20 | acersacc | -| 1 | tiliamer | 20 | betupapy | 1 | betupapy | 20 | betualle | -| 1 | tsugcana | 20 | fraxamer | 1 | fraxamer | 20 | piceglau | + + +```{r tableLBSEtest1, echo = FALSE, eval = TRUE, message = FALSE} +tab <- openxlsx::read.xlsx("LBSE_LandR_comparisonTables.xlsx", sheet = "Table1_Appendix1", + colNames = TRUE, sep.names = " ") +names(tab)[grep("X", names(tab))] <- "" +caption <- paste("Input order and processing order (as determined by", + "LBSE) for the same community used to assess the impact", + "of sequential calculation of the competition index,", + "combined with a lack of explicit species ordering. The", + "input order was the order of species in the initial", + "communities table input file. The processing order was", + "the order used in the simulation, which was obtained from", + "`Landis-log.txt` when `CalibrateMode` was set to 'yes'.", + "Species starting ages are also shown.") +knitr::kable(tab, + caption = caption) %>% + kableExtra::kable_styling(latex_options = c("scale_down", "repeat_header"), full_width = TRUE) +``` -| Input order 1 | | | | Input order 2 | | | | -|:--------------|:---------|:----|:-----------|:--------------|:---------|:----|:-----------| -| Community | Input | Age | Processing | Community | Input | Age | Processing | -| | order | | order | | order | | order | -| 1 | abiebals | 1 | poputrem | 1 | pinustro | 1 | thujocci | -| 1 | acerrubr | 1 | querelli | 1 | poputrem | 1 | tiliamer | -| 1 | acersacc | 1 | pinuresi | 1 | acerrubr | 1 | querelli | -| 1 | betualle | 1 | pinustro | 1 | pinubank | 1 | querrubr | -| 1 | betupapy | 1 | tiliamer | 1 | betualle | 1 | betupapy | -| 1 | fraxamer | 1 | tsugcana | 1 | piceglau | 1 | fraxamer | -| 1 | piceglau | 1 | querrubr | 1 | pinuresi | 1 | tsugcana | -| 1 | pinubank | 1 | thujocci | 1 | acersacc | 1 | abiebals | -| 1 | pinuresi | 1 | acersacc | 1 | querelli | 1 | acerrubr | -| 1 | pinustro | 1 | betualle | 1 | querrubr | 1 | pinubank | -| 1 | poputrem | 1 | abiebals | 1 | thujocci | 1 | pinustro | -| 1 | querelli | 1 | acerrubr | 1 | tiliamer | 1 | poputrem | -| 1 | querrubr | 1 | piceglau | 1 | tsugcana | 1 | pinuresi | -| 1 | thujocci | 1 | pinubank | 1 | abiebals | 1 | acersacc | -| 1 | tiliamer | 1 | betupapy | 1 | betupapy | 1 | betualle | -| 1 | tsugcana | 1 | fraxamer | 1 | fraxamer | 1 | piceglau | + + +```{r tableLBSEtest2, echo = FALSE, eval = TRUE, message = FALSE} +tab <- openxlsx::read.xlsx("LBSE_LandR_comparisonTables.xlsx", sheet = "Table2_Appendix1", + colNames = TRUE, sep.names = " ") +names(tab)[grep("X", names(tab))] <- "" +caption <- paste("Input order and processing order (as determined by LBSE) for", + "the same community used to assess the impact of setting the", + "succession time step to 1, combined with a lack of explicit", + "species ordering. The input order was the order of species in", + "the initial communities table input file. The processing order", + "was the order used in the simulation, which was obtained from", + "`Landis-log.txt` when `CalibrateMode` was set to 'yes'.", + "Species starting ages are also shown.") +knitr::kable(tab, + caption = caption) %>% + kableExtra::kable_styling(latex_options = c("scale_down", "repeat_header"), full_width = TRUE) +``` + + +```{r tableLBSEtest3, echo = FALSE, eval = TRUE, message = FALSE} +tab <- openxlsx::read.xlsx("LBSE_LandR_comparisonTables.xlsx", sheet = "Table3_Appendix1", + colNames = TRUE, sep.names = " ") +caption <- paste("Randomly generated community combination no. 1 used in the", + "recruitment comparison runs.") +knitr::kable(tab, + caption = caption) %>% + kableExtra::kable_styling(latex_options = c("scale_down", "repeat_header"), full_width = TRUE) +``` + + +```{r tableLBSEtest4, echo = FALSE, eval = TRUE, message = FALSE} +tab <- openxlsx::read.xlsx("LBSE_LandR_comparisonTables.xlsx", sheet = "Table4_Appendix1", + colNames = TRUE, sep.names = " ") +caption <- paste("Randomly generated community combination no. 2 used in the", + "recruitment comparison runs.") +knitr::kable(tab, + caption = caption) %>% + kableExtra::kable_styling(latex_options = c("scale_down", "repeat_header"), full_width = TRUE) +``` + + +```{r tableLBSEtest5, echo = FALSE, eval = TRUE, message = FALSE} +tab <- openxlsx::read.xlsx("LBSE_LandR_comparisonTables.xlsx", sheet = "Table5_Appendix1", + colNames = TRUE, sep.names = " ") +caption <- paste("Randomly generated community combination no. 3 used in the", + "recruitment comparison runs.") +knitr::kable(tab, + caption = caption) %>% + kableExtra::kable_styling(latex_options = c("scale_down", "repeat_header"), full_width = TRUE) +``` + + +```{r tableLBSEtest6, echo = FALSE, eval = TRUE, message = FALSE} +tab <- openxlsx::read.xlsx("LBSE_LandR_comparisonTables.xlsx", sheet = "Table6_Appendix1", + colNames = TRUE, sep.names = " ") +caption <- paste("Invariant species traits table used in comparison runs.") +knitr::kable(tab, + caption = caption) %>% + kableExtra::kable_styling(latex_options = c("scale_down", "repeat_header"), full_width = TRUE) +``` + + +```{r tableLBSEtest7, echo = FALSE, eval = TRUE, message = FALSE} +tab <- openxlsx::read.xlsx("LBSE_LandR_comparisonTables.xlsx", sheet = "Table7_Appendix1", + colNames = TRUE, sep.names = " ") +caption <- paste("Minimum relative biomass table used in comparison runs. X0-5", + "represent site shade classes from no-shade (0) to maximum", + "shade (5). All ecolocations shared the same values.") +knitr::kable(tab, + caption = caption) %>% + kableExtra::kable_styling(latex_options = c("scale_down", "repeat_header"), full_width = TRUE) +``` + + + +```{r tableLBSEtest8, echo = FALSE, eval = TRUE, message = FALSE} +tab <- openxlsx::read.xlsx("LBSE_LandR_comparisonTables.xlsx", sheet = "Table8_Appendix1", + colNames = TRUE, sep.names = " ") +caption <- paste("Probability of germination for species shade tolerance and", + "shade level combinations (called (ref:sufficient-light) table in", + "LBSE and `sufficientLight` input `data.table` in LandR", + "(ref:Biomass-core)) used in comparison runs.") +knitr::kable(tab, + caption = caption) %>% + kableExtra::kable_styling(latex_options = c("scale_down", "repeat_header"), full_width = TRUE) +``` + + +```{r tableLBSEtest9, echo = FALSE, eval = TRUE, message = FALSE} +tab <- openxlsx::read.xlsx("LBSE_LandR_comparisonTables.xlsx", sheet = "Table9_Appendix1", + colNames = TRUE, sep.names = " ") +caption <- paste("Species ecolocation table used in comparison runs. `SEP`", + "stands for species establishment probability, `maxB` for", + "maximum biomass and `maxANPP` for maximum aboveground net", + "primary productivity. Values were held constant throughout", + "the simulation.") +knitr::kable(tab, + caption = caption) %>% + kableExtra::kable_styling(latex_options = c("scale_down", "repeat_header"), full_width = TRUE) +``` ### Figures diff --git a/LBSE_LandR_comparisonTables.xlsx b/LBSE_LandR_comparisonTables.xlsx new file mode 100644 index 0000000000000000000000000000000000000000..fc4278790172d19ac6bd41bfac7aecd8a998dfec GIT binary patch literal 22856 zcmeFZ^;;axw=ar2!9#F&cXxMp4KTPn!QEX35AN>n4#5fT?iQHfm-pTKJont^eD_~) zZvW8TGrd-IRrm5wRV&LuLScfzfWd)*fsueUnI}FagM)#I!-IigfWblNi8qi_KFP2p1! zh>Z7SOgZWqX234D*_?<(%P=*n#W^F7D9mMWaTva-NpwhrzW_D^m=QtI2WU{ECXCZgY?TZfk48+#Qy=4%ece<$sp zD7A*TYg)gY+|YrLBd}&4a&$xq{ZUKpm415;J)Tuh+OFrbtPK$LGRn|L3!Xr!^iOxy zS4qcjn%uTYQ=EfU#+3uBs9b~{jQfrxzVQvAeU42yv@?UTQ?{Ko=(`nvuH$(xH#=Rg zM{||;(KcF4m{}2oKzXJ&uu;~pgW1=`KGPn1)s5Xr+^Rapz{%k@o~SUUbt_OL^S$6E z4!@LPm)iz@)Ju+=QFma@0e%!9$6cd4;Pj@1KZFC#Y6#jMD3~I``#RqR!T+a)K;pxh zQ3FhXQn7cuAH2uLVSh)O5c)V#O{nimO?zYV=A zNkM6l87b^q`ZatEw6vLkDk|q8BHc-%?iV1lfzljXNRGGJONEcBjvEXq<=^f1I!d6^)L`N7mv|9R_@Ma)YI%bWW3Ws@fewb6xD~HQonh3%g~uqy5Bn;R5vV(&ptEK2w+4JkRPC}ltge+S?<{#H%YQkox|SWMc#wIZWH_MWRBMm7yMx5*v)uQG*Q{sr(63!mE<|#IEwl63I!|}7%mtbxTh`C zf9Z*bgR_l^gM-aKF7JQo4EU$t`=tH9d+SP_wEoxbhrS2T38r0=E2@%OU?8lvoWjC+ zzY@2Yv7Zh4Z}-m@h2^<_Z$gWK+2qlWm3$f0T81GquA7ss4skbiV6z7GUGo%d4qgJzCkdezT_hh<{ zt_q-1NpZf{3kG2P+EIrySA<>?LJ`n-*V6+6k_T0euL-EVOQAj%kAgS?C{(Oy>w*kg z6XG-Mq=#a*!*zay>2w%#=6>g7Oy|x>hOx2A^K1@VLv`@rSaqM9Lb#7Fk;(q;*;Bd# zo%|zACTDu6ku#P+H&byL7;Ab_(fepSvStMnyY)nwQw)#9#Wa!-U)d<2nM z#B?EI>!_nMn4O2DJ*jbwP)i6?3#oVZgJ4d{It75uTUh!bWp4^1X(osof< z;JijWGkxA3cib$cc!ab6r@nb}0Puu^{lJK?gKyI)n~`r7L&=;9`@9}hF(EO`-SrUE z=aHD4t?E=;m15quXO1j$a_d9YCYk} zauf}Mgvxr_)Gl^1oWp|vXS)UsVIiRDX>3ZNd2>U=PGIF{T^aK>CTlhKQWkWwviNg` zv;>#H{;ikh$G{JHYZQFueB>sA4=ZWb+R5j{x!`wzoj`M(l6=t}Dw$={^48y3dZGHo z1D3nN*-+5s8Zw}BLm1{&r8^?>JCkc{Yu$Xv{CfE*;!3@jZb3Qh-z2r`r-~4B+10sV z&8p7h7Dd4Z^&#Ut`vuAKn0r{B-q9yFB#RBp1iXi~Ibv)iXOVbBnD$#@*h_cbZO?=( zB3;wy?WXt%Jq~>&yM~MzN)pht@3b@BY^eCx>O7&*#)G zRa3g(8^VQRU^5x&!n~^(>?1IEtD@IV%MLy*;f+4vxB7{Utan_e|=UdMo078@larIowB+v;vC`!dp{8T^pIeI z=SP1VR;fn+I{jtqK@t*pd!8JOKX`q(BOF~8$=vny!tXJvEq$3gY4D9l$(l59j*6%8 zQkV|^#qoCk%Gr@UeS1V9bW%sevwv&rx^fXWNILk|E*E$3;MN-3ZT51BN>nS6c4YANXLXNGMH z;OZ46^}TLAH(BoPN4MNUY!u=Ws0*J#%BrL^9BA+ZHsd1L<@K5S)%J?aLl9p;-~i&S zG1^~$s24V4%P8r<2BrWwy34KL6bZWJ?7Z)%e47DzVqJr*D5-qSKEBH2yv*3Axu{d5 zelRMb9-y4Y-|tZPZThSmeaQQT++JP2Woizwcb{HtT^srRxCLZI<>tOjXJ~4j+0|r~ zhP&LECI|{A=RP-$PxNmvg$L6IvrQJjE`v57&s~y=tA3r7fEs_P`b;|)saR2z^aKC+ z`};c+N^UP8Zm%UAcc2EdRCauu*k2lMOCPO`&M=l&#%3E%cQcqmG9Bnh=NS=qV~M6U zPZ5kbvoZ@M&Xs&~p$E(a5rr@4U$dMVG^}IjB&|sd6?p2>vk7-t7>NQE@uj&*+F+zv zL(wzg1!CY%FO!4?TjPCn9Fu)0I>#-_f;1%}mf~e+lO09ft{{uZAmL*NAqHed|457F zeF2ipJ~6OSbDtI(f88iD9uEm>&74^user3Tn7@A{*H1#~2^mR10-xo9?}F*bTL^Ph zK>Wc_kQ628!N+rw{y1~RW!}0t|m)OOX|-b7&4MiY6zKg z*Qr0Rn}7F5#Rkrj=e!W`$pRR+*OFN7rX@w7X(y%FpSYo5|Kc_!tZE?>Z^=;3SDc9` zw?+!Efs^LBCi|o(2aJpB%q!GJp}zds-`STL5sN@cfVGD|hFS(|r=(zK^K0I<9zKD* z1E`%(54wESpOA8xaT(7HKPD|O6d2b(^Xm!0AT%J?uls?HJIF?mXYB}1tB814d_Q@0 z2k2M0OO;nA>aPB02s6ce599}1hjQGdO(O7F+anL7B)g*|pM5XO{MFexnJL9}sw+Z5 zAKOibr$%iv!oLOPKJq8?DFT^*fcWUnK&wsXy-rMikudlyNyPeRQkF@L(bV`;ajmi3 zLKDja8LF^pS^ran0k3a>r^q!ZlX->#oDYMSx8i10jcj4^;9xHHp~5asr3O74Qlrsg zVcq)35FzE72drbKoY&mF93wo!Ywatz`%vT1-UYxj#+AQ<+lC%RPco~IQ)6NW{1ERh z5I1)YHbBFx`gV%n6pn6#RmM7AM8~_Gn9MFg7gTmD!mqvx)dG`RHJ{XWmIGU{R$hd` z>yCV!bL$F!k~G0pVHpnU24YX7)mAtemFw(>d9GPuu$Qlzr}=QFQNe(l=hE@?qdN(~ z?OKlJOJR|?<9+3pXJSf`0(Prem2W0o$oP1qa8!WL&9(%$0`^$FjG{ zKZJHgZ2@Yq&eP2;_|@d4bIx_w+R6{&!YQ+93Sf49DEwBP2dmRgmgjrz!>dP83e2 zO_*rjJi>XoHjucx?g32my8fO+9%cxGrTCuXQqS}ZM74CiUb3`B&rP!N%(KzR$gS*2 z+XacL*+&y9Hzy%2#&|Wu*YA4#WM;|$)65|gr4N(FY~0RG*uYdZaj%p6V*6HSAUc7E zCtTVEhoH_7WMW=(RX1RVrEB;+O0ake$i6!n0rmttHNZz90FE!g-S8_!h;D{gQnE&)IBt$vLo*I>bBRHWpo~yko`z;&H&-7VW9_Lf4qnEZkEhLJJL8NDETB z@l(|@OD^zWDFCsBs{2CP*cw$kWo5Iz-p=b1p34{~Nx!Tl*4Ko?t4kjF%WRn(4y7H6 zQj-|Y7P&M)uyF=yhNMvBmk=`Y4*0_IJv_Zk0Om))`Xu0RF80|PI2?RCL0R`a-*yC^<1`GR zL6m81ZuqFH)mGf?9uc`_s=Q{HJDHjr9pY89b9v^aF&nmGE__Z0=0&y+Ywh_&QRb+3 z*wRtbRUATaCw|F7?a+Ju=b$AusddD+d>U+fvAzf0x%1vYW+@CzdC4;Hu9TKUd5b-4}=;iqNH2!PD zLx9fvX)Ah1h)G2;Ockkl2Gx!oV5Wqr>{)mW_M)L21@7MY>(02iFSvoB&V2yz&77?B z%{9*Vr5VD1Snu_@;BWqr)&19x9-iLIIAFh^-!FfK#1d|7q1JEP#UDMCr59XZS55yW z>DP|uzn%-cJ;`Uki<|fWzmV6;I5T{V`R%H_5g(uW|Hn{Dec{Eh=QF<~ga!k{{I5{T z#qzr|z)a26*~;F+<)1LhHbu{2k@+)>O8kqGxNX&Kk+4yy!bnvPaD_b_bkqK2oe zsXkAEr|0CG@sU;aoP6_6)ZT$*fT6xTbXEC4qZubzbk%|C@|J&AAT{lpq zg|I;hjAr=`73PS|SU!)VGGyinwyt;iuIf540J7hT!2-!D$vE&hh1*J+V%s|f zLFdT@<%ydcs=YlJy zE^Do^=T8-lz`69ydOio=-C&LQ)6V+nChogBqwhn{EAZ^K$BpSfzVEKGl_%pk1uN1xF4C&Zb&4>jSSbA&W^RSrc)l~nwdVf(RmAFTy zkmR-NV)ID~i$B0iLNW3uL@A7ab>74-Z63X%+@cn;iw3@(x?R5Ad;9^M#?}Dbe~f<_ zrZMvFy{iO0+=8|V{V;)`bG=+38QQL^fwu#|tA{AQcD?mA-QYUP#SeX~rVYPQ^|h-j zuJ%|iw|g-*E}Z43{L#K?i;x%Vz+16Wj7jUd!+qY0pU_dMDop!9copWgzwi3bT7{_XdVI3$#5i{}o{GS>D!3Tep&t(lCX$V8r$Nc*$x@q`^ns01;?i&WXYO zFb9q+jmg^o-nt7nS~?zu$@>;M^`cO&N6&kE#rMp`;q|XF;-7254=0XyLX96n*u&n? zMNBphq@w!wVm;M8J}Hs@f_Dmj+!50HuB-m6)V&`^S}dcyWltXW0cBT3LQI7~AE2*L zia(Z6lF!GpW>idiWPDA}+xwwbf>Eoe>+J=f;DQ6L8Q}4+BaL5-I4tY!iHl}2WT%l= zAuYsDtqYZ>mhB!PERC_>5j}r%?XdRruuLx*#FLvnus&XH$B0IV_PSf6ZWjlPQyQ%D zg;VlE_ZFzXBLZY;R1g7@G){;BMH(4IfC!BhBA}ecG{5&Mq~ar1(ek=S@-nLH(Y$#Y zW468DUZ8)cnlq`PDoczAitui!usd+Ag*Eye}*{n50Lp5$Ra%a#Jv!-B^^x zW@Sa$`RSOU7jW<$At`b4DK4{gCDeb!O$y$jW>X4UJt%RbyqZ47YQ_w3In!AhNH{o? zNG0?KfH0I}l+2A`P{U?%aJ<1S^^te*)5%c7V^+Z}M|5b;g5qOQ8*uROw~NNDQlg@E z!KIs~H)Mwd+eO zM_mmeM3Cb5<}V5yXXi5ch1!B^X4&K0D>8 z9|rZHqV>rYFmzClD4Y!ARwbf{prV#i^tMzrW?;>kZYlyyiG$vRI@ZR`*nu$L8iT4{ z60}zyZTrYh;-wK+rhGN=m#}dM7U8n9VpepY z0L!#oOf0bfl8VWn(&=L{|8?w{0GkRKH_2qPocnH4D@`hCSL17;Es52XuiR2ev#ID3 z2|mqwaB>Ha`mP8}WX6|q)s+_MI$}F@ZyJ)X*WeHOY&#ViM(P*YB zp@WpuTG!1N(70TRF)pTikop}XOrMZb1J&XK?!`X3M>1_5*f#pK;ZaTDIK&I1 z?8Z83xH~psU?USD!lKa~%JLjK1{gBXrk04Fjt3c3!82yTvS1ll>Oa53fbA$JtWu<} zyblAVugf<-Be$hYBNSl(Mt}pnm+R6l~^;;L0dRhq*sW%zP}ZhXth`H z$Seu=!QxUXrRVYfON*6Ps7yh9f9n`JAUDf5UuTo~wjn?vuvcXNMZ+^;u!0fEG8{l- z%SUgn05t@o(?~Be_q{xv>jkS_wf)xa|7ixm~o1FJWNd?QSolZq8V9EomN0b*2y} z{W6>QN#*avy&8>tsdl$|o+f1wt|_`u!*^`tWg3=Niz=26JLCe~fcnqF*!=$y3;Tjsme>V>J@Pt z{E1LA7_Uw_i6Bb_0&NZjR$Lx4KN1ZLL8a#>3D;+n4JOdtW9v=He77Dt*_Cun8u9$t z03G}+BZobAS4R6j#jB9|RV<0s*D}VNvzOoTpYYy)sJ6E zLkOMqq&;pV-|dRGaP_Tl)XWk*g!D|xRdhQ4lz!ogw5a5nKdqH^a07VBHsOR?-o#Mfm%JCU_jj5#MCch;I-rJ zKK>zV>SuH#>I7I=)k?ZWF(ch1Z9${-pb04xX>elU)Pi#V@~asZP(LIbJ%#eOEw6#L z)i(?C;kt?1-Got7e0V8Irt&d$iKJ+9^&NkwI3|f-X_Cvc#oymwouAOh|3F~Aa7Qjl z$ynoBH9h-Hm=RuKM7(U~hO7KC@WYucbxN5OC0v3!shXJkJ|$;k1-{_!8$klW(3u#$ zKk{l`3-L17)N-zxXH@S=$NLi*>*@n7G9rb$k2fRiw?ETiBj@Xv_!42A6qrob81+|L zcTyS7qj;Qj?2pvOlNsjFrK!0${h8xbn@25s{2>+}nZ@lp2GrZrD&xJ?gIz+iS?j7V zL~+!l+A!(9tP5R<@&QoqxK>pQ@ajn0yB~X3PG1;DVcoXUCnE)ZGMWpkm7!E$cDa@h zq{Z>%Beb6D_uwR8tUbwC$hkal@ zkdyC7hw*n^dy43Vk}v46#$gYY-WL(%qSZBHa4Y0Nv7>(~^J5v9GIgjcZP&?iJsBc$ z{;VF~jIc!pj?=^@&XnMcw1!te^lbT41Xj$o^N&Ee@q#;ukS?`_Ai09jrdXG>{M#qp zy5)Tb(gxl@;=Ew+mx%Fo@sr46Bg-6YEV{H70*p#Ro8gAJqfHja@PI;tb5=(OI4QY9 zwv&MLE`y3(-DteU`4&^_B~yatBkI;~ZEPWhu?MV{@#*;8kUlVks5hJ(-q!v7Zf^Eg z>nzP@^>Mn?TLh3EaNIxWK5t64V_E%4RW}Vfn3p(j)>B!J8`p?;I~WKj|A%Hxo)Hoh zc7yZd`U#2OIOlr2xl4r6j*n7H;CDH1!XO{a71A!JAO=pGRNq|mjKvN(xC3@26%ZL% zRJl;ePKZ&3b3y)%k(3)EoLCtC%-J*E8H|8aPzn_l$_~tTNtt9OH{M+Xbs)wx(|Pem@I$WM!R5h^ZAAvl z2i+0si%5Wy;+JccFL|=V$8Zoq#zpLn4&^U$`*RBcWx25BBdPDmFMq)=oC!Ul0%Irr z%`-Nfr69qTYAV!7-D99!JHgq~Wcf3smbK4Qd9Hn?d8Dt|jI z<#&fr-I7fyIca{2{#XcKhrSL&jg$7zmn^JfVcm~DgF!d{r3mUKlbup#5d%#EH%K4 zDFK3f7xVN^{vC=Wrp86urg02u^1KGK4om=HzIiv|1NsgR9cKmOk=J=T+%my6ro=8!!pXDK}r>QY)1;+*C%N~HFTQl z-k#FPTiH9(5@779HrWC(FoJMz(#rJx4G02!$Av~@3TMv8ZeS6T{_eN={yg~{do(kg zfocvmQ2gmDMjBG>u;((0zJH&K(KkMjzGpYPVG~-FNK3v^rY(*XAdEe7#~s0L6xBX# zHJ;sPi5tt6WTI)WLm;P;8SDGl!?%zKPLpiy`^Q%#`9@l1f)A->4_y>Oam2Fg`U)9X z5(-kFf;!od3t>86N%}v1#X=Ba2DGF5VHy7Yyy03vlL3)QM8Jam!9g2KFHdEkPWq#} z0s0>$`K_p}518YZ$axFFo3}a^DKM3U5OIEIvXD`_)kN~ubo>$Ocd;^e#7+Z`4=&2C zJGQr6JXmKWBlMQS@!s3O91;ri-zJ<{)7U6%jW} zs&_^>@cC`piXV1j(lD-0H!YKKk#jlL7IB%(r)}TWrWI_sJvr+k=!D{7Nm4iZ@7db2 zmK|?ip{@w6***PWJQ8{URX4AgS7{1czo??OKqpl0S&RwI?x`(@KC9vM8#OM^=6z>S zr`l#DM(5dBe@hg-$2=HcViALhl_4Va`^Y)j0w9PC2XasJxAs9npysFSK?AwJ+yvoQW;DKjP(R3rZ znMmBu$bvs%sk4@;4%+39drR95s@^Z{(ckFxOUr31NlOIcWtH_;<7W}JMiv6f+Sd&t zJJAjvT(xrgo)NX?Rr`}7E}qL;KsdFN!qs!@Denf}XZ@b(A9;0KzKns)D-ZTmF^DK= zzhfTYvI>ySE9FAQpDiWZanExHcy*C|avp^9w*h6s-!4pAF-Ahe;cP~Jgyctf__{?h zhYISF8pL`j<;V2^YuSh_H?hC%Q~dqql7xuD^4Z?E!7Otl0~7iDc=Oasmh17em7xEo z3Z}huANd@I=`ZbCRFTQYnp#E{%5y$X;9@!m^UM@(i^_1J{q)@h^(bJ7wxfv zpqf+_j8b9Y&Kf#m=_wj8<$)JnYzPTdF`Dp>U^)S1HRAg|Cz|uICAKXDT{I3S)_`D5 z7cJq02sN-BbcJ)#yoi3BiT2JPU{cFaO~D4!B&{AnJ^Wg=Eoe2<;7Yq-ndd#f1BJmq zYwS)HTT4jX9rk$y7YZ6(EO20~4qA8!TE~HIG&o*tA}csn2Yf7s7PSah zX+LOr0ELUK=XdCtbueEU{S}>L<$CPd0Vkr;K`XP+FmOP6tiCHNplhshGCFZM-ok3c zfu4IoDWxAEc7Kip)PPb1NPSJ`Q=P~pa@3!6`XIlcV6!9~%#rf?XkuZ@Y~+v0u*%+j zLqUKX7mVgQLa)$k1DHB3dMDPJw2h7T65;#ResATnUjO)XW&fv{&-2{_U;0cI3^BmK zkpH`i?CNC;__usKrM+&y&xz{GH0zK0x8?+WvKd(>nmaB4xiM$o(G#0I>x zb*w~S1}3?Po@yb=>5R~D^A_t}8>KiO7|9t_b#sk*uGX>5fRis79qEo74b~`bhxOr7 zDrsBUFY@WGSsYc-@5_kb%arBVDEx2aKcINN;llYE0cuQcU!S!cA9*CKSvRsTyNT?IrBF`dR~@>` zL`yX{JH+|VO>V`0UC9$1!kpY8e71WL14A038J!d~O>|fWpwBT#2Sb2<_OWheN63<#u z1Q#{ry7e*3_yA`wUo<8NR5Be)t>&~~z5Drs#zMfLkt{L(c6q#z!^* zNGog?yqfg>TuXQq=4~LT?LRAa;o6abXt@bhZPilhEh_=J)tfT5z(4=uH>k_iNyD39 z$C9G8>Z8vTv$JRVwZ<>DQsG+*ou;0E?vU=c<}W{+|5n*eC4zq?`KI`@xCIrSw@E0Y zQiqvSi>k~|aLLgr+{mKPGU(ke{e#tj-z=Z+_87y%RgTmH_ZPN3d&f_vud9nFZ!i8o zu1SP$a80)D^JtMI8#DW}BG(w)rQUCe<&`;%heB>lUn8q`$UWb_up2B2oMw{3oJ2|8YWL$! z3dJCVbm%q3k2gb8W82`uBw$MJ;PB`&$l2cA$S*bYK{kuiVrgsSO9O*0;38XVx%=%} z$Vh0kWy!sWH#tbd)uDIc_q+4oKciQ%95a`(^V30a8l9~U23igVt-tJ>$g2mfb-|s# zE6DJ++1A+WaiwIxWK9e_pdxH09i%dl+GfQM83W~V=TZPn6xF{UID=3b z7%WFp^`LqTPZPgFi{B9gJ|gqB9{Z13HfhRUL4N~keUsj;tJt~|fCVpE-ET7Y=heX& zXaSZrzTSRHR$2WegN+1C>6)2Iaro}Y-i^e8-v|vb{P1tS4(jZYbR{fQU!_^h#K(;4 zBb^54#f*CHhy*|z3ES^(*TM>|wb$1DvEAWEP$XC3uTqV3nV?jrIfbB5rzwS=xNdGE z_MV?^HTd1rWmhOY4U=fdq@?#;2=-JGiVv(nv< zQRLOp_|Sl-MVb};c%geLI>$E~`?zCWHi};G8NL_Or7%`VcQRqoy<%D{NcR}F)J>*)6UnqO zY}OQEdV56xahdcO6B*8C>~lYVkOUs$E7o9;8EtY=uBH~0APrMVsS5sOY!#JfiN zIkb!M6m~GU{4@M*hfN6Bxz~oYvPu2zVASrmfv<-l*#AAQcPdy!2QUh>HNw9K+|V%v z*T(mLJl+&?`=?xc86t~^n6@KrRi3#D;is*GUK3J1hG~Ql4w|`%8f0Jjdyyv>cxDVU zCBxqm;w2Y$N!AG>fijv;!}~Fr$IUtTfIKpIkE(ob(iQ@2{}SN zKYMJW2W3J$w=O-FYAG$5KPUYyw3<3i=Yk5hg;u%O&sKh+P`!R{6~G4E>TX6liaizB z|HK{~Ru=!^jL% z6zHkt>WLWR!{?~drx!c1?OVf#nX=zUbtDhF2oVvZ|2gc?FXA^Z!mfkbRgmw4)-Bn% zhr@O1SVZKB>n7+0Xry9jA9}L4>fvLu#XeDSal5Pk`Yi(7Y;Uf#N)gt*7Y@b^O0ar0 z_{_KU&6D;lL5nP`KxmzJsFinwH9eAYG7t0P8G*0u)I88_8z8;u=JXGaO;Ben$%$CMoIoim6YgX6}g1(_6@WY zRCbV}4c;M!zAO7$u4mSI$^j?EgQ~QB)I*22{qF-#1CApdS8|C%%A99XJk#_{&XWl1 zU^QhQ(_l7v1>_bKsk35KlJlU>`!j>&^^nDt!)nL16r^&p(YrAiD(WI+M&d?O{IVVpubz_muCa8hs>(wXi3jwzbtm4_R za-g>kskt}lsJ9`D1UGaU7(=Ll$kVqZKZWn~Tc(gNn7<`Q)zaM~lAk}ZPQ#wa)sb

-`E(`?J}XhoxsZ%xYizAYRP+CfD~B zBMZuOur~!osF-C+&tOtaR>!|4zRm)qe%m72w4(hPM zX3-`#uw8pjt64XsJw>H@aIw65bk?70(U0q@IW~#wY4KA1Ft@XhG5f zrn8%~d3GX)I;APXO^La}!(7$5J~Ze}J?h03v?2qoYw@vdVU{bHFnj6K_Qg-F1hYfV=#sSYtB~wATW1Zg`lu#qyE* z6aiWOk$buzUJ7s#91qsCYzGEMULDb10BUgE^?u{dvT9j^VM;MPGuNV{Hl_t=%Z$K0q^SS5wj~rHd$(7HZB|^R zvN0Z8r?xP~3Ji8)({`<~_PJ;W?NKzO=h?zku8s8N0xBUtC9$ljyGz5;n=Ts#$&!LG zlWsV1Z6uV|HnhIRU%a;Pr3L%GuWc}YbsNz!6d~M z9bXceq|Z@I4%(HiT)OH}+aoUvXcS&w_wVJT)R|!+zFVAiF-IER-({}6?rm6n+L6eJ z@VRVAyyoSPA0`=BvH@N94miZusA;PBMW`m;H@^(afnJV4+nPTMJn3e#wc@4{fHoj~ z4Pfzc>TQOF3J*GVuG|526n(`3!0B#6uD?)>AfZo^h8}$s6c8+1z%4Dh=xv4IX?;XagF-Dzmq|UrW zD-{0C?ChzVw~*0~P{prIls`VjYyRoA%fO#u)yPYJ2cL4G*dK2Liev!UUj4|@V3-wx z|DccEj+=kch~R>L<*qU?Dxvn8Fnu^sB>(WavB)i9UC_2)?d3i7d}3GO>DE)d2e}2- zZ50V29QVb~dF#H>2!i-|a_Dr>*q&z3R)OKQ0l<1pgBk(c8G8?0ag8P&ti6Rqys?9M zpmZvv-o%6o4khAp`LxVy3l^=BO-H0py7sV8Ih2hDqu6hInva)yoW@iT$u+M%wO$tM zEzMzjD1=VX*NJpN?jpEHEu0Jox$B&_TztJL{L&tEsQj9aA_yv0?`Xwick8(rIDI-$N zOpq4BD6K2SO?SsKj9X>zE|7%mqmXF(OB^_gD&6koQr+v=H=DZ;?b(pH%S-<)e^T1%l)= z=QZRpi}M5FO-xzqc^)Y+%(M&nf=uo?`|T4`Ht}DB)XZq-ziDn-%L1h-t-BPh>Ch9D zxt-V<(jk(TK6?wGPJ(xjCMQ^OOvJ>Yg|`bRaV6jmDnKSCjxaN6WBGoa$rm-?#P-=* z`fCbKjp{F$jJ}J{nY2Iy(i^DIg8n>Av#=ipC-|(_aJCwlBHoJ-$6MF*8SYgj%|n!1 z%1zp8mC=w$Z;^R*$V^b;kT~d{i^wkEY@>^R%5A&GYkRCZn!nt9Z2E3mw;&gvL!p0D zQWXxaZz#)eG4v*HJM4z_fT2pv6Zo+S7|*yIcPeZ_F0HIpTj7lwGAJ~rwDj%T={PBY zvj;9SJ4|1(9&_OF0yT_=X!M9!6rxJ%b)3;0;+<9Y<8u%N5$W512=KO7=bm*;7FPzs zbfL^?bEHiFmN4LNVZ>;rL>P(=o+Z&)erBaCGteEZ;_aNQT(+fVu)!6xZ8p&DcJJ27 zQ^A$1WMU`JN6OlZ8?bDITT|09UVRX@W!Jjy-o;?B^En*c7-2@TKytn*jdE5&F)_m~ zk>$r&c|OYTr!L4?wYQ+O_T{;fHt#%`+WCt1Fr^X?%QP4H5fi1B1XP@ee?U?R!~QXL z5`S9qpxPuEzhL-JB92g zE94)gBzvte-Yy|rrVu1&lNEtFD9c!Wt3GH`b|5Qf{k_{%TPp`j$z)P*mkxM47N9W{?p%Wg!Bs$}!~8TT!}J z9hJscAY<9p&`rjx8&&4&n2Bmw?s<+MLib7Z@CozW7|el<1Xj6Jo>=0wB$QSg&-ZdS z$?aZ}(^omF-ddiM=ogUvH&JX{+yyr-2R4QpU6#q-vSO>MCHVd~Xh&Bu1Kc3Xz(leT zmr}_VOxuqteCHJIK(BPMDtxm3I=m*BEy9IyQc5Yy?6*|@cxl3yq=yKzRiNz^g<3C@ z7fvFS@3^}-`XfaxS<<+MXkSOA|J51HJ2acat6!qG4T~6q|uW#rq0@|YW#1P+8&qNntH259Z;3MY@EPZE+ zr8pSNr#o{RG{+|^LL5-T^PaY#3iWBcb=p40A1c${|07!9CYWKB{J9o22KS#2e*C*0 z)zuPU2VnYl|1TbVp`#bQE{W;K^hXG;o3BTvp?e6=c2#lhf|BIC=)lP~zIr^4U6O4p z7CtbE|Djk}TFwZ;_gstynSFK^_?{jb!uf_Kz?M{<@xYxmS<*ydqg^!TG410rJ;#M@ z(B;ZhGL5Fl^Ic}W+OVwci{gl_Xp+u)HwS)7X3Zem`7wU*`|4ivG z0(=KNl-FZJ(yvn{eUN@d7#X`{_chYUnUe2t=A=^5@WS-6Ff7xi=HZhiwJ8RfIC}f? zQkY&K70Y>e9Cj(~a-!*T##sFzHZUC&{Z19G5xFBrIKRjv+H@%@gyGIV1PVD<9)jk# z?8JIFPV-<&n^UwGAO5QM%RcYjxpTwVSzFDwq;al8ZRWl^uko=KOx9?cq!xo$}H4dLIf5iTK>-c^HU+ z#cEOXpTEOUIB#NQOOH8_x*#M{$iwkYqKFm;mn@ePXbQEeZqlxiaho^10)wozwSX5U z6X^BTzfD|$#gJgq#1cW|aoW?jn6dd$V&db}6w`zm63U(~Da>DfrRoBd%Lo0R?iW*| z;MV%38`HW1;I}Q4eDDPo$Mu^wmHI0yMRJ9_-S2Kr#|Mp+2nBe({<>_nIs;Y=M8@S? zy`KiP{Cz>~_s2}zy*{sQzaOmlmv5Q;p7(|wdV41XV%p$_?;UcxJf9DqT8-Xs_f4Zg zicylhKGG&rIW~V++Q&`4<%J3n7CV@;#Gta!D?{}#)Vz?g1}vvVtT`IkhTXU$(3(OT z8g6j35sIIRqRP!^6|R6?u}OB)H^b~yT*yV=I3`YA1~t9#z29vT@tiR zTyP{;^1Olz#Pe_z>l_c*+#~7%t{!kKdmTz6H2b!+*?dE%q$bGY2{AFEv@taa-|iZk z&_dMl>Q{R&U2&RYJHq4T$-BNr=#HVVa140jFhE7wF@{r@{OAKEMA(v}q@8MyKC}nO z&oBcN{eyT~SM`;?cj?a81`Vt%^e6%ABjuranw~bqVot{h`H;vkXR5Ph&`(#C{*t6n zJKHmV558u*M@|GKz^2$Lfb4=|U4Jq_wF>LI$w~x{QAIB%O-`m~T<<3-qG{4Xt~p5m zkWXTJcuQ$``G{#)=Xl0v-@N*3u-KK1e$MB1m=fkN_y(KW8UA$~8Hs7~XzD?vO$e^_ zr5F3k?)vU&(k*|McxzbKpn7A!8WBX3|3{dfW^3R2a{9YrCQ_b?9qr<@b9Z8vlw*bi z2GRz-#Kee9#^0ET6Jk*p?H#QpPS+8aWwxs+oN%{ZYfU^8pNZBr0s1{(&i|*K^L~db z`{TGeg7_v8HA)a&bkX~0(V|345OwuFnTXzl(W4tZS_l$m5)45iyOvlbNQ@}+MU-F= z#AdOVZ+0iSvCs4U19pBn&pdZNujkx5=brnypL5>t-ksXfhm!?A;kwfKCxi}K*>)~) zK`D|Q&Yv=1 z)2>xXLwlnokGokSX^`y0Xw5|=(xv{UrY=p81YPaZ(vl(9j#O*Cb8;0lQbSo$yaRq% znq_5Va`F&n)zE(WOwIhQ|R)(smh&M&OizwH)2FD=P}XqY2RS;LahVs z6-(#gM`#+%VC$IfN{P{B?N7i#Ntrh}T_6^(LZ0rZ2)-8nEy;q6#FLNc8to9typ`g@CHU)+kVFwNuNG3iEbJ{=4noO>d~8 zy=xd_lBY@-e}6qT6S=}F&^TUm&vwu!JIb9Y8&kryBy+PO&Z71>l|Xv5092y?Aw7~kPLHy`HCM=K2!Ux*nwhGPA+C-z zuTF{cS`znr%D5fwr$i3s@|p*e4+L!Dc2OJleupMm1Cdm{f$bWRE0^w##kkZ>2@e%d zFTIwT(}@LE^f8rspLBUzQ=f-fv9`SJi!zyyP#4arHhP$#cr7E!+_Du@dL<2spb}zA zEaYQR^BX&;5o{ma{a_nwl`J2t6QU9QLGF^&>|9G3YFUF!_;J);U(}V&2j=OiznEEm zEG}T_u7z-;>ztNR^qPj6WmPt>$)~bszVPHa_z!zitj`H)k>w~_i2QQ*y~cEK$JUyn zQ6eKVDTO>-doUz{J<3&5+ZN-xwb!?3T=ZT+eogp8Fip`Do=r8i;S5@@$u3{HLG2sa z9CY1@`zul}7VXQfw5xskLmgjEy2995&Qf;=diFh+wopuf&1!X2`hKEEFCy_g9@_jedMrZlnd;-1 z;xilE)`1kca!VfOp~?T5J^O_>M9R*t`(?zXcPL`M1r<|LLxX4HGoBIba}qJ-JM9W0vN z+{Ql%WzqNa^@^?me&AWJ`r_b^{Vt~dN$fSYq#L9rd1#+~Eb~ZFel7ceNKw3WE|V`T zx6VrprMBq2>e)uw-V3jR?N@uS(M%0pwESo(T$r)o6&^Xo*$SC!^KA$$Z%aw>=*z;5 zx?S(wC5x?`ZNpP7AZtfdcQLcnJO_Xs$d6;&j_Q(yDv-I|0><|_z@Ns+$I-~&$2UOK z(Z}EUXix)IPXF4{0MkNJ#_J?zGlwS*a2ZA&+yMIp!I5(p>zECDMy}O6qMZW(IY2i#Z?H)E0uQ;U#(y0 z^ziy(zxh%my;jxGelSBi9P+M`;#5j0G3BocNL~TuU?t0?1JA{*bknggpKimSpE;su zDExfat(BOtXoCq%>bcFT&t7|K%F4OX#4hZnVC${KlQI{P&iBZAd z#YG(4ys2DtoOMWWR1k6qV_Zm_Q=CbhHHS)SDH%VGl}sgYER;U~1hY0mzE zbrwrzW+rA^zxjX%L~dbm{19Fa8qUxN-b^A+?*Lz>RI}W3f>dRB5lk9~6eO@7k)p6t z-P0-&^^SJ3ce;eAi`iI>0_@zGx_Iy79vY*dN@R9RiA>>t5D8N4&}@*@(Ax!yJ8)e* z@eGyTD5qh78_NVZ!?WMsSoXfY|K3-?CHwk8W*YloInG8*A2||Du^^lK@=uu>ELAFd z+Pr!8{=XUp$cotg~~G#w^jwA7w~Ed1;b0+rDS#fEof}! zl#9xMhyW$Omq>C`+OQH?5RY;=&STvjU(K2JwmU8}JAOOkafxoVQ|`+r$ywcdx(?RA z3kPVH(pxKRTSsb2>t)DAvqin;RH;p+ahvvgH=|v!V2BC>mTt$5E%83Ly_z$a?g)gr z&D;2rXRIrb$2HlfYq!xeR!bjM?5N=(IW+vR zBC>r^c5G6HHgn17Rkus+*$n08h;4+3^leqq1KC45U82)S&5~>I*)+CSzpG!C=YUk% zVM`bjVoiJW%Omk^mU^k{OrmkG3Zd)R6{pRi&QCsyErEA~WZ3fA3l&_YA@UbVZIU88 zk|GxzOBx(Y`osrup^J0g2W`n&weD`axE*gEVa}wqHY}4LoF892p&a`~K46@7RxGvZ zYKK6@J;fBfpKU5-*m>=t0(9@gOgQyk`(h6+ruC@picC^ zM+q^BFd!vA+1>N6fB3KV1g}pcz3&0vTMGUac+~a-g{yB22El>f+pK*XxB(O&{@HX5 z%mLeH5lHsHo_CO$7C0DeRYVAuIQ@6>? zj3@TvSOpHIfTdpqN+U4ieZ3Ulp3Sik3`_ybA_$ZTZZPFUkpvhBRv8e0lRRJ`L2m)3 zfH$!cC@+MLDFJ_PX$6OZ_rHA;3drzJxGu-L;lLE|&K3eiRO&>^@je$Y1-wc{pwuXy zNI71!0#m@{Ujijt?L^9PF&In%SNaH)4d^iiT=xS5z^_>Z08017ZXCaKfhpf7v;+nb zQMv&U(GTe@I2@dq5CEr)jyv)Hq$yzN_qhN8Nkp^^K>zO3*UZ33j~tk@jx0Lph|GbR JcGC3d+n>A!MB4xW literal 0 HcmV?d00001 From a770a309f90ee7021406fd7e14d591d1332bd336 Mon Sep 17 00:00:00 2001 From: CeresBarros Date: Thu, 7 Apr 2022 13:42:07 -0700 Subject: [PATCH 009/148] need LandR@LANDISinitialB to pass `initialB = NA/NULL` --- Biomass_core.R | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Biomass_core.R b/Biomass_core.R index 5f3a5ce..9b16d83 100644 --- a/Biomass_core.R +++ b/Biomass_core.R @@ -21,7 +21,7 @@ defineModule(sim, list( reqdPkgs = list("assertthat", "compiler", "crayon", "data.table", "dplyr", "fpCompare", "ggplot2", "grid", "parallel", "purrr", "quickPlot", "raster", "Rcpp", "R.utils", "scales", "sp", "tidyr", - "PredictiveEcology/LandR@development (>= 1.0.7.9010)", + "PredictiveEcology/LandR@LANDISinitialB (>= 1.0.7.9013)", "PredictiveEcology/pemisc@development", "PredictiveEcology/reproducible@development", "PredictiveEcology/SpaDES.core@development (>= 1.0.8.9000)", From c9c35fb1b4f29598be49b0ba079e8044b06bb8c8 Mon Sep 17 00:00:00 2001 From: CeresBarros Date: Mon, 11 Apr 2022 21:26:09 -0700 Subject: [PATCH 010/148] use LandR::sppHarmonize to make sppEquiv etc. --- Biomass_core.R | 66 ++++++++++++++++---------------------------------- 1 file changed, 21 insertions(+), 45 deletions(-) diff --git a/Biomass_core.R b/Biomass_core.R index 4b9c637..139b4a6 100644 --- a/Biomass_core.R +++ b/Biomass_core.R @@ -21,7 +21,7 @@ defineModule(sim, list( reqdPkgs = list("assertthat", "compiler", "crayon", "data.table", "dplyr", "fpCompare", "ggplot2", "grid", "parallel", "purrr", "quickPlot", "raster", "Rcpp", "R.utils", "scales", "sp", "tidyr", - "PredictiveEcology/LandR@development (>= 1.0.7.9010)", + "PredictiveEcology/LandR@development (>= 1.0.7.9015)", "PredictiveEcology/pemisc@development", "PredictiveEcology/reproducible@development", "PredictiveEcology/SpaDES.core@development (>= 1.0.8.9000)", @@ -189,6 +189,11 @@ defineModule(sim, list( "and should also contain a color for 'Mixed'")), expectsInput("sppEquiv", "data.table", desc = "table of species equivalencies. See `LandR::sppEquivalencies_CA`."), + expectsInput("sppNameVector", "character", + desc = paste("an optional vector of species names to be pulled from `sppEquiv`. Species names must match", + "`P(sim)$sppEquivCol` column in `sppEquiv`. If not provided, then species will be taken from", + "the entire `P(sim)$sppEquivCol` column in `sppEquiv`.", + "See `LandR::sppEquivalencies_CA`.")), expectsInput("studyArea", "SpatialPolygonsDataFrame", desc = paste("Polygon to use as the study area. Must be provided by the user")), expectsInput("studyAreaReporting", "SpatialPolygonsDataFrame", @@ -2061,52 +2066,23 @@ CohortAgeReclassification <- function(sim) { sim$sufficientLight <- data.frame(sufficientLight, stringsAsFactors = FALSE) } - if (is.null(sim$sppEquiv)) { - data("sppEquivalencies_CA", package = "LandR", envir = environment()) - sim$sppEquiv <- as.data.table(sppEquivalencies_CA) - } - if (!is.null(sim$sppNameVector)) { - if (!exists("sppEquivalencies_CA", inherits = FALSE)) - message("Both sppEquiv and sppNameVector are supplied; subsetting sppEquiv with species in sppNameVector") - speciesNameConvention <- LandR::equivalentNameColumn(sim$sppNameVector, LandR::sppEquivalencies_CA) - sim$sppEquiv <- sim$sppEquiv[sim$sppEquiv[[speciesNameConvention]] %in% sim$sppNameVector,] - } - - ## By default, Abies_las is renamed to Abies_sp - sim$sppEquiv[KNN == "Abie_Las", LandR := "Abie_sp"] # TODO: This should be removed as a hard coded thing + ## make sppEquiv table and associated columns, vectors + ## do not use suppliedElsewhere here as we need the tables to exist (or not) + ## already (rather than potentially being supplied by a downstream module) + ## the function checks whether the tables exist internally. + ## check parameter consistency across modules + paramCheckOtherMods(sim, "sppEquivCol", ifSetButDifferent = "error") + paramCheckOtherMods(sim, "vegLeadingProportion", ifSetButDifferent = "error") + + sppOuts <- sppHarmonize(sim$sppEquiv, sim$sppNameVector, P(sim)$sppEquivCol, + sim$sppColorVect, P(sim)$vegLeadingProportion) + ## the following may, or may not change inputs + sim$sppEquiv <- sppOuts$sppEquiv + sim$sppNameVector <- sppOuts$sppNameVector + P(sim)$sppEquivCol <- sppOuts$sppEquivCol + sim$sppColorVect <- sppOuts$sppColorVect ## check spp column to use - # if (P(sim)$sppEquivCol == "Boreal") { - # message(paste("There is no 'sppEquiv' table supplied;", - # "will attempt to use species listed under 'Boreal'", - # "in the 'LandR::sppEquivalencies_CA' table")) - # } else { - if (any(grepl(P(sim)$sppEquivCol, names(sim$sppEquiv)))) { - message(paste("Using species listed under", P(sim)$sppEquivCol, - "column in the 'sim$sppEquiv' table")) - } else { - stop("'P(sim)$sppEquivCol' is not a column in 'sim$sppEquiv'.", - "Please provide conforming 'sppEquivCol', 'sppEquiv' and 'sppColorVect'") - } - #} - - ## remove empty lines/NAs - sim$sppEquiv <- sim$sppEquiv[!"", on = P(sim)$sppEquivCol] - sim$sppEquiv <- na.omit(sim$sppEquiv, P(sim)$sppEquivCol) - - if (is.null(sim$sppColorVect)) { - ## add default colors for species used in model - sim$sppColorVect <- sppColors(sim$sppEquiv, P(sim)$sppEquivCol, - newVals = "Mixed", palette = "Accent") - message("No 'sppColorVect' provided; using default colour palette: Accent") - } - - if (P(sim)$vegLeadingProportion > 0 & is.na(sim$sppColorVect['Mixed'])) { - stop("vegLeadingProportion is > 0 but there is no 'Mixed' color in sim$sppColorVect. ", - "Please supply sim$sppColorVect with a 'Mixed' color or set vegLeadingProportion to zero.") - } - - if (!suppliedElsewhere("treedFirePixelTableSinceLastDisp", sim)) { sim$treedFirePixelTableSinceLastDisp <- data.table(pixelIndex = integer(), pixelGroup = integer(), From 8e0a17d1273fe375a4be9968d29c0ddf7ca7e4ac Mon Sep 17 00:00:00 2001 From: CeresBarros Date: Mon, 11 Apr 2022 21:26:21 -0700 Subject: [PATCH 011/148] minor --- Biomass_core.R | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/Biomass_core.R b/Biomass_core.R index 139b4a6..9304a7c 100644 --- a/Biomass_core.R +++ b/Biomass_core.R @@ -2082,13 +2082,14 @@ CohortAgeReclassification <- function(sim) { P(sim)$sppEquivCol <- sppOuts$sppEquivCol sim$sppColorVect <- sppOuts$sppColorVect - ## check spp column to use + ## make empty treedFirePixelTableSinceLastDisp if (!suppliedElsewhere("treedFirePixelTableSinceLastDisp", sim)) { sim$treedFirePixelTableSinceLastDisp <- data.table(pixelIndex = integer(), pixelGroup = integer(), burnTime = numeric()) } + ## get default species layers if (!suppliedElsewhere("speciesLayers", sim)) { message("No RasterStack map of biomass X species is provided; using KNN") url <- paste0("http://ftp.maps.canada.ca/pub/nrcan_rncan/Forests_Foret/", @@ -2117,6 +2118,7 @@ CohortAgeReclassification <- function(sim) { sppEquivCol = P(sim)$sppEquivCol) } + ## if not using LandR growth/mortality drivers... (assumes LandR.CS) if (P(sim)$growthAndMortalityDrivers != 'LandR') { if (!suppliedElsewhere("cceArgs", sim)) { sim$cceArgs <- list(quote(CMI), From 50f278c82836ed3c776de5298aa9e18b294f42dd Mon Sep 17 00:00:00 2001 From: CeresBarros Date: Mon, 11 Apr 2022 21:52:22 -0700 Subject: [PATCH 012/148] bump LandR version --- Biomass_core.R | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Biomass_core.R b/Biomass_core.R index 9b16d83..bcacb3a 100644 --- a/Biomass_core.R +++ b/Biomass_core.R @@ -21,7 +21,7 @@ defineModule(sim, list( reqdPkgs = list("assertthat", "compiler", "crayon", "data.table", "dplyr", "fpCompare", "ggplot2", "grid", "parallel", "purrr", "quickPlot", "raster", "Rcpp", "R.utils", "scales", "sp", "tidyr", - "PredictiveEcology/LandR@LANDISinitialB (>= 1.0.7.9013)", + "CeresBarros/LandR@LANDISinitialB (>= 1.0.7.9015)", "PredictiveEcology/pemisc@development", "PredictiveEcology/reproducible@development", "PredictiveEcology/SpaDES.core@development (>= 1.0.8.9000)", From 2aedd9404cb34aed2a465373b99e13f82539604c Mon Sep 17 00:00:00 2001 From: CeresBarros Date: Tue, 12 Apr 2022 11:09:11 -0600 Subject: [PATCH 013/148] bump LandR version --- Biomass_core.R | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Biomass_core.R b/Biomass_core.R index f43ef69..46386e5 100644 --- a/Biomass_core.R +++ b/Biomass_core.R @@ -21,7 +21,7 @@ defineModule(sim, list( reqdPkgs = list("assertthat", "compiler", "crayon", "data.table", "dplyr", "fpCompare", "ggplot2", "grid", "parallel", "purrr", "quickPlot", "raster", "Rcpp", "R.utils", "scales", "sp", "tidyr", - "CeresBarros/LandR@LANDISinitialB (>= 1.0.7.9015)", + "CeresBarros/LandR@LANDISinitialB (>= 1.0.7.9016)", "PredictiveEcology/pemisc@development", "PredictiveEcology/reproducible@development", "PredictiveEcology/SpaDES.core@development (>= 1.0.8.9000)", From 2c0ed2552bdf48e5b9665859825d6da2f6dfb08a Mon Sep 17 00:00:00 2001 From: CeresBarros Date: Tue, 12 Apr 2022 14:54:50 -0700 Subject: [PATCH 014/148] bump LandR --- Biomass_core.R | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Biomass_core.R b/Biomass_core.R index f43ef69..8aee85b 100644 --- a/Biomass_core.R +++ b/Biomass_core.R @@ -21,7 +21,7 @@ defineModule(sim, list( reqdPkgs = list("assertthat", "compiler", "crayon", "data.table", "dplyr", "fpCompare", "ggplot2", "grid", "parallel", "purrr", "quickPlot", "raster", "Rcpp", "R.utils", "scales", "sp", "tidyr", - "CeresBarros/LandR@LANDISinitialB (>= 1.0.7.9015)", + "CeresBarros/LandR@LANDISinitialB (>= 1.0.7.9017)", "PredictiveEcology/pemisc@development", "PredictiveEcology/reproducible@development", "PredictiveEcology/SpaDES.core@development (>= 1.0.8.9000)", From 703ba7cd7916d3c6758823518bdd3c60cfc74097 Mon Sep 17 00:00:00 2001 From: CeresBarros Date: Tue, 12 Apr 2022 15:04:20 -0700 Subject: [PATCH 015/148] add assertSppVectors --- Biomass_core.R | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/Biomass_core.R b/Biomass_core.R index 849d004..e8dcfd7 100644 --- a/Biomass_core.R +++ b/Biomass_core.R @@ -641,6 +641,9 @@ Init <- function(sim, verbose = getOption("LandR.verbose", TRUE)) { sim$sppColorVect <- tempObjs$sppColorVect rm(tempObjs) + assertSppVectors(sppEquiv = sim$species, sppEquivCol = "speciesCode", + sppColorVect = sim$sppColorVect) + pixelTable <- makePixelTable(speciesLayers = sim$speciesLayers, #species = sim$species, standAgeMap = standAgeMap, ecoregionFiles = ecoregionFiles, biomassMap = rawBiomassMap, rasterToMatch = sim$rasterToMatch, @@ -1626,6 +1629,8 @@ summaryRegen <- compiler::cmpfun(function(sim) { plotSummaryBySpecies <- compiler::cmpfun(function(sim) { LandR::assertSpeciesPlotLabels(sim$species$species, sim$sppEquiv) + assertSppVectors(sppEquiv = sim$sppEquiv, sppEquivCol = sim$sppEquivCol, + sppColorVect = cols2) checkPath(file.path(outputPath(sim), "figures"), create = TRUE) @@ -1774,6 +1779,8 @@ plotSummaryBySpecies <- compiler::cmpfun(function(sim) { plotVegAttributesMaps <- compiler::cmpfun(function(sim) { LandR::assertSpeciesPlotLabels(sim$species$species, sim$sppEquiv) + assertSppVectors(sppEquiv = sim$sppEquiv, sppEquivCol = sim$sppEquivCol, + sppColorVect = sim$sppColorVect) ## these plots are not saved. plotTypes <- "screen" From 258c157d6943f330335e2f30b15dfeea9f67bb24 Mon Sep 17 00:00:00 2001 From: CeresBarros Date: Tue, 12 Apr 2022 15:04:43 -0700 Subject: [PATCH 016/148] bump LandR --- Biomass_core.R | 1 + 1 file changed, 1 insertion(+) diff --git a/Biomass_core.R b/Biomass_core.R index e8dcfd7..1f050f9 100644 --- a/Biomass_core.R +++ b/Biomass_core.R @@ -22,6 +22,7 @@ defineModule(sim, list( "ggplot2", "grid", "parallel", "purrr", "quickPlot", "raster", "Rcpp", "R.utils", "scales", "sp", "tidyr", "PredictiveEcology/LandR@development (>= 1.0.7.9015)", + "PredictiveEcology/LandR@development (>= 1.0.7.9016)", "PredictiveEcology/pemisc@development", "PredictiveEcology/reproducible@development", "PredictiveEcology/SpaDES.core@development (>= 1.0.8.9000)", From d1dded6ba85aac17f44e7c26e061a19a8b35f56b Mon Sep 17 00:00:00 2001 From: CeresBarros Date: Tue, 12 Apr 2022 15:04:54 -0700 Subject: [PATCH 017/148] add missing dependency --- Biomass_core.R | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Biomass_core.R b/Biomass_core.R index 1f050f9..93ac718 100644 --- a/Biomass_core.R +++ b/Biomass_core.R @@ -21,7 +21,7 @@ defineModule(sim, list( reqdPkgs = list("assertthat", "compiler", "crayon", "data.table", "dplyr", "fpCompare", "ggplot2", "grid", "parallel", "purrr", "quickPlot", "raster", "Rcpp", "R.utils", "scales", "sp", "tidyr", - "PredictiveEcology/LandR@development (>= 1.0.7.9015)", + "RandomFields", "PredictiveEcology/LandR@development (>= 1.0.7.9016)", "PredictiveEcology/pemisc@development", "PredictiveEcology/reproducible@development", From 832b8ced21bfa34bf2d7fed7352a7e1e9bb4272b Mon Sep 17 00:00:00 2001 From: CeresBarros Date: Tue, 12 Apr 2022 15:04:20 -0700 Subject: [PATCH 018/148] add assertSppVectors --- Biomass_core.R | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/Biomass_core.R b/Biomass_core.R index 9304a7c..cb2ce39 100644 --- a/Biomass_core.R +++ b/Biomass_core.R @@ -634,6 +634,9 @@ Init <- function(sim, verbose = getOption("LandR.verbose", TRUE)) { sim$sppColorVect <- tempObjs$sppColorVect rm(tempObjs) + assertSppVectors(sppEquiv = sim$species, sppEquivCol = "speciesCode", + sppColorVect = sim$sppColorVect) + pixelTable <- makePixelTable(speciesLayers = sim$speciesLayers, #species = sim$species, standAgeMap = standAgeMap, ecoregionFiles = ecoregionFiles, biomassMap = rawBiomassMap, rasterToMatch = sim$rasterToMatch, @@ -1617,6 +1620,8 @@ summaryRegen <- compiler::cmpfun(function(sim) { plotSummaryBySpecies <- compiler::cmpfun(function(sim) { LandR::assertSpeciesPlotLabels(sim$species$species, sim$sppEquiv) + assertSppVectors(sppEquiv = sim$sppEquiv, sppEquivCol = sim$sppEquivCol, + sppColorVect = cols2) checkPath(file.path(outputPath(sim), "figures"), create = TRUE) @@ -1765,6 +1770,8 @@ plotSummaryBySpecies <- compiler::cmpfun(function(sim) { plotVegAttributesMaps <- compiler::cmpfun(function(sim) { LandR::assertSpeciesPlotLabels(sim$species$species, sim$sppEquiv) + assertSppVectors(sppEquiv = sim$sppEquiv, sppEquivCol = sim$sppEquivCol, + sppColorVect = sim$sppColorVect) ## these plots are not saved. plotTypes <- "screen" From ce6a18a779afbce5edfcefb02afc4e106873e52c Mon Sep 17 00:00:00 2001 From: CeresBarros Date: Wed, 13 Apr 2022 15:39:24 -0700 Subject: [PATCH 019/148] add missing dependency --- Biomass_core.R | 1 + 1 file changed, 1 insertion(+) diff --git a/Biomass_core.R b/Biomass_core.R index cb2ce39..820f08d 100644 --- a/Biomass_core.R +++ b/Biomass_core.R @@ -21,6 +21,7 @@ defineModule(sim, list( reqdPkgs = list("assertthat", "compiler", "crayon", "data.table", "dplyr", "fpCompare", "ggplot2", "grid", "parallel", "purrr", "quickPlot", "raster", "Rcpp", "R.utils", "scales", "sp", "tidyr", + "RandomFields", "PredictiveEcology/LandR@development (>= 1.0.7.9015)", "PredictiveEcology/pemisc@development", "PredictiveEcology/reproducible@development", From 163421c79c62980d08852f9a1a044ae273050de3 Mon Sep 17 00:00:00 2001 From: CeresBarros Date: Thu, 21 Apr 2022 14:36:34 -0600 Subject: [PATCH 020/148] bugfix: sppEquivCol is a parameter --- Biomass_core.R | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Biomass_core.R b/Biomass_core.R index 820f08d..da7a0d9 100644 --- a/Biomass_core.R +++ b/Biomass_core.R @@ -1621,7 +1621,7 @@ summaryRegen <- compiler::cmpfun(function(sim) { plotSummaryBySpecies <- compiler::cmpfun(function(sim) { LandR::assertSpeciesPlotLabels(sim$species$species, sim$sppEquiv) - assertSppVectors(sppEquiv = sim$sppEquiv, sppEquivCol = sim$sppEquivCol, + assertSppVectors(sppEquiv = sim$sppEquiv, sppEquivCol = P(sim)$sppEquivCol, sppColorVect = cols2) checkPath(file.path(outputPath(sim), "figures"), create = TRUE) @@ -1771,7 +1771,7 @@ plotSummaryBySpecies <- compiler::cmpfun(function(sim) { plotVegAttributesMaps <- compiler::cmpfun(function(sim) { LandR::assertSpeciesPlotLabels(sim$species$species, sim$sppEquiv) - assertSppVectors(sppEquiv = sim$sppEquiv, sppEquivCol = sim$sppEquivCol, + assertSppVectors(sppEquiv = sim$sppEquiv, sppEquivCol = P(sim)$sppEquivCol, sppColorVect = sim$sppColorVect) ## these plots are not saved. From 8e035b2b83f07735b2e3aca6c156034955478b3e Mon Sep 17 00:00:00 2001 From: CeresBarros Date: Fri, 22 Apr 2022 11:20:57 -0700 Subject: [PATCH 021/148] bugfix, can't assign to P(sim) (duh!) --- Biomass_core.R | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Biomass_core.R b/Biomass_core.R index da7a0d9..45af6ad 100644 --- a/Biomass_core.R +++ b/Biomass_core.R @@ -2087,7 +2087,7 @@ CohortAgeReclassification <- function(sim) { ## the following may, or may not change inputs sim$sppEquiv <- sppOuts$sppEquiv sim$sppNameVector <- sppOuts$sppNameVector - P(sim)$sppEquivCol <- sppOuts$sppEquivCol + P(sim, module = currentModule(sim))$sppEquivCol <- sppOuts$sppEquivCol sim$sppColorVect <- sppOuts$sppColorVect ## make empty treedFirePixelTableSinceLastDisp From e7f210ad1095b98c92a8ec675ed7acc8ec2db72b Mon Sep 17 00:00:00 2001 From: CeresBarros Date: Mon, 2 May 2022 13:50:19 -0700 Subject: [PATCH 022/148] bugfix: pass `studyArea` to `sppHarmonize` --- Biomass_core.R | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Biomass_core.R b/Biomass_core.R index 45af6ad..107e693 100644 --- a/Biomass_core.R +++ b/Biomass_core.R @@ -2083,7 +2083,7 @@ CohortAgeReclassification <- function(sim) { paramCheckOtherMods(sim, "vegLeadingProportion", ifSetButDifferent = "error") sppOuts <- sppHarmonize(sim$sppEquiv, sim$sppNameVector, P(sim)$sppEquivCol, - sim$sppColorVect, P(sim)$vegLeadingProportion) + sim$sppColorVect, P(sim)$vegLeadingProportion, sim$studyArea) ## the following may, or may not change inputs sim$sppEquiv <- sppOuts$sppEquiv sim$sppNameVector <- sppOuts$sppNameVector From ac032f1a2b5682792e58d3cb7171c594ce128f0e Mon Sep 17 00:00:00 2001 From: Alex Chubaty Date: Tue, 3 May 2022 09:56:10 -0600 Subject: [PATCH 023/148] minor cleanup --- Biomass_core.R | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/Biomass_core.R b/Biomass_core.R index 107e693..e9597d2 100644 --- a/Biomass_core.R +++ b/Biomass_core.R @@ -2092,9 +2092,9 @@ CohortAgeReclassification <- function(sim) { ## make empty treedFirePixelTableSinceLastDisp if (!suppliedElsewhere("treedFirePixelTableSinceLastDisp", sim)) { - sim$treedFirePixelTableSinceLastDisp <- data.table(pixelIndex = integer(), - pixelGroup = integer(), - burnTime = numeric()) + sim$treedFirePixelTableSinceLastDisp <- data.table(pixelIndex = integer(0), + pixelGroup = integer(0), + burnTime = numeric(0)) } ## get default species layers @@ -2127,7 +2127,7 @@ CohortAgeReclassification <- function(sim) { } ## if not using LandR growth/mortality drivers... (assumes LandR.CS) - if (P(sim)$growthAndMortalityDrivers != 'LandR') { + if (P(sim)$growthAndMortalityDrivers != "LandR") { if (!suppliedElsewhere("cceArgs", sim)) { sim$cceArgs <- list(quote(CMI), quote(ATA), @@ -2143,7 +2143,6 @@ CohortAgeReclassification <- function(sim) { # } } - gc() ## AMC added this 2019-08-20 return(invisible(sim)) From cafee08cdcd13b36b9bda2085df47a0c9c19252e Mon Sep 17 00:00:00 2001 From: CeresBarros Date: Fri, 27 May 2022 15:11:11 -0700 Subject: [PATCH 024/148] fix figure size -manual --- Biomass_core.Rmd | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/Biomass_core.Rmd b/Biomass_core.Rmd index 0461ac4..ccb9de8 100644 --- a/Biomass_core.Rmd +++ b/Biomass_core.Rmd @@ -431,8 +431,9 @@ mySim <- simInitAndSpades(times = times, debug = TRUE) ``` -```{r figBiomassCoreOutPlots, echo = FALSE, eval = TRUE, fig.show='hold', fig.cap = "_Biomass_core_ automatically generates simulation visuals of species dynamics across the landscape in terms of total biomass, number of presences and age and productivity (above), as well as yearly plots of total biomass, productivity, mortality, reproduction and leading species in each pixel (below)."} -knitr::include_graphics(c("figures/Biomass_coreOutPlots1.png", "figures/Biomass_coreOutPlots2.png")) +```{r fig-Biomass-coreOutPlots, echo = FALSE, eval = TRUE, fig.show='hold', out.width = "50%", fig.cap = "(ref:Biomass-core) automatically generates simulation visuals of species dynamics across the landscape in terms of total biomass, number of presences and age and productivity (above), as well as yearly plots of total biomass, productivity, mortality, reproduction and leading species in each pixel (below)."} +knitr::include_graphics(normalizePath(c("figures/Biomass_coreOutPlots1.png", + "figures/Biomass_coreOutPlots2.png"), winslash = "/")) ``` # Appendix From 71486746447b02b810e9a01363953bbb674994f6 Mon Sep 17 00:00:00 2001 From: CeresBarros Date: Thu, 2 Jun 2022 12:06:25 -0700 Subject: [PATCH 025/148] table fixes -- not finished --- Biomass_core.Rmd | 99 +++++------------------------------------------- 1 file changed, 9 insertions(+), 90 deletions(-) diff --git a/Biomass_core.Rmd b/Biomass_core.Rmd index 84b0e56..048b893 100644 --- a/Biomass_core.Rmd +++ b/Biomass_core.Rmd @@ -367,34 +367,15 @@ species traits. Note that *Biomass_core* (alone) requires all the columns Table Please see @SchellerDomingo2011 [p.18] and @SchellerMiranda2015 [p.16] for further detail. - - ```{r invariantSpptraits, echo = FALSE, eval = TRUE, message = FALSE} -tab <- openxlsx::read.xlsx("tables/exampleTables.xlsx", sheet = "invariantTraits", - colNames = TRUE, sep.names = " ") +tab <- read.csv(normPath("tables/invariantTraits_example.csv")) caption <- paste("Example of an invariant species traits table (the", "`species` table object in the module), with species (ref:Abie-sp),", "(ref:Pice-eng), (ref:Pice-gla), (ref:Pinu-sp), (ref:Popu-sp) and (ref:Pseud-men).", " Note that these are theoretical values.") knitr::kable(tab, caption = caption) %>% - kableExtra::kable_styling(latex_options = c("repeat_header")) + kableExtra::kable_styling(latex_options = c("repeat_header", "scale_down")) %>% + kableExtra::landscape(.) ``` #### Spatio-temporally varying species traits {#varying-traits} @@ -412,41 +393,8 @@ further calibrates `maxB` and `maxANPP` by estimating two additional invariant species traits (`inflationFactor` and `mANPPproportion`; also for Western Canadian forests). See Table \@ref(tab:varyingSpptraits) for an example. - - ```{r varyingSpptraits, echo = FALSE, eval = TRUE, message = FALSE} -tab <- openxlsx::read.xlsx("tables/exampleTables.xlsx", sheet = "spatially_varyingTraits", - colNames = TRUE, sep.names = " ") -names(tab)[grep("X", names(tab))] <- "" +tab <- read.csv(normPath("tables/spatiallyVaryingTraits_example.csv")) caption <- paste("Example of a spatio-temporally varying species traits", "table (the `speciesEcoregion` table object in the module), with two ecolocations", "(called `ecoregionGroups`) and species (ref:Abie-sp),", @@ -454,7 +402,7 @@ caption <- paste("Example of a spatio-temporally varying species traits", "If a simulation runs for 10 year using this table, trait values from", "year 2 would be used during simulation years 2-10.") knitr::kable(tab, caption = caption) %>% - kableExtra::kable_styling(latex_options = c("repeat_header")) + kableExtra::kable_styling(latex_options = c("repeat_header", "scale_down")) ``` #### Ecolocation-specific parameters -- minimum relative biomass {#ecolocation-traits} @@ -480,21 +428,8 @@ Western Canada boreal forest dynamics (see Table \@ref(tab:minRelB)). inputs, these values can be adjusted by using other modules or by passing user-defined tables. - - ```{r minRelB, echo = FALSE, eval = TRUE, message = FALSE} -tab <- openxlsx::read.xlsx("tables/exampleTables.xlsx", sheet = "minRelativeB", - colNames = TRUE, sep.names = " ") -names(tab)[grep("X", names(tab))] <- "" +tab <- read.csv(normPath("tables/minRelativeB_example.csv")) caption <- paste("Example of a minimum relative biomass table (the `minRelativeB`", "table object in the module), with two ecolocations (`ecoregionGroups`) sharing", "the same values") @@ -506,35 +441,19 @@ knitr::kable(tab, caption = caption) %>% A species' probability of germination results from the combination of its shade tolerance level (an invariant species trait in the `species` table; Table -\ref\@(tab:invariantSpptraits)) and the site shade [defined by the amount of +\ref@(tab:invariantSpptraits)) and the site shade [defined by the amount of biomass in the pixel -- see [minimum relative biomass parameter](#ecolocation-traits) and @SchellerMiranda2015,p.14]. By default, both *Biomass_core* and *Biomass_borealDataPrep* use a publicly available LANDIS-II table (called `sufficientLight` in the module; Table \@ref(tab:suffLight)). - - ```{r suffLight, echo = FALSE, eval = TRUE, message = FALSE} -tab <- openxlsx::read.xlsx("tables/exampleTables.xlsx", sheet = "probGerm", - colNames = TRUE, sep.names = " ") -names(tab)[grep("X", names(tab))] <- "" +tab <- read.csv(normPath("tables/probGerm_example.csv")) caption <- paste("Default species probability of germination values used by", "(ref:Biomass-core) and (ref:Biomass-borealdataPrep). Columns X0-X5 are different site", "shade levels and each line has the probability of germination for each site", "shade and species shade tolerance combination.") +tab$species.shade.tolerance <- as.character(tab$species.shade.tolerance) ## to ensure left-alignment knitr::kable(tab, caption = caption) %>% kableExtra::kable_styling(latex_options = c("repeat_header")) ``` From 75a092c3aa5e290927394345343f23c9d5b6b742 Mon Sep 17 00:00:00 2001 From: CeresBarros Date: Thu, 2 Jun 2022 14:04:13 -0700 Subject: [PATCH 026/148] manual edits: minor --- Biomass_core.Rmd | 40 ++++++++++++++++++++-------------------- 1 file changed, 20 insertions(+), 20 deletions(-) diff --git a/Biomass_core.Rmd b/Biomass_core.Rmd index 048b893..831b4b0 100644 --- a/Biomass_core.Rmd +++ b/Biomass_core.Rmd @@ -561,26 +561,26 @@ follow `species$speciesCode`. simulation as cohort dynamics are simulated. It must contain the following columns: -- *pixelGroup* -- integer. *pixelGroup* ID. See -[Hashing](#biomass-core-vs-lbse-enhan2). - -- *ecoregionGroup* -- character. Ecolocation names. See `ecoregionMap` and -`ecoregion` objects above. - -- *speciesCode* -- character. Species ID. - -- *age* -- integer. Cohort age. - -- *B* -- integer. Cohort biomass of the current year in $g/m^2$. - -- *mortality* -- integer. Cohort dead biomass of the current year in -$g/m^2$. Usually filled with 0s in initial conditions. - -- *aNPPAct* -- integer. Actual aboveground net primary productivity of the -current year in $g/m^2$. `B` is the result of the previous year's `B` -minus the current year's `mortality` plus `aNPPAct`. Usually filled with -0s in initial conditions. See "*1.1.3 Cohort growth and ageing*" section -of @SchellerMiranda2015. + - *pixelGroup* -- integer. *pixelGroup* ID. See + [Hashing](#biomass-core-vs-lbse-enhan2). + + - *ecoregionGroup* -- character. Ecolocation names. See `ecoregionMap` and + `ecoregion` objects above. + + - *speciesCode* -- character. Species ID. + + - *age* -- integer. Cohort age. + + - *B* -- integer. Cohort biomass of the current year in $g/m^2$. + + - *mortality* -- integer. Cohort dead biomass of the current year in + $g/m^2$. Usually filled with 0s in initial conditions. + + - *aNPPAct* -- integer. Actual aboveground net primary productivity of the + current year in $g/m^2$. `B` is the result of the previous year's `B` + minus the current year's `mortality` plus `aNPPAct`. Usually filled with + 0s in initial conditions. See "*1.1.3 Cohort growth and ageing*" section + of @SchellerMiranda2015. - `pixelGroupMap` -- a raster layer with `pixelGroup` IDs per pixel. Pixels are always grouped based on identical `ecoregionGroup`, `speciesCode`, `age` From d9b51b5d4db6ff96e37f566f71398b48fc18536b Mon Sep 17 00:00:00 2001 From: CeresBarros Date: Thu, 2 Jun 2022 14:04:30 -0700 Subject: [PATCH 027/148] manual edits: add sppNamesVector --- Biomass_core.Rmd | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/Biomass_core.Rmd b/Biomass_core.Rmd index 831b4b0..f6376b9 100644 --- a/Biomass_core.Rmd +++ b/Biomass_core.Rmd @@ -588,6 +588,13 @@ and `B` composition, even if the user supplies other initial groupings (e.g., this is possible in the *Biomass_borealDataPrep* data module). +- `sppNameVector` -- (OPTIONAL) a character vector of species to be simulated. +If provided, *Biomass_core* uses this vector to (attempt to) obtain `speciesLayers` +for the listed species. If not provided, the user (or another module) can pass a filtered `sppEquiv` table +(i.e., containing only the species that are to be simulated). If neither is provided, +then *Biomass_core* attempts to use any species for which if finds available species +(ref:percent) cover data in the study area. + ```{r moduleInputs2-Biomass-core, echo = FALSE, eval = TRUE, message = FALSE} df_inputs <- SpaDES.core::moduleInputs("Biomass_core", "..") caption <- "List of (ref:Biomass-core) input objects and their description." From 179b15ce02255876b093ec1a54b14d81ac54d5f1 Mon Sep 17 00:00:00 2001 From: CeresBarros Date: Thu, 2 Jun 2022 14:10:23 -0700 Subject: [PATCH 028/148] re-knit --- Biomass_core.html | 9430 ++++++++++++++++++++++++++++++--------------- Biomass_core.md | 2884 ++++++++++++-- 2 files changed, 8912 insertions(+), 3402 deletions(-) diff --git a/Biomass_core.html b/Biomass_core.html index 5d00fc7..26bf8b9 100644 --- a/Biomass_core.html +++ b/Biomass_core.html @@ -13,19 +13,6 @@ LandR Biomass_core Manual - @@ -3038,7 +3025,7 @@

LandR Biomass_core Manual

-

Last updated: 2022-05-27

+

Last updated: 2022-06-02

@@ -3046,13 +3033,22 @@

Last updated: 2022-05-27

- -

module-version-Badge Issues-badge

- + + + + + + + + +

module-version-Badge

Authors:

-

Yong Luo [aut], Eliot J B McIntire [aut, cre], Jean Marchal [ctb], Alex M. Chubaty [ctb], Ceres Barros [ctb]

-

This documentation is work in progress. Potential discrepancies and omissions may exist for the time being. If you find any, contact us using the “Get help” link above^^

+

Yong Luo [aut], Eliot J B McIntire [aut, cre], Ceres Barros [aut], Alex M. Chubaty [aut], Ian Eddy [ctb], Jean Marchal [ctb] +

+

This documentation is work in progress. Potential discrepancies and omissions +may exist for the time being. If you find any, contact us using the “Get help” +link above.

Module Overview

@@ -3068,7 +3064,17 @@

Quick links

Summary

-

LandR Biomass_core (hereafter Biomass_core) is the core forest succession simulation module of the LandR ecosystem of SpaDES modules (see Chubaty & McIntire 2019). It simulates tree cohort ageing, growth, mortality and competition for light resources, as well as seed dispersal (Fig. 1), in a spatially explicit manner and using a yearly time step. The model is based on the LANDIS-II Biomass Succession Extension v.3.2.1 (LBSE, Scheller & Miranda 2015), with a few changes (see Differences between Biomass_core and LBSE). Nonetheless, the essential functioning of the succession model still largely follows its LANDIS-II counterpart, and we refer the reader to the corresponding LBSE manual (Scheller & Miranda 2015) for a detailed reading of the mechanisms implemented in the model.

+

LandR Biomass_core (hereafter Biomass_core) is the core forest succession +simulation module of the LandR ecosystem of SpaDES modules (see Chubaty & McIntire 2019). It simulates tree cohort ageing, growth, mortality and +competition for light resources, as well as seed dispersal (Fig. +1), in a spatially explicit manner and using a yearly +time step. The model is based on the LANDIS-II Biomass Succession Extension +v.3.2.1 (LBSE, Scheller & Miranda 2015), with a few changes (see Differences +between Biomass_core and LBSE). Nonetheless, the +essential functioning of the succession model still largely follows its +LANDIS-II counterpart, and we refer the reader to the corresponding LBSE manual +(Scheller & Miranda 2015) for a detailed reading of the mechanisms implemented in +the model.

Biomass_core simulates tree cohort growth, mortality, recruitment and dispersal dynamics, as a function of  cohort ageing and competition for light (shading) and space, as well as disturbances like fire (simulated using other modules).

@@ -3078,24 +3084,60 @@

Summary

@@ -3103,1713 +3145,2532 @@

Links to other modules

Module manual

General functioning

-

LandR Biomass_core (hereafter Biomass_core) is a forest landscape model based on the LANDIS-II Biomass Succession Extension v.3.2.1 model (LBSE, Scheller & Miranda 2015). It is the core forest succession model of the LandR ecosystem of SpaDES modules. Similarly to LBSE, Biomass_core simulates changes in tree cohort aboveground biomass (\(g/m^2\)) by calculating growth, mortality and recruitment as functions of pixel and species characteristics, competition and disturbances (Fig. 1). Note that, by default, cohorts are unique combinations of species and age, but this can be changed via the cohortDefinitionCols parameter (see List of parameters).

-

Specifically, cohort growth is driven by both invariant (growth shape parameter, growthcurve) and spatio-temporally varying species traits (maximum biomass, maxB, and maximum annual net primary productivity, maxANPP), while background mortality (i.e., not caused by disturbances) depends only on invariant species traits (longevity and mortality shape parameter, mortalityshape). All five traits directly influence the realised shape of species growth curves, by determining how fast they grow (growthcurve and maxANPP), how soon age mortality starts with respect to longevity (mortalityshape) and the biomass a cohort can potentially achieve (maxB).

-

Cohort recruitment is determined by available “space” (i.e., pixel shade), invariant species traits (regeneration mode, postfireregen, age at maturity, sexualmature, shade tolerance, shadetolerance) and spatio-temporally varying traits (species establishment probability, establishprob, called SEP hereafter). The available “growing space” is calculated as the species maxB minus the occupied biomass (summed across other cohorts and species). If there is “space”, a cohort can establish from one of three recruitment modes: serotiny, resprouting and germination. While maxB, maxANPP and SEP vary both spatio-temporally and by species (spatio-temporally varying species traits), growthcurve, mortalityshape and longevity vary only between species (invariant species traits)

-

Disturbances (e.g., fire) can cause cohort mortality and trigger post-disturbance regeneration. Two processes of post-disturbance regeneration have been implemented, following LBSE mechanisms: serotiny and resprouting (Scheller & Miranda 2015). These two processes (post-disturbance mortality and regeneration) only occur in response to fire and are simulated in two separate, but interchangeable modules, Biomass_regeneration and Biomass_regenerationPM that differ with respect to the level of post-fire mortality they simulate (complete or partial mortality, respectively).

-

Cohort germination (also called cohort establishment) occurs if seeds are available from local sources (the pixel), or via seed dispersal. Seed dispersal can be of three modes: ‘no dispersal’, ‘universal dispersal’ (only interesting for dummy case studies) or ‘ward dispersal’ (Scheller & Miranda 2015). The ‘ward dispersal’ algorithm describes a flexible kernel that calculates the probability of a species colonising a neighbour pixel as a function of distance from the source and dispersal-related (and invariant) species traits, and is used by default.

-

Both germination and regeneration success depend on the species’ probability of germination in a given pixel (probabilities of germination).

-

We refer the reader to Scheller & Miranda (2015), Scheller & Domingo (2011) and Scheller & Domingo (2012) for further details with respect to the above mentioned mechanisms implemented in Biomass_core. Existing differences between Biomass_core and LBSE are detailed below, together with comparisons between the two modules.

+

Biomass_core is a forest landscape model based on the LANDIS-II Biomass +Succession Extension v.3.2.1 model (LBSE, Scheller & Miranda 2015). It is the core +forest succession model of the LandR ecosystem of SpaDES modules. Similarly to +LBSE, Biomass_core simulates changes in tree cohort aboveground biomass +(\(g/m^2\)) by calculating growth, mortality and recruitment as functions of pixel +and species characteristics, competition and disturbances (Fig. +1). Note that, by default, cohorts are unique +combinations of species and age, but this can be changed via the +cohortDefinitionCols parameter (see List of parameters).

+

Specifically, cohort growth is driven by both invariant (growth shape parameter, +growthcurve) and spatio-temporally varying species traits (maximum biomass, +maxB, and maximum annual net primary productivity, maxANPP), while +background mortality (i.e., not caused by disturbances) depends only on +invariant species traits (longevity and mortality shape parameter, +mortalityshape). All these five traits directly influence the realised shape +of species growth curves, by determining how fast they grow (growthcurve and +maxANPP), how soon age mortality starts with respect to longevity +(mortalityshape) and the biomass a cohort can potentially achieve (maxB).

+

Cohort recruitment is determined by available “space” (i.e., pixel shade), +invariant species traits (regeneration mode, postfireregen, age at maturity, +sexualmature, shade tolerance, shadetolerance) and a third spatio-temporally +varying trait (species establishment probability, establishprob, called SEP +hereafter). The available “growing space” is calculated as the species’ maxB +minus the occupied biomass (summed across other cohorts in the pixel). If there +is “space”, a cohort can establish from one of three recruitment modes: +serotiny, resprouting and germination.

+

Disturbances (e.g., fire) can cause cohort mortality and trigger +post-disturbance regeneration. Two post-disturbance regeneration mechanisms have +been implemented, following LBSE: serotiny and resprouting +(Scheller & Miranda 2015). Post-disturbance mortality and regeneration only occur +in response to fire and are simulated in two separate, but interchangeable +modules, Biomass_regeneration and Biomass_regenerationPM that differ with +respect to the level of post-fire mortality they simulate (complete or partial +mortality, respectively).

+

Cohort germination (also called cohort establishment) occurs if seeds are +available from local sources (the pixel), or via seed dispersal. Seed dispersal +can be of three modes: ‘no dispersal’, ‘universal dispersal’ (arguably, only +interesting for dummy case studies) or ‘ward dispersal’ (Scheller & Miranda 2015). +Briefly, the ‘ward dispersal’ algorithm describes a flexible kernel that +calculates the probability of a species colonising a neighbour pixel as a +function of distance from the source and dispersal-related (and invariant) +species traits, and is used by default.

+

Finally, both germination and regeneration success depend on the species’ +probability of germination in a given pixel (probabilities of +germination).

+

We refer the reader to Scheller & Miranda (2015), Scheller & Domingo (2011) and +Scheller & Domingo (2012) for further details with respect to the above mentioned +mechanisms implemented in Biomass_core. In a later section of this manual, we +highlight existing differences between Biomass_core and +LBSE, together with comparisons between the two +modules.

-

Initialization, inputs and parameters

-

To initialise and simulate forest dynamics in any given landscape, Biomass_core requires a number of inputs and parameters namely:

+

Initialisation, inputs and parameters

+

To initialise and simulate forest dynamics in any given landscape, +Biomass_core requires a number of inputs and parameters namely:

-

These are detailed below and in the full list of input objects. The Biomass_borealDataPrep module manual also provides information about how many of these inputs are derived from available data, or adjusted using published values or our best knowledge of boreal forest dynamics in Western Canada.

-

Unlike the initialisation in LBSE1, Biomass_core initialises the simulation using data-derived initial cohort biomass and age. This information is ideally supplied by data and calibration modules like Biomass_borealDataPrep (Links to other modules), but Biomass_core can also initialise itself using theoretical data.

-

Similarly, although Biomass_core can create all necessary traits and parameters using theoretical values, for realistic simulations these should be provided by data and calibration modules, like Biomass_borealDataPrep and Biomass_speciesParameters. We advise future users and developers to become familiar with these data modules and then try to create their own modules (or modify existing ones) for their purpose.

+

These are detailed below and in the full list of input objects. +The Biomass_borealDataPrep module manual also provides information about the +estimation of many of these traits/inputs from available data, or their +adjustment using published values or our best knowledge of boreal forest +dynamics in Western Canada.

+

Unlike the initialisation in LBSE1, Biomass_core initialises +the simulation using data-derived initial cohort biomass and age. This +information is ideally supplied by data and calibration modules like +Biomass_borealDataPrep (Links to other modules), but +Biomass_core can also initialise itself using theoretical data.

+

Similarly, although Biomass_core can create all necessary traits and +parameters using theoretical values, for realistic simulations these should be +provided by data and calibration modules, like Biomass_borealDataPrep and +Biomass_speciesParameters. We advise future users and developers to become +familiar with these data modules and then try to create their own modules (or +modify existing ones) for their purpose.

Initial cohort biomass and age

-

Initial cohort biomass and age are derived from stand biomass (biomassMap raster layer), stand age (standAgeMap raster layer) and species % cover (speciesLayers raster layers) data (see Table 5) and formatted into the cohortData object, a table that reflects the current year’s cohort biomass, age, mortality (lost biomass) and aboveground net primary productivity (ANPP) per species and pixel group (pixelGroup). At the start of the simulation, cohortData will not have any values of cohort mortality or ANPP.

-

Each pixelGroup is a collection of pixels that share the same ecolocation (by default, a combination of land-cover and ecological zonation, coded in the ecoregionMap raster layer) and the same cohort composition (i.e., species, age and biomass composition). The cohortData table is therefore always associated with the current year’s pixelGroupMap raster layer, which provides the spatial location of all pixelGroups and allows “spatialising” cohort information and dynamics (e.g., dispersal) on a pixel by pixel basis (see also Hashing).

-

The user, or another module, may provide initial cohortData and pixelGroupMap objects to start the simulation, or the input objects necessary to produce them: a study area polygon (studyArea), the biomassMap, standAgeMap, speciesLayers and ecoregionMap raster layers (see the list of input objects for more detail).

+

Initial cohort biomass and age are derived from stand biomass (biomassMap +raster layer), stand age (standAgeMap raster layer) and species % +cover (speciesLayers raster layers) data (see Table +5) and formatted into the cohortData +object. The cohortData table is a central simulation object that tracks the +current year’s cohort biomass, age, mortality (lost biomass) and aboveground net +primary productivity (ANPP) per species and pixel group (pixelGroup). At the +start of the simulation, cohortData will not have any values of cohort +mortality or ANPP.

+

Each pixelGroup is a collection of pixels that share the same ecolocation +(coded in the ecoregionMap raster layer) and the same cohort composition. By +default, an ecolocation is a combination of land-cover and ecological zonation +(see ecoregionMap in the full list of inputs) and unique +cohort compositions are defined as unique combinations of species, age and +biomass. The cohortData table is therefore always associated with the current +year’s pixelGroupMap raster layer, which provides the spatial location of all +pixelGroups, allowing to “spatialise” cohort information and dynamics (e.g., +dispersal) on a pixel by pixel basis (see also +Hashing).

+

The user, or another module, may provide initial cohortData and +pixelGroupMap objects to start the simulation, or the input objects necessary +to produce them: a study area polygon (studyArea), the biomassMap, +standAgeMap, speciesLayers and ecoregionMap raster layers (see the list +of input objects for more detail).

Invariant species traits

-

These are spatio-temporally constant traits that mostly influence population dynamics (e.g., growth, mortality, dispersal) and responses to fire (fire tolerance and regeneration).

-

By default, Biomass_core obtains trait values from available LANDIS-II tables (see Table 5), but traits can be adjusted/supplied by the user or by other modules. For instance, using Biomass_borealDataPrep will adjust some trait values for Western Canadian boreal forests (e.g., longevity values are adjusted following Burton & Cumming 1995), while using Biomass_speciesParameters calibrates the growthcurve and mortalityshape parameters and estimates two additional species traits (inflactionFactor and mANPPproportion) to calibrate maxB and maxANPP (respectively).

-

Table 1 shows an example of a table of invariant species traits. Note that Biomass_core (alone) requires all the columns Table 1 in to be present, with the exception of firetolerance, postfireregen, resproutprob, resproutage_min and resproutage_max, which are used by the post-fire regeneration modules (Biomass_regeneration and Biomass_regenerationPM).

-

Please see Scheller & Domingo (2011) and Scheller & Miranda (2015) for further detail.

-
- --------------- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
speciesCodelongevitysexualmatureshadetolerancefiretolerancepostfireregenresproutprobresproutage_minresproutage_maxseeddistance_effseeddistance_maxmortalityshapegrowthcurve
Abie_sp200202.31none00025100150
Pice_eng460302.12none00030250151.0
Pice_gla400301.62none000100303151.0
Pinu_sp1501512serotiny00030100150
Popu_sp1402011resprout0.510702005000250
Pseu_men5252523none000100500151.0
-
-

: (#tab:invariantSpptraits) Example of an invariant species traits table (the species table object in the module), with species Abies sp. (Abie_sp), Picea engelmannii (Pice_eng), Picea glauca (Pice_gla), Pinus sp. (Pinu_sp), Populus sp. (Popu_sp) and Pseudotsuga menziesii (Pseu_men). Note that these are theoretical values.

-
-
-

Spatio-temporally varying species traits

-

These traits vary between species, by ecolocation and, potentially, by year if the year column is not omitted and several years exist (in which case last year’s values up to the current simulation year are always used). They are maximum biomass, maxB, maximum above-ground net primary productivity, maxANPP, and species establishment probability, SEP (called establishprob in the module). By default, Biomass_core assigns theoretical values to these traits, and thus we recommend using Biomass_borealDataPrep to obtain realistic trait values derived from data (by default, pertinent for Canadian boreal forest applications) or passing a custom table directly. Biomass_speciesParameters further calibrates maxB and maxANPP by estimating two additional invariant species traits (inflactionFactor and mANPPproportion; also for Western Canadian forests). See Table 2 for an example.

- - -------- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Table 2: Example of a spatio-temporally varying species traits table (the speciesEcoregion table object in the module), with two ecolocations (called ecoregionGroups) and species Abies sp. (Abie_sp), Picea engelmannii (Pice_eng), Picea glauca (Pice_gla), Pinus sp. (Pinu_sp), Populus sp. (Popu_sp) and Pseudotsuga menziesii (Pseu_men). If the simulation runs for 10 years, values from year 2 would be use for years 2-10. Note that these are theoretical values.
ecoregionGroupspeciesCodeestablishprobmaxBmaxANPPyear
1_03Abie_sp1.00085672851
1_03Pice_eng0.983101563051
1_03Popu_sp0.73787942931
1_03Pseu_men1.000175341321
1_09Abie_sp0.1121499501
1_09Pice_gla0.30231431021
1_09Pinu_sp0.7142569861
1_09Popu_sp0.60732921101
1_09Pseu_men0.9976020451
1_03Abie_sp0.98989432252
1_03Pice_eng0.98590003152
1_03Popu_sp0.60086002732
1_03Pseu_men1.000135341422
1_09Abie_sp0.2932099452
1_09Pice_gla0.7453643902
1_09Pinu_sp0.5002569802
1_09Popu_sp0.67032621112
1_09Pseu_men1.0006300432
-
-
-

Ecolocation-specific parameters – minimum relative biomass

-

Minimum relative biomass (minRelativeB) is the only the only ecolocation-specific parameter used in Biomass_core. It is used to determine the shade level in each pixel (i.e., site shade) with respect to the total potential maximum biomass for that pixel (i.e., the sum of all maxB values in the pixel’s ecolocation). If relative biomass in the stand (with regards to the total potential maximum biomass) is above one of the minimum relative biomass thresholds, the pixel is assigned that threshold’s site shade value (Scheller & Miranda 2015).

-

The shade level then influences the germination and regeneration of new cohorts, depending on their shade tolerance (see Probabilities of germination).

-

Site shade varies from 0 (no shade) to 5 (maximum shade). By default, Biomass_core uses relative biomass thresholds from available LANDIS-II tables, which are held constant across all ecolocations (see an example in Table 3). Yet, these values can be adjusted by using other modules or passing user-defined tables (e.g., Biomass_borealDataPrep adjusts these values for applications in Western Canadian forests)

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Table 3: Example of a minimum relative biomass table (the minRelativeB table object in the module), with two ecolocations (ecoregionGroups) sharing the same values. Note that the relative biomass values were taken from
ecoregionGroupX1X2X3X4X5
1_030.150.250.50.800.90
1_090.150.250.50.800.90
-
-
-

Probabilities of germination

-

A species’ probability of germination results from the combination of its shade tolerance level (an invariant species trait in the species table) and the site shade (defined by the amount of biomass in the pixel – see minimum relative biomass parameter and Scheller & Miranda 2015). By default, both Biomass_core and Biomass_borealDataPrep use a publicly available LANDIS-II table (called sufficientLight in the module; Table 4).

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Table 4: Default species probability of germination values used by Biomass_core and Biomass_borealDataPrep. Columns X0-X5 are different site shade levels and each line has the probability of germination for each site shade and species shade tolerance combination
species shade toleranceX0X1X2X3X4X5
1100000
2110000
3111000
4111100
5001111
-
-
-

Other module inputs

-

The remaining module input objects either do not directly influence the basic mechanisms implemented in Biomass_core (e.g., sppColorVect and studyAreaReporting are only used for plotting purposes), are objects that keep track of a property/process in the module (e.g., lastReg is a counter of the last year when regeneration occurred), or define the study area for the simulation (e.g., studyArea and rasterToMatch).

-

The next section provides a complete list of all input objects, including those already mentioned above.

-
-
-

List of input objects

-

All of Biomass_core’s input objects have (theoretical) defaults that are produced automatically by the module2. We suggest that new users run Biomass_core by itself supplying only a studyArea object, before attempting to supply their own, or combining Biomass_core with data modules. This will enable them to become familiar with all the input objects in a theoretical setting.

-

Of the inputs in Table 5, the following are particularly important and deserve special attention:

-

Spatial layers

-
    -
  • ecoregionMap – a raster layer with ecolocation IDs (note that the term “ecoregion” was inherited from LBSE and kept for consistency with original LBSE code). Ecolocations group pixels with similar biophysical conditions. By default, we use two levels of grouping in our applications: the first level being an ecological classification (in ) such as the the Natural Ecoregion classification of Canada, and the second level a land-cover classification. Hence, these ecolocations contain relatively fine scale land cover information plus coarse scale regional information. The ecoregionMap layer must be defined as a categorical raster, with an associated Raster Attribute Table (RAT; see, e.g., raster::ratify). The RAT must contain the columns: ID (the value in the raster layer), ecoregion (the first level of grouping) and ecoregionGroup (the full ecolocation “name” written as <firstlevel_secondlevel>). Note that if creating ecoregionGroups from combining two raster layers whose values are numeric (as in Biomass_borealDataPrep, the group label should be a character combination of two grouping levels. For instance, if Natural Ecoregion 2 has land-cover types 1, 2 and 3, the RAT will contain ID = {1,2,3}, ecoregion = {2} and ecoregionGroup = {2_1, 2_2, 2_3}. However, the user is free to use any groupings they wish. Finally, note that all ecolocations are should be listed in the ecoregion table.

  • -
  • rasterToMatch – a RasterLayer, with a given resolution and projection determining the pixels (i.e., non-NA values) where forest dynamics will be simulated. Needs to match studyArea. If not supplied, Biomass_core attempts to produce it from studyArea, using biomassMap as the template for spatial resolution and projection.

  • -
  • studyArea – a shapefile. A SpatialPolygonsDataFrame with a single polygon determining the where the simulation will take place. This is the only input object that must be supplied by the user.

  • -
-

Species traits and other parameter tables

-
    -
  • ecoregiondata.table listing all ecolocation “names” (ecoregionGroup column; see ecoregionMap above for details) and their state (active – yes – or inactive – no)

  • -
  • minRelativeBdata.table of minimum relative biomass values. See Ecolocation-specific parameters – minimum relative biomass.

  • -
  • species – a data.table of invariant species traits. See Invariant species traits.

  • -
  • speciesEcoregion – a data.table of spatio-temporally varying species traits. See Spatio-temporally varying species traits.

  • -
  • sufficientLight – a data.table defining the probability of germination for a species, given its shadetolerance level (see species above) and the shade level in the pixel (see minRelativeB above). See Probabilities of germination.

  • -
  • sppEquiv – a data.table of species name equivalences between various conventions. It must contain the columns LandR (species IDs in the LandR format), EN_generic_short (short generic species names in English – or any other language – used for plotting), Type (type of species, Conifer or Deciduous, as in “broadleaf”) and Leading (same as EN_generic_short but with “leading” appended – e.g., “Poplar leading”) . See ?LandR::sppEquivalencies_CA for more information.

  • -
  • sppColorVect – character. A named vector of colours used to plot species dynamics. Should contain one colour per species in the species table and, potentially a colour for species mixtures (named “Mixed”). Vector names must follow species$speciesCode.

  • -
-

Cohort-simulation-related objects

-
    -
  • cohortData – a data.table containing initial cohort information per pixelGroup (see pixelGroupMap below). This table is updated during the simulation as cohort dynamics are simulated. Must contain the following columns:

    -
      -
    • pixelGroup – integer. pixelGroup ID. See Hashing.

    • -
    • ecoregionGroup – character. Ecolocation names. See ecoregionMap and ecoregion objects above.

    • -
    • speciesCode – character. Species ID.

    • -
    • age – integer. Cohort age.

    • -
    • B – integer. Cohort biomass in \(g/m^2\).

    • -
    • mortality – integer. Cohort dead biomass in the current year in \(g/m^2\). Usually filled with 0s in initial conditions.

    • -
    • aNPPAct – integer. Actual aboveground net primary productivity of the current year in \(g/m^2\). Hence B is the result of the previous year’s B minus mortality plus aNPPAct. Usually filled with 0s in initial conditions. See “1.1.3 Cohort growth and ageing” section of Scheller & Miranda (2015).

    • -
  • -
  • pixelGroupMap – a raster layer with pixelGroup IDs per pixel. Pixels are always grouped based on identical ecoregionGroup, speciesCode, age and B composition, even if the user supplies other initial groupings (e.g., this is possible in the Biomass_borealDataPrep data module).

  • -
+

These are spatio-temporally constant traits that mostly influence population +dynamics (e.g., growth, mortality, dispersal) and responses to fire (fire +tolerance and regeneration).

+

By default, Biomass_core obtains trait values from available LANDIS-II tables +(see Table 5), but traits can be +adjusted/supplied by the user or by other modules. For instance, using +Biomass_borealDataPrep will adjust some trait values for Western Canadian +boreal forests (e.g., longevity values are adjusted following Burton & Cumming 1995), while using Biomass_speciesParameters calibrates the +growthcurve and mortalityshape parameters and estimates two additional +species traits (inflationFactor and mANPPproportion) to calibrate maxB and +maxANPP (respectively).

+

Table 1 shows an example of a table of invariant +species traits. Note that Biomass_core (alone) requires all the columns Table +1 in to be present, with the exception of +firetolerance, postfireregen, resproutprob, resproutage_min and +resproutage_max, which are used by the post-fire regeneration modules +(Biomass_regeneration and Biomass_regenerationPM).

+

Please see Scheller & Domingo (2011) and Scheller & Miranda (2015) for +further detail.

- - + + + + + + + + + - - - - - - - - - - - - - - + - - - - - - - - - - - - - - + - - - - - - - - - - - - - - + - - - - - - - - - - - - - - + - - - - - - - - - - - - - - + - - - - - - - - - - - - - - +
-Table 5: List of Biomass_core input objects and their description. +Table 1: Example of an invariant species traits table (the species table object in the module), with species Abies sp. (Abie_sp), Picea engelmannii (Pice_eng), Picea glauca (Pice_gla), Pinus sp. (Pinu_sp), Populus sp. (Popu_sp) and Pseudotsuga menziesii (Pseu_men). Note that these are theoretical values.
-objectName +speciesCode -objectClass + +longevity -desc + +sexualmature + +shadetolerance + +firetolerance -sourceURL +postfireregen + +resproutprob + +resproutage_min + +resproutage_max + +seeddistance_eff + +seeddistance_max + +mortalityshape + +growthcurve
-biomassMap +Abie_sp -RasterLayer + +200 -total biomass raster layer in study area (in g/m^2), filtered for pixels covered by cohortData. Only used if P(sim)$initialBiomassSource == 'biomassMap', which is currently deactivated. + +20 + +2.3
-cceArgs + +1 -list +none -a list of quoted objects used by the growthAndMortalityDriver calculateClimateEffect function + +0.0 -NA + +0
-cohortData + +0 -data.table + +25 -data.table with cohort-level information on age and biomass, by pixelGroup and ecolocation (i.e., ecoregionGroup). If supplied, it must have the following columns: pixelGroup (integer), ecoregionGroup (factor), speciesCode (factor), B (integer in g/m^2), age (integer in years) + +100 -NA + +15 + +0
-ecoregion +Pice_eng -data.table + +460 -ecoregion look up table + +30 -https://raw.githubusercontent.com/LANDIS-II-Foundation/Extensions-Succession/master/biomass-succession-archive/trunk/tests/v6.0-2.0/ecoregions.txt + +2.1
-ecoregionMap + +2 -RasterLayer +none -ecoregion map that has mapcodes match ecoregion table and speciesEcoregion table. Defaults to a dummy map matching rasterToMatch with two regions + +0.0 -NA + +0
-lastReg + +0 -numeric + +30 -an internal counter keeping track of when the last regeneration event occurred + +250 -NA + +15 + +1
-minRelativeB +Pice_gla -data.frame + +400 -table defining the relative biomass cut points to classify stand shadeness + +30 -NA + +1.6
-pixelGroupMap + +2 -RasterLayer +none -a raster layer with pixelGroup IDs per pixel. Pixels are grouped based on identical ecoregionGroup, speciesCode, age and B composition, even if the user supplies other initial groupings (e.g., via the Biomass_borealDataPrep module. + +0.0 -NA + +0
-rasterToMatch + +0 -RasterLayer + +100 -a raster of the studyArea in the same resolution and projection as biomassMap + +303 -NA + +15 + +1
-species +Pinu_sp -data.table + +150 -a table of invariant species traits with the following trait colums: ‘species’, ‘Area’, ‘longevity’, ‘sexualmature’, ‘shadetolerance’, ‘firetolerance’, ‘seeddistance_eff’, ‘seeddistance_max’, ‘resproutprob’, ‘mortalityshape’, ‘growthcurve’, ‘resproutage_min’, ‘resproutage_max’, ‘postfireregen’, ‘wooddecayrate’, ‘leaflongevity’ ‘leafLignin’, ‘hardsoft’. The last seven traits are not used in Biomass_core , and may be ommited. However, this may result in downstream issues with other modules. Default is from Dominic Cyr and Yan Boulanger’s project + +15 -https://raw.githubusercontent.com/dcyr/LANDIS-II_IA_generalUseFiles/master/speciesTraits.csv + +1.0
-speciesEcoregion + +2 -data.table +serotiny -table of spatially-varying species traits (maxB, maxANPP, establishprob), defined by species and ecoregionGroup) Defaults to a dummy table based on dummy data os biomass, age, ecoregion and land cover class + +0.0 -NA + +0
-speciesLayers + +0 -RasterStack + +30 -percent cover raster layers of tree species in Canada. Defaults to the Canadian Forestry Service, National Forest Inventory, kNN-derived species cover maps from 2001 using a cover threshold of 10 - see https://open.canada.ca/data/en/dataset/ec9e2659-1c29-4ddb-87a2-6aced147a990 for metadata + +100 -http://ftp.maps.canada.ca/pub/nrcan_rncan/Forests_Foret/canada-forests-attributes_attributs-forests-canada/2001-attributes_attributs-2001/ + +15 + +0
-sppColorVect +Popu_sp -character + +140 -A named vector of colors to use for plotting. The names must be in sim$sppEquiv[[sim$sppEquivCol]], and should also contain a color for ‘Mixed’ + +20 -NA + +1.0
-sppEquiv + +1 -data.table +resprout -table of species equivalencies. See LandR::sppEquivalencies_CA. + +0.5 -NA + +10
-studyArea + +70 -SpatialPolygonsDataFrame + +200 -Polygon to use as the study area. Must be provided by the user + +5000 -NA + +25 + +0
-studyAreaReporting +Pseu_men -SpatialPolygonsDataFrame + +525 -multipolygon (typically smaller/unbuffered than studyArea) to use for plotting/reporting. Defaults to studyArea. + +25 -NA + +2.0
-sufficientLight + +3 -data.frame +none -table defining how the species with different shade tolerance respond to stand shade. Default is based on LANDIS-II Biomass Succession v6.2 parameters + +0.0 -https://raw.githubusercontent.com/LANDIS-II-Foundation/Extensions-Succession/master/biomass-succession-archive/trunk/tests/v6.0-2.0/biomass-succession_test.txt + +0
-treedFirePixelTableSinceLastDisp + +0 -data.table + +100 -3 columns: pixelIndex, pixelGroup, and burnTime. Each row represents a forested pixel that was burned up to and including this year, since last dispersal event, with its corresponding pixelGroup and time it occurred + +500 -NA + +15 + +1
-
-

List of parameters

-

In addition to the above inputs objects, Biomass_core uses several parameters3 that control aspects like the simulation length, the “succession” time step, plotting and saving intervals, amongst others. Note that a few of these parameters are only relevant when simulating climate effects of cohort growth and mortality, which require also loading the LandR.CS R package. These are not discussed in detail here, since climate effects are calculated externally to Biomass_core by the LandR.CS package and thus documented there.

-

A list of useful parameters and their description is shown in Table 6, while the full set of parameters is in Table 7. Like with input objects, default values are supplied for all parameters and we suggest the user becomes familiarized with them before attempting any changes. We also note that the "spin-up" and "biomassMap" options for the initialBiomassSource are currently deactivated, since Biomass_core no longer generates initial cohort biomass conditions using a spin-up based on initial stand age like LANDIS-II ("spin-up"), nor does it attempt to fill initial cohort biomasses using biomassMap ("biomassMap").

-
- ---- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Required inputsDescription
Plotting & saving
.plotsactivates/deactivates plotting and defines type fo plotting (see ?Plots)
.plotInitialTimedefines when plotting starts
.plotIntervaldefines plotting frequency
.plotMapsactivates/deactivates map plotting
.saveInitialTimedefines when saving starts
.saveIntervaldefines saving frequency
Simulation
seedingAlgorithmdispersal type (see above)
successionTimestepdefines frequency of dispersal/local recruitment event (growth and mortality are always yearly)
Other
mixedTypehow mixed forest stands are defined
vegLeadingProportionrelative biomass threshold to consider a species “leading” (i.e., dominant)
-
-

: (#tab:tableUsefulParams) Useful Biomass_core parameters.

+
+

Spatio-temporally varying species traits

+

These traits vary between species, by ecolocation and, potentially, by year if +the year column is not omitted and several years exist (in which case last +year’s values up to the current simulation year are always used). They are +maximum biomass, maxB, maximum above-ground net primary productivity, +maxANPP, and species establishment probability, SEP (called establishprob in +the module). By default, Biomass_core assigns theoretical values to these +traits, and thus we recommend using Biomass_borealDataPrep to obtain realistic +trait values derived from data (by default, pertinent for Canadian boreal forest +applications), or passing a custom table directly. Biomass_speciesParameters +further calibrates maxB and maxANPP by estimating two additional invariant +species traits (inflationFactor and mANPPproportion; also for Western +Canadian forests). See Table 2 for an example.

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + +
-Table 7: List of Biomass_core parameters and their description. +Table 2: Example of a spatio-temporally varying species traits table (the speciesEcoregion table object in the module), with two ecolocations (called ecoregionGroups) and species Abies sp. (Abie_sp), Picea engelmannii (Pice_eng), Picea glauca (Pice_gla), Pinus sp. (Pinu_sp), Populus sp. (Popu_sp) and Pseudotsuga menziesii (Pseu_men). If a simulation runs for 10 year using this table, trait values from year 2 would be used during simulation years 2-10.
-paramName +ecoregionGroup -paramClass +speciesCode -default + +establishprob -min + +maxB -max + +maxANPP -paramDesc + +year
-calcSummaryBGM +1_03 -character +Abie_sp -end + +1.000 -NA + +8567 -NA + +285 -A character vector describing when to calculate the summary of biomass, growth and mortality Currently any combination of 5 options is possible: ‘start’- as before vegetation succession events, i.e. before dispersal, ‘postDisp’ - after dispersal, ‘postRegen’ - after post-disturbance regeneration (currently the same as ‘start’), ‘postGM’ - after growth and mortality, ‘postAging’ - after aging, ‘end’ - at the end of vegetation succesion events, before plotting and saving. The ‘end’ option is always active, being also the default option. If NULL, then will skip all summaryBGM related events + +1
-calibrate +1_03 -logical +Pice_eng -FALSE + +0.983 -NA + +10156 -NA + +305 -Do calibration? Defaults to FALSE + +1
-cohortDefinitionCols +1_03 -character +Popu_sp -pixelGro…. + +0.737 -NA + +8794 -NA + +293 -cohortData columns that determine what constitutes a cohort This parameter should only be modified if additional modules are adding columns to cohortData + +1
-cutpoint +1_03 -numeric +Pseu_men -1e+10 + +1.000 -NA + +17534 -NA + +132 -A numeric scalar indicating how large each chunk of an internal data.table is, when processing by chunks + +1
-gmcsGrowthLimits +1_09 -numeric +Abie_sp -66.66666…. + +0.112 -NA + +1499 -NA + +50 -if using LandR.CS for climate-sensitive growth and mortality, a percentile is used to estimate the effect of climate on growth/mortality (currentClimate/referenceClimate). Upper and lower limits are suggested to circumvent problems caused by very small denominators as well as predictions outside the data range used to generate the model + +1
-gmcsMortLimits +1_09 -numeric +Pice_gla -66.66666…. + +0.302 -NA + +3143 -NA + +102 -if using LandR.CS for climate-sensitive growth and mortality, a percentile is used to estimate the effect of climate on growth/mortality (currentClimate/referenceClimate). Upper and lower limits are suggested to circumvent problems caused by very small denominators as well as predictions outside the data range used to generate the model + +1
-gmcsMinAge +1_09 -numeric +Pinu_sp -21 + +0.714 -0 + +2569 -NA + +86 -if using LandR.CS for climate-sensitive growth and mortality, the minimum age for which to predict climate-sensitive growth and mortality. Young stands (< 30) are poorly represented by the PSP data used to parameterize the model. + +1
-growthAndMortalityDrivers +1_09 -character +Popu_sp -LandR + +0.607 -NA + +3292 -NA + +110 -package name where the following functions can be found: calculateClimateEffect, assignClimateEffect (see LandR.CS for climate sensitivity equivalent functions, or leave default if this is not desired) + +1
-growthInitialTime - -numeric - -start(sim) - -NA - -NA +1_09 -Initial time for the growth event to occur +Pseu_men
-initialB + +0.997 -numeric + +6020 -10 + +45 + 1 -NA - -initial biomass values of new age-1 cohorts -
-initialBiomassSource +1_03 -character +Abie_sp -cohortData + +0.989 -NA + +8943 -NA + +225 -Currently, there are three options: ‘spinUp’, ‘cohortData’, ‘biomassMap’. If ‘spinUp’, it will derive biomass by running spinup derived from Landis-II. If ‘cohortData’, it will be taken from the cohortData object, i.e., it is already correct, by cohort. If ‘biomassMap’, it will be taken from sim$biomassMap, divided across species using sim$speciesLayers percent cover values ‘spinUp’ uses sim$standAgeMap as the driver, so biomass is an output . That means it will be unlikely to match any input information about biomass, unless this is set to ‘biomassMap’, and a sim$biomassMap is supplied. Only the ‘cohortData’ option is currently active. + +2
-keepClimateCols +1_03 -logical +Pice_eng -FALSE + +0.985 -NA + +9000 -NA + +315 -include growth and mortality predictions in cohortData? + +2
-minCohortBiomass +1_03 -numeric +Popu_sp -0 + +0.600 -NA + +8600 -NA + +273 -cohorts with biomass below this threshold (in g/m^2) are removed. Not a LANDIS-II BSE parameter. + +2
-mixedType +1_03 -numeric +Pseu_men -2 + +1.000 -NA + +13534 -NA + +142 -How to define mixed stands: 1 for any species admixture; 2 for deciduous > conifer. See ?LandR::vegTypeMapGenerator. + +2
-plotOverstory +1_09 -logical +Abie_sp -FALSE + +0.293 -NA + +2099 -NA + +45 -swap max age plot with overstory biomass + +2
-seedingAlgorithm +1_09 -character +Pice_gla -wardDisp…. + +0.745 -NA + +3643 -NA + +90 -choose which seeding algorithm will be used among ‘noSeeding’ (no horizontal, nor vertical seeding - not in LANDIS-II BSE), ‘noDispersal’ (no horizontal seeding), ‘universalDispersal’ (seeds disperse to any pixel), and ‘wardDispersal’ (default; seeds disperse according to distance and dispersal traits). See Scheller & Miranda (2015) - Biomass Succession extension, v3.2.1 User Guide + +2
-spinupMortalityfraction +1_09 -numeric +Pinu_sp -0.001 + +0.500 -NA + +2569 -NA + +80 -defines the mortality loss fraction in spin up-stage simulation. Only used if P(sim)$initialBiomassSource == 'biomassMap', which is currently deactivated. + +2
-sppEquivCol +1_09 -character +Popu_sp -Boreal + +0.670 -NA + +3262 -NA + +111 -The column in sim$sppEquiv data.table to use as a naming convention + +2
-successionTimestep +1_09 -numeric +Pseu_men -10 + +1.000 -NA + +6300 -NA + +43 -defines the simulation time step, default is 10 years. Note that growth and mortality always happen on a yearly basis. Cohorts younger than this age will not be included in competitive interactions + +2
+
+
+

Ecolocation-specific parameters – minimum relative biomass

+

Minimum relative biomass (minRelativeB) is the only ecolocation-specific +parameter used in Biomass_core. It is used to determine the shade level in +each pixel (i.e., site shade) with respect to the total potential maximum +biomass for that pixel (i.e., the sum of all maxB values in the pixel’s +ecolocation). If relative biomass in the stand (with regards to the total +potential maximum biomass) is above the minimum relative biomass thresholds, the +pixel is assigned that threshold’s site shade value (Scheller & Miranda 2015).

+

The shade level then influences the germination and regeneration of new cohorts, +depending on their shade tolerance (see Probabilities of +germination).

+

Site shade varies from X0 (no shade) to X5 (maximum shade). By default, +Biomass_core uses the same minimum realtive biomass threshold values across +all ecolocations, adjusted from a publicly available LANDIS-II +table to better reflect +Western Canada boreal forest dynamics (see Table 3). +Biomass_borealDataPrep does the same adjustment by default. As with other +inputs, these values can be adjusted by using other modules or by passing +user-defined tables.

+ + + + + + + + + + + + + - - - - - - - - - - + +
+Table 3: Example of a minimum relative biomass table (the minRelativeB table object in the module), with two ecolocations (ecoregionGroups) sharing the same values +
+ecoregionGroup + +X1 + +X2 + +X3 + +X4 + +X5 +
-vegLeadingProportion +1_03 -numeric + +0.15 -0.8 + +0.25 -0 + +0.5 -1 + +0.75 -a number that defines whether a species is leading for a given pixel + +0.85
-.maxMemory +1_09 -numeric + +0.15 -5 + +0.25 -NA + +0.5 -NA + +0.75 -maximum amount of memory (in GB) to use for dispersal calculations. + +0.85
+
+
+

Probabilities of germination

+

A species’ probability of germination results from the combination of its shade +tolerance level (an invariant species trait in the species table; Table +(tab:invariantSpptraits)) and the site shade (defined by the amount of +biomass in the pixel – see minimum relative biomass +parameter and Scheller & Miranda 2015). By default, both +Biomass_core and Biomass_borealDataPrep use a publicly available LANDIS-II +table (called sufficientLight in the module; Table 4).

+ + + + + + + + + + + + + + - - - - - + - - - - - + - - - - - + - - - - - + - + + + + + + + +
+Table 4: Default species probability of germination values used by Biomass_core and Biomass_borealDataPrep. Columns X0-X5 are different site shade levels and each line has the probability of germination for each site shade and species shade tolerance combination. +
+species.shade.tolerance + +X0 + +X1 + +X2 + +X3 + +X4 + +X5 +
-.plotInitialTime +1 -numeric + +1 -start(sim) + +0 -NA + +0 -NA + +0 -Vector of length = 1, describing the simulation time at which the first plot event should occur. To plotting off completely use P(sim)$.plots. + +0 + +0
-.plotInterval +2 -numeric + +1 -NA + +1 -NA + +0 -NA + +0 -defines the plotting time step. If NA, the default, .plotInterval is set to successionTimestep. + +0 + +0
-.plots +3 -character + +1 -object + +1 -NA + +1 -NA + +0 -Passed to types in Plots (see ?Plots). There are a few plots that are made within this module, if set. Note that plots (or their data) saving will ONLY occur at end(sim). If NA, plotting is turned off completely (this includes plot saving). + +0 + +0
-.plotMaps +4 -logical + +1 -TRUE + +1 -NA + +1 -NA + +1 -Controls whether maps should be plotted or not. Set to FALSE if P(sim)$.plots == NA + +0 + +0
-.saveInitialTime +5 -numeric + +0 + +0 +1 + +1 + +1 + +1 +
+
+
+

Other module inputs

+

The remaining module input objects either do not directly influence the basic +mechanisms implemented in Biomass_core (e.g., sppColorVect and +studyAreaReporting are only used for plotting purposes), are objects that keep +track of a property/process in the module (e.g., lastReg is a counter of the +last year when regeneration occurred), or define the study area for the +simulation (e.g., studyArea and rasterToMatch).

+

The next section provides a complete list of all input objects, including those +already mentioned above.

+
+
+
+

List of input objects

+

All of Biomass_core’s input objects have (theoretical) defaults that are +produced automatically by the module2. We suggest that new users +run Biomass_core by itself supplying only a studyArea polygon, before +attempting to supply their own or combining Biomass_core with other modules. +This will enable them to become familiar with all the input objects in a +theoretical setting.

+

Of the inputs listed in Table 5, the +following are particularly important and deserve special attention:

+

Spatial layers

+
    +
  • ecoregionMap – a raster layer with ecolocation IDs. Note that the term +“ecoregion” was inherited from LBSE and kept for consistency with original +LBSE code, but we prefer to call them ecolocations to avoid confusion with +the ecoregion-level classification of the National Ecological +Classification of Canada +(NECC). +Ecolocations group pixels with similar biophysical conditions. By default, +we use two levels of grouping in our applications: the first level being an +ecological classification such as ecodistricts from the NECC, and the second +level is a land-cover classification. Hence, these ecolocations contain +relatively coarse scale regional information plus finer scale land cover +information. The ecoregionMap layer must be defined as a categorical +raster, with an associated Raster Attribute Table (RAT; see, e.g., +raster::ratify). The RAT must contain the columns: ID (the value in the +raster layer), ecoregion (the first level of grouping) and +ecoregionGroup (the full ecolocation “name” written as +<firstlevel_secondlevel>). Note that if creating ecoregionGroup’s by +combining two raster layers whose values are numeric (as in +Biomass_borealDataPrep), the group label is a character combination of two +numeric grouping levels. For instance, if Natural Ecoregion 2 has +land-cover types 1, 2 and 3, the RAT will contain ID = {1,2,3}, +ecoregion = {2} and ecoregionGroup = {2_1, 2_2, 2_3}. However, the user +is free to use any groupings they wish. Finally, note that all ecolocations +(ecoregionGroup’s) are should be listed in the ecoregion table.

  • +
  • rasterToMatch – a RasterLayer, with a given resolution and projection +determining the pixels (i.e., non-NA values) where forest dynamics will be +simulated. Needs to match studyArea. If not supplied, Biomass_core +attempts to produce it from studyArea, using biomassMap as the template +for spatial resolution and projection.

  • +
  • studyArea – a SpatialPolygonsDataFrame with a single polygon +determining the where the simulation will take place. This is the only input +object that must be supplied by the user or another module.

  • +
+

Species traits and other parameter tables

+
    +
  • ecoregion – a data.table listing all ecolocation “names” +(ecoregionGroup column; see ecoregionMap above for details) and their +state (active – yes – or inactive – no)

  • +
  • minRelativeB – a data.table of minimum relative biomass values. See +Ecolocation-specific parameters – minimum relative +biomass.

  • +
  • species – a data.table of invariant species +traits.

  • +
  • speciesEcoregion – a data.table of spatio-temporally varying species +traits.

  • +
  • sufficientLight – a data.table defining the probability of germination +for a species, given its shadetolerance level (see species above) and +the shade level in the pixel (see minRelativeB above). See Probabilities +of germination.

  • +
  • sppEquiv – a data.table of species name equivalences between various +conventions. It must contain the columns LandR (species IDs in the LandR +format), EN_generic_short (short generic species names in English – or +any other language – used for plotting), Type (type of species, Conifer +or Deciduous, as in “broadleaf”) and Leading (same as EN_generic_short +but with “leading” appended – e.g., “Poplar +leading”). +See ?LandR::sppEquivalencies_CA for more information.

  • +
  • sppColorVect – character. A named vector of colours used to plot species +dynamics. Should contain one colour per species in the species table and, +potentially a colour for species mixtures (named “Mixed”). Vector names must +follow species$speciesCode.

  • +
+

Cohort-simulation-related objects

+
    +
  • cohortData – a data.table containing initial cohort information per +pixelGroup (see pixelGroupMap below). This table is updated during the +simulation as cohort dynamics are simulated. It must contain the following +columns:

    +
      +
    • pixelGroup – integer. pixelGroup ID. See +Hashing.

    • +
    • ecoregionGroup – character. Ecolocation names. See ecoregionMap and +ecoregion objects above.

    • +
    • speciesCode – character. Species ID.

    • +
    • age – integer. Cohort age.

    • +
    • B – integer. Cohort biomass of the current year in \(g/m^2\).

    • +
    • mortality – integer. Cohort dead biomass of the current year in +\(g/m^2\). Usually filled with 0s in initial conditions.

    • +
    • aNPPAct – integer. Actual aboveground net primary productivity of the +current year in \(g/m^2\). B is the result of the previous year’s B +minus the current year’s mortality plus aNPPAct. Usually filled with +0s in initial conditions. See “1.1.3 Cohort growth and ageing” section +of Scheller & Miranda (2015).

    • +
  • +
  • pixelGroupMap – a raster layer with pixelGroup IDs per pixel. Pixels +are always grouped based on identical ecoregionGroup, speciesCode, age +and B composition, even if the user supplies other initial groupings +(e.g., this is possible in the Biomass_borealDataPrep data module). +

  • +
  • sppNameVector – (OPTIONAL) a character vector of species to be simulated. +If provided, Biomass_core uses this vector to (attempt to) obtain speciesLayers +for the listed species. If not provided, the user (or another module) can pass a filtered sppEquiv table +(i.e., containing only the species that are to be simulated). If neither is provided, +then Biomass_core attempts to use any species for which if finds available species +% cover data in the study area.

  • +
+ + + + + + + + + + + + + + - - + + + + + + + + - - -
+Table 5: List of Biomass_core input objects and their description. +
+objectName + +objectClass + +desc + +sourceURL +
-NA +biomassMap -NA +RasterLayer -NA +total biomass raster layer in study area (in g/m^2), filtered for pixels covered by cohortData. Only used if P(sim)$initialBiomassSource == 'biomassMap', which is currently deactivated. -Vector of length = 1, describing the simulation time at which the first save event should occur. Set to NA if no saving is desired. If not NA, then saving will occur at P(sim)$.saveInitialTime with a frequency equal to P(sim)$.saveInterval
-.saveInterval +cceArgs -numeric +list -NA +a list of quoted objects used by the growthAndMortalityDriver calculateClimateEffect function NA
-NA +cohortData -defines the saving time step. If NA, the default, .saveInterval is set to P(sim)$successionTimestep. +data.table
-.studyAreaName +data.table with cohort-level information on age and biomass, by pixelGroup and ecolocation (i.e., ecoregionGroup). If supplied, it must have the following columns: pixelGroup (integer), ecoregionGroup (factor), speciesCode (factor), B (integer in g/m^2), age (integer in years) -character +NA
-NA +ecoregion -NA +data.table -NA +ecoregion look up table -Human-readable name for the study area used. If NA, a hash of studyArea will be used. +https://raw.githubusercontent.com/LANDIS-II-Foundation/Extensions-Succession/master/biomass-succession-archive/trunk/tests/v6.0-2.0/ecoregions.txt
-.useCache +ecoregionMap -character +RasterLayer -.inputOb…. +ecoregion map that has mapcodes match ecoregion table and speciesEcoregion table. Defaults to a dummy map matching rasterToMatch with two regions NA
-NA +lastReg -Internal. Can be names of events or the whole module name; these will be cached by SpaDES +numeric + +an internal counter keeping track of when the last regeneration event occurred + +NA
-.useParallel +minRelativeB -ANY +data.frame -2 +table defining the relative biomass cut points to classify stand shadeness. NA
-NA +pixelGroupMap -Used only in seed dispersal. If numeric, it will be passed to data.table::setDTthreads and should be <= 2; If TRUE, it will be passed to parallel::makeCluster; and if a cluster object, it will be passed to parallel::parClusterApplyB. +RasterLayer
-
-
-

List of outputs

-

The main outputs of Biomass_core are the cohortData and pixelGroupMap containing cohort information per year (note that they are not saved by default), visual outputs of species level biomass, age and dominance across the landscape and the simulation length, and several maps of stand biomass, mortality and reproductive success (new biomass) or a yearly basis.

-

However, any of the objects changed/output by Biomass_core listed below (Table 8.) can be saved via the outputs argument in simInit4.

- - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + +
-Table 8: List of Biomass_core output objects and their description. -
-objectName - -desc -
-activePixelIndex +a raster layer with pixelGroup IDs per pixel. Pixels are grouped based on identical ecoregionGroup, speciesCode, age and B composition, even if the user supplies other initial groupings (e.g., via the Biomass_borealDataPrep module. -internal use. Keeps track of which pixels are active +NA
-activePixelIndexReporting +rasterToMatch -internal use. Keeps track of which pixels are active in the reporting study area +RasterLayer
-ANPPMap +a raster of the studyArea in the same resolution and projection as biomassMap -ANPP map at each succession time step (in g /m^2) +NA
-cohortData +species -data.table with cohort-level information on age, biomass, aboveground primary productivity (year’s biomass gain) and mortality (year’s biomass loss), by pixelGroup and ecolocation (i.e., ecoregionGroup). Contains at least the following columns: pixelGroup (integer), ecoregionGroup (factor), speciesCode (factor), B (integer in g/m^2), age (integer in years), mortality (integer in g/m^2), aNPPAct (integer in g/m^2). May have other columns depending on additional simulated processes (i.e., cliamte sensitivity; see, e.g., P(sim)$keepClimateCols). +data.table
-ecoregionMap +a table of invariant species traits with the following trait colums: ‘species’, ‘Area’, ‘longevity’, ‘sexualmature’, ‘shadetolerance’, ‘firetolerance’, ‘seeddistance_eff’, ‘seeddistance_max’, ‘resproutprob’, ‘mortalityshape’, ‘growthcurve’, ‘resproutage_min’, ‘resproutage_max’, ‘postfireregen’, ‘wooddecayrate’, ‘leaflongevity’ ‘leafLignin’, ‘hardsoft’. The last seven traits are not used in Biomass_core , and may be ommited. However, this may result in downstream issues with other modules. Default is from Dominic Cyr and Yan Boulanger’s project -map with mapcodes match ecoregion table and speciesEcoregion table. Defaults to a dummy map matching rasterToMatch with two regions +https://raw.githubusercontent.com/dcyr/LANDIS-II_IA_generalUseFiles/master/speciesTraits.csv
-inactivePixelIndex +speciesEcoregion -internal use. Keeps track of which pixels are inactive +data.table
-inactivePixelIndexReporting +table of spatially-varying species traits (maxB, maxANPP, establishprob), defined by species and ecoregionGroup) Defaults to a dummy table based on dummy data os biomass, age, ecoregion and land cover class -internal use. Keeps track of which pixels are inactive in the reporting study area +NA
-lastFireYear +speciesLayers -Year of the most recent fire year +RasterStack
-lastReg +percent cover raster layers of tree species in Canada. Defaults to the Canadian Forestry Service, National Forest Inventory, kNN-derived species cover maps from 2001 using a cover threshold of 10 - see https://open.canada.ca/data/en/dataset/ec9e2659-1c29-4ddb-87a2-6aced147a990 for metadata -an internal counter keeping track of when the last regeneration event occurred +http://ftp.maps.canada.ca/pub/nrcan_rncan/Forests_Foret/canada-forests-attributes_attributs-forests-canada/2001-attributes_attributs-2001/
-minRelativeB +sppColorVect -define the relative biomass cut points to classify stand shade +character
-mortalityMap +A named vector of colors to use for plotting. The names must be in sim$sppEquiv[[sim$sppEquivCol]], and should also contain a color for ‘Mixed’ -map of biomass lost (in g/m^2) at each succession time step +NA
-pixelGroupMap +sppEquiv -updated community map at each succession time step +data.table
-regenerationOutput +table of species equivalencies. See LandR::sppEquivalencies_CA. -If P(sim)$calibrate == TRUE, an summary of seed dispersal and germination success (i.e., number of pixels where seeds successfully germinated) per species and year. +NA
-reproductionMap +sppNameVector -Regeneration map (biomass gains in g/m^2) at each succession time step +character
-simulatedBiomassMap +an optional vector of species names to be pulled from sppEquiv. Species names must match P(sim)$sppEquivCol column in sppEquiv. If not provided, then species will be taken from the entire P(sim)$sppEquivCol column in sppEquiv. See LandR::sppEquivalencies_CA. -Biomass map at each succession time step (in g/m^2) +NA
-simulationOutput +studyArea -contains simulation results by ecoregionGroup (main output) +SpatialPolygonsDataFrame
-simulationTreeOutput +Polygon to use as the study area. Must be provided by the user -Summary of several characteristics about the stands, derived from cohortData +NA
-species +studyAreaReporting -a table that has species traits such as longevity, shade tolerance, etc. Currently obtained from LANDIS-II Biomass Succession v.6.0-2.0 inputs +SpatialPolygonsDataFrame + +multipolygon (typically smaller/unbuffered than studyArea) to use for plotting/reporting. Defaults to studyArea. + +NA
-speciesEcoregion +sufficientLight -define the maxANPP, maxB and SEP change with both ecoregion and simulation time +data.frame + +table defining how the species with different shade tolerance respond to stand shade. Default is based on LANDIS-II Biomass Succession v6.2 parameters + +https://raw.githubusercontent.com/LANDIS-II-Foundation/Extensions-Succession/master/biomass-succession-archive/trunk/tests/v6.0-2.0/biomass-succession_test.txt
-speciesLayers +treedFirePixelTableSinceLastDisp -species percent cover raster layers, based on input speciesLayers object. Not changed by this module. +data.table +3 columns: pixelIndex, pixelGroup, and burnTime. Each row represents a forested pixel that was burned up to and including this year, since last dispersal event, with its corresponding pixelGroup and time it occurred + +NA +
+
+
+

List of parameters

+

In addition to the above inputs objects, Biomass_core uses several +parameters3 that control aspects like the simulation length, the +“succession” time step, plotting and saving intervals, amongst others. Note that +a few of these parameters are only relevant when simulating climate effects of +cohort growth and mortality, which require also loading the LandR.CS R +package4 (or another similar package). These are not discussed +in detail here, since climate effects are calculated externally to +Biomass_core in LandR.CS functions and thus documented there.

+

A list of useful parameters and their description is listed below, while the +full set of parameters is in Table 6. Like +with input objects, default values are supplied for all parameters and we +suggest the user becomes familiarized with them before attempting any changes. +We also note that the "spin-up" and "biomassMap" options for the +initialBiomassSource parameter are currently deactivated, since Biomass_core +no longer generates initial cohort biomass conditions using a spin-up based on +initial stand age like LANDIS-II ("spin-up"), nor does it attempt to fill +initial cohort biomasses using biomassMap.

+

Plotting and saving - .plots – activates/deactivates plotting and defines +type of plotting (see ?Plots);

+
    +
  • .plotInitialTime – defines when plotting starts;

  • +
  • .plotInterval – defines plotting frequency;

  • +
  • .plotMaps – activates/deactivates map plotting;

  • +
  • .saveInitialTime – defines when saving starts;

  • +
  • .saveInterval – defines saving frequency;

  • +
+

Simulation

+
    +
  • seedingAlgorithm – dispersal type (see above);

  • +
  • successionTimestep – defines frequency of dispersal/local recruitment +event (growth and mortality are always yearly);

  • +
+

Other
+- mixedType – how mixed forest stands are defined;

+
    +
  • vegLeadingProportion – relative biomass threshold to consider a species +“leading” (i.e., dominant);
  • +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - -
+Table 6: List of Biomass_core parameters and their description. +
+paramName + +paramClass + +default + +min + +max + +paramDesc +
-spinupOutput +calcSummaryBGM -Spin-up output. Currently deactivated. +character + +end + +NA + +NA + +A character vector describing when to calculate the summary of biomass, growth and mortality Currently any combination of 5 options is possible: ‘start’- as before vegetation succession events, i.e. before dispersal, ‘postDisp’ - after dispersal, ‘postRegen’ - after post-disturbance regeneration (currently the same as ‘start’), ‘postGM’ - after growth and mortality, ‘postAging’ - after aging, ‘end’ - at the end of vegetation succesion events, before plotting and saving. The ‘end’ option is always active, being also the default option. If NULL, then will skip all summaryBGM related events
-summaryBySpecies +calibrate -The total species biomass (in g/m^2 as in cohortData), average age and aNPP (in g/m^2 as in cohortData), across the landscape (used for plotting and reporting). +logical + +FALSE + +NA + +NA + +Do calibration? Defaults to FALSE
-summaryBySpecies1 +cohortDefinitionCols -No. pixels of each leading vegetation type (used for plotting and reporting). +character + +pixelGro…. + +NA + +NA + +cohortData columns that determine what constitutes a cohort This parameter should only be modified if additional modules are adding columns to cohortData
-summaryLandscape +cutpoint -The averages of total biomass (in tonnes/ha , not g/m^2 like in cohortData), age and aNPP (also in tonnes/ha) across the landscape (used for plotting and reporting). +numeric + +1e+10 + +NA + +NA + +A numeric scalar indicating how large each chunk of an internal data.table is, when processing by chunks
-treedFirePixelTableSinceLastDisp +gmcsGrowthLimits -3 columns: pixelIndex, pixelGroup, and burnTime. Each row represents a forested pixel that was burned up to and including this year, since last dispersal event, with its corresponding pixelGroup and time it occurred +numeric + +66.66666…. + +NA + +NA + +if using LandR.CS for climate-sensitive growth and mortality, a percentile is used to estimate the effect of climate on growth/mortality (currentClimate/referenceClimate). Upper and lower limits are suggested to circumvent problems caused by very small denominators as well as predictions outside the data range used to generate the model
-vegTypeMap +gmcsMortLimits -Map of leading species in each pixel, colored according to sim$sppColorVect. Species mixtures calculated according to P(sim)$vegLeadingProportion and P(sim)$mixedType. +numeric
-
+ +66.66666…. + + +NA + + +NA + + +if using LandR.CS for climate-sensitive growth and mortality, a percentile is used to estimate the effect of climate on growth/mortality (currentClimate/referenceClimate). Upper and lower limits are suggested to circumvent problems caused by very small denominators as well as predictions outside the data range used to generate the model + + + + +gmcsMinAge + + +numeric + + +21 + + +0 + + +NA + + +if using LandR.CS for climate-sensitive growth and mortality, the minimum age for which to predict climate-sensitive growth and mortality. Young stands (< 30) are poorly represented by the PSP data used to parameterize the model. + + + + +growthAndMortalityDrivers + + +character + + +LandR + + +NA + + +NA + + +package name where the following functions can be found: calculateClimateEffect, assignClimateEffect (see LandR.CS for climate sensitivity equivalent functions, or leave default if this is not desired) + + + + +growthInitialTime + + +numeric + + +start(sim) + + +NA + + +NA + + +Initial time for the growth event to occur + + + + +initialB + + +numeric + + +10 + + +1 + + +NA + + +initial biomass values of new age-1 cohorts + + + + +initialBiomassSource + + +character + + +cohortData + + +NA + + +NA + + +Currently, there are three options: ‘spinUp’, ‘cohortData’, ‘biomassMap’. If ‘spinUp’, it will derive biomass by running spinup derived from Landis-II. If ‘cohortData’, it will be taken from the cohortData object, i.e., it is already correct, by cohort. If ‘biomassMap’, it will be taken from sim$biomassMap, divided across species using sim$speciesLayers percent cover values ‘spinUp’ uses sim$standAgeMap as the driver, so biomass is an output . That means it will be unlikely to match any input information about biomass, unless this is set to ‘biomassMap’, and a sim$biomassMap is supplied. Only the ‘cohortData’ option is currently active. + + + + +keepClimateCols + + +logical + + +FALSE + + +NA + + +NA + + +include growth and mortality predictions in cohortData? + + + + +minCohortBiomass + + +numeric + + +0 + + +NA + + +NA + + +cohorts with biomass below this threshold (in g/m^2) are removed. Not a LANDIS-II BSE parameter. + + + + +mixedType + + +numeric + + +2 + + +NA + + +NA + + +How to define mixed stands: 1 for any species admixture; 2 for deciduous > conifer. See ?LandR::vegTypeMapGenerator. + + + + +plotOverstory + + +logical + + +FALSE + + +NA + + +NA + + +swap max age plot with overstory biomass + + + + +seedingAlgorithm + + +character + + +wardDisp…. + + +NA + + +NA + + +choose which seeding algorithm will be used among ‘noSeeding’ (no horizontal, nor vertical seeding - not in LANDIS-II BSE), ‘noDispersal’ (no horizontal seeding), ‘universalDispersal’ (seeds disperse to any pixel), and ‘wardDispersal’ (default; seeds disperse according to distance and dispersal traits). See Scheller & Miranda (2015) - Biomass Succession extension, v3.2.1 User Guide + + + + +spinupMortalityfraction + + +numeric + + +0.001 + + +NA + + +NA + + +defines the mortality loss fraction in spin up-stage simulation. Only used if P(sim)$initialBiomassSource == 'biomassMap', which is currently deactivated. + + + + +sppEquivCol + + +character + + +Boreal + + +NA + + +NA + + +The column in sim$sppEquiv data.table to use as a naming convention + + + + +successionTimestep + + +numeric + + +10 + + +NA + + +NA + + +defines the simulation time step, default is 10 years. Note that growth and mortality always happen on a yearly basis. Cohorts younger than this age will not be included in competitive interactions + + + + +vegLeadingProportion + + +numeric + + +0.8 + + +0 + + +1 + + +a number that defines whether a species is leading for a given pixel + + + + +.maxMemory + + +numeric + + +5 + + +NA + + +NA + + +maximum amount of memory (in GB) to use for dispersal calculations. + + + + +.plotInitialTime + + +numeric + + +start(sim) + + +NA + + +NA + + +Vector of length = 1, describing the simulation time at which the first plot event should occur. To plotting off completely use P(sim)$.plots. + + + + +.plotInterval + + +numeric + + +NA + + +NA + + +NA + + +defines the plotting time step. If NA, the default, .plotInterval is set to successionTimestep. + + + + +.plots + + +character + + +object + + +NA + + +NA + + +Passed to types in Plots (see ?Plots). There are a few plots that are made within this module, if set. Note that plots (or their data) saving will ONLY occur at end(sim). If NA, plotting is turned off completely (this includes plot saving). + + + + +.plotMaps + + +logical + + +TRUE + + +NA + + +NA + + +Controls whether maps should be plotted or not. Set to FALSE if P(sim)$.plots == NA + + + + +.saveInitialTime + + +numeric + + +NA + + +NA + + +NA + + +Vector of length = 1, describing the simulation time at which the first save event should occur. Set to NA if no saving is desired. If not NA, then saving will occur at P(sim)$.saveInitialTime with a frequency equal to P(sim)$.saveInterval + + + + +.saveInterval + + +numeric + + +NA + + +NA + + +NA + + +defines the saving time step. If NA, the default, .saveInterval is set to P(sim)$successionTimestep. + + + + +.studyAreaName + + +character + + +NA + + +NA + + +NA + + +Human-readable name for the study area used. If NA, a hash of studyArea will be used. + + + + +.useCache + + +character + + +.inputOb…. + + +NA + + +NA + + +Internal. Can be names of events or the whole module name; these will be cached by SpaDES + + + + +.useParallel + + +ANY + + +2 + + +NA + + +NA + + +Used only in seed dispersal. If numeric, it will be passed to data.table::setDTthreads and should be <= 2; If TRUE, it will be passed to parallel::makeCluster; and if a cluster object, it will be passed to parallel::parClusterApplyB. + + + + +
+
+

List of outputs

+

The main outputs of Biomass_core are the cohortData and pixelGroupMap +containing cohort information per year (note that they are not saved by +default), visual outputs of species level biomass, age and dominance across the +landscape and the simulation length, and several maps of stand biomass, +mortality and reproductive success (i.e, new biomass) on a yearly basis.

+

However, any of the objects changed/output by Biomass_core (listed in Table +7) can be saved via the outputs argument +in simInit5.

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+Table 7: List of Biomass_core output objects and their description. +
+objectName + +objectClass + +desc +
+activePixelIndex + +integer + +internal use. Keeps track of which pixels are active +
+activePixelIndexReporting + +integer + +internal use. Keeps track of which pixels are active in the reporting study area +
+ANPPMap + +RasterLayer + +ANPP map at each succession time step (in g /m^2) +
+cohortData + +data.table + +data.table with cohort-level information on age, biomass, aboveground primary productivity (year’s biomass gain) and mortality (year’s biomass loss), by pixelGroup and ecolocation (i.e., ecoregionGroup). Contains at least the following columns: pixelGroup (integer), ecoregionGroup (factor), speciesCode (factor), B (integer in g/m^2), age (integer in years), mortality (integer in g/m^2), aNPPAct (integer in g/m^2). May have other columns depending on additional simulated processes (i.e., cliamte sensitivity; see, e.g., P(sim)$keepClimateCols). +
+ecoregionMap + +RasterLayer + +map with mapcodes match ecoregion table and speciesEcoregion table. Defaults to a dummy map matching rasterToMatch with two regions +
+inactivePixelIndex + +logical + +internal use. Keeps track of which pixels are inactive +
+inactivePixelIndexReporting + +integer + +internal use. Keeps track of which pixels are inactive in the reporting study area +
+lastFireYear + +numeric + +Year of the most recent fire year +
+lastReg + +numeric + +an internal counter keeping track of when the last regeneration event occurred +
+minRelativeB + +data.frame + +define the relative biomass cut points to classify stand shade +
+mortalityMap + +RasterLayer + +map of biomass lost (in g/m^2) at each succession time step +
+pixelGroupMap + +RasterLayer + +updated community map at each succession time step +
+regenerationOutput + +data.table + +If P(sim)$calibrate == TRUE, an summary of seed dispersal and germination success (i.e., number of pixels where seeds successfully germinated) per species and year. +
+reproductionMap + +RasterLayer + +Regeneration map (biomass gains in g/m^2) at each succession time step +
+simulatedBiomassMap + +RasterLayer + +Biomass map at each succession time step (in g/m^2) +
+simulationOutput + +data.table + +contains simulation results by ecoregionGroup (main output) +
+simulationTreeOutput + +data.table + +Summary of several characteristics about the stands, derived from cohortData +
+species + +data.table + +a table that has species traits such as longevity, shade tolerance, etc. Currently obtained from LANDIS-II Biomass Succession v.6.0-2.0 inputs +
+speciesEcoregion + +data.table + +define the maxANPP, maxB and SEP change with both ecoregion and simulation time +
+speciesLayers + +RasterStack + +species percent cover raster layers, based on input speciesLayers object. Not changed by this module. +
+spinupOutput + +data.table + +Spin-up output. Currently deactivated. +
+summaryBySpecies + +data.table + +The total species biomass (in g/m^2 as in cohortData), average age and aNPP (in g/m^2 as in cohortData), across the landscape (used for plotting and reporting). +
+summaryBySpecies1 + +data.table + +No. pixels of each leading vegetation type (used for plotting and reporting). +
+summaryLandscape + +data.table + +The averages of total biomass (in tonnes/ha , not g/m^2 like in cohortData), age and aNPP (also in tonnes/ha) across the landscape (used for plotting and reporting). +
+treedFirePixelTableSinceLastDisp + +data.table + +3 columns: pixelIndex, pixelGroup, and burnTime. Each row represents a forested pixel that was burned up to and including this year, since last dispersal event, with its corresponding pixelGroup and time it occurred +
+vegTypeMap + +RasterLayer + +Map of leading species in each pixel, colored according to sim$sppColorVect. Species mixtures calculated according to P(sim)$vegLeadingProportion and P(sim)$mixedType. +

Simulation flow and module events

-

Biomass_core itself does not simulate disturbances, or their effect on vegetation (i.e., post-disturbance mortality and regeneration). Should disturbance module and post-disturbance mortality/regeneration modules be used (e.g., LandMine and Biomass_regeneration), regeneration should occur after the disturbance, but before dispersal and background vegetation growth and mortality. Hence, the disturbance itself should take place either at the very beginning or at the very end of each simulation time step.

+

Biomass_core itself does not simulate disturbances or their effect on +vegetation (i.e., post-disturbance mortality and regeneration). Should +disturbance and post-disturbance mortality/regeneration modules be used (e.g., +LandMine and Biomass_regeneration), the user should make sure that +post-disturbance effects occur after the disturbance, but before dispersal +and background vegetation growth and mortality (simulated in Biomass_core). +Hence, the disturbance itself should take place either at the very beginning or +at the very end of each simulation time step to guarantee that it happens +immediately before post-disturbance effects are calculated.

The general flow of Biomass_core processes with and without disturbances is:

    -
  1. Preparation of necessary objects for the simulation – either by data and calibration modules or by Biomass_core itself (init event);

  2. -
  3. Disturbances (OPTIONAL) – simulated by a disturbance module (e.g., LandMine);

  4. -
  5. Post-disturbance mortality/regeneration (OPTIONAL) – simulated by a regeneration module (e.g., Biomass_regeneration);

  6. -
  7. Seed dispersal (every successionTimestep; Dispersal event) – see Scheller & Domingo (2012) for details

    +
  8. Preparation of necessary objects for the simulation – either by data and +calibration modules or by Biomass_core itself (during simInit and the +init event6);

  9. +
  10. Disturbances (OPTIONAL) – simulated by a disturbance module (e.g., +LandMine);

  11. +
  12. Post-disturbance mortality/regeneration (OPTIONAL) – simulated by a +regeneration module (e.g., Biomass_regeneration);

  13. +
  14. Seed dispersal (every successionTimestep; Dispersal event):

  15. +
    -
  • Seed dispersal can be a slow process and has been adapted to occur every 10 years (default successionTimestep). The user can set it to occur more/less often, with the caveat that if using Biomass_borealDataPrep to estimate species establishment probabilities, these values are integrated over 10 years.
  • -
-
  • Growth and mortality (mortalityAndGrowth event) – see Scheller & Mladenoff (2004)

    +
  • seed dispersal can be a slow process and has been adapted to occur every +10 years (default successionTimestep). The user can set it to occur +more/less often, with the caveat that if using Biomass_borealDataPrep +to estimate species establishment probabilities, these values are +integrated over 10 years.
  • +
  • see Scheller & Domingo (2012) for details on dispersal algorithms.
  • + +
      +
    1. Growth and mortality (mortalityAndGrowth event):
    2. +
    • unlike dispersal, growth and mortality always occur time step (year).
    • -
    -
  • Cohort age binning (every successionTimestep; cohortAgeReclassification event) – see Scheller & Miranda (2015)

    +
  • see Scheller & Mladenoff (2004) for further detail.
  • + +
      +
    1. Cohort age binning (every successionTimestep; cohortAgeReclassification +event):
    2. +
      -
    • follows the same frequency as dispersal, collapsing cohorts (i.e., summing their biomass/mortality/aNPP) to ages classes with resolution equal to successionTimestep.
    • -
    -
  • Summary tables of regeneration (summaryRegen event), biomass, age, growth and mortality (summaryBGM event)

  • -
  • Plots of maps (plotMaps event) and averages (plotAvgs and plotSummaryBySpecies events)

  • -
  • Save outputs (save events)

  • +
  • follows the same frequency as dispersal, collapsing cohorts (i.e., +summing their biomass/mortality/aNPP) to ages classes with resolution +equal to successionTimestep.
  • +
  • see Scheller & Miranda (2015) for further detail.
  • + +
      +
    1. Summary tables of regeneration (summaryRegen event), biomass, age, growth +and mortality (summaryBGM event);

    2. +
    3. Plots of maps (plotMaps event) and averages (plotAvgs and +plotSummaryBySpecies events);

    4. +
    5. Save outputs (save event).

    … (repeat 2-9) …

    @@ -4817,67 +5678,217 @@

    Simulation flow and module events

    Differences between Biomass_core and the LANDIS-II Biomass Succession Extension model (LBSE)

    Algorithm changes

    -

    Upon porting LBSE into R, we made six minor modifications to the original model’s algorithms to better reflect ecological processes. This did not result in dramatic changes in simulation outputs and we note that these changes might also have been implemented in more recent versions of LBSE.

    -

    First, for each year and community (i.e., ‘pixel group’ in Biomass_core, see below), LBSE calculates the competition index for a cohort sequentially (i.e., one cohort at a time) after updating the growth and mortality (i.e., the biomass gain and loss, respectively) of other cohorts, and with the calculation sequence following cohort age in descending order, but no explicit order of species. This sorting of growth and mortality calculations from oldest to youngest cohorts in LBSE was aimed at capturing size-asymmetric competition between cohorts, under the assumption that older cohorts have priority for growing space given their greater height (Scheller pers. comm.). We felt that within-year sequential growth, death and recruitment may be not ecologically accurate, and that the size-asymmetric competition was being accounted for twice, as the calculation of the competition index already considers the competitive advantage of older cohorts (as shown in the User’s Guide, Scheller & Miranda 2015). Hence, in Biomass_core growth, mortality, recruitment and the competition index are calculated at the same time across all cohorts and species.

    -

    Second, the unknown species-level sorting mechanism contained within LBSE (which changed depending on the species order in the input species list file), led to different simulation results depending on the input species list file (e.g., Table 9 and Fig. 2). The calculation of competition, growth and mortality for all cohorts at the same time also circumvented this issue.

    +

    Upon porting LBSE into R, we made six minor modifications to the original +model’s algorithms to better reflect ecological processes. This did not +significantly alter the simulation outputs and we note that these changes might +also have been implemented in more recent versions of LBSE.

    +

    First, for each year and community (i.e., ‘pixel group’ in Biomass_core, see +below), LBSE calculates the competition index for a cohort sequentially (i.e., +one cohort at a time) after updating the growth and mortality of other cohorts +(i.e., their biomass gain and loss, respectively) , and with the calculation +sequence following cohort age in descending order, but no explicit order of +species. This sorting of growth and mortality calculations from oldest to +youngest cohorts in LBSE was aimed at capturing size-asymmetric competition +between cohorts, under the assumption that older cohorts have priority for +growing space given their greater height (Scheller pers. comm.). We felt that +within-year sequential growth, death and recruitment may be not ecologically +accurate, and that the size-asymmetric competition was being accounted for +twice, as the calculation of the competition index already considers the +competitive advantage of older cohorts (as shown in the User’s Guide, Scheller & Miranda 2015). Hence, in Biomass_core growth, mortality, recruitment +and the competition index are calculated at the same time across all cohorts and +species.

    +

    Second, the unknown species-level sorting mechanism contained within LBSE (which +changed depending on the species order in the input species list file), led to +different simulation results depending on the input species list file (e.g., +Table 8 and Fig. 2). The +calculation of competition, growth and mortality for all cohorts at the same +time also circumvented this issue.

    Differences in total landscape aboveground biomass when using two different input species orders for the same community. These simulations demonstrate how the sequential calculation of the competition index, combined with a lack of explicit species ordering affect the overall landscape aboveground biomass in time when using different input species orders (see Table \@ref(tab:tableLBSEtest1)). In order to prevent differences introduced by cohort recruitment, species’ ages at sexual maturity were changed to the species’ longevity values, and the simulation ran for 75 years to prevent any cohorts from reaching sexual maturity. The bottom panel shows the difference between the two simulations in percentage, calculated as $\frac{Biomass_{order2} - Biomass_{order1}}{Biomass_{order2}} * 100$

    -Figure 2: Differences in total landscape aboveground biomass when using two different input species orders for the same community. These simulations demonstrate how the sequential calculation of the competition index, combined with a lack of explicit species ordering affect the overall landscape aboveground biomass in time when using different input species orders (see Table 9). In order to prevent differences introduced by cohort recruitment, species’ ages at sexual maturity were changed to the species’ longevity values, and the simulation ran for 75 years to prevent any cohorts from reaching sexual maturity. The bottom panel shows the difference between the two simulations in percentage, calculated as \(\frac{Biomass_{order2} - Biomass_{order1}}{Biomass_{order2}} * 100\) +Figure 2: Differences in total landscape aboveground biomass when using two different input species orders for the same community. These simulations demonstrate how the sequential calculation of the competition index, combined with a lack of explicit species ordering affect the overall landscape aboveground biomass in time when using different input species orders (see Table 8). In order to prevent differences introduced by cohort recruitment, species’ ages at sexual maturity were changed to the species’ longevity values, and the simulation ran for 75 years to prevent any cohorts from reaching sexual maturity. The bottom panel shows the difference between the two simulations in percentage, calculated as \(\frac{Biomass_{order2} - Biomass_{order1}}{Biomass_{order2}} * 100\)

    -

    Third, in LBSE the calculation of total pixel biomass for the purpose of calculating the initial biomass of a new cohort included the (previously calculated) biomass of other new cohorts when succession time step = 1, but not when time step was > 1. This does not reflect the documentation in the User’s Guide, which stated that “Bsum [total pixel biomass] is the current total biomass for the site (not including other new cohorts)” (Scheller & Miranda 2015), when the succession time step was set to 1. Additionally, together with the lack of explicit ordering, this generated different results in terms of the biomass assigned to each new cohort (e.g. Table 10 and Fig. 3). In Biomass_core the initial biomass of new cohorts is no longer calculated sequentially (as with competition, growth and mortality), and thus the biomass of new cohorts is never included in the calculation of total pixel biomass.

    +

    Third, in LBSE the calculation of total pixel biomass for the purpose of +calculating the initial biomass of a new cohort included the (previously +calculated) biomass of other new cohorts when succession time step = 1, but not +when time step was > 1. This does not reflect the documentation in the User’s +Guide, which stated that “Bsum [total pixel biomass] is the current total +biomass for the site (not including other new cohorts)” +(Scheller & Miranda 2015), when the succession time step was set to 1. +Additionally, together with the lack of explicit ordering, this generated +different results in terms of the biomass assigned to each new cohort (e.g., +Table 9 and Fig. 3). In +Biomass_core the initial biomass of new cohorts is no longer calculated +sequentially (as with competition, growth and mortality), and thus the biomass +of new cohorts is never included in the calculation of total pixel biomass.

    -Differences in the biomasses assigned to new cohorts, summed for each species across pixels, when using two different input species orders for the same community and when the succession time step is 1. These simulations demonstrate how the different summation of total cohort biomass for a succession time step of 1 and the lack of explicit species ordering affect simulation results when changing the species order in the input file (see Table \@ref(tab:tableLBSEtest2)). Here, initial cohort ages were also set to 1. We show the initial total biomass attributed to each species at the end of year 1. +Differences in the biomass assigned to new cohorts, summed for each species across pixels, when using two different input species orders for the same community and when the succession time step is 1. These simulations demonstrate how the different summation of total cohort biomass for a succession time step of 1 and the lack of explicit species ordering affect simulation results when changing the species order in the input file (see Table \@ref(tab:tableLBSEtest2)). Here, initial cohort ages were also set to 1. Values refer to the initial total biomass attributed to each species at the end of year 1.

    -Figure 3: Differences in the biomasses assigned to new cohorts, summed for each species across pixels, when using two different input species orders for the same community and when the succession time step is 1. These simulations demonstrate how the different summation of total cohort biomass for a succession time step of 1 and the lack of explicit species ordering affect simulation results when changing the species order in the input file (see Table 10). Here, initial cohort ages were also set to 1. We show the initial total biomass attributed to each species at the end of year 1. +Figure 3: Differences in the biomass assigned to new cohorts, summed for each species across pixels, when using two different input species orders for the same community and when the succession time step is 1. These simulations demonstrate how the different summation of total cohort biomass for a succession time step of 1 and the lack of explicit species ordering affect simulation results when changing the species order in the input file (see Table 9). Here, initial cohort ages were also set to 1. Values refer to the initial total biomass attributed to each species at the end of year 1.

    -

    Fourth, in LBSE, serotiny and resprouting could not occur in the same pixel following a fire, with serotiny taking precedence if activated. We understand that this provides an advantage to serotinous species, which could perhaps be disadvantaged with respect to fast-growing resprouters. However, we feel that it is ecologically more realistic that serotinous and resprouter species be able to both regenerate in a given community following a fire and allow the competition between serotinous and resprouting species to arise from species traits. This change was implemented in the Biomass_regeneration and Biomass_regenerationPM modules .

    -

    Fifth, in Biomass_core, species shade tolerance values can have decimal values to allow for finer adjustments of between-species competition.

    -

    Sixth, we added a new parameter called minCohortBiomass, that allows the user to control cohort removal bellow a certain threshold of biomass. In some simulation set-ups, we noticed that Biomass_core (and LBSE) were able to generate many very small cohorts in the understory that, due to cohort competition, were not able to gain biomass and grow. However, because competition does not increase mortality, only decreases growth, these cohorts survived at very low biomass levels until they reached sufficient age to suffer age-related mortality. We felt this is unlikely to be realistic in many cases. By default, this parameter is left at 0 to follow LBSE behaviour (i.e., no cohorts removal based on minimum biomass).

    +

    Fourth, in LBSE, serotiny and resprouting could not occur in the same pixel +following a fire, with serotiny taking precedence if activated. We understand +that this provides an advantage to serotinous species, which could perhaps be +disadvantaged with respect to fast-growing resprouters. However, we feel that it +is ecologically more realistic that serotinous and resprouter species be able to +both regenerate in a given pixel following a fire and allow the competition +between serotinous and resprouting species to arise from species traits. Note +that this change was implemented in the Biomass_regeneration and +Biomass_regenerationPM modules, since post-disturbance effects were separated +background vegetation dynamics simulated by Biomass_core.

    +

    Fifth, in Biomass_core, species shade tolerance values can have decimal values +to allow for finer adjustments of between-species competition.

    +

    Sixth, we added a new parameter called minCohortBiomass, that allows the user +to control cohort removal bellow a certain threshold of biomass. In some +simulation set-ups, we noticed that Biomass_core (and LBSE) were able to +generate many very small cohorts in the understory that, due to cohort +competition, were not able to gain biomass and grow. However, because +competition decreases growth but does not increase mortality, these cohorts +survived at very low biomass levels until they reached sufficient age to suffer +age-related mortality. We felt this is unlikely to be realistic in many cases. +By default, this parameter is left at 0 to follow LBSE behaviour (i.e., no +cohorts removal based on minimum biomass).

    Other enhancements

    -

    In addition to the five minor changes in growth, mortality and regeneration, we separated the components that govern vegetation responses to disturbances – only fire at the moment – into two independent modules used interchangeably (Biomass_regeneration and Biomass_regenerationPM, and implemented hashing, caching and testing to improve the model’s computational efficiency and insure its performance.

    +

    In addition to the sixth changes in growth, mortality and regeneration mentioned +above, we enhanced modularity by separating the components that govern +vegetation responses to disturbances from Biomass_core, and implemented +hashing, caching and testing to improve computational efficiency and insure +performance.

    Modularity
    -

    Unlike in LBSE, post-disturbance regeneration is not part of Biomass_core per se, but belongs to two separate modules, used interchangeably (Biomass_regeneration and Biomass_regenerationPM). These need to be loaded and added to the “modules folder” of the project in case the user wants to simulate forest responses to disturbances (only fire disturbances at the moment). Again, this enables higher flexibility when swapping between different approaches to regeneration.

    -

    Climate effects on growth and mortality were also implemented a modular way. The effects of climate on biomass increase (growth) and loss (mortality) were written in functions grouped in two packages. The LandR R package contains default, no climate effect functions, while the LandR.CS R package contains the functions that simulate climate effects (CS stands for “climate sensitive”). Note that these functions do not simulate actual growth/mortality processes, but rather modifiers that increase/decrease cohort biomass on top of background growth/mortality.

    -

    Biomass_core uses the LandR functions by default (see growthAndMortalityDrivers parameter in the full parameters list). Should the user wish to change how climate effects on growth/mortality are calculated, they can provide new compatible functions (i.e., with the same names, inouts and outputs) via another R package.

    +

    Unlike in LBSE, post-disturbance effects are not part of Biomass_core per +se, but belong to two separate modules, used interchangeably +(Biomass_regeneration +and +Biomass_regenerationPM). +These need to be loaded and added to the “modules folder” of the project in case +the user wants to simulate forest responses to disturbances (only fire +disturbances at the moment). Again, this enables higher flexibility when +swapping between different approaches to regeneration.

    +

    Climate effects on growth and mortality were also implemented a modular way. The +effects of climate on biomass increase (growth) and loss (mortality) were +written in functions grouped in two packages. The LandR R package contains +default, “non-climate-sensitive” functions, while the LandR.CS R package +contains the functions that simulate climate effects (CS stands for “climate +sensitive”). Note that these functions do not simulate actual growth/mortality +processes, but estimate modifiers that increase/decrease cohort biomass on top +of background growth/mortality. Biomass_core uses the LandR functions by +default (see growthAndMortalityDrivers parameter in the full parameters +list). Should the user wish to change how climate effects on +growth/mortality are calculated, they can provide new compatible functions +(i.e., with the same names, inputs and outputs) via another R package.

    Hashing
    -

    Our first strategy to improve simulation efficiency in Biomass_core was to use a hashing mechanism (Yang et al. 2011). Instead of assigning a key to each pixel in a raster and tracking the simulation for each pixel in a lookup table, we indexed pixels using a pixelGroup key that contained unique combinations of ecolocation and community composition (i.e., species, age and biomass composition), and tracked and stored simulation data for each pixelGroup (Fig. 4). This algorithm was able to ease the computational burden by significantly reducing the size of the lookup table and speeding-up the simulation process. After recruitment and disturbance events, pixels are rehashed into new pixel groups.

    +

    Our first strategy to improve simulation efficiency in Biomass_core was to use +a hashing mechanism (Yang et al. 2011). Instead of assigning a key to each pixel in +a raster and tracking the simulation for each pixel in a lookup table, we +indexed pixels using a pixelGroup key that contained unique combinations of +ecolocation and community composition (i.e., species, age and biomass +composition), and tracked and stored simulation data for each pixelGroup (Fig. +4). This algorithm was able to ease the computational +burden by significantly reducing the size of the lookup table and speeding-up +the simulation process. After recruitment and disturbance events, pixels are +rehashed into new pixel groups.

    -Hashing design for Biomass_core. In the re-coded Biomass_core, the pixel group map was hashed based on the unique combination of species composition (i.e., community map) and ecolocation map, and associated with a lookup table. The subfigure in the right upper corner was the original design that linked the map to the lookup table by pixel key. +Hashing design for Biomass_core. In the re-coded Biomass_core, the pixel group map was hashed based on the unique combination of species composition ('community map') and ecolocation map, and associated with a lookup table. The insert in the top-right corner was the original design that linked the map to the lookup table by pixel key.

    -Figure 4: Hashing design for Biomass_core. In the re-coded Biomass_core, the pixel group map was hashed based on the unique combination of species composition (i.e., community map) and ecolocation map, and associated with a lookup table. The subfigure in the right upper corner was the original design that linked the map to the lookup table by pixel key. +Figure 4: Hashing design for Biomass_core. In the re-coded Biomass_core, the pixel group map was hashed based on the unique combination of species composition (‘community map’) and ecolocation map, and associated with a lookup table. The insert in the top-right corner was the original design that linked the map to the lookup table by pixel key.

    Caching
    -

    The second strategy aimed at improving model efficacy was the implementation of caching during data-driven parametrisation and initialisation. Caching automatically archives outputs of a given function to disk (or memory) and reads them back when subsequent calls of this function are given identical inputs. All caching operations were achieved using the reproducible R package (McIntire & Chubaty 2020).

    -

    In the current version of Biomass_core, the spin-up phase was replaced by data-driven landscape initialisation and many model parameters were derived from data, using data and calibration modules (e.g., Biomass_borealDataPrep). To avoid having to repeat data downloads and treatment, statistical estimation of parameters and landscape initialisation every time the simulation is re-run under the same conditions, many of these pre-simulation steps are automatically cached. This means that the pre-simulation phase is significantly faster upon a second call when inputs have not changed (e.g., the input data and parametrisation methods), and when inputs do change only directly affected steps are re-run (see main text for examples). When not using data modules, Biomass_core still relies on caching for the preparation of its theoretical inputs.

    +

    The second strategy aimed at improving model efficacy was the implementation of +caching during data-driven parametrisation and initialisation. Caching +automatically archives outputs of a given function to disk (or memory) and reads +them back when subsequent calls of this function are given identical inputs. All +caching operations were achieved using the reproducible R package +(McIntire & Chubaty 2020).

    +

    In the current version of Biomass_core, the spin-up phase was replaced by +data-driven landscape initialisation and many model parameters were derived from +data, using data and calibration modules (e.g., Biomass_borealDataPrep). To +avoid having to repeat data downloads and treatment, statistical estimation of +parameters and landscape initialisation every time the simulation is re-run +under the same conditions, many of these pre-simulation steps are automatically +cached. This means that the pre-simulation phase is significantly faster upon a +second call when inputs have not changed (e.g., the input data and +parametrisation methods), and when inputs do change only directly affected steps +are re-run (see main text for examples). When not using data modules, +Biomass_core still relies on caching for the preparation of its theoretical +inputs.

    Testing
    -

    Finally, we implemented code testing, to facilitate bug detection by comparing the outputs of functions (etc.) to expected outputs (Wickham 2011). We built and integrated code tests in Biomass_core and across all LandR modules and the LandR R package in the form of assertions, unit tests and integration tests. Assertions and unit tests are run automatically during simulations (but can be turned off) and evaluate individual code components (e.g., one function or an object’s class). Integration tests evaluate if several coded processes are integrated correctly. Integration tests are usually run manually. However, because we embedded assertions within the module code, R package dependencies of Biomass_core, such as the LandR R package and SpaDES, they also provide a means to test module integration. We also implemented GitHub Actions continuous integration (CI), which routinely test GitHub hosted packages (e.g., LandR). CRAN-hosted packages (e.g., SpaDES) are also automatically tested and checked on CRAN.

    -

    Finally, because Biomass_core (and all other LandR modules) code is hosted in public GitHub repositories, the module code is subject to the scrutiny of of many users, who can identify issues and contribute to improve module code.

    +

    Finally, we implemented code testing to facilitate bug detection by comparing +the outputs of functions (etc.) to expected outputs (Wickham 2011). We built and +integrated code tests in Biomass_core and across all LandR modules and the +LandR R package in the form of assertions, +unit tests and integration tests. Assertions and unit tests are run +automatically during simulations (but can be turned off) and evaluate individual +code components (e.g., one function or an object’s class). Integration tests +evaluate if several coded processes are integrated correctly and are usually run +manually. However, because we embedded assertions within the module code, R +package dependencies of Biomass_core, such as the LandR R package + and SpaDES, they also provide a means to test +module integration. We also implemented GitHub Actions continuous integration +(CI), which routinely test GitHub hosted packages (e.g., LandR) and modules. +CRAN-hosted packages (e.g., SpaDES) are also automatically tested and checked +on CRAN.

    +

    Finally, because Biomass_core (and all other LandR modules) code is hosted in +public GitHub repositories, the module code is subject to the scrutiny of +many users, who can identify issues and contribute to improve module code.

    Performance and accuracy of Biomass_core with respect to LBSE

    -

    In the recoding of Biomass_core, we ensured similar outputs of each demographic process (namely, growth, mortality and recruitment) to the outputs from its counterpart in LBSE, using integration tests. Here, we report the comparisons of the overall simulation (i.e., including all demographic processes) between LBSE and Biomass_core using three randomly generated initial communities (Tables 11-13). The remaining input parameters were taken from a LANDIS-II training course (Tables 14-17), and contained species attributes information of 16 common tree species in boreal forests and 2 ecolocations. We ran simulations for 1000 years, with a succession time step of 10 and three repetitions, which were enough to account for the variability produced by stochastic processes. Seed dispersal was set as “ward dispersal”.

    -

    The results suggested that Biomass_core had a good agreement with LBSE using the three randomly generated initial communities (Fig. 5), with very small deviations for LBSE-generated biomasses. Notably, the mean differences between LBSE and Biomass_core were 0.03% (range: -0.01% ~ 0.13%), 0.03% (range: -0.01% ~ 0.11%) and 0.05% (-0.02% ~ 0.15%) for each initial community, respectively (right panels in Fig. 5 of this appendix).

    +

    In the recoding of Biomass_core, we used integration tests to ensured similar +outputs of each demographic process (namely, growth, mortality and recruitment) +to the outputs from its counterpart in LBSE. Here, we report the +comparisons of the overall simulation (i.e., including all demographic +processes) between LBSE and Biomass_core using three randomly generated +initial communities (Tables +10-12). The remaining input +parameters were taken from a LANDIS-II training course (Tables +13-16), and contained species +attributes information of 16 common tree species in boreal forests and 2 +ecolocations. We ran simulations for 1000 years, with a succession time step of +10 and three replicates, which were enough to account for the variability +produced by stochastic processes. Seed dispersal was set as “ward dispersal”.

    +

    The results suggested that Biomass_core had a good agreement with LBSE using +the three randomly generated initial communities (Fig. 5), +with very small deviations for LBSE-generated biomasses. Notably, the mean +differences between LBSE and Biomass_core were 0.03% (range: +-0.01% ~ 0.13%), 0.03% (range: +-0.01% ~ 0.11%) and 0.05% +(-0.02% ~ 0.15%) for each initial community, +respectively (right panels in Fig. 5 of this appendix).

    Visual comparison of simulation outputs for three randomly generated initial communities (left panels) and difference between those outputs (right panels). The % difference between LBSE and Biomass_core were calculated as $\frac{Biomass_{LBSE} - Biomass_{Biomass_core}}{Biomass_{LBSE}} * 100$

    Figure 5: Visual comparison of simulation outputs for three randomly generated initial communities (left panels) and difference between those outputs (right panels). The % difference between LBSE and Biomass_core were calculated as \(\frac{Biomass_{LBSE} - Biomass_{Biomass_core}}{Biomass_{LBSE}} * 100\)

    -

    To examine how running time changed with map size, we ran simulations using maps with increasing number of pixels from 22,201 to 638,401 pixels. All maps were initialised with a single ecolocation and 7 different communities. Simulations were run for 120 years using a succession time step of 10 and replicated three times. To eliminate the effect of hardware on running time, we used machines that were all purchased at the same time, with equal specifications and running Windows 7. Each simulation ran on 2 CPU threads with a total RAM of 4000 Mb. For both LBSE and Biomass_core, the simulation time increased linearly with number of pixels, but the increase rate was smaller for Biomass_core (Fig. 6a). This meant that while both models had similar simulation efficiencies in small maps (< 90,000 pixels), as map size increased Biomass_core was ~2 times faster than LBSE (maps > 100,000 pixels; Fig. 6a). Biomass_core also scaled better with map size, as LBSE speeds fluctuated between 19 to 25 seconds per 1,000 pixels across all map sizes, while Biomass_core decreased from 21 to 11 seconds per 1,000 pixels from smaller to larger maps (Fig. 6b).

    +

    To examine how running time changed with map size, we ran simulations using maps +with increasing number of pixels, from 22,201 to 638,401 pixels. All maps were +initialised with a single ecolocation and 7 different communities. Simulations +were run for 120 years using a succession time step of 10 and replicated three +times. To eliminate the effect of hardware on running time, we used machines +that were all purchased at the same time, with equal specifications and running +Windows 7. Each simulation ran on 2 CPU threads with a total RAM of 4000 Mb.

    +

    For both LBSE and Biomass_core, the simulation time increased linearly with number +of pixels, but the increase rate was smaller for Biomass_core (Fig. +6a). This meant that while both models had similar +simulation efficiencies in small maps (< 90,000 pixels), as map size increased +Biomass_core was ~2 times faster than LBSE (maps > 100,000 pixels; Fig. +6a). Biomass_core also scaled better with map size, as +LBSE speeds fluctuated between 19 to 25 seconds per 1,000 pixels across all map +sizes, while Biomass_core decreased from 21 to 11 seconds per 1,000 pixels +from smaller to larger maps (Fig. 6b).

    Simulation efficiencies of LBSE and Biomass_core with increasing map size, in terms of a) mean running time across repetitions (left y-axis) and the ratio LBSE to Biomass_core running times (right y-axis and blue line), and b) running time scalability as the mean running time per 1000 pixels.

    @@ -4909,8 +5920,15 @@

    Set up R libraries

    Get the module and module dependencies

    -

    We can use the SpaDES.install::getModule function to download the module to the module folder specified above. Alternatively, see SpaDES-modules repository to see how to download this and other SpaDES modules, or fork/clone from its GitHub repository directly.

    -

    After downloading the module, it is important to make sure all module R package dependencies are installed in their correct version. SpaDES.install::makeSureAllPackagesInstalled takes care of this for any module in the paths$modulePath.

    +

    We can use the SpaDES.install::getModule function to download the module to +the module folder specified above. Alternatively, see SpaDES-modules +repository to see how to +download this and other SpaDES modules, or fork/clone from its GitHub +repository directly.

    +

    After downloading the module, it is important to make sure all module R package +dependencies are installed in their correct version. +SpaDES.install::makeSureAllPackagesInstalled takes care of this for any module +in the paths$modulePath.

    SpaDES.install::getModule("PredictiveEcology/Biomass_core", 
                               modulePath = paths$modulePath, overwrite = TRUE)
     
    @@ -4919,8 +5937,15 @@ 

    Get the module and module dependencies

    Setup simulation

    -

    Here we setup a simulation in a random study area, using any species within the LandR::sppEquivalencies_CA table that can be found there (Biomass_core will retrieve species % cover maps and filter present species). We also define the colour coding used for plotting, the type of plots we what to produce and choose to output cohortData tables every year – note that these are not pixel-based and to spatialise results a posteriori the pixelBroupMap must also be saved.

    -

    Please see the lists of input objects, parameters and outputs for more information.

    +

    Here we setup a simulation in a random study area, using any species within the +LandR::sppEquivalencies_CA table that can be found there (Biomass_core will +retrieve species % cover maps and filter present species). We also +define the colour coding used for plotting, the type of plots we what to produce +and choose to output cohortData tables every year – note that these are not +pixel-based, so to “spatialise” results a posteriori the pixelBroupMap must +also be saved.

    +

    Please see the lists of input objects, +parameters and outputs for more information.

    times <- list(start = 0, end = 30)
     
     studyArea <- Cache(randomStudyArea, size = 1e7) # cache this so it creates a random one only once on a machine
    @@ -4960,2016 +5985,4083 @@ 

    Setup simulation

    eventPriority = 1, stringsAsFactors = FALSE)) -graphics.off()
    -
    -
    -

    Run simulation

    -

    simInitAndSpades is a wrapper function that runs both simInit (which prepares the simulation) and spades (which initialises and runs the simulation), to which pass all the necessary setup objects created above.

    -
    mySim <- simInitAndSpades(times = times,
    -                          params = parameters, 
    -                          modules = modules, 
    -                          objects = objects, 
    -                          paths = paths,
    -                          outputs = outputs,
    -                          debug = TRUE)
    -
    -Biomass_core automatically generates simulation visuals of species dynamics across the landscape in terms of total biomass, number of presences and age and productivity (above), as well as yearly plots of total biomass, productivity, mortality, reproduction and leading species in each pixel (below).Biomass_core automatically generates simulation visuals of species dynamics across the landscape in terms of total biomass, number of presences and age and productivity (above), as well as yearly plots of total biomass, productivity, mortality, reproduction and leading species in each pixel (below). -

    -Figure 7: Biomass_core automatically generates simulation visuals of species dynamics across the landscape in terms of total biomass, number of presences and age and productivity (above), as well as yearly plots of total biomass, productivity, mortality, reproduction and leading species in each pixel (below). -

    -
    -
    -
    -
    -

    Appendix

    -
    -

    Tables

    - - ---------- +graphics.off() + +
    +

    Run simulation

    +

    simInitAndSpades is a wrapper function that runs both simInit (which +initialises all modules) and spades (which runs all modules, i.e., their events), +to which pass all the necessary setup objects created above.

    +
    mySim <- simInitAndSpades(times = times,
    +                          params = parameters, 
    +                          modules = modules, 
    +                          objects = objects, 
    +                          paths = paths,
    +                          outputs = outputs,
    +                          debug = TRUE)
    +
    +Biomass_core automatically generates simulation visuals of species dynamics across the landscape in terms of total biomass, number of presences and age and productivity (above), as well as yearly plots of total biomass, productivity, mortality, reproduction and leading species in each pixel (below).Biomass_core automatically generates simulation visuals of species dynamics across the landscape in terms of total biomass, number of presences and age and productivity (above), as well as yearly plots of total biomass, productivity, mortality, reproduction and leading species in each pixel (below). +

    +Figure 7: Biomass_core automatically generates simulation visuals of species dynamics across the landscape in terms of total biomass, number of presences and age and productivity (above), as well as yearly plots of total biomass, productivity, mortality, reproduction and leading species in each pixel (below). +

    +
    +
    + +
    +

    Appendix

    +
    +

    Tables

    + +
    Table 9: Input order and processing order (as determined by LBSE) for the same community used to assess the impact of sequential calculation of the competition index, combined with a lack of explicit species ordering. The input order was the order of species in the initial communities table input file. The processing order was the order used in the simulation, which was obtained from Landis-log.txt when CalibrateMode was set to ‘yes’. Species starting ages are also shown.
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    +Table 8: Input order and processing order (as determined by LBSE) for the same community used to assess the impact of sequential calculation of the competition index, combined with a lack of explicit species ordering. The input order was the order of species in the initial communities table input file. The processing order was the order used in the simulation, which was obtained from Landis-log.txt when CalibrateMode was set to ‘yes’. Species starting ages are also shown. +
    +Input order 1 + + + + +Input order 2 + + + +
    +Community + +Input order + +Age + +Processing + +Community + +Input order + +Age + +Processing +
    +1 + +abiebals + +20 + +poputrem + +1 + +pinustro + +20 + +thujocci +
    +1 + +acerrubr + +20 + +querelli + +1 + +poputrem + +20 + +tiliamer +
    +1 + +acersacc + +20 + +pinuresi + +1 + +acerrubr + +20 + +querelli +
    +1 + +betualle + +20 + +pinustro + +1 + +pinubank + +20 + +querrubr +
    +1 + +betupapy + +20 + +tiliamer + +1 + +betualle + +20 + +betupapy +
    +1 + +fraxamer + +20 + +tsugcana + +1 + +piceglau + +20 + +fraxamer +
    +1 + +piceglau + +20 + +querrubr + +1 + +pinuresi + +20 + +tsugcana +
    +1 + +pinubank + +20 + +thujocci + +1 + +acersacc + +20 + +abiebals +
    +1 + +pinuresi + +20 + +acersacc + +1 + +querelli + +20 + +acerrubr +
    +1 + +pinustro + +20 + +betualle + +1 + +querrubr + +20 + +pinubank +
    +1 + +poputrem + +20 + +abiebals + +1 + +thujocci + +20 + +pinustro +
    +1 + +querelli + +20 + +acerrubr + +1 + +tiliamer + +20 + +poputrem +
    +1 + +querrubr + +20 + +piceglau + +1 + +tsugcana + +20 + +pinuresi +
    +1 + +thujocci + +20 + +pinubank + +1 + +abiebals + +20 + +acersacc +
    +1 + +tiliamer + +20 + +betupapy + +1 + +betupapy + +20 + +betualle +
    +1 + +tsugcana + +20 + +fraxamer + +1 + +fraxamer + +20 + +piceglau +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    +Table 9: Input order and processing order (as determined by LBSE) for the same community used to assess the impact of setting the succession time step to 1, combined with a lack of explicit species ordering. The input order was the order of species in the initial communities table input file. The processing order was the order used in the simulation, which was obtained from Landis-log.txt when CalibrateMode was set to ‘yes’. Species starting ages are also shown. +
    +Input order 1 + + + + +Input order 2 + + + +
    +Community + +Input order + +Age + +Processing + +Community + +Input order + +Age + +Processing +
    +1 + +abiebals + +1 + +poputrem + +1 + +pinustro + +1 + +thujocci +
    +1 + +acerrubr + +1 + +querelli + +1 + +poputrem + +1 + +tiliamer +
    +1 + +acersacc + +1 + +pinuresi + +1 + +acerrubr + +1 + +querelli +
    +1 + +betualle + +1 + +pinustro + +1 + +pinubank + +1 + +querrubr +
    +1 + +betupapy + +1 + +tiliamer + +1 + +betualle + +1 + +betupapy +
    +1 + +fraxamer + +1 + +tsugcana + +1 + +piceglau + +1 + +fraxamer +
    +1 + +piceglau + +1 + +querrubr + +1 + +pinuresi + +1 + +tsugcana +
    +1 + +pinubank + +1 + +thujocci + +1 + +acersacc + +1 + +abiebals +
    +1 + +pinuresi + +1 + +acersacc + +1 + +querelli + +1 + +acerrubr +
    +1 + +pinustro + +1 + +betualle + +1 + +querrubr + +1 + +pinubank +
    +1 + +poputrem + +1 + +abiebals + +1 + +thujocci + +1 + +pinustro +
    +1 + +querelli + +1 + +acerrubr + +1 + +tiliamer + +1 + +poputrem +
    +1 + +querrubr + +1 + +piceglau + +1 + +tsugcana + +1 + +pinuresi +
    +1 + +thujocci + +1 + +pinubank + +1 + +abiebals + +1 + +acersacc +
    +1 + +tiliamer + +1 + +betupapy + +1 + +betupapy + +1 + +betualle +
    +1 + +tsugcana + +1 + +fraxamer + +1 + +fraxamer + +1 + +piceglau +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    +Table 10: Randomly generated community combination no. 1 used in the recruitment comparison runs. +
    +Community + +Species + +Age 1 + +Age 2 + +Age 3 + +Age 4 + +Age 5 + +Age 6 + +Age 7 +
    +0 + +betupapy + +1 + +37 + +45 + +46 + +85 + +NA + +NA +
    +0 + +piceglau + +27 + +73 + +153 + +256 + +270 + +NA + +NA +
    +0 + +pinustro + +157 + +159 + +181 + +220 + +223 + +303 + +307 +
    +0 + +querrubr + +80 + +102 + +127 + +152 + +206 + +227 + +NA +
    +1 + +acerrubr + +3 + +91 + +126 + +145 + +NA + +NA + +NA +
    +1 + +acersacc + +138 + +144 + +276 + +NA + +NA + +NA + +NA +
    +1 + +betualle + +24 + +106 + +136 + +149 + +279 + +NA + +NA +
    +1 + +piceglau + +27 + +67 + +70 + +153 + +NA + +NA + +NA +
    +1 + +pinubank + +3 + +10 + +24 + +31 + +71 + +NA + +NA +
    +1 + +querelli + +92 + +224 + +234 + +NA + +NA + +NA + +NA +
    +1 + +thujocci + +73 + +146 + +262 + +NA + +NA + +NA + +NA +
    +2 + +fraxamer + +108 + +118 + +137 + +147 + +204 + +NA + +NA +
    +2 + +piceglau + +40 + +128 + +131 + +159 + +174 + +NA + +NA +
    +2 + +pinustro + +78 + +156 + +237 + +245 + +270 + +NA + +NA +
    +2 + +querelli + +67 + +97 + +186 + +292 + +NA + +NA + +NA +
    +2 + +tiliamer + +70 + +103 + +121 + +152 + +178 + +180 + +245 +
    +3 + +acerrubr + +5 + +83 + +125 + +126 + +127 + +NA + +NA +
    +3 + +pinuresi + +1 + +25 + +42 + +49 + +76 + +79 + +103 +
    +3 + +poputrem + +4 + +9 + +62 + +NA + +NA + +NA + +NA +
    +3 + +querelli + +101 + +104 + +167 + +226 + +NA + +NA + +NA +
    +3 + +tsugcana + +37 + +135 + +197 + +404 + +405 + +NA + +NA +
    +4 + +acerrubr + +15 + +29 + +63 + +70 + +105 + +133 + +NA +
    +4 + +piceglau + +67 + +132 + +189 + +NA + +NA + +NA + +NA +
    +4 + +tsugcana + +21 + +26 + +110 + +146 + +341 + +462 + +463 +
    +5 + +acerrubr + +128 + +137 + +145 + +147 + +NA + +NA + +NA +
    +5 + +acersacc + +241 + +245 + +261 + +277 + +NA + +NA + +NA +
    +5 + +querrubr + +23 + +72 + +120 + +142 + +188 + +NA + +NA +
    +5 + +tiliamer + +4 + +68 + +98 + +118 + +139 + +197 + +NA +
    +6 + +betualle + +5 + +23 + +31 + +249 + +NA + +NA + +NA +
    +6 + +pinubank + +67 + +70 + +89 + +NA + +NA + +NA + +NA +
    +6 + +querelli + +194 + +217 + +257 + +NA + +NA + +NA + +NA +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    +Table 12: Randomly generated community combination no. 3 used in the recruitment comparison runs. +
    +Community + +Species + +Age 1 + +Age 2 + +Age 3 + +Age 4 + +Age 5 + +Age 6 + +Age 7 +
    +0 + +pinubank + +7 + +26 + +32 + +37 + +48 + +85 + +90 +
    +0 + +pinuresi + +11 + +103 + +109 + +179 + +188 + +197 + +NA +
    +0 + +querrubr + +89 + +139 + +180 + +206 + +NA + +NA + +NA +
    +1 + +betupapy + +36 + +39 + +45 + +49 + +66 + +68 + +NA +
    +1 + +piceglau + +13 + +165 + +254 + +NA + +NA + +NA + +NA +
    +1 + +pinubank + +3 + +19 + +54 + +64 + +76 + +NA + +NA +
    +1 + +poputrem + +22 + +59 + +93 + +NA + +NA + +NA + +NA +
    +1 + +thujocci + +68 + +98 + +274 + +275 + +363 + +378 + +NA +
    +1 + +tiliamer + +13 + +20 + +105 + +124 + +248 + +NA + +NA +
    +1 + +tsugcana + +36 + +90 + +142 + +NA + +NA + +NA + +NA +
    +2 + +fraxamer + +11 + +241 + +279 + +NA + +NA + +NA + +NA +
    +2 + +piceglau + +16 + +42 + +129 + +177 + +200 + +244 + +NA +
    +2 + +pinustro + +200 + +342 + +384 + +NA + +NA + +NA + +NA +
    +3 + +abiebals + +31 + +57 + +61 + +92 + +108 + +162 + +183 +
    +3 + +piceglau + +126 + +255 + +261 + +267 + +NA + +NA + +NA +
    +3 + +poputrem + +28 + +41 + +57 + +NA + +NA + +NA + +NA +
    +3 + +querrubr + +83 + +91 + +144 + +173 + +184 + +238 + +NA +
    +3 + +thujocci + +6 + +66 + +68 + +204 + +NA + +NA + +NA +
    +4 + +fraxamer + +12 + +110 + +266 + +270 + +NA + +NA + +NA +
    +4 + +pinustro + +174 + +270 + +359 + +379 + +NA + +NA + +NA +
    +4 + +poputrem + +4 + +7 + +18 + +24 + +63 + +76 + +NA +
    +4 + +tiliamer + +126 + +136 + +197 + +NA + +NA + +NA + +NA +
    +4 + +tsugcana + +49 + +91 + +128 + +194 + +411 + +487 + +NA +
    +5 + +abiebals + +35 + +53 + +108 + +114 + +147 + +174 + +195 +
    +5 + +acerrubr + +1 + +2 + +101 + +145 + +NA + +NA + +NA +
    +5 + +pinubank + +14 + +15 + +38 + +40 + +59 + +69 + +83 +
    +6 + +acerrubr + +4 + +46 + +117 + +NA + +NA + +NA + +NA +
    +6 + +betualle + +36 + +41 + +116 + +213 + +253 + +NA + +NA +
    +6 + +betupapy + +4 + +6 + +76 + +NA + +NA + +NA + +NA +
    +6 + +pinuresi + +43 + +68 + +85 + +171 + +NA + +NA + +NA +
    +6 + +querrubr + +84 + +86 + +113 + +185 + +193 + +223 + +228 +
    +6 + +tiliamer + +13 + +106 + +181 + +199 + +246 + +NA + +NA +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    +Table 13: Invariant species traits table used in comparison runs. +
    +Species + +Longevity + +Sexualmature + +Shadetolerance + +Seeddistance_eff + +Seeddistance_max + +Mortalityshape + +Growthcurve +
    +abiebals + +200 + +25 + +5 + +30 + +160 + +10 + +0.25 +
    +acerrubr + +150 + +10 + +4 + +100 + +200 + +10 + +0.25 +
    +acersacc + +300 + +40 + +5 + +100 + +200 + +10 + +0.25 +
    +betualle + +300 + +40 + +4 + +100 + +400 + +10 + +0.25 +
    +betupapy + +100 + +30 + +2 + +200 + +5000 + +10 + +0.25 +
    +fraxamer + +300 + +30 + +4 + +70 + +140 + +10 + +0.25 +
    +piceglau + +300 + +25 + +3 + +30 + +200 + +10 + +0.25 +
    +pinubank + +100 + +15 + +1 + +20 + +100 + +10 + +0.25 +
    +pinuresi + +200 + +35 + +2 + +20 + +275 + +10 + +0.25 +
    +pinustro + +400 + +40 + +3 + +60 + +210 + +10 + +0.25 +
    +poputrem + +100 + +20 + +1 + +1000 + +5000 + +10 + +0.25 +
    +querelli + +300 + +35 + +2 + +30 + +3000 + +10 + +0.25 +
    +querrubr + +250 + +25 + +3 + +30 + +3000 + +10 + +0.25 +
    +thujocci + +400 + +30 + +2 + +45 + +60 + +10 + +0.25 +
    +tiliamer + +250 + +30 + +4 + +30 + +120 + +10 + +0.25 +
    +tsugcana + +500 + +30 + +5 + +30 + +100 + +10 + +0.25 +
    + + + + + + + + + + + + + + + + + + + + + + + + + +
    +Table 14: Minimum relative biomass table used in comparison runs. X0-5 represent site shade classes from no-shade (0) to maximum shade (5). All ecolocations shared the same values. +
    +Ecolocation + +X0 + +X1 + +X2 + +X3 + +X4 + +X5 +
    +All + +0 + +0.15 + +0.25 + +0.5 + +0.8 + +0.95 +
    + + + - - - - - - - - - + + + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + - -
    +Table 15: Probability of germination for species shade tolerance and shade level combinations (called sufficient light table in LBSE and sufficientLight input data.table in LandR Biomass_core) used in comparison runs. +
    Input order 1Input order 2
    +Shadetolerance + +0 + +1 + +2 + +3 + +4 + +5 +
    CommunityInputAgeProcessingCommunityInputAgeProcessing
    orderorderorderorder
    1abiebals20poputrem1pinustro20thujocci
    1acerrubr20querelli1poputrem20tiliamer
    1acersacc20pinuresi1acerrubr20querelli
    1betualle20pinustro1pinubank20querrubr
    1betupapy20tiliamer1betualle20betupapy
    1fraxamer20tsugcana1piceglau20fraxamer
    1piceglau20querrubr1pinuresi20tsugcana
    1pinubank20thujocci1acersacc20abiebals
    1pinuresi20acersacc1querelli20acerrubr
    1pinustro20betualle1querrubr20pinubank
    1poputrem20abiebals1thujocci20pinustro
    1querelli20acerrubr1tiliamer20poputrem
    1querrubr20piceglau1tsugcana20pinuresi
    1thujocci20pinubank1abiebals20acersacc
    1tiliamer20betupapy1betupapy20betualle
    1tsugcana20fraxamer1fraxamer20piceglau
    +1 + +1 + +0 + +0 + +0 + +0 + +0 +
    - - ---------- - - - - - - - - - - + + + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + - -
    Table 10: Input order and processing order (as determined by LBSE) for the same community used to assess the impact of setting the succession time step to 1, combined with a lack of explicit species ordering. The input order was the order of species in the initial communities table input file. The processing order was the order used in the simulation, which was obtained from Landis-log.txt when CalibrateMode was set to ‘yes’. Species starting ages are also shown.
    Input order 1Input order 2
    +2 + +1 + +1 + +0 + +0 + +0 + +0 +
    CommunityInputAgeProcessingCommunityInputAgeProcessing
    orderorderorderorder
    1abiebals1poputrem1pinustro1thujocci
    1acerrubr1querelli1poputrem1tiliamer
    1acersacc1pinuresi1acerrubr1querelli
    1betualle1pinustro1pinubank1querrubr
    1betupapy1tiliamer1betualle1betupapy
    1fraxamer1tsugcana1piceglau1fraxamer
    1piceglau1querrubr1pinuresi1tsugcana
    1pinubank1thujocci1acersacc1abiebals
    1pinuresi1acersacc1querelli1acerrubr
    1pinustro1betualle1querrubr1pinubank
    1poputrem1abiebals1thujocci1pinustro
    1querelli1acerrubr1tiliamer1poputrem
    1querrubr1piceglau1tsugcana1pinuresi
    1thujocci1pinubank1abiebals1acersacc
    1tiliamer1betupapy1betupapy1betualle
    1tsugcana1fraxamer1fraxamer1piceglau
    +3 + +1 + +1 + +1 + +0 + +0 + +0 +
    - - ----------- - - - - - - - - - - - + + + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + +
    Table 11: Randomly generated community combination no. 1 used in the recruitment comparison runs.
    CommunitySpeciesAge 1Age 2Age 3Age 4Age 5Age 6Age 7
    +4 + +1 + +1 + +1 + +1 + +0 + +0 +
    0betupapy137454685NANA
    0piceglau2773153256270NANA
    0pinustro157159181220223303307
    0querrubr80102127152206227NA
    1acerrubr391126145NANANA
    1acersacc138144276NANANANA
    1betualle24106136149279NANA
    1piceglau276770153NANANA
    1pinubank310243171NANA
    1querelli92224234NANANANA
    1thujocci73146262NANANANA
    2fraxamer108118137147204NANA
    2piceglau40128131159174NANA
    2pinustro78156237245270NANA
    2querelli6797186292NANANA
    2tiliamer70103121152178180245
    3acerrubr583125126127NANA
    3pinuresi12542497679103
    3poputrem4962NANANANA
    3querelli101104167226NANANA
    3tsugcana37135197404405NANA
    4acerrubr15296370105133NA
    4piceglau67132189NANANANA
    4tsugcana2126110146341462463
    5acerrubr128137145147NANANA
    5acersacc241245261277NANANA
    5querrubr2372120142188NANA
    5tiliamer46898118139197NA
    6betualle52331249NANANA
    6pinubank677089NANANANA
    6querelli194217257NANANANA
    +5 + +0 + +0 + +1 + +1 + +1 + +1 +
    - - ----------- + +
    Table 12: Randomly generated community combination no. 2 used in the recruitment comparison runs.
    + - - - - - - - - - - + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + - -
    +Table 16: Species ecolocation table used in comparison runs. SEP stands for species establishment probability, maxB for maximum biomass and maxANPP for maximum aboveground net primary productivity. Values were held constant throughout the simulation. +
    CommunitySpeciesAge 1Age 2Age 3Age 4Age 5Age 6Age 7
    +Ecolocation + +Species + +SEP + +maxANPP + +maxB +
    0acerrubr2226304047145146
    0betualle234143120209227270
    0fraxamer2590119173185282NA
    0pinuresi485370121157NANA
    0pinustro582126298352NANA
    0querrubr230347477162245
    1acerrubr2394384116127143
    1pinubank345775NANANANA
    1querelli108202218243NANANA
    1querrubr5117131186189246NA
    1tiliamer10194680133148231
    1tsugcana3148190246330NANA
    2pinubank113738476793NA
    2querrubr114857177180228236
    2tiliamer28427879223250NA
    2tsugcana140202372381451NANA
    3acersacc48107262265NANANA
    3betupapy41245658396NA
    3poputrem1320377590NANA
    3querelli7290104115116265278
    3tiliamer20215698237NANA
    3tsugcana86224425429NANANA
    4fraxamer77133181NANANANA
    4pinustro133767220287293375
    4querrubr27488997NANANA
    4thujocci91244305390NANANA
    5abiebals8695119121127158NA
    5betualle83113136161216231NA
    5betupapy103864NANANANA
    5piceglau166370102NANANA
    6acerrubr834112NANANANA
    6betupapy1315761748091
    6fraxamer63100108140196294NA
    6pinubank151944475180NA
    6thujocci78146163213214228NA
    6tsugcana47108387389449NANA
    +1 + +abiebals + +0.90 + +886 + +26580 +
    - - ----------- - - - - - - - - - - - + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + - -
    Table 13: Randomly generated community combination no. 3 used in the recruitment comparison runs.
    CommunitySpeciesAge 1Age 2Age 3Age 4Age 5Age 6Age 7
    +1 + +acerrubr + +1.00 + +1175 + +35250 +
    0pinubank7263237488590
    0pinuresi11103109179188197NA
    0querrubr89139180206NANANA
    1betupapy363945496668NA
    1piceglau13165254NANANANA
    1pinubank319546476NANA
    1poputrem225993NANANANA
    1thujocci6898274275363378NA
    1tiliamer1320105124248NANA
    1tsugcana3690142NANANANA
    2fraxamer11241279NANANANA
    2piceglau1642129177200244NA
    2pinustro200342384NANANANA
    3abiebals31576192108162183
    3piceglau126255261267NANANA
    3poputrem284157NANANANA
    3querrubr8391144173184238NA
    3thujocci66668204NANANA
    4fraxamer12110266270NANANA
    4pinustro174270359379NANANA
    4poputrem4718246376NA
    4tiliamer126136197NANANANA
    4tsugcana4991128194411487NA
    5abiebals3553108114147174195
    5acerrubr12101145NANANA
    5pinubank14153840596983
    6acerrubr446117NANANANA
    6betualle3641116213253NANA
    6betupapy4676NANANANA
    6pinuresi436885171NANANA
    6querrubr8486113185193223228
    6tiliamer13106181199246NANA
    +1 + +acersacc + +0.82 + +1106 + +33180 +
    - - ---------- - - - - - - - - - - + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + - -
    Table 14: Invariant species traits table used in comparison runs.
    SpeciesLongevitySexualmatureShadetoleranceSeeddistance_effSeeddistance_maxMortalityshapeGrowthcurve
    +1 + +betualle + +0.64 + +1202 + +36060 +
    abiebals20025530160100.25
    acerrubr150104100200100.25
    acersacc300405100200100.25
    betualle300404100400100.25
    betupapy1003022005000100.25
    fraxamer30030470140100.25
    piceglau30025330200100.25
    pinubank10015120100100.25
    pinuresi20035220275100.25
    pinustro40040360210100.25
    poputrem10020110005000100.25
    querelli300352303000100.25
    querrubr250253303000100.25
    thujocci4003024560100.25
    tiliamer25030430120100.25
    tsugcana50030530100100.25
    +1 + +betupapy + +1.00 + +1202 + +36060 +
    - - - - - - - - - - - + + + + + + - - - - - - - - - - + + + + + + - -
    Table 15: Minimum relative biomass table used in comparison runs. X0-5 represent site shade classes from no-shade (0) to maximum shade (5). All ecolocations shared the same values.
    EcolocationX0X1X2X3X4X5
    +1 + +fraxamer + +0.18 + +1202 + +36060 +
    All00.150.250.50.80.95
    +1 + +piceglau + +0.58 + +969 + +29070 +
    - - - - - - - - - - - + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + - -
    Table 16: Probability of germination for species shade tolerance and shade level combinations (called sufficient light table in LBSE and sufficientLight input data.table in LandR Biomass_core) used in comparison runs.
    Shadetolerance012345
    +1 + +pinubank + +1.00 + +1130 + +33900 +
    1100000
    2110000
    3111000
    4111100
    5001111
    +1 + +pinuresi + +0.56 + +1017 + +30510 +
    - - - - - - - - - + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    Table 17: Species ecolocation table used in comparison runs. SEP stands for species establishment probability, maxB for maximum biomass and maxANPP for maximum aboveground net primary productivity. Values were held constant throughout the simulation.
    EcolocationSpeciesSEPmaxANPPmaxB
    +1 + +pinustro + +0.72 + +1090 + +38150 +
    1abiebals0.988626580
    1acerrubr1117535250
    1acersacc0.82110633180
    1betualle0.64120236060
    1betupapy1120236060
    1fraxamer0.18120236060
    1piceglau0.5896929070
    1pinubank1113033900
    1pinuresi0.56101730510
    1pinustro0.72109038150
    1poputrem1107832340
    1querelli0.96109632880
    1querrubr0.66101730510
    1thujocci0.76109032700
    1tiliamer0.54107832340
    1tsugcana0.22109632880
    +1 + +poputrem + +1.00 + +1078 + +32340 +
    +1 + +querelli + +0.96 + +1096 + +32880 +
    +1 + +querrubr + +0.66 + +1017 + +30510 +
    +1 + +thujocci + +0.76 + +1090 + +32700 +
    +1 + +tiliamer + +0.54 + +1078 + +32340 +
    +1 + +tsugcana + +0.22 + +1096 + +32880 +
    @@ -7013,10 +10105,24 @@

    References


      -
    1. In LBSE the initialisation consists in “iterat[ing] the number of time steps equal to the maximum cohort age for each site”, beginning at 0 minus t (t = oldest cohort age) and adding cohorts at the appropriate time until the initial simulation time is reached (0) (Scheller & Miranda 2015).↩︎

    2. -
    3. usually, default inputs are made when running the .inputObjects function (inside the module R script) during the simInit call and in the init event during the spades call – see ?SpaDES.core::events and SpaDES.core::simInit↩︎

    4. -
    5. in SpaDES lingo parameters are “small” objects, such as an integer or boolean, that can be controlled via the parameters argument in simInit↩︎

    6. -
    7. see ?SpaDES.core::outputs↩︎

    8. +
    9. in LBSE the initialisation consists in “iterat[ing] the +number of time steps equal to the maximum cohort age for each site”, +beginning at 0 minus t (t = oldest cohort age) and adding cohorts at the +appropriate time until the initial simulation time is reached (0) +(Scheller & Miranda 2015).↩︎

    10. +
    11. usually, default inputs are made when running the +.inputObjects function (inside the module R script) during the simInit +call and in the init event during the spades call – see +?SpaDES.core::events and SpaDES.core::simInit↩︎

    12. +
    13. in SpaDES lingo parameters are “small” objects, such as an +integer or boolean, that can be controlled via the parameters argument in +simInit.↩︎

    14. +
    15. https://github.com/ianmseddy/LandR.CS↩︎

    16. +
    17. see ?SpaDES.core::outputs↩︎

    18. +
    19. simInit is a SpaDES function that initialises the +execution of one or more modules by parsing and checking their code and +executing the .inputObjects function(s), where the developer provides +mechanisms to satisfy each module’s expected inputs with default values.↩︎

    diff --git a/Biomass_core.md b/Biomass_core.md index 5a0ac51..c626545 100644 --- a/Biomass_core.md +++ b/Biomass_core.md @@ -1,6 +1,6 @@ --- title: "LandR _Biomass_core_ Manual" -date: "Last updated: 2022-05-27" +date: "Last updated: 2022-06-02" output: bookdown::html_document2: toc: true @@ -22,22 +22,38 @@ always_allow_html: true (ref:Biomass-core) *Biomass_core* +(ref:Biomass-borealdataPrep) *Biomass_borealDataPrep* + (ref:percent) % +(ref:sufficient-light) *sufficient light* + +(ref:Abie-sp) *Abies sp.* (Abie_sp) + +(ref:Pinu-sp) *Pinus sp.* (Pinu_sp) + +(ref:Pice-eng) *Picea engelmannii* (Pice_eng) +(ref:Pice-gla) *Picea glauca* (Pice_gla) +(ref:Popu-sp) *Populus sp.* (Popu_sp) +(ref:Pseud-men) *Pseudotsuga menziesii* (Pseu_men) - -[![module-version-Badge](figures/moduleVersionBadge.png)](https://github.com/CeresBarros/Biomass_core/commit/665d6db36f5f12d3c5068aa3e5ecc874e84f51f0) [![Issues-badge](figures/issuesBadge.png)](https://github.com/PredictiveEcology/Biomass_core/issues) - + + + +[![module-version-Badge](D:/GitHub/LandR-Manual/modules/Biomass_core/figures/moduleVersionBadge.png)](https://github.com:CeresBarros/Biomass_core/commit//tree/d9b51b5d4db6ff96e37f566f71398b48fc18536b) #### Authors: -Yong Luo [aut], Eliot J B McIntire [aut, cre], Jean Marchal [ctb], Alex M. Chubaty [ctb], Ceres Barros [ctb] +Yong Luo [aut], Eliot J B McIntire [aut, cre], Ceres Barros [aut], Alex M. Chubaty [aut], Ian Eddy [ctb], Jean Marchal [ctb] + -**This documentation is work in progress. Potential discrepancies and omissions may exist for the time being. If you find any, contact us using the "Get help" link above\^\^** +**This documentation is work in progress. Potential discrepancies and omissions +may exist for the time being. If you find any, contact us using the "Get help" +link above.** ## Module Overview @@ -55,223 +71,799 @@ Yong Luo [aut], Eliot J B McIntire -(ref:Biomass-core) simulates tree cohort growth, mortality, recruitment and dispersal dynamics, as a function of  cohort ageing and competition for light (shading) and space, as well as disturbances like fire (simulated using other modules). +(ref:Biomass-core) simulates tree cohort growth, mortality, recruitment and dispersal dynamics, as a function of  cohort ageing and competition for light (shading) and space, as well as disturbances like fire (simulated using other modules).

    (\#fig:fig-Biomass-core)(ref:Biomass-core) simulates tree cohort growth, mortality, recruitment and dispersal dynamics, as a function of cohort ageing and competition for light (shading) and space, as well as disturbances like fire (simulated using other modules).

    ### Links to other modules {#links-modules} -*Biomass_core* is intended to be used with data/calibration modules, disturbance modules and validation modules, amongst others. The following is a list of the modules most commonly used with *Biomass_core*. Not all are in the [LandR Manual](https://landr-manual.predictiveecology.org/), but click the links to their repository URLs where documentation can be found (`.Rmd` file). See [here](https://rpubs.com/PredictiveEcology/LandR_Module_Ecosystem) for all available modules and select *Biomass_core* from the drop-down menu to see linkages. +*Biomass_core* is intended to be used with data/calibration modules, disturbance +modules and validation modules, amongst others. The following is a list of the +modules most commonly used with *Biomass_core*. Not all are in the [LandR +Manual](https://landr-manual.predictiveecology.org/), but see each module's +documentation (`.Rmd` file) available in its repository. + +See [here](https://rpubs.com/PredictiveEcology/LandR_Module_Ecosystem) for all +available modules and select *Biomass_core* from the drop-down menu to see +linkages. **Data and calibration modules:** -- [*Biomass_speciesData*](https://github.com/PredictiveEcology/Biomass_speciesData): grabs and merges several sources of species cover data, making species percent cover ((ref:percent) cover) layers used by other LandR Biomass modules. Default source data spans the entire Canadian territory; -- [*Biomass_borealDataPrep*](https://github.com/PredictiveEcology/Biomass_borealDataPrep): prepares all parameters and inputs (including initial landscape conditions) that *Biomass_core* needs to run a realistic simulation. By default, the values/inputs produced are relevant for boreal forests of Western Canada; -- [*Biomass_speciesParameters*](https://github.com/PredictiveEcology/Biomass_speciesParameters): calibrates four-species level traits using permanent sample plot data across Western Canada. +- [*Biomass_speciesData*](https://github.com/PredictiveEcology/Biomass_speciesData): +grabs and merges several sources of species cover data, making species +percent cover ((ref:percent) cover) layers used by other LandR Biomass +modules. Default source data spans the entire Canadian territory; + +- [*Biomass_borealDataPrep*](https://github.com/PredictiveEcology/Biomass_borealDataPrep): +prepares all parameters and inputs (including initial landscape conditions) +that *Biomass_core* needs to run a realistic simulation. Default +values/inputs produced are relevant for boreal forests of Western Canada; + +- [*Biomass_speciesParameters*](https://github.com/PredictiveEcology/Biomass_speciesParameters): +calibrates four-species level traits using permanent sample plot data (i.e., +repeated tree biomass measurements) across Western Canada. **Disturbance-related modules:** -- [*Biomass_regeneration*](https://github.com/PredictiveEcology/Biomass_regeneration): simulates cohort biomass responses to stand-replacing fires (as in LBSE), including cohort mortality and regeneration through resprouting and/or serotiny; +- [*Biomass_regeneration*](https://github.com/PredictiveEcology/Biomass_regeneration): +simulates cohort biomass responses to stand-replacing fires (as in LBSE), +including cohort mortality and regeneration through resprouting and/or +serotiny; -- [*Biomass_regenerationPM*](https://github.com/PredictiveEcology/Biomass_regenerationPM): like *Biomass_regeneration*, but allowing partial mortality. Based on the LANDIS-II Dynamic Fuels & Fire System extension [@SturtevantEtAl2018]; +- [*Biomass_regenerationPM*](https://github.com/PredictiveEcology/Biomass_regenerationPM): +like *Biomass_regeneration*, but allowing partial mortality. Based on the +LANDIS-II Dynamic Fuels & Fire System extension [@SturtevantEtAl2018]; -- *fireSense*: climate- and land-cover-sensitive fire model simulating fire ignition, escape and spread processes as a function of climate and land-cover. Includes built-in parameterisation of these processes using climate, land-cover, fire occurrence and fire perimeter data. Requires using *Biomass_regeneration* or *Biomass_regenerationPM*. See modules prefixed "*fireSense\_*" at ; +- *fireSense*: climate- and land-cover-sensitive fire model simulating fire +ignition, escape and spread processes as a function of climate and +land-cover. Includes built-in parameterisation of these processes using +climate, land-cover, fire occurrence and fire perimeter data. Requires using +*Biomass_regeneration* or *Biomass_regenerationPM*. See modules prefixed +"*fireSense\_*" at ; -- [*LandMine*](https://github.com/PredictiveEcology/LandMine): wildfire ignition and cover-sensitive wildfire spread model based on a fire return interval input. Requires using *Biomass_regeneration* or *Biomass_regenerationPM*; +- [*LandMine*](https://github.com/PredictiveEcology/LandMine): wildfire +ignition and cover-sensitive wildfire spread model based on a fire return +interval input. Requires using *Biomass_regeneration* or +*Biomass_regenerationPM*; -- [*scfm*](https://github.com/PredictiveEcology/scfm): spatially explicit fire spread module parameterised and modelled as a stochastic three-part process of ignition, escape, and spread. Requires using *Biomass_regeneration* or *Biomass_regenerationPM*. +- [*scfm*](https://github.com/PredictiveEcology/scfm): spatially explicit fire +spread module parameterised and modelled as a stochastic three-part process +of ignition, escape, and spread. Requires using *Biomass_regeneration* or +*Biomass_regenerationPM*. **Validation modules:** -- [*Biomass_validationKNN*](https://github.com/PredictiveEcology/Biomass_validationKNN): calculates two validation metrics (mean absolute deviation and sum of negative log-likelihoods) on species presences/absences and biomass-related properties across the simulated landscape. By default, it uses an independent dataset of species (ref:percent) cover and stand biomass for 2011, assuming that this is a second snapshot of the landscape. +- [*Biomass_validationKNN*](https://github.com/PredictiveEcology/Biomass_validationKNN): +calculates two validation metrics (mean absolute deviation and sum of +negative log-likelihoods) on species presences/absences and biomass-related +properties across the simulated landscape. By default, it uses an +independent dataset of species (ref:percent) cover and stand biomass for +2011, assuming that this is a second snapshot of the landscape. ## Module manual ### General functioning {#general-functioning} -LandR *Biomass_core* (hereafter *Biomass_core*) is a forest landscape model based on the LANDIS-II Biomass Succession Extension v.3.2.1 model [LBSE, @SchellerMiranda2015]. It is the core forest succession model of the LandR ecosystem of `SpaDES` modules. Similarly to LBSE, *Biomass_core* simulates changes in tree cohort aboveground biomass ($g/m^2$) by calculating growth, mortality and recruitment as functions of pixel and species characteristics, competition and disturbances (Fig. \@ref(fig:fig-Biomass-core)). Note that, by default, cohorts are unique combinations of species and age, but this can be changed via the `cohortDefinitionCols` parameter (see [List of parameters](#params-list)). - -Specifically, cohort growth is driven by both invariant (growth shape parameter, `growthcurve`) and spatio-temporally varying species traits (maximum biomass, `maxB`, and maximum annual net primary productivity, `maxANPP`), while background mortality (i.e., not caused by disturbances) depends only on invariant species traits (`longevity` and mortality shape parameter, `mortalityshape`). All five traits directly influence the realised shape of species growth curves, by determining how fast they grow (`growthcurve` and `maxANPP`), how soon age mortality starts with respect to longevity (`mortalityshape`) and the biomass a cohort can potentially achieve (`maxB`). - -Cohort recruitment is determined by available "space" (i.e., pixel shade), invariant species traits (regeneration mode, `postfireregen`, age at maturity, `sexualmature`, shade tolerance, `shadetolerance`) and spatio-temporally varying traits (species establishment probability, `establishprob`, called SEP hereafter). The available "growing space" is calculated as the species `maxB` minus the occupied biomass (summed across other cohorts and species). If there is "space", a cohort can establish from one of three recruitment modes: serotiny, resprouting and germination. While `maxB`, `maxANPP` and SEP vary both spatio-temporally and by species ([spatio-temporally varying species traits](#varying-traits)), `growthcurve`, `mortalityshape` and `longevity` vary only between species ([invariant species traits](#invariant-traits)) - -Disturbances (e.g., fire) can cause cohort mortality and trigger post-disturbance regeneration. Two processes of post-disturbance regeneration have been implemented, following LBSE mechanisms: serotiny and resprouting [@SchellerMiranda2015]. These two processes (post-disturbance mortality and regeneration) only occur in response to fire and are simulated in two separate, but interchangeable modules, *Biomass_regeneration* and *Biomass_regenerationPM* that differ with respect to the level of post-fire mortality they simulate (complete or partial mortality, respectively). - -Cohort germination (also called cohort establishment) occurs if seeds are available from local sources (the pixel), or via seed dispersal. Seed dispersal can be of three modes: 'no dispersal', 'universal dispersal' (only interesting for dummy case studies) or 'ward dispersal' [@SchellerMiranda2015]. The 'ward dispersal' algorithm describes a flexible kernel that calculates the probability of a species colonising a neighbour pixel as a function of distance from the source and dispersal-related (and invariant) species traits, and is used by default. - -Both germination and regeneration success depend on the species' probability of germination in a given pixel ([probabilities of germination](#prob-germ)). - -We refer the reader to @SchellerMiranda2015, @SchellerDomingo2011 and @SchellerDomingo2012 for further details with respect to the above mentioned mechanisms implemented in *Biomass_core*. Existing [differences between *Biomass_core* and LBSE](#biomass-core-vs-lbse) are detailed below, together with [comparisons between the two modules](#biomass-core-vs-lbse-comparisons). - -### Initialization, inputs and parameters {#init-inputs-params} - -To initialise and simulate forest dynamics in any given landscape, *Biomass_core* requires a number of inputs and parameters namely: +*Biomass_core* is a forest landscape model based on the LANDIS-II Biomass +Succession Extension v.3.2.1 model [LBSE, @SchellerMiranda2015]. It is the core +forest succession model of the LandR ecosystem of `SpaDES` modules. Similarly to +LBSE, *Biomass_core* simulates changes in tree cohort aboveground biomass +($g/m^2$) by calculating growth, mortality and recruitment as functions of pixel +and species characteristics, competition and disturbances (Fig. +\@ref(fig:fig-Biomass-core)). Note that, by default, cohorts are unique +combinations of species and age, but this can be changed via the +`cohortDefinitionCols` parameter (see [List of parameters](#params-list)). + +Specifically, cohort growth is driven by both invariant (growth shape parameter, +`growthcurve`) and spatio-temporally varying species traits (maximum biomass, +`maxB`, and maximum annual net primary productivity, `maxANPP`), while +background mortality (i.e., not caused by disturbances) depends only on +invariant species traits (`longevity` and mortality shape parameter, +`mortalityshape`). All these five traits directly influence the realised shape +of species growth curves, by determining how fast they grow (`growthcurve` and +`maxANPP`), how soon age mortality starts with respect to longevity +(`mortalityshape`) and the biomass a cohort can potentially achieve (`maxB`). + +Cohort recruitment is determined by available "space" (i.e., pixel shade), +invariant species traits (regeneration mode, `postfireregen`, age at maturity, +`sexualmature`, shade tolerance, `shadetolerance`) and a third spatio-temporally +varying trait (species establishment probability, `establishprob`, called SEP +hereafter). The available "growing space" is calculated as the species' `maxB` +minus the occupied biomass (summed across other cohorts in the pixel). If there +is "space", a cohort can establish from one of three recruitment modes: +serotiny, resprouting and germination. + +Disturbances (e.g., fire) can cause cohort mortality and trigger +post-disturbance regeneration. Two post-disturbance regeneration mechanisms have +been implemented, following LBSE: serotiny and resprouting +[@SchellerMiranda2015]. Post-disturbance mortality and regeneration only occur +in response to fire and are simulated in two separate, but interchangeable +modules, *Biomass_regeneration* and *Biomass_regenerationPM* that differ with +respect to the level of post-fire mortality they simulate (complete or partial +mortality, respectively). + +Cohort germination (also called cohort establishment) occurs if seeds are +available from local sources (the pixel), or via seed dispersal. Seed dispersal +can be of three modes: 'no dispersal', 'universal dispersal' (arguably, only +interesting for dummy case studies) or 'ward dispersal' [@SchellerMiranda2015]. +Briefly, the 'ward dispersal' algorithm describes a flexible kernel that +calculates the probability of a species colonising a neighbour pixel as a +function of distance from the source and dispersal-related (and invariant) +species traits, and is used by default. + +Finally, both germination and regeneration success depend on the species' +probability of germination in a given pixel ([probabilities of +germination](#prob-germ)). + +We refer the reader to @SchellerMiranda2015, @SchellerDomingo2011 and +@SchellerDomingo2012 for further details with respect to the above mentioned +mechanisms implemented in *Biomass_core*. In a later section of this manual, we +highlight existing [differences between *Biomass_core* and +LBSE](#biomass-core-vs-lbse), together with [comparisons between the two +modules](#biomass-core-vs-lbse-comparisons). + +### Initialisation, inputs and parameters {#init-inputs-params} + +To initialise and simulate forest dynamics in any given landscape, +*Biomass_core* requires a number of inputs and parameters namely: - [initial cohort biomass and age](#initial-objs) values across the landscape; - [invariant species traits](#invariant-traits) values; -- [spatio-temporally varying species traits](#varying-traits) values (or just spatially-varying); +- [spatio-temporally varying species traits](#varying-traits) values (or just +spatially-varying); - [location- (ecolocation-) specific parameters](#ecolocation-traits); -- [probabilities of germination](#prob-germ) given a species' shade tolerance and site shade. - -These are detailed below and in the full [list of input objects](#inputs-list). The *Biomass_borealDataPrep* module manual also provides information about how many of these inputs are derived from available data, or adjusted using published values or our best knowledge of boreal forest dynamics in Western Canada. - -Unlike the initialisation in LBSE[^1], *Biomass_core* initialises the simulation using data-derived initial cohort biomass and age. This information is ideally supplied by data and calibration modules like *Biomass_borealDataPrep* ([Links to other modules](#links-modules)), but *Biomass_core* can also initialise itself using theoretical data. - -[^1]: In LBSE the initialisation consists in "iterat[ing] the number of time steps equal to the maximum cohort age for each site", beginning at 0 minus *t* (*t =* oldest cohort age) and adding cohorts at the appropriate time until the initial simulation time is reached (0) [@SchellerMiranda2015]. - -Similarly, although *Biomass_core* can create all necessary traits and parameters using theoretical values, for realistic simulations these should be provided by data and calibration modules, like *Biomass_borealDataPrep* and *Biomass_speciesParameters*. We advise future users and developers to become familiar with these data modules and then try to create their own modules (or modify existing ones) for their purpose. +- and the [probabilities of germination](#prob-germ) given a species' shade +tolerance and site shade. + +These are detailed below and in the [full list of input objects](#inputs-list). +The *Biomass_borealDataPrep* module manual also provides information about the +estimation of many of these traits/inputs from available data, or their +adjustment using published values or our best knowledge of boreal forest +dynamics in Western Canada. + +Unlike the initialisation in LBSE[^biomass_core-1], *Biomass_core* initialises +the simulation using data-derived initial cohort biomass and age. This +information is ideally supplied by data and calibration modules like +*Biomass_borealDataPrep* ([Links to other modules](#links-modules)), but +*Biomass_core* can also initialise itself using theoretical data. + +Similarly, although *Biomass_core* can create all necessary traits and +parameters using theoretical values, for realistic simulations these should be +provided by data and calibration modules, like *Biomass_borealDataPrep* and +*Biomass_speciesParameters*. We advise future users and developers to become +familiar with these data modules and then try to create their own modules (or +modify existing ones) for their purpose. + +[^biomass_core-1]: in LBSE the initialisation consists in "iterat[ing] the +number of time steps equal to the maximum cohort age for each site", +beginning at 0 minus *t* (*t =* oldest cohort age) and adding cohorts at the +appropriate time until the initial simulation time is reached (0) +[@SchellerMiranda2015]. #### Initial cohort biomass and age {#initial-objs} -Initial cohort biomass and age are derived from stand biomass (`biomassMap` raster layer), stand age (`standAgeMap` raster layer) and species (ref:percent) cover (`speciesLayers` raster layers) data (see Table \@ref(tab:moduleInputs2-Biomass-core)) and formatted into the `cohortData` object, a table that reflects the current year's cohort biomass, age, mortality (lost biomass) and aboveground net primary productivity (ANPP) per species and pixel group (`pixelGroup`). At the start of the simulation, `cohortData` will not have any values of cohort mortality or ANPP. - -Each `pixelGroup` is a collection of pixels that share the same ecolocation (by default, a combination of land-cover and ecological zonation, coded in the `ecoregionMap` raster layer) and the same cohort composition (i.e., species, age and biomass composition). The `cohortData` table is therefore always associated with the current year's `pixelGroupMap` raster layer, which provides the spatial location of all `pixelGroups` and allows "spatialising" cohort information and dynamics (e.g., dispersal) on a pixel by pixel basis (see also [Hashing](#biomass-core-vs-lbse-enhan2)). - -The user, or another module, may provide initial `cohortData` and `pixelGroupMap` objects to start the simulation, or the input objects necessary to produce them: a study area polygon (`studyArea`), the `biomassMap`, `standAgeMap`, `speciesLayers` and `ecoregionMap` raster layers (see the [list of input objects](#inputs-list) for more detail). +Initial cohort biomass and age are derived from stand biomass (`biomassMap` +raster layer), stand age (`standAgeMap` raster layer) and species (ref:percent) +cover (`speciesLayers` raster layers) data (see Table +\@ref(tab:moduleInputs2-Biomass-core)) and formatted into the `cohortData` +object. The `cohortData` table is a central simulation object that tracks the +current year's cohort biomass, age, mortality (lost biomass) and aboveground net +primary productivity (ANPP) per species and pixel group (`pixelGroup`). At the +start of the simulation, `cohortData` will not have any values of cohort +mortality or ANPP. + +Each `pixelGroup` is a collection of pixels that share the same ecolocation +(coded in the `ecoregionMap` raster layer) and the same cohort composition. By +default, an ecolocation is a combination of land-cover and ecological zonation +(see `ecoregionMap` in the [full list of inputs](#inputs-list)) and unique +cohort compositions are defined as unique combinations of species, age and +biomass. The `cohortData` table is therefore always associated with the current +year's `pixelGroupMap` raster layer, which provides the spatial location of all +`pixelGroups`, allowing to "spatialise" cohort information and dynamics (e.g., +dispersal) on a pixel by pixel basis (see also +[Hashing](#biomass-core-vs-lbse-enhan2)). + +The user, or another module, may provide initial `cohortData` and +`pixelGroupMap` objects to start the simulation, or the input objects necessary +to produce them: a study area polygon (`studyArea`), the `biomassMap`, +`standAgeMap`, `speciesLayers` and `ecoregionMap` raster layers (see the [list +of input objects](#inputs-list) for more detail). #### Invariant species traits {#invariant-traits} -These are spatio-temporally constant traits that mostly influence population dynamics (e.g., growth, mortality, dispersal) and responses to fire (fire tolerance and regeneration). - -By default, *Biomass_core* obtains trait values from available LANDIS-II tables (see Table \@ref(tab:moduleInputs2-Biomass-core)), but traits can be adjusted/supplied by the user or by other modules. For instance, using *Biomass_borealDataPrep* will adjust some trait values for Western Canadian boreal forests [e.g., longevity values are adjusted following @BurtonCumming1995], while using *Biomass_speciesParameters* calibrates the `growthcurve` and `mortalityshape` parameters and estimates two additional species traits (`inflactionFactor` and `mANPPproportion`) to calibrate `maxB` and `maxANPP` (respectively). - -Table \@ref(tab:invariantSpptraits) shows an example of a table of invariant species traits. Note that *Biomass_core* (alone) requires all the columns Table \@ref(tab:invariantSpptraits) in to be present, with the exception of `firetolerance`, `postfireregen`, `resproutprob`, `resproutage_min` and `resproutage_max`, which are used by the post-fire regeneration modules (*Biomass_regeneration* and *Biomass_regenerationPM*). +These are spatio-temporally constant traits that mostly influence population +dynamics (e.g., growth, mortality, dispersal) and responses to fire (fire +tolerance and regeneration). + +By default, *Biomass_core* obtains trait values from available LANDIS-II tables +(see Table \@ref(tab:moduleInputs2-Biomass-core)), but traits can be +adjusted/supplied by the user or by other modules. For instance, using +*Biomass_borealDataPrep* will adjust some trait values for Western Canadian +boreal forests [e.g., longevity values are adjusted following +@BurtonCumming1995], while using *Biomass_speciesParameters* calibrates the +`growthcurve` and `mortalityshape` parameters and estimates two additional +species traits (`inflationFactor` and `mANPPproportion`) to calibrate `maxB` and +`maxANPP` (respectively). + +Table \@ref(tab:invariantSpptraits) shows an example of a table of invariant +species traits. Note that *Biomass_core* (alone) requires all the columns Table +\@ref(tab:invariantSpptraits) in to be present, with the exception of +`firetolerance`, `postfireregen`, `resproutprob`, `resproutage_min` and +`resproutage_max`, which are used by the post-fire regeneration modules +(*Biomass_regeneration* and *Biomass_regenerationPM*). + +Please see @SchellerDomingo2011 [p.18] and @SchellerMiranda2015 [p.16] for +further detail. -Please see @SchellerDomingo2011 [p.18] and @SchellerMiranda2015 [p.16] for further detail. - -::: fullwidth -| speciesCode | longevity | sexualmature | shadetolerance | firetolerance | postfireregen | resproutprob | resproutage_min | resproutage_max | seeddistance_eff | seeddistance_max | mortalityshape | growthcurve | -|------|------|------|------|------|------|------|------|------|------|------|------|------| -| Abie_sp | 200 | 20 | 2.3 | 1 | none | 0 | 0 | 0 | 25 | 100 | 15 | 0 | -| Pice_eng | 460 | 30 | 2.1 | 2 | none | 0 | 0 | 0 | 30 | 250 | 15 | 1.0 | -| Pice_gla | 400 | 30 | 1.6 | 2 | none | 0 | 0 | 0 | 100 | 303 | 15 | 1.0 | -| Pinu_sp | 150 | 15 | 1 | 2 | serotiny | 0 | 0 | 0 | 30 | 100 | 15 | 0 | -| Popu_sp | 140 | 20 | 1 | 1 | resprout | 0.5 | 10 | 70 | 200 | 5000 | 25 | 0 | -| Pseu_men | 525 | 25 | 2 | 3 | none | 0 | 0 | 0 | 100 | 500 | 15 | 1.0 | -::: - -: (#tab:invariantSpptraits) Example of an invariant species traits table (the `species` table object in the module), with species *Abies sp.* (Abie_sp), *Picea engelmannii* (Pice_eng), *Picea glauca* (Pice_gla), *Pinus sp.* (Pinu_sp), *Populus sp.* (Popu_sp) and *Pseudotsuga menziesii* (Pseu_men). Note that these are theoretical values. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    (\#tab:invariantSpptraits)Example of an invariant species traits table (the `species` table object in the module), with species (ref:Abie-sp), (ref:Pice-eng), (ref:Pice-gla), (ref:Pinu-sp), (ref:Popu-sp) and (ref:Pseud-men). Note that these are theoretical values.
    speciesCode longevity sexualmature shadetolerance firetolerance postfireregen resproutprob resproutage_min resproutage_max seeddistance_eff seeddistance_max mortalityshape growthcurve
    Abie_sp 200 20 2.3 1 none 0.0 0 0 25 100 15 0
    Pice_eng 460 30 2.1 2 none 0.0 0 0 30 250 15 1
    Pice_gla 400 30 1.6 2 none 0.0 0 0 100 303 15 1
    Pinu_sp 150 15 1.0 2 serotiny 0.0 0 0 30 100 15 0
    Popu_sp 140 20 1.0 1 resprout 0.5 10 70 200 5000 25 0
    Pseu_men 525 25 2.0 3 none 0.0 0 0 100 500 15 1
    #### Spatio-temporally varying species traits {#varying-traits} -These traits vary between species, by ecolocation and, potentially, by year if the `year` column is not omitted and several years exist (in which case last year's values up to the current simulation year are always used). They are maximum biomass, `maxB`, maximum above-ground net primary productivity, `maxANPP`, and species establishment probability, SEP (called `establishprob` in the module). By default, *Biomass_core* assigns theoretical values to these traits, and thus we recommend using *Biomass_borealDataPrep* to obtain realistic trait values derived from data (by default, pertinent for Canadian boreal forest applications) or passing a custom table directly. *Biomass_speciesParameters* further calibrates `maxB` and `maxANPP` by estimating two additional invariant species traits (`inflactionFactor` and `mANPPproportion`; also for Western Canadian forests). See Table \@ref(tab:varyingSpptraits) for an example. - -| ecoregionGroup | speciesCode | establishprob | maxB | maxANPP | year | -|----------------|-------------|---------------|-------|---------|------| -| 1_03 | Abie_sp | 1.000 | 8567 | 285 | 1 | -| 1_03 | Pice_eng | 0.983 | 10156 | 305 | 1 | -| 1_03 | Popu_sp | 0.737 | 8794 | 293 | 1 | -| 1_03 | Pseu_men | 1.000 | 17534 | 132 | 1 | -| 1_09 | Abie_sp | 0.112 | 1499 | 50 | 1 | -| 1_09 | Pice_gla | 0.302 | 3143 | 102 | 1 | -| 1_09 | Pinu_sp | 0.714 | 2569 | 86 | 1 | -| 1_09 | Popu_sp | 0.607 | 3292 | 110 | 1 | -| 1_09 | Pseu_men | 0.997 | 6020 | 45 | 1 | -| 1_03 | Abie_sp | 0.989 | 8943 | 225 | 2 | -| 1_03 | Pice_eng | 0.985 | 9000 | 315 | 2 | -| 1_03 | Popu_sp | 0.600 | 8600 | 273 | 2 | -| 1_03 | Pseu_men | 1.000 | 13534 | 142 | 2 | -| 1_09 | Abie_sp | 0.293 | 2099 | 45 | 2 | -| 1_09 | Pice_gla | 0.745 | 3643 | 90 | 2 | -| 1_09 | Pinu_sp | 0.500 | 2569 | 80 | 2 | -| 1_09 | Popu_sp | 0.670 | 3262 | 111 | 2 | -| 1_09 | Pseu_men | 1.000 | 6300 | 43 | 2 | - -: (#tab:varyingSpptraits) Example of a spatio-temporally varying species traits table (the `speciesEcoregion` table object in the module), with two ecolocations (called `ecoregionGroups`) and species *Abies sp.* (Abie_sp), *Picea engelmannii* (Pice_eng), *Picea glauca* (Pice_gla), *Pinus sp.* (Pinu_sp), *Populus sp.* (Popu_sp) and *Pseudotsuga menziesii* (Pseu_men). If the simulation runs for 10 years, values from year 2 would be use for years 2-10. Note that these are theoretical values. - -#### Ecolocation-specific parameters -- minimum relative biomass {#ecolocation-traits} - -Minimum relative biomass (`minRelativeB`) is the only the only ecolocation-specific parameter used in *Biomass_core*. It is used to determine the shade level in each pixel (i.e., site shade) with respect to the total potential maximum biomass for that pixel (i.e., the sum of all `maxB` values in the pixel's ecolocation). If relative biomass in the stand (with regards to the total potential maximum biomass) is above one of the minimum relative biomass thresholds, the pixel is assigned that threshold's site shade value [@SchellerMiranda2015]. +These traits vary between species, by ecolocation and, potentially, by year if +the `year` column is not omitted and several years exist (in which case last +year's values up to the current simulation year are always used). They are +maximum biomass, `maxB`, maximum above-ground net primary productivity, +`maxANPP`, and species establishment probability, SEP (called `establishprob` in +the module). By default, *Biomass_core* assigns theoretical values to these +traits, and thus we recommend using *Biomass_borealDataPrep* to obtain realistic +trait values derived from data (by default, pertinent for Canadian boreal forest +applications), or passing a custom table directly. *Biomass_speciesParameters* +further calibrates `maxB` and `maxANPP` by estimating two additional invariant +species traits (`inflationFactor` and `mANPPproportion`; also for Western +Canadian forests). See Table \@ref(tab:varyingSpptraits) for an example. -The shade level then influences the germination and regeneration of new cohorts, depending on their shade tolerance (see [Probabilities of germination](#prob-germ)). + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    (\#tab:varyingSpptraits)Example of a spatio-temporally varying species traits table (the `speciesEcoregion` table object in the module), with two ecolocations (called `ecoregionGroups`) and species (ref:Abie-sp), (ref:Pice-eng), (ref:Pice-gla), (ref:Pinu-sp), (ref:Popu-sp) and (ref:Pseud-men). If a simulation runs for 10 year using this table, trait values from year 2 would be used during simulation years 2-10.
    ecoregionGroup speciesCode establishprob maxB maxANPP year
    1_03 Abie_sp 1.000 8567 285 1
    1_03 Pice_eng 0.983 10156 305 1
    1_03 Popu_sp 0.737 8794 293 1
    1_03 Pseu_men 1.000 17534 132 1
    1_09 Abie_sp 0.112 1499 50 1
    1_09 Pice_gla 0.302 3143 102 1
    1_09 Pinu_sp 0.714 2569 86 1
    1_09 Popu_sp 0.607 3292 110 1
    1_09 Pseu_men 0.997 6020 45 1
    1_03 Abie_sp 0.989 8943 225 2
    1_03 Pice_eng 0.985 9000 315 2
    1_03 Popu_sp 0.600 8600 273 2
    1_03 Pseu_men 1.000 13534 142 2
    1_09 Abie_sp 0.293 2099 45 2
    1_09 Pice_gla 0.745 3643 90 2
    1_09 Pinu_sp 0.500 2569 80 2
    1_09 Popu_sp 0.670 3262 111 2
    1_09 Pseu_men 1.000 6300 43 2
    -Site shade varies from 0 (no shade) to 5 (maximum shade). By default, *Biomass_core* uses relative biomass thresholds from available LANDIS-II tables, which are held constant across all ecolocations (see an example in Table \@ref(tab:minRelB)). Yet, these values can be adjusted by using other modules or passing user-defined tables (e.g., *Biomass_borealDataPrep* adjusts these values for applications in Western Canadian forests) +#### Ecolocation-specific parameters -- minimum relative biomass {#ecolocation-traits} -| ecoregionGroup | X1 | X2 | X3 | X4 | X5 | -|----------------|------|------|-----|------|------| -| 1_03 | 0.15 | 0.25 | 0.5 | 0.80 | 0.90 | -| 1_09 | 0.15 | 0.25 | 0.5 | 0.80 | 0.90 | +Minimum relative biomass (`minRelativeB`) is the only ecolocation-specific +parameter used in *Biomass_core*. It is used to determine the shade level in +each pixel (i.e., site shade) with respect to the total potential maximum +biomass for that pixel (i.e., the sum of all `maxB` values in the pixel's +ecolocation). If relative biomass in the stand (with regards to the total +potential maximum biomass) is above the minimum relative biomass thresholds, the +pixel is assigned that threshold's site shade value [@SchellerMiranda2015]. + +The shade level then influences the germination and regeneration of new cohorts, +depending on their shade tolerance (see [Probabilities of +germination](#prob-germ)). + +Site shade varies from X0 (no shade) to X5 (maximum shade). By default, +*Biomass_core* uses the same minimum realtive biomass threshold values across +all ecolocations, adjusted from a [publicly available LANDIS-II +table](https://github.com/dcyr/LANDIS-II_IA_generalUseFiles) to better reflect +Western Canada boreal forest dynamics (see Table \@ref(tab:minRelB)). +*Biomass_borealDataPrep* does the same adjustment by default. As with other +inputs, these values can be adjusted by using other modules or by passing +user-defined tables. -: (#tab:minRelB) Example of a minimum relative biomass table (the `minRelativeB` table object in the module), with two ecolocations (`ecoregionGroups`) sharing the same values. Note that the relative biomass values were taken from + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    (\#tab:minRelB)Example of a minimum relative biomass table (the `minRelativeB` table object in the module), with two ecolocations (`ecoregionGroups`) sharing the same values
    ecoregionGroup X1 X2 X3 X4 X5
    1_03 0.15 0.25 0.5 0.75 0.85
    1_09 0.15 0.25 0.5 0.75 0.85
    #### Probabilities of germination {#prob-germ} -A species' probability of germination results from the combination of its shade tolerance level (an invariant species trait in the `species` table) and the site shade [defined by the amount of biomass in the pixel -- see [minimum relative biomass parameter](#ecolocation-traits) and @SchellerMiranda2015,p.14]. By default, both *Biomass_core* and *Biomass_borealDataPrep* use a publicly available LANDIS-II table (called `sufficientLight` in the module; Table \@ref(tab:suffLight)). +A species' probability of germination results from the combination of its shade +tolerance level (an invariant species trait in the `species` table; Table +\ref@(tab:invariantSpptraits)) and the site shade [defined by the amount of +biomass in the pixel -- see [minimum relative biomass +parameter](#ecolocation-traits) and @SchellerMiranda2015,p.14]. By default, both +*Biomass_core* and *Biomass_borealDataPrep* use a publicly available LANDIS-II +table (called `sufficientLight` in the module; Table \@ref(tab:suffLight)). -| species shade tolerance | X0 | X1 | X2 | X3 | X4 | X5 | -|-------------------------|-----|-----|-----|-----|-----|-----| -| 1 | 1 | 0 | 0 | 0 | 0 | 0 | -| 2 | 1 | 1 | 0 | 0 | 0 | 0 | -| 3 | 1 | 1 | 1 | 0 | 0 | 0 | -| 4 | 1 | 1 | 1 | 1 | 0 | 0 | -| 5 | 0 | 0 | 1 | 1 | 1 | 1 | - -: (#tab:suffLight) Default species probability of germination values used by *Biomass_core* and *Biomass_borealDataPrep*. Columns X0-X5 are different site shade levels and each line has the probability of germination for each site shade and species shade tolerance combination + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    (\#tab:suffLight)Default species probability of germination values used by (ref:Biomass-core) and (ref:Biomass-borealdataPrep). Columns X0-X5 are different site shade levels and each line has the probability of germination for each site shade and species shade tolerance combination.
    species.shade.tolerance X0 X1 X2 X3 X4 X5
    1 1 0 0 0 0 0
    2 1 1 0 0 0 0
    3 1 1 1 0 0 0
    4 1 1 1 1 0 0
    5 0 0 1 1 1 1
    #### Other module inputs {#other-inputs} -The remaining module input objects either do not directly influence the basic mechanisms implemented in *Biomass_core* (e.g., `sppColorVect` and `studyAreaReporting` are only used for plotting purposes), are objects that keep track of a property/process in the module (e.g., `lastReg` is a counter of the last year when regeneration occurred), or define the study area for the simulation (e.g., `studyArea` and `rasterToMatch`). - -The next section provides a complete list of all input objects, including those already mentioned above. +The remaining module input objects either do not directly influence the basic +mechanisms implemented in *Biomass_core* (e.g., `sppColorVect` and +`studyAreaReporting` are only used for plotting purposes), are objects that keep +track of a property/process in the module (e.g., `lastReg` is a counter of the +last year when regeneration occurred), or define the study area for the +simulation (e.g., `studyArea` and `rasterToMatch`). -#### List of input objects {#inputs-list} +The next section provides a complete list of all input objects, including those +already mentioned above. -All of *Biomass_core*'s input objects have (theoretical) defaults that are produced automatically by the module[^2]. We suggest that new users run *Biomass_core* by itself supplying only a `studyArea` object, before attempting to supply their own, or combining *Biomass_core* with data modules. This will enable them to become familiar with all the input objects in a theoretical setting. +### List of input objects {#inputs-list} -[^2]: usually, default inputs are made when running the `.inputObjects` function (inside the module R script) during the `simInit` call and in the `init` event during the `spades` call -- see `?SpaDES.core::events` and `SpaDES.core::simInit` +All of *Biomass_core*'s input objects have (theoretical) defaults that are +produced automatically by the module[^biomass_core-2]. We suggest that new users +run *Biomass_core* by itself supplying only a `studyArea` polygon, before +attempting to supply their own or combining *Biomass_core* with other modules. +This will enable them to become familiar with all the input objects in a +theoretical setting. -Of the inputs in Table \@ref(tab:moduleInputs2-Biomass-core), the following are particularly important and deserve special attention: +Of the inputs listed in Table \@ref(tab:moduleInputs2-Biomass-core), the +following are particularly important and deserve special attention: **Spatial layers** -- `ecoregionMap` -- a raster layer with ecolocation IDs (note that the term "ecoregion" was inherited from LBSE and kept for consistency with original LBSE code). Ecolocations group pixels with similar biophysical conditions. By default, we use two levels of grouping in our applications: the first level being an ecological classification (in ) such as the the Natural Ecoregion classification of Canada, and the second level a land-cover classification. Hence, these ecolocations contain relatively fine scale land cover information plus coarse scale regional information. The `ecoregionMap` layer must be defined as a categorical raster, with an associated Raster Attribute Table (RAT; see, e.g., `raster::ratify`). The RAT must contain the columns: `ID` (the value in the raster layer), `ecoregion` (the first level of grouping) and `ecoregionGroup` (the full ecolocation "name" written as \). Note that if creating `ecoregionGroup`s from combining two raster layers whose values are numeric (as in *Biomass_borealDataPrep*, the group label should be a character combination of two grouping levels. For instance, if Natural Ecoregion `2` has land-cover types `1`, `2` and `3`, the RAT will contain `ID = {1,2,3}`, `ecoregion = {2}` and `ecoregionGroup = {2_1, 2_2, 2_3}`. However, the user is free to use any groupings they wish. Finally, note that all ecolocations are should be listed in the `ecoregion` table. - -- `rasterToMatch` -- a RasterLayer, with a given resolution and projection determining the pixels (i.e., non-NA values) where forest dynamics will be simulated. Needs to match `studyArea`. If not supplied, *Biomass_core* attempts to produce it from `studyArea`, using `biomassMap` as the template for spatial resolution and projection. - -- `studyArea` -- a shapefile. A `SpatialPolygonsDataFrame` with a single polygon determining the where the simulation will take place. This is the only input object that **must be supplied by the user**. +- `ecoregionMap` -- a raster layer with ecolocation IDs. Note that the term +"ecoregion" was inherited from LBSE and kept for consistency with original +LBSE code, but we prefer to call them ecolocations to avoid confusion with +the ecoregion-level classification of the [National Ecological +Classification of Canada +(NECC)](https://open.canada.ca/data/en/dataset/3ef8e8a9-8d05-4fea-a8bf-7f5023d2b6e1). +Ecolocations group pixels with similar biophysical conditions. By default, +we use two levels of grouping in our applications: the first level being an +ecological classification such as ecodistricts from the NECC, and the second +level is a land-cover classification. Hence, these ecolocations contain +relatively coarse scale regional information plus finer scale land cover +information. The `ecoregionMap` layer must be defined as a categorical +raster, with an associated Raster Attribute Table (RAT; see, e.g., +`raster::ratify`). The RAT must contain the columns: `ID` (the value in the +raster layer), `ecoregion` (the first level of grouping) and +`ecoregionGroup` (the full ecolocation "name" written as +\). Note that if creating `ecoregionGroup`'s by +combining two raster layers whose values are numeric (as in +*Biomass_borealDataPrep*), the group label is a character combination of two +numeric grouping levels. For instance, if Natural Ecoregion `2` has +land-cover types `1`, `2` and `3`, the RAT will contain `ID = {1,2,3}`, +`ecoregion = {2}` and `ecoregionGroup = {2_1, 2_2, 2_3}`. However, the user +is free to use any groupings they wish. Finally, note that all ecolocations +(`ecoregionGroup`'s) are should be listed in the `ecoregion` table. + +- `rasterToMatch` -- a RasterLayer, with a given resolution and projection +determining the pixels (i.e., non-NA values) where forest dynamics will be +simulated. Needs to match `studyArea`. If not supplied, *Biomass_core* +attempts to produce it from `studyArea`, using `biomassMap` as the template +for spatial resolution and projection. + +- `studyArea` -- a `SpatialPolygonsDataFrame` with a single polygon +determining the where the simulation will take place. This is the only input +object that **must be supplied by the user or another module**. **Species traits and other parameter tables** -- `ecoregion` -- `data.table` listing all ecolocation "names" (*ecoregionGroup* column; see `ecoregionMap` above for details) and their state (active -- `yes` -- or inactive -- `no`) +- `ecoregion` -- a `data.table` listing all ecolocation "names" +(*ecoregionGroup* column; see `ecoregionMap` above for details) and their +state (active -- `yes` -- or inactive -- `no`) -- `minRelativeB` -- `data.table` of minimum relative biomass values. See [Ecolocation-specific parameters -- minimum relative biomass](#ecolocation-traits). +- `minRelativeB` -- a `data.table` of minimum relative biomass values. See +[Ecolocation-specific parameters -- minimum relative +biomass](#ecolocation-traits). -- `species` -- a `data.table` of invariant species traits. See [Invariant species traits](#invariant-traits). +- `species` -- a `data.table` of [invariant species +traits](#invariant-traits). -- `speciesEcoregion` -- a `data.table` of spatio-temporally varying species traits. See [Spatio-temporally varying species traits](#varying-traits). +- `speciesEcoregion` -- a `data.table` of [spatio-temporally varying species +traits](#varying-traits). -- `sufficientLight` -- a `data.table` defining the probability of germination for a species, given its `shadetolerance` level (see `species` above) and the shade level in the pixel (see `minRelativeB` above). See [Probabilities of germination](#prob-germ). +- `sufficientLight` -- a `data.table` defining the probability of germination +for a species, given its `shadetolerance` level (see `species` above) and +the shade level in the pixel (see `minRelativeB` above). See [Probabilities +of germination](#prob-germ). -- `sppEquiv` -- a `data.table` of species name equivalences between various conventions. It must contain the columns *LandR* (species IDs in the LandR format), *EN_generic_short* (short generic species names in English -- or any other language -- used for plotting), *Type* (type of species, *Conifer* or *Deciduous*, as in "broadleaf") and *Leading* (same as *EN_generic_short* but with "leading" appended -- e.g., "Poplar leading") . See `?LandR::sppEquivalencies_CA` for more information. +- `sppEquiv` -- a `data.table` of species name equivalences between various +conventions. It must contain the columns *LandR* (species IDs in the LandR +format), *EN_generic_short* (short generic species names in English -- or +any other language -- used for plotting), *Type* (type of species, *Conifer* +or *Deciduous*, as in "broadleaf") and *Leading* (same as *EN_generic_short* +but with "leading" appended -- e.g., "Poplar +leading"). +See `?LandR::sppEquivalencies_CA` for more information. -- `sppColorVect` -- character. A named vector of colours used to plot species dynamics. Should contain one colour per species in the `species` table and, potentially a colour for species mixtures (named "Mixed"). Vector names must follow `species$speciesCode`. +- `sppColorVect` -- character. A named vector of colours used to plot species +dynamics. Should contain one colour per species in the `species` table and, +potentially a colour for species mixtures (named "Mixed"). Vector names must +follow `species$speciesCode`. **Cohort-simulation-related objects** -- `cohortData` -- a `data.table` containing initial cohort information per `pixelGroup` (see `pixelGroupMap` below). This table is updated during the simulation as cohort dynamics are simulated. Must contain the following columns: - - - *pixelGroup* -- integer. *pixelGroup* ID. See [Hashing](#biomass-core-vs-lbse-enhan2). - - - *ecoregionGroup* -- character. Ecolocation names. See `ecoregionMap` and `ecoregion` objects above. - +- `cohortData` -- a `data.table` containing initial cohort information per +`pixelGroup` (see `pixelGroupMap` below). This table is updated during the +simulation as cohort dynamics are simulated. It must contain the following +columns: + + - *pixelGroup* -- integer. *pixelGroup* ID. See + [Hashing](#biomass-core-vs-lbse-enhan2). + + - *ecoregionGroup* -- character. Ecolocation names. See `ecoregionMap` and + `ecoregion` objects above. + - *speciesCode* -- character. Species ID. - + - *age* -- integer. Cohort age. - - - *B* -- integer. Cohort biomass in $g/m^2$. - - - *mortality* -- integer. Cohort dead biomass in the current year in $g/m^2$. Usually filled with 0s in initial conditions. - - - *aNPPAct* -- integer. Actual aboveground net primary productivity of the current year in $g/m^2$. Hence `B` is the result of the previous year's `B` minus `mortality` plus `aNPPAct`. Usually filled with 0s in initial conditions. See "1.1.3 Cohort growth and ageing" section of @SchellerMiranda2015. - -- `pixelGroupMap` -- a raster layer with `pixelGroup` IDs per pixel. Pixels are always grouped based on identical `ecoregionGroup`, `speciesCode`, `age` and `B` composition, even if the user supplies other initial groupings (e.g., this is possible in the *Biomass_borealDataPrep* data module). + + - *B* -- integer. Cohort biomass of the current year in $g/m^2$. + + - *mortality* -- integer. Cohort dead biomass of the current year in + $g/m^2$. Usually filled with 0s in initial conditions. + + - *aNPPAct* -- integer. Actual aboveground net primary productivity of the + current year in $g/m^2$. `B` is the result of the previous year's `B` + minus the current year's `mortality` plus `aNPPAct`. Usually filled with + 0s in initial conditions. See "*1.1.3 Cohort growth and ageing*" section + of @SchellerMiranda2015. + +- `pixelGroupMap` -- a raster layer with `pixelGroup` IDs per pixel. Pixels +are always grouped based on identical `ecoregionGroup`, `speciesCode`, `age` +and `B` composition, even if the user supplies other initial groupings +(e.g., this is possible in the *Biomass_borealDataPrep* data module). + + +- `sppNameVector` -- (OPTIONAL) a character vector of species to be simulated. +If provided, *Biomass_core* uses this vector to (attempt to) obtain `speciesLayers` +for the listed species. If not provided, the user (or another module) can pass a filtered `sppEquiv` table +(i.e., containing only the species that are to be simulated). If neither is provided, +then *Biomass_core* attempts to use any species for which if finds available species +(ref:percent) cover data in the study area. @@ -323,7 +915,7 @@ Of the inputs in Table \@ref(tab:moduleInputs2-Biomass-core), the following are - + @@ -368,6 +960,12 @@ Of the inputs in Table \@ref(tab:moduleInputs2-Biomass-core), the following are + + + + + + @@ -395,33 +993,57 @@ Of the inputs in Table \@ref(tab:moduleInputs2-Biomass-core), the following are
    (\#tab:moduleInputs2-Biomass-core)List of (ref:Biomass-core) input objects and their description.
    minRelativeB data.frame table defining the relative biomass cut points to classify stand shadeness table defining the relative biomass cut points to classify stand shadeness. NA
    table of species equivalencies. See `LandR::sppEquivalencies_CA`. NA
    sppNameVector character an optional vector of species names to be pulled from `sppEquiv`. Species names must match `P(sim)$sppEquivCol` column in `sppEquiv`. If not provided, then species will be taken from the entire `P(sim)$sppEquivCol` column in `sppEquiv`. See `LandR::sppEquivalencies_CA`. NA
    studyArea SpatialPolygonsDataFrame
    -#### List of parameters {#params-list} +[^biomass_core-2]: usually, default inputs are made when running the +`.inputObjects` function (inside the module R script) during the `simInit` +call and in the `init` event during the `spades` call -- see +`?SpaDES.core::events` and `SpaDES.core::simInit` + +### List of parameters {#params-list} + +In addition to the above inputs objects, *Biomass_core* uses several +parameters[^biomass_core-3] that control aspects like the simulation length, the +"succession" time step, plotting and saving intervals, amongst others. Note that +a few of these parameters are only relevant when simulating climate effects of +cohort growth and mortality, which require also loading the `LandR.CS` R +package[^biomass_core-4] (or another similar package). These are not discussed +in detail here, since climate effects are calculated externally to +*Biomass_core* in `LandR.CS` functions and thus documented there. + +A list of useful parameters and their description is listed below, while the +full set of parameters is in Table \@ref(tab:moduleParams2-Biomass-core). Like +with input objects, default values are supplied for all parameters and we +suggest the user becomes familiarized with them before attempting any changes. +We also note that the `"spin-up"` and `"biomassMap"` options for the +`initialBiomassSource` parameter are currently deactivated, since *Biomass_core* +no longer generates initial cohort biomass conditions using a spin-up based on +initial stand age like LANDIS-II (`"spin-up"`), nor does it attempt to fill +initial cohort biomasses using `biomassMap`. + +**Plotting and saving** - `.plots` -- activates/deactivates plotting and defines +type of plotting (see `?Plots`); + +- `.plotInitialTime` -- defines when plotting starts; + +- `.plotInterval` -- defines plotting frequency; + +- `.plotMaps` -- activates/deactivates map plotting; + +- `.saveInitialTime` -- defines when saving starts; + +- `.saveInterval` -- defines saving frequency; -In addition to the above inputs objects, *Biomass_core* uses several parameters[^3] that control aspects like the simulation length, the "succession" time step, plotting and saving intervals, amongst others. Note that a few of these parameters are only relevant when simulating climate effects of cohort growth and mortality, which require also loading the `LandR.CS` R package. These are not discussed in detail here, since climate effects are calculated externally to *Biomass_core* by the `LandR.CS` package and thus documented there. +**Simulation** -[^3]: in `SpaDES` lingo parameters are "small" objects, such as an integer or boolean, that can be controlled via the `parameters` argument in `simInit` +- `seedingAlgorithm` -- dispersal type (see above); -A list of useful parameters and their description is shown in Table \@ref(tab:tableUsefulParams), while the full set of parameters is in Table \@ref(tab:moduleParams2-Biomass-core). Like with input objects, default values are supplied for all parameters and we suggest the user becomes familiarized with them before attempting any changes. We also note that the `"spin-up"` and `"biomassMap"` options for the `initialBiomassSource` are currently deactivated, since *Biomass_core* no longer generates initial cohort biomass conditions using a spin-up based on initial stand age like LANDIS-II (`"spin-up"`), nor does it attempt to fill initial cohort biomasses using `biomassMap` (`"biomassMap"`). +- `successionTimestep` -- defines frequency of dispersal/local recruitment +event (growth and mortality are always yearly); -::: fullwidth -| Required inputs | Description | -|:------------------------|:----------------------------------------------| -| Plotting & saving | | -| `.plots` | activates/deactivates plotting and defines type fo plotting (see `?Plots`) | -| `.plotInitialTime` | defines when plotting starts | -| `.plotInterval` | defines plotting frequency | -| `.plotMaps` | activates/deactivates map plotting | -| `.saveInitialTime` | defines when saving starts | -| `.saveInterval` | defines saving frequency | -| Simulation | | -| `seedingAlgorithm` | dispersal type (see above) | -| `successionTimestep` | defines frequency of dispersal/local recruitment event (growth and mortality are always yearly) | -| Other | | -| `mixedType` | how mixed forest stands are defined | -| `vegLeadingProportion` | relative biomass threshold to consider a species "leading" (i.e., dominant) | -::: +**Other**\ +- `mixedType` -- how mixed forest stands are defined; -: (#tab:tableUsefulParams) Useful *Biomass_core* parameters. +- `vegLeadingProportion` -- relative biomass threshold to consider a species +"leading" (i.e., dominant); @@ -679,238 +1301,457 @@ A list of useful parameters and their description is shown in Table \@ref(tab:ta
    (\#tab:moduleParams2-Biomass-core)List of (ref:Biomass-core) parameters and their description.
    -#### List of outputs {#outputs-list} +[^biomass_core-3]: in `SpaDES` lingo parameters are "small" objects, such as an +integer or boolean, that can be controlled via the `parameters` argument in +`simInit`. -The main outputs of *Biomass_core* are the `cohortData` and `pixelGroupMap` containing cohort information per year (note that they are not saved by default), visual outputs of species level biomass, age and dominance across the landscape and the simulation length, and several maps of stand biomass, mortality and reproductive success (new biomass) or a yearly basis. +[^biomass_core-4]: -However, any of the objects changed/output by *Biomass_core* listed below (Table \@ref(tab:moduleOutputs-Biomass-core).) can be saved via the `outputs` argument in `simInit`[^4]. +### List of outputs {#outputs-list} -[^4]: see `?SpaDES.core::outputs` +The main outputs of *Biomass_core* are the `cohortData` and `pixelGroupMap` +containing cohort information per year (note that they are not saved by +default), visual outputs of species level biomass, age and dominance across the +landscape and the simulation length, and several maps of stand biomass, +mortality and reproductive success (i.e, new biomass) on a yearly basis. + +However, any of the objects changed/output by *Biomass_core* (listed in Table +\@ref(tab:moduleOutputs-Biomass-core)) can be saved via the `outputs` argument +in `simInit`[^biomass_core-5]. + + + + + + + + + + + + + + + + + + + + + + + + + + - + +
    (\#tab:moduleOutputs-Biomass-core)List of (ref:Biomass-core) output objects and their description.
    objectName objectClass desc
    activePixelIndex integer internal use. Keeps track of which pixels are active
    activePixelIndexReporting integer internal use. Keeps track of which pixels are active in the reporting study area
    ANPPMap RasterLayer ANPP map at each succession time step (in g /m^2)
    cohortData data.table `data.table` with cohort-level information on age, biomass, aboveground primary productivity (year's biomass gain) and mortality (year's biomass loss), by `pixelGroup` and ecolocation (i.e., `ecoregionGroup`). Contains at least the following columns: `pixelGroup` (integer), `ecoregionGroup` (factor), `speciesCode` (factor), `B` (integer in g/m^2), `age` (integer in years), `mortality` (integer in g/m^2), `aNPPAct` (integer in g/m^2). May have other columns depending on additional simulated processes (i.e., cliamte sensitivity; see, e.g., `P(sim)$keepClimateCols`).
    ecoregionMap RasterLayer map with mapcodes match `ecoregion` table and `speciesEcoregion` table. Defaults to a dummy map matching rasterToMatch with two regions
    inactivePixelIndex logical internal use. Keeps track of which pixels are inactive
    inactivePixelIndexReporting integer internal use. Keeps track of which pixels are inactive in the reporting study area
    lastFireYear numeric Year of the most recent fire year
    lastReg numeric an internal counter keeping track of when the last regeneration event occurred
    minRelativeB data.frame define the relative biomass cut points to classify stand shade
    mortalityMap RasterLayer map of biomass lost (in g/m^2) at each succession time step
    pixelGroupMap RasterLayer updated community map at each succession time step
    regenerationOutput data.table If `P(sim)$calibrate == TRUE`, an summary of seed dispersal and germination success (i.e., number of pixels where seeds successfully germinated) per species and year.
    reproductionMap RasterLayer Regeneration map (biomass gains in g/m^2) at each succession time step
    simulatedBiomassMap RasterLayer Biomass map at each succession time step (in g/m^2)
    simulationOutput data.table contains simulation results by `ecoregionGroup` (main output)
    simulationTreeOutput data.table Summary of several characteristics about the stands, derived from `cohortData`
    species data.table a table that has species traits such as longevity, shade tolerance, etc. Currently obtained from LANDIS-II Biomass Succession v.6.0-2.0 inputs
    speciesEcoregion data.table define the maxANPP, maxB and SEP change with both ecoregion and simulation time
    speciesLayers RasterStack species percent cover raster layers, based on input `speciesLayers` object. Not changed by this module.
    spinupOutput data.table Spin-up output. Currently deactivated.
    summaryBySpecies data.table The total species biomass (in g/m^2 as in `cohortData`), average age and aNPP (in g/m^2 as in `cohortData`), across the landscape (used for plotting and reporting).
    summaryBySpecies1 data.table No. pixels of each leading vegetation type (used for plotting and reporting).
    summaryLandscape data.table The averages of total biomass (in tonnes/ha , not g/m^2 like in `cohortData`), age and aNPP (also in tonnes/ha) across the landscape (used for plotting and reporting).
    treedFirePixelTableSinceLastDisp data.table 3 columns: `pixelIndex`, `pixelGroup`, and `burnTime`. Each row represents a forested pixel that was burned up to and including this year, since last dispersal event, with its corresponding `pixelGroup` and time it occurred
    vegTypeMap Map of leading species in each pixel, colored according to `sim$sppColorVect`. Species mixtures calculated according to `P(sim)$vegLeadingProportion` and `P(sim)`$mixedType. RasterLayer Map of leading species in each pixel, colored according to `sim$sppColorVect`. Species mixtures calculated according to `P(sim)$vegLeadingProportion` and `P(sim)$mixedType`.
    +[^biomass_core-5]: see `?SpaDES.core::outputs` + ### Simulation flow and module events {#sim-flow} -*Biomass_core* itself does not simulate disturbances, or their effect on vegetation (i.e., post-disturbance mortality and regeneration). Should disturbance module and post-disturbance mortality/regeneration modules be used (e.g., *LandMine* and *Biomass_regeneration*), regeneration should occur after the disturbance, but **before** dispersal and background vegetation growth and mortality. Hence, the disturbance itself should take place either at the very beginning or at the very end of each simulation time step. +*Biomass_core* itself does not simulate disturbances or their effect on +vegetation (i.e., post-disturbance mortality and regeneration). Should +disturbance and post-disturbance mortality/regeneration modules be used (e.g., +*LandMine* and *Biomass_regeneration*), the user should make sure that +post-disturbance effects occur *after* the disturbance, but *before* dispersal +and background vegetation growth and mortality (simulated in *Biomass_core*). +Hence, the disturbance itself should take place either at the very beginning or +at the very end of each simulation time step to guarantee that it happens +immediately before post-disturbance effects are calculated. The general flow of *Biomass_core* processes with and without disturbances is: -1. Preparation of necessary objects for the simulation -- either by data and calibration modules or by *Biomass_core* itself (`init` event); +1. Preparation of necessary objects for the simulation -- either by data and +calibration modules or by *Biomass_core* itself (during `simInit` and the +`init` event[^biomass_core-6]); -2. Disturbances (OPTIONAL) -- simulated by a disturbance module (e.g., *LandMine*); +2. Disturbances (OPTIONAL) -- simulated by a disturbance module (e.g., +*LandMine*); -3. Post-disturbance mortality/regeneration (OPTIONAL) -- simulated by a regeneration module (e.g., *Biomass_regeneration*); +3. Post-disturbance mortality/regeneration (OPTIONAL) -- simulated by a +regeneration module (e.g., *Biomass_regeneration*); -4. Seed dispersal (every `successionTimestep`; `Dispersal` event) -- see @SchellerDomingo2012 for details +4. Seed dispersal (every `successionTimestep`; `Dispersal` event): - - Seed dispersal can be a slow process and has been adapted to occur every 10 years (default `successionTimestep`). The user can set it to occur more/less often, with the caveat that if using *Biomass_borealDataPrep* to estimate species establishment probabilities, these values are integrated over 10 years. +- seed dispersal can be a slow process and has been adapted to occur every +10 years (default `successionTimestep`). The user can set it to occur +more/less often, with the caveat that if using *Biomass_borealDataPrep* +to estimate species establishment probabilities, these values are +integrated over 10 years. +- see @SchellerDomingo2012 for details on dispersal algorithms. -5. Growth and mortality (`mortalityAndGrowth` event) -- see @SchellerMladenoff2004 +5. Growth and mortality (`mortalityAndGrowth` event): - - unlike dispersal, growth and mortality always occur time step (year). +- unlike dispersal, growth and mortality always occur time step (year). +- see @SchellerMladenoff2004 for further detail. -6. Cohort age binning (every `successionTimestep`; `cohortAgeReclassification` event) -- see @SchellerMiranda2015 +6. Cohort age binning (every `successionTimestep`; `cohortAgeReclassification` +event): - - follows the same frequency as dispersal, collapsing cohorts (i.e., summing their biomass/mortality/aNPP) to ages classes with resolution equal to `successionTimestep`. +- follows the same frequency as dispersal, collapsing cohorts (i.e., +summing their biomass/mortality/aNPP) to ages classes with resolution +equal to `successionTimestep`. +- see @SchellerMiranda2015 for further detail. -7. Summary tables of regeneration (`summaryRegen` event), biomass, age, growth and mortality (`summaryBGM` event) +7. Summary tables of regeneration (`summaryRegen` event), biomass, age, growth +and mortality (`summaryBGM` event); -8. Plots of maps (`plotMaps` event) and averages (`plotAvgs` and `plotSummaryBySpecies` events) +8. Plots of maps (`plotMaps` event) and averages (`plotAvgs` and +`plotSummaryBySpecies` events); -9. Save outputs (`save` events) +9. Save outputs (`save` event). ... (repeat 2-9) ... +[^biomass_core-6]: `simInit` is a `SpaDES` function that initialises the +execution of one or more modules by parsing and checking their code and +executing the `.inputObjects` function(s), where the developer provides +mechanisms to satisfy each module's expected inputs with default values. + ### Differences between *Biomass_core* and the LANDIS-II Biomass Succession Extension model (LBSE) {#biomass-core-vs-lbse} #### Algorithm changes {#biomass-core-vs-lbse-algo} -Upon porting LBSE into R, we made six minor modifications to the original model's algorithms to better reflect ecological processes. This did not result in dramatic changes in simulation outputs and we note that these changes might also have been implemented in more recent versions of LBSE. - -First, for each year and community (i.e., 'pixel group' in *Biomass_core*, see below), LBSE calculates the competition index for a cohort sequentially (i.e., one cohort at a time) after updating the growth and mortality (i.e., the biomass gain and loss, respectively) of other cohorts, and with the calculation sequence following cohort age in descending order, but no explicit order of species. This sorting of growth and mortality calculations from oldest to youngest cohorts in LBSE was aimed at capturing size-asymmetric competition between cohorts, under the assumption that older cohorts have priority for growing space given their greater height (Scheller pers. comm.). We felt that within-year sequential growth, death and recruitment may be not ecologically accurate, and that the size-asymmetric competition was being accounted for twice, as the calculation of the competition index already considers the competitive advantage of older cohorts [as shown in the User's Guide, @SchellerMiranda2015]. Hence, in *Biomass_core* growth, mortality, recruitment and the competition index are calculated at the same time across all cohorts and species. - -Second, the unknown species-level sorting mechanism contained within LBSE (which changed depending on the species order in the input species list file), led to different simulation results depending on the input species list file (e.g., Table \@ref(tab:tableLBSEtest1) and Fig. \@ref(fig:figLBSEtest1)). The calculation of competition, growth and mortality for all cohorts at the same time also circumvented this issue. +Upon porting LBSE into R, we made six minor modifications to the original +model's algorithms to better reflect ecological processes. This did not +significantly alter the simulation outputs and we note that these changes might +also have been implemented in more recent versions of LBSE. + +First, for each year and community (i.e., 'pixel group' in *Biomass_core*, see +below), LBSE calculates the competition index for a cohort sequentially (i.e., +one cohort at a time) after updating the growth and mortality of other cohorts +(i.e., their biomass gain and loss, respectively) , and with the calculation +sequence following cohort age in descending order, but no explicit order of +species. This sorting of growth and mortality calculations from oldest to +youngest cohorts in LBSE was aimed at capturing size-asymmetric competition +between cohorts, under the assumption that older cohorts have priority for +growing space given their greater height (Scheller pers. comm.). We felt that +within-year sequential growth, death and recruitment may be not ecologically +accurate, and that the size-asymmetric competition was being accounted for +twice, as the calculation of the competition index already considers the +competitive advantage of older cohorts [as shown in the User's Guide, +@SchellerMiranda2015]. Hence, in *Biomass_core* growth, mortality, recruitment +and the competition index are calculated at the same time across all cohorts and +species. + +Second, the unknown species-level sorting mechanism contained within LBSE (which +changed depending on the species order in the input species list file), led to +different simulation results depending on the input species list file (e.g., +Table \@ref(tab:tableLBSEtest1) and Fig. \@ref(fig:figLBSEtest1)). The +calculation of competition, growth and mortality for all cohorts at the same +time also circumvented this issue.
    -Differences in total landscape aboveground biomass when using two different input species orders for the same community. These simulations demonstrate how the sequential calculation of the competition index, combined with a lack of explicit species ordering affect the overall landscape aboveground biomass in time when using different input species orders (see Table \@ref(tab:tableLBSEtest1)). In order to prevent differences introduced by cohort recruitment, species’ ages at sexual maturity were changed to the species’ longevity values, and the simulation ran for 75 years to prevent any cohorts from reaching sexual maturity. The bottom panel shows the difference between the two simulations in percentage, calculated as $\frac{Biomass_{order2} - Biomass_{order1}}{Biomass_{order2}} * 100$ +Differences in total landscape aboveground biomass when using two different input species orders for the same community. These simulations demonstrate how the sequential calculation of the competition index, combined with a lack of explicit species ordering affect the overall landscape aboveground biomass in time when using different input species orders (see Table \@ref(tab:tableLBSEtest1)). In order to prevent differences introduced by cohort recruitment, species’ ages at sexual maturity were changed to the species’ longevity values, and the simulation ran for 75 years to prevent any cohorts from reaching sexual maturity. The bottom panel shows the difference between the two simulations in percentage, calculated as $\frac{Biomass_{order2} - Biomass_{order1}}{Biomass_{order2}} * 100$

    (\#fig:figLBSEtest1)Differences in total landscape aboveground biomass when using two different input species orders for the same community. These simulations demonstrate how the sequential calculation of the competition index, combined with a lack of explicit species ordering affect the overall landscape aboveground biomass in time when using different input species orders (see Table \@ref(tab:tableLBSEtest1)). In order to prevent differences introduced by cohort recruitment, species’ ages at sexual maturity were changed to the species’ longevity values, and the simulation ran for 75 years to prevent any cohorts from reaching sexual maturity. The bottom panel shows the difference between the two simulations in percentage, calculated as $\frac{Biomass_{order2} - Biomass_{order1}}{Biomass_{order2}} * 100$

    -Third, in LBSE the calculation of total pixel biomass for the purpose of calculating the initial biomass of a new cohort included the (previously calculated) biomass of other new cohorts when succession time step = 1, but not when time step was \> 1. This does not reflect the documentation in the User's Guide, which stated that "Bsum [total pixel biomass] is the current total biomass for the site (not including other new cohorts)" [@SchellerMiranda2015,p. 4], when the succession time step was set to 1. Additionally, together with the lack of explicit ordering, this generated different results in terms of the biomass assigned to each new cohort (e.g. Table \@ref(tab:tableLBSEtest2) and Fig. \@ref(fig:figLBSEtest2)). In *Biomass_core* the initial biomass of new cohorts is no longer calculated sequentially (as with competition, growth and mortality), and thus the biomass of new cohorts is never included in the calculation of total pixel biomass. +Third, in LBSE the calculation of total pixel biomass for the purpose of +calculating the initial biomass of a new cohort included the (previously +calculated) biomass of other new cohorts when succession time step = 1, but not +when time step was \> 1. This does not reflect the documentation in the User's +Guide, which stated that "*Bsum [total pixel biomass] is the current total +biomass for the site (not including other new cohorts)*" +[@SchellerMiranda2015,p. 4], when the succession time step was set to 1. +Additionally, together with the lack of explicit ordering, this generated +different results in terms of the biomass assigned to each new cohort (e.g., +Table \@ref(tab:tableLBSEtest2) and Fig. \@ref(fig:figLBSEtest2)). In +*Biomass_core* the initial biomass of new cohorts is no longer calculated +sequentially (as with competition, growth and mortality), and thus the biomass +of new cohorts is never included in the calculation of total pixel biomass.
    -Differences in the biomasses assigned to new cohorts, summed for each species across pixels, when using two different input species orders for the same community and when the succession time step is 1. These simulations demonstrate how the different summation of total cohort biomass for a succession time step of 1 and the lack of explicit species ordering affect simulation results when changing the species order in the input file (see Table \@ref(tab:tableLBSEtest2)). Here, initial cohort ages were also set to 1. We show the initial total biomass attributed to each species at the end of year 1. -

    (\#fig:figLBSEtest2)Differences in the biomasses assigned to new cohorts, summed for each species across pixels, when using two different input species orders for the same community and when the succession time step is 1. These simulations demonstrate how the different summation of total cohort biomass for a succession time step of 1 and the lack of explicit species ordering affect simulation results when changing the species order in the input file (see Table \@ref(tab:tableLBSEtest2)). Here, initial cohort ages were also set to 1. We show the initial total biomass attributed to each species at the end of year 1.

    +Differences in the biomass assigned to new cohorts, summed for each species across pixels, when using two different input species orders for the same community and when the succession time step is 1. These simulations demonstrate how the different summation of total cohort biomass for a succession time step of 1 and the lack of explicit species ordering affect simulation results when changing the species order in the input file (see Table \@ref(tab:tableLBSEtest2)). Here, initial cohort ages were also set to 1. Values refer to the initial total biomass attributed to each species at the end of year 1. +

    (\#fig:figLBSEtest2)Differences in the biomass assigned to new cohorts, summed for each species across pixels, when using two different input species orders for the same community and when the succession time step is 1. These simulations demonstrate how the different summation of total cohort biomass for a succession time step of 1 and the lack of explicit species ordering affect simulation results when changing the species order in the input file (see Table \@ref(tab:tableLBSEtest2)). Here, initial cohort ages were also set to 1. Values refer to the initial total biomass attributed to each species at the end of year 1.

    -Fourth, in LBSE, serotiny and resprouting could not occur in the same pixel following a fire, with serotiny taking precedence if activated. We understand that this provides an advantage to serotinous species, which could perhaps be disadvantaged with respect to fast-growing resprouters. However, we feel that it is ecologically more realistic that serotinous and resprouter species be able to both regenerate in a given community following a fire and allow the competition between serotinous and resprouting species to arise from species traits. **This change was implemented in the *Biomass_regeneration* and *Biomass_regenerationPM* modules** . - -Fifth, in *Biomass_core*, species shade tolerance values can have decimal values to allow for finer adjustments of between-species competition. - -Sixth, we added a new parameter called `minCohortBiomass`, that allows the user to control cohort removal bellow a certain threshold of biomass. In some simulation set-ups, we noticed that *Biomass_core* (and LBSE) were able to generate many very small cohorts in the understory that, due to cohort competition, were not able to gain biomass and grow. However, because competition does not increase mortality, only decreases growth, these cohorts survived at very low biomass levels until they reached sufficient age to suffer age-related mortality. We felt this is unlikely to be realistic in many cases. By default, this parameter is left at 0 to follow LBSE behaviour (i.e., no cohorts removal based on minimum biomass). +Fourth, in LBSE, serotiny and resprouting could not occur in the same pixel +following a fire, with serotiny taking precedence if activated. We understand +that this provides an advantage to serotinous species, which could perhaps be +disadvantaged with respect to fast-growing resprouters. However, we feel that it +is ecologically more realistic that serotinous and resprouter species be able to +both regenerate in a given pixel following a fire and allow the competition +between serotinous and resprouting species to arise from species traits. Note +that this change was implemented in the *Biomass_regeneration* and +*Biomass_regenerationPM* modules, since post-disturbance effects were separated +background vegetation dynamics simulated by *Biomass_core*. + +Fifth, in *Biomass_core*, species shade tolerance values can have decimal values +to allow for finer adjustments of between-species competition. + +Sixth, we added a new parameter called `minCohortBiomass`, that allows the user +to control cohort removal bellow a certain threshold of biomass. In some +simulation set-ups, we noticed that *Biomass_core* (and LBSE) were able to +generate many very small cohorts in the understory that, due to cohort +competition, were not able to gain biomass and grow. However, because +competition decreases growth but does not increase mortality, these cohorts +survived at very low biomass levels until they reached sufficient age to suffer +age-related mortality. We felt this is unlikely to be realistic in many cases. +By default, this parameter is left at 0 to follow LBSE behaviour (i.e., no +cohorts removal based on minimum biomass). #### Other enhancements {#biomass-core-vs-lbse-enhan} -In addition to the five minor changes in growth, mortality and regeneration, we separated the components that govern vegetation responses to disturbances -- only fire at the moment -- into two independent modules used interchangeably (Biomass_regeneration and *Biomass_regenerationPM*, and implemented hashing, caching and testing to improve the model's computational efficiency and insure its performance. +In addition to the sixth changes in growth, mortality and regeneration mentioned +above, we enhanced modularity by separating the components that govern +vegetation responses to disturbances from *Biomass_core*, and implemented +hashing, caching and testing to improve computational efficiency and insure +performance. ##### Modularity {#biomass-core-vs-lbse-enhan1} -Unlike in LBSE, post-disturbance regeneration is not part of *Biomass_core* *per se*, but belongs to two separate modules, used interchangeably ([*Biomass_regeneration*](https://github.com/PredictiveEcology/Biomass_regeneration/blob/master/Biomass_regeneration.Rmd) and [*Biomass_regenerationPM*](https://github.com/PredictiveEcology/Biomass_regenerationPM/blob/master/Biomass_regenerationPM.Rmd)). These need to be loaded and added to the "modules folder" of the project in case the user wants to simulate forest responses to disturbances (only fire disturbances at the moment). Again, this enables higher flexibility when swapping between different approaches to regeneration. - -Climate effects on growth and mortality were also implemented a modular way. The effects of climate on biomass increase (growth) and loss (mortality) were written in functions grouped in two packages. The `LandR` R package contains default, no climate effect functions, while the `LandR.CS` R package contains the functions that simulate climate effects (CS stands for "climate sensitive"). Note that these functions do not simulate actual growth/mortality processes, but rather modifiers that increase/decrease cohort biomass on top of background growth/mortality. - -*Biomass_core* uses the `LandR` functions by default (see `growthAndMortalityDrivers` parameter in the [full parameters list](#params-list)). Should the user wish to change how climate effects on growth/mortality are calculated, they can provide new compatible functions (i.e., with the same names, inouts and outputs) via another R package. +Unlike in LBSE, post-disturbance effects are not part of *Biomass_core* *per +se*, but belong to two separate modules, used interchangeably +([*Biomass_regeneration*](https://github.com/PredictiveEcology/Biomass_regeneration/blob/master/Biomass_regeneration.Rmd) +and +[*Biomass_regenerationPM*](https://github.com/PredictiveEcology/Biomass_regenerationPM/blob/master/Biomass_regenerationPM.Rmd)). +These need to be loaded and added to the "modules folder" of the project in case +the user wants to simulate forest responses to disturbances (only fire +disturbances at the moment). Again, this enables higher flexibility when +swapping between different approaches to regeneration. + +Climate effects on growth and mortality were also implemented a modular way. The +effects of climate on biomass increase (growth) and loss (mortality) were +written in functions grouped in two packages. The `LandR` R package contains +default, "non-climate-sensitive" functions, while the `LandR.CS` R package +contains the functions that simulate climate effects (CS stands for "climate +sensitive"). Note that these functions do not simulate actual growth/mortality +processes, but estimate modifiers that increase/decrease cohort biomass on top +of background growth/mortality. *Biomass_core* uses the `LandR` functions by +default (see `growthAndMortalityDrivers` parameter in the [full parameters +list](#params-list)). Should the user wish to change how climate effects on +growth/mortality are calculated, they can provide new compatible functions +(i.e., with the same names, inputs and outputs) via another R package. ##### Hashing {#biomass-core-vs-lbse-enhan2} -Our first strategy to improve simulation efficiency in *Biomass_core* was to use a hashing mechanism [@YangEtAl2011]. Instead of assigning a key to each pixel in a raster and tracking the simulation for each pixel in a lookup table, we indexed pixels using a *pixelGroup* key that contained unique combinations of ecolocation and community composition (i.e., species, age and biomass composition), and tracked and stored simulation data for each *pixelGroup* (Fig. \@ref(fig:figLBSEtest3)). This algorithm was able to ease the computational burden by significantly reducing the size of the lookup table and speeding-up the simulation process. After recruitment and disturbance events, pixels are rehashed into new pixel groups. +Our first strategy to improve simulation efficiency in *Biomass_core* was to use +a hashing mechanism [@YangEtAl2011]. Instead of assigning a key to each pixel in +a raster and tracking the simulation for each pixel in a lookup table, we +indexed pixels using a *pixelGroup* key that contained unique combinations of +ecolocation and community composition (i.e., species, age and biomass +composition), and tracked and stored simulation data for each *pixelGroup* (Fig. +\@ref(fig:figLBSEtest3)). This algorithm was able to ease the computational +burden by significantly reducing the size of the lookup table and speeding-up +the simulation process. After recruitment and disturbance events, pixels are +rehashed into new pixel groups.
    -Hashing design for (ref:Biomass-core). In the re-coded (ref:Biomass-core), the pixel group map was hashed based on the unique combination of species composition (i.e., community map) and ecolocation map, and associated with a lookup table. The subfigure in the right upper corner was the original design that linked the map to the lookup table by pixel key. -

    (\#fig:figLBSEtest3)Hashing design for (ref:Biomass-core). In the re-coded (ref:Biomass-core), the pixel group map was hashed based on the unique combination of species composition (i.e., community map) and ecolocation map, and associated with a lookup table. The subfigure in the right upper corner was the original design that linked the map to the lookup table by pixel key.

    +Hashing design for (ref:Biomass-core). In the re-coded (ref:Biomass-core), the pixel group map was hashed based on the unique combination of species composition ('community map') and ecolocation map, and associated with a lookup table. The insert in the top-right corner was the original design that linked the map to the lookup table by pixel key. +

    (\#fig:figLBSEtest3)Hashing design for (ref:Biomass-core). In the re-coded (ref:Biomass-core), the pixel group map was hashed based on the unique combination of species composition ('community map') and ecolocation map, and associated with a lookup table. The insert in the top-right corner was the original design that linked the map to the lookup table by pixel key.

    ##### Caching {#biomass-core-vs-lbse-enhan3} -The second strategy aimed at improving model efficacy was the implementation of caching during data-driven parametrisation and initialisation. Caching automatically archives outputs of a given function to disk (or memory) and reads them back when subsequent calls of this function are given identical inputs. All caching operations were achieved using the `reproducible` R package [@McIntireChubaty2020]. - -In the current version of *Biomass_core*, the spin-up phase was replaced by data-driven landscape initialisation and many model parameters were derived from data, using data and calibration modules (e.g., *Biomass_borealDataPrep*). To avoid having to repeat data downloads and treatment, statistical estimation of parameters and landscape initialisation every time the simulation is re-run under the same conditions, many of these pre-simulation steps are automatically cached. This means that the pre-simulation phase is significantly faster upon a second call when inputs have not changed (e.g., the input data and parametrisation methods), and when inputs do change only directly affected steps are re-run (see main text for examples). When not using data modules, *Biomass_core* still relies on caching for the preparation of its theoretical inputs. +The second strategy aimed at improving model efficacy was the implementation of +caching during data-driven parametrisation and initialisation. Caching +automatically archives outputs of a given function to disk (or memory) and reads +them back when subsequent calls of this function are given identical inputs. All +caching operations were achieved using the `reproducible` R package +[@McIntireChubaty2020]. + +In the current version of *Biomass_core*, the spin-up phase was replaced by +data-driven landscape initialisation and many model parameters were derived from +data, using data and calibration modules (e.g., *Biomass_borealDataPrep*). To +avoid having to repeat data downloads and treatment, statistical estimation of +parameters and landscape initialisation every time the simulation is re-run +under the same conditions, many of these pre-simulation steps are automatically +cached. This means that the pre-simulation phase is significantly faster upon a +second call when inputs have not changed (e.g., the input data and +parametrisation methods), and when inputs do change only directly affected steps +are re-run (see main text for examples). When not using data modules, +*Biomass_core* still relies on caching for the preparation of its theoretical +inputs. ##### Testing {#biomass-core-vs-lbse-enhan4} -Finally, we implemented code testing, to facilitate bug detection by comparing the outputs of functions (etc.) to expected outputs [@Wickham2011]. We built and integrated code tests in *Biomass_core* and across all LandR modules and the `LandR` R package in the form of assertions, unit tests and integration tests. Assertions and unit tests are run automatically during simulations (but can be turned off) and evaluate individual code components (e.g., one function or an object's class). Integration tests evaluate if several coded processes are integrated correctly. Integration tests are usually run manually. However, because we embedded assertions within the module code, R package dependencies of *Biomass_core*, such as the `LandR` R package and `SpaDES`, they also provide a means to test module integration. We also implemented GitHub Actions continuous integration (CI), which routinely test GitHub hosted packages (e.g., `LandR`). CRAN-hosted packages (e.g., `SpaDES`) are also automatically tested and checked on CRAN. - -Finally, because *Biomass_core* (and all other LandR modules) code is hosted in public GitHub repositories, the module code is subject to the scrutiny of of many users, who can identify issues and contribute to improve module code. +Finally, we implemented code testing to facilitate bug detection by comparing +the outputs of functions (etc.) to expected outputs [@Wickham2011]. We built and +integrated code tests in *Biomass_core* and across all LandR modules and the +`LandR` R package in the form of assertions, +unit tests and integration tests. Assertions and unit tests are run +automatically during simulations (but can be turned off) and evaluate individual +code components (e.g., one function or an object's class). Integration tests +evaluate if several coded processes are integrated correctly and are usually run +manually. However, because we embedded assertions within the module code, R +package dependencies of *Biomass_core*, such as the `LandR` R package + and `SpaDES`, they also provide a means to test +module integration. We also implemented GitHub Actions continuous integration +(CI), which routinely test GitHub hosted packages (e.g., `LandR`) and modules. +CRAN-hosted packages (e.g., `SpaDES`) are also automatically tested and checked +on CRAN. + +Finally, because *Biomass_core* (and all other LandR modules) code is hosted in +public GitHub repositories, the module code is subject to the scrutiny of +many users, who can identify issues and contribute to improve module code. #### Performance and accuracy of *Biomass_core* with respect to LBSE {#biomass-core-vs-lbse-comparisons} -In the recoding of *Biomass_core*, we ensured similar outputs of each demographic process (namely, growth, mortality and recruitment) to the outputs from its counterpart in LBSE, using integration tests. Here, we report the comparisons of the overall simulation (i.e., including all demographic processes) between LBSE and *Biomass_core* using three randomly generated initial communities (Tables \@ref(tab:tableLBSEtest3)-\@ref(tab:tableLBSEtest5)). The remaining input parameters were taken from a LANDIS-II training course (Tables \@ref(tab:tableLBSEtest6)-\@ref(tab:tableLBSEtest9)), and contained species attributes information of 16 common tree species in boreal forests and 2 ecolocations. We ran simulations for 1000 years, with a succession time step of 10 and three repetitions, which were enough to account for the variability produced by stochastic processes. Seed dispersal was set as "ward dispersal". - -The results suggested that *Biomass_core* had a good agreement with LBSE using the three randomly generated initial communities (Fig. \@ref(fig:figLBSEtest4)), with very small deviations for LBSE-generated biomasses. Notably, the mean differences between LBSE and *Biomass_core* were 0.03(ref:percent) (range: -0.01(ref:percent) \~ 0.13(ref:percent)), 0.03(ref:percent) (range: -0.01(ref:percent) \~ 0.11(ref:percent)) and 0.05(ref:percent) (-0.02(ref:percent) \~ 0.15(ref:percent)) for each initial community, respectively (right panels in Fig. \@ref(fig:figLBSEtest4) of this appendix). +In the recoding of *Biomass_core*, we used integration tests to ensured similar +outputs of each demographic process (namely, growth, mortality and recruitment) +to the outputs from its counterpart in LBSE. Here, we report the +comparisons of the overall simulation (i.e., including all demographic +processes) between LBSE and *Biomass_core* using three randomly generated +initial communities (Tables +\@ref(tab:tableLBSEtest3)-\@ref(tab:tableLBSEtest5)). The remaining input +parameters were taken from a LANDIS-II training course (Tables +\@ref(tab:tableLBSEtest6)-\@ref(tab:tableLBSEtest9)), and contained species +attributes information of 16 common tree species in boreal forests and 2 +ecolocations. We ran simulations for 1000 years, with a succession time step of +10 and three replicates, which were enough to account for the variability +produced by stochastic processes. Seed dispersal was set as "ward dispersal". + +The results suggested that *Biomass_core* had a good agreement with LBSE using +the three randomly generated initial communities (Fig. \@ref(fig:figLBSEtest4)), +with very small deviations for LBSE-generated biomasses. Notably, the mean +differences between LBSE and *Biomass_core* were 0.03(ref:percent) (range: +-0.01(ref:percent) \~ 0.13(ref:percent)), 0.03(ref:percent) (range: +-0.01(ref:percent) \~ 0.11(ref:percent)) and 0.05(ref:percent) +(-0.02(ref:percent) \~ 0.15(ref:percent)) for each initial community, +respectively (right panels in Fig. \@ref(fig:figLBSEtest4) of this appendix).
    -Visual comparison of simulation outputs for three randomly generated initial communities (left panels) and difference between those outputs (right panels). The (ref:percent) difference between LBSE and (ref:Biomass-core) were calculated as $\frac{Biomass_{LBSE} - Biomass_{Biomass_core}}{Biomass_{LBSE}} * 100$ +Visual comparison of simulation outputs for three randomly generated initial communities (left panels) and difference between those outputs (right panels). The (ref:percent) difference between LBSE and (ref:Biomass-core) were calculated as $\frac{Biomass_{LBSE} - Biomass_{Biomass_core}}{Biomass_{LBSE}} * 100$

    (\#fig:figLBSEtest4)Visual comparison of simulation outputs for three randomly generated initial communities (left panels) and difference between those outputs (right panels). The (ref:percent) difference between LBSE and (ref:Biomass-core) were calculated as $\frac{Biomass_{LBSE} - Biomass_{Biomass_core}}{Biomass_{LBSE}} * 100$

    -To examine how running time changed with map size, we ran simulations using maps with increasing number of pixels from 22,201 to 638,401 pixels. All maps were initialised with a single ecolocation and 7 different communities. Simulations were run for 120 years using a succession time step of 10 and replicated three times. To eliminate the effect of hardware on running time, we used machines that were all purchased at the same time, with equal specifications and running Windows 7. Each simulation ran on 2 CPU threads with a total RAM of 4000 Mb. For both LBSE and *Biomass_core*, the simulation time increased linearly with number of pixels, but the increase rate was smaller for *Biomass_core* (Fig. \@ref(fig:figLBSEtest5)a). This meant that while both models had similar simulation efficiencies in small maps (\< 90,000 pixels), as map size increased *Biomass_core* was \~2 times faster than LBSE (maps \> 100,000 pixels; Fig. \@ref(fig:figLBSEtest5)a). *Biomass_core* also scaled better with map size, as LBSE speeds fluctuated between 19 to 25 seconds per 1,000 pixels across all map sizes, while *Biomass_core* decreased from 21 to 11 seconds per 1,000 pixels from smaller to larger maps (Fig. \@ref(fig:figLBSEtest5)b). +To examine how running time changed with map size, we ran simulations using maps +with increasing number of pixels, from 22,201 to 638,401 pixels. All maps were +initialised with a single ecolocation and 7 different communities. Simulations +were run for 120 years using a succession time step of 10 and replicated three +times. To eliminate the effect of hardware on running time, we used machines +that were all purchased at the same time, with equal specifications and running +Windows 7. Each simulation ran on 2 CPU threads with a total RAM of 4000 Mb. + +For both LBSE and *Biomass_core*, the simulation time increased linearly with number +of pixels, but the increase rate was smaller for *Biomass_core* (Fig. +\@ref(fig:figLBSEtest5)a). This meant that while both models had similar +simulation efficiencies in small maps (\< 90,000 pixels), as map size increased +*Biomass_core* was \~2 times faster than LBSE (maps \> 100,000 pixels; Fig. +\@ref(fig:figLBSEtest5)a). *Biomass_core* also scaled better with map size, as +LBSE speeds fluctuated between 19 to 25 seconds per 1,000 pixels across all map +sizes, while *Biomass_core* decreased from 21 to 11 seconds per 1,000 pixels +from smaller to larger maps (Fig. \@ref(fig:figLBSEtest5)b).
    -Simulation efficiencies of LBSE and (ref:Biomass-core) with increasing map size, in terms of a) mean running time across repetitions (left y-axis) and the ratio LBSE to (ref:Biomass-core) running times (right y-axis and blue line), and b) running time scalability as the mean running time per 1000 pixels. +Simulation efficiencies of LBSE and (ref:Biomass-core) with increasing map size, in terms of a) mean running time across repetitions (left y-axis) and the ratio LBSE to (ref:Biomass-core) running times (right y-axis and blue line), and b) running time scalability as the mean running time per 1000 pixels.

    (\#fig:figLBSEtest5)Simulation efficiencies of LBSE and (ref:Biomass-core) with increasing map size, in terms of a) mean running time across repetitions (left y-axis) and the ratio LBSE to (ref:Biomass-core) running times (right y-axis and blue line), and b) running time scalability as the mean running time per 1000 pixels.

    @@ -939,9 +1780,16 @@ paths <- list(inputPath = normPath(file.path(tempDir, "inputs")), ### Get the module and module dependencies {#example-pkg-mods} -We can use the `SpaDES.install::getModule` function to download the module to the module folder specified above. Alternatively, see [SpaDES-modules repository](https://github.com/PredictiveEcology/SpaDES-modules) to see how to download this and other `SpaDES` modules, or fork/clone from its [GitHub repository](https://github.com/PredictiveEcology/Biomass_core/) directly. +We can use the `SpaDES.install::getModule` function to download the module to +the module folder specified above. Alternatively, see [SpaDES-modules +repository](https://github.com/PredictiveEcology/SpaDES-modules) to see how to +download this and other `SpaDES` modules, or fork/clone from its [GitHub +repository](https://github.com/PredictiveEcology/Biomass_core/) directly. -After downloading the module, it is important to make sure all module R package dependencies are installed in their correct version. `SpaDES.install::makeSureAllPackagesInstalled` takes care of this for any module in the `paths$modulePath`. +After downloading the module, it is important to make sure all module R package +dependencies are installed in their correct version. +`SpaDES.install::makeSureAllPackagesInstalled` takes care of this for any module +in the `paths$modulePath`. ```r @@ -954,9 +1802,16 @@ SpaDES.install::makeSureAllPackagesInstalled(paths$modulePath) ### Setup simulation {#example-setupSim} -Here we setup a simulation in a random study area, using any species within the `LandR::sppEquivalencies_CA` table that can be found there (*Biomass_core* will retrieve species (ref:percent) cover maps and filter present species). We also define the colour coding used for plotting, the type of plots we what to produce and choose to output `cohortData` tables every year -- note that these are not pixel-based and to spatialise results *a posteriori* the `pixelBroupMap` must also be saved. +Here we setup a simulation in a random study area, using any species within the +`LandR::sppEquivalencies_CA` table that can be found there (*Biomass_core* will +retrieve species (ref:percent) cover maps and filter present species). We also +define the colour coding used for plotting, the type of plots we what to produce +and choose to output `cohortData` tables every year -- note that these are not +pixel-based, so to "spatialise" results *a posteriori* the `pixelBroupMap` must +also be saved. -Please see the lists of [input objects](#inputs-list), [parameters](#params-list) and [outputs](#outputs-list) for more information. +Please see the lists of [input objects](#inputs-list), +[parameters](#params-list) and [outputs](#outputs-list) for more information. ```r @@ -1004,7 +1859,9 @@ graphics.off() ### Run simulation {#example-runSim} -`simInitAndSpades` is a wrapper function that runs both `simInit` (which prepares the simulation) and `spades` (which initialises and runs the simulation), to which pass all the necessary setup objects created above. +`simInitAndSpades` is a wrapper function that runs both `simInit` (which +initialises all modules) and `spades` (which runs all modules, i.e., their events), +to which pass all the necessary setup objects created above. ```r @@ -1018,16 +1875,16 @@ mySim <- simInitAndSpades(times = times, ```
    -(ref:Biomass-core) automatically generates simulation visuals of species dynamics across the landscape in terms of total biomass, number of presences and age and productivity (above), as well as yearly plots of total biomass, productivity, mortality, reproduction and leading species in each pixel (below).(ref:Biomass-core) automatically generates simulation visuals of species dynamics across the landscape in terms of total biomass, number of presences and age and productivity (above), as well as yearly plots of total biomass, productivity, mortality, reproduction and leading species in each pixel (below). +(ref:Biomass-core) automatically generates simulation visuals of species dynamics across the landscape in terms of total biomass, number of presences and age and productivity (above), as well as yearly plots of total biomass, productivity, mortality, reproduction and leading species in each pixel (below).(ref:Biomass-core) automatically generates simulation visuals of species dynamics across the landscape in terms of total biomass, number of presences and age and productivity (above), as well as yearly plots of total biomass, productivity, mortality, reproduction and leading species in each pixel (below).

    (\#fig:fig-Biomass-coreOutPlots)(ref:Biomass-core) automatically generates simulation visuals of species dynamics across the landscape in terms of total biomass, number of presences and age and productivity (above), as well as yearly plots of total biomass, productivity, mortality, reproduction and leading species in each pixel (below).

    ## Appendix {#appendix} ### Tables {#appendix-tables} - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    (\#tab:tableLBSEtest1)Input order and processing order (as determined by LBSE) for the same community used to assess the impact of sequential calculation of the competition index, combined with a lack of explicit species ordering. The input order was the order of species in the initial communities table input file. The processing order was the order used in the simulation, which was obtained from `Landis-log.txt` when `CalibrateMode` was set to 'yes'. Species starting ages are also shown.
    Input order 1 Input order 2
    Community Input order Age Processing Community Input order Age Processing
    1 abiebals 20 poputrem 1 pinustro 20 thujocci
    1 acerrubr 20 querelli 1 poputrem 20 tiliamer
    1 acersacc 20 pinuresi 1 acerrubr 20 querelli
    1 betualle 20 pinustro 1 pinubank 20 querrubr
    1 betupapy 20 tiliamer 1 betualle 20 betupapy
    1 fraxamer 20 tsugcana 1 piceglau 20 fraxamer
    1 piceglau 20 querrubr 1 pinuresi 20 tsugcana
    1 pinubank 20 thujocci 1 acersacc 20 abiebals
    1 pinuresi 20 acersacc 1 querelli 20 acerrubr
    1 pinustro 20 betualle 1 querrubr 20 pinubank
    1 poputrem 20 abiebals 1 thujocci 20 pinustro
    1 querelli 20 acerrubr 1 tiliamer 20 poputrem
    1 querrubr 20 piceglau 1 tsugcana 20 pinuresi
    1 thujocci 20 pinubank 1 abiebals 20 acersacc
    1 tiliamer 20 betupapy 1 betupapy 20 betualle
    1 tsugcana 20 fraxamer 1 fraxamer 20 piceglau
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    (\#tab:tableLBSEtest2)Input order and processing order (as determined by LBSE) for the same community used to assess the impact of setting the succession time step to 1, combined with a lack of explicit species ordering. The input order was the order of species in the initial communities table input file. The processing order was the order used in the simulation, which was obtained from `Landis-log.txt` when `CalibrateMode` was set to 'yes'. Species starting ages are also shown.
    Input order 1 Input order 2
    Community Input order Age Processing Community Input order Age Processing
    1 abiebals 1 poputrem 1 pinustro 1 thujocci
    1 acerrubr 1 querelli 1 poputrem 1 tiliamer
    1 acersacc 1 pinuresi 1 acerrubr 1 querelli
    1 betualle 1 pinustro 1 pinubank 1 querrubr
    1 betupapy 1 tiliamer 1 betualle 1 betupapy
    1 fraxamer 1 tsugcana 1 piceglau 1 fraxamer
    1 piceglau 1 querrubr 1 pinuresi 1 tsugcana
    1 pinubank 1 thujocci 1 acersacc 1 abiebals
    1 pinuresi 1 acersacc 1 querelli 1 acerrubr
    1 pinustro 1 betualle 1 querrubr 1 pinubank
    1 poputrem 1 abiebals 1 thujocci 1 pinustro
    1 querelli 1 acerrubr 1 tiliamer 1 poputrem
    1 querrubr 1 piceglau 1 tsugcana 1 pinuresi
    1 thujocci 1 pinubank 1 abiebals 1 acersacc
    1 tiliamer 1 betupapy 1 betupapy 1 betualle
    1 tsugcana 1 fraxamer 1 fraxamer 1 piceglau
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    (\#tab:tableLBSEtest3)Randomly generated community combination no. 1 used in the recruitment comparison runs.
    Community Species Age 1 Age 2 Age 3 Age 4 Age 5 Age 6 Age 7
    0 betupapy 1 37 45 46 85 NA NA
    0 piceglau 27 73 153 256 270 NA NA
    0 pinustro 157 159 181 220 223 303 307
    0 querrubr 80 102 127 152 206 227 NA
    1 acerrubr 3 91 126 145 NA NA NA
    1 acersacc 138 144 276 NA NA NA NA
    1 betualle 24 106 136 149 279 NA NA
    1 piceglau 27 67 70 153 NA NA NA
    1 pinubank 3 10 24 31 71 NA NA
    1 querelli 92 224 234 NA NA NA NA
    1 thujocci 73 146 262 NA NA NA NA
    2 fraxamer 108 118 137 147 204 NA NA
    2 piceglau 40 128 131 159 174 NA NA
    2 pinustro 78 156 237 245 270 NA NA
    2 querelli 67 97 186 292 NA NA NA
    2 tiliamer 70 103 121 152 178 180 245
    3 acerrubr 5 83 125 126 127 NA NA
    3 pinuresi 1 25 42 49 76 79 103
    3 poputrem 4 9 62 NA NA NA NA
    3 querelli 101 104 167 226 NA NA NA
    3 tsugcana 37 135 197 404 405 NA NA
    4 acerrubr 15 29 63 70 105 133 NA
    4 piceglau 67 132 189 NA NA NA NA
    4 tsugcana 21 26 110 146 341 462 463
    5 acerrubr 128 137 145 147 NA NA NA
    5 acersacc 241 245 261 277 NA NA NA
    5 querrubr 23 72 120 142 188 NA NA
    5 tiliamer 4 68 98 118 139 197 NA
    6 betualle 5 23 31 249 NA NA NA
    6 pinubank 67 70 89 NA NA NA NA
    6 querelli 194 217 257 NA NA NA NA
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    (\#tab:tableLBSEtest5)Randomly generated community combination no. 3 used in the recruitment comparison runs.
    Community Species Age 1 Age 2 Age 3 Age 4 Age 5 Age 6 Age 7
    0 pinubank 7 26 32 37 48 85 90
    0 pinuresi 11 103 109 179 188 197 NA
    0 querrubr 89 139 180 206 NA NA NA
    1 betupapy 36 39 45 49 66 68 NA
    1 piceglau 13 165 254 NA NA NA NA
    1 pinubank 3 19 54 64 76 NA NA
    1 poputrem 22 59 93 NA NA NA NA
    1 thujocci 68 98 274 275 363 378 NA
    1 tiliamer 13 20 105 124 248 NA NA
    1 tsugcana 36 90 142 NA NA NA NA
    2 fraxamer 11 241 279 NA NA NA NA
    2 piceglau 16 42 129 177 200 244 NA
    2 pinustro 200 342 384 NA NA NA NA
    3 abiebals 31 57 61 92 108 162 183
    3 piceglau 126 255 261 267 NA NA NA
    3 poputrem 28 41 57 NA NA NA NA
    3 querrubr 83 91 144 173 184 238 NA
    3 thujocci 6 66 68 204 NA NA NA
    4 fraxamer 12 110 266 270 NA NA NA
    4 pinustro 174 270 359 379 NA NA NA
    4 poputrem 4 7 18 24 63 76 NA
    4 tiliamer 126 136 197 NA NA NA NA
    4 tsugcana 49 91 128 194 411 487 NA
    5 abiebals 35 53 108 114 147 174 195
    5 acerrubr 1 2 101 145 NA NA NA
    5 pinubank 14 15 38 40 59 69 83
    6 acerrubr 4 46 117 NA NA NA NA
    6 betualle 36 41 116 213 253 NA NA
    6 betupapy 4 6 76 NA NA NA NA
    6 pinuresi 43 68 85 171 NA NA NA
    6 querrubr 84 86 113 185 193 223 228
    6 tiliamer 13 106 181 199 246 NA NA
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    (\#tab:tableLBSEtest6)Invariant species traits table used in comparison runs.
    Species Longevity Sexualmature Shadetolerance Seeddistance_eff Seeddistance_max Mortalityshape Growthcurve
    abiebals 200 25 5 30 160 10 0.25
    acerrubr 150 10 4 100 200 10 0.25
    acersacc 300 40 5 100 200 10 0.25
    betualle 300 40 4 100 400 10 0.25
    betupapy 100 30 2 200 5000 10 0.25
    fraxamer 300 30 4 70 140 10 0.25
    piceglau 300 25 3 30 200 10 0.25
    pinubank 100 15 1 20 100 10 0.25
    pinuresi 200 35 2 20 275 10 0.25
    pinustro 400 40 3 60 210 10 0.25
    poputrem 100 20 1 1000 5000 10 0.25
    querelli 300 35 2 30 3000 10 0.25
    querrubr 250 25 3 30 3000 10 0.25
    thujocci 400 30 2 45 60 10 0.25
    tiliamer 250 30 4 30 120 10 0.25
    tsugcana 500 30 5 30 100 10 0.25
    + + + + + + + + + + + + + + + + + + + + + + + + + + +
    (\#tab:tableLBSEtest7)Minimum relative biomass table used in comparison runs. X0-5 represent site shade classes from no-shade (0) to maximum shade (5). All ecolocations shared the same values.
    Ecolocation X0 X1 X2 X3 X4 X5
    All 0 0.15 0.25 0.5 0.8 0.95
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    (\#tab:tableLBSEtest8)Probability of germination for species shade tolerance and shade level combinations (called (ref:sufficient-light) table in LBSE and `sufficientLight` input `data.table` in LandR (ref:Biomass-core)) used in comparison runs.
    Shadetolerance 0 1 2 3 4 5
    1 1 0 0 0 0 0
    2 1 1 0 0 0 0
    3 1 1 1 0 0 0
    4 1 1 1 1 0 0
    5 0 0 1 1 1 1
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    (\#tab:tableLBSEtest9)Species ecolocation table used in comparison runs. `SEP` stands for species establishment probability, `maxB` for maximum biomass and `maxANPP` for maximum aboveground net primary productivity. Values were held constant throughout the simulation.
    Ecolocation Species SEP maxANPP maxB
    1 abiebals 0.90 886 26580
    1 acerrubr 1.00 1175 35250
    1 acersacc 0.82 1106 33180
    1 betualle 0.64 1202 36060
    1 betupapy 1.00 1202 36060
    1 fraxamer 0.18 1202 36060
    1 piceglau 0.58 969 29070
    1 pinubank 1.00 1130 33900
    1 pinuresi 0.56 1017 30510
    1 pinustro 0.72 1090 38150
    1 poputrem 1.00 1078 32340
    1 querelli 0.96 1096 32880
    1 querrubr 0.66 1017 30510
    1 thujocci 0.76 1090 32700
    1 tiliamer 0.54 1078 32340
    1 tsugcana 0.22 1096 32880
    ## References {#refs} From 657d8f0c945c4e7f02606a3b5aa780f961fb6400 Mon Sep 17 00:00:00 2001 From: Alex Chubaty Date: Mon, 20 Jun 2022 20:42:49 -0600 Subject: [PATCH 029/148] use LandR from PredictiveEcology instead of CeresBarros --- Biomass_core.R | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Biomass_core.R b/Biomass_core.R index a84e329..2f27b23 100644 --- a/Biomass_core.R +++ b/Biomass_core.R @@ -22,7 +22,7 @@ defineModule(sim, list( "ggplot2", "grid", "parallel", "purrr", "quickPlot", "raster", "Rcpp", "R.utils", "scales", "sp", "tidyr", "RandomFields", - "CeresBarros/LandR@LANDISinitialB (>= 1.0.7.9017)", + "PredictiveEcology/LandR@LANDISinitialB (>= 1.0.7.9018)", "PredictiveEcology/pemisc@development", "PredictiveEcology/reproducible@development", "PredictiveEcology/SpaDES.core@development (>= 1.0.8.9000)", From 025a0a081e4838b9240666876539e5d6da9363ae Mon Sep 17 00:00:00 2001 From: Alex Chubaty Date: Mon, 20 Jun 2022 20:43:24 -0600 Subject: [PATCH 030/148] Update Biomass_core.R with prev --- Biomass_core.R | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Biomass_core.R b/Biomass_core.R index 2f27b23..b2793e1 100644 --- a/Biomass_core.R +++ b/Biomass_core.R @@ -22,7 +22,7 @@ defineModule(sim, list( "ggplot2", "grid", "parallel", "purrr", "quickPlot", "raster", "Rcpp", "R.utils", "scales", "sp", "tidyr", "RandomFields", - "PredictiveEcology/LandR@LANDISinitialB (>= 1.0.7.9018)", + "PredictiveEcology/LandR@development (>= 1.0.7.9018)", "PredictiveEcology/pemisc@development", "PredictiveEcology/reproducible@development", "PredictiveEcology/SpaDES.core@development (>= 1.0.8.9000)", From 9866b414de6cf372a5762b69c645aa6b68a32d8a Mon Sep 17 00:00:00 2001 From: Alex Chubaty Date: Mon, 20 Jun 2022 23:19:05 -0600 Subject: [PATCH 031/148] bump min LandR version reqd --- Biomass_core.R | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Biomass_core.R b/Biomass_core.R index fbe1c9a..40f9d01 100644 --- a/Biomass_core.R +++ b/Biomass_core.R @@ -22,7 +22,7 @@ defineModule(sim, list( "ggplot2", "grid", "parallel", "purrr", "quickPlot", "raster", "Rcpp", "R.utils", "scales", "sp", "tidyr", "RandomFields", - "PredictiveEcology/LandR@development (>= 1.0.7.9018)", + "PredictiveEcology/LandR@development (>= 1.0.7.9022)", "PredictiveEcology/pemisc@development", "PredictiveEcology/reproducible@development", "PredictiveEcology/SpaDES.core@development (>= 1.0.8.9000)", From 4b023054fd568d24c7dbb2c83c0c7b5b791e434c Mon Sep 17 00:00:00 2001 From: Alex Chubaty Date: Wed, 29 Jun 2022 14:25:33 -0600 Subject: [PATCH 032/148] need latest LandR bugfix `sppHarmonize()` --- Biomass_core.R | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Biomass_core.R b/Biomass_core.R index 40f9d01..97425bc 100644 --- a/Biomass_core.R +++ b/Biomass_core.R @@ -22,7 +22,7 @@ defineModule(sim, list( "ggplot2", "grid", "parallel", "purrr", "quickPlot", "raster", "Rcpp", "R.utils", "scales", "sp", "tidyr", "RandomFields", - "PredictiveEcology/LandR@development (>= 1.0.7.9022)", + "PredictiveEcology/LandR@development (>= 1.0.7.9025)", "PredictiveEcology/pemisc@development", "PredictiveEcology/reproducible@development", "PredictiveEcology/SpaDES.core@development (>= 1.0.8.9000)", From bc02fd8ccf2773bfad36cb5cec219abff8439b2a Mon Sep 17 00:00:00 2001 From: Alex Chubaty Date: Thu, 30 Jun 2022 12:24:22 -0600 Subject: [PATCH 033/148] v minor --- Biomass_core.R | 1 + 1 file changed, 1 insertion(+) diff --git a/Biomass_core.R b/Biomass_core.R index 97425bc..4681174 100644 --- a/Biomass_core.R +++ b/Biomass_core.R @@ -2099,6 +2099,7 @@ CohortAgeReclassification <- function(sim) { sppOuts <- sppHarmonize(sim$sppEquiv, sim$sppNameVector, P(sim)$sppEquivCol, sim$sppColorVect, P(sim)$vegLeadingProportion, sim$studyArea) + ## the following may, or may not change inputs sim$sppEquiv <- sppOuts$sppEquiv sim$sppNameVector <- sppOuts$sppNameVector From 12c4ad6e2555b3bd177d99533fd410c06fdf0550 Mon Sep 17 00:00:00 2001 From: Alex Chubaty Date: Wed, 7 Sep 2022 16:05:17 -0600 Subject: [PATCH 034/148] remove RandomFields dependency --- Biomass_core.R | 1 - 1 file changed, 1 deletion(-) diff --git a/Biomass_core.R b/Biomass_core.R index 4681174..24c503f 100644 --- a/Biomass_core.R +++ b/Biomass_core.R @@ -21,7 +21,6 @@ defineModule(sim, list( reqdPkgs = list("assertthat", "compiler", "crayon", "data.table", "dplyr", "fpCompare", "ggplot2", "grid", "parallel", "purrr", "quickPlot", "raster", "Rcpp", "R.utils", "scales", "sp", "tidyr", - "RandomFields", "PredictiveEcology/LandR@development (>= 1.0.7.9025)", "PredictiveEcology/pemisc@development", "PredictiveEcology/reproducible@development", From adf7f3b6421ad0e0dd2824d4acb094e9c2bb681f Mon Sep 17 00:00:00 2001 From: Alex Chubaty Date: Thu, 8 Sep 2022 14:23:29 -0600 Subject: [PATCH 035/148] httr::config(ssl_verify) controlled by module param --- Biomass_core.R | 22 +++++++++++++++------- 1 file changed, 15 insertions(+), 7 deletions(-) diff --git a/Biomass_core.R b/Biomass_core.R index 24c503f..8ad40f8 100644 --- a/Biomass_core.R +++ b/Biomass_core.R @@ -18,10 +18,12 @@ defineModule(sim, list( timeunit = "year", citation = list("citation.bib"), documentation = list("README.txt", "Biomass_core.Rmd"), - reqdPkgs = list("assertthat", "compiler", "crayon", "data.table", "dplyr", "fpCompare", - "ggplot2", "grid", "parallel", "purrr", "quickPlot", - "raster", "Rcpp", "R.utils", "scales", "sp", "tidyr", - "PredictiveEcology/LandR@development (>= 1.0.7.9025)", + reqdPkgs = list("assertthat", "compiler", "crayon", "data.table", "dplyr", "fpCompare", "ggplot2", "grid", + # "curl", "httr", ## called directly by this module, but pulled in by LandR (Sep 6th 2022). + ## Excluded because loading is not necessary (just installation) + "parallel", "purrr", "quickPlot", "raster", "Rcpp", + "R.utils", "scales", "sp", "tidyr", + "PredictiveEcology/LandR@development (>= 1.0.9.9000)", "PredictiveEcology/pemisc@development", "PredictiveEcology/reproducible@development", "PredictiveEcology/SpaDES.core@development (>= 1.0.8.9000)", @@ -125,6 +127,10 @@ defineModule(sim, list( defineParameter(".saveInterval", "numeric", NA, NA, NA, desc = paste("defines the saving time step.", "If `NA`, the default, .saveInterval is set to `P(sim)$successionTimestep`.")), + defineParameter(".sslVerify", "integer", unname(curl::curl_options("^ssl_verifypeer$")), NA , NA, + paste("Passed to `httr::config(ssl_verifypeer = P(sim)$sslVerify)` when downloading KNN", + "(NFI) datasets. Set to 0L if necessary to bypass checking the SSL certificate (this", + "may be necessary when NFI's website SSL certificate is not correctly configured).")), defineParameter(".studyAreaName", "character", NA, NA, NA, "Human-readable name for the study area used. If `NA`, a hash of `studyArea` will be used."), defineParameter(".useCache", "character", c(".inputObjects", "init"), NA, NA, @@ -606,7 +612,9 @@ Init <- function(sim, verbose = getOption("LandR.verbose", TRUE)) { blue("'cohortData' or 'pixelGroupMap'.\n If this is wrong, provide matching ", "'cohortData', 'pixelGroupMap' and 'biomassMap'")) ## note that to make the dummy sim$biomassMap, we need to first make a dummy rawBiomassMap - rawBiomassMap <- makeDummyRawBiomassMap(sim$rasterToMatch) + httr::with_config(config = httr::config(ssl_verifypeer = P(sim)$.sslVerify), { + rawBiomassMap <- makeDummyRawBiomassMap(sim$rasterToMatch) + }) if (suppliedElsewhere("standAgeMap", sim, where = "sim")) message(blue("'standAgeMap' was supplied, but "), @@ -2010,7 +2018,7 @@ CohortAgeReclassification <- function(sim) { "2001-attributes_attributs-2001/", "NFI_MODIS250m_2001_kNN_Structure_Biomass_TotalLiveAboveGround_v1.tif") rawBiomassMapFilename <- "NFI_MODIS250m_2001_kNN_Structure_Biomass_TotalLiveAboveGround_v1.tif" - # httr::with_config(config = httr::config(ssl_verifypeer = 0L), { ## TODO: re-enable verify + httr::with_config(config = httr::config(ssl_verifypeer = P(sim)$.sslVerify), { #necessary for KNN rawBiomassMap <- Cache(prepInputs, targetFile = rawBiomassMapFilename, @@ -2025,7 +2033,7 @@ CohortAgeReclassification <- function(sim) { filename2 = NULL, userTags = c(cacheTags, "rawBiomassMap"), omitArgs = c("destinationPath", "targetFile", "userTags", "stable")) - # }) + }) } else { rawBiomassMap <- Cache(postProcess, x = sim$rawBiomassMap, From 0fb4fae71d31b3de876eb170607eb4b1734ec56a Mon Sep 17 00:00:00 2001 From: Alex Chubaty Date: Thu, 8 Sep 2022 21:49:40 -0600 Subject: [PATCH 036/148] metadata description formatting --- Biomass_core.R | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Biomass_core.R b/Biomass_core.R index 8ad40f8..3b388d9 100644 --- a/Biomass_core.R +++ b/Biomass_core.R @@ -113,7 +113,7 @@ defineModule(sim, list( "To plotting off completely use `P(sim)$.plots`.")), defineParameter(".plotInterval", "numeric", NA, NA, NA, desc = paste("defines the plotting time step.", - "If `NA`, the default, .plotInterval is set to successionTimestep.")), + "If `NA`, the default, `.plotInterval` is set to `successionTimestep`.")), defineParameter(".plots", "character", default = "object", desc = paste("Passed to `types` in `Plots` (see `?Plots`). There are a few plots that are made within this module, if set.", "Note that plots (or their data) saving will ONLY occur at `end(sim)`.", From 31edabf2d1a4edcf48809a5300152b7165e77528 Mon Sep 17 00:00:00 2001 From: Alex Chubaty Date: Fri, 9 Sep 2022 15:23:28 -0600 Subject: [PATCH 037/148] use latest LandR pkg --- Biomass_core.R | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Biomass_core.R b/Biomass_core.R index 3b388d9..990f40e 100644 --- a/Biomass_core.R +++ b/Biomass_core.R @@ -23,7 +23,7 @@ defineModule(sim, list( ## Excluded because loading is not necessary (just installation) "parallel", "purrr", "quickPlot", "raster", "Rcpp", "R.utils", "scales", "sp", "tidyr", - "PredictiveEcology/LandR@development (>= 1.0.9.9000)", + "PredictiveEcology/LandR@development (>= 1.0.9.9002)", "PredictiveEcology/pemisc@development", "PredictiveEcology/reproducible@development", "PredictiveEcology/SpaDES.core@development (>= 1.0.8.9000)", From 3530309f9c927cace16053627a35509594a20540 Mon Sep 17 00:00:00 2001 From: CeresBarros Date: Thu, 13 Oct 2022 21:09:16 -0700 Subject: [PATCH 038/148] fix GitHub Actions wrkflow: need bookdown --- .github/workflows/render-module-rmd.yaml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/render-module-rmd.yaml b/.github/workflows/render-module-rmd.yaml index 20127f0..4192ec6 100644 --- a/.github/workflows/render-module-rmd.yaml +++ b/.github/workflows/render-module-rmd.yaml @@ -49,6 +49,7 @@ jobs: install.packages("remotes") remotes::install_cran("rmarkdown") remotes::install_cran("knitr") + remotes::install_cran("bookdown") shell: Rscript {0} - name: Install SpaDES From f72956c031d097f3dc51c856cc07ea1bffd5db8e Mon Sep 17 00:00:00 2001 From: Alex Chubaty Date: Mon, 17 Oct 2022 20:26:35 -0600 Subject: [PATCH 039/148] simplify GHA workflow to rubild Rmd --- .github/workflows/render-module-rmd.yaml | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) diff --git a/.github/workflows/render-module-rmd.yaml b/.github/workflows/render-module-rmd.yaml index 20127f0..05d4ac3 100644 --- a/.github/workflows/render-module-rmd.yaml +++ b/.github/workflows/render-module-rmd.yaml @@ -1,10 +1,12 @@ on: pull_request: branches: + - main - master - development push: branches: + - main - master - development paths: @@ -16,21 +18,23 @@ name: Render module Rmd jobs: render: + if: "!contains(github.event.commits[0].message, '[skip-ci]')" name: Render module Rmd runs-on: ubuntu-20.04 env: - RSPM: "https://packagemanager.rstudio.com/cran/__linux__/focal/latest" GITHUB_PAT: ${{ secrets.GITHUB_TOKEN }} steps: - uses: actions/checkout@v2 - - uses: r-lib/actions/setup-r@v1 + - uses: r-lib/actions/setup-pandoc@v2 + + - uses: r-lib/actions/setup-r@v2 + with: + use-public-rspm: true - - uses: r-lib/actions/setup-pandoc@v1 - - - name: Install GDAL and other dependencies + - name: Install additional system dependencies run: | sudo apt-get install -y \ libcurl4-openssl-dev \ @@ -51,9 +55,10 @@ jobs: remotes::install_cran("knitr") shell: Rscript {0} - - name: Install SpaDES + - name: Install SpaDES packages run: | install.packages("SpaDES", dependencies = TRUE) + remotes::install_github("PredictiveEcology/SpaDES.docs@development") shell: Rscript {0} - name: Install module package dependencies From ba7303a900ae65e7505c39267919ddf5e6e3bc23 Mon Sep 17 00:00:00 2001 From: Alex Chubaty Date: Mon, 17 Oct 2022 21:11:27 -0600 Subject: [PATCH 040/148] GHA: render rmd needs bookdown --- .github/workflows/render-module-rmd.yaml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/render-module-rmd.yaml b/.github/workflows/render-module-rmd.yaml index 05d4ac3..28ff2da 100644 --- a/.github/workflows/render-module-rmd.yaml +++ b/.github/workflows/render-module-rmd.yaml @@ -53,6 +53,7 @@ jobs: install.packages("remotes") remotes::install_cran("rmarkdown") remotes::install_cran("knitr") + remotes::install_cran("bookdown") shell: Rscript {0} - name: Install SpaDES packages From 59069302e5b2c1f1e509fa61558c5d5c6cf32aed Mon Sep 17 00:00:00 2001 From: Alex Chubaty Date: Tue, 18 Oct 2022 10:57:10 -0600 Subject: [PATCH 041/148] sslVerify as integer --- Biomass_core.R | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Biomass_core.R b/Biomass_core.R index 990f40e..6c9beec 100644 --- a/Biomass_core.R +++ b/Biomass_core.R @@ -127,7 +127,7 @@ defineModule(sim, list( defineParameter(".saveInterval", "numeric", NA, NA, NA, desc = paste("defines the saving time step.", "If `NA`, the default, .saveInterval is set to `P(sim)$successionTimestep`.")), - defineParameter(".sslVerify", "integer", unname(curl::curl_options("^ssl_verifypeer$")), NA , NA, + defineParameter(".sslVerify", "integer", as.integer(unname(curl::curl_options("^ssl_verifypeer$"))), NA_integer_, NA_integer_, paste("Passed to `httr::config(ssl_verifypeer = P(sim)$sslVerify)` when downloading KNN", "(NFI) datasets. Set to 0L if necessary to bypass checking the SSL certificate (this", "may be necessary when NFI's website SSL certificate is not correctly configured).")), From 7861d4353ff5d56547f0e9ca4b53f41a42d1feb0 Mon Sep 17 00:00:00 2001 From: Alex Chubaty Date: Tue, 18 Oct 2022 21:54:08 -0600 Subject: [PATCH 042/148] Update render-module-rmd.yaml need `openxlsx` package --- .github/workflows/render-module-rmd.yaml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/render-module-rmd.yaml b/.github/workflows/render-module-rmd.yaml index 28ff2da..2409bf2 100644 --- a/.github/workflows/render-module-rmd.yaml +++ b/.github/workflows/render-module-rmd.yaml @@ -54,6 +54,7 @@ jobs: remotes::install_cran("rmarkdown") remotes::install_cran("knitr") remotes::install_cran("bookdown") + remotes::install_cran("openxlsx") shell: Rscript {0} - name: Install SpaDES packages From edd5dbf340165417e7204541a4615aeeb4fb29b8 Mon Sep 17 00:00:00 2001 From: GitHub Actions Date: Wed, 19 Oct 2022 04:15:14 +0000 Subject: [PATCH 043/148] Re-build Biomass_core.Rmd --- Biomass_core.html | 7685 ++++++++++++++++++++++++++++++++------------- 1 file changed, 5502 insertions(+), 2183 deletions(-) diff --git a/Biomass_core.html b/Biomass_core.html index 95a2c03..f6a142c 100644 --- a/Biomass_core.html +++ b/Biomass_core.html @@ -13,7 +13,6 @@ LandR Biomass_core Manual - @@ -63,6 +62,7 @@ + +h1.title {font-size: 38px;} +h2 {font-size: 30px;} +h3 {font-size: 24px;} +h4 {font-size: 18px;} +h5 {font-size: 16px;} +h6 {font-size: 12px;} +code {color: inherit; background-color: rgba(0, 0, 0, 0.04);} +pre:not([class]) { background-color: white } +!function(t){"use strict";"function"==typeof define&&define.amd?define(["jquery"],t):t(jQuery)}(function(V){"use strict";V.ui=V.ui||{};V.ui.version="1.13.2";var n,i=0,a=Array.prototype.hasOwnProperty,r=Array.prototype.slice;V.cleanData=(n=V.cleanData,function(t){for(var e,i,s=0;null!=(i=t[s]);s++)(e=V._data(i,"events"))&&e.remove&&V(i).triggerHandler("remove");n(t)}),V.widget=function(t,i,e){var s,n,o,a={},r=t.split(".")[0],l=r+"-"+(t=t.split(".")[1]);return e||(e=i,i=V.Widget),Array.isArray(e)&&(e=V.extend.apply(null,[{}].concat(e))),V.expr.pseudos[l.toLowerCase()]=function(t){return!!V.data(t,l)},V[r]=V[r]||{},s=V[r][t],n=V[r][t]=function(t,e){if(!this||!this._createWidget)return new n(t,e);arguments.length&&this._createWidget(t,e)},V.extend(n,s,{version:e.version,_proto:V.extend({},e),_childConstructors:[]}),(o=new i).options=V.widget.extend({},o.options),V.each(e,function(e,s){function n(){return i.prototype[e].apply(this,arguments)}function o(t){return i.prototype[e].apply(this,t)}a[e]="function"==typeof s?function(){var t,e=this._super,i=this._superApply;return this._super=n,this._superApply=o,t=s.apply(this,arguments),this._super=e,this._superApply=i,t}:s}),n.prototype=V.widget.extend(o,{widgetEventPrefix:s&&o.widgetEventPrefix||t},a,{constructor:n,namespace:r,widgetName:t,widgetFullName:l}),s?(V.each(s._childConstructors,function(t,e){var i=e.prototype;V.widget(i.namespace+"."+i.widgetName,n,e._proto)}),delete s._childConstructors):i._childConstructors.push(n),V.widget.bridge(t,n),n},V.widget.extend=function(t){for(var e,i,s=r.call(arguments,1),n=0,o=s.length;n",options:{classes:{},disabled:!1,create:null},_createWidget:function(t,e){e=V(e||this.defaultElement||this)[0],this.element=V(e),this.uuid=i++,this.eventNamespace="."+this.widgetName+this.uuid,this.bindings=V(),this.hoverable=V(),this.focusable=V(),this.classesElementLookup={},e!==this&&(V.data(e,this.widgetFullName,this),this._on(!0,this.element,{remove:function(t){t.target===e&&this.destroy()}}),this.document=V(e.style?e.ownerDocument:e.document||e),this.window=V(this.document[0].defaultView||this.document[0].parentWindow)),this.options=V.widget.extend({},this.options,this._getCreateOptions(),t),this._create(),this.options.disabled&&this._setOptionDisabled(this.options.disabled),this._trigger("create",null,this._getCreateEventData()),this._init()},_getCreateOptions:function(){return{}},_getCreateEventData:V.noop,_create:V.noop,_init:V.noop,destroy:function(){var i=this;this._destroy(),V.each(this.classesElementLookup,function(t,e){i._removeClass(e,t)}),this.element.off(this.eventNamespace).removeData(this.widgetFullName),this.widget().off(this.eventNamespace).removeAttr("aria-disabled"),this.bindings.off(this.eventNamespace)},_destroy:V.noop,widget:function(){return this.element},option:function(t,e){var i,s,n,o=t;if(0===arguments.length)return V.widget.extend({},this.options);if("string"==typeof t)if(o={},t=(i=t.split(".")).shift(),i.length){for(s=o[t]=V.widget.extend({},this.options[t]),n=0;n
    "),i=e.children()[0];return V("body").append(e),t=i.offsetWidth,e.css("overflow","scroll"),t===(i=i.offsetWidth)&&(i=e[0].clientWidth),e.remove(),s=t-i},getScrollInfo:function(t){var e=t.isWindow||t.isDocument?"":t.element.css("overflow-x"),i=t.isWindow||t.isDocument?"":t.element.css("overflow-y"),e="scroll"===e||"auto"===e&&t.widthx(k(s),k(n))?o.important="horizontal":o.important="vertical",u.using.call(this,t,o)}),a.offset(V.extend(h,{using:t}))})},V.ui.position={fit:{left:function(t,e){var i=e.within,s=i.isWindow?i.scrollLeft:i.offset.left,n=i.width,o=t.left-e.collisionPosition.marginLeft,a=s-o,r=o+e.collisionWidth-n-s;e.collisionWidth>n?0n?0")[0],w=d.each;function P(t){return null==t?t+"":"object"==typeof t?p[e.call(t)]||"object":typeof t}function M(t,e,i){var s=v[e.type]||{};return null==t?i||!e.def?null:e.def:(t=s.floor?~~t:parseFloat(t),isNaN(t)?e.def:s.mod?(t+s.mod)%s.mod:Math.min(s.max,Math.max(0,t)))}function S(s){var n=m(),o=n._rgba=[];return s=s.toLowerCase(),w(g,function(t,e){var i=e.re.exec(s),i=i&&e.parse(i),e=e.space||"rgba";if(i)return i=n[e](i),n[_[e].cache]=i[_[e].cache],o=n._rgba=i._rgba,!1}),o.length?("0,0,0,0"===o.join()&&d.extend(o,B.transparent),n):B[s]}function H(t,e,i){return 6*(i=(i+1)%1)<1?t+(e-t)*i*6:2*i<1?e:3*i<2?t+(e-t)*(2/3-i)*6:t}y.style.cssText="background-color:rgba(1,1,1,.5)",b.rgba=-1o.mod/2?s+=o.mod:s-n>o.mod/2&&(s-=o.mod)),l[i]=M((n-s)*a+s,e)))}),this[e](l)},blend:function(t){if(1===this._rgba[3])return this;var e=this._rgba.slice(),i=e.pop(),s=m(t)._rgba;return m(d.map(e,function(t,e){return(1-i)*s[e]+i*t}))},toRgbaString:function(){var t="rgba(",e=d.map(this._rgba,function(t,e){return null!=t?t:2").addClass("ui-effects-wrapper").css({fontSize:"100%",background:"transparent",border:"none",margin:0,padding:0}),e={width:i.width(),height:i.height()},n=document.activeElement;try{n.id}catch(t){n=document.body}return i.wrap(t),i[0]!==n&&!V.contains(i[0],n)||V(n).trigger("focus"),t=i.parent(),"static"===i.css("position")?(t.css({position:"relative"}),i.css({position:"relative"})):(V.extend(s,{position:i.css("position"),zIndex:i.css("z-index")}),V.each(["top","left","bottom","right"],function(t,e){s[e]=i.css(e),isNaN(parseInt(s[e],10))&&(s[e]="auto")}),i.css({position:"relative",top:0,left:0,right:"auto",bottom:"auto"})),i.css(e),t.css(s).show()},removeWrapper:function(t){var e=document.activeElement;return t.parent().is(".ui-effects-wrapper")&&(t.parent().replaceWith(t),t[0]!==e&&!V.contains(t[0],e)||V(e).trigger("focus")),t}}),V.extend(V.effects,{version:"1.13.2",define:function(t,e,i){return i||(i=e,e="effect"),V.effects.effect[t]=i,V.effects.effect[t].mode=e,i},scaledDimensions:function(t,e,i){if(0===e)return{height:0,width:0,outerHeight:0,outerWidth:0};var s="horizontal"!==i?(e||100)/100:1,e="vertical"!==i?(e||100)/100:1;return{height:t.height()*e,width:t.width()*s,outerHeight:t.outerHeight()*e,outerWidth:t.outerWidth()*s}},clipToBox:function(t){return{width:t.clip.right-t.clip.left,height:t.clip.bottom-t.clip.top,left:t.clip.left,top:t.clip.top}},unshift:function(t,e,i){var s=t.queue();1").insertAfter(t).css({display:/^(inline|ruby)/.test(t.css("display"))?"inline-block":"block",visibility:"hidden",marginTop:t.css("marginTop"),marginBottom:t.css("marginBottom"),marginLeft:t.css("marginLeft"),marginRight:t.css("marginRight"),float:t.css("float")}).outerWidth(t.outerWidth()).outerHeight(t.outerHeight()).addClass("ui-effects-placeholder"),t.data(j+"placeholder",e)),t.css({position:i,left:s.left,top:s.top}),e},removePlaceholder:function(t){var e=j+"placeholder",i=t.data(e);i&&(i.remove(),t.removeData(e))},cleanUp:function(t){V.effects.restoreStyle(t),V.effects.removePlaceholder(t)},setTransition:function(s,t,n,o){return o=o||{},V.each(t,function(t,e){var i=s.cssUnit(e);0");l.appendTo("body").addClass(t.className).css({top:s.top-a,left:s.left-r,height:i.innerHeight(),width:i.innerWidth(),position:n?"fixed":"absolute"}).animate(o,t.duration,t.easing,function(){l.remove(),"function"==typeof e&&e()})}}),V.fx.step.clip=function(t){t.clipInit||(t.start=V(t.elem).cssClip(),"string"==typeof t.end&&(t.end=G(t.end,t.elem)),t.clipInit=!0),V(t.elem).cssClip({top:t.pos*(t.end.top-t.start.top)+t.start.top,right:t.pos*(t.end.right-t.start.right)+t.start.right,bottom:t.pos*(t.end.bottom-t.start.bottom)+t.start.bottom,left:t.pos*(t.end.left-t.start.left)+t.start.left})},Y={},V.each(["Quad","Cubic","Quart","Quint","Expo"],function(e,t){Y[t]=function(t){return Math.pow(t,e+2)}}),V.extend(Y,{Sine:function(t){return 1-Math.cos(t*Math.PI/2)},Circ:function(t){return 1-Math.sqrt(1-t*t)},Elastic:function(t){return 0===t||1===t?t:-Math.pow(2,8*(t-1))*Math.sin((80*(t-1)-7.5)*Math.PI/15)},Back:function(t){return t*t*(3*t-2)},Bounce:function(t){for(var e,i=4;t<((e=Math.pow(2,--i))-1)/11;);return 1/Math.pow(4,3-i)-7.5625*Math.pow((3*e-2)/22-t,2)}}),V.each(Y,function(t,e){V.easing["easeIn"+t]=e,V.easing["easeOut"+t]=function(t){return 1-e(1-t)},V.easing["easeInOut"+t]=function(t){return t<.5?e(2*t)/2:1-e(-2*t+2)/2}});y=V.effects,V.effects.define("blind","hide",function(t,e){var i={up:["bottom","top"],vertical:["bottom","top"],down:["top","bottom"],left:["right","left"],horizontal:["right","left"],right:["left","right"]},s=V(this),n=t.direction||"up",o=s.cssClip(),a={clip:V.extend({},o)},r=V.effects.createPlaceholder(s);a.clip[i[n][0]]=a.clip[i[n][1]],"show"===t.mode&&(s.cssClip(a.clip),r&&r.css(V.effects.clipToBox(a)),a.clip=o),r&&r.animate(V.effects.clipToBox(a),t.duration,t.easing),s.animate(a,{queue:!1,duration:t.duration,easing:t.easing,complete:e})}),V.effects.define("bounce",function(t,e){var i,s,n=V(this),o=t.mode,a="hide"===o,r="show"===o,l=t.direction||"up",h=t.distance,c=t.times||5,o=2*c+(r||a?1:0),u=t.duration/o,d=t.easing,p="up"===l||"down"===l?"top":"left",f="up"===l||"left"===l,g=0,t=n.queue().length;for(V.effects.createPlaceholder(n),l=n.css(p),h=h||n["top"==p?"outerHeight":"outerWidth"]()/3,r&&((s={opacity:1})[p]=l,n.css("opacity",0).css(p,f?2*-h:2*h).animate(s,u,d)),a&&(h/=Math.pow(2,c-1)),(s={})[p]=l;g").css({position:"absolute",visibility:"visible",left:-s*p,top:-i*f}).parent().addClass("ui-effects-explode").css({position:"absolute",overflow:"hidden",width:p,height:f,left:n+(u?a*p:0),top:o+(u?r*f:0),opacity:u?0:1}).animate({left:n+(u?0:a*p),top:o+(u?0:r*f),opacity:u?1:0},t.duration||500,t.easing,m)}),V.effects.define("fade","toggle",function(t,e){var i="show"===t.mode;V(this).css("opacity",i?0:1).animate({opacity:i?1:0},{queue:!1,duration:t.duration,easing:t.easing,complete:e})}),V.effects.define("fold","hide",function(e,t){var i=V(this),s=e.mode,n="show"===s,o="hide"===s,a=e.size||15,r=/([0-9]+)%/.exec(a),l=!!e.horizFirst?["right","bottom"]:["bottom","right"],h=e.duration/2,c=V.effects.createPlaceholder(i),u=i.cssClip(),d={clip:V.extend({},u)},p={clip:V.extend({},u)},f=[u[l[0]],u[l[1]]],s=i.queue().length;r&&(a=parseInt(r[1],10)/100*f[o?0:1]),d.clip[l[0]]=a,p.clip[l[0]]=a,p.clip[l[1]]=0,n&&(i.cssClip(p.clip),c&&c.css(V.effects.clipToBox(p)),p.clip=u),i.queue(function(t){c&&c.animate(V.effects.clipToBox(d),h,e.easing).animate(V.effects.clipToBox(p),h,e.easing),t()}).animate(d,h,e.easing).animate(p,h,e.easing).queue(t),V.effects.unshift(i,s,4)}),V.effects.define("highlight","show",function(t,e){var i=V(this),s={backgroundColor:i.css("backgroundColor")};"hide"===t.mode&&(s.opacity=0),V.effects.saveStyle(i),i.css({backgroundImage:"none",backgroundColor:t.color||"#ffff99"}).animate(s,{queue:!1,duration:t.duration,easing:t.easing,complete:e})}),V.effects.define("size",function(s,e){var n,i=V(this),t=["fontSize"],o=["borderTopWidth","borderBottomWidth","paddingTop","paddingBottom"],a=["borderLeftWidth","borderRightWidth","paddingLeft","paddingRight"],r=s.mode,l="effect"!==r,h=s.scale||"both",c=s.origin||["middle","center"],u=i.css("position"),d=i.position(),p=V.effects.scaledDimensions(i),f=s.from||p,g=s.to||V.effects.scaledDimensions(i,0);V.effects.createPlaceholder(i),"show"===r&&(r=f,f=g,g=r),n={from:{y:f.height/p.height,x:f.width/p.width},to:{y:g.height/p.height,x:g.width/p.width}},"box"!==h&&"both"!==h||(n.from.y!==n.to.y&&(f=V.effects.setTransition(i,o,n.from.y,f),g=V.effects.setTransition(i,o,n.to.y,g)),n.from.x!==n.to.x&&(f=V.effects.setTransition(i,a,n.from.x,f),g=V.effects.setTransition(i,a,n.to.x,g))),"content"!==h&&"both"!==h||n.from.y!==n.to.y&&(f=V.effects.setTransition(i,t,n.from.y,f),g=V.effects.setTransition(i,t,n.to.y,g)),c&&(c=V.effects.getBaseline(c,p),f.top=(p.outerHeight-f.outerHeight)*c.y+d.top,f.left=(p.outerWidth-f.outerWidth)*c.x+d.left,g.top=(p.outerHeight-g.outerHeight)*c.y+d.top,g.left=(p.outerWidth-g.outerWidth)*c.x+d.left),delete f.outerHeight,delete f.outerWidth,i.css(f),"content"!==h&&"both"!==h||(o=o.concat(["marginTop","marginBottom"]).concat(t),a=a.concat(["marginLeft","marginRight"]),i.find("*[width]").each(function(){var t=V(this),e=V.effects.scaledDimensions(t),i={height:e.height*n.from.y,width:e.width*n.from.x,outerHeight:e.outerHeight*n.from.y,outerWidth:e.outerWidth*n.from.x},e={height:e.height*n.to.y,width:e.width*n.to.x,outerHeight:e.height*n.to.y,outerWidth:e.width*n.to.x};n.from.y!==n.to.y&&(i=V.effects.setTransition(t,o,n.from.y,i),e=V.effects.setTransition(t,o,n.to.y,e)),n.from.x!==n.to.x&&(i=V.effects.setTransition(t,a,n.from.x,i),e=V.effects.setTransition(t,a,n.to.x,e)),l&&V.effects.saveStyle(t),t.css(i),t.animate(e,s.duration,s.easing,function(){l&&V.effects.restoreStyle(t)})})),i.animate(g,{queue:!1,duration:s.duration,easing:s.easing,complete:function(){var t=i.offset();0===g.opacity&&i.css("opacity",f.opacity),l||(i.css("position","static"===u?"relative":u).offset(t),V.effects.saveStyle(i)),e()}})}),V.effects.define("scale",function(t,e){var i=V(this),s=t.mode,s=parseInt(t.percent,10)||(0===parseInt(t.percent,10)||"effect"!==s?0:100),s=V.extend(!0,{from:V.effects.scaledDimensions(i),to:V.effects.scaledDimensions(i,s,t.direction||"both"),origin:t.origin||["middle","center"]},t);t.fade&&(s.from.opacity=1,s.to.opacity=0),V.effects.effect.size.call(this,s,e)}),V.effects.define("puff","hide",function(t,e){t=V.extend(!0,{},t,{fade:!0,percent:parseInt(t.percent,10)||150});V.effects.effect.scale.call(this,t,e)}),V.effects.define("pulsate","show",function(t,e){var i=V(this),s=t.mode,n="show"===s,o=2*(t.times||5)+(n||"hide"===s?1:0),a=t.duration/o,r=0,l=1,s=i.queue().length;for(!n&&i.is(":visible")||(i.css("opacity",0).show(),r=1);l li > :first-child").add(t.find("> :not(li)").even())},heightStyle:"auto",icons:{activeHeader:"ui-icon-triangle-1-s",header:"ui-icon-triangle-1-e"},activate:null,beforeActivate:null},hideProps:{borderTopWidth:"hide",borderBottomWidth:"hide",paddingTop:"hide",paddingBottom:"hide",height:"hide"},showProps:{borderTopWidth:"show",borderBottomWidth:"show",paddingTop:"show",paddingBottom:"show",height:"show"},_create:function(){var t=this.options;this.prevShow=this.prevHide=V(),this._addClass("ui-accordion","ui-widget ui-helper-reset"),this.element.attr("role","tablist"),t.collapsible||!1!==t.active&&null!=t.active||(t.active=0),this._processPanels(),t.active<0&&(t.active+=this.headers.length),this._refresh()},_getCreateEventData:function(){return{header:this.active,panel:this.active.length?this.active.next():V()}},_createIcons:function(){var t,e=this.options.icons;e&&(t=V(""),this._addClass(t,"ui-accordion-header-icon","ui-icon "+e.header),t.prependTo(this.headers),t=this.active.children(".ui-accordion-header-icon"),this._removeClass(t,e.header)._addClass(t,null,e.activeHeader)._addClass(this.headers,"ui-accordion-icons"))},_destroyIcons:function(){this._removeClass(this.headers,"ui-accordion-icons"),this.headers.children(".ui-accordion-header-icon").remove()},_destroy:function(){var t;this.element.removeAttr("role"),this.headers.removeAttr("role aria-expanded aria-selected aria-controls tabIndex").removeUniqueId(),this._destroyIcons(),t=this.headers.next().css("display","").removeAttr("role aria-hidden aria-labelledby").removeUniqueId(),"content"!==this.options.heightStyle&&t.css("height","")},_setOption:function(t,e){"active"!==t?("event"===t&&(this.options.event&&this._off(this.headers,this.options.event),this._setupEvents(e)),this._super(t,e),"collapsible"!==t||e||!1!==this.options.active||this._activate(0),"icons"===t&&(this._destroyIcons(),e&&this._createIcons())):this._activate(e)},_setOptionDisabled:function(t){this._super(t),this.element.attr("aria-disabled",t),this._toggleClass(null,"ui-state-disabled",!!t),this._toggleClass(this.headers.add(this.headers.next()),null,"ui-state-disabled",!!t)},_keydown:function(t){if(!t.altKey&&!t.ctrlKey){var e=V.ui.keyCode,i=this.headers.length,s=this.headers.index(t.target),n=!1;switch(t.keyCode){case e.RIGHT:case e.DOWN:n=this.headers[(s+1)%i];break;case e.LEFT:case e.UP:n=this.headers[(s-1+i)%i];break;case e.SPACE:case e.ENTER:this._eventHandler(t);break;case e.HOME:n=this.headers[0];break;case e.END:n=this.headers[i-1]}n&&(V(t.target).attr("tabIndex",-1),V(n).attr("tabIndex",0),V(n).trigger("focus"),t.preventDefault())}},_panelKeyDown:function(t){t.keyCode===V.ui.keyCode.UP&&t.ctrlKey&&V(t.currentTarget).prev().trigger("focus")},refresh:function(){var t=this.options;this._processPanels(),!1===t.active&&!0===t.collapsible||!this.headers.length?(t.active=!1,this.active=V()):!1===t.active?this._activate(0):this.active.length&&!V.contains(this.element[0],this.active[0])?this.headers.length===this.headers.find(".ui-state-disabled").length?(t.active=!1,this.active=V()):this._activate(Math.max(0,t.active-1)):t.active=this.headers.index(this.active),this._destroyIcons(),this._refresh()},_processPanels:function(){var t=this.headers,e=this.panels;"function"==typeof this.options.header?this.headers=this.options.header(this.element):this.headers=this.element.find(this.options.header),this._addClass(this.headers,"ui-accordion-header ui-accordion-header-collapsed","ui-state-default"),this.panels=this.headers.next().filter(":not(.ui-accordion-content-active)").hide(),this._addClass(this.panels,"ui-accordion-content","ui-helper-reset ui-widget-content"),e&&(this._off(t.not(this.headers)),this._off(e.not(this.panels)))},_refresh:function(){var i,t=this.options,e=t.heightStyle,s=this.element.parent();this.active=this._findActive(t.active),this._addClass(this.active,"ui-accordion-header-active","ui-state-active")._removeClass(this.active,"ui-accordion-header-collapsed"),this._addClass(this.active.next(),"ui-accordion-content-active"),this.active.next().show(),this.headers.attr("role","tab").each(function(){var t=V(this),e=t.uniqueId().attr("id"),i=t.next(),s=i.uniqueId().attr("id");t.attr("aria-controls",s),i.attr("aria-labelledby",e)}).next().attr("role","tabpanel"),this.headers.not(this.active).attr({"aria-selected":"false","aria-expanded":"false",tabIndex:-1}).next().attr({"aria-hidden":"true"}).hide(),this.active.length?this.active.attr({"aria-selected":"true","aria-expanded":"true",tabIndex:0}).next().attr({"aria-hidden":"false"}):this.headers.eq(0).attr("tabIndex",0),this._createIcons(),this._setupEvents(t.event),"fill"===e?(i=s.height(),this.element.siblings(":visible").each(function(){var t=V(this),e=t.css("position");"absolute"!==e&&"fixed"!==e&&(i-=t.outerHeight(!0))}),this.headers.each(function(){i-=V(this).outerHeight(!0)}),this.headers.next().each(function(){V(this).height(Math.max(0,i-V(this).innerHeight()+V(this).height()))}).css("overflow","auto")):"auto"===e&&(i=0,this.headers.next().each(function(){var t=V(this).is(":visible");t||V(this).show(),i=Math.max(i,V(this).css("height","").height()),t||V(this).hide()}).height(i))},_activate:function(t){t=this._findActive(t)[0];t!==this.active[0]&&(t=t||this.active[0],this._eventHandler({target:t,currentTarget:t,preventDefault:V.noop}))},_findActive:function(t){return"number"==typeof t?this.headers.eq(t):V()},_setupEvents:function(t){var i={keydown:"_keydown"};t&&V.each(t.split(" "),function(t,e){i[e]="_eventHandler"}),this._off(this.headers.add(this.headers.next())),this._on(this.headers,i),this._on(this.headers.next(),{keydown:"_panelKeyDown"}),this._hoverable(this.headers),this._focusable(this.headers)},_eventHandler:function(t){var e=this.options,i=this.active,s=V(t.currentTarget),n=s[0]===i[0],o=n&&e.collapsible,a=o?V():s.next(),r=i.next(),a={oldHeader:i,oldPanel:r,newHeader:o?V():s,newPanel:a};t.preventDefault(),n&&!e.collapsible||!1===this._trigger("beforeActivate",t,a)||(e.active=!o&&this.headers.index(s),this.active=n?V():s,this._toggle(a),this._removeClass(i,"ui-accordion-header-active","ui-state-active"),e.icons&&(i=i.children(".ui-accordion-header-icon"),this._removeClass(i,null,e.icons.activeHeader)._addClass(i,null,e.icons.header)),n||(this._removeClass(s,"ui-accordion-header-collapsed")._addClass(s,"ui-accordion-header-active","ui-state-active"),e.icons&&(n=s.children(".ui-accordion-header-icon"),this._removeClass(n,null,e.icons.header)._addClass(n,null,e.icons.activeHeader)),this._addClass(s.next(),"ui-accordion-content-active")))},_toggle:function(t){var e=t.newPanel,i=this.prevShow.length?this.prevShow:t.oldPanel;this.prevShow.add(this.prevHide).stop(!0,!0),this.prevShow=e,this.prevHide=i,this.options.animate?this._animate(e,i,t):(i.hide(),e.show(),this._toggleComplete(t)),i.attr({"aria-hidden":"true"}),i.prev().attr({"aria-selected":"false","aria-expanded":"false"}),e.length&&i.length?i.prev().attr({tabIndex:-1,"aria-expanded":"false"}):e.length&&this.headers.filter(function(){return 0===parseInt(V(this).attr("tabIndex"),10)}).attr("tabIndex",-1),e.attr("aria-hidden","false").prev().attr({"aria-selected":"true","aria-expanded":"true",tabIndex:0})},_animate:function(t,i,e){var s,n,o,a=this,r=0,l=t.css("box-sizing"),h=t.length&&(!i.length||t.index()",delay:300,options:{icons:{submenu:"ui-icon-caret-1-e"},items:"> *",menus:"ul",position:{my:"left top",at:"right top"},role:"menu",blur:null,focus:null,select:null},_create:function(){this.activeMenu=this.element,this.mouseHandled=!1,this.lastMousePosition={x:null,y:null},this.element.uniqueId().attr({role:this.options.role,tabIndex:0}),this._addClass("ui-menu","ui-widget ui-widget-content"),this._on({"mousedown .ui-menu-item":function(t){t.preventDefault(),this._activateItem(t)},"click .ui-menu-item":function(t){var e=V(t.target),i=V(V.ui.safeActiveElement(this.document[0]));!this.mouseHandled&&e.not(".ui-state-disabled").length&&(this.select(t),t.isPropagationStopped()||(this.mouseHandled=!0),e.has(".ui-menu").length?this.expand(t):!this.element.is(":focus")&&i.closest(".ui-menu").length&&(this.element.trigger("focus",[!0]),this.active&&1===this.active.parents(".ui-menu").length&&clearTimeout(this.timer)))},"mouseenter .ui-menu-item":"_activateItem","mousemove .ui-menu-item":"_activateItem",mouseleave:"collapseAll","mouseleave .ui-menu":"collapseAll",focus:function(t,e){var i=this.active||this._menuItems().first();e||this.focus(t,i)},blur:function(t){this._delay(function(){V.contains(this.element[0],V.ui.safeActiveElement(this.document[0]))||this.collapseAll(t)})},keydown:"_keydown"}),this.refresh(),this._on(this.document,{click:function(t){this._closeOnDocumentClick(t)&&this.collapseAll(t,!0),this.mouseHandled=!1}})},_activateItem:function(t){var e,i;this.previousFilter||t.clientX===this.lastMousePosition.x&&t.clientY===this.lastMousePosition.y||(this.lastMousePosition={x:t.clientX,y:t.clientY},e=V(t.target).closest(".ui-menu-item"),i=V(t.currentTarget),e[0]===i[0]&&(i.is(".ui-state-active")||(this._removeClass(i.siblings().children(".ui-state-active"),null,"ui-state-active"),this.focus(t,i))))},_destroy:function(){var t=this.element.find(".ui-menu-item").removeAttr("role aria-disabled").children(".ui-menu-item-wrapper").removeUniqueId().removeAttr("tabIndex role aria-haspopup");this.element.removeAttr("aria-activedescendant").find(".ui-menu").addBack().removeAttr("role aria-labelledby aria-expanded aria-hidden aria-disabled tabIndex").removeUniqueId().show(),t.children().each(function(){var t=V(this);t.data("ui-menu-submenu-caret")&&t.remove()})},_keydown:function(t){var e,i,s,n=!0;switch(t.keyCode){case V.ui.keyCode.PAGE_UP:this.previousPage(t);break;case V.ui.keyCode.PAGE_DOWN:this.nextPage(t);break;case V.ui.keyCode.HOME:this._move("first","first",t);break;case V.ui.keyCode.END:this._move("last","last",t);break;case V.ui.keyCode.UP:this.previous(t);break;case V.ui.keyCode.DOWN:this.next(t);break;case V.ui.keyCode.LEFT:this.collapse(t);break;case V.ui.keyCode.RIGHT:this.active&&!this.active.is(".ui-state-disabled")&&this.expand(t);break;case V.ui.keyCode.ENTER:case V.ui.keyCode.SPACE:this._activate(t);break;case V.ui.keyCode.ESCAPE:this.collapse(t);break;default:e=this.previousFilter||"",s=n=!1,i=96<=t.keyCode&&t.keyCode<=105?(t.keyCode-96).toString():String.fromCharCode(t.keyCode),clearTimeout(this.filterTimer),i===e?s=!0:i=e+i,e=this._filterMenuItems(i),(e=s&&-1!==e.index(this.active.next())?this.active.nextAll(".ui-menu-item"):e).length||(i=String.fromCharCode(t.keyCode),e=this._filterMenuItems(i)),e.length?(this.focus(t,e),this.previousFilter=i,this.filterTimer=this._delay(function(){delete this.previousFilter},1e3)):delete this.previousFilter}n&&t.preventDefault()},_activate:function(t){this.active&&!this.active.is(".ui-state-disabled")&&(this.active.children("[aria-haspopup='true']").length?this.expand(t):this.select(t))},refresh:function(){var t,e,s=this,n=this.options.icons.submenu,i=this.element.find(this.options.menus);this._toggleClass("ui-menu-icons",null,!!this.element.find(".ui-icon").length),e=i.filter(":not(.ui-menu)").hide().attr({role:this.options.role,"aria-hidden":"true","aria-expanded":"false"}).each(function(){var t=V(this),e=t.prev(),i=V("").data("ui-menu-submenu-caret",!0);s._addClass(i,"ui-menu-icon","ui-icon "+n),e.attr("aria-haspopup","true").prepend(i),t.attr("aria-labelledby",e.attr("id"))}),this._addClass(e,"ui-menu","ui-widget ui-widget-content ui-front"),(t=i.add(this.element).find(this.options.items)).not(".ui-menu-item").each(function(){var t=V(this);s._isDivider(t)&&s._addClass(t,"ui-menu-divider","ui-widget-content")}),i=(e=t.not(".ui-menu-item, .ui-menu-divider")).children().not(".ui-menu").uniqueId().attr({tabIndex:-1,role:this._itemRole()}),this._addClass(e,"ui-menu-item")._addClass(i,"ui-menu-item-wrapper"),t.filter(".ui-state-disabled").attr("aria-disabled","true"),this.active&&!V.contains(this.element[0],this.active[0])&&this.blur()},_itemRole:function(){return{menu:"menuitem",listbox:"option"}[this.options.role]},_setOption:function(t,e){var i;"icons"===t&&(i=this.element.find(".ui-menu-icon"),this._removeClass(i,null,this.options.icons.submenu)._addClass(i,null,e.submenu)),this._super(t,e)},_setOptionDisabled:function(t){this._super(t),this.element.attr("aria-disabled",String(t)),this._toggleClass(null,"ui-state-disabled",!!t)},focus:function(t,e){var i;this.blur(t,t&&"focus"===t.type),this._scrollIntoView(e),this.active=e.first(),i=this.active.children(".ui-menu-item-wrapper"),this._addClass(i,null,"ui-state-active"),this.options.role&&this.element.attr("aria-activedescendant",i.attr("id")),i=this.active.parent().closest(".ui-menu-item").children(".ui-menu-item-wrapper"),this._addClass(i,null,"ui-state-active"),t&&"keydown"===t.type?this._close():this.timer=this._delay(function(){this._close()},this.delay),(i=e.children(".ui-menu")).length&&t&&/^mouse/.test(t.type)&&this._startOpening(i),this.activeMenu=e.parent(),this._trigger("focus",t,{item:e})},_scrollIntoView:function(t){var e,i,s;this._hasScroll()&&(i=parseFloat(V.css(this.activeMenu[0],"borderTopWidth"))||0,s=parseFloat(V.css(this.activeMenu[0],"paddingTop"))||0,e=t.offset().top-this.activeMenu.offset().top-i-s,i=this.activeMenu.scrollTop(),s=this.activeMenu.height(),t=t.outerHeight(),e<0?this.activeMenu.scrollTop(i+e):s",options:{appendTo:null,autoFocus:!1,delay:300,minLength:1,position:{my:"left top",at:"left bottom",collision:"none"},source:null,change:null,close:null,focus:null,open:null,response:null,search:null,select:null},requestIndex:0,pending:0,liveRegionTimer:null,_create:function(){var i,s,n,t=this.element[0].nodeName.toLowerCase(),e="textarea"===t,t="input"===t;this.isMultiLine=e||!t&&this._isContentEditable(this.element),this.valueMethod=this.element[e||t?"val":"text"],this.isNewMenu=!0,this._addClass("ui-autocomplete-input"),this.element.attr("autocomplete","off"),this._on(this.element,{keydown:function(t){if(this.element.prop("readOnly"))s=n=i=!0;else{s=n=i=!1;var e=V.ui.keyCode;switch(t.keyCode){case e.PAGE_UP:i=!0,this._move("previousPage",t);break;case e.PAGE_DOWN:i=!0,this._move("nextPage",t);break;case e.UP:i=!0,this._keyEvent("previous",t);break;case e.DOWN:i=!0,this._keyEvent("next",t);break;case e.ENTER:this.menu.active&&(i=!0,t.preventDefault(),this.menu.select(t));break;case e.TAB:this.menu.active&&this.menu.select(t);break;case e.ESCAPE:this.menu.element.is(":visible")&&(this.isMultiLine||this._value(this.term),this.close(t),t.preventDefault());break;default:s=!0,this._searchTimeout(t)}}},keypress:function(t){if(i)return i=!1,void(this.isMultiLine&&!this.menu.element.is(":visible")||t.preventDefault());if(!s){var e=V.ui.keyCode;switch(t.keyCode){case e.PAGE_UP:this._move("previousPage",t);break;case e.PAGE_DOWN:this._move("nextPage",t);break;case e.UP:this._keyEvent("previous",t);break;case e.DOWN:this._keyEvent("next",t)}}},input:function(t){if(n)return n=!1,void t.preventDefault();this._searchTimeout(t)},focus:function(){this.selectedItem=null,this.previous=this._value()},blur:function(t){clearTimeout(this.searching),this.close(t),this._change(t)}}),this._initSource(),this.menu=V("