Skip to content

Commit 52df991

Browse files
committed
Move R script to vignette, add read_hdf5 function
1 parent 6d00695 commit 52df991

File tree

7 files changed

+326
-109
lines changed

7 files changed

+326
-109
lines changed

DESCRIPTION

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,13 +15,17 @@ License: MIT + file LICENSE
1515
URL: https://github.com/KWB-R/kwb.raindrop
1616
BugReports: https://github.com/KWB-R/kwb.raindrop/issues
1717
Imports:
18+
dplyr,
1819
fs,
1920
hdf5r,
2021
kwb.utils,
2122
magrittr,
22-
stringr
23+
purrr,
24+
stringr,
25+
tibble
2326
Suggests:
2427
covr,
28+
ggplot2,
2529
knitr,
2630
rmarkdown
2731
VignetteBuilder:

NAMESPACE

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,10 @@
11
# Generated by roxygen2: do not edit by hand
22

33
export("%>%")
4+
export(read_hdf5_timeseries)
45
export(run_model)
6+
importFrom(dplyr,filter)
7+
importFrom(dplyr,pull)
58
importFrom(fs,dir_create)
69
importFrom(fs,file_copy)
710
importFrom(fs,file_exists)
@@ -10,4 +13,7 @@ importFrom(hdf5r,H5File)
1013
importFrom(kwb.utils,catAndRun)
1114
importFrom(kwb.utils,resolve)
1215
importFrom(magrittr,"%>%")
16+
importFrom(purrr,map_dfr)
1317
importFrom(stringr,str_c)
18+
importFrom(tibble,as_tibble)
19+
importFrom(tibble,tibble)

R/.raindrop.R

Lines changed: 59 additions & 89 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,4 @@
1-
################################################################################
2-
### 1) Datei öffnen (lesen & schreiben) + Überblick
3-
################################################################################
1+
library(kwb.raindrop)
42

53
path_list <- list(
64
root_path = "C:/kwb/projects/raindrop/01102025_Raindrop_Daten",
@@ -24,78 +22,44 @@ path_list <- list(
2422
path_results_txt_multilayer = "<dir_target_output>/<file_results_txt_multilayer>",
2523
path_target_input = "<dir_input>/<file_target>",
2624
path_target_output = "<dir_output>/<file_target>"
27-
)
25+
)
2826

2927
for(i in 1:100) {
30-
31-
paths <- kwb.utils::resolve(path_list, dir_target = sprintf("s%05d", i))
32-
33-
fs::dir_create(paths$dir_input)
34-
fs::dir_create(paths$dir_output)
35-
fs::dir_create(paths$dir_target_output)
36-
37-
fs::file_copy(path = paths$path_base,
38-
new_path = paths$path_target_input,
39-
overwrite = TRUE)
40-
41-
h5 <- hdf5r::H5File$new(paths$path_target_input, mode = "a")
42-
43-
h5[["/Berechnungsparameter/Ergebnispfad"]]$read()
44-
45-
new_path <- stringr::str_c(normalizePath(fs::path_abs(paths$dir_target_output)),
46-
"\\")
47-
48-
h5[["/Berechnungsparameter/Ergebnispfad"]][] <- new_path
49-
50-
h5[["/Berechnungsparameter/Ergebnispfad"]]$read()
51-
52-
# "a" = read/write (legt an, falls nicht da); alternativ "r+" = read/write, aber nicht neu anlegen
53-
54-
h5$flush()
55-
## 2) Alle Handles schließen, sonst blockiert Windows das Umbenennen
56-
gc()
57-
h5$close_all()
58-
59-
run_model(path_exe = paths$path_exe,
60-
path_input = paths$path_target_input)
28+
29+
paths <- kwb.utils::resolve(path_list, dir_target = sprintf("s%05d", i))
30+
31+
fs::dir_create(paths$dir_input)
32+
fs::dir_create(paths$dir_output)
33+
fs::dir_create(paths$dir_target_output)
34+
35+
fs::file_copy(path = paths$path_base,
36+
new_path = paths$path_target_input,
37+
overwrite = TRUE)
38+
39+
# "a" = read/write (legt an, falls nicht da); alternativ "r+" = read/write, aber nicht neu anlegen
40+
h5 <- hdf5r::H5File$new(paths$path_target_input, mode = "a")
41+
42+
h5[["/Berechnungsparameter/Ergebnispfad"]]$read()
43+
44+
new_path <- stringr::str_c(normalizePath(fs::path_abs(paths$dir_target_output)),
45+
"\\")
46+
47+
h5[["/Berechnungsparameter/Ergebnispfad"]][] <- new_path
48+
49+
h5[["/Berechnungsparameter/Ergebnispfad"]]$read()
50+
51+
h5$flush()
52+
53+
## 2) Alle Handles schließen, sonst blockiert Windows das Umbenennen
54+
gc()
55+
h5$close_all()
56+
57+
kwb.raindrop::run_model(path_exe = paths$path_exe,
58+
path_input = paths$path_target_input)
6159
}
6260

