knitr::opts_chunk$set(echo = TRUE)
devtools::load_all()

required_pkg <- c(
  "RColorBrewer", "ggplot2", "tidyverse",
  "reshape2", "here"
)

pkg_to_install <- required_pkg[!(required_pkg %in%
  installed.packages()[, "Package"])]
if (length(pkg_to_install)) install.packages(pkg_to_install, repos = "http://cran.us.r-project.org")

invisible(lapply(required_pkg, library, character.only = TRUE))

options(digits = 2)

EwE scenario

We used the output data from EwE AMO_PCP scenario for generating single species stock assessment input data. The AMO_PCP scenario incorporates Atlantic Multidecadal Oscillation and precipitation information in the ecosystem modeling work and it creates a strong response.

devtools::load_all()

set.seed(999)

# specify working directories ---------------------------------------------

project_path <- here::here()
ewe_output_path <- file.path(project_path, "data", "ewe", "7ages", "ecosim_with_environmental_driver", "amo_pcp")
menhadenSA_output_path <- file.path(project_path, "data", "AtlanticMenhadenSA")

# read Atlantic menhaden Beaufort Assessment Model output data --------

menhadenSA_output <- dget(file.path(menhadenSA_output_path, "am019.rdat"))

years <- 1985:2017
ages <- 0:6
skip_nrows <- 8
species <- 4:10
species_labels <- paste0("age", ages)
species_vec <- paste0("X", species)

# Load biomass data
temp <- scan(file.path(ewe_output_path, "biomass_annual.csv"), what = "", sep = "\n")
data <- temp[-c(1:skip_nrows)]
data <- read.table(
  text = as.character(data),
  sep = ",",
  col.names = read.table(text = temp[skip_nrows], sep = ",")
)

data <- data[, c("year.group", species_vec)]
data[, species_vec] <- data[, species_vec] * 1000000  # biomass in mt
colnames(data) <- c("year", species_labels)

#data[, species_labels] <- data[, species_labels] / rowSums(data[, species_labels])
baa <- reshape2::melt(data, id.vars = c("year"))
colnames(baa) <- c("Year", "Age", "Biomass")

p <- ggplot(data=baa, aes(x=Age, fill=Age, y=Biomass)) +
      geom_bar(position='dodge', stat='identity') +
      facet_wrap(~Year) +
      labs(
        title = "Biomass-at-age",
        x = "Age",
        y = "Proportion"
      )+
      theme_bw()+
      theme(axis.text.x = element_text(angle = 45))
  print(p)

IFA4EBFM::create_fishery() is used to simulate fishery data

# Create fishery ----------------------------------------------------------

fishery_sample_num <- cbind(
  menhadenSA_output$t.series$acomp.cRs.n[which(menhadenSA_output$t.series$year %in% years)],
  menhadenSA_output$t.series$acomp.cBs.n[which(menhadenSA_output$t.series$year %in% years)],
  menhadenSA_output$t.$acomp.cBn.n[which(menhadenSA_output$t.series$year %in% years)],
  menhadenSA_output$t.series$acomp.cRn.n[which(menhadenSA_output$t.series$year %in% years)]
)
fishery_sample_num[fishery_sample_num==-99999] <- 0

fishery <- create_fishery(
  file_path = file.path(ewe_output_path, "catch_annual.csv"),
  skip_nrows = 8,
  species = 4:10,
  species_labels = paste0("age", ages),
  ewe_years = 0:32,
  data_years = years,
  fleet_num = 1,
  selectivity = NULL,
  CV = rep(0.05, length(years)),
  sample_num = apply(fishery_sample_num, 1, sum),
  waa_path = file.path(ewe_output_path, "weight_annual.csv")
)

Catch biomass and catch-at-age in proportion over time

# Total catch in biomass
om <- data.frame (
  Year = years, 
  Catch = fishery$om_total_catch_biomass,
  Model = "OM"
)

obs <- data.frame (
  Year = years, 
  Catch = fishery$obs_total_catch_biomass$fleet1,
  Model = "OBS"
)

year_id <- which(menhadenSA_output$t.series$year %in% years)
bam <- data.frame (
  Year = years, 
  Catch = (menhadenSA_output$t.series$L.cBs.ob[year_id] + menhadenSA_output$t.series$L.cBn.ob[year_id] + menhadenSA_output$t.series$L.cRs.ob[year_id] + menhadenSA_output$t.series$L.cRn.ob[year_id]) * 1000,
  Model = "BAM"
)

