4 Results and Discussion

Results of Phase 1 and Phase 2 assessments are summarized in Figure 4.1 with additional details provided in sections below.


##make colors for the priorities
pal <- 
   leaflet::colorFactor(palette = c("red", "yellow", "grey", "black"), 
               levels = c("High", "Moderate", "Low", "No Fix"))

pal_phase1 <- 
   leaflet::colorFactor(palette = c("red", "yellow", "grey", "black"), 
               levels = c("High", "Moderate", "Low", NA))

  
map <- leaflet::leaflet(height=500, width=780) |>
  leaflet::addTiles()  |> 
  # leafem::addMouseCoordinates(proj4 = 26911) |> ##can't seem to get it to render utms yet
  # leaflet::addProviderTiles(providers$"Esri.DeLorme") |> 
  leaflet::addProviderTiles("Esri.WorldTopoMap", group = "Topo") |>
  leaflet::addProviderTiles("Esri.WorldImagery", group = "ESRI Aerial") |> 
  leaflet::addPolygons(data = wshd_study_areas, color = "#F29A6E", weight = 1, smoothFactor = 0.5,
              opacity = 1.0, fillOpacity = 0,
              fillColor = "#F29A6E", label = wshd_study_areas$watershed_group_name) |>
  leaflet::addPolygons(data = wshds, color = "#0859C6", weight = 1, smoothFactor = 0.5,
              opacity = 1.0, fillOpacity = 0.25,
              fillColor = "#00DBFF",
              label = wshds$stream_crossing_id,
              popup = leafpop::popupTable(x = dplyr::select(wshds |> sf::st_set_geometry(NULL),
                                                     Site = stream_crossing_id,
                                                     elev_site:area_km),
                                          feature.id = F,
                                          row.numbers = F),
              group = "Phase 2") |> 
  leaflet::addLegend(
    position = "topright",
    colors = c("red", "yellow", "grey", "black"),
    labels = c("High", "Moderate", "Low", 'No fix'), opacity = 1,
    title = "Fish Passage Priorities") |> 
  
leaflet::addCircleMarkers(data=dplyr::filter(tab_map_phase_1, assess_type_phase1 == "Yes" | assess_type_reassessment == "Yes"),
                 label = dplyr::filter(tab_map_phase_1, assess_type_phase1 == "Yes" | assess_type_reassessment == "Yes") |>
                   dplyr::pull(pscis_crossing_id),
                 # label = tab_map_phase_1$pscis_crossing_id,
                 labelOptions = leaflet::labelOptions(noHide = F, textOnly = TRUE),
                 popup = leafpop::popupTable(x = dplyr::select((tab_map_phase_1 |> sf::st_set_geometry(NULL) |> dplyr::filter(assess_type_phase1 == "Yes" | assess_type_reassessment == "Yes")),
                                                        Site = pscis_crossing_id, Priority = priority_phase1, Stream = stream_name, Road = road_name, `Habitat value`= habitat_value, `Barrier Result` = barrier_result, `Culvert data` = data_link, `Culvert photos` = photo_link, `Model data` = model_link),
                                             feature.id = F,
                                             row.numbers = F),
                 radius = 9,
                 fillColor = ~pal_phase1(priority_phase1),
                 color= "#ffffff",
                 stroke = TRUE,
                 fillOpacity = 1.0,
                 weight = 2,
                 opacity = 1.0,
                 group = "Phase 1") |> 
  leaflet::addPolylines(data=habitat_confirmation_tracks,
               opacity=0.75, color = '#e216c4',
               fillOpacity = 0.75, weight=5, group = "Phase 2") |>