6361

64-
#### Read results
65-
66-
### HDF-5
67-
68-
i <- 1
69-
paths <- kwb.utils::resolve(path_list, dir_target = sprintf("s%05d", i))
70-
71-
72-
read_hdf5_timeseries <- function(ts_groupvariable) {
73-
74-
# 1) Nur Datasets (keine Subgruppen) auflisten
75-
ds_ts_groupvariable <- ts_groupvariable$ls() %>%
76-
tibble::as_tibble() %>%
77-
dplyr::filter(obj_type == "H5I_DATASET") %>%
78-
dplyr::pull(name)
79-
80-
ds_ts_groupvariable
81-
82-
83-
# als benannte Liste mit Matrizen (2 x N)
84-
states_list <- setNames(lapply(ds_ts_groupvariable, function(nm) ts_groupvariable[[nm]]$read()), ds_ts_groupvariable)
85-
86-
# oder direkt als langes tibble (time/value angenommen: 1. Zeile = Zeit, 2. Zeile = Wert)
87-
states_long <- purrr::map_dfr(ds_ts_groupvariable, function(nm) {
88-
m <- ts_groupvariable[[nm]]$read()
89-
tibble::tibble(
90-
variable = nm,
91-
time = as.numeric(m[1, ]),
92-
value = as.numeric(m[2, ])
93-
)
94-
})
95-
96-
states_long
97-
}
98-
62+
### Read results for first run
9963

10064
simulation_names <- basename(fs::dir_ls(paths$dir_output))
10165

@@ -105,34 +69,40 @@ errors_df <- lapply(simulation_names, function(s_name) {
10569
paths <- kwb.utils::resolve(path_list, dir_target = s_name)
10670

10771
if(fs::file_exists(paths$path_errors_hdf5)) {
108-
error_hdf <- hdf5r::H5File$new(paths$path_errors_hdf5, mode = "r")
109-
110-
tibble::tibble(id = i,
111-
path = paths$path_errors_hdf5,
112-
number_of_errors = error_hdf[["AnzahlFehler"]]$read()
113-
)
72+
error_hdf <- hdf5r::H5File$new(paths$path_errors_hdf5, mode = "r")
73+
74+
tibble::tibble(id = i,
75+
path = paths$path_errors_hdf5,
76+
number_of_errors = error_hdf[["AnzahlFehler"]]$read()
77+
)
11478
}
11579
}) %>%
11680
dplyr::bind_rows()
11781

82+
83+
i <- 1
84+
paths <- kwb.utils::resolve(path_list, dir_target = sprintf("s%05d", i))
85+
86+
# "a" = read/write (legt an, falls nicht da); alternativ "r+" = read/write, aber nicht neu anlegen
11887
res_hdf <- hdf5r::H5File$new(paths$path_results_hdf5, mode = "r")
11988

12089
hdf5_results <- list(
121-
rates = read_hdf5_timeseries(ts_groupvariable = res_hdf5[["Raten"]]),
122-
additional_evapotranspiration = read_hdf5_timeseries(ts_groupvariable = res_hdf5[["Zusaetzliche Variablen Evapotranspiration"]]),
123-
additional_infiltration = read_hdf5_timeseries(ts_groupvariable = res_hdf5[["Zusaetzliche Variablen Infiltration"]]),
124-
states = read_hdf5_timeseries(ts_groupvariable = res_hdf5[["Zustandsvariablen"]])
90+
rates = kwb.raindrop::read_hdf5_timeseries(res_hdf5[["Raten"]]),
91+
additional_evapotranspiration = kwb.raindrop::read_hdf5_timeseries(res_hdf5[["Zusaetzliche Variablen Evapotranspiration"]]),
92+
additional_infiltration = kwb.raindrop::read_hdf5_timeseries(res_hdf5[["Zusaetzliche Variablen Infiltration"]]),
93+
states = kwb.raindrop::read_hdf5_timeseries(res_hdf5[["Zustandsvariablen"]])
12594
)
12695

96+
### Plot results
12797

