DFO is undertaking status assessments of Yukon Chinook Conservation Units (CUs) as part of the CSAS process “Estimating Precautionary Approach Reference Points and Assessing Consequences of Harvest Control Rules for Canadian Origin Yukon Chinook salmon”.
Their general approach to estimating spawner abundance and relative abundance benchmarks for Yukon Chinook CUs relies on reconstructing spawners and recruitment using (1) border counts at the Eagle sonar and (2) identification of the proportion of fish at Eagle that belong to different genetic stock aggregates, which correspond roughly to CUs.
For some CUs, namely Teslin Chinook and Upper Yukon Chinook, the reconstructed spawner abundance seems to overestimate observed spawner abundance in tributary surveys and is inconsistent with local knowledge of returns.
PSF is also undertaking status assessments of CUs as part of adding the Yukon to the Pacific Salmon Explorer.
Here, we consider alternatives to DFO’s run reconstructions for estimating an index of CU-level spawner abundance for:
The following is work in progress. Any feedback on the proposed approaches to assessing the status of these CUs is welcomed!
In general, CU-level spawner abundance can be estimated using one of three approaches, depending on the CU and available data:
A spawner survey may be considered a complete count of the CU if there is a weir or other high-quality survey that counts the entire CU. This is often the case for lake-type sockeye.
CU-level spawner abundance may be calculated by splitting an aggregate count of multiple CUs (e.g., the Eagle sonar) into its component CUs using additional information on genetics, run timing, or body size (or in some cases egg size!) that differs among CUs. This is the approach taken by Connors et al. and proposed for Yukon Chinook CUs by DFO.
An index of CU-level spawner abundance is calculated from multiple spawner surveys within the CU by expanding from available data in a given year to account for those surveys that weren’t done. This expansion approach is commonly applied on the North and Central coast (see English et al. 2018 for full description).
Generating an index of spawner abundance for a CU from available indicator surveys (approach 3) involves summing the counts among surveys, imputing counts for a survey when they are missing to ensure the index is consistent through time.
In years when none of the indicator surveys are conducted in a CU, it is not possible to estimate the index of spawner abundance for CU in that year.
When there is at least one survey, we can impute missing survey counts based on their average proportional contribution to the index in other years. The proportional contribution is estimated by calculating the following:
The average count for each survey, \(\bar{S_i}\).
The sum of average counts among all \(n\) surveys in a CU: \(\bf{S} = \sum_{i = 1}^n \bar{S_i}\).
The average proportional contribution of survey \(i\) to the sum: \(P_i = \bar{S_i}/\bf{S}\).
We can then impute the missing data by applying an expansion factor to the sum among surveys in a given year based on which survey is missing. The expansion factor for year \(y\) is calculated as: \[ E_y = \frac{1}{\sum_i(P_{i} \times w_{iy})} \] where \(w_{iy}\) is an indicator taking the value ‘1’ if an survey count is available for survey \(i\) in year \(y\) and ‘0’ if an survey count is not available.
trib_spwn.csv
was provided by DFO and contains
tributary spawner survey data for all Yukon Chinook CUs:## year estimate system type CU hatch_contrib pni comments
## 1 2005 5618 bigsalmon sonar BigSalmonR NA NA
## 2 2006 7308 bigsalmon sonar BigSalmonR NA NA
## 3 2007 4506 bigsalmon sonar BigSalmonR NA NA
## 4 2008 1329 bigsalmon sonar BigSalmonR NA NA
## 5 2009 9261 bigsalmon sonar BigSalmonR NA NA
## 6 2010 3817 bigsalmon sonar BigSalmonR NA NA
system
and create new
surveys_teslin
dataframe:## nisutlin wolf
## 1969 105 NA
## 1970 615 NA
## 1971 650 750
## 1972 237 13
## 1973 NA NA
## 1974 NA NA
# Calculate average spawners for each survey
avgSpawners_teslin <- apply(surveys_teslin, 2, sum, na.rm = TRUE) / apply(is.na(surveys_teslin) == FALSE, 2, sum)
# Calculate proportional contribution of each survey to the sum
P_teslin <- matrix(avgSpawners_teslin / sum(avgSpawners_teslin, na.rm = TRUE), nrow = 1, dimnames = list(NULL, c("nisutlin", "wolf")))
In this case, the average proportional contribution of Nisutlin to the index is \(P_1 =\) 0.66 and the average proportional contribution of Wolf is \(P_2 =\) 0.34.
The expanded_index
can then be calculated using the
formula above:
# Create matrix to indicate when a survey is missing
w_teslin <- is.na(surveys_teslin) == FALSE
# Calculate expansion factor as 1 over the proportional contribution of the missing stream
E_teslin <- apply(matrix(rep(P_teslin, dim(w_teslin)[1]), nrow = dim(w_teslin)[1], ncol=dim(w_teslin)[2], byrow = TRUE) * w_teslin, 1, sum, na.rm=TRUE) ^ (-1)
# Expansions cannot be done when both surveys are missing
E_teslin[which(apply(w_teslin, 1, sum) == 0)] <- NA
# Calculate simple sum of observed counts
surveys_teslin$sum <- apply(surveys_teslin[, c("nisutlin", "wolf")], 1, sum, na.rm = TRUE)
surveys_teslin$sum[which(apply(w_teslin, 1, sum) == 0)] <- NA
# Calculate expanded sum of observed counts
surveys_teslin$expanded_index <- round(surveys_teslin$sum * E_teslin)
# Calculate smoothed generational average of index
surveys_teslin$generational_mean <- rollapply(
data = log(surveys_teslin$expanded_index),
FUN = mean,
width = 6,
# na.pad = TRUE, # deprecated. Use fill = NA instead of na.pad = TRUE
na.rm = T,
fill = NA,
align = "right") %>%
exp() %>%
round()
Current geometric mean abundance over the most recent generation (2019-2024) based on the expanded index of spawner abundance is 82 spawners.
Percentile benchmarks based on the expanded index (if you went this route) would be \(S_{25}=\) 231 and \(S_{75}=\) 828, putting this CU in the Red status zone. This is likely the appraoch that PSF will take for assessing this CU, since we commonly apply percentile benchmarks to other CUs outside of the Yukon.
However, using percentile benchmarks here would be inconsistent with benchmarks used for other Yukon Chinook CUs in DFO’s assessments. Further, there has likely been high exploitation of this CU historically, which can introduce bias in status outcomes with percentiles (Holt and Folkes 2015).
# Calculate long-term trend
teslin.LT_trend <- round(surveys_teslin$generational_mean[yrs_teslin == 2024] / exp(mean(log(surveys_teslin$expanded_index), na.rm = TRUE)) * 100)
# Calculate short-term trend (smoothed data, log-scale)
teslin.lm.data <- data.frame(y = log(tail(surveys_teslin$generational_mean, 6*3)),
x = tail(yrs_teslin, 18))
teslin.trend <- lm(y ~ x, data = teslin.lm.data)
teslin.predict <- predict.lm(teslin.trend, newdata = data.frame(x = c(2007, 2024)))
teslin.percChange <- round((exp(teslin.predict[2]) - exp(teslin.predict[1]))/exp(teslin.predict[1]) * 100)
Figure 1. Time series of aerial survey counts for the Nisutlin River and Wolf River, along with a CU-level index of spawner abundance calculated as the expanded sum of these two surveys. See table below for data.
Figure 2. Comparison of run-reconstruction estimates of spawner abundance for the Yukon River Headwaters/Teslin Chinook CU compared to the index constructed from two aerial surveys (Fig. 1).
Table 1. Time series of aerial survey counts for the Nisutlin River and Wolf River, along with a CU-level index of spawner abundance calculated as the expanded sum of these two surveys. The generational average is calculated as the right-aligned running geometric mean of the expanded index over a generation length of 6 years, ignoring missing years of data. (Note that DFO does not calculate this generational mean metric if any one of 6 years are missing within a generation.)
It has been estimated that the counts at the Whitehorse Fish ladder and the Takhini sonar together account for nearly all of the spawners in the Upper Yukon CU.
The Whitehorse Fish Ladder has counts of salmon for every year
from 1961 to 2024, while the Takhini River sonar has only 12 counts in
that same period. Early counts provided in trib-spwn.csv
by
DFO appear to be aerial surveys, with lower abundances and may not be
comparable to more recent years. A sonar project on the Takhini has been
run six of the past eight years, and those estimates have been close to
or higher than the counts at the Whitehorse Fish Ladder.
cu_upper <- read.csv(paste0(wd_data,"/run-reconstruction-CU-spawners.25Apr2025.csv")) %>%
filter(stock == "UpperYukonR.")
# Calculate running mean
cu_upper$smoothed_mean <- c(rep(NA, 5), exp(apply(log(cbind(cu_upper$mean[1:35], cu_upper$mean[2:36], cu_upper$mean[3:37], cu_upper$mean[4:38], cu_upper$mean[5:39], cu_upper$mean[6:40])), 1, mean)))
# Extract range of years for surveys
yrs_upper <- c(min(surveys_long$year[surveys_long$system %in% c("whitehorse", "tahkini")]):max(surveys_long$year[surveys_long$system %in% c("whitehorse", "tahkini")]))
# Construct data frame with survey counts for each year
# Note spelling error in data file: tahkini instead of takhini
surveys_upper <- data.frame(
whitehorse = surveys_long$estimate[surveys_long$system == "whitehorse"][match(yrs_upper, surveys_long$year[surveys_long$system == "whitehorse"])],
takhini = surveys_long$estimate[surveys_long$system == "tahkini"][match(yrs_upper, surveys_long$year[surveys_long$system == "tahkini"])]
)
rownames(surveys_upper) <- yrs_upper
surveys_upper$whitehorse_wild <- round(surveys_upper$whitehorse * (1 - surveys_long$hatch_contrib[surveys_long$system == "whitehorse"][match(yrs_upper, surveys_long$year[surveys_long$system == "whitehorse"])]))
surveys_upper <- surveys_upper %>%
select(whitehorse, whitehorse_wild, takhini)
Figure 3. (a) The time series of spawner counts at the Whitehorse Fish ladder and Takhini River sonar. The horizontal dashed line of 1,500 is the absolute spawner abundance threshold below which the CU would be assessed as Red. (b) The spawner counts as above, alongside the run reconstructions from Connors et al. based on border counts and genetic stock identification at Eagle.
It may not be justifiable to impute the Takhini River sonar counts for all missing years and calculate an expanded index of abundance as for Teslin (above) because there are so few years of data and the proportional contribution of the Takhini to the sum is high.
It could be possible to calculate the expanded index in more recent years (e.g., 2017 - 2024):
# Shorter time series
surveys_upper_recent <- surveys_upper[which(yrs_upper %in% c(2017:2024)), ]
# Calculate average *wild* spawners for each survey
avgSpawners_upper <- apply(surveys_upper_recent[, c("whitehorse_wild", "takhini")], 2, sum, na.rm = TRUE) / apply(is.na(surveys_upper_recent[, c("whitehorse_wild", "takhini")]) == FALSE, 2, sum)
# Calculate proportional contribution of each survey to the sum of *wild* spawners
P_upper <- matrix(avgSpawners_upper / sum(avgSpawners_upper, na.rm = TRUE), nrow = 1, dimnames = list(NULL, c("whitehorse_wild", "takhini")))
In this case, the average proportional contribution of Whitehorse to the wild spawner index is \(P_1 =\) 0.23 and the average proportional contribution of Takhini is \(P_2 =\) 0.77.
The expanded_index
is then calculated as
follows:
# Create matrix to indicate when a survey is missing
w_upper <- is.na(surveys_upper_recent[, c("whitehorse_wild", "takhini")]) == FALSE
# Calculate expansion factor as 1 over the proportional contribution of the missing stream
E_upper <- apply(matrix(rep(P_upper, dim(w_upper)[1]), nrow = dim(w_upper)[1], ncol=dim(w_upper)[2], byrow = TRUE) * w_upper, 1, sum, na.rm=TRUE) ^ (-1)
# Expansions cannot be done when both surveys are missing
E_upper[which(apply(w_upper, 1, sum) == 0)] <- NA
# Calculate simple sum of observed counts
surveys_upper_recent$sum <- apply(surveys_upper_recent[, c("whitehorse", "takhini")], 1, sum, na.rm = TRUE)
surveys_upper_recent$sum[which(apply(w_upper, 1, sum) == 0)] <- NA
# Calculate expanded sum of observed counts
surveys_upper_recent$expanded_index <- round(surveys_upper_recent$sum * E_upper)
# Smoothed abundance
surveys_upper_recent$generational_mean <- c(NA, NA, NA, NA, NA, round(exp(mean(log(surveys_upper_recent$expanded_index[1:6])))), round(exp(mean(log(surveys_upper_recent$expanded_index[2:7])))), round(exp(mean(log(surveys_upper_recent$expanded_index[3:8])))))
Table 2. Time series of counts at the Whitehorse fish ladder, and sonar counts on the Takhini River for 2017-2024, along with a CU-level index of spawner abundance calculated as the expanded sum of these two surveys and the smoothed generational average (used to assess status).
Current geometric mean abundance over the most recent generation (2019-2024) based on the expanded index of spawner abundance is 818 spawners, which is far below the lower absolute abundance threshold of 1,500.
The time series of expanded index is not long enough to apply relative abundance benchmarks. (To calculate percentiles of historical spawner abundance, you need at least 15 years of data.)