Skip to content

5. Castor Modules, Functions and Parameters

Muhly edited this page Jul 18, 2023 · 1 revision

Castor Modules, Functions and Parameters

Previously we reviewed conceptually how Castor modules work together to compile data for an analysis and to run a simulation scenario. We also provided a directory for the program code contained within the Castor GitHub. There we outlined that the key folders for running the Castor model are SpaDES-modules, Params and functions. Here we provide a more detailed description of the modules, parameters and functions needed to run the Castor model.

Castor SpaDES Modules

Castor uses the SpaDES R package to structure the simulation model. Each SpaDES module contains the code to run a distinct component of the Castor model. The SpaDES-modules folder contains the bulk of the scripts that run the Castor model functions. SpaDES-modules include:

Each folder within the directory contains a .R and .Rmd file. The .R file contains the functions that process, analyze, summarize and output the data, whereas the .Rmd file is where you set and describe in text the model parameters and 'run' the model, i.e., by running the code chunk in the .Rmd file, you run the program functions in the .R file. Detailed information on the modules are provided in .Rmd files within each module folder, and these modules are described in more detail below.

As described previously there are essentially two modules that run the bulk of the Castor model functions and processes, i.e., dataLoaderCastor and forestryCastor. These modules can connect to other modules to run customized functions within them, as needed. The dataLoaderCastor module creates a SQLite database of the data needed to run a forest harvest simulation. Thus, you need to run the dataLoaderCastor.Rmd for each unique area where you want to run simulations. The forestryCastormodule essentially runs the forest harvest functions and tracks the various forest indicators of interest, throughout the simulation.

Below is a description of each module, what parameters you need to set for each module, and how the module is connected to other modules (particularly the dataLoaderCastorand forestryCastormodules).

dataLoaderCastor

The dataLoaderCastor module compiles data on forest inventory and stand yields, the timber harvest land base, forest or other (e.g., caribou habitat) indicators, and defines management zones and their constraints for the area of interest. The area of interest could be any portion of British Columbia, but is typically a forest management unit, like a timber supply area or tree farm license area. The dataLoaderCastor module takes data from a network PostgreSQL database and compiles it into a SQLite database for the area of interest.

To run the dataLoaderCastor module, you will need to have created the following spatial data sets within the PostgreSQL database that you will be connecting to (parameter names as they are named in the dataLoaderCastor module are indicated in parentheses):

  • the analysis area boundary spatial file, e.g., timber supply areas (nameBoundaryFile)
  • the column/field in the analysis area boundary file that contains the names of each unique area of interest (nameBoundaryColumn)
  • the name of the area of interest, as defined in the column (nameBoundary)
  • the geometry type in the analysis area boundary file (nameBoundaryGeom)
  • the rasterized version of the analysis area boundaries (nameCompartmentRaster)
  • the value attribute table (VAT) that links the integer values in the analysis area raster to the name of the area of interest (nameCompartmentTable)
  • the raster of the timber harvest land base (nameMaskHarvestLandbaseRaster)
  • the rasters of each zone where a forest harvest constraint will be applied, including all zones in the 'business-as-usual' or alternative forest management scenarios (nameZoneRasters)
  • the table where the constraints for each raster zone are defined (nameZoneTable)
  • a raster with a unique integer id for each unique 'natural' forest stand yield curve, i.e., Variable Density Yield Projection (VDYP) curves, corresponding to the raster pixel where that curve applies (nameYieldsRaster)
  • the VDYP yield table, which can be linked to each stand by the unique integer id (nameYieldTable)
  • a raster with a unique integer id for each unique 'managed' forest stand yield curve, i.e., Table Interpolation Program for Stand Yields (TIPSY) curves, which can be linked to each stand by the unique id (nameYieldsTransitionRaster)
  • the TIPSY table, which can be linked to each stand by the unique integer id (nameYieldTransitionTable)
  • the forest inventory raster, with a unique integer id for each forest stand in the inventory (nameForestInventoryRaster)
  • the inventory data table (nameForestInventoryTable)
  • the column/field in the the forest inventory data that defines each unique forest stand (nameForestInventoryKey), that can be linked to the raster integer id
  • the column/field in the the forest inventory data that defines the age of each unique forest stand (nameForestInventoryAge)
  • the column/field in the the forest inventory data that defines the height of each unique forest stand (nameForestInventoryHeight)
  • the column/field in the the forest inventory data that defines the crown closure of each unique forest stand (nameForestInventoryCrownClosure)
  • the column/field in the the forest inventory data that defines which areas are forested (nameForestInventoryTreed)
  • the column/field in the the forest inventory data that defines the site index of each unique forest stand (nameForestInventorySiteIndex)
  • the name of the raster where you want to apply a harvest priority scheme at a zone level of the spatial hierarchy (nameZonePriorityRaster); for example, this could be used to define the priority for harvesting of landscape units (or some other defined area) in a TSA; note that currently the raster must have an integer value for each pixel in the area of interest (pixels with NA values will not be harvested in a simulation using forestryCastor)

