diff --git a/NEWS.md b/NEWS.md index 02233d4..9427a1b 100644 --- a/NEWS.md +++ b/NEWS.md @@ -1,5 +1,6 @@ # fireSense_ignitionPredict (development version) +- The objective of a fitted model is read with `fireSenseUtils::xgbObjective()`, the one copy shared with `fireSense_ignitionFit`, instead of this module's own lookup; same result. Needs fireSenseUtils (>= 0.2.3.9104). - Fix: the objective of the fitted models is read with `xgboost::xgb.config()` (falling back to `attr(model, "params")`), not `model$params`, which is `NULL` for xgboost >= 3 boosters, so every prediction run stopped at the ignition step. `xgboost (>= 3.0.0)` is now in `reqdPkgs`. - Breaking: the module now only predicts; it draws nothing and no longer makes `ignitionsAndEscapes`. `fireSense_burn` draws the ignitions and escapes from the new `fireSense_IgAndEscapeDistribution` and `fireSense_IgAndEscapeProbRas`, and places them (`placeIgnitions()`, `coarseToFineMap()` and `fineCoarseTable()` moved there). `flammableRTM` is no longer an input. - `fireSense_IgAndEscapeProbRas` layer `escapeProb` is the expected escapes per pixel and year for every pixel (it was NA where no ignition was drawn), no longer clamped to [0, 1]; `ignitionProb` is the expected ignitions. diff --git a/fireSense_ignitionPredict.R b/fireSense_ignitionPredict.R index 86d6800..0de2ffc 100644 --- a/fireSense_ignitionPredict.R +++ b/fireSense_ignitionPredict.R @@ -20,7 +20,7 @@ defineModule(sim, list( "data.table", "magrittr", "terra", "xgboost (>= 3.0.0)", "PredictiveEcology/SpaDES.core@development (>= 3.0.4)", "PredictiveEcology/reproducible@development", - "PredictiveEcology/fireSenseUtils@development (>=0.1.0)" + "PredictiveEcology/fireSenseUtils@development (>= 0.2.3.9104)" ), loadOrder = list(after = "fireSense_dataPrepPredict"), parameters = bindrows( @@ -259,8 +259,6 @@ foldMeanPrediction <- function(fit, newdata) { rowMeans(do.call(cbind, preds)) } -isOneString <- function(x) is.character(x) && length(x) == 1L && !is.na(x) - #' The objective the fitted models were fitted with #' #' `fireSense_burn` draws from the predicted means with the distribution this implies, so every fold of @@ -273,15 +271,10 @@ isOneString <- function(x) is.character(x) && length(x) == 1L && !is.na(x) fitObjective <- function(fits, process) { what <- c(ign = "ignition", esc = "escape")[[process]] perELF <- lapply(fits, function(f) { - obj <- vapply(foldModels(f[[process]]), function(model) { - o <- tryCatch(xgboost::xgb.config(model)$learner$objective$name, error = function(e) NULL) - if (!isOneString(o)) o <- tryCatch(attr(model, "params")$objective, error = function(e) NULL) - if (!isOneString(o)) - stop("fireSense_ignitionPredict: cannot read the objective of a fitted ", what, - " model (tried `xgboost::xgb.config(model)$learner$objective$name` and `attr(model, \"params\")$objective`);", - " fireSense_burn needs it to draw from the predictions") - o - }, "") + obj <- fireSenseUtils::xgbObjective(foldModels(f[[process]])) + if (anyNA(obj)) + stop("fireSense_ignitionPredict: cannot read the objective of a fitted ", what, + " model (`fireSenseUtils::xgbObjective()` found none); fireSense_burn needs it to draw from the predictions") if (length(unique(obj)) > 1L) stop("fireSense_ignitionPredict: the folds of the ", what, " model of ELF ", f$elf, " have different objectives: ", paste(unique(obj), collapse = ", "))