Skip to content

Species-dependent dam-class handling in dimensions.csv #83

@NewGraphEnvironment

Description

@NewGraphEnvironment

Problem

bcfishpass treats dams as a parallel anthropogenic-barrier dimension that does NOT gate any per-species habitat classification. Verified across all 5 model_access_<species>.sql files and all 8 load_habitat_linear_<sp>.sql files: zero references to barriers_dams, barriers_anthropogenic, or barriers_pscis. The natural-barrier set unioned per species is identical (gradient + falls + subsurfaceflow + user_definite) — only the gradient threshold differs by species.

This means species-dependent dam handling — e.g. "BT (resident) is unaffected by certain dams while anadromous salmon are blocked" — is not a bcfishpass parity concern. It's a green-field methodology decision link could codify via dimensions.csv.

Why this matters

Adding dams to link as a uniform break_order entry (the easy path) would block access for ALL species at every dam. That may be too aggressive — for resident BT in tributaries above an irrigation diversion, the dam doesn't matter for the resident's habitat use. For anadromous SK trying to reach the same tributary, it does.

bcfishpass sidesteps the question by tracking dams as a parallel dimension and letting downstream consumers (reports, WCRP tracking, dam-impact analyses) compose dam awareness in their own queries. Link's habitat-classification output is a more direct consumer than bcfishpass's habitat_linear_<sp> — so we have a methodology choice to make.

Proposed approach (for discussion)

Add a dams_block column (or similar) per species in dimensions.csv. Values yes / no / per-dam_use granularity (Hydroelectricity / Water supply / etc.).

Three implementation paths in fresh / link, in order of preference:

  1. Per-species label_block — dam break source emits label 'blocked_anth'. frs_habitat_classify is called per species with label_block = c("blocked", "blocked_anth") only when the species' dams_block flag is yes. Uses fresh's existing label-based gating; smallest surface area.
  2. Post-classification mask — classify uniformly, then per species set spawning/rearing to FALSE on segments downstream of a dam where dams_block=yes. Easier to bolt on but means classify output is "wrong" before the mask, which complicates intermediate consumers.
  3. Per-species break sources — separate streams_breaks per species. Heaviest lift, but most flexible.

Recommended: option 1.

Scope of this issue

This is a thinking issue — not committing implementation yet. Decisions to land:

  • Are dams species-dependent at the methodology level? If yes, what species and what dam classes (dam_use, barrier_status = BARRIER vs POTENTIAL, hydro vs not)?
  • Should the dimensions extend to PSCIS-assessed crossings (barriers_pscis) and modelled crossings (barriers_anthropogenic) too? Or are these always universal?
  • Does the dimension need temporal / age cutoffs (recently-decommissioned dams)?

Reference

  • research/bcfishpass_comparison.md (post PR Add subsurface-flow as an opt-in access barrier class #82) — sections "How bcfishpass classifies segments — natural vs anthropogenic tiers" and "Dams design — much smaller than expected" lay out the two-tier classification + the source-side data-flow story (CABD edits already applied at bcfishpass.crossings; fresh's crossings.csv projection drops the dam_id / stream_crossing_id columns).
  • bcfishpass per-species SQL: model/01_access/sql/model_access_*.sql and model/02_habitat_linear/sql/load_habitat_linear_*.sql — all dam-blind.

Relates to NewGraphEnvironment/sred-2025-2026#24

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