knitr::opts_chunk$set( collapse = TRUE, comment = "#>" )
This vignette shall serve as an introduction to the modLWFB90 package. It shows how to use its essential functions and how to specify certain aspects if desired.
The hydrological model LWFBrook90 is increasingly used at the FVA-BW in various projects and applications. It is a dynamic 1-D model that, through a large number of settings, allows for a detailed representation of soil, climate, and vegetation conditions. Hence, it is pretty useful for soil water modeling in the forest background we're working in.
Paul Schmidt-Walter at the NW-FVA developed an R-package that serves as an R-wrapper for LWFBrook90.exe. LWFBrook90R makes it possible and relatively easy to use and work with LWFBrook90 from within Rstudio.
The package in front of you, modLWFB90, even goes one step further: It uses the whole functionality of LWFBrook90R, but adds a link to soil data and climate data available on the FVA-BW servers. This way users can do hydrological modelling by just giving the desired methods as arguments. All you need is one tidy data frame with the points you want to model in the following form:
ID_custom
- a unique ID that all intermediate products as well as the results will be assigned to easting
and northing
- coordinates in UTM 32N EPSG:32632Then, all you need to specify is the time period, a number of settings (the origin of the soil data, the PTF to be used, the type of forest you want to model, etc.), and the way you want the output to be structured.
In the course of the project WHH-KW, parametrisation settings for the main tree species (beech - Buche, spruce - Fichte, oak - Eiche, pine - Kiefer) were agreed upon and can be selected in modLWFB90.
For WHH-KW the UHH Hamburg created a new and improved climate data set containing regionalised 250m-raster climate data for the historic time period 1961-2018, as well as the following climate scenarios:
The following soil options can be selected:
There's also a function to compare the three soil data outputs.
First of all, get release 0.4.5 of LWFBrook90R. Newer versions have changes that are incompatible with modLWFB90. github:pschmidtwalter/LWFBrook90R Then, install modLWFB90, together with the dependency packages, which are required and will be installed automatically. The easiest way to install from github is with the following line of code:
if(!require("remotes")) install.packages("remotes") # HTTPS not supported when installing from github: Sys.setenv(R_REMOTES_NO_ERRORS_FROM_WARNINGS=TRUE) Sys.setenv(HTTPS_PROXY=Sys.getenv("HTTP_PROXY")) remotes::install_github(repo="pschmidtwalter/LWFBrook90R@v0.4.5") remotes::install_github(repo="rhabel/modLWFB90")
library(modLWFB90)
As https is not supported from FVA-servers, this first has to be overwritten You might encounter issues with updates that can't be overwritten and other R-package-problems, in which case the following function might help you install the missing packages quicker (no install.packages(x); library(x) over and over again):
check_packages <- function(pkg){ new.pkg <- pkg[!(pkg %in% installed.packages()[, "Package"])] if (length(new.pkg)) install.packages(new.pkg, dependencies = TRUE) sapply(pkg, require, character.only = TRUE) } # example: check_packages(c("LWFBrook90R", "parallel"))
Essential for hydrological modelling are three datasets: Soil, Climate, and Parameters. This is how to get them the simplest possible way. First, we need sample data. test.ids.bds
includes five points in the forest near Lake Constance (Bodensee).
test.ids.bds
The function to create soil data is called fnc_get_soil and returns a list of soil data frames, so best assign it to a list object like this:
ls.soil <- fnc_get_soil(df.ids = test.ids.bds, soil_option = "STOK", PTF_to_use = "WESSOLEK", limit_MvG = T) ls.soil[[1]]
There's a number of options to choose from:
ID_custom
, easting
and northing
STOK
, BZE
, (STOK_BZE
for or OWN
, if own you need to specify own soil data through df.soils. HYPRES
, PTFPUH2
or WESSOLEK
?fnc_get_soil
There's also the option to compare the soil data created by the different options. Plus, the option to compare the hydraulic parameters created by the differnt PTFs. See ?fnc_compare_soil
for more information.
The function to create climate data is called fnc_get_climate
and works the same way:
ls.clim <- fnc_get_clim(df.ids = test.ids.bds, mindate = as.Date("2010-01-01"), maxdate = as.Date("2011-12-31"))
Here you can only specify the time period for which you need climate data. The additional arguments path_std
and path_climdb
lead to the current position of the climate databases on the FVA-Servers. They may have to be adjusted at some point, but for now they are up to date and shouldn't be changed.
If you model many points, large climate data files might use up all your RAM. In this case you should have a look at fnc_read_climdb
and fnc_write_climdb
.
The list of parameters you can pass to LWFBrook90 is pretty exhaustive. See LWFBrook90R::setparam_LWFB90
for a complete list. In the project WHH-KW, a set of parameters was agreed upon for the most relevant tree species (Buche - beech
, Eiche - oak
, Fichte - spruce
, Kiefer - pine
). They can be used by specifying the argument tree_species
either as one value for all points, or as a vector of values for each individual point. Additional information on the modelling points can be passed with the argument df.ind.info
. See ?fnc_get_params
to find out how to do this.
The default setting for spruce would look like this:
ls.parms <- fnc_get_params(df.ids = test.ids.bds, tree_species = "spruce")
Modelling options are set with the function set_optionsLWFB90
from the LWFBrook90R package. If you use modLWFB90 the only settings you need to adjust are
budburst.method
and leaffall.method
- if you want something other than fixed
startdate
and enddate
- as desired, but should match your settings in fnc_get_clim
root.method
check ?set_optionsLWFB90
for more information.
Finally, we need to define how our output should look like. LWFBrook90 creates a lot of output files. In order to keep data storage to a minimum, both run_LWFB90
and run_multisite_LWFB90
provide an output_fun
- argument that can be used to reduce the output and directly write it.
This is what the functions fnc_write
(daily values) and fnc_write_agg
(options to aggregate over year, vegetation period, or months) function are made for. They write temporary files with the desired output for each point. fnc_write_to_sql
can be used to convert these files into a SQLite-DB. This "step-in-between" is necessary because SQLite does not support parallel writing. If you model few enough points that your memory can handle them, you can set dir_name to NA
and get the results loaded into your environment. See the help pages of the write-functions on how to do this.
# create ID-dataframe df.ids = test.ids.bds # set options options.b90 <- set_optionsLWFB90(budburst.method = "Menzel", leaffall.method = "vonWilpert", startdate = as.Date("2010-01-01"), enddate = as.Date("2011-12-31"), root.method = "betamodel") # set df.output df.output <- set_outputLWFB90() df.output[,] <- 0L df.output[c("Evap", "Swat", "Flow"), c("Day")] <- 1 df.output[c("Flow"), c("Mon")] <- 1 output_path <- paste0(getwd(), "/") # create data ls.parms <- fnc_get_params(df.ids = test.ids.bds, tree_species = "spruce") ls.clim <- fnc_get_clim(df.ids = test.ids.bds) ls.soil <- fnc_get_soil(df.ids = test.ids.bds, soil_option = "STOK", testgebiet = "BDS", PTF_to_use = "WESSOLEK") # this chunk of code removes non-mapped STOK-points, if there are any and # the BZE-filling option was not selected. Otherwise it doesn't do anything. ls.clim <- ls.clim[which(!unlist(lapply(ls.soil, is.null))==T)] ls.parms <- ls.parms[which(!unlist(lapply(ls.soil, is.null))==T)] ls.soil <- ls.soil[which(!unlist(lapply(ls.soil, is.null))==T)] # Run: res <- run_multisite_LWFB90(options_b90 = options.b90, param_b90 = ls.parms, soil = ls.soil, climate = ls.clim, output = df.output, all_combinations = F, cores = parallel::detectCores(), # if you have more than one core available, this will speed things up significantly output_fun = fnc_write_agg, aggr_tp = "vegper", dir_name=paste0(output_path, "tmp/")) # save soils names(ls.soil) <- NULL soils <- bind_rows(ls.soil) # create dirs if(!dir.exists(paste0(output_path, "tmp/soils/"))){ dir.create(paste0(output_path, "tmp/soils/"), recursive = T) } save(soils, file = paste0(output_path, "tmp/soils/soils.RData")) # write to db --------------- #### fnc_write_to_sql(db_name = paste0(output_path, "test_db.sqlite"), dir_tmp = paste0(output_path, "tmp"))
Add the following code to your website.
For more information on customizing the embed code, read Embedding Snippets.