At a minimum, the SQLite database that is created by the dataLoaderCastor module includes four tables, called "pixels", "yields", "zone" and "zoneConstraints". The "pixels" table includes (but is not limited) to columns describing the unique integer for each pixel in the area of interest (pixelid), each yield curve id (yieldid and yieldid_trans), THLB (thlb), stand age (age), volume (vol), height (height), crown closure (crownclosure), site index (siteindex), and percent deciduous (dec_pcnt) assigned to that pixel, and columns for each relevant zonal constraint (e.g., zone1, zone2, zone3....) that identifies which forest harvest constraint zones or harvest priority areas that the pixel occurs within. The "yields" table includes the volume (tvol) and height of each unique yield curve (yieldid) at each age. The "zone" table contains the identifier for each zone (e.g., zone1, zone2, zone3....) that's been included in the "pixels" table, and the unique zone constraint identifier in the raster (reference_zone). The "zoneConstraints" table also contains the zone identifier for each zone that has a constraint applied, and the related information on the constraint in each zone (e.g., type and threshold).

The dataLoaderCastor can be used with other modules. In this case, these modules need to be listed in the 'modules' list in the .Rmd code chunk. The dataLoaderCastor can be used with the blockingCastor, roadCastor, survivalCastor, disturbanceCalcCastor and rsfCastor modules to create additional information and data for tracking caribou indicators, and to model forest harvest blocks and roads.

The 'objects' list should include any additional objects in the code chunk that are required by a module. In the dataLoaderCastor this includes the "scenario" and for blockingCastorthis includes 'patchSizeDist'. The "scenario" object identifies the name and description of the scenario. Since you aren't running a scenario during the initial run of dataLoaderCastor, it's not critical to set this parameter, but you can set it to be consistent with the forestryCastor module. Also, within the dataLoaderCastor module you set the patchSizeDist parameter, which establishes the size of blocks and the frequency of each block size by each natural disturbance type (ndt). These are currently determined based on the provincial biodiversity guidebook.

blockingCastor

The blockingCastor module provides the option to pre-define cutblocks for harvest, by Castortering or grouping similar forested pixels together into contiguous, unique blocks. When setting the blockMethod to "pre", it takes data on crown closure and height in each pixel and calculates distance statistics between neighbouring pixels, then groups neighbouring pixels together where they are below a specified distance threshold, as defined by the "patchVariation" parameter (i.e., neighbouring pixels with similar characteristics will have relatively small distance metrics and get grouped into 'blocks'). Thus, the module is used to identify spatial cutblock boundaries, assuming a forestry company is likely to cut stands with relatively uniform characteristics.

To use the blockingCastor module, include the module in the module list stated in the dataLoaderCastor and set the parameters for blockMethod (set this to 'pre' to define the blocks as part of the dataLoaderCastor process), patchZone (we use landscape units but any zonal raster can be applied), patchVariation (we recommend setting to 6 - which roughly corresponds to a significance level of 0.05 for differences between neighbouring pixels), nameCutblockRaster (the name of the raster that defines existing cutblocks; we use rast.cns_cut_bl, as stored in our PostgreSQL database) and useLandingsArea (set to FALSE - when not using Castor as back-casting tool). You will also need to set the patchSizeDist targets as an object in dataLoaderCastor . We provide the distribution targets for natural disturbance types (NDTs) as a 'default' value. The blockingCastor module adds a blockid column to the "pixels" table to identify each unique block.

