Skip to contents

Maps of where salmon and trout can spawn and rear in British Columbia’s streams have so far been built for screening. bcfishpass (Norris 2024b) models which streams fish can reach below natural barriers such as falls and steep slopes, the road and rail crossings and dams on those streams, and which streams could hold spawning or rearing from their slope and size, so that crews can choose where to look first among more than half a million mapped crossings and dams. The Province publishes its access model as the Freshwater Fish Habitat Accessibility Model: Pacific Salmon and Steelhead. The spawning and rearing thresholds sit in bcfishpass’s repository as parameter sets: New Graph’s and other organizations’. To choose where to look first, a fair guess at where fish spawn and rear is enough.

The R package link (Irvine 2026b) builds on bcfishpass, and fresh (Irvine 2026a) runs its rules on the BC Freshwater Atlas. For every stretch of stream link asks a few plain questions: is it big enough, is it too steep, and can fish get to it? Each question has a cut-off, and each cut-off is a row in a config, so a rule can be changed and run beside another. That makes the cut-offs testable against evidence: the places crews have electrofished, and whether they caught the species there. We try many possible rules, keep the ones that best tell the two kinds of site apart, and check that they hold on parts of the province they were not chosen from. A rule can also carry the biology, such as young chinook using small streams close to a large river, so the map points to where fish are most likely to be.

This article describes that test. The steps run in order, from the fish records to values link can read.

What is a threshold, and what does “tuned” mean?

A threshold is one of those cut-offs: a minimum stream size or a maximum slope. A rule is the few thresholds a species uses together. A tuned threshold is one chosen by the test this article describes rather than taken from the literature or set by judgment.

For chinook rearing, for example, link’s current rule counts a stream as habitat if it is at least 1.5 m wide, no steeper than 5.5 %. The fish records support a rule where it carries at least 0.75 m³/s, no steeper than 13 %; a smaller stream also counts if it passes the slope test and a river carrying at least 3 m³/s lies within 1 km downstream. We tested between 6,100 and 8,400 candidate rules for each of the 6 species and life stages with enough records. The chinook rearing article works through one of them in full.

What happens, in order?

The 11 steps are each done by one package. Each box links to its package or source; each step links to its section below.

pipeline cluster_src cluster_leg x_fdis FDIS electrofishing x_fwa Freshwater Atlas x_pcic PCIC streamflow l_link link x_obs bcfishobs l_knowledge knowledge l_fwapg fwapg s1 1 The fish records l_wet wet l_fresh fresh s2 2 Putting sites on thestream map s1->s2 s3 3 link’s streamsegments s2->s3 s4 4 How much water eachstream carries s3->s4 s5 5 Joining each site toits segment s4->s5 s6 6 Candidate rules s5->s6 s7 7 Scoring and choosing s6->s7 s8 8 Checking the choiceis not luck s7->s8 s9 9 A curve and a grade s8->s9 s10 10 Running the rule onlink’s streams s9->s10 s11 11 Publishing s10->s11

1. The fish records

The Province’s electrofishing records (Province of British Columbia 2022): where crews fished, how much stream they covered, and what they caught. About 52,000 site visits. A survey loaded twice is kept once.

Code and settings
  • Run by: scripts/0230-fdis-load.R; knw_fdis_quality()
  • In: FDIS electrofishing export (2020-11-16; 2022-03-22). Out: data/fdis/derived/fdis_sites.csv
  • FDIS sentinel value: 9999
  • Earliest visit year kept: 1950
  • Latest visit year kept: 2022

2. Putting sites on the stream map

Each site’s map point is moved onto a stream of the BC Freshwater Atlas (FLNRORD 2021), held in a database by fwapg (Norris 2024c). Where the record names the site’s tributary in a form the Atlas can check, the site goes to the nearest stream of that tributary, even past a nearer stream, if it lies within 500 m, and is dropped if none does. A site with no such record goes to the nearest stream, if that lies within 200 m (how a site is placed). About 4,000 visits are dropped here, most because the stream is too far away.

