rswap is an R-package designed to help interface and work with SWAP 4.2.0 [1]. It consists of a variety of functions that assist the user in otherwise tedious and repetitive tasks during the calibration process. The scope of the package will hopefully be expanded overtime to include sensitivity analysis, multi-core parallelization, autocalibration / PEST integration, scenario runs, and much more. DISCLAIMER: rswap is very much in development, and therefore not robustly tested, nor extremely stable. use at your own risk, and be critical of the results, for now..
You can install rswap
from GitHub:
# install remotes, if not already present
install.packages("remotes")
remotes::install_github("moritzshore/rswap")
library(rswap)
A useful place to start would be the rswap_init()
function. This function creates the “Hupselbrook” example case in the same directory as your swap.exe
. It goes on to run the setup, copy in the observed data template file, and plot the results. If this function finished successfully, you know rswap
is working properly.
rswap_init(swapexe = "C:/path/to/swap.exe")
for help on any specific function, use > ?functionname
⚠️IMPORTANT⚠️ Its important to know that rswap
never modifies files in your project directory (project_path
), instead all files are copied from project_path
to project_path/rswap
, modified there, and executed. All results are stored there as well and will be overwritten over time. Remember to save your results if you would like to keep them, and remember that anything in the project_path/rswap
directory is temporary!
The SWAP model can be run using the run_swap()
function. It needs to know where your model setup is located (project_path
). The swap.exe
must be located in the parent directory of project_path
!
run_swap(project_path)
run_swap()
can be further customized with the following parameters:
swap_file
can be set to a custom name for your SWAP main file (*.swp)autoset_output
can be enabled, such that the output of the SWAP model matches your provided observed data (more on that later)timeout
sets the max allowed runtime of SWAPTo read the output of your executed SWAP run, you can use the following command.
modelled_data <- read_swap_output(project_path)
read_swap_output()
returns two dataframes, daily_output
which contains depth wise values of various variables.
> modelled_data$daily_output
# A tibble: 17,520 x 5
DATE DEPTH H WC TEMP
<chr> <dbl> <dbl> <dbl> <dbl>
1 2013-01-01 -0.5 -687. 0.118 0
2 2013-01-01 -1.5 -684. 0.118 0
3 2013-01-01 -2.5 -680. 0.118 0
# i 17,517 more rows
# i Use `print(n = ...)` to see more rows
The other is custom_depth
which contains custom variables at custom depths either explicitly altered by the user, or automatically parsed by the autoset_output
flag of run_swap()
. This dataframe is used widely throughout the package. (more/all results will be added over time)
> modelled_data$custom_depth
# A tibble: 730 x 14
DATE RAIN SNOW DRAINAGE DSTOR H_10 H_20 H_30 WC_15 WC_40 WC_70 TEMP_15 TEMP_40 TEMP_70
<date> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl>
1 2013-01-01 0 0 0 -0.0266 -648. -603. -550. 0.122 0.111 0.111 0 0 0
2 2013-01-02 0 0 0 -0.027 -624. -597. -564. 0.124 0.107 0.111 0 0 0
3 2013-01-03 0 0 0 -0.0305 -618. -595. -568. 0.124 0.104 0.111 0 0 0
# i 727 more rows
# i Use `print(n = ...)` to see more rows
As rswap heavily revolves around calibration, observed data is of high importance. When running either build_rswap_directory()
or run_swap()
, a template observed file will be copied into the project_directory
(if not already existing). It is up to the user to fill this excel sheet with the appropriate data and column names. Documentation for how to do this will be found in the excel sheet. (I will switch to .csv format soon)
To load your observed file, you can use the following command:
observed_data <- load_observed(project_path)
which will return a dataframe of the user-entered observed data:
> observed_data$data
# A tibble: 168 x 11
DATE WC_15 WC_40 WC_70 H_15 H_40 H_70 DRAINAGE TEMP_15 TEMP_40 TEMP_70
<date> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl>
1 2013-10-10 0.21 0.12 0.08 0.21 0.12 0.08 0.21 0.12 0.08 0.21
2 2013-10-11 0.21 0.12 0.08 0.21 0.12 0.08 0.21 0.12 0.08 0.21
3 2013-10-12 0.2 0.12 0.08 0.2 0.12 0.08 0.2 0.12 0.08 0.2
# i 158 more rows
# i Use `print(n = ...)` to see more rows
…as well as a vector for the detected variables
> observed_data$observed_variables
[1] "WC" "H" "DRAINAGE" "TEMP"
To find out what depths your observed variables have, you can use the following command:
get_depths(observed_data$data)
..this can also be filtered by a specific variable by passing variable
There are a variety of functions used to visualize your SWAP data, such as plot_over_under()
plot_over_under(project_path, variable = "WC", depth = c(15, 40, 70))
plot_over_und()
can be passed a variable
, as well as a vector depth
.
(this plot heavily relies on code from Neal Grantham)
For a more detailed look at multiple variables at once, you can use the soft_calibration_plot()
> soft_calibration_plot(project_path, vars = c("H", "WC", "DRAINAGE"))
This function can be passed up to 3 variables, and will display them interactively on the same plot. If observed data is available, they will be displayed as well.
A few functions focus on assessing model performance by comparing modelling values to user provided observed values. This functionality is based on the get_performance()
function:
> get_performance(project_path, stat = "NSE", variable = "WC", depth = 15)
# A tibble: 1 × 2
var NSE
<chr> <dbl>
1 WC_15 0.62
This function is very flexible and can be passed any number of variables
, depths
, and performance indicators stat
(currently supported are NSE
, PBIAS
, RSR
, and RMSE
.
While calibrating a model it can be useful to keep track of different model runs with different parameterization. rswap
aids this process with a variety of functions, such as
save_run(project_path, run_name = "COFRED = 0.35")
This function saves your entire model set up in a directory (project_directory/rswap_saved
). Once a model run has been saved, it can be compared to other model runs, with the following functions.
Once you have saved at least one run, you can compare them using the
comparative_plot(project_path, variable = "WC", depth = 15)
Once again, this function is quite flexible, and can be passed any available variable
or depth
You can compare the performance of your various model runs by using the plot_statistics()
function.
plot_statistics(project_path, var = "WC", depth = c(15,40,70))
This plot is equally flexible and can be passed any variable
and any amount of depths
for any supported stat
. the graph type can be switched between default
, sorted
and ggplot
changing a parameter in rswap can be done using the parse_swp_file()
function.
parsed <- parse_swp_file(project_path, swap_file)
This returns both a dataframe of all the parameters, as well as a path to where the saved tables are located (I am working on getting a “list of dataframes” to work in R, instead of just writing tables #TODO!)
You can modify the dataframe how you wish, with whatever tools you would like, however rswap
does have a simple dedicated function to do this for you.
parameters <- change_swap_par(param = parsed$parameters, name = "COFRED", value = 0.55)
This function takes in the dataframe parsed by the previous function and returns that same dataframe with the modified parameter.
If you would like to run SWAP with the modified parameter set, you first would write the new SWAP main file:
write_swap_file(parameters = parameters, table_path = parsed$table_path, outpath = paste0(project_path, "/modified.swp"))
And to run this modified SWAP main file, you would of course use run_swap()
with the corresponding project_path
and swap_file
parameters.
The aforementioned functions rely on more basic general functions which, while are designed for internal use, can possibly also be of assistance to the end user. These are listed below.
filter_swap_data() # filters SWAP data (observed or modelled) by var and depth
match_mod_obs() # matches dataframe structure of observed and modelled
melt_all_runs() # melts together all saved runs + current into
tidyformat
autoset_output
plot_over_under()
, and support missing valuesrswap
functions a consistent naming scheme (verb_swap_noun()
)write_swap_output()
parse_swp_file()
and change_swap_par()
(and write_swap_file()
?)plot_statistics()
sorting to follow stat propertyio.R
-> melt_all_runs()
set_swap_output()
, and expand on it.If you run into any bugs or problems, please open an issue on the repository page. (or contact me directly: moritz.shore@nibio.no) The same goes for if you have any suggestions for improvement. If would you like to contribute to the project, let me know! Very open towards collaborative improvement. Fork/Branch off as you please :)
Any OPTAIN case-studies which use rswap
are required to bake Moritz Shore a cake using a local recipe from the case-study country.
This package was developed for the OPTAIN project and has received funding from the European Union’s Horizon 2020 research and innovation program under grant agreement No. 862756.
[1] Van Dam, J. Field-Scale Water Flow and Solute Transport: SWAP Model Concepts, Parameter Estimation, and Case Studies. Ph.D. Thesis, Wageningen University, Wageningen, The Netherlands, 2000.