#data <- rbind(om, obs, bam)
data <- rbind(om, obs)
ggplot(data, aes(x = Year, y = Catch, color = Model)) +
  geom_line() +
  labs(
    title = "Comparison between models",
    x = "Year",
    y = "Total Catch (mt)"
  ) +
  theme_bw()

# Catch-at-age in number
om <- fishery$om_caa_abundance/rowSums(fishery$om_caa_abundance)
om$Year <- years
om$Model <- "OM"
om <- reshape2::melt(om, id.vars = c("Year", "Model"))
colnames(om) <- c("Year", "Model", "Age", "Catch")

obs <- fishery$obs_caa_prop$fleet1
obs$Year <- years
obs$Model <- "OBS"
obs <- reshape2::melt(obs, id.vars = c("Year", "Model"))
colnames(obs) <- c("Year", "Model", "Age", "Catch")

bam_crn <- as.data.frame(menhadenSA_output$comp.mats$acomp.cRn.ob[paste(years), ])
colnames(bam_crn) <- paste0("age", ages)
bam_crn$Year <- years
bam_crn$Model <- "BAM_cRn"
bam_crn <- reshape2::melt(bam_crn, id.vars = c("Year", "Model"))
colnames(bam_crn) <- c("Year", "Model", "Age", "Catch")

bam_crs <- as.data.frame(menhadenSA_output$comp.mats$acomp.cRs.ob[paste(years), ])
colnames(bam_crs) <- paste0("age", ages)
bam_crs$Year <- years
bam_crs$Model <- "BAM_cRs"
bam_crs <- reshape2::melt(bam_crs, id.vars = c("Year", "Model"))
colnames(bam_crs) <- c("Year", "Model", "Age", "Catch")

bam_cbn <- as.data.frame(menhadenSA_output$comp.mats$acomp.cBn.ob[paste(years), ])
colnames(bam_cbn) <- paste0("age", ages)
bam_cbn$Year <- years
bam_cbn$Model <- "BAM_cBn"
bam_cbn <- reshape2::melt(bam_cbn, id.vars = c("Year", "Model"))
colnames(bam_cbn) <- c("Year", "Model", "Age", "Catch")

bam_cbs <- as.data.frame(menhadenSA_output$comp.mats$acomp.cBs.ob[paste(years), ])
colnames(bam_cbs) <- paste0("age", ages)
bam_cbs$Year <- years
bam_cbs$Model <- "BAM_cBs"
bam_cbs <- reshape2::melt(bam_cbs, id.vars = c("Year", "Model"))
colnames(bam_cbs) <- c("Year", "Model", "Age", "Catch")

data <- list(om=om, obs=obs, bam_crn=bam_crn, bam_crs=bam_crs, bam_cbn=bam_cbn, bam_cbs=bam_cbs)
title <- paste(c("OM", "OBS", "BAM_cRn", "BAM_cRs", "BAM_cBn", "BAM_cBs"), "catch-at-age")

for (i in 1:2){
#for (i in 1:length(data)){
  p <- ggplot(data=data[[i]], aes(x=Age, fill=Age, y=Catch)) +
      geom_bar(position='dodge', stat='identity') +
      facet_wrap(~Year) +
      labs(
        title = title[i],
        x = "Age",
        y = "Proportion"
      )+
      theme_bw()+
      theme(axis.text.x = element_text(angle = 45))
  print(p)
}

IFA4EBFM::create_survey() is used to simulate survey data

# Create survey ----------------------------------------------------------

# selectivity settings
survey_num <- 4

survey_name <- c("survey1", "survey2", "survey3", "survey4")

# set up survey time
# Need to check Table 26 from BAM assessment: Length cutoffs used to distinguish age-0 from age-1+ Atlantic menhaden at different regions.

survey1_year <- 1990:2017 # Adult Index (survey1): age 1+ fish; September - January; Time of the year when menhaden were most abundant in this region

survey2_year <- 1985:2017 # Adult Index (survey2): age 1+ fish; March - May

survey3_year <- 1990:2017 # Adult Index (survey3): age 1+ fish: April - July

survey4_year <- 1985:2017 # YOY Index (survey4): covered all months, many surveys starts at July

survey_time <- list(
  survey1 = data.frame(
    year = survey1_year,
    month = rep(10, length(survey1_year)) # Oct 15
  ),
  survey2 = data.frame(
    year = survey2_year,
    month = rep(4, length(survey2_year)) # April 15
  ),
  survey3 = data.frame(
    year = survey3_year,
    month = rep(4, length(survey3_year)) # April 15
  ),
  survey4 = data.frame(
    year = survey4_year,
    month = rep(6, length(survey4_year)) # June 1
  )
)

