Problem
fresh 0.12.5 runs frs_break_find separately for each gradient threshold (15%, 20%, 25%, 30%). Each run does its own vertex sampling and island detection with a boolean above/below grouping. This misses class transitions WITHIN a steep section — a section going 12%→18%→25% is one island at threshold=15%, so only one barrier is placed at the downstream entry. The 25% transition point is lost.
bcfishpass v0.5.0 gradient_barriers_load.sql does one pass, tags every vertex with its gradient class (5, 7, 10, 12, 15, 20, 25, 30), and creates separate islands per class. Class transitions within a steep section produce separate barriers. This is biologically correct — the point where gradient jumps from 15% to 25% matters because CH is blocked at 15% but BT passes through to 25%.
Result: bcfishpass generates 7,136 gradient_15 barriers for ADMS. fresh generates 5,571 (found) / 4,229 (in breaks). The missing barriers are at class transitions within steep sections.
Impact
Different barrier counts → different break points → different segments → different channel width coverage on accessible segments → -23% CH spawning gap vs bcfishpass v0.5.0 (link 0.0.0.9000 ADMS comparison).
Proposed Solution
Change frs_break_find to use bcfishpass's multi-class approach:
- One pass: sample gradient at every FWA vertex over 100m upstream window (same as now)
- Tag classes: assign each vertex to a gradient class (5, 7, 10, 12, 15, 20, 25, 30) instead of boolean above/below
- Island detection per class: group consecutive same-class vertices, place one barrier at the downstream entry of each class island
- Output: all barriers in one table with a
gradient_class column
frs_habitat() then filters by species access threshold — BT uses 25+30, CH/CO/SK use 15+20+25+30.
The breaks_gradient parameter on frs_habitat() becomes the list of classes to generate (default all 8), not the list of thresholds to run separately.
Key SQL difference
Current fresh (boolean):
lag(above) OVER (...) IS DISTINCT FROM above AS step
bcfishpass (class-based):
lag(grade_class) OVER (...) <> grade_class AS step
Additional bcfishpass filter to match
bcfishpass line 22: AND blue_line_key = watershed_key — only samples main flow lines, excludes 382 of 11,520 ADMS segments (secondary/side channels). Minor impact but should be a parameter for exact matching.
Versions
- fresh: 0.12.5
- bcfishpass: v0.5.0
- link: 0.0.0.9000
- fwapg: Docker local (FWA 20240830)
Relates to NewGraphEnvironment/link#16
Relates to #124
Problem
fresh 0.12.5 runs
frs_break_findseparately for each gradient threshold (15%, 20%, 25%, 30%). Each run does its own vertex sampling and island detection with a boolean above/below grouping. This misses class transitions WITHIN a steep section — a section going 12%→18%→25% is one island at threshold=15%, so only one barrier is placed at the downstream entry. The 25% transition point is lost.bcfishpass v0.5.0
gradient_barriers_load.sqldoes one pass, tags every vertex with its gradient class (5, 7, 10, 12, 15, 20, 25, 30), and creates separate islands per class. Class transitions within a steep section produce separate barriers. This is biologically correct — the point where gradient jumps from 15% to 25% matters because CH is blocked at 15% but BT passes through to 25%.Result: bcfishpass generates 7,136 gradient_15 barriers for ADMS. fresh generates 5,571 (found) / 4,229 (in breaks). The missing barriers are at class transitions within steep sections.
Impact
Different barrier counts → different break points → different segments → different channel width coverage on accessible segments → -23% CH spawning gap vs bcfishpass v0.5.0 (link 0.0.0.9000 ADMS comparison).
Proposed Solution
Change
frs_break_findto use bcfishpass's multi-class approach:gradient_classcolumnfrs_habitat()then filters by species access threshold — BT uses 25+30, CH/CO/SK use 15+20+25+30.The
breaks_gradientparameter onfrs_habitat()becomes the list of classes to generate (default all 8), not the list of thresholds to run separately.Key SQL difference
Current fresh (boolean):
bcfishpass (class-based):
Additional bcfishpass filter to match
bcfishpass line 22:
AND blue_line_key = watershed_key— only samples main flow lines, excludes 382 of 11,520 ADMS segments (secondary/side channels). Minor impact but should be a parameter for exact matching.Versions
Relates to NewGraphEnvironment/link#16
Relates to #124