diff --git a/DESCRIPTION b/DESCRIPTION index 774286d5002a07115751a262eebe3efc9d899dff..ad61b48fe74be0c5d7b57b508558b14aba5938a9 100644 --- a/DESCRIPTION +++ b/DESCRIPTION @@ -20,4 +20,5 @@ RoxygenNote: 7.1.2 Roxygen: list(markdown = TRUE) Imports: logger, - terra + terra, + tidyquery diff --git a/NAMESPACE b/NAMESPACE index 7dc999954092ddc68bde30d1eb1d15f94a9b7109..61371cb73ce1e8e19069e5fe811cbf7cf6ee279b 100644 --- a/NAMESPACE +++ b/NAMESPACE @@ -8,10 +8,16 @@ export(dem_to_reach) export(dem_to_reach_txt) export(dem_to_section) export(extract_reach) +export(get_result) +export(get_result_tree) export(get_section_centers) export(loadConfig) export(merge_reaches) +export(read_bin_result_matrix) export(set_initial_conditions) export(sic_run_export) export(sic_run_fortran) export(split_reach) +import(magrittr) +import(xml2) +importFrom(rlang,parse_expr) diff --git a/R/get_result.R b/R/get_result.R new file mode 100644 index 0000000000000000000000000000000000000000..aa91ab5b097b388e4f1491073f49ed27c1d31430 --- /dev/null +++ b/R/get_result.R @@ -0,0 +1,149 @@ +#' Get resultat +#' +#' @inheritParams sic_run_export +#' @param filter +#' @param m +#' +#' @return +#' @export +#' @importFrom rlang parse_expr +#' @import magrittr +#' +#' @examples +#' cfg <- cfg_tmp_project() +#' sic_run_fortran("fluvia", list(SCE = 1), cfg = cfg) +#' get_result(cfg, 1, filters = c("bf==4", "var=='Z'")) +get_result <- function(cfg, + scenario, + variant = 0, + filters = c(""), + m = read_bin_result_matrix(cfg, scenario, variant)) { + + df_col <- get_result_tree(cfg, scenario, variant) + filters <- paste(filters, collapse = " AND ") + if (filters != "") { + df_col %<>% tidyquery::query(paste("SELECT * WHERE", filters)) + } + m <- m[, df_col$col, drop = FALSE] + column_names <- sapply(seq_len(nrow(df_col)), + function(i) { + df_col$col <- NULL + cols <- sapply(names(df_col), + function(name) { + if (df_col[i, name] > 0) { + paste(name, df_col[i, name], sep = ":") + } else { + NULL + } + }) + cols[sapply(cols, is.null)] <- NULL + paste(cols, collapse = "|") + }) + colnames(m) <- column_names + return(m) +} + + +#' Read matrix of SIC simulation result file +#' +#' @inheritParams sic_run_export +#' +#' @return [matrix] with the simulation results +#' @export +#' +#' +read_bin_result_matrix <- function(cfg, scenario, variant) { + file <- paste0( + paste(gsub("\\.xml", "", cfg$project$path), + scenario, variant, sep = "_"), + ".res" + ) + con = file(file, "rb") + # Skip header + readBin(con, "raw", n = 4 * 5 + 4 + 8 + 4 + 4) + dims <- + readBin(con, + "integer", + n = 2, + size = 4, + endian = "little") + # Skip (data type code?) + readBin(con, "raw", n = 2) + data <- + readBin(con, + "double", + n = prod(dims), + size = 4, + endian = "little") + readBin(con, "raw", n = 4) # @todo check end file content + close(con) + return(matrix(data, ncol = dims[2], byrow = TRUE)) +} + + +#' Get correspondence between network object and columns in result binary file +#' +#' @inheritParams sic_run_export +#' +#' @return a [data.frame] with following columns: +#' +#' @export +#' @import xml2 +#' @import magrittr +#' +#' @examples +get_result_tree <- function(cfg, scenario, variant) { + x <- read_xml(cfg$project$path) + objs = c("Ouvrage", "Section", "Prise", "Noeud") + names(objs) <- objs + defcol <- get_DefCol(x, scenario, variant) + + df <- data.frame(bf = integer(), + sn = integer(), + nd = integer(), + pr = integer(), + ouv = integer(), + var = character(), + col = integer()) + + # Sections + xpath_biefs <- "/Reseau/Liste_Biefs/Bief" + + for (iBf in seq_along(xml_find_all(x, xpath_biefs))) { + xpath_sections <- paste0(xpath_biefs, sprintf("[@Num=%d]/Liste_Sections/SectionMin", iBf)) + for (iSn in seq_along(xml_find_all(x, xpath_sections))) { + xpath_res <- paste0(xpath_sections, "[@Num=%d]/Flu[@nScenario=%d]/ListeRes/Res[@nVar=%d]") %>% + sprintf(iSn, scenario, variant) + cols <- x %>% xml_find_first(xpath_res) %>% + xml_attr("nCol") %>% strsplit(":") %>% "[["(1) %>% as.integer + cols <- seq(from = cols[1], length.out = cols[2]) + + df %<>% result_tree_add(list(bf = iBf, sn = iSn), + defcol$Section, + cols) + } + } + return(df) +} + +result_tree_add <- function(df, loc, defcol, cols) { + loc <- utils::modifyList(list(bf = 0, sn = 0, nd = 0, pr = 0, ouv = 0), + loc) + return(rbind(df, data.frame(as.data.frame(loc), var = defcol, col = cols))) +} + +get_DefCol <- + function(x, + scenario, + variant, + xpath = "/Reseau/Flu[@nScenario=%d]/ListeRes/Res[@nVar=%d]/ListeDefCol/DefCol[@Objet=\"%s\"]", + objs = c("Ouvrage", "Section", "Prise", "Noeud")) { + names(objs) <- objs + lapply(objs, function(obj) + get_text_xml_path(x, xpath, scenario, variant, obj)) + } + +get_text_xml_path <- function(x, xpath, scenario, var, obj) { + x %>% xml_find_first(xpath = sprintf(xpath, scenario, var, obj)) %>% + xml_text %>% strsplit("\t") %>% "[["(1) +} diff --git a/man/get_result.Rd b/man/get_result.Rd new file mode 100644 index 0000000000000000000000000000000000000000..a7871bf0bfd0a37110ff572bc61afe0e44663182 --- /dev/null +++ b/man/get_result.Rd @@ -0,0 +1,34 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/get_result.R +\name{get_result} +\alias{get_result} +\title{Get resultat} +\usage{ +get_result( + cfg, + scenario, + variant = 0, + filters = c(""), + m = read_bin_result_matrix(cfg, scenario, variant) +) +} +\arguments{ +\item{cfg}{a \link{config} object. Configuration to use. See \link{loadConfig} for details} + +\item{scenario}{\link{numeric}, the scenario to read} + +\item{variant}{\link{numeric}, the variant to read} + +\item{m}{} +} +\value{ + +} +\description{ +Get resultat +} +\examples{ +cfg <- cfg_tmp_project() +sic_run_fortran("fluvia", list(SCE = 1), cfg = cfg) +get_result(cfg, 1, filters = c("bf==4", "var=='Z'")) +} diff --git a/man/get_result_tree.Rd b/man/get_result_tree.Rd new file mode 100644 index 0000000000000000000000000000000000000000..d885d1a06902d99ec5b168cd86c68009722231e2 --- /dev/null +++ b/man/get_result_tree.Rd @@ -0,0 +1,21 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/get_result.R +\name{get_result_tree} +\alias{get_result_tree} +\title{Get correspondence between network object and columns in result binary file} +\usage{ +get_result_tree(cfg, scenario, variant) +} +\arguments{ +\item{cfg}{a \link{config} object. Configuration to use. See \link{loadConfig} for details} + +\item{scenario}{\link{numeric}, the scenario to read} + +\item{variant}{\link{numeric}, the variant to read} +} +\value{ +a \link{data.frame} with following columns: +} +\description{ +Get correspondence between network object and columns in result binary file +} diff --git a/man/read_bin_result_matrix.Rd b/man/read_bin_result_matrix.Rd new file mode 100644 index 0000000000000000000000000000000000000000..760544b420a8ef94f2994973f9b2b9673b9c4b59 --- /dev/null +++ b/man/read_bin_result_matrix.Rd @@ -0,0 +1,21 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/get_result.R +\name{read_bin_result_matrix} +\alias{read_bin_result_matrix} +\title{Read matrix of SIC simulation result file} +\usage{ +read_bin_result_matrix(cfg, scenario, variant) +} +\arguments{ +\item{cfg}{a \link{config} object. Configuration to use. See \link{loadConfig} for details} + +\item{scenario}{\link{numeric}, the scenario to read} + +\item{variant}{\link{numeric}, the variant to read} +} +\value{ +\link{matrix} with the simulation results +} +\description{ +Read matrix of SIC simulation result file +} diff --git a/tests/testthat/test-get_result.R b/tests/testthat/test-get_result.R new file mode 100644 index 0000000000000000000000000000000000000000..cbe939ddd9679d0a2f93ccab4a7216de527ff526 --- /dev/null +++ b/tests/testthat/test-get_result.R @@ -0,0 +1,11 @@ +skip_on_ci() + +cfg <- cfg_tmp_project() +sic_run_fortran("fluvia", list(SCE = 1), cfg = cfg) + +test_that("get_result returns a matrix with correct colnames", { + result <- get_result(cfg, 1, filters = c("bf=4", "var='Z'")) + expect_true(is.matrix(result)) + expect_type(result, "double") + expect_equal(colnames(result), sprintf("bf:4|sn:%d|var:Z", 1:4)) +})