Repository navigation
Per-crossing upstream habitat per species, checked against bcfishpass, on frs_aggregate() #321
Description
If done: per-crossing upstream habitat counts the whole upstream network, split into stream / lake / wetland km with connectors apart. If never: a crossing's "upstream rearing km" misses every tributary, and per-crossing tallies can't be compared with the WSG rollups.
Problem (link@c3ea9d7)
lnk_aggregate()joins habitat onblue_line_key = crossing's AND measure >= crossing's(R/lnk_aggregate.R:160-167). That is the crossing's own line upstream, notfwa_upstream(), so tributary habitat is never counted.- It sums boolean habitat columns only (
cols_sum), so it cannot express the polygon class or the connector split the rollups now carry (Lake km: should 1450 connection lines count as lake rearing? #317, rearing_km means two things: lnk_rollup_wsg() keeps lake connection lines, the compare rollups do not #319). fresh::frs_aggregate()already does network-upstream aggregation with SQLmetrics(fresh v0.39.0,fwa_upstream()/fwa_downstream()).- No caller in link's
R/ordata-raw/. CLAUDE.md's "Integration with fresh" example shows it as the per-crossing rollup.
Plan
-
Confirm the defect on one WSG:
lnk_aggregate()againstfrs_aggregate()for crossings with habitat on tributaries. -
Rebuild
lnk_aggregate()onfresh::frs_aggregate(). The features are habitat joined to streams and the polygon join, withwaterbodyandconnectioncolumns, so the default metrics match the rollups:rearing_km(connectors out);rearing_stream_km/rearing_lake_km/rearing_wetland_km;rearing_lake_connection_km.
Keep the signature where it can be kept;
cols_sumbecomes SQL metrics. -
Tests against a hand-built network, the example, and the CLAUDE.md integration snippet.
Widened 2026-10-15: per-crossing totals, checked crossing by crossing against bcfishpass (step 1 of the barrier-rules work)
The plan above stands: rebuild lnk_aggregate() on fresh::frs_aggregate() (fresh#40, which was written to replace bcfishpass's per-crossing aggregation scripts). Before any barrier definition changes, the totals are checked against a reference. Searched 2026-10-14: no per-crossing comparison with bcfishpass exists in link, fresh, or our reporting repos. The reporting repos read bcfishpass's own *_belowupstrbarriers_km columns directly. The nearest earlier check is #16's sub-basin match for ADMS.
Reference
bcfishpass.crossings_upstream_habitat at smnorris/bcfishpass@620dbe4 (model/02_habitat_linear/sql/load_crossings_upstream_habitat_01.sql, _02.sql). It carries per crossing and per species:
<sp>_spawning_km,<sp>_rearing_kmand<sp>_spawningrearing_kmfor everything upstream;<sp>_*_belowupstrbarriers_km: the same, minus what lies above the next human-made barrier upstream. It is set for barriers with barriers upstream, and for passable or unknown crossings with a barrier upstream, on main-stem crossings only (blue_line_key = watershed_key).
Tasks
- Totals per species, read from each
streams_habitat_<sp>. The persisted habitat tables have noblue_line_key, measure or length, so the features are habitat joined tostreamson(id_segment, watershed_group_code). - A "below upstream barriers" total. It stops at the next human-made barrier upstream, using link's own human-made barrier set (
lnk_barriers_emit()), so a crossing is credited only with what fixing it alone opens. - Parity under the
bcfishpassbundle on two watershed groups, at least one with crossings above crossings (ADMS plus BULK or PARS): per crossing and per species, link againstcrossings_upstream_habitat. Join crossings onaggregated_crossings_id. Report the distribution of differences, not a single total, and annotate any departures, such as the side-channel rule and segmentation (PCEA: link (bcfishpass config) flags different BT rearing segments than bcfishpass (−8.2 km connection, +30.3 km other) #324). - Keep the stream / lake / wetland and connector split from the plan above as extra columns, beside the parity columns.
- Output that the barrier-rule scenarios can compare: a per-crossing table keyed by crossing id, config and species.
Next step: the barrier rule table, #341. Its scenarios are compared through these totals.
Activity
[-]lnk_aggregate() counts only the crossing's own stream line, and has no stream / lake / wetland split[/-][+]Per-crossing upstream habitat per species, checked against bcfishpass, on frs_aggregate()[/+]