Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Read ST clusters with readAntares() #252

Merged
merged 15 commits into from
Jun 14, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion DESCRIPTION
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ Authors@R: c(
person("Clement", "Berthet", role = "ctb"),
person("Kamel", "Kemiha", role = "ctb"),
person("Abdallah", "Mahoudi", role = "ctb"),
person("Nicolas", "Boitard", role = "ctb"),
person("RTE", role = "cph")
)
Description: Import, manipulate and explore results generated by 'Antares', a
Expand All @@ -40,7 +41,8 @@ Imports:
utils,
memuse,
purrr,
lifecycle
lifecycle,
assertthat
Suggests:
rhdf5 (>= 2.24.0),
testthat,
Expand Down
1 change: 1 addition & 0 deletions NAMESPACE
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,7 @@ import(doParallel)
import(jsonlite)
import(parallel)
import(plyr)
importFrom(assertthat,assert_that)
importFrom(doParallel,registerDoParallel)
importFrom(grDevices,col2rgb)
importFrom(grDevices,rgb)
Expand Down
2 changes: 2 additions & 0 deletions NEWS.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ NEW FEATURES:
* `readInputRES()` new parameter **areas** to get desired clusters from selected areas.
* `setSimulationPath()` return a new parameter `binding` (for studies >= v8.7.0).
It contains a table with group dimensions of time series for binding constraints.
* `readAntares()` new parameter **clustersST** to read (output simulation) short-term clusters

BREAKING CHANGES :

Expand All @@ -18,6 +19,7 @@ BREAKING CHANGES :
BUGFIXES :

* `readInputThermal()` return data from file data.txt with `thermalData` parameter
* `setSimulationPath()` has also the parameter **areasWithSTClusters** in 'output' mode


# antaresRead 2.7.0
Expand Down
167 changes: 92 additions & 75 deletions R/importOutput.R
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@
#' - "areas", "values" => areas
#' - "areas", "details" => clusters
#' - "areas", "details-res" => renewables clusters
#' - "areas", "details-STstorage" => short-term clusters
#' - "links", "values" => links
#'
#' @return
Expand Down Expand Up @@ -281,30 +282,37 @@

