From 276a81163671b2aeae5bf7307bf7161a8d8e8d18 Mon Sep 17 00:00:00 2001 From: Jannes Breier Date: Mon, 20 Mar 2023 13:59:40 +0100 Subject: [PATCH] major update to version 1.0.0, rearranging code, introducing deprecation to some arguments --- .buildlibrary | 2 +- .zenodo.json | 2 +- DESCRIPTION | 4 +- R/LPJmLData.R | 3 - R/calc_cellarea.R | 48 ++++---- R/check_config.R | 34 ++++-- R/get_git_urlhash.R | 55 --------- R/read_io.R | 15 +-- R/run_lpjml.R | 66 ++++++----- R/submit_lpjml.R | 68 +++++------ R/subset_array.R | 10 +- R/utils.R | 150 ++++++++++++++++++++++++ R/write_config.R | 171 +++++++++++++--------------- README.md | 6 +- man/calc_cellarea.Rd | 10 +- man/check_config.Rd | 21 ++-- man/run_lpjml.Rd | 32 +++--- man/submit_lpjml.Rd | 32 +++--- man/write_config.Rd | 43 ++++--- tests/testthat/test-calc_cellarea.R | 30 ++--- tests/testthat/test-write_config.R | 62 +++++----- tests/testthat/test_utils.R | 49 ++++++++ vignettes/lpjml-data.Rmd | 2 +- vignettes/lpjml-data.md | 2 +- vignettes/lpjml-runner.Rmd | 42 +++---- vignettes/lpjml-runner.md | 44 +++---- 26 files changed, 581 insertions(+), 422 deletions(-) delete mode 100644 R/get_git_urlhash.R create mode 100644 R/utils.R create mode 100644 tests/testthat/test_utils.R diff --git a/.buildlibrary b/.buildlibrary index 8556bf7..20f08e7 100644 --- a/.buildlibrary +++ b/.buildlibrary @@ -1,4 +1,4 @@ -ValidationKey: '1651805' +ValidationKey: '1943600' AutocreateReadme: yes AcceptedWarnings: - 'Warning: package ''.*'' was built under R version' diff --git a/.zenodo.json b/.zenodo.json index 05ee533..a07ed14 100644 --- a/.zenodo.json +++ b/.zenodo.json @@ -1,6 +1,6 @@ { "title": "lpjmlkit: Toolkit for basic LPJmL handling", - "version": "0.8.5", + "version": "1.0.0", "description": "

A collection of basic functions to facilitate the work with the\n Dynamic Global Vegetation Model (DGVM) Lund-Potsdam-Jena managed Land\n (LPJmL) hosted at the Potsdam Institute for Climate Impact Research (PIK).\n It provides functions for performing LPJmL simulations, as well as reading,\n processing and writing model-related data such as inputs and outputs or\n configuration files.<\/p>", "creators": [ { diff --git a/DESCRIPTION b/DESCRIPTION index 7ff2202..a3807c6 100644 --- a/DESCRIPTION +++ b/DESCRIPTION @@ -1,7 +1,7 @@ Package: lpjmlkit Type: Package Title: Toolkit for basic LPJmL handling -Version: 0.8.5 +Version: 1.0.0 Authors@R: c( person("Jannes", "Breier", , "jannesbr@pik-potsdam.de", role = c("aut", "cre"), comment = c(ORCID = "0000-0002-9055-6904")), person("Sebastian","Ostberg", , "ostberg@pik-potsdam.de", role = "aut", comment = c(ORCID = "0000-0002-2368-7015")), @@ -48,4 +48,4 @@ Suggests: maps Config/testthat/edition: 3 VignetteBuilder: knitr -Date: 2023-03-17 +Date: 2023-03-20 diff --git a/R/LPJmLData.R b/R/LPJmLData.R index 48ec043..c7edffe 100644 --- a/R/LPJmLData.R +++ b/R/LPJmLData.R @@ -515,6 +515,3 @@ find_gridfile <- function(searchdir) { filename } - -# Avoid note for "."... -utils::globalVariables(".") # nolint:undesirable_function_linter diff --git a/R/calc_cellarea.R b/R/calc_cellarea.R index 264852d..af3d1fc 100644 --- a/R/calc_cellarea.R +++ b/R/calc_cellarea.R @@ -7,11 +7,11 @@ #' @param x `LPJmLData` object with `$grid` attribute, an LPJmLData object of #' variable `"grid"` (`"LPJGRID"`) or a vector of cell-center latitude #' coordinates in degrees. -#' @param res_lon Grid resolution in longitude direction in degrees +#' @param cellsize_lon Grid resolution in longitude direction in degrees #' (default: `0.5`). If `x` is an LPJmLData object the resolution will be #' taken from the meta data included in `x` if available. -#' @param res_lat Grid resolution in latitude direction in degrees (default: -#' same as `res_lon`). If `x` is an LPJmLData object the resolution will be +#' @param cellsize_lat Grid resolution in latitude direction in degrees (default: +#' same as `cellsize_lon`). If `x` is an LPJmLData object the resolution will be #' taken from the meta data included in `x` if available. #' @param earth_radius Radius of the sphere (in \eqn{m}) used to calculate the #' cell areas. @@ -32,8 +32,8 @@ #' #' @export calc_cellarea <- function(x, # nolint:cyclocomp_linter. - res_lon = 0.5, - res_lat = res_lon, + cellsize_lon = 0.5, + cellsize_lat = cellsize_lon, earth_radius = 6371000.785, return_unit = "m2" ) { @@ -58,14 +58,14 @@ calc_cellarea <- function(x, # nolint:cyclocomp_linter. stop("Grid attribute is missing. Use method add_grid() to add it.") } - if (!is.null(x$meta$cellsize_lon) && any(res_lon != x$meta$cellsize_lon)) { - res_lon <- x$meta$cellsize_lon - warning("Using x$meta$cellsize_lon instead of supplied res_lon.") + if (!is.null(x$meta$cellsize_lon) && any(cellsize_lon != x$meta$cellsize_lon)) { + cellsize_lon <- x$meta$cellsize_lon + warning("Using x$meta$cellsize_lon instead of supplied cellsize_lon.") } - if (!is.null(x$meta$cellsize_lat) && any(res_lat != x$meta$cellsize_lat)) { - res_lat <- x$meta$cellsize_lat - warning("Using x$meta$cellsize_lat instead of supplied res_lat.") + if (!is.null(x$meta$cellsize_lat) && any(cellsize_lat != x$meta$cellsize_lat)) { + cellsize_lat <- x$meta$cellsize_lat + warning("Using x$meta$cellsize_lat instead of supplied cellsize_lat.") } # Check for format of space dimensions, apply different processing @@ -94,22 +94,22 @@ calc_cellarea <- function(x, # nolint:cyclocomp_linter. } # Check for irregular grid resolution arguments - if (length(res_lon) > 1) { - warning("res_lon has length ", length(res_lon), ". Using first element.") - res_lon <- res_lon[1] + if (length(cellsize_lon) > 1) { + warning("cellsize_lon has length ", length(cellsize_lon), ". Using first element.") + cellsize_lon <- cellsize_lon[1] } - if (length(res_lon) == 0 || is.na(res_lon)) { - stop("Invalid longitude grid resolution 'res_lon'") + if (length(cellsize_lon) == 0 || is.na(cellsize_lon)) { + stop("Invalid longitude grid resolution 'cellsize_lon'") } - res_lon <- as.double(res_lon) - if (length(res_lat) > 1) { - warning("res_lat has length ", length(res_lat), ". Using first element.") - res_lat <- res_lat[1] + cellsize_lon <- as.double(cellsize_lon) + if (length(cellsize_lat) > 1) { + warning("cellsize_lat has length ", length(cellsize_lat), ". Using first element.") + cellsize_lat <- cellsize_lat[1] } - if (length(res_lat) == 0 || is.na(res_lat)) { - stop("Invalid latitude grid resolution 'res_lat'") + if (length(cellsize_lat) == 0 || is.na(cellsize_lat)) { + stop("Invalid latitude grid resolution 'cellsize_lat'") } - res_lat <- as.double(res_lat) + cellsize_lat <- as.double(cellsize_lat) # Check for irregular latitude coordinates if (any(x < -90 | x > 90, na.rm = TRUE)) { @@ -118,7 +118,7 @@ calc_cellarea <- function(x, # nolint:cyclocomp_linter. cellwidth <- earth_radius * pi / 180 - cellwidth * res_lon * cellwidth * res_lat * cos(x / 180 * pi) %>% + cellwidth * cellsize_lon * cellwidth * cellsize_lat * cos(x / 180 * pi) %>% # Apply conversion factor based on return_unit parameter switch(return_unit, diff --git a/R/check_config.R b/R/check_config.R index 07f548b..106c09c 100644 --- a/R/check_config.R +++ b/R/check_config.R @@ -11,8 +11,9 @@ #' @param model_path Character string providing the path to LPJmL #' (equal to `LPJROOT` environment variable). Defaults to ".". #' -#' @param output_path Character string providing path where an output, a restart -#' and a configuration folder are created. If `NULL`, `model_path` is used. +#' @param sim_path Character string defining path where all simulation data are +#' written, including output, restart and configuration files. If `NULL`, +#' `model_path` is used. See also [write_config] #' #' @param return_output Parameter affecting the output. If `FALSE` print #' stdout/stderr message. If `TRUE`, return the result of the check. @@ -21,6 +22,9 @@ #' @param raise_error Logical. Whether to raise an error if sub-process has #' non-zero exit status. Defaults to `FALSE`. #' +#' @param output_path Argument is deprecated as of version 1.0; use sim_path +#' instead. +#' #' @return NULL. #' #' @examples @@ -29,7 +33,7 @@ #' library(lpjmlkit) #' #' model_path <- "./LPJmL_internal" -#' output_path <-"./my_runs" +#' sim_path <-"./my_runs" #' #' #' # Basic usage @@ -42,25 +46,30 @@ #' ) #' #' config_details <- write_config( -#' params = my_params, +#' x = my_params, #' model_path = model_path, -#' output_path = output_path +#' sim_path = sim_path #' ) #' #' check_config(x = config_details, #' model_path = model_path, -#' output_path = output_path, +#' sim_path = sim_path, #' return_output = FALSE #' ) #' } #' @export check_config <- function(x, model_path = ".", - output_path = NULL, + sim_path = NULL, return_output = FALSE, - raise_error = FALSE) { + raise_error = FALSE, + output_path = NULL) { + + sim_path <- deprecate_arg(new_arg = sim_path, + deprec_arg = output_path, + version = "1.0.0") - if (is.null(output_path)) output_path <- model_path + if (is.null(sim_path)) sim_path <- model_path # Check if x is character (vector). If so convert to tibble for the following. if (methods::is(x, "character")) { @@ -78,7 +87,7 @@ check_config <- function(x, config_files <- paste0("config_", x$sim_name, ".json") if (length(config_files) > 1) { - files <- paste0(output_path, + files <- paste0(sim_path, "/configurations/", config_files, collapse = " ") @@ -97,7 +106,7 @@ check_config <- function(x, } else { inner_command <- paste0(model_path, "/bin/lpjcheck ", # nolint:absolute_path_linter. - output_path, + sim_path, "/configurations/", config_files) } @@ -107,7 +116,8 @@ check_config <- function(x, check <- processx::run(command = "sh", args = c("-c", inner_command), error_on_status = raise_error, - cleanup_tree = TRUE) + cleanup_tree = TRUE, + wd = sim_path) if (!return_output) { return( diff --git a/R/get_git_urlhash.R b/R/get_git_urlhash.R deleted file mode 100644 index a551d63..0000000 --- a/R/get_git_urlhash.R +++ /dev/null @@ -1,55 +0,0 @@ -# Function to get gitlab commit hash of repository path. -# Via include_url = TRUE url + hash is returned to be called via webbrowser. -get_git_urlhash <- function(path = ".", - include_url = TRUE, - raise_error = TRUE) { - - # List of bash commands - inner_commands <- paste0( - # Filter .git in URL - "git='.git';", - - # Get origin URL (with .git at ending, not legit for URL) - "orig_url=$(git config --get remote.origin.url);", - - # Get commit hash - "hash=$(git rev-parse HEAD);", - - # Some URLs include a cluster extension in before real URL starting with @ - "if [[ $orig_url == *'@'* ]]; then ", - "orig_url=https://${orig_url##*@}; fi;", - - # Check for github or gitlab - "if [[ $orig_url == *'github'* ]]; then ", - - # Concatenate URL and hash if required. Github has slightly different - # routing. - "url=${orig_url%%$git*}/tree/${hash}; else ", - "url=${orig_url%%$git*}/-/tree/${hash}; fi;", - - # Replace ":" in URLs if SSH is used to clone repository - "url=${url//de:/de/}; ", - "url=${url//com:/com/}; ", - ifelse(include_url, "echo ${url};", "echo ${hash};") - ) - - # System call - out <- processx::run(command = "bash", - args = c("-c", inner_commands), - wd = path, - cleanup_tree = TRUE, - error_on_status = FALSE) - - # Check output, ignore errors - if (out$stderr == "") { - return(sub("\n", "", out$stdout)) - } else { - - if (raise_error) { - stop("For path \"", path, "\": ", out$stderr, call. = FALSE) - } else { - warning("For path \"", path, "\": ", out$stderr, call. = FALSE) - return("") - } - } -} diff --git a/R/read_io.R b/R/read_io.R index e90dcab..cea334f 100644 --- a/R/read_io.R +++ b/R/read_io.R @@ -185,6 +185,7 @@ read_io <- function( # nolint:cyclocomp_linter. # Switch off fancy quotes but revert setting when leaving the function quotes_option <- options(useFancyQuotes = FALSE) # nolint:undesirable_function_linter. on.exit(options(quotes_option)) # nolint:undesirable_function_linter. + # Detect file_type if not provided by user if (is.null(file_type)) { file_type <- detect_io_type(filename) @@ -196,6 +197,7 @@ read_io <- function( # nolint:cyclocomp_linter. "This function can read files of type ", toString(dQuote(supported_types)) ) } + # Check valid dim_order valid_dim_names <- c("cell", "time", "band") if (!all(dim_order %in% valid_dim_names)) { @@ -620,7 +622,7 @@ read_io_metadata_meta <- function(filename, file_type, band_names, } } # Prepare additional attributes to be added to metadata - additional_attributes <- sapply( + additional_attributes <- sapply( # nolint:undesirable_function_linter. set_args, function(x) unname(get(x)), simplify = FALSE @@ -880,14 +882,3 @@ check_year_subset <- function(subset, meta_data, silent = FALSE) { } invisible(subset) } - -# Utility function to replace missing attribute with default value -default <- function(value, default) { - if (is.null(value)) { - return(default) - } else { - return(value) - } -} -# file_type options supported by read_io -supported_types <- c("raw", "clm", "meta") diff --git a/R/run_lpjml.R b/R/run_lpjml.R index 71aa9c7..a9e4760 100644 --- a/R/run_lpjml.R +++ b/R/run_lpjml.R @@ -15,9 +15,9 @@ #' @param model_path Character string providing the path to LPJmL #' (equal to `LPJROOT` environment variable). Defaults to "." #' -#' @param output_path Character string providing path where an output, a restart -#' and a configuration folder are created to store respective data. If `NULL`, -#' `model_path` is used. +#' @param sim_path Character string defining path where all simulation data are +#' written, including output, restart and configuration files. If `NULL`, +#' `model_path` is used. See also [write_config] #' #' @param parallel_cores Integer defining the number of available CPU #' cores/nodes for parallelization. Defaults to `1` (no parallelization). @@ -31,6 +31,9 @@ #' @param raise_error Logical. Whether to raise an error if sub-process has #' non-zero exit status. Defaults to `TRUE`. #' +#' @param output_path Argument is deprecated as of version 1.0; use sim_path +#' instead. +#' #' @return See `x`, extended by columns `"type"`, `"job_id"` and `"status"`. #' #' @details @@ -66,7 +69,7 @@ #' library(tibble) #' #' model_path <- "./LPJmL_internal" -#' output_path <-"./my_runs" +#' sim_path <-"./my_runs" #' #' # Basic usage #' my_params1 <- tibble( @@ -79,12 +82,12 @@ #' new_phenology = c(TRUE, FALSE) #' ) #' -#' config_details1 <- write_config(my_params1, model_path, output_path) +#' config_details1 <- write_config(my_params1, model_path, sim_path) #' #' run_details1 <- run_lpjml( #' x = config_details1, #' model_path = model_path, -#' output_path = output_path +#' sim_path = sim_path #' ) #' #' run_details1 @@ -104,9 +107,9 @@ #' dependency = c(NA, "scen1_spinup") #' ) #' -#' config_details2 <- write_config(my_params2, model_path, output_path) +#' config_details2 <- write_config(my_params2, model_path, sim_path) #' -#' run_details2 <- run_lpjml(config_details2, model_path, output_path) +#' run_details2 <- run_lpjml(config_details2, model_path, sim_path) #' #' run_details2 #' # sim_name order dependency type job_id status @@ -121,21 +124,21 @@ #' random_seed = as.integer(c(1, 42)), #' dependency = c(NA, "scen1_spinup") #' ) %>% -#' write_config(model_path, output_path) %>% -#' run_lpjml(model_path, output_path) +#' write_config(model_path, sim_path) %>% +#' run_lpjml(model_path, sim_path) #' #' #' # Shortcut approaches #' run_details3 <- run_lpjml( #' x = "./config_scen1_transient.json", #' model_path = model_path, -#' output_path = output_path +#' sim_path = sim_path #' ) #' #' run_details4 <- run_lpjml( #' c("./config_scen1_spinup.json", "./config_scen1_transient.json"), #' model_path, -#' output_path +#' sim_path #' ) #' #' } @@ -144,16 +147,22 @@ #' @export run_lpjml <- function(x, model_path = ".", - output_path = NULL, + sim_path = NULL, parallel_cores = 1, write_stdout = FALSE, - raise_error = TRUE) { + raise_error = TRUE, + output_path = NULL) { # Check if model_path is set or unit test flag provided if (!dir.exists(model_path)) { stop("Folder of model_path \"", model_path, "\" does not exist.") } - if (is.null(output_path)) output_path <- model_path + + sim_path <- deprecate_arg(new_arg = sim_path, + deprec_arg = output_path, + version = "1.0.0") + + if (is.null(sim_path)) sim_path <- model_path # Case if character vector with file names is supplied instead of tibble if (methods::is(x, "character")) { @@ -179,11 +188,11 @@ run_lpjml <- function(x, if (parallel_cores == 1) { do_sequential( - sim_names, model_path, output_path, write_stdout, raise_error + sim_names, model_path, sim_path, write_stdout, raise_error ) } else if (parallel_cores > 1 && Sys.getenv("SLURM_JOB_ID") != "") { do_parallel( - sim_names, model_path, output_path, parallel_cores, raise_error + sim_names, model_path, sim_path, parallel_cores, raise_error ) } else { stop( @@ -197,11 +206,11 @@ run_lpjml <- function(x, } else { if (parallel_cores == 1) { do_sequential( - x$sim_name, model_path, output_path, write_stdout, raise_error + x$sim_name, model_path, sim_path, write_stdout, raise_error ) } else if (parallel_cores > 1 && Sys.getenv("SLURM_JOB_ID") != "") { do_parallel( - x$sim_name, model_path, output_path, parallel_cores, raise_error + x$sim_name, model_path, sim_path, parallel_cores, raise_error ) } else { stop( @@ -220,7 +229,7 @@ run_lpjml <- function(x, # Inner run function do_run <- function(sim_name, model_path, - output_path, + sim_path, write_stdout, raise_error) { @@ -240,12 +249,12 @@ do_run <- function(sim_name, "srun --propagate "), model_path, "/bin/lpjml ", # nolint:absolute_path_linter. - output_path, + sim_path, "/configurations/", config_file) stdout_file <- ifelse(write_stdout, - paste0(output_path, + paste0(sim_path, "/output/", sim_name, "/", @@ -266,7 +275,7 @@ do_run <- function(sim_name, args = c("-c", inner_command), stdout = stdout_file, stderr = ifelse(write_stdout, - paste0(output_path, + paste0(sim_path, "/output/", sim_name, "/", @@ -280,7 +289,8 @@ do_run <- function(sim_name, Sys.getenv("SLURM_JOB_ID") == "", TRUE, FALSE), - error_on_status = raise_error) + error_on_status = raise_error, + wd = sim_path) } @@ -288,7 +298,7 @@ do_run <- function(sim_name, # node. do_sequential <- function(sim_names, model_path, - output_path, + sim_path, write_stdout, raise_error) { @@ -304,7 +314,7 @@ do_sequential <- function(sim_names, I_MPI_DAPL_FABRIC = "shm:sh") } for (sim_name in sim_names) { - do_run(sim_name, model_path, output_path, write_stdout, raise_error) + do_run(sim_name, model_path, sim_path, write_stdout, raise_error) } }, finally = { # Check if slurm is available @@ -320,7 +330,7 @@ do_sequential <- function(sim_names, # Conduct parallel runs. do_parallel <- function(sim_names, model_path, - output_path, + sim_path, parallel_cores, raise_error) { @@ -340,7 +350,7 @@ do_parallel <- function(sim_names, # Write single call tryCatch({ do_run( - sim_name, model_path, output_path, write_stdout = TRUE, raise_error + sim_name, model_path, sim_path, write_stdout = TRUE, raise_error ) # Stop when error occures diff --git a/R/submit_lpjml.R b/R/submit_lpjml.R index 3579730..97ab300 100644 --- a/R/submit_lpjml.R +++ b/R/submit_lpjml.R @@ -15,9 +15,9 @@ #' @param model_path Character string providing the path to LPJmL #' (equal to `LPJROOT` environment variable). #' -#' @param output_path Character string providing path where an output, a restart -#' and a configuration folder are created to store respective data. If `NULL`, -#' `model_path` is used. +#' @param sim_path Character string defining path where all simulation data are +#' written, including output, restart and configuration files. If `NULL`, +#' `model_path` is used. See also [write_config] #' #' @param group Character string defining the user group for which the job is #' submitted. Defaults to `"lpjml"`. @@ -42,6 +42,9 @@ #' @param no_submit Logical. Set to `TRUE` to test if `x` set correctly or #' `FALSE` to actually submit job to SLURM. #' +#' @param output_path Argument is deprecated as of version 1.0; use sim_path +#' instead. +#' #' @return See `x`, extended by columns `"type"`, `"job_id"` and `"status"`. #' #' @details @@ -88,7 +91,7 @@ #' library(tibble) #' #' model_path <- "./LPJmL_internal" -#' output_path <-"./my_runs" +#' sim_path <-"./my_runs" #' #' #' # Basic usage @@ -100,12 +103,12 @@ #' new_phenology = c(TRUE, FALSE) #' ) #' -#' config_details <- write_config(my_params, model_path, output_path) +#' config_details <- write_config(my_params, model_path, sim_path) #' #' run_details <- submit_lpjml( #' x = config_details, #' model_path = model_path, -#' output_path = output_path +#' sim_path = sim_path #' ) #' #' run_details @@ -124,9 +127,9 @@ #' wtime = c("8:00:00", "4:00:00"), #' ) #' -#' config_details2 <- write_config(my_params2, model_path, output_path) +#' config_details2 <- write_config(my_params2, model_path, sim_path) #' -#' run_details2 <- submit_lpjml(config_details2, model_path, output_path) +#' run_details2 <- submit_lpjml(config_details2, model_path, sim_path) #' #' run_details2 #' # sim_name order dependency wtime type job_id status @@ -142,21 +145,21 @@ #' dependency = c(NA, "scen1_spinup"), #' wtime = c("8:00:00", "4:00:00"), #' ) %>% -#' write_config(model_path, output_path) %>% -#' submit_lpjml(model_path, output_path) +#' write_config(model_path, sim_path) %>% +#' submit_lpjml(model_path, sim_path) #' #' #' # Shortcut approach #' run_details <- submit_lpjml( #' x = "./config_scen1_transient.json", #' model_path = model_path, -#' output_path = output_path +#' sim_path = sim_path #' ) #' #' run_details <- submit_lpjml( #' c("./config_scen1_spinup.json", "./config_scen1_transient.json"), #' model_path, -#' output_path +#' sim_path #' ) #' #' } @@ -165,13 +168,14 @@ #' @export submit_lpjml <- function(x, # nolint:cyclocomp_linter. model_path, - output_path = NULL, + sim_path = NULL, group = "lpjml", sclass = "short", ntasks = 256, wtime = "", blocking = "", - no_submit = FALSE) { + no_submit = FALSE, + output_path = NULL) { # Check if SLURM is available if (!is_slurm_available() && !no_submit && !testthat::is_testing()) { @@ -183,7 +187,12 @@ submit_lpjml <- function(x, # nolint:cyclocomp_linter. if (!dir.exists(model_path)) { stop("Folder of model_path \"", model_path, "\" does not exist!") } - if (is.null(output_path)) output_path <- model_path + + sim_path <- deprecate_arg(new_arg = sim_path, + deprec_arg = output_path, + version = "1.0.0") + + if (is.null(sim_path)) sim_path <- model_path # Case if character vector with file names is supplied instead of tibble if (methods::is(x, "character")) { @@ -240,7 +249,7 @@ submit_lpjml <- function(x, # nolint:cyclocomp_linter. if (!no_submit) { job <- submit_run(sim_name, model_path, - output_path, + sim_path, group, sclass, ntasks, @@ -289,7 +298,7 @@ submit_lpjml <- function(x, # nolint:cyclocomp_linter. if (!no_submit) { job <- submit_run(sim_name, model_path, - output_path, + sim_path, group, sclass, ntasks, @@ -323,7 +332,7 @@ submit_lpjml <- function(x, # nolint:cyclocomp_linter. # Internal submit run function submit_run <- function(sim_name, model_path, - output_path, + sim_path, group, sclass, ntasks, @@ -337,7 +346,7 @@ submit_run <- function(sim_name, timestamp <- format(Sys.time(), "%Y%m%d_%H%M") - stdout <- paste0(output_path, + stdout <- paste0(sim_path, "/output/", sim_name, "/", @@ -345,7 +354,7 @@ submit_run <- function(sim_name, timestamp, ".out") - stderr <- paste0(output_path, + stderr <- paste0(sim_path, "/output/", sim_name, "/", @@ -353,7 +362,7 @@ submit_run <- function(sim_name, timestamp, ".err") - output_config <- paste0(output_path, + output_config <- paste0(sim_path, "/output/", sim_name, "/", @@ -379,7 +388,7 @@ submit_run <- function(sim_name, " ", ntasks, " ", - output_path, + sim_path, "/configurations/", config_file) @@ -395,9 +404,10 @@ submit_run <- function(sim_name, submit_status <- processx::run(command = "sh", args = c("-c", inner_command), cleanup_tree = TRUE, - error_on_status = FALSE) + error_on_status = FALSE, + wd = sim_path) if (!testthat::is_testing()) { - copied <- file.copy(from = paste(output_path, # nolint:object_usage_linter. + copied <- file.copy(from = paste(sim_path, # nolint:object_usage_linter. "configurations", config_file, sep = "/"), @@ -418,13 +428,3 @@ submit_run <- function(sim_name, return(submit_status) } - - -# Function checks and returns whether SLURM is available -is_slurm_available <- function() { - processx::run(command = "sh", - args = c("-c", "sinfo"), - error_on_status = FALSE) %>% - .$status == 0 %>% - return() -} diff --git a/R/subset_array.R b/R/subset_array.R index e7d950e..028885b 100644 --- a/R/subset_array.R +++ b/R/subset_array.R @@ -271,14 +271,6 @@ subset_array_pair <- function(x, } -# Drop dimensions of length 1 except those that are selected by name -drop_omit <- function(x, omit_dim) { - dims <- dim(x) - dims_check <- dims == 1 & !(names(dims) %in% omit_dim) - - abind::adrop(x, dims_check) -} - # Check if indices exist in dimension of array check_index <- function(x, y, dim_name) { if (any(abs(x) > length(y) | x == 0)) { @@ -287,6 +279,7 @@ check_index <- function(x, y, dim_name) { } } + # Check if character vector elements exist in dimension of array check_string_index <- function(x, valids, dim_name) { if (any(is.na(valids))) { @@ -295,6 +288,7 @@ check_string_index <- function(x, valids, dim_name) { } } + # Print error for non valid elements of dimension stop_subset <- function(x, nonvalids, dim_name, string_index = FALSE) { if (string_index) { diff --git a/R/utils.R b/R/utils.R new file mode 100644 index 0000000..d9d7094 --- /dev/null +++ b/R/utils.R @@ -0,0 +1,150 @@ +# Collection of small utility function applied across the package + +# Function to deprecate a function argument that is replaced by a new one +deprecate_arg <- function(new_arg, deprec_arg, version = "1.0.0") { + + new_name <- deparse(substitute(new_arg)) + deprec_name <- deparse(substitute(deprec_arg)) + + # Only if deprecated argument is set + if (!is.null(deprec_arg)) { + + if (is.null(new_arg)) { + new_arg <- deprec_arg + + } else { + warning( + "Argument `", deprec_name, "` will be ignored in favour of argument `", + new_name, "`." + ) + } + + message( + "Argument `", deprec_name, "` is deprecated as of version ", version, ";", + " use `", new_name, "` instead." + ) + } + + new_arg +} + + +# Utility function to replace missing attribute with default value +default <- function(value, default) { + if (is.null(value)) { + return(default) + } else { + return(value) + } +} + + +# Drop dimensions of length 1 except those that are selected by name +drop_omit <- function(x, omit_dim) { + dims <- dim(x) + dims_check <- dims == 1 & !(names(dims) %in% omit_dim) + + abind::adrop(x, dims_check) +} + + +# Function to get list names recursively +names_recursively <- function(x) { + + # Standard names of list elements + y <- names(x) + + # Recursion for list elements + y_append <- sapply(x, function(y) { # nolint:undesirable_function_linter. + if (is.list(y)) + return(names_recursively(y)) + }) %>% unlist(use.names = FALSE) + + # Only return unique elements + append(y, y_append) %>% + unique() %>% + return() +} + + +# colorize variable name for messages, warning, stop +col_var <- function(x) { + col_blue <- "\u001b[34m" + unset_col <- "\u001b[0m" + paste0(col_blue, x, unset_col) +} + + +# Function to get gitlab commit hash of repository path. +# Via include_url = TRUE url + hash is returned to be called via webbrowser. +get_git_urlhash <- function(path = ".", + include_url = TRUE, + raise_error = TRUE) { + + # List of bash commands + inner_commands <- paste0( + # Filter .git in URL + "git='.git';", + + # Get origin URL (with .git at ending, not legit for URL) + "orig_url=$(git config --get remote.origin.url);", + + # Get commit hash + "hash=$(git rev-parse HEAD);", + + # Some URLs include a cluster extension in before real URL starting with @ + "if [[ $orig_url == *'@'* ]]; then ", + "orig_url=https://${orig_url##*@}; fi;", + + # Check for github or gitlab + "if [[ $orig_url == *'github'* ]]; then ", + + # Concatenate URL and hash if required. Github has slightly different + # routing. + "url=${orig_url%%$git*}/tree/${hash}; else ", + "url=${orig_url%%$git*}/-/tree/${hash}; fi;", + + # Replace ":" in URLs if SSH is used to clone repository + "url=${url//de:/de/}; ", + "url=${url//com:/com/}; ", + ifelse(include_url, "echo ${url};", "echo ${hash};") + ) + + # System call + out <- processx::run(command = "bash", + args = c("-c", inner_commands), + wd = path, + cleanup_tree = TRUE, + error_on_status = FALSE) + + # Check output, ignore errors + if (out$stderr == "") { + return(sub("\n", "", out$stdout)) + } else { + + if (raise_error) { + stop("For path \"", path, "\": ", out$stderr, call. = FALSE) + } else { + warning("For path \"", path, "\": ", out$stderr, call. = FALSE) + return("") + } + } +} + + +# Function checks and returns whether SLURM is available +is_slurm_available <- function() { + processx::run(command = "sh", + args = c("-c", "sinfo"), + error_on_status = FALSE) %>% + .$status == 0 %>% + return() +} + + +# file_type options supported by read_io +supported_types <- c("raw", "clm", "meta") + + +# Avoid note for "."... +utils::globalVariables(".") # nolint:undesirable_function_linter diff --git a/R/write_config.R b/R/write_config.R index 49bf473..114628e 100644 --- a/R/write_config.R +++ b/R/write_config.R @@ -5,14 +5,15 @@ #' file `"config_*.json"`. Each row in the tibble corresponds to a model run. #' The generated `"config_*.json"` is based on a js file (e.g. `"lpjml_*.js"`). #' -#' @param params A tibble in a defined format (see details). +#' @param x A tibble in a defined format (see details). #' #' @param model_path Character string providing the path to LPJmL #' (equal to `LPJROOT` environment variable). #' -#' @param output_path Character string providing path where an output, a restart -#' and a configuration folder are created to store respective data. If `NULL`, -#' `model_path` is used. +#' @param sim_path Character string defining path where all simulation data +#' are written. Also an output, a restart and a configuration folder are +#' created in `sim_path` to store respective data. If `NULL`, `model_path` is +#' used. #' #' @param output_list Character vector containing the `"id"` of outputvars. #' If defined, only these defined outputs will be written. Otherwise, all @@ -37,14 +38,20 @@ #' @param debug logical If `TRUE`, the inner parallelization is switched off #' to enable tracebacks and all types of error messages. Defaults to `FALSE`. #' +#' @param params Argument is deprecated as of version 1.0; use x +#' instead. +#' +#' @param output_path Argument is deprecated as of version 1.0; use sim_path +#' instead. +#' #' @return \link[tibble]{tibble} with at least one column named `"sim_name"`. #' Run parameters `"order"` and `"dependency"` are included if defined in -#' `params`. \link[tibble]{tibble} in this format is required for +#' `x`. \link[tibble]{tibble} in this format is required for #' [`submit_lpjml()`]. #' #' @details #' -#' Supply a \link[tibble]{tibble} for `params`, in which each row represents +#' Supply a \link[tibble]{tibble} for `x`, in which each row represents #' a configuration (config) for an LPJmL simulation. \cr #' Here a config is referred to as the precompiled `"lpjml.js"` file (or file #' name provided as `js_filename` argument), which links to all other @@ -157,7 +164,7 @@ #' ``` #' #' ### In short -#' * `write_config()` creates subdirectories within the `output_path` directory +#' * `write_config()` creates subdirectories within the `sim_path` directory #' * `"./configurations"` to store the config files. #' * `"./output"` to store the output within subdirectories for each #' `sim_name`. @@ -181,7 +188,7 @@ #' library(lpjmlkit) #' #' model_path <- "./LPJmL_internal" -#' output_path <-"./my_runs" +#' sim_path <-"./my_runs" #' #' #' # Basic usage @@ -194,9 +201,9 @@ #' ) #' #' config_details <- write_config( -#' params = my_params, +#' x = my_params, #' model_path = model_path, -#' output_path = output_path +#' sim_path = sim_path #' ) #' #' config_details @@ -214,9 +221,9 @@ #' ) #' #' config_details <- write_config( -#' params = my_params, +#' x = my_params, #' model_path = model_path, -#' output_path = output_path +#' sim_path = sim_path #' ) #' #' config_details @@ -236,9 +243,9 @@ #' ) #' #' config_details <- write_config( -#' params = my_params, +#' x = my_params, #' model_path = model_path, -#' output_path = output_path +#' sim_path = sim_path #' ) #' #' config_details @@ -253,29 +260,40 @@ #' @importFrom foreach "%dopar%" #' @importFrom magrittr %>% #' @export -write_config <- function(params, +write_config <- function(x, model_path, - output_path = NULL, + sim_path = NULL, output_list = c(), output_list_timestep = "annual", output_format = "raw", js_filename = "lpjml.js", parallel_cores = 4, - debug = FALSE) { + debug = FALSE, + params = NULL, + output_path = NULL) { + + + # Deprecate argument params + if (missing("x")) x <- NULL + x <- deprecate_arg(new_arg = x, + deprec_arg = params, + version = "1.0.0") # Check if model_path is valid if (!dir.exists(model_path)) { stop("Folder of model_path \"", model_path, "\" does not exist!") } - # If output_path is not supplied use model_path as output_path - if (is.null(output_path)) { - output_path <- model_path - } + # Deprecate argument output_path + sim_path <- deprecate_arg(new_arg = sim_path, + deprec_arg = output_path, + version = "1.0.0") + + if (is.null(sim_path)) sim_path <- model_path # Create configurations directory to store config_*.json files dir.create( - paste(ifelse(is.null(output_path), model_path, output_path), + paste(ifelse(is.null(sim_path), model_path, sim_path), "configurations", sep = "/"), recursive = TRUE, @@ -283,14 +301,14 @@ write_config <- function(params, ) # Check if dependency exists but not order. Calculate order automatically. - if ("dependency" %in% colnames(params) && !"order" %in% colnames(params)) { - params <- get_order(params) + if ("dependency" %in% colnames(x) && !"order" %in% colnames(x)) { + x <- get_order(x) } commit_hash <- get_git_urlhash(path = model_path, raise_error = FALSE) # Call function row-wise on dataframe/tibble. - # Initiate run/SLURM parameters. If not defined by params tibble, NA columns + # Initiate run/SLURM parameters. If not defined by x tibble, NA columns # are removed at the end of this function. config_tmp <- tibble::tibble(sim_name = NA, order = NA, @@ -315,7 +333,7 @@ write_config <- function(params, row_id <- NULL # Parallel foreach param row with row binding. - job_details <- foreach::foreach(row_id = seq_len(nrow(params)), + job_details <- foreach::foreach(row_id = seq_len(nrow(x)), .combine = "rbind", .packages = "tibble", .errorhandling = "stop" @@ -323,9 +341,9 @@ write_config <- function(params, # Write a single configuration tryCatch({ - write_single_config(params = params[row_id, ], + write_single_config(x = x[row_id, ], model_path = model_path, - output_path = output_path, + sim_path = sim_path, output_format = output_format, output_list = output_list, output_list_timestep = output_list_timestep, @@ -371,10 +389,10 @@ write_config <- function(params, # Run without parallelization to allow debugging of write_single_config() job_details <- config_tmp - for (row_id in seq_len(dim(params)[1])) { - job_details[row_id, ] <- write_single_config(params[row_id, ], + for (row_id in seq_len(dim(x)[1])) { + job_details[row_id, ] <- write_single_config(x[row_id, ], model_path = model_path, - output_path = output_path, + sim_path = sim_path, output_format = ( output_format), output_list = output_list, @@ -389,7 +407,7 @@ write_config <- function(params, # Return job_details with sim_names as well as config_names. - # "order" and "dependency" are only returned if defined in the params. + # "order" and "dependency" are only returned if defined in x. if (any(is.na(job_details$order)) || all(is.na(job_details$dependency))) { job_details$order <- NULL @@ -412,9 +430,9 @@ write_config <- function(params, # config.json file. # mutate* functions are applied to change params/keys after provided # data frame/tibble. -write_single_config <- function(params, +write_single_config <- function(x, model_path, - output_path, + sim_path, output_list, output_list_timestep, output_format, @@ -426,48 +444,48 @@ write_single_config <- function(params, # Read json file without simplification (to vector) to avoid destroying the # original json structure (important to be readable for LPJmL). # Save it as config.json (as a convention). - if (is.null(params[["sim_name"]])) { - stop("A sim_name is missing in params.") + if (is.null(x[["sim_name"]])) { + stop("A sim_name is missing in `x`.") } - config_tmp$sim_name <- params[["sim_name"]] + config_tmp$sim_name <- x[["sim_name"]] # Check if order and dependency is defined to set sequence of dependent runs. # Include error catching for missing order or dependency if other is defined. - if (!is.null(params[["order"]])) { + if (!is.null(x[["order"]])) { - if (params[["order"]] == 1) { + if (x[["order"]] == 1) { from_restart <- FALSE - config_tmp$order <- params[["order"]] + config_tmp$order <- x[["order"]] - } else if (params[["order"]] > 1) { + } else if (x[["order"]] > 1) { from_restart <- TRUE - config_tmp$order <- params[["order"]] + config_tmp$order <- x[["order"]] - if (is.null(params[["dependency"]])) { - stop(params[["sim_name"]], "'s field dependency is missing!") + if (is.null(x[["dependency"]])) { + stop(x[["sim_name"]], "'s field dependency is missing!") } else { - config_tmp$dependency <- params[["dependency"]] + config_tmp$dependency <- x[["dependency"]] } } else { - stop(params[["sim_name"]], "'s order is not valid!") + stop(x[["sim_name"]], "'s order is not valid!") } } else { from_restart <- FALSE } - if (any(slurm_args %in% colnames(params))) { - config_tmp[slurm_args[slurm_args %in% colnames(params)]] <- ( - params[slurm_args[slurm_args %in% colnames(params)]] + if (any(slurm_args %in% colnames(x))) { + config_tmp[slurm_args[slurm_args %in% colnames(x)]] <- ( + x[slurm_args[slurm_args %in% colnames(x)]] ) } # Check if macros defined use option -D for filtering. # If macros are set false then ignore but use names to sort from parameters. - if (any(grepl("^-D", colnames(params)))) { - macro <- unlist(params[grepl("^-D", colnames(params))]) + if (any(grepl("^-D", colnames(x)))) { + macro <- unlist(x[grepl("^-D", colnames(x))]) macro_name <- names(macro) if (length(which(macro)) == 0) { @@ -487,17 +505,18 @@ write_single_config <- function(params, js_filename = js_filename, macro = macro) %>% - # Replace output and restart params (paths, output format & which outputs) - mutate_config_output(params = params, - output_path = output_path, + # Replace output and restart parameters (paths, output format & which + # outputs) + mutate_config_output(params = x, + sim_path = sim_path, output_format = output_format, output_list = output_list, output_timestep = output_list_timestep, dir_create = !testthat::is_testing()) %>% - # Insert parameters/keys from params data frame. + # Insert parameters/keys from x. # Columns as keys and rows as values (values, vectors possible). - mutate_config_param(params = params, + mutate_config_param(params = x, exclude_macros = macro_name, commit_hash = commit_hash, slurm_args = slurm_args) @@ -508,10 +527,10 @@ write_single_config <- function(params, # Additional jsonlite::write_json arguments are very important to be # readable in LPJmL (type conservation/hinting). jsonlite::write_json( - path = paste0(output_path, + path = paste0(sim_path, "/configurations/", "config_", - params[["sim_name"]], + x[["sim_name"]], ".json"), x = tmp_json, auto_unbox = TRUE, @@ -559,14 +578,14 @@ parse_config <- function(path, # Output format (raw, clm cdf), output selection, output path, restart_path. mutate_config_output <- function(x, # nolint:cyclocomp_linter. params, - output_path, + sim_path, output_format, output_list, output_timestep, dir_create = FALSE) { # Concatenate output path and create folder if set - opath <- paste(output_path, "output", params[["sim_name"]], "", sep = "/") + opath <- paste(sim_path, "output", params[["sim_name"]], "", sep = "/") if (dir_create) dir.create(opath, recursive = TRUE, showWarnings = FALSE) if (is.null(output_list) || x[["nspinup"]] > 500) { @@ -717,7 +736,7 @@ mutate_config_output <- function(x, # nolint:cyclocomp_linter. } # Replace restart paths if write restart is set - rpath <- paste(output_path, "restart", params[["sim_name"]], "", sep = "/") + rpath <- paste(sim_path, "restart", params[["sim_name"]], "", sep = "/") if (dir_create) dir.create(rpath, recursive = TRUE, showWarnings = FALSE) @@ -732,7 +751,7 @@ mutate_config_output <- function(x, # nolint:cyclocomp_linter. # If dependency is defined start from restart file of dependency sim_name x[["restart_filename"]] <- paste0(ifelse(is.na(params[["dependency"]]), rpath, - paste(output_path, + paste(sim_path, "restart", params[["dependency"]], "", @@ -990,31 +1009,3 @@ get_order <- function(x) { dplyr::mutate(order = get_order_each(., .data$sim_name, .data$dependency)) %>% # nolint return() } - - -# colorize variable name for messages, warning, stop -col_var <- function(x) { - col_blue <- "\u001b[34m" - unset_col <- "\u001b[0m" - paste0(col_blue, x, unset_col) -} - - - -# Function to get names recursively -names_recursively <- function(x) { - - # Standard names of list elements - y <- names(x) - - # Recursion for list elements - y_append <- sapply(x, function(y) { # nolint:undesirable_function_linter. - if (is.list(y)) - return(names_recursively(y)) - }) %>% unlist(use.names = FALSE) - - # Only return unique elements - append(y, y_append) %>% - unique() %>% - return() -} diff --git a/README.md b/README.md index 0538d90..5cc9e4d 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ # Toolkit for basic LPJmL handling -R package **lpjmlkit**, version **0.8.5** +R package **lpjmlkit**, version **1.0.0** [![CRAN status](https://www.r-pkg.org/badges/version/lpjmlkit)](https://cran.r-project.org/package=lpjmlkit) [![R build status](https://github.com/PIK-LPJmL/lpjmlkit/workflows/check/badge.svg)](https://github.com/PIK-LPJmL/lpjmlkit/actions) [![codecov](https://codecov.io/gh/PIK-LPJmL/lpjmlkit/branch/master/graph/badge.svg)](https://app.codecov.io/gh/PIK-LPJmL/lpjmlkit) [![r-universe](https://pik-piam.r-universe.dev/badges/lpjmlkit)](https://pik-piam.r-universe.dev/builds) @@ -76,7 +76,7 @@ In case of questions / problems please contact Jannes Breier . +Breier J, Ostberg S, Wirth S, Minoli S, Stenzel F, Müller C (2023). _lpjmlkit: Toolkit for basic LPJmL handling_. R package version 1.0.0, . A BibTeX entry for LaTeX users is @@ -85,7 +85,7 @@ A BibTeX entry for LaTeX users is title = {lpjmlkit: Toolkit for basic LPJmL handling}, author = {Jannes Breier and Sebastian Ostberg and Stephen Björn Wirth and Sara Minoli and Fabian Stenzel and Christoph Müller}, year = {2023}, - note = {R package version 0.8.5}, + note = {R package version 1.0.0}, url = {https://github.com/PIK-LPJmL/lpjmlkit}, } ``` diff --git a/man/calc_cellarea.Rd b/man/calc_cellarea.Rd index 133597d..7e68000 100644 --- a/man/calc_cellarea.Rd +++ b/man/calc_cellarea.Rd @@ -6,8 +6,8 @@ \usage{ calc_cellarea( x, - res_lon = 0.5, - res_lat = res_lon, + cellsize_lon = 0.5, + cellsize_lat = cellsize_lon, earth_radius = 6371000.785, return_unit = "m2" ) @@ -17,12 +17,12 @@ calc_cellarea( variable \code{"grid"} (\code{"LPJGRID"}) or a vector of cell-center latitude coordinates in degrees.} -\item{res_lon}{Grid resolution in longitude direction in degrees +\item{cellsize_lon}{Grid resolution in longitude direction in degrees (default: \code{0.5}). If \code{x} is an LPJmLData object the resolution will be taken from the meta data included in \code{x} if available.} -\item{res_lat}{Grid resolution in latitude direction in degrees (default: -same as \code{res_lon}). If \code{x} is an LPJmLData object the resolution will be +\item{cellsize_lat}{Grid resolution in latitude direction in degrees (default: +same as \code{cellsize_lon}). If \code{x} is an LPJmLData object the resolution will be taken from the meta data included in \code{x} if available.} \item{earth_radius}{Radius of the sphere (in \eqn{m}) used to calculate the diff --git a/man/check_config.Rd b/man/check_config.Rd index a816a19..5ef7d83 100644 --- a/man/check_config.Rd +++ b/man/check_config.Rd @@ -7,9 +7,10 @@ check_config( x, model_path = ".", - output_path = NULL, + sim_path = NULL, return_output = FALSE, - raise_error = FALSE + raise_error = FALSE, + output_path = NULL ) } \arguments{ @@ -20,8 +21,9 @@ character vector providing the config file names \item{model_path}{Character string providing the path to LPJmL (equal to \code{LPJROOT} environment variable). Defaults to ".".} -\item{output_path}{Character string providing path where an output, a restart -and a configuration folder are created. If \code{NULL}, \code{model_path} is used.} +\item{sim_path}{Character string defining path where all simulation data are +written, including output, restart and configuration files. If \code{NULL}, +\code{model_path} is used. See also \link{write_config}} \item{return_output}{Parameter affecting the output. If \code{FALSE} print stdout/stderr message. If \code{TRUE}, return the result of the check. @@ -29,6 +31,9 @@ Defaults to \code{FALSE}.} \item{raise_error}{Logical. Whether to raise an error if sub-process has non-zero exit status. Defaults to \code{FALSE}.} + +\item{output_path}{Argument is deprecated as of version 1.0; use sim_path +instead.} } \value{ NULL. @@ -44,7 +49,7 @@ library(tibble) library(lpjmlkit) model_path <- "./LPJmL_internal" -output_path <-"./my_runs" +sim_path <-"./my_runs" # Basic usage @@ -57,14 +62,14 @@ my_params <- tibble( ) config_details <- write_config( - params = my_params, + x = my_params, model_path = model_path, - output_path = output_path + sim_path = sim_path ) check_config(x = config_details, model_path = model_path, - output_path = output_path, + sim_path = sim_path, return_output = FALSE ) } diff --git a/man/run_lpjml.Rd b/man/run_lpjml.Rd index eef4d43..88b66b7 100644 --- a/man/run_lpjml.Rd +++ b/man/run_lpjml.Rd @@ -7,10 +7,11 @@ run_lpjml( x, model_path = ".", - output_path = NULL, + sim_path = NULL, parallel_cores = 1, write_stdout = FALSE, - raise_error = TRUE + raise_error = TRUE, + output_path = NULL ) } \arguments{ @@ -24,9 +25,9 @@ multiple generated configuration file(s).} \item{model_path}{Character string providing the path to LPJmL (equal to \code{LPJROOT} environment variable). Defaults to "."} -\item{output_path}{Character string providing path where an output, a restart -and a configuration folder are created to store respective data. If \code{NULL}, -\code{model_path} is used.} +\item{sim_path}{Character string defining path where all simulation data are +written, including output, restart and configuration files. If \code{NULL}, +\code{model_path} is used. See also \link{write_config}} \item{parallel_cores}{Integer defining the number of available CPU cores/nodes for parallelization. Defaults to \code{1} (no parallelization). @@ -39,6 +40,9 @@ SLURM job \code{write_stdout} is automatically set to \code{TRUE}.} \item{raise_error}{Logical. Whether to raise an error if sub-process has non-zero exit status. Defaults to \code{TRUE}.} + +\item{output_path}{Argument is deprecated as of version 1.0; use sim_path +instead.} } \value{ See \code{x}, extended by columns \code{"type"}, \code{"job_id"} and \code{"status"}. @@ -81,7 +85,7 @@ library(lpjmlkit) library(tibble) model_path <- "./LPJmL_internal" -output_path <-"./my_runs" +sim_path <-"./my_runs" # Basic usage my_params1 <- tibble( @@ -94,12 +98,12 @@ my_params1 <- tibble( new_phenology = c(TRUE, FALSE) ) -config_details1 <- write_config(my_params1, model_path, output_path) +config_details1 <- write_config(my_params1, model_path, sim_path) run_details1 <- run_lpjml( x = config_details1, model_path = model_path, - output_path = output_path + sim_path = sim_path ) run_details1 @@ -119,9 +123,9 @@ my_params2 <- tibble( dependency = c(NA, "scen1_spinup") ) -config_details2 <- write_config(my_params2, model_path, output_path) +config_details2 <- write_config(my_params2, model_path, sim_path) -run_details2 <- run_lpjml(config_details2, model_path, output_path) +run_details2 <- run_lpjml(config_details2, model_path, sim_path) run_details2 # sim_name order dependency type job_id status @@ -136,21 +140,21 @@ run_details2 <- tibble( random_seed = as.integer(c(1, 42)), dependency = c(NA, "scen1_spinup") ) \%>\% - write_config(model_path, output_path) \%>\% - run_lpjml(model_path, output_path) + write_config(model_path, sim_path) \%>\% + run_lpjml(model_path, sim_path) # Shortcut approaches run_details3 <- run_lpjml( x = "./config_scen1_transient.json", model_path = model_path, - output_path = output_path + sim_path = sim_path ) run_details4 <- run_lpjml( c("./config_scen1_spinup.json", "./config_scen1_transient.json"), model_path, - output_path + sim_path ) } diff --git a/man/submit_lpjml.Rd b/man/submit_lpjml.Rd index c88ad0c..0a7a684 100644 --- a/man/submit_lpjml.Rd +++ b/man/submit_lpjml.Rd @@ -7,13 +7,14 @@ submit_lpjml( x, model_path, - output_path = NULL, + sim_path = NULL, group = "lpjml", sclass = "short", ntasks = 256, wtime = "", blocking = "", - no_submit = FALSE + no_submit = FALSE, + output_path = NULL ) } \arguments{ @@ -27,9 +28,9 @@ multiple generated config file(s).} \item{model_path}{Character string providing the path to LPJmL (equal to \code{LPJROOT} environment variable).} -\item{output_path}{Character string providing path where an output, a restart -and a configuration folder are created to store respective data. If \code{NULL}, -\code{model_path} is used.} +\item{sim_path}{Character string defining path where all simulation data are +written, including output, restart and configuration files. If \code{NULL}, +\code{model_path} is used. See also \link{write_config}} \item{group}{Character string defining the user group for which the job is submitted. Defaults to \code{"lpjml"}.} @@ -53,6 +54,9 @@ information at \url{https://www.pik-potsdam.de} and \item{no_submit}{Logical. Set to \code{TRUE} to test if \code{x} set correctly or \code{FALSE} to actually submit job to SLURM.} + +\item{output_path}{Argument is deprecated as of version 1.0; use sim_path +instead.} } \value{ See \code{x}, extended by columns \code{"type"}, \code{"job_id"} and \code{"status"}. @@ -107,7 +111,7 @@ library(lpjmlkit) library(tibble) model_path <- "./LPJmL_internal" -output_path <-"./my_runs" +sim_path <-"./my_runs" # Basic usage @@ -119,12 +123,12 @@ my_params <- tibble( new_phenology = c(TRUE, FALSE) ) -config_details <- write_config(my_params, model_path, output_path) +config_details <- write_config(my_params, model_path, sim_path) run_details <- submit_lpjml( x = config_details, model_path = model_path, - output_path = output_path + sim_path = sim_path ) run_details @@ -143,9 +147,9 @@ my_params <- tibble( wtime = c("8:00:00", "4:00:00"), ) -config_details2 <- write_config(my_params2, model_path, output_path) +config_details2 <- write_config(my_params2, model_path, sim_path) -run_details2 <- submit_lpjml(config_details2, model_path, output_path) +run_details2 <- submit_lpjml(config_details2, model_path, sim_path) run_details2 # sim_name order dependency wtime type job_id status @@ -161,21 +165,21 @@ run_details <- tibble( dependency = c(NA, "scen1_spinup"), wtime = c("8:00:00", "4:00:00"), ) \%>\% - write_config(model_path, output_path) \%>\% - submit_lpjml(model_path, output_path) + write_config(model_path, sim_path) \%>\% + submit_lpjml(model_path, sim_path) # Shortcut approach run_details <- submit_lpjml( x = "./config_scen1_transient.json", model_path = model_path, - output_path = output_path + sim_path = sim_path ) run_details <- submit_lpjml( c("./config_scen1_spinup.json", "./config_scen1_transient.json"), model_path, - output_path + sim_path ) } diff --git a/man/write_config.Rd b/man/write_config.Rd index 914128b..a3c241f 100644 --- a/man/write_config.Rd +++ b/man/write_config.Rd @@ -5,26 +5,29 @@ \title{Write LPJmL config files (JSON)} \usage{ write_config( - params, + x, model_path, - output_path = NULL, + sim_path = NULL, output_list = c(), output_list_timestep = "annual", output_format = "raw", js_filename = "lpjml.js", parallel_cores = 4, - debug = FALSE + debug = FALSE, + params = NULL, + output_path = NULL ) } \arguments{ -\item{params}{A tibble in a defined format (see details).} +\item{x}{A tibble in a defined format (see details).} \item{model_path}{Character string providing the path to LPJmL (equal to \code{LPJROOT} environment variable).} -\item{output_path}{Character string providing path where an output, a restart -and a configuration folder are created to store respective data. If \code{NULL}, -\code{model_path} is used.} +\item{sim_path}{Character string defining path where all simulation data +are written. Also an output, a restart and a configuration folder are +created in \code{sim_path} to store respective data. If \code{NULL}, \code{model_path} is +used.} \item{output_list}{Character vector containing the \code{"id"} of outputvars. If defined, only these defined outputs will be written. Otherwise, all @@ -48,11 +51,17 @@ parallelization. Defaults to \code{4}.} \item{debug}{logical If \code{TRUE}, the inner parallelization is switched off to enable tracebacks and all types of error messages. Defaults to \code{FALSE}.} + +\item{params}{Argument is deprecated as of version 1.0; use x +instead.} + +\item{output_path}{Argument is deprecated as of version 1.0; use sim_path +instead.} } \value{ \link[tibble]{tibble} with at least one column named \code{"sim_name"}. Run parameters \code{"order"} and \code{"dependency"} are included if defined in -\code{params}. \link[tibble]{tibble} in this format is required for +\code{x}. \link[tibble]{tibble} in this format is required for \code{\link[=submit_lpjml]{submit_lpjml()}}. } \description{ @@ -62,7 +71,7 @@ file \code{"config_*.json"}. Each row in the tibble corresponds to a model run. The generated \code{"config_*.json"} is based on a js file (e.g. \code{"lpjml_*.js"}). } \details{ -Supply a \link[tibble]{tibble} for \code{params}, in which each row represents +Supply a \link[tibble]{tibble} for \code{x}, in which each row represents a configuration (config) for an LPJmL simulation. \cr Here a config is referred to as the precompiled \code{"lpjml.js"} file (or file name provided as \code{js_filename} argument), which links to all other @@ -174,7 +183,7 @@ my_params2 \subsection{In short}{ \itemize{ -\item \code{write_config()} creates subdirectories within the \code{output_path} directory +\item \code{write_config()} creates subdirectories within the \code{sim_path} directory \itemize{ \item \code{"./configurations"} to store the config files. \item \code{"./output"} to store the output within subdirectories for each @@ -202,7 +211,7 @@ library(tibble) library(lpjmlkit) model_path <- "./LPJmL_internal" -output_path <-"./my_runs" +sim_path <-"./my_runs" # Basic usage @@ -215,9 +224,9 @@ my_params <- tibble( ) config_details <- write_config( - params = my_params, + x = my_params, model_path = model_path, - output_path = output_path + sim_path = sim_path ) config_details @@ -235,9 +244,9 @@ my_params <- tibble( ) config_details <- write_config( - params = my_params, + x = my_params, model_path = model_path, - output_path = output_path + sim_path = sim_path ) config_details @@ -256,9 +265,9 @@ my_params <- tibble( ) config_details <- write_config( - params = my_params, + x = my_params, model_path = model_path, - output_path = output_path + sim_path = sim_path ) config_details diff --git a/tests/testthat/test-calc_cellarea.R b/tests/testthat/test-calc_cellarea.R index b8bff02..99723c8 100644 --- a/tests/testthat/test-calc_cellarea.R +++ b/tests/testthat/test-calc_cellarea.R @@ -5,27 +5,27 @@ test_that("Calculate cell area", { testthat::expect_type(calc_cellarea(lats), "double") testthat::expect_length(calc_cellarea(lats), length(lats)) - # Vector > 1 not supported for res_lon + # Vector > 1 not supported for cellsize_lon testthat::expect_warning( - calc_cellarea(lats, res_lon = c(0.5, 0.5)), - "res_lon has length" + calc_cellarea(lats, cellsize_lon = c(0.5, 0.5)), + "cellsize_lon has length" ) - # Non-supported type for res_lon + # Non-supported type for cellsize_lon testthat::expect_error( - calc_cellarea(lats, res_lon = NA), + calc_cellarea(lats, cellsize_lon = NA), "Invalid longitude grid" ) - # Vector > 1 not supported for res_lat + # Vector > 1 not supported for cellsize_lat testthat::expect_warning( - calc_cellarea(lats, res_lat = c(0.5, 0.5)), - "res_lat has length" + calc_cellarea(lats, cellsize_lat = c(0.5, 0.5)), + "cellsize_lat has length" ) - # Non-supported type for res_lat + # Non-supported type for cellsize_lat testthat::expect_error( - calc_cellarea(lats, res_lat = NA), + calc_cellarea(lats, cellsize_lat = NA), "Invalid latitude grid" ) @@ -62,14 +62,14 @@ test_that("Calculate cell area with LPJmLData object and grid attribute", { as.vector(cell_area2[match(names(cell_area), output$grid$data)]) ) - # Test that function arguments res_lon and res_lat are ignored for LPJmLData + # Test that function arguments cellsize_lon and cellsize_lat are ignored for LPJmLData testthat::expect_warning( - calc_cellarea(output, res_lon = 0.25), - "Using .+ instead of supplied res_lon" + calc_cellarea(output, cellsize_lon = 0.25), + "Using .+ instead of supplied cellsize_lon" ) testthat::expect_warning( - calc_cellarea(output, res_lat = 0.25), - "Using .+ instead of supplied res_lat" + calc_cellarea(output, cellsize_lat = 0.25), + "Using .+ instead of supplied cellsize_lat" ) # Test alternative dim_order diff --git a/tests/testthat/test-write_config.R b/tests/testthat/test-write_config.R index 5a8846f..158f84c 100644 --- a/tests/testthat/test-write_config.R +++ b/tests/testthat/test-write_config.R @@ -23,9 +23,9 @@ testthat::test_that("write correct config with dot syntax", { # Test main function of write_config since write_config is hard to test tmp_objects <- write_single_config( - params = test_params, + x = test_params, model_path = "../testdata", - output_path = "../testdata", + sim_path = "../testdata", output_list = c(), output_list_timestep = "annual", output_format = "clm", @@ -55,9 +55,9 @@ testthat::test_that("write correct config with dot syntax", { test_params["test_param"] <- TRUE testthat::expect_error( write_single_config( - params = test_params, + x = test_params, model_path = "../testdata", - output_path = "../testdata", + sim_path = "../testdata", output_list = c(), output_list_timestep = "annual", output_format = "clm", @@ -73,9 +73,9 @@ testthat::test_that("write correct config with dot syntax", { test_params["sim_name.landuse"] <- TRUE testthat::expect_error( write_single_config( - params = test_params, + x = test_params, model_path = "../testdata", - output_path = "../testdata", + sim_path = "../testdata", output_list = c(), output_list_timestep = "annual", output_format = "clm", @@ -110,9 +110,9 @@ testthat::test_that("write correct config with common list syntax", { # Test main function of write_config since write_config is hard to test tmp_objects <- write_single_config( - params = test_params, + x = test_params, model_path = "../testdata", - output_path = "../testdata", + sim_path = "../testdata", output_list = c(), output_list_timestep = "annual", output_format = "clm", @@ -129,9 +129,9 @@ testthat::test_that("write correct config with common list syntax", { test_params["test_param$check"] <- TRUE expect_error( write_single_config( - params = test_params, + x = test_params, model_path = "../testdata", - output_path = "../testdata", + sim_path = "../testdata", output_list = c(), output_list_timestep = "annual", output_format = "clm", @@ -147,9 +147,9 @@ testthat::test_that("write correct config with common list syntax", { test_params["sim_name$landuse"] <- TRUE testthat::expect_error( write_single_config( - params = test_params, + x = test_params, model_path = "../testdata", - output_path = "../testdata", + sim_path = "../testdata", output_list = c(), output_list_timestep = "annual", output_format = "clm", @@ -165,9 +165,9 @@ testthat::test_that("write correct config with common list syntax", { test_params["sim_name"] <- NULL testthat::expect_error( write_single_config( - params = test_params, + x = test_params, model_path = "../testdata", - output_path = "../testdata", + sim_path = "../testdata", output_list = c(), output_list_timestep = "annual", output_format = "clm", @@ -175,7 +175,7 @@ testthat::test_that("write correct config with common list syntax", { config_tmp = test_tmp, slurm_args = slurm_args ), - "A sim_name is missing in params." + "A sim_name is missing in" ) test_params["sim_name"] <- "spinup_pnv" @@ -185,9 +185,9 @@ testthat::test_that("write correct config with common list syntax", { test_params["dependency"] <- NULL testthat::expect_error( write_single_config( - params = test_params, + x = test_params, model_path = "../testdata", - output_path = "../testdata", + sim_path = "../testdata", output_list = c(), output_list_timestep = "annual", output_format = "clm", @@ -202,9 +202,9 @@ testthat::test_that("write correct config with common list syntax", { test_params["order"] <- -1 testthat::expect_error( write_single_config( - params = test_params, + x = test_params, model_path = "../testdata", - output_path = "../testdata", + sim_path = "../testdata", output_list = c(), output_list_timestep = "annual", output_format = "clm", @@ -220,9 +220,9 @@ testthat::test_that("write correct config with common list syntax", { test_params["restart_filename"] <- NULL testthat::expect_warning( write_single_config( - params = test_params, + x = test_params, model_path = "../testdata", - output_path = "../testdata", + sim_path = "../testdata", output_list = c(), output_list_timestep = "annual", output_format = "clm", @@ -239,9 +239,9 @@ testthat::test_that("write correct config with common list syntax", { test_params["dependency"] <- "spinup_spinup" testthat::expect_error( write_single_config( - params = test_params, + x = test_params, model_path = "../testdata", - output_path = "../testdata", + sim_path = "../testdata", output_list = c("irrig", "irrig"), output_list_timestep = c("subannual", "subannual"), output_format = "clm", @@ -256,9 +256,9 @@ testthat::test_that("write correct config with common list syntax", { # Non matching length if output_list and output_list_timestep testthat::expect_error( write_single_config( - params = test_params, + x = test_params, model_path = "../testdata", - output_path = "../testdata", + sim_path = "../testdata", output_list = c("irrig"), output_list_timestep = c("annual", "annual"), output_format = "cdf", @@ -272,9 +272,9 @@ testthat::test_that("write correct config with common list syntax", { # Non valid output testthat::expect_warning( write_single_config( - params = test_params, + x = test_params, model_path = "../testdata", - output_path = "../testdata", + sim_path = "../testdata", output_list = c("soil_health"), output_list_timestep = c("annual"), output_format = "cdf", @@ -290,9 +290,9 @@ testthat::test_that("write correct config with common list syntax", { test_params["wtime"] <- "10:00:00" test_params["-DMY_MACRO"] <- TRUE tmp_objects <- write_single_config( - params = test_params, + x = test_params, model_path = "../testdata", - output_path = "../testdata", + sim_path = "../testdata", output_list = c(), output_list_timestep = "annual", output_format = "clm", @@ -321,9 +321,9 @@ testthat::test_that("include non output defined outputvars", { # test main function of write_config since write_config is hard to test tmp_objects <- write_single_config( - params = test_params, + x = test_params, model_path = "../testdata", - output_path = "../testdata", + sim_path = "../testdata", output_list = c("grid", "irrig"), output_list_timestep = "annual", output_format = "clm", diff --git a/tests/testthat/test_utils.R b/tests/testthat/test_utils.R new file mode 100644 index 0000000..a47446e --- /dev/null +++ b/tests/testthat/test_utils.R @@ -0,0 +1,49 @@ +test_that("Test argument deprecation", { + + # Set values + new_arg <- NULL + deprec_arg <- "test" + + # Test if deprec_arg replaces new_arg + new_arg <- suppressMessages( + deprecate_arg( + new_arg = new_arg, + deprec_arg = deprec_arg + ) + ) + testthat::expect_equal(new_arg, deprec_arg) + + new_arg <- NULL + # Test for deprecation message + testthat::expect_message( + deprecate_arg( + new_arg = new_arg, + deprec_arg = deprec_arg + ), + "is deprecated as of version" + ) + + # Test for prior usage of new_arg + new_arg <- "better_test" + new_arg <- suppressMessages( + suppressWarnings( + deprecate_arg( + new_arg = new_arg, + deprec_arg = deprec_arg + ) + ) + ) + testthat::expect_equal(new_arg, new_arg) + + # Test corresponding message + new_arg <- "better_test" + suppressMessages( + testthat::expect_warning( + deprecate_arg( + new_arg = new_arg, + deprec_arg = deprec_arg + ), + "will be ignored in favour of argument" + ) + ) +}) diff --git a/vignettes/lpjml-data.Rmd b/vignettes/lpjml-data.Rmd index f9cea0c..77136e4 100644 --- a/vignettes/lpjml-data.Rmd +++ b/vignettes/lpjml-data.Rmd @@ -496,7 +496,7 @@ coordinates <- tibble::tibble(lat = c(52.25, 52.400922, 53.25), # Complete pipe notation, from reading to plotting data. read_io( - filename = glue("{output_path}/cftfrac.bin.json"), + filename = glue("./cftfrac.bin.json"), subset = list(year = 2000:2018) ) |> transform(to = "lon_lat") |> diff --git a/vignettes/lpjml-data.md b/vignettes/lpjml-data.md index 793b31f..4fe48f1 100644 --- a/vignettes/lpjml-data.md +++ b/vignettes/lpjml-data.md @@ -491,7 +491,7 @@ coordinates <- tibble::tibble(lat = c(52.25, 52.400922, 53.25), # Complete pipe notation, from reading to plotting data. read_io( - filename = glue("{output_path}/cftfrac.bin.json"), + filename = glue("./cftfrac.bin.json"), subset = list(year = 2000:2018) ) |> transform(to = "lon_lat") |> diff --git a/vignettes/lpjml-runner.Rmd b/vignettes/lpjml-runner.Rmd index 2981fd8..8888f95 100644 --- a/vignettes/lpjml-runner.Rmd +++ b/vignettes/lpjml-runner.Rmd @@ -77,7 +77,7 @@ run or submit LPJmL with each configurations (4). `?write_config` *for more information.* ```{r, echo = TRUE, eval = FALSE, highlight = TRUE} - config_details <- write_config(my_params, model_path, output_path) + config_details <- write_config(my_params, model_path, sim_path) ``` #### **3. `r if (!knitr::is_latex_output()) {"🔍"}` Check validity of Configurations**\ @@ -87,7 +87,7 @@ run or submit LPJmL with each configurations (4). be satisfied yet) but will print/return the information of `lpjcheck`. ```{r, echo = TRUE, eval = FALSE, highlight = TRUE} - lpjml_check(config_details, model_path, output_path) + lpjml_check(config_details, model_path, sim_path) ``` #### **4. `r if (!knitr::is_latex_output()) {"▶"}` Run or `r if (!knitr::is_latex_output()) {"🚀"}` submit LPJmL**\ @@ -99,10 +99,10 @@ run or submit LPJmL with each configurations (4). ```{r, eval = FALSE, highlight = TRUE} # run interactively - run_details <- run_lpjml(config_details, model_path, output_path) + run_details <- run_lpjml(config_details, model_path, sim_path) # OR submit to SLURM - submit_details <- submit_lpjml(config_details, model_path, output_path) + submit_details <- submit_lpjml(config_details, model_path, sim_path) ``` #### **miscellaneous** \ @@ -128,7 +128,7 @@ library(lpjmlkit) library(tibble) model_path <- "./LPJmL_internal" -output_path <- "./my_runs" +sim_path <- "./my_runs" ``` @@ -167,15 +167,15 @@ params <- tibble( # write config files config_details <- write_config( - params = params, # pass the defined parameter tibble + x = params, # pass the defined parameter tibble model_path = model_path, - output_path = output_path, + sim_path = sim_path, js_filename = "lpjml.js" # (default) the base config file ) # read and view config config_lu <- read_config( - filename = paste0(output_path, "/configurations/config_lu.json") # nolint:absolute_path_linter. + filename = paste0(sim_path, "/configurations/config_lu.json") # nolint:absolute_path_linter. ) View(config_lu) @@ -183,14 +183,14 @@ View(config_lu) check_config( x = config_details, # can be filename (vector) or tibble model_path = model_path, - output_path = output_path + sim_path = sim_path ) # execute runs sequentially run_details <- run_lpjml( config_details, model_path = model_path, - output_path = output_path) + sim_path = sim_path) ``` @@ -223,13 +223,13 @@ params <- tibble( ) # write config files -config_details <- write_config(params, model_path, output_path) +config_details <- write_config(params, model_path, sim_path) # check config & LPJmL -check_config(config_details, model_path, output_path) +check_config(config_details, model_path, sim_path) # execute runs sequentially -run_details <- run_lpjml(config_details, model_path, output_path) +run_details <- run_lpjml(config_details, model_path, sim_path) ``` @@ -268,22 +268,22 @@ params <- tibble( # write config files config_details <- write_config( - params = params, + x = params, model_path = model_path, - output_path = output_path, + sim_path = sim_path, output_list = c("vegc", "soilc", "cftfrac", "pft_harvestc", "irrig"), output_list_timestep = c("annual", "annual", "annual", "annual", "monthly"), output_format = "clm" ) # check config & LPJmL -check_config(config_details, model_path, output_path) +check_config(config_details, model_path, sim_path) # submit runs to slurm run_details <- submit_lpjml( x = config_details, model_path = model_path, - output_path = output_path, + sim_path = sim_path, group = "open") ``` @@ -300,10 +300,10 @@ for a rerun or resubmission next time ... ```{r, echo = TRUE, eval = FALSE, highlight = TRUE} saveRDS(config_details, - paste0(output_path, "/configurations/config_details.rds")) # nolint:absolute_path_linter. + paste0(sim_path, "/configurations/config_details.rds")) # nolint:absolute_path_linter. # next time ... - config_details <- readRDS(paste0(output_path, + config_details <- readRDS(paste0(sim_path, "/configurations/config_details.rds")) # nolint:absolute_path_linter. ``` @@ -315,10 +315,10 @@ for a rerun or resubmission next time ... run_details <- submit_lpjml( x = config_details[2:3, ], model_path = model_path, - output_path = output_path, + sim_path = sim_path, group = "open") ``` 3. *a bit dirty though* If you want to reuse an old spinup simulation, you can copy the file or -create a symlink of the file to `"/restart//restart.lpj"`. +create a symlink of the file to `"/restart//restart.lpj"`. Make sure the file/symlink is named `"restart.lpj"` diff --git a/vignettes/lpjml-runner.md b/vignettes/lpjml-runner.md index dab7b66..2bca2e5 100644 --- a/vignettes/lpjml-runner.md +++ b/vignettes/lpjml-runner.md @@ -48,7 +48,7 @@ the parameters of a base config file `"lpjml.js"` to be changed. `?write_config` *for more information.* ``` r -config_details <- write_config(my_params, model_path, output_path) +config_details <- write_config(my_params, model_path, sim_path) ``` #### **3. 🔍 Check validity of Configurations** @@ -60,7 +60,7 @@ not be satisfied yet) but will print/return the information of `lpjcheck`. ``` r -lpjml_check(config_details, model_path, output_path) +lpjml_check(config_details, model_path, sim_path) ``` #### **4. ▶ Run or 🚀 submit LPJmL** @@ -74,10 +74,10 @@ runs. ``` r # run interactively -run_details <- run_lpjml(config_details, model_path, output_path) +run_details <- run_lpjml(config_details, model_path, sim_path) # OR submit to SLURM -submit_details <- submit_lpjml(config_details, model_path, output_path) +submit_details <- submit_lpjml(config_details, model_path, sim_path) ``` #### **miscellaneous** @@ -104,7 +104,7 @@ library(lpjmlkit) library(tibble) model_path <- "./LPJmL_internal" -output_path <- "./my_runs" +sim_path <- "./my_runs" ```     @@ -140,15 +140,15 @@ params <- tibble( # write config files config_details <- write_config( - params = params, # pass the defined parameter tibble + x = params, # pass the defined parameter tibble model_path = model_path, - output_path = output_path, + sim_path = sim_path, js_filename = "lpjml.js" # (default) the base config file ) # read and view config config_lu <- read_config( - filename = paste0(output_path, "/configurations/config_lu.json") # nolint:absolute_path_linter. + filename = paste0(sim_path, "/configurations/config_lu.json") # nolint:absolute_path_linter. ) View(config_lu) @@ -156,14 +156,14 @@ View(config_lu) check_config( x = config_details, # can be filename (vector) or tibble model_path = model_path, - output_path = output_path + sim_path = sim_path ) # execute runs sequentially run_details <- run_lpjml( config_details, model_path = model_path, - output_path = output_path) + sim_path = sim_path) ``` #### **Example** *Old vs. new phenology and old land-use vs. input toolbox* @@ -194,13 +194,13 @@ params <- tibble( ) # write config files -config_details <- write_config(params, model_path, output_path) +config_details <- write_config(params, model_path, sim_path) # check config & LPJmL -check_config(config_details, model_path, output_path) +check_config(config_details, model_path, sim_path) # execute runs sequentially -run_details <- run_lpjml(config_details, model_path, output_path) +run_details <- run_lpjml(config_details, model_path, sim_path) ```       @@ -237,22 +237,22 @@ params <- tibble( # write config files config_details <- write_config( - params = params, + x = params, model_path = model_path, - output_path = output_path, + sim_path = sim_path, output_list = c("vegc", "soilc", "cftfrac", "pft_harvestc", "irrig"), output_list_timestep = c("annual", "annual", "annual", "annual", "monthly"), output_format = "clm" ) # check config & LPJmL -check_config(config_details, model_path, output_path) +check_config(config_details, model_path, sim_path) # submit runs to slurm run_details <- submit_lpjml( x = config_details, model_path = model_path, - output_path = output_path, + sim_path = sim_path, group = "open") ``` @@ -265,10 +265,10 @@ run_details <- submit_lpjml( ``` r saveRDS(config_details, - paste0(output_path, "/configurations/config_details.rds")) # nolint:absolute_path_linter. + paste0(sim_path, "/configurations/config_details.rds")) # nolint:absolute_path_linter. # next time ... - config_details <- readRDS(paste0(output_path, + config_details <- readRDS(paste0(sim_path, "/configurations/config_details.rds")) # nolint:absolute_path_linter. ``` @@ -280,11 +280,11 @@ run_details <- submit_lpjml( run_details <- submit_lpjml( x = config_details[2:3, ], model_path = model_path, - output_path = output_path, + sim_path = sim_path, group = "open") ``` 3. *a bit dirty though* If you want to reuse an old spinup simulation, you can copy the file or create a symlink of the file to - `"/restart//restart.lpj"`. Make sure - the file/symlink is named `"restart.lpj"` + `"/restart//restart.lpj"`. Make sure the + file/symlink is named `"restart.lpj"`