From 020ae8478829c53339064ce8da22f3b32b584d55 Mon Sep 17 00:00:00 2001 From: Delaigue Olivier <olivier.delaigue@irstea.priv> Date: Wed, 6 Mar 2019 09:24:08 +0100 Subject: [PATCH] v1.2.8.0 UPDATE: CreateInputsCrit now returns a idLayer to indicate which layer to use for SCA or SWE --- DESCRIPTION | 2 +- NEWS.rmd | 4 ++- R/CreateInputsCrit.R | 85 +++++++++++++++++++++++++++++++++++++++----- 3 files changed, 80 insertions(+), 11 deletions(-) diff --git a/DESCRIPTION b/DESCRIPTION index 5dbd28ba..3616934d 100644 --- a/DESCRIPTION +++ b/DESCRIPTION @@ -1,7 +1,7 @@ Package: airGR Type: Package Title: Suite of GR Hydrological Models for Precipitation-Runoff Modelling -Version: 1.2.7.12 +Version: 1.2.8.0 Date: 2019-03-06 Authors@R: c( person("Laurent", "Coron", role = c("aut", "trl"), comment = c(ORCID = "0000-0002-1503-6204")), diff --git a/NEWS.rmd b/NEWS.rmd index a34b6e69..ae751659 100644 --- a/NEWS.rmd +++ b/NEWS.rmd @@ -13,7 +13,7 @@ output: -### 1.2.7.12 Release Notes (2019-03-06) +### 1.2.8.0 Release Notes (2019-03-06) @@ -36,6 +36,8 @@ output: - <code>CreateInputsCrit()</code> now presents a <code>warnings</code> argument to replace the verbose action (the <code>verbose</code> argument is keep to print messages). +- <code>CreateInputsCrit()</code> now returns a <code>idLayer</code> element to indicate which layer to use for SCA or SWE aggregation. + - <code>CreateRunOptions()</code> now presents a <code>warnings</code> argument to replace the verbose action (the <code>verbose</code> argument is keep to print messages). - <code>Calibration()</code> function now returns an error message if <code>FUN_CALIB</code> is not a function diff --git a/R/CreateInputsCrit.R b/R/CreateInputsCrit.R index 02cab174..3d98d517 100644 --- a/R/CreateInputsCrit.R +++ b/R/CreateInputsCrit.R @@ -1,14 +1,13 @@ CreateInputsCrit <- function(FUN_CRIT, InputsModel, RunOptions, - Qobs, + Qobs, # deprecated obs, varObs = "Q", BoolCrit = NULL, transfo = "", - # groupLayer, weights = NULL, - Ind_zeroes = NULL, + Ind_zeroes = NULL, # deprecated epsilon = NULL, warnings = TRUE, verbose = TRUE) { @@ -47,25 +46,33 @@ CreateInputsCrit <- function(FUN_CRIT, LLL <- length(InputsModel$DatesR[RunOptions$IndPeriod_Run]) - ## check 'obs' + ## check 'obs' and definition of idLayer vecObs <- unlist(obs) if (length(vecObs) %% LLL != 0 | !is.numeric(vecObs)) { stop(sprintf("'obs' must be a (list of) vector(s) of numeric values of length %i", LLL), call. = FALSE) } if (!is.list(obs)) { + idLayer <- list(1L) obs <- list(obs) } else { + idLayer <- lapply(obs, function(i) { + if (is.list(i)) { + length(i) + } else { + 1L + } + }) obs <- lapply(obs, function(x) rowMeans(as.data.frame(x))) } - + ## create list of arguments listArgs <- list(FUN_CRIT = FUN_CRIT, obs = obs, varObs = varObs, BoolCrit = BoolCrit, + idLayer = idLayer, transfo = transfo, - # groupLayer = groupLayer, weights = weights, epsilon = epsilon) @@ -90,6 +97,21 @@ CreateInputsCrit <- function(FUN_CRIT, # } } + ## check 'varObs' + 'RunOptions' + if ("Q" %in% varObs & !inherits(RunOptions, "GR")) { + stop("'varObs' cannot contain Q if a GR rainfall-runoff model is not used") + } + if (any(c("SCA", "SWE") %in% varObs) & !inherits(RunOptions, "CemaNeige")) { + stop("'varObs' cannot contain SCA or SWE if CemaNeige is not used") + } + if ("SCA" %in% varObs & inherits(RunOptions, "CemaNeige") & !"Gratio" %in% RunOptions$Outputs_Sim) { + stop("'Gratio' is missing in 'Outputs_Sim' of 'RunOptions', which is necessary to output SCA with CemaNeige") + } + if ("SWE" %in% varObs & inherits(RunOptions, "CemaNeige") & !"SnowPack" %in% RunOptions$Outputs_Sim) { + stop("'SnowPack' is missing in 'Outputs_Sim' of 'RunOptions', which is necessary to output SWE with CemaNeige") + } + + ## check 'transfo' if (missing(transfo)) { listArgs$transfo <- as.list(rep("", times = length(listArgs$obs))) @@ -117,10 +139,11 @@ CreateInputsCrit <- function(FUN_CRIT, } + ## ---------- reformat + ## reformat list of arguments listArgs2 <- lapply(seq_along(listArgs$FUN_CRIT), function(i) lapply(listArgs, "[[", i)) - ## preparation of warning messages inVarObs <- c("Q", "SCA", "SWE") msgVarObs <- "'varObs' must be a (list of) character vector(s) and one of %s" @@ -219,7 +242,7 @@ CreateInputsCrit <- function(FUN_CRIT, obs = iListArgs2$obs, varObs = iListArgs2$varObs, BoolCrit = iListArgs2$BoolCrit, - # groupLayer = iListArgs2$groupLayer, + idLayer = iListArgs2$idLayer, transfo = iListArgs2$transfo, epsilon = iListArgs2$epsilon, weights = iListArgs2$weights) @@ -229,7 +252,51 @@ CreateInputsCrit <- function(FUN_CRIT, }) names(InputsCrit) <- paste0("IC", seq_along(InputsCrit)) - # if only one criterion --> not a list of InputsCrit but directly an InputsCrit + + listVarObs <- sapply(InputsCrit, FUN = "[[", "varObs") + inCnVarObs <- c("SCA", "SWE") + if (!"ZLayers" %in% names(InputsModel)) { + if(any(listVarObs %in% inCnVarObs)) { + stop(sprintf("'varOBS' can not be equal to %i if CemaNeige is not used", + paste(sapply(inCnVarObs, shQuote), collapse = " or "))) + } + } else { + listGroupLayer0 <- sapply(InputsCrit, FUN = "[[", "idLayer") + listGroupLayer <- rep(listVarObs, times = listGroupLayer0) + tabGroupLayer <- as.data.frame(table(listGroupLayer)) + colnames(tabGroupLayer) <- c("varObs", "freq") + nLayers <- length(InputsModel$ZLayers) + for (iInCnVarObs in inCnVarObs) { + if (any(listVarObs %in% iInCnVarObs)) { + if (tabGroupLayer[tabGroupLayer$varObs %in% iInCnVarObs, "freq"] != nLayers) { + stop(sprintf("'obs' must contains %i vector(s) about %s", nLayers, iInCnVarObs)) + } + } + } + } + + ## define idLayer as an index of the layer to use + for (iInCnVarObs in unique(listVarObs)) { + if (iInCnVarObs == "Q") { + k <- 1 + for (i in which(listVarObs == iInCnVarObs)) { + InputsCrit[[i]]$idLayer <- NA + k <- k + 1 + } + } else { + aa <- listGroupLayer0[listVarObs == iInCnVarObs] + bb <- c(0, aa[-length(aa)]) + cc <- lapply(seq_along(aa), function(x) seq_len(aa[x]) + bb[x]) + k <- 1 + for (i in which(listVarObs == iInCnVarObs)) { + InputsCrit[[i]]$idLayer <- cc[[k]] + k <- k + 1 + } + } + } + + + ## if only one criterion --> not a list of InputsCrit but directly an InputsCrit if (length(InputsCrit) < 2) { InputsCrit <- InputsCrit[[1L]] InputsCrit["weights"] <- list(weights = NULL) -- GitLab