From c8e2dd54a70e8459888ecc52377f5305773f04d8 Mon Sep 17 00:00:00 2001 From: Eliot McIntire Date: Wed, 30 Sep 2026 12:34:10 -0700 Subject: [PATCH 1/2] Drop other_agb; stop on fits that have an other_agb term Co-Authored-By: Claude Opus 5.5 Claude-Session: https://claude.ai/code/session_01CwcjqqK59FmTJscyi7xUqv --- NEWS.md | 2 ++ fireSense_dataPrepPredict.R | 9 +++++++-- ...domSecOtherFuels.R => test-domSecWetlandFuels.R} | 13 +++++++++++-- 3 files changed, 20 insertions(+), 4 deletions(-) rename tests/testthat/{test-domSecOtherFuels.R => test-domSecWetlandFuels.R} (88%) diff --git a/NEWS.md b/NEWS.md index 990af62..6c393fc 100644 --- a/NEWS.md +++ b/NEWS.md @@ -1,5 +1,7 @@ # fireSense_dataPrepPredict (development version) +- The pooled `other_agb` spread covariate is gone, and `fuelCovariates = "domSecOther"` is renamed `"domSecWetland"` in the call to `fireSenseUtils::fireSenseCovariatesCreate()`: prediction builds `dom_agb_`, `sec_agb_` and `treedWetland_agb`. A fitted model with an `other_agb` term now stops with a message to refit, instead of being predicted without that term. Needs the `fireSenseUtils` change that renames the value (PredictiveEcology/fireSenseUtils#116). + - reqdPkgs now lists `LandR`, `reproducible` and `SpaDES.core`, which the module calls (`LandR::.compareRas`, `postProcess`, `Cache`, `asPath`, `.suffix`, `paramCheckOtherMods`); it relied on another module attaching them. Version 1.0.4.9010. - `fireSense_EscapePredict` no longer exists (`fireSense_ignitionPredict` predicts ignition and escape): it is removed from the diff --git a/fireSense_dataPrepPredict.R b/fireSense_dataPrepPredict.R index 892cd0e..90477db 100644 --- a/fireSense_dataPrepPredict.R +++ b/fireSense_dataPrepPredict.R @@ -499,7 +499,7 @@ prepare_SpreadPredict <- function(sim) { nonForest_timeSinceDisturbance = sim$nonForest_timeSinceDisturbance, studyAreaName = P(sim)$.studyAreaName, useCache = FALSE, # predict is annual, no point in caching - fuelCovariates = if (is.na(fs$fuelClassRoles$domClass)) "species" else "domSecOther", + fuelCovariates = if (is.na(fs$fuelClassRoles$domClass)) "species" else "domSecWetland", domClass = fs$fuelClassRoles$domClass, secClass = fs$fuelClassRoles$secClass ) @@ -552,14 +552,19 @@ prepare_SpreadPredict <- function(sim) { #' The fuel-class name after `dom_agb_`/`sec_agb_` in a fitted covariate name #' -#' `fireSenseUtils::fireSenseCovariatesCreate(fuelCovariates = "domSecOther")` names those columns +#' `fireSenseUtils::fireSenseCovariatesCreate(fuelCovariates = "domSecWetland")` names those columns #' `dom_agb_`/`sec_agb_` with the fuel class's own name unchanged (no further #' mangling), so recovering `domClass`/`secClass` from a fitted term name is stripping the prefix. #' #' @param termNames character vector, e.g. `colnames(sim$studyAreaWithSpreadParams$params[[1]])`. #' @return `list(domClass =, secClass =)`; both `NA` when `termNames` has no `dom_agb_*` term (an #' older, per-species fit -- predicts with the previous one-column-per-fuel-class covariates). +#' Stops when `termNames` has `other_agb` (a fit made before that covariate was removed). fuelClassRolesFromTermNames <- function(termNames) { + if ("other_agb" %in% termNames) + stop("fireSense_dataPrepPredict: the fitted model has an `other_agb` term, a fuel covariate that no longer exists ", + "(fuels are now dom_agb_, sec_agb_ and treedWetland_agb). Refit the spread model with the current ", + "fireSense_dataPrepFit and fireSense_spreadFit.") domTerm <- grep("^dom_agb_", termNames, value = TRUE) secTerm <- grep("^sec_agb_", termNames, value = TRUE) if (!length(domTerm)) diff --git a/tests/testthat/test-domSecOtherFuels.R b/tests/testthat/test-domSecWetlandFuels.R similarity index 88% rename from tests/testthat/test-domSecOtherFuels.R rename to tests/testthat/test-domSecWetlandFuels.R index 6330248..a45383d 100644 --- a/tests/testthat/test-domSecOtherFuels.R +++ b/tests/testthat/test-domSecWetlandFuels.R @@ -23,11 +23,19 @@ test_that("fuelClassRolesFromTermNames() strips the prefix, and is NA/NA with no list(domClass = NA_character_, secClass = NA_character_)) }) +test_that("a fit that has an other_agb term stops with a message to refit, rather than dropping the term", { + expect_error(fuelClassRolesFromTermNames(c("b0", "MDC", "dom_agb_Pice_mar", "sec_agb_Pinu_ban", "other_agb")), + "other_agb.*Refit") + o <- toyObjects() + o$studyAreaWithSpreadParams <- toyLedgerRow(c("b0", "MDC", "youngAge", "dom_agb_class1", "sec_agb_class2", "other_agb")) + expect_error(toyPrepRun(o), "other_agb.*Refit") +}) + test_that("with no studyAreaWithSpreadParams, prediction gets the previous per-fuel-class columns", { out <- toyPrepRun(toyObjects()) sp <- covDF(out$fireSense_SpreadCovariates) expect_true(all(c("class1", "class2") %in% names(sp))) - expect_false(any(grepl("^dom_agb_|^sec_agb_|^other_agb$", names(sp)))) + expect_false(any(grepl("^dom_agb_|^sec_agb_", names(sp)))) ## rstLCC is now passed regardless of fuelCovariates: treedWetland appears (all 0: no LCC 81 here) expect_true("treedWetland" %in% names(sp)) expect_true(all(sp$treedWetland == 0)) @@ -50,7 +58,8 @@ test_that("a fitted dom_agb_class2/sec_agb_class1 row builds THOSE columns, not out <- toyPrepRun(o) sp <- covDF(out$fireSense_SpreadCovariates) - expect_true(all(c("dom_agb_class2", "sec_agb_class1", "other_agb") %in% names(sp))) + expect_true(all(c("dom_agb_class2", "sec_agb_class1") %in% names(sp))) + expect_false("other_agb" %in% names(sp)) expect_false(any(c("class1", "class2") %in% names(sp))) ## pixel 1 (PG1): class1 (Pice_mar 2000 + Pinu_ban 1000) = 3000, class2 (Popu_tre) = 0 From 79cf675d09d35bf8745e1aba9b62336c9db81f28 Mon Sep 17 00:00:00 2001 From: Eliot McIntire Date: Wed, 30 Sep 2026 12:49:40 -0700 Subject: [PATCH 2/2] reqdPkgs: fireSenseUtils (>= 0.2.3.9070) for domSecWetland Co-Authored-By: Claude Opus 5.5 Claude-Session: https://claude.ai/code/session_01CwcjqqK59FmTJscyi7xUqv --- fireSense_dataPrepPredict.R | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fireSense_dataPrepPredict.R b/fireSense_dataPrepPredict.R index 90477db..8517915 100644 --- a/fireSense_dataPrepPredict.R +++ b/fireSense_dataPrepPredict.R @@ -19,7 +19,7 @@ defineModule(sim, list( "fireSense_ignitionFit", "fireSense_spreadFit")), reqdPkgs = list( "data.table", - "PredictiveEcology/fireSenseUtils@development (>= 0.2.3.9062)", + "PredictiveEcology/fireSenseUtils@development (>= 0.2.3.9070)", "PredictiveEcology/LandR@development", "PredictiveEcology/reproducible@development", "PredictiveEcology/SpaDES.core@development (>= 3.0.4)",