diff --git a/NEWS.md b/NEWS.md index e8f361a..91acc87 100644 --- a/NEWS.md +++ b/NEWS.md @@ -1,5 +1,9 @@ # fireSense_dataPrepPredict (development version) +- New parameter `.studyAreaName` (default `NA`). The module already read `P(sim)$.studyAreaName` without defining it, + so it was always `NULL`, whatever the user set. Left `NA`, it becomes a hash of `studyArea` (or of the extent of + `rasterToMatch`), as in Biomass_borealDataPrep. It names the study area in the landcover file + (`rstLCC__.tif`) and in cache tags, so caches built before this rebuild. - Several fitted ELFs in one study area: with `sppEquivs`, `nonForestedLCCGroupsList` and `missingLCCgroupList` from `fireSense_dataPrepFit` (one element per ELF), every ELF's fuel covariates are made for every pixel, each with its own species table, non-forest groups and `landcoverDT`, and merged by `pixelID` (spread) or by layer (ignition). `fireSense_SpreadPredict` and `fireSense_IgnitionPredict` then apply each ELF's model to its own columns. One ELF works as before. # fireSense_dataPrepPredict 1.0.2 diff --git a/fireSense_dataPrepPredict.R b/fireSense_dataPrepPredict.R index fbf0825..adb573a 100644 --- a/fireSense_dataPrepPredict.R +++ b/fireSense_dataPrepPredict.R @@ -10,7 +10,7 @@ defineModule(sim, list( person("Alex M", "Chubaty", role = "ctb", email = "achubaty@for-cast.ca") ), childModules = character(0), - version = list(fireSense_dataPrepPredict = "1.0.4.9001"), + version = list(fireSense_dataPrepPredict = "1.0.4.9002"), timeframe = as.POSIXlt(c(NA, NA)), timeunit = "year", citation = list("citation.bib"), @@ -62,6 +62,8 @@ defineModule(sim, list( defineParameter( ".runInitialTime", "numeric", start(sim), NA, NA, "Time of the first climate and covariate preparation events." ), + defineParameter(".studyAreaName", "character", NA, NA, NA, + "Human-readable name for the study area used."), defineParameter( ".useCache", "logical", FALSE, NA, NA, paste( @@ -221,6 +223,7 @@ doEvent.fireSense_dataPrepPredict <- function(sim, eventTime, eventType) { #' #' @return The `simList`, invisibly. Init <- function(sim) { + sim <- resolveStudyAreaName(sim) # force it to be same as the other module's value params(sim)[[currentModule(sim)]][["igAggFactor"]] <- SpaDES.core::paramCheckOtherMods(sim, "igAggFactor") @@ -573,6 +576,20 @@ unionLCCGroups <- function(fuelSets) { #' @param sim A `simList`. #' #' @return The `simList`, invisibly. +## An NA `.studyAreaName` becomes a hash of the study area (as in Biomass_borealDataPrep), so NA never +## reaches a file name or cache tag. Without `studyArea`, the extent of `rasterToMatch` stands in for it. +resolveStudyAreaName <- function(sim) { + if (is.na(P(sim)$.studyAreaName)) { + sa <- sim$studyArea + if (is.null(sa)) + sa <- terra::as.polygons(terra::ext(sim$rasterToMatch), crs = terra::crs(sim$rasterToMatch)) + params(sim)[[currentModule(sim)]][[".studyAreaName"]] <- reproducible::studyAreaName(sa) + message("The .studyAreaName is not supplied; derived name from the study area: ", + params(sim)[[currentModule(sim)]][[".studyAreaName"]]) + } + sim +} + .inputObjects <- function(sim) { cacheTags <- c(currentModule(sim), "otherFunctions:.inputObjects") dPath <- asPath(inputPath(sim), 1) @@ -589,6 +606,7 @@ unionLCCGroups <- function(fuelSets) { if (suppliedElsewhere("rstLCCs", sim)) { sim$rstLCC_RTM <- tail(sim$rstLCCs, 1)[[1]] } else { + sim <- resolveStudyAreaName(sim) rstLCC <- Cache(makeFireSenseLCC, neededYear = P(sim)$dataYear, writeTo = .suffix( diff --git a/tests/testthat/test-metadata.R b/tests/testthat/test-metadata.R index 20aa09c..aeae8d4 100644 --- a/tests/testthat/test-metadata.R +++ b/tests/testthat/test-metadata.R @@ -56,7 +56,7 @@ test_that("parameters are the expected names", { md <- SpaDES.core::moduleMetadata(module = moduleName, path = modulePath) expect_identical( sort(md$parameters$paramName), - sort(c(".runInitialTime", ".useCache", "cutoffForYoungAge", "dataYear", + sort(c(".runInitialTime", ".studyAreaName", ".useCache", "cutoffForYoungAge", "dataYear", "fireTimeStep", "flammabilityThreshold", "forestedLCC", "fuelClassCol", "igAggFactor", "nonflammableLCC", "nonForestCanBeYoungAge", "sppEquivCol", "whichModulesToPrepare")) diff --git a/tests/testthat/test-studyAreaName.R b/tests/testthat/test-studyAreaName.R new file mode 100644 index 0000000..309079d --- /dev/null +++ b/tests/testthat/test-studyAreaName.R @@ -0,0 +1,25 @@ +## `.studyAreaName` names the study area in the landcover file and cache tags. Its default, NA, +## must become a real name before use, never "NA" in a file name. + +test_that("an unset .studyAreaName becomes a hash of the study area", { + objs <- toyObjects() + sim <- SpaDES.core::spades(toyPrepSim(objs), events = "init", debug = FALSE) + nm <- SpaDES.core::P(sim, module = moduleName)$.studyAreaName + expect_false(is.na(nm)) + expect_identical(nm, reproducible::studyAreaName(objs$studyArea)) +}) + +test_that("without studyArea, the extent of rasterToMatch names it", { + objs <- toyObjects() + objs$studyArea <- NULL + sim <- SpaDES.core::spades(toyPrepSim(objs), events = "init", debug = FALSE) + nm <- SpaDES.core::P(sim, module = moduleName)$.studyAreaName + expect_false(is.na(nm)) + expect_type(nm, "character") +}) + +test_that("a supplied .studyAreaName is kept", { + sim <- SpaDES.core::spades(toyPrepSim(params = list(.studyAreaName = "myArea")), + events = "init", debug = FALSE) + expect_identical(SpaDES.core::P(sim, module = moduleName)$.studyAreaName, "myArea") +})