leaflet::addAwesomeMarkers(
    lng = as.numeric(photo_metadata$gps_longitude),
    lat = as.numeric(photo_metadata$gps_latitude),
    popup = leafpop::popupImage(photo_metadata$url, src = "remote"),
    clusterOptions = leaflet::markerClusterOptions(),
    group = "Phase 2") |>


  leaflet::addCircleMarkers(
    data=tab_map_phase_2,
    label = tab_map_phase_2$pscis_crossing_id,
    labelOptions = leaflet::labelOptions(noHide = T, textOnly = TRUE),
    popup = leafpop::popupTable(x = dplyr::select((tab_map_phase_2 |> sf::st_drop_geometry()),
                                           Site = pscis_crossing_id,
                                           Priority = priority,
                                           Stream = stream_name,
                                           Road = road_name,
                                           `Habitat (m)`= upstream_habitat_length_m,
                                           Comments = comments,
                                           `Culvert data` = data_link,
                                           `Culvert photos` = photo_link,
                                           `Model data` = model_link),
                                feature.id = F,
                                row.numbers = F),
    radius = 9,
    fillColor = ~pal(priority),
    color= "#ffffff",
    stroke = TRUE,
    fillOpacity = 1.0,
    weight = 2,
    opacity = 1.0,
    group = "Phase 2"
    ) |>

  leaflet::addLayersControl(
    baseGroups = c(
      "Esri.DeLorme",
      "ESRI Aerial"),
    overlayGroups = c("Phase 1", "Phase 2"),
    options = leaflet::layersControlOptions(collapsed = F)) |>
  leaflet.extras::addFullscreenControl() |>
  leaflet::addMiniMap(tiles = leaflet::providers$"Esri.NatGeoWorldMap",
             zoomLevelOffset = -6, width = 100, height = 100)

map

Figure 4.1: Map of fish passage and habitat confirmation results

4.1 Site Assessment Data

A summary of fish passage assessment procedures conducted through SERNbc since 2023 — including assessments, habitat confirmations, design, remediation, monitoring, fish sampling, eDNA sampling, and drone imagery — is provided in Appendix - Assessment Data Summary.


Orthoimagery and elevation model rasters generated since 2023 are catalogued in Appendix - UAV Imagery.


4.2 Climate Departure

Four findings from the regional climate-departure analysis carry to fish-passage prioritisation.

Warming is broad and significant region-wide. All eight ecoregions of the study area warmed about 1.6 °C since 1951 — annual mean (+1.6 °C), daytime maximum (+1.5 °C), and overnight minimum (+1.8 °C) all tell the same story (Mann-Kendall p < 0.001 in every ecoregion). The rate has been steady rather than accelerating — the 1981–present slope is shallower than the 1951–present slope. A west-to-east gradient layers on top, with the interior plateau ecoregions warming roughly 0.5 °C more than the eastern Rocky Mountain ecoregions — see Appendix - Climate Departure Figure 5.11.

The atmosphere is drying despite flat precipitation. Vapour pressure deficit rose 0.34 hPa region-wide, significant in every ecoregion. Annual precipitation rose +3 % regionally but the long-term trend is not statistically significant in any of the eight ecoregions; soil moisture is essentially flat because the warmer atmosphere is drinking the modest precipitation increase back through evaporation and transpiration.

The snowpack signal is about timing, not quantity. Total annual snowfall is essentially unchanged (-6 %); annual snow water equivalent is down 10 %, neither significant. The unambiguous signals are on the summer side and at the midpoint: summer SWE collapsed 52 % and the snowmelt midpoint moved 12 days earlier (p < 0.001 regionally and in every ecoregion). Counterbalancing rises in winter snowmelt (+45 %) and spring snowmelt (+18 %) point in the same direction but are noisier season-by-season. The freshet is arriving weeks earlier and the high-elevation snowpack that historically lingered into summer no longer does.

Day-night asymmetry is present. Overnight minimums warmed 1.8 °C while daytime maximums warmed 1.5 °C — overnight outpacing daytime is the textbook fingerprint of greenhouse warming (Karl et al. 1993). Mean diurnal range has narrowed by 0.3 °C across the record.

For barrier prioritisation these signals cut both ways. Where upstream reaches are cold-limited, added growing-degree-days can raise the intrinsic potential of habitat above the barrier and increase the value of restoring passage; where upstream reaches sit closer to the upper edge of the cold-water thermal niche, the same warming reduces usable habitat and lowers the payoff. The watershed-group breakdown in Appendix - Climate Departure maps the eight-ecoregion signal onto the seven watershed groups via a percentage crosswalk.

4.3 Planning — Habitat, Connectivity and Floodplain Modelling

4.3.1 Habitat Modelling

Habitat modelling from bcfishpass including access model, linear spawning/rearing habitat model and lateral habitat connectivity models for watershed groups within our study area were updated for the spring of 2025 and are included spatially in the collaborative GIS project. A snapshot of these outputs related to each modeled and PSCIS stream crossing structure are also included within an sqlite database within this year’s project reporting/code repository here.

