From e28141c3a699b75123b5dfc5f3bed52d9fae4f50 Mon Sep 17 00:00:00 2001 From: Claude Date: Fri, 7 Aug 2026 13:26:49 +0000 Subject: [PATCH 1/3] Spell the project name RainDrop consistently; record the Zenodo DOI - RAINDROP -> RainDrop across DESCRIPTION (funder), NEWS, roxygen docs, regenerated man pages, vignettes, CITATION.cff and .zenodo.json. The engine's fixed output file names (Mulde_Rigole_RAINDROP*.txt, Optimierung_MuldenRigole_RAINDROP*.txt) are technical identifiers written by the Tandler engine and deliberately keep their spelling. - CITATION.cff and inst/CITATION now carry the version DOI of the released v0.1.0 archive (10.5281/zenodo.21839223); the placeholder footer pointing to a future DOI is gone. Co-Authored-By: Claude Opus 5 Claude-Session: https://claude.ai/code/session_017npvdq8XW1Lg1t2dNX9sGH --- .zenodo.json | 4 ++-- CITATION.cff | 5 +++-- DESCRIPTION | 2 +- R/compute_costs.R | 2 +- R/find_min_feasible.R | 2 +- R/h5_ensure_dataset.R | 4 ++-- R/h5_ensure_datasets_from_values.R | 4 ++-- R/hdf5_read-write.R | 4 ++-- R/make_swale_runner.R | 2 +- R/read_raindrop_errors.R | 4 ++-- inst/CITATION | 8 +++----- man/default_cost_rates.Rd | 2 +- man/download_engine.Rd | 2 +- man/find_min_feasible.Rd | 2 +- man/h5_ensure_dataset.Rd | 2 +- man/h5_ensure_datasets_from_values.Rd | 2 +- man/h5_validate_write.Rd | 2 +- man/h5_write_values.Rd | 2 +- man/make_swale_runner.Rd | 2 +- man/plot_valid_design_space.Rd | 2 +- man/read_raindrop_errors.Rd | 4 ++-- man/run_model.Rd | 8 ++++---- vignettes/example_wien_minimal.Rmd | 2 +- vignettes/monotonicity_analysis.Rmd | 2 +- vignettes/workflow_badaussee.Rmd | 4 ++-- vignettes/workflow_eisenstadt-2005.Rmd | 4 ++-- vignettes/workflow_wien.Rmd | 4 ++-- 27 files changed, 43 insertions(+), 44 deletions(-) diff --git a/.zenodo.json b/.zenodo.json index cd307a7..d39c12a 100644 --- a/.zenodo.json +++ b/.zenodo.json @@ -1,6 +1,6 @@ { "title": "kwb.raindrop: R Package for Optimisation Simulations for Rainwater Management", - "description": "

R interface and control unit for the RAINDROP hydrodynamic planning tool: long-term simulation of blue-green infrastructure (swale-trench elements) driven by real climate series, plus two cost optimisers that find the cost-minimal design per allowed overflow frequency — a deterministic bisection-based coordinate descent whose search order is derived from the construction cost rates, and an assumption-free simultaneous search (penalised Nelder-Mead, differential evolution and Halton sampling) as cross-check.

The proprietary calculation engine ("Regenwasserbewirtschaftung", © Tandler.com GmbH) is not part of this archive; it is downloaded on demand from the companion repository kwb.raindrop.binaries.

", + "description": "

R interface and control unit for the RainDrop hydrodynamic planning tool: long-term simulation of blue-green infrastructure (swale-trench elements) driven by real climate series, plus two cost optimisers that find the cost-minimal design per allowed overflow frequency — a deterministic bisection-based coordinate descent whose search order is derived from the construction cost rates, and an assumption-free simultaneous search (penalised Nelder-Mead, differential evolution and Halton sampling) as cross-check.

The proprietary calculation engine ("Regenwasserbewirtschaftung", © Tandler.com GmbH) is not part of this archive; it is downloaded on demand from the companion repository kwb.raindrop.binaries.