Code and settings
  • Run by: scripts/0230-fdis-load.R; fresh::frs_point_snap(), knw_fdis_place(), knw_fdis_quality()
  • In: FDIS site points; Freshwater Atlas streams; fwa_streams_20k_50k. Out: placed visits (blue line and measure)
  • Snap search radius: 500 m
  • Snap distance limit, unconfirmed pick: 200 m
  • Snap distance limit, code-confirmed pick: 500 m
  • Edge type never snapped to: 6010 edge type
  • 1:50k code length the check reads: 45 characters
  • 1:50k code digits below the basin that, all zero, mark a code not checked: 42 characters

3. link’s stream segments

link (Irvine 2026b) cuts the Atlas streams into short segments and records, for each species, whether fish can reach each one and what link’s current rules call habitat. It also cuts streams where the species it models have been observed, using bcfishobs (Norris 2024a), so those observations shape the segments, but they never score a rule: they say where fish were seen, not where they were looked for and missed. A catch of a species link models can be one of those observations, so a stream-line site that caught fish is far more likely than one that caught none to start a segment of its own.

Code and settings
  • Run by: link’s province-wide run; link::lnk_pipeline_run(), fresh::frs_habitat_classify()
  • In: Freshwater Atlas; link’s default configuration. Out: fresh_default.streams; streams_access; streams_habitat_<species>

4. How much water each stream carries

Flows come from wet (Irvine 2026c). Mostly that is PCIC’s modelled streamflow (Schnorbus 2018; Craig et al. 2020), carried onto Atlas streams by New Graph’s fork of fwapg (Norris and Irvine 2026). Where PCIC’s flow does not reach a stream, or carries under a fifth of wet’s estimate on a stream’s own line, it is wet’s own water balance, fitted to Water Survey of Canada gauges (Environment and Climate Change Canada 2021). About 87 % of the kept sites use PCIC’s flow.

Code and settings
  • Run by: wet’s discharge build; wet::wet_db_load()
  • In: PCIC VIC-GL runoff routed by Raven; wet’s water balance. Out: discharge.fwa_v1_segment_monthly
  • Routed flow kept unless under this share of the balance’s: 0.2 ratio

5. Joining each site to its segment

Each kept site takes its segment’s flow, width, access and slope, and the distance downstream to rivers of each size. The slope is the segment’s own, the slope link applies a rule to, not that of the whole Atlas line the segment was cut from: a line can be gentle at one end and steep at the other, and averaging it would score a rule on a slope link never tests. Sites with no usable date, no fished area or time, no known catch, or no segment at their place drop out. About 46,000 sites remain.

Code and settings
  • Run by: scripts/0310-evidence-build.R; knw_build_record(), knw_link_place(), knw_fdis_species(), knw_link_flow(), knw_link_width(), knw_link_barrier_dnstr(), knw_link_walks(), knw_bcfishobs_match()
  • In: placed visits; link’s schema (SCHEMA, checked by knw_build_record); discharge.fwa_v1_segment_monthly. Out: data/fdis/derived/visits_link.csv; visits_species.csv; walks.csv
  • Width model control: least share within 5 %: 0.9 share
  • Edge types a parent’s flow is never taken from: 1100, 1150, 1300, 1350, 2300 FWA edge type
  • Edge types a dam’s regulated reach never follows: 1100, 1150, 1300, 1350, 2300 FWA edge type
  • River sizes walked to: 1, 3, 5, 10, 20, 30, 50 m3/s
  • Segment start taken as the visit’s segment within: 5 m
  • Largest segment overlap tolerated: 0.01 m
  • Wetland area making a line a wetland branch: 1 ha
  • Lake area making a line a lake branch: 100 ha
  • Dam to segment snap: 500 m
  • Degree of regulation that counts a dam without a reservoir: 10 %
  • Natural barrier classes downstream: GRADIENT, FALLS, SUBSURFACE_FLOW, USER_DEFINITE
  • Edge types a walk never ends on: 1100, 1150, 1300, 1350, 2300, 1400, 1450 FWA edge type
  • Most hops a walk takes before it stops: 60 hops