4.3.2 Statistical Support for Habitat Modelling

The statistical modelling underpinning these outputs — channel-width prediction, and Bayesian Spatial Stream Network modelling of stream temperature with Poisson Consulting (Hill et al. 2024; Hill et al. 2025) — is described in the Methods chapter. The 2024 effort was carried out in this study area, mapping stream discharge and temperature causal-effects pathways across the Nechako Watershed; the 2025 Skeena effort extended it to a larger network and added Growing-Season Degree Days as the productivity-relevant thermal metric, with observations drawn from water-temp-bc (Irvine [2025] 2025b). Both studies are linked in Attachment - Water Temperature Modelling.

These predictions are the route by which thermal condition enters prioritization: reaches too cold to support production can be discounted from intrinsic habitat models, and reaches becoming warm enough to support it recognised as gaining value.

4.3.3 Floodplain Delineation

Modelled functional floodplain in the Nechako River Watershed Group covers 54,306 ha — 13.1 % of the 4,148 km² watershed group — attached to 1,312 km of chinook accessible order-3+ streams. Within that footprint sit 439 lakes and 702 mapped wetland polygons — the off-channel inventory that crossing remediations in these reaches stand to reconnect or leave severed, depending on whether design accounts for the floodplain context around the structure. The full metric table, watershed-scale map, and Murray Creek confluence detail map are in Appendix - Floodplain Delineation.

4.4 Fish Passage Assessemnts

Field assessments were conducted between September 15, 2025 and October 05, 2025 by Allan Irvine, R.P.Bio. and Lucy Schick, B.Sc. A total of 12 Fish Passage Assessments were completed, including 12 Phase 1 assessments and 0 reassessments.


Of the 12 sites where fish passage assessments were completed, 12 were not yet inventoried in the PSCIS system. This included 3 crossings considered “passable”, 2 crossings considered a “potential” barrier, and 7 crossings were considered “barriers” according to threshold values based on culvert embedment, outlet drop, slope, diameter (relative to channel size) and length (MoE 2011).


A summary of crossings assessed, a rough cost estimate for remediation, and a priority ranking for follow-up for Phase 1 sites is presented in Table 4.1. Detailed data with photos are presented in Appendix - Phase 1 Fish Passage Assessment Data and Photos.



 tab_cost_est_phase1 |>
  select(`PSCIS ID`:`Cost Est ( $K)`) |> 
   fpr::fpr_kable(caption_text = paste0("Upstream habitat estimates and cost benefit analysis for Phase 1 assessments ranked as a 'barrier' or 'potential' barrier. ", sp_network_caption),
                  scroll = T)
Table 4.1: Upstream habitat estimates and cost benefit analysis for Phase 1 assessments ranked as a ‘barrier’ or ‘potential’ barrier. Bull trout network model used for habitat estimates (total length of stream network <25% gradient).
PSCIS ID External ID Priority Stream Road Barrier Result Habitat value Habitat Upstream (km) Stream Width (m) Fix Cost Est ( $K)
203577 5400047 low Van Lear Creek Unnamed Barrier Low 20.1 2.5 OBS 450
203578 24403467 moderate Tributary To Willow River Willow FSR Barrier Medium 20.1 3.2 OBS 450
203579 24403486 low Tributary To Willow River Willow FSR Potential Medium 7.8 2.0 OBS 450
203580 5400321 moderate Cordella Creek Colleymount Creek Potential High 23.9 3.2 OBS 450
203581 19703295 low Tributary To Fraser River Railway Barrier Medium 30.3 4.0 OBS 26625
203582 19703257 moderate Tabor Creek Railway Barrier Medium 196.4 10.0 OBS 27000
203583 5405348 low Tributary To Nadina River Tahtsa FSR Barrier Low 29.3 1.5 SS-CBS 100
203584 5405311 moderate Tributary To Nadina River Tahtsa FSR Barrier Medium 12.5 2.3 OBS 450
203585 5400078 low Van Lear Creek Colleymount Road Barrier Low 20.1 2.5 OBS 450

4.5 Habitat Confirmation Assessments

During the 2025 field assessments, habitat confirmation assessments were conducted at 6 sites within the Tabor River and Willow River watershed groups. A total of approximately 4.3 km of stream was assessed, combining reaches surveyed upstream and downstream of each crossing.


