Skip to content

new parameter LCCClassesToReplaceNNMethod; require LandR (>= 1.2.0.9005) - #102

Merged
achubaty merged 1 commit into
PredictiveEcology:developmentfrom
FOR-CAST:upstream-convertUnwantedLCC-method
Aug 5, 2026
Merged

new parameter LCCClassesToReplaceNNMethod; require LandR (>= 1.2.0.9005)#102
achubaty merged 1 commit into
PredictiveEcology:developmentfrom
FOR-CAST:upstream-convertUnwantedLCC-method

Conversation

@achubaty

@achubaty achubaty commented Aug 5, 2026

Copy link
Copy Markdown
Collaborator

Exposes the method argument added to LandR::convertUnwantedLCC() in PredictiveEcology/LandR#197 as a module parameter.

Depends on PredictiveEcology/LandR#197 — merge that first.

Targets development (not main, which is 128 commits behind it).

New parameter

LCCClassesToReplaceNNMethod, passed straight through to convertUnwantedLCC(method = ). Both options allocate each LCCClassesToReplaceNN pixel a neighbouring class drawn in proportion to that class's abundance in the pixel's neighbourhood; they differ only in where the draw comes from:

value behaviour
"nearestRandom" (default) draws from the RNG — preserves the stochastic allocation this module has always had
"nearestWeighted" keys the draw on the pixel's ground position: deterministic, needs no set.seed(), stable under Cache(), and a grid-aligned crop of the study area gives the same answer as the full extent

The default deliberately keeps existing behaviour. "nearestWeighted" is there for workflows that need reproducibility without seed management, or that develop on a cropped subset before scaling up.

Why the LandR floor moves to 1.2.0.9005

Two reasons:

  1. method doesn't exist before it, so an older LandR fails with a clear unused-argument error rather than silently ignoring the parameter.
  2. LandR 1.2.0.9004 dropped the newPossLCC column used below to write replacement classes back into rstLCCAdj. The is.null() guard there silently stopped firing, leaving rstLCCAdj — and therefore ecoregionMap — showing the un-replaced classes. LandR#197 restores it; the comment now records the gap so the floor isn't lowered later without noticing.

Context worth knowing

LandR 1.2.0.9004 briefly replaced this function's stochastic search with a deterministic nearest-class rule that broke distance ties to the lowest land-cover class. Ties turn out to be common — 35–41% of unwanted pixels on real landscapes — and because the Canada LCC codes run non-vegetated → non-forest vegetation → forest, that biased imputation systematically out of forest. Pooled over four real SCANFI+FAO landscapes, versus the previous implementation:

class cover type old 1.2.0.9004 rule
50 shrubs 9.63% 16.25% (1.69×)
220 broadleaf 15.12% 8.75% (0.58×)
230 mixedwood 6.97% 1.96% (0.28×)

Non-forest vegetation went 11.3% → 18.6% of replaced pixels — about one in fourteen pixels that would have been forest wasn't. For this module that is not cosmetic: a pixel imputed as shrubs or herbs carries no tree cohorts at all.

LandR#197 removed that rule. Neither value of this parameter reintroduces it — both weight by local abundance and land within 0.9–1.0× of the old algorithm on every cover type.

Testing

  • Module metadata parses; SpaDES.core::moduleParams() registers the new parameter and moduleMetadata() reports the bumped floor and version.
  • Not yet exercised end-to-end — that needs LandR#197 merged and installed first.

Related

🤖 Generated with Claude Code

Exposes the `method` argument added to LandR::convertUnwantedLCC() in
PredictiveEcology/LandR#197. Both options allocate each LCCClassesToReplaceNN pixel a
neighbouring class drawn in proportion to that class's abundance in the pixel's
neighbourhood, and differ only in reproducibility:

  nearestRandom (default) -- draws from the RNG, preserving the stochastic allocation
    this module has always had.
  nearestWeighted -- keys the draw on the pixel's ground position: deterministic,
    seed-free, stable under Cache(), and a grid-aligned crop of the study area gives
    the same answer as the full extent.

The LandR floor moves to 1.2.0.9005 for two reasons. `method` does not exist before it,
so an older LandR fails with a clear unused-argument error rather than silently ignoring
the parameter. And 1.2.0.9004 had dropped the `newPossLCC` column used below to write
replacement classes back into rstLCCAdj -- the is.null() guard there silently stopped
firing, leaving rstLCCAdj, and hence ecoregionMap, showing the un-replaced classes.
1.2.0.9005 restores it; the comment now records the gap.

Note for reviewers: LandR 1.2.0.9004 briefly made convertUnwantedLCC() deterministic by
breaking distance ties to the lowest land-cover class. Ties are common (35-41% of
unwanted pixels on real landscapes) and, because the Canada LCC codes run non-vegetated
-> non-forest vegetation -> forest, that biased imputation out of forest: shrubs 1.69x,
broadleaf 0.58x, mixedwood 0.28x relative to the previous implementation. LandR#197
removed that rule; neither value of this parameter reintroduces it.

See PredictiveEcology#101 for the Cache()/RNG interaction that
affects the "nearestRandom" default.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
@achubaty
achubaty force-pushed the upstream-convertUnwantedLCC-method branch from c305bbf to 1ab874d Compare August 5, 2026 16:12
@achubaty
achubaty changed the base branch from main to development August 5, 2026 16:12
@achubaty
achubaty merged commit 47059af into PredictiveEcology:development Aug 5, 2026
1 of 2 checks passed
achubaty added a commit to PredictiveEcology/LandWeb that referenced this pull request Aug 5, 2026
…lDataPrep

Bumps the Biomass_borealDataPrep submodule to FOR-CAST main, which merges the new
`LCCClassesToReplaceNNMethod` parameter (FOR-CAST/Biomass_borealDataPrep#1), and sets it
explicitly in both parameter configs.

The fork already defaults to "nearestWeighted", so setting it here is belt-and-braces --
it keeps the intent visible next to LCCClassesToReplaceNN, and pins the behaviour if this
project ever tracks upstream, whose default is "nearestRandom"
(PredictiveEcology/Biomass_borealDataPrep#102).

"nearestWeighted" allocates each replaced pixel a neighbouring class drawn in proportion
to that class's local abundance, keyed on the pixel's ground position rather than the RNG:
deterministic without a seed, stable under Cache(), and a grid-aligned crop of a study
area gives the same answer as the full extent -- so a small development subset agrees with
the scaled-up run.

NOT yet runnable: renv still pins LandR 1.2.0.9004, which has no `method` argument. Once
PredictiveEcology/LandR#197 merges, update the lockfile via
`renv::install("PredictiveEcology/LandR@development", lock = TRUE)` (never snapshot()).

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
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