From 85e638450ad95d2ecaa66b0d99d8674ecbb441ef Mon Sep 17 00:00:00 2001 From: ARIADNA BATALLA FERRES Date: Wed, 24 Apr 2024 11:01:48 +0200 Subject: [PATCH 01/14] Implement unit test for detecting hard-coded absolute paths in the code --- tests/testthat/test-hardcoded_paths.R | 49 +++++++++++++++++++++++++++ 1 file changed, 49 insertions(+) create mode 100644 tests/testthat/test-hardcoded_paths.R diff --git a/tests/testthat/test-hardcoded_paths.R b/tests/testthat/test-hardcoded_paths.R new file mode 100644 index 00000000..9caeae6e --- /dev/null +++ b/tests/testthat/test-hardcoded_paths.R @@ -0,0 +1,49 @@ + +# Unit test: detect hard-coded absolute paths in the code + +library(lintr) + +detect_hardcoded_paths <- function() { + + # Define the directories to check + directories <- c("modules", "tools") + + # Define custom lintr to detect the string "/esarchive/" + esarchive_linter <- function(source_file) { + lines <- readLines(soure_file, warn = FALSE) + # Remove comments: everything from '#' to the end of line + code_lines <- gsub("#.*$", "", lines) + # Check if any cleaned line contains "/esarchive/" + if (any(grepl("/esarchive/", code_lines))) { + lint <- lintr::Lint( + filename = source_file, + line_number = which(grepl("/esarchive/", code_lines)), + column_number = NULL, + type = "error", + message = "Hard-coded path '/esarchive/' found.", + linter = "esarchive_linter" + ) + return(list(lint)) # Returns list of lint objects + } + return(list()) # Returns empty list if "/esarchive/" not found + } + + # Apply the custom linter to each directory and save results + files_with_issues <- unlist(lapply(directories, function(dir) { + lint_dir(path = dir, linters = list(esarchive = esarchive_linter)) + }), recursive = TRUE) + + # Check results and print out the test outcome + if (length(files_with_issues) > 0) { + cat("Test FAILED. '/esarchive/' found in the following files:\n") + issues_report <- vapply(files_with_issues, function(l) { + paste(l$filename, "Line:", l$line_number) # Print file name and line number + }, character(1)) + print(issues_report) + return(FALSE) + } else { + cat("Test PASSED. No '/esarchive/' found in any file.\n") + return(TRUE) + } +} + -- GitLab From f7c240fb478b6dcd9b92e9c13b473ee2e9157ae9 Mon Sep 17 00:00:00 2001 From: ARIADNA BATALLA FERRES Date: Thu, 25 Apr 2024 13:56:31 +0200 Subject: [PATCH 02/14] Replace custom function with absolute_path_linter(lax = TRUE) --- tests/testthat/test-hardcoded_paths.R | 31 +++++---------------------- 1 file changed, 5 insertions(+), 26 deletions(-) diff --git a/tests/testthat/test-hardcoded_paths.R b/tests/testthat/test-hardcoded_paths.R index 9caeae6e..72bf8c40 100644 --- a/tests/testthat/test-hardcoded_paths.R +++ b/tests/testthat/test-hardcoded_paths.R @@ -8,42 +8,21 @@ detect_hardcoded_paths <- function() { # Define the directories to check directories <- c("modules", "tools") - # Define custom lintr to detect the string "/esarchive/" - esarchive_linter <- function(source_file) { - lines <- readLines(soure_file, warn = FALSE) - # Remove comments: everything from '#' to the end of line - code_lines <- gsub("#.*$", "", lines) - # Check if any cleaned line contains "/esarchive/" - if (any(grepl("/esarchive/", code_lines))) { - lint <- lintr::Lint( - filename = source_file, - line_number = which(grepl("/esarchive/", code_lines)), - column_number = NULL, - type = "error", - message = "Hard-coded path '/esarchive/' found.", - linter = "esarchive_linter" - ) - return(list(lint)) # Returns list of lint objects - } - return(list()) # Returns empty list if "/esarchive/" not found - } - - # Apply the custom linter to each directory and save results + # Apply absolute_path_linter() to each directory and save results files_with_issues <- unlist(lapply(directories, function(dir) { - lint_dir(path = dir, linters = list(esarchive = esarchive_linter)) + lint_dir(path = dir, linters = absolute_path_linter(lax = TRUE)) }), recursive = TRUE) # Check results and print out the test outcome if (length(files_with_issues) > 0) { - cat("Test FAILED. '/esarchive/' found in the following files:\n") + cat("Test FAILED. Absolute paths found in the following files:\n") issues_report <- vapply(files_with_issues, function(l) { - paste(l$filename, "Line:", l$line_number) # Print file name and line number + paste(l$filename, "Line:", l$line_number, "Message:", l$message) }, character(1)) print(issues_report) return(FALSE) } else { - cat("Test PASSED. No '/esarchive/' found in any file.\n") + cat("Test PASSED. No absolute paths found in any file.\n") return(TRUE) } } - -- GitLab From d6381f13cf7f6a6e82307986f6817972046ab6ab Mon Sep 17 00:00:00 2001 From: ARIADNA BATALLA FERRES Date: Thu, 25 Apr 2024 17:43:21 +0200 Subject: [PATCH 03/14] Include call to function within the script --- tests/testthat/test-hardcoded_paths.R | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/tests/testthat/test-hardcoded_paths.R b/tests/testthat/test-hardcoded_paths.R index 72bf8c40..d8b60962 100644 --- a/tests/testthat/test-hardcoded_paths.R +++ b/tests/testthat/test-hardcoded_paths.R @@ -15,14 +15,16 @@ detect_hardcoded_paths <- function() { # Check results and print out the test outcome if (length(files_with_issues) > 0) { - cat("Test FAILED. Absolute paths found in the following files:\n") + cat("Test FAILED. Hard-coded paths found in the following files:\n") issues_report <- vapply(files_with_issues, function(l) { paste(l$filename, "Line:", l$line_number, "Message:", l$message) }, character(1)) print(issues_report) return(FALSE) } else { - cat("Test PASSED. No absolute paths found in any file.\n") + cat("Test PASSED😊 No hard-coded paths found in any file.\n") return(TRUE) } } + +detect_hardcoded_paths() -- GitLab From 9d01111460955cf173a2c651cadf7f39a8c81424 Mon Sep 17 00:00:00 2001 From: ARIADNA BATALLA FERRES Date: Fri, 26 Apr 2024 10:59:14 +0200 Subject: [PATCH 04/14] Create call to unit test: test/test_paths.R --- tests/test_paths.R | 9 +++++++++ 1 file changed, 9 insertions(+) create mode 100644 tests/test_paths.R diff --git a/tests/test_paths.R b/tests/test_paths.R new file mode 100644 index 00000000..87dbed4a --- /dev/null +++ b/tests/test_paths.R @@ -0,0 +1,9 @@ +library(testthat) + +path_testthat <- file.path('./tests/testthat/') +files_testthat <- list.files('./tests/testthat/', pattern = 'paths') + +for (i_file in 1:length(files_testthat)) { + source(paste0('./tests/testthat/', files_testthat[i_file])) +} + -- GitLab From 16c3cb1a2a7b81962484944e1f6b6ddfdc2eefd2 Mon Sep 17 00:00:00 2001 From: vagudets Date: Tue, 30 Apr 2024 16:52:19 +0200 Subject: [PATCH 05/14] Remove hardcoded paths in load_sample(), test_check_number_of_independent_varifications.R and write_autosubmit_conf() --- modules/Loading/R/load_sample.R | 3 +-- tools/test_check_number_of_independent_verifications.R | 4 ++-- tools/write_autosubmit_conf.R | 6 +++--- 3 files changed, 6 insertions(+), 7 deletions(-) diff --git a/modules/Loading/R/load_sample.R b/modules/Loading/R/load_sample.R index e0d906d3..e1a8fe65 100644 --- a/modules/Loading/R/load_sample.R +++ b/modules/Loading/R/load_sample.R @@ -1,8 +1,7 @@ -## TODO: remove paths to personal scratchs -source("/esarchive/scratch/vagudets/repos/csoperational/R/get_regrid_params.R") # Load required libraries/funs source("tools/CST_ChangeDimName.R") source("modules/Loading/R/compare_exp_obs_grids.R") +source("modules/Loading/R/get_regrid_params.R") load_sample <- function(recipe) { # Hindcast: diff --git a/tools/test_check_number_of_independent_verifications.R b/tools/test_check_number_of_independent_verifications.R index 846dc5be..0ddc6bbb 100644 --- a/tools/test_check_number_of_independent_verifications.R +++ b/tools/test_check_number_of_independent_verifications.R @@ -1,12 +1,12 @@ library(testthat) test_that("A few combinations", { - source("/esarchive/scratch/nperez/git/auto-s2s/tools/check_recipe.R") + source("tools/check_recipe.R") recipe <- list(Analysis = list(Variables = list(ECVs = list( list(name = 'tas', freq = 'daily_mean')), Indicators = list(list(name = 'gdd'))), Workflow = list(Calibration = 'SBC', Indicators = TRUE))) - conf <- list(code_dir = "/esarchive/scratch/nperez/git/auto-s2s/") + conf <- list(code_dir = "./") expect_equal(check_number_of_dependent_verifications(recipe, conf), list(independent = NULL, dependent = list(list(list(name = 'tas', freq = 'daily_mean'), diff --git a/tools/write_autosubmit_conf.R b/tools/write_autosubmit_conf.R index 5f398197..0ccd8543 100644 --- a/tools/write_autosubmit_conf.R +++ b/tools/write_autosubmit_conf.R @@ -21,8 +21,8 @@ write_autosubmit_conf <- function(recipe, nchunks, # Read autosubmit info for the specific filesystem (e.g. esarchive) auto_specs <- read_yaml("conf/autosubmit.yml")[[recipe$Run$filesystem]] # Output directory - dest_dir <- paste0(auto_specs$experiment_dir, expid, "/conf/") - proj_dir <- paste0(auto_specs$experiment_dir, expid, "/proj/auto-s2s/") + dest_dir <- file.path(auto_specs$experiment_dir, expid, "conf") + proj_dir <- file.path(auto_specs$experiment_dir, expid, "proj", "auto-s2s") # Create project directory if it does not exist yet so that chunk_to_recipe # and split_to_recipe files can be created if (!dir.exists(proj_dir)) { @@ -146,7 +146,7 @@ write_autosubmit_conf <- function(recipe, nchunks, paste("##### AUTOSUBMIT CONFIGURATION WRITTEN FOR", expid, "#####")) info(recipe$Run$logger, paste0("You can check your experiment configuration at: ", - "/esarchive/autosubmit/", expid, "/conf/")) + dest_dir)) # Print instructions/commands for user if (recipe$Run$Terminal) { ## TODO: Change SSH message for other environments (outside BSC) -- GitLab From 5f68baabe8c127cdd6f788cbdd656df37bb9d2d3 Mon Sep 17 00:00:00 2001 From: ARIADNA BATALLA FERRES Date: Tue, 30 Apr 2024 17:42:27 +0200 Subject: [PATCH 06/14] Flagged paths rewritten using file.path() instead of paste0() --- modules/Anomalies/Anomalies.R | 4 +- modules/Calibration/Calibration.R | 4 +- modules/Downscaling/Downscaling.R | 4 +- modules/Indices/R/compute_nao.R | 86 ++++++++++++----------- modules/Indices/R/compute_nino.R | 99 ++++++++++++++------------- modules/Scorecards/Scorecards.R | 6 +- modules/Skill/Skill.R | 8 +-- modules/Statistics/Statistics.R | 4 +- tests/testthat/test-hardcoded_paths.R | 13 ++-- 9 files changed, 117 insertions(+), 111 deletions(-) diff --git a/modules/Anomalies/Anomalies.R b/modules/Anomalies/Anomalies.R index d5f11228..a6411e6c 100644 --- a/modules/Anomalies/Anomalies.R +++ b/modules/Anomalies/Anomalies.R @@ -122,8 +122,8 @@ Anomalies <- function(recipe, data) { if (recipe$Analysis$Workflow$Anomalies$save != 'none') { info(recipe$Run$logger, "##### START SAVING ANOMALIES #####") - recipe$Run$output_dir <- paste0(recipe$Run$output_dir, - "/outputs/Anomalies/") + recipe$Run$output_dir <- file.path(recipe$Run$output_dir, + "outputs", "Anomalies") # Save forecast if ((recipe$Analysis$Workflow$Anomalies$save %in% c('all', 'exp_only', 'fcst_only')) && !is.null(data$fcst)) { diff --git a/modules/Calibration/Calibration.R b/modules/Calibration/Calibration.R index f1362a22..e6afb210 100644 --- a/modules/Calibration/Calibration.R +++ b/modules/Calibration/Calibration.R @@ -169,8 +169,8 @@ Calibration <- function(recipe, data) { info(recipe$Run$logger, "##### START SAVING CALIBRATED DATA #####") ## TODO: What do we do with the full values? - recipe$Run$output_dir <- paste0(recipe$Run$output_dir, - "/outputs/Calibration/") + recipe$Run$output_dir <- file.path(recipe$Run$output_dir, + "outputs", "Calibration") if ((recipe$Analysis$Workflow$Calibration$save %in% c('all', 'exp_only', 'fcst_only')) && (!is.null(data$fcst))) { save_forecast(recipe = recipe, data_cube = fcst_calibrated, type = 'fcst') diff --git a/modules/Downscaling/Downscaling.R b/modules/Downscaling/Downscaling.R index 59233dc2..65d654cd 100644 --- a/modules/Downscaling/Downscaling.R +++ b/modules/Downscaling/Downscaling.R @@ -278,8 +278,8 @@ Downscaling <- function(recipe, data) { info(recipe$Run$logger, "##### START SAVING DOWNSCALED DATA #####") } ## TODO: What do we do with the full values? - recipe$Run$output_dir <- paste0(recipe$Run$output_dir, - "/outputs/Downscaling/") + recipe$Run$output_dir <- file.path(recipe$Run$output_dir, + "outputs", "Downscaling") # if ((recipe$Analysis$Workflow$Downscaling$save %in% # c('all', 'exp_only', 'fcst_only')) && (!is.null(data$fcst))) { # save_forecast(recipe = recipe, data_cube = data$fcst, type = 'fcst') diff --git a/modules/Indices/R/compute_nao.R b/modules/Indices/R/compute_nao.R index bdf2bb85..0e24b5fe 100644 --- a/modules/Indices/R/compute_nao.R +++ b/modules/Indices/R/compute_nao.R @@ -117,7 +117,7 @@ compute_nao <- function(data, recipe, obsproj, plot_ts, plot_sp, Dates = data$obs$attrs$Dates, Dataset = recipe$Analysis$Datasets$Reference$name)) if (recipe$Analysis$Workflow$Indices$NAO$save == 'all') { - file_dest <- paste0(recipe$Run$output_dir, "/outputs/Indices/") + file_dest <- file.path(recipe$Run$output_dir, "outputs", "Indices") if (tolower(recipe$Analysis$Horizon) == "seasonal") { # Use startdates param from SaveExp to correctly name the files: if (length(data$hcst$attrs$source_files) == dim(data$hcst$data)['syear']) { @@ -159,7 +159,7 @@ compute_nao <- function(data, recipe, obsproj, plot_ts, plot_sp, recipe$Analysis$Variables$name)]]$long if (plot_ts) { - dir.create(paste0(recipe$Run$output_dir, "/plots/Indices/"), + dir.create(file.path(recipe$Run$output_dir, "plots", "Indices"), showWarnings = F, recursive = T) source("modules/Indices/R/plot_deterministic_forecast.R") for (tstep in 1:dim(nao$hcst$data)['time']) { @@ -179,10 +179,11 @@ compute_nao <- function(data, recipe, obsproj, plot_ts, plot_sp, month.abb[mes], "/", recipe$Analysis$Time$hcst_start, "-", recipe$Analysis$Time$hcst_end) - plotfile <- paste0(recipe$Run$output_dir, "/plots/Indices/NAO_", - system, "_", recipe$Analysis$Datasets$Reference$name, - "_s", recipe$Analysis$Time$sdate, "_ftime", - sprintf("%02d", tstep - 1 + recipe$Analysis$Time$ftime_min), ".pdf") + plotfile <- file.path(recipe$Run$output_dir, "plots", "Indices", + paste0("NAO_", + system, "_", recipe$Analysis$Datasets$Reference$name, + "_s", recipe$Analysis$Time$sdate, "_ftime", + sprintf("%02d", tstep - 1 + recipe$Analysis$Time$ftime_min), ".pdf")) caption <- paste0("NAO method: ", ifelse(recipe$Analysis$Workflow$Indices$NAO$obsproj, "Pobs", "Pmod"), " (Doblas-Reyes et al., 2003)\n", @@ -196,10 +197,10 @@ compute_nao <- function(data, recipe, obsproj, plot_ts, plot_sp, "Lead time", fmonth, " / Start dates", recipe$Analysis$Time$hcst_start, "-", recipe$Analysis$Time$hcst_end) - plotfile <- paste0(recipe$Run$output_dir, "/plots/Indices/NAO_", - system, "_", recipe$Analysis$Datasets$Reference$name, - "_ftime", - sprintf("%02d", tstep - 1 + recipe$Analysis$Time$ftime_min), ".pdf") + plotfile <- file.path(recipe$Run$output_dir, "plots", "Indices", + paste0("NAO_", + system, "_", recipe$Analysis$Datasets$Reference$name, "_ftime", + sprintf("%02d", tstep - 1 + recipe$Analysis$Time$ftime_min), ".pdf")) caption <- paste0("NAO method: ", ifelse(recipe$Analysis$Workflow$Indices$NAO$obsproj, "Pobs", "Pmod"), " (Doblas-Reyes et al., 2003)\n", @@ -229,7 +230,7 @@ compute_nao <- function(data, recipe, obsproj, plot_ts, plot_sp, source("modules/Visualization/R/tmp/PlotRobinson.R") source("modules/Indices/R/correlation_eno.R") source("modules/Visualization/R/get_proj_code.R") - dir.create(paste0(recipe$Run$output_dir, "/plots/Indices/"), + dir.create(file.path(recipe$Run$output_dir, "plots", "Indices"), showWarnings = F, recursive = T) # Get correct code for stereographic projection projection_code <- get_proj_code(proj_name = "stereographic") @@ -273,11 +274,12 @@ compute_nao <- function(data, recipe, obsproj, plot_ts, plot_sp, " Correlation /", month.abb[mes], "/", recipe$Analysis$Time$hcst_start, "-", recipe$Analysis$Time$hcst_end) - plotfile <- paste0(recipe$Run$output_dir, "/plots/Indices/NAO_correlation_", - recipe$Analysis$Variable$name, "_", - recipe$Analysis$Datasets$Reference$name, - "_s", recipe$Analysis$Time$sdate, - "_ftime", fmonth, ".pdf") + plotfile <- file.path(recipe$Run$output_dir, "plots", "Indices", + paste0("NAO_correlation_", + recipe$Analysis$Variable$name, "_", + recipe$Analysis$Datasets$Reference$name, + "_s", recipe$Analysis$Time$sdate, + "_ftime", fmonth, ".pdf")) caption <- paste0("NAO method: ", ifelse(recipe$Analysis$Workflow$Indices$NAO$obsproj, "Pobs", "Pmod"), " (Doblas-Reyes et al., 2003)\n", @@ -292,10 +294,11 @@ compute_nao <- function(data, recipe, obsproj, plot_ts, plot_sp, " Correlation / Start dates ", recipe$Analysis$Time$hcst_start, "-", recipe$Analysis$Time$hcst_end) - plotfile <- paste0(recipe$Run$output_dir, "/plots/Indices/NAO_correlation_", - recipe$Analysis$Variable$name, "_", - recipe$Analysis$Datasets$Reference$name, - "_ftime", fmonth, ".pdf") + plotfile <- file.path(recipe$Run$output_dir, "plots", "Indices", + paste0("NAO_correlation_", + recipe$Analysis$Variable$name, "_", + recipe$Analysis$Datasets$Reference$name, + "_ftime", fmonth, ".pdf")) caption <- paste0("NAO method: ", ifelse(recipe$Analysis$Workflow$Indices$NAO$obsproj, "Pobs", "Pmod"), " (Doblas-Reyes et al., 2003)\n", @@ -331,11 +334,11 @@ compute_nao <- function(data, recipe, obsproj, plot_ts, plot_sp, " Correlation /", month.abb[mes], "/", recipe$Analysis$Time$hcst_start, "-", recipe$Analysis$Time$hcst_end) - plotfile <- paste0(recipe$Run$output_dir, "/plots/Indices/NAO_correlation_", - recipe$Analysis$Variable$name, "_ensmean_", - system, - "_s", recipe$Analysis$Time$sdate, - "_ftime", fmonth, ".pdf") + plotfile <- file.path(recipe$Run$output_dir, "plots", "Indices", + paste0("NAO_correlation_", + recipe$Analysis$Variable$name, "_ensmean_", + system, "_s", recipe$Analysis$Time$sdate, + "_ftime", fmonth, ".pdf")) caption <- paste0("NAO method: ", ifelse(recipe$Analysis$Workflow$Indices$NAO$obsproj, "Pobs", "Pmod"), " (Doblas-Reyes et al., 2003)\n", @@ -351,11 +354,12 @@ compute_nao <- function(data, recipe, obsproj, plot_ts, plot_sp, " Correlation / Start dates ", recipe$Analysis$Time$hcst_start, "-", recipe$Analysis$Time$hcst_end) - plotfile <- paste0(recipe$Run$output_dir, "/plots/Indices/NAO_correlation_", - recipe$Analysis$Variable$name, "_ensmean_", - system, - recipe$Analysis$Datasets$Reference$name, - "_ftime", fmonth, ".pdf") + plotfile <- file.path(recipe$Run$output_dir, "plots", "Indices", + paste0("NAO_correlation_", + recipe$Analysis$Variable$name, "_ensmean_", + system, + recipe$Analysis$Datasets$Reference$name, + "_ftime", fmonth, ".pdf")) caption <- paste0("NAO method: ", ifelse(recipe$Analysis$Workflow$Indices$NAO$obsproj, "Pobs", "Pmod"), " (Doblas-Reyes et al., 2003)\n", @@ -388,11 +392,12 @@ compute_nao <- function(data, recipe, obsproj, plot_ts, plot_sp, " Correlation /", month.abb[mes], "/", recipe$Analysis$Time$hcst_start, "-", recipe$Analysis$Time$hcst_end) - plotfile <- paste0(recipe$Run$output_dir, "/plots/Indices/NAO_correlation_", - recipe$Analysis$Variable$name, "_member_", - system, - "_s", recipe$Analysis$Time$sdate, - "_ftime", fmonth, ".pdf") + plotfile <- file.path(recipe$Run$output_dir, "plots", "Indices", + paste0("NAO_correlation_", + recipe$Analysis$Variable$name, "_member_", + system, + "_s", recipe$Analysis$Time$sdate, + "_ftime", fmonth, ".pdf")) caption <- paste0("NAO method: ", ifelse(recipe$Analysis$Workflow$Indices$NAO$obsproj, "Pobs", "Pmod"), " (Doblas-Reyes et al., 2003)\n", @@ -408,11 +413,12 @@ compute_nao <- function(data, recipe, obsproj, plot_ts, plot_sp, " Correlation / Start dates ", recipe$Analysis$Time$hcst_start, "-", recipe$Analysis$Time$hcst_end) - plotfile <- paste0(recipe$Run$output_dir, "/plots/Indices/NAO_correlation_", - recipe$Analysis$Variable$name, "_member_", - system, - recipe$Analysis$Datasets$Reference$name, - "_ftime", fmonth, ".pdf") + plotfile <- file.path(recipe$Run$output_dir, "plots", "Indices", + paste0("NAO_correlation_", + recipe$Analysis$Variable$name, "_member_", + system, + recipe$Analysis$Datasets$Reference$name, + "_ftime", fmonth, ".pdf")) caption <- paste0("NAO method: ", ifelse(recipe$Analysis$Workflow$Indices$NAO$obsproj, "Pobs", "Pmod"), " (Doblas-Reyes et al., 2003)\n", diff --git a/modules/Indices/R/compute_nino.R b/modules/Indices/R/compute_nino.R index b47d9ee2..f251ce44 100644 --- a/modules/Indices/R/compute_nino.R +++ b/modules/Indices/R/compute_nino.R @@ -104,7 +104,7 @@ compute_nino <- function(data, recipe, region, standardised = TRUE, Dataset = recipe$Analysis$Datasets$Reference$name)) if (save == 'all') { - file_dest <- paste0(recipe$Run$output_dir, "/outputs/Indices/") + file_dest <- file.path(recipe$Run$output_dir, "outputs", "Indices") # Use startdates param from SaveExp to correctly name the files: if (tolower(recipe$Analysis$Horizon) == "seasonal") { if (length(data$hcst$attrs$source_files) == dim(data$hcst$data)['syear']) { @@ -145,7 +145,7 @@ compute_nino <- function(data, recipe, region, standardised = TRUE, var_name <- conf$vars[[which(names(conf$vars) == recipe$Analysis$Variables$name)]]$long if (plot_ts) { - dir.create(paste0(recipe$Run$output_dir, "/plots/Indices/"), + dir.create(file.path(recipe$Run$output_dir, "plots", "Indices"), showWarnings = F, recursive = T) source("modules/Indices/R/plot_deterministic_forecast.R") for (tstep in 1:dim(nino$hcst$data)['time']) { @@ -165,12 +165,12 @@ compute_nino <- function(data, recipe, region, standardised = TRUE, month.abb[mes], "/", recipe$Analysis$Time$hcst_start, "-", recipe$Analysis$Time$hcst_end) - plotfile <- paste0(recipe$Run$output_dir, "/plots/Indices/", - nino_name, "_", - system, "_", recipe$Analysis$Datasets$Reference$name, - "_s", recipe$Analysis$Time$sdate, "_ftime", - sprintf("%02d", tstep - 1 + recipe$Analysis$Time$ftime_min), - ".pdf") + plotfile <- file.path(recipe$Run$output_dir, "plots", "Indices", + paste0(nino_name, "_", + system, "_", recipe$Analysis$Datasets$Reference$name, + "_s", recipe$Analysis$Time$sdate, "_ftime", + sprintf("%02d", tstep - 1 + recipe$Analysis$Time$ftime_min), + ".pdf")) caption <- paste0("Nominal start date: 1st of ", month.name[as.numeric(substr(recipe$Analysis$Time$sdate, 1,2))], "\n", @@ -181,10 +181,12 @@ compute_nino <- function(data, recipe, region, standardised = TRUE, "Lead time", fmonth, "/", recipe$Analysis$Time$hcst_start, "-", recipe$Analysis$Time$hcst_end) - plotfile <- paste0(recipe$Run$output_dir, "/plots/Indices/", nino_name, "_", - system, "_", recipe$Analysis$Datasets$Reference$name, - "_ftime", - sprintf("%02d", tstep - 1 + recipe$Analysis$Time$ftime_min), ".pdf") + plotfile <- file.path(recipe$Run$output_dir, "plots", "Indices", + paste0(nino_name, "_", + system, "_", recipe$Analysis$Datasets$Reference$name, + "_ftime", + sprintf("%02d", tstep - 1 + recipe$Analysis$Time$ftime_min), + ".pdf")) caption <- paste0("Start date month: ", month.name[get_archive(recipe)$System[[recipe$Analysis$Datasets$System$name]]$initial_month], "\n", @@ -217,7 +219,7 @@ compute_nino <- function(data, recipe, region, standardised = TRUE, # Get code for Robinson projection depending on GEOS/GDAL/PROJ version projection_code <- get_proj_code("robinson") # Avoid rewriten longitudes a shift is neeced: - dir.create(paste0(recipe$Run$output_dir, "/plots/Indices/"), + dir.create(file.path(recipe$Run$output_dir, "plots", "Indices"), showWarnings = F, recursive = T) correl_obs <- Apply(list(data$obs$data, nino$obs$data), target_dims = 'syear', @@ -267,12 +269,13 @@ compute_nino <- function(data, recipe, region, standardised = TRUE, month.abb[mes], "/", recipe$Analysis$Time$hcst_start, "-", recipe$Analysis$Time$hcst_end) - plotfile <- paste0(recipe$Run$output_dir, "/plots/Indices/", nino_name, - "_correlation_", - recipe$Analysis$Variable$name, "_", - recipe$Analysis$Datasets$Reference$name, - "_s", recipe$Analysis$Time$sdate, - "_ftime", fmonth, ".pdf") + plotfile <- file.path(recipe$Run$output_dir, "plots", "Indices", + paste0(nino_name, + "_correlation_", + recipe$Analysis$Variable$name, "_", + recipe$Analysis$Datasets$Reference$name, + "_s", recipe$Analysis$Time$sdate, + "_ftime", fmonth, ".pdf")) caption <- paste0("Nominal start date: 1st of ", month.name[as.numeric(substr(recipe$Analysis$Time$sdate, 1,2))], "\n", @@ -285,11 +288,11 @@ compute_nino <- function(data, recipe, region, standardised = TRUE, "Correlation / Start dates", recipe$Analysis$Time$hcst_start, "-", recipe$Analysis$Time$hcst_end) - plotfile <- paste0(recipe$Run$output_dir, "/plots/Indices/", - nino_name, "_correlation_", - recipe$Analysis$Variable$name, "_", - recipe$Analysis$Datasets$Reference$name, - "_ftime", fmonth, ".pdf") + plotfile <- file.path(recipe$Run$output_dir, "plots", "Indices", + paste0(nino_name, "_correlation_", + recipe$Analysis$Variable$name, "_", + recipe$Analysis$Datasets$Reference$name, + "_ftime", fmonth, ".pdf")) caption <- paste0("Start date: month ", month.name[get_archive(recipe)$System[[recipe$Analysis$Datasets$System$name]]$initial_month], "\n", @@ -325,12 +328,12 @@ compute_nino <- function(data, recipe, region, standardised = TRUE, month.abb[mes], "/", recipe$Analysis$Time$hcst_start, "-", recipe$Analysis$Time$hcst_end) - plotfile <- paste0(recipe$Run$output_dir, "/plots/Indices/", - nino_name, "_correlation_", - recipe$Analysis$Variable$name, "_ensmean_", - system, - "_s", recipe$Analysis$Time$sdate, - "_ftime", fmonth, ".pdf") + plotfile <- file.path(recipe$Run$output_dir, "plots", "Indices", + paste0(nino_name, "_correlation_", + recipe$Analysis$Variable$name, "_ensmean_", + system, + "_s", recipe$Analysis$Time$sdate, + "_ftime", fmonth, ".pdf")) caption <- paste0("Ensemble mean\n", "Nominal start date: 1st of ", month.name[as.numeric(substr(recipe$Analysis$Time$sdate, 1,2))], @@ -343,12 +346,12 @@ compute_nino <- function(data, recipe, region, standardised = TRUE, "Correlation / Start dates", recipe$Analysis$Time$hcst_start, "-", recipe$Analysis$Time$hcst_end) - plotfile <- paste0(recipe$Run$output_dir, "/plots/Indices/", - nino_name, "_correlation_", - recipe$Analysis$Variable$name, "_ensmean_", - system, - recipe$Analysis$Datasets$Reference$name, - "_ftime", fmonth, ".pdf") + plotfile <- file.path(recipe$Run$output_dir, "plots", "Indices", + paste0(nino_name, "_correlation_", + recipe$Analysis$Variable$name, "_ensmean_", + system, + recipe$Analysis$Datasets$Reference$name, + "_ftime", fmonth, ".pdf")) caption <- paste0("Correlation ensemble mean\n", "Start date month: ", month.name[get_archive(recipe)$System[[recipe$Analysis$Datasets$System$name]]$initial_month], @@ -379,12 +382,12 @@ compute_nino <- function(data, recipe, region, standardised = TRUE, month.abb[mes], "/", recipe$Analysis$Time$hcst_start, "-", recipe$Analysis$Time$hcst_end) - plotfile <- paste0(recipe$Run$output_dir, "/plots/Indices/", - nino_name, "_correlation_", - recipe$Analysis$Variable$name, "_member_", - system, - "_s", recipe$Analysis$Time$sdate, - "_ftime", fmonth, ".pdf") + plotfile <- file.path(recipe$Run$output_dir, "plots", "Indices", + paste0(nino_name, "_correlation_", + recipe$Analysis$Variable$name, "_member_", + system, + "_s", recipe$Analysis$Time$sdate, + "_ftime", fmonth, ".pdf")) caption <- paste0("Individual members\n", "Nominal start date: 1st of ", month.name[as.numeric(substr(recipe$Analysis$Time$sdate, 1,2))], @@ -397,12 +400,12 @@ compute_nino <- function(data, recipe, region, standardised = TRUE, "Correlation / Start dates", recipe$Analysis$Time$hcst_start, "-", recipe$Analysis$Time$hcst_end) - plotfile <- paste0(recipe$Run$output_dir, "/plots/Indices/", - nino_name, "_correlation_", - recipe$Analysis$Variable$name, "_ensmean_", - system, - recipe$Analysis$Datasets$Reference$name, - "_ftime", fmonth, ".pdf") + plotfile <- file.path(recipe$Run$output_dir, "plots", "Indices", + paste0(nino_name, "_correlation_", + recipe$Analysis$Variable$name, "_ensmean_", + system, + recipe$Analysis$Datasets$Reference$name, + "_ftime", fmonth, ".pdf")) caption <- paste0("Correlation ensemble mean\n", "Start date month: ", month.name[get_archive(recipe)$System[[recipe$Analysis$Datasets$System$name]]$initial_month], diff --git a/modules/Scorecards/Scorecards.R b/modules/Scorecards/Scorecards.R index 37aa421c..02e4f72c 100644 --- a/modules/Scorecards/Scorecards.R +++ b/modules/Scorecards/Scorecards.R @@ -22,9 +22,9 @@ source('modules/Scorecards/R/tmp/ClimPalette.R') Scorecards <- function(recipe) { ## Parameters for loading data files - skill.input.path <- paste0(recipe$Run$output_dir, "/outputs/Skill/") - stats.input.path <- paste0(recipe$Run$output_dir, "/outputs/Statistics/") - output.path <- paste0(recipe$Run$output_dir, "/plots/Scorecards/") + skill.input.path <- file.path(recipe$Run$output_dir, "outputs", "Skill") + stats.input.path <- file.path(recipe$Run$output_dir, "outputs", "Statistics") + output.path <- file.path(recipe$Run$output_dir, "plots", "Scorecards") dir.create(output.path, recursive = T, showWarnings = F) system <- recipe$Analysis$Datasets$System$name reference <- recipe$Analysis$Datasets$Reference$name diff --git a/modules/Skill/Skill.R b/modules/Skill/Skill.R index aa22838a..77cf2af4 100644 --- a/modules/Skill/Skill.R +++ b/modules/Skill/Skill.R @@ -357,8 +357,8 @@ Skill <- function(recipe, data, agg = 'global') { if (recipe$Analysis$Workflow$Skill$save != 'none') { info(recipe$Run$logger, "##### START SAVING SKILL METRIC #####") } - recipe$Run$output_dir <- paste0(recipe$Run$output_dir, - "/outputs/Skill/") + recipe$Run$output_dir <- file.path(recipe$Run$output_dir, + "outputs", "Skill") # Separate 'corr' from the rest of the metrics because of extra 'ensemble' dim ## TODO: merge save_metrics() and save_metrics_scorecards() if (recipe$Analysis$Workflow$Skill$save == 'all') { @@ -486,8 +486,8 @@ Probabilities <- function(recipe, data) { info(recipe$Run$logger, "##### START SAVING PERCENTILES AND PROBABILITY CATEGORIES #####") - recipe$Run$output_dir <- paste0(recipe$Run$output_dir, - "/outputs/Skill/") + recipe$Run$output_dir <- file.path(recipe$Run$output_dir, + "outputs", "Skill") # Save percentiles if (recipe$Analysis$Workflow$Probabilities$save %in% c('all', 'percentiles_only')) { diff --git a/modules/Statistics/Statistics.R b/modules/Statistics/Statistics.R index 085bcdc5..462791e6 100644 --- a/modules/Statistics/Statistics.R +++ b/modules/Statistics/Statistics.R @@ -84,8 +84,8 @@ Statistics <- function(recipe, data, agg = 'global') { if (recipe$Analysis$Workflow$Skill$save != 'none') { info(recipe$Run$logger, "##### START SAVING STATISTICS #####") } - recipe$Run$output_dir <- paste0(recipe$Run$output_dir, - "/outputs/Statistics/") + recipe$Run$output_dir <- file.path(recipe$Run$output_dir, + "outputs", "Statistics") if (recipe$Analysis$Workflow$Statistics$save == 'all') { # Save all statistics diff --git a/tests/testthat/test-hardcoded_paths.R b/tests/testthat/test-hardcoded_paths.R index d8b60962..1345e013 100644 --- a/tests/testthat/test-hardcoded_paths.R +++ b/tests/testthat/test-hardcoded_paths.R @@ -9,17 +9,14 @@ detect_hardcoded_paths <- function() { directories <- c("modules", "tools") # Apply absolute_path_linter() to each directory and save results - files_with_issues <- unlist(lapply(directories, function(dir) { + files_with_issues <- lapply(directories, function(dir) { lint_dir(path = dir, linters = absolute_path_linter(lax = TRUE)) - }), recursive = TRUE) - + }) + # Check results and print out the test outcome if (length(files_with_issues) > 0) { - cat("Test FAILED. Hard-coded paths found in the following files:\n") - issues_report <- vapply(files_with_issues, function(l) { - paste(l$filename, "Line:", l$line_number, "Message:", l$message) - }, character(1)) - print(issues_report) + cat("Test FAILED. Hard-coded paths found:\n") + print(files_with_issues) return(FALSE) } else { cat("Test PASSED😊 No hard-coded paths found in any file.\n") -- GitLab From c648a71104f6293ce5405b07cbad54c97194da5e Mon Sep 17 00:00:00 2001 From: ARIADNA BATALLA FERRES Date: Tue, 30 Apr 2024 17:46:04 +0200 Subject: [PATCH 07/14] More rewritten flagged paths --- tools/divide_recipe.R | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/tools/divide_recipe.R b/tools/divide_recipe.R index 3b2e6eee..1f83d63c 100644 --- a/tools/divide_recipe.R +++ b/tools/divide_recipe.R @@ -51,7 +51,7 @@ divide_recipe <- function(recipe) { # Modify the saving of the individual models in case multimodel is yes or both if (recipe$Analysis$Datasets$Multimodel$execute %in% c(TRUE, 'both')) { # Create directory for multimodel recipes - dir.create(paste0(recipe$Run$output_dir, "/logs/recipes/multimodel/"), + dir.create(file.path(recipe$Run$output_dir, "logs", "recipes", "multimodel"), recursive = TRUE) n_models <- length(recipe$Analysis$Datasets$System) + 1 mm <- tolower(recipe$Analysis$Datasets$Multimodel$approach) @@ -189,11 +189,11 @@ divide_recipe <- function(recipe) { if (all_recipes[[reci]]$Analysis$Datasets$System$name == 'Multimodel') { - recipe_dir <- paste0(recipe$Run$output_dir, "/logs/recipes/multimodel/") + recipe_dir <- file.path(recipe$Run$output_dir, "logs", "recipes", "multimodel") split_to_recipe[split] <- recipe_split split <- split + 1 } else { - recipe_dir <- paste0(recipe$Run$output_dir, "/logs/recipes/") + recipe_dir <- file.path(recipe$Run$output_dir, "logs", "recipes") chunk_to_recipe[chunk] <- recipe_name chunk <- chunk + 1 } @@ -206,8 +206,8 @@ divide_recipe <- function(recipe) { paste("The main recipe has been divided into", length(chunk_to_recipe), "single model atomic recipes, plus", length(split_to_recipe), "multi-model atomic recipes.")) - text <- paste0("Check output directory ", recipe$Run$output_dir, - "/logs/recipes/ to see all the individual atomic recipes.") + text <- paste0("Check output directory ", recipe$Run$output_dir, "/", + file.path("logs", "recipes"), "/", " to see all the individual atomic recipes.") info(recipe$Run$logger, text) ## TODO: Change returns? return(list(n_atomic_recipes = length(chunk_to_recipe), # length(all_recipes) -- GitLab From 3c8d79cb6e32b4c7e2e1655cc76f351b351ad847 Mon Sep 17 00:00:00 2001 From: vagudets Date: Thu, 2 May 2024 09:49:24 +0200 Subject: [PATCH 08/14] Fix bugs related to use of paste0() instead of file.path() --- conf/autosubmit.yml | 4 ++-- recipes/recipe_multimodel_seasonal.yml | 2 +- tools/check_recipe.R | 6 +++--- tools/write_autosubmit_conf.R | 6 +++--- 4 files changed, 9 insertions(+), 9 deletions(-) diff --git a/conf/autosubmit.yml b/conf/autosubmit.yml index 3e3f1220..db2f503e 100644 --- a/conf/autosubmit.yml +++ b/conf/autosubmit.yml @@ -3,12 +3,12 @@ esarchive: module_version: autosubmit/4.0.98-foss-2015a-Python-3.7.3 auto_version: 4.0.98 conf_format: yaml - experiment_dir: /esarchive/autosubmit/ + experiment_dir: /esarchive/autosubmit userID: bsc32 mars: platform: NORD3 ## TO BE CHANGED module_version: autosubmit/4.0.0b-foss-2015a-Python-3.7.3 ## TO BE CHANGED auto_version: 4.0.0 conf_format: yaml - experiment_dir: /esarchive/autosubmit/ ## TO BE CHANGED + experiment_dir: /esarchive/autosubmit ## TO BE CHANGED userID: bsc32 ## TO BE CHANGED diff --git a/recipes/recipe_multimodel_seasonal.yml b/recipes/recipe_multimodel_seasonal.yml index f974fc48..f7ff4b72 100644 --- a/recipes/recipe_multimodel_seasonal.yml +++ b/recipes/recipe_multimodel_seasonal.yml @@ -67,7 +67,7 @@ Run: # fill only if using autosubmit auto_conf: script: ./example_scripts/multimodel_seasonal.R # replace with the path to your script - expid: a6wq # replace with your EXPID + expid: a6v7 # replace with your EXPID hpc_user: bsc32762 # replace with your hpc username wallclock: 01:00 # hh:mm wallclock_multimodel: 02:00 diff --git a/tools/check_recipe.R b/tools/check_recipe.R index 42cb832c..57415018 100644 --- a/tools/check_recipe.R +++ b/tools/check_recipe.R @@ -787,11 +787,11 @@ check_recipe <- function(recipe) { paste("autosubmit expid -H", auto_specs$platform, "-d ")) error_status <- TRUE - } else if (!dir.exists(paste0(auto_specs$experiment_dir, - recipe$Run$auto_conf$expid))) { + } else if (!dir.exists(file.path(auto_specs$experiment_dir, + recipe$Run$auto_conf$expid))) { error(recipe$Run$logger, paste0("No folder in ", auto_specs$experiment_dir, - " for the EXPID", recipe$Run$auto_conf$expid, + " for the EXPID ", recipe$Run$auto_conf$expid, ". Please make sure it is correct.")) error_status <- TRUE } diff --git a/tools/write_autosubmit_conf.R b/tools/write_autosubmit_conf.R index 0ccd8543..f1989642 100644 --- a/tools/write_autosubmit_conf.R +++ b/tools/write_autosubmit_conf.R @@ -132,15 +132,15 @@ write_autosubmit_conf <- function(recipe, nchunks, recipe$Run$auto_conf$hpc_user } else if (conf_type == "proj") { # Section 5: proj - ## modules? Info that goes on script, e.g. output directory + ## modules? Info that goes on script, e.g. directory conf$common$OUTDIR <- recipe$Run$output_dir conf$common$SCRIPT <- recipe$Run$auto_conf$script conf$common$RECIPE <- paste0(recipe$name, ".yml") } # Write config file inside autosubmit dir - write.config(conf, paste0(dest_dir, dest_file), + write.config(conf, file.path(dest_dir, dest_file), write.type = auto_specs$conf_format) - Sys.chmod(paste0(dest_dir, dest_file), mode = "755", use_umask = F) + Sys.chmod(file.path(dest_dir, dest_file), mode = "755", use_umask = F) } info(recipe$Run$logger, paste("##### AUTOSUBMIT CONFIGURATION WRITTEN FOR", expid, "#####")) -- GitLab From 8c5dca529dfb6aeb3f1d090b07a92961acf9ce08 Mon Sep 17 00:00:00 2001 From: vagudets Date: Thu, 2 May 2024 11:03:48 +0200 Subject: [PATCH 09/14] Change paste0() to file.path() in get_filename() --- modules/Saving/R/get_filename.R | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/Saving/R/get_filename.R b/modules/Saving/R/get_filename.R index b2345691..4c2dd726 100644 --- a/modules/Saving/R/get_filename.R +++ b/modules/Saving/R/get_filename.R @@ -76,6 +76,6 @@ get_filename <- function(dir, recipe, var, date, agg, file.type) { "probs" = {filename <- paste0(var, gg, "-probs_", date)}, "bias" = {filename <- paste0(var, gg, "-bias_", date)}) } - return(paste0(dir, filename, ".nc")) + return(file.path(dir, paste0(filename, ".nc"))) } -- GitLab From d6bed5c99fbcc4cd15583667ac7909f25a539677 Mon Sep 17 00:00:00 2001 From: vagudets Date: Fri, 3 May 2024 12:28:43 +0200 Subject: [PATCH 10/14] Change pending paste0() to file.path() to fix pipeline --- modules/Saving/R/get_dir.R | 2 +- modules/Saving/R/save_metrics.R | 3 ++- modules/Visualization/R/plot_ensemble_mean.R | 18 ++++++++---------- modules/Visualization/R/plot_metrics.R | 6 +++--- .../R/plot_most_likely_terciles_map.R | 3 ++- modules/Visualization/Visualization.R | 2 +- recipes/recipe_multimodel_seasonal.yml | 2 +- 7 files changed, 18 insertions(+), 18 deletions(-) diff --git a/modules/Saving/R/get_dir.R b/modules/Saving/R/get_dir.R index 35bede6f..a0b054c6 100644 --- a/modules/Saving/R/get_dir.R +++ b/modules/Saving/R/get_dir.R @@ -17,7 +17,7 @@ get_dir <- function(recipe, variable, agg = "global") { # Define output dir name accordint to Scorecards format dict <- read_yaml("conf/output_dictionaries/scorecards.yml") # system <- dict$System[[recipe$Analysis$Datasets$System$name]]$short_name - dir <- paste0(outdir, system, "/", reference, "/", calib.method, "/", variable, "/") + dir <- file.path(outdir, system, reference, calib.method, variable) } else { # Default generic output format based on FOCUS # Get startdate or hindcast period diff --git a/modules/Saving/R/save_metrics.R b/modules/Saving/R/save_metrics.R index 57063a0c..b3d9fb97 100644 --- a/modules/Saving/R/save_metrics.R +++ b/modules/Saving/R/save_metrics.R @@ -101,8 +101,9 @@ save_metrics <- function(recipe, } ## TODO: Maybe 'scorecards' condition could go here to further simplify ## the code - extra_string <- get_filename(NULL, recipe, variable, + extra_string <- get_filename("", recipe, variable, fcst.sdate, agg, names(subset_metric)[[i]]) + browser() SaveExp(data = subset_metric[[i]], destination = outdir, Dates = dates, coords = c(data_cube$coords['longitude'], diff --git a/modules/Visualization/R/plot_ensemble_mean.R b/modules/Visualization/R/plot_ensemble_mean.R index 59881864..8186838d 100644 --- a/modules/Visualization/R/plot_ensemble_mean.R +++ b/modules/Visualization/R/plot_ensemble_mean.R @@ -81,18 +81,16 @@ plot_ensemble_mean <- function(recipe, fcst, mask = NULL, dots = NULL, outdir, o } for (i_syear in start_date) { + i_var_ens_mean <- ClimProjDiags::Subset(var_ens_mean, + along = c("syear"), + indices = which(start_date == i_syear), + drop = 'selected') if (length(start_date) == 1) { - i_var_ens_mean <- ClimProjDiags::Subset(var_ens_mean, - along = c("syear"), - indices = which(start_date == i_syear), - drop = 'selected') - outfile <- paste0(outdir[[var]], "forecast_ensemble_mean-", start_date) + outfile <- file.path(outdir[[var]], + paste0("forecast_ensemble_mean-", start_date)) } else { - i_var_ens_mean <- ClimProjDiags::Subset(var_ens_mean, - along = c("syear"), - indices = which(start_date == i_syear), - drop = 'selected') - outfile <- paste0(outdir[[var]], "forecast_ensemble_mean-", i_syear) + outfile <- file.path(outdir[[var]], + paste0("forecast_ensemble_mean-", i_syear)) } # Mask if (!is.null(mask)) { diff --git a/modules/Visualization/R/plot_metrics.R b/modules/Visualization/R/plot_metrics.R index c00e8164..141987d0 100644 --- a/modules/Visualization/R/plot_metrics.R +++ b/modules/Visualization/R/plot_metrics.R @@ -1,7 +1,7 @@ library(stringr) plot_metrics <- function(recipe, data_cube, metrics, - outdir, significance = F, output_conf) { + outdir, significance = F, output_conf) { # recipe: Auto-S2S recipe # archive: Auto-S2S archive # data_cube: s2dv_cube object with the corresponding hindcast data @@ -194,9 +194,9 @@ plot_metrics <- function(recipe, data_cube, metrics, } # Define output file name and titles if (tolower(recipe$Analysis$Horizon) == "seasonal") { - outfile <- paste0(outdir[var], name, "-", month_label) + outfile <- file.path(outdir[var], paste0(name, "-", month_label)) } else { - outfile <- paste0(outdir[var], name) + outfile <- file.path(outdir[var], name) } # Get variable name and long name var_name <- data_cube$attrs$Variable$varName[[var]] diff --git a/modules/Visualization/R/plot_most_likely_terciles_map.R b/modules/Visualization/R/plot_most_likely_terciles_map.R index c9ce70f2..0e6e27c5 100644 --- a/modules/Visualization/R/plot_most_likely_terciles_map.R +++ b/modules/Visualization/R/plot_most_likely_terciles_map.R @@ -87,7 +87,8 @@ plot_most_likely_terciles <- function(recipe, along = c("syear"), indices = which(start_date == i_syear), drop = 'selected') - outfile <- paste0(outdir[[var]], "forecast_most_likely_tercile-", i_syear) + outfile <- file.path(outdir[[var]], + paste0("forecast_most_likely_tercile-", i_syear)) # Mask if (!is.null(mask)) { outfile <- paste0(outfile, "_rpssmask") diff --git a/modules/Visualization/Visualization.R b/modules/Visualization/Visualization.R index 3750baea..109251c9 100644 --- a/modules/Visualization/Visualization.R +++ b/modules/Visualization/Visualization.R @@ -55,7 +55,7 @@ Visualization <- function(recipe, # Get plot types and create output directories plots <- strsplit(recipe$Analysis$Workflow$Visualization$plots, ", | |,")[[1]] ## TODO: Do not modify output dir here - recipe$Run$output_dir <- paste0(recipe$Run$output_dir, "/plots/") + recipe$Run$output_dir <- file.path(recipe$Run$output_dir, "plots") outdir <- get_dir(recipe = recipe, variable = data$hcst$attrs$Variable$varName) for (directory in outdir) { diff --git a/recipes/recipe_multimodel_seasonal.yml b/recipes/recipe_multimodel_seasonal.yml index f7ff4b72..3b14e09b 100644 --- a/recipes/recipe_multimodel_seasonal.yml +++ b/recipes/recipe_multimodel_seasonal.yml @@ -68,7 +68,7 @@ Run: auto_conf: script: ./example_scripts/multimodel_seasonal.R # replace with the path to your script expid: a6v7 # replace with your EXPID - hpc_user: bsc32762 # replace with your hpc username + hpc_user: bsc032762 # replace with your hpc username wallclock: 01:00 # hh:mm wallclock_multimodel: 02:00 processors_per_job: 4 -- GitLab From 16218459b2442d7ed3a3a1b04a26a3fe9003e215 Mon Sep 17 00:00:00 2001 From: vagudets Date: Fri, 3 May 2024 14:26:49 +0200 Subject: [PATCH 11/14] Move lintr tests and add to git pipeline --- .gitlab-ci.yml | 13 +++++++++++++ tests/{test_paths.R => test_lintr.R} | 2 +- ...rdcoded_paths.R => test-lintr_hardcoded_paths.R} | 0 3 files changed, 14 insertions(+), 1 deletion(-) rename tests/{test_paths.R => test_lintr.R} (71%) rename tests/testthat/{test-hardcoded_paths.R => test-lintr_hardcoded_paths.R} (100%) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 997870c8..90f49c1f 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -26,3 +26,16 @@ unit-test-decadal: # This job runs in the test stage. - module list - echo "Running decadal unit tests..." - Rscript ./tests/test_decadal.R + +unit-test-lintr: # This job runs in the test stage. + stage: test + script: + - echo "Loading modules..." + - module load R/4.1.2-foss-2015a-bare + - module load CDO/1.9.8-foss-2015a + - module load GEOS/3.7.2-foss-2015a-Python-3.7.3 + - module load GDAL/2.2.1-foss-2015a + - module load PROJ/4.8.0-foss-2015a + - module list + - echo "Running lintr unit tests..." + - Rscript ./tests/test_lintr.R diff --git a/tests/test_paths.R b/tests/test_lintr.R similarity index 71% rename from tests/test_paths.R rename to tests/test_lintr.R index 87dbed4a..7d0d1349 100644 --- a/tests/test_paths.R +++ b/tests/test_lintr.R @@ -1,7 +1,7 @@ library(testthat) path_testthat <- file.path('./tests/testthat/') -files_testthat <- list.files('./tests/testthat/', pattern = 'paths') +files_testthat <- list.files('./tests/testthat/', pattern = 'lintr') for (i_file in 1:length(files_testthat)) { source(paste0('./tests/testthat/', files_testthat[i_file])) diff --git a/tests/testthat/test-hardcoded_paths.R b/tests/testthat/test-lintr_hardcoded_paths.R similarity index 100% rename from tests/testthat/test-hardcoded_paths.R rename to tests/testthat/test-lintr_hardcoded_paths.R -- GitLab From ee9268f348d89c0bfb0e2c64b1e6bc45060c2b19 Mon Sep 17 00:00:00 2001 From: ARIADNA BATALLA FERRES Date: Fri, 3 May 2024 16:11:19 +0200 Subject: [PATCH 12/14] Fixed if() clause and added directory names to output --- tests/testthat/test-hardcoded_paths.R | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/tests/testthat/test-hardcoded_paths.R b/tests/testthat/test-hardcoded_paths.R index 1345e013..6616e747 100644 --- a/tests/testthat/test-hardcoded_paths.R +++ b/tests/testthat/test-hardcoded_paths.R @@ -13,13 +13,16 @@ detect_hardcoded_paths <- function() { lint_dir(path = dir, linters = absolute_path_linter(lax = TRUE)) }) + # Assign names to the list elements + names(files_with_issues) <- directories + # Check results and print out the test outcome - if (length(files_with_issues) > 0) { + if (any(sapply(files_with_issues, function(x) length(x) > 0))) { cat("Test FAILED. Hard-coded paths found:\n") print(files_with_issues) return(FALSE) } else { - cat("Test PASSED😊 No hard-coded paths found in any file.\n") + cat("Test PASSED🥳 No hard-coded paths found in any file.\n") return(TRUE) } } -- GitLab From 3dd18f10b357f1570adada38fc2d9d34b0efb04e Mon Sep 17 00:00:00 2001 From: vagudets Date: Mon, 6 May 2024 16:09:33 +0200 Subject: [PATCH 13/14] Add test_that() clause --- .gitlab-ci.yml | 2 +- tests/testthat/test-lintr_hardcoded_paths.R | 8 +++++--- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 90f49c1f..fe4abf17 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -37,5 +37,5 @@ unit-test-lintr: # This job runs in the test stage. - module load GDAL/2.2.1-foss-2015a - module load PROJ/4.8.0-foss-2015a - module list - - echo "Running lintr unit tests..." + - echo "Running lint tests..." - Rscript ./tests/test_lintr.R diff --git a/tests/testthat/test-lintr_hardcoded_paths.R b/tests/testthat/test-lintr_hardcoded_paths.R index 6616e747..f5a62cef 100644 --- a/tests/testthat/test-lintr_hardcoded_paths.R +++ b/tests/testthat/test-lintr_hardcoded_paths.R @@ -18,13 +18,15 @@ detect_hardcoded_paths <- function() { # Check results and print out the test outcome if (any(sapply(files_with_issues, function(x) length(x) > 0))) { - cat("Test FAILED. Hard-coded paths found:\n") + cat("Test FAILED. Absolute paths found:\n") print(files_with_issues) return(FALSE) } else { - cat("Test PASSED🥳 No hard-coded paths found in any file.\n") + cat("No absolute paths found in any file.\n") return(TRUE) } } -detect_hardcoded_paths() +test_that("Check code for absolute paths", { + expect_true(detect_hardcoded_paths()) +}) -- GitLab From 904288e4bf592d08d9dc0c680dbc6b1759758494 Mon Sep 17 00:00:00 2001 From: vagudets Date: Wed, 8 May 2024 09:34:17 +0200 Subject: [PATCH 14/14] Fix atomic recipe file path --- tools/divide_recipe.R | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/tools/divide_recipe.R b/tools/divide_recipe.R index 1f83d63c..ddaff215 100644 --- a/tools/divide_recipe.R +++ b/tools/divide_recipe.R @@ -198,7 +198,8 @@ divide_recipe <- function(recipe) { chunk <- chunk + 1 } write_yaml(all_recipes[[reci]], - paste0(recipe_dir, "atomic_recipe_", recipe_name, ".yml")) + file.path(recipe_dir, + paste0("atomic_recipe_", recipe_name, ".yml"))) } # Print information for user -- GitLab