# set up survey selectivity
survey1_sel <- IFA4EBFM::logistic(
  pattern = "simple_logistic",
  x = ages,
  slope_asc = 2.2,
  location_asc = 3.0
)

survey2_sel <- IFA4EBFM::logistic(
  pattern = "double_logistic",
  x = ages,
  slope_asc = 4.3,
  location_asc = 2.3,
  slope_desc = 3.5,
  location_desc = 2.3
)

survey3_sel <- IFA4EBFM::logistic(
  pattern = "double_logistic",
  x = ages,
  slope_asc = 7.0,
  location_asc = 0.3,
  slope_desc = 7.0,
  location_desc = 2.0
)

survey_selectivity <- list(
  survey1 = as.data.frame(
    matrix(rep(survey1_sel, times = length(years)), ncol = length(ages), byrow = TRUE),
    row.names = years
  ),
  survey2 = as.data.frame(
    matrix(rep(survey2_sel, times = length(years)), ncol = length(ages), byrow = TRUE),
    row.names = years,
  ),
  survey3 = as.data.frame(
    matrix(rep(survey3_sel, times = length(years)), ncol = length(ages), byrow = TRUE),
    row.names = years,
  ),
  survey4 = as.data.frame(
    matrix(rep(c(1, rep(0, 6)), times = length(years)), ncol = length(ages), byrow = TRUE),
    row.names = years,
  )
)

survey_selectivity <- lapply(survey_selectivity, setNames, paste("age", ages))

# set up catchability
yr_catchability_change_survey4 <- 1986

survey_catchability <- list(
  survey1 = menhadenSA_output$t.series$q.nad[which(menhadenSA_output$t.series$year %in% years)],
  survey2 = menhadenSA_output$t.series$q.mad[which(menhadenSA_output$t.series$year %in% years)],
  survey3 = menhadenSA_output$t.series$q.sad[which(menhadenSA_output$t.series$year %in% years)],
  survey4 = c(menhadenSA_output$t.series$q.jai[which(menhadenSA_output$t.series$year %in% c(years[1]:yr_catchability_change_survey4))], menhadenSA_output$t.series$q2.jai[which(menhadenSA_output$t.series$year %in% c((yr_catchability_change_survey4 + 1):tail(years, n = 1)))])
)

survey_catchability <- lapply(survey_catchability, setNames, years)

# set up CV
survey_CV <- list(
  survey1 = menhadenSA_output$t.series$cv.U.nad[which(menhadenSA_output$t.series$year %in% years)],
  survey2 = menhadenSA_output$t.series$cv.U.mad[which(menhadenSA_output$t.series$year %in% years)],
  survey3 = menhadenSA_output$t.series$cv.U.sad[which(menhadenSA_output$t.series$year %in% years)],
  survey4 = menhadenSA_output$t.series$cv.U.jai[which(menhadenSA_output$t.series$year %in% years)]
)
survey_CV <- lapply(survey_CV, setNames, years)

# set up sample number
# survey_sample_num <- list(
#   survey1 = menhadenSA_output$t.series$lcomp.nad.nfish[which(menhadenSA_output$t.series$year %in% years)],
#   survey2 = menhadenSA_output$t.series$lcomp.mad.nfish[which(menhadenSA_output$t.series$year %in% years)],
#   survey3 = rep(NA, length = length(years)),
#   survey4 = rep(NA, length = length(years))
# )

survey_sample_num <- list(
    survey1 = rep(800, length= length(years)),
    survey2 = rep(800, length= length(years)),
    survey3 = rep(800, length= length(years)),
    survey4 = rep(800, length= length(years))
)
survey_sample_num <- lapply(survey_sample_num, setNames, years)

for (i in 1:length(survey_sample_num)){
  survey_sample_num[[i]][survey_sample_num[[i]] == -99999] <- NA
}

# set up age-length population structure
length_bin <- seq(10.0, 400, 10)/10 # in cm
mid_length_bin <- seq(10.5, 405, 10)/10 # in cm
nbin <- length(length_bin)
bin_width <- 1

length_CV <- list(
  survey1 = 0.12,
  survey2 = 0.17,
  survey3 = NA,
  survey4 = NA
)

