diff --git a/DESCRIPTION b/DESCRIPTION index 6224560f..6cbe66ea 100644 --- a/DESCRIPTION +++ b/DESCRIPTION @@ -1,7 +1,7 @@ Package: antaresRead Type: Package Title: Import, Manipulate and Explore the Results of an 'Antares' Simulation -Version: 2.6.2 +Version: 2.7.0 Authors@R: c( person("Tatiana", "Vargas", email = "tatiana.vargas@rte-france.com", role = c("aut", "cre")), person("Jalal-Edine", "ZAWAM", role = "aut"), @@ -39,7 +39,8 @@ Imports: httr, utils, memuse, - purrr + purrr, + lifecycle Suggests: rhdf5 (>= 2.24.0), testthat, diff --git a/NAMESPACE b/NAMESPACE index 1badafdd..a3692c35 100644 --- a/NAMESPACE +++ b/NAMESPACE @@ -1,119 +1,120 @@ -# Generated by roxygen2: do not edit by hand - -S3method("[",antaresDataTable) -S3method(as.antaresDataList,antaresDataList) -S3method(as.antaresDataList,antaresDataTable) -S3method(as.antaresDataList,data.frame) -S3method(as.antaresDataList,default) -S3method(as.antaresDataList,list) -S3method(as.antaresDataTable,antaresDataTable) -S3method(as.antaresDataTable,data.frame) -S3method(as.antaresDataTable,default) -S3method(copyToClipboard,antaresDataList) -S3method(copyToClipboard,data.frame) -S3method(copyToClipboard,default) -S3method(copyToClipboard,matrix) -S3method(merge,antaresDataTable) -S3method(print,antaresDataList) -S3method(print,antaresDataTable) -S3method(print,simOptions) -S3method(subset,antaresDataList) -S3method(summary,bindingConstraints) -S3method(viewAntares,antaresDataList) -S3method(viewAntares,default) -export(.getOptionsH5) -export(.h5ReadAntares) -export(.writeAntaresH5Fun) -export(aggregateResult) -export(api_delete) -export(api_get) -export(api_post) -export(api_put) -export(as.antaresDataList) -export(as.antaresDataTable) -export(changeTimeStep) -export(copyToClipboard) -export(extractDataList) -export(getAlias) -export(getAreas) -export(getDistricts) -export(getGeographicTrimming) -export(getIdCols) -export(getLinks) -export(hvdcModification) -export(isH5Opts) -export(mergeDigests) -export(parAggregateMCall) -export(ponderateMcAggregation) -export(readAntares) -export(readAntaresAreas) -export(readAntaresClusters) -export(readBindingConstraints) -export(readClusterDesc) -export(readClusterResDesc) -export(readClusterSTDesc) -export(readDigestFile) -export(readIni) -export(readIniAPI) -export(readIniFile) -export(readInputRES) -export(readInputTS) -export(readInputThermal) -export(readLayout) -export(readOptimCriteria) -export(removeVirtualAreas) -export(setAlias) -export(setHvdcAreas) -export(setRam) -export(setSimulationPath) -export(setSimulationPathAPI) -export(setTimeoutAPI) -export(showAliases) -export(simOptions) -export(viewAntares) -export(writeAntaresH5) -export(writeDigest) -import(bit64) -import(data.table) -import(doParallel) -import(jsonlite) -import(parallel) -import(plyr) -importFrom(doParallel,registerDoParallel) -importFrom(grDevices,col2rgb) -importFrom(grDevices,rgb) -importFrom(httr,DELETE) -importFrom(httr,GET) -importFrom(httr,POST) -importFrom(httr,PUT) -importFrom(httr,accept_json) -importFrom(httr,add_headers) -importFrom(httr,content) -importFrom(httr,content_type_json) -importFrom(httr,http_status) -importFrom(httr,stop_for_status) -importFrom(httr,timeout) -importFrom(memuse,Sys.meminfo) -importFrom(methods,is) -importFrom(pbapply,pblapply) -importFrom(pbapply,pboptions) -importFrom(plyr,llply) -importFrom(purrr,quietly) -importFrom(shiny,getDefaultReactiveDomain) -importFrom(shiny,incProgress) -importFrom(shiny,withProgress) -importFrom(stats,as.formula) -importFrom(stats,setNames) -importFrom(stats,weighted.mean) -importFrom(stringi,stri_replace_last_fixed) -importFrom(stringr,str_match) -importFrom(stringr,str_replace) -importFrom(stringr,str_split) -importFrom(utils,URLencode) -importFrom(utils,View) -importFrom(utils,read.table) -importFrom(utils,setTxtProgressBar) -importFrom(utils,txtProgressBar) -importFrom(utils,type.convert) -importFrom(utils,untar) -importFrom(utils,write.table) +# Generated by roxygen2: do not edit by hand + +S3method("[",antaresDataTable) +S3method(as.antaresDataList,antaresDataList) +S3method(as.antaresDataList,antaresDataTable) +S3method(as.antaresDataList,data.frame) +S3method(as.antaresDataList,default) +S3method(as.antaresDataList,list) +S3method(as.antaresDataTable,antaresDataTable) +S3method(as.antaresDataTable,data.frame) +S3method(as.antaresDataTable,default) +S3method(copyToClipboard,antaresDataList) +S3method(copyToClipboard,data.frame) +S3method(copyToClipboard,default) +S3method(copyToClipboard,matrix) +S3method(merge,antaresDataTable) +S3method(print,antaresDataList) +S3method(print,antaresDataTable) +S3method(print,simOptions) +S3method(subset,antaresDataList) +S3method(summary,bindingConstraints) +S3method(viewAntares,antaresDataList) +S3method(viewAntares,default) +export(.getOptionsH5) +export(.h5ReadAntares) +export(.writeAntaresH5Fun) +export(aggregateResult) +export(api_delete) +export(api_get) +export(api_post) +export(api_put) +export(as.antaresDataList) +export(as.antaresDataTable) +export(changeTimeStep) +export(copyToClipboard) +export(extractDataList) +export(getAlias) +export(getAreas) +export(getDistricts) +export(getGeographicTrimming) +export(getIdCols) +export(getLinks) +export(hvdcModification) +export(isH5Opts) +export(mergeDigests) +export(parAggregateMCall) +export(ponderateMcAggregation) +export(readAntares) +export(readAntaresAreas) +export(readAntaresClusters) +export(readBindingConstraints) +export(readClusterDesc) +export(readClusterResDesc) +export(readClusterSTDesc) +export(readDigestFile) +export(readIni) +export(readIniAPI) +export(readIniFile) +export(readInputRES) +export(readInputTS) +export(readInputThermal) +export(readLayout) +export(readOptimCriteria) +export(removeVirtualAreas) +export(setAlias) +export(setHvdcAreas) +export(setRam) +export(setSimulationPath) +export(setSimulationPathAPI) +export(setTimeoutAPI) +export(showAliases) +export(simOptions) +export(viewAntares) +export(writeAntaresH5) +export(writeDigest) +import(bit64) +import(data.table) +import(doParallel) +import(jsonlite) +import(parallel) +import(plyr) +importFrom(doParallel,registerDoParallel) +importFrom(grDevices,col2rgb) +importFrom(grDevices,rgb) +importFrom(httr,DELETE) +importFrom(httr,GET) +importFrom(httr,POST) +importFrom(httr,PUT) +importFrom(httr,accept_json) +importFrom(httr,add_headers) +importFrom(httr,content) +importFrom(httr,content_type_json) +importFrom(httr,http_status) +importFrom(httr,stop_for_status) +importFrom(httr,timeout) +importFrom(lifecycle,deprecated) +importFrom(memuse,Sys.meminfo) +importFrom(methods,is) +importFrom(pbapply,pblapply) +importFrom(pbapply,pboptions) +importFrom(plyr,llply) +importFrom(purrr,quietly) +importFrom(shiny,getDefaultReactiveDomain) +importFrom(shiny,incProgress) +importFrom(shiny,withProgress) +importFrom(stats,as.formula) +importFrom(stats,setNames) +importFrom(stats,weighted.mean) +importFrom(stringi,stri_replace_last_fixed) +importFrom(stringr,str_match) +importFrom(stringr,str_replace) +importFrom(stringr,str_split) +importFrom(utils,URLencode) +importFrom(utils,View) +importFrom(utils,read.table) +importFrom(utils,setTxtProgressBar) +importFrom(utils,txtProgressBar) +importFrom(utils,type.convert) +importFrom(utils,untar) +importFrom(utils,write.table) diff --git a/NEWS.md b/NEWS.md index 74cc2131..30c65bf9 100644 --- a/NEWS.md +++ b/NEWS.md @@ -1,5 +1,29 @@ > Copyright © 2016 RTE Réseau de transport d’électricité +# antaresRead 2.7.0 + +### Breaking changes (Antares v8.7.0) : + +* `readBindingConstraints()` read now Scenarized RHS for binding constraints (cf. Antares v8.7 changelog) + - function returns a new list structure +* Private function `fread_antares()` no longer returns warnings +* `api_put()/api_delete()` return a server error message + +BUGFIXES : + +* `readBindingConstraints()` read well study >= v8.3.2 + +DATA : + +* A test study in tar.gz format is available in version v8.7.0 +* An empty test study in version v8.7.0 for marginal cases + +Dependencies : + +* New package `lifecycle` to manage functions status/package status + + + # antaresRead 2.6.2 (development) BUGFIXES : diff --git a/R/API-methods.R b/R/API-methods.R index 49319bca..9ba0e907 100644 --- a/R/API-methods.R +++ b/R/API-methods.R @@ -144,7 +144,13 @@ api_put <- function(opts, endpoint, ..., default_endpoint = "v1/studies") { config, ... ) - stop_for_status(result) + api_content <- content(result) + if(!is.null(names(api_content))) + api_content <- paste0("\n[Description] : ", api_content$description, + "\n[Exception] : ", api_content$exception) + else + api_content <- NULL + stop_for_status(result, task = api_content) content(result) } @@ -178,6 +184,12 @@ api_delete <- function(opts, endpoint, ..., default_endpoint = "v1/studies") { config = config, ... ) - stop_for_status(result) + api_content <- content(result) + if(!is.null(names(api_content))) + api_content <- paste0("\n[Description] : ", api_content$description, + "\n[Exception] : ", api_content$exception) + else + api_content <- NULL + stop_for_status(result, task = api_content) content(result) } diff --git a/R/antaresRead-package.R b/R/antaresRead-package.R new file mode 100644 index 00000000..425b3c1c --- /dev/null +++ b/R/antaresRead-package.R @@ -0,0 +1,7 @@ +#' @keywords internal +"_PACKAGE" + +## usethis namespace: start +#' @importFrom lifecycle deprecated +## usethis namespace: end +NULL diff --git a/R/readBindingConstraints.R b/R/readBindingConstraints.R index f510d3bd..4cd4d63c 100644 --- a/R/readBindingConstraints.R +++ b/R/readBindingConstraints.R @@ -3,6 +3,9 @@ #' Read binding constraints #' #' @description +#' `r antaresRead:::badge_api_ok()` +#' `r lifecycle::badge("experimental")` +#' #' This function reads the binding constraints of an Antares project. #' #' Be aware that binding constraints are read in the input files of a study. So @@ -11,17 +14,29 @@ #' @inheritParams readAntares #' #' @return -#' \code{readBindingConstraints} returns an object of class \code{bindingConstraints}. -#' It is a named list with one element per read constraint. Each element is itself -#' a list with the following elements: -#' \item{enabled}{is the constraint enabled ?} -#' \item{timeStep}{time step the constraint applies to} -#' \item{operator}{type of constraint: equality, inequality on one side or both sides} -#' \item{coefficients}{elements containing the coefficients used by the constraint} -#' \item{values}{values used by the constraint. It contains one line per time step -#' and three columns "less", "greater" and "equal"} +#' An object of class \code{bindingConstraints}. This object is also a named +#' list with 3 sections per read constraint. +#' +#' @section Warning: +#' Since `release 2.7.0` the structure of the returned object has evolved for +#' all versions of study Antares: +#' - .ini parameters are in section `properties` +#' - Coeffcients links or thermal are in section `coefs` +#' - Values are already in section `values` +#' +#' @note +#' For an study Antares **version >=8.7.0**. Now contains `data.frame` with +#' one line per time step and \eqn{p} colums according to "scenarized RHS". +#' +#' For "both" case, you will find in section `values` two `data.frame` : +#' - One `data.frame` for `less` +#' - One `data.frame` for `greater` +#' +#' For an study Antares **version <8.7.0**. +#' +#' Section \code{values} contains one line +#' per time step and three columns "less", "greater" and "equal" #' -#' The \code{summary} method returns a data.frame with one line per constraint. #' #' #' @examples @@ -29,13 +44,26 @@ #' setSimulationPath() #' #' constraints <- readBindingConstraints() +#' +#' # read properties +#' constraints$properties +#' +#' # read coefs +#' constraints$coefs +#' +#' # read values +#' constraints$values +#' # both case ( study Antares >=8.7.0) +#' constraints$values$less +#' constraints$values$greater +#' +#' # display equation (only for study Antares <8.7.0) #' summary(constraints) #' #' } #' #' @export readBindingConstraints <- function(opts = simOptions()) { - if(isH5Opts(opts)){ if(.requireRhdf5_Antares(stopP = FALSE)){ return(h5ReadBindingConstraints(opts)) @@ -44,76 +72,254 @@ readBindingConstraints <- function(opts = simOptions()) { } } + ## + # API BLOC + ## + if(opts$typeLoad == 'api'){ - bindingConstraints <- read_secure_json(file.path(opts$inputPath, "bindingconstraints", "bindingconstraints"), - opts$token, timeout = opts$timeout, config = opts$httr_config) + bindingConstraints <- read_secure_json(file.path(opts$inputPath, + "bindingconstraints", + "bindingconstraints"), + opts$token, + timeout = opts$timeout, + config = opts$httr_config) }else{ - path <- file.path(opts$inputPath, "bindingconstraints/bindingconstraints.ini") - bindingConstraints <- readIniFile(path, stringsAsFactors = FALSE) + path <- file.path(opts$inputPath, + "bindingconstraints/bindingconstraints.ini") + bindingConstraints <- readIniFile(path, + stringsAsFactors = FALSE) } + ## + # Exception if no properties + ## + if(length(bindingConstraints) == 0) { warning("It looks like there is no binding constraints is this study.") return(NULL) } - for (i in 1:length(bindingConstraints)) { - path <- file.path(opts$inputPath, sprintf("bindingconstraints/%s.txt", bindingConstraints[[i]]$id)) + ## + # read values txt files + ## + bindingConstraints <- lapply(bindingConstraints, + .read_binding_values, + opts = opts) + + ## + # manage full list object + ## + + # to return named list + constraintNames <- sapply(bindingConstraints, + `[[`, + "id") + + # re structure list ($properties, $coefs, $values) + # [breaking changes] add "$properties" for all version + bindingConstraints <- lapply(bindingConstraints, + .manage_list_structure, + opts = opts) + + names(bindingConstraints) <- constraintNames + class(bindingConstraints) <- "bindingConstraints" + bindingConstraints +} + +# read values files for every binding of study +.read_binding_values <- function(binding_object, + opts = simOptions()){ + # dimension according to parameter "type" to return default value (TS file) + nrows <- switch(binding_object$type, + hourly = 24*7*52, + daily = 7 * 52, + weekly = 52, + monthly = 12, + annual = 1) + + # v870 + if(opts$antaresVersion>=870){ - nrows <- switch(bindingConstraints[[i]]$type, - hourly = 24*7*52, - daily = 7 * 52, - weekly = 52, - monthly = 12, - annual = 1) + parse_type <- switch(binding_object$operator, + less = "lt", + greater = "gt", + equal = "eq", + both = c("lt", "gt")) # "both" case ? - if (opts$typeLoad != "api" && file.size(path) == 0) { - bindingConstraints[[i]]$values <- as.data.table(matrix(0L, nrow = nrows, 3)) - } else { - # bindingConstraints[[i]]$values <- fread(path) + path_file_value <- file.path(opts$inputPath, + sprintf("bindingconstraints/%s.txt", + paste0(binding_object$id, + "_", + parse_type))) + + # check if "both" case + both_case <- binding_object$operator %in% "both" + + # check path file + # multiple path for "both" case + if(opts$typeLoad != "api"){ + if(!all(file.exists(path_file_value))) + stop("Time series file for binding constraint ", + binding_object$id, + " not exist", + call. = FALSE) + } + + + # Read files + # both case + if(both_case){ + tmp_values <- lapply(path_file_value, + fread_antares, + opts = opts) + names(tmp_values) <- c("less", "greater") + } + else + tmp_values <- fread_antares(opts = opts, + file = path_file_value) + + + # check empty values to return default values + # both case + default_scenarised_values <- as.data.table( + matrix(0L, nrow = nrows, ncol = 1)) + + if(both_case){ + check_nrow <- unlist(lapply(tmp_values, nrow)) + if(any(check_nrow %in% 0)){ + tmp_values[["less"]] <- default_scenarised_values + tmp_values[["greater"]] <- default_scenarised_values + } + } + else + if(nrow(tmp_values)==0) + tmp_values <- default_scenarised_values + # return + binding_object$values <- tmp_values + return(binding_object) + + }else{ # <870 (legacy) + path <- file.path(opts$inputPath, + sprintf("bindingconstraints/%s.txt", + binding_object$id)) + + # why return 0 if file.size(path) == 0 ? + if(opts$typeLoad != "api" && file.size(path) == 0){ + binding_object$values <- as.data.table( + matrix(0L, nrow = nrows, 3)) + setnames(binding_object$values, + names(binding_object$values), + c("less", "greater", "equal")) + return(binding_object) + } + else{ + # binding_object$values <- fread(path) tmp_values <- fread_antares(opts = opts, file = path) + + # this test do nothing => tmp_values never NULL + # return 0 row/col for empty file or error if file does not exist if(is.null(tmp_values)){ tmp_values <- as.data.table(matrix(0L, nrow = nrows, 3)) } - bindingConstraints[[i]]$values <- tmp_values + + binding_object$values <- tmp_values + setnames(binding_object$values, + names(binding_object$values), + c("less", "greater", "equal")) + return(binding_object) } + } +} + +# build list structure according to antares version +.manage_list_structure <- function(binding_object, + opts = simOptions()){ + # default names of parameters (core parameters) + names_elements <- c("name", "id", "enabled", "type", "operator", "values") + + # get links information from list + coefs_elements <- setdiff(names(binding_object), + names_elements) + coefs_values <- binding_object[which(names(binding_object) %in% + coefs_elements)] + + ## + # manage properties with version (filter) + ## + # filter on parameters to keep only links information + + # v832 + if (opts$antaresVersion>=832){ + names_elements_832 <- c("filter-year-by-year", + "filter-synthesis") + elements_832 <- binding_object[which(names(binding_object) %in% + names_elements_832)] - setnames(bindingConstraints[[i]]$values, - names(bindingConstraints[[i]]$values), - c("less", "greater", "equal")) + coefs_values[names_elements_832] <- NULL + } + + # v870 + if(opts$antaresVersion>=870){ + names_elements_870 <- "group" + elements_870 <- binding_object[which(names(binding_object) %in% + names_elements_870)] + coefs_values[names_elements_870] <- NULL } - res <- unname(bindingConstraints) + ## + # update list + ## - constraintNames <- vapply(res, function(x) x$name, character(1)) + # core elements list + core_list <- list( + properties = list( + name = binding_object$name, + id = binding_object$id, + enabled = binding_object$enabled, + timeStep = binding_object$type, + operator = binding_object$operator), + coefs = unlist(coefs_values), + values = binding_object$values) - res <- lapply(res, function(x) { - coefs <- x - for (v in c("name", "id", "enabled", "type", "operator", "values")) { - coefs[[v]] <- NULL - } - - list( - enabled = x$enabled, - timeStep = x$type, - operator = x$operator, - coefs = unlist(coefs), - values = x$values - ) - }) + # add properties according to version + # decreasing approach + + # v870 + if(opts$antaresVersion>=870){ + list_870 <- list() + list_870$properties = append(core_list$properties, + c( + unlist(elements_832), + unlist(elements_870))) + list_870 <- append(list_870, + core_list[c(2,3)]) + return(list_870) + } + # v832 + if(opts$antaresVersion>=832){ + list_832 <- list() + list_832$properties = append(core_list$properties, + unlist(elements_832)) + list_832 <- append(list_832, + core_list[c(2,3)]) + return(list_832) + } - names(res) <- constraintNames - class(res) <- "bindingConstraints" - res + return(core_list) } +#' @title Display equation of binding constraint +#' @description +#' `r lifecycle::badge("deprecated")` +#' This function cannot be used for a study `>= 8.7.0` #' @param object Object returned by readBindingConstraints #' @param ... Unused #' +#' @return A data.frame with one line per constraint. #' @export -#' @rdname readBindingConstraints summary.bindingConstraints <- function(object, ...) { + lifecycle::deprecate_warn(">= 2.7.0", "antaresRead::summary.bindingConstraints()") equations <- vapply(object, FUN.VALUE = character(1), function(x) { coefs <- sprintf( "%s %s x %s", @@ -126,7 +332,7 @@ summary.bindingConstraints <- function(object, ...) { lhs <- gsub("^ (\\+ )?", "", lhs) lhs <- gsub("1 x ", "", lhs) - if (x$operator == "both") { + if (x$properties$operator == "both") { # Left inequality rhs <- mean(x$values$greater) range <- range(x$values$greater) @@ -144,9 +350,9 @@ summary.bindingConstraints <- function(object, ...) { res <- sprintf("%s < [%s, %s]", res, range[1], range[2]) } } else { - operator <- switch(x$operator, equal = "=", less = "<", greater = ">") - rhs <- mean(x$values[[x$operator]]) - range <- range(x$values[[x$operator]]) + operator <- switch(x$properties$operator, equal = "=", less = "<", greater = ">") + rhs <- mean(x$values[[x$properties$operator]]) + range <- range(x$values[[x$properties$operator]]) if(range[1] == range[2]) { res <- sprintf("%s %s %s", lhs, operator, rhs) } else { @@ -157,8 +363,8 @@ summary.bindingConstraints <- function(object, ...) { res }) - timeStep <- vapply(object, function(x) x$timeStep, character(1)) - enabled <- vapply(object, function(x) x$enabled, logical(1)) + timeStep <- vapply(object, function(x) x$properties$timeStep, character(1)) + enabled <- vapply(object, function(x) x$properties$enabled, logical(1)) data.frame( enabled = enabled, diff --git a/R/utils_api.R b/R/utils_api.R index 921e2715..40284089 100644 --- a/R/utils_api.R +++ b/R/utils_api.R @@ -7,9 +7,13 @@ fread_antares <- function(opts, file, ...) { endpoint = I(file), query = list(formatted = FALSE) ) - tryCatch(fread(response, ...), error = function(e) {message(file); message(e)}) + suppressWarnings( + tryCatch(fread(response, ...), error = function(e){ + message(file); message(e) + })) } else { - fread(file, ...) + suppressWarnings( + fread(file, ...)) } } diff --git a/README.md b/README.md index 9a7f8238..56b31069 100644 --- a/README.md +++ b/README.md @@ -7,7 +7,7 @@ [![CRAN_Status_Badge](https://www.r-pkg.org/badges/version/antaresRead)](https://cran.r-project.org/package=antaresRead) -[![Lifecycle: stable](https://img.shields.io/badge/lifecycle-stable-brightgreen.svg)](https://www.tidyverse.org/lifecycle/#stable) +[![Lifecycle: experimental](https://img.shields.io/badge/lifecycle-experimental-orange.svg)](https://lifecycle.r-lib.org/articles/stages.html#experimental) [![Project Status: Active – The project has reached a stable, usable state and is being actively developed.](https://www.repostatus.org/badges/latest/active.svg)](https://www.repostatus.org/#active) [![R-CMD-check](https://github.com/rte-antares-rpackage/antaresRead/actions/workflows/R-CMD-check.yaml/badge.svg)](https://github.com/rte-antares-rpackage/antaresRead/actions/workflows/R-CMD-check.yaml) [![Codecov test coverage](https://codecov.io/gh/rte-antares-rpackage/antaresRead/branch/master/graph/badge.svg)](https://app.codecov.io/gh/rte-antares-rpackage/antaresRead?branch=master) diff --git a/inst/test_empty_study/empty_study_v870.tar.gz b/inst/test_empty_study/empty_study_v870.tar.gz new file mode 100644 index 00000000..947872f9 Binary files /dev/null and b/inst/test_empty_study/empty_study_v870.tar.gz differ diff --git a/inst/test_v8/test_case_study_v86.tar.gz b/inst/test_v8/test_case_study_v86.tar.gz deleted file mode 100644 index e107fb31..00000000 Binary files a/inst/test_v8/test_case_study_v86.tar.gz and /dev/null differ diff --git a/inst/test_v8/test_case_study_v870.tar.gz b/inst/test_v8/test_case_study_v870.tar.gz new file mode 100644 index 00000000..55a85fce Binary files /dev/null and b/inst/test_v8/test_case_study_v870.tar.gz differ diff --git a/man/antaresRead-package.Rd b/man/antaresRead-package.Rd new file mode 100644 index 00000000..6e14dd10 --- /dev/null +++ b/man/antaresRead-package.Rd @@ -0,0 +1,44 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/antaresRead-package.R +\docType{package} +\name{antaresRead-package} +\alias{antaresRead} +\alias{antaresRead-package} +\title{antaresRead: Import, Manipulate and Explore the Results of an 'Antares' Simulation} +\description{ +Import, manipulate and explore results generated by 'Antares', a powerful open source software developed by RTE (Réseau de Transport d’Électricité) to simulate and study electric power systems (more information about 'Antares' here : \url{https://antares-simulator.org/}). +} +\seealso{ +Useful links: +\itemize{ + \item \url{https://github.com/rte-antares-rpackage/antaresRead} + \item \url{https://rte-antares-rpackage.github.io/antaresRead/} + \item Report bugs at \url{https://github.com/rte-antares-rpackage/antaresRead/issues} +} + +} +\author{ +\strong{Maintainer}: Tatiana Vargas \email{tatiana.vargas@rte-france.com} + +Authors: +\itemize{ + \item Jalal-Edine ZAWAM + \item Francois Guillem + \item Benoit Thieurmel + \item Titouan Robert +} + +Other contributors: +\itemize{ + \item Frederic Breant [contributor] + \item Victor Perrier [contributor] + \item Etienne Sanchez [contributor] + \item Assil Mansouri [contributor] + \item Clement Berthet [contributor] + \item Kamel Kemiha [contributor] + \item Abdallah Mahoudi [contributor] + \item RTE [copyright holder] +} + +} +\keyword{internal} diff --git a/man/figures/lifecycle-archived.svg b/man/figures/lifecycle-archived.svg new file mode 100644 index 00000000..48f72a6f --- /dev/null +++ b/man/figures/lifecycle-archived.svg @@ -0,0 +1 @@ + lifecyclelifecyclearchivedarchived \ No newline at end of file diff --git a/man/figures/lifecycle-defunct.svg b/man/figures/lifecycle-defunct.svg new file mode 100644 index 00000000..01452e5f --- /dev/null +++ b/man/figures/lifecycle-defunct.svg @@ -0,0 +1 @@ +lifecyclelifecycledefunctdefunct \ No newline at end of file diff --git a/man/figures/lifecycle-deprecated.svg b/man/figures/lifecycle-deprecated.svg new file mode 100644 index 00000000..4baaee01 --- /dev/null +++ b/man/figures/lifecycle-deprecated.svg @@ -0,0 +1 @@ +lifecyclelifecycledeprecateddeprecated \ No newline at end of file diff --git a/man/figures/lifecycle-experimental.svg b/man/figures/lifecycle-experimental.svg new file mode 100644 index 00000000..d1d060e9 --- /dev/null +++ b/man/figures/lifecycle-experimental.svg @@ -0,0 +1 @@ +lifecyclelifecycleexperimentalexperimental \ No newline at end of file diff --git a/man/figures/lifecycle-maturing.svg b/man/figures/lifecycle-maturing.svg new file mode 100644 index 00000000..df713101 --- /dev/null +++ b/man/figures/lifecycle-maturing.svg @@ -0,0 +1 @@ +lifecyclelifecyclematuringmaturing \ No newline at end of file diff --git a/man/figures/lifecycle-questioning.svg b/man/figures/lifecycle-questioning.svg new file mode 100644 index 00000000..08ee0c90 --- /dev/null +++ b/man/figures/lifecycle-questioning.svg @@ -0,0 +1 @@ +lifecyclelifecyclequestioningquestioning \ No newline at end of file diff --git a/man/figures/lifecycle-stable.svg b/man/figures/lifecycle-stable.svg new file mode 100644 index 00000000..e015dc81 --- /dev/null +++ b/man/figures/lifecycle-stable.svg @@ -0,0 +1 @@ +lifecyclelifecyclestablestable \ No newline at end of file diff --git a/man/figures/lifecycle-superseded.svg b/man/figures/lifecycle-superseded.svg new file mode 100644 index 00000000..75f24f55 --- /dev/null +++ b/man/figures/lifecycle-superseded.svg @@ -0,0 +1 @@ + lifecyclelifecyclesupersededsuperseded \ No newline at end of file diff --git a/man/readBindingConstraints.Rd b/man/readBindingConstraints.Rd index af6e6928..83de9997 100644 --- a/man/readBindingConstraints.Rd +++ b/man/readBindingConstraints.Rd @@ -2,45 +2,72 @@ % Please edit documentation in R/readBindingConstraints.R \name{readBindingConstraints} \alias{readBindingConstraints} -\alias{summary.bindingConstraints} \title{Read binding constraints} \usage{ readBindingConstraints(opts = simOptions()) - -\method{summary}{bindingConstraints}(object, ...) } \arguments{ \item{opts}{list of simulation parameters returned by the function \code{\link{setSimulationPath}}} - -\item{object}{Object returned by readBindingConstraints} - -\item{...}{Unused} } \value{ -\code{readBindingConstraints} returns an object of class \code{bindingConstraints}. -It is a named list with one element per read constraint. Each element is itself -a list with the following elements: -\item{enabled}{is the constraint enabled ?} -\item{timeStep}{time step the constraint applies to} -\item{operator}{type of constraint: equality, inequality on one side or both sides} -\item{coefficients}{elements containing the coefficients used by the constraint} -\item{values}{values used by the constraint. It contains one line per time step -and three columns "less", "greater" and "equal"} - -The \code{summary} method returns a data.frame with one line per constraint. +An object of class \code{bindingConstraints}. This object is also a named +list with 3 sections per read constraint. } \description{ +\ifelse{html}{\figure{badge_api_ok.svg}{options: alt='Antares API OK'}}{Antares API: \strong{OK}} +\ifelse{html}{\href{https://lifecycle.r-lib.org/articles/stages.html#experimental}{\figure{lifecycle-experimental.svg}{options: alt='[Experimental]'}}}{\strong{[Experimental]}} + This function reads the binding constraints of an Antares project. Be aware that binding constraints are read in the input files of a study. So they may have changed since a simulation has been run. } +\note{ +For an study Antares \strong{version >=8.7.0}. Now contains \code{data.frame} with +one line per time step and \eqn{p} colums according to "scenarized RHS". + +For "both" case, you will find in section \code{values} two \code{data.frame} : +\itemize{ +\item One \code{data.frame} for \code{less} +\item One \code{data.frame} for \code{greater} +} + +For an study Antares \strong{version <8.7.0}. + +Section \code{values} contains one line +per time step and three columns "less", "greater" and "equal" +} +\section{Warning}{ + +Since \verb{release 2.7.0} the structure of the returned object has evolved for +all versions of study Antares: +\itemize{ +\item .ini parameters are in section \code{properties} +\item Coeffcients links or thermal are in section \code{coefs} +\item Values are already in section \code{values} +} +} + \examples{ \dontrun{ setSimulationPath() constraints <- readBindingConstraints() + +# read properties +constraints$properties + +# read coefs +constraints$coefs + +# read values +constraints$values + # both case ( study Antares >=8.7.0) +constraints$values$less +constraints$values$greater + +# display equation (only for study Antares <8.7.0) summary(constraints) } diff --git a/man/summary.bindingConstraints.Rd b/man/summary.bindingConstraints.Rd new file mode 100644 index 00000000..e2d2f3c7 --- /dev/null +++ b/man/summary.bindingConstraints.Rd @@ -0,0 +1,20 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/readBindingConstraints.R +\name{summary.bindingConstraints} +\alias{summary.bindingConstraints} +\title{Display equation of binding constraint} +\usage{ +\method{summary}{bindingConstraints}(object, ...) +} +\arguments{ +\item{object}{Object returned by readBindingConstraints} + +\item{...}{Unused} +} +\value{ +A data.frame with one line per constraint. +} +\description{ +\ifelse{html}{\href{https://lifecycle.r-lib.org/articles/stages.html#deprecated}{\figure{lifecycle-deprecated.svg}{options: alt='[Deprecated]'}}}{\strong{[Deprecated]}} +This function cannot be used for a study \verb{>= 8.7.0} +} diff --git a/revdep/README.md b/revdep/README.md index de65d83c..16a7e2e3 100644 --- a/revdep/README.md +++ b/revdep/README.md @@ -1,23 +1,28 @@ # Platform -|field |value | -|:--------|:----------------------------| -|version |R version 3.6.2 (2019-12-12) | -|os |Windows 10 x64 | -|system |x86_64, mingw32 | -|ui |RStudio | -|language |(EN) | -|collate |French_France.1252 | -|ctype |French_France.1252 | -|tz |Europe/Berlin | -|date |2020-03-03 | +|field |value | +|:--------|:-----------------------------------| +|version |R version 4.2.2 (2022-10-31 ucrt) | +|os |Windows 10 x64 (build 19045) | +|system |x86_64, mingw32 | +|ui |RStudio | +|language |(EN) | +|collate |French_France.utf8 | +|ctype |French_France.utf8 | +|tz |Europe/Paris | +|date |2024-05-27 | +|rstudio |2023.12.0+369 Ocean Storm (desktop) | +|pandoc |NA | # Dependencies -|package |old |new | | +|package |old |new |Δ | |:-----------|:-----|:-----|:--| -|antaresRead |2.2.4 |2.2.5 |* | -|rlang |NA |0.4.5 |* | +|antaresRead |2.6.1 |2.7.0 |* | +|cachem |NA |1.0.8 |* | +|fastmap |NA |1.1.1 |* | +|openssl |NA |2.1.2 |* | +|stringi |NA |1.8.3 |* | # Revdeps diff --git a/revdep/cran.md b/revdep/cran.md new file mode 100644 index 00000000..29c19611 --- /dev/null +++ b/revdep/cran.md @@ -0,0 +1,7 @@ +## revdepcheck results + +We checked 3 reverse dependencies, comparing R CMD check results across CRAN and dev versions of this package. + + * We saw 0 new problems + * We failed to check 0 packages + diff --git a/tests/testthat/helper_init.R b/tests/testthat/helper_init.R index 94c0e486..6f99f670 100644 --- a/tests/testthat/helper_init.R +++ b/tests/testthat/helper_init.R @@ -170,3 +170,28 @@ skip_according_to_options <- function() { } pathAPI <- "http://localhost:8080/studies/antaresStd/" + + +# study empty ---- + # latest version of study + # empty study to test exceptions +sourcedir_empty_study <- system.file("test_empty_study", + package = "antaresRead") + +setup_study_empty <- function(dir_path){ + studies <- list.files(dir_path, pattern = "\\.tar\\.gz$", + full.names = TRUE) + # choose pattern + studies <- studies[grep(x = studies, + pattern = "v87")] + # untar etude + path_sty <- file.path(tempdir(), + "study_empty_latest_version") + untar(studies[1], exdir = path_sty) # version latest + study_temp_path <- file.path(path_sty, "test_case") + + assign("study_empty_latest_version", + file.path(path_sty, + "test_case"), + envir = globalenv()) +} diff --git a/tests/testthat/test-bindingConstraints.R b/tests/testthat/test-bindingConstraints.R deleted file mode 100644 index c0c83ae5..00000000 --- a/tests/testthat/test-bindingConstraints.R +++ /dev/null @@ -1,37 +0,0 @@ -context("bindingConstraints") - - -sapply(studyPathS, function(studyPath){ - -opts <- setSimulationPath(studyPath, 0) - -describe("readBindingConstraints", { - it("returns an object of class 'bindingConstraints'", { - constraints <- readBindingConstraints(opts) - expect_is(constraints, "bindingConstraints") - }) -}) - - -describe("summary.bindingConstraints", { - it ("returns a data.frame describing the constraints", { - constraints <- readBindingConstraints(opts) - sumConstraints <- summary(constraints) - expect_is(sumConstraints, "data.frame") - expect_true(all(c("enabled", "timeStep", "equation") %in% names(sumConstraints))) - }) -}) - - -describe("Both operator", { - it ("returns a data.frame describing the constraints", { - constraints <- readBindingConstraints(opts) - constraints[[1]]$operator <- "both" - sumConstraints <- summary(constraints) - expect_is(sumConstraints, "data.frame") - expect_true(all(c("enabled", "timeStep", "equation") %in% names(sumConstraints))) - }) -}) - - -}) diff --git a/tests/testthat/test-readBindingConstraints.R b/tests/testthat/test-readBindingConstraints.R new file mode 100644 index 00000000..2e9128d1 --- /dev/null +++ b/tests/testthat/test-readBindingConstraints.R @@ -0,0 +1,188 @@ +context("bindingConstraints") + +# >= v710 ---- +opts <- setSimulationPath(studyPathS, 0) + +test_that("returns an object of class 'bindingConstraints'", { + constraints <- readBindingConstraints(opts) + expect_is(constraints, "bindingConstraints") +}) + +test_that("summary.bindingConstraints",{ + constraints <- readBindingConstraints(opts) + sumConstraints <- summary(constraints) + expect_is(sumConstraints, "data.frame") + expect_true(all(c("enabled", "timeStep", "equation") %in% + names(sumConstraints))) +}) + + +test_that("Both operator",{ + constraints <- readBindingConstraints(opts) + constraints[[1]]$properties$operator <- "both" + sumConstraints <- summary(constraints) + expect_is(sumConstraints, "data.frame") + expect_true(all(c("enabled", "timeStep", "equation") %in% + names(sumConstraints))) +}) + + +# >= v800 ---- + +opts <- antaresRead::setSimulationPath(studyPathSV8[1], "input") + +test_that("test if exist data value file", { + bc <- antaresRead::readBindingConstraints(opts = opts) + + # test class object return + testthat::expect_equal(class(bc), "bindingConstraints") + + names_bc_test <- paste0(names(bc), ".txt") + path_test_bc <- paste0(file.path(opts$inputPath, "bindingconstraints", + names_bc_test)) + + # test if values files exists + testthat::expect_true(all(unlist(lapply(path_test_bc, file.exists)))) +}) + + +# >= v870 ---- + +# read latest version of empty study +setup_study_empty(sourcedir_empty_study) +opts_test_empty <- antaresRead::setSimulationPath(study_empty_latest_version, + "input") + +# read latest version study +path_study_test <- grep(pattern = "87", x = studyPathSV8, value = TRUE) +opts_study_test <- setSimulationPath(path_study_test, simulation = "input") + +## empty study test ---- +test_that("Read scenarised BC with empty study", { + + bc <- readBindingConstraints(opts = opts_test_empty) + + # test exception + testthat::expect_equal(bc, NULL) + +}) + +## test object structure ---- +test_that("test object structure", { + + bc <- readBindingConstraints(opts = opts_study_test) + + # test class object + testthat::expect_equal(class(bc), "bindingConstraints") + + # test structure object + # every BC must have 3 named elements + nb_items <- unlist(lapply(bc, length)) + + testthat::expect_true(all(nb_items %in% 3)) + + # every BC must be named + names_items <- unlist(lapply(bc, names)) + + testthat::expect_true(all(names_items + %in% c("properties", "coefs", "values"))) +}) + +# test values / operator ---- +test_that("data verification based on the 'operator' property", { + bc <- readBindingConstraints(opts = opts_study_test) + + # test values + # one or two txt files are associated with one BC + # only "both" values have two .txt files + bc_prop <- lapply(bc, `[[`, "properties") + bc_id <- lapply(bc_prop, `[[`, "id") + bc_operator <- lapply(bc_prop, `[[`, "operator") + + # list all values + path_bc_values <- file.path(opts_study_test$inputPath, + "bindingconstraints") + list_values_bc <- list.files(path = path_bc_values, pattern = ".txt") + + # test "less" (one file must be present) + index <- bc_operator %in% "less" + id_bc <- names(bc_operator[index]) + + nb_file_present <- length(grep(pattern = id_bc, + x = list_values_bc)) + + testthat::expect_true(nb_file_present %in% 1) + + # test "greater" (one file must be present) + index <- bc_operator %in% "greater" + id_bc <- names(bc_operator[index]) + + nb_file_present <- length(grep(pattern = id_bc, + x = list_values_bc)) + + testthat::expect_true(nb_file_present %in% 1) + + # test "equal" (one file must be present) + index <- bc_operator %in% "equal" + id_bc <- names(bc_operator[index]) + + nb_file_present <- length(grep(pattern = id_bc, + x = list_values_bc)) + + testthat::expect_true(nb_file_present %in% 1) + + # test "both" (two file must be present) + index <- bc_operator %in% "both" + id_bc <- names(bc_operator[index]) + + nb_file_present <- length(grep(pattern = id_bc, + x = list_values_bc)) + + testthat::expect_true(nb_file_present %in% 2) + +}) + +## test default values ---- +test_that("test if default values are well returned", { + bc <- readBindingConstraints(opts = opts_study_test) + + # if txt values files are empty, default value is returned + + # check empty values files + # list all values + path_bc_values <- file.path(opts_study_test$inputPath, + "bindingconstraints") + + list_path_values_bc <- list.files(path = path_bc_values, + pattern = ".txt", + full.names = TRUE) + list_values_bc <- list.files(path = path_bc_values, pattern = ".txt") + + # check empty size + is_value_null <- file.size(list_path_values_bc) %in% 0 + + list_values_bc_null <- list_values_bc[is_value_null] + + # check bindings concerned + list_null_values <- lapply(names(bc), + grepl, + x= list_values_bc_null) + + is_true_null <- unlist(lapply(list_null_values, + all)) + + bc_default_values <- bc[is_true_null] + + # two data frames are returned for "both" case + less_values_default <- bc_default_values[[names(bc_default_values)]]$values$less + testthat::expect_true(sum(less_values_default) %in% 0) + + greater_values_default <- bc_default_values[[names(bc_default_values)]]$values$greater + testthat::expect_true(sum(greater_values_default) %in% 0) + + # test if length of default values are ok with timestep + # daily => 364 + testthat::expect_true(dim(bc_default_values[[names(bc_default_values)]]$values$greater)[1] + %in% 364) + }) + diff --git a/tests/testthat/test-readClusterDesc.R b/tests/testthat/test-readClusterDesc.R index c7d14398..3b938df7 100644 --- a/tests/testthat/test-readClusterDesc.R +++ b/tests/testthat/test-readClusterDesc.R @@ -1,15 +1,14 @@ - -# v860 ---- - -path_study_test <- grep(pattern = "86", x = studyPathSV8, value = TRUE) +# read study ---- + # latest version +path_study_test <- grep(pattern = "87", x = studyPathSV8, value = TRUE) opts_study_test <- setSimulationPath(path_study_test, simulation = "input") +# all version ---- #minimal columns mandatory_cols <- c("area","cluster") ## Thermal ---- test_that("test read cluster", { - # function setSimulationPath() provide areas names with st-storage clusters areas <- opts_study_test$areasWithClusters @@ -21,24 +20,26 @@ test_that("test read cluster", { testthat::expect_true(all(areas %in% unique(readClusterDesc()$area))) testthat::expect_true(all(mandatory_cols %in% colnames(input))) testthat::expect_true(nrow(input) == length(input$cluster)) - }) ## Renewables ---- test_that("test read cluster renewables", { - # function setSimulationPath() provide areas names with st-storage clusters - areas_res <- opts_study_test$areasWithRESClusters + areas_res <- opts_study_test$areasWithResClusters - #Study not renewables (need activateRES() from antaresEditObject) - expect_error(readClusterResDesc(), - regexp = "readClusterDesc is available only on studies with 'renewable-generation-modelling'") + #read + input <- readClusterResDesc() + # tests + testthat::expect_true("data.table" %in% class(input)) + testthat::expect_true(all(areas_res %in% unique(input$area))) + testthat::expect_true(all(mandatory_cols %in% colnames(input))) + testthat::expect_true(nrow(input) == length(input$cluster)) }) +# v860 ---- ## st-storage ---- test_that("test read cluster st-storage v860", { - # function setSimulationPath() provide areas names with st-storage clusters areas_st <- opts_study_test$areasWithSTClusters @@ -47,8 +48,9 @@ test_that("test read cluster st-storage v860", { # tests testthat::expect_true("data.table" %in% class(input_st)) + testthat::expect_true(all( + areas_st %in% unique(readClusterSTDesc()$area))) testthat::expect_true(all(areas_st %in% unique(readClusterSTDesc()$area))) testthat::expect_true(all(mandatory_cols %in% colnames(input_st))) testthat::expect_true(nrow(input_st) == length(input_st$cluster)) - }) diff --git a/tests/testthat/test-readInputTS.R b/tests/testthat/test-readInputTS.R index e7129140..1fbc3e81 100644 --- a/tests/testthat/test-readInputTS.R +++ b/tests/testthat/test-readInputTS.R @@ -1,7 +1,7 @@ #Copyright © 2016 RTE Réseau de transport d’électricité -# v710---- +# >= v710---- context("Function readInputTS") sapply(studyPathS, function(studyPath){ @@ -125,12 +125,12 @@ test_that("readInputTs must work if we change opts$timeIdMin and opts$timeIdMax" } }) - -# v860---- - -path_study_test <- grep(pattern = "86", x = studyPathSV8, value = TRUE) +# read latest version study +path_study_test <- grep(pattern = "87", x = studyPathSV8, value = TRUE) opts_study_test <- setSimulationPath(path_study_test, simulation = "input") +# >= v860---- + test_that("readInputTs mingen file v860", { # to read 8760