if (!interactive()) options(warn=2, error = function() { sink(stderr()) ; traceback(3) ; q(status = 1) })
library(unittest)
library(gadget3)
st <- g3_stock("st", c(10))
stocks_fl <- list(
a = g3_fleet(c(type = 'fl', 'a')),
# NB: We don't use this one, just added to ensure we alter names accordingly
b = g3_fleet(c(type = 'fl', 'b')) )
# Define quota for the fleet, with an assessment in spring, application in autumn
fl_quota <- g3_quota(
g3_quota_hockeyfleet(stocks_fl, list(st), preyprop_fs = 1),
start_step = 4L,
run_revstep = -2L )
ok_group("g3_quota_hockeyfleet: selectivity function preyprop_fs", {
g3_suitability_blueling <- function(){
~1/(1+exp(-0.23*(stock__midlen - 91.5856)))
}
stocks <- list(
g3_stock(c("st", "male"), 0:10 * 10) |> g3s_age(1, 3),
g3_stock(c("st", "female"), 0:10 * 10) |> g3s_age(1, 3))
q_hf <- g3_quota_hockeyfleet(
stocks_fl,
stocks,
preyprop_fs = g3_suitability_blueling() )
actions <- list(
g3a_time(1990, 1991),
lapply(stocks, g3a_initialconditions_normalcv),
g3_step(g3_formula({
REPORT(q_hf)
}, q_hf = q_hf )),
NULL )
full_actions <- c(actions, list(
g3a_report_detail(actions),
NULL))
model_fn <- g3_to_r(full_actions)
model_cpp <- g3_to_tmb(full_actions)
attr(model_fn, "parameter_template") |>
g3_init_val("*.K", 0.3, lower = 0.04, upper = 1.2) |>
g3_init_val("st_male.Linf", 80, spread = 0.2) |>
g3_init_val("st_female.Linf", 105, spread = 0.2) |>
g3_init_val("*.t0", g3_stock_def(stocks[[1]], "minage") - 0.8, spread = 2) |>
g3_init_val("*.lencv", 0.1, optimise = FALSE) |>
g3_init_val("*.walpha", 0.01, optimise = FALSE) |>
g3_init_val("*.wbeta", 3, optimise = FALSE) |>
g3_init_val("fl.hf.btrigger", 1000, optimise = FALSE) |>
g3_init_val("fl.hf.harvest_rate", 1000, optimise = FALSE) |>
identity() -> params.in
nll <- model_fn(params.in) ; r <- attributes(nll) ; nll <- as.vector(nll)
# Work out expected ssb, show we've used it to calculate results
expectedssb <-
sum(r$dstart_st_male__num[,,1] * r$dstart_st_male__wgt[,,1] * 1/(1+exp(-0.23*((0:10 * 10 + 5) - 91.5856)))) +
sum(r$dstart_st_female__num[,,1] * r$dstart_st_female__wgt[,,1] * 1/(1+exp(-0.23*((0:10 * 10 + 5) - 91.5856))))
ok(ut_cmp_equal(
r$q_hf,
expectedssb), "r$q_hf: Matches expectedssb, as fl.hf.btrigger is greater than ssb")
gadget3:::ut_tmb_r_compare2(model_fn, model_cpp, params.in)
params.in |>
g3_init_val("fl.hf.btrigger", expectedssb + 50, optimise = FALSE) |>
identity() -> params.in
nll <- model_fn(params.in) ; r <- attributes(nll) ; nll <- as.vector(nll)
ok(ut_cmp_equal(
r$q_hf,
1000 * (expectedssb / (expectedssb + 50)) ), "r$q_hf: expectedssb below btrigger, so scaling result")
gadget3:::ut_tmb_r_compare2(model_fn, model_cpp, params.in)
})
actions <- list(
g3a_time(1990, 1995, c(3,3,3,3)),
# Define st with steadily collapsing stock
g3a_otherfood(st, num_f = g3_timeareadata('st_abund', data.frame(
year = rep(1990:2050, each = 4),
step = rep(1:4, times = length(1990:2050)),
abund = 1e6 - 1e4 * seq(0, 2050-1990 + 0.75, by = 0.25)), "abund"), wgt_f = 10),
# Fleet predates stock
g3a_predate(
stocks_fl$a,
list(st),
suitabilities = 0.8,
catchability_f = g3a_predate_catchability_project(
# Use the quota when projecting, otherwise use landings parameters
fl_quota,
g3_parameterized("landings", value = 0, by_year = TRUE, by_predator = TRUE) )),
NULL )
full_actions <- c(actions, list(
g3a_report_detail(actions),
g3a_report_history(actions, "__num$|__wgt$", out_prefix="dend_"), # NB: Late reporting
g3a_report_history(actions, "quota_", out_prefix = NULL),
NULL))
model_fn <- g3_to_r(full_actions)
model_cpp <- g3_to_tmb(full_actions)
attr(model_fn, "parameter_template") |>
# Project for 30 years
g3_init_val("project_years", 30) |>
# Fishing generally occurs in spring/summer, none in winter
g3_init_val("fl_a.cons.step.#", c(0.0, 0.5, 0.4, 0.1)) |>
# Initial landings fixed
g3_init_val("fl_a.landings.#", 1e6) |>
# Hockefleet: harvest rate & trigger biomass
g3_init_val("fl.hf.harvest_rate", 0.2) |>
g3_init_val("fl.hf.btrigger", 7.8e6) |>
identity() -> params.in
nll <- model_fn(params.in) ; r <- attributes(nll) ; nll <- as.vector(nll)
to_vect <- function (x) structure(as.vector(x), names = dimnames(x)[[1]])
ok(ut_cmp_identical(
# NB: dend because assessment comes after consumption
# NB: step=2 comes from start_step = 4 / run_revstep = -2
names(which((g3_array_agg(r$dend_st__num * r$dend_st__wgt, "year", step = 2) < 7.8e6 )))[[1]],
"2005"), "Fall below btrigger at 2005 assessment step")
ok(ut_cmp_equal(
to_vect(r$quota_hockeyfleet_fl__var), c(
`1990:1990` = 0, `1990:1991` = 0.2, `1991:1992` = 0.2, `1992:1993` = 0.2,
`1993:1994` = 0.2, `1994:1995` = 0.2, `1995:1996` = 0.2, `1996:1997` = 0.2,
`1997:1998` = 0.2, `1998:1999` = 0.2, `1999:2000` = 0.2, `2000:2001` = 0.2,
`2001:2002` = 0.2, `2002:2003` = 0.2, `2003:2004` = 0.2, `2004:2005` = 0.2,
`2005:2006` = 0.199819, `2006:2007` = 0.19758, `2007:2008` = 0.195411,
`2008:2009` = 0.193231, `2009:2010` = 0.191048, `2010:2011` = 0.18886,
`2011:2012` = 0.186669, `2012:2013` = 0.184473, `2013:2014` = 0.182274,
`2014:2015` = 0.18007, `2015:2016` = 0.177861, `2016:2017` = 0.175649,
`2017:2018` = 0.173432, `2018:2019` = 0.171212, `2019:2020` = 0.168986,
`2020:2021` = 0.166757, `2021:2022` = 0.164524, `2022:2023` = 0.162286,
`2023:2024` = 0.160044, `2024:2025` = 0.157797, `2025:2026` = 0.155546
), tolerance = 5e-5), "quota_hockeyfleet_fl__var Constant until btrigger, then starts dropping")
x <- g3_array_agg(r$detail_st_fl_a__cons, year = 1990:1995, "step")
ok(ut_cmp_equal(
as.vector(x),
c(6e6, 6e6, 6e6, 6e6),
tolerance = 3e-7 ), "detail_st_fl_a__cons: Specified by parameters (before projecting)")
x <- g3_array_agg(r$detail_st_fl_a__cons, year = 1996:2024, "step")
ok(ut_cmp_equal(
as.vector(x / sum(x)),
c(0, 0.5, 0.4, 0.1),
tolerance = 4e-3 ), "detail_st_fl_a__cons: Follows seasonal pattern (whilst projecting)")
fishingyear_cons <- c(0, tail(g3_array_agg(r$detail_st_fl_a__cons, year = 1990:2024, "year", step = 1:3), -1)) +
g3_array_agg(r$detail_st_fl_a__cons, year = 1990:2024, "year", step = 4)
ok(ut_cmp_equal(
fishingyear_cons[[1]],
1e6), "fishingyear_cons: First year only contains an autumn")
ok(ut_cmp_equal(
as.vector(fishingyear_cons[2:6]),
rep(4e6, 5)), "fishingyear_cons: Outside projections we consume landings rate")
ok(ut_cmp_equal(
as.vector(tail(g3_array_agg(r$detail_st_fl_a__cons, "year", step = 1), -6)),
as.vector(tail(to_vect(g3_array_agg(
r$dstart_st__num * r$dstart_st__wgt * 0.8, "year", step = 1) * head(r$quota_hockeyfleet_fl__var * 0, -1)), -6)),
tolerance = 1e-7), "detail_st_fl_a__cons[step = 1]: consumption based on quota")
ok(ut_cmp_equal(
as.vector(tail(g3_array_agg(r$detail_st_fl_a__cons, "year", step = 2), -6)),
as.vector(tail(to_vect(g3_array_agg(
r$dstart_st__num * r$dstart_st__wgt * 0.8, "year", step = 2) * head(r$quota_hockeyfleet_fl__var * 0.5, -1)), -6)),
tolerance = 1e-7), "detail_st_fl_a__cons[step = 2]: consumption based on quota")
ok(ut_cmp_equal(
as.vector(tail(g3_array_agg(r$detail_st_fl_a__cons, "year", step = 3), -6)),
as.vector(tail(to_vect(g3_array_agg(
r$dstart_st__num * r$dstart_st__wgt * 0.8, "year", step = 3) * head(r$quota_hockeyfleet_fl__var * 0.4, -1)), -6)),
tolerance = 1e-7), "detail_st_fl_a__cons[step = 3]: consumption based on quota")
ok(ut_cmp_equal(
as.vector(tail(g3_array_agg(r$detail_st_fl_a__cons, "year", step = 4), -6)),
as.vector(tail(to_vect(g3_array_agg(
r$dstart_st__num * r$dstart_st__wgt * 0.8, "year", step = 4) * tail(r$quota_hockeyfleet_fl__var * 0.1, -1)), -6)),
tolerance = 1e-7), "detail_st_fl_a__cons[step = 4]: consumption based on quota")
gadget3:::ut_tmb_r_compare2(model_fn, model_cpp, params.in)
Add the following code to your website.
For more information on customizing the embed code, read Embedding Snippets.