Skip to content

frs_barriers_minimal: reduce barriers to downstream-most per reach #160

@NewGraphEnvironment

Description

@NewGraphEnvironment

Problem

The link comparison pipeline (link/data-raw/compare_bcfishpass.R) hand-writes a fwa_upstream() self-join to reduce gradient barriers to the minimal set needed for access blocking — keeping only the downstream-most barrier on each upstream path. On ADMS this reduces ~27,443 raw barriers to 677.

This is a generic graph operation, not link-specific. It belongs in fresh:

  • Pushes the domain boundary correctly — fresh does generic network ops, link does interpretation
  • Already paralleled by fresh's existing fwa_upstream() wrappers
  • Currently the only composite op in link's pipeline DAG that isn't a named function call — makes the research doc DAG ambiguous (see link/research/bcfishpass_comparison.md)
  • Every link pipeline variant would otherwise re-implement the same SQL

The operation in plain language: given a point table on an FWA network, drop any point that has another point downstream of it on the same flow path. Result = minimal set of points that define access blocking per reach.

Proposed function

frs_barriers_minimal(
  conn,
  from,                                      # input table name (schema-qualified OK)
  to,                                        # output table name
  key_col = "blue_line_key",                 # configurable for non-FWA networks
  measure_col = "downstream_route_measure",
  keep_cols = NULL                           # additional cols to preserve; NULL = all
)

Return: invisible to (for pipeability). Writes a new table at to containing only the downstream-most point per upstream flow path.

Implementation reference: the self-join SQL in link/data-raw/compare_bcfishpass.R — grep for fwa_upstream / non-minimal. Port that pattern into an R function following fresh's frs_* conventions (see frs_break_find, frs_break_apply for signature and doc style).

Abstraction notes

Alternatives considered:

  • Keep as inline SQL in link — violates domain boundary (fresh owns graph ops), forces every link pipeline variant to re-implement
  • Generalize to frs_points_minimal — over-abstracts. Gradient barriers are the only current use case. Rename later if falls/crossings need the same reduction
  • Add to fwapg as a SQL helper — requires upstream PR + release cycle for something that's a trivial R wrapper
  • Name frs_barriers_minimal vs frs_barriers_reduceminimal matches bcfishpass terminology already documented in link research doc

Execution checklist

  • /planning-init only if scope grows beyond one function (probably unnecessary here)
  • Port self-join SQL from link/data-raw/compare_bcfishpass.R
  • Follow fresh conventions: roxygen docs, frs_* signature style, conn first arg, to return
  • Unit tests in tests/testthat/test-frs_barriers_minimal.R
  • Integration test: run on a real WSG's gradient barriers, assert count reduction
  • Runnable example on the exported function (not \dontrun{}) — show before/after counts on bundled or filtered data
  • /code-check before commit
  • PR with Fixes #N
  • NEWS.md entry
  • Bump version (0.13.8 → 0.14.0)

Tests required

  • Empty input → empty output
  • Single point → single-row output (nothing to remove)
  • Two points on same blue_line_key, different downstream_route_measure → only the downstream one kept
  • Two points on different blue_line_keys (unrelated streams) → both kept
  • Branching: point on main stem + point on tributary → both kept (tributary not downstream of main)
  • Integration: real WSG gradient barriers → reduction observed (count_before > count_after)

Example must show

  • Why — reduce ~27k+ gradient barriers to the ~700 needed for access blocking
  • How — one function call with before/after counts printed
  • Where it fits — pipes into frs_break_apply() for segmentation

Not in scope

  • Generalizing to arbitrary point types (defer until a second use case appears — falls, crossings, observations)
  • Per-species minimal barriers (that's link's barrier overrides logic — different concern)
  • Spatial filtering (input table is assumed already filtered)

Cross-refs

  • Unlocks: NewGraphEnvironment/link targets-based pipeline refactor (filing separately)
  • Reference SQL: link/data-raw/compare_bcfishpass.R (the fwa_upstream self-join block)

Versions

  • fresh: 0.13.8 (target: 0.14.0)
  • link: main (0.1.0)
  • bcfishpass: ea3c5d8
  • fwapg: Docker (FWA 20240830)

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