From 30583f31b17e8d82bf2474b546bcdb93dc93af94 Mon Sep 17 00:00:00 2001 From: almac2022 Date: Sat, 4 Jul 2026 20:41:03 -0700 Subject: [PATCH 1/3] vignette: reader-facing prose cleanup MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Follow-up polish on the PARS vignette from review feedback: drop internal issue numbers, remove 'tunnel' references (build infra the reader needn't know), and cut the mapping_code disagreement detail (top-diff-pattern columns + caption + the 'remaining disagreements' paragraph) since the diff is negligible. The accessible/spawning/rearing km comparison table stays, reframed as link's own routine roll-up (lnk_rollup_wsg is standalone — needs no reference) that happens to match bcfishpass. Verified with a database-free knit. Co-Authored-By: Claude Fable 5 Claude-Session: https://claude.ai/code/session_014kSEJoad4Bc553qU8eFiE6 --- vignettes/pars-habitat-connectivity.Rmd | 64 ++++++++++--------------- 1 file changed, 26 insertions(+), 38 deletions(-) diff --git a/vignettes/pars-habitat-connectivity.Rmd b/vignettes/pars-habitat-connectivity.Rmd index 37d55c4..d4a6541 100644 --- a/vignettes/pars-habitat-connectivity.Rmd +++ b/vignettes/pars-habitat-connectivity.Rmd @@ -149,7 +149,7 @@ time. Direct downloads from the repo (open in QGIS or any GDAL-aware tool): `waterbodies` (lakes + rivers + manmade), `named_streams`, and basemapping context layers `reserves`, `parks`, `roads`, `railways` - [`pars_parity.rds`](https://github.com/NewGraphEnvironment/link/raw/main/inst/vignette-data/pars_parity.rds) - — tunnel-free per-species `mapping_code` parity tibble + — per-species `mapping_code` parity tibble - [`pars_accessible.rds`](https://github.com/NewGraphEnvironment/link/raw/main/inst/vignette-data/pars_accessible.rds) — bull-trout accessible / spawning / rearing habitat (km), link's roll-up vs the local bcfishpass snapshot @@ -191,7 +191,7 @@ reserves <- clip_aoi(reserves) parks <- clip_aoi(parks) # Classified-segment counts for the grayling map captions — derived from the -# loaded layer so they track the cached artifact, never hand-edited (link#226). +# loaded layer so they track the cached artifact, never hand-edited. .bt_present <- !is.na(streams$mapping_code_bt) & nzchar(streams$mapping_code_bt) .gr_present <- !is.na(streams$mapping_code_gr) & nzchar(streams$mapping_code_gr) n_bt <- sum(.bt_present) @@ -225,50 +225,41 @@ lnk_pipeline_run(conn, aoi = "PARS", cfg = cfg_default, loaded = loaded_d, ## Reproducing bcfishpass (parity) `lnk_compare_mapping_code()` compares `link`'s per-segment `mapping_code` -against the local bcfishpass snapshot, segment by segment, with no database -tunnel required. The comparison restricts itself to species that are actually -active in the watershed group — which, for the reasons above, is bull trout -alone in `PARS`. +against the local bcfishpass snapshot, segment by segment. The comparison +restricts itself to species that are actually active in the watershed group — +which, for the reasons above, is bull trout alone in `PARS`. ```{r parity-table, echo = FALSE} -ptab <- parity[, c("wsg", "species", "total_segs", "match_pct", - "n_diffs", "top_pattern", "top_pattern_count")] -names(ptab) <- c("WSG", "species", "segments", "match %", "n diffs", - "top diff pattern (link | bcfishpass)", "count") +ptab <- parity[, c("wsg", "species", "total_segs", "match_pct")] +names(ptab) <- c("WSG", "species", "segments", "match %") knitr::kable( ptab, row.names = FALSE, caption = paste0( "Per-segment mapping_code parity for bull trout in PARS, link's ", - "bcfishpass config vs the local bcfishpass snapshot. The top diff pattern ", - "column shows the most common (link | reference) disagreement, not a ", - "literal mapping_code value." + "bcfishpass config vs the local bcfishpass snapshot." ) ) ``` ```{r parity-pct, echo = FALSE, results = "asis"} cat(sprintf(paste0("link reproduces **%.2f%%** of bcfishpass's per-segment ", - "bull-trout `mapping_code` across %s segments, with %s ", - "disagreements. That is consistent with the 99.66%% ", - "study-area median established for the Peace.\n"), + "bull-trout `mapping_code` across %s segments — consistent ", + "with the 99.66%% study-area median established for the ", + "Peace.\n"), parity$match_pct[1], - format(parity$total_segs[1], big.mark = ","), - format(parity$n_diffs[1], big.mark = ","))) + format(parity$total_segs[1], big.mark = ","))) ``` -The remaining disagreements concentrate on intermittent reaches downstream of -dams — segments where the `;INTERMITTENT` and `;DAM` qualifiers interact, and -where cross-watershed-group ordering is most sensitive. - ### Accessible habitat (km) Per-segment `mapping_code` agreement is one lens; the habitat **totals** are -another. `link`'s `accessible_km` roll-up (`lnk_rollup_wsg()`) sums stream length -a species can reach — `access` in {modelled, observed} — and compares it against -the same quantity from the bcfishpass reference view, tunnel-free, using the -identical `IN (1, 2)` predicate. Before the #223 access-segmentation fix a reach -could straddle a gradient frontier and be credited whole; now streams break at -**every** frontier, so the accessible total converges on bcfishpass exactly. +another. `lnk_rollup_wsg()` sums, per species, the stream length a fish can reach +(accessible) and the lengths modelled as spawning and rearing — link's own model +output, produced whether or not there is anything to compare against. Below, +those totals sit next to the same quantities from the bcfishpass habitat model. +Because `link` breaks streams at every gradient frontier, a reach never straddles +the accessibility boundary, so the accessible total matches bcfishpass to a +rounding error. ```{r accessible-table, echo = FALSE} atab <- accessible @@ -277,8 +268,8 @@ knitr::kable( atab, row.names = FALSE, digits = 2, caption = paste0( "Bull-trout accessible / spawning / rearing habitat (km) in PARS: link's ", - "roll-up vs the local bcfishpass snapshot. accessible_km is the #223 target ", - "and matches exactly; spawning and rearing agree within habitat-methodology ", + "roll-up vs the local bcfishpass snapshot. Accessible habitat matches to a ", + "rounding error; spawning and rearing agree within the habitat model's ", "tolerance (both well inside the 5% parity band)." ) ) @@ -286,16 +277,13 @@ knitr::kable( ```{r accessible-pct, echo = FALSE, results = "asis"} acc <- accessible[accessible$metric == "accessible", ] -cat(sprintf(paste0("link models **%s km** of bull-trout accessible habitat in ", - "PARS against bcfishpass's **%s km** — a **%+.2f%%** difference. ", - "That aggregate holds to hundredths of a percent even though the ", - "per-segment `mapping_code` above disagrees on %s segments: the ", - "disagreements fall on short reaches that do not move the ", - "habitat totals.\n"), +cat(sprintf(paste0("link models **%s km** of accessible bull-trout habitat in ", + "PARS against bcfishpass's **%s km** — a **%+.2f%%** ", + "difference. Spawning and rearing agree within the habitat ", + "model's tolerance.\n"), formatC(acc$link_km, format = "f", digits = 1, big.mark = ","), formatC(acc$bcfp_km, format = "f", digits = 1, big.mark = ","), - acc$diff_pct, - format(parity$n_diffs[1], big.mark = ","))) + acc$diff_pct)) ``` ```{r symbology, include = FALSE} From fbbaa98fb46cee6451d49299652d101131f08bd9 Mon Sep 17 00:00:00 2001 From: almac2022 Date: Sun, 5 Jul 2026 08:15:09 -0700 Subject: [PATCH 2/3] vignette: correct mapping_code colour + barrier-direction description MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The symbology paragraph said 'a purple segment sits below a dam' — inverted. Verified against R/lnk_pipeline_mapping_code.R (token 2 = most-relevant barrier DOWNSTREAM, emitted only when the species' blocking barriers downstream are empty) and the PARS data (every coloured reach has has_barriers_bt_dnstr = false; the 58,916 blocked reaches carry no code). Rewritten: only accessible reaches are coloured; colour names the most-significant structure downstream (necessarily non-blocking for the species) with all five classes + their colours (blue none / orange modelled / red assessed-PSCIS / purple dam / green remediated); width carries habitat use. Co-Authored-By: Claude Fable 5 Claude-Session: https://claude.ai/code/session_014kSEJoad4Bc553qU8eFiE6 --- vignettes/pars-habitat-connectivity.Rmd | 24 +++++++++++++++--------- 1 file changed, 15 insertions(+), 9 deletions(-) diff --git a/vignettes/pars-habitat-connectivity.Rmd b/vignettes/pars-habitat-connectivity.Rmd index d4a6541..3e4d6cb 100644 --- a/vignettes/pars-habitat-connectivity.Rmd +++ b/vignettes/pars-habitat-connectivity.Rmd @@ -120,15 +120,21 @@ knitr::kable( Each segment's `mapping_code` is a compact token of the form `;`, optionally suffixed `;INTERMITTENT` for intermittent -streams. The first field is the highest-value habitat use modelled for that -segment — `SPAWN`, `REAR`, or `ACCESS` (reachable, but no modelled spawning or -rearing habitat). The second records the most significant barrier *downstream* -of the segment: `NONE` (none known), `MODELLED` (a modelled potential barrier), -`ASSESSED` (a field-assessed known barrier), `DAM`, or `REMEDIATED` (a barrier -since fixed). Stream colour is keyed on barrier status alone — a purple segment -sits below a dam, a red one below a field-assessed barrier — regardless of -habitat use, while line width encodes the habitat use itself: spawning reaches -draw thickest, rearing medium, access-only thinnest. Intermittent reaches +streams. A segment is classified only where the species can reach it — its +blocking barriers all lie upstream — so **every coloured reach is accessible +habitat**; reaches the species cannot reach carry no code and stay grey. The +first field is the highest-value habitat use modelled for the reach — `SPAWN`, +`REAR`, or `ACCESS` (reachable, but no modelled spawning or rearing habitat) — +and it sets the **line width**: spawning thickest, rearing medium, access-only +thinnest. The second field sets the **colour** and names the most significant +structure lying *downstream* of the reach — necessarily one that does not block +the species, since a blocking barrier would leave the reach inaccessible and +uncoloured: `NONE` (blue, none known), `MODELLED` (orange, a mapped but +unassessed crossing), `ASSESSED` (red, a field-assessed PSCIS crossing), `DAM` +(purple), or `REMEDIATED` (green, a barrier since fixed). So a purple reach is +accessible habitat with a dam downstream of it, and a red reach has a +field-assessed crossing downstream — the colour reflects that downstream +structure, not the habitat use, which the width carries. Intermittent reaches (`;INTERMITTENT`) draw dashed. Colours and widths are read straight from the bcfishpass symbology registry, so the maps match a bcfishpass QGIS project exactly. From c6ee5fb151c40cf5206a24279cb164f31387aa49 Mon Sep 17 00:00:00 2001 From: almac2022 Date: Mon, 6 Jul 2026 11:46:42 -0700 Subject: [PATCH 3/3] vignette: drop the mapping_code symbology paragraph Per review: the prose kept mis-stating the colour semantics (esp. red = a PSCIS crossing ranked BARRIER, not just any field-assessed crossing), and the per-map legend already carries the colour key. Cleaner to remove the whole paragraph than to keep chasing exact wording. Co-Authored-By: Claude Fable 5 Claude-Session: https://claude.ai/code/session_014kSEJoad4Bc553qU8eFiE6 --- vignettes/pars-habitat-connectivity.Rmd | 21 --------------------- 1 file changed, 21 deletions(-) diff --git a/vignettes/pars-habitat-connectivity.Rmd b/vignettes/pars-habitat-connectivity.Rmd index 3e4d6cb..16adf36 100644 --- a/vignettes/pars-habitat-connectivity.Rmd +++ b/vignettes/pars-habitat-connectivity.Rmd @@ -118,27 +118,6 @@ knitr::kable( ) ``` -Each segment's `mapping_code` is a compact token of the form -`;`, optionally suffixed `;INTERMITTENT` for intermittent -streams. A segment is classified only where the species can reach it — its -blocking barriers all lie upstream — so **every coloured reach is accessible -habitat**; reaches the species cannot reach carry no code and stay grey. The -first field is the highest-value habitat use modelled for the reach — `SPAWN`, -`REAR`, or `ACCESS` (reachable, but no modelled spawning or rearing habitat) — -and it sets the **line width**: spawning thickest, rearing medium, access-only -thinnest. The second field sets the **colour** and names the most significant -structure lying *downstream* of the reach — necessarily one that does not block -the species, since a blocking barrier would leave the reach inaccessible and -uncoloured: `NONE` (blue, none known), `MODELLED` (orange, a mapped but -unassessed crossing), `ASSESSED` (red, a field-assessed PSCIS crossing), `DAM` -(purple), or `REMEDIATED` (green, a barrier since fixed). So a purple reach is -accessible habitat with a dam downstream of it, and a red reach has a -field-assessed crossing downstream — the colour reflects that downstream -structure, not the habitat use, which the width carries. Intermittent reaches -(`;INTERMITTENT`) draw dashed. Colours and widths are read straight from the -bcfishpass symbology registry, so the maps match a bcfishpass QGIS project -exactly. - ## Cached inputs The model run and the bcfishpass comparison both require a populated