Source

Target

Commits (16)
Showing with 262 additions and 151 deletions
+262 -151
......@@ -22,7 +22,6 @@ S3method(plot,GRiwrm)
S3method(plot,GRiwrmOutputsModel)
S3method(plot,Qm3s)
export(Calibration)
export(CheckColumnTypes)
export(ConvertMeteoSD)
export(CreateCalibOptions)
export(CreateController)
......@@ -32,8 +31,9 @@ export(CreateInputsModel)
export(CreateRunOptions)
export(CreateSupervisor)
export(RunModel)
export(createControl)
import(airGR)
importFrom(grDevices,rainbow)
importFrom(graphics,matplot)
importFrom(graphics,par)
importFrom(graphics,plot)
importFrom(graphics,title)
#' Calibration of a semi-distributed run-off model
#'
#' @param InputsModel object of class \emph{GRiwrmInputsModel}, see [CreateInputsModel.GRiwrm] for details.
#' @param RunOptions object of class \emph{GRiwrmRunOptions}, see [CreateRunOptions.GRiwrmInputsModel] for details.
#' @param InputsCrit object of class \emph{GRiwrmInputsCrit}, see [CreateInputsCrit.GRiwrmInputsModel] for details.
#' @param CalibOptions object of class \emph{GRiwrmCalibOptions}, see [CreateCalibOptions.GRiwrmInputsModel] for details.
#' @param useUpstreamQsim boolean describing if simulated (\code{TRUE}) or observed (\code{FALSE}) flows are used for calibration. Default is \code{TRUE}.
#' @param ... further arguments passed to [airGR::Calibration].
#'
#' @return GRiwrmOutputsCalib object which is a list of OutputsCalib (See [airGR::Calibration]) for each node of the semi-distributed model.
#' @param useUpstreamQsim boolean describing if simulated (\code{TRUE}) or observed (\code{FALSE}) flows are used for calibration. Default is \code{TRUE}
#' @rdname Calibration
#' @export
Calibration.GRiwrmInputsModel <- function(InputsModel,
RunOptions,
......
#' Wrapper to [airGR::Calibration] for one sub-basin.
#'
#' @inherit airGR::Calibration
#' @param ... Further arguments for compatibility with S3 method
#' @rdname Calibration
#' @export
Calibration.InputsModel <- function(InputsModel, ...) {
airGR::Calibration(InputsModel, FUN_MOD = InputsModel$FUN_MOD, ...)
......
#' Calibration of either **airGR** model and **airGRiwrm** semi-distributive model
#' Calibration of the parameters of one catchment or a network of sub-catchments
#'
#' @param InputsModel the class of the first parameter determine which calibration is used
#' @param ... further arguments passed to or from other methods.
#' Calibration algorithm that optimises the error criterion selected as objective function using the provided functions.
#'
#' @return \emph{OutputsCalib} or \emph{GRiwrmOutputsCalib} object
#' This function can be used either for a catchment (with an \emph{InputsModel} object) or for a network (with a \emph{GRiwrmInputsModel} object)
#'
#' @param InputsModel \[object of class \emph{InputsModel} or \emph{GRiwrmInputsModel}\] see [CreateInputsModel]
#' @param RunOptions \[object of class \emph{RunOptions} or \emph{GRiwrmRunOptions}\] see [CreateRunOptions]
#' @param InputsCrit \[object of class \emph{InputsCrit} or \emph{GRiwrmInputsCrit}\] see [CreateInputsCrit]
#' @param CalibOptions \[object of class \emph{CalibOptions} or \emph{GRiwrmCalibOptions}\] see [CreateCalibOptions] for details
#' @param ... further arguments passed to [airGR::Calibration], see details
#'
#' @details Argument classes should be consistent to the usage:
#' - a `InputsModel` argument of class \emph{InputsModel} must be followed by a `RunOptions` argument of class \emph{RunOptions}, a `InputsCrit` argument of class \emph{InputsCrit} and a `CalibOptions` of class \emph{CalibOptions}
#' - - a `InputsModel` argument of class \emph{GRiwrmInputsModel} must be followed by a `RunOptions` argument of class \emph{GRiwrmRunOptions}, a `InputsCrit` argument of class \emph{GRiwrmInputsCrit} and a `CalibOptions` of class \emph{GRiwrmCalibOptions}
#'
#' See the vignettes for examples.
#'
#' @return Depending on the class of `InputsModel` argument (respectively `InputsModel` and `GRiwrmInputsModel` object), the returned value is respectively:
#' - a `InputsCrit` object (See [airGR::CreateInputsCrit])
#' - a `GRiwrmInputsCrit` object which is a [list] of `InputsCrit` object with one item per modelled sub-catchment
#'
#' @rdname Calibration
#' @export
Calibration <- function(InputsModel, ...) {
UseMethod("Calibration", InputsModel)
......
#' Convert meteorological data from basin scale to sub-basin scale
#' Conversion of meteorological data from basin scale to sub-basin scale
#'
#' @param x either a `GRiwrm` network description (See [CreateGRiwrm]), a [character] id of a node, a [matrix] containing meteorological data
#' @param x either a `GRiwrm` network description (See [CreateGRiwrm]), a [character] id of a node, or a [matrix] containing meteorological data
#' @param ... Parameters passed to the methods
#'
#' @return Either a [matrix] containing the converted meteorological data
#' @return [matrix] a matrix containing the converted meteorological data
#' @export
#' @rdname ConvertMeteoSD
#'
......@@ -11,7 +11,7 @@ ConvertMeteoSD <- function(x, ...) {
UseMethod("ConvertMeteoSD")
}
#' @param meteo [matrix] or [data.frame] containing meteorological data. Its [colnames] should be equal to the IDof the basins
#' @param meteo [matrix] or [data.frame] containing meteorological data. Its [colnames] should be equal to the ID of the basins
#' @export
#' @rdname ConvertMeteoSD
ConvertMeteoSD.GRiwrm <- function(x, meteo, ...) {
......@@ -22,7 +22,7 @@ ConvertMeteoSD.GRiwrm <- function(x, meteo, ...) {
return(meteoOut)
}
#' @param griwrm `GRiwrm` object describing the semi-distributive network (See [CreateGRiwrm])
#' @param griwrm `GRiwrm` object describing the semi-distributed network (See [CreateGRiwrm])
#' @export
#' @rdname ConvertMeteoSD
ConvertMeteoSD.character <- function(x, griwrm, meteo, ...) {
......@@ -39,8 +39,8 @@ ConvertMeteoSD.character <- function(x, griwrm, meteo, ...) {
return(output)
}
#' @param areas [numeric] vector with the total area of the basin followed by the areas of the upstream basins in km^2^
#' @param temperature [logical] `TRUE` if the meteorological data is temperature. if `FALSE` minimum output values are bounded to zero
#' @param areas [numeric] vector with the total area of the basin followed by the areas of the upstream basins in km2
#' @param temperature [logical] `TRUE` if the meteorological data contain air temperature. If `FALSE` minimum output values are bounded to zero
#' @export
#' @rdname ConvertMeteoSD
ConvertMeteoSD.matrix <- function(x, areas, temperature = FALSE, ...) {
......
#' Title
#'
#' @param InputsModel object of class \emph{GRiwrmInputsModel}, see [CreateInputsModel.GRiwrm] for details.
#' @param ... further arguments passed to [airGR::CreateCalibOptions].
#'
#' @return \emph{GRiwrmCalibOptions} object.
#' @rdname CreateCalibOptions
#' @export
CreateCalibOptions.GRiwrmInputsModel <- function(InputsModel, ...) {
......
#' Wrapper to [airGR::CreateCalibOptions] for one sub-basin.
#'
#' @param InputsModel object of class \emph{InputsModel}. See [airGR::CreateInputsModel] for details
#' @param ... Arguments passed to [airGR::CreateCalibOptions]
#' @rdname CreateCalibOptions
#' @export
CreateCalibOptions.InputsModel <- function(InputsModel,
...) {
......
#' CreateCalibOptions both available for \emph{InputsModel} and \emph{GRwirmInputsModel} objects
#' Creation of the CalibOptions object
#'
#' @param InputsModel object of class \emph{InputsModel} or \emph{GRwirmInputsModel}. See [CreateInputsModel] for details
#' @param ... further arguments passed to or from other methods
#' This function can be used either for a catchment (with an \emph{InputsModel} object) or for a network (with a \emph{GRiwrmInputsModel} object)
#'
#' @return Either a `CalibOptions` or a `GRiwrmCalibOptions` object
#' @param InputsModel object of class \emph{InputsModel} or \emph{GRiwrmInputsModel}. See [CreateInputsModel] for details
#' @param ... arguments passed to [airGR::CreateCalibOptions], see details
#'
#' @details See [airGR::CreateCalibOptions] documentation for a complete list of arguments.
#'
#' With a \emph{GRiwrmInputsModel} object, all arguments are applied on each sub-catchments of the network.
#'
#' @return Depending on the class of `InputsModel` argument (respectively `InputsModel` and `GRiwrmInputsModel` object), the returned value is respectively:
#' - a `CalibOptions` object (See [airGR::CreateCalibOptions])
#' - a `GRiwrmCalibOptions` object which is a [list] of `CalibOptions` object with one item per modelled sub-catchment
#'
#' @rdname CreateCalibOptions
#' @export
CreateCalibOptions <- function(InputsModel, ...) {
UseMethod("CreateCalibOptions", InputsModel)
......
#' Create and add a controller in a supervisor
#' Creation and adding of a controller in a supervisor
#'
#' @details
#' `ctrl.id` parameter is a unique id for finding the controller in the supervisor.
#' The `ctrl.id` is a unique id for finding the controller in the supervisor.
#' If a controller with the same id already exists, it is overwritten by this new one.
#'
#' `FUN` parameter should be a function with one [numeric] parameter.
#' `FUN` should be a function with one [numeric] parameter.
#' This parameter will receive the measured values of at `Y` locations as input
#' for the previous time step and returns calculated `U`. These `U` will then be applied
#' at their location for the current time step of calculation of the model.
#'
#' @param supervisor `Supervisor` object, see [CreateSupervisor]
#' @param ctrl.id [character] id of the controller (see Details)
#' @param Y [character] location of the controlled and/or measured variables in the model. See [createControl]
#' @param U [character] location of the command variables in the model. See [createControl]
#' @param Y [character] location of the controlled and/or measured variables in the model.
#' @param U [character] location of the command variables in the model.
#' @param FUN [function] controller logic which calculates `U` from `Y` (see Details)
#'
#' @return `Controller`
#' @return a `Controller` object which is a list with the following items:
#' - `id` [character]: the controller identifier
#' - `U` [matrix]: the list of controls for command variables with each column being the location of the variables and the rows being
#' the values of the variable for the current time steps (empty by default)
#' - `Unames` [character]: location of the command variables
#' - `Y` [matrix]: the lists of controls for controlled variables with each column being the location of the variables and the rows being
#' the values of the variable for the current time steps (empty by default)
#' - `Ynames` [character]: location of the controlled variables
#' - `FUN` [function]: controller logic which calculates `U` from `Y`
#' @export
#'
#' @examples
......@@ -33,9 +41,9 @@ CreateController <- function(supervisor, ctrl.id, Y, U, FUN){
ctrlr <- list(
id = ctrl.id,
U = createControl(U),
U = CreateControl(U),
Unames = U,
Y = createControl(Y),
Y = CreateControl(Y),
Ynames = Y,
FUN = FUN
)
......@@ -51,18 +59,18 @@ CreateController <- function(supervisor, ctrl.id, Y, U, FUN){
invisible(ctrlr)
}
#' Create a list of controls for command (U) and controlled variables (Y)
#' Creation of a list of controls for command (U) and controlled variables (Y)
#'
#' @param locations vector of [character] containing the location of the variable in the model (see details)
#' @param locations [character] containing the location of the variable in the model (see details)
#'
#' @return a [matrix] with each column is the location of the variables and the rows
#' @return [matrix] with each column being the location of the variables and the rows being
#' the values of the variable for the current time steps (empty by default)
#' @export
#' @noRd
#'
#' @examples
#' # For pointing the discharge at the oulet of basins "54095" and "54002"
#' createControl(c("54095", "54002"))
createControl <- function(locations) {
#' CreateControl(c("54095", "54002"))
CreateControl <- function(locations) {
if(!is.character(locations)) {
stop("Parameter `locations` should be character")
}
......
#' Generate a network description containing all hydraulic nodes and the description
#' Generation of a network description containing all hydraulic nodes and the description
#' of their connections
#'
#' @details `db` is a [data.frame] which at least contains in its columns:
#'
#' * a node identifier (column `id`),
#' * the identifier and the hydraulic distance to the downstream node ([character] columns `down` and [numeric] columns `length` in km). The last downstream node should have fields `down` and `length` set to `NA`,
#' * the area of the basin ([numeric] column `area` in km^2^)
#' * the hydrological model to use if so ([character] column `model`) ([NA] for using observed flow instead of a run-off model output)
#' * the area of the basin ([numeric] column `area` in km2)
#' * the hydrological model to use if necessary ([character] column `model`) ([NA] for using observed flow instead of a runoff model output)
#'
#' @param db a [data.frame] containing the description of the network (See details)
#' @param cols named list or vector for matching columns of `db` parameter. By default, mandatory columns names are: `id`, `down`, `length`. But other names can be handled with a named list or vector containing items defined as `"required name" = "column name in db"`
#' @param keep_all keep all column of `db` or keep only columns defined in `cols`
#' @param db [data.frame] description of the network (See details)
#' @param cols [list] or [vector] columns of `db`. By default, mandatory column names are: `id`, `down`, `length`. Other names can be handled with a named list or vector containing items defined as `"required name" = "column name in db"`
#' @param keep_all [logical] indicating if all columns of `db` should be kept or if only columns defined in `cols` should be kept
#'
#' @return An object of class `GRiwrm` describing the airGR semi-distributed model network.
#'
#' It's a [data.frame] with each line corresponding to a location on the river network and with the following columns:
#' @return [data.frame] of class `GRiwrm` describing the airGR semi-distributed model network, with each line corresponding to a location on the river network and with the following columns:
#' * `id` ([character]): node identifier
#' * `down` ([character]): the identifier of the node downstream of the current node ([NA] for the most downstream node)
#' * `length` ([numeric]): the hydraulic distance to the downstream node in km ([NA] for the most downstream node)
#' * `area` ([numeric]): the total area of the basin starting from the current node location in km^2^
#' * `model` ([character]): the hydrological model to use if so ([NA] for using observed flow instead of a run-off model output)
#' * `down` ([character]): identifier of the node downstream of the current node ([NA] for the most downstream node)
#' * `length` ([numeric]): hydraulic distance to the downstream node in km ([NA] for the most downstream node)
#' * `area` ([numeric]): total area of the basin starting from the current node location in km2
#' * `model` ([character]): hydrological model to use if necessary ([NA] for using observed flow instead of a runoff model output)
#'
#' @aliases GRiwrm
#' @export
......@@ -28,13 +26,13 @@
#' # Run the `airGR::RunModel_Lag` example in the GRiwrm fashion way #
#' ###################################################################
#'
#' # Run airGR RunModel_Lag example for harvesting necessary data
#' # Run the airGR RunModel_Lag example for harvesting the necessary data
#' library(airGR)
#' example(RunModel_Lag)
#' # detach the package because airGR overwrite airGRiwrm functions here
#' # detach the package because otherwise airGR overwrites the airGRiwrm functions
#' detach("package:airGR")
#'
#' # This example is a network of 2 nodes which can be describe like this:
#' # This example is a network of 2 nodes which can be described like this:
#' db <- data.frame(id = c("Reservoir", "GaugingDown"),
#' length = c(LengthHydro, NA),
#' down = c("GaugingDown", NA),
......@@ -80,19 +78,19 @@ CreateGRiwrm <- function(db,
db
}
#' Check the column types of a [data.frame]
#' Check of the column types of a [data.frame]
#'
#' @param df [data.frame] to check
#' @param coltypes named [list] with the name of the columns to check as key and the required type as value
#'
#' @return [NULL] or throw an error if a wrong type is detected.
#' @export
#' @return [NULL] or error message if a wrong type is detected
#' @examples
#' CheckColumnTypes(
#' data.frame(string = c("A"), numeric = c(1), stringsAsFactors = FALSE),
#' list(string = "character", numeric = "double")
#' )
#'
#' @noRd
CheckColumnTypes <- function(df, coltypes) {
lapply(names(df), function(x) {
if (typeof(df[[x]]) != coltypes[[x]]) {
......@@ -109,11 +107,12 @@ CheckColumnTypes <- function(df, coltypes) {
return(NULL)
}
#' Sort the nodes from upstream to downstream.
#' Sorting of the nodes from upstream to downstream
#'
#' @param griwrm See [CreateGRiwrm]
#' @param griwrm \[object of class `GRiwrm`\] see [CreateGRiwrm] for details
#'
#' @return vector with the ordered node names.
#' @return [numeric] ordered node names
#' @noRd
getNodeRanking <- function(griwrm) {
if (!inherits(griwrm, "GRiwrm")) {
stop("getNodeRanking: griwrm argument should be of class GRiwrm")
......
#' Create \emph{GRiwrmInputsCrit} object for **airGRiwrm**.
#'
#' This function does the same operations as [airGR::CreateInputsCrit] for all sub-basins of the GRiwrm model.
#'
#' @param InputsModel object of class \emph{GRiwrmInputsModel}, see [CreateInputsModel.GRiwrm] for details.
#' @param FUN_CRIT \[function (atomic or list)\] error criterion function (e.g. [airGR::ErrorCrit_RMSE], [airGR::ErrorCrit_NSE])
#' @param RunOptions object of class \emph{GRiwrmRunOptions}, see [CreateRunOptions.GRiwrmInputsModel] for details.
#' @param Obs matrix or data frame containing observed flows. Column names correspond to nodes ID
#' @param ... further arguments passed to [airGR::CreateInputsCrit].
#'
#' @return Object of class \emph{GRiwrmInputsCrit} which is a list of `airGR::InputsCrit` objects (See [airGR::CreateInputsCrit])
#' @rdname CreateInputsCrit
#' @export
CreateInputsCrit.GRiwrmInputsModel <- function(InputsModel,
FUN_CRIT = airGR::ErrorCrit_NSE,
......
#' Wrapper to [airGR::CreateInputsCrit] for one sub-basin.
#'
#' @inherit airGR::CreateInputsCrit
#' @param ... Further arguments for compatibility with S3 method
#' @rdname CreateInputsCrit
#' @export
CreateInputsCrit.InputsModel <- function(InputsModel,
FUN_CRIT,
......
#' Creation of the InputsCrit object required to the ErrorCrit functions
#' Creation of the InputsCrit object required to the `ErrorCrit` functions
#'
#' @param InputsModel InputsModel for **airGRiwrm** (See \code{[CreateInputsModel.GRiwrmInputsModel]}) or **airGR** (See [airGR::CreateInputsModel])
#' @param ... further arguments passed to or from other methods.
#' This function can be used either for a catchment (with an \emph{InputsModel} object) or for a network (with a \emph{GRiwrmInputsModel} object)
#'
#' @return Either a `InputsCrit` or a `GRiwrmInputsCrit` object
#' @param InputsModel object of class \emph{InputsModel} or \emph{GRiwrmInputsModel}. See [CreateInputsModel]
#' @param FUN_CRIT \[function (atomic or list)\] error criterion function (e.g. [airGR::ErrorCrit_RMSE], [airGR::ErrorCrit_NSE])
#' @param RunOptions object of class \emph{RunOptions} or \emph{GRiwrmRunOptions}, see [CreateRunOptions]
#' @param Obs [numeric], [matrix] or [data.frame] series of observed flows, see details
#' @param ... arguments passed to [airGR::CreateInputsCrit], see details
#'
#' @details See [airGR::CreateInputsCrit] documentation for a complete list of arguments.
#'
#' `Obs` argument is equivalent to the same argument in [airGR::CreateInputsCrit] except that it must a [matrix] or a [data.frame] if `InputsModel` is a \emph{GRiwrmInputsModel} object. Then, each column of the [matrix] or [data.frame] represents the observations of one of the simulated node with the name of the columns representing the id of each node.
#'
#' With a \emph{GRiwrmInputsModel} object, all arguments are applied on each sub-catchments of the network.
#'
#' @return Depending on the class of `InputsModel` argument (respectively `InputsModel` and `GRiwrmInputsModel` object), the returned value is respectively:
#' - a `InputsCrit` object (See [airGR::CreateInputsCrit])
#' - a `GRiwrmInputsCrit` object which is a [list] of `InputsCrit` object with one item per modelled sub-catchment
#'
#' @rdname CreateInputsCrit
#' @export
CreateInputsCrit <- function(InputsModel, ...) {
UseMethod("CreateInputsCrit", InputsModel)
......
#' Create InputsModel object for a **airGRiwrm** network
#' Creation of an InputsModel object for a **airGRiwrm** network
#'
#' @param x GRiwrm object describing the diagram of the semi-distributed model (See [CreateGRiwrm])
#' @param DatesR Vector of POSIXt observation time steps
#' @param Precip Matrix or data frame of numeric containing precipitation in mm. Column names correspond to node IDs
#' @param PotEvap Matrix or data frame of numeric containing potential evaporation in mm. Column names correspond to node IDs
#' @param Qobs Matrix or data frame of numeric containing potential observed flow in mm. Column names correspond to node IDs
#' @param ... further arguments passed to [airGR::CreateInputsModel]
#' @param x \[GRiwrm object\] diagram of the semi-distributed model (See [CreateGRiwrm])
#' @param DatesR [POSIXt] vector of dates
#' @param Precip [matrix] or [data.frame] frame of numeric containing precipitation in \[mm per time step\]. Column names correspond to node IDs
#' @param PotEvap [matrix] or [data.frame] frame of numeric containing potential evaporation \[mm per time step\]. Column names correspond to node IDs
#' @param Qobs [matrix] or [data.frame] frame of numeric containing observed flows in \[mm per time step\]. Column names correspond to node IDs
#' @param PrecipScale (optional) named [vector] of [logical] indicating if the mean of the precipitation interpolated on the elevation layers must be kept or not, required to create CemaNeige module inputs, default `TRUE` (the mean of the precipitation is kept to the original value)
#' @param TempMean (optional) [matrix] or [data.frame] of time series of mean air temperature \[°C\], required to create the CemaNeige module inputs
#' @param TempMin (optional) [matrix] or [data.frame] of time series of minimum air temperature \[°C\], possibly used to create the CemaNeige module inputs
#' @param TempMax (optional) [matrix] or [data.frame] of time series of maximum air temperature \[°C\], possibly used to create the CemaNeige module inputs
#' @param ZInputs (optional) named [vector] of [numeric] giving the mean elevation of the Precip and Temp series (before extrapolation) \[m\], possibly used to create the CemaNeige module input
#' @param HypsoData (optional) [matrix] or [data.frame] containing 101 [numeric] rows: min, q01 to q99 and max of catchment elevation distribution \[m\], if not defined a single elevation is used for CemaNeige
#' @param NLayers (optional) named [vector] of [numeric] integer giving the number of elevation layers requested [-], required to create CemaNeige module inputs, default=5
#' @param ... used for compatibility with S3 methods
#'
#' @return GRiwrmInputsModel object equivalent to **airGR** InputsModel object for a semi-distributed model (See [airGR::CreateInputsModel])
#' @details Meteorological data are needed for the nodes of the network that represent a catchment simulated by a rainfall-runoff model. Instead of [airGR::CreateInputsModel] that has [numeric] [vector] as time series inputs, this function uses [matrix] or [data.frame] with the id of the sub-catchment as column names. For single values (`ZInputs` or `NLayers`), the function requires named [vector] with the id of the sub-catchment as name item. If an argument is optional, only the column or the named item has to be provided.
#'
#' See [airGR::CreateInputsModel] documentation for details concerning each input.
#'
#' @return A \emph{GRiwrmInputsModel} object which is a list of \emph{InputsModel} objects created by [airGR::CreateInputsModel] with one item per modelled sub-catchment.
#' @export
#' @examples
#' #################################################################
#' # Run the `airGRRunModel_Lag` example in the GRiwrm fashion way #
#' #################################################################
#' ##################################################################
#' # Run the `airGR RunModel_Lag` example in the GRiwrm fashion way #
#' ##################################################################
#'
#' # Run airGR RunModel_Lag example for harvesting necessary data
#' # Run the airGR RunModel_Lag example for harvesting necessary data
#' library(airGR)
#' example(RunModel_Lag)
#' # detach the package because airGR overwrite airGRiwrm functions here
#' # detach the package because otherwise airGR overwrites the airGRiwrm functions
#' detach("package:airGR")
#'
#' # This example is a network of 2 nodes which can be describe like this:
#' # This example is a network of 2 nodes which can be described like this:
#' db <- data.frame(id = c("Reservoir", "GaugingDown"),
#' length = c(LengthHydro, NA),
#' down = c("GaugingDown", NA),
......@@ -33,7 +44,7 @@
#' str(griwrm)
#'
#' # Formatting observations for the hydrological models
#' # Each input data should be a matrix or a data.frame with the good id in the name of the column
#' # Each input data should be a matrix or a data.frame with the correct id as the column name
#' Precip <- matrix(BasinObs$P, ncol = 1)
#' colnames(Precip) <- "GaugingDown"
#' PotEvap <- matrix(BasinObs$E, ncol = 1)
......@@ -53,27 +64,72 @@
#' Qobs = Qobs)
#' str(InputsModels)
#'
CreateInputsModel.GRiwrm <- function(x, DatesR, Precip, PotEvap, Qobs, ...) {
CreateInputsModel.GRiwrm <- function(x, DatesR,
Precip,
PotEvap = NULL,
Qobs,
PrecipScale = TRUE,
TempMean = NULL, TempMin = NULL,
TempMax = NULL, ZInputs = NULL,
HypsoData = NULL, NLayers = 5, ...) {
# Check and format inputs
varNames <- c("Precip", "PotEvap", "TempMean",
"TempMin", "TempMax", "ZInputs", "HypsoData", "NLayers")
names(varNames) <- varNames
lapply(varNames, function(varName) {
v <- get(varName)
if(!is.null(v)) {
if(is.matrix(v) || is.data.frame(v)) {
if(is.null(colnames(v))) {
stop(sprintf(
"'%s' must have column names",
varName
))
} else if(!all(colnames(v) %in% x$id)) {
stop(sprintf(
"'%s' column names must be included in 'id's of the GRiwrm object",
varName
))
}
} else if (!varName %in% c("ZInputs", "NLayers")) {
stop(sprintf("'%s' must be a matrix or a data.frame", varName))
}
}
})
InputsModel <- CreateEmptyGRiwrmInputsModel(x)
Qobs[is.na(Qobs)] <- -99 # airGR::CreateInputsModel doesn't accept NA values
for(id in getNodeRanking(x)) {
message("CreateInputsModel.GRiwrm: Treating sub-basin ", id, "...")
InputsModel[[id]] <- CreateOneGRiwrmInputsModel(
id, x, DatesR,Precip[,id], PotEvap[,id], Qobs, ...
)
InputsModel[[id]] <-
CreateOneGRiwrmInputsModel(id = id,
griwrm = x,
DatesR = DatesR,
Precip = getInputBV(Precip, id),
PrecipScale,
PotEvap = getInputBV(PotEvap, id),
TempMean = getInputBV(TempMean, id),
TempMin = getInputBV(TempMin, id),
TempMax = getInputBV(TempMax, id),
ZInputs = getInputBV(ZInputs, id),
HypsoData = getInputBV(HypsoData, id),
NLayers = getInputBV(NLayers, id, 5),
Qobs = Qobs
)
}
attr(InputsModel, "TimeStep") <- getModelTimeStep(InputsModel)
return(InputsModel)
}
#' Create an empty InputsModel object for **airGRiwrm** nodes
#' Creation of an empty InputsModel object for **airGRiwrm** nodes
#'
#' @param griwrm a `GRiwrm` object (See [CreateGRiwrm])
#'
#' @return \emph{GRiwrmInputsModel} empty object
#' @noRd
CreateEmptyGRiwrmInputsModel <- function(griwrm) {
InputsModel <- list()
class(InputsModel) <- c("GRiwrmInputsModel", class(InputsModel))
......@@ -90,9 +146,10 @@ CreateEmptyGRiwrmInputsModel <- function(griwrm) {
#' @param Precip time series of potential evapotranspiration (catchment average) (mm/time step)
#' @param PotEvap time series of potential evapotranspiration (catchment average) (mm/time step)
#' @param Qobs Matrix or data frame of numeric containing observed flow (mm/time step). Column names correspond to node IDs
##'
#'
#' @return \emph{InputsModel} object for one.
CreateOneGRiwrmInputsModel <- function(id, griwrm, DatesR, Precip, PotEvap, Qobs) {
#' @noRd
CreateOneGRiwrmInputsModel <- function(id, griwrm, ..., Qobs) {
node <- griwrm[griwrm$id == id,]
FUN_MOD <- griwrm$model[griwrm$id == id]
......@@ -111,15 +168,19 @@ CreateOneGRiwrmInputsModel <- function(id, griwrm, DatesR, Precip, PotEvap, Qobs
griwrm$area[griwrm$id %in% UpstreamNodes],
node$area - sum(griwrm$area[griwrm$id %in% UpstreamNodes], na.rm = TRUE)
)
if (BasinAreas[length(BasinAreas)] < 0) {
stop(sprintf(
"Area of the catchment %s must be greater than the sum of the areas of its upstream catchments",
id
))
}
names(BasinAreas) <- c(UpstreamNodes, id)
}
# Set model inputs with the **airGR** function
InputsModel <- CreateInputsModel(
FUN_MOD,
DatesR = DatesR,
Precip = Precip,
PotEvap = PotEvap,
...,
Qupstream = Qupstream,
LengthHydro = LengthHydro,
BasinAreas = BasinAreas
......@@ -142,14 +203,14 @@ CreateOneGRiwrmInputsModel <- function(id, griwrm, DatesR, Precip, PotEvap, Qobs
}
#' Check time steps of the model of all the nodes and return the time step in seconds
#' Check of time steps of the model for all nodes and return of the time step in seconds
#'
#' This function is called inside [CreateInputsModel.GRiwrm] for defining the time step of the big model.
#' Function that is called inside [CreateInputsModel.GRiwrm] for defining the time step of the complete model
#'
#' @param InputsModel a `GRiwrmInputsModel`
#'
#' @return A [numeric] representing the time step in seconds
#' @param InputsModel \[object of class `GRiwrmInputsModel`\]
#'
#' @return [numeric] time step in seconds
#' @noRd
getModelTimeStep <- function(InputsModel) {
TS <- sapply(InputsModel, function(x) {
if (inherits(x, "hourly")) {
......@@ -165,3 +226,32 @@ getModelTimeStep <- function(InputsModel) {
}
return(unique(TS))
}
#' Select the node input for input arguments of [airGR::CreateInputsModel]
#'
#' @param x [matrix] [data.frame] or named [vector] the input argument
#' @param id [character] the id of the node
#' @param unset default value if the id is not found in `x`
#'
#' @return the selected column or value in respect to `id`
#' @noRd
getInputBV <- function(x, id, unset = NULL) {
if(is.null(x)) {
return(unset)
}
if (is.matrix(x) || is.data.frame(x)) {
if (!id %in% colnames(x)) {
return(unset)
}
} else {
# vector (for ZInputs and NLayers)
if (length(x) == 1 && is.null(names(x))) {
return(x)
} else if(!id %in% names(x)) {
return(unset)
} else {
return(x[id])
}
}
return(x[, id])
}
#' Wrapper for [airGR::CreateInputsModel] for one sub-basin.
#' Wrapper for [airGR::CreateInputsModel] for one sub-basin
#'
#' @param x [function] hydrological model function (e.g. [airGR::RunModel_GR4J]...)
#' @param ... arguments passed to [airGR::CreateInputsModel]
......
#' Create \emph{GRiwrmRunOptions} object for running and calibrating model in **airGRiwrm**.
#'
#' @param InputsModel object of class \emph{GRiwrmInputsModel}, see [CreateInputsModel.GRiwrm] for details.
#' @param ... further arguments passed to [airGR::CreateRunOptions].
#'
#' @return \emph{GRiwrmRunOptions} object for running and calibrating model in **airGRiwrm**.
#' @rdname CreateRunOptions
#' @export
#' @inherit RunModel.GRiwrmInputsModel return examples
#'
CreateRunOptions.GRiwrmInputsModel <- function(InputsModel, ...) {
RunOptions <- list()
......
#' Wrapper for [airGR::CreateRunOptions] for one sub-basin.
#'
#' @param InputsModel object of class \emph{InputsModel}, see [airGR::CreateInputsModel] for details.
#' @param ... Arguments passed to [airGR::CreateRunOptions]
#' @rdname CreateRunOptions
#' @export
CreateRunOptions.InputsModel <- function(InputsModel, ...) {
......
#' Create \emph{RunOptions} object for **airGR** and **airGRiwrm**.
#' Creation of the CalibOptions object
#'
#' See [airGR::CreateRunOptions] and [CreateRunOptions.GRiwrmInputsModel] for usage.
#' This function can be used either for a catchment (with an \emph{InputsModel} object) or for a network (with a \emph{GRiwrmInputsModel} object)
#'
#' @param InputsModel object of class \emph{InputsModel} (see [airGR::CreateInputsModel]) or \emph{GRiwrmInputsModel} (See [CreateInputsModel.GRiwrm]).
#' @param ... further arguments passed to or from other methods.
#' @param InputsModel object of class \emph{InputsModel} or \emph{GRiwrmInputsModel}. See [CreateInputsModel] for details
#' @param ... arguments passed to [airGR::CreateRunOptions], see details
#'
#' @return Object of \emph{RunOptions} class family
#' @details See [airGR::CreateRunOptions] documentation for a complete list of arguments.
#'
#' With a \emph{GRiwrmInputsModel} object, all arguments are applied on each sub-catchments of the network.
#'
#' @return Depending on the class of `InputsModel` argument (respectively `InputsModel` and `GRiwrmInputsModel` object), the returned value is respectively:
#' - a `RunOptions` object (See [airGR::CreateRunOptions])
#' - a `GRiwrmRunOptions` object which is a [list] of `RunOptions` object with one item per modelled sub-catchment
#'
#' @rdname CreateRunOptions
#' @export
#' @inherit RunModel.GRiwrmInputsModel return examples
CreateRunOptions <- function(InputsModel, ...) {
UseMethod("CreateRunOptions", InputsModel)
}
#' Create a Supervisor for handling regulation in a model
#' Creation of a Supervisor for handling regulation in a model
#'
#' @param InputsModel `GRiwrmInputsModel` The inputs of the basin model
#' @param TimeStep [integer] The number of time steps between each supervision
#' @param InputsModel \[object of type `GRiwrmInputsModel`\] inputs of the model
#' @param TimeStep [numeric] number of time steps between each supervision
#'
#' @return `Supervisor` object
#' @return A `Supervisor` object which is an [environment] containing all the necessary variables to run a supervised simulation, such as:
#' - `DatesR` [POSIXct]: vector of date from `InputsModel`
#' - `InputsModel`: a copy of `InputsModel` provided by [CreateInputsModel.GRiwrm]
#' - `griwrm`: a copy of `griwrm` provided by [CreateGRiwrm]
#' - `Controllers` [list]: list of the controllers used in the supervised simulation (See [CreateController])
#' - some internal state variables updated during simulation (`ts.index`, `ts.previous`, `ts.date`, `ts.index0`, `controller.id`)
#' @export
#'
#' @examples
......
#' Run rainfall-runoff part of a sub-basin model
#' Run of a rainfall-runoff model on a sub-basin
#'
#' @inherit airGR::RunModel
#' @param x `InputsModel` used as `InputsModel` parameter for [airGR::RunModel]
#' @param x \[object of class `InputsModel`\] `InputsModel` for [airGR::RunModel]
#' @param ... further arguments passed to or from other methods
#'
#' @export
......