As collaborative decision-making was ongoing at the time of reporting, site prioritization can be considered preliminary. Results are summarized in Figure 4.1 and Table 4.2 with raw habitat data included in Attachment - Data. A summary of preliminary modelling results illustrating quantities of bull trout spawning and rearing habitat potentially available upstream of each crossing as estimated by measured/modelled channel width and upstream accessible stream length are presented in Figure 4.2. Detailed information for each site assessed with Phase 2 assessments, including maps, is presented in the per-site habitat-confirmation appendices: Tributary to Stony Lake (PSCIS 126158), Tabor Creek (PSCIS 196085 and 203582), South Yuzkli Creek (PSCIS 196332), and Tributary to Fraser River (PSCIS 203581 and 196076).


table_phase2_overview <- function(dat, caption_text = '', font = font_set, scroll = TRUE){
  dat2 <- dat |>
    kable(caption = caption_text, booktabs = T, label = NA) |>
    kableExtra::kable_styling(c("condensed"),
                              full_width = T,
                              font_size = font) |>
    kableExtra::column_spec(column = c(11), width_min = '1.5in') |>
    kableExtra::column_spec(column = c(1:10), width_max = '1in')

  if(identical(scroll,TRUE)){
    dat2 <- dat2 |>
      kableExtra::scroll_box(width = "100%", height = "500px")
  }
  dat2
}

tab_overview |> 
  table_phase2_overview(caption_text = paste0("Overview of habitat confirmation sites. ", sp_rearing_caption), 
                        scroll = gitbook_on)
Table 4.2: Overview of habitat confirmation sites. Bull trout rearing model used for habitat estimates (total length of stream network <10.5% gradient).
PSCIS ID Stream Road Tenure UTM UTM zone Fish Species Habitat Gain (km) Habitat Value Priority Comments
203581 Tributary To Fraser River Railway CN Rail 526469 5985767 10 11.6 Medium Low Landslide ~300m upstream of railway tracks - Wp208. Low gradient stream with abundant gravels and numerous fish to 60mm observed. Entrenched steep wall valley with several sections where clay banks have collapsed into the stream. Surveyed upstream from railway culvert for 650m. eDNA samples collected upstream of the crossing.
196076 Tributary To Fraser River Beaver FSR McLean R02924 A 527373 5985002 10 10.3 Medium Moderate Moderate-sized, low-gradient stream with abundant gravels and habitat suitable for fry and juvenile salmonid rearing, including shallow pools, small and large woody debris, and undercut banks. No fish or barriers were observed at the time of assessment. eDNA samples collected upstream and downstream of the crossing.
196085 Tabor Creek Willow-Cale FSR MoTi 518498 5962011 10 75.3 Medium Moderate Channel was dewatered at the time of assessment with shallow pools present at the downstream end of the site. Gravels were abundant throughout and suitable for chinook and sockeye spawning under adequate flow conditions. Deep pools were likely present when the stream was flowing. Chinook were documented downstream of the Willow FSR crossing in 2004. eDNA sample collected at the bottom end of the survey (upstream of the crossing).
203582 Tabor Creek Railway CN Rail 518844 5961981 10 74.8 Medium Moderate Stream was dewatered until approximately 360m upstream of the railway culverts. The farthest downstream pool contained numerous fry and was where eDNA sampling was conducted. Upstream, occasional pools transitioned to increasing flow toward the upper end of the site where a continually flowing channel reemerged. The system was extremely large with high flows during freshet based on the size of the substrates. Gravels were abundant throughout, with limited woody debris or instream cover at low flow, restricted mainly to interstitial spaces between cobbles and boulders.
126158 Tributary To Stony Lake Willow FSR MoF 577622 5918587 10 4.4 Medium High Low-gradient stream with abundant gravels and diverse cover types including boulders, small and large woody debris, and undercut banks. Good flow with no natural barriers observed within the surveyed area. eDNA sample was collected at the downstream end of the site. Bull trout documented downstream of the crossing in 2014.
196332 South Yuzkli Creek 24 Y Road W Fraser R14273 100S 578271 5895125 10 2.8 Medium High Steep stream with good flow and numerous step-pool features ranging from 30–50cm in height. Shallow pools were 30–40cm deep with pockets of gravel suitable for resident Bull trout spawning. Large woody debris was abundant throughout. eDNA sample was collected at the downstream end of the site.


