From 53a283674d99f77af9f0514f88e910b4e8eddfcd Mon Sep 17 00:00:00 2001 From: ARIADNA BATALLA FERRES Date: Wed, 15 Jan 2025 16:18:15 +0100 Subject: [PATCH 01/17] Copy plot_ensemble_mean.R and test-seasonal_visualization_metadata.R from dev-test_vis_dots --- modules/Visualization/R/plot_ensemble_mean.R | 30 +- .../test-seasonal_visualization_metadata.R | 319 ++++++++++++++++++ 2 files changed, 348 insertions(+), 1 deletion(-) create mode 100644 tests/testthat/test-seasonal_visualization_metadata.R diff --git a/modules/Visualization/R/plot_ensemble_mean.R b/modules/Visualization/R/plot_ensemble_mean.R index 31a20e55..cc8b36b6 100644 --- a/modules/Visualization/R/plot_ensemble_mean.R +++ b/modules/Visualization/R/plot_ensemble_mean.R @@ -1,4 +1,5 @@ -plot_ensemble_mean <- function(recipe, fcst, mask = NULL, dots = NULL, outdir, output_conf) { +plot_ensemble_mean <- function(recipe, fcst, mask = NULL, dots = NULL, outdir, + output_conf, return_elements = FALSE) { ## TODO: Add 'anomaly' to plot title # Abort if frequency is daily if (recipe$Analysis$Variables$freq %in% c("daily", "daily_mean")) { @@ -258,6 +259,33 @@ plot_ensemble_mean <- function(recipe, fcst, mask = NULL, dots = NULL, outdir, o } } } + if (return_elements) { + elements <- list( + latitude = latitude, + longitude = longitude, + system_name = system_name, + start_date = start_date, + init_date = init_date, + projection = projection, + ensemble_mean = ensemble_mean, + palette = if (exists("palette")) palette else NULL, + brks = if (exists("brks")) brks else NULL, + cols = if (exists("cols")) brks else NULL, + toptitle = if (exists("toptitle")) toptitle else NULL, + labels = if (exists("labels")) labels else NULL, + time_labels = if (exists("time_labels")) time_labels else NULL, + var_mask = if (exists("var_mask")) var_mask else NULL, + dim_mask = if (exists("dim_mask")) dim_mask else NULL, + var_dots = if (exists("var_dots")) var_dots else NULL, + dim_dots = if (exists("dim_dots")) dim_dots else NULL, + years = if (exists("years")) years else NULL, + toptitle = if (exists("toptitle")) toptitle else NULL, + forecast_time_caption = if (exists("forecast_time_caption")) + forecast_time_caption else NULL, + fileout = if (exists("fileout")) fileout else NULL + ) + return(elements) + } info(recipe$Run$logger, "##### FORECAST ENSEMBLE MEAN PLOTS SAVED TO OUTPUT DIRECTORY #####") } diff --git a/tests/testthat/test-seasonal_visualization_metadata.R b/tests/testthat/test-seasonal_visualization_metadata.R new file mode 100644 index 00000000..72876bca --- /dev/null +++ b/tests/testthat/test-seasonal_visualization_metadata.R @@ -0,0 +1,319 @@ +# Seasonal monthly data + +## TO REMOVE ## **************************************************************** +## setwd("/home/Earth/abatalla/SUNSET_RS_GIT/sunset") ## dev +## # setwd("/home/Earth/abatalla/SUNSET_RS_GIT/sunset/tests/testthat") +## library(testthat) +# ****************************************************************************** + +source("modules/Loading/Loading.R") +source("modules/Units/Units.R") +source("modules/Calibration/Calibration.R") +source("modules/Skill/Skill.R") +source("modules/Anomalies/Anomalies.R") +source("modules/Saving/Saving.R") +source("modules/Visualization/Visualization.R") + + +recipe_file <- "./tests/recipes/recipe-seasonal_visualization.yml" +recipe <- prepare_outputs(recipe_file, disable_checks = FALSE) + +# Load datasets +suppressWarnings({invisible(capture.output( + data <- Loading(recipe) +))}) + +# Units transformation +suppressWarnings({invisible(capture.output( + data <- Units(recipe, data) +))}) + +# Calibrate data +suppressWarnings({invisible(capture.output( + data <- Calibration(recipe, data) +))}) + +# Compute skill metrics +suppressWarnings({invisible(capture.output( + skill_metrics <- Skill(recipe, data) +))}) + +# Compute percentiles and probability bins +suppressWarnings({invisible(capture.output( + probabilities <- Probabilities(recipe, data) +))}) + + + +# ------- TESTS -------- + + +test_that("1. Loading", { + + expect_equal( + is.list(data), + TRUE + ) + + expect_true( + all(c("hcst", "fcst", "obs") %in% names(data)) + ) + + expect_equal( + class(data$hcst), + "s2dv_cube" + ) + + expect_equal( + class(data$fcst), + "s2dv_cube" + ) + + expect_equal( + class(data$obs), + "s2dv_cube" + ) + + expect_equal( + names(data$hcst), + c("data", "dims", "coords", "attrs") + ) + + expect_equal( + names(data$hcst), + names(data$fcst) + ) + + expect_equal( + names(data$hcst), + names(data$obs) + ) + + expect_equal( + dim(data$hcst$data), + c(dat = 1, var = 1, sday = 1, sweek = 1, syear = 4, time = 1, latitude = 12, longitude = 15, ensemble = 25) + ) + + expect_equal( + dim(data$fcst$data), + c(dat = 1, var = 1, sday = 1, sweek = 1, syear = 1, time = 1, latitude = 12, longitude = 15, ensemble = 51) + ) + + expect_equal( + dim(data$hcst$attrs$Dates), + c(sday = 1, sweek = 1, syear = 4, time = 1) + ) + +}) + + +# ---------------------- + + +# output_conf <- read_yaml("modules/Visualization/output_size.yml", +# eval.exp = TRUE)$region +# outdir <- "./tests/testthat/_snaps/" ## "./_snaps/" ## dev: "./tests/testthat/_snaps/" +# pem_elements <- plot_ensemble_mean(recipe = recipe, fcst = data$fcst, +# mask = NULL, dots = NULL, +# outdir = outdir, output_conf = output_conf, +# return_elements = TRUE) +# +# test_that("2. Test plot_ensemble_mean()", { +# +# expect_equal( +# pem_elements$latitude[1], +# 34.5 +# ) +# +# expect_equal( +# pem_elements$longitude[1], +# -9.5 +# ) +# +# expect_equal( +# pem_elements$system_name, +# "ECMWF SEAS5 (v5.1)" +# ) +# +# expect_equal( +# pem_elements$start_date, +# "20230601" +# ) +# +# expect_equal( +# pem_elements$init_date, +# 6 +# ) +# +# expect_equal( +# pem_elements$projection, +# "robinson" +# ) +# +# expect_equal( +# pem_elements$ensemble_mean[, , 1, 1, 1, 1, 1, 1], +# 295.0356, +# tolerance = 0.001 +# ) +# +# expect_equal( +# pem_elements$palette, +# "RdBu" +# ) +# +# expect_equal( +# pem_elements$brks[1:3], +# c(284, 285, 286) +# ) +# +# expect_equal( +# pem_elements$cols[1:3], +# c(284, 285, 286) +# ) +# +# expect_equal( +# pem_elements$toptitle, +# "ECMWF SEAS5 (v5.1) / 2 Metre Temperature\nEnsemble Mean / June 2023 / Start date: 01-06-2023" +# ) +# +# expect_equal( +# class(pem_elements$labels$time_labels), +# c("ordered", "factor") +# ) +# +# expect_equal( +# pem_elements$labels$years, +# 2023 +# ) +# +# }) + + + +# --- SNAPSHOT TESTS --- + +Sys.setenv(TESTTHAT_EDITION = "3") + +outdir <- "./tests/testthat/_snaps/seasonal_visualization_metadata/" + +output_conf <- read_yaml("modules/Visualization/output_size.yml", + eval.exp = TRUE)$region + + +# plot_ensemble_mean + +save_fun_1 <- function(...) { + path <- "./tests/testthat/_snaps/seasonal_visualization_metadata/" ## dev: "./_snaps/" + do.call(plot_ensemble_mean, list(...)) + return(path) +} + +rpss_sig <- skill_metrics$rpss_significance +rpss_sig[1, 1, 1:6, ] <- TRUE + +test_that("2. Snapshot checks: plot_ensemble_mean", { + + expect_snapshot_file( + paste0(save_fun_1(recipe = recipe, fcst = data$fcst, + outdir = outdir, output_conf = output_conf), + "forecast_ensemble_mean-20230601_ft01.png"), + name = "forecast_ensemble_mean-20230601_ft01.png") + + expect_snapshot_file( + paste0(save_fun_1(recipe = recipe, fcst = data$fcst, dots = rpss_sig, + outdir = outdir, output_conf = output_conf), + "forecast_ensemble_mean-20230601_enscordots_ft01.png"), + name = "forecast_ensemble_mean-20230601_enscordots_ft01.png") + + expect_snapshot_file( + paste0(save_fun_1(recipe = recipe, fcst = data$fcst, mask = rpss_sig, + outdir = outdir, output_conf = output_conf), + "forecast_ensemble_mean-20230601_enscormask_ft01.png"), + name = "forecast_ensemble_mean-20230601_enscormask_ft01.png") +}) + + +# ---------------------- + +# plot_metrics + +save_fun_2 <- function(...) { + path <- "./tests/testthat/_snaps/seasonal_visualization_metadata/" + do.call(plot_metrics, list(...)) + return(path) +} + +skill_metrics$rpss_significance[1, 1, 1:6, ] <- TRUE + +test_that("3. Snapshot checks: plot_metrics", { + + expect_snapshot_file( + paste0(save_fun_2(recipe = recipe, data_cube = data$hcst, + metrics = skill_metrics, outdir = outdir, + significance = FALSE, output_conf = output_conf), + "rpss-june_ft01.png"), + name = "rpss-june_ft01.png") + + expect_snapshot_file( + paste0(save_fun_2(recipe = recipe, data_cube = data$hcst, + metrics = skill_metrics, outdir = outdir, + significance = TRUE, output_conf = output_conf), + "rpss-june_ft01_mask.png"), + name = "rpss-june_ft01_mask.png") + +}) + + +# ---------------------- + +# plot_most_likely_terciles + +save_fun_3 <- function(...) { + path <- "./tests/testthat/_snaps/seasonal_visualization_metadata/" + do.call(plot_most_likely_terciles, list(...)) + return(path) +} + +test_that("4. Snapshot checks: plot_most_likely_terciles", { + + expect_snapshot_file( + paste0(save_fun_3(recipe = recipe, fcst = data$fcst, + probabilities = probabilities, + mask = NULL, dots = NULL, + outdir = outdir, output_conf = output_conf), + "forecast_most_likely_tercile-20230601_ft01.png"), + name = "forecast_most_likely_tercile-20230601_ft01.png") + + expect_snapshot_file( + paste0(save_fun_3(recipe = recipe, fcst = data$fcst, + probabilities = probabilities, + mask = rpss_sig, dots = NULL, + outdir = outdir, output_conf = output_conf), + "forecast_most_likely_tercile-20230601_rpssmask_ft01.png"), + name = "forecast_most_likely_tercile-20230601_rpssmask_ft01.png") + + expect_snapshot_file( + paste0(save_fun_3(recipe = recipe, fcst = data$fcst, + probabilities = probabilities, + mask = NULL, dots = rpss_sig, + outdir = outdir, output_conf = output_conf), + "forecast_most_likely_tercile-20230601_rpssdots_ft01.png"), + name = "forecast_most_likely_tercile-20230601_rpssdots_ft01.png") + +}) + +# Remove the pdf files +unlink(list.files(outdir, pattern = "\\.pdf$", full.names = TRUE)) + +# ---------------------- + +# To test locally: +# testthat::test_file("./tests/testthat/test-seasonal_visualization_metadata.R") + + +# How the snapshot tests work: +# the "save_fun" part creates the new plot, by default a pdf. It needs a name +# It is then compared to the png in the "name" part. +# If they are different, a png with the plot created in "save_fun" is created with the name from the "name" part + ".new". +# The first part needs a name so that it can be compared. Otherwise an empty ".new" png is created. +# Summarizing: now a pdf and a png (from the png) are created, If the png is the same as the one that exists, the test passes. -- GitLab From 2bc82302202ccebb4928d88d22322d053f625979 Mon Sep 17 00:00:00 2001 From: ARIADNA BATALLA FERRES Date: Wed, 15 Jan 2025 16:23:34 +0100 Subject: [PATCH 02/17] Add tests/recipes/recipe-seasonal_visualization.yml --- .../recipes/recipe-seasonal_visualization.yml | 65 +++++++++++++++++++ 1 file changed, 65 insertions(+) create mode 100644 tests/recipes/recipe-seasonal_visualization.yml diff --git a/tests/recipes/recipe-seasonal_visualization.yml b/tests/recipes/recipe-seasonal_visualization.yml new file mode 100644 index 00000000..1223c30d --- /dev/null +++ b/tests/recipes/recipe-seasonal_visualization.yml @@ -0,0 +1,65 @@ +Description: + Author: nperez + Info: ECVs Oper ESS ECMWF SEAS5 Seasonal Forecast recipe (monthly mean, tas) + +Analysis: + Horizon: seasonal # Mandatory, str: either subseasonal, seasonal, or decadal + Variables: + name: tas + freq: monthly_mean + units: K + Datasets: + System: + name: ECMWF-SEAS5.1 # Mandatory, str: system5c3s system21_m1 system35c3s + Multimodel: no # Mandatory, bool: Either yes/true or no/false + Reference: + name: ERA5 # Mandatory, str: Reference codename. See docu. + Time: + sdate: '0601' ## MMDD + fcst_year: '2023' # Optional, int: Forecast year 'YYYY' + hcst_start: '2013' # Mandatory, int: Hindcast start year 'YYYY' + hcst_end: '2016' # Mandatory, int: Hindcast end year 'YYYY' + ftime_min: 1 # Mandatory, int: First leadtime time step in months + ftime_max: 1 # Mandatory, int: Last leadtime time step in months + Region: + latmin: 34 + latmax: 46 + lonmin: -10 + lonmax: 5 + Regrid: + method: bilinear # Mandatory, str: Interpolation method. See docu. + type: "to_system" + #type: /esarchive/scratch/nmilders/gitlab/git_clones/auto-s2s/conf/grid_description.txt #'r360x180' # Mandatory, str: to_system, to_reference, or CDO-accepted grid. + Workflow: + Anomalies: + compute: no + cross_validation: no + save: none + Calibration: + method: evmos # Mandatory, str: Calibration method. See docu. + cross_validation: yes + save: none + Skill: + metric: rpss + save: 'all' + cross_validation: yes + Probabilities: + percentiles: [[1/3, 2/3], [1/10, 9/10]] # frac: Quantile thresholds. + save: 'all' + Indicators: + index: no + Visualization: + plots: forecast_ensemble_mean skill_metrics + multi_panel: no + projection: 'robinson' + mask_terciles: both + file_format: 'PNG' + ncores: 4 # Optional, int: number of cores, defaults to 1 + remove_NAs: # Optional, bool: Whether NAs are removed, defaults to FALSE + Output_format: scorecards + logo: yes +Run: + Loglevel: INFO + Terminal: TRUE + output_dir: ./tests/out-logs/ ## dev: ../out-logs/ + code_dir: /esarchive/scratch/nperez/git6/sunset/ -- GitLab From 0aa1439e49d2c5d8e32f13cf13c4cf88eb7d079a Mon Sep 17 00:00:00 2001 From: ARIADNA BATALLA FERRES Date: Wed, 15 Jan 2025 17:06:19 +0100 Subject: [PATCH 03/17] Keep metadata checks and Remove snapshot checks --- .../test-seasonal_visualization_metadata.R | 245 +++++------------- 1 file changed, 60 insertions(+), 185 deletions(-) diff --git a/tests/testthat/test-seasonal_visualization_metadata.R b/tests/testthat/test-seasonal_visualization_metadata.R index 72876bca..9186b896 100644 --- a/tests/testthat/test-seasonal_visualization_metadata.R +++ b/tests/testthat/test-seasonal_visualization_metadata.R @@ -2,9 +2,8 @@ ## TO REMOVE ## **************************************************************** ## setwd("/home/Earth/abatalla/SUNSET_RS_GIT/sunset") ## dev -## # setwd("/home/Earth/abatalla/SUNSET_RS_GIT/sunset/tests/testthat") ## library(testthat) -# ****************************************************************************** +## ****************************************************************************** source("modules/Loading/Loading.R") source("modules/Units/Units.R") @@ -110,210 +109,86 @@ test_that("1. Loading", { # ---------------------- -# output_conf <- read_yaml("modules/Visualization/output_size.yml", -# eval.exp = TRUE)$region -# outdir <- "./tests/testthat/_snaps/" ## "./_snaps/" ## dev: "./tests/testthat/_snaps/" -# pem_elements <- plot_ensemble_mean(recipe = recipe, fcst = data$fcst, -# mask = NULL, dots = NULL, -# outdir = outdir, output_conf = output_conf, -# return_elements = TRUE) -# -# test_that("2. Test plot_ensemble_mean()", { -# -# expect_equal( -# pem_elements$latitude[1], -# 34.5 -# ) -# -# expect_equal( -# pem_elements$longitude[1], -# -9.5 -# ) -# -# expect_equal( -# pem_elements$system_name, -# "ECMWF SEAS5 (v5.1)" -# ) -# -# expect_equal( -# pem_elements$start_date, -# "20230601" -# ) -# -# expect_equal( -# pem_elements$init_date, -# 6 -# ) -# -# expect_equal( -# pem_elements$projection, -# "robinson" -# ) -# -# expect_equal( -# pem_elements$ensemble_mean[, , 1, 1, 1, 1, 1, 1], -# 295.0356, -# tolerance = 0.001 -# ) -# -# expect_equal( -# pem_elements$palette, -# "RdBu" -# ) -# -# expect_equal( -# pem_elements$brks[1:3], -# c(284, 285, 286) -# ) -# -# expect_equal( -# pem_elements$cols[1:3], -# c(284, 285, 286) -# ) -# -# expect_equal( -# pem_elements$toptitle, -# "ECMWF SEAS5 (v5.1) / 2 Metre Temperature\nEnsemble Mean / June 2023 / Start date: 01-06-2023" -# ) -# -# expect_equal( -# class(pem_elements$labels$time_labels), -# c("ordered", "factor") -# ) -# -# expect_equal( -# pem_elements$labels$years, -# 2023 -# ) -# -# }) - - - -# --- SNAPSHOT TESTS --- - -Sys.setenv(TESTTHAT_EDITION = "3") - -outdir <- "./tests/testthat/_snaps/seasonal_visualization_metadata/" - output_conf <- read_yaml("modules/Visualization/output_size.yml", eval.exp = TRUE)$region +outdir <- "./tests/testthat/_snaps/" ## "./_snaps/" ## dev: "./tests/testthat/_snaps/" +pem_elements <- plot_ensemble_mean(recipe = recipe, fcst = data$fcst, + mask = NULL, dots = NULL, + outdir = outdir, output_conf = output_conf, + return_elements = TRUE) +test_that("2. Test metadata plot_ensemble_mean()", { -# plot_ensemble_mean + expect_equal( + pem_elements$latitude[1], + 34.5 + ) -save_fun_1 <- function(...) { - path <- "./tests/testthat/_snaps/seasonal_visualization_metadata/" ## dev: "./_snaps/" - do.call(plot_ensemble_mean, list(...)) - return(path) -} + expect_equal( + pem_elements$longitude[1], + -9.5 + ) -rpss_sig <- skill_metrics$rpss_significance -rpss_sig[1, 1, 1:6, ] <- TRUE + expect_equal( + pem_elements$system_name, + "ECMWF SEAS5 (v5.1)" + ) -test_that("2. Snapshot checks: plot_ensemble_mean", { - - expect_snapshot_file( - paste0(save_fun_1(recipe = recipe, fcst = data$fcst, - outdir = outdir, output_conf = output_conf), - "forecast_ensemble_mean-20230601_ft01.png"), - name = "forecast_ensemble_mean-20230601_ft01.png") - - expect_snapshot_file( - paste0(save_fun_1(recipe = recipe, fcst = data$fcst, dots = rpss_sig, - outdir = outdir, output_conf = output_conf), - "forecast_ensemble_mean-20230601_enscordots_ft01.png"), - name = "forecast_ensemble_mean-20230601_enscordots_ft01.png") - - expect_snapshot_file( - paste0(save_fun_1(recipe = recipe, fcst = data$fcst, mask = rpss_sig, - outdir = outdir, output_conf = output_conf), - "forecast_ensemble_mean-20230601_enscormask_ft01.png"), - name = "forecast_ensemble_mean-20230601_enscormask_ft01.png") -}) + expect_equal( + pem_elements$start_date, + "20230601" + ) + expect_equal( + pem_elements$init_date, + 6 + ) -# ---------------------- + expect_equal( + pem_elements$projection, + "robinson" + ) -# plot_metrics + expect_equal( + pem_elements$ensemble_mean[, , 1, 1, 1, 1, 1, 1], + 295.0356, + tolerance = 0.001 + ) -save_fun_2 <- function(...) { - path <- "./tests/testthat/_snaps/seasonal_visualization_metadata/" - do.call(plot_metrics, list(...)) - return(path) -} + expect_equal( + pem_elements$palette, + "RdBu" + ) -skill_metrics$rpss_significance[1, 1, 1:6, ] <- TRUE + expect_equal( + pem_elements$brks[1:3], + c(284, 285, 286) + ) -test_that("3. Snapshot checks: plot_metrics", { - - expect_snapshot_file( - paste0(save_fun_2(recipe = recipe, data_cube = data$hcst, - metrics = skill_metrics, outdir = outdir, - significance = FALSE, output_conf = output_conf), - "rpss-june_ft01.png"), - name = "rpss-june_ft01.png") - - expect_snapshot_file( - paste0(save_fun_2(recipe = recipe, data_cube = data$hcst, - metrics = skill_metrics, outdir = outdir, - significance = TRUE, output_conf = output_conf), - "rpss-june_ft01_mask.png"), - name = "rpss-june_ft01_mask.png") - -}) + expect_equal( + pem_elements$cols[1:3], + c(284, 285, 286) + ) + expect_equal( + pem_elements$toptitle, + "ECMWF SEAS5 (v5.1) / 2 Metre Temperature\nEnsemble Mean / June 2023 / Start date: 01-06-2023" + ) -# ---------------------- + expect_equal( + class(pem_elements$labels$time_labels), + c("ordered", "factor") + ) -# plot_most_likely_terciles - -save_fun_3 <- function(...) { - path <- "./tests/testthat/_snaps/seasonal_visualization_metadata/" - do.call(plot_most_likely_terciles, list(...)) - return(path) -} - -test_that("4. Snapshot checks: plot_most_likely_terciles", { - - expect_snapshot_file( - paste0(save_fun_3(recipe = recipe, fcst = data$fcst, - probabilities = probabilities, - mask = NULL, dots = NULL, - outdir = outdir, output_conf = output_conf), - "forecast_most_likely_tercile-20230601_ft01.png"), - name = "forecast_most_likely_tercile-20230601_ft01.png") - - expect_snapshot_file( - paste0(save_fun_3(recipe = recipe, fcst = data$fcst, - probabilities = probabilities, - mask = rpss_sig, dots = NULL, - outdir = outdir, output_conf = output_conf), - "forecast_most_likely_tercile-20230601_rpssmask_ft01.png"), - name = "forecast_most_likely_tercile-20230601_rpssmask_ft01.png") - - expect_snapshot_file( - paste0(save_fun_3(recipe = recipe, fcst = data$fcst, - probabilities = probabilities, - mask = NULL, dots = rpss_sig, - outdir = outdir, output_conf = output_conf), - "forecast_most_likely_tercile-20230601_rpssdots_ft01.png"), - name = "forecast_most_likely_tercile-20230601_rpssdots_ft01.png") + expect_equal( + pem_elements$labels$years, + 2023 + ) }) -# Remove the pdf files -unlink(list.files(outdir, pattern = "\\.pdf$", full.names = TRUE)) # ---------------------- # To test locally: # testthat::test_file("./tests/testthat/test-seasonal_visualization_metadata.R") - - -# How the snapshot tests work: -# the "save_fun" part creates the new plot, by default a pdf. It needs a name -# It is then compared to the png in the "name" part. -# If they are different, a png with the plot created in "save_fun" is created with the name from the "name" part + ".new". -# The first part needs a name so that it can be compared. Otherwise an empty ".new" png is created. -# Summarizing: now a pdf and a png (from the png) are created, If the png is the same as the one that exists, the test passes. -- GitLab From 0d1ef2820a8ec45b3640f95c6cfd7d328845fd73 Mon Sep 17 00:00:00 2001 From: ARIADNA BATALLA FERRES Date: Thu, 16 Jan 2025 10:38:33 +0100 Subject: [PATCH 04/17] Change outdir in test-seasonal_visualization_metadata.R --- tests/testthat/test-seasonal_visualization_metadata.R | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/testthat/test-seasonal_visualization_metadata.R b/tests/testthat/test-seasonal_visualization_metadata.R index 9186b896..34a59103 100644 --- a/tests/testthat/test-seasonal_visualization_metadata.R +++ b/tests/testthat/test-seasonal_visualization_metadata.R @@ -111,7 +111,7 @@ test_that("1. Loading", { output_conf <- read_yaml("modules/Visualization/output_size.yml", eval.exp = TRUE)$region -outdir <- "./tests/testthat/_snaps/" ## "./_snaps/" ## dev: "./tests/testthat/_snaps/" +outdir <- "./tests/out-logs/" pem_elements <- plot_ensemble_mean(recipe = recipe, fcst = data$fcst, mask = NULL, dots = NULL, outdir = outdir, output_conf = output_conf, -- GitLab From eb1dfd290c98805cd13606ff44e5bff342d1f761 Mon Sep 17 00:00:00 2001 From: ARIADNA BATALLA FERRES Date: Wed, 19 Mar 2025 12:10:40 +0100 Subject: [PATCH 05/17] Update tests/testthat/test-seasonal_visualization_metadata.R --- .../test-seasonal_visualization_metadata.R | 53 +++++++++---------- 1 file changed, 26 insertions(+), 27 deletions(-) diff --git a/tests/testthat/test-seasonal_visualization_metadata.R b/tests/testthat/test-seasonal_visualization_metadata.R index 34a59103..f2bfbea2 100644 --- a/tests/testthat/test-seasonal_visualization_metadata.R +++ b/tests/testthat/test-seasonal_visualization_metadata.R @@ -14,7 +14,7 @@ source("modules/Saving/Saving.R") source("modules/Visualization/Visualization.R") -recipe_file <- "./tests/recipes/recipe-seasonal_visualization.yml" +recipe_file <- "tests/recipes/recipe-seasonal_visualization.yml" recipe <- prepare_outputs(recipe_file, disable_checks = FALSE) # Load datasets @@ -112,76 +112,75 @@ test_that("1. Loading", { output_conf <- read_yaml("modules/Visualization/output_size.yml", eval.exp = TRUE)$region outdir <- "./tests/out-logs/" -pem_elements <- plot_ensemble_mean(recipe = recipe, fcst = data$fcst, - mask = NULL, dots = NULL, - outdir = outdir, output_conf = output_conf, - return_elements = TRUE) - -test_that("2. Test metadata plot_ensemble_mean()", { +pfm_elements <- plot_forecast_map(recipe = recipe, fcst = data$fcst, + mask = NULL, dots = NULL, + outdir = outdir, output_conf = output_conf, + return_elements = TRUE) +test_that("2. Test metadata plot_forecast_map()", { expect_equal( - pem_elements$latitude[1], + pfm_elements$latitude[1], 34.5 ) expect_equal( - pem_elements$longitude[1], + pfm_elements$longitude[1], -9.5 ) expect_equal( - pem_elements$system_name, + pfm_elements$system_name, "ECMWF SEAS5 (v5.1)" ) expect_equal( - pem_elements$start_date, + pfm_elements$start_date, "20230601" ) expect_equal( - pem_elements$init_date, + pfm_elements$init_date, 6 ) expect_equal( - pem_elements$projection, + pfm_elements$projection, "robinson" ) - expect_equal( - pem_elements$ensemble_mean[, , 1, 1, 1, 1, 1, 1], - 295.0356, - tolerance = 0.001 - ) + # expect_equal( + # pfm_elements$ensemble_mean[, , 1, 1, 1, 1, 1, 1], + # 295.0356, + # tolerance = 0.001 + # ) expect_equal( - pem_elements$palette, + pfm_elements$palette, "RdBu" ) expect_equal( - pem_elements$brks[1:3], - c(284, 285, 286) + pfm_elements$brks[1:3], + c(-350, -300, -250) ) expect_equal( - pem_elements$cols[1:3], - c(284, 285, 286) + pfm_elements$cols[1:3], + c(-350, -300, -250) ) expect_equal( - pem_elements$toptitle, - "ECMWF SEAS5 (v5.1) / 2 Metre Temperature\nEnsemble Mean / June 2023 / Start date: 01-06-2023" + pfm_elements$toptitle, + "ECMWF SEAS5 (v5.1) / 2 Metre Temperature\nEnsemble median / June 2023 / Start date: 01-06-2023" ) expect_equal( - class(pem_elements$labels$time_labels), + class(pfm_elements$labels$time_labels), c("ordered", "factor") ) expect_equal( - pem_elements$labels$years, + pfm_elements$labels$years, 2023 ) -- GitLab From dc67284d4adc24142e71772020d35a80a72c0428 Mon Sep 17 00:00:00 2001 From: ARIADNA BATALLA FERRES Date: Wed, 19 Mar 2025 16:24:20 +0100 Subject: [PATCH 06/17] Add checks for plot_metrics() --- modules/Visualization/R/plot_forecast_map.R | 1 - modules/Visualization/R/plot_metrics.R | 18 ++++++- .../test-seasonal_visualization_metadata.R | 49 +++++++++++++++++++ 3 files changed, 66 insertions(+), 2 deletions(-) diff --git a/modules/Visualization/R/plot_forecast_map.R b/modules/Visualization/R/plot_forecast_map.R index 3fac64e5..c84f937b 100644 --- a/modules/Visualization/R/plot_forecast_map.R +++ b/modules/Visualization/R/plot_forecast_map.R @@ -344,7 +344,6 @@ plot_forecast_map <- function(recipe, fcst, mask = NULL, dots = NULL, var_dots = if (exists("var_dots")) var_dots else NULL, dim_dots = if (exists("dim_dots")) dim_dots else NULL, years = if (exists("years")) years else NULL, - toptitle = if (exists("toptitle")) toptitle else NULL, forecast_time_caption = if (exists("forecast_time_caption")) forecast_time_caption else NULL, fileout = if (exists("fileout")) fileout else NULL diff --git a/modules/Visualization/R/plot_metrics.R b/modules/Visualization/R/plot_metrics.R index fb799191..b7846d87 100644 --- a/modules/Visualization/R/plot_metrics.R +++ b/modules/Visualization/R/plot_metrics.R @@ -3,7 +3,7 @@ library(lubridate) plot_metrics <- function(recipe, data_cube, metrics, outdir, significance = F, output_conf, - logo = NULL) { + logo = NULL, return_elements = FALSE) { # recipe: Auto-S2S recipe # archive: Auto-S2S archive # data_cube: s2dv_cube object with the corresponding hindcast data @@ -498,6 +498,22 @@ plot_metrics <- function(recipe, data_cube, metrics, } } } + if (return_elements) { + elements <- list( + latitude = latitude, + longitude = longitude, + system_name = system_name, + start_date = start_date, + projection = projection, + brks = if (exists("brks")) brks else NULL, + cols = if (exists("cols")) brks else NULL, + toptitle = if (exists("toptitle")) toptitle else NULL, + nominal_startdate_caption = nominal_startdate_caption, + forecast_time_caption = forecast_time_caption, + fileout = if (exists("fileout")) fileout else NULL + ) + return(elements) + } info(recipe$Run$logger, "##### SKILL METRIC PLOTS SAVED TO OUTPUT DIRECTORY #####") } diff --git a/tests/testthat/test-seasonal_visualization_metadata.R b/tests/testthat/test-seasonal_visualization_metadata.R index f2bfbea2..a3bec504 100644 --- a/tests/testthat/test-seasonal_visualization_metadata.R +++ b/tests/testthat/test-seasonal_visualization_metadata.R @@ -187,6 +187,55 @@ test_that("2. Test metadata plot_forecast_map()", { }) +# ---------------------- + +skill_metrics$rpss_significance[1, 1, 1:6, ] <- TRUE + +pm_elements <- plot_metrics(recipe = recipe, data_cube = data$hcst, + metrics = skill_metrics, outdir = outdir, + output_conf = output_conf, + return_elements = TRUE) + +test_that("3. Test metadata plot_metrics()", { + + expect_equal( + pm_elements$start_date, + "0601" + ) + + expect_equal( + pm_elements$brks, + c(-1.0, -0.8, -0.6, -0.4, -0.2, 0.0, 0.2, 0.4, 0.6, 0.8, 1.0) + ) + + expect_equal( + pm_elements$cols, + c(-1.0, -0.8, -0.6, -0.4, -0.2, 0.0, 0.2, 0.4, 0.6, 0.8, 1.0) + ) + + expect_equal( + pm_elements$toptitle, + "ECMWF SEAS5 (v5.1) / 2 Metre Temperature \n RPSS / June / 2013-2016" + ) + + expect_equal( + pm_elements$nominal_startdate_caption, + "1st of June" + ) + + expect_equal( + pm_elements$forecast_time_caption, + "Forecast month: 01" + ) + + # expect_equal( + # pm_elements$fileout, + # "./tests/out-logs/rpss-june_ft01.png" + # ) + +}) + + # ---------------------- # To test locally: -- GitLab From 0f0a8f979c7119d20eec5c1d5e097455f155f465 Mon Sep 17 00:00:00 2001 From: ARIADNA BATALLA FERRES Date: Wed, 19 Mar 2025 16:40:47 +0100 Subject: [PATCH 07/17] Commenting potentially unnecessary elements in plot_metrics.R --- modules/Visualization/R/plot_metrics.R | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/modules/Visualization/R/plot_metrics.R b/modules/Visualization/R/plot_metrics.R index b7846d87..86b28be7 100644 --- a/modules/Visualization/R/plot_metrics.R +++ b/modules/Visualization/R/plot_metrics.R @@ -500,11 +500,11 @@ plot_metrics <- function(recipe, data_cube, metrics, } if (return_elements) { elements <- list( - latitude = latitude, - longitude = longitude, - system_name = system_name, + # latitude = latitude, + # longitude = longitude, + # system_name = system_name, start_date = start_date, - projection = projection, + # projection = projection, brks = if (exists("brks")) brks else NULL, cols = if (exists("cols")) brks else NULL, toptitle = if (exists("toptitle")) toptitle else NULL, -- GitLab From 8f65bae8ec5bc026bb411a0aaaa76d0d934ba1a8 Mon Sep 17 00:00:00 2001 From: ARIADNA BATALLA FERRES Date: Wed, 19 Mar 2025 17:37:41 +0100 Subject: [PATCH 08/17] Add checks for lot_most_likely_terciles_map.R --- .../R/plot_most_likely_terciles_map.R | 31 +++++++-- .../test-seasonal_visualization_metadata.R | 65 +++++++++++++++++++ 2 files changed, 91 insertions(+), 5 deletions(-) diff --git a/modules/Visualization/R/plot_most_likely_terciles_map.R b/modules/Visualization/R/plot_most_likely_terciles_map.R index 886db225..d42f6655 100644 --- a/modules/Visualization/R/plot_most_likely_terciles_map.R +++ b/modules/Visualization/R/plot_most_likely_terciles_map.R @@ -13,11 +13,12 @@ source("modules/Visualization/R/tmp/GradientCatsColorBar.R") plot_most_likely_terciles <- function(recipe, fcst, probabilities, - mask, - dots, + mask = NULL, + dots = NULL, outdir, output_conf, - logo = NULL) { + logo = NULL, + return_elements = FALSE) { ## TODO: Add 'anomaly' to plot title # Abort if frequency is daily @@ -339,6 +340,26 @@ plot_most_likely_terciles <- function(recipe, } } } -info(recipe$Run$logger, - "##### MOST LIKELY TERCILE PLOTS SAVED TO OUTPUT DIRECTORY #####") + if (return_elements) { + elements <- list( + # latitude = latitude, + # longitude = longitude, + # system_name = system_name, + start_date = start_date, + init_date = init_date, + # projection = projection, + brks = if (exists("brks")) brks else NULL, + cols = if (exists("cols")) cols else NULL, + toptitle = if (exists("toptitle")) toptitle else NULL, + labels = if (exists("labels")) labels else NULL, + time_labels = if (exists("time_labels")) time_labels else NULL, + forecast_time = if (exists("forecast_time")) forecast_time else NULL, + years = if (exists("years")) years else NULL, + toptitle = if (exists("toptitle")) toptitle else NULL, + fileout = if (exists("fileout")) fileout else NULL + ) + return(elements) + } + info(recipe$Run$logger, + "##### MOST LIKELY TERCILE PLOTS SAVED TO OUTPUT DIRECTORY #####") } diff --git a/tests/testthat/test-seasonal_visualization_metadata.R b/tests/testthat/test-seasonal_visualization_metadata.R index a3bec504..6a4f0acd 100644 --- a/tests/testthat/test-seasonal_visualization_metadata.R +++ b/tests/testthat/test-seasonal_visualization_metadata.R @@ -238,5 +238,70 @@ test_that("3. Test metadata plot_metrics()", { # ---------------------- +pmlt_elements <- plot_most_likely_terciles(recipe = recipe, + fcst = data$fcst, + probabilities = probabilities, + outdir = outdir, + output_conf = output_conf, + return_elements = TRUE) + +test_that("3. Test metadata plot_metrics()", { + + expect_equal( + pmlt_elements$start_date, + "20230601" + ) + + expect_equal( + pmlt_elements$init_date, + 6 + ) + + expect_equal( + pmlt_elements$brks, + NULL ## + ) + + expect_equal( + pmlt_elements$cols[[1]], + c("#A0E5E4", "#33BFD1") + ) + + expect_equal( + pmlt_elements$toptitle, + "ECMWF SEAS5 (v5.1) / 2 Metre Temperature\nMost Likely Tercile / June 2023 / Start date: 01-06-2023" + ) + + expect_equal( + pmlt_elements$labels[2]$years, + 2023 + ) + + expect_equal( + class(pmlt_elements$time_labels), + c("ordered", "factor") + ) + + expect_equal( + pmlt_elements$forecast_time, + "01" + ) + + expect_equal( + pmlt_elements$years, + 2023 + ) + + # expect_equal( + # pmlt_elements$fileout, + # "./tests/out-logs/forecast_most_likely_tercile-20230601_ft01.png" + # ) + +}) + + +# ---------------------- + + # To test locally: # testthat::test_file("./tests/testthat/test-seasonal_visualization_metadata.R") -- GitLab From 0616db8dbefe2c45a652467244e056cd1f114c35 Mon Sep 17 00:00:00 2001 From: ARIADNA BATALLA FERRES Date: Thu, 20 Mar 2025 17:08:51 +0100 Subject: [PATCH 09/17] Improve time_labels checks, add/remove checks and add more information to test_that() descriptions --- .../test-seasonal_visualization_metadata.R | 98 +++++++++++++------ 1 file changed, 70 insertions(+), 28 deletions(-) diff --git a/tests/testthat/test-seasonal_visualization_metadata.R b/tests/testthat/test-seasonal_visualization_metadata.R index 6a4f0acd..fe3e3857 100644 --- a/tests/testthat/test-seasonal_visualization_metadata.R +++ b/tests/testthat/test-seasonal_visualization_metadata.R @@ -116,7 +116,9 @@ pfm_elements <- plot_forecast_map(recipe = recipe, fcst = data$fcst, mask = NULL, dots = NULL, outdir = outdir, output_conf = output_conf, return_elements = TRUE) -test_that("2. Test metadata plot_forecast_map()", { +test_that("2. Test metadata plot_forecast_map(). This example has 'median' as + forecast_method, is single-panel, has a Robinson projection, and has + no masked or dotted points.", { expect_equal( pfm_elements$latitude[1], @@ -143,17 +145,6 @@ test_that("2. Test metadata plot_forecast_map()", { 6 ) - expect_equal( - pfm_elements$projection, - "robinson" - ) - - # expect_equal( - # pfm_elements$ensemble_mean[, , 1, 1, 1, 1, 1, 1], - # 295.0356, - # tolerance = 0.001 - # ) - expect_equal( pfm_elements$palette, "RdBu" @@ -175,20 +166,32 @@ test_that("2. Test metadata plot_forecast_map()", { ) expect_equal( - class(pfm_elements$labels$time_labels), - c("ordered", "factor") + as.character(pfm_elements$labels$time_labels), + "June" + ) + + expect_equal( + levels(pfm_elements$labels$time_labels), + c("January", "February", "March", "April", "May", "June", "July", + "August", "September", "October", "November", "December") ) expect_equal( pfm_elements$labels$years, 2023 ) + + expect_equal( + pfm_elements$fileout, + "./tests/out-logs/forecast_ensemble_median-20230601_ft01.png" + ) }) # ---------------------- + skill_metrics$rpss_significance[1, 1, 1:6, ] <- TRUE pm_elements <- plot_metrics(recipe = recipe, data_cube = data$hcst, @@ -196,7 +199,23 @@ pm_elements <- plot_metrics(recipe = recipe, data_cube = data$hcst, output_conf = output_conf, return_elements = TRUE) -test_that("3. Test metadata plot_metrics()", { +test_that("3. Test metadata plot_metrics(). This example is single-panel, has a + Robinson projection, and has no masked or dotted points.", { + + expect_equal( + pm_elements$latitude[1], + 34.5 + ) + + expect_equal( + pm_elements$longitude[1], + -9.5 + ) + + expect_equal( + pm_elements$system_name, + "ECMWF SEAS5 (v5.1)" + ) expect_equal( pm_elements$start_date, @@ -228,16 +247,17 @@ test_that("3. Test metadata plot_metrics()", { "Forecast month: 01" ) - # expect_equal( - # pm_elements$fileout, - # "./tests/out-logs/rpss-june_ft01.png" - # ) + expect_equal( + pm_elements$fileout, + "./tests/out-logs/rpss-june_ft01.png" + ) }) # ---------------------- + pmlt_elements <- plot_most_likely_terciles(recipe = recipe, fcst = data$fcst, probabilities = probabilities, @@ -245,7 +265,23 @@ pmlt_elements <- plot_most_likely_terciles(recipe = recipe, output_conf = output_conf, return_elements = TRUE) -test_that("3. Test metadata plot_metrics()", { +test_that("3. Test metadata plot_metrics(). This example is single-panel, has a + Robinson projection, and has no masked or dotted points.", { + + expect_equal( + pmlt_elements$latitude[1], + 34.5 + ) + + expect_equal( + pmlt_elements$longitude[1], + -9.5 + ) + + expect_equal( + pmlt_elements$system_name, + "ECMWF SEAS5 (v5.1)" + ) expect_equal( pmlt_elements$start_date, @@ -273,13 +309,19 @@ test_that("3. Test metadata plot_metrics()", { ) expect_equal( - pmlt_elements$labels[2]$years, - 2023 + as.character(pmlt_elements$labels$time_labels), + "June" ) expect_equal( - class(pmlt_elements$time_labels), - c("ordered", "factor") + levels(pmlt_elements$labels$time_labels), + c("January", "February", "March", "April", "May", "June", "July", + "August", "September", "October", "November", "December") + ) + + expect_equal( + pmlt_elements$labels$years, + 2023 ) expect_equal( @@ -292,10 +334,10 @@ test_that("3. Test metadata plot_metrics()", { 2023 ) - # expect_equal( - # pmlt_elements$fileout, - # "./tests/out-logs/forecast_most_likely_tercile-20230601_ft01.png" - # ) + expect_equal( + pmlt_elements$fileout, + "./tests/out-logs/forecast_most_likely_tercile-20230601_ft01.png" + ) }) -- GitLab From e16524b92061af8238cb12cdd449628348f99496 Mon Sep 17 00:00:00 2001 From: ARIADNA BATALLA FERRES Date: Thu, 20 Mar 2025 17:10:20 +0100 Subject: [PATCH 10/17] Update return_elements list in plot_forecast_map.R, plot_metrics.R and plot_most_likely_terciles_map.R --- modules/Visualization/R/plot_forecast_map.R | 1 - modules/Visualization/R/plot_metrics.R | 7 +++---- modules/Visualization/R/plot_most_likely_terciles_map.R | 8 +++----- 3 files changed, 6 insertions(+), 10 deletions(-) diff --git a/modules/Visualization/R/plot_forecast_map.R b/modules/Visualization/R/plot_forecast_map.R index c84f937b..1c2670b7 100644 --- a/modules/Visualization/R/plot_forecast_map.R +++ b/modules/Visualization/R/plot_forecast_map.R @@ -332,7 +332,6 @@ plot_forecast_map <- function(recipe, fcst, mask = NULL, dots = NULL, system_name = system_name, start_date = start_date, init_date = init_date, - projection = projection, palette = if (exists("palette")) palette else NULL, brks = if (exists("brks")) brks else NULL, cols = if (exists("cols")) brks else NULL, diff --git a/modules/Visualization/R/plot_metrics.R b/modules/Visualization/R/plot_metrics.R index 86b28be7..db9ef00f 100644 --- a/modules/Visualization/R/plot_metrics.R +++ b/modules/Visualization/R/plot_metrics.R @@ -500,11 +500,10 @@ plot_metrics <- function(recipe, data_cube, metrics, } if (return_elements) { elements <- list( - # latitude = latitude, - # longitude = longitude, - # system_name = system_name, + latitude = latitude, + longitude = longitude, + system_name = system_name, start_date = start_date, - # projection = projection, brks = if (exists("brks")) brks else NULL, cols = if (exists("cols")) brks else NULL, toptitle = if (exists("toptitle")) toptitle else NULL, diff --git a/modules/Visualization/R/plot_most_likely_terciles_map.R b/modules/Visualization/R/plot_most_likely_terciles_map.R index d42f6655..d6e2da32 100644 --- a/modules/Visualization/R/plot_most_likely_terciles_map.R +++ b/modules/Visualization/R/plot_most_likely_terciles_map.R @@ -342,12 +342,11 @@ plot_most_likely_terciles <- function(recipe, } if (return_elements) { elements <- list( - # latitude = latitude, - # longitude = longitude, - # system_name = system_name, + latitude = latitude, + longitude = longitude, + system_name = system_name, start_date = start_date, init_date = init_date, - # projection = projection, brks = if (exists("brks")) brks else NULL, cols = if (exists("cols")) cols else NULL, toptitle = if (exists("toptitle")) toptitle else NULL, @@ -355,7 +354,6 @@ plot_most_likely_terciles <- function(recipe, time_labels = if (exists("time_labels")) time_labels else NULL, forecast_time = if (exists("forecast_time")) forecast_time else NULL, years = if (exists("years")) years else NULL, - toptitle = if (exists("toptitle")) toptitle else NULL, fileout = if (exists("fileout")) fileout else NULL ) return(elements) -- GitLab From c67d4480d0a44c92efab580d45a3196276bdcfd6 Mon Sep 17 00:00:00 2001 From: ARIADNA BATALLA FERRES Date: Thu, 20 Mar 2025 17:15:08 +0100 Subject: [PATCH 11/17] Improve format tests/testthat/test-seasonal_visualization_metadata.R --- tests/testthat/test-seasonal_visualization_metadata.R | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/tests/testthat/test-seasonal_visualization_metadata.R b/tests/testthat/test-seasonal_visualization_metadata.R index fe3e3857..a2c180c9 100644 --- a/tests/testthat/test-seasonal_visualization_metadata.R +++ b/tests/testthat/test-seasonal_visualization_metadata.R @@ -1,9 +1,6 @@ + # Seasonal monthly data -## TO REMOVE ## **************************************************************** -## setwd("/home/Earth/abatalla/SUNSET_RS_GIT/sunset") ## dev -## library(testthat) -## ****************************************************************************** source("modules/Loading/Loading.R") source("modules/Units/Units.R") @@ -346,4 +343,5 @@ test_that("3. Test metadata plot_metrics(). This example is single-panel, has a # To test locally: +# library(testthat) # testthat::test_file("./tests/testthat/test-seasonal_visualization_metadata.R") -- GitLab From 1d321565fba542e33ec5e355ff2d59a6e7b376b8 Mon Sep 17 00:00:00 2001 From: ARIADNA BATALLA FERRES Date: Fri, 21 Mar 2025 18:30:41 +0100 Subject: [PATCH 12/17] Draft of the subseasonal visualization metadata test --- .../recipe-subseasonal_visualization.yml | 175 ++++++++++ .../test-seasonal_visualization_metadata.R | 7 +- .../test-subseasonal_visualization_metadata.R | 298 ++++++++++++++++++ 3 files changed, 477 insertions(+), 3 deletions(-) create mode 100644 tests/recipes/recipe-subseasonal_visualization.yml create mode 100644 tests/testthat/test-subseasonal_visualization_metadata.R diff --git a/tests/recipes/recipe-subseasonal_visualization.yml b/tests/recipes/recipe-subseasonal_visualization.yml new file mode 100644 index 00000000..41bd4512 --- /dev/null +++ b/tests/recipes/recipe-subseasonal_visualization.yml @@ -0,0 +1,175 @@ +# IMPORTANT: This is recipe is not intended to represent a real workflow: it is only a template showcasing ALL available options. +Description: + Author: Ariadna Batalla Ferrés + Info: Subseasonal recipe for testing the Visualization module. +Analysis: + Horizon: subseasonal # Mandatory, str: 'seasonal', or 'decadal'. Subseasonal is in development + Variables: + # name: variable name(s) in the /esarchive (Mandatory, str) + # freq: 'monthly_mean', 'daily' or 'daily_mean' (Mandatory, str) + # units: desired data units for each variable. Only available for temperature, + # precipitation, and pressure variables. +# - {name: 'tas', freq: 'weekly_mean', units: 'C'} + name: tas + freq: weekly_mean + units: C + # To request more variables to be divided in atomic recipes, add them this way: + # - {name: 'prlr', freq: 'monthly_mean', units: 'mm'} + # To request multiple variables *in the same* atomic recipe, add them this way: + # - {name: 'tas, prlr', freq: 'monthly_mean', units: {tas: 'C', prlr: 'mm'}} + Datasets: + System: + # name: System name (Mandatory, str) + # member: 'all' or individual members, separated by a comma and in quotes (decadal only, str) + - {name: 'NCEP-CFSv2', member: 'all'} + # To request more Systems to be divided in atomic recipes, add them this way: + # - {name: 'Meteo-France-System7'} + Multimodel: + execute: no # Either yes/true or no/false (Mandatory, bool) + approach: pooled # Multimodel computation approach. 'pooled' currently the only option (str) + createFrom: Anomalies # Which module should the anomalies be created from (str) + Reference: + - {name: 'ERA5'} # Reference name (Mandatory, str) + # To request more References to be divided into atomic recipes, add them this way: + # - {name: 'ERA5Land'} + Time: + sdate: 20240104 #%Y%m%d + #- '1201' # Start date, 'mmdd' (Mandatory, int) + # To request more startdates to be divided into atomic recipes, add them this way: + # - '0101' + # - '0201' + # ... + fcst_year: '2024' # Forecast initialization year 'YYYY' (Optional, int) + hcst_start: '1999' # Hindcast initialization start year 'YYYY' (Mandatory, int) + hcst_end: '2003' # Hindcast initialization end year 'YYYY' (Mandatory, int) + ftime_min: 1 # First forecast time step in months. Starts at “1”. (Mandatory, int) + ftime_max: 4 # Last forecast time step in months. Starts at “1”. (Mandatory, int) + week_day: Thursday + sweek_window: 5 + sday_window: 3 + Region: + # latmin: minimum latitude (Mandatory, int) + # latmax: maximum latitude (Mandatory, int) + # lonmin: # minimum longitude (Mandatory, int) + # lonmax: # maximum longitude (Mandatory, int) + #- {name: global, latmin: -90, latmax: 90, lonmin: 0, lonmax: 359.9} + # To request more regions to be divided in atomic recipes, add them this way: + {name: "nino34", latmin: -5, latmax: 5, lonmin: -10, lonmax: 10} + Regrid: + method: bilinear # Interpolation method (Mandatory, str) + type: to_system # Interpolate to: 'to_system', 'to_reference', 'none', + # or CDO-accepted grid. (Mandatory, str) + Workflow: + # This is the section of the recipe where the parameters for each module are specified + Calibration: + method: mse_min # Calibration method. (Mandatory, str) + save: 'all' # Options: 'all', 'none', 'exp_only', 'fcst_only' (Mandatory, str) + Anomalies: + compute: yes # Either yes/true or no/false (Mandatory, bool) + cross_validation: no # Either yes/true or no/false (Mandatory if 'compute: yes', bool) + save: 'fcst_only' # Options: 'all', 'none', 'exp_only', 'fcst_only' (Mandatory, str) + Downscaling: + # Assumption 1: leave-one-out cross-validation is always applied + # Assumption 2: for analogs, we select the best analog (minimum distance) + type: intbc # mandatory, 'none', 'int', 'intbc', 'intlr', 'analogs', 'logreg'. + int_method: conservative # regridding method accepted by CDO. (Mandatory, str) + bc_method: bias # If type=intbc. Options: 'bias', 'calibration', 'quantile_mapping', 'qm', 'evmos', 'mse_min', 'crps_min', 'rpc-based'. + lr_method: # If type=intlr. Options: 'basic', 'large_scale', '9nn' + log_reg_method: # If type=logreg. Options: 'ens_mean', 'ens_mean_sd', 'sorted_members' + target_grid: /esarchive/exp/ncep/cfs-v2/weekly_mean/s2s/tas_f24h/tas_20000202.nc # nc file or grid accepted by CDO + nanalogs: # If type analgs. Number of analogs to be searched + save: 'all' # Options: 'all'/'none'/'exp_only' (Mandatory, str) + Time_aggregation: + execute: yes # # Either yes/true or no/false. Defaults to false. (Mandatory, bool) + method: average # Aggregation method. Available methods: 'average, 'accumulated'. (Mandatory, string) + # ini and end: list, pairs initial and final time steps to aggregate. + # In this example, aggregate from 1 to 2; from 2 to 3 and from 1 to 3 + ini: [1, 2, 1] + end: [2, 3, 3] + # user_def: List of lists, Custom user-defined forecast times to aggregate. + # Elements should be named, named can be chosen by the user. + # An R expression can be entered using '!expr"; it will be evaluated by the code. + # If both ini/end and user_def are defined, ini/end takes preference. + #user_def: + # DJF_Y1: [1, 3] # aggregate from 1 to 3 forecast times + # DJF: !expr sort(c(seq(1, 120, 12), seq(2, 120, 13), seq(3, 120, 14))) # aggregate 1,2,3,13,14,15,... + Indices: + ## Indices available: - NAO (for psl and/or z500); + # - Nino1+2, Nino3, Nino3.4, Nino4 (for tos) + ## Each index can only be computed if its area is within the selected region. + # obsproj: NAO computation method (see s2dv::NAO()) Default is yes/true. (Optional, bool) + # save: What to save. Options: 'all'/'none'. Default is 'all'. + # plot_ts: Generate time series plot? Default is yes/true. (Optional, bool) + # plot_sp: Generate spatial pattern plot? Default is yes/true. (Optional, bool) + # alpha: Significance threshold. Default value is 0.05 (Optional, numeric) + #Nino1+2: {save: 'all', plot_ts: yes, plot_sp: yes, alpha: 0.05} + #Nino3: {save: 'all', plot_ts: yes, plot_sp: yes, alpha: 0.05} + #Nino3.4: {save: 'all', plot_ts: yes, plot_sp: yes, alpha: 0.05} + #Nino4: {save: 'all', plot_ts: yes, plot_sp: yes, alpha: 0.05} + # Also available if variable is psl and/or z500: + # NAO: {obsproj: yes, save: 'all', plot_ts: yes, plot_sp: yes} + Skill: + metric: mean_bias enscorr rpss crpss enssprerr # List of skill metrics separated by spaces or commas. (Mandatory, str) + save: 'all' # Options: 'all', 'none' (Mandatory, str) + Statistics: + metric: RPS RPSS # List of statistics separated by spaces or commas. (Mandatory, str) + save: 'all' # Options: 'all', 'none' (Mandatory, str) + Probabilities: + percentiles: [[1/3, 2/3]] # Thresholds + save: 'all' # Options: 'all', 'none', 'bins_only', 'percentiles_only' (Mandatory, str) + Visualization: + plots: forecast_ensemble_mean # Types of plots to generate (Optional, str) + multi_panel: no # Multi-panel plot or single-panel plots. Default is 'no/false'. (Optional, bool) + projection: 'cylindrical_equidistant' # Options: 'cylindrical_equidistant', 'robinson', 'lambert_europe'. Default is cylindrical equidistant. (Optional, str) + mask_terciles: no # Whether to mask the non-significant points by rpss in the most likely tercile plot. yes/true, no/false or 'both'. Default is no/false. (Optional, str) + dots_terciles: no # Whether to dot the non-significant by rpss in the most likely tercile plot. yes/true, no/false or 'both'. Default is no/false. (Optional, str) + mask_ens: no # Whether to mask the non-significant points by rpss in the forecast ensemble mean plot. yes/true, no/false or 'both'. Default is no/false. (Optional, str) + file_format: 'PNG' # Final file format of the plots. Formats available: PNG, JPG, JPEG, EPS. Defaults to PDF. + Scorecards: + execute: no # yes/no + regions: + # Mandatory: Define regions for which the spatial aggregation will be performed. + # The regions must be included within the area defined in the 'Analysis:Region' section. + Extra-tropical NH: {lon.min: 0, lon.max: 360, lat.min: 30, lat.max: 90} + Tropics: {lon.min: 0, lon.max: 360, lat.min: -30, lat.max: 30} + Extra-tropical SH : {lon.min: 0, lon.max: 360, lat.min: -90, lat.max: -30} + start_months: 1, 2, 3 # Mandatory, int: start months to visualise in scorecard table. Options: 'all' or a sequence of numbers. + metric: mean_bias enscorr rpss crpss enssprerr # Mandatory: metrics to visualise in scorecard table + metric_aggregation: 'score' # Mandatory, str: level of aggregation for skill scores. Options: 'score' or 'skill' + inf_to_na: True # Optional, bool: set inf values in data to NA, default is no/False + table_label: NULL # Optional, str: extra information to add in scorecard table title + fileout_label: NULL # Optional, str: extra information to add in scorecard output filename + col1_width: NULL # Optional, int: to adjust width of first column in scorecards table + col2_width: NULL # Optional, int: to adjust width of second column in scorecards table + calculate_diff: False # Mandatory, bool: True/False + ncores: 10 # Number of cores to be used in parallel computation. + # If left empty, defaults to 1. (Optional, int) + remove_NAs: yes # Whether to remove NAs. + # If left empty, defaults to no/false. (Optional, bool) + Output_format: 'S2S4E' # 'S2S4E' or 'Scorecards'. Determines the format of the output. Default is 'S2S4E'. +Run: + filesystem: esarchive # Name of the filesystem as defined in the archive configuration file + Loglevel: INFO # Minimum category of log messages to display: 'DEBUG', 'INFO', 'WARN', 'ERROR' or 'FATAL'. + # Default value is 'INFO'. (Optional, str) + Terminal: yes # Optional, bool: Whether to display log messages in the terminal. + # Default is yes/true. + output_dir: ./tests/out-logs/ # Output directory. Must have write permissions. (Mandatory, str) + code_dir: /esarchive/scratch/nperez/git3/sunset/ # Directory where the code is stored. Is used when launching jobs (not running interactively) + autosubmit: no # Whether or not to run with Autosubmit. Only for non-atomic recipes (not running interactively) + # 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 + hpc_user: bsc032762 # replace with your hpc username + wallclock: 01:00 # wallclock for single-model jobs, hh:mm + wallclock_multimodel: 02:00 # wallclock for multi-model jobs, hh:mm. If empty, 'wallclock' will be used. + processors_per_job: 4 # processors to request for each single-model job. + processors_multimodel: 16 # processors to request for each multi-model job. If empty, 'processors_per_job' will be used. + custom_directives: ['#SBATCH --exclusive'] # custom scheduler directives for single-model jobs. + custom_directives_multimodel: ['#SBATCH --exclusive', '#SBATCH --constraint=highmem'] # custom scheduler directives for multi-model jobs. If empty, 'custom_directives' will be used. + platform: nord3v2 # platform (for now, only nord3v2 is available) + email_notifications: yes # enable/disable email notifications. Change it if you want to. + email_address: victoria.agudetse@bsc.es # replace with your email address + notify_completed: yes # notify me by email when a job finishes + notify_failed: yes # notify me by email when a job fails + diff --git a/tests/testthat/test-seasonal_visualization_metadata.R b/tests/testthat/test-seasonal_visualization_metadata.R index a2c180c9..33f01c31 100644 --- a/tests/testthat/test-seasonal_visualization_metadata.R +++ b/tests/testthat/test-seasonal_visualization_metadata.R @@ -113,7 +113,8 @@ pfm_elements <- plot_forecast_map(recipe = recipe, fcst = data$fcst, mask = NULL, dots = NULL, outdir = outdir, output_conf = output_conf, return_elements = TRUE) -test_that("2. Test metadata plot_forecast_map(). This example has 'median' as + +test_that("2. Test plot_forecast_map() metadata. This example has 'median' as forecast_method, is single-panel, has a Robinson projection, and has no masked or dotted points.", { @@ -196,7 +197,7 @@ pm_elements <- plot_metrics(recipe = recipe, data_cube = data$hcst, output_conf = output_conf, return_elements = TRUE) -test_that("3. Test metadata plot_metrics(). This example is single-panel, has a +test_that("3. Test plot_metrics() metadata. This example is single-panel, has a Robinson projection, and has no masked or dotted points.", { expect_equal( @@ -262,7 +263,7 @@ pmlt_elements <- plot_most_likely_terciles(recipe = recipe, output_conf = output_conf, return_elements = TRUE) -test_that("3. Test metadata plot_metrics(). This example is single-panel, has a +test_that("3. Test plot_metrics() metadata. This example is single-panel, has a Robinson projection, and has no masked or dotted points.", { expect_equal( diff --git a/tests/testthat/test-subseasonal_visualization_metadata.R b/tests/testthat/test-subseasonal_visualization_metadata.R new file mode 100644 index 00000000..4f04d529 --- /dev/null +++ b/tests/testthat/test-subseasonal_visualization_metadata.R @@ -0,0 +1,298 @@ + +context("Subseasonal weekly data") + + +# source("modules/Loading/Loading.R") +# source("modules/Units/Units.R") +# source("modules/Calibration/Calibration.R") +# source("modules/Skill/Skill.R") +# source("modules/Anomalies/Anomalies.R") +# source("modules/Saving/Saving.R") +source("modules/Visualization/Visualization.R") +source("modules/Loading/Loading.R") +source("modules/Saving/R/get_dir.R") + + +recipe_file <- "tests/recipes/recipe-subseasonal_visualization.yml" +recipe <- prepare_outputs(recipe_file, disable_checks = FALSE) + +# Load datasets +suppressWarnings({invisible(capture.output( + data <- Loading(recipe) +))}) + +# Units transformation +suppressWarnings({invisible(capture.output( + data <- Units(recipe, data) +))}) + +# Compute skill metrics +# suppressWarnings({invisible(capture.output( +# skill_metrics <- Skill(recipe, data) +# ))}) + +# Compute percentiles and probability bins +# suppressWarnings({invisible(capture.output( +# probabilities <- Probabilities(recipe, data) +# ))}) + +## outdir <- get_dir(recipe = recipe, variable = data$hcst$attrs$Variable$varName) +outdir <- "./tests/out-logs/" + +output_conf <- read_yaml("modules/Visualization/output_size.yml", + eval.exp = TRUE)$region + + + + +# ------- TESTS -------- + + +test_that("1. Loading", { + + expect_equal( + is.list(data), + TRUE + ) + + expect_true( + all(c("hcst", "fcst", "obs") %in% names(data)) + ) + + expect_equal( + class(data$hcst), + "s2dv_cube" + ) + + expect_equal( + class(data$fcst), + "s2dv_cube" + ) + + expect_equal( + class(data$obs), + "s2dv_cube" + ) + + expect_equal( + names(data$hcst), + c("data", "dims", "coords", "attrs") + ) + + expect_equal( + names(data$hcst), + names(data$fcst) + ) + + expect_equal( + names(data$hcst), + names(data$obs) + ) + + expect_equal( + dim(data$hcst$data), + c(dat = 1, var = 1, sday = 3, sweek = 5, syear = 5, time = 4, latitude = 10, longitude = 21, ensemble = 12) + ) + + expect_equal( + dim(data$fcst$data), + c(dat = 1, var = 1, sday = 1, sweek = 1, syear = 1, time = 4, latitude = 10, longitude = 21, ensemble = 48) + ) + + expect_equal( + dim(data$hcst$attrs$Dates), + c(sday = 3, sweek = 5, syear = 5, time = 4) + ) + +}) + + +# ---------------------- + + + +pfm_elements <- plot_forecast_map(recipe = recipe, fcst = data$fcst, + mask = NULL, dots = NULL, + outdir = outdir, output_conf = output_conf, + return_elements = TRUE) + + +test_that("2. Test plot_forecast_map() metadata.", { + + expect_equal( + pfm_elements$latitude[1], + -4.251954, + tolerance = 0.001 + ) + + expect_equal( + pfm_elements$longitude[1], + -9.375, + tolerance = 0.001 + ) + + expect_equal( + pfm_elements$system_name, + "NCEP CFSv2" + ) + + expect_equal( + pfm_elements$start_date, + 20240104 + ) + + expect_equal( + pfm_elements$init_date, + 20240104 + ) + + expect_equal( + pfm_elements$palette, + "RdBu" + ) + + expect_equal( + pfm_elements$brks[1:3], + c(-30, -25, -20) + ) + + expect_equal( + pfm_elements$cols[1:3], + c(-30, -25, -20) + ) + + expect_equal( + pfm_elements$toptitle, + "NCEP CFSv2 / 2 Metre Temperature\nEnsemble median / Issued on 04-01-2024\nValid from 29-01 to 04-02 of 2024" + ) + + expect_equal( + pfm_elements$labels$time_labels[1], + "Valid from 08-01 to 14-01 of " + ) + + expect_equal( + pfm_elements$labels$years[1], + 2024 + ) + + expect_equal( + pfm_elements$fileout, + "./tests/out-logs/forecast_ensemble_median-20240104_ft04.png" + ) + +}) + +# ---------------------- + +## Skill module not adapted for subseasonal data yet +skill_metrics_dims <- c(var = 1, time = 4, latitude = 10, longitude = 21) +bool_array <- array(rep(c(TRUE, FALSE), length.out = prod(skill_metrics_dims)), dim = skill_metrics_dims) +skill_metrics_subs <- list( + rpss = bool_array, + rpss_significance = bool_array +) + +pm_elements <- plot_metrics(recipe = recipe, data_cube = data$hcst, + metrics = skill_metrics_subs, outdir = outdir, + output_conf = output_conf, + return_elements = TRUE) + + +test_that("3. Test plot_metrics() metadata.", { + + expect_equal( + pm_elements$latitude[1], + -4.251954, + tolerance = 0.001 + ) + + expect_equal( + pm_elements$longitude[1], + -9.187988, ## gata$fcst$coords$longitude[1] (pfm) != data$hcst$coords$longitude[1] (pm) + tolerance = 0.001 + ) + + expect_equal( + pm_elements$system_name, + "NCEP CFSv2" + ) + + expect_equal( + pm_elements$start_date, + 20240104 + ) + + expect_equal( + pm_elements$brks[1:3], + c(-1, -0.8, -0.6) + ) + + expect_equal( + pm_elements$cols[1:3], + c(-1, -0.8, -0.6) + ) + + expect_equal( + pm_elements$toptitle, + "NCEP CFSv2 / 2 Metre Temperature \n RPSS / Issued on 04-01-2024 / 1999-2003 \n Valid from 29-01 to 04-02 of 2024" + ) + + expect_equal( + pm_elements$nominal_startdate_caption, + as.Date("2024-01-04") + ) + + expect_equal( + pm_elements$forecast_time_caption, + "Forecast week: 04" + ) + + expect_equal( + pm_elements$fileout, + "./tests/out-logs/rpss-20240104_ft04.png" + ) + +}) + + +# ---------------------- + +## Probabilities module not adapted for subseasonal data yet + +data$probs$fcst ## Not loading from recipe? + +pmlt_elements <- plot_most_likely_terciles(recipe = recipe, + fcst = data$fcst, + probabilities = probabilities_subs, + outdir = outdir, + output_conf = output_conf, + return_elements = TRUE) + + + + +# multiprobs_global <- readRDS("~/SUNSET_RS_GIT/sunset/Ari_multiprobs_global.Rds") + +# probabilities_dims <- c(var = 1, syear = 1, time = 4, bin = 1, latitude = 10, longitude = 21) +# set.seed(42) # For reproducibility +# prob_b33 <- array(runif(prod(probabilities_dims), min = 0, max = 0.3), dim = probabilities_dims) +# prob_33_to_66 <- array(runif(prod(probabilities_dims), min = 0.3, max = 0.7), dim = probabilities_dims) +# prob_a66 <- array(runif(prod(probabilities_dims), min = 0.7, max = 1), dim = probabilities_dims) +# prob_b10 <- array(runif(prod(probabilities_dims), min = 0, max = 0.1), dim = probabilities_dims) +# prob_10_to_90 <- array(runif(prod(probabilities_dims), min = 0.1, max = 0.9), dim = probabilities_dims) +# prob_a90 <- array(runif(prod(probabilities_dims), min = 0.9, max = 1), dim = probabilities_dims) +# +# probs_fcst <- list( +# prob_b33 = prob_b33, +# prob_33_to_66 = prob_33_to_66, +# prob_a66 = prob_a66, +# prob_b10 = prob_b10, +# prob_10_to_90 = prob_10_to_90, +# prob_a90 = prob_a90 +# ) +# +# probabilities_subs <- list( +# probs_fcst = probs_fcst +# ) + -- GitLab From 4dddc274ed3c90a872683182900ea9d2ef7b08dd Mon Sep 17 00:00:00 2001 From: ARIADNA BATALLA FERRES Date: Mon, 24 Mar 2025 09:58:00 +0100 Subject: [PATCH 13/17] Remove Unit module from subseasonal test --- tests/testthat/test-subseasonal_visualization_metadata.R | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/tests/testthat/test-subseasonal_visualization_metadata.R b/tests/testthat/test-subseasonal_visualization_metadata.R index 4f04d529..41c92514 100644 --- a/tests/testthat/test-subseasonal_visualization_metadata.R +++ b/tests/testthat/test-subseasonal_visualization_metadata.R @@ -22,9 +22,9 @@ suppressWarnings({invisible(capture.output( ))}) # Units transformation -suppressWarnings({invisible(capture.output( - data <- Units(recipe, data) -))}) +# suppressWarnings({invisible(capture.output( +# data <- Units(recipe, data) +# ))}) # Compute skill metrics # suppressWarnings({invisible(capture.output( -- GitLab From 84de93a8ac8aaa44545788bafa3bfd6518d0474d Mon Sep 17 00:00:00 2001 From: ARIADNA BATALLA FERRES Date: Mon, 24 Mar 2025 10:16:48 +0100 Subject: [PATCH 14/17] comment plot_most_likely terciles for subseasonal test --- .../test-subseasonal_visualization_metadata.R | 28 ++++++++++++------- 1 file changed, 18 insertions(+), 10 deletions(-) diff --git a/tests/testthat/test-subseasonal_visualization_metadata.R b/tests/testthat/test-subseasonal_visualization_metadata.R index 41c92514..c386c10a 100644 --- a/tests/testthat/test-subseasonal_visualization_metadata.R +++ b/tests/testthat/test-subseasonal_visualization_metadata.R @@ -109,7 +109,7 @@ test_that("1. Loading", { # ---------------------- - +# Plot forecast map pfm_elements <- plot_forecast_map(recipe = recipe, fcst = data$fcst, mask = NULL, dots = NULL, @@ -117,7 +117,9 @@ pfm_elements <- plot_forecast_map(recipe = recipe, fcst = data$fcst, return_elements = TRUE) -test_that("2. Test plot_forecast_map() metadata.", { +test_that("2. Test plot_forecast_map() metadata. This example has 'median' as + forecast method, is single-panel, has 'cylindrical_equidistant' + projection, and has no masked or dotted points.", { expect_equal( pfm_elements$latitude[1], @@ -185,6 +187,8 @@ test_that("2. Test plot_forecast_map() metadata.", { # ---------------------- +# Plot metrics + ## Skill module not adapted for subseasonal data yet skill_metrics_dims <- c(var = 1, time = 4, latitude = 10, longitude = 21) bool_array <- array(rep(c(TRUE, FALSE), length.out = prod(skill_metrics_dims)), dim = skill_metrics_dims) @@ -199,7 +203,9 @@ pm_elements <- plot_metrics(recipe = recipe, data_cube = data$hcst, return_elements = TRUE) -test_that("3. Test plot_metrics() metadata.", { +test_that("3. Test plot_metrics() metadata. This example is single-panel, has a + 'cylindrical_equidistant' projection, and has no masked or dotted + points.", { expect_equal( pm_elements$latitude[1], @@ -258,16 +264,18 @@ test_that("3. Test plot_metrics() metadata.", { # ---------------------- +# Plot most likely terciles + ## Probabilities module not adapted for subseasonal data yet -data$probs$fcst ## Not loading from recipe? +# data$probs$fcst ## Not loading from recipe? -pmlt_elements <- plot_most_likely_terciles(recipe = recipe, - fcst = data$fcst, - probabilities = probabilities_subs, - outdir = outdir, - output_conf = output_conf, - return_elements = TRUE) +# pmlt_elements <- plot_most_likely_terciles(recipe = recipe, +# fcst = data$fcst, +# probabilities = probabilities_subs, +# outdir = outdir, +# output_conf = output_conf, +# return_elements = TRUE) -- GitLab From f1a8a13b77d3e4362cc36d183d8e562a60a1154e Mon Sep 17 00:00:00 2001 From: ARIADNA BATALLA FERRES Date: Mon, 24 Mar 2025 11:20:22 +0100 Subject: [PATCH 15/17] fix plot_forecast_map brks and colsafter Units removal --- tests/testthat/test-subseasonal_visualization_metadata.R | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/testthat/test-subseasonal_visualization_metadata.R b/tests/testthat/test-subseasonal_visualization_metadata.R index c386c10a..38e47518 100644 --- a/tests/testthat/test-subseasonal_visualization_metadata.R +++ b/tests/testthat/test-subseasonal_visualization_metadata.R @@ -155,12 +155,12 @@ test_that("2. Test plot_forecast_map() metadata. This example has 'median' as expect_equal( pfm_elements$brks[1:3], - c(-30, -25, -20) + c(-350, -300, -250) ) expect_equal( pfm_elements$cols[1:3], - c(-30, -25, -20) + c(-350, -300, -250) ) expect_equal( -- GitLab From f7ff4679896df6cb2f17f00556a2588192156c2a Mon Sep 17 00:00:00 2001 From: ARIADNA BATALLA FERRES Date: Mon, 24 Mar 2025 17:21:22 +0100 Subject: [PATCH 16/17] Updates to seasonal and subseasonal metadata tests --- .../R/plot_most_likely_terciles_map.R | 2 +- .../test-seasonal_visualization_metadata.R | 82 +----------------- .../test-subseasonal_visualization_metadata.R | 86 +++---------------- 3 files changed, 17 insertions(+), 153 deletions(-) diff --git a/modules/Visualization/R/plot_most_likely_terciles_map.R b/modules/Visualization/R/plot_most_likely_terciles_map.R index d6e2da32..6c26f6e5 100644 --- a/modules/Visualization/R/plot_most_likely_terciles_map.R +++ b/modules/Visualization/R/plot_most_likely_terciles_map.R @@ -347,7 +347,7 @@ plot_most_likely_terciles <- function(recipe, system_name = system_name, start_date = start_date, init_date = init_date, - brks = if (exists("brks")) brks else NULL, + base_args_brks = if (exists("base_args")) base_args$brks else NULL, cols = if (exists("cols")) cols else NULL, toptitle = if (exists("toptitle")) toptitle else NULL, labels = if (exists("labels")) labels else NULL, diff --git a/tests/testthat/test-seasonal_visualization_metadata.R b/tests/testthat/test-seasonal_visualization_metadata.R index 33f01c31..b5460c66 100644 --- a/tests/testthat/test-seasonal_visualization_metadata.R +++ b/tests/testthat/test-seasonal_visualization_metadata.R @@ -44,68 +44,6 @@ suppressWarnings({invisible(capture.output( # ------- TESTS -------- -test_that("1. Loading", { - - expect_equal( - is.list(data), - TRUE - ) - - expect_true( - all(c("hcst", "fcst", "obs") %in% names(data)) - ) - - expect_equal( - class(data$hcst), - "s2dv_cube" - ) - - expect_equal( - class(data$fcst), - "s2dv_cube" - ) - - expect_equal( - class(data$obs), - "s2dv_cube" - ) - - expect_equal( - names(data$hcst), - c("data", "dims", "coords", "attrs") - ) - - expect_equal( - names(data$hcst), - names(data$fcst) - ) - - expect_equal( - names(data$hcst), - names(data$obs) - ) - - expect_equal( - dim(data$hcst$data), - c(dat = 1, var = 1, sday = 1, sweek = 1, syear = 4, time = 1, latitude = 12, longitude = 15, ensemble = 25) - ) - - expect_equal( - dim(data$fcst$data), - c(dat = 1, var = 1, sday = 1, sweek = 1, syear = 1, time = 1, latitude = 12, longitude = 15, ensemble = 51) - ) - - expect_equal( - dim(data$hcst$attrs$Dates), - c(sday = 1, sweek = 1, syear = 4, time = 1) - ) - -}) - - -# ---------------------- - - output_conf <- read_yaml("modules/Visualization/output_size.yml", eval.exp = TRUE)$region outdir <- "./tests/out-logs/" @@ -114,7 +52,7 @@ pfm_elements <- plot_forecast_map(recipe = recipe, fcst = data$fcst, outdir = outdir, output_conf = output_conf, return_elements = TRUE) -test_that("2. Test plot_forecast_map() metadata. This example has 'median' as +test_that("1. Test plot_forecast_map() metadata. This example has 'median' as forecast_method, is single-panel, has a Robinson projection, and has no masked or dotted points.", { @@ -167,12 +105,6 @@ test_that("2. Test plot_forecast_map() metadata. This example has 'median' as as.character(pfm_elements$labels$time_labels), "June" ) - - expect_equal( - levels(pfm_elements$labels$time_labels), - c("January", "February", "March", "April", "May", "June", "July", - "August", "September", "October", "November", "December") - ) expect_equal( pfm_elements$labels$years, @@ -197,7 +129,7 @@ pm_elements <- plot_metrics(recipe = recipe, data_cube = data$hcst, output_conf = output_conf, return_elements = TRUE) -test_that("3. Test plot_metrics() metadata. This example is single-panel, has a +test_that("2. Test plot_metrics() metadata. This example is single-panel, has a Robinson projection, and has no masked or dotted points.", { expect_equal( @@ -292,8 +224,8 @@ test_that("3. Test plot_metrics() metadata. This example is single-panel, has a ) expect_equal( - pmlt_elements$brks, - NULL ## + pmlt_elements$base_args_brks, + list(4, 2, 4) ) expect_equal( @@ -311,12 +243,6 @@ test_that("3. Test plot_metrics() metadata. This example is single-panel, has a "June" ) - expect_equal( - levels(pmlt_elements$labels$time_labels), - c("January", "February", "March", "April", "May", "June", "July", - "August", "September", "October", "November", "December") - ) - expect_equal( pmlt_elements$labels$years, 2023 diff --git a/tests/testthat/test-subseasonal_visualization_metadata.R b/tests/testthat/test-subseasonal_visualization_metadata.R index 38e47518..fe5f9535 100644 --- a/tests/testthat/test-subseasonal_visualization_metadata.R +++ b/tests/testthat/test-subseasonal_visualization_metadata.R @@ -2,15 +2,14 @@ context("Subseasonal weekly data") -# source("modules/Loading/Loading.R") -# source("modules/Units/Units.R") +source("modules/Loading/Loading.R") +source("modules/Visualization/Visualization.R") +source("modules/Units/Units.R") +source("modules/Saving/R/get_dir.R") # source("modules/Calibration/Calibration.R") # source("modules/Skill/Skill.R") # source("modules/Anomalies/Anomalies.R") # source("modules/Saving/Saving.R") -source("modules/Visualization/Visualization.R") -source("modules/Loading/Loading.R") -source("modules/Saving/R/get_dir.R") recipe_file <- "tests/recipes/recipe-subseasonal_visualization.yml" @@ -22,9 +21,9 @@ suppressWarnings({invisible(capture.output( ))}) # Units transformation -# suppressWarnings({invisible(capture.output( -# data <- Units(recipe, data) -# ))}) +suppressWarnings({invisible(capture.output( + data <- Units(recipe, data) +))}) # Compute skill metrics # suppressWarnings({invisible(capture.output( @@ -47,68 +46,6 @@ output_conf <- read_yaml("modules/Visualization/output_size.yml", # ------- TESTS -------- - -test_that("1. Loading", { - - expect_equal( - is.list(data), - TRUE - ) - - expect_true( - all(c("hcst", "fcst", "obs") %in% names(data)) - ) - - expect_equal( - class(data$hcst), - "s2dv_cube" - ) - - expect_equal( - class(data$fcst), - "s2dv_cube" - ) - - expect_equal( - class(data$obs), - "s2dv_cube" - ) - - expect_equal( - names(data$hcst), - c("data", "dims", "coords", "attrs") - ) - - expect_equal( - names(data$hcst), - names(data$fcst) - ) - - expect_equal( - names(data$hcst), - names(data$obs) - ) - - expect_equal( - dim(data$hcst$data), - c(dat = 1, var = 1, sday = 3, sweek = 5, syear = 5, time = 4, latitude = 10, longitude = 21, ensemble = 12) - ) - - expect_equal( - dim(data$fcst$data), - c(dat = 1, var = 1, sday = 1, sweek = 1, syear = 1, time = 4, latitude = 10, longitude = 21, ensemble = 48) - ) - - expect_equal( - dim(data$hcst$attrs$Dates), - c(sday = 3, sweek = 5, syear = 5, time = 4) - ) - -}) - - -# ---------------------- - # Plot forecast map pfm_elements <- plot_forecast_map(recipe = recipe, fcst = data$fcst, @@ -155,12 +92,12 @@ test_that("2. Test plot_forecast_map() metadata. This example has 'median' as expect_equal( pfm_elements$brks[1:3], - c(-350, -300, -250) + c(-30, -25, -20) ) expect_equal( pfm_elements$cols[1:3], - c(-350, -300, -250) + c(-30, -25, -20) ) expect_equal( @@ -192,8 +129,9 @@ test_that("2. Test plot_forecast_map() metadata. This example has 'median' as ## Skill module not adapted for subseasonal data yet skill_metrics_dims <- c(var = 1, time = 4, latitude = 10, longitude = 21) bool_array <- array(rep(c(TRUE, FALSE), length.out = prod(skill_metrics_dims)), dim = skill_metrics_dims) +runif_array <- runif(prod(skill_metrics_dims), min = -1, max = 1) skill_metrics_subs <- list( - rpss = bool_array, + rpss = runif_array, rpss_significance = bool_array ) @@ -215,7 +153,7 @@ test_that("3. Test plot_metrics() metadata. This example is single-panel, has a expect_equal( pm_elements$longitude[1], - -9.187988, ## gata$fcst$coords$longitude[1] (pfm) != data$hcst$coords$longitude[1] (pm) + -9.187988, ## data$fcst$coords$longitude[1] (pfm) != data$hcst$coords$longitude[1] (pm) (see Requests #2766) tolerance = 0.001 ) -- GitLab From 94dafb450b3ea40adf6f8286d77b725787fdbb76 Mon Sep 17 00:00:00 2001 From: ARIADNA BATALLA FERRES Date: Tue, 25 Mar 2025 09:32:17 +0100 Subject: [PATCH 17/17] fix array error --- .../test-subseasonal_visualization_metadata.R | 37 ++----------------- 1 file changed, 4 insertions(+), 33 deletions(-) diff --git a/tests/testthat/test-subseasonal_visualization_metadata.R b/tests/testthat/test-subseasonal_visualization_metadata.R index fe5f9535..8d712294 100644 --- a/tests/testthat/test-subseasonal_visualization_metadata.R +++ b/tests/testthat/test-subseasonal_visualization_metadata.R @@ -129,7 +129,8 @@ test_that("2. Test plot_forecast_map() metadata. This example has 'median' as ## Skill module not adapted for subseasonal data yet skill_metrics_dims <- c(var = 1, time = 4, latitude = 10, longitude = 21) bool_array <- array(rep(c(TRUE, FALSE), length.out = prod(skill_metrics_dims)), dim = skill_metrics_dims) -runif_array <- runif(prod(skill_metrics_dims), min = -1, max = 1) +set.seed(0) +runif_array <- array(runif(prod(skill_metrics_dims), min = -1, max = 1), dim = skill_metrics_dims) skill_metrics_subs <- list( rpss = runif_array, rpss_significance = bool_array @@ -204,41 +205,11 @@ test_that("3. Test plot_metrics() metadata. This example is single-panel, has a # Plot most likely terciles -## Probabilities module not adapted for subseasonal data yet - -# data$probs$fcst ## Not loading from recipe? +# Probabilities module not adapted for subseasonal data yet # pmlt_elements <- plot_most_likely_terciles(recipe = recipe, # fcst = data$fcst, -# probabilities = probabilities_subs, +# probabilities = probabilities, # outdir = outdir, # output_conf = output_conf, # return_elements = TRUE) - - - - -# multiprobs_global <- readRDS("~/SUNSET_RS_GIT/sunset/Ari_multiprobs_global.Rds") - -# probabilities_dims <- c(var = 1, syear = 1, time = 4, bin = 1, latitude = 10, longitude = 21) -# set.seed(42) # For reproducibility -# prob_b33 <- array(runif(prod(probabilities_dims), min = 0, max = 0.3), dim = probabilities_dims) -# prob_33_to_66 <- array(runif(prod(probabilities_dims), min = 0.3, max = 0.7), dim = probabilities_dims) -# prob_a66 <- array(runif(prod(probabilities_dims), min = 0.7, max = 1), dim = probabilities_dims) -# prob_b10 <- array(runif(prod(probabilities_dims), min = 0, max = 0.1), dim = probabilities_dims) -# prob_10_to_90 <- array(runif(prod(probabilities_dims), min = 0.1, max = 0.9), dim = probabilities_dims) -# prob_a90 <- array(runif(prod(probabilities_dims), min = 0.9, max = 1), dim = probabilities_dims) -# -# probs_fcst <- list( -# prob_b33 = prob_b33, -# prob_33_to_66 = prob_33_to_66, -# prob_a66 = prob_a66, -# prob_b10 = prob_b10, -# prob_10_to_90 = prob_10_to_90, -# prob_a90 = prob_a90 -# ) -# -# probabilities_subs <- list( -# probs_fcst = probs_fcst -# ) - -- GitLab