If you do not wish to pre-define cutblocks, and want harvest to occur randomly, set the blockMethod parameter to "dynamic". This harvests pixels based on a random probability of 'spreading' from one pixel to a neighbouring pixel (not yet tested).

roadCastor

The roadCastor module can be used to simulate historic and future roads in the area of interest using a number of simulation options: 'pre', 'snap', 'lcp' and 'mst', which each use different assumptions about how roads should be connected (see the roads report for more details).

To simulate future roads, roadCastor can be used within the dataLoaderCastor module and paired with the blockingCastor module to pre-solve the road network using the 'pre' method. The 'pre' method creates roads from the existing road network to each potential cutblock landing in the area of interest (identified using blockingCastor) following a least cost pathway. Within the forestryCastor module, future roads can then either be simulated using the 'pre' option, which will create roads using the pre-solved road network from dataLoaderCastor, or by simulating new roads in real-time using the 'snap', 'lcp' or 'mst' methods.

We currently recommend using the 'pre' method within dataLoaderCastor to have the pre-solved road network available for simulations. However, when running the simulation with forestryCastor we recommend using the "mst" method (unless computer processing speed is a concern, in which case, use the 'pre' method), as it accounts for the least-cost pathway and other nearby landings when simulating roads, and thus simulates the most efficient and realistic road network of all the methods.

To use the roadCastor module, set the roadMethod ('pre', 'snap', 'lcp' or 'mst'), nameCostSurfaceRas (the cost surface raster; called rast.rd_cost_surface in our PostgreSQL database) and nameRoads (the raster of the existing road network; called rast.crds_resource in our PostgreSQL database).

The roadCastor module adds a "roadyear" column to the "pixels" table, which gets updated with the time interval in the Castor model that a road gets built. When using the "pre" method it also adds a "roadslist" table to the SQLite database that contains the landing that each potential road is attributed to and a character list of the pixel ID's that need to be converted into a road to reach the landing. Thus, if the landing gets selected for harvest when using the 'pre' method in forestryCastor, the associated pixels get converted to a road.

You can also pair the roadCastor module with the cutblockSeqPrepCastor module within dataLoaderCastor to estimate the historical development of forestry roads in an area of interest (see details under the cutblockSeqPrepCastor heading below).

survivalCastor

The survivalCastor module is used to estimate adult female caribou survival rate in a caribou herd as a function of the amount of forest less than 40 years old in the herd range, using a model developed by Wittmer et al. (2005). Thus, it can be used to assess how forest harvest activities in a caribou herd range might influence survival of caribou there, where higher proportions of early seral forest results in lower survival rates.

For the purpose of using this module with dataLoaderCastor or forestryCastor, the important parameters to set are the raster (nameRasCaribouHerd) and table (tableCaribouHerd) that define the caribou herd boundaries of interest where survival will be estimated. Defining these in the dataLoaderCastor adds a column to the pixels table called 'herd_bounds'.

grizzlysurvivalCastor

The grizzlysurvivalCastor module is used to estimate adult female grizzly bear survival rate in a grizzly bear population unit (GBPU) as a function of the density of roads. Adult female grizzly bear survival rate is estimated by adapting a model developed by Boulanger and Stenhouse (2014) that related grizzly bear survival rates to their exposure to roads in a landscape in Alberta with active forestry. Thus, it can be used to assess how forestry road development in a GBPU might influence survival, and thus population trajectories of grizzly bear.

For the purpose of using this module with dataLoaderCastor or forestryCastor, the important parameters to set are the raster (rasterGBPU) and associated look-up table (tableGBPU) that define the GBPUs where survival will be estimated. Defining these in the dataLoaderCastor adds a column to the pixels table called 'gbpu_name'.

smcaribouAbundanceCastor

