Repository navigation
Research: calibrate CH and BT gradient and channel-width thresholds from observations #284
Description
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_tunedkeeps 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.
defaultis re-run in the same harness: the existingfresh_defaultBULK 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.
- Prepare each WSG once, then re-classify it per variant, so every variant shares its segmentation.
-
One value moves: BT
rear_gradient_max0.1049 → 0.1349, indefault_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 arespawn_gradient_min(CH spawning selects the flattest bin, ratio 2.8) and the bridge (1.2 % of BT observations lost to clustering). Sodefault_tunedstill inheritsparameters_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
- Empirical distributions. For CH and BT, join
bcfishobs.observations(afterobservation_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. - 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
knowledgeparse covers site, collection and habitat sheets, not individual fish.) - Literature. One cited value or range per threshold, including CH stream-type vs ocean-type and BT life-history forms.
- Candidates. Set values in the
default_tunedbundle (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 inresearch/default_vs_bcfishpass.md), and BTcluster_bridge_gradient. - Score. Run
defaultanddefault_tunedon 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). - 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).
Activity
Record #284 plan review (3 blockers) for resume
Pool BT and DV as primary BT evidence; BT rear_gradient_max 0.1349 (#284
Regenerate #284 evidence outputs with BT and DV pooled
Merge pull request #287 from NewGraphEnvironment/284-research-calibra…
Record #284 status and threshold facts above the CLAUDE.md marker
Split Skeena DV pooling at Hazelton; add obs_year_max to the tracker (#…
Regenerate #284, #283 and pooling-scenario evidence under the Hazelto…
NewGraphEnvironment commentedon Sep 30, 2026
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 andextended. 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
nonerows. 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.
nonerows.MAD, lake/wetland area, access gradient and the rearing bridge.
Findings that bear on the verdicts in
research/habitat_thresholds.md: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.
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.
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.
Reach-scale BT spawning gradients now exist:
All three are consistent with keeping BT
spawn_gradient_maxat 0.0549. Morice BT rearing spans 1–14.5 %(mean 3.2 %, n = 33), which is relevant to the 0.1349 candidate.
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.
Page corrections to
literature.md: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.
Score: taper and elevation diagnostics, and the expected-count floor …
Score: tolerate clustering's small against-direction moves, report th…
Score: elevation-adjusted band ratio (#284)
#284 step 5 results: BT rear_gradient_max 0.1349 scored and held (#284)
Archive planning files for issue #284 step 5
Score: per-WSG habitat change against the base (#284)
Step 5 docs: plain-language summary and per-WSG habitat change (#284)
Merge pull request #296 from NewGraphEnvironment/284-research-calibra…