This vignette is designed to illustrate running alternative scenarios of standard CAMS discard functions. Here, Support tables are function variables. This allows them to be modified and run for diagnostic testing. You can output a summary of discard information by strata, including number of trips used, variance, CV, discard amount, and KALL. Youcan also output a table, by subtrip, with all information. This table can be summarized afterward as well. If testing several scenarios, it is recommended to only output the summary rather than the full subtrip table as each output is 1-2GB. The original function pushed .fst files directly to the Wind server at GARFO. This version does not do that and only produces local results.

knitr::opts_chunk$set(echo = T, warning = FALSE, 
                                            message = FALSE, cache = FALSE,
                                            progress = TRUE, verbose = FALSE, comment = F
                                            , error = FALSE, dev = 'png', dpi = 200)

options(knitr.kable.NA = '')
options(dplyr.summarise.inform = FALSE)

Get connected.

# you can also use odbc, or connect via server using keyring or other method
library(remotes)
remotes::install_github("NOAA-Fisheries-Greater-Atlantic-Region/discaRd", ref = 'model_estimator')

library(discaRd)

keyring::keyring_unlock(keyring = 'apsd_ma', password = 'mysecrets')
con = apsdFuns::roracle_login(key_name = 'apsd_ma', key_service = 'maps')

# or source your uid and password

con <- ROracle::dbConnect(
    drv = ROracle::Oracle(),
    username = uid,
    password = pwd,  
    dbname = "NERO.world"
)

load the CAMS_OBS_CATCH table. This may be slow..

## ----get obs and catch data from oracle ----
# you need to get enough years to cover the current (focal) and previous fishing year. This is for transitions rate determination

start_year = 2017
end_year = year(today())

dat = get_catch_obs(con, start_year, end_year)
gf_dat = dat$gf_dat
non_gf_dat = dat$non_gf_dat
all_dat = dat$all_dat
rm(dat)
gc()

Get species list, choose one for diagnosis/testing

# get calendar year species list ----