The smcaribouAbundanceCastor module is used to estimate the abundance of caribou subpopulations in the southern group of southern mountain caribou. It estimates abundance as a function of the percentage of forested area in each caribou subpopulations critical habitat (core and matrix) that is 'disturbed' by cutblocks less than 80 years old or forestry roads, using the model developed by [Lochhead et al.](citation tbd). Thus, it can be used to assess how forestry development in a caribou subpopulations habitat might influence abundance of that subpopulation.

For the purpose of using this module with dataLoaderCastor or forestryCastor, the important parameters to set are a raster (nameRasSMCHerd) and associated look-up table (tableSMCCoeffs). The nameRasSMCHerd parameter defines the location of critical habitat for each southern mountain caribou subpopulation, as defined by the government of British Columbia. The tableSMCCoeffs parameter is a look-up table that defines the subpopulation and habitat names, and the model coefficients for estimating abundance.

This module identifies the overlap between caribou subpopulations and the area of interest and adds two columns to the 'pixels' table, 'subpop_name' which identifies the subpopulation name, and 'herd_hab_name', which identifies the critical habitat type. It then calculates the percentage of the forested critical habitat in these areas that is disturbed, then applies the exponential model coefficients to estimate abundance. Note that the abundance estimates may not necessarily apply to the entire subpopulation, depending on how much that each subpopulations habitat overlaps the area of interest. Therefore, the estimates should be used with caution, as they implicitly assume the amount of disturbance calculated in the area of interest is equivalent to the amount of disturbance in the entire subpopulation. We recommend treating these as relative abundance estimates unless the entire subpopulations habitat occurs within the area of interest.

disturbanceCalcCastor

The disturbanceCalcCastor module is used to estimate disturbance metrics in caribou herd areas. The module calculates the area of forestry cutblocks and roads of a defined age, and 'permanent' disturbance features. In addition, it calculates the distance of each undisturbed pixel from the nearest disturbed pixel, so that buffered disturbance metrics can be estimated. For example, disturbance buffered by 500m is typically a metric of interest in caribou recovery.