fpr::fpr_table_cv_summary(dat = pscis_phase2)  |>  
  fpr::fpr_kable(caption_text = 'Summary of Phase 2 fish passage reassessments.', scroll = F)
Table 4.3: Summary of Phase 2 fish passage reassessments.
PSCIS ID Embedded Outlet Drop (m) Diameter (m) SWR Slope (%) Length (m) Final score Barrier Result
126158 No 1.60 1.5 2.80 2.5 37 37 Barrier
196076 No 0.55 1.2 3.33 2.0 50 37 Barrier
196085 No 0.00 4.0 2.50 2.5 32 27 Barrier
196332 No 0.60 1.2 2.83 6.5 23 39 Barrier
203581 No 2.50 2.1 1.90 2.5 50 37 Barrier
203582 No 0.30 5.2 1.92 0.5 50 32 Barrier


tab_cost_est_phase2 |>
    dplyr::rename(
    `PSCIS ID` = pscis_crossing_id,
    Stream = stream_name,
    Road = road_name,
    `Barrier Result` = barrier_result,
    `Habitat value` = habitat_value,
    `Habitat Upstream (m)` = upstream_habitat_length_m,
    `Stream Width (m)` = avg_channel_width_m,
    Fix = crossing_fix_code,
    `Cost Est ( $K)` = cost_est_1000s,
    `Cost Benefit (m / $K)` = cost_net,
    `Cost Benefit (m2 / $K)` = cost_area_net
  ) |> 
  fpr::fpr_kable(caption_text = paste0("Cost benefit analysis for Phase 2 assessments. ", sp_rearing_caption),
                 scroll = F)
Table 4.4: Cost benefit analysis for Phase 2 assessments. Bull trout rearing model used for habitat estimates (total length of stream network <10.5% gradient).
PSCIS ID Stream Road Barrier Result Habitat value Stream Width (m) Fix Cost Est ( $K) Habitat Upstream (m) Cost Benefit (m / $K) Cost Benefit (m2 / $K)
126158 Tributary To Stony Lake Willow FSR Barrier Medium 3.5 OBS 900 4447 4941.1 10376.3
196076 Tributary To Fraser River Beaver FSR Barrier Medium 3.5 OBS 585 10278 17569.2 35138.5
196085 Tabor Creek Willow-Cale FSR Barrier Medium 11.0 OBS 3600 75254 20903.9 104519.4
196332 South Yuzkli Creek 24 Y Road Barrier Medium 3.0 OBS 450 2774 6164.4 10479.6
203581 Tributary To Fraser River Railway Barrier Medium 4.5 OBS 26625 11634 437.0 873.9
203582 Tabor Creek Railway Barrier Medium 14.6 OBS 27000 74788 2769.9 13849.6


# Match Location exactly rather than with stringr::str_like(). str_like() is
# case sensitive as of stringr 1.5.0, so str_like(Location, 'upstream') stopped
# matching the "Upstream" values that 0130-tables.R writes, and this table has
# been rendering empty ever since.
tab_hab_upstream <- tab_hab_summary |>
  dplyr::filter(Location == 'Upstream') |>
  dplyr::select(-Location) |>
  dplyr::rename(`PSCIS ID` = Site, `Length surveyed upstream (m)` = `Length Surveyed (m)`)

# Total the surveyed length only. The remaining columns are averages, which do
# not sum, so they are left blank in the total row rather than showing numbers
# a reader would take for totals.
tab_hab_upstream |>
  dplyr::mutate(dplyr::across(dplyr::everything(), as.character)) |>
  dplyr::bind_rows(
    tibble::tibble(
      `PSCIS ID` = "Total",
      `Length surveyed upstream (m)` = as.character(
        sum(tab_hab_upstream$`Length surveyed upstream (m)`, na.rm = TRUE))
    )
  ) |>
  fpr::fpr_kable(
    caption_text = paste0(
      "Summary of Phase 2 habitat confirmation details. Lengths are for the reach surveyed ",
      "upstream of each crossing only; downstream reaches are reported in the site appendices, ",
      "and the combined upstream and downstream total is given in the text above."),
    scroll = F)