12898
for(name in names(hdf5_results)) {
129-
130-
gg <- hdf5_results[[name]] %>%
131-
ggplot2::ggplot(ggplot2::aes(x = time, y = value)) +
132-
ggplot2::facet_wrap(~ variable, ncol = 1, scales = "free_y") +
133-
ggplot2::geom_line() +
134-
ggplot2::labs(title = name) +
135-
ggplot2::theme_bw()
136-
137-
plot(gg)
99+
100+
gg <- hdf5_results[[name]] %>%
101+
ggplot2::ggplot(ggplot2::aes(x = time, y = value)) +
102+
ggplot2::facet_wrap(~ variable, ncol = 1, scales = "free_y") +
103+
ggplot2::geom_line() +
104+
ggplot2::labs(title = name) +
105+
ggplot2::theme_bw()
106+
107+
plot(gg)
138108
}

R/read_hdf5_timeseries.R

Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
#' Read HDF5 Results Time Series from HDF5 Group into a Long Tibble
2+
#'
3+
#' @description
4+
#' Extracts all **datasets** (no subgroups) from a given HDF5 group and
5+
#' converts each 2×N matrix into a tidy long table. It assumes the first row
6+
#' holds the time/index vector and the second row the values.
7+
#'
8+
#' @param ts_groupvariable `hdf5r::H5Group`
9+
#' An open HDF5 group whose children are time-series datasets stored as 2×N
10+
#' numeric matrices (`[1, ] = time/index`, `[2, ] = value`). Typically a group
11+
#' like `"/Zustandsvariablen"` or similar in your model output file.
12+
#'
13+
#' @return A `tibble` with columns:
14+
#' \itemize{
15+
#' \item `variable` (`character`): dataset name within the group.
16+
#' \item `time` (`numeric`): time or index taken from the first row.
17+
#' \item `value` (`numeric`): values taken from the second row.
18+
#' }
19+
#'
20+
#' @details
21+
#' The function lists all child objects of `ts_groupvariable`, filters for
22+
#' datasets (`H5I_DATASET`), reads each dataset into memory, and stacks them
23+
#' into one long tibble. Datasets are expected to be **2×N**; if your storage
24+
#' differs (e.g., `N×2` or 1D), adapt the reading logic accordingly.
25+
#'
26+
#' @section Assumptions:
27+
#' - Each dataset under `ts_groupvariable` is a numeric matrix of shape 2×N.
28+
#' - Row 1 is the time/index vector; row 2 contains the values.
29+
#'
30+
#' @examples
31+
#' \dontrun{
32+
#' library(hdf5r)
33+
#' f <- H5File$new("Optimierung_MuldenRigole.h5", mode = "r")
34+
#' grp <- f[["Zustandsvariablen"]]
35+
#' ts_long <- read_hdf5_timeseries(grp)
36+
#' head(ts_long)
37+
#' f$close_all()
38+
#' }
39+
#'
40+
#' @seealso
41+
#' \code{\link[hdf5r]{H5File}}, \code{\link[hdf5r]{H5Group}}
42+
#'
43+
#' @importFrom tibble tibble as_tibble
44+
#' @importFrom dplyr filter pull
45+
#' @importFrom purrr map_dfr
46+
#' @export
47+
48+
read_hdf5_timeseries <- function(ts_groupvariable) {
49+
50+
# 1) Nur Datasets (keine Subgruppen) auflisten
51+
ds_ts_groupvariable <- ts_groupvariable$ls() %>%
52+
tibble::as_tibble() %>%
53+
dplyr::filter(obj_type == "H5I_DATASET") %>%
54+
dplyr::pull(name)
55+
56+
ds_ts_groupvariable
57+
58+
59+
# als benannte Liste mit Matrizen (2 x N)
60+
states_list <- setNames(lapply(ds_ts_groupvariable, function(nm) {
61+
ts_groupvariable[[nm]]$read()}), nm = ds_ts_groupvariable)
62+
63+
# oder direkt als langes tibble (time/value angenommen: 1. Zeile = Zeit, 2. Zeile = Wert)
64+
states_long <- purrr::map_dfr(ds_ts_groupvariable, function(nm) {
65+
m <- ts_groupvariable[[nm]]$read()
66+
tibble::tibble(
67+
variable = nm,
68+
time = as.numeric(m[1, ]),
69+
value = as.numeric(m[2, ])
70+
)
71+
})
72+
73+
states_long
74+
}

man/read_hdf5_timeseries.Rd

Lines changed: 55 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

vignettes/tutorial.Rmd

Lines changed: 0 additions & 19 deletions
This file was deleted.

0 commit comments

Comments
 (0)