|
1 | 1 | #' Write model-specific run scripts and configuration files |
2 | 2 | #' |
3 | | -#' @md |
4 | 3 | #' Generates run scripts and configuration files for all analyses (ensemble |
5 | 4 | #' and/or sensitivity analysis) specified in the provided settings. Delegates |
6 | 5 | #' the model-specific config writing to the appropriate `write.config.*` |
|
43 | 42 | #' appended. This forces use of only files within this workflow, to avoid |
44 | 43 | #' confusion. |
45 | 44 | #' |
| 45 | +#' @md |
| 46 | +#' |
46 | 47 | #' @param settings a PEcAn settings list |
47 | 48 | #' @param ensemble.size number of ensemble runs |
48 | 49 | #' @param input_design Input design data.frame coordinating input files across |
|
53 | 54 | #' ensemble and sensitivity analysis (e.g. `post.distns.Rdata`, or |
54 | 55 | #' `prior.distns.Rdata`). |
55 | 56 | #' @param overwrite logical: Replace output files that already exist? |
| 57 | +#' @param samples Optional pre-computed parameter samples (a list with |
| 58 | +#' `trait.samples`, `sa.samples`, `ensemble.samples`). When supplied, these |
| 59 | +#' are used directly and `samples.Rdata` is not read from disk. When `NULL` |
| 60 | +#' (default), the function falls back to loading `samples.Rdata` from |
| 61 | +#' `settings$outdir`. |
56 | 62 | #' |
57 | 63 | #' @return The `settings` list (invisibly), updated with ensemble IDs for SA |
58 | 64 | #' and ensemble analysis (e.g. `settings$sensitivity.analysis$ensemble.id`, |
|
63 | 69 |
|
64 | 70 | run.write.configs <- function(settings, ensemble.size, input_design, write = TRUE, |
65 | 71 | posterior.files = rep(NA, length(settings$pfts)), |
66 | | - overwrite = TRUE) { |
| 72 | + overwrite = TRUE, samples = NULL) { |
67 | 73 |
|
68 | 74 | # Validate that input_design matches ensemble.size for ensemble runs |
69 | 75 | # Note: for SA, ensemble.size is not meaningful; SA design size is determined by |
@@ -158,36 +164,43 @@ run.write.configs <- function(settings, ensemble.size, input_design, write = TRU |
158 | 164 | scipen <- getOption("scipen") |
159 | 165 | options(scipen = 12) |
160 | 166 |
|
161 | | - samples.file <- file.path(settings$outdir, "samples.Rdata") |
162 | | - if (file.exists(samples.file)) { |
163 | | - existing_data <- new.env() |
164 | | - load(samples.file, envir = existing_data) ## loads ensemble.samples, trait.samples, sa.samples, runs.samples, env.samples |
165 | | - trait.samples <- existing_data$trait.samples |
166 | | - sa.samples <- existing_data$sa.samples |
167 | | - |
168 | | - # build ensemble.samples only for ensemble runs |
169 | | - # SA runs use sa.samples directly (quantile-based), not ensemble.samples |
170 | | - if ("ensemble" %in% names(settings) && |
171 | | - !is.null(input_design) && |
172 | | - "param" %in% colnames(input_design)) { |
173 | | - trait_sample_indices <- input_design[["param"]] |
174 | | - ensemble.samples <- list() |
175 | | - for (pft in names(trait.samples)) { |
176 | | - pft_traits <- trait.samples[[pft]] |
177 | | - ensemble.samples[[pft]] <- as.data.frame( |
178 | | - lapply( |
179 | | - names(pft_traits), |
180 | | - function(trait) pft_traits[[trait]][trait_sample_indices] |
181 | | - ) |
182 | | - ) |
183 | | - names(ensemble.samples[[pft]]) <- names(pft_traits) |
184 | | - } |
| 167 | + ## Resolve parameter samples: use the in-memory bundle when passed, |
| 168 | + ## otherwise fall back to loading samples.Rdata from disk. |
| 169 | + if (!is.null(samples)) { |
| 170 | + existing_data <- samples |
| 171 | + } else { |
| 172 | + samples.file <- file.path(settings$outdir, "samples.Rdata") |
| 173 | + if (file.exists(samples.file)) { |
| 174 | + existing_data <- new.env() |
| 175 | + load(samples.file, envir = existing_data) ## loads ensemble.samples, trait.samples, sa.samples, runs.samples, env.samples |
185 | 176 | } else { |
186 | | - # use pre-generated samples |
187 | | - ensemble.samples <- existing_data$ensemble.samples |
| 177 | + PEcAn.logger::logger.error(samples.file, "not found, this file is required by the run.write.configs function") |
| 178 | + } |
| 179 | + } |
| 180 | + |
| 181 | + trait.samples <- existing_data$trait.samples |
| 182 | + sa.samples <- existing_data$sa.samples |
| 183 | + |
| 184 | + # build ensemble.samples only for ensemble runs |
| 185 | + # SA runs use sa.samples directly (quantile-based), not ensemble.samples |
| 186 | + if ("ensemble" %in% names(settings) && |
| 187 | + !is.null(input_design) && |
| 188 | + "param" %in% colnames(input_design)) { |
| 189 | + trait_sample_indices <- input_design[["param"]] |
| 190 | + ensemble.samples <- list() |
| 191 | + for (pft in names(trait.samples)) { |
| 192 | + pft_traits <- trait.samples[[pft]] |
| 193 | + ensemble.samples[[pft]] <- as.data.frame( |
| 194 | + lapply( |
| 195 | + names(pft_traits), |
| 196 | + function(trait) pft_traits[[trait]][trait_sample_indices] |
| 197 | + ) |
| 198 | + ) |
| 199 | + names(ensemble.samples[[pft]]) <- names(pft_traits) |
188 | 200 | } |
189 | 201 | } else { |
190 | | - PEcAn.logger::logger.error(samples.file, "not found, this file is required by the run.write.configs function") |
| 202 | + # use pre-generated samples |
| 203 | + ensemble.samples <- existing_data$ensemble.samples |
191 | 204 | } |
192 | 205 |
|
193 | 206 | ## remove previous runs.txt |
|
0 commit comments