Skip to content

frs_habitat_classify path-1 should accept known-spawning as a rearing trigger #189

@NewGraphEnvironment

Description

@NewGraphEnvironment

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.

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