Skip to content

Research: calibrate CH and BT gradient and channel-width thresholds from observations #284

Closed

Description

@NewGraphEnvironment

If we do it: CH and BT habitat in the default_tuned bundle rests on measured fish distributions and cited literature, with a recorded verdict per threshold. If we never do: both species keep inherited bcfishpass cutoffs, and the size difference that separates them (big-river CH spawning vs small-stream BT) is represented only by spawn_channel_width_min 4 vs 2.

Status (2026-09-29): all six steps done, and BT 0.1349 is scored and held

The verdicts are in research/habitat_thresholds.md, including the Step 5 results.

  • Step 5 changed shape before it ran. A counts-only power check found the planned held-out set could decide one step of six (BT 10 / 1 / 0 and CH 0 / 1 / 2 locations in the bands). So:
    • BT was widened to eight held-out WSGs: ELKR, BULL, UARL, REVL, CLRH, LILL, BABL and BABR.
    • CH was dropped. Its verdicts stay "keep", unscored, because the data is too thin.
    • An underpowered step changes nothing (operator's calls, 2026-09-29).
  • Result. All three variants were built on one shared segmentation of the 23-WSG closure. The steps to 0.1349 add rearing that BT use at 0.60 and 0.71 of the core rate; at the same elevation that is 0.75 and 0.89. The step to 0.1449 falls to 0.32 (8 found where 25 were expected). default_tuned keeps 0.1349. Capture goes from 81.2 % to 84.2 % for 585 km more rearing (+5.7 %).
  • The floor question. The rule's n ≥ 10 counts locations found, and so cannot refuse a band fish avoid. A floor on locations expected at the core rate can. Both readings agree here, and the choice stays open.
  • Cutoffs vs weights. Use tapers with gradient and thins with elevation. So the discussion moved to weighting habitat instead of cutting it, biology first: NewGraphEnvironment/knowledge#28.

The earlier status and plan, kept for the record:

  • Step 5 plan (agreed 2026-09-26, run after Region-scoped DV→BT observation pooling, tracked in bundle CSVs #290):

    • Prepare each WSG once, then re-classify it per variant, so every variant shares its segmentation. default is re-run in the same harness: the existing fresh_default BULK is pre-BT/ST accessible_km over-credit: access segmentation drops the accessibility frontier #223, with 42,860 segments against 87,639.
    • Seven variants: default, default_tuned, BT rear 0.1249 and 0.1449, CH spawn 0.0549 and 0.0299, and CH rear 0.0649.
    • WSGs: BT is read on ELKR and BULL (held out), with PARS, KOTL, BULK and MORR in-sample. CH is read on UNTH and LNTH (held out), with BULK and MORR in-sample.
    • Rule, fixed before the runs: the marginal band is habitat when its observation density per km is ≥ 0.5× the incumbent's. It is read on held-out WSGs and needs n ≥ 10, else keep. The literature veto stands.
    • Everything is species-agnostic: variants, WSG roles and absence taxa are data.
  • One value moves: BT rear_gradient_max 0.1049 → 0.1349, in default_tuned (high confidence: BT and DV records pooled, n 4,764 accessible, P95 0.135; Isaak et al. 2015's 15 % natal envelope agrees). BT records alone give 0.1249, and both are recorded. Every other CH/BT gradient maximum and width minimum is kept, as are spawn_gradient_min (CH spawning selects the flattest bin, ratio 2.8) and the bridge (1.2 % of BT observations lost to clustering). So default_tuned still inherits parameters_fresh.csv.

  • Vetoed by the literature: CH spawning width 6.6 m (Cooney & Holzer, Busch and Woll all put the minimum at 3.6–4 m).

  • Changed after the numbers were seen: restricting use to accessible segments moved three verdicts (CH spawning 0.0549 → keep, CH rearing 0.0649 → keep, BT rearing 0.1349 → 0.1249, before pooling brought BT back to 0.1349). Scoring should test the retired CH values too.

  • Coverage is not interior-only: about a third of the CH locations are in the lower Fraser and coastal Skeena, where ocean-type runs occur. The CH rearing verdict is sensitive to the gradient measure: the 100 m window gradient would give 0.0649 rather than keep.

  • BT and DV are pooled. Inland, DV records are bull trout recorded under the other name; on the coast either occurs, and their habitat biology is treated as equivalent. BT has no life stage anywhere in bcfishobs, so the staged evidence is the DV records. With full confidence the rule would loosen BT spawning gradient (0.1949) and width (1.2 m); the literature vetoes both.

  • Step 2 route: the FISS data-submission parse in knowledge (per-site width, gradient, effort, no-fish-captured) covers COTR, LNTH, PINE, UNTH and UPCE. Modelled width is good to about −30 % / +55 % of measured.

Problem

Current values (fresh parameters_habitat_thresholds.csv; link default/parameters_fresh.csv):

spawn gradient max spawn cw min rear gradient max rear cw min MAD access gradient max
CH 0.0449 4 0.0549 1.5 spawn ≥ 0.46, rear 0.28–100 (unused: no WSG uses the mad method and streams carry no mad_m3s — fresh#114) 0.15
BT 0.0549 2 0.1049 1.5 — 0.25

Rearing-to-spawning connection is identical for both (cluster_rearing = TRUE, direction both, cluster_bridge_gradient 0.05, cluster_bridge_distance 10000). In fresh's .frs_cluster_both(), a rearing cluster is kept if spawning lies anywhere upstream of it, with no gradient test. Failing that, it is kept if a downstream trace reaches spawning within 10 km through reaches under the bridge gradient. So the 5 % bridge governs only rearing that sits above spawning. (Corrected 2026-09-26: this previously said steep BT rearing "only survives with spawning upstream of it", which leaves out the downstream route.)

Channel width is mostly modelled: on the local fresh.streams, 1.38 M segments modelled, 98.5 k field-measured, 90 k river polygons and 2.19 M NULL. NULL fails every width test, and order-1 streams are NULL (fresh#28), which likely removes BT headwater rearing wholesale. (Measured 2026-09-26: 49 % of accessible BT stream length in fresh_default has NULL width, while 4 % of BT observations on those streams sit there, a selection ratio of 0.08. That does not separate under-sampling of headwaters from absence.)

Proposed Solution

  1. Empirical distributions. For CH and BT, join bcfishobs.observations (after observation_exclusions; release records removed) to segments. Plot gradient and channel width at observation points by life stage where known, by region, against the current cutoffs. Use measured channel width where it exists, and report modelled vs measured separately.
  2. Site-level evidence. Add per-site measured width/gradient, effort, absences and fish size from FISS data submissions as an input table, to separate adult (spawning) from juvenile (rearing) evidence, especially for BT, where the provincial layer has no life stage. (Fish size is not parsed yet: the knowledge parse covers site, collection and habitat sheets, not individual fish.)
  3. Literature. One cited value or range per threshold, including CH stream-type vs ocean-type and BT life-history forms.
  4. Candidates. Set values in the default_tuned bundle (per-bundle thresholds, Per-bundle habitat thresholds CSV in config.yaml #282) for spawn/rear gradient max, channel width min, spawn_gradient_min (see the reverted 0.0025 floor in research/default_vs_bcfishpass.md), and BT cluster_bridge_gradient.
  5. Score. Run default and default_tuned on pilot WSGs with both species present and good sampling, then compare with the observation validation (Validate modelled habitat against fish observations per species and watershed group #283).
  6. Verdict in research/habitat_thresholds.md, revised in place per species.

Out of scope here: MAD (fresh#114), temperature/GSDD (#21), channel-class segmentation (#52).

Relates to #20, #282, #283

Activity

  1. added 7 commits that reference this issue on Sep 26, 2026
  2. NewGraphEnvironment commented on Sep 30, 2026

    @NewGraphEnvironment
    OwnerAuthor

    Input for this issue: a verified literature evidence table for CH and BT thresholds (NewGraphEnvironment/knowledge#19)

    The literature review archived with this issue (literature.md) was ported into a table in the knowledge repo and
    extended. Every row has a Zotero key, a printed page and a verbatim quote, and a gate script checks each quote
    against the PDF text before the table can change. Rows where a search found nothing are kept as explicit
    none rows. Each row names the model parameter it bears on (spawn_gradient_max, cluster_bridge_distance,
    and so on). Gradient is in percent; divide by 100 for the model.

    • 190 rows: 108 CH, 82 BT, from 47 sources.
    • Gate: 176 quotes verified against their PDFs, compared token by token (12 of them through OCR of scanned reports), plus 14 none rows.
    • Coverage: every CH/BT × parameter cell has at least one row, covering spawn/rear gradient, channel width,
      MAD, lake/wetland area, access gradient and the rearing bridge.

    Findings that bear on the verdicts in research/habitat_thresholds.md:

    1. CH spawning MAD 0.46 m³/s has no source. Rebellato et al. 2024 cite five works for it, and none of them
      gives a discharge threshold. Rearing MAD 0.28 does trace to Agrawal et al., through Sheer et al. 2009 p. 13.

    2. The rearing bridge (10 km, no segment ≥ 5 %) has one documented origin: Rebellato et al. 2024 p. 7,
      rearing criterion 4, for CH, coho and steelhead. It is a design choice with no literature behind it, and there
      is nothing for BT.

    3. Rearing gradient 5 %: neither Porter et al. 2008 nor Woll et al. 2017 states it. Woll 2015 (Mat-Su) rates
      juvenile CH "No potential" above 5 %, so the citation may be meant for Woll 2015.

    4. Reach-scale BT spawning gradients now exist:

      • O'Brien 1999 (Duncan, adfluvial): 1.3, 1.9 and 4 % section averages at reaches with redds;
      • Bustard & Schell 2002 (Morice): 1–4 %, all spawning sites in reaches wider than 7 m;
      • Cope & Morris 2001 (Wigwam): 0.6–1.0 %.

      All three are consistent with keeping BT spawn_gradient_max at 0.0549. Morice BT rearing spans 1–14.5 %
      (mean 3.2 %, n = 33), which is relevant to the 0.1349 candidate.

    5. Roberge's CH "0.5 m" bankfull width (the open question in §1) is a transcription error: Porter et al. 2000
      Table 2 gives 20.2 m.

    6. Page corrections to literature.md:

      • Cooney & Holzer's > 5 % exclusion is on C-8, not C-7;
      • Hagen et al. 2015's 2 m wetted is on p. 23, not 22;
      • Hagen et al. 2020's footnote 9 is on p. 31, not 30;
      • Trotter's last-fish values are on p. 10, not 9.

    The table lives in a private repo, so it is not linked here. A snapshot for link can be agreed separately if
    scoring needs it.

  3. added a commit that references this issue on Sep 30, 2026
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