species <- tbl(con, sql("
  select *
  from CFG_DISCARD_RUNID
  ")) %>%
    filter(RUN_ID == 'CALENDAR') %>%
    collect() %>%
    group_by(ITIS_TSN) %>%
    slice(1) %>%
    ungroup()

# get one species for testing (black sea bass)
species = species %>% 
    filter(NESPP3 == 335)

read in default support tables. These will be species specific!

# GEAR TABLE
CAMS_GEAR_STRATA = tbl(con, sql('  select * from CFG_GEARCODE_STRATA')) %>%
    collect() %>%
    dplyr::rename(GEARCODE = SECGEAR_MAPPED) %>%
    filter(ITIS_TSN == species$ITIS_TSN) %>%
    dplyr::select(-NESPP3, -ITIS_TSN)

# Stock (Estimation) areas table ----
STOCK_AREAS = tbl(con, sql('select * from CFG_STATAREA_STOCK')) %>%
    collect() %>%
    filter(ITIS_TSN == species$ITIS_TSN) %>%
    group_by(AREA_NAME, ITIS_TSN) %>%
    distinct(AREA) %>%
    mutate(AREA = as.character(AREA)
                 , SPECIES_STOCK = AREA_NAME) %>%
    ungroup()

# Discard Mortality table ----
CAMS_DISCARD_MORTALITY_STOCK = tbl(con, sql("select * from CFG_DISCARD_MORTALITY_STOCK"))  %>%
    collect() %>%
    mutate(SPECIES_STOCK = AREA_NAME
                 , GEARCODE = CAMS_GEAR_GROUP
                 , CAMS_GEAR_GROUP = as.character(CAMS_GEAR_GROUP)) %>%
    select(-AREA_NAME) %>%
    filter(ITIS_TSN == species$ITIS_TSN) %>%
    dplyr::select(-ITIS_TSN)

Now, modify anything you wish to test in the support tables! For example, here is an example for scallop estiamtion areas. CAMS do not match the previous assessment and were worth investigating. CAMS ended up doing a good job in this case, regardless of the area splits.

if(species$ITIS_TSN == '079718'){

    STOCK_AREAS = tbl(con, sql("
                select ITIS_TSN
                , AREA
                , case when area > 599 then 'MA'
                when area like '53%' then 'SNE'
                when area >= 520 and area <599 and area not like '53%'  then 'GB'
                when area < 520 then 'GOM'
                end as AREA_NAME
                , case when area > 599 then 'MA'
                when area like '53%' then 'SNE'
                when area >= 520 and area <599 and area not like '53%'  then 'GB'
                when area < 520 then 'GOM'
                end as SPECIES_STOCK
              from CFG_STATAREA_STOCK
                where ITIS_TSN = '079718'")) %>%
        collect() %>%
        group_by(AREA_NAME, ITIS_TSN) %>%
        distinct(AREA) %>%
        mutate(AREA = as.character(AREA)
                     , SPECIES_STOCK = AREA_NAME) %>%
        ungroup()

}

Run the discard function, generic example

mydiscard = discard_generic_diagnostic(con = con
                                                        , species = species
                                                        , FY = 2019
                                                        #, FY_TYPE = c('Calendar','March','April','May','November')
                                                        , all_dat = all_dat
                                                        , return_table = T
                                                        , return_summary = T
                                                        , CAMS_GEAR_STRATA = CAMS_GEAR_STRATA
                                                        , STOCK_AREAS = STOCK_AREAS
                                                        , CAMS_DISCARD_MORTALITY_STOCK = CAMS_DISCARD_MORTALITY_STOCK

)

look at the summary only

mydiscard$discard_summary %>% 
    # knitr::kable()
    DT::datatable()

build a summary from the output table

d_summary = mydiscard$trips_discard %>% 
        group_by(FISHING_YEAR, STRATA_USED, DISCARD_SOURCE, SPECIES_STOCK, CAMS_GEAR_GROUP, MESH_CAT, TRIPCATEGORY, ACCESSAREA, FED_OR_STATE) %>%
        dplyr::summarise(rate = max(COAL_RATE, na.rm = T)
                                         , n_f = max(n_obs_trips_f)
                                         , n_p = max(n_obs_trips_p)
                                         , N = n_distinct(CAMS_SUBTRIP)
                                         # , rate_min = min(COAL_RATE, na.rm = T)
                                         , KALL = round(sum(LIVE_POUNDS, na.rm = T))
                                         , D = round(sum(DISCARD, na.rm = T), 2)
                                         , CV = max(CV, na.rm = T)
        )

d_summary %>% 
    DT::datatable()
    # knitr::kable()

Groundfish example (all at once)

species <- tbl(con, sql("
  select *
  from CFG_DISCARD_RUNID
  ")) %>%
    filter(RUN_ID == 'GROUNDFISH') %>%
    collect() %>%
    group_by(ITIS_TSN) %>%
    slice(1) %>%
    ungroup()

# get one species for testing (witch flounder)
species = species %>% 
    filter(NESPP3 == 122)


# GEAR TABLE
CAMS_GEAR_STRATA = tbl(con, sql('  select * from CFG_GEARCODE_STRATA')) %>%
    collect() %>%
    dplyr::rename(GEARCODE = SECGEAR_MAPPED) %>%
    filter(ITIS_TSN == species$ITIS_TSN) %>%
    dplyr::select(-NESPP3, -ITIS_TSN)

# Stock (Estimation) areas table ----
STOCK_AREAS = tbl(con, sql('select * from CFG_STATAREA_STOCK')) %>%
    collect() %>%
    filter(ITIS_TSN == species$ITIS_TSN) %>%
    group_by(AREA_NAME, ITIS_TSN) %>%
    distinct(AREA) %>%
    mutate(AREA = as.character(AREA)
                 , SPECIES_STOCK = AREA_NAME) %>%
    ungroup()

# Discard Mortality table ----
CAMS_DISCARD_MORTALITY_STOCK = tbl(con, sql("select * from CFG_DISCARD_MORTALITY_STOCK"))  %>%
    collect() %>%
    mutate(SPECIES_STOCK = AREA_NAME
                 , GEARCODE = CAMS_GEAR_GROUP
                 , CAMS_GEAR_GROUP = as.character(CAMS_GEAR_GROUP)) %>%
    select(-AREA_NAME) %>%
    filter(ITIS_TSN == species$ITIS_TSN) %>%
    dplyr::select(-ITIS_TSN)

# discard estimate ----

discard_wtf = discard_groundfish_diagnostic(con = con
                                                             , FY = 2019
                                                             , species = species
                                                             , gf_dat = gf_dat
                                                             , non_gf_dat = non_gf_dat
                                                             , return_table = T
                                                             , return_summary = T
                                                             , CAMS_GEAR_STRATA = CAMS_GEAR_STRATA
                                                             , STOCK_AREAS = STOCK_AREAS
                                                             , CAMS_DISCARD_MORTALITY_STOCK = CAMS_DISCARD_MORTALITY_STOCK
                                                             ) 


# summary output 

discard_wtf$discard_summary %>% 
    DT::datatable()

# tabular summary output

# GF trips only 
 gftrips_wtf_summary = discard_wtf$trips_discard %>% 
    filter(GF == 1) %>% 
    group_by(SPECIES_STOCK, CAMS_GEAR_GROUP, MESH_CAT, SECTID, EM, REDFISH_EXEMPTION , SNE_SMALLMESH_EXEMPTION, XLRG_GILLNET_EXEMPTION, EXEMPT_7130) %>%    dplyr::summarise(rate = max(COAL_RATE, na.rm = T)
                                         , n_f = max(n_obs_trips_f)
                                         , n_p = max(n_obs_trips_p)
                                         , N = n_distinct(CAMS_SUBTRIP)
                                         # , rate_min = min(COAL_RATE, na.rm = T)
                                         , KALL = round(sum(LIVE_POUNDS, na.rm = T))
                                         , D = round(sum(DISCARD, na.rm = T), 2)
                                         , CV = max(CV, na.rm = T)
        )




nongf_trips_wtf_summary = discard_wtf$trips_discard %>% 
    filter(GF == 0) %>%
        group_by(FISHING_YEAR
                         , GF
                         , STRATA_USED
                         , DISCARD_SOURCE
                         , SPECIES_STOCK
                         , CAMS_GEAR_GROUP
                         , MESH_CAT
                         , TRIPCATEGORY
                         , ACCESSAREA
                         , FED_OR_STATE) %>%
        dplyr::summarise(rate = max(COAL_RATE, na.rm = T)
                                         , n_f = max(n_obs_trips_f)
                                         , n_p = max(n_obs_trips_p)
                                         , N = n_distinct(CAMS_SUBTRIP)
                                         # , rate_min = min(COAL_RATE, na.rm = T)
                                         , KALL = round(sum(LIVE_POUNDS, na.rm = T))
                                         , D = round(sum(DISCARD, na.rm = T), 2)
                                         , CV = max(CV, na.rm = T)
        )


gftrips_wtf_summary %>% 
    DT::datatable()

nongf_trips_wtf_summary %>% 
    DT::datatable()

Yellowtail example with scallop trips

species <- tbl(con, sql("
  select *
  from CFG_DISCARD_RUNID
  ")) %>%
    filter(RUN_ID == 'GROUNDFISH') %>%
    collect() %>%
    group_by(ITIS_TSN) %>%
    slice(1) %>%
    ungroup()

# get one species for testing (witch flounder)
species = species %>% 
    filter(NESPP3 == 123)


# GEAR TABLE
CAMS_GEAR_STRATA = tbl(con, sql('  select * from CFG_GEARCODE_STRATA')) %>%
    collect() %>%
    dplyr::rename(GEARCODE = SECGEAR_MAPPED) %>%
    filter(ITIS_TSN == species$ITIS_TSN) %>%
    dplyr::select(-NESPP3, -ITIS_TSN)

# Stock (Estimation) areas table ----
STOCK_AREAS = tbl(con, sql('select * from CFG_STATAREA_STOCK')) %>%
    collect() %>%
    filter(ITIS_TSN == species$ITIS_TSN) %>%
    group_by(AREA_NAME, ITIS_TSN) %>%
    distinct(AREA) %>%
    mutate(AREA = as.character(AREA)
                 , SPECIES_STOCK = AREA_NAME) %>%
    ungroup()

# Discard Mortality table ----
CAMS_DISCARD_MORTALITY_STOCK = tbl(con, sql("select * from CFG_DISCARD_MORTALITY_STOCK"))  %>%
    collect() %>%
    mutate(SPECIES_STOCK = AREA_NAME
                 , GEARCODE = CAMS_GEAR_GROUP
                 , CAMS_GEAR_GROUP = as.character(CAMS_GEAR_GROUP)) %>%
    select(-AREA_NAME) %>%
    filter(ITIS_TSN == species$ITIS_TSN) %>%
    dplyr::select(-ITIS_TSN)

# discard estimate ----

discard_ytf = discard_groundfish_diagnostic(con = con
                                                             , FY = 2019
                                                             , species = species
                                                             , gf_dat = gf_dat
                                                             , non_gf_dat = non_gf_dat
                                                             , return_table = T
                                                             , return_summary = T
                                                             , CAMS_GEAR_STRATA = CAMS_GEAR_STRATA
                                                             , STOCK_AREAS = STOCK_AREAS
                                                             , CAMS_DISCARD_MORTALITY_STOCK = CAMS_DISCARD_MORTALITY_STOCK
                                                             ) 


# summary output 

discard_ytf$discard_summary %>% 
    DT::datatable()

# tabular summary output

# GF trips only 
 gftrips_ytf_summary = discard_wtf$trips_discard %>% 
    filter(GF == 1) %>% 
    group_by(SPECIES_STOCK, CAMS_GEAR_GROUP, MESH_CAT, SECTID, EM, REDFISH_EXEMPTION , SNE_SMALLMESH_EXEMPTION, XLRG_GILLNET_EXEMPTION, EXEMPT_7130) %>%    dplyr::summarise(rate = max(COAL_RATE, na.rm = T)
                                         , n_f = max(n_obs_trips_f)
                                         , n_p = max(n_obs_trips_p)
                                         , N = n_distinct(CAMS_SUBTRIP)
                                         # , rate_min = min(COAL_RATE, na.rm = T)
                                         , KALL = round(sum(LIVE_POUNDS, na.rm = T))
                                         , D = round(sum(DISCARD, na.rm = T), 2)
                                         , CV = max(CV, na.rm = T)
        )




nongf_trips_ytf_summary = discard_wtf$trips_discard %>% 
    filter(GF == 0) %>%
        group_by(FISHING_YEAR
                         , GF
                         , STRATA_USED
                         , DISCARD_SOURCE
                         , SPECIES_STOCK
                         , CAMS_GEAR_GROUP
                         , MESH_CAT
                         , TRIPCATEGORY
                         , ACCESSAREA
                         , FED_OR_STATE) %>%
        dplyr::summarise(rate = max(COAL_RATE, na.rm = T)
                                         , n_f = max(n_obs_trips_f)
                                         , n_p = max(n_obs_trips_p)
                                         , N = n_distinct(CAMS_SUBTRIP)
                                         # , rate_min = min(COAL_RATE, na.rm = T)
                                         , KALL = round(sum(LIVE_POUNDS, na.rm = T))
                                         , D = round(sum(DISCARD, na.rm = T), 2)
                                         , CV = max(CV, na.rm = T)
        )


gftrips_ytf_summary %>% 
    DT::datatable()

nongf_trips_ytf_summary %>% 
    DT::datatable()


noaa-garfo/discaRd documentation built on April 17, 2025, 10:32 p.m.