knitr::opts_chunk$set(echo = TRUE)
library(medfate)
library(medfateland)
library(meteoland)

Aim

The aim of this vignette is to illustrate how to use medfateland (v. r packageVersion("medfateland")) to carry out simulations of forest function and dynamics on a set of spatial units, without taking into account spatial processes. This is done using functions spwb_spatial(), growth_spatial() and fordyn_spatial(); which are counterparts of functions spwb(), growth() and fordyn() in package medfate. As an example, we will use function spwb_spatial(), but the other two functions would be used similarly.

Preparation

Input structures

The fundamental input structure in medfateland is an object of class sf, i.e. a simple feature collection where geometries (normally points) are described with attributes. In the case of medfateland, spatial attributes correspond to model inputs for each of the spatial units represented. We begin by loading an example data set of 100 forest stands distributed on points in the landscape:

data("example_ifn")
example_ifn

Despite the geometries themselves (which have a coordinate reference system), the following columns are required:

Note that columns forest and soil contain vectors of lists, where elements are either lists or data.frames. For example, the forest corresponding to the first stand is:

example_ifn$forest[[3]]

and the soil is:

example_ifn$soil[[3]]

Displaying maps of landscape properties

Using plot_variable() functions for spatial landscape objects, we can draw maps of some variables using:

plot_variable(example_ifn, "basal_area")

The set of maps available can be known by inspecting the help of function extract_variables(). Alternatively, the package provides function shinyplot_land() to display maps interactively.

Climate forcing

In medfateland there are several alternatives to specify climate forcing.

(1) Provide a single data frame with daily weather for all stands. (2) Provide a different daily weather for each stand (in an additional column of sf called meteo) (3) Provide an object to perform daily weather interpolation during simulations (see later in this document).

For most of this document, we will follow the simpler option, which is to assume the same weather for all stands. We will supply a single data frame with daily weather for all plots:

data("examplemeteo")
head(examplemeteo)

More interesting alternatives are described in the help of function spwb_spatial(). Notably, a column meteo may be defined in the sf input object, where for each spatial unit the user can supply a different data frame.

Species parameters and local control parameters

Since it builds on medfate, simulations using medfateland require species parameters and control parameters for local simulations:

data("SpParamsMED")
local_control <- defaultControl()

Importantly, the same control parameters will apply to all spatial units of the sf object.

Carrying out simulations

As you should already know, package medfate includes functions spwb(), growth() and fordyn() to simulate soil water balance, carbon balance and forest dynamics on a single forest stand, respectively. This section describe how to run simulations on a set of forest stands in one call. As an example, we will use function spwb_spatial(), which simulates soil plant water balance on forests distributed in particular locations, but growth_spatial() and fordyn_spatial() are very similar.

Calling the simulation function

The call to spwb_spatial() can be done as follows (here we use parameter dates restrict the simulation period to january and february):

dates <- seq(as.Date("2001-01-01"), as.Date("2001-02-28"), by="day")
res <- spwb_spatial(example_ifn, SpParamsMED, examplemeteo, 
                    dates = dates, local_control = local_control,  
                    parallelize = TRUE)

Function spwb_spatial() first initializes model inputs by calling spwbInput() for each forest stand described in the sf landscape object. Then it calls function spwb() for each forest stand and stores the result. In this case, we asked for parallel computation via the parameter parallelize = TRUE.

The simulation result is also an object of class sf with the following columns:

names(res)

Column geometry contains the geometry given as input to simulations, column id contains the identification label of each stand, column state contains the spwbInput corresponding to each forest stand (which can be used in subsequent simulations) and column result contains the output of spwb() function for each forest stand (i.e. its elements are objects of the S3 class spwb).

Temporal summaries, plots and maps

The structure of the output of spwb_spatial() allows querying information for the simulation of any particular forest stand. For example, we may use function plot.spwb(), from package medfate, to display the simulation results on a particular plot:

plot(res$result[[1]], "Evapotranspiration")

Similarly, if we want a monthly summary of water balance for the first stand, we can use function summary.spwb() from package medfate:

summary(res$result[[1]], freq="months",FUN=sum, output="WaterBalance")

However, a more convenient way of generating summaries is by calculating them on all forest stands in one step, using function simulation_summary() on objects issued from simulations:

res_sum <- simulation_summary(res, summary_function = summary.spwb, 
                              freq="months", output="WaterBalance")