# Create survey
survey <- IFA4EBFM::create_survey(
  file_path = file.path(ewe_output_path, "biomass_monthly.csv"),
  skip_nrows = 8,
  species = 4:10,
  species_labels = paste0("age", ages),
  years = years,
  survey_num = survey_num,
  survey_time = survey_time,
  selectivity = survey_selectivity,
  catchability = survey_catchability,
  CV = survey_CV,
  sample_num = survey_sample_num,
  waa_path = file.path(ewe_output_path, "weight_monthly.csv"),
  length_bin = length_bin,
  mid_length_bin = mid_length_bin,
  nbin = nbin,
  bin_width = bin_width,
  length_CV = length_CV
)

Survey selectivity patterns

plot(0:6, as.numeric(survey_selectivity$survey1[1, ]), 
     type="o", pch=1, col=1, lty=1,
     xlab = "Age", ylab = "Selectivity")
lines(0:6, as.numeric(survey_selectivity$survey2[1, ]), pch=2, col=2, lty=2, type="o")
lines(0:6, as.numeric(survey_selectivity$survey3[1,]), pch=3, col=3, lty=3, type="o")
lines(0:6, as.numeric(survey_selectivity$survey4[1, ]), pch=4, col=4, lty=4, type="o")
legend("topright",
       names(survey_selectivity),
       pch= 1:4,
       col = 1:4, 
       lty=1:4,
       bty="n"
       )

Survey index over time

om <- data.frame(matrix(ncol=4, nrow=0))
for (i in 1:length(survey$om_abundance_index)){
  temp <- data.frame(
  Year = as.numeric(names(survey$om_abundance_index[[i]])), 
  Index = survey$om_abundance_index[[i]],
  Model = "OM",
  Survey = names(survey$om_abundance_index)[i]
)
  om <- rbind(om, temp)
}

obs <- data.frame(matrix(ncol=4, nrow=0))
for (i in 1:length(survey$obs_abundance_index)){
  temp <- data.frame(
  Year = as.numeric(names(survey$obs_abundance_index[[i]])), 
  Index = survey$obs_abundance_index[[i]],
  Model = "OBS",
  Survey = names(survey$obs_abundance_index)[i]
)
  obs <- rbind(obs, temp)
}

data <- rbind(om, obs)
ggplot(data, aes(x = Year, y = Index, color = Model)) +
  geom_line() +
  facet_wrap(~Survey, scales = "free_y") +
  labs(
    title = "Comparison between models",
    x = "Year",
    y = "Abundance Index"
  ) +
  theme_bw()

Survey length composition over time

for (i in 1:length(survey$obs_lencomp_proportion_ss3)){
  obs <- as.data.frame(survey$obs_lencomp_proportion_ss3[[i]])
  obs$Year <- as.numeric(row.names(survey$obs_lencomp_proportion_ss3[[i]]))
  obs$Model <- "OBS"
  obs$Survey <- names(survey$obs_lencomp_proportion_ss3)[i]

  obs <- na.omit(obs)

  obs <- reshape2::melt(obs, id.vars = c("Year", "Model", "Survey"))
  colnames(obs) <- c("Year", "Model", "Survey", "Length_Bin", "Value")

  if (nrow(obs) != 0) {
    obs$Length_Bin <- as.numeric(as.character(obs$Length_Bin))
    p <- ggplot(data=obs, aes(x=Length_Bin, fill=Length_Bin, y=Value)) +
      geom_bar(position='dodge', stat='identity') +
      facet_wrap(~Year) +
      labs(
        title = names(survey$obs_lencomp_proportion_ss3)[i],
        x = "Length Bins (cm)",
        y = "Proportion"
      )+
      theme_bw()
  print(p)
  }
}
for (i in 1:length(survey$obs_lencomp_proportion_bam)){
  obs <- as.data.frame(survey$obs_lencomp_proportion_bam[[i]])
  obs$Year <- as.numeric(row.names(survey$obs_lencomp_proportion_bam[[i]]))
  obs$Model <- "OBS"
  obs$Survey <- names(survey$obs_lencomp_proportion_bam)[i]

  obs <- na.omit(obs)

  obs <- reshape2::melt(obs, id.vars = c("Year", "Model", "Survey"))
  colnames(obs) <- c("Year", "Model", "Survey", "Length_Bin", "Value")

  if (nrow(obs) != 0) {
    obs$Length_Bin <- as.numeric(as.character(obs$Length_Bin))
    p <- ggplot(data=obs, aes(x=Length_Bin, fill=Length_Bin, y=Value)) +
      geom_bar(position='dodge', stat='identity') +
      facet_wrap(~Year) +
      labs(
        title = names(survey$obs_lencomp_proportion_bam)[i],
        x = "Year",
        y = "Proportion"
      )+
      theme_bw()
  print(p)
  }
}

Key findings

