vgest_read_chrono.R 3.96 KiB
#' Read Chrono.txt or PaChrono.txt
#'
#' @description
#' Read the time series provided by VGEST for the forward calculation (Chrono.txt) and backward calculation (PaChrono.txt)
#'
#' @details
#' The format of the file is has follow. Headers are in line 53 followed by the complete time series which is backward in time for PaChrono.txt. The columns and respected widths are:
#' - Downstream date (10)
#' - QXsous (22)
#' For each lake, we next have:
#' - Upstream date (14)
#' - 25 columns of flow and storage data (22)
#' - if `DistributionType %in% c(4,5)`, 1 extra column (22)
#' - 5 columns of codes (6)
#' And then at the end:
#' - 7 columns of flow (22)
#' - 3 columns of codes (8)
#' - 1 extra column of code for `DistributionType==5` (8)
#' The file is saved in RDS format for quicker reading the next time.
#' @param x file to read with txt extension
#' @param ... further arguments passed to or from other methods
#' @return
#' @export
#' @rdname vgest_read_chrono
vgest_read_chrono <- function(x, ...) {
  UseMethod("vgest_read_chrono", x)
#' @param nLakes number of lakes in the file
#' @param distributionType Distribution type. See [vgest_write_batch] details
#' @return [data.frame] with the content of the file
#' @export
#' @rdname vgest_read_chrono
vgest_read_chrono.default <- function(x, nLakes, distributionType, ...) {
  # Reading cached file if exists
  rdsFile <- paste0(sub('\\..[^\\.]*$', '', x), ".rds")
  if(file.exists(rdsFile)) {
    df <- readRDS(rdsFile)
  } else {
    # Widths
    width1Lake <- c(14, rep(22, 25))
    if(distributionType %in% c(4,5)) { width1Lake <- c(width1Lake, 22)}
    width1Lake <- c(width1Lake, rep(6,5))
    widths <- c(10, 22, rep(width1Lake, nLakes), rep(22,7), rep(8,3))
    if(distributionType == 5) { widths <- c(widths, 8) }
    # Headers
    if(distributionType %in% c(4,5)) {
      headLine <- 54
    } else {
      headLine <- 53
    s <- readLines(x, n = headLine)[headLine]
    headers = trimws(unlist(read.fwf(textConnection(s), widths = widths, as.is = TRUE), use.names = FALSE))
    # Read file in fixed format
    df <- read.fwf(
      file = x,
      col.names = headers,
      widths = widths,
      skip = headLine,
7172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119
strip.white = TRUE ) df[,grep(pattern = "date", names(df))] <- lapply(df[,grep(pattern = "date", names(df))], as.Date, format = "%d/%m/%Y") df <- dplyr::arrange(df, date.aval) saveRDS(df, file = rdsFile) } class(df) <- c("Chrono", class(df)) return(df) } #' #' @param result.dir path for storing the result of vgest run. The result is stored in a subfolder named high or low (depending on \code{bFlood}) followed by the threshold #' @param distributionType Distribution type. See [vgest_write_batch] details #' @param backward boolean `TRUE` for reading "PaChrono.txt", `FALSE` for reading "Chrono.txt" #' #' @return A list with items named \[station\]_\[high/low\]_\[threshold\] containing [data.frame] with the content of each file #' @export #' @rdname vgest_read_chrono #' #' @examples #' \dontrun{ #' objective <- objectives[1,] #' distributionType <- 2 #' vgest_run_store(objective, #' 1, 1, "Q_NAT_1900-2009.txt", #' "01/01/1900", "31/12/2009", distributionType) #' lChrono <- vgest_read_chrono(objective, distributionType) #' } vgest_read_chrono.Objectives <- function(x, distributionType, result.dir = "database", backward = TRUE, ...) { if(backward) { fileName <- "PaChrono.txt" } else { fileName <- "Chrono.txt" } sLowHigh <- c("low", "high") objectivePaths <- file.path(result.dir, x$station, paste0(sLowHigh[x$flood + 1], "_", x$threshold)) l <- lapply(1:nrow(x), function(i) { cat("Treating folder", objectivePaths[i], "...\n") vgest_read_chrono.default( file.path(objectivePaths[i], fileName), nLakes = nrow(x[i, "lakes"][[1]]), distributionType = distributionType ) }) names(l) <- paste(x$station, sLowHigh[x$flood + 1], x$threshold, sep = "_") class(l) <- c("ListChrono", class(l)) return(l) }