6. Candidate rules

For each species we build thousands of rules around link’s current values: different minimum stream sizes, slope limits, and an allowance for small streams close to a big river.

Code and settings
  • Run by: scripts/0320-tune-run.R; knw_tune_grid(), knw_rule_in()
  • In: link’s parameters_habitat_thresholds.csv. Out: candidate rules per species and stage
  • MAD floors in the grid: 0.1, 0.15, 0.2, 0.28, 0.35, 0.5, 0.75, 1 m3/s
  • Width floors in the grid: 1, 1.5, 2, 3, 4 m
  • Gradient maxima in the grid: 0.03, 0.04, 0.0549, 0.07, 0.09, 0.11, 0.13, 0.15, 0.2, 0.25, 0.3 m/m
  • Exception river sizes: 1, 3, 5, 10, 20, 30, 50 m3/s
  • Exception distances: 100, 250, 500, 1000, 2000, 5000 m

7. Scoring and choosing

Each rule is scored and chosen as described below, where a table gives each species’ choice. The model also accounts for how much stream was fished, which data set the record comes from, its period (1994 or earlier, 1995 to 2004, or later) and its watershed group, so a rule is not credited for those. A short trial run checks the scoring before the full run starts.

Code and settings
  • Run by: scripts/0320-tune-run.R; knw_tune_smoke(), knw_tune_score(), knw_tune_repick()
  • In: the evidence; the grid. Out: data/tune/<key>_tune.csv
  • Stream edge types scored: 1000, 1100, 2000, 2300 FWA edge type
  • Fished area kept: 10, 10000 m2
  • Gradient the rules are scored on: segment_gradient
  • Fold seed: 54
  • Group folds: 5
  • Group intercepts absorbed: fe
  • Prior SD on data set and era: 2.5 cloglog
  • Region width: 1 SE
  • Stricter reading: 1.96 SE
  • Exception distance the pick moves off: 200 m
  • Smoke gate: tolerance on no rule: 0.25 deviance
  • Smoke gate: largest nuisance coefficient: 5 cloglog
  • Least groups with both outcomes to fit: 5 groups
  • Groups below which a fit is underpowered: 10 groups
  • Maturity codes that count as spawner evidence: IM, M, MT, SP, ST
  • Length counted as a large spawner: 350 mm
  • Flow source the rules read: pick
  • Walk targets on a lake or regulated river excluded: FALSE
  • Era breaks of the nuisance term: 1994, 2004
  • Open work: #70

8. Checking the choice is not luck

Many rules score almost alike, so the winner could come down to chance. We choose again three ways: with the groups split 4 other ways; leaving out one part of the groups, choosing on the rest and scoring the choice on the part left out, for each part in turn; and on 200 random redraws of the groups. For chinook rearing the exact rule came back on 4 of the 4 other splits but in only 4 % of the redraws. It stayed a close call on all 4 splits, and choosing this way scored better than link’s rule on the parts left out (1,328 against 1,481; lower is better).

Code and settings
  • Run by: scripts/0320-tune-run.R; knw_tune_score()
  • In: the evidence; the grid. Out: data/tune/<key>_seeds.csv; <key>_honest.csv; <key>_summary.csv
  • Extra fold seeds: 55, 56, 57, 58
  • Group bootstrap resamples: 200
  • Bootstrap seed: 541

9. A curve and a grade

We fit a smooth curve of how often the species is caught against stream size, distance to the river and slope, and use it to grade every segment from low to high expected use. A species whose curve predicts no better than no rule at all gets no grade.