Modify selectivity pattern for survey survey1 and update length bins

survey1_sel <- IFA4EBFM::logistic(
  pattern = "simple_logistic",
  x = ages,
  slope_asc = 3.0,
  location_asc = 3.0
)

survey1 = as.data.frame(
    matrix(rep(survey1_sel, times = length(years)), ncol = length(ages), byrow = TRUE),
    row.names = years
  )
colnames(survey1) <- paste0("ages", ages)

survey_selectivity$survey1 <- survey1

# set up age-length population structure
length_bin <- seq(10, 500, 10)/10 # in cm
mid_length_bin <- seq(15, 505, 10)/10 # in cm
nbin <- length(length_bin)
bin_width <- 1

# Create survey
survey <- IFA4EBFM::create_survey(
  file_path = file.path(ewe_output_path, "biomass_monthly.csv"),
  skip_nrows = 8,
  species = 4:10,
  species_labels = paste0("age", ages),
  years = years,
  survey_num = survey_num,
  survey_time = survey_time,
  selectivity = survey_selectivity,
  catchability = survey_catchability,
  CV = survey_CV,
  sample_num = survey_sample_num,
  waa_path = file.path(ewe_output_path, "weight_monthly.csv"),
  length_bin = length_bin,
  mid_length_bin = mid_length_bin,
  nbin = nbin,
  bin_width = bin_width,
  length_CV = length_CV
)

Updated survey length composition over time

om <- data.frame(matrix(ncol=4, nrow=0))
for (i in 1:length(survey$om_abundance_index)){
  temp <- data.frame(
  Year = as.numeric(names(survey$om_abundance_index[[i]])), 
  Index = survey$om_abundance_index[[i]],
  Model = "OM",
  Survey = names(survey$om_abundance_index)[i]
)
  om <- rbind(om, temp)
}

obs <- data.frame(matrix(ncol=4, nrow=0))
for (i in 1:length(survey$obs_abundance_index)){
  temp <- data.frame(
  Year = as.numeric(names(survey$obs_abundance_index[[i]])), 
  Index = survey$obs_abundance_index[[i]],
  Model = "OBS",
  Survey = names(survey$obs_abundance_index)[i]
)
  obs <- rbind(obs, temp)
}

data <- rbind(om, obs)
for (i in 1:length(survey$obs_lencomp_proportion_ss3)){
  obs <- as.data.frame(survey$obs_lencomp_proportion_ss3[[i]])
  obs$Year <- as.numeric(row.names(survey$obs_lencomp_proportion_ss3[[i]]))
  obs$Model <- "OBS"
  obs$Survey <- names(survey$obs_lencomp_proportion_ss3)[i]

  obs <- na.omit(obs)

  obs <- reshape2::melt(obs, id.vars = c("Year", "Model", "Survey"))
  colnames(obs) <- c("Year", "Model", "Survey", "Length_Bin", "Value")

  if (nrow(obs) != 0) {
    obs$Length_Bin <- as.numeric(as.character(obs$Length_Bin))
    p <- ggplot(data=obs, aes(x=Length_Bin, fill=Length_Bin, y=Value)) +
      geom_bar(position='dodge', stat='identity') +
      facet_wrap(~Year) +
      labs(
        title = names(survey$obs_lencomp_proportion_ss3)[i],
        x = "Length Bins (cm)",
        y = "Proportion"
      )+
      theme_bw()
  print(p)
  }
}

IFA4EBFM::create_biodata() is used to prepare biological data for a stock assessment

biodata <- create_biodata(nsex=1, narea=1, ages=ages, years=years,
                          length_bin=length_bin, mid_length_bin=mid_length_bin,
                          nbin=nbin, bin_width=bin_width, length_CV=length_CV,
                          annual_weight_path=file.path(ewe_output_path, "weight_annual.csv"),
                          monthly_weight_path=file.path(ewe_output_path, "weight_monthly.csv"),
                          species=4:10,
                          species_labels=paste0("age", ages),
                          skip_nrows=8,
                          lw_a=0.01, lw_b=3,
                          k=0.331,
                          t0 = -0.1,
                          winf = 0.237,
                          maturity_at_age=c(0.0, 0.1, 0.5, 0.9, 1.0, 1.0, 1.0), # From both BAM and EwE
                          natural_mortality_at_age=c(1.76, 1.31, 1.03, 0.9, 0.81, 0.76, 0.72) # From both BAM and EwE
                          )

Key findings



Bai-Li-NOAA/IFA4EBFM documentation built on April 5, 2024, 6:41 p.m.