diff --git a/R/Calibration.R b/R/Calibration.R index 319dbb4b2f9d083f64631e49dc1b65953012e434..e4fc1984fad39839755ebd90ee3f900b76c7a9e5 100644 --- a/R/Calibration.R +++ b/R/Calibration.R @@ -3,7 +3,6 @@ Calibration <- function(InputsModel, InputsCrit, CalibOptions, FUN_MOD, - FUN_SD, FUN_CRIT, # deprecated FUN_CALIB = Calibration_Michel, FUN_TRANSFO = NULL, @@ -23,7 +22,7 @@ Calibration <- function(InputsModel, } return(FUN_CALIB(InputsModel = InputsModel, RunOptions = RunOptions, InputsCrit = InputsCrit, CalibOptions = CalibOptions, - FUN_MOD = FUN_MOD, FUN_SD, FUN_TRANSFO = FUN_TRANSFO, + FUN_MOD = FUN_MOD, FUN_TRANSFO = FUN_TRANSFO, verbose = verbose, ...)) } diff --git a/R/Calibration_Michel.R b/R/Calibration_Michel.R index 8a59765e57dfd2f28bbd0fe2d3b0af9e6d4e554d..c7119cba1a00fbcef54e38d7a499b46418a28f75 100644 --- a/R/Calibration_Michel.R +++ b/R/Calibration_Michel.R @@ -3,7 +3,6 @@ Calibration_Michel <- function(InputsModel, InputsCrit, CalibOptions, FUN_MOD, - FUN_SD, FUN_CRIT, # deprecated FUN_TRANSFO = NULL, verbose = TRUE, @@ -148,7 +147,7 @@ Calibration_Michel <- function(InputsModel, } ##Model_run Param <- CandidatesParamR[iNew, ] - OutputsModel <- RunModel(InputsModel, RunOptions, Param, FUN_MOD = FUN_MOD, FUN_SD = FUN_SD,...) + OutputsModel <- RunModel(InputsModel, RunOptions, Param, FUN_MOD = FUN_MOD, FUN_SD = RunOptions$FUN_SD,...) ##Calibration_criterion_computation OutputsCrit <- ErrorCrit(InputsCrit, OutputsModel, verbose = FALSE) diff --git a/R/CreateCalibOptions.R b/R/CreateCalibOptions.R index 8a2e9a3bbeae5bc0262a719c8db547f01c0df6de..a7b0810feaecf4b4737a0d661b0d8fe9cddbb6cb 100644 --- a/R/CreateCalibOptions.R +++ b/R/CreateCalibOptions.R @@ -64,7 +64,7 @@ CreateCalibOptions <- function(FUN_MOD, NParam <- NParam + 2 } if (IsSD) { - NParam <- NParam + FeatFUN_MOD$ParamSD + NParam <- NParam + FeatFUN_MOD$NParamSD } ## check FixedParam @@ -204,6 +204,12 @@ CreateCalibOptions <- function(FUN_MOD, +5.00), ncol = 1, byrow = TRUE) ParamT <- cbind(ParamTSD, ParamT) } + if (identical(RunModel_LLR, FUN_SD)){ + ParamTSD <- matrix(c(+1.25, +1.25 + +2.50, +2.50, + +5.00, +5.00), ncol = 2, byrow = TRUE) + ParamT <- cbind(ParamTSD, ParamT) + } } StartParamList <- NULL StartParamDistrib <- TransfoParam(ParamIn = ParamT, Direction = "TR", FUN_TRANSFO = FUN_TRANSFO) diff --git a/R/CreateRunOptions.R b/R/CreateRunOptions.R index 76daea77263c05c010abdbc74805b47120bf260a..9a8b4e9082ce32dbccdb775761f141b2ba05a199 100644 --- a/R/CreateRunOptions.R +++ b/R/CreateRunOptions.R @@ -44,7 +44,7 @@ CreateRunOptions <- function(FUN_MOD, InputsModel, ## SD model FeatFUN_MOD$IsSD <- inherits(InputsModel, "SD") if (FeatFUN_MOD$IsSD) { - FeatFUN_MOD$NbParam <- FeatFUN_MOD$NbParam + FeatFUN_MOD$ParamSD + FeatFUN_MOD$NbParam <- FeatFUN_MOD$NbParam + FeatFUN_MOD$NParamSD } if (!"CemaNeige" %in% ObjectClass & "hysteresis" %in% ObjectClass) { @@ -466,7 +466,8 @@ CreateRunOptions <- function(FUN_MOD, InputsModel, Outputs_Cal = Outputs_Cal, Outputs_Sim = Outputs_Sim, FortranOutputs = FortranOutputs, - FeatFUN_MOD = FeatFUN_MOD) + FeatFUN_MOD = FeatFUN_MOD, + FUN_SD = FUN_SD) if ("CemaNeige" %in% ObjectClass) { RunOptions <- c(RunOptions, list(MeanAnSolidPrecip = MeanAnSolidPrecip)) diff --git a/R/RunModel.R b/R/RunModel.R index 378f87e3f7963dc3f9809c5b161f9dfb4f882ca1..685cfbe9f2c96f731e7372a2f5101f691da4a1b9 100644 --- a/R/RunModel.R +++ b/R/RunModel.R @@ -4,8 +4,8 @@ RunModel <- function(InputsModel, RunOptions, Param, FUN_MOD, FUN_SD = RunModel_ if (inherits(InputsModel, "SD") && !identical(FUN_MOD, FUN_SD)) { # Lag model take one parameter at the beginning of the vector - iFirstParamRunOffModel <- RunOptions$FeatFUN_MOD$ParamSD + 1 - RunOptions$FeatFUN_MOD$NbParam <- RunOptions$FeatFUN_MOD$NbParam - RunOptions$FeatFUN_MOD$ParamSD + iFirstParamRunOffModel <- RunOptions$FeatFUN_MOD$NParamSD + 1 + RunOptions$FeatFUN_MOD$NbParam <- RunOptions$FeatFUN_MOD$NbParam - RunOptions$FeatFUN_MOD$NParamSD } else { # All parameters iFirstParamRunOffModel <- 1 @@ -14,7 +14,7 @@ RunModel <- function(InputsModel, RunOptions, Param, FUN_MOD, FUN_SD = RunModel_ Param = Param[iFirstParamRunOffModel:length(Param)], ...) if (inherits(InputsModel, "SD") && !identical(FUN_MOD, FUN_SD)) { - OutputsModel <- RunModel_Lag(InputsModel, RunOptions, Param[1:RunOptions$FeatFUN_MOD$ParamSD], + OutputsModel <- RunModel_Lag(InputsModel, RunOptions, Param[1:RunOptions$FeatFUN_MOD$NParamSD], OutputsModel) } return(OutputsModel) diff --git a/R/RunModel_GR5H.R b/R/RunModel_GR5H.R index 6c5fb4323b477b1316d51feede865e405c23206f..29d0d39a91c414fb5398a3797e0063f5789f5b02 100644 --- a/R/RunModel_GR5H.R +++ b/R/RunModel_GR5H.R @@ -1,93 +1,93 @@ -RunModel_GR5H <- function(InputsModel, RunOptions, Param) { - - - ## Initialization of variables - IsIntStore <- inherits(RunOptions, "interception") - if (IsIntStore) { - Imax <- RunOptions$Imax - } else { - Imax <- -99 - } - - .ArgumentsCheckGR(InputsModel, RunOptions, Param) - - Param <- as.double(Param) - - Param_X1X3_threshold <- 1e-2 - Param_X4_threshold <- 0.5 - if (Param[1L] < Param_X1X3_threshold) { - warning(sprintf("Param[1] (X1: production store capacity [mm]) < %.2f\n X1 set to %.2f", Param_X1X3_threshold, Param_X1X3_threshold)) - Param[1L] <- Param_X1X3_threshold - } - if (Param[3L] < Param_X1X3_threshold) { - warning(sprintf("Param[3] (X3: routing store capacity [mm]) < %.2f\n X3 set to %.2f", Param_X1X3_threshold, Param_X1X3_threshold)) - Param[3L] <- Param_X1X3_threshold - } - if (Param[4L] < Param_X4_threshold) { - warning(sprintf("Param[4] (X4: unit hydrograph time constant [h]) < %.2f\n X4 set to %.2f", Param_X4_threshold, Param_X4_threshold)) - Param[4L] <- Param_X4_threshold - } - - ## Input data preparation - if (identical(RunOptions$IndPeriod_WarmUp, 0L)) { - RunOptions$IndPeriod_WarmUp <- NULL - } - IndPeriod1 <- c(RunOptions$IndPeriod_WarmUp, RunOptions$IndPeriod_Run) - LInputSeries <- as.integer(length(IndPeriod1)) - if ("all" %in% RunOptions$Outputs_Sim) { - IndOutputs <- as.integer(1:length(RunOptions$FortranOutputs$GR)) - } else { - IndOutputs <- which(RunOptions$FortranOutputs$GR %in% RunOptions$Outputs_Sim) - } - - ## Output data preparation - IndPeriod2 <- (length(RunOptions$IndPeriod_WarmUp)+1):LInputSeries - ExportDatesR <- "DatesR" %in% RunOptions$Outputs_Sim - ExportStateEnd <- "StateEnd" %in% RunOptions$Outputs_Sim - - ## Use of IniResLevels - if (!is.null(RunOptions$IniResLevels)) { - RunOptions$IniStates[1] <- RunOptions$IniResLevels[1] * Param[1] ### production store level (mm) - RunOptions$IniStates[2] <- RunOptions$IniResLevels[2] * Param[3] ### routing store level (mm) - if (IsIntStore) { - RunOptions$IniStates[4] <- RunOptions$IniResLevels[4] * Imax ### interception store level (mm) - } - } - - ## Call GR model Fortan - RESULTS <- .Fortran("frun_gr5h", PACKAGE = "airGR", - ## inputs - LInputs = LInputSeries, ### length of input and output series - InputsPrecip = InputsModel$Precip[IndPeriod1], ### input series of total precipitation [mm/h] - InputsPE = InputsModel$PotEvap[IndPeriod1], ### input series potential evapotranspiration [mm/h] - NParam = as.integer(length(Param)), ### number of model parameter - Param = Param, ### parameter set - NStates = as.integer(length(RunOptions$IniStates)), ### number of state variables used for model initialising - StateStart = RunOptions$IniStates, ### state variables used when the model run starts - Imax = Imax, ### maximal capacity of interception store - NOutputs = as.integer(length(IndOutputs)), ### number of output series - IndOutputs = IndOutputs, ### indices of output series - ## outputs - Outputs = matrix(as.double(-99e9), nrow = LInputSeries, ncol = length(IndOutputs)), ### output series [mm or mm/h] - StateEnd = rep(as.double(-99e9), length(RunOptions$IniStates)) ### state variables at the end of the model run - ) - RESULTS$Outputs[RESULTS$Outputs <= -99e8] <- NA - RESULTS$StateEnd[RESULTS$StateEnd <= -99e8] <- NA - if (ExportStateEnd) { - RESULTS$StateEnd[-3L] <- ifelse(RESULTS$StateEnd[-3L] < 0, 0, RESULTS$StateEnd[-3L]) ### remove negative values except for the ExpStore location - RESULTS$StateEnd <- CreateIniStates(FUN_MOD = RunModel_GR5H, InputsModel = InputsModel, - ProdStore = RESULTS$StateEnd[1L], RoutStore = RESULTS$StateEnd[2L], ExpStore = NULL, - IntStore = RESULTS$StateEnd[4L], - UH1 = NULL, - UH2 = RESULTS$StateEnd[(1:(40*24)) + (7+20*24)], - GCemaNeigeLayers = NULL, eTGCemaNeigeLayers = NULL, - verbose = FALSE) - } - - ## OutputsModel generation - .GetOutputsModelGR(InputsModel, - RunOptions, - RESULTS, - LInputSeries, - Param) -} +RunModel_GR5H <- function(InputsModel, RunOptions, Param) { + + + ## Initialization of variables + IsIntStore <- inherits(RunOptions, "interception") + if (IsIntStore) { + Imax <- RunOptions$Imax + } else { + Imax <- -99 + } + + .ArgumentsCheckGR(InputsModel, RunOptions, Param) + + Param <- as.double(Param) + + Param_X1X3_threshold <- 1e-2 + Param_X4_threshold <- 0.5 + if (Param[1L] < Param_X1X3_threshold) { + warning(sprintf("Param[1] (X1: production store capacity [mm]) < %.2f\n X1 set to %.2f", Param_X1X3_threshold, Param_X1X3_threshold)) + Param[1L] <- Param_X1X3_threshold + } + if (Param[3L] < Param_X1X3_threshold) { + warning(sprintf("Param[3] (X3: routing store capacity [mm]) < %.2f\n X3 set to %.2f", Param_X1X3_threshold, Param_X1X3_threshold)) + Param[3L] <- Param_X1X3_threshold + } + if (Param[4L] < Param_X4_threshold) { + warning(sprintf("Param[4] (X4: unit hydrograph time constant [h]) < %.2f\n X4 set to %.2f", Param_X4_threshold, Param_X4_threshold)) + Param[4L] <- Param_X4_threshold + } + + ## Input data preparation + if (identical(RunOptions$IndPeriod_WarmUp, 0L)) { + RunOptions$IndPeriod_WarmUp <- NULL + } + IndPeriod1 <- c(RunOptions$IndPeriod_WarmUp, RunOptions$IndPeriod_Run) + LInputSeries <- as.integer(length(IndPeriod1)) + if ("all" %in% RunOptions$Outputs_Sim) { + IndOutputs <- as.integer(1:length(RunOptions$FortranOutputs$GR)) + } else { + IndOutputs <- which(RunOptions$FortranOutputs$GR %in% RunOptions$Outputs_Sim) + } + + ## Output data preparation + IndPeriod2 <- (length(RunOptions$IndPeriod_WarmUp)+1):LInputSeries + ExportDatesR <- "DatesR" %in% RunOptions$Outputs_Sim + ExportStateEnd <- "StateEnd" %in% RunOptions$Outputs_Sim + + ## Use of IniResLevels + if (!is.null(RunOptions$IniResLevels)) { + RunOptions$IniStates[1] <- RunOptions$IniResLevels[1] * Param[1] ### production store level (mm) + RunOptions$IniStates[2] <- RunOptions$IniResLevels[2] * Param[3] ### routing store level (mm) + if (IsIntStore) { + RunOptions$IniStates[4] <- RunOptions$IniResLevels[4] * Imax ### interception store level (mm) + } + } + + ## Call GR model Fortan + RESULTS <- .Fortran("frun_gr5h", PACKAGE = "airGR", + ## inputs + LInputs = LInputSeries, ### length of input and output series + InputsPrecip = InputsModel$Precip[IndPeriod1], ### input series of total precipitation [mm/h] + InputsPE = InputsModel$PotEvap[IndPeriod1], ### input series potential evapotranspiration [mm/h] + NParam = as.integer(length(Param)), ### number of model parameter + Param = Param, ### parameter set + NStates = as.integer(length(RunOptions$IniStates)), ### number of state variables used for model initialising + StateStart = RunOptions$IniStates, ### state variables used when the model run starts + Imax = Imax, ### maximal capacity of interception store + NOutputs = as.integer(length(IndOutputs)), ### number of output series + IndOutputs = IndOutputs, ### indices of output series + ## outputs + Outputs = matrix(as.double(-99e9), nrow = LInputSeries, ncol = length(IndOutputs)), ### output series [mm or mm/h] + StateEnd = rep(as.double(-99e9), length(RunOptions$IniStates)) ### state variables at the end of the model run + ) + RESULTS$Outputs[RESULTS$Outputs <= -99e8] <- NA + RESULTS$StateEnd[RESULTS$StateEnd <= -99e8] <- NA + if (ExportStateEnd) { + RESULTS$StateEnd[-3L] <- ifelse(RESULTS$StateEnd[-3L] < 0, 0, RESULTS$StateEnd[-3L]) ### remove negative values except for the ExpStore location + RESULTS$StateEnd <- CreateIniStates(FUN_MOD = RunModel_GR5H, InputsModel = InputsModel, + ProdStore = RESULTS$StateEnd[1L], RoutStore = RESULTS$StateEnd[2L], ExpStore = NULL, + IntStore = RESULTS$StateEnd[4L], + UH1 = NULL, + UH2 = RESULTS$StateEnd[(1:(40*24)) + (7+20*24)], + GCemaNeigeLayers = NULL, eTGCemaNeigeLayers = NULL, + verbose = FALSE) + } + + ## OutputsModel generation + .GetOutputsModelGR(InputsModel, + RunOptions, + RESULTS, + LInputSeries, + Param) +} diff --git a/R/RunModel_LLR.R b/R/RunModel_LLR.R new file mode 100644 index 0000000000000000000000000000000000000000..f5dff3161c35775e4d7aff98ca6be4b561fcea42 --- /dev/null +++ b/R/RunModel_LLR.R @@ -0,0 +1,183 @@ +RunModel_LLR <- function(InputsModel, RunOptions, Param, QcontribDown) { + NParam <- 2 + + ## argument check + if (!inherits(InputsModel, "InputsModel")) { + stop("'InputsModel' must be of class 'InputsModel'") + } + if (!inherits(InputsModel, "SD")) { + stop("'InputsModel' must be of class 'SD'") + } + if (!inherits(RunOptions, "RunOptions")) { + stop("'RunOptions' must be of class 'RunOptions'") + } + if (!is.vector(Param) | !is.numeric(Param)) { + stop("'Param' must be a numeric vector") + } + if (sum(!is.na(Param)) != NParam) { + stop(paste("'Param' must be a vector of length", NParam, "and contain no NA")) + } + if (inherits(QcontribDown, "OutputsModel")) { + if (is.null(QcontribDown$Qsim)) { + stop("'QcontribDown' should contain a key 'Qsim' containing the output of the runoff of the downstream subcatchment") + } + if (length(QcontribDown$Qsim) != length(RunOptions$IndPeriod_Run)) { + stop("Time series Qsim in 'QcontribDown' should have the same length as 'RunOptions$IndPeriod_Run'") + } + if (!identical(RunOptions$IndPeriod_WarmUp, 0L) && !identical(RunOptions$Outputs_Sim, RunOptions$Outputs_Cal)) { + # This test is not necessary during calibration but usefull in other cases because + # WarmUpQsim is then used for downstream sub-basins because of the delay in Qupstream + if (is.null(QcontribDown$RunOptions$WarmUpQsim) || + length(QcontribDown$RunOptions$WarmUpQsim) != length(RunOptions$IndPeriod_WarmUp)) { + stop("Time series WarmUpQsim in 'QcontribDown' should have the same length as 'RunOptions$IndPeriod_WarmUp'") + } + } + } else if (is.vector(QcontribDown) && is.numeric(QcontribDown)) { + if (length(QcontribDown) != length(RunOptions$IndPeriod_Run)) { + stop("'QcontribDown' should have the same length as 'RunOptions$IndPeriod_Run'") + } + } else { + stop("'QcontribDown' must be a numeric vector or a 'OutputsModel' object") + } + + # data set up + + NbUpBasins <- length(InputsModel$LengthHydro) + if (identical(RunOptions$IndPeriod_WarmUp, 0L)) { + RunOptions$IndPeriod_WarmUp <- NULL + } + IndPeriod1 <- c(RunOptions$IndPeriod_WarmUp, RunOptions$IndPeriod_Run) + LInputSeries <- as.integer(length(IndPeriod1)) + IndPeriod2 <- (length(RunOptions$IndPeriod_WarmUp)+1):LInputSeries + + if (inherits(QcontribDown, "OutputsModel")) { + OutputsModel <- QcontribDown + if (is.null(OutputsModel$RunOptions$WarmUpQsim)) { + OutputsModel$RunOptions$WarmUpQsim <- rep(NA, length(RunOptions$IndPeriod_WarmUp)) + } + QsimDown <- c(OutputsModel$RunOptions$WarmUpQsim, OutputsModel$Qsim) + } else if (is.vector(QcontribDown) && is.numeric(QcontribDown)) { + OutputsModel <- list() + class(OutputsModel) <- c("OutputsModel", class(RunOptions)[-1]) + QsimDown <- c(rep(NA, length(RunOptions$IndPeriod_WarmUp)), + QcontribDown) + } + + ## Parameters set up + + TParam <- Param[1L] + KParam <- Param[2L] + + C0 <- exp(-1/KParam) + C1 <- ((KParam/1) * (1-C0))-C0 + C2 <- 1 - (KParam/1) * (1-C0) + + + ## propagation time from upstream meshes to outlet + PT <- InputsModel$LengthHydro * 1e3 / TParam / RunOptions$FeatFUN_MOD$TimeStep + print(PT) + HUTRANS <- rbind(1 - (PT - floor(PT)), PT - floor(PT)) + ## set up initial states + IniSD <- RunOptions$IniStates[grep("SD", names(RunOptions$IniStates))] + if (length(IniSD) > 0) { + if (sum(floor(PT)) + NbUpBasins != length(IniSD)) { + stop( + sprintf( + "SD initial states has a length of %i and a length of %i is required", + length(IniSD), + sum(floor(PT)) + NbUpBasins + ) + ) + } + IniStates <- lapply(seq_len(NbUpBasins), function(x) { + iStart <- 1 + if (x > 1) { + iStart <- iStart + sum(floor(PT[1:x - 1]) + 1) + } + as.vector(IniSD[iStart:(iStart + PT[x])]) + }) + } else { + IniStates <- lapply( + seq_len(NbUpBasins), + function(iUpBasins) { + iWarmUp <- seq.int( + from = max(1, IndPeriod1[1] - floor(PT[iUpBasins]) - 1), + to = max(1, IndPeriod1[1] - 1) + ) + ini <- InputsModel$Qupstream[iWarmUp, iUpBasins] + if (length(ini) != floor(PT[iUpBasins] + 1)) { + # If warm-up period is not enough long complete beginning with first value + ini <- c(rep(ini[1], floor(PT[iUpBasins] + 1) - length(ini)), ini) + } + return(as.vector(ini)) + } + ) + } + # message("IniStates: ", paste(IniStates, collapse = ", ")) + + ## Lag model computation + Qsim_m3 <- QsimDown * + InputsModel$BasinAreas[length(InputsModel$BasinAreas)] * 1e3 + + for (upstream_basin in seq_len(NbUpBasins)) { + Qupstream <- c(IniStates[[upstream_basin]], + InputsModel$Qupstream[IndPeriod1, upstream_basin]) + # message("Qupstream[", upstream_basin, "]: ", paste(Qupstream, collapse = ", ")) + Qsim_m3 <- Qsim_m3 + + Qupstream[2:(1 + LInputSeries)] * HUTRANS[1, upstream_basin] + + Qupstream[1:LInputSeries] * HUTRANS[2, upstream_basin] + } + + ## OutputsModel + + if ("Qsim_m3" %in% RunOptions$Outputs_Sim) { + OutputsModel$Qsim_m3 <- Qsim_m3[IndPeriod2] + } + + if ("Qsim" %in% RunOptions$Outputs_Sim) { + # Convert back Qsim to mm + OutputsModel$Qsim <- Qsim_m3[IndPeriod2] / sum(InputsModel$BasinAreas, na.rm = TRUE) / 1e3 + # message("Qsim: ", paste(OutputsModel$Qsim, collapse = ", ")) + } + + if ("QsimDown" %in% RunOptions$Outputs_Sim) { + # Convert back Qsim to mm + OutputsModel$QsimDown <- QsimDown[IndPeriod2] + } + + # Warning for negative flows or NAs only in extended outputs + if (length(RunOptions$Outputs_Sim) > 2) { + if (any(OutputsModel$Qsim[!is.na(OutputsModel$Qsim)] < 0)) { + warning(length(which(OutputsModel$Qsim < 0)), " time steps with negative flow, set to zero.") + OutputsModel$Qsim[OutputsModel$Qsim < 0] <- 0 + } + # Warning for NAs + if (any(is.na(OutputsModel$Qsim))) { + warning(length(which(is.na(OutputsModel$Qsim))), " time steps with NA values") + } + } + + if ("StateEnd" %in% RunOptions$Outputs_Sim) { + SD <- lapply(seq(NbUpBasins), function(x) { + lastTS <- RunOptions$IndPeriod_Run[length(RunOptions$IndPeriod_Run)] + InputsModel$Qupstream[(lastTS - floor(PT[x])):lastTS, x] + }) + if (is.null(OutputsModel$StateEnd)) { + OutputsModel$StateEnd <- CreateIniStates(RunModel_Lag, InputsModel, SD = SD) + } else { + OutputsModel$StateEnd$SD <- SD + } + # message("StateEnd: ", paste(OutputsModel$StateEnd$SD, collapse = ", ")) + } + if ("WarmUpQsim" %in% RunOptions$Outputs_Sim) { + OutputsModel$RunOptions$WarmUpQsim <- Qsim_m3[seq_len(length(RunOptions$IndPeriod_WarmUp))] / sum(InputsModel$BasinAreas, na.rm = TRUE) / 1e3 + } + + if ("Param" %in% RunOptions$Outputs_Sim) { + OutputsModel$RunOptions$Param <- c(Param, OutputsModel$RunOptions$Param) + } + + class(OutputsModel) <- c(class(OutputsModel), "SD") + + return(OutputsModel) +} diff --git a/R/TransfoParam.R b/R/TransfoParam.R index dcda7b088a732c5a867cb13e09d0f7d2784861ed..6173285ce7f383f71cda8cfaca7182e134005c01 100644 --- a/R/TransfoParam.R +++ b/R/TransfoParam.R @@ -1,4 +1,4 @@ -TransfoParam <- function(ParamIn, Direction, FUN_TRANSFO) { - FUN_TRANSFO <- match.fun(FUN_TRANSFO) - return(FUN_TRANSFO(ParamIn, Direction)) -} +TransfoParam <- function(ParamIn, Direction, FUN_TRANSFO) { + FUN_TRANSFO <- match.fun(FUN_TRANSFO) + return(FUN_TRANSFO(ParamIn, Direction)) +} diff --git a/R/TransfoParam_LLR.R b/R/TransfoParam_LLR.R new file mode 100644 index 0000000000000000000000000000000000000000..d791f8e4f11be93350ffa4a1f782f1a34bdc95da --- /dev/null +++ b/R/TransfoParam_LLR.R @@ -0,0 +1,39 @@ +TransfoParam_LLR <- function(ParamIn, Direction) { + + ## number of model parameters + NParam <- 2L + ## 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 & Route model requires %i parameters", NParam)) + } + + + ## transformation + if (Direction == "TR") { + ParamOut[, 1] <- 20 * (ParamIn[, 1] + 10) / 20.0 + ParamOut[, 2] <- 20 * (ParamIn[, 2] + 10) / 20.0 + } + if (Direction == "RT") { + ParamOut[, 1] <- ParamIn[, 1] * 20.0 / 20 - 10 + ParamOut[, 2] <- 20 * (ParamIn[, 2] + 10) / 20.0 + } + + + ## check output + if (isVecParamIn) { + ParamOut <- as.vector(ParamOut) + } + + return(ParamOut) + +} diff --git a/R/Utils.R b/R/Utils.R index 2e84abd2ee019e06ec830ce836f31cc7cdf7ed2b..f3716df2bbdf5945ed4a8e22ab45dde021ac5c0b 100644 --- a/R/Utils.R +++ b/R/Utils.R @@ -74,8 +74,11 @@ } } if (!is.null(FUN_SD)){ - if (identical(match.fun(RunModel_Lag), FUN_SD)){ - res$ParamSD <- FeatMod$NbParam[14] + if (identical(RunModel_Lag, FUN_SD)){ + res$NParamSD <- FeatMod$NbParam[14] + } + if(identical(RunModel_LLR, FUN_SD)){ + res$NParamSD <- FeatMod$NbParam[15] } } return(res) diff --git a/R/UtilsCalibOptions.R b/R/UtilsCalibOptions.R index 92c9fa2f323d03293d3f35d249e83f23793e88d1..a9ecfe084e28ad51b7738a62c5aa1e6e7dbe119e 100644 --- a/R/UtilsCalibOptions.R +++ b/R/UtilsCalibOptions.R @@ -30,6 +30,9 @@ if (identical(RunModel_Lag, FUN_SD)){ FUN_ROUT <- TransfoParam_Lag } + if (identical(RunModel_LLR, FUN_SD)){ + FUN_ROUT <- TransfoParam_LLR + } } @@ -45,8 +48,8 @@ } ParamOut <- NA * ParamIn NParam <- ncol(ParamIn) - ParamOut[, (FeatFUN_MOD$ParamSD + 1):NParam] <- FUN_GR(ParamIn[, (FeatFUN_MOD$ParamSD + 1):NParam], Direction) - ParamOut[, FeatFUN_MOD$ParamSD ] <- FUN_ROUT(as.matrix(ParamIn[, FeatFUN_MOD$ParamSD]), Direction) + ParamOut[, (FeatFUN_MOD$NParamSD + 1):NParam] <- FUN_GR(ParamIn[, (FeatFUN_MOD$NParamSD + 1):NParam], Direction) + ParamOut[, FeatFUN_MOD$NParamSD ] <- FUN_ROUT(as.matrix(ParamIn[, FeatFUN_MOD$NParamSD]), Direction) if (!Bool) { ParamOut <- ParamOut[1, ] } diff --git a/inst/modelsFeatures/FeatModelsGR.csv b/inst/modelsFeatures/FeatModelsGR.csv index 38d9e5ca7bfab6eef3e8932e1f3c9ebadd5a220a..db34200d5bf8ba1c2a177215323162c319320643 100644 --- a/inst/modelsFeatures/FeatModelsGR.csv +++ b/inst/modelsFeatures/FeatModelsGR.csv @@ -1,15 +1,16 @@ -CodeMod;NameMod;NbParam;TimeUnit;Id;Class;Pkg -GR1A;GR1A;1;yearly;NA;GR;airGR -GR2M;GR2M;2;monthly;NA;GR;airGR -GR4J;GR4J;4;daily;NA;GR;airGR -GR5J;GR5J;5;daily;NA;GR;airGR -GR6J;GR6J;6;daily;NA;GR;airGR -GR4H;GR4H;4;hourly;NA;GR;airGR -GR5H;GR5H;5;hourly;NA;GR;airGR -CemaNeige;CemaNeige;2;NA;NA;NA;airGR -CemaNeigeGR4J;CemaNeigeGR4J;6;daily;NA;GR;airGR -CemaNeigeGR5J;CemaNeigeGR5J;7;daily;NA;GR;airGR -CemaNeigeGR6J;CemaNeigeGR6J;8;daily;NA;GR;airGR -CemaNeigeGR4H;CemaNeigeGR4H;6;hourly;NA;GR;airGR -CemaNeigeGR5H;CemaNeigeGR5H;7;hourly;NA;GR;airGR -Lag;Lag;1;NA;NA;SD;airGR +CodeMod;NameMod;NbParam;TimeUnit;Id;Class;Pkg +GR1A;GR1A;1;yearly;NA;GR;airGR +GR2M;GR2M;2;monthly;NA;GR;airGR +GR4J;GR4J;4;daily;NA;GR;airGR +GR5J;GR5J;5;daily;NA;GR;airGR +GR6J;GR6J;6;daily;NA;GR;airGR +GR4H;GR4H;4;hourly;NA;GR;airGR +GR5H;GR5H;5;hourly;NA;GR;airGR +CemaNeige;CemaNeige;2;NA;NA;NA;airGR +CemaNeigeGR4J;CemaNeigeGR4J;6;daily;NA;GR;airGR +CemaNeigeGR5J;CemaNeigeGR5J;7;daily;NA;GR;airGR +CemaNeigeGR6J;CemaNeigeGR6J;8;daily;NA;GR;airGR +CemaNeigeGR4H;CemaNeigeGR4H;6;hourly;NA;GR;airGR +CemaNeigeGR5H;CemaNeigeGR5H;7;hourly;NA;GR;airGR +Lag;Lag;1;NA;NA;SD;airGR +LinearLagAndRoute;Lag;2;NA;NA;SD;airGR