#' .get_value_columns_details_file
#'
#' Private function used to get the column names for the details-timeStep.txt or details-res-timeStep.txt.
#' Used in .importOutputForClusters() and .importOutputForResClusters()
#' Private function used to get the column names for the details-timeStep.txt, details-res-timeStep.txt, or details-STstorage-timeStep.txt.
#' Used in .importOutputForClusters(), .importOutputForResClusters(), and .importOutputForSTClusters()
#' From the opts, we detect which outputs the user decides to take
#'
#' @return
#' a vector
#'
#' @importFrom assertthat assert_that
#'
#' @noRd
#'
.get_value_columns_details_file <- function(opts, type) {

if(type == "details") {
# Order is important. There is a correspondance between elements.
all_thematic_variables <- c("DTG by plant", "NP Cost by plant", "NODU by plant")
colNames <- c("production", "NP Cost", "NODU")
if (opts$antaresVersion >= 830){
all_thematic_variables <- c(all_thematic_variables, "Profit by plant")
colNames <- c(colNames, "profit")
}
} else if(type == "details-res") {
# Order is important. There is a correspondance between elements.
all_thematic_variables <- c("RES generation by plant")
colNames <- c("production")
}
assert_that(type %in% c("details","details-res","details-STstorage"))

simulation_variables_names_by_support <- read.table(system.file(
"format_output","simulation_variables_names_by_support.csv",package="antaresRead"
),sep=";",fileEncoding="UTF-8",header = TRUE)

filtered_variables_names <- subset(simulation_variables_names_by_support,DETAILS_FILES_TYPE==type)
if (type=="details" && opts$antaresVersion < 830)
filtered_variables_names <- subset(filtered_variables_names,ANTARES_DISPLAYED_NAME!="Profit by plant")

# Order is important. There is a correspondance between elements
ordered_filtered_variables_names <- filtered_variables_names[
order(filtered_variables_names$ORDINAL_POSITION_BY_TOPIC),
]

all_thematic_variables <- ordered_filtered_variables_names$ANTARES_DISPLAYED_NAME
colNames <- ordered_filtered_variables_names$RPACKAGE_DISPLAYED_NAME

# With thematic-trimming enabled
if (opts$parameters$general$`thematic-trimming`) {
if ("variables selection" %in% names(opts$parameters)) {
Expand Down Expand Up @@ -346,36 +354,8 @@
.importOutputForClusters <- function(areas, timeStep, select = NULL, mcYears = NULL,
showProgress, opts, mustRun = FALSE, parallel) {

# In output files, there is one file per area with the follwing form:
# cluster1-var1 | cluster2-var1 | cluster1-var2 | cluster2-var2
# the following function reshapes the result to have variable cluster in column.
# To improve greatly the performance we use our knowledge of the position of
# the columns instead of using more general functions like dcast.
reshapeFun <- function(x) {

# Get cluster names
n <- names(x)
idx <- ! n %in% pkgEnv$idVars
clusterNames <- tolower(unique(n[idx]))

# Id vars names
idVarsId <- which(!idx)
idVarsNames <- n[idVarsId]

# Column names of the output table
colNames <- .get_value_columns_details_file(opts, "details")

# Loop over clusters
nclusters <- length(clusterNames)

res <- llply(1:nclusters, function(i) {
dt <- x[, c(nclusters * 0:(length(colNames) - 1) + i, idVarsId), with = FALSE]
setnames(dt, c(colNames, idVarsNames))
dt[, cluster := as.factor(clusterNames[i])]
dt
})

rbindlist(res)
reshapeFun <- function(x){
.reshape_details_file(x,file_type="details",opts=opts)
}

if (!mustRun) {
Expand Down Expand Up @@ -488,6 +468,47 @@
}


#' .reshape_details_file
#'
#' In output files, there is one file per area with the follwing form:
#' cluster1-var1 | cluster2-var1 | cluster1-var2 | cluster2-var2
#' the following function reshapes the result to have variable cluster in column.
#' To improve greatly the performance we use our knowledge of the position of
#' the columns instead of using more general functions like dcast.
#'
#' @return
#' a data.table
#'
#' @noRd
#'
.reshape_details_file <- function(x,file_type,opts) {

# Get cluster names
n <- names(x)
idx <- ! n %in% pkgEnv$idVars
clusterNames <- tolower(unique(n[idx]))

# Id vars names
idVarsId <- which(!idx)
idVarsNames <- n[idVarsId]

# Column names of the output table
colNames <- .get_value_columns_details_file(opts=opts,type=file_type)

# Loop over clusters
nclusters <- length(clusterNames)

res <- llply(1:nclusters, function(i) {
dt <- x[, c(nclusters * 0:(length(colNames) - 1) + i, idVarsId), with = FALSE]
setnames(dt, c(colNames, idVarsNames))
dt[, cluster := as.factor(clusterNames[i])]
dt
})

rbindlist(res)
}


#' .importOutputForResClusters
#'
#' Private function used to import the output for the renewable clusters of one area
Expand All @@ -500,38 +521,11 @@
.importOutputForResClusters <- function(areas, timeStep, select = NULL, mcYears = NULL,
showProgress, opts, parallel) {

# In output files, there is one file per area with the follwing form:
# cluster1-var1 | cluster2-var1 | cluster1-var2 | cluster2-var2
# the following function reshapes the result to have variable cluster in column.
# To improve greatly the performance we use our knowledge of the position of
# the columns instead of using more general functions like dcast.

reshapeFun <- function(x) {

# Get cluster names
n <- names(x)
idx <- ! n %in% pkgEnv$idVars
clusterNames <- tolower(unique(n[idx]))

# Id vars names
idVarsId <- which(!idx)
idVarsNames <- n[idVarsId]

# Column names of the output table
colNames <- .get_value_columns_details_file(opts, "details-res")

# Loop over clusters
nclusters <- length(clusterNames)

res <- llply(1:nclusters, function(i) {
dt <- x[, c(nclusters * 0:(length(colNames) - 1) + i, idVarsId), with = FALSE]
setnames(dt, c(colNames, idVarsNames))
dt[, cluster := as.factor(clusterNames[i])]
dt
})

rbindlist(res)
.reshape_details_file(x,file_type="details-res",opts=opts)
}

suppressWarnings(
.importOutput("areas", "details-res", "area", areas, timeStep, NULL,
mcYears, showProgress, opts, reshapeFun, sameNames = FALSE,
Expand All @@ -540,6 +534,29 @@
}


#' .importOutputForSTClusters
#'
#' Private function used to import the output for the short-term clusters of one area
#'
#' @return
#' a data.table
#'
#' @noRd
#'
.importOutputForSTClusters <- function(areas, timeStep, select = NULL, mcYears = NULL,
showProgress, opts, parallel) {

reshapeFun <- function(x) {
.reshape_details_file(x,file_type="details-STstorage",opts=opts)
}

suppressWarnings(
.importOutput("areas", "details-STstorage", "area", areas, timeStep, NULL,
mcYears, showProgress, opts, reshapeFun, sameNames = FALSE,
objectDisplayName = "clustersST", parallel = parallel)
)
}

#' .importOutputForBindingConstraints
#'
#' Private function used to import the output for binding constraints.
Expand Down
32 changes: 27 additions & 5 deletions R/readAntares.R
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@
#' Read the data of an Antares simulation
#'
#' @description
#' `r antaresRead:::badge_api_ok()`
#'
#' \code{readAntares} is a swiss-army-knife function used to read almost every
#' possible time series of an antares Project at any desired time resolution
#' (hourly, daily, weekly, monthly or annual).
Expand Down Expand Up @@ -85,6 +87,11 @@
#' import results at renewable cluster level. If \code{NULL} no cluster is imported. The
#' special value \code{"all"} tells the function to import renewable clusters from all
#' areas.
#' @param clustersST
#' Vector containing the name of the areas for which you want to
#' import results at short-term cluster level. If \code{NULL} no cluster is imported. The
#' special value \code{"all"} tells the function to import short-term clusters from all
#' areas.
#' @param bindingConstraints
#' Should binding constraints be imported (v8.4+)?
#' @param districts
Expand Down Expand Up @@ -210,8 +217,8 @@
#' @export
#'
readAntares <- function(areas = NULL, links = NULL, clusters = NULL,
districts = NULL, clustersRes = NULL, bindingConstraints = FALSE,
misc = FALSE, thermalAvailabilities = FALSE,
districts = NULL, clustersRes = NULL, clustersST = NULL,
bindingConstraints = FALSE, misc = FALSE, thermalAvailabilities = FALSE,
hydroStorage = FALSE, hydroStorageMaxPower = FALSE,
reserve = FALSE, linkCapacity = FALSE, mustRun = FALSE,
thermalModulation = FALSE,
Expand All @@ -221,7 +228,7 @@ readAntares <- function(areas = NULL, links = NULL, clusters = NULL,
mcWeights = NULL,
opts = simOptions(),
parallel = FALSE, simplify = TRUE, showProgress = TRUE) {

if((!is.null(opts$parameters$`other preferences`$`renewable-generation-modelling`) &&
!opts$parameters$`other preferences`$`renewable-generation-modelling` %in% "clusters") ||
is.null(opts$parameters$`other preferences`$`renewable-generation-modelling`)){
Expand Down Expand Up @@ -309,6 +316,7 @@ readAntares <- function(areas = NULL, links = NULL, clusters = NULL,
links = links,
clusters = clusters,
clustersRes = clustersRes,
clustersST = clustersST,
districts = districts,
mcYears = mcYears)

Expand All @@ -317,6 +325,7 @@ readAntares <- function(areas = NULL, links = NULL, clusters = NULL,
links <- reqInfos$links
clusters <- reqInfos$clusters
clustersRes <- reqInfos$clustersRes
clustersST <- reqInfos$clustersST
districts <- reqInfos$districts
mcYears <- reqInfos$mcYears
synthesis <- reqInfos$synthesis
Expand All @@ -328,7 +337,7 @@ readAntares <- function(areas = NULL, links = NULL, clusters = NULL,
return(aggregateResult(opts = opts,
verbose = showProgress,
filtering = TRUE,
selected = list(areas = areas, links = links, clusters = clusters, clustersRes = clustersRes),
selected = list(areas = areas, links = links, clusters = clusters, clustersRes = clustersRes, clustersST = clustersST),
timestep = timeStep,
writeOutput = FALSE,
mcWeights = mcWeights, mcYears = mcYears))
Expand All @@ -342,7 +351,7 @@ readAntares <- function(areas = NULL, links = NULL, clusters = NULL,
}

# If all arguments are NULL, import all areas
if (is.null(areas) & is.null(links) & is.null(clusters) & is.null(clustersRes) & is.null(districts)) {
if (is.null(areas) & is.null(links) & is.null(clusters) & is.null(clustersRes) & is.null(clustersST) & is.null(districts)) {
areas <- "all"
}

Expand All @@ -353,6 +362,7 @@ readAntares <- function(areas = NULL, links = NULL, clusters = NULL,
links <- .checkArg(links, opts$linkList, "Links %s do not exist in the simulation.")
clusters <- .checkArg(clusters, opts$areasWithClusters, "Areas %s do not exist in the simulation or do not have any thermal cluster.")
clustersRes <- .checkArg(clustersRes, opts$areasWithResClusters, "Areas %s do not exist in the simulation or do not have any renewable cluster.")
clustersST <- .checkArg(clustersST, opts$areasWithSTClusters, "Areas %s do not exist in the simulation or do not have any short-term cluster.")
districts <- .checkArg(districts, opts$districtList, "Districts %s do not exist in the simulation.")
mcYears <- .checkArg(mcYears, opts$mcYears, "Monte-Carlo years %s have not been exported.", allowDup = TRUE)

Expand Down Expand Up @@ -476,6 +486,12 @@ readAntares <- function(areas = NULL, links = NULL, clusters = NULL,
opts, parallel = parallel)
if(!is.null(res$clustersRes) && nrow(res$clustersRes) == 0) res$clustersRes <- NULL

# Import short-term clusters
res$clustersST <- .importOutputForSTClusters(clustersST, timeStep, NULL,
mcYears, showProgress,
opts, parallel = parallel)
if(!is.null(res$clustersST) && nrow(res$clustersST) == 0) res$clustersST <- NULL

# Import thermal clusters and eventually must run
if (!mustRun) {
res$clusters <- .importOutputForClusters(clusters, timeStep, NULL, mcYears,
Expand Down Expand Up @@ -820,6 +836,7 @@ readAntaresAreas <- function(areas, links = TRUE, clusters = TRUE, clustersRes =
links,
clusters,
clustersRes,
clustersST,
districts,
mcYears){

Expand Down Expand Up @@ -873,6 +890,10 @@ readAntaresAreas <- function(areas, links = TRUE, clusters = TRUE, clustersRes =
if (!is.null(areas)) clustersRes <- areas
else clustersRes <- "all"
}
if ("clustersST" %in% unlist(select) & is.null(clustersST)) {
if (!is.null(areas)) clustersST <- areas
else clustersST <- "all"
}
if ("mcYears" %in% unlist(select) & is.null(mcYears)) mcYears <- "all"

# If all arguments are NULL, import all areas
Expand All @@ -888,6 +909,7 @@ readAntaresAreas <- function(areas, links = TRUE, clusters = TRUE, clustersRes =
links = links,
clusters = clusters,
clustersRes = clustersRes,
clustersST = clustersST,
districts = districts,
mcYears = mcYears,
synthesis = synthesis,
Expand Down
Loading
Loading