tutorials:sensitivity-analysis-using-grolink-and-gror
Differences
This shows you the differences between two versions of the page.
Both sides previous revisionPrevious revisionNext revision | Previous revision | ||
tutorials:sensitivity-analysis-using-grolink-and-gror [2024/06/25 15:00] – thomas | tutorials:sensitivity-analysis-using-grolink-and-gror [2024/07/01 12:39] (current) – [Example: Morris Screening using the sensitivity package] thomas | ||
---|---|---|---|
Line 1: | Line 1: | ||
====== Sensitivity analysis on GroIMP models using GroR ====== | ====== Sensitivity analysis on GroIMP models using GroR ====== | ||
- | This wiki explains how to do a sensitivity analysis on GroIMP models using the GroR interface using a Morris screening over input parameters of the [[https://wwwuser.gwdguser.de/ | + | This wiki explains how to do a sensitivity analysis on GroIMP models using the GroR interface using a Morris screening over input parameters of the [[http://134.76.18.36/wordpress/courses-and-tutorials/simplefspm/ | " |
===== Prerequisites ===== | ===== Prerequisites ===== | ||
Make sure to [[: | Make sure to [[: | ||
+ | |||
+ | ==== Downloads ==== | ||
+ | * {{ : | ||
+ | * {{ : | ||
===== Prepare your model===== | ===== Prepare your model===== | ||
Line 33: | Line 37: | ||
lf[al] = lm.getAbsorbedPower3d(lf).integrate()*2.25; | lf[al] = lm.getAbsorbedPower3d(lf).integrate()*2.25; | ||
lf.(setShader(new AlgorithmSwitchShader(new RGBAShader((float) lf[al]/ | lf.(setShader(new AlgorithmSwitchShader(new RGBAShader((float) lf[al]/ | ||
- | // | ||
lf[as] = (lf[al]*86400*2)/ | lf[as] = (lf[al]*86400*2)/ | ||
lf[age]++; | lf[age]++; | ||
Line 66: | Line 69: | ||
==== POI definition and output communication ==== | ==== POI definition and output communication ==== | ||
+ | The '' | ||
+ | For this example, I decided that the interesting output would be the total absorbed light by the leaves at the point when the first flower emerges. Because you can conveniently grab the output on the console in GroR, I added some code in the '' | ||
+ | |||
+ | <code java> | ||
+ | if(count((*NiceFlower*)) > 0){ | ||
+ | println(sum((* Leaf *)[al])); | ||
+ | } else { | ||
+ | println(" | ||
+ | } | ||
+ | </ | ||
+ | |||
+ | So, after every '' | ||
+ | |||
Line 71: | Line 87: | ||
===== Model execution and output gathering in R===== | ===== Model execution and output gathering in R===== | ||
+ | I will first demonstrate the concept by gathering the output (the amount of absorbed light) from just one model execution (run). | ||
+ | |||
+ | First, load some libraries and set up the workbench with the prepared model: | ||
+ | |||
<code R> | <code R> | ||
- | source(" | + | source(" |
- | ... | + | |
+ | library(future) | ||
+ | library(future.apply) | ||
+ | library(sensitivity) | ||
+ | |||
+ | wb1 <- GroLink.open(" | ||
</ | </ | ||
+ | |||
+ | You can make sure that everything works by looking up the available model functions or reading the parameter file: | ||
+ | |||
+ | <code R> | ||
+ | (functions <- WBRef.listRGGFunctions(wb1)) | ||
+ | WBRef.getFile(wb1, | ||
+ | </ | ||
+ | |||
+ | Now here is the code that gets the model output. It executes the '' | ||
+ | |||
+ | <code R> | ||
+ | model_output <- "" | ||
+ | n_grows <- 0 | ||
+ | while (!(is.numeric(model_output)) && (n_grows < 200)) { | ||
+ | result <- WBRef.runRGGFunction(wb1," | ||
+ | model_output <- unlist(result$console) | ||
+ | if (model_output != "no flower" | ||
+ | model_output <- as.numeric(model_output) | ||
+ | } | ||
+ | } | ||
+ | </ | ||
+ | |||
+ | |||
+ | |||
+ | |||
+ | |||
+ | |||
===== Example: Morris Screening using the sensitivity package ===== | ===== Example: Morris Screening using the sensitivity package ===== | ||
+ | The Morris Screening will be used to analyze the 5 structural plant growth parameters with regard to their importance (their main and interaction effect) on the total amount of absorbed light by leaves. This is just a random example out of the plethora of available sensitivity analysis methods. Most of the common ones are implemented in the '' | ||
+ | |||
+ | First, I generate a set of input parameters for the model: | ||
+ | |||
+ | <code R> | ||
+ | m <- morris(model = NULL, factors = c(" | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | " | ||
+ | r = 20, # 20 repetitions | ||
+ | binf = c(0.05, 0.01, 0.05, 0.1, 0.1), # min value of inputs | ||
+ | bsup = c(0.8, 0.1, 1, 1, 1), # max value of inputs | ||
+ | | ||
+ | # grid.jump is recommended to be levels/2, see ?morris | ||
+ | |||
+ | |||
+ | params <- m$X | ||
+ | </ | ||
+ | |||
+ | '' | ||
+ | |||
+ | <code R> | ||
+ | executeModel <- function(params, | ||
+ | wb1 <- GroLink.open(" | ||
+ | WBRef.updateFile(wb1, | ||
+ | | ||
+ | "; | ||
+ | "; | ||
+ | "; | ||
+ | "; | ||
+ | ";", | ||
+ | sep = "" | ||
+ | |||
+ | WBRef.compile(wb1) | ||
+ | |||
+ | model_output <- "" | ||
+ | n_grows <- 0 | ||
+ | while (!(is.numeric(model_output)) && (n_grows < timeout)) { | ||
+ | result <- WBRef.runRGGFunction(wb1," | ||
+ | model_output <- unlist(result$console) | ||
+ | if (model_output != "no flower" | ||
+ | model_output <- as.numeric(model_output) | ||
+ | } | ||
+ | n_grows <- n_grows + 1 | ||
+ | } | ||
+ | if (n_grows == timeout) { | ||
+ | model_output <- NA | ||
+ | } | ||
+ | WBRef.close(wb1) | ||
+ | return(model_output) | ||
+ | } | ||
+ | </ | ||
+ | |||
+ | This function contains the while-loop from above but also modifies (overrides) the '' | ||
+ | |||
+ | <code R> | ||
+ | plan(multisession, | ||
+ | |||
+ | system.time(model_outputs <- future_apply(params, | ||
+ | |||
+ | saveRDS(model_outputs, | ||
+ | </ | ||
+ | |||
+ | Through the use of '' | ||
+ | |||
+ | The only thing remaining is to analyze the output and plot the results: | ||
+ | |||
+ | <code R> | ||
+ | sensitivity:: | ||
+ | |||
+ | plot(m) | ||
+ | </ | ||
+ | |||
+ | This should now look something like this: | ||
+ | |||
+ | {{: | ||
+ | |||
tutorials/sensitivity-analysis-using-grolink-and-gror.1719320434.txt.gz · Last modified: 2024/06/25 15:00 by thomas