Code and settings
  • Run by: scripts/0320-tune-run.R; knw_tune_curve(), knw_grade_species(), knw_grade()
  • In: the evidence; link’s segments. Out: data/tune/<key>_curves.csv; <key>_grades.csv
  • Walk cap read by the curve: 50000 m
  • River size walked to where the pick has no exception: 10 m3/s
  • Smooth basis sizes (size, distance, gradient): 6, 6, 6
  • Grade reference quantile: 0.95 quantile
  • Grade class breaks: 0, 0.2, 0.4, 0.6, 0.8, 1
  • Gradient ceiling the curve and grade read: 0.2 m/m
  • Offset before the log of distance: 10 m
  • Gradient the grade reads on link’s segments: gradient
  • Flow the grade reads on link’s segments under a MAD rule: mad_pick
  • Width the grade reads on link’s segments under a width rule: channel_width

10. Running the rule on link’s streams

link’s current rule and the chosen rule both go through the steps link itself uses, run by fresh (Irvine 2026a): the rule’s test, link’s hand-entered habitat, and dropping rearing that has no spawning nearby. On the Bulkley, those last two steps removed 976 of the 7,273 segments link’s rule passed, so we compare whole runs, not the test alone.

Code and settings
  • Run by: scripts/0330-compare.R; knw_compare_rules(), fresh::frs_habitat_predicates(), fresh::frs_habitat_overlay()
  • In: fresh_default; link’s default configuration. Out: data/compare/
  • Comparison check: least fished area: 10 m2
  • Comparison check: largest fished area: 10000 m2
  • Connectivity bridge distance: 10000 m
  • Connectivity bridge gradient: 0.05 m/m
  • Comparison bootstrap resamples: 200
  • Comparison check: edge types of the FDIS visits it counts: 1000, 1050, 1100, 1150, 2000, 2100, 2300, 1250, 1350 FWA edge type
  • Wetland structure reported as tuned: door
  • Comparison bootstrap seed: 542
  • discharge_source in link’s default bundle: unset

11. Publishing

The chosen values are written under link’s own parameter names, with the grades, so link can read them.

Code and settings

What feeds what?

lineage cluster_leg l_source source l_knowledge knowledge l_fwapg fwapg l_link link l_wet wet fdis FDISelectrofishingexport(Province ofBC) l_fresh fresh sites sites on thestream map fdis->sites fwa BC FreshwaterAtlas atlas Atlas streamsin a database fwa->atlas pcic PCIC VIC-GLrunoff, routedby Raven cross PCIC flows puton Atlasstreams (thefwapg fork) pcic->cross obs bcfishobs fishobservations segs link’s streamsegments,access andhabitat obs->segs atlas->cross atlas->sites atlas->segs flow flow on eachsegment,PCIC’s orwet’s balance cross->flow evid each site withits segment sites->evid segs->evid cmp both rules runon link’sstreams segs->cmp flow->evid tune rules scoredand chosen,curves andgrades evid->tune tune->cmp pub thresholds andgrades forlink tune->pub cmp->pub

How is a site placed?

A site’s point is matched with every mapped Atlas stream within 500 m, except the lines that carry a stream across a watershed group’s boundary (edge type 6010). Where the site’s record names its tributary in a form the Atlas can check, the nearest stream of that tributary is taken, kept if it lies within 500 m, even when another stream is nearer; with none of its streams that close, the site is dropped. A site with no such record takes the nearest stream, kept if it lies within 200 m. The table shows three sites: one kept on its nearest stream, one moved past a nearer stream to the tributary its record names, and one dropped for its distance.

Three BULK sites and every Atlas stream within 500 m of each.
site visit fate Atlas stream name distance (m) snapped to
117123_15_1 kept 360818287 (unnamed) 10.4 yes
117123_15_1 kept 360698223 (unnamed) 111.7
117123_15_1 kept 360772213 (unnamed) 114.1
117123_15_1 kept 360361812 (unnamed) 160.6
117123_15_1 kept 360448614 (unnamed) 299.3
117123_15_1 kept 360323225 (unnamed) 312.4
48104_117_1 moved 360807112 (unnamed) 4.0
48104_117_1 moved 360830673 (unnamed) 37.8
48104_117_1 moved 360795300 (unnamed) 223.1 yes
48104_117_1 moved 360887296 Pine Creek 366.4
48104_117_1 moved 360752411 (unnamed) 492.5
103962_6_1 dropped 360559120 (unnamed) 239.7 yes
103962_6_1 dropped 360717148 (unnamed) 348.3
103962_6_1 dropped 360784252 (unnamed) 356.7

How are two rules told apart?

Each rule gets a score: how well “habitat or not” predicts where the species was caught, at sites in watershed groups that were left out while the model was fitted. Lower is better.

Scores move with the sites we happen to have. The standard error (SE) of the difference between two rules’ scores says how far that difference would move with a different set of watershed groups. Rules whose scores are within 1 SE of the best are close calls: the records cannot rank them. From the close calls we take the one that changes link’s current rule least.

One SE is a rule of thumb, fixed before the run. It began with pruning classification trees (Breiman et al. 1984; as cited in Chen and Yang 2021) and is now a common way to prefer the simpler of close models (Hastie et al. 2009). It is a convention, not a line below which rules are equal: there is no evidence it consistently beats taking the best score, though it often picks fewer variables (Chen and Yang 2021). The standard error it rests on has no unbiased estimate (Bengio and Grandvalet 2004), and the usual estimate is often too small (Bengio and Grandvalet 2004; Bates et al. 2024), though it can also be too large (Chen and Yang 2021).

1.96 SE is the stricter reading, about the width of a 95 % interval: more rules become close calls, and the choice can stay nearer link’s rule. Both are reported.

link’s current rule and the rule chosen at each width of close call, for each species and stage tuned.
species and stage link’s rule close calls at 1 SE chosen at 1 SE close calls at 1.96 SE chosen at 1.96 SE
bull trout rearing is at least 1.5 m wide, no steeper than 10.5 % 176 carries at least 0.1 m³/s, no steeper than 25 % 1,446 carries at least 0.1 m³/s, no steeper than 10.5 %
bull trout spawning is at least 2 m wide, no steeper than 5.5 % 140 is at least 2 m wide, no steeper than 11 % 7,021 is at least 2 m wide, no steeper than 5.5 %
chinook rearing is at least 1.5 m wide, no steeper than 5.5 % 169 carries at least 0.75 m³/s, no steeper than 13 %; a smaller stream also counts if it passes the slope test and a river carrying at least 3 m³/s lies within 1 km downstream 2,297 carries at least 0.75 m³/s, no steeper than 13 %; a smaller stream also counts if it passes the slope test and a river carrying at least 3 m³/s lies within 1 km downstream
coho rearing is at least 1.5 m wide, no steeper than 5.5 % 54 carries at least 0.1 m³/s, no steeper than 5.5 %; a smaller stream also counts if it passes the slope test and a river carrying at least 3 m³/s lies within 2 km downstream 1,296 is at least 1.5 m wide, no steeper than 5.5 %; a smaller stream also counts if it passes the slope test and a river carrying at least 1 m³/s lies within 500 m downstream
grayling rearing is at least 1.5 m wide, no steeper than 3.5 % 1,189 is at least 1.5 m wide, no steeper than 5.5 % 6,680 is at least 1.5 m wide, no steeper than 3.5 %
steelhead rearing is at least 1.5 m wide, no steeper than 8.5 % 265 carries at least 1 m³/s, no steeper than 8.5 %; a smaller stream also counts if it passes the slope test and a river carrying at least 1 m³/s lies within 250 m downstream 6,678 is at least 1.5 m wide, no steeper than 8.5 %

Where are fish sampling records lost?

Most of the records lost are lost when sites are put on the map (66 % of the 6,100 dropped). A site far from any stream, or on the wrong tributary, cannot be trusted to sit on the stream that was fished.

Site visits each step drops, in the order the steps run.

Site visits each step drops, in the order the steps run.

Each species then keeps the sites its rules can speak to: on a stream line (not in a river polygon, a wetland of 1 ha or more or a lake of 100 ha or more), of a usual fished area, where link expects the species, with no code that could hide it and no natural barrier to it downstream. The score uses the groups where the species was caught at some sites and not others.

Rearing site visits per species after each filter.
species kept stream line fished area where expected not hidden no barrier scored groups scored
bull trout 45,529 31,585 29,335 24,373 24,079 11,805 9,344 76
chinook 45,529 31,585 29,335 17,942 17,812 7,823 4,858 45
coho 45,529 31,585 29,335 14,289 14,218 6,184 4,628 63
grayling 45,529 31,585 29,335 5,650 5,625 1,580 1,355 27
steelhead 45,529 31,585 29,335 11,633 11,288 5,663 1,530 11

Limits

  • A site’s tributary code can name several Atlas streams, and the site goes to the nearest of them, which need not be the one the crew fished (#91).
  • link’s segments are shortest where fish were caught: 44 % of stream-line sites that caught fish start a segment of their own, against 7 % of those that caught none, and the median segment is 305 m long against 466 m. So which stretch a site’s slope is worked out over depends on what the crew caught. Scored on the whole Atlas line’s slope instead, the chosen rule is still a close call for 4 of the 6 species and stages (#92); slopes over a fixed length would not depend on where fish were caught (#70).
  • The results are on the segments of link’s build of 2026-11-03. That build cuts streams at steep sections only at the first place, going upstream, that a species present in the group cannot get past (link#326), and at fish records only at each species’ highest record on a stream (link#396).
  • Crews measured the slope of the channel at 18,759 of the 45,529 placed sites. On the stretches the rules score, link’s segment slope puts those sites in much the same order as the crews’ readings (a rank correlation of 0.68, where 1 is the same order and a second reading at the same site gives 0.90), but differs from the site’s by a median of 2.3 percentage points. So a tuned slope limit sorts sites well taken together, but reads as a slope on the ground only to within a few points: counting each species’ sites within one step of its own limit (1,496 in all), 39 % sit on the other side of it as the crews measured it (#121).
  • Flows are 30-year averages, so no single dry year is in them.

Which numbers shape the result, and which have been tested?

Every number below shapes a result. Each was checked against the code and the run when this article’s data were written. Source says where the value came from: a published source, a convention set here, a value inherited from link or bcfishpass (Norris 2024b), or a value measured from data. Tested says whether the result has been compared with another value. The untested rows come first: they are the work still to do.

Of the 69 settings, 11 have been tested and 8 of the untested ones were inherited.

All 69 settings
The settings, from inst/method/settings.csv.
setting value unit step source tested issue
Snap search radius 500 m 2 inherited no #91
Wetland area making a line a wetland branch 1 ha 5 inherited no
Lake area making a line a lake branch 100 ha 5 inherited no
Natural barrier classes downstream GRADIENT, FALLS, SUBSURFACE_FLOW, USER_DEFINITE 5 inherited no
Gradient the grade reads on link’s segments gradient 9 inherited no #92
Connectivity bridge distance 10000 m 10 inherited no
Connectivity bridge gradient 0.05 m/m 10 inherited no
discharge_source in link’s default bundle unset 10 inherited no #89
FDIS sentinel value 9999 1 measured no
Earliest visit year kept 1950 1 convention no
Latest visit year kept 2022 1 convention no
1:50k code length the check reads 45 characters 2 source no #91
1:50k code digits below the basin that, all zero, mark a code not checked 42 characters 2 source no #91
Routed flow kept unless under this share of the balance’s 0.2 ratio 4 convention no
Width model control: least share within 5 % 0.9 share 5 measured no
Edge types a parent’s flow is never taken from 1100, 1150, 1300, 1350, 2300 FWA edge type 5 convention no
Edge types a dam’s regulated reach never follows 1100, 1150, 1300, 1350, 2300 FWA edge type 5 convention no
River sizes walked to 1, 3, 5, 10, 20, 30, 50 m3/s 5 convention no
Segment start taken as the visit’s segment within 5 m 5 convention no #92
Largest segment overlap tolerated 0.01 m 5 measured no
Dam to segment snap 500 m 5 convention no
Degree of regulation that counts a dam without a reservoir 10 % 5 convention no
Edge types a walk never ends on 1100, 1150, 1300, 1350, 2300, 1400, 1450 FWA edge type 5 convention no #73
Most hops a walk takes before it stops 60 hops 5 convention no
MAD floors in the grid 0.1, 0.15, 0.2, 0.28, 0.35, 0.5, 0.75, 1 m3/s 6 convention no
Width floors in the grid 1, 1.5, 2, 3, 4 m 6 convention no
Exception river sizes 1, 3, 5, 10, 20, 30, 50 m3/s 6 convention no
Exception distances 100, 250, 500, 1000, 2000, 5000 m 6 convention no
Stream edge types scored 1000, 1100, 2000, 2300 FWA edge type 7 convention no
Fished area kept 10, 10000 m2 7 convention no
Group folds 5 7 convention no
Exception distance the pick moves off 200 m 7 convention no
Smoke gate: tolerance on no rule 0.25 deviance 7 convention no #84
Smoke gate: largest nuisance coefficient 5 cloglog 7 convention no #84
Least groups with both outcomes to fit 5 groups 7 convention no
Groups below which a fit is underpowered 10 groups 7 convention no
Maturity codes that count as spawner evidence IM, M, MT, SP, ST 7 source no
Length counted as a large spawner 350 mm 7 convention no
Flow source the rules read pick 7 convention no #89
Walk targets on a lake or regulated river excluded FALSE 7 convention no
Era breaks of the nuisance term 1994, 2004 7 convention no
Extra fold seeds 55, 56, 57, 58 8 convention no
Group bootstrap resamples 200 8 convention no
Bootstrap seed 541 8 convention no
Walk cap read by the curve 50000 m 9 convention no
River size walked to where the pick has no exception 10 m3/s 9 convention no
Smooth basis sizes (size, distance, gradient) 6, 6, 6 9 convention no
Grade reference quantile 0.95 quantile 9 convention no
Grade class breaks 0, 0.2, 0.4, 0.6, 0.8, 1 9 convention no
Gradient ceiling the curve and grade read 0.2 m/m 9 convention no
Offset before the log of distance 10 m 9 convention no
Flow the grade reads on link’s segments under a MAD rule mad_pick 9 convention no
Width the grade reads on link’s segments under a width rule channel_width 9 convention no
Comparison check: least fished area 10 m2 10 convention no
Comparison check: largest fished area 10000 m2 10 convention no
Comparison bootstrap resamples 200 10 convention no
Comparison check: edge types of the FDIS visits it counts 1000, 1050, 1100, 1150, 2000, 2100, 2300, 1250, 1350 FWA edge type 10 convention no
Comparison bootstrap seed 542 10 convention no
Snap distance limit, unconfirmed pick 200 m 2 measured yes #91
Snap distance limit, code-confirmed pick 500 m 2 measured yes #91
Edge type never snapped to 6010 edge type 2 measured yes #91
Gradient maxima in the grid 0.03, 0.04, 0.0549, 0.07, 0.09, 0.11, 0.13, 0.15, 0.2, 0.25, 0.3 m/m 6 convention yes #67
Gradient the rules are scored on segment_gradient 7 convention yes #92
Fold seed 54 7 convention yes
Group intercepts absorbed fe 7 convention yes #83
Prior SD on data set and era 2.5 cloglog 7 convention yes #84
Region width 1 SE 7 convention yes #79
Stricter reading 1.96 SE 7 convention yes #79
Wetland structure reported as tuned door 10 convention yes

Software and citation

The steps run on the PostgreSQL tools fwapg and New Graph’s fork of it, and on the R packages link (segments, access and habitat), wet (flows), fresh (the habitat tests) and knowledge (the evidence and the tuning). This article’s data were written on 2026-11-04 at commit f6b6d0a. To cite this package:

Irvine A (2026). knowledge: Fisheries Evidence and Tuned Habitat Thresholds for BC Watershed Groups. New Graph Environment Ltd. Version 0.4.27, https://newgraphenvironment.github.io/knowledge/.

References

Bates, Stephen, Trevor Hastie, and Robert Tibshirani. 2024. “Cross-Validation: What Does It Estimate and How Well Does It Do It?” Journal of the American Statistical Association 119 (546): 1434–45. https://doi.org/10.1080/01621459.2023.2197686.
Bengio, Yoshua, and Yves Grandvalet. 2004. “No Unbiased Estimator of the Variance of K-Fold Cross-Validation.” Journal of Machine Learning Research 5: 1089–105. https://jmlr.org/papers/v5/grandvalet04a.html.
Breiman, Leo, Jerome H. Friedman, Richard A. Olshen, and Charles J. Stone. 1984. Classification and Regression Trees. The Wadsworth Statistics/Probability Series. Wadsworth International Group.
Chen, Yuchen, and Yuhong Yang. 2021. “The One Standard Error Rule for Model Selection: Does It Work?” Stats 4 (4): 868–92. https://doi.org/10.3390/stats4040051.
Craig, James R., Genevieve Brown, Robert Chlumsky, et al. 2020. “Flexible Watershed Simulation with the Raven Hydrological Modelling Framework.” Environmental Modelling & Software 129 (July): 104728. https://doi.org/10.1016/j.envsoft.2020.104728.
Environment and Climate Change Canada. 2021. “National Water Data Archive: HYDAT.” Service description. Environment and Climate Change Canada (ECCC). https://www.canada.ca/en/environment-climate-change/services/water-overview/quantity/monitoring/survey/data-products-services/national-archive-hydat.html.
FLNRORD. 2021. “Freshwater Atlas Stream Network - Data Catalogue.” Published by Ministry of Forests, Lands, Natural Resource Operations and Rural Development. https://catalogue.data.gov.bc.ca/dataset/freshwater-atlas-stream-network.
Hastie, Trevor, Robert Tibshirani, and Jerome Friedman. 2009. The Elements of Statistical Learning: Data Mining, Inference, and Prediction. 2nd ed. Springer Series in Statistics. Springer. https://doi.org/10.1007/978-0-387-84858-7.
Irvine, Allan. 2026a. fresh: Freshwater Referenced Spatial Hydrology. Version 0.52.0. New Graph Environment Ltd. https://github.com/NewGraphEnvironment/fresh.
Irvine, Allan. 2026b. link: Develop, Test and Communicate Intrinsic Habitat and Connectivity Models for the BC Freshwater Atlas Stream Network. Version 0.78.2. New Graph Environment Ltd. https://doi.org/10.5281/zenodo.23264990.
Irvine, Allan. 2026c. wet: Stream Flow and Water Temperature for the BC Freshwater Atlas. Version discharge/fwa/v1. New Graph Environment Ltd. https://doi.org/10.5281/zenodo.23305781.
Norris, Simon. 2024a. bcfishobs. https://github.com/smnorris/bcfishobs.
Norris, Simon. 2024b. bcfishpass. https://github.com/smnorris/bcfishpass.
Norris, Simon. 2024c. fwapg. Version 9a62b0c. https://github.com/smnorris/fwapg.
Norris, Simon, and Allan Irvine. 2026. fwapg, New Graph Environment’s fork. Version 7c30f58. New Graph Environment Ltd. https://github.com/NewGraphEnvironment/fwapg/tree/newgraph.
Province of British Columbia. 2022. “Fisheries Data Information System (FDIS) Electrofishing Extract.” Electrofishing extract, exports of 2020-11-16 and 2022-03-22.
Schnorbus, Markus A. 2018. VIC-Glacier (VIC-GL): Description of VIC Model Changes and Upgrades. Pacific Climate Impacts Consortium, University of Victoria. https://hdl.handle.net/1828/21631.