From dd7c0dbb4a18b8148aa706c939139d135856631e Mon Sep 17 00:00:00 2001 From: Thirel Guillaume <guillaume.thirel@inrae.fr> Date: Thu, 30 Apr 2020 15:04:45 +0200 Subject: [PATCH] feat: Modification of Michel's calibration for SD models Refs #34 --- NAMESPACE | 1 + R/Calibration_Michel.R | 107 +++++++++++++++++++++++++++++------------ R/CreateCalibOptions.R | 98 ++++++++++++++++++++++++++++++++----- R/TransfoParam_LAG.R | 39 +++++++++++++++ 4 files changed, 203 insertions(+), 42 deletions(-) create mode 100644 R/TransfoParam_LAG.R diff --git a/NAMESPACE b/NAMESPACE index 17665070..858dd293 100644 --- a/NAMESPACE +++ b/NAMESPACE @@ -56,6 +56,7 @@ export(TransfoParam_GR5H) export(TransfoParam_GR4J) export(TransfoParam_GR5J) export(TransfoParam_GR6J) +export(TransfoParam_LAG) export(plot.OutputsModel) exportPattern(".FortranOutputs") exportPattern(".ErrorCrit") diff --git a/R/Calibration_Michel.R b/R/Calibration_Michel.R index 759630ea..dc813358 100644 --- a/R/Calibration_Michel.R +++ b/R/Calibration_Michel.R @@ -57,27 +57,31 @@ Calibration_Michel <- function(InputsModel, ##_check_FUN_TRANSFO if (is.null(FUN_TRANSFO)) { - if (identical(FUN_MOD, RunModel_GR4H )) { - FUN_TRANSFO <- TransfoParam_GR4H + if (identical(FUN_MOD, RunModel_GR4H) | identical(FUN_MOD, RunModel_CemaNeigeGR4H)) { + FUN1 <- TransfoParam_GR4H } - if (identical(FUN_MOD, RunModel_GR5H )) { - FUN_TRANSFO <- TransfoParam_GR5H + if (identical(FUN_MOD, RunModel_GR5H) | identical(FUN_MOD, RunModel_CemaNeigeGR5H)) { + FUN1 <- TransfoParam_GR5H } - if (identical(FUN_MOD, RunModel_GR4J )) { - FUN_TRANSFO <- TransfoParam_GR4J + if (identical(FUN_MOD, RunModel_GR4J) | identical(FUN_MOD, RunModel_CemaNeigeGR4J)) { + FUN1 <- TransfoParam_GR4J } - if (identical(FUN_MOD, RunModel_GR5J )) { - FUN_TRANSFO <- TransfoParam_GR5J + if (identical(FUN_MOD, RunModel_GR5J) | identical(FUN_MOD, RunModel_CemaNeigeGR5J)) { + FUN1 <- TransfoParam_GR5J } - if (identical(FUN_MOD, RunModel_GR6J )) { - FUN_TRANSFO <- TransfoParam_GR6J + if (identical(FUN_MOD, RunModel_GR6J) | identical(FUN_MOD, RunModel_CemaNeigeGR6J)) { + FUN1 <- TransfoParam_GR6J } - if (identical(FUN_MOD, RunModel_GR2M )) { - FUN_TRANSFO <- TransfoParam_GR2M + if (identical(FUN_MOD, RunModel_GR2M )) { + FUN1 <- TransfoParam_GR2M } - if (identical(FUN_MOD, RunModel_GR1A )) { - FUN_TRANSFO <- TransfoParam_GR1A + if (identical(FUN_MOD, RunModel_GR1A )) { + FUN1 <- TransfoParam_GR1A } + ##_set_FUN_LAG + if (inherits(CalibOptions, "SD")) { + FUN_LAG <- TransfoParam_LAG + } if (identical(FUN_MOD, RunModel_CemaNeige )) { if (inherits(CalibOptions, "hysteresis")) { FUN_TRANSFO <- TransfoParam_CemaNeigeHyst @@ -85,29 +89,35 @@ Calibration_Michel <- function(InputsModel, FUN_TRANSFO <- TransfoParam_CemaNeige } } + if (identical(FUN_MOD, RunModel_GR4H) | identical(FUN_MOD, RunModel_GR5H) | + identical(FUN_MOD, RunModel_GR4J) | identical(FUN_MOD, RunModel_GR5J) | identical(FUN_MOD, RunModel_GR6J)) { + if (!inherits(CalibOptions, "SD")) { + FUN_TRANSFO <- FUN1 + } else { + FUN_TRANSFO <- function(ParamIn, Direction) { + Bool <- is.matrix(ParamIn) + if (!Bool) { + ParamIn <- rbind(ParamIn) + } + ParamOut <- NA * ParamIn + NParam <- ncol(ParamIn) + ParamOut[, 1:(NParam-1)] <- FUN1(ParamIn[, 1:(NParam-1)], Direction) + ParamOut[, NParam ] <- FUN_LAG(ParamIn[, NParam ], Direction) + if (!Bool) { + ParamOut <- ParamOut[1, ] + } + return(ParamOut) + } + } + } if (identical(FUN_MOD, RunModel_CemaNeigeGR4H) | identical(FUN_MOD, RunModel_CemaNeigeGR5H) | identical(FUN_MOD, RunModel_CemaNeigeGR4J) | identical(FUN_MOD, RunModel_CemaNeigeGR5J) | identical(FUN_MOD, RunModel_CemaNeigeGR6J)) { - if (identical(FUN_MOD, RunModel_CemaNeigeGR4H)) { - FUN1 <- TransfoParam_GR4H - } - if (identical(FUN_MOD, RunModel_CemaNeigeGR5H)) { - FUN1 <- TransfoParam_GR5H - } - if (identical(FUN_MOD, RunModel_CemaNeigeGR4J)) { - FUN1 <- TransfoParam_GR4J - } - if (identical(FUN_MOD, RunModel_CemaNeigeGR5J)) { - FUN1 <- TransfoParam_GR5J - } - if (identical(FUN_MOD, RunModel_CemaNeigeGR6J)) { - FUN1 <- TransfoParam_GR6J - } if (inherits(CalibOptions, "hysteresis")) { FUN2 <- TransfoParam_CemaNeigeHyst } else { FUN2 <- TransfoParam_CemaNeige } - if (inherits(CalibOptions, "hysteresis")) { + if (inherits(CalibOptions, "hysteresis") & !inherits(CalibOptions, "SD")) { FUN_TRANSFO <- function(ParamIn, Direction) { Bool <- is.matrix(ParamIn) if (!Bool) { @@ -122,7 +132,8 @@ Calibration_Michel <- function(InputsModel, } return(ParamOut) } - } else { + } + if (!inherits(CalibOptions, "hysteresis") & !inherits(CalibOptions, "SD")) { FUN_TRANSFO <- function(ParamIn, Direction) { Bool <- is.matrix(ParamIn) if (!Bool) { @@ -138,6 +149,40 @@ Calibration_Michel <- function(InputsModel, return(ParamOut) } } + if (inherits(CalibOptions, "hysteresis") & inherits(CalibOptions, "SD")) { + FUN_TRANSFO <- function(ParamIn, Direction) { + Bool <- is.matrix(ParamIn) + if (!Bool) { + ParamIn <- rbind(ParamIn) + } + ParamOut <- NA * ParamIn + NParam <- ncol(ParamIn) + ParamOut[, 1:(NParam-5)] <- FUN1( ParamIn[, 1:(NParam-5)], Direction) + ParamOut[, (NParam-4):(NParam-1)] <- FUN2( ParamIn[, (NParam-4):(NParam-1)], Direction) + ParamOut[, NParam ] <- FUN_LAG(ParamIn[, NParam ], Direction) + if (!Bool) { + ParamOut <- ParamOut[1, ] + } + return(ParamOut) + } + } + if (!inherits(CalibOptions, "hysteresis") & inherits(CalibOptions, "SD")) { + FUN_TRANSFO <- function(ParamIn, Direction) { + Bool <- is.matrix(ParamIn) + if (!Bool) { + ParamIn <- rbind(ParamIn) + } + ParamOut <- NA * ParamIn + NParam <- ncol(ParamIn) + ParamOut[, 1:(NParam-3)] <- FUN1( ParamIn[, 1:(NParam-3)], Direction) + ParamOut[, (NParam-2):(NParam-1)] <- FUN2( ParamIn[, (NParam-2):(NParam-1)], Direction) + ParamOut[, NParam ] <- FUN_LAG(ParamIn[, NParam ], Direction) + if (!Bool) { + ParamOut <- ParamOut[1, ] + } + return(ParamOut) + } + } } if (is.null(FUN_TRANSFO)) { diff --git a/R/CreateCalibOptions.R b/R/CreateCalibOptions.R index 56dedd96..b3475e84 100644 --- a/R/CreateCalibOptions.R +++ b/R/CreateCalibOptions.R @@ -2,6 +2,7 @@ CreateCalibOptions <- function(FUN_MOD, FUN_CALIB = Calibration_Michel, FUN_TRANSFO = NULL, IsHyst = FALSE, + IsSD = FALSE, FixedParam = NULL, SearchRanges = NULL, StartParamList = NULL, @@ -17,6 +18,9 @@ CreateCalibOptions <- function(FUN_MOD, if (!is.logical(IsHyst) | length(IsHyst) != 1L) { stop("'IsHyst' must be a logical of length 1") } + if (!is.logical(IsSD) | length(IsSD) != 1L) { + stop("'IsSD' must be a logical of length 1") + } ##check_FUN_MOD BOOL <- FALSE @@ -75,6 +79,9 @@ CreateCalibOptions <- function(FUN_MOD, if (IsHyst) { ObjectClass <- c(ObjectClass, "hysteresis") } + if (IsSD) { + ObjectClass <- c(ObjectClass, "SD") + } if (!BOOL) { stop("incorrect 'FUN_MOD' for use in 'CreateCalibOptions'") return(NULL) @@ -139,11 +146,32 @@ CreateCalibOptions <- function(FUN_MOD, } else { FUN2 <- TransfoParam_CemaNeige } + ##_set_FUN_LAG + if (IsSD) { + FUN_LAG <- TransfoParam_LAG + } ##_set_FUN_TRANSFO if (sum(ObjectClass %in% c("GR4H", "GR5H", "GR4J", "GR5J", "GR6J", "GR2M", "GR1A", "CemaNeige")) > 0) { - FUN_TRANSFO <- FUN1 + if (!IsSD) { + FUN_TRANSFO <- FUN1 + } else { + FUN_TRANSFO <- function(ParamIn, Direction) { + Bool <- is.matrix(ParamIn) + if (!Bool) { + ParamIn <- rbind(ParamIn) + } + ParamOut <- NA * ParamIn + NParam <- ncol(ParamIn) + ParamOut[, 1:(NParam-1)] <- FUN1(ParamIn[, 1:(NParam-1)], Direction) + ParamOut[, NParam ] <- FUN_LAG(ParamIn[, NParam ], Direction) + if (!Bool) { + ParamOut <- ParamOut[1, ] + } + return(ParamOut) + } + } } else { - if (IsHyst) { + if (IsHyst & !IsSD) { FUN_TRANSFO <- function(ParamIn, Direction) { Bool <- is.matrix(ParamIn) if (!Bool) { @@ -151,14 +179,15 @@ CreateCalibOptions <- function(FUN_MOD, } ParamOut <- NA * ParamIn NParam <- ncol(ParamIn) - ParamOut[, 1:(NParam - 4)] <- FUN1(ParamIn[, 1:(NParam - 4)], Direction) + ParamOut[, 1:(NParam - 4) ] <- FUN1(ParamIn[, 1:(NParam - 4) ], Direction) ParamOut[, (NParam - 3):NParam] <- FUN2(ParamIn[, (NParam - 3):NParam], Direction) if (!Bool) { ParamOut <- ParamOut[1, ] } return(ParamOut) } - } else { + } + if (!IsHyst & !IsSD) { FUN_TRANSFO <- function(ParamIn, Direction) { Bool <- is.matrix(ParamIn) if (!Bool) { @@ -169,7 +198,7 @@ CreateCalibOptions <- function(FUN_MOD, if (NParam <= 3) { ParamOut[, 1:(NParam - 2)] <- FUN1(cbind(ParamIn[, 1:(NParam - 2)]), Direction) } else { - ParamOut[, 1:(NParam - 2)] <- FUN1(ParamIn[, 1:(NParam - 2)], Direction) + ParamOut[, 1:(NParam - 2)] <- FUN1( ParamIn[, 1:(NParam - 2)], Direction) } ParamOut[, (NParam - 1):NParam] <- FUN2(ParamIn[, (NParam - 1):NParam], Direction) if (!Bool) { @@ -178,6 +207,44 @@ CreateCalibOptions <- function(FUN_MOD, return(ParamOut) } } + if (IsHyst & IsSD) { + FUN_TRANSFO <- function(ParamIn, Direction) { + Bool <- is.matrix(ParamIn) + if (!Bool) { + ParamIn <- rbind(ParamIn) + } + ParamOut <- NA * ParamIn + NParam <- ncol(ParamIn) + ParamOut[, 1:(NParam - 5) ] <- FUN1( ParamIn[, 1:(NParam - 5) ], Direction) + ParamOut[, (NParam - 4):(NParam - 1)] <- FUN2( ParamIn[, (NParam - 4):(NParam - 1)], Direction) + ParamOut[, NParam ] <- FUN_LAG(ParamIn[, NParam ], Direction) + if (!Bool) { + ParamOut <- ParamOut[1, ] + } + return(ParamOut) + } + } + if (!IsHyst & IsSD) { + FUN_TRANSFO <- function(ParamIn, Direction) { + Bool <- is.matrix(ParamIn) + if (!Bool) { + ParamIn <- rbind(ParamIn) + } + ParamOut <- NA * ParamIn + NParam <- ncol(ParamIn) + if (NParam <= 3) { + ParamOut[, 1:(NParam - 3)] <- FUN1(cbind(ParamIn[, 1:(NParam - 3)]), Direction) + } else { + ParamOut[, 1:(NParam - 3)] <- FUN1( ParamIn[, 1:(NParam - 3)], Direction) + } + ParamOut[, (NParam - 2):(NParam - 1)] <- FUN2( ParamIn[, (NParam - 2):(NParam - 1)], Direction) + ParamOut[, NParam ] <- FUN_LAG(ParamIn[, NParam], Direction) + if (!Bool) { + ParamOut <- ParamOut[1, ] + } + return(ParamOut) + } + } } } if (is.null(FUN_TRANSFO)) { @@ -228,6 +295,9 @@ CreateCalibOptions <- function(FUN_MOD, if (IsHyst) { NParam <- NParam + 2 } + if (IsSD) { + NParam <- NParam + 1 + } ##check_FixedParam if (is.null(FixedParam)) { @@ -276,22 +346,22 @@ CreateCalibOptions <- function(FUN_MOD, if ("GR4H" %in% ObjectClass) { ParamT <- matrix(c(+5.12, -1.18, +4.34, -9.69, +5.58, -0.85, +4.74, -9.47, - +6.01, -0.50, +5.14, -8.87), ncol = 4, byrow = TRUE) + +6.01, -0.50, +5.14, -8.87), ncol = 4, byrow = TRUE) } if (("GR5H" %in% ObjectClass) & ("interception" %in% ObjectClass)) { ParamT <- matrix(c(+3.46, -1.25, +4.04, -9.53, -9.34, +3.74, -0.41, +4.78, -8.94, -3.33, - +4.29, +0.16, +5.39, -7.39, +3.33),ncol=5,byrow=TRUE); + +4.29, +0.16, +5.39, -7.39, +3.33), ncol=5, byrow = TRUE); } if (("GR5H" %in% ObjectClass) & !("interception" %in% ObjectClass)) { ParamT <- matrix(c(+3.28, -0.39, +4.14, -9.54, -7.49, +3.62, -0.19, +4.80, -9.00, -6.31, - +4.01, -0.04, +5.43, -7.53, -5.33), ncol=5,byrow=TRUE); + +4.01, -0.04, +5.43, -7.53, -5.33), ncol=5, byrow = TRUE); } if ("GR4J" %in% ObjectClass) { ParamT <- matrix(c(+5.13, -1.60, +3.03, -9.05, +5.51, -0.61, +3.74, -8.51, - +6.07, -0.02, +4.42, -8.06), ncol = 4, byrow = TRUE) + +6.07, -0.02, +4.42, -8.06), ncol = 4, byrow = TRUE) } if ("GR5J" %in% ObjectClass) { ParamT <- matrix(c(+5.17, -1.13, +3.08, -9.37, -7.45, @@ -329,12 +399,12 @@ CreateCalibOptions <- function(FUN_MOD, if (("CemaNeigeGR5H" %in% ObjectClass) & ("interception" %in% ObjectClass)) { ParamT <- matrix(c(+3.46, -1.25, +4.04, -9.53, -9.34, -9.96, +6.63, +3.74, -0.41, +4.78, -8.94, -3.33, -9.14, +6.90, - +4.29, +0.16, +5.39, -7.39, +3.33, +4.10, +7.21),ncol=7,byrow=TRUE); + +4.29, +0.16, +5.39, -7.39, +3.33, +4.10, +7.21), ncol = 7, byrow = TRUE); } if (("CemaNeigeGR5H" %in% ObjectClass) & !("interception" %in% ObjectClass)) { ParamT <- matrix(c(+3.28, -0.39, +4.14, -9.54, -7.49, -9.96, +6.63, +3.62, -0.19, +4.80, -9.00, -6.31, -9.14, +6.90, - +4.01, -0.04, +5.43, -7.53, -5.33, +4.10, +7.21), ncol=7,byrow=TRUE); + +4.01, -0.04, +5.43, -7.53, -5.33, +4.10, +7.21), ncol = 7, byrow = TRUE); } if ("CemaNeigeGR4J" %in% ObjectClass) { ParamT <- matrix(c(+5.13, -1.60, +3.03, -9.05, -9.96, +6.63, @@ -358,6 +428,12 @@ CreateCalibOptions <- function(FUN_MOD, +7.00, +7.00), ncol = 2, byrow = TRUE) ParamT <- cbind(ParamT, ParamTHyst) } + if (IsSD) { + ParamTSD <- matrix(c(+1.25, + +2.50, + +5.00), ncol = 1, byrow = TRUE) + ParamT <- cbind(ParamT, ParamTSD) + } StartParamList <- NULL StartParamDistrib <- TransfoParam(ParamIn = ParamT, Direction = "TR", FUN_TRANSFO = FUN_TRANSFO) diff --git a/R/TransfoParam_LAG.R b/R/TransfoParam_LAG.R new file mode 100644 index 00000000..c484bf78 --- /dev/null +++ b/R/TransfoParam_LAG.R @@ -0,0 +1,39 @@ +TransfoParam_LAG <- function(ParamIn, Direction) { + + ## number of model parameters + NParam <- 1L + + + ## check arguments + isVecParamIn <- is.vector(ParamIn) + if (isVecParamIn) { + ParamIn <- matrix(ParamIn, nrow = 1) + } + if (!inherits(ParamIn, "matrix")) { + stop("'ParamIn' must be of class 'matrix'") + } + if (!inherits(Direction, "character") | length(Direction) != 1 | any(!Direction %in% c("RT", "TR"))) { + stop("'Direction' must be a character vector of length 1 equal to 'RT' or 'TR'") + } + if (ncol(ParamIn) != NParam) { + stop(sprintf("the LAG model requires %i parameters", NParam)) + } + + + ## transformation + if (Direction == "TR") { + ParamOut <- 20 * (ParamIn + 10) / 20.0 + } + if (Direction == "RT") { + ParamOut <- ParamIn * 20.0 / 20 - 10 + } + + + ## check output + if (isVecParamIn) { + ParamOut <- as.vector(ParamOut) + } + + return(ParamOut) + +} -- GitLab