where the argument summary_function points to the function to be used to generate local summaries and the remaining arguments are those of the local summary function. The result of using simulation_summary() is again an object of class sf that contains the spatial geometry and the list of summaries for all stands:

names(res_sum)

The summary for the first stand can now be accessed through the first element of column summary:

res_sum$summary[[1]]

Summary objects are handy because their plot_summary() function allows us to display maps of summaries for specific dates:

plot_summary(res_sum, "Transpiration", "2001-01-01", limits=c(0,45))
plot_summary(res_sum, "Transpiration", "2001-02-01", limits=c(0,45))

To avoid displaying maps one by one, the package includes function shinyplot_land() that allows displaying maps of temporal summaries interactively.

Simulation with integrated temporal summaries

If one needs to save memory, it is possible with spwb_spatial() to generate temporal summaries automatically after the simulation of soil water balance of each stand, and storing those summaries instead of all the output of function spwb().

For example the following code will keep temporal summaries of water balance components instead of simulation results:

res_2 <- spwb_spatial(example_ifn, SpParamsMED, examplemeteo, 
                  dates = dates, local_control = local_control,                  
                  keep_results = FALSE, parallelize = TRUE,
                  summary_function = summary.spwb, summary_arguments = list(freq="months"))

Parameter keep_results = FALSE tells spwb_spatial() not to keep the simulation results of forest stands, whereas summary_function = summary.spwb tells spwb_spatial() to perform and store summaries before discarding the results of any stand. The output has slightly different column names:

names(res_2)

In particular, result is not included. Now the temporal summaries can be directly accessed through the column summary:

res_2$summary[[1]]

And one can produce maps with summary results directly from the output of the simulation function:

plot_summary(res_2, "Transpiration", "2001-02-01", limits=c(0,45))

The possibility of running a summary function after the simulation of each stand is not limited to summary.spwb(). Users can define their own summary functions, provided the first argument is object, which will contain the result of the simulation (i.e., the result of calling spwb(), growth() or fordyn()). For example, the following function returns the data frame corresponding to plant drought stress:

f_stress <- function(object, ...) {
  return(object$Plants$PlantStress)
}

Now we can call again spwb_spatial:

res_3 <- spwb_spatial(example_ifn, SpParamsMED, examplemeteo,
                  dates = dates, local_control = local_control,
                  keep_results = FALSE, parallelize = TRUE,
                  summary_function = f_stress)

The drought stress summary of stand 3 is:

head(res_3$summary[[3]])

Continuing a previous simulation

The result of a simulation includes an element state, which stores the state of soil and stand variables at the end of the simulation. This information can be used to perform a new simulation from the point where the first one ended. In order to do so, we need to update the state variables in spatial object with their values at the end of the simulation, using function update_landscape():

example_ifn_mod <- update_landscape(example_ifn, res)
names(example_ifn_mod)

Note that a new column state appears in now in the sf object. We can check the effect by drawing the soil water potential:

plot_variable(example_ifn_mod, "soil_psi_curr")

By using this new object as input we can now simulate water balance in the set of stands for an extra month:

dates <- seq(as.Date("2001-03-01"), as.Date("2001-03-31"), by="day")
res_3 <- spwb_spatial(example_ifn_mod, SpParamsMED, examplemeteo, 
                      dates = dates, local_control = local_control, 
                      summary_function = summary.spwb, summary_arguments = list(freq = "months"),
                      parallelize = TRUE)

And display a map with the resulting month transpiration:

plot_summary(res_3, "Transpiration", "2001-03-01", limits=c(0,45))

Simulations using weather interpolation

Specifying a single weather data frame for all the forest stands may be not suitable if they are very far from each other. Specifying a different weather data frame for each stand can also be a problem if there are thousands of stands to simulate, due to the huge data requirements. A solution for this can be using interpolation on the fly, inside simulations. This can be done by supplying an interpolator object (or a list of them), as defined in package meteoland. Here we use the example data provided in the package:

interpolator <- meteoland::with_meteo(meteoland_meteo_example, verbose = FALSE) |>
    meteoland::create_meteo_interpolator(params = defaultInterpolationParams())

Once we have this object, using it is straightforward, via parameter meteo:

res_4 <- spwb_spatial(example_ifn_mod, SpParamsMED, meteo = interpolator, 
                      local_control = local_control, 
                      summary_function = summary.spwb, summary_arguments = list(freq = "months"),
                      parallelize = FALSE)


emf-creaf/medfateland documentation built on April 17, 2025, 5:43 a.m.