", "upload_type": "software", "access_right": "open", "license": "MIT", @@ -27,5 +27,5 @@ "scheme": "url" } ], - "notes": "Developed within the project RAINDROP (Rainwater Drainage Optimization, GZ C300428), funded by the Austrian Federal Ministry of Agriculture, Forestry, Regions and Water Management." + "notes": "Developed within the project RainDrop (Rainwater Drainage Optimization, GZ C300428), funded by the Austrian Federal Ministry of Agriculture, Forestry, Regions and Water Management." } diff --git a/CITATION.cff b/CITATION.cff index f906950..7eb6a5f 100644 --- a/CITATION.cff +++ b/CITATION.cff @@ -3,6 +3,7 @@ message: "If you use this software, please cite it using the metadata below." type: software title: "kwb.raindrop: R Package for Optimisation Simulations for Rainwater Management" version: 0.1.0 +doi: "10.5281/zenodo.21839223" date-released: "2026-08-07" license: MIT repository-code: "https://github.com/KWB-R/kwb.raindrop" @@ -21,7 +22,7 @@ keywords: - infiltration swale - R package abstract: >- - R interface and control unit for the RAINDROP hydrodynamic planning + R interface and control unit for the RainDrop hydrodynamic planning tool: long-term simulation of blue-green infrastructure (swale-trench elements) driven by real climate series, plus two cost optimisers that find the cost-minimal design per allowed overflow frequency - a @@ -32,6 +33,6 @@ abstract: >- proprietary calculation engine ("Regenwasserbewirtschaftung", (c) Tandler.com GmbH) is not part of this package; it is downloaded on demand from the companion repository kwb.raindrop.binaries. - Developed within the project RAINDROP (Rainwater Drainage + Developed within the project RainDrop (Rainwater Drainage Optimization, GZ C300428), funded by the Austrian Federal Ministry of Agriculture, Forestry, Regions and Water Management. diff --git a/DESCRIPTION b/DESCRIPTION index f5fa2b4..5092dbb 100644 --- a/DESCRIPTION +++ b/DESCRIPTION @@ -5,7 +5,7 @@ Version: 0.1.0 Authors@R: c( person("Michael", "Rustler", , "michael.rustler@kompetenz-wasser.de", role = c("aut", "cre"), comment = c(ORCID = "0000-0003-0647-7726")), - person("RAINDROP", role = "fnd"), + person("RainDrop", role = "fnd"), person("Kompetenzzentrum Wasser Berlin gGmbH (KWB)", role = "cph") ) Description: R Package for Optimisation Simulations for Rainwater diff --git a/R/compute_costs.R b/R/compute_costs.R index 6651673..cfe1015 100644 --- a/R/compute_costs.R +++ b/R/compute_costs.R @@ -2,7 +2,7 @@ #' #' Returns the default Austrian unit-cost rates used by [`compute_costs()`]. #' Rates were provided by Johannes Leimgruber (OeStaP) on 2026-03-27 for the -#' RAINDROP cost-optimisation work. +#' RainDrop cost-optimisation work. #' #' @return A named `list` of rates in EUR per m² or m³: #' `excavation_eur_per_m3`, `profiling_eur_per_m2`, diff --git a/R/find_min_feasible.R b/R/find_min_feasible.R index 69a76ec..90dbfef 100644 --- a/R/find_min_feasible.R +++ b/R/find_min_feasible.R @@ -3,7 +3,7 @@ #' Core building block of the swale-design optimiser: finds the smallest #' value of one design parameter for which the overflow target is met #' (`n_overflows <= x_max`), assuming quasi-monotone feasibility (larger -#' value = never more overflows; verified for the RAINDROP model in the +#' value = never more overflows; verified for the RainDrop model in the #' `monotonicity_analysis` vignette). Each evaluation halves the search #' interval, so `ceiling(log2(range / tol))` evaluations suffice. #' diff --git a/R/h5_ensure_dataset.R b/R/h5_ensure_dataset.R index 9623a20..fcd1eeb 100644 --- a/R/h5_ensure_dataset.R +++ b/R/h5_ensure_dataset.R @@ -1,7 +1,7 @@ #' Ensure that an HDF5 dataset exists (create if missing) #' #' Creates missing groups along the path and then creates the dataset. -#' Designed for RAINDROP input files where missing scalar parameters can +#' Designed for RainDrop input files where missing scalar parameters can #' crash the model definition reader. #' #' @param h5 Open \code{hdf5r::H5File} (mode "a" or "r+"). @@ -38,7 +38,7 @@ h5_ensure_dataset <- function(h5, path, value, dtype = NULL, dims = NULL) { infer_dims <- function(v) { if (is.data.frame(v) && ncol(v) == 2L) { - # R Nx2 -> HDF5 2xN (RAINDROP style) + # R Nx2 -> HDF5 2xN (RainDrop style) n <- nrow(v) return(c(2L, as.integer(n))) } diff --git a/R/h5_ensure_datasets_from_values.R b/R/h5_ensure_datasets_from_values.R index 4599358..64554ec 100644 --- a/R/h5_ensure_datasets_from_values.R +++ b/R/h5_ensure_datasets_from_values.R @@ -6,7 +6,7 @@ #' @param h5 Open hdf5r::H5File (mode "a" or "r+"). #' @param values Named list; names are dataset paths (leading // allowed). #' @param ts_cols Character(2). Column names for TS (default time/value). -#' @param ts_layout One of "2xN" or "Nx2". For RAINDROP typically "2xN" in HDF5. +#' @param ts_layout One of "2xN" or "Nx2". For RainDrop typically "2xN" in HDF5. #' @param ts_dtype Either an H5T object or a string ("double","integer","logical","float"). #' @param strict Stop if creation fails. #' @return Invisibly, the character vector of created dataset paths. @@ -50,7 +50,7 @@ h5_ensure_datasets_from_values <- function(h5, values, } .infer_dims <- function(v) { - # TS: 2-col df/tibble -> create as 2xN (RAINDROP) or Nx2 + # TS: 2-col df/tibble -> create as 2xN (RainDrop) or Nx2 if (is.data.frame(v) && ncol(v) == 2L) { n <- nrow(v) if (ts_layout == "2xN") return(c(2L, as.integer(n))) diff --git a/R/hdf5_read-write.R b/R/hdf5_read-write.R index 2f5c140..26cb8ad 100644 --- a/R/hdf5_read-write.R +++ b/R/hdf5_read-write.R @@ -237,7 +237,7 @@ h5_read_values <- function(h5, #' Write (updated) values back into existing HDF5 datasets (robust for your hdf5r build) #' #' - Scalars: write with required `args` (args=list() or args=1L fallback). -#' - 2-col TS (data.frame/tibble): expects Nx2 in R; writes as 2xN in HDF5 (RAINDROP style), +#' - 2-col TS (data.frame/tibble): expects Nx2 in R; writes as 2xN in HDF5 (RainDrop style), #' using explicit hyperslab args=list(1:2, 1:N) to avoid empty selections. #' - If TS length changes and dataset maxdims blocks resize, the dataset is deleted via #' parent$link_delete(name) and recreated with dims=2xN (fixed), then written. @@ -518,7 +518,7 @@ h5_write_values <- function(h5, values, #' #' Notes: #' - 2-column data.frames/tibbles are treated as Nx2 in R and mapped to 2xN in HDF5. -#' - Many RAINDROP files store time series as HDF5 dims 2xN (appearing as Nx2 in R). +#' - Many RainDrop files store time series as HDF5 dims 2xN (appearing as Nx2 in R). #' #' @param h5 An open \code{hdf5r::H5File}. #' @param values Named list of values to write (names are HDF5 paths). diff --git a/R/make_swale_runner.R b/R/make_swale_runner.R index abe4e6a..056f84d 100644 --- a/R/make_swale_runner.R +++ b/R/make_swale_runner.R @@ -15,7 +15,7 @@ psi_s_mm <- function(kf_mmh) { #' #' Factors the `run_one()` function that was duplicated across the three #' workflow vignettes (Eisenstadt 2005, Wien, Bad Aussee) into one -#' package-level closure factory. The returned function runs the RAINDROP +#' package-level closure factory. The returned function runs the RainDrop #' engine for one parameter set and returns the thinned one-row #' optimisation result (overflow events + water balance), augmented with #' the input parameters and the overflow volume in m3. diff --git a/R/read_raindrop_errors.R b/R/read_raindrop_errors.R index 2388660..0ab3da9 100644 --- a/R/read_raindrop_errors.R +++ b/R/read_raindrop_errors.R @@ -1,6 +1,6 @@ -#' Read RAINDROP error logs into a nested tibble +#' Read RainDrop error logs into a nested tibble #' -#' Reads the RAINDROP error protocol HDF5 (typically \code{Fehlerprotokoll.h5}) +#' Reads the RainDrop error protocol HDF5 (typically \code{Fehlerprotokoll.h5}) #' for a set of simulation runs and returns a tibble with one row per run and a #' nested tibble column containing all errors found in the file. #' diff --git a/inst/CITATION b/inst/CITATION index 4d53ab8..337f261 100644 --- a/inst/CITATION +++ b/inst/CITATION @@ -8,10 +8,8 @@ bibentry( comment = c(ORCID = "0000-0003-0647-7726")), year = "2026", note = "R package version 0.1.0", - url = "https://github.com/KWB-R/kwb.raindrop" + url = "https://github.com/KWB-R/kwb.raindrop", + doi = "10.5281/zenodo.21839223" ) -citFooter(paste( - "After the first Zenodo release, please prefer the version DOI", - "shown at https://github.com/KWB-R/kwb.raindrop (Cite this repository)." -)) + diff --git a/man/default_cost_rates.Rd b/man/default_cost_rates.Rd index 094919e..65d2685 100644 --- a/man/default_cost_rates.Rd +++ b/man/default_cost_rates.Rd @@ -15,7 +15,7 @@ A named \code{list} of rates in EUR per m² or m³: \description{ Returns the default Austrian unit-cost rates used by \code{\link[=compute_costs]{compute_costs()}}. Rates were provided by Johannes Leimgruber (OeStaP) on 2026-03-27 for the -RAINDROP cost-optimisation work. +RainDrop cost-optimisation work. } \section{Source rates (Leimgruber, 2026-03-27, "Kostenansätze Optimierung")}{ diff --git a/man/download_engine.Rd b/man/download_engine.Rd index d131caa..7aee68b 100644 --- a/man/download_engine.Rd +++ b/man/download_engine.Rd @@ -19,7 +19,7 @@ pinned version.} \item{cache_dir}{\code{character(1)} Directory where engine binaries are cached. A sub-directory named after \code{version} is used so multiple versions can coexist. Defaults to -\code{\link[tools:R_user_dir]{tools::R_user_dir}}\verb{("kwb.raindrop", "cache")}.} +\code{\link[tools:userdir]{tools::R_user_dir}}\verb{("kwb.raindrop", "cache")}.} \item{force}{\code{logical(1)} If \code{TRUE}, re-download even if the executable already exists in the diff --git a/man/find_min_feasible.Rd b/man/find_min_feasible.Rd index 4137642..4c65bc6 100644 --- a/man/find_min_feasible.Rd +++ b/man/find_min_feasible.Rd @@ -65,7 +65,7 @@ volume), sorted by value} Core building block of the swale-design optimiser: finds the smallest value of one design parameter for which the overflow target is met (\code{n_overflows <= x_max}), assuming quasi-monotone feasibility (larger -value = never more overflows; verified for the RAINDROP model in the +value = never more overflows; verified for the RainDrop model in the \code{monotonicity_analysis} vignette). Each evaluation halves the search interval, so \code{ceiling(log2(range / tol))} evaluations suffice. } diff --git a/man/h5_ensure_dataset.Rd b/man/h5_ensure_dataset.Rd index 83acf73..8cfd71e 100644 --- a/man/h5_ensure_dataset.Rd +++ b/man/h5_ensure_dataset.Rd @@ -23,6 +23,6 @@ Invisibly TRUE } \description{ Creates missing groups along the path and then creates the dataset. -Designed for RAINDROP input files where missing scalar parameters can +Designed for RainDrop input files where missing scalar parameters can crash the model definition reader. } diff --git a/man/h5_ensure_datasets_from_values.Rd b/man/h5_ensure_datasets_from_values.Rd index 6ce3d12..7916047 100644 --- a/man/h5_ensure_datasets_from_values.Rd +++ b/man/h5_ensure_datasets_from_values.Rd @@ -20,7 +20,7 @@ h5_ensure_datasets_from_values( \item{ts_cols}{Character(2). Column names for TS (default time/value).} -\item{ts_layout}{One of "2xN" or "Nx2". For RAINDROP typically "2xN" in HDF5.} +\item{ts_layout}{One of "2xN" or "Nx2". For RainDrop typically "2xN" in HDF5.} \item{ts_dtype}{Either an H5T object or a string ("double","integer","logical","float").} diff --git a/man/h5_validate_write.Rd b/man/h5_validate_write.Rd index 880af8e..f7013a8 100644 --- a/man/h5_validate_write.Rd +++ b/man/h5_validate_write.Rd @@ -29,6 +29,6 @@ Summarizes for each path: Notes: \itemize{ \item 2-column data.frames/tibbles are treated as Nx2 in R and mapped to 2xN in HDF5. -\item Many RAINDROP files store time series as HDF5 dims 2xN (appearing as Nx2 in R). +\item Many RainDrop files store time series as HDF5 dims 2xN (appearing as Nx2 in R). } } diff --git a/man/h5_write_values.Rd b/man/h5_write_values.Rd index 361f5f8..eb342cd 100644 --- a/man/h5_write_values.Rd +++ b/man/h5_write_values.Rd @@ -41,7 +41,7 @@ Invisibly, written paths. \description{ \itemize{ \item Scalars: write with required \code{args} (args=list() or args=1L fallback). -\item 2-col TS (data.frame/tibble): expects Nx2 in R; writes as 2xN in HDF5 (RAINDROP style), +\item 2-col TS (data.frame/tibble): expects Nx2 in R; writes as 2xN in HDF5 (RainDrop style), using explicit hyperslab args=list(1:2, 1:N) to avoid empty selections. \item If TS length changes and dataset maxdims blocks resize, the dataset is deleted via parent$link_delete(name) and recreated with dims=2xN (fixed), then written. diff --git a/man/make_swale_runner.Rd b/man/make_swale_runner.Rd index b42c579..2d22b5d 100644 --- a/man/make_swale_runner.Rd +++ b/man/make_swale_runner.Rd @@ -71,7 +71,7 @@ scenario name and the optimisation metrics (\code{n_overflows}, \description{ Factors the \code{run_one()} function that was duplicated across the three workflow vignettes (Eisenstadt 2005, Wien, Bad Aussee) into one -package-level closure factory. The returned function runs the RAINDROP +package-level closure factory. The returned function runs the RainDrop engine for one parameter set and returns the thinned one-row optimisation result (overflow events + water balance), augmented with the input parameters and the overflow volume in m3. diff --git a/man/plot_valid_design_space.Rd b/man/plot_valid_design_space.Rd index f40f2e6..c2752a5 100644 --- a/man/plot_valid_design_space.Rd +++ b/man/plot_valid_design_space.Rd @@ -102,7 +102,7 @@ split by \code{storage_type} into two stacked panels (infiltration box on top, gravel trench below) with free y-scales, so disjoint per-type levels (e.g. \code{storage_height}: 300-1200 mm boxes vs. 900-3600 mm trenches) fill their own panel; duplicate counting for \code{alpha_mode = -"duplicates"} then happens per panel and the points stay plain circles + "duplicates"} then happens per panel and the points stay plain circles (the strips already name the type). Requires a \code{storage_type} column in \code{param_grid}. Without faceting, points are shaped by the storage type (filled square = infiltration box, filled triangle = gravel diff --git a/man/read_raindrop_errors.Rd b/man/read_raindrop_errors.Rd index 7670ade..f4d22bd 100644 --- a/man/read_raindrop_errors.Rd +++ b/man/read_raindrop_errors.Rd @@ -2,7 +2,7 @@ % Please edit documentation in R/read_raindrop_errors.R \name{read_raindrop_errors} \alias{read_raindrop_errors} -\title{Read RAINDROP error logs into a nested tibble} +\title{Read RainDrop error logs into a nested tibble} \usage{ read_raindrop_errors(simulation_names, path_list, debug = FALSE) } @@ -28,7 +28,7 @@ A tibble with columns: } } \description{ -Reads the RAINDROP error protocol HDF5 (typically \code{Fehlerprotokoll.h5}) +Reads the RainDrop error protocol HDF5 (typically \code{Fehlerprotokoll.h5}) for a set of simulation runs and returns a tibble with one row per run and a nested tibble column containing all errors found in the file. } diff --git a/man/run_model.Rd b/man/run_model.Rd index 2a349ee..6dccb8f 100644 --- a/man/run_model.Rd +++ b/man/run_model.Rd @@ -23,7 +23,7 @@ output as a character vector.} Forwarded to \code{kwb.utils::catAndRun(dbg = ...)} to enable/disable the progress message. Default: \code{TRUE}.} -\item{...}{Additional arguments passed to \code{\link[base:shell]{base::shell()}}, e.g. \code{timeout} on Windows. +\item{...}{Additional arguments passed to \code{\link[base:system]{base::shell()}}, e.g. \code{timeout} on Windows. See \code{?base::shell} for details.} } \value{ @@ -39,8 +39,8 @@ command output are wrapped with \code{\link[kwb.utils:catAndRun]{kwb.utils::catA } \details{ Both \code{path_exe} and \code{path_input} are converted to absolute, normalised -paths via \code{\link[fs:path_abs]{fs::path_abs()}} and \code{\link[base:normalizePath]{base::normalizePath()}}. The command is -executed with \code{\link[base:shell]{base::shell()}}, which on Windows invokes the system shell. +paths via \code{\link[fs:path_math]{fs::path_abs()}} and \code{\link[base:normalizePath]{base::normalizePath()}}. The command is +executed with \code{\link[base:system]{base::shell()}}, which on Windows invokes the system shell. On non-Windows platforms, prefer \code{\link[base:system]{base::system()}} if you need full POSIX semantics. } \section{Side effects}{ @@ -64,5 +64,5 @@ status <- run_model(exe, input, print_output = TRUE) } \seealso{ -\code{\link[base:shell]{base::shell()}}, \code{\link[fs:path_abs]{fs::path_abs()}}, \code{\link[kwb.utils:catAndRun]{kwb.utils::catAndRun()}} +\code{\link[base:system]{base::shell()}}, \code{\link[fs:path_math]{fs::path_abs()}}, \code{\link[kwb.utils:catAndRun]{kwb.utils::catAndRun()}} } diff --git a/vignettes/example_wien_minimal.Rmd b/vignettes/example_wien_minimal.Rmd index a40f54a..b0ce5ce 100644 --- a/vignettes/example_wien_minimal.Rmd +++ b/vignettes/example_wien_minimal.Rmd @@ -330,7 +330,7 @@ The XLSX dump bundles, in one file: ET0 series fed to every scenario (these are identical across runs). * `applied_settings` — long-format diff of every key the package writes on top of `base.h5`, per scenario (`scenario × parameter × base_value - × scenario_value`). Use this to see at a glance exactly what RAINDROP + × scenario_value`). Use this to see at a glance exactly what RainDrop is being told to change. * `s00001`, `s00002`, ..., `s00012` — full per-scenario H5 dump (the same view as `base`, but for each scenario's modified input file). diff --git a/vignettes/monotonicity_analysis.Rmd b/vignettes/monotonicity_analysis.Rmd index 544f0de..7a9055e 100644 --- a/vignettes/monotonicity_analysis.Rmd +++ b/vignettes/monotonicity_analysis.Rmd @@ -94,7 +94,7 @@ sie ablegen — nur die Links zeigen auf die Deploy-Orte.) ```{r report_link, echo = FALSE, results = 'asis', eval = !is_ghactions} cat(paste0( "Der zusammenfassende, allgemeinverständliche Ergebnisbericht (Artefakt, ", - "Titel: „Monotonie-Analyse RAINDROP“) liegt als [index.html](index.html) ", + "Titel: „Monotonie-Analyse RainDrop“) liegt als [index.html](index.html) ", "direkt neben dieser Seite — als Verzeichnis-Startseite von ", "`…/optimisation/monotonicity_analysis/`. Nicht zu verwechseln mit dem ", "„Brute-Force“-Linkhub: Dessen Quelle `index.Rmd` liegt in `vignettes/`, ", diff --git a/vignettes/workflow_badaussee.Rmd b/vignettes/workflow_badaussee.Rmd index 89f6f27..b6817ce 100644 --- a/vignettes/workflow_badaussee.Rmd +++ b/vignettes/workflow_badaussee.Rmd @@ -484,7 +484,7 @@ htmlwidgets::saveWidget(DT::datatable(simulation_results_optimisation, autoWidth = TRUE)), file = sprintf("simulation_results_optimisation_%s.html", paths$modelname), - title = sprintf("RAINDROP - '%s': Solution Space", + title = sprintf("RainDrop - '%s': Solution Space", paths$modelname) ) ### Plot results @@ -575,7 +575,7 @@ htmlwidgets::saveWidget( file = sprintf("simulation_results_optimisation_%s_main-effects.html", paths$modelname), selfcontained = TRUE, - title = sprintf("RAINDROP - '%s': Main Effects", + title = sprintf("RainDrop - '%s': Main Effects", paths$modelname) ) diff --git a/vignettes/workflow_eisenstadt-2005.Rmd b/vignettes/workflow_eisenstadt-2005.Rmd index b21d339..b16bc68 100644 --- a/vignettes/workflow_eisenstadt-2005.Rmd +++ b/vignettes/workflow_eisenstadt-2005.Rmd @@ -378,7 +378,7 @@ htmlwidgets::saveWidget(DT::datatable(simulation_results_optimisation, autoWidth = TRUE)), file = sprintf("simulation_results_optimisation_%s.html", paths$modelname), - title = sprintf("RAINDROP - '%s': Solution Space", + title = sprintf("RainDrop - '%s': Solution Space", paths$modelname) ) ### Plot results @@ -467,7 +467,7 @@ htmlwidgets::saveWidget( file = sprintf("simulation_results_optimisation_%s_main-effects.html", paths$modelname), selfcontained = TRUE, - title = sprintf("RAINDROP - '%s': Main Effects", + title = sprintf("RainDrop - '%s': Main Effects", paths$modelname) ) diff --git a/vignettes/workflow_wien.Rmd b/vignettes/workflow_wien.Rmd index fab82b8..80dc67b 100644 --- a/vignettes/workflow_wien.Rmd +++ b/vignettes/workflow_wien.Rmd @@ -480,7 +480,7 @@ htmlwidgets::saveWidget(DT::datatable(simulation_results_optimisation, autoWidth = TRUE)), file = sprintf("simulation_results_optimisation_%s.html", paths$modelname), - title = sprintf("RAINDROP - '%s': Solution Space", + title = sprintf("RainDrop - '%s': Solution Space", paths$modelname) ) ### Plot results @@ -571,7 +571,7 @@ htmlwidgets::saveWidget( file = sprintf("simulation_results_optimisation_%s_main-effects.html", paths$modelname), selfcontained = TRUE, - title = sprintf("RAINDROP - '%s': Main Effects", + title = sprintf("RainDrop - '%s': Main Effects", paths$modelname) ) From 3580ffb9f3b6db997f40400ae70e3306f290de81 Mon Sep 17 00:00:00 2001 From: Claude Date: Tue, 22 Sep 2026 08:44:33 +0000 Subject: [PATCH 2/3] Record the concept DOI next to the version DOI The version DOI (10.5281/zenodo.21839223) pins the archived v0.1.0 and stays where it is: it sits next to `version: 0.1.0` / `date-released:` in CITATION.cff and next to `note = "R package version 0.1.0"` in inst/CITATION, so a citation built from either file resolves to exactly the release it names. What was missing is the concept DOI (10.5281/zenodo.21839222), which Zenodo always resolves to the newest release: - CITATION.cff gains an `identifiers` block listing both DOIs with a description each. CFF 1.2.0 treats the top-level `doi` as shorthand "most useful when there is just one DOI"; with two, `identifiers` is the place that can say which is which. Validated against the official CFF 1.2.0 JSON schema. - inst/CITATION gains a footer naming the concept DOI for citing the package in general. .zenodo.json deliberately stays without a DOI: it describes the upload for which Zenodo mints the next DOI itself. Co-Authored-By: Claude Opus 5 Claude-Session: https://claude.ai/code/session_012P8tqzLoudLCjx18ASDatE --- CITATION.cff | 9 ++++++++- inst/CITATION | 6 ++++++ 2 files changed, 14 insertions(+), 1 deletion(-) diff --git a/CITATION.cff b/CITATION.cff index 7eb6a5f..7573cf2 100644 --- a/CITATION.cff +++ b/CITATION.cff @@ -3,8 +3,15 @@ message: "If you use this software, please cite it using the metadata below." type: software title: "kwb.raindrop: R Package for Optimisation Simulations for Rainwater Management" version: 0.1.0 -doi: "10.5281/zenodo.21839223" date-released: "2026-08-07" +doi: "10.5281/zenodo.21839223" +identifiers: + - type: doi + value: "10.5281/zenodo.21839222" + description: "Concept DOI - always resolves to the latest release." + - type: doi + value: "10.5281/zenodo.21839223" + description: "Version DOI of release v0.1.0." license: MIT repository-code: "https://github.com/KWB-R/kwb.raindrop" url: "https://kwb-r.github.io/kwb.raindrop" diff --git a/inst/CITATION b/inst/CITATION index d09e269..0af63d6 100644 --- a/inst/CITATION +++ b/inst/CITATION @@ -11,3 +11,9 @@ bibentry( url = "https://github.com/KWB-R/kwb.raindrop", doi = "10.5281/zenodo.21839223" ) + +citFooter(paste( + "The DOI above identifies version 0.1.0. To cite the package in general,", + "use the concept DOI 10.5281/zenodo.21839222, which always resolves to", + "the latest release." +)) From 09dbcc87305143c5294527cd79023dd4172b5ea7 Mon Sep 17 00:00:00 2001 From: Claude Date: Tue, 22 Sep 2026 09:10:25 +0000 Subject: [PATCH 3/3] Cite the concept DOI, not the version DOI The version DOI cannot be recorded in the repository: Zenodo mints it only after a release has been archived, so at the moment CITATION.cff and inst/CITATION are written - before tagging - the DOI of the release being tagged does not exist yet. Writing the previous release's version DOI would make every archived snapshot point at its predecessor. The concept DOI (10.5281/zenodo.21839222) has neither problem: it is fixed from the first release on and always resolves to the newest one. It is now the DOI in both files, with a comment in each saying why, so it does not get "corrected" to a version DOI later. Version DOIs stay available where they are always accurate: the version list on the Zenodo record the concept DOI resolves to. Also drops the hard-coded package version from inst/CITATION in favour of `meta$Version`, so that field cannot go stale at release time either. CITATION.cff re-validated against the official CFF 1.2.0 JSON schema. Co-Authored-By: Claude Opus 5 Claude-Session: https://claude.ai/code/session_012P8tqzLoudLCjx18ASDatE --- CITATION.cff | 13 +++++-------- inst/CITATION | 13 ++++++++----- 2 files changed, 13 insertions(+), 13 deletions(-) diff --git a/CITATION.cff b/CITATION.cff index 7573cf2..cbaac7c 100644 --- a/CITATION.cff +++ b/CITATION.cff @@ -4,14 +4,11 @@ type: software title: "kwb.raindrop: R Package for Optimisation Simulations for Rainwater Management" version: 0.1.0 date-released: "2026-08-07" -doi: "10.5281/zenodo.21839223" -identifiers: - - type: doi - value: "10.5281/zenodo.21839222" - description: "Concept DOI - always resolves to the latest release." - - type: doi - value: "10.5281/zenodo.21839223" - description: "Version DOI of release v0.1.0." +# Concept DOI: always resolves to the newest release. Do not replace it with a +# version DOI - Zenodo mints those only after a release has been archived, so +# the DOI of the release being tagged cannot be known when this file is +# written. Version DOIs are listed on the Zenodo record this one resolves to. +doi: "10.5281/zenodo.21839222" license: MIT repository-code: "https://github.com/KWB-R/kwb.raindrop" url: "https://kwb-r.github.io/kwb.raindrop" diff --git a/inst/CITATION b/inst/CITATION index 0af63d6..dab351f 100644 --- a/inst/CITATION +++ b/inst/CITATION @@ -1,5 +1,9 @@ citHeader("To cite kwb.raindrop in publications use:") +## The DOI is the concept DOI, which always resolves to the newest release. +## Do not replace it with a version DOI: Zenodo mints those only after a +## release has been archived, so the DOI of the release being tagged cannot be +## known when this file is written. bibentry( bibtype = "Manual", title = paste("kwb.raindrop: R Package for Optimisation Simulations", @@ -7,13 +11,12 @@ bibentry( author = person("Michael", "Rustler", comment = c(ORCID = "0000-0003-0647-7726")), year = "2026", - note = "R package version 0.1.0", + note = paste("R package version", meta$Version), url = "https://github.com/KWB-R/kwb.raindrop", - doi = "10.5281/zenodo.21839223" + doi = "10.5281/zenodo.21839222" ) citFooter(paste( - "The DOI above identifies version 0.1.0. To cite the package in general,", - "use the concept DOI 10.5281/zenodo.21839222, which always resolves to", - "the latest release." + "The DOI above resolves to the newest release. To cite the exact version you", + "used, take its version DOI from the version list on that Zenodo record." ))