Skip to content

lnk_pipeline_crossings: missing PSCIS<->modelled 100m-instream auto-snap layer #154

@NewGraphEnvironment

Description

@NewGraphEnvironment

Problem

lnk_pipeline_crossings v0.32.0 carries the PSCIS<->modelled crossing linkage only from the xref CSV (pscis_modelledcrossings_streams_xref). It's missing bcfp's automatic 100m-instream snap layer that produces the bulk of PSCIS<->modelled linkages.

See research/bcfp_table_map.md for the full mechanism analysis. Short version: bcfp's 02_pscis_streams_150m.sql (at smnorris/bcfishpass@v0.7.14-125-g6e9cf1c, current tunnel state bcfishpass.log.model_run_id=121 rebuilt 2026-05-05) auto-matches each PSCIS to its nearest modelled crossing within 100m instream distance on the same stream. The xref CSV layers manual overrides on top. link skips the auto-snap entirely.

Evidence (Phase A bcfp parity, 2026-05-10)

WSG extra <schema>.barriers_anthropogenic vs tunnel mapping_code parity (worst species)
ADMS +89 bt 98.53% (211 diffs)
BULK +1391 bt 76.30% (9357 diffs)
WILL +N (unmeasured) bt 85.48% (2490 diffs)
PARS cross-WSG dnstr (#152) bt 56.16% (16445 diffs)

The +1391 in BULK is the largest single contributor to BULK's mapping_code drift. Closing this gap is expected to bring all WSGs' mapping_code parity into >=99% (modulo cross-WSG dnstr, handled by #152).

Dependencies

Blocked by fresh#206 -- the generic frs_point_match primitive (point-to-point match on FWA network within instream distance). Once that ships, this issue is a thin integration.

Proposed solution

Once fresh ships frs_point_match:

  1. Add <schema>.pscis build step in lnk_pipeline_crossings, mirroring bcfp's bcfishpass.pscis:
    • Source: <schema>.pscis_assessment_snapped (already produced by lnk_points_snap)
    • Call fresh::frs_point_match with table_a = <schema>.pscis_assessment_snapped, table_b = fresh.modelled_stream_crossings, table_to = <schema>.pscis, distance_max = 100, table_a_id_col = "stream_crossing_id", table_b_id_col = "modelled_crossing_id"
    • Result: PSCIS rows with modelled_crossing_id populated where auto-snap found a match
    • Apply xref-CSV overrides on top (xref overrides auto-snap matches)
  2. .lnk_crossings_union reads from <schema>.pscis for the PSCIS branch (instead of <schema>.pscis_assessment_snapped).
  3. The modelled-branch exclusion changes: drop the xref-based WHERE NOT IN (xref) and replace with WHERE NOT IN (SELECT modelled_crossing_id FROM <schema>.pscis WHERE modelled_crossing_id IS NOT NULL) -- picks up both auto-snap and xref-derived linkages from the same source.

Acceptance

  • <schema>.pscis.modelled_crossing_id populated where bcfp's bcfishpass.pscis.modelled_crossing_id is, for ADMS / BULK / WILL / PARS (within tolerance)
  • <schema>.crossings modelled-source row count matches bcfishpass.crossings for ADMS / BULK / WILL / PARS (within tolerance)
  • compare_bcfp_mapping_code.R --wsgs=ADMS,BULK,WILL,PARS mapping_code parity >=99% for all species except PARS BT (cross-WSG, separately handled by Unified <persist_schema>.barriers (province-wide) with blocks_species predicate #152)
  • Roxygen + lintr clean

Out of scope

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