Table 4.5: Summary of Phase 2 habitat confirmation details. Lengths are for the reach surveyed upstream of each crossing only; downstream reaches are reported in the site appendices, and the combined upstream and downstream total is given in the text above.
PSCIS ID Length surveyed upstream (m) Average Channel Width (m) Average Wetted Width (m) Average Pool Depth (m) Average Gradient (%) Total Cover Habitat Value
126158 330 3.5 2.7 0.3 4.8 moderate medium
196076 700 3.5 2.1 0.4 2.8 moderate medium
196085 410 11 1.9 1.5 trace medium
196332 400 3 2.3 0.3 8.8 moderate medium
203581 650 4.5 1.9 0.3 2.5 moderate medium
203582 650 14.6 2.5 0.8 trace medium
Total 3140


fpr::fpr_table_wshd_sum() |> 
  fpr::fpr_kable(caption_text = paste0('Summary of watershed area statistics upstream of Phase 2 crossings.'),
                                 footnote_text = 'Elev P60 = Elevation at which 60% of the watershed area is above', scroll = F)
Table 4.6: Summary of watershed area statistics upstream of Phase 2 crossings.
Site Area Km Elev Site Elev Min Elev Max Elev Median Elev P60 Aspect
126158 10.4 956 929 1870 1376 1297 SSW
196076 14.9 629 572 784 696 691 SSW
196085 145.6 592 558 1254 703 683 SSW
196332 5.1 1218 1200 1636 1417 1398 SW
203581 17.5 592 572 784 688 680 SW
203582 145.6 601 558 1254 703 683 SSW
* Elev P60 = Elevation at which 60% of the watershed area is above


my_caption = paste0("Summary of potential rearing and spawning habitat upstream of habitat confirmation assessment sites. ", model_species_name," rearing and spawning models used for habitat estimates (total length of stream network <", rear_gradient, "% and <", spawn_gradient, "% gradient, respectively).")
bcfp_xref_plot <- xref_bcfishpass_names |> 
  filter(!is.na(id_join) &
         !stringr::str_detect(bcfishpass, 'below') &
         !stringr::str_detect(bcfishpass, 'all') &
         !stringr::str_detect(bcfishpass, '_ha') &
         (stringr::str_detect(bcfishpass, 'rearing') | 
          stringr::str_detect(bcfishpass, 'spawning')))


bcfishpass_phase2_plot_prep <- bcfishpass |> 
  dplyr::mutate(dplyr::across(where(is.numeric), round, 1)) |>
  dplyr::filter(stream_crossing_id %in% (pscis_phase2 |> dplyr::pull(pscis_crossing_id))) |> 
  dplyr::select(stream_crossing_id, dplyr::all_of(bcfp_xref_plot$bcfishpass)) |> 
  dplyr::mutate(stream_crossing_id = as.factor(stream_crossing_id)) |> 
  tidyr::pivot_longer(cols = bt_rearing_km:bt_spawning_km) |> 
  dplyr::filter(value > 0.0 &
                !is.na(value)) |> 
  dplyr::mutate(
    name = dplyr::case_when(stringr::str_detect(name, '_rearing') ~ paste0(model_species_name, " rearing km"),
                            TRUE ~ name),
    name = dplyr::case_when(stringr::str_detect(name, '_spawning') ~ paste0(model_species_name, " spawning km"),
                            TRUE ~ name)
    # Use when more than one modelling species 
   # name = stringr::str_replace_all(name, '_rearing', ' rearing'),
   # name = stringr::str_replace_all(name, '_spawning', ' spawning')
  )
  
  
  
bcfishpass_phase2_plot_prep |> 
  ggplot2::ggplot(ggplot2::aes(x = stream_crossing_id, y = value)) +
  ggplot2::geom_bar(stat = "identity") +
  ggplot2::facet_wrap(~name, ncol = 2) +
  # ggdark::dark_theme_bw(base_size = 11) +
  ggplot2::theme_bw(base_size = 11) +
  ggplot2::theme(axis.text.x = ggplot2::element_text(angle = 45, hjust = 1, vjust = 1)) +
  ggplot2::labs(x = "Site", y = "Modelled habitat (km)")
Summary of potential rearing and spawning habitat upstream of habitat confirmation assessment sites. Bull trout rearing and spawning models used for habitat estimates (total length of stream network <10.5% and <5.5% gradient, respectively).

