Source

Target

Commits (1342)
Showing with 2554 additions and 2416 deletions
+2554 -2416
...@@ -2,3 +2,14 @@ ...@@ -2,3 +2,14 @@
^\.Rproj\.user$ ^\.Rproj\.user$
^\.Rprofile$ ^\.Rprofile$
^packrat/ ^packrat/
^tests/tmp/
^\.gitlab-ci.yml$
^\.regressionignore$
^\.vignettechunkignore$
^\.gitlab-ci\.yml$
^\.vscode$
^Rplots\.pdf$
^ci$
^data-raw$
^revdep$
^\.devcontainer$
{
"image": "rocker/geospatial:devel",
"customizations": {
"vscode": {
"extensions": [
"eamodio.gitlens",
"REditorSupport.r"
]
}
},
// Use 'postCreateCommand' to run commands after the container is created.
"postCreateCommand": "R -q -e 'install.packages(\"languageserver\");remotes::install_deps(dep = TRUE)'",
"postStartCommand": "R -q -e 'devtools::install()'"
}
.Rproj.user # Specific files for airGR
packrat/lib*/
# Compiled files
/src/*.o
/src/*.so
/src/*.dll
/src-*
# Test temporary files
/tests/tmp/
*.pdf
!man/figures/*.pdf
# revdep
/revdep/
######################################################################################################
### Generic .gitignore for R (source: https://github.com/github/gitignore/blob/master/R.gitignore) ###
######################################################################################################
# History files
.Rhistory .Rhistory
.Rapp.history
# Session Data files
.RData .RData
airGR.Rproj
packrat/lib*/ # User-specific files
.Ruserdata
# Example code in package build process
*-Ex.R
# Output files from R CMD build
/*.tar.gz
# Output files from R CMD check
/*.Rcheck/
# RStudio files
.Rproj.user
# produced vignettes
vignettes/*.html
vignettes/*.pdf
# OAuth2 token, see https://github.com/hadley/httr/releases/tag/v0.3
.httr-oauth
# knitr and R markdown default cache directories
*_cache/
/cache/
# Temporary files created by R markdown
*.utf8.md
*.knit.md
# R Environment Variables
.Renviron
.Rprofile
# pkgdown site
docs/
# vscode IDE
.vscode/*
*.code-workspace
.history/
stages:
- check
- scheduled_tests
- revdepcheck
variables:
R_LIBS_USER: "$CI_PROJECT_DIR/ci/lib"
default:
tags: [docker]
cache:
key: "airGR-${R_VERSION}"
paths:
- $R_LIBS_USER
before_script:
- mkdir -p $R_LIBS_USER
- echo "R_LIBS='$R_LIBS_USER'" > .Renviron
- echo 'options(repos = c(CRAN = "https://packagemanager.posit.co/cran/__linux__/focal/latest"))' > .Rprofile
- apt-get update && apt-get install -y libstdc++6
- R -q -e 'remotes::install_deps(dependencies = TRUE)'
.R-devel:
image: rocker/geospatial:devel
variables:
R_VERSION: devel
.R-patched:
only:
refs:
- tags
- schedules
image: rocker/geospatial:latest
variables:
R_VERSION: patched
.R-oldrel:
only:
refs:
- tags
- schedules
image: rocker/geospatial:4.1
variables:
R_VERSION: oldrel
.scheduled_tests:
only:
refs:
- tags
- schedules
- master
stage: scheduled_tests
script:
- R -q -e 'devtools::install()'
- Rscript tests/scheduled_tests/scheduled.R
- Rscript tests/scheduled_tests/regression.R stable
- R CMD INSTALL .
- Rscript tests/scheduled_tests/regression.R dev
- Rscript tests/scheduled_tests/regression.R compare
.check:
stage: check
script:
- R -q -e 'tinytex::tlmgr("option repository https://ftp.tu-chemnitz.de/pub/tug/historic/systems/texlive/2021/tlnet-final")'
- tlmgr update --self && tlmgr install ec epstopdf-pkg amsmath
- R -q -e 'remotes::update_packages("rcmdcheck")'
- R -q -e 'rcmdcheck::rcmdcheck(args = c("--as-cran"), error_on = "warning")'
.test_all:
stage: check
script:
- R -q -e 'testthat::test_local()'
benchmark_devel:
extends: .R-devel
stage: check
allow_failure: true
script:
- R -q -e 'remotes::update_packages("microbenchmark", repos = "http://cran.r-project.org")'
- R -q -e 'install.packages("airGR", repos = "http://cran.r-project.org")'
- Rscript tests/scheduled_tests/benchmarkRunModel.R
- R CMD INSTALL .
- Rscript tests/scheduled_tests/benchmarkRunModel.R
artifacts:
paths:
- tests/tmp/benchmark.tsv
- tests/tmp/mean_execution_time.tsv
scheduled_tests_patched:
extends:
- .scheduled_tests
- .R-patched
scheduled_tests_devel:
extends:
- .scheduled_tests
- .R-devel
scheduled_tests_oldrel:
extends:
- .scheduled_tests
- .R-oldrel
check_patched:
extends:
- .check
- .R-patched
check_devel:
extends:
- .check
- .R-devel
test_all_patched:
extends:
- .test_all
- .R-patched
test_all_devel:
extends:
- .test_all
- .R-devel
test_all_oldrel:
extends:
- .test_all
- .R-oldrel
revdepcheck_devel:
stage: revdepcheck
only:
refs:
- tags
- schedule
- master
extends: .R-devel
script:
- R -q -e 'remotes::install_github("https://github.com/r-lib/revdepcheck")'
- R -q -e 'revdepcheck::revdep_check(timeout = as.difftime(20, units = "mins"))'
- R -q -e 'stopifnot(all("+" == sapply(revdepcheck::revdep_summary(), "[[", "status")))'
- R -q -e 'if (any(sapply(revdepcheck::revdep_summary(), function(x) {any(x$cmp$change == 1)}))) stop()'
artifacts:
when: on_failure
paths:
- revdep/README.md
- revdep/problems.md
- revdep/failures.md
- revdep/cran.md
- revdep/checks/*.log
# .test-regression.ignore contains the list of topic/variables produces by
# documentation examples that should be ignore in the regression test
# The format of this file is: 5 lines of comments followed by one line by
# ignored variable : [Topic]<SPACE>[Variable] or *<SPACE>[Variable] for every variable whatever the topic
# Example for ignoring OutputsModel variable produced by example("RunModel_GR2M"): RunModel_GR2M OutputsModel
# This file is used by the script tests/testthat/test-vignettes which test all
# chunks including those with `eval=FALSE`
# It serves to ignore chunks that should not be tested anyway
# Format: `vignette file name`[space]`id of the chunk`
V02.1_param_optim.Rmd hydroPSO1
V02.1_param_optim.Rmd hydroPSO2
V02.1_param_optim.Rmd resGLOB
Package: airGR Package: airGR
Type: Package Type: Package
Title: Suite of GR Hydrological Models for Precipitation-Runoff Modelling Title: Suite of GR Hydrological Models for Precipitation-Runoff Modelling
Version: 1.0.13.0 Version: 1.7.6.9000
Date: 2018-08-29 Date: 2023-10-25
Authors@R: c( Authors@R: c(
person("Laurent", "Coron", role = c("aut", "trl"), comment = c(ORCID = "0000-0002-1503-6204")), person("Laurent", "Coron", role = c("aut", "trl"), comment = c(ORCID = "0000-0002-1503-6204")),
person("Olivier", "Delaigue", role = c("aut", "cre"), comment = c(ORCID = "0000-0002-7668-8468"), email = "airGR@inrae.fr"),
person("Guillaume", "Thirel", role = c("aut", "ths"), comment = c(ORCID = "0000-0002-1444-1830")),
person("David", "Dorchies", role = c("aut"), comment = c(ORCID = "0000-0002-6595-7984")),
person("Charles", "Perrin", role = c("aut", "ths"), comment = c(ORCID = "0000-0001-8552-1881")), person("Charles", "Perrin", role = c("aut", "ths"), comment = c(ORCID = "0000-0001-8552-1881")),
person("Olivier", "Delaigue", role = c("aut", "cre"), comment = c(ORCID = "0000-0002-7668-8468"), email = "airGR@irstea.fr"),
person("Guillaume", "Thirel", role = c("aut"), comment = c(ORCID = "0000-0002-1444-1830")),
person("Claude", "Michel", role = c("aut", "ths")), person("Claude", "Michel", role = c("aut", "ths")),
person("Vazken", "Andréassian", role = c("ctb", "ths"), comment = c(ORCID = "0000-0001-7124-9303")), person("Vazken", "Andréassian", role = c("ctb", "ths"), comment = c(ORCID = "0000-0001-7124-9303")),
person("François", "Bourgin", role = c("ctb"), comment = c(ORCID = "0000-0002-2820-7260", vignette = "'Parameter estimation' vignettes")), person("François", "Bourgin", role = c("ctb"), comment = c(ORCID = "0000-0002-2820-7260")),
person("Pierre", "Brigode", role = c("ctb"), comment = c(ORCID = "0000-0001-8257-0741")), person("Pierre", "Brigode", role = c("ctb"), comment = c(ORCID = "0000-0001-8257-0741")),
person("Nicolas", "Le Moine", role = c("ctb")), person("Nicolas", "Le Moine", role = c("ctb")),
person("Thibaut", "Mathevet", role = c("ctb")), person("Thibaut", "Mathevet", role = c("ctb"), comment = c(ORCID = "0000-0002-4142-4454")),
person("Safouane", "Mouelhi", role = c("ctb")), person("Safouane", "Mouelhi", role = c("ctb")),
person("Ludovic", "Oudin", role = c("ctb")), person("Ludovic", "Oudin", role = c("ctb"), comment = c(ORCID = "0000-0002-3712-0933")),
person("Raji", "Pushpalatha", role = c("ctb")), person("Raji", "Pushpalatha", role = c("ctb")),
person("Audrey", "Valéry", role = c("ctb")) person("Audrey", "Valéry", role = c("ctb"))
) )
Depends: R (>= 3.0.1) Depends: R (>= 3.1.0)
Suggests: knitr, rmarkdown, coda, DEoptim, dplyr, FME, ggmcmc, hydroPSO, Rmalschains Imports:
Description: Hydrological modelling tools developed at Irstea-Antony (HYCAR Research Unit, France). The package includes several conceptual rainfall-runoff models (GR4H, GR4J, GR5J, GR6J, GR2M, GR1A), a snow accumulation and melt model (CemaNeige) and the associated functions for their calibration and evaluation. Use help(airGR) for package description. graphics,
grDevices,
stats,
utils
Suggests:
knitr, markdown, rmarkdown,
caRamel, coda, DEoptim, FME, ggmcmc, Rmalschains,
GGally, ggplot2,
testthat
Description: Hydrological modelling tools developed at INRAE-Antony (HYCAR Research Unit, France). The package includes several conceptual rainfall-runoff models (GR4H, GR5H, GR4J, GR5J, GR6J, GR2M, GR1A) that can be applied either on a lumped or semi-distributed way. A snow accumulation and melt model (CemaNeige) and the associated functions for the calibration and evaluation of models are also included. Use help(airGR) for package description and references.
License: GPL-2 License: GPL-2
URL: https://webgr.irstea.fr/en/airGR/ URL: https://hydrogr.github.io/airGR/
BugReports: https://gitlab.irstea.fr/HYCAR-Hydro/airgr/-/issues
NeedsCompilation: yes NeedsCompilation: yes
Encoding: UTF-8 Encoding: UTF-8
VignetteBuilder: knitr VignetteBuilder: knitr
RoxygenNote: 7.1.1
...@@ -8,7 +8,13 @@ useDynLib(airGR, .registration = TRUE) ...@@ -8,7 +8,13 @@ useDynLib(airGR, .registration = TRUE)
##################################### #####################################
## S3 methods ## ## S3 methods ##
##################################### #####################################
S3method("plot", "OutputsModel") S3method('[', InputsModel)
#S3method('[', OutputsModel) ### to add in version 2.0
S3method(plot, OutputsModel)
S3method(SeriesAggreg, data.frame)
S3method(SeriesAggreg, list)
S3method(SeriesAggreg, InputsModel)
S3method(SeriesAggreg, OutputsModel)
...@@ -18,8 +24,10 @@ S3method("plot", "OutputsModel") ...@@ -18,8 +24,10 @@ S3method("plot", "OutputsModel")
export(Calibration) export(Calibration)
export(Calibration_Michel) export(Calibration_Michel)
export(CreateCalibOptions) export(CreateCalibOptions)
export(CreateErrorCrit_GAPX)
export(CreateIniStates) export(CreateIniStates)
export(CreateInputsCrit) export(CreateInputsCrit)
export(CreateInputsCrit_Lavenne)
export(CreateInputsModel) export(CreateInputsModel)
export(CreateRunOptions) export(CreateRunOptions)
export(DataAltiExtrapolation_Valery) export(DataAltiExtrapolation_Valery)
...@@ -28,30 +36,38 @@ export(ErrorCrit_KGE) ...@@ -28,30 +36,38 @@ export(ErrorCrit_KGE)
export(ErrorCrit_KGE2) export(ErrorCrit_KGE2)
export(ErrorCrit_NSE) export(ErrorCrit_NSE)
export(ErrorCrit_RMSE) export(ErrorCrit_RMSE)
export(PEdaily_Oudin) export(Imax)
export(PE_Oudin)
export(plot.OutputsModel) ### to remove from version 2.0
export(RunModel) export(RunModel)
export(RunModel_CemaNeige) export(RunModel_CemaNeige)
export(RunModel_CemaNeigeGR4H)
export(RunModel_CemaNeigeGR5H)
export(RunModel_CemaNeigeGR4J) export(RunModel_CemaNeigeGR4J)
export(RunModel_CemaNeigeGR5J) export(RunModel_CemaNeigeGR5J)
export(RunModel_CemaNeigeGR6J) export(RunModel_CemaNeigeGR6J)
export(RunModel_GR1A) export(RunModel_GR1A)
export(RunModel_GR2M) export(RunModel_GR2M)
export(RunModel_GR4H) export(RunModel_GR4H)
export(RunModel_GR5H)
export(RunModel_GR4J) export(RunModel_GR4J)
export(RunModel_GR5J) export(RunModel_GR5J)
export(RunModel_GR6J) export(RunModel_GR6J)
export(RunModel_Lag)
export(SeriesAggreg) export(SeriesAggreg)
export(TransfoParam) export(TransfoParam)
export(TransfoParam_CemaNeige) export(TransfoParam_CemaNeige)
export(TransfoParam_CemaNeigeHyst)
export(TransfoParam_GR1A) export(TransfoParam_GR1A)
export(TransfoParam_GR2M) export(TransfoParam_GR2M)
export(TransfoParam_GR4H) export(TransfoParam_GR4H)
export(TransfoParam_GR5H)
export(TransfoParam_GR4J) export(TransfoParam_GR4J)
export(TransfoParam_GR5J) export(TransfoParam_GR5J)
export(TransfoParam_GR6J) export(TransfoParam_GR6J)
export(plot.OutputsModel) export(TransfoParam_Lag)
export(plot_OutputsModel) #export(.ErrorCrit)
#export(.FeatModels)
##################################### #####################################
......
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
#' @name BasinInfo
#' @docType data
#' @title Data sample: characteristics of a fictional catchment (L0123001, L0123002 or L0123003)
#' @description
#' R-object containing the code, station's name, area and hypsometric curve of the catchment.
#' @encoding UTF-8
#' @format
#' List named 'BasinInfo' containing
#' \itemize{
#' \item two strings: catchment's code and station's name
#' \item one float: catchment's area in km2
#' \item one numeric vector: catchment's hypsometric curve (min, quantiles 01 to 99 and max) in metres
#' }
#' @examples
#' require(airGR)
#' data(L0123001)
#' str(BasinInfo)
NULL
#' @name BasinObs
#' @docType data
#' @title Data sample: time series of observations of a fictional catchment (L0123001, L0123002 or L0123003)
#' @description
#' R-object containing the times series of precipitation, temperature, potential evapotranspiration and discharges. \cr
#' Times series for L0123001 or L0123002 are at the daily time-step for use with daily models such as GR4J, GR5J, GR6J, CemaNeigeGR4J, CemaNeigeGR5J and CemaNeigeGR6J.
#' Times series for L0123003 are at the hourly time-step for use with hourly models such as GR4H.
#' @encoding UTF-8
#' @format
#' Data frame named 'BasinObs' containing
#' \itemize{
#' \item one POSIXlt vector: time series dates in the POSIXlt format
#' \item five numeric vectors: time series of catchment average precipitation [mm], catchment average air temperature [degC], catchment average potential evapotranspiration [mm], outlet discharge [l/s], outlet discharge [mm]
#' }
#' @examples
#' require(airGR)
#' data(L0123001)
#' str(BasinObs)
NULL
Calibration <- function(InputsModel, RunOptions, InputsCrit, CalibOptions, FUN_MOD, FUN_CRIT, FUN_CALIB = Calibration_Michel, FUN_TRANSFO = NULL, verbose = TRUE) { Calibration <- function(InputsModel,
return(FUN_CALIB(InputsModel, RunOptions, InputsCrit, CalibOptions, FUN_MOD, FUN_CRIT, FUN_TRANSFO, verbose = verbose)) RunOptions,
InputsCrit,
CalibOptions,
FUN_MOD,
FUN_CRIT, # deprecated
FUN_CALIB = Calibration_Michel,
FUN_TRANSFO = NULL,
verbose = TRUE,
...) {
FUN_MOD <- match.fun(FUN_MOD)
if (!missing(FUN_CRIT)) {
FUN_CRIT <- match.fun(FUN_CRIT)
}
FUN_CALIB <- match.fun(FUN_CALIB)
if (!is.null(FUN_TRANSFO)) {
FUN_TRANSFO <- match.fun(FUN_TRANSFO)
}
return(FUN_CALIB(InputsModel = InputsModel, RunOptions = RunOptions, InputsCrit = InputsCrit,
CalibOptions = CalibOptions,
FUN_MOD = FUN_MOD, FUN_TRANSFO = FUN_TRANSFO,
verbose = verbose, ...))
} }
This diff is collapsed.
This diff is collapsed.
CreateErrorCrit_GAPX <- function(FUN_TRANSFO) {
FUN_CRIT <- function(InputsCrit, OutputsModel, warnings = TRUE, verbose = TRUE) {
## Arguments check
if (!inherits(OutputsModel, "OutputsModel")) {
stop("'OutputsModel' must be of class 'OutputsModel'")
}
OutputsModel$RunOptions$ParamT <- FUN_TRANSFO(OutputsModel$RunOptions$Param, "RT")
EC <- .ErrorCrit(InputsCrit = InputsCrit, Crit = "GAPX", OutputsModel = OutputsModel, warnings = warnings)
CritValue <- NA
if (EC$CritCompute) {
ParamApr <- EC$VarObs[!EC$TS_ignore]
ParamOpt <- EC$VarSim[!EC$TS_ignore]
## ErrorCrit
Crit <- 1 - sum(((ParamApr - ParamOpt) / 20)^2)^0.5
if (is.numeric(Crit) & is.finite(Crit)) {
CritValue <- Crit
}
## Verbose
if (verbose) {
message(sprintf("Crit. %s = %.4f", EC$CritName, CritValue))
}
}
## Output
OutputsCrit <- list(CritValue = CritValue,
CritName = EC$CritName,
CritBestValue = EC$CritBestValue,
Multiplier = EC$Multiplier,
Ind_notcomputed = EC$Ind_TS_ignore)
class(OutputsCrit) <- c("GAPX", "ErrorCrit")
return(OutputsCrit)
}
class(FUN_CRIT) <- c("FUN_CRIT", class(FUN_CRIT))
return(FUN_CRIT)
}
CreateIniStates <- function(FUN_MOD, InputsModel, CreateIniStates <- function(FUN_MOD, InputsModel, IsHyst = FALSE, IsIntStore = FALSE,
ProdStore = 350, RoutStore = 90, ExpStore = NULL, ProdStore = 350, RoutStore = 90, ExpStore = NULL, IntStore = NULL,
UH1 = NULL, UH2 = NULL, UH1 = NULL, UH2 = NULL,
GCemaNeigeLayers = NULL, eTGCemaNeigeLayers = NULL, GCemaNeigeLayers = NULL, eTGCemaNeigeLayers = NULL,
GthrCemaNeigeLayers = NULL, GlocmaxCemaNeigeLayers = NULL,
SD = NULL,
verbose = TRUE) { verbose = TRUE) {
ObjectClass <- NULL ObjectClass <- NULL
UH1n <- 20L UH1n <- 20L
UH2n <- UH1n * 2L UH2n <- UH1n * 2L
FUN_MOD <- match.fun(FUN_MOD)
## check FUN_MOD
BOOL <- FALSE FeatFUN_MOD <- .GetFeatModel(FUN_MOD = FUN_MOD, DatesR = InputsModel$DatesR)
if (identical(FUN_MOD, RunModel_GR4H)) { ObjectClass <- FeatFUN_MOD$Class
ObjectClass <- c(ObjectClass, "GR", "hourly")
BOOL <- TRUE if (!"CemaNeige" %in% ObjectClass & IsHyst) {
} stop("'IsHyst' cannot be TRUE if CemaNeige is not used in 'FUN_MOD'")
if (identical(FUN_MOD, RunModel_GR4J) |
identical(FUN_MOD, RunModel_GR5J) |
identical(FUN_MOD, RunModel_GR6J)) {
ObjectClass <- c(ObjectClass, "GR", "daily")
BOOL <- TRUE
}
if (identical(FUN_MOD, RunModel_GR2M)) {
ObjectClass <- c(ObjectClass, "GR", "monthly")
BOOL <- TRUE
}
if (identical(FUN_MOD, RunModel_GR1A)) {
stop("'RunModel_GR1A' does not require 'IniStates' object")
}
if (identical(FUN_MOD, RunModel_CemaNeige)) {
ObjectClass <- c(ObjectClass, "CemaNeige", "daily")
BOOL <- TRUE
}
if (identical(FUN_MOD, RunModel_CemaNeigeGR4J) |
identical(FUN_MOD, RunModel_CemaNeigeGR5J) |
identical(FUN_MOD, RunModel_CemaNeigeGR6J)) {
ObjectClass <- c(ObjectClass, "GR", "CemaNeige", "daily")
BOOL <- TRUE
} }
if (!BOOL) { if (!(identical(FUN_MOD, RunModel_GR5H) | identical(FUN_MOD, RunModel_CemaNeigeGR5H)) & IsIntStore) {
stop("Incorrect 'FUN_MOD' for use in 'CreateIniStates'") stop("'IsIntStore' cannot be TRUE if GR5H is not used in 'FUN_MOD'")
return(NULL)
} }
## check InputsModel ## check InputsModel
if (!inherits(InputsModel, "InputsModel")) { if (!inherits(InputsModel, "InputsModel")) {
stop("'InputsModel' must be of class 'InputsModel'") stop("'InputsModel' must be of class 'InputsModel'")
return(NULL)
} }
if ("GR" %in% ObjectClass & !inherits(InputsModel, "GR")) { if ("GR" %in% ObjectClass & !inherits(InputsModel, "GR")) {
stop("'InputsModel' must be of class 'GR'") stop("'InputsModel' must be of class 'GR'")
return(NULL)
} }
if ("CemaNeige" %in% ObjectClass & if ("CemaNeige" %in% ObjectClass &
!inherits(InputsModel, "CemaNeige")) { !inherits(InputsModel, "CemaNeige")) {
stop("'InputsModel' must be of class 'CemaNeige'") stop("'InputsModel' must be of class 'CemaNeige'")
return(NULL)
} }
## check states ## check states
if (any(eTGCemaNeigeLayers > 0)) { if (any(eTGCemaNeigeLayers > 0)) {
stop("Positive values are not allowed for 'eTGCemaNeigeLayers'") stop("Positive values are not allowed for 'eTGCemaNeigeLayers'")
} }
if (identical(FUN_MOD, RunModel_GR6J) | identical(FUN_MOD, RunModel_CemaNeigeGR6J)) { if (identical(FUN_MOD, RunModel_GR6J) | identical(FUN_MOD, RunModel_CemaNeigeGR6J)) {
if (is.null(ExpStore)) { if (is.null(ExpStore)) {
stop("'RunModel_*GR6J' need an 'ExpStore' value") stop("'RunModel_*GR6J' need an 'ExpStore' value")
return(NULL)
} }
} else if (!is.null(ExpStore)) { } else if (!is.null(ExpStore)) {
if (verbose) { if (verbose) {
warning(sprintf("'%s' does not require 'ExpStore'. Value set to NA", as.character(substitute(FUN_MOD)))) warning(sprintf("'%s' does not require 'ExpStore'. Value set to NA", FeatFUN_MOD$NameFunMod))
} }
ExpStore <- Inf ExpStore <- Inf
} }
if (identical(FUN_MOD, RunModel_GR2M)) { if (identical(FUN_MOD, RunModel_GR2M)) {
if (!is.null(UH1)) { if (!is.null(UH1)) {
if (verbose) { if (verbose) {
warning(sprintf("'%s' does not require 'UH1'. Values set to NA", as.character(substitute(FUN_MOD)))) warning(sprintf("'%s' does not require 'UH1'. Values set to NA", FeatFUN_MOD$NameFunMod))
} }
UH1 <- rep(Inf, UH1n) UH1 <- rep(Inf, UH1n)
} }
if (!is.null(UH2)) { if (!is.null(UH2)) {
if (verbose) { if (verbose) {
warning(sprintf("'%s' does not require 'UH2'. Values set to NA", as.character(substitute(FUN_MOD)))) warning(sprintf("'%s' does not require 'UH2'. Values set to NA", FeatFUN_MOD$NameFunMod))
} }
UH2 <- rep(Inf, UH2n) UH2 <- rep(Inf, UH2n)
} }
} }
if ((identical(FUN_MOD, RunModel_GR5J) | identical(FUN_MOD, RunModel_CemaNeigeGR5J)) & !is.null(UH1)) { if ((identical(FUN_MOD, RunModel_GR5J) | identical(FUN_MOD, RunModel_CemaNeigeGR5J)) & !is.null(UH1)) {
if (verbose) { if (verbose) {
warning(sprintf("'%s' does not require 'UH1'. Values set to NA", as.character(substitute(FUN_MOD)))) warning(sprintf("'%s' does not require 'UH1'. Values set to NA", FeatFUN_MOD$NameFunMod))
} }
UH1 <- rep(Inf, UH1n) UH1 <- rep(Inf, UH1n)
} }
if (!(identical(FUN_MOD, RunModel_GR5H) | identical(FUN_MOD, RunModel_CemaNeigeGR5H)) & !is.null(IntStore)) {
if (verbose) {
warning(sprintf("'%s' does not require 'IntStore'. Values set to NA", FeatFUN_MOD$NameFunMod))
}
IntStore <- Inf
}
if ("CemaNeige" %in% ObjectClass & ! "GR" %in% ObjectClass) { if ("CemaNeige" %in% ObjectClass & ! "GR" %in% ObjectClass) {
if (!is.null(ProdStore)) { if (!is.null(ProdStore)) {
if (verbose) { if (verbose) {
warning(sprintf("'%s' does not require 'ProdStore'. Values set to NA", as.character(substitute(FUN_MOD)))) warning(sprintf("'%s' does not require 'ProdStore'. Values set to NA", FeatFUN_MOD$NameFunMod))
} }
} }
ProdStore <- Inf ProdStore <- Inf
if (!is.null(RoutStore)) { if (!is.null(RoutStore)) {
if (verbose) { if (verbose) {
warning(sprintf("'%s' does not require 'RoutStore'. Values set to NA", as.character(substitute(FUN_MOD)))) warning(sprintf("'%s' does not require 'RoutStore'. Values set to NA", FeatFUN_MOD$NameFunMod))
} }
} }
RoutStore <- Inf RoutStore <- Inf
if (!is.null(ExpStore)) { if (!is.null(ExpStore)) {
if (verbose) { if (verbose) {
warning(sprintf("'%s' does not require 'ExpStore'. Values set to NA", as.character(substitute(FUN_MOD)))) warning(sprintf("'%s' does not require 'ExpStore'. Values set to NA", FeatFUN_MOD$NameFunMod))
} }
} }
ExpStore <- Inf ExpStore <- Inf
if (!is.null(IntStore)) {
if (verbose) {
warning(sprintf("'%s' does not require 'IntStore'. Values set to NA", FeatFUN_MOD$NameFunMod))
}
}
IntStore <- Inf
if (!is.null(UH1)) { if (!is.null(UH1)) {
if (verbose) { if (verbose) {
warning(sprintf("'%s' does not require 'UH1'. Values set to NA", as.character(substitute(FUN_MOD)))) warning(sprintf("'%s' does not require 'UH1'. Values set to NA", FeatFUN_MOD$NameFunMod))
} }
} }
UH1 <- rep(Inf, UH1n) UH1 <- rep(Inf, UH1n)
if (!is.null(UH2)) { if (!is.null(UH2)) {
if (verbose) { if (verbose) {
warning(sprintf("'%s' does not require 'UH2'. Values set to NA", as.character(substitute(FUN_MOD)))) warning(sprintf("'%s' does not require 'UH2'. Values set to NA", FeatFUN_MOD$NameFunMod))
} }
} }
UH2 <- rep(Inf, UH2n) UH2 <- rep(Inf, UH2n)
} }
if("CemaNeige" %in% ObjectClass & if (IsIntStore & is.null(IntStore)) {
stop(sprintf("'%s' need values for 'IntStore'", FeatFUN_MOD$NameFunMod))
}
if ("CemaNeige" %in% ObjectClass & !IsHyst &
(is.null(GCemaNeigeLayers) | is.null(eTGCemaNeigeLayers))) { (is.null(GCemaNeigeLayers) | is.null(eTGCemaNeigeLayers))) {
stop("'RunModel_CemaNeigeGR*' need values for 'GCemaNeigeLayers' and 'GCemaNeigeLayers'") stop(sprintf("'%s' need values for 'GCemaNeigeLayers' and 'GCemaNeigeLayers'", FeatFUN_MOD$NameFunMod))
return(NULL) }
if ("CemaNeige" %in% ObjectClass & IsHyst &
(is.null(GCemaNeigeLayers) | is.null(eTGCemaNeigeLayers) |
is.null(GthrCemaNeigeLayers) | is.null(GlocmaxCemaNeigeLayers))) {
stop(sprintf("'%s' need values for 'GCemaNeigeLayers', 'GCemaNeigeLayers', 'GthrCemaNeigeLayers' and 'GlocmaxCemaNeigeLayers'", FeatFUN_MOD$NameFunMod))
}
if ("CemaNeige" %in% ObjectClass & !IsHyst &
(!is.null(GthrCemaNeigeLayers) | !is.null(GlocmaxCemaNeigeLayers))) {
if (verbose) {
warning(sprintf("'%s' does not require 'GthrCemaNeigeLayers' and 'GlocmaxCemaNeigeLayers'. Values set to NA", FeatFUN_MOD$NameFunMod))
}
GthrCemaNeigeLayers <- Inf
GlocmaxCemaNeigeLayers <- Inf
} }
if(!"CemaNeige" %in% ObjectClass & if (!"CemaNeige" %in% ObjectClass &
(!is.null(GCemaNeigeLayers) | !is.null(eTGCemaNeigeLayers))) { (!is.null(GCemaNeigeLayers) | !is.null(eTGCemaNeigeLayers) | !is.null(GthrCemaNeigeLayers) | !is.null(GlocmaxCemaNeigeLayers))) {
if (verbose) { if (verbose) {
warning(sprintf("'%s' does not require 'GCemaNeigeLayers' and 'GCemaNeigeLayers'. Values set to NA", as.character(substitute(FUN_MOD)))) warning(sprintf("'%s' does not require 'GCemaNeigeLayers' 'GCemaNeigeLayers', 'GthrCemaNeigeLayers' and 'GlocmaxCemaNeigeLayers'. Values set to NA", FeatFUN_MOD$NameFunMod))
} }
GCemaNeigeLayers <- Inf GCemaNeigeLayers <- Inf
eTGCemaNeigeLayers <- Inf eTGCemaNeigeLayers <- Inf
GthrCemaNeigeLayers <- Inf
GlocmaxCemaNeigeLayers <- Inf
} }
## set states ## set states
if("CemaNeige" %in% ObjectClass) { if ("CemaNeige" %in% ObjectClass) {
NLayers <- length(InputsModel$LayerPrecip) NLayers <- length(InputsModel$LayerPrecip)
} else { } else {
NLayers <- 1 NLayers <- 1
} }
## manage NULL values ## manage NULL values
if (is.null(ExpStore)) { if (is.null(ExpStore)) {
ExpStore <- Inf ExpStore <- Inf
}
if (is.null(IntStore)) {
IntStore <- Inf
} }
if (is.null(UH1)) { if (is.null(UH1)) {
if ("hourly" %in% ObjectClass) { if ("hourly" %in% ObjectClass) {
...@@ -165,7 +172,7 @@ CreateIniStates <- function(FUN_MOD, InputsModel, ...@@ -165,7 +172,7 @@ CreateIniStates <- function(FUN_MOD, InputsModel,
} else { } else {
k <- 1 k <- 1
} }
UH1 <- rep(Inf, 20 * k) UH1 <- rep(Inf, UH1n * k)
} }
if (is.null(UH2)) { if (is.null(UH2)) {
if ("hourly" %in% ObjectClass) { if ("hourly" %in% ObjectClass) {
...@@ -173,7 +180,7 @@ CreateIniStates <- function(FUN_MOD, InputsModel, ...@@ -173,7 +180,7 @@ CreateIniStates <- function(FUN_MOD, InputsModel,
} else { } else {
k <- 1 k <- 1
} }
UH2 <- rep(Inf, 40 * k) UH2 <- rep(Inf, UH2n * k)
} }
if (is.null(GCemaNeigeLayers)) { if (is.null(GCemaNeigeLayers)) {
GCemaNeigeLayers <- rep(Inf, NLayers) GCemaNeigeLayers <- rep(Inf, NLayers)
...@@ -181,19 +188,29 @@ CreateIniStates <- function(FUN_MOD, InputsModel, ...@@ -181,19 +188,29 @@ CreateIniStates <- function(FUN_MOD, InputsModel,
if (is.null(eTGCemaNeigeLayers)) { if (is.null(eTGCemaNeigeLayers)) {
eTGCemaNeigeLayers <- rep(Inf, NLayers) eTGCemaNeigeLayers <- rep(Inf, NLayers)
} }
if (is.null(GthrCemaNeigeLayers)) {
GthrCemaNeigeLayers <- rep(Inf, NLayers)
}
if (any(is.infinite(GthrCemaNeigeLayers))) {
GthrCemaNeigeLayers <- rep(Inf, NLayers)
}
if (is.null(GlocmaxCemaNeigeLayers)) {
GlocmaxCemaNeigeLayers <- rep(Inf, NLayers)
}
if (any(is.infinite(GlocmaxCemaNeigeLayers))) {
GlocmaxCemaNeigeLayers <- rep(Inf, NLayers)
}
# check negative values # check negative values
if (any(ProdStore < 0) | any(RoutStore < 0) | if (any(ProdStore < 0) | any(RoutStore < 0) | any(IntStore < 0) |
any(UH1 < 0) | any(UH2 < 0) | any(UH1 < 0) | any(UH2 < 0) |
any(GCemaNeigeLayers < 0)) { any(GCemaNeigeLayers < 0)) {
stop("Negative values are not allowed for any of 'ProdStore', 'RoutStore', 'UH1', 'UH2', 'GCemaNeigeLayers'") stop("Negative values are not allowed for any of 'ProdStore', 'RoutStore', 'IntStore', 'UH1', 'UH2', 'GCemaNeigeLayers'")
} }
## check length ## check length
if (!is.numeric(ProdStore) || length(ProdStore) != 1L) { if (!is.numeric(ProdStore) || length(ProdStore) != 1L) {
print(ProdStore)
stop("'ProdStore' must be numeric of length one") stop("'ProdStore' must be numeric of length one")
} }
if (!is.numeric(RoutStore) || length(RoutStore) != 1L) { if (!is.numeric(RoutStore) || length(RoutStore) != 1L) {
...@@ -202,16 +219,19 @@ CreateIniStates <- function(FUN_MOD, InputsModel, ...@@ -202,16 +219,19 @@ CreateIniStates <- function(FUN_MOD, InputsModel,
if (!is.numeric(ExpStore) || length(ExpStore) != 1L) { if (!is.numeric(ExpStore) || length(ExpStore) != 1L) {
stop("'ExpStore' must be numeric of length one") stop("'ExpStore' must be numeric of length one")
} }
if ( "hourly" %in% ObjectClass & (!is.numeric(UH1) || length(UH1) != 480L)) { if (!is.numeric(IntStore) || length(IntStore) != 1L) {
stop("'IntStore' must be numeric of length one")
}
if ( "hourly" %in% ObjectClass & (!is.numeric(UH1) || length(UH1) != UH1n * 24)) {
stop(sprintf("'UH1' must be numeric of length 480 (%i * 24)", UH1n)) stop(sprintf("'UH1' must be numeric of length 480 (%i * 24)", UH1n))
} }
if (!"hourly" %in% ObjectClass & (!is.numeric(UH1) || length(UH1) != 20L)) { if (!"hourly" %in% ObjectClass & (!is.numeric(UH1) || length(UH1) != UH1n)) {
stop(sprintf("'UH1' must be numeric of length %i", UH1n)) stop(sprintf("'UH1' must be numeric of length %i", UH1n))
} }
if ( "hourly" %in% ObjectClass & (!is.numeric(UH2) || length(UH2) != 960L)) { if ( "hourly" %in% ObjectClass & (!is.numeric(UH2) || length(UH2) != UH2n * 24)) {
stop(sprintf("'UH2' must be numeric of length 960 (%i * 24)", UH2n)) stop(sprintf("'UH2' must be numeric of length 960 (%i * 24)", UH2n))
} }
if (!"hourly" %in% ObjectClass & (!is.numeric(UH2) || length(UH2) != 40L)) { if (!"hourly" %in% ObjectClass & (!is.numeric(UH2) || length(UH2) != UH2n)) {
stop(sprintf("'UH2' must be numeric of length %i (2 * %i)", UH2n, UH1n)) stop(sprintf("'UH2' must be numeric of length %i (2 * %i)", UH2n, UH1n))
} }
if (!is.numeric(GCemaNeigeLayers) || length(GCemaNeigeLayers) != NLayers) { if (!is.numeric(GCemaNeigeLayers) || length(GCemaNeigeLayers) != NLayers) {
...@@ -220,18 +240,54 @@ CreateIniStates <- function(FUN_MOD, InputsModel, ...@@ -220,18 +240,54 @@ CreateIniStates <- function(FUN_MOD, InputsModel,
if (!is.numeric(eTGCemaNeigeLayers) || length(eTGCemaNeigeLayers) != NLayers) { if (!is.numeric(eTGCemaNeigeLayers) || length(eTGCemaNeigeLayers) != NLayers) {
stop(sprintf("'eTGCemaNeigeLayers' must be numeric of length %i", NLayers)) stop(sprintf("'eTGCemaNeigeLayers' must be numeric of length %i", NLayers))
} }
if (IsHyst) {
if (!is.numeric(GthrCemaNeigeLayers) || length(GthrCemaNeigeLayers) != NLayers) {
stop(sprintf("'eTGCemaNeigeLayers' must be numeric of length %i", NLayers))
}
if (!is.numeric(GlocmaxCemaNeigeLayers) || length(GlocmaxCemaNeigeLayers) != NLayers) {
stop(sprintf("'eTGCemaNeigeLayers' must be numeric of length %i", NLayers))
}
}
# SD model state handling
if (!is.null(SD)) {
if (!inherits(InputsModel, "SD")) {
stop("'SD' argument provided and 'InputsModel' is not of class 'SD'")
}
if (!is.list(SD)) {
stop("'SD' argument must be a list")
}
lapply(SD, function(x) {
if (!is.numeric(x)) stop("Each item of 'SD' list argument must be numeric")
})
if (length(SD) != length(InputsModel$LengthHydro)) {
stop("Number of items of 'SD' list argument must be the same as the number of upstream connections",
sprintf(" (%i required, found %i)", length(InputsModel$LengthHydro), length(SD)))
}
}
## format output ## format output
IniStates <- list(Store = list(Prod = ProdStore, Rout = RoutStore, Exp = ExpStore), IniStates <- list(Store = list(Prod = ProdStore, Rout = RoutStore, Exp = ExpStore, Int = IntStore),
UH = list(UH1 = UH1, UH2 = UH2), UH = list(UH1 = UH1, UH2 = UH2),
CemaNeigeLayers = list(G = GCemaNeigeLayers, eTG = eTGCemaNeigeLayers)) CemaNeigeLayers = list(G = GCemaNeigeLayers, eTG = eTGCemaNeigeLayers,
Gthr = GthrCemaNeigeLayers, Glocmax = GlocmaxCemaNeigeLayers))
IniStatesNA <- unlist(IniStates) IniStatesNA <- unlist(IniStates)
IniStatesNA[is.infinite(IniStatesNA)] <- NA IniStatesNA[is.infinite(IniStatesNA)] <- NA
IniStatesNA <- relist(IniStatesNA, skeleton = IniStates) IniStatesNA <- relist(IniStatesNA, skeleton = IniStates)
if (!is.null(SD)) {
IniStatesNA$SD <- SD
}
class(IniStatesNA) <- c("IniStates", ObjectClass) class(IniStatesNA) <- c("IniStates", ObjectClass)
if (IsHyst) {
class(IniStatesNA) <- c(class(IniStatesNA), "hysteresis")
}
if (IsIntStore) {
class(IniStatesNA) <- c(class(IniStatesNA), "interception")
}
return(IniStatesNA) return(IniStatesNA)
} }
CreateInputsCrit <- function(FUN_CRIT, CreateInputsCrit <- function(FUN_CRIT,
InputsModel, InputsModel,
RunOptions, RunOptions,
Qobs, Obs,
VarObs = "Q",
BoolCrit = NULL, BoolCrit = NULL,
transfo = "", transfo = "",
Ind_zeroes = NULL, Weights = NULL,
epsilon = NULL, epsilon = NULL,
verbose = TRUE) { warnings = TRUE) {
ObjectClass <- NULL ObjectClass <- NULL
##check_FUN_CRIT ## ---------- check arguments
BOOL <- FALSE
## check 'InputsModel'
if (identical(FUN_CRIT, ErrorCrit_NSE) | identical(FUN_CRIT, ErrorCrit_KGE) | if (!inherits(InputsModel, "InputsModel")) {
identical(FUN_CRIT, ErrorCrit_KGE2) | identical(FUN_CRIT, ErrorCrit_RMSE)) { stop("'InputsModel' must be of class 'InputsModel'")
BOOL <- TRUE }
}
if (!BOOL) {
stop("incorrect FUN_CRIT for use in CreateInputsCrit \n") ## length of index of period to be used for the model run
return(NULL) LLL <- length(InputsModel$DatesR[RunOptions$IndPeriod_Run])
}
##check_arguments ## check 'Obs' and definition of idLayer
if (inherits(InputsModel, "InputsModel") == FALSE) { if (!is.numeric(unlist(Obs))) {
stop("InputsModel must be of class 'InputsModel' \n") stop("'Obs' must be a (list of) vector(s) of numeric values")
return(NULL) }
} Obs2 <- Obs
if (inherits(RunOptions , "RunOptions") == FALSE) { if ("ParamT" %in% VarObs) {
stop("RunOptions must be of class 'RunOptions' \n") if (is.list(Obs2)) {
return(NULL) Obs2[[which(VarObs == "ParamT")]] <- NULL
} } else {
Obs2 <- NULL
LLL <- length(InputsModel$DatesR[RunOptions$IndPeriod_Run]) }
}
if (is.null(Qobs)) { if (!is.null(Obs2)) {
stop("Qobs is missing \n") vecObs <- unlist(Obs2)
return(NULL) if (length(vecObs) %% LLL != 0) {
} stop(sprintf("'Obs' must be a (list of) vector(s) of numeric values of length %i", LLL), call. = FALSE)
if (!is.vector(Qobs)) { }
stop(paste("Qobs must be a vector of numeric values \n", sep = "")) }
return(NULL) if (!is.list(Obs)) {
} idLayer <- list(1L)
if (!is.numeric(Qobs)) { Obs <- list(Obs)
stop(paste("Qobs must be a vector of numeric values \n", sep = "")) } else {
return(NULL) idLayer <- lapply(Obs, function(i) {
} if (is.list(i)) {
if (length(Qobs) != LLL) { length(i)
stop("Qobs and InputsModel series must have the same length \n") } else {
return(NULL) 1L
} }
if (is.null(BoolCrit)) { })
BoolCrit <- rep(TRUE, length(Qobs)) Obs <- lapply(Obs, function(x) rowMeans(as.data.frame(x)))
} }
if (!is.logical(BoolCrit)) {
stop("BoolCrit must be a vector of boolean \n")
return(NULL) ## create list of arguments
} listArgs <- list(FUN_CRIT = FUN_CRIT,
if (length(BoolCrit) != LLL) { Obs = Obs,
stop("BoolCrit and InputsModel series must have the same length \n") VarObs = VarObs,
return(NULL) BoolCrit = BoolCrit,
} idLayer = idLayer,
if (is.null(transfo)) { transfo = as.character(transfo),
stop("transfo must be a chosen among the following: '', 'sqrt', 'log' or 'inv' or 'sort' \n") Weights = Weights,
return(NULL) epsilon = epsilon)
}
if (!is.vector(transfo)) {
stop("transfo must be a chosen among the following: '', 'sqrt', 'log' or 'inv' or 'sort' \n") ## check lists lengths
return(NULL) for (iArgs in names(listArgs)) {
} if (iArgs %in% c("Weights", "BoolCrit", "epsilon")) {
if (length(transfo) != 1) { if (any(is.null(listArgs[[iArgs]]))) {
stop("transfo must be a chosen among the following: '', 'sqrt', 'log' or 'inv' or 'sort' \n") listArgs[[iArgs]] <- lapply(seq_along(listArgs$FUN_CRIT), function(x) NULL)
return(NULL) }
} }
if (!is.character(transfo)) { if (iArgs %in% c("FUN_CRIT", "VarObs", "transfo", "Weights") & length(listArgs[[iArgs]]) > 1L) {
stop("transfo must be a chosen among the following: '', 'sqrt', 'log' or 'inv' or 'sort' \n") listArgs[[iArgs]] <- as.list(listArgs[[iArgs]])
return(NULL) }
} if (!is.list(listArgs[[iArgs]])) {
if (! transfo %in% c("", "sqrt", "log", "inv", "sort")) { listArgs[[iArgs]] <- list(listArgs[[iArgs]])
stop("transfo must be a chosen among the following: '', 'sqrt', 'log' or 'inv' or 'sort' \n") }
return(NULL) }
}
## check 'FUN_CRIT'
if (!missing(Ind_zeroes)) { listArgs$FUN_CRIT <- lapply(listArgs$FUN_CRIT, FUN = match.fun)
warning("Deprecated \"Ind_zeroes\" argument")
}
## check 'VarObs'
if (!is.null(epsilon)) { if (missing(VarObs)) {
if (!is.vector(epsilon) | listArgs$VarObs <- as.list(rep("Q", times = length(listArgs$Obs)))
length(epsilon) != 1 | !is.numeric(epsilon)) { # if (warnings) {
stop("epsilon must be single numeric value \n") # warning("'VarObs' automatically set to \"Q\"")
return(NULL) # }
} }
epsilon = as.double(epsilon)
}
## check 'VarObs' + 'RunOptions'
if (transfo == "log" & verbose) { if ("Q" %in% VarObs & !inherits(RunOptions, "GR")) {
warn_log_kge <- "we do not advise using the %s with a log transformation on Qobs (see the details part in the 'CreateInputsCrit' help)" stop("'VarObs' cannot contain Q if a GR rainfall-runoff model is not used")
if (identical(FUN_CRIT, ErrorCrit_KGE)) { }
warning(sprintf(warn_log_kge, "KGE")) 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)))
# if (warnings) {
# warning("'transfo' automatically set to \"\"")
# }
}
## check length of each args
if (length(unique(sapply(listArgs, FUN = length))) != 1) {
stopListArgs <- paste(sapply(names(listArgs), shQuote), collapse = ", ")
stop(sprintf("arguments %s must have the same length", stopListArgs))
}
## check 'RunOptions'
if (!inherits(RunOptions , "RunOptions")) {
stop("'RunOptions' must be of class 'RunOptions'")
}
## check 'Weights'
if (length(listArgs$Weights) > 1 & sum(unlist(listArgs$Weights)) == 0 & !any(sapply(listArgs$Weights, is.null))) {
stop("sum of 'Weights' cannot be equal to zero")
}
## ---------- 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", "ParamT")
msgVarObs <- "'VarObs' must be a (list of) character vector(s) and one of %s"
msgVarObs <- sprintf(msgVarObs, paste(sapply(inVarObs, shQuote), collapse = ", "))
inTransfo <- c("", "sqrt", "log", "inv", "sort", "boxcox") # pow is not checked by inTransfo, but appears in the warning message and checkef after (see ## check 'transfo')
msgTransfo <- "'transfo' must be a (list of) character vector(s) and one of %s, or numeric value for power transformation"
msgTransfo <- sprintf(msgTransfo, paste(sapply(inTransfo, shQuote), collapse = ", "))
## ---------- loop on the list of inputs
InputsCrit <- lapply(listArgs2, function(iListArgs2) {
## define FUN_CRIT as a character string
iListArgs2$FUN_CRIT <- match.fun(iListArgs2$FUN_CRIT)
## check 'FUN_CRIT'
if (!all(class(iListArgs2$FUN_CRIT) == c("FUN_CRIT", "function"))) {
stop("incorrect 'FUN_CRIT' for use in 'CreateInputsCrit'", call. = FALSE)
}
if (identical(iListArgs2$FUN_CRIT, ErrorCrit_RMSE) & length(listArgs$Weights) > 1 & all(!is.null(unlist(listArgs$Weights)))) {
stop("calculating a composite criterion with the RMSE is not allowed since RMSE is not a dimensionless metric", call. = FALSE)
}
## check 'Obs'
if (iListArgs2$VarObs == "ParamT") {
# Parameter for regularisation
L2 <- RunOptions$FeatFUN_MOD$NbParam
} else {
# Observation time series
L2 <- LLL
}
if (!is.vector(iListArgs2$Obs) | length(iListArgs2$Obs) != L2 | !is.numeric(iListArgs2$Obs)) {
stop(sprintf("'Obs' must be a (list of) vector(s) of numeric values of length %i", L2), call. = FALSE)
}
## check 'BoolCrit'
if (is.null(iListArgs2$BoolCrit)) {
iListArgs2$BoolCrit <- rep(TRUE, length(iListArgs2$Obs))
}
if (!is.logical(iListArgs2$BoolCrit)) {
stop("'BoolCrit' must be a (list of) vector(s) of boolean", call. = FALSE)
}
if (length(iListArgs2$BoolCrit) != L2) {
stop("'BoolCrit' and the period defined in 'RunOptions' must have the same length", call. = FALSE)
}
## check 'VarObs'
if (!is.vector(iListArgs2$VarObs) | length(iListArgs2$VarObs) != 1 | !is.character(iListArgs2$VarObs) | !all(iListArgs2$VarObs %in% inVarObs)) {
stop(msgVarObs, call. = FALSE)
}
## check 'VarObs' + 'Obs'
if (any(iListArgs2$VarObs %in% "SCA")) {
idSCA <- which(iListArgs2$VarObs == "SCA")
if (length(idSCA) == 1L) {
vecSCA <- iListArgs2$Obs
} else {
vecSCA <- unlist(iListArgs2$Obs[idSCA])
}
if (min(vecSCA, na.rm = TRUE) < 0 | max(vecSCA, na.rm = TRUE) > 1) {
stop("'Obs' outside [0,1] for \"SCA\"", call. = FALSE)
}
}
inPosVarObs <- c("Q", "SWE")
if (any(iListArgs2$VarObs %in% inPosVarObs)) {
idQSS <- which(iListArgs2$VarObs %in% inPosVarObs)
if (length(idQSS) == 1L) {
vecQSS <- iListArgs2$Obs
} else {
vecQSS <- unlist(iListArgs2$Obs[idQSS])
}
if (all(is.na(vecQSS))) {
stop("'Obs' contains only missing values", call. = FALSE)
}
if (min(vecQSS, na.rm = TRUE) < 0) {
stop(sprintf("'Obs' outside [0,Inf[ for \"%s\"", iListArgs2$VarObs), call. = FALSE)
}
}
## check 'transfo'
if (is.null(iListArgs2$transfo) | !is.vector(iListArgs2$transfo) | length(iListArgs2$transfo) != 1 | !is.character(iListArgs2$transfo)) {
stop(msgTransfo, call. = FALSE)
}
isNotInTransfo <- !(iListArgs2$transfo %in% inTransfo)
if (any(isNotInTransfo)) {
powTransfo <- iListArgs2$transfo[isNotInTransfo]
powTransfo <- gsub("\\^|[[:alpha:]]", "", powTransfo)
numExpTransfo <- suppressWarnings(as.numeric(powTransfo))
if (any(is.na(numExpTransfo))) {
stop(msgTransfo, call. = FALSE)
}
iListArgs2$transfo <- paste0("^", iListArgs2$transfo)
}
## check 'Weights'
if (!is.null(iListArgs2$Weights)) {
if (!is.vector(iListArgs2$Weights) | length(iListArgs2$Weights) != 1 | !is.numeric(iListArgs2$Weights) | any(iListArgs2$Weights < 0)) {
stop("'Weights' must be a single (list of) positive or equal to zero value(s)", call. = FALSE)
}
}
## check 'epsilon'
if (!is.null(iListArgs2$epsilon)) {
if (!is.vector(iListArgs2$epsilon) | length(iListArgs2$epsilon) != 1 | !is.numeric(iListArgs2$epsilon) | any(iListArgs2$epsilon <= 0)) {
stop("'epsilon' must be a single (list of) positive value(s)", call. = FALSE)
}
} else if (iListArgs2$transfo %in% c("log", "inv") & any(iListArgs2$Obs %in% 0) & warnings) {
warning("zeroes detected in Obs: the corresponding time-steps will be excluded by the 'ErrorCrit*' functions as the epsilon argument was set to NULL", call. = FALSE)
}
## check 'transfo' + 'FUN_CRIT'
if (iListArgs2$transfo == "log" & warnings) {
warn_log_kge <- "we do not advise using the %s with a log transformation on Obs (see the details section in the 'CreateInputsCrit' help)"
if (identical(iListArgs2$FUN_CRIT, ErrorCrit_KGE)) {
warning(sprintf(warn_log_kge, "KGE"), call. = FALSE)
}
if (identical(iListArgs2$FUN_CRIT, ErrorCrit_KGE2)) {
warning(sprintf(warn_log_kge, "KGE'"), call. = FALSE)
}
}
## Create InputsCrit
iInputsCrit <- list(FUN_CRIT = iListArgs2$FUN_CRIT,
Obs = iListArgs2$Obs,
VarObs = iListArgs2$VarObs,
BoolCrit = iListArgs2$BoolCrit,
idLayer = iListArgs2$idLayer,
transfo = iListArgs2$transfo,
epsilon = iListArgs2$epsilon,
Weights = iListArgs2$Weights)
class(iInputsCrit) <- c("Single", "InputsCrit", ObjectClass)
return(iInputsCrit)
})
names(InputsCrit) <- paste0("IC", seq_along(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 contain %i vector(s) about %s", nLayers, iInCnVarObs))
} }
if (identical(FUN_CRIT, ErrorCrit_KGE2)) { }
warning(sprintf(warn_log_kge, "KGE'")) }
}
}
##Create_InputsCrit
InputsCrit <- list(BoolCrit = BoolCrit,
Qobs = Qobs,
transfo = transfo,
epsilon = epsilon)
class(InputsCrit) <- c("InputsCrit", ObjectClass)
return(InputsCrit)
} }
## define idLayer as an index of the layer to use
for (iInCnVarObs in unique(listVarObs)) {
if (!iInCnVarObs %in% inCnVarObs) {
for (i in which(listVarObs == iInCnVarObs)) {
InputsCrit[[i]]$idLayer <- NA
}
} else {
aa <- listGroupLayer0[listVarObs == iInCnVarObs]
aa <- unname(aa)
bb <- cumsum(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)
} else {
if (any(sapply(listArgs$Weights, is.null))) {
for (iListArgs in InputsCrit) {
iListArgs$Weights <- NULL
}
class(InputsCrit) <- c("Multi", "InputsCrit", ObjectClass)
} else {
class(InputsCrit) <- c("Compo", "InputsCrit", ObjectClass)
}
combInputsCrit <- combn(x = length(InputsCrit), m = 2)
apply(combInputsCrit, MARGIN = 2, function(i) {
equalInputsCrit <- identical(InputsCrit[[i[1]]], InputsCrit[[i[2]]])
if (equalInputsCrit) {
warning(sprintf("elements %i and %i of the criteria list are identical. This might not be necessary", i[1], i[2]), call. = FALSE)
}
})
}
return(InputsCrit)
}
CreateInputsCrit_Lavenne <- function(FUN_CRIT = ErrorCrit_KGE,
InputsModel,
RunOptions,
Obs,
VarObs = "Q",
AprParamR,
AprCrit = 1,
k = 0.15,
BoolCrit = NULL,
transfo = "sqrt",
epsilon = NULL) {
# Check parameters
if (!is.numeric(AprCrit) || length(AprCrit) != 1 || AprCrit > 1) {
stop("'AprCrit' must be a numeric of length 1 with a maximum value of 1")
}
if (!is.numeric(k) || length(k) != 1 || k < 0 || k > 1) {
stop("'k' must be a numeric of length 1 with a value between 0 and 1")
}
if (!is.null(BoolCrit) && !is.logical(BoolCrit)) {
stop("'BoolCrit must be logical")
}
if (!is.character(transfo)) {
stop("'transfo' must be character")
}
if (!is.null(epsilon) && !is.numeric(epsilon)) {
stop("'epsilon' must be numeric")
}
if (!is.numeric(AprParamR) || length(AprParamR) != RunOptions$FeatFUN_MOD$NbParam) {
stop("'AprParamR' must be a numeric vector of length ",
RunOptions$FeatFUN_MOD$NbParam)
}
FUN_TRANSFO <- .FunTransfo(RunOptions$FeatFUN_MOD)
AprParamT <- FUN_TRANSFO(AprParamR, "RT")
ErrorCrit_GAPX <- CreateErrorCrit_GAPX(FUN_TRANSFO)
CreateInputsCrit(FUN_CRIT = list(FUN_CRIT, ErrorCrit_GAPX),
InputsModel = InputsModel,
RunOptions = RunOptions,
Obs = list(Obs, AprParamT),
VarObs = c("Q", "ParamT"),
Weights = c(1 - k, k * max(0, AprCrit)),
BoolCrit = list(BoolCrit, NULL),
transfo = list(transfo, ""),
epsilon = list(epsilon, NULL))
}
This diff is collapsed.