The module creates two new columns in the 'pixels' table, 'perm_dist' and 'dist', where 'perm_dist' identifies pixels that are permanently disturbed (i.e., don't recover to forest in the simulation), and 'dist' identifies the distance of the pixel to the nearest disturbed pixel. Disturbed pixels are identified as pixels where permanent disturbances occur, as identified by the 'permDisturbanceRaster' parameter, roads less than a certain age and forest cutblocks less than a certain age. The age is defined by the 'recovery' parameter. This allows some flexibility in defining when a disturbance recovers, either by passive vegetation succession or active habitat restoration. Permanent disturbance features are typically things like mines, agricultural areas and highways that are unlikely to recover or be restored over the long term. The other parameters in the module define how often disturbance metrics are calculated (calculateInterval) and the area within which to summarize the disturbance metrics (criticalHabRaster and criticalHabitatTable).

yieldUncertaintyCastor

The yieldUncertaintyCastor module calculates uncertainty metrics around the amount of volume harvested for a stand, using a yield uncertainty model. For the dataLoaderCastor, the module adds an elevation field (elv) to the 'pixels' table. Elevation is a parameter in the model to calculate uncertainty metrics around harvest yield.

uploaderCastor

The uploaderCastor module defines the data (tables and rasters) that get output from the model and saved in a cloud-based PostgreSQL database. Some of these data are also summarized in the Castor Explorer web application. When running uploaderCastor with dataLoaderCastor, you need to set the parameters for the name of the area of interest (aoiName), the database where the data is uploaded (dbInfo) and the name of the schema (aoiName) in the database.

forestryCastor

The forestryCastor module is the primary module for running the forest harvest simulator, i.e., it contains many of the forest harvest event functions. There are a few parameter inputs exCastorive to the module, including:

  • harvest block priority queue logic (harvestBlockPriority)
  • harvest zone priority queue logic (harvestZonePriority)
  • interval for harvesting priority zones (harvestZonePriorityInterval)
  • green-up or adjacency requirement (adjacencyConstraint)
  • logical parameter (reportHarvestConstraints) to report whether the constraints in applicable zones (nameZoneRasters) are being met throughout the simulation

The "harvestBlockPriority" parameter is an SQL query for ordering the harvestable 'pixels' or blocks (if blockingCastor was used to define harvest blocks) for harvest. It reads the 'pixels' table in the SQLite database and orders the blocks, based on the average value of the pixels in the block for the desired harvest criteria. For example, an SQL statement of "age DESC, vol DESC" prioritizes blocks with the oldest and then highest volume average of pixels in the block as the harvest queue. This query can be used to prioritize harvest according to any data that is in the 'pixels' table. In the case of partitions, for example, to establish a priority for salvaging stands that are primarily dead, an SQL statement of "salvage_vol DESC, age DESC" prioritizes blocks that are primarily dead volume (salvage volume) and then oldest stands.

The "harvestZonePriority" parameter is an SQL query for ordering harvest priority areas within the area of interest. Thus, you can use it to prioritize the location of harvest at a larger scale than a block. This may be useful for scenarios where you want to 'force' harvest into pre-defined areas, or to harvest areas in order of some forest characteristics of interest in specified areas. Currently, the parameters for prioritizing a zone are: "zoneid", "age", "dist" and "vol". The "zoneid" is an integer value that you define when you establish the "nameZonePriorityRaster" parameter. It should be defined based on the priority you want to harvest the various zones (e.g., zoneid = 1 gets harvested first, zoneid = 2 gets harvested second, etc.). Note that when using the "harvestZonePriority" parameter, each pixel in the area of interest must have an integer value for zoneid (is not "NA"), otherwise it will not get harvested. The "age" (average age of stands in the zone), "dist" (total disturbance in the zone) and "vol" (total volume in the zone) parameters are defined in each zone at the start of the simulation, and the zones are harvested based on the order established by the SQL query. Note that currently the query considers all forest stands in the zone, not just stands in the timber harvest land base (THLB).

You can use the "harvestZonePriorityInterval" in combination with the "harvestZonePriority" parameter to define at what simulation interval the zone priority queue gets recalculated. If not defined, the same zone priority queue will be established throughout the simulation. Note that currently the prioritization is only recalculated for "age", "dist" and "vol". Future model versions will consider how to re-prioritize zones based on "zoneid".

The "reportHarvestConstraints" parameter is logical (TRUE or FALSE) and, if TRUE, will create an output table object ("zoneManagement") in the R environment that identifies the percent area (percent) of each constraint zone ("nameZoneRasters") that is achieving the desired constraint for each time interval. This parameter will be useful for checking whether a desired constraint is being properly implemented or achieved in a simulation. Note that the table does not report any constraint zones with no harvest ('nh').

The "adjacencyConstraint" parameter establishes the minimum height requirement (in meters) of adjacent stands before a block can be cut.

The "salvageRaster" parameter is used to define the location of dead forest volume on the land base. It is a raster of the amount of dead volume estimated by the forest inventory. It is used to parameterize the 'pixels' tables in the SQLite database with a column ("salvage_vol") of the amount of dead volume in each pixel within the area of interest. This column can then be queried to establish the harvest priority.

The forestryCastor module also requires a "scenario" object, a patch size distribution ("patchSizeDist") object and a harvest flow ("harvestFlow") object.

The "patchSizeDist" object provides patch size distribution targets for biodiversity emphasis option (BEO) natural disturbance types (NDTs) as a 'default' value. These are currently determined based on the provincial biodiversity guidebook. These patch size distributions pre-identify harvest block size distributions used in blockingCastor.

The "harvestFlow" object is used to establish harvest flows for the simulation, and can be partitioned by location ("compartment"), e.g., a compartment of a TSA, time period ("period"), and stand type ("partition_type"). The 'flow' parameter, specifies the target total cubic meters harvested per time period for a given partition. The "period" parameter in this object is used to define the start ("from") and end ("to") period of the harvest flow, and the temporal interval ("by") of the simulation. The "partition" parameter is used to further establish harvest criteria, such as setting a minimum harvest volume, using an SQL query (e.g., ' vol > 150 ', which specifies that only stands with greater than 150 m^3^/ha of volume will be queried in the harvest units). The "partition_type" parameter can currently be set as either "live"" or "dead", where the model is set to target the harvest of live or dead volume (e.g., use the query ' salvage_vol/(vol + salvage_vol) < 0.5 ' to target stands less than 50% dead volume as live, and ' salvage_vol/(vol + salvage_vol) >= 0.5 ' to target stands greater than or equal to 50% dead volume as dead).

The "scenario" object is used to name each unique run of the model, for example, if adjusting parameters to compare alternate scenarios or run sensitivity analyses. It includes a 'name' and 'description' parameter for each scenario. The scenario name gets assigned to output tables from model runs, and should be something short but easy to understand (we typically use acronyms). A scenario table with both parameters is also uploaded to the schema in the cloud-based PostgreSQL database.

All other parameters in forestryCastor are related to, or dependent on other modules. Some of the key parameters in these modules include the database name and location, the 'study area', forest inventory data, blocking, harvest queue, caribou indicator, patch size distribution and scenario parameters.

Database parameters are listed within forestryCastoras part of the dataLoaderCastor module parameters, i.e., the forestryCastormodule needs to be consistent with dataLoaderCastor for the area of interest. You need to specify the PostgreSQL database name (dbName), and the location for the SQLite database that was created by the dataLoaderCastor module (useCastordb). Here you also specify the spatial area of the analysis (nameBoundaryFile, nameBoundaryColumn, nameBoundary, nameBoundaryGeom, nameCompartmentRaster and nameCompartmentTable), the timber harvest land base area (nameMaskHarvestLandbaseRaster), and importantly, the names of the rasters where forest harvest constraints will be applied (nameZoneRasters). Forest harvest constraints will include existing legal constraints as are typically defined for timber supply modeling in BC. They include biodiversity emphasis options (rast.zone_cond_beo), visual quality objectives (rast.zone_cond_vqo), wildlife habitat areas (rast.zone_cond_wha), ungulate winter ranges (rast.zone_cond_uwr or rast.zone_uwr_2021), fisheries sensitive watersheds (rast.zone_cond_fsw), community watersheds (rast.zone_cond_cw) and no harvest areas (rast.zone_cond_nharv), such as provincial parks. The forest harvest constraints to apply to these areas are defined in the nameZoneTable parameter. Refer to the "Params" section, below, for details. Also, within dataLoaderCastor, the forest inventory parameters are defined, including the yield tables and rasters, and forest stand characteristics such as age, height, crown closure and site index.

Blocking parameters in the forestryCastor module are referred to in blockingCastor module. To use blocking in the forestryCastor module you will have needed to define the blocking method as part of running the dataLoaderCastor module. It will have created a "blocks" table in the SQLite database that will be used to define forest stands for harvest in forestryCastor.

You can periodically calculate growing stock as part of the forestryCastor simulation by listing the growingStockCastor module. You only need to set the periodLength parameter, and the forestryCastor module will call the growingStockCastor module at that interval and calculate the amount of volume available to be harvested.

The roadCastor module can be listed as a parameter to create roads within a forestry simulation. The roadCastor model will need to have been run with the dataLoaderCastor module to use the predefined roads (i.e., roadMethod = 'pre').

The uploaderCastor is important to identify where outputs for the simulation are stored. The module consist of two parameters, "aoiName" and "dbInfo", which identify the name of the schema and the database where the output information will be stored. This module will upload the tables described in the 'outputs' object of the simulation. Within this object you can identify the desired outputs from the various modules (often referred to as 'reports').

cutblockSeqPrepCastor

The cutblockSeqPrepCastor module queries the location and timing of existing (historic) cutblocks in spatial harvest data (e.g., harvest areas of BC). It can be used within dataLoaderCastor and in combination with roadCastor to estimate the historical development of forestry roads in an area of interest.

The "nameCutblockRaster", "nameCutblockTable" and "queryCutblocks" parameters are inputs that define the location of the historic cutblocks. The "nameCutblockRaster" and "nameCutblockTable" parameters provide the spatial extents of the cutblocks and year they were harvested. The "queryCutblocks" parameter is a point data file with the centroids (x and y coordinates) and year of harvest of the cutblocks. These centroids act as 'landings' or targets for the roadCastor module. The module iteratively identifies the landings of harvested cutblocks each year, and then fits the least-cost path along the existing road network to link the landing to a permanent road. It then assigns a roadyear (i.e., the year the road was first 'built' in the model) and roadstatus (i.e., the year the road was last used) to each roaded pixel. Thus, roadyear is the first year a road was needed in the model to link a landing to a permanent road. However, roads may be re-used, and thus roadstatus is the latest year the pixel was used to link a landing to a permanent road.

The "startHarvestYear" parameter is used to define the first year you want to simulate historic roads. For example, you may have historic cutblock data from 1950 to 2020, but only want to simulate roads from 1980 to 2020. You can then set "startHarvestYear" to 1980, and the model will simulate all cutblocks/landings harvested prior to 1980 in a single iteration, and then iterate annually from 1980 to 2020. Thus, all roads to cutblocks harvested prior to 1980 will have a roadyear equal to 0.

If the "resetAge" parameter is set to FALSE (or not used, which defaults to FALSE) then it assigns roadyear and roadstatus as the year in the dataLoaderCastor "times" sequence that it was built or used. For example, if you set the "times" parameter in dataLoaderCastor to "start" at 0 and "end" at 40, then roads simulated in 1980 will have a roadyear of 1, roads simulated in 1981 will have a roadyear of 2 and roads simulated in 2020 will have a roadyear of 40, etc. However, if using the dataLoaderCastor module to create data for a forestryCastor simulation, we recommend setting the "resetAge" parameter to TRUE so that it reports roadyear and roadstatus as the number of time steps in the past from the "end" parameter since a road was built or used. For example, roads simulated in 1980 will have a roadyear of -39, roads simulated in 1981 will have a roadyear of -38 and roads simulated in 2020 will have a roadyear of 0. This framework is compatible with modules that have parameters for estimating road recovery at certain ages (e.g., disturbanceCalcCastor).

Other Modules

The SpaDES-modules folder has additional modules developed to complete specific tasks.

The fisherCastor module can be used to define fisher (Pekania pennanti) territories and probability of fisher occupancy of those territories over a simulation period.

The volumebyareaReportCastor module can be used to create a report of the amount of volume harvested from a specified area during a simulation scenario. The area is defined by a raster (AreaofInterestRaster) with integers to identify the areas and a table (AreaofInterestTable) with the corresponding name for each area. These volumes can be calculated at specified intervals (calculateInterval). The output table includes the scenario name, forest harvest area name, time step, name of the specified area and the volume and area harvested from that area during the simulation.

Castor Functions

The functions folder contains several scripts necessary for completing functions within or related to Castor. The R_Postgres script in particular is critical to running the dataLoaderCastor and forestryCastor modules, as it contains several custom functions for querying and manipulating data within a PostgreSQL database. For example, there are functions for clipping raster data to a polygon. Notably, in the .Rmd files for dataLoaderCastor and forestryCastor you will see this script called using the 'source' R command (i.e., source (paste0(here::here(), "/R/functions/R_Postgres.R")).

The keyring_init script contains instructions and scripts for setting up password protection using the keyring package. You will need to run this script if you use our database structure. Contact us for setting up passwords if you would like to do that.

Other scripts document how to connect to an Oracle database from R, manipulate raster data, use open SSH connections for connecting network computers, migrating Oracle data to a PostgreSQL database, read big data in R, and setting up Parallel computing in R.

Castor Parameters

The Params folder contains various .Rmd scripts for creating data and parameters needed to run the Castor model. Many of these are used to populate the data in our PostgreSQL database.

Simulation Area Boundaries

Forest harvest simulation areas are defined in the study_area_boundaries.Rmd. Currently we use timber supply areas (TSAs) and tree farm license (TFL) areas to simulate forestry based scenarios for maintaining consistency with provincial timber supply modeling, but any area of interest could be defined. The .Rmd creates a raster of integers representing each unique TSA or TFL boundary, and a look-up table to link the polygon names to the raster integers.

Forest Harvest Constraints

There are several scripts in the Params folder for creating spatial forest harvest constraints for Castor simulations. These include 'typical' constraints used in timber supply models to support timber supply reviews. For example, the prov_manage_objs.Rmd develops constraints related to biodiversity emphasis options (BEO), fisheries sensitive watershed areas (FSW), visual quality objectives (VQOs), old growth management areas (OGMAs), parks and protected areas and community watersheds (CWs) across British Columbia. The uwr_cond_harvest.Rmd and wha_cond_harvest.Rmd files develop constraints around government action regulation (GAR) orders, including ungulate winter ranges (UWRs) and wildlife habitat areas (WHAs), respectively. Forest harvest constraints in some of these GAR order area are complex, and are subject to interpretation (see UWR and WHA orders), but these can be reviewed and modified as required using the script.

Additionally, there are also scripts for defining proposed or hypothetical areas to apply new forestry constraints, for example, caribou management areas.

The output from running any of these scripts is a table and a raster. The raster is created from the input locations (polygonal data), rasterized to a 1 ha scale, following the provincial 1 ha raster standard. Each zone gets a unique integer identifier that is the primary key, corresponding to the table that describes the particulars of the constraint that will be applied to that specific zone. The table includes the zone ID integer (i.e., the zone identifier for the raster pixels), the name of the zone (i.e., the name of the corresponding raster in the PostgreSQL database), the "variable" to be constrained (i.e., age, height, crown closure, or whatever data is in, or can be created from the 'pixels' table in the SQLite database), the type of constraint (i.e., 'nh' = no harvest, 'ge' = greater than or equal to, or 'le' = less than or equal to), the threshold of the constraint (i.e., the value at which the variable will be constrained), and the "percentage" of the zone that must meet the constraint threshold. For example, if you want to apply a minimum 40% of a zone to be age 40 or more, then: variable = 'age', type = 'ge' and percentage = '40'. You can also specify the area over which to apply a constraint, e.g., to set the area denominator (the denom field) as total area of the zone, or treed area within the zone, and the time period, in years when to apply a constraint (the start and stop fields).

To make this process less cumbersome, each table that is created for each zonal constraint, gets added to a 'parent' table called 'constraints' located in the 'zone' schema of the PostgreSQL database. Thus, the 'zone.constraints' table inherits all of the zone constraint tables identified in the Paramsfolder, thereby, removing the need to define each table for each constraint.

Growth and Yield Data

Data from TASS/TIPSY and VDYP growth and yield models are incorporated into the Castor model to estimate future yields of 'managed' and 'natural origin' forest stands, respectively. Outputs form these stand models are obtained provincially, calculated by FAIB staff, for all polygons within the Vegetation Resources Inventory ( VRI).

Projected stand volume and height data from TIPSY is organized for Castor via the tipsy_curves.Rmd. This .Rmd creates a raster of the foreign key used in the VRI that correspond to each TIPSY modeled stand. It also creates volume (tipsy_prov) and height (tipsy_ht_prov) tables that are stored in the PostgreSQL database.

Similarly, the stand volume and height data from VDYP is organized for Castor via the vdyp_curves.Rmd. This .Rmd creates a raster of the VRI stand ID's that correspond to each VDYP model stand. Height, basal area and volume data for each stand is created in a table (vdyp_output)

Forest Inventory and the Timber Harvest Land Base

We use the provincial forest inventory to obtain forest stand characteristics. Other data could be substituted here if it's available and considered more useful, but the provincial forest inventory provides a standard for analyses across British Columbia, and is consistent with timber supply reviews.

Forest inventory data is organized for Castor via the raster_data.Rmd. The input is the VRI layer 1 polygon data, from which a raster of each polygon identifier (feature_id) is created for the province. The specifics of which data from the inventory get incorporated into Castor are documented in the dataLoaderCastor (see above). A raster of the timber harvest land base (THLB) is also created in the raster_data.Rmd.

Wildlife Habitat Models

The rsf_model_coeff.Rmd can be used to create habitat models for various wildlife species, using the resource selection function (RSF) approach. The .Rmd creates a coefficient table for estimating habitat selection. The table includes the coefficient values and spatial data, if required to apply coefficients.

The fisher_constraints.Rmd can be used to define habitat constraints specific to fisher.