Figure 4.2: Summary of potential rearing and spawning habitat upstream of habitat confirmation assessment sites. Bull trout rearing and spawning models used for habitat estimates (total length of stream network <10.5% and <5.5% gradient, respectively).

# ### Fish Sampling
# 
# Fish sampling was conducted at `r tab_fish_sites_sum |> n_distinct()` sites within 6 streams, with a total of `r tab_fish_summary |> dplyr::pull(count_fish) |> sum(na.rm = TRUE)` fish captured. Fork length, weight, and species were documented for each fish. Salmonids with fork lengths >60mm were PIT-tagged to facilitate long-term tracking of health and movement. Fork length data was used to delineate salmonids based on life stages: fry (0 to 65mm), parr (>65 to 110mm), juvenile (>110mm to 140mm), and adult (>140mm) by visually assessing the histograms presented in Figure \@ref(fig:fish-histogram). A summary of sites assessed is included in Table \@ref(tab:tab-fish-site-summary), and raw data is provided in [Attachment - Data](#attach-dat). A summary of density results is also presented in Figure \@ref(fig:plot-fish-all).
# 
# <br>
# 
# Results are presented in detail within the individual appendices in this report with the [2023 report](https://newgraphenvironment.github.io/fish_passage_peace_2023_reporting) updated with fish sampling data for PSCIS crossing 125131 on Chuchinka-Table FSR.  Documentation for each site can be accessed `r if(identical(gitbook_on, FALSE)){knitr::asis_output(paste0("online within the Assessment Data Summary appendix of the report found ", ngr::ngr_str_link_url(url_base = params$report_url, url_resource = "app-site-data.html", anchor_text = "here")))}else{knitr::asis_output("by searching the site number in Table \\@ref(tab:tab-sites-cap) of [Appendix - Assessment Data Summary](#app-site-data) and clicking the _Link Report_")}`.
# 
# <br>
# 
# `r if(gitbook_on){knitr::asis_output("")} else knitr::asis_output("<br><br><br><br>")`
# 
# <br>
tab_fish_sites_sum |> 
  fpr::fpr_kable(caption_text = 'Summary of electrofishing sites.')


plot_fish_box_all <- fish_abund |> 
  dplyr::filter(
    !species_code %in% c('Mountain Whitefish', 
                         'Sucker (General)',
                         'NFC',
                         'Longnose Sucker',
                         'Sculpin (General)')
  ) |> 
  ggplot2::ggplot(ggplot2::aes(x = location, y = density_100m2)) +
  ggplot2::geom_boxplot(fill = NA) +
  ggplot2::facet_grid(life_stage ~ site, scales = "free_y", as.table = TRUE) +

  # ggplot2::facet_grid(site ~ species_code, scales = "fixed", as.table = TRUE) +
  ggplot2::theme(legend.position = "none", axis.title.x = ggplot2::element_blank()) +
  ggplot2::geom_dotplot(binaxis = 'y', stackdir = 'center', dotsize = 1) +
  ggplot2::ylab(expression(Density ~ (Fish/100 ~  m^2))) +
  ggplot2::theme_bw()
  # ggdark::dark_theme_bw()



plot_fish_box_all


# Fish histogram -----------------------------------------------------------------------
bin_1 <- floor(min(fish_data_complete$length, na.rm = TRUE) / 5) * 5
bin_n <- ceiling(max(fish_data_complete$length, na.rm = TRUE) / 5) * 5
bins <- seq(bin_1, bin_n, by = 5)

# Check what species we have and filter out any we don't want
# fish_data_complete |> dplyr::distinct(species)

plot_fish_hist <- ggplot2::ggplot(
  fish_data_complete |> dplyr::filter(!species %in% c('Fish Unidentified Species', 'Sculpin (General)', 'NFC')),
  ggplot2::aes(x = length)
) +
  ggplot2::geom_histogram(breaks = bins, alpha = 0.75,
                          position = "identity", size = 0.75) +
  ggplot2::labs(x = "Fork Length (mm)", y = "Count (#)") +
  ggplot2::facet_wrap(~species) +
  ggplot2::theme_bw(base_size = 8) +
  ggplot2::scale_x_continuous(breaks = bins[seq(1, length(bins), by = 2)]) +
  ggplot2::theme(axis.text.x = ggplot2::element_text(angle = 45, hjust = 1))

