--- title: "Getting started with the plant model" output: rmarkdown::html_vignette vignette: > %\VignetteIndexEntry{Getting started with the plant model} %\VignetteEncoding{UTF-8} %\VignetteEngine{knitr::rmarkdown} --- ```{r setup, include=FALSE} options(rmarkdown.html_vignette.check_title = FALSE) ``` **authors**: DS Falster, A O'Reilly-Nugent, I Towers, F Robinson **date**: 2022 # Background This page contains a brief introduction to get you started with `plant`. At a high level, `plant` has two key use cases - modelling individuals or modelling patches. Modelling either is dependent on the species parameters, the environment and the intial conditions. By modifying these inputs you can grow different individuals or patches of species. XXXX diagram here More extensive information and tutorials are available, such as: **Details of the modelling approaches (concepts):** [Modelling demography of individuals, patches and metapopulations](https://traitecoevo.github.io/plant/articles/demography.html) [The `FF16` physiological strategy model](https://traitecoevo.github.io/plant/articles/demography.html) **Details of using `plant` in R:** - [Individuals](https://traitecoevo.github.io/plant/articles/individuals.html) - [Patches of competing individuals (patch level dynamics)](https://traitecoevo.github.io/plant/articles/patch.html) - [Finding demographic equilibrium](https://traitecoevo.github.io/plant/articles/equilibrium.html) - [Emergent properties of patches](https://traitecoevo.github.io/plant/articles/emergent.html) - [Calculating fitness](https://traitecoevo.github.io/plant/articles/fitness.html) - [The node spacing algorithm](https://traitecoevo.github.io/plant/articles/node_spacing.html) - [Modifying parameters of strategies (modifying parameters of physiological model)](https://traitecoevo.github.io/plant/articles/parameters.html) - [Implementing a new strategy](https://traitecoevo.github.io/plant/articles/strategy.html) # Setup First, load plant, tidyverse and purrr, which will be useful (for working with list objects): ```{r} library(plant) library(dplyr) library(tidyr) library(ggplot2) library(purrr) ``` For a full list of available functions run library(help=plant), or see the [online reference](https://traitecoevo.github.io/plant/reference/index.html). # Strategy objects Strategies are the corner stone of `plant`, describing the system of dynamical equations that determine an individuals vital rates -- i.e. growth, reproduction and mortality. The `plant` package is setup to accept different stratgies. Think of these as sets of rules which determine how biological foundation of your model. To get started, we'll use the `FF16` strategy. You can feed these strategies into either individuals or patches to alter the solver outcomes. For definitions of each of these parameters see [Concepts: FF16 Strategy tables](https://traitecoevo.github.io/plant/articles/physiology.html#tables). For further information on how to adjust the strategies see [Modifying parameters of strategies](https://traitecoevo.github.io/plant/articles/parameters.html) ```{r} s <- FF16_Strategy() str(s) ``` # Individuals We can define one or more individuals for a given strategy. These are accessed using the `Individual` class: ```{r} ind <- FF16_Individual() ``` Noting that `FF16_Individual` uses the `FF16_Strategy` by default (see `?FF16_Individual` for more information). Our individual also shares the `FF16_Environment` (more on that soon) and a number of rates and functions for us to explore. The [Individuals vignette](https://traitecoevo.github.io/plant/articles/individuals.html) describes the nuts and bolts of all these functions, for now we're only going to grow and plot our individual's height. ```{r} str(ind) ``` First we set a fixed environment (here `1.0` represents full light exposure in an open canopy) then use the `grow_individual_to_time` function to grow our individual for a range of time steps. ```{r} env <- FF16_fixed_environment(1.0) times <- seq(0, 50, length.out = 101) result <- grow_individual_to_time(ind, times, env) %>% tidy_individual() ``` The tidy_indivdual function puts the outputs from grow_individual_to_time into `tidy format`, as defined in the tidyverse. Examining our result, we see a matrix of our state variables at each timestep ```{r} result %>% head() ``` Which we can plot against time ```{r} #need to create a function to convert individual results to tidy-format #just do ggplot for now result %>% ggplot() + geom_line(aes(x=time, y=height), linewidth =1.5) + theme_classic() ``` You can find out more about how to grow individuals [under the Individual plants example](https://traitecoevo.github.io/plant/articles/individuals.html) OR if you're wanting to learn more about the concept and equations underlying individuals you can find them under [Concepts: demography of plants, patches and metacommunities](https://traitecoevo.github.io/plant/articles/demography.html#individual-plants) # Patches While we can torture our individual into all sorts of shapes and sizes, it's far more interesting to see how many individuals interact. The most important feature of `plant` is enabling easy modeling of size-distributions for multiple competing species within a patch. A patch is simply an area in which a collection of individuals grow and compete for resources (see [Concepts: patches](https://traitecoevo.github.io/plant/articles/demography.html#patches-of-competing-plants-size-structured-populations)). By size distribution we mean the distribution the relationship for density of individuals against their size (see Concepts-> XXX). By default, `plant` starts with a bare/empty patch, but you can also start with an existing size distribution (see XXXX). (XXX figure: Example size distribution (stylised) Modelling a patch involves - introducing individuals into the patch over time for each species, together which form a size-distribution for that species, and - stepping the size distributions for one or more species through time, integrating the rates of change on individuals to describe their state (such as height) and integrating the impact their state has on other individuals in a patch via the environment. Plant uses a particular mathematical method to model size distributions, which assumes large populations and continuous size distribution. The dynamics are solved by integrating along so-called "characteristics" of a partial differential equation (see Concepts-> XXX). The output from modelling a patch is size distribution at a series of times during patch development. At each time, the model reports states and rates for example individuals along the characteristics. From this, you can calculate a wide variety of metrics for the individual, population, community or environment within a patch at a given time. Below we provide some examples to get you started. More worked examples are available at XXXXX. ## Single species First, let's activate the logger (to keep us updated on what's happening): ```{r} plant_log_console() ``` Then start by specifying the model rules and load some basic controls. Here we'll use the FF16 ruleset: ```{r} params <- scm_base_parameters("FF16") ``` We can then need to specify the particular species by specifying their traits and birth rates. Here we use `lma` but other traits are possible (see Examples -> XXX). ```{r} species_parameters <- expand_parameters(trait_matrix(0.0825, "lma"), params) ``` Then we run `plant` solver (SCM) to solve the size distribution over time. There are two steps ```{r} # 1. Resolve number of characteristics needed for specified accuracy species_parameters <- build_schedule(species_parameters) # 2. Rerun, gathering outputs at each time step result <- run_scm_collect(species_parameters) %>% tidy_patch() ``` If you're working through this yourself, the SCM solver should be blazingly fast. This is quite cool, given that this model has hundreds of coupled differential equations veing stepped through time, wtih complex compeititve interactions at each step. The results is a list with a number of objects, which are explained in full at XXXX, and include * the times the size-distribution is reported (the exact times used are determined by the solver, via adaptive stepping of system. See XXXX), * details on the size distribution for each species in the patch at each timestep, * details on the environment in the patch at each at each timestep. ```{r} str(result, max.level = 1) ``` For easy usage, the `tidy_patch` function puts the `species` and `env` outputs into `tidy format`, as defined in the tidyverse. The species object looks like this: ```{r} result %>% pluck("species") %>% drop_na() ``` Let's look at height. Each line represents the height of an example individual growing along a characteristic curve over time, beginning from the point at which the example individual recruited into the patch. Notably, the first example individuals follow much the same growth curve as our individual above, but subsequent individuals have a bumpier ride, with growth slowing as the canopy closes over. Another variable in the species output is the log density of the example individual, which we can use to weight the growth trajectories to show thinning. For example, by following the growth of an example individual we can see that the relative density of these individuals is initially high after recruitment into the patch and declines progressively through time. ```{r} result%>% pluck("species") %>% drop_na() %>% plot_size_distribution() ``` To see the change in canopy openness over time we can explore the patch Environment. Lets look at year 20 first, which corresponds to the 99th timestep in our model (not all timesteps are equal!) Our FF16 environment is described in terms of canopy openness, with 1.0 being completely open and 0.0 being completely shaded. We see that the shortest individuals experience intense shading while taller individuals enjoy full sunlight: ```{r} result %>% pluck("env", "light_availability") %>% filter(step == "99") %>% ggplot() + geom_line(aes(x=height, y = light_availability), linewidth =1.5) + theme_classic() ``` If we look at the light environment at the forest floor (height = 0.0) we can see that it varies through time as older individuals thin out and gaps form ```{r} result %>% pluck("env", "light_availability") %>% filter(height == 0) %>% ggplot() + geom_line(aes(x= time, y=light_availability), linewidth=1.5) + theme_classic() ``` We can now look at the size distributions of two species competing in a patch. We can use the trait matrix function to specify multiple values for a given trait, each representing a different species in the community, or, as below, we can build upon the one-patch example above by using the expand_parameters function, including species_parameters as an argument. ```{r} species_parameters_2sp <- expand_parameters(trait_matrix(0.2625, "lma"), species_parameters) ``` As above in the single-species patch, we then determine the appropriate number of characteristics and rerun the solver, collecting the output from the patch-level dynamics. ```{r} species_parameters_2sp <- build_schedule(species_parameters_2sp) result <- run_scm_collect(species_parameters_2sp) %>% tidy_patch() ``` We can now plot the size distributions of these two species through time ```{r} result$species %>% drop_na() %>% plot_size_distribution() ``` # Meta-populations 🚧 Coming soon 🚧