Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion DESCRIPTION
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
Package: link
Title: Stream Network Habitat Interpretation (Experimental)
Version: 0.41.0
Version: 0.41.1
Date: 2026-05-27
Authors@R: c(
person("Allan", "Irvine", , "airvine@newgraphenvironment.com",
Expand Down
4 changes: 4 additions & 0 deletions NEWS.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
# link 0.41.1

`data-raw/study_area_run.sh` gains a `--schema=<persist-schema>` flag for side-by-side bundle compares. Without the flag, behaviour is unchanged (config's YAML `pipeline$schema` default). With the flag, the driver exports `LNK_SCHEMA` so all per-WSG R scripts (`wsg_run_one.R`, `wsg_recompute_one.R`, `study_area_compare.R`) override `cfg$pipeline$schema` at runtime. The propagation works through SSH to cyphers too (each remote shell exports `LNK_SCHEMA` before its WSG loop). Use case: `--config=default --schema=fresh_default` lets a default-config run land in `fresh_default` without clobbering an earlier `--config=bcfishpass` baseline in `fresh`. Empty `--schema=` value errors loudly rather than silently falling through to the YAML default. Live-validated on ADMS (2.2 min, 11 species habitat tables landed in `fresh_default`, `fresh` untouched).

# link 0.41.0

New exported function `lnk_wsg_resolve()` — the bundle-aware "what WSGs should we model?" resolver ([#207](https://github.com/NewGraphEnvironment/link/issues/207)). Composes the FWA drainage closure (now a fresh primitive: `fresh::frs_wsg_drainage()`, [NewGraphEnvironment/fresh#211](https://github.com/NewGraphEnvironment/fresh/pull/212) / fresh v0.32.0) with the bundle's `wsg_species_presence` filter (link#157). Three call patterns dispatched by `(wsgs, expand)`: province mode (`wsgs = NULL` → all bundle-species WSGs, sorted alphabetically), closure mode (`wsgs = c(...), expand = TRUE` → focal + drainage closure, DS-first preserved), strict mode (`wsgs = c(...), expand = FALSE` → species-filter input verbatim). Validation mirrors `lnk_pipeline_species`; closure mode opens its own DB conn via `lnk_db_conn()` with `on.exit` cleanup; closure + strict modes emit `message()` listing any species-less WSGs dropped from the result (parity with the previous inline diagnostic). New `@family wsg` — pre-stages a `lnk_wsg_*` family for follow-on topology helpers (e.g. cross-host DS-first bucketing).
Expand Down
5 changes: 5 additions & 0 deletions data-raw/study_area_compare.R
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,11 @@ suppressPackageStartupMessages({
source("data-raw/wsg_compare.R")

cfg <- lnk_config(config)
# LNK_SCHEMA env var (set by study_area_run.sh --schema=) overrides the
# config's YAML default persist schema. Compare must read from the schema
# the run/recompute wrote to.
.lnk_schema_env <- Sys.getenv("LNK_SCHEMA")
if (nzchar(.lnk_schema_env)) cfg$pipeline$schema <- .lnk_schema_env

rows <- list()
for (w in wsgs) {
Expand Down
21 changes: 16 additions & 5 deletions data-raw/study_area_run.sh
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@
# --focal=<dispatcher focal csv> \
# --focal=<cy1 focal csv> \
# --focal=<cy2 focal csv> \
# [--config=bcfishpass] [--keep-cyphers]
# [--config=bcfishpass] [--schema=<persist-schema>] [--keep-cyphers]
#
# The number of --focal flags MUST equal 1 (dispatcher) + N cyphers, in
# order: first --focal -> dispatcher, the rest -> cyphers in --cy-workspaces
Expand All @@ -38,12 +38,15 @@ set -euo pipefail
# --- args ---
CY_WS=""
CONFIG="bcfishpass"
SCHEMA_OVERRIDE=""
KEEP_CYPHERS=0
FOCAL_ARR=()
for arg in "$@"; do
case "$arg" in
--cy-workspaces=*) CY_WS="${arg#--cy-workspaces=}" ;;
--config=*) CONFIG="${arg#--config=}" ;;
--schema=*) SCHEMA_OVERRIDE="${arg#--schema=}"
[ -n "$SCHEMA_OVERRIDE" ] || { echo "FATAL: --schema= requires a non-empty value" >&2; exit 1; } ;;
--focal=*) FOCAL_ARR+=("${arg#--focal=}") ;;
--keep-cyphers) KEEP_CYPHERS=1 ;;
*) echo "unknown arg: $arg" >&2; exit 1 ;;
Expand Down Expand Up @@ -73,10 +76,18 @@ CYPHER_TF="$HOME/Projects/repo/rtj/env/do/dev/cypher"
# cypher_prep does `git fetch origin && git reset --hard origin/$BRANCH`.
LINK_BRANCH="$(git -C "$REPO_ROOT" branch --show-current)"

# Resolve persist schema (don't hardcode "fresh").
SCHEMA=$(cd "$REPO_ROOT" && Rscript -e \
'cat(link::lnk_config(commandArgs(TRUE)[1])$pipeline$schema)' "$CONFIG" 2>/dev/null || true)
# Resolve persist schema: --schema= overrides the config's YAML default
# (e.g. for side-by-side bundle compares: --config=default --schema=fresh_default
# keeps the bcfp-config run intact in `fresh`). All R scripts read LNK_SCHEMA
# below and override `cfg$pipeline$schema` if it is non-empty.
if [ -n "$SCHEMA_OVERRIDE" ]; then
SCHEMA="$SCHEMA_OVERRIDE"
else
SCHEMA=$(cd "$REPO_ROOT" && Rscript -e \
'cat(link::lnk_config(commandArgs(TRUE)[1])$pipeline$schema)' "$CONFIG" 2>/dev/null || true)
fi
[ -n "$SCHEMA" ] || { echo "FATAL: could not resolve persist schema for --config=$CONFIG"; exit 1; }
export LNK_SCHEMA="$SCHEMA"

echo "=== study_area_run $TS ==="
echo " config: $CONFIG"
Expand Down Expand Up @@ -208,7 +219,7 @@ LOCAL_PID=$!
declare -A CY_PID
for WS in "${CY_WS_ARR[@]}"; do
IP="${CY_IP[$WS]}"; B_SPACE=$(echo "${CY_BUCKET[$WS]}" | tr ',' ' ')
ssh "cypher@$IP" "cd ~/Projects/repo/link && for w in $B_SPACE; do Rscript data-raw/wsg_run_one.R \$w '$CONFIG' || echo \"[WARN] cy WSG \$w failed\"; done" \
ssh "cypher@$IP" "cd ~/Projects/repo/link && export LNK_SCHEMA='$SCHEMA' && for w in $B_SPACE; do Rscript data-raw/wsg_run_one.R \$w '$CONFIG' || echo \"[WARN] cy WSG \$w failed\"; done" \
> "$LOG_DIR/${TS}_run_$WS.log" 2>&1 &
CY_PID[$WS]=$!
done
Expand Down
5 changes: 5 additions & 0 deletions data-raw/wsg_recompute_one.R
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,11 @@ DBI::dbExecute(conn, "SET statement_timeout = '600000'") # 10 min / statement
DBI::dbExecute(conn, "SET lock_timeout = '60000'") # 1 min on lock waits

cfg <- lnk_config(config)
# LNK_SCHEMA env var (set by study_area_run.sh --schema=) overrides the
# config's YAML default persist schema. Recompute must match the schema
# used by the run/consolidate phases.
.lnk_schema_env <- Sys.getenv("LNK_SCHEMA")
if (nzchar(.lnk_schema_env)) cfg$pipeline$schema <- .lnk_schema_env
loaded <- lnk_load_overrides(cfg)

active <- lnk_pipeline_species(cfg, loaded, wsg)
Expand Down
6 changes: 6 additions & 0 deletions data-raw/wsg_run_one.R
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,12 @@ conn <- lnk_db_conn(dbname = "fwapg", host = "localhost", port = 5432L,
on.exit(try(DBI::dbDisconnect(conn), silent = TRUE), add = TRUE)

cfg <- lnk_config(config)
# LNK_SCHEMA env var (set by study_area_run.sh --schema=) overrides the
# config's YAML default persist schema — used for side-by-side bundle
# compares so e.g. `--config=default --schema=fresh_default` doesn't
# clobber an earlier `--config=bcfishpass` run sitting in `fresh`.
.lnk_schema_env <- Sys.getenv("LNK_SCHEMA")
if (nzchar(.lnk_schema_env)) cfg$pipeline$schema <- .lnk_schema_env
loaded <- lnk_load_overrides(cfg)

# Defensive skip (link#157): a WSG with no bundle-species presence can't be
Expand Down