plot_fish_hist

4.5.1 Environmental DNA (eDNA) sampling

New in 2025, environmental DNA (eDNA) sampling was incorporated into the program at both previously assessed and newly added sites. A total of 38 collection events were undertaken across 16 streams, comprising 33 real environmental samples, 2 field blanks, and 3 office blanks collected for quality assurance.

Per-species detection results across the 33 real environmental samples are summarized in Table 4.7. Detections use the four-droplet call threshold applied by the laboratory; results below that threshold, including two- and three-droplet results that were retested without reaching the cutoff, are reported as not detected. Laboratory methods and per-sample results are in the UNBC technical report, available here. Non-detections should be read with care: internal amplification controls were reported for only a minority of samples, and where they are absent a zero result cannot be distinguished from a reaction that failed or was inhibited. Detections are unaffected, since a well returning positive droplets demonstrably amplified. Site-level detail — the per-site detection table, field blanks, and retests — is provided in Appendix - Environmental DNA Results, and the interactive Fraser eDNA map shows toggleable per-species layers.


edna_summary_fraser |>
  fpr::fpr_kable(
    caption_text = "Per-species summary of eDNA results across real environmental samples in the Fraser project area (excludes field and office blanks).",
    scroll = FALSE
  )
Table 4.7: Per-species summary of eDNA results across real environmental samples in the Fraser project area (excludes field and office blanks).
Species Code Sites tested Detected (≥4 droplets) Not detected
Rainbow Trout RAIN 23 20 3
Chinook Salmon CHIN 30 9 21
Bull Trout BULT 33 5 28
Burbot BURB 5 1 4
Sockeye Salmon SOCK 12 1 11
Coho Salmon COHO 21 0 21
Rainbow Trout (confirmation primer) RAIN2 2 0 2


4.6 Engineering Design

No new designs were commissioned in 2025 due to uncertainty related to forest harvesting activities and lack of funding for the 50% costs of replacing structures. All sites with a design for remediation of fish passage can be found in Table 5.10 of Appendix - Assessment Data Summary by filtering using Design = yes.

4.7 Monitoring

In 2025, baseline or follow up monitoring data was gathered through completion of an effectivness montoring form (sites where remediation has been completed) and/or through eDNA sampling and aquistion of aerial imagery at the following sites (Table 4.8:

  • Effectiveness monitoring was conducted on Tabor Creek (PSCIS crossing 196085) on Willow Cale FSR, where previous remediation work backwatered the outlet, removed the outlet drop and installed baffles within the culvert. The crossing remains ranked a barrier to upstream passage.

  • Effectiveness monitoring continued on Bittner Creek (PSCIS crossing 196200) on Forman Road, where the culvert was replaced with a bridge prior to the 2022 reassessment and now ranks passable (Irvine 2024). Results are presented in the Bittner Creek - 196200 - Monitoring Appendix.

# started but not sure if this is going to be helpful. 
form_monitoring |> 
 sf::st_drop_geometry() |> 
 dplyr::select(
    `PSCIS ID` = pscis_crossing_id,
    Stream = stream_name,
    Road = road_name,
    `Crossing type` = crossing_type,
    `Crossing subtype` = crossing_subtype,
    `Diameter or span (m)` = diameter_or_span_meters,
    `Length or width (m)` = length_or_width_meters,
    `Assessment comments` = assessment_comment
  ) |> 
   fpr::fpr_kable(caption_text = 'Summary of monitoring sites.', scroll = F)
Table 4.8: Summary of monitoring sites.
PSCIS ID Stream Road Crossing type Crossing subtype Diameter or span (m) Length or width (m) Assessment comments
196085 Tabor Creek Willow-Cale FRS CBS OVAL 4 32 eDNA samples collected upstream and downstream of the crossing during the monitoring assessment.
196200 Bittner Creek Foreman Road OBS BRIDGE


4.8 Collaborative GIS Environment

Fieldwork activities and background spatial layers are maintained in a collaborative QGIS and Mergin Maps environment (sern_fraser_2024), which field crews and partners use to view, edit and add data. The layers loaded at the time of writing are listed in Appendix - Collaborative GIS Layers.