From f9af7663669c71f4988a481b3c54e6c87a23b1cf Mon Sep 17 00:00:00 2001 From: fbenke-pik Date: Tue, 11 Jul 2023 16:36:26 +0200 Subject: [PATCH] introduce data validation tests --- Makefile | 3 ++ .../testthat/validation/test_01-mifs_exist.R | 20 ++++++++++ .../testthat/validation/test_02-fe_liquids.R | 37 ++++++++++++++++++ .../validation/test_03-negative_electrictiy.R | 32 +++++++++++++++ .../testthat/validation/test_04-invest_esm.R | 39 +++++++++++++++++++ 5 files changed, 131 insertions(+) create mode 100644 tests/testthat/validation/test_01-mifs_exist.R create mode 100644 tests/testthat/validation/test_02-fe_liquids.R create mode 100644 tests/testthat/validation/test_03-negative_electrictiy.R create mode 100644 tests/testthat/validation/test_04-invest_esm.R diff --git a/Makefile b/Makefile index bc0e047da..a748d15f9 100644 --- a/Makefile +++ b/Makefile @@ -63,3 +63,6 @@ test-full: ## Run all tests, including coupling tests and a default ## REMIND scenario. Takes significantly longer than 10 minutes to run. $(info Full tests take more than an hour to run, please be patient) @R_PROFILE_USER= TESTTHAT_RUN_SLOW=TRUE Rscript -e 'testthat::test_dir("tests/testthat")' +test-validation: ## Run validation tests, requires a full set of runs in the output folder + $(info Run validation tests, requires a full set of runs in the output folder) + @R_PROFILE_USER= TESTTHAT_RUN_SLOW=TRUE Rscript -e 'testthat::test_dir("tests/testthat/validation")' diff --git a/tests/testthat/validation/test_01-mifs_exist.R b/tests/testthat/validation/test_01-mifs_exist.R new file mode 100644 index 000000000..e8c1139a5 --- /dev/null +++ b/tests/testthat/validation/test_01-mifs_exist.R @@ -0,0 +1,20 @@ +# | (C) 2006-2023 Potsdam Institute for Climate Impact Research (PIK) +# | authors, and contributors see CITATION.cff file. This file is part +# | of REMIND and licensed under AGPL-3.0-or-later. Under Section 7 of +# | AGPL-3.0, you are granted additional permissions described in the +# | REMIND License Exception, version 1.0 (see LICENSE file). +# | Contact: remind@pik-potsdam.de +test_that("each output folder contains standard mif files", { + dirs <- list.dirs("../../../output", recursive = FALSE, full.names = FALSE) + for (dir in dirs) { + d <- paste0("../../../output/", dir) + r <- expect_true( + length(list.files(path = d, pattern = "REMIND_generic_.*.mif")) == 2 && + length(list.files(path = d, pattern = "REMIND_climate_.*.mif")) == 1 + ) + + if (!r) { + print(paste0("some mifs are missing in ", dir)) + } + } +}) diff --git a/tests/testthat/validation/test_02-fe_liquids.R b/tests/testthat/validation/test_02-fe_liquids.R new file mode 100644 index 000000000..bfadc523c --- /dev/null +++ b/tests/testthat/validation/test_02-fe_liquids.R @@ -0,0 +1,37 @@ +# | (C) 2006-2023 Potsdam Institute for Climate Impact Research (PIK) +# | authors, and contributors see CITATION.cff file. This file is part +# | of REMIND and licensed under AGPL-3.0-or-later. Under Section 7 of +# | AGPL-3.0, you are granted additional permissions described in the +# | REMIND License Exception, version 1.0 (see LICENSE file). +# | Contact: remind@pik-potsdam.de +# Source: https://github.com/remindmodel/development_issues/issues/168 +library(magclass) +library(quitte) +library(dplyr) +test_that("liquids demand in buildings in NPi and NDC is not higher than baseline", { + dirs <- list.dirs("../../../output", recursive = FALSE) + data <- NULL + for (d in dirs) { + mifs <- list.files(path = d, pattern = "REMIND_generic_.*_withoutPlus.mif", full.names = TRUE) + if (length(mifs) == 1) { + m <- suppressWarnings(read.report(mifs[1], as.list = FALSE)["GLO", , "FE|Buildings|Liquids (EJ/yr)"]) + data <- mbind(data, m) + } + } + + if (all(c("SSP2EU-Base", "SSP2EU-NPi", "SSP2EU-NDC") %in% getNames(data, dim = 1))) { + xBase <- as.quitte(data[, , "SSP2EU-Base"]) + x <- as.quitte(data[, , c("SSP2EU-NPi", "SSP2EU-NDC")]) + # data frame with all data points where Base value is greater than NPi/NDC value, + # excluding historical values + x <- left_join(x, xBase, by = c("model", "region", "variable", "unit", "period")) %>% + filter(value.x > value.y, period > 2025) + } + + r <- expect_true(nrow(x) == 0) + + if (!r) { + print("Examples of test violation:") + print(head(x)) + } +}) diff --git a/tests/testthat/validation/test_03-negative_electrictiy.R b/tests/testthat/validation/test_03-negative_electrictiy.R new file mode 100644 index 000000000..0c56148f7 --- /dev/null +++ b/tests/testthat/validation/test_03-negative_electrictiy.R @@ -0,0 +1,32 @@ +# | (C) 2006-2023 Potsdam Institute for Climate Impact Research (PIK) +# | authors, and contributors see CITATION.cff file. This file is part +# | of REMIND and licensed under AGPL-3.0-or-later. Under Section 7 of +# | AGPL-3.0, you are granted additional permissions described in the +# | REMIND License Exception, version 1.0 (see LICENSE file). +# | Contact: remind@pik-potsdam.de +# Source: https://github.com/remindmodel/development_issues/issues/91 +library(magclass) +test_that("there are no negative electricity prices in historic years in EU regions", { + dirs <- list.dirs("../../../output", recursive = FALSE) + data <- NULL + reg <- c("EU27", "DEU", "ECE", "ECS", "ENC", "ESC", "ESW", "EWN", "FRA") + for (d in dirs) { + mifs <- list.files(path = d, pattern = "REMIND_generic_.*_withoutPlus.mif", full.names = TRUE) + if (length(mifs) == 1) { + m <- suppressWarnings( + read.report(mifs[1], as.list = FALSE)[ + , , + c( + "Price|Secondary Energy|Electricity (US$2005/GJ)", + "Price|Final Energy|Industry|Electricity (US$2005/GJ)" + ) + ] + ) + if (all(reg %in% getRegions(m))) { + data <- mbind(data, m[reg, seq(2005, 2025, 5), ]) + } + } + } + + expect_true(length(data[data < 0 & !is.na(data)]) == 0) +}) diff --git a/tests/testthat/validation/test_04-invest_esm.R b/tests/testthat/validation/test_04-invest_esm.R new file mode 100644 index 000000000..0030b211e --- /dev/null +++ b/tests/testthat/validation/test_04-invest_esm.R @@ -0,0 +1,39 @@ +# | (C) 2006-2023 Potsdam Institute for Climate Impact Research (PIK) +# | authors, and contributors see CITATION.cff file. This file is part +# | of REMIND and licensed under AGPL-3.0-or-later. Under Section 7 of +# | AGPL-3.0, you are granted additional permissions described in the +# | REMIND License Exception, version 1.0 (see LICENSE file). +# | Contact: remind@pik-potsdam.de +library(magclass) +library(quitte) +library(dplyr) +test_that("Non-ESM Investments never drop more than 50% in comparison to previous timestep until 2100", { + dirs <- list.dirs("../../../output", recursive = FALSE) + data <- NULL + reg <- c( + "CAZ", "CHA", "EUR", "IND", "JPN", "LAM", "MEA", + "NEU", "OAS", "REF", "SSA", "USA", "GLO" + ) + for (d in dirs) { + mifs <- list.files(path = d, pattern = "REMIND_generic_.*_withoutPlus.mif", full.names = TRUE) + if (length(mifs) == 1) { + m <- suppressWarnings( + read.report(mifs[1], as.list = FALSE) + )[reg, , "Investments|Non-ESM (billion US$2005/yr)"] + data <- mbind(data, m) + } + } + data <- data[, getYears(data, as.integer = TRUE) <= 2100, ] + x <- as.quitte(data) + xPrev <- mutate(x, period_next := period + 5) + xDiff <- inner_join(x, xPrev, by = c("period" = "period_next", "model", "scenario", "region", "variable", "unit")) %>% + mutate(value := (value.x - value.y) / value.x) %>% + filter(value < -0.5) + + r <- expect_true(nrow(xDiff) == 0) + + if (!r) { + print("Examples of test violation:") + print(head(xDiff)) + } +})