Skip to content

Corrected annual series: per-pixel run-length filter that keeps a sustained switch and overwrites flicker years #64

Description

@NewGraphEnvironment

Context

#62 ran dft_rast_break_class() on the published seven-year IO LULC series of every group that has one (bulk_co_ff04, necr_ch_ff04, lnth_ch_ff04, kotl_bt_ff04). The #9 body named a "corrected series" — a per-pixel mode filter that keeps a sustained break and overwrites the flicker years — as worth building only if flicker turned out large everywhere. It did.

The numbers (data-raw/logs/break_class_groups/summary_groups.csv, one row per group)

group changed_ha pct_sustained pct_endpoint pct_flicker stable_flicker_ha pct_stable_flicker_of_valid
bulk 4625.0 19.7 36.4 44.0 3186.5 7.76
necr 5779.4 31.0 29.4 39.6 3828.3 9.15
lnth 1629.7 20.6 31.0 48.5 1576.7 9.85
kotl 3537.8 24.7 33.1 42.3 2235.5 3.22

Flicker is the largest category of the 2017 -> 2023 changed area in every group (39.6-48.5%), and a further 3.2-9.9% of every floodplain flickers while reading stable on the endpoints — 0.63 to 0.97 times the changed area itself (stable_flicker_over_changed), invisible to the two-epoch layer. Full reading in inst/notes/temporal-qa-groups.md.

What to build

A function that takes the same named list of classified years dft_rast_break_class() takes and returns a corrected series (a named list, same grid) in which:

  • a pixel with n_flips == 0 is unchanged;
  • a pixel with n_flips == 1 is unchanged — a clean switch is real by this leg's evidence, whatever its n_before / n_after (the caller thresholds, as everywhere else in the package);
  • a pixel with n_flips >= 2 is overwritten year by year with a mode that respects a sustained switch: not the whole-series mode (dft_rast_consensus() already does that and votes a real mid-window switch back to its old class), but a run-length rule — a run of at least run_min consecutive years of one class is kept, and any run shorter than that is relabelled to the neighbouring long run (the earlier one on a tie, or by a documented rule).

The two-epoch transition of the corrected series is then the deliverable a report can quote as change: dft_rast_transition(corrected, from = "2017", to = "2023"). Its changed area should land near the pct_sustained + pct_endpoint share of today's, and the note's Q1 table is the acceptance check — run the corrected series through dft_rast_break_class() again and the flicker row should be near zero.

Open decisions for the plan gate

Relates to #9, #62. Scale-test on the BULK pair before the PR per CLAUDE.md; the four groups' COGs are one data-raw/break_class_groups.R <group> away.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions