Problem
frs_habitat_classify path-1 (rearing-on-spawning) only triggers when h.spawning IS TRUE (modelled, rule-based). bcfishpass's habitat_linear_<sp> path-1 is broader:
WHERE (h.spawning IS TRUE or coalesce(hk.spawning_st, 0) = 1)
hk.spawning_st comes from bcfishpass.streams_habitat_known, populated from user_habitat_classification.csv. So bcfp's "rule-based" habitat_linear_<sp> already includes operator-known spawning as a path-1 trigger.
Link's apply_habitat_overlay: no config is meant to match bcfp's rule-based output. But because fresh's classify doesn't read user_habitat_classification, link misses the known-spawning-trigger rearing credits that bcfp produces.
Three logical modes (only two exist in fresh)
| Mode |
Modelled rule |
Known-spawning triggers rearing |
Final overlay |
bcfp habitat_linear_<sp> |
yes |
yes |
no |
bcfp streams_habitat_linear |
yes |
yes |
yes |
fresh apply_habitat_overlay: no |
yes |
no |
no |
fresh apply_habitat_overlay: yes |
yes |
no (only post-overlay) |
yes |
Bcfp's rule-based table corresponds to a third mode that fresh doesn't currently produce.
Concrete case
link MORR ST gap, 2026-04-30. bcfp credits ~60 km of ST rearing across the top 10 streams alone via the hk-trigger path:
| blue_line_key |
n rearing segs (with hk.spawning_st = 1) |
rearing km |
| 360885316 (Morice River) |
179 |
35.24 |
| 360885021 (Gosnell Creek) |
59 |
12.14 |
| 360819468 |
24 |
5.44 |
| 360837468 |
16 |
3.71 |
| ... |
|
|
bcfishpass.streams_habitat_known on MORR has 353 ST segments with spawning_st = 1 (from 31 distinct rows in user_habitat_classification.csv expanded across DRM ranges). Link's classify path-1 doesn't see them, so the rearing-on-spawning credit on those streams doesn't fire.
Proposed fix
frs_habitat_classify gains an optional known_habitat arg (a schema-qualified table reference, e.g. <schema>.user_habitat_classification). When non-NULL, path-1 rearing evaluation uses (modelled_spawn OR known_spawn) as the trigger condition. Default NULL preserves current behaviour.
Path-1 rearing-on-spawning credit fires when EITHER the segment has rule-based spawning OR the user_habitat_classification table flags spawning for that species at that segment's DRM range.
This same hk-trigger appears in bcfishpass cluster paths-2 and -3 (the (h.spawning OR hk.spawning_st) predicate inside their downstream/upstream CTEs). To match fully, frs_cluster and .frs_connected_waterbody should also accept the known_habitat arg and use the same OR predicate when checking for the connection target.
Reproduction
Tunnel DB: bcfishpass on localhost:63333 (db_newgraph, rebuilt Mondays). WSG: MORR. Species: ST. bcfishpass.streams_habitat_known provides the trigger source. Link's bcfishpass-bundle ships inst/extdata/configs/bcfishpass/overrides/user_habitat_classification.csv — same data, just not currently consumed by classify.
Related
This is the third mechanism in the same parity-investigation slice. fresh#186/#187 fixed link's over-credits; this fixes the under-credit. Together they should close most of the remaining MORR ST / BABL ST / MORR CO gap.
Problem
frs_habitat_classifypath-1 (rearing-on-spawning) only triggers whenh.spawning IS TRUE(modelled, rule-based). bcfishpass'shabitat_linear_<sp>path-1 is broader:hk.spawning_stcomes frombcfishpass.streams_habitat_known, populated fromuser_habitat_classification.csv. So bcfp's "rule-based"habitat_linear_<sp>already includes operator-known spawning as a path-1 trigger.Link's
apply_habitat_overlay: noconfig is meant to match bcfp's rule-based output. But because fresh's classify doesn't read user_habitat_classification, link misses the known-spawning-trigger rearing credits that bcfp produces.Three logical modes (only two exist in fresh)
habitat_linear_<sp>streams_habitat_linearapply_habitat_overlay: noapply_habitat_overlay: yesBcfp's rule-based table corresponds to a third mode that fresh doesn't currently produce.
Concrete case
link MORR ST gap, 2026-04-30. bcfp credits ~60 km of ST rearing across the top 10 streams alone via the hk-trigger path:
bcfishpass.streams_habitat_known on MORR has 353 ST segments with
spawning_st = 1(from 31 distinct rows in user_habitat_classification.csv expanded across DRM ranges). Link's classify path-1 doesn't see them, so the rearing-on-spawning credit on those streams doesn't fire.Proposed fix
frs_habitat_classifygains an optionalknown_habitatarg (a schema-qualified table reference, e.g.<schema>.user_habitat_classification). When non-NULL, path-1 rearing evaluation uses(modelled_spawn OR known_spawn)as the trigger condition. DefaultNULLpreserves current behaviour.Path-1 rearing-on-spawning credit fires when EITHER the segment has rule-based spawning OR the user_habitat_classification table flags spawning for that species at that segment's DRM range.
This same hk-trigger appears in bcfishpass cluster paths-2 and -3 (the
(h.spawning OR hk.spawning_st)predicate inside their downstream/upstream CTEs). To match fully,frs_clusterand.frs_connected_waterbodyshould also accept theknown_habitatarg and use the same OR predicate when checking for the connection target.Reproduction
Tunnel DB:
bcfishpassonlocalhost:63333(db_newgraph, rebuilt Mondays). WSG: MORR. Species: ST.bcfishpass.streams_habitat_knownprovides the trigger source. Link's bcfishpass-bundle shipsinst/extdata/configs/bcfishpass/overrides/user_habitat_classification.csv— same data, just not currently consumed by classify.Related
frs_clusterphase-1 + confluence-boostfrs_trace_downstreamaveraged-FWA gradient.frs_connected_waterbodyfor SK lake-proximityThis is the third mechanism in the same parity-investigation slice. fresh#186/#187 fixed link's over-credits; this fixes the under-credit. Together they should close most of the remaining MORR ST / BABL ST / MORR CO gap.