Skip to content

Apply youngAge mutual exclusivity at prediction time, matching the fit - #21

Merged
eliotmcintire merged 2 commits into
developmentfrom
fix/youngage-exclusivity
Sep 28, 2026
Merged

eliotmcintire merged 2 commits into
developmentfrom
fix/youngage-exclusivity

Conversation

@eliotmcintire

Copy link
Copy Markdown
Collaborator

spreadProbOneELF() (fireSense_SpreadPredict.R:282) called fireSenseUtils::spreadProbFromIntegerCovs() with mutuallyExclusive = NULL, commented "already done in dataPrepPredict". That step never actually zeroed a young non-forest pixel's land-cover value (PredictiveEcology/fireSenseUtils#92), so a young pixel's fuel biomass and nfLCC_* columns could reach the logistic unchanged instead of being cleared alongside youngAge = 1, as the fit requires.

Prediction now builds the same exclusivity rule the fit uses, via the new fireSenseUtils::youngAgeExclusiveCols(): it reuses the fuel columns this module already identifies from covMinMax_spread, plus the fixed nfLCC_*/treedWetland naming convention, so the invariant holds here even if a covariate table ever arrives from somewhere other than the current dataPrepPredict path. Requires fireSenseUtils@development (>= 0.2.3.9047).

A new test gives a toy young pixel a fuel-range biomass and a nfLCC_40 column and checks the predicted probability matches hand-computed values with both zeroed, not the values you get if they leak through; an existing test with the same shape (a young pixel keeping fuel it should have lost) is corrected. Both fail on development and pass here. SpaDES.core::convertToPackage() + testthat::test_local(): 44 tests / 101 expectations pass on development, 45 tests / 104 expectations pass on this branch, 0 failures either way. Version bumped to 1.0.0.9006.

Merge PredictiveEcology/fireSenseUtils#92 first.

🤖 Generated with Claude Code

https://claude.ai/code/session_01CwcjqqK59FmTJscyi7xUqv

fireSense_SpreadPredict.R:282 called fireSenseUtils::spreadProbFromIntegerCovs() with
mutuallyExclusive = NULL ("already done in dataPrepPredict"), so a young pixel's fuel biomass and
non-forest land-cover columns reached the logistic unchanged instead of being zeroed alongside
youngAge = 1, as the fit requires and as fireSenseCovariatesCreate() is now fixed to actually do
upstream (PredictiveEcology/fireSenseUtils#92). Prediction now derives the same rule itself, via
the new fireSenseUtils::youngAgeExclusiveCols(), using the fuel columns it already identifies
from covMinMax_spread plus the nfLCC_*/treedWetland naming convention, so it does not depend on
covariates always arriving pre-zeroed from an upstream module.

Requires fireSenseUtils@development (>= 0.2.3.9047).

Version 1.0.0.9006.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01CwcjqqK59FmTJscyi7xUqv
fireSenseUtils#92 landed as 0.2.3.9048 (development moved to 0.2.3.9047 via a concurrent PR
first), so the floor here follows.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01CwcjqqK59FmTJscyi7xUqv
@eliotmcintire
eliotmcintire merged commit fcffb00 into development Sep 28, 2026
6 of 11 checks passed
@eliotmcintire
eliotmcintire deleted the fix/youngage-exclusivity branch September 28, 2026 18:28
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant