latest developments of the airgr rainfall-runoff modelling ...€¦ · latest developments of the...
TRANSCRIPT
Latest developments of the airGR rainfall-runoff modelling R package:new calibration procedures and other features
Olivier Delaigue1, Guillaume Thirel1, Francois Bourgin2, Laurent Coron3
1 IRSTEA – Hydrology Research Group (HYCAR) – Antony, France2 IFSTTAR – GERS, EE – Nantes, France
3 EDF – PMC Hydrometeorological Center – Toulouse, France
airGR is a family of lumped hydrological models designed for flow simulation at various time steps. The models are freely available in an R package called airGR(Coron et al., 2017a, 2017b). The models can easily be implemented on a set of catchments with limited data requirements.
GR hydrological models
I Designed with the objective to be as efficient as possible for flow simulation at varioustime steps (from hourly to interannual)
I Warranted complexity structures and limited data requirements
I Can be applied on a wide range of conditions, including snowy catchments (CemaNeigesnow routine included)
Main components of the airGR package Plot diagnostics example (GR4J + CemaNeige)
Pot. evaporation computation (from temp.-based formula)
Optimization algorithm
Calibration/Validation testing procedure
Criteria for model calibration and evaluation
Outputs • Time series of simulated flows and internal
state variables • Efficiency criteria • Plot diagnostics for simulation
Inputs • Precipitation and temperature time series • Streamflow time series • Catchment size and latitude • Hypsometric curve (for snow module)
Hydrological models • GR4H (hourly) • GR4J, GR5J, GR6J (daily) • GR2M (monthly) • GR1A (annual)
Snow model • CemaNeige
7020
prec
ip. [
mm
/d]
solidliquid
01/1990 01/1991 01/1992 01/1993 01/1994 01/1995 01/1996 01/1997 01/1998 01/1999
−10
010
20
tem
p. [°
C]
meanlayers
01/1990 01/1991 01/1992 01/1993 01/1994 01/1995 01/1996 01/1997 01/1998 01/1999
040
080
012
00
snow
pac
k [m
m] mean
layers
01/1990 01/1991 01/1992 01/1993 01/1994 01/1995 01/1996 01/1997 01/1998 01/1999
05
1015
2025
flow
[mm
/d]
01/1990 01/1991 01/1992 01/1993 01/1994 01/1995 01/1996 01/1997 01/1998 01/1999
observedsimulated
150
0
Jan May Sep
015
0
30−days rolling mean
prec
ip. &
flow
reg
ime
[mm
/mon
th]
0 0.4 0.8
non−exceedance prob. [−]
0.2
15
20
flow
[m
m/d
] observedsimulated
log scale
0.2 1 5 20
0.2
15
20
observed flow [mm/d]
sim
ulat
ed fl
ow [m
m/d
]
log scale
News since EGU 2017 – airGR 1.0.9.64 vs airGR 1.0.5.12
I The Param Sets GR4J dataset was added. It contains generalist parameter sets for theGR4J model. If the calibration period is too short (< 6 months) and by consequence non
representative of the catchment behaviour, a local calibration algorithm can give poorresults and we recommend to use the generalist parameter sets instead
I Vignettes were added. They explain how to perform parameters estimation with:. Differential Evolution calibration algorithm. Particle Swarm calibration algorithm. MA-LS-Chains calibration algorithm. Bayesian MCMC framework
I A new airGRteaching package (Delaigue et al., 2018) provides tools to simplify the useof the airGR hydrological package for education, including a ’Shiny’ interface
Future developments
I New version of CemaNeige that allows to use satellite snow cover area for calibration(Riboust et al., accepted)
I Parameters maps on France for GR4J, GR5J & GR6J models for ungauged bassins(Poncelet et al., submitted)
How to use other R packages to perform parameters estimation
I Definition of the necessary function:. transformation of parameters to real space (available in airGR). computation of the value of the performance criterion (e.g. RMSE)
OptimGR4J <- function(Param_Optim) {Param_Optim_Vre <- airGR::TransfoParam_GR4J(ParamIn = Param_Optim,
Direction = "TR")
OutputsModel <- airGR::RunModel_GR4J(InputsModel = InputsModel,
RunOptions = RunOptions,
Param = Param_Optim_Vre)
OutputsCrit <- airGR::ErrorCrit_RMSE(InputsCrit = InputsCrit,
OutputsModel = OutputsModel)
return(OutputsCrit$CritValue)
}
lowerGR4J <- rep(-9.99, times = 4)
upperGR4J <- rep(+9.99, times = 4)
Local optimization
startGR4J <- c(4.1, 3.9, -0.9, -8.7)
optPORT <- stats::nlminb(start = startGR4J, objective = OptimGR4J,
lower = lowerGR4J, upper = upperGR4J,
control = list(trace = 1))
startGR4J <- expand.grid(data.frame(CalibOptions$StartParamDistrib))
optPORT_ <- function(x) {opt <- stats::nlminb(start = x, objective = OptimGR4J,
lower = lowerGR4J, upper = upperGR4J,
control = list(trace = 1))
}list_opt <- apply(startGR4J, 1, optPORT_)
summary(df_port)
Global optimizationDifferential Evolution
optDE <- DEoptim::DEoptim(fn = OptimGR4J,
lower = lowerGR4J, upper = upperGR4J,
control = DEoptim::DEoptim.control(NP = 40, trace = 10))
Particle Swarm
optPSO <- hydroPSO::hydroPSO(fn = OptimGR4J,
lower = lowerGR4J, upper = upperGR4J,
control = list(write2disk = FALSE)
MA-LS-Chains
optMALS <- Rmalschains::malschains(fn = OptimGR4J, maxEvals = 2000,
lower = lowerGR4J, upper = upperGR4J)
Results
## % latex table generated in R 3.4.2 by xtable 1.8-2 package
## % Tue Mar 27 17:21:31 2018
## \begin{table}[ht]
## \centering
## \begin{tabular}{rlrrrr}
## \hline
## & Algo & X1 & X2 & X3 & X4 \\
## \hline
## 1 & Michel & 257.00 & 1.01 & 88.20 & 2.21 \\
## 2 & PORT & 257.00 & 1.00 & 88.20 & 2.21 \\
## 3 & DE & 257.00 & 1.00 & 88.20 & 2.21 \\
1
I Definition of the lower and upper bounds of the four GR4J parameters in thetransformed parameter space
OptimGR4J <- function(Param_Optim) {Param_Optim_Vre <- airGR::TransfoParam_GR4J(ParamIn = Param_Optim,
Direction = "TR")
OutputsModel <- airGR::RunModel_GR4J(InputsModel = InputsModel,
RunOptions = RunOptions,
Param = Param_Optim_Vre)
OutputsCrit <- airGR::ErrorCrit_RMSE(InputsCrit = InputsCrit,
OutputsModel = OutputsModel)
return(OutputsCrit$CritValue)
}
lowerGR4J <- rep(-9.99, times = 4)
upperGR4J <- rep(+9.99, times = 4)
Local optimization
startGR4J <- c(4.1, 3.9, -0.9, -8.7)
optPORT <- stats::nlminb(start = startGR4J, objective = OptimGR4J,
lower = lowerGR4J, upper = upperGR4J,
control = list(trace = 1))
startGR4J <- expand.grid(data.frame(CalibOptions$StartParamDistrib))
optPORT_ <- function(x) {opt <- stats::nlminb(start = x, objective = OptimGR4J,
lower = lowerGR4J, upper = upperGR4J,
control = list(trace = 1))
}list_opt <- apply(startGR4J, 1, optPORT_)
summary(df_port)
Global optimizationDifferential Evolution
optDE <- DEoptim::DEoptim(fn = OptimGR4J,
lower = lowerGR4J, upper = upperGR4J,
control = DEoptim::DEoptim.control(NP = 40, trace = 10))
Particle Swarm
optPSO <- hydroPSO::hydroPSO(fn = OptimGR4J,
lower = lowerGR4J, upper = upperGR4J,
control = list(write2disk = FALSE)
MA-LS-Chains
optMALS <- Rmalschains::malschains(fn = OptimGR4J, maxEvals = 2000,
lower = lowerGR4J, upper = upperGR4J)
Results
## % latex table generated in R 3.4.2 by xtable 1.8-2 package
## % Tue Mar 27 17:21:31 2018
## \begin{table}[ht]
## \centering
## \begin{tabular}{rlrrrr}
## \hline
## & Algo & X1 & X2 & X3 & X4 \\
## \hline
## 1 & Michel & 257.00 & 1.01 & 88.20 & 2.21 \\
## 2 & PORT & 257.00 & 1.00 & 88.20 & 2.21 \\
## 3 & DE & 257.00 & 1.00 & 88.20 & 2.21 \\
1
I Local optimisation. Single-start (here) or multi-start approach to test the consistency of the local
optimisation
OptimGR4J <- function(Param_Optim) {Param_Optim_Vre <- airGR::TransfoParam_GR4J(ParamIn = Param_Optim,
Direction = "TR")
OutputsModel <- airGR::RunModel_GR4J(InputsModel = InputsModel,
RunOptions = RunOptions,
Param = Param_Optim_Vre)
OutputsCrit <- airGR::ErrorCrit_RMSE(InputsCrit = InputsCrit,
OutputsModel = OutputsModel)
return(OutputsCrit$CritValue)
}
lowerGR4J <- rep(-9.99, times = 4)
upperGR4J <- rep(+9.99, times = 4)
Local optimization
startGR4J <- c(4.1, 3.9, -0.9, -8.7)
optPORT <- stats::nlminb(start = startGR4J, objective = OptimGR4J,
lower = lowerGR4J, upper = upperGR4J,
control = list(trace = 1))
startGR4J <- expand.grid(data.frame(CalibOptions$StartParamDistrib))
optPORT_ <- function(x) {opt <- stats::nlminb(start = x, objective = OptimGR4J,
lower = lowerGR4J, upper = upperGR4J,
control = list(trace = 1))
}list_opt <- apply(startGR4J, 1, optPORT_)
summary(df_port)
Global optimizationDifferential Evolution
optDE <- DEoptim::DEoptim(fn = OptimGR4J,
lower = lowerGR4J, upper = upperGR4J,
control = DEoptim::DEoptim.control(NP = 40, trace = 10))
Particle Swarm
optPSO <- hydroPSO::hydroPSO(fn = OptimGR4J,
lower = lowerGR4J, upper = upperGR4J,
control = list(write2disk = FALSE)
MA-LS-Chains
optMALS <- Rmalschains::malschains(fn = OptimGR4J, maxEvals = 2000,
lower = lowerGR4J, upper = upperGR4J)
Results
## % latex table generated in R 3.4.2 by xtable 1.8-2 package
## % Tue Mar 27 17:21:31 2018
## \begin{table}[ht]
## \centering
## \begin{tabular}{rlrrrr}
## \hline
## & Algo & X1 & X2 & X3 & X4 \\
## \hline
## 1 & Michel & 257.00 & 1.01 & 88.20 & 2.21 \\
## 2 & PORT & 257.00 & 1.00 & 88.20 & 2.21 \\
## 3 & DE & 257.00 & 1.00 & 88.20 & 2.21 \\
1
I Global optimisationMost often used when facing a complex response surface, with multiple local mimina. Differential Evolution
OptimGR4J <- function(Param_Optim) {Param_Optim_Vre <- airGR::TransfoParam_GR4J(ParamIn = Param_Optim,
Direction = "TR")
OutputsModel <- airGR::RunModel_GR4J(InputsModel = InputsModel,
RunOptions = RunOptions,
Param = Param_Optim_Vre)
OutputsCrit <- airGR::ErrorCrit_RMSE(InputsCrit = InputsCrit,
OutputsModel = OutputsModel)
return(OutputsCrit$CritValue)
}
lowerGR4J <- rep(-9.99, times = 4)
upperGR4J <- rep(+9.99, times = 4)
Local optimization
startGR4J <- c(4.1, 3.9, -0.9, -8.7)
optPORT <- stats::nlminb(start = startGR4J, objective = OptimGR4J,
lower = lowerGR4J, upper = upperGR4J,
control = list(trace = 1))
startGR4J <- expand.grid(data.frame(CalibOptions$StartParamDistrib))
optPORT_ <- function(x) {opt <- stats::nlminb(start = x, objective = OptimGR4J,
lower = lowerGR4J, upper = upperGR4J,
control = list(trace = 1))
}list_opt <- apply(startGR4J, 1, optPORT_)
summary(df_port)
Global optimizationDifferential Evolution
optDE <- DEoptim::DEoptim(fn = OptimGR4J,
lower = lowerGR4J, upper = upperGR4J,
control = DEoptim::DEoptim.control(NP = 40, trace = 10))
Particle Swarm
optPSO <- hydroPSO::hydroPSO(fn = OptimGR4J,
lower = lowerGR4J, upper = upperGR4J,
control = list(write2disk = FALSE)
MA-LS-Chains
optMALS <- Rmalschains::malschains(fn = OptimGR4J, maxEvals = 2000,
lower = lowerGR4J, upper = upperGR4J)
Results
## % latex table generated in R 3.4.2 by xtable 1.8-2 package
## % Tue Mar 27 17:21:31 2018
## \begin{table}[ht]
## \centering
## \begin{tabular}{rlrrrr}
## \hline
## & Algo & X1 & X2 & X3 & X4 \\
## \hline
## 1 & Michel & 257.00 & 1.01 & 88.20 & 2.21 \\
## 2 & PORT & 257.00 & 1.00 & 88.20 & 2.21 \\
## 3 & DE & 257.00 & 1.00 & 88.20 & 2.21 \\
1
. Particle Swarm
OptimGR4J <- function(Param_Optim) {Param_Optim_Vre <- airGR::TransfoParam_GR4J(ParamIn = Param_Optim,
Direction = "TR")
OutputsModel <- airGR::RunModel_GR4J(InputsModel = InputsModel,
RunOptions = RunOptions,
Param = Param_Optim_Vre)
OutputsCrit <- airGR::ErrorCrit_RMSE(InputsCrit = InputsCrit,
OutputsModel = OutputsModel)
return(OutputsCrit$CritValue)
}
lowerGR4J <- rep(-9.99, times = 4)
upperGR4J <- rep(+9.99, times = 4)
Local optimization
startGR4J <- c(4.1, 3.9, -0.9, -8.7)
optPORT <- stats::nlminb(start = startGR4J, objective = OptimGR4J,
lower = lowerGR4J, upper = upperGR4J,
control = list(trace = 1))
startGR4J <- expand.grid(data.frame(CalibOptions$StartParamDistrib))
optPORT_ <- function(x) {opt <- stats::nlminb(start = x, objective = OptimGR4J,
lower = lowerGR4J, upper = upperGR4J,
control = list(trace = 1))
}list_opt <- apply(startGR4J, 1, optPORT_)
summary(df_port)
Global optimizationDifferential Evolution
optDE <- DEoptim::DEoptim(fn = OptimGR4J,
lower = lowerGR4J, upper = upperGR4J,
control = DEoptim::DEoptim.control(NP = 40, trace = 10))
Particle Swarm
optPSO <- hydroPSO::hydroPSO(fn = OptimGR4J,
lower = lowerGR4J, upper = upperGR4J,
control = list(write2disk = FALSE)
MA-LS-Chains
optMALS <- Rmalschains::malschains(fn = OptimGR4J, maxEvals = 2000,
lower = lowerGR4J, upper = upperGR4J)
Results
## % latex table generated in R 3.4.2 by xtable 1.8-2 package
## % Tue Mar 27 17:21:31 2018
## \begin{table}[ht]
## \centering
## \begin{tabular}{rlrrrr}
## \hline
## & Algo & X1 & X2 & X3 & X4 \\
## \hline
## 1 & Michel & 257.00 & 1.01 & 88.20 & 2.21 \\
## 2 & PORT & 257.00 & 1.00 & 88.20 & 2.21 \\
## 3 & DE & 257.00 & 1.00 & 88.20 & 2.21 \\
1
. MA-LS-Chains
OptimGR4J <- function(Param_Optim) {Param_Optim_Vre <- airGR::TransfoParam_GR4J(ParamIn = Param_Optim,
Direction = "TR")
OutputsModel <- airGR::RunModel_GR4J(InputsModel = InputsModel,
RunOptions = RunOptions,
Param = Param_Optim_Vre)
OutputsCrit <- airGR::ErrorCrit_RMSE(InputsCrit = InputsCrit,
OutputsModel = OutputsModel)
return(OutputsCrit$CritValue)
}
lowerGR4J <- rep(-9.99, times = 4)
upperGR4J <- rep(+9.99, times = 4)
Local optimization
startGR4J <- c(4.1, 3.9, -0.9, -8.7)
optPORT <- stats::nlminb(start = startGR4J, objective = OptimGR4J,
lower = lowerGR4J, upper = upperGR4J,
control = list(trace = 1))
startGR4J <- expand.grid(data.frame(CalibOptions$StartParamDistrib))
optPORT_ <- function(x) {opt <- stats::nlminb(start = x, objective = OptimGR4J,
lower = lowerGR4J, upper = upperGR4J,
control = list(trace = 1))
}list_opt <- apply(startGR4J, 1, optPORT_)
summary(df_port)
Global optimizationDifferential Evolution
optDE <- DEoptim::DEoptim(fn = OptimGR4J,
lower = lowerGR4J, upper = upperGR4J,
control = DEoptim::DEoptim.control(NP = 40, trace = 10))
Particle Swarm
optPSO <- hydroPSO::hydroPSO(fn = OptimGR4J,
lower = lowerGR4J, upper = upperGR4J,
control = list(write2disk = FALSE)
MA-LS-Chains
optMALS <- Rmalschains::malschains(fn = OptimGR4J, maxEvals = 2000,
lower = lowerGR4J, upper = upperGR4J)
Results
## % latex table generated in R 3.4.2 by xtable 1.8-2 package
## % Tue Mar 27 17:21:31 2018
## \begin{table}[ht]
## \centering
## \begin{tabular}{rlrrrr}
## \hline
## & Algo & X1 & X2 & X3 & X4 \\
## \hline
## 1 & Michel & 257.00 & 1.01 & 88.20 & 2.21 \\
## 2 & PORT & 257.00 & 1.00 & 88.20 & 2.21 \\
## 3 & DE & 257.00 & 1.00 & 88.20 & 2.21 \\
1
I Results
Algo X1 X2 X3 X4 RMSE CPU
airGR 257.238 1.012 88.235 2.208 0.7852 00.53 s
PORT 256.808 1.004 88.167 2.205 0.7852 01.79 s
DE 256.808 1.004 88.167 2.205 0.7852 75.10 s
PSO 256.836 1.006 88.207 2.204 0.7852 29.55 s
MA-LS 256.808 1.004 88.167 2.205 0.7852 18.42 s
Download the airGR package
The airGR package is available on the Comprehensive Archive Network:https://CRAN.R-project.org/package=airGR/
Evolution of 3 Markov chains & posterior density for each parameter
X4
X3
X2
X1
0 500 1000 1500 2000
0 500 1000 1500 2000
0 500 1000 1500 2000
0 500 1000 1500 2000
200
300
400
0.8
1.0
1.2
1.4
60
80
100
120
140
1.5
2.0
2.5
3.0
Iteration
valu
e
X4
X3
X2
X1
2.15 2.20 2.25 2.30
84 88 92 96
0.9 1.0 1.1
230 240 250 260 270 280
0.00
0.02
0.04
0.06
0.0
2.5
5.0
7.5
0.00
0.05
0.10
0.15
0.20
0
5
10
15
value
dens
ity
References
I Coron, L., Thirel, G., Delaigue, O., Perrin, C. & Andreassian, V. (2017). The suite of lumped GRhydrological models in an R package. Environmental Modelling & Software 94, 166–171. DOI:10.1016/j.envsoft.2017.05.002.
I Coron L., Perrin C., Delaigue, O., Thirel, G. & Michel C. (2017). airGR: Suite of GR Hydrological Modelsfor Precipitation-Runoff Modelling. R package version 1.0.9.64. URL:https://webgr.irstea.fr/en/airGR/.
I Delaigue, O., Coron, L. & Brigode, P. (2018). airGRteaching: Teaching Hydrological Modelling with theGR Rainfall-Runoff Models (’Shiny’ Interface Included). R package version 0.2.2.2. URL:https://webgr.irstea.fr/en/airGR/.
I Poncelet, C., Andreassian, V., & Oudin, L. (submitterd). Regionalization of Hydrological Models byGroup Calibration. Water Resources Research.
I Riboust, P., Thirel, G., Le Moine, N. & Ribstein, P. (accepted). Revisiting a simple degree-day model for
integrating satellite data: implementation of SWE-SCA hystereses. Journal of Hydrology and
Hydrodynamics, DOI: 10.2478/johh-2018-0004.
National Research Instituteof Science and Technology
for Environment and Agriculture
HYDRO
Olivier Delaigue <[email protected]> EGU General Assembly 2018 - 8-13 April 2018 - Vienna (Austria) - EGU2018-13049 | HS3.1 airGR Development Team <[email protected]>