@@ -7,7 +7,7 @@ utils::globalVariables(c("cluster_name", "full_path"))
77
88# ' @title Read Short-term storages / additional constraints
99# ' @description
10- # ' `r antaresRead:::badge_api_no ()`
10+ # ' `r antaresRead:::badge_api_ok ()`
1111# ' `r lifecycle::badge("experimental")`
1212# '
1313# ' This function reads constraints of an Antares project (by area/cluster) :
@@ -38,7 +38,163 @@ read_storages_constraints <- function(opts=simOptions()){
3838 # #
3939 # API bloc
4040 # #
41- if (is_api_study(opts = opts )){}
41+ # =========================
42+ # DIRECTLY transforms:
43+ # - body_json (api_get table-mode)
44+ # - st_constraints_ts (importSTConstraints_API)
45+ # into structure:
46+ # full_st_constraints -> area -> cluster -> {properties, values}
47+ # =========================
48+
49+ `%||%` <- function (x , y ) if (is.null(x )) y else x
50+
51+ # returns a list of hour vectors (one entry per occurrence)
52+ .collect_hours_lists <- function (occs ) {
53+ if (length(occs ) == 0 ) return (list ())
54+ lapply(occs , function (oc ) as.integer(oc $ hours %|| % integer()))
55+ }
56+
57+ .to_bracket_string <- function (v ) paste0(" [" , paste(v , collapse = " , " ), " ]" )
58+
59+ # extract a numeric vector (priority to column V1) for rhs_*
60+ .extract_rhs_vector <- function (dt_raw ) {
61+ if (is.null(dt_raw )) return (numeric ())
62+ if (" V1" %in% names(dt_raw )) return (as.numeric(dt_raw $ V1 ))
63+ num_cols <- names(dt_raw )[vapply(dt_raw , is.numeric , logical (1 ))]
64+ if (length(num_cols )) return (as.numeric(dt_raw [[ num_cols [1 ] ]]))
65+ as.numeric(dt_raw [[1 ]])
66+ }
67+
68+ # --------------- main builder ----------------
69+ # body_json : named list "area / cluster / constraint" -> list(variable, operator, occurrences, enabled)
70+ # st_constraints_ts : named list "area/cluster/rhs_name" -> data.table (values)
71+ # hours_format :
72+ # - "list_string"
73+ # - "list_vector"
74+ build_full_st_constraints_from_json <- function (
75+ body_json ,
76+ st_constraints_ts ,
77+ hours_format = c(" list_string" , " list_vector" )
78+ ) {
79+ hours_format <- match.arg(hours_format )
80+ out <- list ()
81+
82+ # ---- properties from body_json (without using data.table) ----
83+ if (length(body_json ) && ! is.null(names(body_json ))) {
84+ for (key in names(body_json )) {
85+ item <- body_json [[key ]]
86+ parts <- strsplit(key , " / " , fixed = TRUE )[[1 ]]
87+ area <- parts [1 ] %|| % NA_character_
88+ cluster <- parts [2 ] %|| % NA_character_
89+ constraint <- parts [3 ] %|| % NA_character_
90+
91+ if (is.null(out [[area ]])) out [[area ]] <- list ()
92+ if (is.null(out [[area ]][[cluster ]])) out [[area ]][[cluster ]] <- list (properties = list (), values = list ())
93+
94+ hrs_lists <- .collect_hours_lists(item $ occurrences )
95+ hrs_out <- switch (
96+ hours_format ,
97+ list_string = vapply(hrs_lists , .to_bracket_string , character (1 )),
98+ list_vector = hrs_lists
99+ )
100+
101+ out [[area ]][[cluster ]]$ properties [[constraint ]] <- list (
102+ variable = item $ variable %|| % NA_character_ ,
103+ operator = item $ operator %|| % NA_character_ ,
104+ hours = hrs_out ,
105+ enabled = isTRUE(item $ enabled )
106+ )
107+ }
108+ }
109+
110+ # ---- values from st_constraints_ts (rhs_*) ----
111+ ks <- names(st_constraints_ts %|| % list ())
112+ if (length(ks )) {
113+ for (k in ks ) {
114+ parts <- strsplit(k , " /" , fixed = TRUE )[[1 ]] # "area/cluster/file"
115+ area <- parts [1 ] %|| % NA_character_
116+ cluster <- parts [2 ] %|| % NA_character_
117+ file <- parts [3 ] %|| % NA_character_
118+
119+ if (is.null(out [[area ]])) out [[area ]] <- list ()
120+ if (is.null(out [[area ]][[cluster ]])) out [[area ]][[cluster ]] <- list (properties = list (), values = list ())
121+
122+ v <- .extract_rhs_vector(st_constraints_ts [[k ]])
123+ out [[area ]][[cluster ]]$ values [[file ]] <- list (V1 = v )
124+ }
125+ }
126+
127+ return ( out )
128+ }
129+
130+ # ---- API block ----
131+ table_type <- " st-storages-additional-constraints"
132+
133+ if (is_api_study(opts = opts )) {
134+
135+ body_json <- api_get(
136+ opts = opts ,
137+ endpoint = paste0(opts $ study_id , " /table-mode/" , table_type ),
138+ query = list (columns = " " )
139+ )
140+ # Reads ALL rhs_* under input/st-storage/constraints/<area>/<cluster>/,
141+ # and returns the files as read by fread_antares
142+ importSTConstraints_API <- function (opts , verbose = FALSE ) {
143+ # remove trailing slashes
144+ trim_slash <- function (x ) sub(" /+$" , " " , x )
145+ api_base <- trim_slash(opts $ inputPath )
146+
147+ # list names (areas, clusters, files) from the API (named list, character vector or list of objects)
148+ ls_names <- function (path ) {
149+ x <- read_secure_json(path , token = opts $ token ,
150+ timeout = opts $ timeout , config = opts $ httr_config )
151+ if (is.null(x )) return (character (0 ))
152+ nms <- names(x ); if (! is.null(nms ) && length(nms )) return (nms )
153+ if (is.character(x )) return (x )
154+ if (is.list(x ) && length(x )) {
155+ has <- vapply(x , function (e ) ! is.null(e [[" name" ]]), logical (1 ))
156+ if (all(has )) return (vapply(x , `[[` , character (1 ), " name" ))
157+ }
158+ character (0 )
159+ }
160+
161+ # full URL /raw?path=/input/<rel>
162+ make_raw_url <- function (rel ) {
163+ paste0(api_base , " /" , rel , " &formatted=FALSE" )
164+ }
165+
166+ # ---- raw reading of ALL rhs_* ----
167+ res <- list ()
168+
169+ areas <- tolower(ls_names(paste0(api_base , " /st-storage/constraints" )))
170+ for (a in areas ) {
171+ clusters <- tolower(ls_names(paste0(api_base , " /st-storage/constraints/" , a )))
172+ for (cl in clusters ) {
173+ files <- ls_names(paste0(api_base , " /st-storage/constraints/" , a , " /" , cl ))
174+ rhs <- grep(" ^rhs_" , files , value = TRUE , ignore.case = TRUE )
175+ for (f in rhs ) {
176+ rel <- paste(" st-storage/constraints" , a , cl , f , sep = " /" )
177+ url <- make_raw_url(rel )
178+ dt_raw <- fread_antares(
179+ opts = opts , file = url , integer64 = " numeric" ,
180+ header = FALSE , showProgress = FALSE
181+ )
182+ dt_raw
183+ res [[paste(a , cl , f , sep = " /" )]] <- dt_raw
184+ }
185+ }
186+ }
187+
188+ res
189+ }
190+
191+ st_constraints_ts <- importSTConstraints_API(opts , verbose = FALSE )
192+ return (res <- build_full_st_constraints_from_json(
193+ body_json ,
194+ st_constraints_ts ,
195+ hours_format = " list_string"
196+ ))
197+ }
42198
43199 # #
44200 # Desktop
0 commit comments