Title: | Globally-Applicable Area Disaggregated General Ecosystem Toolbox V3 |
---|---|
Description: | A framework to assist creation of marine ecosystem models, generating either 'R' or 'C++' code which can then be optimised using the 'TMB' package and standard 'R' tools. Principally designed to reproduce gadget2 models in 'TMB', but can be extended beyond gadget2's capabilities. Kasper Kristensen, Anders Nielsen, Casper W. Berg, Hans Skaug, Bradley M. Bell (2016) <doi:10.18637/jss.v070.i05> "TMB: Automatic Differentiation and Laplace Approximation.". Begley, J., & Howell, D. (2004) <https://core.ac.uk/download/pdf/225936648.pdf> "An overview of Gadget, the globally applicable area-disaggregated general ecosystem toolbox. ICES.". |
Authors: | Jamie Lentin [aut, cre] , Bjarki Thor Elvarsson [aut] , William Butler [aut] , Marine and Freshwater Research Institute (Iceland) [cph] |
Maintainer: | Jamie Lentin <[email protected]> |
License: | GPL-2 |
Version: | 0.12-1-999 |
Built: | 2024-11-21 09:27:36 UTC |
Source: | https://github.com/gadget-framework/gadget3 |
Produce objects with special meaning to gadget3
g3_native(r, cpp, depends = c()) g3_global_formula(f = quote(noop), init_val = NULL)
g3_native(r, cpp, depends = c()) g3_global_formula(f = quote(noop), init_val = NULL)
r |
An R function to decorate with a 'C++' equivalent |
cpp |
Either:
|
depends |
A list of string names of dependent functions.
The content of this and the initial |
f |
An optional formula to modify the content of a globablly-defined variable |
init_val |
An optiona formula to set the initial value of a globally-defined variable |
These functions are generally for gadget3 development, but made available so actions can be produced outside the package.
Returns a function that can be used in formulas for both R and TMB-based models.
Returns a formula that will be defined globally, and this can preserve state across timesteps.
# The definition of g3_env$ratio_add_vec looks like: eg_ratio_add_vec <- g3_native(r = function(orig_vec, orig_amount, new_vec, new_amount) { ((orig_vec * orig_amount + new_vec * new_amount) / avoid_zero_vec(orig_amount + new_amount)) }, cpp = '[](vector<Type> orig_vec, vector<Type> orig_amount, vector<Type> new_vec, vector<Type> new_amount) -> vector<Type> { return (orig_vec * orig_amount + new_vec * new_amount) / avoid_zero_vec(orig_amount + new_amount); }', depends = c('avoid_zero_vec')) # eg_ratio_add_vec() can then be used in formulas, both in R & TMB. # Define a random walk action, using g3_global_formula to keep track of # previous value. NB: my_randomwalk_prevrec must be unique in a model random_walk_action <- g3_formula(quote({ if (cur_time > 0) nll <- nll + dnorm(x, stock__prevrec, 1, 1) my_randomwalk_prevrec <- x }), x = 'TODO', my_randomwalk_prevrec = g3_global_formula(init_val = 0.0))
# The definition of g3_env$ratio_add_vec looks like: eg_ratio_add_vec <- g3_native(r = function(orig_vec, orig_amount, new_vec, new_amount) { ((orig_vec * orig_amount + new_vec * new_amount) / avoid_zero_vec(orig_amount + new_amount)) }, cpp = '[](vector<Type> orig_vec, vector<Type> orig_amount, vector<Type> new_vec, vector<Type> new_amount) -> vector<Type> { return (orig_vec * orig_amount + new_vec * new_amount) / avoid_zero_vec(orig_amount + new_amount); }', depends = c('avoid_zero_vec')) # eg_ratio_add_vec() can then be used in formulas, both in R & TMB. # Define a random walk action, using g3_global_formula to keep track of # previous value. NB: my_randomwalk_prevrec must be unique in a model random_walk_action <- g3_formula(quote({ if (cur_time > 0) nll <- nll + dnorm(x, stock__prevrec, 1, 1) my_randomwalk_prevrec <- x }), x = 'TODO', my_randomwalk_prevrec = g3_global_formula(init_val = 0.0))
Functions available to any gadget3 model
g3_env
is the top-level environment that any gadget3 model uses,
populated with utility functions.
NB: Several functions have _vec
variants.
Due to TMB limitations these should be used when you have a vector not scalar input.
TMB's ADREPORT
function. See sdreport documentation
C++ compatible equivalent to as.integer
R as.numeric
or TMB asDouble
C++/R function that ensures expression is true, or stops model.
assert_msg(x > 0, "x must be positive")
Adds small value to input to ensure output is never zero
avoid_zero_vec
is identical to avoid_zero
, and is only present for backward compatibility.
Ensures x is within limits b & a.
If x positive, return a.
If x negative, b.
If x -10..10
, smoothly transition from b to a
bounded_vec(x, 200, 100)
Apply matrix transformation tf to vector vec, return resultant vector.
g3_matrix_vec(tf, vec)
Vector equivalent of lgamma
TMB's logspace_add
, essentially a differentiable version of pmax
.
Divide vector a by it's sum, i.e. so it now sums to 1. If vector is all-zero, return an all-zero vector instead.
Return first non-null argument. NB: No C++ implementation.
Utility to pretty-print array ar
Sum orig_vec & new_vec according to ratio of orig_amount & new_amount
Scalar sum/multiply/divide 2 non-conforming arrays, by treating the latter as a vector and repeating as many times as required. Results will be structured identically to the first array.
nonconform_div_avz(x, y)
is equivalent to nonconform_div(x, avoid_zero_vec(y))
TMB's REPORT
function.
Equivalent of RCpp REprintf
Equivalent of RCpp Rprintf
## avoid_zero g3_eval(quote( c( avoid_zero(0), avoid_zero(10) ) )) g3_eval(quote( avoid_zero(0:5) )) ## bounded / bounded_vec curve(g3_eval(quote( bounded(x, 200, 100) ), x = x), -100, 100) ## logspace_add curve(g3_eval(quote( logspace_add(x, 10) ), x = x), 0, 40) ## normalize_vec g3_eval(quote( normalize_vec(c( 4, 4, 8, 2 )) )) ## nonconform_mult g3_eval(quote( nonconform_mult( array(seq(0, 4*5*6), dim = c(4,5,6)), c(1e1, 1e2, 1e3, 1e4)) )) ## nonconform_div_avz g3_eval(quote( nonconform_div_avz( array(seq(0, 4*5*6), dim = c(4,5,6)), c(1e1, 1e2, 0, 1e4)) )) g3_eval(quote( nonconform_div( array(seq(0, 4*5*6), dim = c(4,5,6)), avoid_zero(c(1e1, 1e2, 0, 1e4))) ))
## avoid_zero g3_eval(quote( c( avoid_zero(0), avoid_zero(10) ) )) g3_eval(quote( avoid_zero(0:5) )) ## bounded / bounded_vec curve(g3_eval(quote( bounded(x, 200, 100) ), x = x), -100, 100) ## logspace_add curve(g3_eval(quote( logspace_add(x, 10) ), x = x), 0, 40) ## normalize_vec g3_eval(quote( normalize_vec(c( 4, 4, 8, 2 )) )) ## nonconform_mult g3_eval(quote( nonconform_mult( array(seq(0, 4*5*6), dim = c(4,5,6)), c(1e1, 1e2, 1e3, 1e4)) )) ## nonconform_div_avz g3_eval(quote( nonconform_div_avz( array(seq(0, 4*5*6), dim = c(4,5,6)), c(1e1, 1e2, 0, 1e4)) )) g3_eval(quote( nonconform_div( array(seq(0, 4*5*6), dim = c(4,5,6)), avoid_zero(c(1e1, 1e2, 0, 1e4))) ))
Add ageing actions to a g3 model
g3a_age( stock, output_stocks = list(), output_ratios = rep(1/length(output_stocks), times = length(output_stocks)), run_f = ~cur_step_final, run_at = g3_action_order$age, transition_at = g3_action_order$age)
g3a_age( stock, output_stocks = list(), output_ratios = rep(1/length(output_stocks), times = length(output_stocks)), run_f = ~cur_step_final, run_at = g3_action_order$age, transition_at = g3_action_order$age)
stock |
|
output_stocks |
List of |
output_ratios |
Vector of proportions for how to distribute into output_stocks, default evenly spread. |
run_f |
formula specifying a condition for running this action, default is end of model year. |
run_at |
Integer order that actions will be run within model, see |
transition_at |
Integer order that transition actions will be run within model, see |
An action (i.e. list of formula objects) that will, for the given stock...
Move the final age group into temporary storage, stock__transitioning_num
/ stock__transitioning_wgt
Move the contents of all other age groups into the age group above
Move the contents of the temporary storage into output_stocks
If stock has only one age, and output_stocks has been specified, then the contentes will be moved, if output_stocks is empty, then the action will do nothing.
https://gadget-framework.github.io/gadget2/userguide/chap-stock.html#sec:stockmature,
g3_stock
ling_imm <- g3_stock('ling_imm', seq(20, 156, 4)) %>% g3s_age(3, 10) ling_mat <- g3_stock('ling_mat', seq(20, 156, 4)) %>% g3s_age(5, 15) # Ageing for immature ling age_action <- g3a_age(ling_imm, output_stocks = list(ling_mat))
ling_imm <- g3_stock('ling_imm', seq(20, 156, 4)) %>% g3s_age(3, 10) ling_mat <- g3_stock('ling_mat', seq(20, 156, 4)) %>% g3s_age(5, 15) # Ageing for immature ling age_action <- g3a_age(ling_imm, output_stocks = list(ling_mat))
Add growth/maturity actions to a g3 model
g3a_grow_lengthvbsimple( linf_f = g3_parameterized('Linf', by_stock = by_stock), kappa_f = g3_parameterized('K', by_stock = by_stock), by_stock = TRUE) g3a_grow_weightsimple( alpha_f = g3_parameterized('walpha', by_stock = by_stock), beta_f = g3_parameterized('wbeta', by_stock = by_stock), by_stock = TRUE) g3a_grow_impl_bbinom( delta_len_f = g3a_grow_lengthvbsimple(by_stock = by_stock), delta_wgt_f = g3a_grow_weightsimple(by_stock = by_stock), beta_f = g3_parameterized('bbin', by_stock = by_stock), maxlengthgroupgrowth, by_stock = TRUE) g3a_grow_length_multspec( p0 = g3_parameterized('multispec.p0', value = 1, by_stock = by_stock), p1 = g3_parameterized('multispec.p1', value = 1, by_stock = by_stock), p2 = g3_parameterized('multispec.p2', value = 1, by_stock = by_stock), p3 = g3_parameterized('multispec.p3', value = 0, by_stock = by_stock), temperature = 0, by_stock = TRUE) g3a_grow_weight_multspec( p4 = g3_parameterized('multispec.p4', value = 1, by_stock = by_stock), p5 = g3_parameterized('multispec.p5', value = 1, by_stock = by_stock), p6 = g3_parameterized('multispec.p6', value = 0, by_stock = by_stock), p7 = g3_parameterized('multispec.p7', value = 1, by_stock = by_stock), p8 = g3_parameterized('multispec.p8', value = 0, by_stock = by_stock), temperature = 0, by_stock = TRUE) g3a_grow_length_weightjones( p0 = g3_parameterized('weightjones.p0', value = 0, by_stock = by_stock), p1 = g3_parameterized('weightjones.p1', value = 0, by_stock = by_stock), p2 = g3_parameterized('weightjones.p2', value = 1, by_stock = by_stock), p3 = g3_parameterized('weightjones.p3', value = 0, by_stock = by_stock), p4 = g3_parameterized('weightjones.p4', value = 1, by_stock = by_stock), p5 = g3_parameterized('weightjones.p5', value = 100, by_stock = by_stock), p6 = g3_parameterized('weightjones.p6', value = 1, by_stock = by_stock), p7 = g3_parameterized('weightjones.p7', value = 1, by_stock = by_stock), reference_weight = 0, temperature = 0, by_stock = TRUE) g3a_grow_weight_weightjones( q0 = g3_parameterized('weightjones.q0', value = 1, by_stock = by_stock), q1 = g3_parameterized('weightjones.q1', value = 1, by_stock = by_stock), q2 = g3_parameterized('weightjones.q2', value = 1, by_stock = by_stock), q3 = g3_parameterized('weightjones.q3', value = 1, by_stock = by_stock), q4 = g3_parameterized('weightjones.q4', value = 1, by_stock = by_stock), q5 = g3_parameterized('weightjones.q5', value = 0, by_stock = by_stock), max_consumption = g3a_predate_maxconsumption(temperature = temperature), temperature = 0, by_stock = TRUE) g3a_growmature(stock, impl_f, maturity_f = ~0, output_stocks = list(), output_ratios = rep(1/length(output_stocks), times = length(output_stocks)), transition_f = ~cur_step_final, run_f = ~TRUE, run_at = g3_action_order$grow, transition_at = g3_action_order$mature)
g3a_grow_lengthvbsimple( linf_f = g3_parameterized('Linf', by_stock = by_stock), kappa_f = g3_parameterized('K', by_stock = by_stock), by_stock = TRUE) g3a_grow_weightsimple( alpha_f = g3_parameterized('walpha', by_stock = by_stock), beta_f = g3_parameterized('wbeta', by_stock = by_stock), by_stock = TRUE) g3a_grow_impl_bbinom( delta_len_f = g3a_grow_lengthvbsimple(by_stock = by_stock), delta_wgt_f = g3a_grow_weightsimple(by_stock = by_stock), beta_f = g3_parameterized('bbin', by_stock = by_stock), maxlengthgroupgrowth, by_stock = TRUE) g3a_grow_length_multspec( p0 = g3_parameterized('multispec.p0', value = 1, by_stock = by_stock), p1 = g3_parameterized('multispec.p1', value = 1, by_stock = by_stock), p2 = g3_parameterized('multispec.p2', value = 1, by_stock = by_stock), p3 = g3_parameterized('multispec.p3', value = 0, by_stock = by_stock), temperature = 0, by_stock = TRUE) g3a_grow_weight_multspec( p4 = g3_parameterized('multispec.p4', value = 1, by_stock = by_stock), p5 = g3_parameterized('multispec.p5', value = 1, by_stock = by_stock), p6 = g3_parameterized('multispec.p6', value = 0, by_stock = by_stock), p7 = g3_parameterized('multispec.p7', value = 1, by_stock = by_stock), p8 = g3_parameterized('multispec.p8', value = 0, by_stock = by_stock), temperature = 0, by_stock = TRUE) g3a_grow_length_weightjones( p0 = g3_parameterized('weightjones.p0', value = 0, by_stock = by_stock), p1 = g3_parameterized('weightjones.p1', value = 0, by_stock = by_stock), p2 = g3_parameterized('weightjones.p2', value = 1, by_stock = by_stock), p3 = g3_parameterized('weightjones.p3', value = 0, by_stock = by_stock), p4 = g3_parameterized('weightjones.p4', value = 1, by_stock = by_stock), p5 = g3_parameterized('weightjones.p5', value = 100, by_stock = by_stock), p6 = g3_parameterized('weightjones.p6', value = 1, by_stock = by_stock), p7 = g3_parameterized('weightjones.p7', value = 1, by_stock = by_stock), reference_weight = 0, temperature = 0, by_stock = TRUE) g3a_grow_weight_weightjones( q0 = g3_parameterized('weightjones.q0', value = 1, by_stock = by_stock), q1 = g3_parameterized('weightjones.q1', value = 1, by_stock = by_stock), q2 = g3_parameterized('weightjones.q2', value = 1, by_stock = by_stock), q3 = g3_parameterized('weightjones.q3', value = 1, by_stock = by_stock), q4 = g3_parameterized('weightjones.q4', value = 1, by_stock = by_stock), q5 = g3_parameterized('weightjones.q5', value = 0, by_stock = by_stock), max_consumption = g3a_predate_maxconsumption(temperature = temperature), temperature = 0, by_stock = TRUE) g3a_growmature(stock, impl_f, maturity_f = ~0, output_stocks = list(), output_ratios = rep(1/length(output_stocks), times = length(output_stocks)), transition_f = ~cur_step_final, run_f = ~TRUE, run_at = g3_action_order$grow, transition_at = g3_action_order$mature)
linf_f |
A formula to substitute for |
kappa_f |
A formula to substitute for |
alpha_f |
A formula to substitute for |
beta_f |
A formula to substitute for |
p0 , p1 , p2 , p3 , p4 , p5 , p6 , p7 , p8 , q0 , q1 , q2 , q3 , q4 , q5
|
A formula to substitute for the equivalent value. |
max_consumption |
Maximum predator consumption, see |
temperature |
A formula providing values for the current temperature,
likely implemented with |
maxlengthgroupgrowth |
An integer with the maximum length groups an individual can jump in one step. |
reference_weight |
Reference weight. see formula for |
stock |
|
delta_len_f |
A formula defining a non-negative vector for mean increase in length for |
delta_wgt_f |
A formula defining the corresponding weight increase as a matrix of
lengthgroup to lengthgroup delta for |
by_stock |
Change the default parameterisation (e.g. to be by 'species'), see |
impl_f |
A pair of formula objects, as defined by |
maturity_f |
A maturity formula, as defined by |
output_stocks |
List of |
output_ratios |
Vector of proportions for how to distribute into output_stocks, summing to 1, default evenly spread. |
transition_f |
formula specifying a contition for running maturation steps as well as growth, default final step of year. |
run_f |
formula specifying a condition for running this action, default always runs. |
run_at |
Integer order that actions will be run within model, see |
transition_at |
Integer order that transition actions will be run within model, see |
A model can have any number of g3a_growmature
actions, so long as the
calling arguments are different. For instance, run_f = ~age == 5
and
run_f = ~age == 7
.
impl_f's dependent variables are analysed to see what will affect growth.
If nothing but cur_step_size
will affect growth, then growth will only
be recalculated when the step size changes.
Returns a formula for use as delta_len_f:
Length of current step as a proportion of the year, e.g. 0.25. See cur_step_size
in g3a_time
Returns a formula for use as delta_wgt_f:
Vector of all possible length group increases i.e 0..maxlengthgroupgrowth
Returns a formula for use as delta_len_f:
Supplied parameters
Length of current step as a proportion of the year, e.g. 0.25. See cur_step_size
in g3a_time
Current length
Feeding level of stock. See g3a_predate_catchability_predator
Temperature of current region
Returns a formula for use as delta_wgt_f:
Supplied parameters
Length of current step as a proportion of the year, e.g. 0.25. See cur_step_size
in g3a_time
Current mean weight
Feeding level of stock. See g3a_predate_catchability_predator
Temperature of current region
Note that the equation is not dependent on the change in length, the value will be the same for each .
Returns a formula for use as delta_len_f:
Current mean weight
Supplied parameters
Feeding level of stock. See g3a_predate_catchability_predator
Reference weight, from the reference_weight parameter
Change in weight, i.e. the output from the delta_wgt_f formula, probably g3a_grow_weight_weightjones
.
Returns a formula for use as delta_wgt_f:
Supplied parameters
Length of current step as a proportion of the year, e.g. 0.25. See cur_step_size
in g3a_time
Maximum theoretical consumption, as defined by g3a_predate_maxconsumption
Feeding level of stock. See g3a_predate_catchability_predator
Current mean weight
Temperature of current region
Note that the equation is not dependent on the change in length, the value will be the same for each .
formula object converting mean growths using beta-binomia distribution. See https://gadget-framework.github.io/gadget2/userguide/chap-stock.html#beta-binomial
An action (i.e. list of formula objects) that will, for the given stock...
Move any maturing individuals into temporary storage, stock__transitioning_num
/ stock__transitioning_wgt
Calculate increase in length/weight using growth_f and impl_f
Move the contents of the temporary storage into output_stocks
https://gadget-framework.github.io/gadget2/userguide/chap-stock.html#sec:stockgrowth,
g3_stock
ling_imm <- g3_stock(c(species = 'ling', 'imm'), seq(20, 156, 4)) ling_mat <- g3_stock(c(species = 'ling', 'mat'), seq(20, 156, 4)) # Growth / maturity for immature ling growth_action <- g3a_growmature(ling_imm, impl_f = g3a_grow_impl_bbinom( # Parameters will be ling.Linf, ling.K g3a_grow_lengthvbsimple(by_stock = 'species'), # Parameters will be ling_imm.walpha, ling_imm.wbeta g3a_grow_weightsimple(), maxlengthgroupgrowth = 15), maturity_f = g3a_mature_constant( alpha = g3_parameterized('ling.mat1', scale = 0.001), l50 = g3_parameterized('ling.mat2')), output_stocks = list(ling_mat)) # Multspec growth - define a data frame with temperature temperature <- g3_timeareadata( 'temp', data.frame(year = 2000, step=c(1,2), temp=c(10, 14)), value_field = "temp" ) ms_growth_actions <- list( g3a_growmature(ling_imm, g3a_grow_impl_bbinom( g3a_grow_length_multspec(temperature = temperature), g3a_grow_weight_multspec(temperature = temperature), maxlengthgroupgrowth = 8 )), NULL)
ling_imm <- g3_stock(c(species = 'ling', 'imm'), seq(20, 156, 4)) ling_mat <- g3_stock(c(species = 'ling', 'mat'), seq(20, 156, 4)) # Growth / maturity for immature ling growth_action <- g3a_growmature(ling_imm, impl_f = g3a_grow_impl_bbinom( # Parameters will be ling.Linf, ling.K g3a_grow_lengthvbsimple(by_stock = 'species'), # Parameters will be ling_imm.walpha, ling_imm.wbeta g3a_grow_weightsimple(), maxlengthgroupgrowth = 15), maturity_f = g3a_mature_constant( alpha = g3_parameterized('ling.mat1', scale = 0.001), l50 = g3_parameterized('ling.mat2')), output_stocks = list(ling_mat)) # Multspec growth - define a data frame with temperature temperature <- g3_timeareadata( 'temp', data.frame(year = 2000, step=c(1,2), temp=c(10, 14)), value_field = "temp" ) ms_growth_actions <- list( g3a_growmature(ling_imm, g3a_grow_impl_bbinom( g3a_grow_length_multspec(temperature = temperature), g3a_grow_weight_multspec(temperature = temperature), maxlengthgroupgrowth = 8 )), NULL)
Add maturity actions to a g3 model
g3a_mature_continuous( alpha = g3_parameterized('mat.alpha', by_stock = by_stock), l50 = g3_parameterized('mat.l50', by_stock = by_stock), beta = 0, a50 = 0, bounded = TRUE, by_stock = TRUE) g3a_mature_constant(alpha = NULL, l50 = NA, beta = NULL, a50 = NA, gamma = NULL, k50 = NA) g3a_mature(stock, maturity_f, output_stocks, output_ratios = rep(1/length(output_stocks), times = length(output_stocks)), run_f = ~TRUE, run_at = g3_action_order$grow, transition_at = g3_action_order$mature)
g3a_mature_continuous( alpha = g3_parameterized('mat.alpha', by_stock = by_stock), l50 = g3_parameterized('mat.l50', by_stock = by_stock), beta = 0, a50 = 0, bounded = TRUE, by_stock = TRUE) g3a_mature_constant(alpha = NULL, l50 = NA, beta = NULL, a50 = NA, gamma = NULL, k50 = NA) g3a_mature(stock, maturity_f, output_stocks, output_ratios = rep(1/length(output_stocks), times = length(output_stocks)), run_f = ~TRUE, run_at = g3_action_order$grow, transition_at = g3_action_order$mature)
alpha |
A formula to substitute for |
l50 |
A formula to substitute for |
beta |
A formula to substitute for |
a50 |
A formula to substitute for |
gamma |
A formula to substitute for |
k50 |
A formula to substitute for |
bounded |
Should the maturity ratio be bounded to 0..1? Set TRUE if maturity is producing negative numbers of individuals. |
by_stock |
Change the default parameterisation (e.g. to be by 'species'), see |
stock |
|
maturity_f |
A maturity formula, as defined by |
output_stocks |
List of |
output_ratios |
Vector of proportions for how to distribute into output_stocks, summing to 1, default evenly spread. |
run_f |
formula specifying a condition for running this action, default always runs. |
run_at |
Integer order that actions will be run within model, see |
transition_at |
Integer order that transition actions will be run within model, see |
Generally you would use g3a_growmature
, which does both growth
and maturity at the same time.
A model can have any number of g3a_mature
actions, so long as the
calling arguments are different. For instance, run_f = ~age == 5
and
run_f = ~age == 7
.
A formula object representing
The g3a_mature_constant
formula, as defined below, using parameters supplied to g3a_mature_continuous
Vector of all possible changes in length, as per current growth matrix (see g3a_grow_impl_bbinom)
Length of current step as a proportion of the year, e.g. 0.25. See cur_step_size
in g3a_time
A formula object with the following equation
length of stock
length of stock when 50% are mature
age of stock
age of stock when 50% are mature
weight of stock
weight of stock when 50% are mature
An action (i.e. list of formula objects) that will, for the given stock...
Move any maturing individuals into temporary storage, stock__transitioning_num
/ stock__transitioning_wgt
Move the contents of the temporary storage into output_stocks
https://gadget-framework.github.io/gadget2/userguide/chap-stock.html#sec:stockmature,
g3a_growmature
,
g3_stock
ling_imm <- g3_stock('ling_imm', seq(20, 156, 4)) ling_mat <- g3_stock('ling_mat', seq(20, 156, 4)) # Maturity for immature ling maturity_action <- g3a_mature(ling_imm, maturity_f = g3a_mature_continuous(), output_stocks = list(ling_mat))
ling_imm <- g3_stock('ling_imm', seq(20, 156, 4)) ling_mat <- g3_stock('ling_mat', seq(20, 156, 4)) # Maturity for immature ling maturity_action <- g3a_mature(ling_imm, maturity_f = g3a_mature_continuous(), output_stocks = list(ling_mat))
Add migration to a g3 model
g3a_migrate_normalize(row_total = 1) g3a_migrate(stock, migrate_f, normalize_f = g3a_migrate_normalize(), run_f = TRUE, run_at = g3_action_order$migrate)
g3a_migrate_normalize(row_total = 1) g3a_migrate(stock, migrate_f, normalize_f = g3a_migrate_normalize(), run_f = TRUE, run_at = g3_action_order$migrate)
row_total |
When calculating the proportion of individuals that will stay in place, use this total for what rows are expected to sum to. |
stock |
The |
migrate_f |
A formula describing the migration in terms of (source) |
normalize_f |
Function to normalize a vector of possible destinations, to make sure fish aren't added or destroyed. |
run_f |
formula specifying a condition for running this action, default always runs. |
run_at |
Integer order that spawning actions will be run within model, see |
To restrict movement to a particular step in a year, or a particular area, use run_f. For example:
cur_step == 1
Migration will happen on first step of every year
cur_step == 1 && cur_year >= 1990
Migration will happen on first step of every year after 1990
cur_step == 2 && area = 1
Migration will happen on second step of every year, in the first area
Multiple migration actions can be added, for a separate spring and autumn migration, for instance.
The action will define the following stock instance variables for each given stock:
array, containing proportion of (stock) moved from one area to another. If NaN, no movement has occurred
A formula transforming stock__migratematrix[,stock__area_idx]
(i.e.
all possible destinations from a given area) by:
Squaring so values are all positive
Altering the proportion of static individuals so a row sums to row_total
Dividing by row_total so a row sums to 1
An action (i.e. list of formula objects) that will, for the given stock...
Fill in stock__migratematrix using migrate_f and normalize_f
Apply movement to stock
areas <- list(a=1, b=2, c=3, d=4) # NB: stock doesn't live in b, so won't figure in stock_acd__migratematrix stock_acd <- (g3_stock('stock_acd', seq(10, 40, 10)) %>% g3s_livesonareas(areas[c('a', 'c', 'd')])) movement_action <- list( g3a_migrate( stock_acd, # In spring, individuals in area 'a' will migrate to 'd'. ~if (area == area_a && dest_area == area_d) 0.8 else 0, run_f = ~cur_step == 2), g3a_migrate( stock_acd, # In autumn, individuals in all areas will migrate to 'a' ~if (dest_area == area_a) 0.8 else 0, run_f = ~cur_step == 4), list())
areas <- list(a=1, b=2, c=3, d=4) # NB: stock doesn't live in b, so won't figure in stock_acd__migratematrix stock_acd <- (g3_stock('stock_acd', seq(10, 40, 10)) %>% g3s_livesonareas(areas[c('a', 'c', 'd')])) movement_action <- list( g3a_migrate( stock_acd, # In spring, individuals in area 'a' will migrate to 'd'. ~if (area == area_a && dest_area == area_d) 0.8 else 0, run_f = ~cur_step == 2), g3a_migrate( stock_acd, # In autumn, individuals in all areas will migrate to 'a' ~if (dest_area == area_a) 0.8 else 0, run_f = ~cur_step == 4), list())
Add natural mortality to a g3 model
g3a_naturalmortality_exp( param_f = g3_parameterized('M', by_stock = by_stock, by_age = TRUE), by_stock = TRUE, action_step_size_f = ~cur_step_size) g3a_naturalmortality( stock, mortality_f = g3a_naturalmortality_exp(), run_f = TRUE, run_at = g3_action_order$naturalmortality)
g3a_naturalmortality_exp( param_f = g3_parameterized('M', by_stock = by_stock, by_age = TRUE), by_stock = TRUE, action_step_size_f = ~cur_step_size) g3a_naturalmortality( stock, mortality_f = g3a_naturalmortality_exp(), run_f = TRUE, run_at = g3_action_order$naturalmortality)
param_f |
A formula to substitute for |
action_step_size_f |
How much model time passes in between runs of action? defaults to |
by_stock |
Change the default parameterisation (e.g. to be by 'species'), see |
stock |
|
mortality_f |
A mortality formula, as defined by |
run_f |
formula specifying a condition for running this action, default always runs. |
run_at |
Integer order that actions will be run within model, see |
A model can have any number of g3a_naturalmortality
actions, so long as the
calling arguments are different. For instance, run_f = ~age == 5
and
run_f = ~age == 7
.
A formula object with the following equation
Length of current step as a proportion of the year, e.g. 0.25. See cur_step_size
in g3a_time
An action (i.e. list of formula objects) that will, for the given stock...
Remove a proportion of each stock group as calculated by the mortality formula mortality_f
https://gadget-framework.github.io/gadget2/userguide/chap-stock.html#sec:stocknatmort,
g3a_growmature
,
g3_stock
ling_imm <- g3_stock('ling_imm', seq(20, 156, 4)) %>% g3s_age(3, 10) # Natural mortality for immature ling naturalmortality_action <- g3a_naturalmortality(ling_imm) # NB: M is used in both g3a_naturalmortality and g3a_renewal_initabund, to # customise, you need to make sure the definitions are in sync, for example: M <- g3_parameterized('M', by_stock = TRUE, by_age = FALSE) actions <- list( g3a_naturalmortality(ling_imm, g3a_naturalmortality_exp(M)), g3a_initialconditions_normalparam(ling_imm, factor_f = g3a_renewal_initabund(M = M)), NULL)
ling_imm <- g3_stock('ling_imm', seq(20, 156, 4)) %>% g3s_age(3, 10) # Natural mortality for immature ling naturalmortality_action <- g3a_naturalmortality(ling_imm) # NB: M is used in both g3a_naturalmortality and g3a_renewal_initabund, to # customise, you need to make sure the definitions are in sync, for example: M <- g3_parameterized('M', by_stock = TRUE, by_age = FALSE) actions <- list( g3a_naturalmortality(ling_imm, g3a_naturalmortality_exp(M)), g3a_initialconditions_normalparam(ling_imm, factor_f = g3a_renewal_initabund(M = M)), NULL)
Constant defining standard order of actions
g3_action_order
g3_action_order
All gadget3 actions have a run_at parameter. This decides the point in the model that the action will happen relative to others.
The defaults for these are set via g3_action_order
.
A named integer list
https://gadget-framework.github.io/gadget2/userguide/chap-order.html
# The default action order unlist(g3_action_order) # View single value g3_action_order$age
# The default action order unlist(g3_action_order) # View single value g3_action_order$age
Add predation to a g3 model
g3a_predate_catchability_totalfleet(E) g3a_predate_catchability_numberfleet(E) g3a_predate_catchability_linearfleet(E) g3a_predate_catchability_effortfleet(catchability_fs, E) g3a_predate_catchability_quotafleet(quota_table, E, sum_stocks = list(), recalc_f = NULL) g3a_predate_maxconsumption( m0 = g3_parameterized('consumption.m0', value = 1, by_predator = TRUE, optimise = FALSE), m1 = g3_parameterized('consumption.m1', value = 0, by_predator = TRUE, optimise = FALSE), m2 = g3_parameterized('consumption.m2', value = 0, by_predator = TRUE, optimise = FALSE), m3 = g3_parameterized('consumption.m3', value = 0, by_predator = TRUE, optimise = FALSE), temperature = 0 ) g3a_predate_catchability_predator( prey_preferences = 1, energycontent = g3_parameterized('energycontent', value = 1, by_stock = by_stock, optimise = FALSE), half_feeding_f = g3_parameterized('halffeeding', by_predator = by_predator, optimise = FALSE), max_consumption = g3a_predate_maxconsumption(temperature = temperature), temperature = 0, by_predator = TRUE, by_stock = TRUE ) g3a_predate( predstock, prey_stocks, suitabilities, catchability_f, overconsumption_f = quote( dif_pmin(stock__consratio, 0.95, 1e3) ), run_f = ~TRUE, run_at = g3_action_order$predate ) # NB: Deprecated interface, use g3a_predate() g3a_predate_fleet(fleet_stock, prey_stocks, suitabilities, catchability_f, overconsumption_f = quote( dif_pmin(stock__consratio, 0.95, 1e3) ), run_f = ~TRUE, run_at = g3_action_order$predate) # NB: Deprecated interface, use g3a_predate() with g3a_predate_catchability_totalfleet g3a_predate_totalfleet(fleet_stock, prey_stocks, suitabilities, amount_f, overconsumption_f = quote( dif_pmin(stock__consratio, 0.95, 1e3) ), run_f = ~TRUE, run_at = g3_action_order$predate)
g3a_predate_catchability_totalfleet(E) g3a_predate_catchability_numberfleet(E) g3a_predate_catchability_linearfleet(E) g3a_predate_catchability_effortfleet(catchability_fs, E) g3a_predate_catchability_quotafleet(quota_table, E, sum_stocks = list(), recalc_f = NULL) g3a_predate_maxconsumption( m0 = g3_parameterized('consumption.m0', value = 1, by_predator = TRUE, optimise = FALSE), m1 = g3_parameterized('consumption.m1', value = 0, by_predator = TRUE, optimise = FALSE), m2 = g3_parameterized('consumption.m2', value = 0, by_predator = TRUE, optimise = FALSE), m3 = g3_parameterized('consumption.m3', value = 0, by_predator = TRUE, optimise = FALSE), temperature = 0 ) g3a_predate_catchability_predator( prey_preferences = 1, energycontent = g3_parameterized('energycontent', value = 1, by_stock = by_stock, optimise = FALSE), half_feeding_f = g3_parameterized('halffeeding', by_predator = by_predator, optimise = FALSE), max_consumption = g3a_predate_maxconsumption(temperature = temperature), temperature = 0, by_predator = TRUE, by_stock = TRUE ) g3a_predate( predstock, prey_stocks, suitabilities, catchability_f, overconsumption_f = quote( dif_pmin(stock__consratio, 0.95, 1e3) ), run_f = ~TRUE, run_at = g3_action_order$predate ) # NB: Deprecated interface, use g3a_predate() g3a_predate_fleet(fleet_stock, prey_stocks, suitabilities, catchability_f, overconsumption_f = quote( dif_pmin(stock__consratio, 0.95, 1e3) ), run_f = ~TRUE, run_at = g3_action_order$predate) # NB: Deprecated interface, use g3a_predate() with g3a_predate_catchability_totalfleet g3a_predate_totalfleet(fleet_stock, prey_stocks, suitabilities, amount_f, overconsumption_f = quote( dif_pmin(stock__consratio, 0.95, 1e3) ), run_f = ~TRUE, run_at = g3_action_order$predate)
predstock , fleet_stock
|
|
prey_stocks |
List of |
suitabilities |
Either a list of stock names to formula objects, with an optional unnamed default option, or a formula object (which is always used). Each formula should define suitability of a stock, for example
by using |
catchability_f |
A list of formulas generated by one of the |
E |
A formula defining total catch a fleet can harvest at the current time/area (totalfleet/numberfleet), or a scaling factor used to define the stock caught (linearfleet/effortfleet/quotafleet). |
catchability_fs |
Either a list of stock names to formula objects, with an optional unnamed default option, or a formula object (which is always used). |
quota_table |
A data.frame with 'biomass' and 'quota' columns,
'biomass' a numeric column, an upper bound for total biomass amount, the final value always being |
sum_stocks |
Either a list of g3_stock objects to sum when choosing a value from quote_table,
or |
recalc_f |
A formula denoting when to recalculate the current quota. For example |
amount_f |
Equivalent to E passed to g3a_predate_catchability_totalfleet. |
prey_preferences |
Either 1, indicating a Type II functional response, or >1 for a Type III functional response. Either a list of stock names to numbers, with an optional unnamed default option, or a single number to be used for all stocks. |
energycontent |
A formula object for the energy content of the current prey, in in kilojoules per kilogram. |
half_feeding_f |
The biomass of prey required to allow the predator to consume prey at half the maximum consumption level. |
max_consumption |
A formula for maximum consumption of the predator, in kilojoules per month.
Generally generated by |
m0 , m1 , m2 , m3
|
Parameters for maximum possible consumption formula, see below. |
temperature |
A formula object for the current temperature, probably generated by |
overconsumption_f |
Overconsumption rule, a formula that should cap all values in stock__consratio to <= 95 |
by_stock |
Change the default parameterisation (e.g. to be by 'species'), see |
by_predator |
Change the default parameterisation (e.g. to be by 'species'), see |
run_f |
formula specifying a condition for running this action, default always runs. |
run_at |
Integer order that actions will be run within model, see |
g3a_predate
will, given a g3_fleet
"predator" and a set of g3_stock
preys,
add predation into a model. The behaviour is driven by 2 parameters:
Defines a predator's preference within a prey stock, normally one of the suitability functions, e.g. g3_suitability_exponentiall50
Defines a predator's overall requirements, set with one of the catchability functions, e.g. g3a_predate_catchability_totalfleet
For the definition of each catchability function, see the values section below.
The actions will define the following stock instance variables for each given fleet_stock and prey_stock:
Total suitable prey for (predstock), i.e.
Suitability of (prey_stock) for (fleet_stock), i.e.
Biomass of (prey_stock) caught by (predstock), by predator & prey dimensions
Biomass of total consumed (prey_stock), in a prey array
Ratio of prey_stock__totalpredate / (current biomass), capped by overconsumption_f
In addition, g3a_predate_fleet
will generate prey_stock__predby_predstock, Biomass of (prey_stock) caught by (fleet_stock), in a prey array,
for compatibility with older models. It is otherwise identical to g3a_predate
.
A model can have any number of g3a_predate_*
actions, so long as the
calling arguments are different. For instance, run_f = ~age == 5
and
run_f = ~age == 7
.
formula objects that define a fleet's desired catch by total biomass (e.g. landings data):
Suitability form suitabilities argument
E argument, biomass caught by fleet. Generally a g3_timeareadata
table containing landings data, with year/step/area/weight columns
Number of prey in length cell for prey , length
Mean weight of prey in length cell for prey , length
formula objects that define a fleet's desired catch by total number of stock landed (individuals, not biomass):
Suitability form suitabilities argument
E argument, numbers caught by fleet. Generally a g3_timeareadata
table containing landings data, or a constant quota
Number of prey in length cell for prey , length
Mean weight of prey in length cell for prey , length
formula objects that define a linear relationship between desired catch and available biomass:
Suitability form suitabilities argument
E argument, scaling factor for the stock that is to be caught, per month
Length of current step as a proportion of the year, e.g. 0.25. See cur_step_size
in g3a_time
Number of prey in length cell for prey , length
Mean weight of prey in length cell for prey , length
This is a multi-species extension to linearfleet, allowing differently-parameterized catchability per-stock:
Suitability form suitabilities argument
catchability_fs argument for the current stock
E argument, scaling factor for the stock that is to be caught, per month
Length of current step as a proportion of the year, e.g. 0.25. See cur_step_size
in g3a_time
Number of prey in length cell for prey , length
Mean weight of prey in length cell for prey , length
A formula onject that defines catch based on the available biomass of the stock multiplied by a scaling factor set according to a simple harvest control rule:
quota selected from quota_table, corresponding to the total biomass of sum_stocks.
For example, given data.frame(biomass = c(10000, Inf), quota = I(list(g3_parameterized('quota.low'), g3_parameterized('quota.high'))))
,
'quota.low' will be chosen when total biomass is less than 10000, otherwise 'quota.high' will be used.
Suitability form suitabilities argument
E argument, scaling factor for the stock that is to be caught, per month
Length of current step as a proportion of the year, e.g. 0.25. See cur_step_size
in g3a_time
Number of prey in length cell for prey , length
Mean weight of prey in length cell for prey , length
...if recalc_f is set, this will only be recaculated when true. Any other step will use the previous value.
formula objects that define a predator's maximum consumption:
mx parameter, for , maximum possible consumption for the predator on the current timestep
Length of current step as a proportion of the year, e.g. 0.25. See cur_step_size
in g3a_time
temperature parameter, formula representing current temperature
formula objects that define the predator/prey relationship:
Suitability form suitabilities argument
Length of current step as a proportion of the year, e.g. 0.25. See cur_step_size
in g3a_time
Number of prey in length cell for prey , length
Mean weight of prey in length cell for prey , length
Maximum possible consumption for the predator on the current timestep, in in kilojoules per month. See g3a_predate_maxconsumption
Length of the current predator
energycontent parameter, the energy content of prey
half_feeding_f parameter, the biomass of prey required to allow the predator to consume prey at half the maximum consumption level
temperature parameter, formula representing current temperature
An action (i.e. list of formula objects) that will...
For each prey, collect all suitable stock into a predstock_prey_stock__suit variable, using the catchability_f formula. The units here will depend on the catchability_f method used.
After all predator consumption is done, scale consumption using the catchability_f formula into predstock_prey_stock__cons, summed into prey_stock__totalpredate
Calculate prey_stock__consratio (ratio of consumed to available), capping using overconsumption_f. Update prey_stock__num
Recalculate predstock_prey_stock__cons, predstock_prey_stock__suit, post-overconsumption
https://gadget-framework.github.io/gadget2/userguide/chap-stock.html#sec:stockpredator,
g3_stock
areas <- c(a = 1, b = 2) ling_imm <- g3_stock(c(species = 'ling', 'imm'), seq(20, 156, 4)) %>% g3s_age(3, 10) ling_mat <- g3_stock(c(species = 'ling', 'mat'), seq(20, 156, 4)) %>% g3s_age(5, 15) lln <- g3_fleet('lln') %>% g3s_livesonareas(areas[c('a', 'b')]) # Invent a lln_landings table lln_landings <- expand.grid( year = 1999:2000, step = c(1, 2), area = areas[c('a', 'b')]) lln_landings$total_weight <- floor(runif(nrow(lln_landings), min=100, max=999)) # g3a_predate_catchability_totalfleet(): Set catch accordings to landings data predate_action <- g3a_predate_fleet( lln, list(ling_imm, ling_mat), suitabilities = g3_suitability_exponentiall50(by_stock = 'species'), catchability_f = g3a_predate_catchability_totalfleet( g3_timeareadata('lln_landings', lln_landings, "total_weight") )) # g3a_predate_catchability_numberfleet(): Fixed quota of 1000 fish predate_action <- g3a_predate_fleet( lln, list(ling_imm, ling_mat), suitabilities = g3_suitability_exponentiall50(by_stock = 'species'), catchability_f = g3a_predate_catchability_numberfleet( g3_parameterized( 'quota', value = 1000, by_predator = TRUE, scale = 0.5, optimise = FALSE) )) attr(suppressWarnings(g3_to_r(list(predate_action))), 'parameter_template')
areas <- c(a = 1, b = 2) ling_imm <- g3_stock(c(species = 'ling', 'imm'), seq(20, 156, 4)) %>% g3s_age(3, 10) ling_mat <- g3_stock(c(species = 'ling', 'mat'), seq(20, 156, 4)) %>% g3s_age(5, 15) lln <- g3_fleet('lln') %>% g3s_livesonareas(areas[c('a', 'b')]) # Invent a lln_landings table lln_landings <- expand.grid( year = 1999:2000, step = c(1, 2), area = areas[c('a', 'b')]) lln_landings$total_weight <- floor(runif(nrow(lln_landings), min=100, max=999)) # g3a_predate_catchability_totalfleet(): Set catch accordings to landings data predate_action <- g3a_predate_fleet( lln, list(ling_imm, ling_mat), suitabilities = g3_suitability_exponentiall50(by_stock = 'species'), catchability_f = g3a_predate_catchability_totalfleet( g3_timeareadata('lln_landings', lln_landings, "total_weight") )) # g3a_predate_catchability_numberfleet(): Fixed quota of 1000 fish predate_action <- g3a_predate_fleet( lln, list(ling_imm, ling_mat), suitabilities = g3_suitability_exponentiall50(by_stock = 'species'), catchability_f = g3a_predate_catchability_numberfleet( g3_parameterized( 'quota', value = 1000, by_predator = TRUE, scale = 0.5, optimise = FALSE) )) attr(suppressWarnings(g3_to_r(list(predate_action))), 'parameter_template')
Add renewal / initialconditions to a g3 model
g3a_renewal_vonb_recl( Linf = g3_parameterized('Linf', value = 1, by_stock = by_stock), K = g3_parameterized('K', value = 1, by_stock = by_stock), recl = g3_parameterized('recl', by_stock = by_stock), recage = g3_parameterized('recage', by_stock = FALSE, optimise = FALSE), by_stock = TRUE) g3a_renewal_vonb_t0( Linf = g3_parameterized('Linf', value = 1, by_stock = by_stock), K = g3_parameterized('K', value = 1, by_stock = by_stock), t0 = g3_parameterized('t0', by_stock = by_stock), by_stock = TRUE) g3a_renewal_initabund( scalar = g3_parameterized('init.scalar', value = 1, by_stock = by_stock), init = g3_parameterized('init', value = 1, by_stock = by_stock, by_age = TRUE), M = g3_parameterized('M', by_stock = by_stock, by_age = TRUE), init_F = g3_parameterized('init.F', by_stock = by_stock_f), recage = g3_parameterized('recage', by_stock = FALSE, optimise = FALSE), proportion_f = ~1, by_stock = TRUE, by_stock_f = FALSE) ############################# g3a_initialconditions g3a_initialconditions(stock, num_f, wgt_f, run_f = ~cur_time == 0L, run_at = g3_action_order$initial) g3a_initialconditions_normalparam( stock, factor_f = g3a_renewal_initabund(by_stock = by_stock), mean_f = g3a_renewal_vonb_t0(by_stock = by_stock), stddev_f = g3_parameterized('init.sd', value = 10, by_stock = by_stock, by_age = by_age), alpha_f = g3_parameterized('walpha', by_stock = wgt_by_stock), beta_f = g3_parameterized('wbeta', by_stock = wgt_by_stock), age_offset = quote( cur_step_size ), by_stock = TRUE, by_age = FALSE, wgt_by_stock = TRUE, run_f = ~cur_time == 0L, run_at = g3_action_order$initial) g3a_initialconditions_normalcv( stock, factor_f = g3a_renewal_initabund(by_stock = by_stock), mean_f = g3a_renewal_vonb_t0(by_stock = by_stock), cv_f = g3_parameterized('lencv', by_stock = by_stock, value = 0.1, optimise = FALSE), alpha_f = g3_parameterized('walpha', by_stock = wgt_by_stock), beta_f = g3_parameterized('wbeta', by_stock = wgt_by_stock), age_offset = quote( cur_step_size ), by_stock = TRUE, by_age = FALSE, wgt_by_stock = TRUE, run_f = ~cur_time == 0L, run_at = g3_action_order$initial) ############################# g3a_renewal g3a_renewal(stock, num_f, wgt_f, run_f = ~TRUE, run_at = g3_action_order$renewal) g3a_renewal_normalparam( stock, factor_f = g3_parameterized('rec', by_stock = by_stock, by_year = TRUE, scale = g3_parameterized( name = 'rec.scalar', by_stock = by_stock), ifmissing = NaN), mean_f = g3a_renewal_vonb_t0(by_stock = by_stock), stddev_f = g3_parameterized('rec.sd', value = 10, by_stock = by_stock), alpha_f = g3_parameterized('walpha', by_stock = wgt_by_stock), beta_f = g3_parameterized('wbeta', by_stock = wgt_by_stock), by_stock = TRUE, wgt_by_stock = TRUE, run_age = quote(stock__minage), run_projection = FALSE, run_step = 1, run_f = NULL, run_at = g3_action_order$renewal) g3a_renewal_normalcv( stock, factor_f = g3_parameterized('rec', by_stock = by_stock, by_year = TRUE, scale = g3_parameterized( name = 'rec.scalar', by_stock = by_stock), ifmissing = NaN), mean_f = g3a_renewal_vonb_t0(by_stock = by_stock), cv_f = g3_parameterized('lencv', by_stock = by_stock, value = 0.1, optimise = FALSE), alpha_f = g3_parameterized('walpha', by_stock = wgt_by_stock), beta_f = g3_parameterized('wbeta', by_stock = wgt_by_stock), by_stock = TRUE, wgt_by_stock = TRUE, run_age = quote(stock__minage), run_projection = FALSE, run_step = 1, run_f = NULL, run_at = g3_action_order$renewal) ############################# g3a_otherfood g3a_otherfood( stock, num_f = g3_parameterized('of_abund', by_year = TRUE, by_stock = by_stock, scale = g3_parameterized('of_abund.step', by_step = TRUE, by_stock = by_stock) ), wgt_f = g3_parameterized('of_meanwgt', by_stock = by_stock), by_stock = TRUE, force_lengthvector = !any(grepl("__midlen$", all.vars(num_f))), run_f = quote( cur_time <= total_steps ), run_at = g3_action_order$initial) g3a_otherfood_normalparam( stock, factor_f = g3_parameterized( 'of_abund', by_year = TRUE, by_stock = by_stock, scale = g3_parameterized( 'of_abund.step', value = 1, by_step = TRUE, by_stock = by_stock), ifmissing = "of_abund.proj" ), mean_f = g3a_renewal_vonb_t0(by_stock = by_stock), stddev_f = g3_parameterized('init.sd', value = 10, by_stock = by_stock, by_age = by_age), alpha_f = g3_parameterized('walpha', by_stock = wgt_by_stock), beta_f = g3_parameterized('wbeta', by_stock = wgt_by_stock), by_stock = TRUE, by_age = FALSE, wgt_by_stock = TRUE, run_f = quote( cur_time <= total_steps ), run_at = g3_action_order$initial) g3a_otherfood_normalcv( stock, factor_f = g3_parameterized( 'of_abund', by_year = TRUE, by_stock = by_stock, scale = g3_parameterized( 'of_abund.step', value = 1, by_step = TRUE, by_stock = by_stock), ifmissing = "of_abund.proj" ), mean_f = g3a_renewal_vonb_t0(by_stock = by_stock), cv_f = g3_parameterized('lencv', by_stock = by_stock, value = 0.1, optimise = FALSE), alpha_f = g3_parameterized('walpha', by_stock = wgt_by_stock), beta_f = g3_parameterized('wbeta', by_stock = wgt_by_stock), by_stock = TRUE, by_age = FALSE, wgt_by_stock = TRUE, run_f = quote( cur_time <= total_steps ), run_at = g3_action_order$initial)
g3a_renewal_vonb_recl( Linf = g3_parameterized('Linf', value = 1, by_stock = by_stock), K = g3_parameterized('K', value = 1, by_stock = by_stock), recl = g3_parameterized('recl', by_stock = by_stock), recage = g3_parameterized('recage', by_stock = FALSE, optimise = FALSE), by_stock = TRUE) g3a_renewal_vonb_t0( Linf = g3_parameterized('Linf', value = 1, by_stock = by_stock), K = g3_parameterized('K', value = 1, by_stock = by_stock), t0 = g3_parameterized('t0', by_stock = by_stock), by_stock = TRUE) g3a_renewal_initabund( scalar = g3_parameterized('init.scalar', value = 1, by_stock = by_stock), init = g3_parameterized('init', value = 1, by_stock = by_stock, by_age = TRUE), M = g3_parameterized('M', by_stock = by_stock, by_age = TRUE), init_F = g3_parameterized('init.F', by_stock = by_stock_f), recage = g3_parameterized('recage', by_stock = FALSE, optimise = FALSE), proportion_f = ~1, by_stock = TRUE, by_stock_f = FALSE) ############################# g3a_initialconditions g3a_initialconditions(stock, num_f, wgt_f, run_f = ~cur_time == 0L, run_at = g3_action_order$initial) g3a_initialconditions_normalparam( stock, factor_f = g3a_renewal_initabund(by_stock = by_stock), mean_f = g3a_renewal_vonb_t0(by_stock = by_stock), stddev_f = g3_parameterized('init.sd', value = 10, by_stock = by_stock, by_age = by_age), alpha_f = g3_parameterized('walpha', by_stock = wgt_by_stock), beta_f = g3_parameterized('wbeta', by_stock = wgt_by_stock), age_offset = quote( cur_step_size ), by_stock = TRUE, by_age = FALSE, wgt_by_stock = TRUE, run_f = ~cur_time == 0L, run_at = g3_action_order$initial) g3a_initialconditions_normalcv( stock, factor_f = g3a_renewal_initabund(by_stock = by_stock), mean_f = g3a_renewal_vonb_t0(by_stock = by_stock), cv_f = g3_parameterized('lencv', by_stock = by_stock, value = 0.1, optimise = FALSE), alpha_f = g3_parameterized('walpha', by_stock = wgt_by_stock), beta_f = g3_parameterized('wbeta', by_stock = wgt_by_stock), age_offset = quote( cur_step_size ), by_stock = TRUE, by_age = FALSE, wgt_by_stock = TRUE, run_f = ~cur_time == 0L, run_at = g3_action_order$initial) ############################# g3a_renewal g3a_renewal(stock, num_f, wgt_f, run_f = ~TRUE, run_at = g3_action_order$renewal) g3a_renewal_normalparam( stock, factor_f = g3_parameterized('rec', by_stock = by_stock, by_year = TRUE, scale = g3_parameterized( name = 'rec.scalar', by_stock = by_stock), ifmissing = NaN), mean_f = g3a_renewal_vonb_t0(by_stock = by_stock), stddev_f = g3_parameterized('rec.sd', value = 10, by_stock = by_stock), alpha_f = g3_parameterized('walpha', by_stock = wgt_by_stock), beta_f = g3_parameterized('wbeta', by_stock = wgt_by_stock), by_stock = TRUE, wgt_by_stock = TRUE, run_age = quote(stock__minage), run_projection = FALSE, run_step = 1, run_f = NULL, run_at = g3_action_order$renewal) g3a_renewal_normalcv( stock, factor_f = g3_parameterized('rec', by_stock = by_stock, by_year = TRUE, scale = g3_parameterized( name = 'rec.scalar', by_stock = by_stock), ifmissing = NaN), mean_f = g3a_renewal_vonb_t0(by_stock = by_stock), cv_f = g3_parameterized('lencv', by_stock = by_stock, value = 0.1, optimise = FALSE), alpha_f = g3_parameterized('walpha', by_stock = wgt_by_stock), beta_f = g3_parameterized('wbeta', by_stock = wgt_by_stock), by_stock = TRUE, wgt_by_stock = TRUE, run_age = quote(stock__minage), run_projection = FALSE, run_step = 1, run_f = NULL, run_at = g3_action_order$renewal) ############################# g3a_otherfood g3a_otherfood( stock, num_f = g3_parameterized('of_abund', by_year = TRUE, by_stock = by_stock, scale = g3_parameterized('of_abund.step', by_step = TRUE, by_stock = by_stock) ), wgt_f = g3_parameterized('of_meanwgt', by_stock = by_stock), by_stock = TRUE, force_lengthvector = !any(grepl("__midlen$", all.vars(num_f))), run_f = quote( cur_time <= total_steps ), run_at = g3_action_order$initial) g3a_otherfood_normalparam( stock, factor_f = g3_parameterized( 'of_abund', by_year = TRUE, by_stock = by_stock, scale = g3_parameterized( 'of_abund.step', value = 1, by_step = TRUE, by_stock = by_stock), ifmissing = "of_abund.proj" ), mean_f = g3a_renewal_vonb_t0(by_stock = by_stock), stddev_f = g3_parameterized('init.sd', value = 10, by_stock = by_stock, by_age = by_age), alpha_f = g3_parameterized('walpha', by_stock = wgt_by_stock), beta_f = g3_parameterized('wbeta', by_stock = wgt_by_stock), by_stock = TRUE, by_age = FALSE, wgt_by_stock = TRUE, run_f = quote( cur_time <= total_steps ), run_at = g3_action_order$initial) g3a_otherfood_normalcv( stock, factor_f = g3_parameterized( 'of_abund', by_year = TRUE, by_stock = by_stock, scale = g3_parameterized( 'of_abund.step', value = 1, by_step = TRUE, by_stock = by_stock), ifmissing = "of_abund.proj" ), mean_f = g3a_renewal_vonb_t0(by_stock = by_stock), cv_f = g3_parameterized('lencv', by_stock = by_stock, value = 0.1, optimise = FALSE), alpha_f = g3_parameterized('walpha', by_stock = wgt_by_stock), beta_f = g3_parameterized('wbeta', by_stock = wgt_by_stock), by_stock = TRUE, by_age = FALSE, wgt_by_stock = TRUE, run_f = quote( cur_time <= total_steps ), run_at = g3_action_order$initial)
stock |
The |
num_f |
formula that produces a lengthgroup vector of number of individuals for the current age/area/... length group. |
wgt_f |
formula that produces a lenghgroup vector of mean weight for the current age/area/... length group. |
run_at |
Integer order that actions will be run within model, see |
factor_f , mean_f , stddev_f , alpha_f , beta_f
|
formula substituted into normalparam calcuations, see below. |
cv_f |
formula substituted into normalcv calcuations, basically |
age_offset |
Replace |
force_lengthvector |
Should we assume that |
run_age |
Age to run renewals for, used as |
run_projection |
Boolean. Run renewal in projection years? If false adds |
run_step |
Which step to perform renewal in, or |
run_f |
formula specifying a condition for running this action, For initialconditions defaults to first timestep. For renewal, the default is a combination of run_age, run_step & run_projection. For otherfood, the default is to always run, apart from when the model is ending. |
Linf , K , t0 , recl
|
formula substituted into vonb calcuations, see below. |
recage |
formula substituted into initial abundance and vonb calcuations, see below. |
proportion_f , scalar , init , M , init_F
|
formula substituted into initial abundance calcuations, see below. |
by_stock , wgt_by_stock , by_stock_f , by_age
|
Controls how parameters are grouped, see |
All of the following actions will renew stock in a model. The differences are when and what they apply to by default:
g3a_initialconditions_*
Will run at the start of the model, building an inital state of all ages
g3a_renewal_*
Will run at every step but only for the minimal age, adding new recruits as an alternative to g3a_spawn()
g3a_otherfood_*
Will run at every step, replacing the previous state, creating a non-dynamic stock for predators to consume
Specifying the quantities and mean-weights in each case works identically.
A model can have any number of g3a_renewal_*
actions, so long as the
calling arguments are different. For instance, run_f = ~age == 5
and
run_f = ~age == 7
.
The g3a_renewal_*
actions will define the following stock instance variables for stock:
Extra individuals added to the stock
Mean weight of added individuals
A formula object representing
Substituted for recl
Substituted for Linf
Substituted for K
Substituted for recage
NB: g3a_initialconditions_normalparam
will replace with
, see age_offset
A formula object representing
Substituted for Linf
Substituted for K
Substituted for t0
NB: g3a_initialconditions_normalparam
will replace with
, see age_offset
An alias for g3a_renewal_vonb_recl
()
A formula object representing
Substituted for scalar
Substituted for init
Substituted for M
Substituted for init_F
Substituted for recage
Substituted for proportion
An action (i.e. list of formula objects) that will, for the given stock, iterate over each area/age/etc. combination, and generate a lengthgroup vector of new individuals and weights using num_f and wgt_f.
renewal will add fish to the existing stock, whereas initialconditions & otherfood will replace any previous values.
As g3a_initialconditions / g3a_renewal, but the following formulae are used to calculate num/wgt:
Midlength of length groups for current area/age/...
Substituted for factor_f
Substituted for mean_f
Substituted for stddev_f
Substituted for alpha_f
Substituted for beta_f
As g3a_initialconditions / g3a_renewal, but the following formulae are used to calculate num/wgt:
Midlength of length groups for current area/age/...
Substituted for factor_f
Substituted for mean_f
Substituted for cv_f
Substituted for alpha_f
Substituted for beta_f
https://gadget-framework.github.io/gadget2/userguide/chap-stock.html#sec:stockinitial,
https://gadget-framework.github.io/gadget2/userguide/chap-stock.html#sec:stockrenew,
https://gadget-framework.github.io/gadget2/userguide/chap-other.html#chap-other,
g3_stock
ling_imm <- g3_stock('ling_imm', seq(20, 156, 4)) %>% g3s_age(3, 10) initialconditions_action <- g3a_initialconditions_normalparam( ling_imm, by_age = TRUE) # per-age init.sd parameters renewal_action <- g3a_renewal_normalparam( ling_imm, run_step = 2) # Renewal happens in spring # To get a single ling_imm.lencv parameter instead of init.sd initialconditions_action <- g3a_initialconditions_normalcv( ling_imm) renewal_action <- g3a_renewal_normalcv( ling_imm, run_step = 2) # Renewal happens in spring ## Plots par(mar = c(4,2,2,1), cex.main = 1) curve(g3_eval(g3a_renewal_vonb_t0(Linf = 20, K = 0.8, t0 = 0), age = x), 0, 10, col = 2, xlab = "age", main = "g3a_renewal_vonb_t0(Linf = 20, K = 0.8..1.4, t0 = 0)") curve(g3_eval(g3a_renewal_vonb_t0(Linf = 20, K = 1.0, t0 = 0), age = x), 0, 10, col = 1, add = TRUE) curve(g3_eval(g3a_renewal_vonb_t0(Linf = 20, K = 1.2, t0 = 0), age = x), 0, 10, col = 3, add = TRUE) curve(g3_eval(g3a_renewal_vonb_t0(Linf = 20, K = 1.4, t0 = 0), age = x), 0, 10, col = 4, add = TRUE) ## Otherfood # "Otherfood" stocks are defined in a similar manner to any other stock # Note that _normalparam & _normalcv need both length & age dimensions other_wgt <- g3_stock('other_wgt', 0) other_cv <- g3_stock('other_cv', seq(50, 100, by = 10)) %>% g3s_age(5,10) otherfood_actions <- list( # Will get other_wgt.of_abund.1998.1, other_wgt.of_meanwgt parameters g3a_otherfood(other_wgt), # Use standard vonB parameters (Linf/K/t0) to define abundance g3a_otherfood_normalcv(other_cv) )
ling_imm <- g3_stock('ling_imm', seq(20, 156, 4)) %>% g3s_age(3, 10) initialconditions_action <- g3a_initialconditions_normalparam( ling_imm, by_age = TRUE) # per-age init.sd parameters renewal_action <- g3a_renewal_normalparam( ling_imm, run_step = 2) # Renewal happens in spring # To get a single ling_imm.lencv parameter instead of init.sd initialconditions_action <- g3a_initialconditions_normalcv( ling_imm) renewal_action <- g3a_renewal_normalcv( ling_imm, run_step = 2) # Renewal happens in spring ## Plots par(mar = c(4,2,2,1), cex.main = 1) curve(g3_eval(g3a_renewal_vonb_t0(Linf = 20, K = 0.8, t0 = 0), age = x), 0, 10, col = 2, xlab = "age", main = "g3a_renewal_vonb_t0(Linf = 20, K = 0.8..1.4, t0 = 0)") curve(g3_eval(g3a_renewal_vonb_t0(Linf = 20, K = 1.0, t0 = 0), age = x), 0, 10, col = 1, add = TRUE) curve(g3_eval(g3a_renewal_vonb_t0(Linf = 20, K = 1.2, t0 = 0), age = x), 0, 10, col = 3, add = TRUE) curve(g3_eval(g3a_renewal_vonb_t0(Linf = 20, K = 1.4, t0 = 0), age = x), 0, 10, col = 4, add = TRUE) ## Otherfood # "Otherfood" stocks are defined in a similar manner to any other stock # Note that _normalparam & _normalcv need both length & age dimensions other_wgt <- g3_stock('other_wgt', 0) other_cv <- g3_stock('other_cv', seq(50, 100, by = 10)) %>% g3s_age(5,10) otherfood_actions <- list( # Will get other_wgt.of_abund.1998.1, other_wgt.of_meanwgt parameters g3a_otherfood(other_wgt), # Use standard vonB parameters (Linf/K/t0) to define abundance g3a_otherfood_normalcv(other_cv) )
Add report to a g3 model
g3a_report_stock(report_stock, input_stock, report_f, include_adreport = FALSE, run_f = TRUE, run_at = g3_action_order$report) g3a_report_history( actions, var_re = "__num$|__wgt$", out_prefix = "hist_", run_f = TRUE, run_at = g3_action_order$report) g3a_report_detail(actions, run_f = quote( g3_param('report_detail', optimise = FALSE, value = 1L, source = "g3a_report_detail") == 1 ), abundance_run_at = g3_action_order$report_early, run_at = g3_action_order$report)
g3a_report_stock(report_stock, input_stock, report_f, include_adreport = FALSE, run_f = TRUE, run_at = g3_action_order$report) g3a_report_history( actions, var_re = "__num$|__wgt$", out_prefix = "hist_", run_f = TRUE, run_at = g3_action_order$report) g3a_report_detail(actions, run_f = quote( g3_param('report_detail', optimise = FALSE, value = 1L, source = "g3a_report_detail") == 1 ), abundance_run_at = g3_action_order$report_early, run_at = g3_action_order$report)
report_stock |
The |
input_stock |
The |
report_f |
formula specifying what to collect, for instance |
actions |
List of actions that model will consist of. |
var_re |
Regular expression specifying variables to log history for. |
out_prefix |
Prefix to add to history report output, e.g. |
include_adreport |
Should the aggregated value get ADREPORT'ed? |
abundance_run_at |
Integer order that abundance will be collected within the model. Note that by default it's collected at the start, not the end |
run_f |
formula specifying a condition for running this action, default always runs. |
run_at |
Integer order that actions will be run within model, see |
The g3a_report_detail
defines a selection of default reports from your model, using g3a_report_history
:
*_surveyindices_*__params
The slope/intercept as used by g3l_distribution_surveyindices_log
step_lengths
*_weight
The weighting of likelihood components
nll_*
Breakdown of nll for each likelihood component
dstart_*__num
Abundance in numbers, at start of each model step
dstart_*__wgt
Mean weight of individuals, at start of each model step
detail_*__renewalnum
Numbers produced by renewal at each model step
detail_*__spawnednum
Numbers produced by spawning at each model step
detail_*_*__cons
Total biomass of prey consumed by predator, at each model step
detail_*_*__suit
Total suitable biomass of prey for predator, at each model step
The reports produced by g3a_report_history
will vary based on the provided inputs.
A model can have any number of g3a_report_*
actions, so long as the
calling arguments are different. For instance, run_f = ~age == 5
and
run_f = ~age == 7
.
An action (i.e. list of formula objects) that will...
Iterate over input_stock, collecting data into report_stock
Add the contents of report_stock__instance_name to the model report
An action (i.e. list of formula objects) that will store the current state of each variable found matching var_re.
Uses g3a_report_history to generate detailed reports suitable for use in g3_fit
.
ling_imm <- g3_stock('ling_imm', seq(20, 156, 4)) %>% g3s_age(3, 10) # Report that aggregates ages together agg_report <- g3_stock('agg_report', c(1)) %>% g3s_agegroup(list(young = 1:3, old = 4:5)) %>% g3s_time(year = 2000:2002) # Generate dissaggregated report by cloning the source stock, adding time raw_report <- g3s_clone(ling_imm, 'raw_report') %>% g3s_time(year = 2000:2002) actions <- list( g3a_age(ling_imm), g3a_report_stock(agg_report, ling_imm, g3_formula( stock_ss(ling_imm__num) ), include_adreport = TRUE), g3a_report_stock(raw_report, ling_imm, g3_formula( stock_ss(ling_imm__num) ))) # "raw_report__num" and "agg_report__num" will be available in the model report # In addition, agg_report__num will be included in TMB::sdreport() output # Report history of all "__num" and "__wgt" variables actions <- c(actions, list(g3a_report_history(actions))) # Report history of just "ling_imm__num" actions <- c(actions, list(g3a_report_history(actions, "^ling_imm__num$"))) # Add a detail report suitable for g3_fit actions <- c(actions, list(g3a_report_detail(actions)))
ling_imm <- g3_stock('ling_imm', seq(20, 156, 4)) %>% g3s_age(3, 10) # Report that aggregates ages together agg_report <- g3_stock('agg_report', c(1)) %>% g3s_agegroup(list(young = 1:3, old = 4:5)) %>% g3s_time(year = 2000:2002) # Generate dissaggregated report by cloning the source stock, adding time raw_report <- g3s_clone(ling_imm, 'raw_report') %>% g3s_time(year = 2000:2002) actions <- list( g3a_age(ling_imm), g3a_report_stock(agg_report, ling_imm, g3_formula( stock_ss(ling_imm__num) ), include_adreport = TRUE), g3a_report_stock(raw_report, ling_imm, g3_formula( stock_ss(ling_imm__num) ))) # "raw_report__num" and "agg_report__num" will be available in the model report # In addition, agg_report__num will be included in TMB::sdreport() output # Report history of all "__num" and "__wgt" variables actions <- c(actions, list(g3a_report_history(actions))) # Report history of just "ling_imm__num" actions <- c(actions, list(g3a_report_history(actions, "^ling_imm__num$"))) # Add a detail report suitable for g3_fit actions <- c(actions, list(g3a_report_detail(actions)))
Add spawning to a g3 model
g3a_spawn_recruitment_fecundity( p0 = g3_parameterized('spawn.p0', value = 1, by_stock = by_stock), p1 = g3_parameterized('spawn.p1', value = 1, by_stock = by_stock), p2 = g3_parameterized('spawn.p2', value = 1, by_stock = by_stock), p3 = g3_parameterized('spawn.p3', value = 1, by_stock = by_stock), p4 = g3_parameterized('spawn.p4', value = 1, by_stock = by_stock), by_stock = TRUE ) g3a_spawn_recruitment_simplessb( mu = g3_parameterized('spawn.mu', by_stock = by_stock), by_stock = TRUE ) g3a_spawn_recruitment_ricker( mu = g3_parameterized('spawn.mu', by_stock = by_stock), lambda = g3_parameterized('spawn.lambda', by_stock = by_stock), by_stock = TRUE ) g3a_spawn_recruitment_bevertonholt( mu = g3_parameterized('spawn.mu', by_stock = by_stock), lambda = g3_parameterized('spawn.lambda', by_stock = by_stock), by_stock = TRUE ) g3a_spawn_recruitment_bevertonholt_ss3( # Steepness parameter h = g3_parameterized('spawn.h', lower = 0.1, upper = 1, value = 0.5, by_stock = by_stock ), # Recruitment deviates R = g3_parameterized('spawn.R', by_year = TRUE, exponentiate = TRUE, # Unfished equilibrium recruitment scale = "spawn.R0", by_stock = by_stock), # Unfished equilibrium spawning biomass (corresponding to R0) B0 = g3_parameterized('spawn.B0', by_stock = by_stock), by_stock = TRUE ) g3a_spawn_recruitment_hockeystick( r0 = g3_parameterized('spawn.r0', by_stock = by_stock), blim = g3_parameterized('spawn.blim', value = 1, by_stock = by_stock), by_stock = TRUE ) g3a_spawn( stock, recruitment_f, proportion_f = 1, mortality_f = 0, weightloss_f = 0, weightloss_args = list(), output_stocks = list(), output_ratios = rep(1 / length(output_stocks), times = length(output_stocks)), mean_f = g3a_renewal_vonb_t0(by_stock = by_stock), stddev_f = g3_parameterized('rec.sd', value = 10, by_stock = by_stock), alpha_f = g3_parameterized('walpha', by_stock = wgt_by_stock), beta_f = g3_parameterized('wbeta', by_stock = wgt_by_stock), by_stock = TRUE, wgt_by_stock = TRUE, run_step = NULL, run_f = ~TRUE, run_at = g3_action_order$spawn, recruit_at = g3_action_order$renewal)
g3a_spawn_recruitment_fecundity( p0 = g3_parameterized('spawn.p0', value = 1, by_stock = by_stock), p1 = g3_parameterized('spawn.p1', value = 1, by_stock = by_stock), p2 = g3_parameterized('spawn.p2', value = 1, by_stock = by_stock), p3 = g3_parameterized('spawn.p3', value = 1, by_stock = by_stock), p4 = g3_parameterized('spawn.p4', value = 1, by_stock = by_stock), by_stock = TRUE ) g3a_spawn_recruitment_simplessb( mu = g3_parameterized('spawn.mu', by_stock = by_stock), by_stock = TRUE ) g3a_spawn_recruitment_ricker( mu = g3_parameterized('spawn.mu', by_stock = by_stock), lambda = g3_parameterized('spawn.lambda', by_stock = by_stock), by_stock = TRUE ) g3a_spawn_recruitment_bevertonholt( mu = g3_parameterized('spawn.mu', by_stock = by_stock), lambda = g3_parameterized('spawn.lambda', by_stock = by_stock), by_stock = TRUE ) g3a_spawn_recruitment_bevertonholt_ss3( # Steepness parameter h = g3_parameterized('spawn.h', lower = 0.1, upper = 1, value = 0.5, by_stock = by_stock ), # Recruitment deviates R = g3_parameterized('spawn.R', by_year = TRUE, exponentiate = TRUE, # Unfished equilibrium recruitment scale = "spawn.R0", by_stock = by_stock), # Unfished equilibrium spawning biomass (corresponding to R0) B0 = g3_parameterized('spawn.B0', by_stock = by_stock), by_stock = TRUE ) g3a_spawn_recruitment_hockeystick( r0 = g3_parameterized('spawn.r0', by_stock = by_stock), blim = g3_parameterized('spawn.blim', value = 1, by_stock = by_stock), by_stock = TRUE ) g3a_spawn( stock, recruitment_f, proportion_f = 1, mortality_f = 0, weightloss_f = 0, weightloss_args = list(), output_stocks = list(), output_ratios = rep(1 / length(output_stocks), times = length(output_stocks)), mean_f = g3a_renewal_vonb_t0(by_stock = by_stock), stddev_f = g3_parameterized('rec.sd', value = 10, by_stock = by_stock), alpha_f = g3_parameterized('walpha', by_stock = wgt_by_stock), beta_f = g3_parameterized('wbeta', by_stock = wgt_by_stock), by_stock = TRUE, wgt_by_stock = TRUE, run_step = NULL, run_f = ~TRUE, run_at = g3_action_order$spawn, recruit_at = g3_action_order$renewal)
p0 , p1 , p2 , p3 , p4
|
Substituted into |
mu , lambda , h , R , B0 , r0 , blim
|
Substituted into |
stock |
The mature |
recruitment_f |
A list of formula generated by one of the
|
proportion_f |
formula generated by one of the g3_suitability_* functions, describing the proportion of stock that will spawn at this timestep. |
mortality_f |
formula generated by one of the g3_suitability_* functions, describing the proportion of spawning stock that will die during spawning. |
weightloss_f |
formula generated by one of the g3_suitability_* functions, describing the overall weight loss during spawning. DEPRECATED: Use weightloss_args for new models. |
weightloss_args |
list of options to pass to |
output_stocks |
List of |
output_ratios |
Vector of proportions for how to distribute into output_stocks, summing to 1, default evenly spread. |
mean_f , stddev_f , alpha_f , beta_f
|
formula substituted into stock structure calculations, see g3a_renewal_normalparam for details. |
run_step |
Which step to perform renewal in, or |
run_f |
formula specifying a condition for running this action, default always runs. |
run_at |
Integer order that spawning actions will be run within model, see |
recruit_at |
Integer order that recruitment from spawning will be run within model, see |
by_stock , wgt_by_stock
|
Controls how parameters are grouped, see |
To restrict spawning to a particular step in a year, or a particular area, use run_f. For example:
cur_step == 1
Spawning will happen on first step of every year
cur_step == 1 && cur_year >= 1990
Spawning will happen on first step of every year after 1990
cur_step == 2 && area = 1
Spawning will happen on second step of every year, in the first area
The action will define the following stock instance variables for each given stock and output_stock:
Proportion of (stock) that are spawning in this spawning event
Numbers of (stock) that are spawning in this spawning event
Numbers of (output_stock) that will be produced in this spawning event
A pair of formula objects:
Number of parent stock
Weight of parent stock
Proportion of parent stock spawning, from proportion_f
Arguments provided to function
A pair of formula objects:
Number of parent stock
Weight of parent stock
Proportion of parent stock spawning, from proportion_f
Argument provided to function
A pair of formula objects:
Number of parent stock
Weight of parent stock
Proportion of parent stock spawning, from proportion_f
Argument provided to function
Argument provided to function
A pair of formula objects:
Number of parent stock
Weight of parent stock
Proportion of parent stock spawning, from proportion_f
Argument provided to function
Argument provided to function
A modified beverton-holt implementation from SS3 returning a pair of formula objects:
Number of parent stock
Weight of parent stock
Proportion of parent stock spawning, from proportion_f
Steepness parameter, by default provided by the srr_h
parameter
Unfished equilibrium recruitment, by default provided by the R0
parameter
Recruitment deviates, by default provided by the R
parameter table
Unfished equilibrium spawning biomass (corresponding to R0), by default provided by the B0
parameter
Argument provided to function
A pair of formula objects:
Number of parent stock
Weight of parent stock
Proportion of parent stock spawning, from proportion_f
Argument r0
provided to function
Argument blim
provided to function
NB: This formula is differentiable, despite using min()
in the
definition above.
An action (i.e. list of formula objects) that will, for the given stock...
Use proportion_f to calculate the total parent stock that will spawn
Use recruitment_f to derive the total newly spawned stock
Apply weightloss and mortality_f to the parent stock
... then, at recruitment stage ...
Recruit evenly into output_stocks, using mean_f, stddev_f, alpha_f, beta_f as-per g3a_renewal_normalparam
https://gadget-framework.github.io/gadget2/userguide/chap-stock.html#sec-stockspawn,
https://nmfs-ost.github.io/ss3-doc/SS330_User_Manual_release.html#beverton-holt,
g3a_naturalmortality
,
g3_stock
ling_imm <- g3_stock(c('ling', maturity = 'imm'), seq(20, 156, 4)) |> g3s_age(0, 10) ling_mat <- g3_stock(c('ling', maturity = 'mat'), seq(20, 156, 4)) |> g3s_age(3, 10) actions <- list( g3a_time(1990, 1994, c(6, 6)), g3a_initialconditions_normalcv(ling_imm), g3a_initialconditions_normalcv(ling_mat), g3a_age(ling_imm), g3a_age(ling_mat), g3a_spawn( # Spawn from ling_mat ling_mat, # Use Ricker Recruitment Function to calculate # of recruits from total biomass recruitment_f = g3a_spawn_recruitment_ricker(), # Proportion of ling_mat spawning exponential relationship based on length proportion_f = g3_suitability_exponentiall50( alpha = g3_parameterized("spawn.prop.alpha", value = 4, scale = -1), l50 = g3_parameterized("spawn.prop.l50", value = 60)), # Proportion of ling_mat dying during spawning linear relationship to length mortality_f = g3_suitability_straightline( alpha = g3_parameterized("spawn.mort.alpha"), beta = g3_parameterized("spawn.mort.beta")), # Weight of spawning ling_imm should reduce by a fixed absolute amount (see g3a_weightloss) weightloss_args = list( abs_loss = g3_parameterized("spawn.weightloss", value = 0.1) ), # Spawn into ling_imm output_stocks = list(ling_imm), # Spawning should happen on the first step of every year run_f = ~cur_step==1 ), NULL ) model_fn <- g3_to_r(c(actions, g3a_report_detail(actions), g3a_report_history(actions, "__spawningnum$|__offspringnum$") )) attr(model_fn, "parameter_template") |> # g3a_initialconditions_normalcv() g3_init_val("*.Linf", 50) |> g3_init_val("*.t0", -1.4) |> g3_init_val("*.walpha", 0.1) |> g3_init_val("*.wbeta", 1) |> # g3a_spawn_recruitment_ricker() g3_init_val("*.spawn.mu", 1e6) |> g3_init_val("*.spawn.lambda", 30) |> identity() -> params r <- attributes(model_fn(params)) colSums(r$dstart_ling_imm__num) colSums(r$dstart_ling_mat__wgt)
ling_imm <- g3_stock(c('ling', maturity = 'imm'), seq(20, 156, 4)) |> g3s_age(0, 10) ling_mat <- g3_stock(c('ling', maturity = 'mat'), seq(20, 156, 4)) |> g3s_age(3, 10) actions <- list( g3a_time(1990, 1994, c(6, 6)), g3a_initialconditions_normalcv(ling_imm), g3a_initialconditions_normalcv(ling_mat), g3a_age(ling_imm), g3a_age(ling_mat), g3a_spawn( # Spawn from ling_mat ling_mat, # Use Ricker Recruitment Function to calculate # of recruits from total biomass recruitment_f = g3a_spawn_recruitment_ricker(), # Proportion of ling_mat spawning exponential relationship based on length proportion_f = g3_suitability_exponentiall50( alpha = g3_parameterized("spawn.prop.alpha", value = 4, scale = -1), l50 = g3_parameterized("spawn.prop.l50", value = 60)), # Proportion of ling_mat dying during spawning linear relationship to length mortality_f = g3_suitability_straightline( alpha = g3_parameterized("spawn.mort.alpha"), beta = g3_parameterized("spawn.mort.beta")), # Weight of spawning ling_imm should reduce by a fixed absolute amount (see g3a_weightloss) weightloss_args = list( abs_loss = g3_parameterized("spawn.weightloss", value = 0.1) ), # Spawn into ling_imm output_stocks = list(ling_imm), # Spawning should happen on the first step of every year run_f = ~cur_step==1 ), NULL ) model_fn <- g3_to_r(c(actions, g3a_report_detail(actions), g3a_report_history(actions, "__spawningnum$|__offspringnum$") )) attr(model_fn, "parameter_template") |> # g3a_initialconditions_normalcv() g3_init_val("*.Linf", 50) |> g3_init_val("*.t0", -1.4) |> g3_init_val("*.walpha", 0.1) |> g3_init_val("*.wbeta", 1) |> # g3a_spawn_recruitment_ricker() g3_init_val("*.spawn.mu", 1e6) |> g3_init_val("*.spawn.lambda", 30) |> identity() -> params r <- attributes(model_fn(params)) colSums(r$dstart_ling_imm__num) colSums(r$dstart_ling_mat__wgt)
A simple production model can be used in place of a set of gadget stock dynamics actions.
g3a_spmodel_logistic( r = g3_parameterized("spm_r", lower = 0.01, upper = 1, value = 0.5, by_stock = by_stock), p = g3_parameterized("spm_p", lower = 0.01, upper = 10, value = 1, by_stock = by_stock), K = g3_parameterized("spm_K", lower = 100, upper = 1e6, value = 1000, by_stock = by_stock), by_stock = TRUE) g3a_spmodel( stock, spm_num = g3a_spmodel_logistic(), spm_num_init = g3_parameterized("spm_n0", by_stock = TRUE), spm_wgt = 1, run_f = TRUE, run_at = g3_action_order$initial)
g3a_spmodel_logistic( r = g3_parameterized("spm_r", lower = 0.01, upper = 1, value = 0.5, by_stock = by_stock), p = g3_parameterized("spm_p", lower = 0.01, upper = 10, value = 1, by_stock = by_stock), K = g3_parameterized("spm_K", lower = 100, upper = 1e6, value = 1000, by_stock = by_stock), by_stock = TRUE) g3a_spmodel( stock, spm_num = g3a_spmodel_logistic(), spm_num_init = g3_parameterized("spm_n0", by_stock = TRUE), spm_wgt = 1, run_f = TRUE, run_at = g3_action_order$initial)
r , p , K
|
Parameters for the logistic model, see value section. |
by_stock |
Change the default parameterisation (e.g. to be by 'species'), see |
stock |
|
spm_num |
formula to calculate the relative change in abundance, one of the |
spm_num_init |
Starting point for stock abundance. |
spm_wgt |
formula to calculate the mean weight, if "1", then abundance in numbers == total biomass. |
run_f |
formula specifying a condition for running this action, default always runs. |
run_at |
Integer order that actions will be run within model, see |
The actions will define the following variables in your model, which could be reported with g3a_report_history
:
Numbers added to the abundance of stock
Note that the input stock should not have g3s_age
,
if the stock was broken up by age the model would quickly not make sense.
Returns a formula for use as spm_num:
r argument, by default the (stock)_spm_r
model parameter
p argument, by default the (stock)_spm_p
model parameter
K argument, by default the (stock)_spm_K
model parameter
G3 action that maintains stock abundance / mean weight according to simple production model
# NB: Stock only has one length group, 30:40. So the stocks midlen is 35 stock_a <- g3_stock(c("stock", "a"), c(30, 40), open_ended = FALSE) stocks <- list(stock_a) fleet_a <- g3_fleet(c('fleet', "a")) actions <- list( g3a_time(2000, 2010, step_lengths = c(6,6), project_years = 0), g3a_spmodel( stock_a ), g3a_predate( fleet_a, stocks, suitabilities = 1, catchability_f = g3a_predate_catchability_linearfleet( g3_parameterized("effort", value = 1e-1, by_predator = TRUE) )), # NB: Dummy parameter so model will compile in TMB ~{nll <- nll + g3_param("x", value = 0, optimise = TRUE)} ) actions <- c(actions, list( # NB: Late reporting for abundance g3a_report_history(actions, "__num$|__wgt$", out_prefix="dend_"), g3a_report_detail(actions) )) model_fn <- g3_to_r(actions) attr(model_fn, 'parameter_template') |> # Surplus production model parameters g3_init_val("*.spm_n0", 1e4) |> g3_init_val("*.spm_r", 0.1) |> g3_init_val("*.spm_p", 0.01) |> g3_init_val("*.spm_K", 1e8, lower = 0, upper = 1e20) |> identity() -> params.in r <- attributes(model_fn(params.in)) barplot(r$dend_stock_a__num, las = 2) barplot(r$detail_stock_a__renewalnum, las = 2)
# NB: Stock only has one length group, 30:40. So the stocks midlen is 35 stock_a <- g3_stock(c("stock", "a"), c(30, 40), open_ended = FALSE) stocks <- list(stock_a) fleet_a <- g3_fleet(c('fleet', "a")) actions <- list( g3a_time(2000, 2010, step_lengths = c(6,6), project_years = 0), g3a_spmodel( stock_a ), g3a_predate( fleet_a, stocks, suitabilities = 1, catchability_f = g3a_predate_catchability_linearfleet( g3_parameterized("effort", value = 1e-1, by_predator = TRUE) )), # NB: Dummy parameter so model will compile in TMB ~{nll <- nll + g3_param("x", value = 0, optimise = TRUE)} ) actions <- c(actions, list( # NB: Late reporting for abundance g3a_report_history(actions, "__num$|__wgt$", out_prefix="dend_"), g3a_report_detail(actions) )) model_fn <- g3_to_r(actions) attr(model_fn, 'parameter_template') |> # Surplus production model parameters g3_init_val("*.spm_n0", 1e4) |> g3_init_val("*.spm_r", 0.1) |> g3_init_val("*.spm_p", 0.01) |> g3_init_val("*.spm_K", 1e8, lower = 0, upper = 1e20) |> identity() -> params.in r <- attributes(model_fn(params.in)) barplot(r$dend_stock_a__num, las = 2) barplot(r$detail_stock_a__renewalnum, las = 2)
Add tag-release to a g3 model
g3a_predate_tagrelease( fleet_stock, prey_stocks, suitabilities, catchability_f, output_tag_f, mortality_f = 0, run_f = ~TRUE, run_at = g3_action_order$predate, ...) g3a_tag_shedding(stocks, tagshed_f, run_f = ~TRUE, run_at = g3_action_order$straying)
g3a_predate_tagrelease( fleet_stock, prey_stocks, suitabilities, catchability_f, output_tag_f, mortality_f = 0, run_f = ~TRUE, run_at = g3_action_order$predate, ...) g3a_tag_shedding(stocks, tagshed_f, run_f = ~TRUE, run_at = g3_action_order$straying)
fleet_stock |
Tagging fleet, see g3a_predate_fleet |
prey_stocks |
Stocks fleet harvests, see g3a_predate_fleet |
suitabilities |
|
catchability_f |
|
output_tag_f |
formula specifying which numeric tag (see g3s_tag) stock will be released into. Implemented with a g3_timeareadata table, e.g. |
mortality_f |
formula generated by one of the g3_suitability_* functions, describing the proportion of tagged stock that will die during tagging. |
stocks |
Stocks that will shed tags |
tagshed_f |
formula for proportion that will shed tags at this point |
run_f |
formula specifying a condition for running this action, default always runs. |
run_at |
Integer order that spawning actions will be run within model, see |
... |
Any further options for g3a_predate_fleet |
An action (i.e. list of formula objects) that will...
Harvest as-per g3a_predate_fleet
Use mortality_f to apply tagging mortality to harvested stock
Use output_tag_f to decide what tag should be applied to harvested stock
Put harvested stock back into general circulation
An action (i.e. list of formula objects) that will...
For each stock, move the proportion tagshed_f back to the "untagged" tag
tags <- c('H1-00', 'H1-01') tags <- structure(seq_along(tags), names = tags) prey_a <- g3_stock('prey_a', seq(1, 10)) %>% g3s_tag(tags) fleet_a <- g3_fleet('fleet_a') actions <- list( # NB: If g3_tag() is used in the stock, initialconditions/renewal # will only renew into tag == 0 (i.e. untagged) g3a_predate_tagrelease( # Setup as-per g3a_predate_fleet fleet_a, list(prey_a), suitabilities = list(prey_a = 1), catchability_f = g3a_predate_catchability_numberfleet(~100), # Optional tag mortality suitability mortality_f = g3_suitability_straightline( g3_parameterized('mort_alpha'), g3_parameterized('mort_beta')), # Formula to decide which tag to output into, generate table # with one tag per year output_tag_f = g3_timeareadata('fleet_a_tags', data.frame( year = 2000:2001, tag = tags[c('H1-00', 'H1-01')], stringsAsFactors = FALSE), value_field = "tag"), # Experiment only happens in spring run_f = ~cur_step == 2), g3a_tag_shedding( list(prey_a), # i.e. 0.125 will loose their tag each step tagshed_f = log(8)))
tags <- c('H1-00', 'H1-01') tags <- structure(seq_along(tags), names = tags) prey_a <- g3_stock('prey_a', seq(1, 10)) %>% g3s_tag(tags) fleet_a <- g3_fleet('fleet_a') actions <- list( # NB: If g3_tag() is used in the stock, initialconditions/renewal # will only renew into tag == 0 (i.e. untagged) g3a_predate_tagrelease( # Setup as-per g3a_predate_fleet fleet_a, list(prey_a), suitabilities = list(prey_a = 1), catchability_f = g3a_predate_catchability_numberfleet(~100), # Optional tag mortality suitability mortality_f = g3_suitability_straightline( g3_parameterized('mort_alpha'), g3_parameterized('mort_beta')), # Formula to decide which tag to output into, generate table # with one tag per year output_tag_f = g3_timeareadata('fleet_a_tags', data.frame( year = 2000:2001, tag = tags[c('H1-00', 'H1-01')], stringsAsFactors = FALSE), value_field = "tag"), # Experiment only happens in spring run_f = ~cur_step == 2), g3a_tag_shedding( list(prey_a), # i.e. 0.125 will loose their tag each step tagshed_f = log(8)))
Add timekeeping to a g3 model
g3a_time( start_year, end_year, step_lengths = c(12), final_year_steps = quote( length(step_lengths) ), project_years = g3_parameterized("project_years", value = 0, optimise = FALSE), retro_years = g3_parameterized("retro_years", value = 0, optimise = FALSE), run_at = g3_action_order$initial, run_stop_at = g3_action_order$time)
g3a_time( start_year, end_year, step_lengths = c(12), final_year_steps = quote( length(step_lengths) ), project_years = g3_parameterized("project_years", value = 0, optimise = FALSE), retro_years = g3_parameterized("retro_years", value = 0, optimise = FALSE), run_at = g3_action_order$initial, run_stop_at = g3_action_order$time)
start_year |
Year model run will start. |
end_year |
After this year, model run will stop. |
step_lengths |
Either an MFDB time grouping, e.g. |
final_year_steps |
Number of steps of final year to include. Either as an integer or quoted code, in which case it will be calcuated when the model runs. For example:
|
project_years |
Number of years to continue running after the "end" of the model. Must be Defaults to an unoptimized |
retro_years |
Adjust end_year to finish model early. Must be The true end year of the model will be Defaults to an unoptimized |
run_at , run_stop_at
|
Integer order that actions will be run within model, see |
The actions will define the following variables in your model:
Current iteration of model, starts at 0 and increments until finished
Current step within individual year
Proportion of year this step contains, e.g. quarterly = 3/12
Current year
TRUE iff this is the final step of the year
TRUE iff we are currently projecting past end_year
Total # of iterations (including projection) before model stops
Total # of years (including projection) before model stops
An action (i.e. list of formula objects) that will...
Define cur_* variables listed above
If we've reached the end of the model, return nll
# Run model 2000..2004, in quarterly steps time_action <- g3a_time( start_year = 2000, end_year = 2004, c(3, 3, 3, 3))
# Run model 2000..2004, in quarterly steps time_action <- g3a_time( start_year = 2000, end_year = 2004, c(3, 3, 3, 3))
Add weight loss events to a g3 model
g3a_weightloss( stock, rel_loss = NULL, abs_loss = NULL, min_weight = 1e-7, apply_to_pop = quote( stock__num ), run_f = TRUE, run_step = NULL, run_at = g3_action_order$naturalmortality )
g3a_weightloss( stock, rel_loss = NULL, abs_loss = NULL, min_weight = 1e-7, apply_to_pop = quote( stock__num ), run_f = TRUE, run_step = NULL, run_at = g3_action_order$naturalmortality )
stock |
The |
rel_loss |
Fractional weight loss, |
abs_loss |
Absolute weight loss, applied after rel_loss.
|
min_weight |
Minimum weight below which weight cannot fall further. Should be more than zero to avoid models returning NaN. |
apply_to_pop |
Stock instance weightloss applies to, by default applies to whole stock.
Used by |
run_step |
Which step to perform renewal in, or |
run_f |
formula specifying a condition for running this action, default always runs. |
run_at |
Integer order that spawning actions will be run within model, see |
An action (i.e. list of formula objects) that will, for the given stock...
Apply rel_loss and abs_loss to the parent stock
g3a_naturalmortality
,
g3a_spawn
,
g3_stock
st <- g3_stock('st', 10:20) |> g3s_age(3, 5) actions <- list( g3a_time(2000, 2005, step_lengths = c(3, 3, 3, 3)), g3a_initialconditions(st, # Set initial abundance & weight based on age ~1e5 + 0 * st__midlen, ~1000 * age + 0 * st__midlen ), g3a_age(st), g3a_weightloss(st, # 20% of body weight should be shed in autumn rel_loss = g3_parameterized("rel_loss_autumn", by_stock = TRUE, value = 0.2), run_step = 4 ), g3a_weightloss(st, # Remove "10" from body weight, with a minimum based on length abs_loss = g3_parameterized("absloss_length_mw", by_stock = TRUE, value = 10), min_weight = g3_formula( wmin.a * st__midlen^wmin.b, wmin.a = g3_parameterized("wmin.a", by_stock = TRUE, value = 10), wmin.b = g3_parameterized("wmin.a", by_stock = TRUE, value = 2) )), NULL) model_fn <- g3_to_r(c(actions, g3a_report_detail(actions))) r <- model_fn(attr(model_fn, 'parameter_template')) g3_array_agg(attr(r, "dstart_st__wgt"), c("age", "time")) ## See g3a_spawn for an example of weightloss in spawning
st <- g3_stock('st', 10:20) |> g3s_age(3, 5) actions <- list( g3a_time(2000, 2005, step_lengths = c(3, 3, 3, 3)), g3a_initialconditions(st, # Set initial abundance & weight based on age ~1e5 + 0 * st__midlen, ~1000 * age + 0 * st__midlen ), g3a_age(st), g3a_weightloss(st, # 20% of body weight should be shed in autumn rel_loss = g3_parameterized("rel_loss_autumn", by_stock = TRUE, value = 0.2), run_step = 4 ), g3a_weightloss(st, # Remove "10" from body weight, with a minimum based on length abs_loss = g3_parameterized("absloss_length_mw", by_stock = TRUE, value = 10), min_weight = g3_formula( wmin.a * st__midlen^wmin.b, wmin.a = g3_parameterized("wmin.a", by_stock = TRUE, value = 10), wmin.b = g3_parameterized("wmin.a", by_stock = TRUE, value = 2) )), NULL) model_fn <- g3_to_r(c(actions, g3a_report_detail(actions))) r <- model_fn(attr(model_fn, 'parameter_template')) g3_array_agg(attr(r, "dstart_st__wgt"), c("age", "time")) ## See g3a_spawn for an example of weightloss in spawning
Tools to make munging array reports easier
g3_array_agg( ar, margins = NULL, agg = sum, opt_time_split = !("time" %in% margins || "time" %in% ...names()), opt_length_midlen = FALSE, ... )
g3_array_agg( ar, margins = NULL, agg = sum, opt_time_split = !("time" %in% margins || "time" %in% ...names()), opt_length_midlen = FALSE, ... )
ar |
Input array, e.g. |
margins |
dimension names to include in the final array, e.g. |
agg |
Function to use when aggregating |
opt_time_split |
Boolean, should we split up "time" into separate "year" & "step" dimensions? |
opt_length_midlen |
Boolean, should we convert "length" |
... |
Filters to apply to any dimension, including "year" / "step" if opt_time_split is TRUE. e.g. |
g3_array_agg
allows you to both filter & aggregate an array at the same time.
Specifying a filter in ... is simplfied in comparison to a regular R subset:
You can give the dimensions in any order
Values are always interpreted, age = 3
will be interpreted as "age3"
, not the third age.
For particular dimensions we have extra helpers:
Numeric ages e.g. age = 5
are converted to "age5", as generated by gadget3
Numeric lengths will pick a value within groups, e.g. with lengths "10:20", "20:30", length = 15
will pick the smaller lengthgroup
An array, filtered by ... and aggregated by margins
# Generate an array to test with dn <- list( length = c("50:60", "60:70", "70:Inf"), age = paste0("age", 0:5), time = paste0(rep(1990:1996, each = 2), c("-01", "-02")) ) ar <- array( seq_len(prod(sapply(dn, length))), dim = sapply(dn, length), dimnames = dn) ar[,,"1994-02", drop = FALSE] # Generate by-year report for ages 2..4 g3_array_agg(ar, c('age', 'year'), age = 2:4) # ...for only step 1 g3_array_agg(ar, c('age', 'year'), age = 2:4, step = 1) # Report on smallest length group, for each timestep g3_array_agg(ar, c('length', 'time'), length = 55) # Use midlen as the dimension name g3_array_agg(ar, c('length', 'time'), length = 55, opt_length_midlen = TRUE)
# Generate an array to test with dn <- list( length = c("50:60", "60:70", "70:Inf"), age = paste0("age", 0:5), time = paste0(rep(1990:1996, each = 2), c("-01", "-02")) ) ar <- array( seq_len(prod(sapply(dn, length))), dim = sapply(dn, length), dimnames = dn) ar[,,"1994-02", drop = FALSE] # Generate by-year report for ages 2..4 g3_array_agg(ar, c('age', 'year'), age = 2:4) # ...for only step 1 g3_array_agg(ar, c('age', 'year'), age = 2:4, step = 1) # Report on smallest length group, for each timestep g3_array_agg(ar, c('length', 'time'), length = 55) # Use midlen as the dimension name g3_array_agg(ar, c('length', 'time'), length = 55, opt_length_midlen = TRUE)
Differentiable helper functions available to any gadget3 model
These functions are part of g3_env
is the top-level environment that any gadget3 model uses.
dif_pmax(a, b, scale)
Returns the maximum of a & b. If a is a vector/array, then all members of a are compared against b. If b is also a vector, then all members of a are compared against the matching member of b (repeating b if necessary).
scale influences the sharpness of inflection points, should be about 1e5, depending on ranges of input values.
dif_pmin(a, b, scale)
Returns the minimum of a & b, otherwise works like dif_pmax
.
scale influences the sharpness of inflection points, should be about 1e5, depending on ranges of input values.
dif_pminmax(a, lower, upper, scale)
Returns values of a bounded between lower & upper.
scale influences the sharpness of inflection points at lower & upper, should be about 1e5, depending on ranges of input values.
## dif_pmax g3_eval(quote( dif_pmax(1:10, 5, 1e5) )) g3_eval(quote( dif_pmax(1:10, c(4, 7), 1e5) )) g3_eval(quote( dif_pmax(array(1:9, dim = c(3,3)), c(3,6,8), 1e5) )) ## dif_pmin g3_eval(quote( dif_pmin(1:10, 5, 1e5) )) g3_eval(quote( dif_pmin(1:10, c(4, 7), 1e5) )) ## dif_pminmax g3_eval(quote( dif_pminmax(1:10, 3, 6, 1e5) ))
## dif_pmax g3_eval(quote( dif_pmax(1:10, 5, 1e5) )) g3_eval(quote( dif_pmax(1:10, c(4, 7), 1e5) )) g3_eval(quote( dif_pmax(array(1:9, dim = c(3,3)), c(3,6,8), 1e5) )) ## dif_pmin g3_eval(quote( dif_pmin(1:10, 5, 1e5) )) g3_eval(quote( dif_pmin(1:10, c(4, 7), 1e5) )) ## dif_pminmax g3_eval(quote( dif_pminmax(1:10, 3, 6, 1e5) ))
Evaluate G3 formulas / code outside a model
g3_eval(f, ...)
g3_eval(f, ...)
f |
|
... |
Named items to add to the formula's environment, or a single list / environment to use. |
Allows snippets of gadget3 code to be run outside a model. This could
be done with regular eval
, however, g3_eval
does a number of things first:
The global g3_env
is in the environment, so functions such as avoid_zero
can be used
If substituting a g3_stock
, all definitions such as stock__minlen
will also be substituted
g3_param('x')
will pull param.x
from the environment
Result of evaluating f.
# Evaluate suitiability function for given stocks g3_eval( g3_suitability_andersen(0,1,2,3,4), predator_length = 100, stock = g3_stock('prey', 1:10)) # Parameters can be filled in with "param." items in environment g3_eval(quote( g3_param('x') ), param.x = 88) g3_eval( g3_parameterized('lln.alpha', by_stock = TRUE, value = 99), stock = g3_stock("fish", 1:10), param.fish.lln.alpha = 123) # Graph gadget3's built-in logspace_add() if (interactive()) { curve(g3_eval(quote( logspace_add(a, 10) ), a = x), 0, 50) }
# Evaluate suitiability function for given stocks g3_eval( g3_suitability_andersen(0,1,2,3,4), predator_length = 100, stock = g3_stock('prey', 1:10)) # Parameters can be filled in with "param." items in environment g3_eval(quote( g3_param('x') ), param.x = 88) g3_eval( g3_parameterized('lln.alpha', by_stock = TRUE, value = 99), stock = g3_stock("fish", 1:10), param.fish.lln.alpha = 123) # Graph gadget3's built-in logspace_add() if (interactive()) { curve(g3_eval(quote( logspace_add(a, 10) ), a = x), 0, 50) }
Tools to create R formulas
g3_formula(code, ...)
g3_formula(code, ...)
code |
Unevaluated code to be turned into a formula |
... |
Named items to add to the formula's environment, or a single list / environment to use. |
When using ~
, the local environment is attached to the code.
This can leak unwanted variables into a model. This allows you to avoid
the problem without resorting to local.
A formula object, with environment created from .... Can then be used anywhere in gadget3 that accepts a formula.
# g3_formula is identical to defining a formula within local(): stopifnot(all.equal( g3_formula(x + 1, z = 44), local({ z = 44; ~x + 1 }) )) # If the code is destined for CRAN, you need to quote() to avoid check errors: stopifnot(all.equal( g3_formula(quote( x + 1 ), z = 44), local({ z = 44; ~x + 1 }) ))
# g3_formula is identical to defining a formula within local(): stopifnot(all.equal( g3_formula(x + 1, z = 44), local({ z = 44; ~x + 1 }) )) # If the code is destined for CRAN, you need to quote() to avoid check errors: stopifnot(all.equal( g3_formula(quote( x + 1 ), z = 44), local({ z = 44; ~x + 1 }) ))
Helper for setting initial parameter value
g3_init_val( param_template, name_spec, value = NULL, spread = NULL, lower = if (!is.null(spread)) min(value * (1-spread), value * (1+spread)), upper = if (!is.null(spread)) max(value * (1-spread), value * (1+spread)), optimise = !is.null(lower) & !is.null(upper), parscale = if (is.null(lower) || is.null(upper)) NULL else 'auto', random = NULL, auto_exponentiate = TRUE)
g3_init_val( param_template, name_spec, value = NULL, spread = NULL, lower = if (!is.null(spread)) min(value * (1-spread), value * (1+spread)), upper = if (!is.null(spread)) max(value * (1-spread), value * (1+spread)), optimise = !is.null(lower) & !is.null(upper), parscale = if (is.null(lower) || is.null(upper)) NULL else 'auto', random = NULL, auto_exponentiate = TRUE)
param_template |
|
name_spec |
A glob-like string to match parameter names, see Details |
value |
Numeric value / vector of values to set for value / 'value' column in template. Original value left if NULL |
spread |
Shortcut for setting lower & upper. |
lower |
Numeric value / vector of values to set for 'lower' column in template. Original value left if NULL |
upper |
Numeric value / vector of values to set for 'upper' column in template. Original value left if NULL |
optimise |
Boolean value to set for 'optimise' column in template. Default is true iff both lower and upper are non-NULL. Original value left if NULL |
parscale |
Numeric value / vector of values to set for 'parscale' column in template.
Default ( |
random |
Boolean value to set for 'random' column in template. Original value left if NULL |
auto_exponentiate |
If TRUE, will implicitly match parameters ending with "_exp",
and if this is the case |
name_spec is a glob (or wildcard) matching parameters.
It is a string separated by .
, where each part can be:
A wildcard matching anything (*
), or a matching anything with a prefix, e.g. m*
A wildcard matching any number (#
), or a matching a number with a prefix, e.g. age*
A range of numbers, e.g. [1979-1984]
A choice of options can be separated with |
, e.g. init|rec
or [1979-1984]|[2000-2003]
A new parameter template list/table containing modifications
# A parameter template, would already be got via. attr(g3_to_tmb(...), "parameter_template") pt <- data.frame( switch = c( paste0('fish.init.', 1:9), paste0('fish.rec.', 1990:2000), 'fish.M'), value = NA, lower = NA, upper = NA, parscale = NA, optimise = FALSE, random = FALSE) # Set all fish.init.# parameters to optimise pt <- g3_init_val(pt, 'fish.init.#', 4, spread = 8) # Set a fixed value for any .M pt <- g3_init_val(pt, '*.M', value = 0.3, optimise = FALSE) # Set a fixed value for a range of recruitment years, optimise the rest pt |> g3_init_val('*.rec.#', value = 4, lower = 0, upper = 10) |> g3_init_val('*.rec.[1993-1996]', value = 0, optimise = FALSE) |> identity() -> pt pt
# A parameter template, would already be got via. attr(g3_to_tmb(...), "parameter_template") pt <- data.frame( switch = c( paste0('fish.init.', 1:9), paste0('fish.rec.', 1990:2000), 'fish.M'), value = NA, lower = NA, upper = NA, parscale = NA, optimise = FALSE, random = FALSE) # Set all fish.init.# parameters to optimise pt <- g3_init_val(pt, 'fish.init.#', 4, spread = 8) # Set a fixed value for any .M pt <- g3_init_val(pt, '*.M', value = 0.3, optimise = FALSE) # Set a fixed value for a range of recruitment years, optimise the rest pt |> g3_init_val('*.rec.#', value = 4, lower = 0, upper = 10) |> g3_init_val('*.rec.[1993-1996]', value = 0, optimise = FALSE) |> identity() -> pt pt
Additional meta-functions available for use in G3 formula.
Whilst used as functions, these functions alter the code output of the model, rather than appearing directly.
Adds a - 1
to the supplied expression, but only in C++ (which has 0-based
indexes). Under R the expression is passed through unchanged.
Note: This is generally for internal use, as [[
will do this
automatically for you.
For example, g3_idx(a)
will be replaced with a
in R output
and a - 1
in C++ output.
Reference a scalar parameter by name. Arguments:
Variable name for parameter. Required
Initial value in model parameter_template. Default 0
Initial optimise setting in parameter_template. Default TRUE
Initial random setting in parameter_template. Default FALSE
Initial lower setting in parameter_template. Default NA
Initial upper setting in parameter_template. Default NA
For example, g3_param("ling.Linf")
will register a scalar parameter
called ling.Linf, available in the model parameter template, and be
replaced by a reference to that parameter.
g3_param("ling.Linf")
can be used multiple times, to refer to the same
value.
Reference a vector parameter by name. Arguments:
Variable name for parameter. Required
Initial value for use in model paramter_template. Default 0
Same as g3_param
, but the parameter will be expected to be a vector.
You can then dereference with [[
.
For example, g3_param_vector("lingimm.M")[[age - 3 + 1]]
.
Reference a lookup-table of parameters.
Variable name for parameter. Required
A data.frame, one column for each variable to check, one row for possible values. Required
Initial value for use in model parameter_template. Default 0
Initial optimise setting in parameter_template. Default TRUE
Initial random setting in parameter_template. Default FALSE
Initial lower setting in parameter_template. Default NA
Initial upper setting in parameter_template. Default NA
Value to return when outside of table bounds. Default NaN with warning if a value is missing
This is similar to providing a vector, but can use values in the model to provide bounds-checking.
The function takes 2 arguments, a prefix for the generated parameters, and a
data.frame of variables to possible values. expand.grid
can be
used to produce a cross product of all provided variables.
Note: The variables referenced will need to be integer variables, most
likely iteration variables such as cur_year
, age
,
area
...
For example, the following: g3_param_table('lingimm.M', expand.grid(age = seq(ling_imm__minage,
ling_imm__maxage)))
will generate parameters
lingimm.M.3..lingimm.M.10, assuming that ling_imm has ages 3..10.
The call to g3_param_table
will be replaced with
param[[paste("lingimm.M", age, sep = ".")]]
, or equivalent code
in C++.
g3_with(var1 := val1, var2 := val2, { x <- val1 * val2 })
is equivalent to
local({var1 <- val1, var2 <- val2, { x <<- val1 * val2 } })
However, we don't make a new environment for the code block in R, only in C++.
Add a liklihood penalty for parameters leaving the bounds set in parameter_template
g3l_bounds_penalty( actions_or_parameter_template, weight = 1, run_at = g3_action_order$likelihood)
g3l_bounds_penalty( actions_or_parameter_template, weight = 1, run_at = g3_action_order$likelihood)
actions_or_parameter_template |
Either: A list of actions, to extract parameters from and to add bounds to. A parameter template generated by |
weight |
Weighting applied to this likelihood component. |
run_at |
Integer order that actions will be run within model, see |
Whilst lower/upper can be passed to optim
, not all methods can use them.
Adding g3l_bounds_penalty
OTOH can be used with any method.
An action (i.e. list of formula objects) that will...
If a actions list is supplied, add a large number to likelihood when any parameter is outside bounds.
Bounds are updated whenever g3_tmb_adfun
is run.
If a parameter_template is supplied, add a large number to likelihood when outside the bounds in the template. The bounds are baked into the model at this point.
anch <- g3_stock('anch', seq(20, 156, 4)) %>% g3s_age(3, 10) actions <- list( g3a_time(1990, 1994), g3a_growmature(anch, g3a_grow_impl_bbinom( maxlengthgroupgrowth = 38L)), g3a_naturalmortality(anch), g3a_initialconditions_normalparam(anch), g3a_renewal_normalparam(anch, run_step = NULL), g3a_age(anch), NULL) # Generate code with bounds added model_code <- g3_to_tmb(c(actions, list(g3l_bounds_penalty(actions)))) attr(model_code, "parameter_template") %>% # Set lower / upper bounds for initial conditions g3_init_val("*.init.#", 10, lower = 0.001, upper = 200) %>% identity() -> params.in # The objective function produced by g3_tmb_adfun() will honour the bounds # above, without having to pass them to stats::optim()
anch <- g3_stock('anch', seq(20, 156, 4)) %>% g3s_age(3, 10) actions <- list( g3a_time(1990, 1994), g3a_growmature(anch, g3a_grow_impl_bbinom( maxlengthgroupgrowth = 38L)), g3a_naturalmortality(anch), g3a_initialconditions_normalparam(anch), g3a_renewal_normalparam(anch, run_step = NULL), g3a_age(anch), NULL) # Generate code with bounds added model_code <- g3_to_tmb(c(actions, list(g3l_bounds_penalty(actions)))) attr(model_code, "parameter_template") %>% # Set lower / upper bounds for initial conditions g3_init_val("*.init.#", 10, lower = 0.001, upper = 200) %>% identity() -> params.in # The objective function produced by g3_tmb_adfun() will honour the bounds # above, without having to pass them to stats::optim()
Gather nll in a g3 model
g3l_distribution_sumofsquares( over = c('area', 'predator', 'predator_tag', 'predator_age', 'predator_length')) g3l_distribution_multinomial(epsilon = 10) g3l_distribution_multivariate(rho_f, sigma_f, over = c("area")) g3l_distribution_surveyindices_log(alpha = NULL, beta = 1) g3l_distribution_surveyindices_linear(alpha = NULL, beta = 1) g3l_distribution_sumofsquaredlogratios(epsilon = 10) g3l_abundancedistribution( nll_name, obs_data, fleets = list(), stocks, function_f, predators = list(), transform_fs = list(), missing_val = 0, area_group = NULL, report = FALSE, nll_breakdown = FALSE, weight = g3_parameterized(paste0(nll_name, "_weight"), optimise = FALSE, value = 1), run_at = g3_action_order$likelihood) g3l_catchdistribution( nll_name, obs_data, fleets = list(), stocks, function_f, predators = list(), transform_fs = list(), missing_val = 0, area_group = NULL, report = FALSE, nll_breakdown = FALSE, weight = g3_parameterized(paste0(nll_name, "_weight"), optimise = FALSE, value = 1), run_at = g3_action_order$likelihood) g3_distribution_preview( obs_data, predators = list(), fleets = list(), stocks = list(), area_group = NULL)
g3l_distribution_sumofsquares( over = c('area', 'predator', 'predator_tag', 'predator_age', 'predator_length')) g3l_distribution_multinomial(epsilon = 10) g3l_distribution_multivariate(rho_f, sigma_f, over = c("area")) g3l_distribution_surveyindices_log(alpha = NULL, beta = 1) g3l_distribution_surveyindices_linear(alpha = NULL, beta = 1) g3l_distribution_sumofsquaredlogratios(epsilon = 10) g3l_abundancedistribution( nll_name, obs_data, fleets = list(), stocks, function_f, predators = list(), transform_fs = list(), missing_val = 0, area_group = NULL, report = FALSE, nll_breakdown = FALSE, weight = g3_parameterized(paste0(nll_name, "_weight"), optimise = FALSE, value = 1), run_at = g3_action_order$likelihood) g3l_catchdistribution( nll_name, obs_data, fleets = list(), stocks, function_f, predators = list(), transform_fs = list(), missing_val = 0, area_group = NULL, report = FALSE, nll_breakdown = FALSE, weight = g3_parameterized(paste0(nll_name, "_weight"), optimise = FALSE, value = 1), run_at = g3_action_order$likelihood) g3_distribution_preview( obs_data, predators = list(), fleets = list(), stocks = list(), area_group = NULL)
over |
When comparing proportions of lengthgroups, specifies the dimensions that define the total. For example the default "area" means the proprtion of the current lengthgroup to all individuals in that area.
Note that any unknown dimensions will be ignored; for example a fleet does not have a tag/age/length, so only area will have an effect here. |
rho_f , sigma_f
|
formula substituted into multivariate calcuations, see below. |
epsilon |
Value to be used whenever the calculated probability is very unlikely. Default 10. |
alpha |
formula substituted into surveyindices calcuations to fix intercept of linear regression, or NULL if not fixed. See below. |
beta |
formula substituted into surveyindices calcuations to fix slope of linear regression, or NULL if not fixed. See below. |
nll_name |
Character string, used to define the variable name for obsstock and modelstock. |
obs_data |
Data.frame of observation data, for example the results of mfdb_sample_count. Should at least have a year column, and a length or weight column. For more information, see "obs_data and data aggregation" below. |
fleets , predators
|
A list of |
stocks |
A list of |
function_f |
A formula to compare obsstock__x to modelstock__x and generate nll, defined by one of the g3l_distribution_* functions. This will be adapted to compare either number (modelstock__num) or weight (modelstock__wgt) depending on what columns obs_data has. |
transform_fs |
A list of dimension names to either formula objects or list of stock names to formula objects (where the transform differs between stocks). See examples. |
missing_val |
Where there are missing values in the incoming data, value to replace them with. |
area_group |
mfdb_group or list mapping area names used in obs_data to integer model areas, see "obs_data and data aggregation" below. |
report |
If TRUE, add model and observation arrays to the model report, called
|
nll_breakdown |
Should the nll report be broken down by time? |
weight |
Weighting applied to this likelihood component. Default is a |
run_at |
Integer order that actions will be run within model, see |
The actions will define the following variables in your model:
A g3_stock
instance that contains all observations in an array
A g3_stock
instance that groups in an identical fashion to obsstock,
that will be filled with the model's predicted values
The model report will contain nll_cdist_nll_name__num and/or nll_cdist_nll_name__wgt, depending on
the columns in obs_data (a number column will compare by individuals, and produce a corresponding num report).
If nll_breakdown is TRUE
, this will be an array with one entry per timestep.
g3l_abundancedistribution compares abundance of stocks, g3l_catchdistribution compares fleet catch. Thus providing fleets is mandatory for g3l_catchdistribution, and an error for g3l_abundancedistribution.
The obs_data data.frame, as well as providing the observation data to compare the model data against, controls the grouping of model data to compare to the observation data, by inspecting the MFDB column attributes produced by e.g. mfdb_sample_count.
Metadata columns describe the observation datapoint in that row. The columns should be from this list:
Required. Year for the data point. Gaps in years will result in no comparison for that year
Optional. If there is no step column, then the data is assumed to be yearly, and the model data for all timesteps will be summed before comparing.
Model timestep for the data point. Gaps in steps will result in no comparison for that year/step.
Optional. If missing all lengthgroups in the model will be summed to compare to the data.
The column can be a factor, as generated by cut()
, e.g
cut(raw_length, c(seq(0, 50, by = 10), Inf), right = FALSE)
for an open-ended upper group.
The column can be character strings also formatted as factors as above. The column entries are assumed to be sorted in order and converted back to a factor.
If open_ended = c('lower', 'upper')
was used when querying MFDB
for the data, then the bottom/top length groups will be modified to
start from zero or be infinite respectively.
Any missing lengthgroups (when there is otherwise data for that year/step) will be compared to zero.
Optional. If missing all age-groups (if any) in the model will be summed to compare to the data.
Model ages will be grouped by the same groupings as MFDB used, thus if
the data was formed with a query age = mfdb_group(young = 1:3,
old = 4:5)
, then the model data will similarly have 2 groups in it.
Any missing ages (when there is otherwise data for that year/step) will be compared to zero.
Optional.
Values are the same as with length/age/tag respectively, but group by the predator rather than the prey.
Optional. If tmissing all stocks in stocks will be summed to compare to the data.
The values in the stocks column should match the names of the stocks given in the stocks parameter. This column can be factor or character.
The values can also some of the stock name parts, e.g. "st_f"
or "f"
which would then aggregate "st_imm_f"
, "st_mat_f"
together.
However, note that a stock can only be included in one grouping,
so given columns "f"
& "imm"
, "st_imm_f"
would only be included in the former group.
If you want to do something along these lines, 2 separate likelihood actions would be more appropriate.
Any missing stocks (when there is otherwise data for that year/step) will be compared to zero.
Optional. If this and stock are missing all stocks in stocks will be summed to compare to the data.
The values in the stocks column will be used as regular expressions to match the names of the stocks given in the stocks parameter. For example, '_mat_' will match both 'ghd_mat_f' and 'ghd_mat_m' and will be compared against the sum of the 2 stocks.
Any missing stocks (when there is otherwise data for that year/step) will be compared to zero.
Optional. If this and fleet_re are missing all fleets in fleets will be summed to compare to the data.
The values in the fleets column should match the names of the fleets given in the fleets parameter. This column can be factor or character.
Any missing fleets (when there is otherwise data for that year/step) will be compared to zero.
Optional. If this and fleet are missing all fleets in fleets will be summed to compare to the data.
The values in the fleets column will be used as regular expressions to match the names of the fleets given in the fleets parameter. For example, '_trawl_' will match both 'fleet_trawl_is' and 'fleet_trawl_no' and will be compared against the sum of the 2 fleets.
Any missing fleets (when there is otherwise data for that year/step) will be compared to zero.
Optional. If missing all areas in the model will be summed to compare to the data.
Unlike other columns, the MFDB grouping here is ignored (the areas it is grouping over aren't integer model areas). Instead, the area_group parameter should describe how to map from the area names used in the table to integer model areas.
For example, if area_group = list(north=1:2, south=3:5)
, then
the area column of obs_data should contain either "north" or
"south", and corresponding model data will be summed from integer model
areas 1,2 and 3,4,5 respectively.
If area_group is not supplied, then we assume that obs_data area column will contain model area integers.
Any missing areas (when there is otherwise data for that year/step) will be compared to zero.
Data columns contain the observation data to compare. There should be at least one of:
If a number column appears in obs_data, then the stock abundance by individuals will be aggregated and compared to the obs_data number column.
If a weight column appears in obs_data, then the total biomass of the stock will be aggregated and compared to the obs_data number column.
You can use g3_distribution_preview
to see how your observation data
will be converted into an array.
Returns a formula for use as function_f:
Observation sample size for current time/area/age/length combination
Model sample size for current time/area/age/length combination
Total observation sample size for current time/area (or dimensions set in over)
Total model sample size for current time/area (or dimensions set in over)
Returns a formula for use as function_f:
Observation sample size for current time/area/age/length combination
Model sample size for current time/area/age/length combination
Number of lengthgroups in sample
epsilon parameter
Returns a formula for use as function_f, which calls TMB's SCALE(AR1(rho), sigma)(x)
, where
rho and sigma are parameters, and x
is defined as:
Observation sample size for current time/area/age/length combination
Model sample size for current time/area/age/length combination
Total observation sample size for current time/area (or dimensions set in over)
Total model sample size for current time/area (or dimensions set in over)
For more information, see Autoregressive processes in the TMB book.
Returns a formula for use as function_f:
Observation sample size for current time/area/age/length combination
Model sample size for current time/area/age/length combination
alpha parameter
beta parameter
If alpha or beta is not provided, then linear regression is
performed on ,
over time for each area/age/length combination.
The used values will be stored in a
cdist_nll_name_model__param
array and
reported after model run, whether calculated or hard-coded.
Returns a formula for use as function_f:
Observation sample size for current time/area/age/length combination
Model sample size for current time/area/age/length combination
alpha parameter
beta parameter
If alpha or beta is not provided, then linear regression is
performed on ,
over time for each area/age/length combination.
The used values will be stored in a
cdist_nll_name_model__param
array and
reported after model run, whether calculated or hard-coded.
The equivalent of gadget2's catchinkilos
.
Returns a formula for use as function_f:
Observation sample size for current time/area/age/length combination
Model sample size for current time/area/age/length combination
epsilon parameter
An action (i.e. list of formula objects) that will...
For all stocks, collect catch data into modelstock__num or modelstock__wgt, depending on the columns provided in obs_data
Compare modelstock__num/wgt with obsstock__num/wgt, using function_f
The output of function_f is summed over all stock dimensions (age/area) and time and added to nll
.
An action (i.e. list of formula objects) that will...
For all fleets and stocks combinations, collect catch data into modelstock__num or modelstock__wgt, depending on the columns provided in obs_data
Compare modelstock__num/wgt with obsstock__num/wgt, using function_f
The output of function_f is summed over all stock dimensions (age/area) and time and added to nll
.
The input obs_data formatted as an array, applying the same rules that g3l_*distribution
will.
https://gadget-framework.github.io/gadget2/userguide/chap-like.html,
g3_stock
ling_imm <- g3_stock('ling_imm', seq(20, 156, 4)) %>% g3s_age(3, 10) ling_mat <- g3_stock('ling_mat', seq(20, 156, 4)) %>% g3s_age(5, 15) lln <- g3_fleet('lln') # Invent a ldist.lln table for our tests ldist.lln.raw <- data.frame( year = c(1999, 2000), age = sample(5:9, 100, replace = TRUE), length = sample(10:70, 100, replace = TRUE), number = 1, stringsAsFactors = FALSE) # Group length into 10-long bins # NB: The last 2 bins will be empty, but gadget3 will use the factor levels, include them as zero # NB: Generally one would use mfdb::mfdb_sample_count() source and group data for you ldist.lln.raw |> dplyr::group_by( year = year, age = age, length = cut(length, breaks = seq(10, 100, by = 10), right = FALSE) ) |> dplyr::summarise(number = sum(number), .groups = 'keep') -> ldist.lln # Turn age into a factor, indicating all ages we should be interested in ldist.lln$age <- factor(ldist.lln$age, levels = 5:15) # We can see the results of this being turned into an array: g3_distribution_preview(ldist.lln) likelihood_actions <- list( g3l_catchdistribution( 'ldist_lln', ldist.lln, fleets = list(lln), stocks = list(ling_imm, ling_mat), g3l_distribution_sumofsquares())) # Make an (incomplete) model using the action, extract the observation array fn <- suppressWarnings(g3_to_r(likelihood_actions)) environment(fn)$cdist_sumofsquares_ldist_lln_obs__num # Apply age-reading error matrix to model data more_likelihood_actions <- list( g3l_catchdistribution( 'ldist_lln_readerror', ldist.lln, fleets = list(lln), stocks = list(ling_imm, ling_mat), transform_fs = list(age = g3_formula( g3_param_array('reader1matrix', value = diag(5))[g3_idx(preage), g3_idx(age)] )), g3l_distribution_sumofsquares())) # Apply per-stock age-reading error matrix to model data more_likelihood_actions <- list( g3l_catchdistribution( 'ldist_lln_readerror', ldist.lln, fleets = list(lln), stocks = list(ling_imm, ling_mat), transform_fs = list(age = list( ling_imm = quote( g3_param_array('imm_readermatrix', value = diag(ling_imm__maxage - ling_imm__minage + 1) )[ling_imm__preage_idx, ling_imm__age_idx] ), ling_mat = quote( g3_param_array('mat_readermatrix', value = diag(ling_mat__maxage - ling_mat__minage + 1) )[ling_mat__preage_idx, ling_mat__age_idx] ), unused = 0)), g3l_distribution_sumofsquares())) ## Stomach content: predator-prey species preference prey_a <- g3_stock('prey_a', seq(1, 10)) |> g3s_age(1,3) prey_b <- g3_stock('prey_b', seq(1, 10)) |> g3s_age(1,3) pred_a <- g3_stock('pred_a', seq(50, 80, by = 10)) |> g3s_age(0, 10) otherfood <- g3_stock('otherfood', 0) # Produce data.frame with columns: # * predator_length or predator_age # * stock # * number or weight pred_a_preypref_obs <- expand.grid( year = 2000:2005, predator_length = c(50,70), stock = c('prey_a', 'prey_b', 'otherfood'), number = 0 ) # Create catchdistribution likelihood component actions <- list( g3l_catchdistribution( 'pred_a_preypref', pred_a_preypref_obs, fleets = list(pred_a), stocks = list(prey_a, prey_b, otherfood), g3l_distribution_sumofsquares(), nll_breakdown = TRUE, report = TRUE ), NULL) ## Stomach content: predator-prey size preference # Produce data.frame with columns: # * predator_length or predator_age # * (prey) length # * number or weight pred_a_sizepref_obs <- expand.grid( year = 2000:2005, predator_length = c(50,70), length = seq(1, 10), number = 0 ) # Create catchdistribution likelihood component actions <- list( g3l_catchdistribution( 'pred_a_sizepref', pred_a_sizepref_obs, predators = list(pred_a), # NB: Only referencing stocks included in observation data stocks = list(prey_a), function_f = g3l_distribution_sumofsquares(), # Use transform_fs to apply digestioncoefficients transform_fs = list(length = list(prey_a = g3_formula( quote( diag(d0 + d1 * prey_a__midlen^d2) ), d0 = g3_parameterized('d0', by_stock = TRUE), d1 = g3_parameterized('d1', by_stock = TRUE), d2 = g3_parameterized('d2', by_stock = TRUE) ))), nll_breakdown = TRUE, report = TRUE ), NULL)
ling_imm <- g3_stock('ling_imm', seq(20, 156, 4)) %>% g3s_age(3, 10) ling_mat <- g3_stock('ling_mat', seq(20, 156, 4)) %>% g3s_age(5, 15) lln <- g3_fleet('lln') # Invent a ldist.lln table for our tests ldist.lln.raw <- data.frame( year = c(1999, 2000), age = sample(5:9, 100, replace = TRUE), length = sample(10:70, 100, replace = TRUE), number = 1, stringsAsFactors = FALSE) # Group length into 10-long bins # NB: The last 2 bins will be empty, but gadget3 will use the factor levels, include them as zero # NB: Generally one would use mfdb::mfdb_sample_count() source and group data for you ldist.lln.raw |> dplyr::group_by( year = year, age = age, length = cut(length, breaks = seq(10, 100, by = 10), right = FALSE) ) |> dplyr::summarise(number = sum(number), .groups = 'keep') -> ldist.lln # Turn age into a factor, indicating all ages we should be interested in ldist.lln$age <- factor(ldist.lln$age, levels = 5:15) # We can see the results of this being turned into an array: g3_distribution_preview(ldist.lln) likelihood_actions <- list( g3l_catchdistribution( 'ldist_lln', ldist.lln, fleets = list(lln), stocks = list(ling_imm, ling_mat), g3l_distribution_sumofsquares())) # Make an (incomplete) model using the action, extract the observation array fn <- suppressWarnings(g3_to_r(likelihood_actions)) environment(fn)$cdist_sumofsquares_ldist_lln_obs__num # Apply age-reading error matrix to model data more_likelihood_actions <- list( g3l_catchdistribution( 'ldist_lln_readerror', ldist.lln, fleets = list(lln), stocks = list(ling_imm, ling_mat), transform_fs = list(age = g3_formula( g3_param_array('reader1matrix', value = diag(5))[g3_idx(preage), g3_idx(age)] )), g3l_distribution_sumofsquares())) # Apply per-stock age-reading error matrix to model data more_likelihood_actions <- list( g3l_catchdistribution( 'ldist_lln_readerror', ldist.lln, fleets = list(lln), stocks = list(ling_imm, ling_mat), transform_fs = list(age = list( ling_imm = quote( g3_param_array('imm_readermatrix', value = diag(ling_imm__maxage - ling_imm__minage + 1) )[ling_imm__preage_idx, ling_imm__age_idx] ), ling_mat = quote( g3_param_array('mat_readermatrix', value = diag(ling_mat__maxage - ling_mat__minage + 1) )[ling_mat__preage_idx, ling_mat__age_idx] ), unused = 0)), g3l_distribution_sumofsquares())) ## Stomach content: predator-prey species preference prey_a <- g3_stock('prey_a', seq(1, 10)) |> g3s_age(1,3) prey_b <- g3_stock('prey_b', seq(1, 10)) |> g3s_age(1,3) pred_a <- g3_stock('pred_a', seq(50, 80, by = 10)) |> g3s_age(0, 10) otherfood <- g3_stock('otherfood', 0) # Produce data.frame with columns: # * predator_length or predator_age # * stock # * number or weight pred_a_preypref_obs <- expand.grid( year = 2000:2005, predator_length = c(50,70), stock = c('prey_a', 'prey_b', 'otherfood'), number = 0 ) # Create catchdistribution likelihood component actions <- list( g3l_catchdistribution( 'pred_a_preypref', pred_a_preypref_obs, fleets = list(pred_a), stocks = list(prey_a, prey_b, otherfood), g3l_distribution_sumofsquares(), nll_breakdown = TRUE, report = TRUE ), NULL) ## Stomach content: predator-prey size preference # Produce data.frame with columns: # * predator_length or predator_age # * (prey) length # * number or weight pred_a_sizepref_obs <- expand.grid( year = 2000:2005, predator_length = c(50,70), length = seq(1, 10), number = 0 ) # Create catchdistribution likelihood component actions <- list( g3l_catchdistribution( 'pred_a_sizepref', pred_a_sizepref_obs, predators = list(pred_a), # NB: Only referencing stocks included in observation data stocks = list(prey_a), function_f = g3l_distribution_sumofsquares(), # Use transform_fs to apply digestioncoefficients transform_fs = list(length = list(prey_a = g3_formula( quote( diag(d0 + d1 * prey_a__midlen^d2) ), d0 = g3_parameterized('d0', by_stock = TRUE), d1 = g3_parameterized('d1', by_stock = TRUE), d2 = g3_parameterized('d2', by_stock = TRUE) ))), nll_breakdown = TRUE, report = TRUE ), NULL)
Add likelihood components for random effects
g3l_random_dnorm( nll_name, param_f, mean_f = 0, sigma_f = 1, log_f = TRUE, period = 'auto', nll_breakdown = FALSE, weight = g3_parameterized(paste0(nll_name, "_weight"), optimise = FALSE, value = 1), run_at = g3_action_order$likelihood) g3l_random_walk( nll_name, param_f, sigma_f = 1, log_f = TRUE, period = 'auto', nll_breakdown = FALSE, weight = g3_parameterized(paste0(nll_name, "_weight"), optimise = FALSE, value = 1), run_at = g3_action_order$likelihood)
g3l_random_dnorm( nll_name, param_f, mean_f = 0, sigma_f = 1, log_f = TRUE, period = 'auto', nll_breakdown = FALSE, weight = g3_parameterized(paste0(nll_name, "_weight"), optimise = FALSE, value = 1), run_at = g3_action_order$likelihood) g3l_random_walk( nll_name, param_f, sigma_f = 1, log_f = TRUE, period = 'auto', nll_breakdown = FALSE, weight = g3_parameterized(paste0(nll_name, "_weight"), optimise = FALSE, value = 1), run_at = g3_action_order$likelihood)
param_f |
A formula representing the value to apply dnorm to. Invariably a g3_param for g3l_random_dnorm, a g3_param_table with cur_year for g3l_random_walk. |
mean_f |
|
sigma_f |
|
log_f |
|
period |
When dnorm should be recalculated. Once per |
nll_name |
Character string, used to define the variable name for dnorm output. |
nll_breakdown |
Should the nll report be broken down by time? |
weight |
Weighting applied to this likelihood component. |
run_at |
Integer order that actions will be run within model, see |
The model report will contain nll_random_dnorm_dnorm_lin__dnorm
, the results of applying dnorm.
If nll_breakdown is TRUE
, this will be an array with one entry per timestep.
An action (i.e. list of formula objects) that will...
On the final model step, calculate dnorm(param_f, mean_f, sigma_f)
& add to nll
An action (i.e. list of formula objects) that will...
Calculate dnorm(param_f, previous param_f, sigma_f)
(at final year if period = year)
Add to nll.
likelihood_actions <- list( # Calculate dnorm() for the dnorm_log parameter g3l_random_dnorm('dnorm_log', g3_parameterized('dnorm_log', value = 0, random = TRUE), mean_f = 0), # Treat the walk_year.xxxx parameters as a random walk g3l_random_walk('walk_year', g3_parameterized('walk_year', by_year = TRUE, value = 0, random = TRUE)) )
likelihood_actions <- list( # Calculate dnorm() for the dnorm_log parameter g3l_random_dnorm('dnorm_log', g3_parameterized('dnorm_log', value = 0, random = TRUE), mean_f = 0), # Treat the walk_year.xxxx parameters as a random walk g3l_random_walk('walk_year', g3_parameterized('walk_year', by_year = TRUE, value = 0, random = TRUE)) )
Compare model predictions against a set of sparse data points
g3l_sparsesample_linreg( fit = c('log', 'linear'), slope = 1, intercept = NULL ) g3l_sparsesample_sumsquares( weighting = "model_stddev" ) g3l_sparsesample( nll_name, obs_df, stocks, measurement_f = quote( wgt ), function_f = g3l_sparsesample_linreg(), predstocks = list(), area_group = NULL, weight = g3_parameterized(paste( if (length(predstocks) > 0) "csparse" else "asparse", function_f_name, nll_name, "weight", sep = "_"), optimise = FALSE, value = 1), run_at = g3_action_order$likelihood )
g3l_sparsesample_linreg( fit = c('log', 'linear'), slope = 1, intercept = NULL ) g3l_sparsesample_sumsquares( weighting = "model_stddev" ) g3l_sparsesample( nll_name, obs_df, stocks, measurement_f = quote( wgt ), function_f = g3l_sparsesample_linreg(), predstocks = list(), area_group = NULL, weight = g3_parameterized(paste( if (length(predstocks) > 0) "csparse" else "asparse", function_f_name, nll_name, "weight", sep = "_"), optimise = FALSE, value = 1), run_at = g3_action_order$likelihood )
slope , intercept
|
formula substituted into surveyindices calcuations to fix slope/intercept of linear regression, or NULL if not fixed. See below. |
fit |
Is the fit 'log' or 'linear'? See below. |
weighting |
Weighting applied to sum-of-squares. One of "model_stddev", "obs_stddev" or a formula. |
nll_name |
Character string, used to define the variable name for obsstock and modelstock.
By default set to |
obs_df |
Data.frame of observation data. See details. |
stocks |
A list of |
measurement_f |
formula to derive the model's equivalent predicted value for a data point.
You can use |
function_f |
A formula to compare obs_df to predicted values generated via transform_f and generate nll, defined by one of the g3l_sparsesample_* functions. |
predstocks |
A list of |
area_group |
List mapping area names used in obs_df to integer model areas,
most likely generated by |
weight |
Weighting applied to this likelihood component. Default is a |
run_at |
Integer order that actions will be run within model, see |
The actions will define the following variables in your model, which could be reported with g3a_report_history
:
Observation mean, the mean column from obs_df
Observation standard deviation, the stddev column from obs_df
Observation number, the number column from obs_df
The corresponding model prediction vector, total datapoints. __model_sum / __model_n
for the mean
The corresponding model prediction vector, sqared-sum datapoints.
The number of data points at each point in the model prediction vector, if predstocks set this is the number of individuals caught matching the datapoint (length/age/...), otherwise abundance of individuals matching the datapoint.
data.frame of observation data. Unlike g3l_abundancedistribution
, gaps and sparse data is accepted,
and gaps will not be filled with zero.
For each row in the table, all matching predictions are aggregated. Aggregation columns include:
Required. The year the sample is from
Optional. The timestep/season the sample is from
Optional. Only aggregate predicted values from given area
Optional. Only aggregate predicted values with given age
Optional. Only aggregate predicted values with given length (matches nearest lengthgroup)
So, a row with "year=1998,age=4" will be compared against age 4 individuals of all lengths in 1998, step 1 & 2. A row with "year=2004,step=1,age=2,length=19" will be compared against individuals of age 4, length 10..20, in winter 2004.
The observation data is provided in the following columns:
Required. Mean value at this data point
Optional. Number of data points, defaults to 1
Optional. Observed standard deviation (only required if weighting = "obs_stddev"
)
Returns a formula for use as function_f:
If fit = "log":
If fit = "linear":
"mean" column from obs_df
Total predicted values for all data points, i.e. nll_spabund_name__model_sum
Number of data points, i.e. nll_spabund_name__model_n
intercept parameter, defaults to 1
, i.e. fixed slope
slope parameter, defaults to NULL
, i.e. linear regression performed to find optimal value
If either alpha or beta is not provided, then linear regression is
performed on vs
for each value in table, and the optimal value used for each.
Returns a formula for use as function_f:
"mean" column from obs_df
Total predicted values, i.e. nll_spabund_name__model_sum
Number of data points, i.e. nll_spabund_name__model_n
weighting parameter, either:
, using stddev of model predicted values if
weighting = "model_stddev"
, using stddev column from obs_df if
weighting = "obs_stddev"
A custom forumla provided for weighting
https://gadget-framework.github.io/gadget2/userguide/chap-like.html,
g3l_catchdistribution
g3_stock
st <- g3_stock("fish", c(10, 20, 30)) %>% g3s_age(3,5) # Generate some random sparsesample samples obs_df <- data.frame( # NB: No 1993, we don't have any samples for that year year = rep(c(1990, 1991, 1992, 1994), each = 2), step = 1:2 ) obs_df$age = floor(runif(nrow(obs_df), min = 3, max = 5.1)) obs_df$length = floor(runif(nrow(obs_df), min = 10, max = 50)) obs_df$mean = runif(nrow(obs_df), min = 10, max = 1000) actions <- list( g3a_time(1990, 1994, c(6,6)), # Use otherfood to populate abundance / mean weight g3a_otherfood(st, quote( age * 100 + stock__minlen ), quote( cur_year * 1e5 + cur_step * 1e4 + 0 * stock__minlen ) ), g3l_sparsesample( "bt", obs_df, list(st), measurement_f = g3_formula( # Derive blubber thickness from length/weight ((wgt/(wmax.a * length^wmax.b) - 0.5) * 100 - 4.44) / (5693 * (length/wgt)^0.5), wmax.a = g3_parameterized("wmax.a", by_stock = TRUE), wmax.b = g3_parameterized("wmax.b", by_stock = TRUE), end = NULL ), function_f = g3l_sparsesample_linreg(fit = "linear") ), NULL ) model_fn <- g3_to_r(c(actions, list( g3a_report_detail(actions), # TODO: Not reporting anything useful NULL ))) r <- attributes(model_fn()) colSums(r$dstart_fish__num) # TODO: Report something related
st <- g3_stock("fish", c(10, 20, 30)) %>% g3s_age(3,5) # Generate some random sparsesample samples obs_df <- data.frame( # NB: No 1993, we don't have any samples for that year year = rep(c(1990, 1991, 1992, 1994), each = 2), step = 1:2 ) obs_df$age = floor(runif(nrow(obs_df), min = 3, max = 5.1)) obs_df$length = floor(runif(nrow(obs_df), min = 10, max = 50)) obs_df$mean = runif(nrow(obs_df), min = 10, max = 1000) actions <- list( g3a_time(1990, 1994, c(6,6)), # Use otherfood to populate abundance / mean weight g3a_otherfood(st, quote( age * 100 + stock__minlen ), quote( cur_year * 1e5 + cur_step * 1e4 + 0 * stock__minlen ) ), g3l_sparsesample( "bt", obs_df, list(st), measurement_f = g3_formula( # Derive blubber thickness from length/weight ((wgt/(wmax.a * length^wmax.b) - 0.5) * 100 - 4.44) / (5693 * (length/wgt)^0.5), wmax.a = g3_parameterized("wmax.a", by_stock = TRUE), wmax.b = g3_parameterized("wmax.b", by_stock = TRUE), end = NULL ), function_f = g3l_sparsesample_linreg(fit = "linear") ), NULL ) model_fn <- g3_to_r(c(actions, list( g3a_report_detail(actions), # TODO: Not reporting anything useful NULL ))) r <- attributes(model_fn()) colSums(r$dstart_fish__num) # TODO: Report something related
*Experimental* CKMR tagging likelihood
g3l_tagging_ckmr( nll_name, obs_data, fleets, parent_stocks, offspring_stocks, weight = g3_parameterized(paste0(nll_name, "_weight"), optimise = FALSE, value = 1), run_at = g3_action_order$likelihood)
g3l_tagging_ckmr( nll_name, obs_data, fleets, parent_stocks, offspring_stocks, weight = g3_parameterized(paste0(nll_name, "_weight"), optimise = FALSE, value = 1), run_at = g3_action_order$likelihood)
nll_name |
Character string, used to define the variable name for obsstock and modelstock. |
obs_data |
Data.frame of observed mother-offspring pairs with columns year / parent_age / offspring_age / mo_pairs |
fleets |
A list of |
parent_stocks |
A list of |
offspring_stocks |
A list of |
weight |
Weighting applied to this likelihood component. Default is a |
run_at |
Integer order that actions will be run within model, see |
Implementation of CKMR based on Bravington, M.V., Skaug, H.J., & Anderson, E.C. (2016). Close-Kin Mark-Recapture. Statistical Science, 31, 259-274.
Only one kinship probability is implemented, mother-offspring with lethal sampling, i.e. (3.2) in the paper. This is then used as a pseudo-likelihood as per (4.1).
The obs_data data.frame provides observed pairs. Unlike other likelihood mehthods, it has a fixed structure:
Year of observation for the data point.
Age of the parent in an observed parent-offspring pair.
Age of the offspring in an observed parent-offspring pair.
Number of pairs observed with these ages.
An action (i.e. list of formula objects) that will...
For all parent_stocks and offspring_stocks, collect spawing rate into modelhist__spawning and modelhist__spawned, total number of parents and total number of spawned offspring respectively
For all fleets, collect catch data into modelhist__catch
For any observed pairs that year, include the probability of that event happening into nll
Bravington, M.V., Skaug, H.J., & Anderson, E.C. (2016). Close-Kin Mark-Recapture. Statistical Science, 31, 259-274.
g3_stock
Add rates of understocking in a g3 model to nll
g3l_understocking( prey_stocks, power_f = ~2, nll_breakdown = FALSE, weight = 1e+08, run_at = g3_action_order$likelihood)
g3l_understocking( prey_stocks, power_f = ~2, nll_breakdown = FALSE, weight = 1e+08, run_at = g3_action_order$likelihood)
prey_stocks |
A list of |
power_f |
A formula representing power coefficient |
nll_breakdown |
Should the nll report be broken down by time? |
weight |
Weighting applied to this likelihood component. |
run_at |
Integer order that actions will be run within model, see |
The model report will contain nll_understocking__wgt, the results of the formula below.
If nll_breakdown is TRUE
, this will be an array with one entry per timestep.
An action (i.e. list of formula objects) that will...
Sum the total biomass adjustment due to overstocking for each prey according to the formula
Where is the power coefficient from power_f,
is the total biomass adjustment to predator consumtion due to overconsumtion.
ling_imm <- g3_stock('ling_imm', seq(20, 156, 4)) %>% g3s_age(3, 10) ling_mat <- g3_stock('ling_mat', seq(20, 156, 4)) %>% g3s_age(5, 15) lln <- g3_fleet('lln') likelihood_actions <- list( g3l_understocking(list(ling_imm, ling_mat)))
ling_imm <- g3_stock('ling_imm', seq(20, 156, 4)) %>% g3s_age(3, 10) ling_mat <- g3_stock('ling_mat', seq(20, 156, 4)) %>% g3s_age(5, 15) lln <- g3_fleet('lln') likelihood_actions <- list( g3l_understocking(list(ling_imm, ling_mat)))
Shortcuts to parameterise a model with g3_param
g3_parameterized( name, by_stock = FALSE, by_predator = FALSE, by_year = FALSE, by_step = FALSE, by_age = FALSE, by_area = FALSE, exponentiate = FALSE, avoid_zero = FALSE, scale = 1, offset = 0, ifmissing = NULL, ...)
g3_parameterized( name, by_stock = FALSE, by_predator = FALSE, by_year = FALSE, by_step = FALSE, by_age = FALSE, by_area = FALSE, exponentiate = FALSE, avoid_zero = FALSE, scale = 1, offset = 0, ifmissing = NULL, ...)
name |
Suffix for parameter name. |
by_stock |
Should there be individual parameters per-stock?
|
by_predator |
Should there be individual parameters per-predator (read: per-fleet) stock?
|
by_year |
Should there be individual parameters per model year?
|
by_step |
Should there be individual parameters per step within years?
|
by_age |
Should there be individual parameters per stock age?
|
by_area |
Should there be individual parameters per stock area?
|
ifmissing |
Value to use for when there is no valid parameter (read: year when by_year = TRUE) Either a numeric constant or character. If character, add another parameter for ifmissing, using the same by_stock value. |
exponentiate |
Use |
avoid_zero |
If TRUE, wrap parameter with |
scale |
Use |
offset |
Use |
... |
Additional parameters passed through to |
The function provides shortcuts to common formulas used when parameterising a model.
A formula object defining the given parameters
g3_param
,
g3_param_table
,
stock_prepend
stock_imm <- g3_stock(c(species = 'stock', 'imm'), seq(10, 35, 5)) %>% g3s_age(1, 4) stock_mat <- g3_stock(c(species = 'stock', 'mat'), seq(10, 35, 5)) %>% g3s_age(3, 6) # Helper function that shows the parameter template for the given parameter param_template_for <- function (g3_param) { model_code <- g3_to_tmb(list( # g3a_naturalmortality() isn't important, it is a place to add our parameter g3a_naturalmortality(stock_imm, g3_param), # We also need stock_mat in the model at least once g3a_naturalmortality(stock_mat, 0), # Set a year range to use for parameters where relevant g3a_time(1990, 1994) )) # Extract template, throw away default parameters from g3a_time() params <- attr(model_code, "parameter_template") params <- params[!(rownames(params) %in% c('retro_years', 'project_years')),] return(params) } # Not 'by' anything, so we add a single parameter value param_template_for( g3_parameterized('K') ) # Can set defaults for the parameter template when defining a parameter param_template_for( g3_parameterized('K', value = 5, lower = 2, upper = 8, optimise = FALSE) ) # by_stock, so the parameters will have the stock name prepended param_template_for( g3_parameterized('K', by_stock = TRUE) ) # Similarly, we can prepend year & age param_template_for( g3_parameterized('K', by_stock = TRUE, by_year = TRUE, by_age = TRUE) ) # You can specify the name part to use, # e.g. if a parameter should be shared between mature and immature: param_template_for( g3_parameterized('K', by_stock = 'species', by_year = TRUE) ) # Can give a list of stocks, in which case it works out name parts for you param_template_for( g3_parameterized('K', by_stock = list(stock_imm, stock_mat)) ) param_template_for( g3_parameterized('K', by_stock = list(stock_imm, stock_mat), by_age = TRUE) ) # If there are no shared name parts, then all names will be added param_template_for( g3_parameterized( 'btrigger', by_stock = list(g3_fleet("surv"), g3_fleet("comm"))) ) # You can set fixed scale/offset for the parameter g3_parameterized('K', scale = 5, offset = 9) # ...or give names and they will also be parameters, sharing the by_stock setting param_template_for( g3_parameterized('K', by_stock = TRUE, scale = "sc", offset = "offs") )
stock_imm <- g3_stock(c(species = 'stock', 'imm'), seq(10, 35, 5)) %>% g3s_age(1, 4) stock_mat <- g3_stock(c(species = 'stock', 'mat'), seq(10, 35, 5)) %>% g3s_age(3, 6) # Helper function that shows the parameter template for the given parameter param_template_for <- function (g3_param) { model_code <- g3_to_tmb(list( # g3a_naturalmortality() isn't important, it is a place to add our parameter g3a_naturalmortality(stock_imm, g3_param), # We also need stock_mat in the model at least once g3a_naturalmortality(stock_mat, 0), # Set a year range to use for parameters where relevant g3a_time(1990, 1994) )) # Extract template, throw away default parameters from g3a_time() params <- attr(model_code, "parameter_template") params <- params[!(rownames(params) %in% c('retro_years', 'project_years')),] return(params) } # Not 'by' anything, so we add a single parameter value param_template_for( g3_parameterized('K') ) # Can set defaults for the parameter template when defining a parameter param_template_for( g3_parameterized('K', value = 5, lower = 2, upper = 8, optimise = FALSE) ) # by_stock, so the parameters will have the stock name prepended param_template_for( g3_parameterized('K', by_stock = TRUE) ) # Similarly, we can prepend year & age param_template_for( g3_parameterized('K', by_stock = TRUE, by_year = TRUE, by_age = TRUE) ) # You can specify the name part to use, # e.g. if a parameter should be shared between mature and immature: param_template_for( g3_parameterized('K', by_stock = 'species', by_year = TRUE) ) # Can give a list of stocks, in which case it works out name parts for you param_template_for( g3_parameterized('K', by_stock = list(stock_imm, stock_mat)) ) param_template_for( g3_parameterized('K', by_stock = list(stock_imm, stock_mat), by_age = TRUE) ) # If there are no shared name parts, then all names will be added param_template_for( g3_parameterized( 'btrigger', by_stock = list(g3_fleet("surv"), g3_fleet("comm"))) ) # You can set fixed scale/offset for the parameter g3_parameterized('K', scale = 5, offset = 9) # ...or give names and they will also be parameters, sharing the by_stock setting param_template_for( g3_parameterized('K', by_stock = TRUE, scale = "sc", offset = "offs") )
Convert g3 actions into a character vector describing the model
g3_to_desc(actions, minor_steps = FALSE)
g3_to_desc(actions, minor_steps = FALSE)
actions |
A list of actions (i.e. list of formula objects), as produced by g3a_* functions. |
minor_steps |
Include minor steps (e.g. zeroing cumulative arrays)? |
Character vector describing each step in the model. An action in a model may have generated multiple steps (e.g. select each prey stock, scale total amount, apply overstocking), and there will be a line in here for each.
ling_imm <- g3_stock('ling_imm', seq(20, 156, 4)) %>% g3s_age(3, 10) initialconditions_action <- g3a_initialconditions_normalparam( ling_imm, by_age = TRUE) # Timekeeping action time_action <- g3a_time( start_year = 2000, end_year = 2004, c(3, 3, 3, 3)) # Generate a list outlining the steps the model uses as.list(g3_to_desc(list(initialconditions_action, time_action)))
ling_imm <- g3_stock('ling_imm', seq(20, 156, 4)) %>% g3s_age(3, 10) initialconditions_action <- g3a_initialconditions_normalparam( ling_imm, by_age = TRUE) # Timekeeping action time_action <- g3a_time( start_year = 2000, end_year = 2004, c(3, 3, 3, 3)) # Generate a list outlining the steps the model uses as.list(g3_to_desc(list(initialconditions_action, time_action)))
Convert g3 actions into an R function that can then be executed
g3_to_r( actions, work_dir = getOption('gadget3.r.work_dir', default = tempdir()), trace = FALSE, strict = FALSE, cmp_options = list(optimize = 3) ) ## S3 method for class 'g3_r' print(x, ..., with_environment = FALSE, with_template = FALSE)
g3_to_r( actions, work_dir = getOption('gadget3.r.work_dir', default = tempdir()), trace = FALSE, strict = FALSE, cmp_options = list(optimize = 3) ) ## S3 method for class 'g3_r' print(x, ..., with_environment = FALSE, with_template = FALSE)
actions |
A list of actions (i.e. list of formula objects), as produced by g3a_* functions. |
work_dir |
Where to write the temporary R script containing your function |
cmp_options |
options to pass through to |
trace |
If TRUE, turn all comments into print statements. |
strict |
If TRUE, enable extra sanity checking in actions. Any invalid conditions (e.g. more/less fish after growth) will result in a warning. |
x |
The |
with_environment |
If TRUE, list data stored in function environment when printing |
with_template |
If TRUE, show parameter template when printing |
... |
Other arguments |
A function that takes a params variable, which can be:
A list of parameters as defined by attr(fn, 'parameter_template')
A data.frame of parameters defined by g3_to_tmb
's parameter template
Not provided, in which case the parameter defaults are used
The function will have the following attributes:
The original actions list given to the function
A list of all parameters expected by the model, to fill in
Use e.g. attr(fn, 'parameter_template')
to retrieve them.
Invariant model data will be stored as a closure, i.e. in environment(fn)
.
This can be fetched with environment(fn)$cdist_sumofsquares_ldist_gil_obs__num
.
The function will return nll produced by the model.
You can also use attributes(nll)
to get any report variables from the model.
ling_imm <- g3_stock(c(species = 'ling', 'imm'), seq(20, 156, 4)) %>% g3s_age(3, 10) initialconditions_action <- g3a_initialconditions_normalparam( ling_imm, factor_f = g3a_renewal_initabund(by_stock_f = 'species'), by_stock = 'species', by_age = TRUE) # Timekeeping action time_action <- g3a_time( start_year = 2000, end_year = 2004, c(3, 3, 3, 3)) # Generate a model from the above 2 actions # NB: Obviously in reality we'd need more actions fn <- g3_to_r(list(initialconditions_action, time_action)) if (interactive()) { # Edit the resulting function fn <- edit(fn) } param <- attr(fn, 'parameter_template') param$project_years <- 0 param$ling.init.F <- 0.4 param$ling.Linf <- 160 param$ling.K <- 90 param$ling.recl <- 12 param$recage <- g3_stock_def(ling_imm, 'minage') param[grepl('^ling.init.sd.', names(param))] <- 50.527220 param[grepl('^ling_imm.init.\\d+', names(param))] <- 1 param$ling_imm.init.scalar <- 200 param$ling_imm.walpha <- 2.27567436711055e-06 param$ling_imm.wbeta <- 3.20200445996187 param$ling_imm.M <- 0.15 # Run the model with the provided parameters nll <- fn(param) # Get the report from the last model run report <- attributes(nll) # Fetch a value from the model data environment(fn)$ling_imm__midlen
ling_imm <- g3_stock(c(species = 'ling', 'imm'), seq(20, 156, 4)) %>% g3s_age(3, 10) initialconditions_action <- g3a_initialconditions_normalparam( ling_imm, factor_f = g3a_renewal_initabund(by_stock_f = 'species'), by_stock = 'species', by_age = TRUE) # Timekeeping action time_action <- g3a_time( start_year = 2000, end_year = 2004, c(3, 3, 3, 3)) # Generate a model from the above 2 actions # NB: Obviously in reality we'd need more actions fn <- g3_to_r(list(initialconditions_action, time_action)) if (interactive()) { # Edit the resulting function fn <- edit(fn) } param <- attr(fn, 'parameter_template') param$project_years <- 0 param$ling.init.F <- 0.4 param$ling.Linf <- 160 param$ling.K <- 90 param$ling.recl <- 12 param$recage <- g3_stock_def(ling_imm, 'minage') param[grepl('^ling.init.sd.', names(param))] <- 50.527220 param[grepl('^ling_imm.init.\\d+', names(param))] <- 1 param$ling_imm.init.scalar <- 200 param$ling_imm.walpha <- 2.27567436711055e-06 param$ling_imm.wbeta <- 3.20200445996187 param$ling_imm.M <- 0.15 # Run the model with the provided parameters nll <- fn(param) # Get the report from the last model run report <- attributes(nll) # Fetch a value from the model data environment(fn)$ling_imm__midlen
Turn g3 actions into CPP code that can be compiled using TMB
g3_to_tmb(actions, trace = FALSE, strict = FALSE) g3_tmb_adfun( cpp_code, parameters = attr(cpp_code, 'parameter_template'), compile_flags = getOption('gadget3.tmb.compile_flags', default = if (.Platform$OS.type == "windows") c("-O1", "-march=native") else c("-O3", "-flto=auto", "-march=native") ), work_dir = getOption('gadget3.tmb.work_dir', default = tempdir()), output_script = FALSE, compile_args = list( framework = getOption("gadget3.tmb.framework", default = "TMBad") ), ...) g3_tmb_par(parameters, include_random = TRUE) g3_tmb_lower(parameters) g3_tmb_upper(parameters) g3_tmb_parscale(parameters) g3_tmb_relist(parameters, par)
g3_to_tmb(actions, trace = FALSE, strict = FALSE) g3_tmb_adfun( cpp_code, parameters = attr(cpp_code, 'parameter_template'), compile_flags = getOption('gadget3.tmb.compile_flags', default = if (.Platform$OS.type == "windows") c("-O1", "-march=native") else c("-O3", "-flto=auto", "-march=native") ), work_dir = getOption('gadget3.tmb.work_dir', default = tempdir()), output_script = FALSE, compile_args = list( framework = getOption("gadget3.tmb.framework", default = "TMBad") ), ...) g3_tmb_par(parameters, include_random = TRUE) g3_tmb_lower(parameters) g3_tmb_upper(parameters) g3_tmb_parscale(parameters) g3_tmb_relist(parameters, par)
actions |
A list of actions (i.e. list of formula objects), as produced by g3a_* functions. |
trace |
If TRUE, turn all comments into print statements. |
strict |
If TRUE, enable extra sanity checking in actions. Any invalid conditions (e.g. more/less fish after growth) will result in a warning. |
cpp_code |
cpp_code as produced by g3_to_tmb. |
parameters |
Parameter table as produced by |
par |
Parameter vector, as produced by one of
The first will not include random parameters by default, the others will. |
include_random |
Should random parameters assumed to be part of par? Should be |
compile_flags |
List of extra flags to compile with, use e.g. "-g" to enable debugging output.
Can be set with an option, e.g. |
compile_args |
Any other arguments to pass to TMB::compile |
work_dir |
Directory to write and compile .cpp files in. Defaults to R's current temporary directory
Set this to preserve compiled output and re-use between R sessions if possible.
Can be set with an option, e.g. |
output_script |
If |
... |
Any other options handed directly to MakeADFun |
g3_tmb_adfun
will do both the compile and MakeADFun
steps of making a model. If the code is identical to an already-loaded model then it
won't be recompiled, so repeated calls to g3_tmb_adfun to change parameters are fast.
If MakeADFun is crashing your R session, then you can use output_script to run in a separate R session. Use this with gdbsource to debug your model.
A string of C++ code that can be used as an input to g3_tmb_adfun, with the following attributes:
The original actions list given to the function
An environment containing data attached to the model
A data.frame to be filled in and used as parameters in the other g3_tmb_*
functions
Use e.g. attr(cpp_code, 'parameter_template')
to retrieve them.
An ADFun as produced by TMB's MakeADFun, or location of temporary script if output_script is TRUE
Values extracted from parameters table converted into a vector of values for obj$fn(par)
or nlminb
Lower bounds extracted from parameters table converted into a vector of values for nlminb
. Random parameters are always excluded
Lower bounds extracted from parameters table converted into a vector of values for nlminb
. Random parameters are always excluded
Parscale extracted from parameters table, converted into a vector of values for nlminb
. Random parameters are always excluded
The parameters table value column, but with optimised values replaced with contents of par vector. i.e. the inverse operation to g3_tmb_par. par can either include or discount random variables.
ling_imm <- g3_stock(c(species = 'ling', 'imm'), seq(20, 156, 4)) %>% g3s_age(3, 10) initialconditions_action <- g3a_initialconditions_normalparam( ling_imm, factor_f = g3a_renewal_initabund(by_stock_f = 'species'), by_stock = 'species', by_age = TRUE) abundance_action <- g3l_abundancedistribution( 'abundance', data.frame(year = 2000:2004, number = 100), stocks = list(ling_imm), function_f = g3l_distribution_sumofsquares()) # Timekeeping action time_action <- g3a_time( start_year = 2000, end_year = 2004, c(3, 3, 3, 3)) # Generate a model from the above 2 actions # NB: Obviously in reality we'd need more actions cpp <- g3_to_tmb(list(initialconditions_action, abundance_action, time_action)) if (interactive()) { # Edit the resulting code cpp <- edit(cpp) } # Set initial conditions for parameters attr(cpp, 'parameter_template') |> g3_init_val("project_years", 0) |> g3_init_val("ling.init.F", 0.4) |> g3_init_val("ling.Linf", 160) |> g3_init_val("ling.K", 90) |> g3_init_val("ling.t0", 0) |> g3_init_val("ling.init.sd.#", 50.527220) |> g3_init_val("ling_imm.init.#", 1, lower = 0, upper = 1000) |> g3_init_val("ling_imm.init.scalar", 200) |> g3_init_val("ling_imm.walpha", 2.275e-06) |> g3_init_val("ling_imm.wbeta", 3.2020) |> g3_init_val("ling_*.M.#", 0.15) |> identity() -> tmb_param if (!( nzchar(Sys.getenv('GITHUB_CI')) && .Platform$OS.type == "windows" )) { # Compile to a TMB ADFun tmb <- g3_tmb_adfun(cpp, tmb_param) } # NB: TMB::gdbsource() requires both "R" and "gdb" to be available # NB: gdbsource hangs on windows - https://github.com/kaskr/adcomp/issues/385 if (all(nzchar(Sys.which(c('gdb', 'R')))) && .Platform$OS.type !="windows") { cpp_broken <- g3_to_tmb(list( initialconditions_action, abundance_action, g3_formula(quote( stop("This model is broken") )), time_action)) # Build the model in an isolated R session w/debugger writeLines(TMB::gdbsource(g3_tmb_adfun( cpp_broken, compile_flags = "-g", output_script = TRUE))) } if (!( nzchar(Sys.getenv('GITHUB_CI')) && .Platform$OS.type == "windows" )) { # Perform a single run, using values in table result <- tmb$fn(g3_tmb_par(tmb_param)) } if (!( nzchar(Sys.getenv('GITHUB_CI')) && .Platform$OS.type == "windows" )) { # perform optimisation using upper/lower/parscale from table fit <- optim(tmb$par, tmb$fn, tmb$gr, method = "L-BFGS-B", upper = g3_tmb_upper(tmb_param), lower = g3_tmb_lower(tmb_param), control = list(maxit=10, parscale=g3_tmb_parscale(tmb_param))) } if (!( nzchar(Sys.getenv('GITHUB_CI')) && .Platform$OS.type == "windows" )) { # perform optimisation without bounds fit <- optim(tmb$par, tmb$fn, tmb$gr) } if (!( nzchar(Sys.getenv('GITHUB_CI')) && .Platform$OS.type == "windows" )) { # Go back to a list of parameters, suitable for the R version # NB: This will not set the values for random parameters param_list <- g3_tmb_relist(tmb_param, fit$par) } if (!( nzchar(Sys.getenv('GITHUB_CI')) && .Platform$OS.type == "windows" )) { # Update parameters with values from last run, *including* random parameters. param_list <- g3_tmb_relist(tmb_param, tmb$env$last.par) } if (!( nzchar(Sys.getenv('GITHUB_CI')) && .Platform$OS.type == "windows" )) { # Rebuild, only including "Fun" (i.e. without auto-differentiation) # Result will only work for tmb$report tmb <- g3_tmb_adfun(cpp, tmb_param, type = "Fun") result <- tmb$report(g3_tmb_par(tmb_param)) }
ling_imm <- g3_stock(c(species = 'ling', 'imm'), seq(20, 156, 4)) %>% g3s_age(3, 10) initialconditions_action <- g3a_initialconditions_normalparam( ling_imm, factor_f = g3a_renewal_initabund(by_stock_f = 'species'), by_stock = 'species', by_age = TRUE) abundance_action <- g3l_abundancedistribution( 'abundance', data.frame(year = 2000:2004, number = 100), stocks = list(ling_imm), function_f = g3l_distribution_sumofsquares()) # Timekeeping action time_action <- g3a_time( start_year = 2000, end_year = 2004, c(3, 3, 3, 3)) # Generate a model from the above 2 actions # NB: Obviously in reality we'd need more actions cpp <- g3_to_tmb(list(initialconditions_action, abundance_action, time_action)) if (interactive()) { # Edit the resulting code cpp <- edit(cpp) } # Set initial conditions for parameters attr(cpp, 'parameter_template') |> g3_init_val("project_years", 0) |> g3_init_val("ling.init.F", 0.4) |> g3_init_val("ling.Linf", 160) |> g3_init_val("ling.K", 90) |> g3_init_val("ling.t0", 0) |> g3_init_val("ling.init.sd.#", 50.527220) |> g3_init_val("ling_imm.init.#", 1, lower = 0, upper = 1000) |> g3_init_val("ling_imm.init.scalar", 200) |> g3_init_val("ling_imm.walpha", 2.275e-06) |> g3_init_val("ling_imm.wbeta", 3.2020) |> g3_init_val("ling_*.M.#", 0.15) |> identity() -> tmb_param if (!( nzchar(Sys.getenv('GITHUB_CI')) && .Platform$OS.type == "windows" )) { # Compile to a TMB ADFun tmb <- g3_tmb_adfun(cpp, tmb_param) } # NB: TMB::gdbsource() requires both "R" and "gdb" to be available # NB: gdbsource hangs on windows - https://github.com/kaskr/adcomp/issues/385 if (all(nzchar(Sys.which(c('gdb', 'R')))) && .Platform$OS.type !="windows") { cpp_broken <- g3_to_tmb(list( initialconditions_action, abundance_action, g3_formula(quote( stop("This model is broken") )), time_action)) # Build the model in an isolated R session w/debugger writeLines(TMB::gdbsource(g3_tmb_adfun( cpp_broken, compile_flags = "-g", output_script = TRUE))) } if (!( nzchar(Sys.getenv('GITHUB_CI')) && .Platform$OS.type == "windows" )) { # Perform a single run, using values in table result <- tmb$fn(g3_tmb_par(tmb_param)) } if (!( nzchar(Sys.getenv('GITHUB_CI')) && .Platform$OS.type == "windows" )) { # perform optimisation using upper/lower/parscale from table fit <- optim(tmb$par, tmb$fn, tmb$gr, method = "L-BFGS-B", upper = g3_tmb_upper(tmb_param), lower = g3_tmb_lower(tmb_param), control = list(maxit=10, parscale=g3_tmb_parscale(tmb_param))) } if (!( nzchar(Sys.getenv('GITHUB_CI')) && .Platform$OS.type == "windows" )) { # perform optimisation without bounds fit <- optim(tmb$par, tmb$fn, tmb$gr) } if (!( nzchar(Sys.getenv('GITHUB_CI')) && .Platform$OS.type == "windows" )) { # Go back to a list of parameters, suitable for the R version # NB: This will not set the values for random parameters param_list <- g3_tmb_relist(tmb_param, fit$par) } if (!( nzchar(Sys.getenv('GITHUB_CI')) && .Platform$OS.type == "windows" )) { # Update parameters with values from last run, *including* random parameters. param_list <- g3_tmb_relist(tmb_param, tmb$env$last.par) } if (!( nzchar(Sys.getenv('GITHUB_CI')) && .Platform$OS.type == "windows" )) { # Rebuild, only including "Fun" (i.e. without auto-differentiation) # Result will only work for tmb$report tmb <- g3_tmb_adfun(cpp, tmb_param, type = "Fun") result <- tmb$report(g3_tmb_par(tmb_param)) }
Additional meta-functions to help manage writing stock-handling actions.
g3_step(step_f, recursing = FALSE, orig_env = environment(step_f))
g3_step(step_f, recursing = FALSE, orig_env = environment(step_f))
step_f |
Input formula containing references to functions below |
recursing |
Only use default value |
orig_env |
Only use default value |
All action producing functions will run their output through g3_step
.
This means that the functions described here will be available in any gadget3
code.
They handle translation of stock instance naming, so code can refer to e.g.
stock__num
without having to translate naming to the final stock name,
and iterating over stock dimensions.
A formula object with references to above functions replaced.
Add a comment to the code to act as a label for that step, when producing an
outline of the model. There shouldn't be more than one debug_label
call in a step.
Models compiled with trace = TRUE
will print the resultant string to stdout.
Any number of character strings, or g3_stock variables. The latter will be replaced with the final name.
Identical to debug_label, but not considered a "label", just a code comment, so any number of calls can be added.
stock_assert(expression, message, message/stock-var, ...)
Assert that expression is true, if not abort with a message.
stock_reshape(dest_stock, expression)
Output expression with it's length structure reshaped to match dest_stock. The source stock is considered to be the first one found in expression
How this is achieved depends on the difference. If the source and destination match then this is a no-op. Otherwise a transformation matrix is generated and included into the model.
stock_ss(stock_var, [ dimname = override, dimname = override, ... ][, vec = (dimname|full|single) ])
Subsets stock_var for the current iteration of stock_iterate().
The vec parameter decides the start value for all dimensions
If full
, no other dimensions are set.
If set to a dimname, all dimensions after that dimension are set (i.e. a dimname-vector will be returned)
If single
, all dimensions are set (i.e. a single value wil be returned).
The default is length
if a length dimension is present (i.e. a length vector will be returned), otherwise single
.
If dimnames are supplied, then the code supplied will override the above.
This code can include default
, which will be substituted for the default subset,
or missing
to represent an empty position in the subset.
If a dimname is not present in stock_var, it will be ignored.
stock_ssinv(stock_var, [ dimname, dimname, ... ])
like stock_ss(), but subset only the mentioned dimnames.
stock_switch(stock, stock_name1 = expr, stock_name2 = expr, ... [ default ])
Switch based on name of stock, returning the relevant expr or default. If no default supplied, then an unknown stock is an error.
expr is implicitly wrapped with stock_with(stock, ...)
,
so any references to the stock variable will work. If only default is provided,
then this is identical to calling stock_with
.
stock_with(stock, expr)
Replaced with expr but with all stock variables of stock renamed with their final name. This is generally needed when not iterating over a stock, but e.g. zeroing or summing the whole thing.
stock_iterate(stock, expr)
Wrap expr with the code to iterate over vector dimensions in
stock, accessed using stock_ss(stock)
.
Which dimensions are iterated over is decided based on the call to
stock_ss(stock)
. By default, stock_ss leaves length blank so will
iterate over a length vector for each dimension.
You can iterate over each value individually with the following:
stock_iterate(stock, stock_ss(stock, length = default) )
Current values for each dimension will be available as variables,
e.g. area
, age
, and can be used in formulae.
stock_intersect(stock, expr)
Wrap expr with the code to intersect all dimensions with the dimensions of an outer stock_iterate().
stock_interact(stock, expr, prefix = prefix)
Wrap expr with the code to interact with the dimensions of an outer stock_iterate(). Interact means to intersect over area, but try the combinatoral explosion of all other dimensions, i.e. what would make most sense when 2 stocks interact in a predator-prey relationship.
Additional variables will be prefixed with prefix.
stock_prepend(stock, param_call, name_part = NULL)
Converts a g3_param or g3_param_table call, prefixing the parameter name with the stock name, and renaming any references to stock variables. If name_part given, will only add given part(s) of the stock name.
Returns param_call with the additions made.
### debug_label stock <- g3_stock('halibut', 1:10) %>% g3s_age(1,10) prey_stock <- g3_stock('herring', 1:3) %>% g3s_age(1,3) g3_step(~debug_trace("Zero ", stock, "-", prey_stock, " biomass-consuming counter")) ### stock_assert stock <- g3_stock('halibut', 1:10) %>% g3s_age(1,10) g3_step(~stock_assert(stock_with(stock, all(is.finite(stock__num))), stock, "__num became NaN/Inf")) ### stock_reshape s <- g3_stock('s', seq(3, 21, 3)) s__num <- g3_stock_instance(s, 100) agg <- g3_stock('agg', c(3, 10, 21), open_ended = FALSE) g3_eval(~stock_iterate(s, stock_reshape(agg, stock_ss(s__num)))) ### stock_ss stock <- g3_stock('halibut', 1:10) %>% g3s_age(1,10) %>% g3s_livesonareas(1) stock__num <- g3_stock_instance(stock) g3_step(~stock_iterate(stock, { x <- x + stock_ss(stock__num) })) g3_step(~stock_ss(stock__num, area = 5)) # Lengthgroups for age_idx + 1 g3_step(~stock_ss(stock__num, age = default + 1)) # Vector for the entirety of the "next" area g3_step(~stock_ss(stock__num, area = default + 1, vec = area)) g3_step(~stock_ss(stock__num, area = , age = j)) ### stock_ssinv stock <- g3_stock('halibut', 1:10) %>% g3s_age(1,10) %>% g3s_livesonareas(1) g3_step(~g3_step(~stock_ssinv(stock, 'age'))) g3_step(~g3_step(~stock_ssinv(stock, 'area'))) ### stock_switch stock <- g3_stock('halibut', 1:10) ; fleet_stock <- g3_fleet('igfs') g3_step(~stock_switch(stock, halibut = 2, herring = 3, -1)) g3_step(~stock_switch(fleet_stock, halibut = 2, herring = 3, -1)) g3_step(~stock_switch(stock, halibut = stock__midlen, -1)) ### stock_with stock <- g3_stock('halibut', 1:10) g3_step(~stock_with(stock, sum(stock__num))) ### stock_iterate stock <- g3_stock('halibut', 1:10) %>% g3s_age(1,10) g3_step(~stock_iterate(stock, x <- x + stock_ss(stock__num))) ### stock_intersect stock <- g3_stock('halibut', 1:10) %>% g3s_age(1,10) prey_stock <- g3_stock('herring', 1:3) %>% g3s_age(1,3) g3_step(~stock_iterate(stock, stock_intersect(prey_stock, { x <- x + stock_ss(stock__num) + stock_ss(prey_stock__num) }))) ### stock_interact stock <- g3_stock('halibut', 1:10) %>% g3s_age(1,10) prey_stock <- g3_stock('herring', 1:3) %>% g3s_age(1,3) g3_step(~stock_iterate(stock, stock_interact(prey_stock, { x <- x + stock_ss(stock__num) + stock_ss(prey_stock__num) }, prefix = "prey" )))
### debug_label stock <- g3_stock('halibut', 1:10) %>% g3s_age(1,10) prey_stock <- g3_stock('herring', 1:3) %>% g3s_age(1,3) g3_step(~debug_trace("Zero ", stock, "-", prey_stock, " biomass-consuming counter")) ### stock_assert stock <- g3_stock('halibut', 1:10) %>% g3s_age(1,10) g3_step(~stock_assert(stock_with(stock, all(is.finite(stock__num))), stock, "__num became NaN/Inf")) ### stock_reshape s <- g3_stock('s', seq(3, 21, 3)) s__num <- g3_stock_instance(s, 100) agg <- g3_stock('agg', c(3, 10, 21), open_ended = FALSE) g3_eval(~stock_iterate(s, stock_reshape(agg, stock_ss(s__num)))) ### stock_ss stock <- g3_stock('halibut', 1:10) %>% g3s_age(1,10) %>% g3s_livesonareas(1) stock__num <- g3_stock_instance(stock) g3_step(~stock_iterate(stock, { x <- x + stock_ss(stock__num) })) g3_step(~stock_ss(stock__num, area = 5)) # Lengthgroups for age_idx + 1 g3_step(~stock_ss(stock__num, age = default + 1)) # Vector for the entirety of the "next" area g3_step(~stock_ss(stock__num, area = default + 1, vec = area)) g3_step(~stock_ss(stock__num, area = , age = j)) ### stock_ssinv stock <- g3_stock('halibut', 1:10) %>% g3s_age(1,10) %>% g3s_livesonareas(1) g3_step(~g3_step(~stock_ssinv(stock, 'age'))) g3_step(~g3_step(~stock_ssinv(stock, 'area'))) ### stock_switch stock <- g3_stock('halibut', 1:10) ; fleet_stock <- g3_fleet('igfs') g3_step(~stock_switch(stock, halibut = 2, herring = 3, -1)) g3_step(~stock_switch(fleet_stock, halibut = 2, herring = 3, -1)) g3_step(~stock_switch(stock, halibut = stock__midlen, -1)) ### stock_with stock <- g3_stock('halibut', 1:10) g3_step(~stock_with(stock, sum(stock__num))) ### stock_iterate stock <- g3_stock('halibut', 1:10) %>% g3s_age(1,10) g3_step(~stock_iterate(stock, x <- x + stock_ss(stock__num))) ### stock_intersect stock <- g3_stock('halibut', 1:10) %>% g3s_age(1,10) prey_stock <- g3_stock('herring', 1:3) %>% g3s_age(1,3) g3_step(~stock_iterate(stock, stock_intersect(prey_stock, { x <- x + stock_ss(stock__num) + stock_ss(prey_stock__num) }))) ### stock_interact stock <- g3_stock('halibut', 1:10) %>% g3s_age(1,10) prey_stock <- g3_stock('herring', 1:3) %>% g3s_age(1,3) g3_step(~stock_iterate(stock, stock_interact(prey_stock, { x <- x + stock_ss(stock__num) + stock_ss(prey_stock__num) }, prefix = "prey" )))
Define multi-dimensional storage for use in models, mostly to contain state about stocks.
g3_stock(var_name, lengthgroups, open_ended = TRUE) g3_stock_instance(stock, init_value = NA, desc = "") g3_fleet(var_name) g3_stock_def(stock, name) g3s_clone(inner_stock, var_name) g3_is_stock(stock)
g3_stock(var_name, lengthgroups, open_ended = TRUE) g3_stock_instance(stock, init_value = NA, desc = "") g3_fleet(var_name) g3_stock_def(stock, name) g3s_clone(inner_stock, var_name) g3_is_stock(stock)
var_name |
Prefix used for all instance variables of this stock. Can have multiple parts that will be concatentated together, see example. |
lengthgroups |
Vector defining length groups, each entry defining the minimum value. |
open_ended |
If TRUE, final lengthgroups value defines a group |
inner_stock |
|
stock |
A |
init_value |
Intially the array will be filled with this constant, e.g. |
desc |
Description of the array that will be included in models |
name |
Name of definition to extract, e.g. |
A g3_stock
with length groups
An array with dimensions matching the stock.
A g3_stock
without length groups
The definition of the given variable in the stock. If stock is a list, then a list with the definition of each will be returned.
A g3_stock
with identical dimensions to inner_stock but with a new name.
TRUE
iff stock is a g3_stock
object.
# Define a stock with 3 lengthgroups stock <- g3_stock('name', c(1, 10, 100)) # Define a stock with a multi-part name. We can then dig out species name stock <- g3_stock(c(species = 'ling', 'imm'), c(1, 10, 100)) stopifnot( stock$name == 'ling_imm' ) stopifnot( stock$name_parts[['species']] == 'ling' ) # Use stock_instance define storage for mean weight of stock, # has dimensions matching what was defined above. g3_stock_instance(stock, 1, "Mean weight") # Can get definitions for multiple stocks in one go stocks <- list( imm = g3_stock(c('st', 'imm'), 1:10), mat = g3_stock(c('st', 'mat'), 1:10) ) g3_stock_def(stocks, 'minlen') # Retrieve the upperlen for the stock g3_stock_def(stock, 'upperlen') # Define a stock, not-open-ended. Now only 2 groups long stock <- g3_stock('name', c(1, 10, 100), open_ended = FALSE) # Use stock_instance to see what the array would look like g3_stock_instance(stock) # Fleets don't have lengthgroups stock <- g3_fleet('name') %>% g3s_livesonareas(1) # Use stock_instance to see what the array would look like g3_stock_instance(stock)
# Define a stock with 3 lengthgroups stock <- g3_stock('name', c(1, 10, 100)) # Define a stock with a multi-part name. We can then dig out species name stock <- g3_stock(c(species = 'ling', 'imm'), c(1, 10, 100)) stopifnot( stock$name == 'ling_imm' ) stopifnot( stock$name_parts[['species']] == 'ling' ) # Use stock_instance define storage for mean weight of stock, # has dimensions matching what was defined above. g3_stock_instance(stock, 1, "Mean weight") # Can get definitions for multiple stocks in one go stocks <- list( imm = g3_stock(c('st', 'imm'), 1:10), mat = g3_stock(c('st', 'mat'), 1:10) ) g3_stock_def(stocks, 'minlen') # Retrieve the upperlen for the stock g3_stock_def(stock, 'upperlen') # Define a stock, not-open-ended. Now only 2 groups long stock <- g3_stock('name', c(1, 10, 100), open_ended = FALSE) # Use stock_instance to see what the array would look like g3_stock_instance(stock) # Fleets don't have lengthgroups stock <- g3_fleet('name') %>% g3s_livesonareas(1) # Use stock_instance to see what the array would look like g3_stock_instance(stock)
Add age dimensions to g3_stock classes
g3s_age(inner_stock, minage, maxage) g3s_agegroup(inner_stock, agegroups)
g3s_age(inner_stock, minage, maxage) g3s_agegroup(inner_stock, agegroups)
inner_stock |
A |
minage |
Minimum age to store, integer. |
maxage |
Maximum age to store, integer. |
agegroups |
(optionally named) list of vectors of ages, grouping them together. |
A g3_stock
with an additional 'age' dimension.
When iterating over the stock, iterate over each age in turn, age will be set to the current integer age.
When intersecting with another stock, only do anything if age is betweem minage and maxage.
If an age dimension already exists, it is redefined with new parameters.
A g3_stock
with an additional 'age' dimension.
When iterating over the stock, iterate over each agegroup in turn, age will be set to the first age in the group.
When intersecting with another stock, only do anything if age is part of one of the groups.
# Define a stock with 3 lengthgroups and 3 ages stock <- g3_stock('name', c(1, 10, 100)) %>% g3s_age(5, 10) # Use stock_instance to see what the array would look like g3_stock_instance(stock) # Define a stock that groups age into "young" and "old" stock <- g3_stock('name', c(1, 10, 100)) %>% g3s_agegroup(list( young = 5:7, old = 8:10)) # Use stock_instance to see what the array would look like g3_stock_instance(stock)
# Define a stock with 3 lengthgroups and 3 ages stock <- g3_stock('name', c(1, 10, 100)) %>% g3s_age(5, 10) # Use stock_instance to see what the array would look like g3_stock_instance(stock) # Define a stock that groups age into "young" and "old" stock <- g3_stock('name', c(1, 10, 100)) %>% g3s_agegroup(list( young = 5:7, old = 8:10)) # Use stock_instance to see what the array would look like g3_stock_instance(stock)
Add area dimensions to g3_stock classes
g3_areas(area_names) g3s_livesonareas(inner_stock, areas) g3s_areagroup(inner_stock, areagroups)
g3_areas(area_names) g3s_livesonareas(inner_stock, areas) g3s_areagroup(inner_stock, areagroups)
area_names |
A character vector of area names to use in the model |
inner_stock |
A |
areas |
A vector of numeric areas that the stock is part of |
areagroups |
A list mapping names to vectors of numeric areas the stock is part of |
g3s_livesonareas
breaks up a stock by area.
Within a model, areas are only referred to by integer, however if these are named
then that name will be used for report output.
Each area will be defined as a variable in your model as area_x
,
allowing you to use names in formulas, e.g. run_f = quote( area == area_x )
.
g3_areas
is a helper to map a set of names to an integer
Inside a model each area will only be referred to by integer.
g3s_areagroup
allows areas to be combined, this is mostly used internally
by g3l_catchdistribution
.
A named integer vector, assigning each of area_names a number.
A g3_stock
with an additional 'area' dimension.
When iterating over the stock, iterate over each area in turn, area will be set to the current integer area.
When intersecting with another stock, only do anything if area is also part of our list of areas.
A g3_stock
with an additional 'area' dimension.
When iterating over the stock, iterate over each areagroup in turn, area will be set to the first area in the group.
When intersecting with another stock, only do anything if area is part of one of the groups.
# Make a lookup so we can refer to areas by name area_names <- g3_areas(c('a', 'b', 'c', 'd', 'e')) stopifnot(area_names == c(a=1, b=2, c=3, d=4, e=5)) # Define a stock with 3 lengthgroups and 3 areas stock <- g3_stock('name', c(1, 10, 100)) %>% g3s_livesonareas(area_names[c('a', 'b', 'c')]) # Area variables will be defined, so you can refer to them in formulas: g3a_migrate(stock, g3_parameterized("migrate_spring"), run_f = ~area == area_b && cur_step == 2) # Use stock_instance to see what the array would look like g3_stock_instance(stock) # Define a stock that groups areas into "north" and "south" stock <- g3_stock('name', c(1, 10, 100)) %>% g3s_areagroup(list( north = area_names[c('a', 'b', 'c')], south = area_names[c('d', 'e')])) # Use stock_instance to see what the array would look like g3_stock_instance(stock)
# Make a lookup so we can refer to areas by name area_names <- g3_areas(c('a', 'b', 'c', 'd', 'e')) stopifnot(area_names == c(a=1, b=2, c=3, d=4, e=5)) # Define a stock with 3 lengthgroups and 3 areas stock <- g3_stock('name', c(1, 10, 100)) %>% g3s_livesonareas(area_names[c('a', 'b', 'c')]) # Area variables will be defined, so you can refer to them in formulas: g3a_migrate(stock, g3_parameterized("migrate_spring"), run_f = ~area == area_b && cur_step == 2) # Use stock_instance to see what the array would look like g3_stock_instance(stock) # Define a stock that groups areas into "north" and "south" stock <- g3_stock('name', c(1, 10, 100)) %>% g3s_areagroup(list( north = area_names[c('a', 'b', 'c')], south = area_names[c('d', 'e')])) # Use stock_instance to see what the array would look like g3_stock_instance(stock)
Add tag dimensions to g3_stock classes
g3s_tag(inner_stock, tag_ids, force_untagged = TRUE)
g3s_tag(inner_stock, tag_ids, force_untagged = TRUE)
inner_stock |
A |
tag_ids |
A vector of numeric tags the stock can have, generated by |
force_untagged |
If TRUE, if "untagged" tag 0 isn't present it will be added. |
A g3_stock
with an additional 'tag' dimension.
When iterating over the stock, iterate over each tag in turn, tag will be set to the current integer area.
When interacting with another stock, iterate over each tag in turn, the variable name will depend on the scenario, e.g. prey_tag.
# Make a lookup of text names to integers tags <- c('H1-00', 'H1-01') tags <- structure(seq_along(tags), names = tags) # prey_a can have any of these tags prey_a <- g3_stock('prey_a', seq(1, 10)) %>% g3s_tag(tags) # Use stock_instance to see what the array would look like g3_stock_instance(prey_a)
# Make a lookup of text names to integers tags <- c('H1-00', 'H1-01') tags <- structure(seq_along(tags), names = tags) # prey_a can have any of these tags prey_a <- g3_stock('prey_a', seq(1, 10)) %>% g3s_tag(tags) # Use stock_instance to see what the array would look like g3_stock_instance(prey_a)
Add time dimensions to g3_stock classes
g3s_time_convert(year_or_time, step = NULL) g3s_time(inner_stock, times, year = NULL, step = NULL)
g3s_time_convert(year_or_time, step = NULL) g3s_time(inner_stock, times, year = NULL, step = NULL)
year_or_time |
Etiher vector of years, or vector of year & step strings, e.g. "1999-01". |
year |
Vector of years, used to generate times if provided. |
step |
Vector of steps, used to generate times if provided. |
inner_stock |
A |
times |
A vector of year/step integers as generated by g3s_time_convert |
A single integer vector representing year and step.
If step is NULL
, returns year, otherwise year * 1000 + step
.
A g3_stock
with an additional 'time' dimension.
If year/step provided, time is defined by those, otherwise times.
The g3_stock
will not support iterating,
only intersecting.
When intersecting with another stock, only do anything if cur_year and cur_step matches a time stored in the vector
# Define a stock with 3 lengthgroups and 3 years, not continuous # When used, all steps within a year will be aggregated, year 2002 will be ignored. stock <- g3_stock('name', c(1, 10, 100)) %>% g3s_time(year = c(2000, 2001, 2003)) # Use stock_instance to see what the array would look like g3_stock_instance(stock) # Define a stock with 3 lengthgroups and 3 years, 2 steps # The dimension will have 6 entries, 2000.1, 2000.2, 2001.1, 2001.2, 2002.1, 2002.2 stock <- g3_stock('name', c(1, 10, 100)) %>% g3s_time(year = c(2000, 2001, 2002), step = 1:2) # Use stock_instance to see what the array would look like g3_stock_instance(stock) # g3s_time_convert is best used with a data.frame data <- read.table(header = TRUE, text = ' year step 2001 1 2001 2 # NB: No "2002 1" 2002 2 ') stock <- g3_stock('name', c(1, 10, 100)) %>% g3s_time(times = g3s_time_convert(data$year, data$step)) # Will also parse strings g3s_time_convert(c("1999-01", "1999-02")) # Use stock_instance to see what the array would look like g3_stock_instance(stock)
# Define a stock with 3 lengthgroups and 3 years, not continuous # When used, all steps within a year will be aggregated, year 2002 will be ignored. stock <- g3_stock('name', c(1, 10, 100)) %>% g3s_time(year = c(2000, 2001, 2003)) # Use stock_instance to see what the array would look like g3_stock_instance(stock) # Define a stock with 3 lengthgroups and 3 years, 2 steps # The dimension will have 6 entries, 2000.1, 2000.2, 2001.1, 2001.2, 2002.1, 2002.2 stock <- g3_stock('name', c(1, 10, 100)) %>% g3s_time(year = c(2000, 2001, 2002), step = 1:2) # Use stock_instance to see what the array would look like g3_stock_instance(stock) # g3s_time_convert is best used with a data.frame data <- read.table(header = TRUE, text = ' year step 2001 1 2001 2 # NB: No "2002 1" 2002 2 ') stock <- g3_stock('name', c(1, 10, 100)) %>% g3s_time(times = g3s_time_convert(data$year, data$step)) # Will also parse strings g3s_time_convert(c("1999-01", "1999-02")) # Use stock_instance to see what the array would look like g3_stock_instance(stock)
Formula-returning functions describing length suitability relationships.
g3_suitability_exponentiall50( alpha = g3_parameterized("alpha", by_stock = by_stock, by_predator = by_predator), l50 = g3_parameterized("l50", by_stock = by_stock, by_predator = by_predator), by_stock = TRUE, by_predator = TRUE) g3_suitability_andersen(p0, p1, p2, p3 = p4, p4, p5 = quote( predator_length )) g3_suitability_andersenfleet( p0 = g3_parameterized('andersen.p0', value = 0, optimise = FALSE, by_stock = by_stock), p1 = g3_parameterized('andersen.p1', value = log(2), by_stock = by_stock, by_predator = by_predator), p2 = g3_parameterized('andersen.p2', value = 1, optimise = FALSE, by_stock = by_stock), p3 = g3_parameterized('andersen.p3', value = 0.1, exponentiate = exponentiate, by_stock = by_stock, by_predator = by_predator), p4 = g3_parameterized('andersen.p4', value = 0.1, exponentiate = exponentiate, by_stock = by_stock, by_predator = by_predator), p5 = quote( stock__maxmidlen ), by_stock = TRUE, by_predator = TRUE, exponentiate = TRUE) g3_suitability_gamma(alpha, beta, gamma) g3_suitability_exponential(alpha, beta, gamma, delta) g3_suitability_straightline(alpha, beta) g3_suitability_constant( suit = g3_parameterized("suit", by_stock = by_stock, by_predator = by_predator), by_stock = TRUE, by_predator = TRUE ) g3_suitability_richards(p0, p1, p2, p3, p4)
g3_suitability_exponentiall50( alpha = g3_parameterized("alpha", by_stock = by_stock, by_predator = by_predator), l50 = g3_parameterized("l50", by_stock = by_stock, by_predator = by_predator), by_stock = TRUE, by_predator = TRUE) g3_suitability_andersen(p0, p1, p2, p3 = p4, p4, p5 = quote( predator_length )) g3_suitability_andersenfleet( p0 = g3_parameterized('andersen.p0', value = 0, optimise = FALSE, by_stock = by_stock), p1 = g3_parameterized('andersen.p1', value = log(2), by_stock = by_stock, by_predator = by_predator), p2 = g3_parameterized('andersen.p2', value = 1, optimise = FALSE, by_stock = by_stock), p3 = g3_parameterized('andersen.p3', value = 0.1, exponentiate = exponentiate, by_stock = by_stock, by_predator = by_predator), p4 = g3_parameterized('andersen.p4', value = 0.1, exponentiate = exponentiate, by_stock = by_stock, by_predator = by_predator), p5 = quote( stock__maxmidlen ), by_stock = TRUE, by_predator = TRUE, exponentiate = TRUE) g3_suitability_gamma(alpha, beta, gamma) g3_suitability_exponential(alpha, beta, gamma, delta) g3_suitability_straightline(alpha, beta) g3_suitability_constant( suit = g3_parameterized("suit", by_stock = by_stock, by_predator = by_predator), by_stock = TRUE, by_predator = TRUE ) g3_suitability_richards(p0, p1, p2, p3, p4)
suit , alpha , beta , gamma , delta , l50 , p0 , p1 , p2 , p3 , p4 , p5
|
formula substituted into calcuations, see below. |
by_stock |
Change the default parameterisation (e.g. to be by 'species'), passed through to default calls to
|
by_predator |
Change the default parameterisation (e.g. to be by 'fleet'), passed through to default calls to
|
exponentiate |
Exponentiate parameters,passed through to default calls to
|
When using these to describe a predator/prey relationship, the stock midlength
will refer to the prey midlength.
All functions return a formula for use in g3a_predate_fleet
's suitabilities argument:
A logarithmic dependence on the length of the prey as given by the following equation
(note that the prey length dependence is actually dependant on the difference between the length of the prey and ):
Vector of stock midlength for each lengthgroup
Length of the stock with a 50% probability of predation, from parameter l50
This is a more general suitability function that is dependant on the ratio of the predator length to the prey length as given by the following equation:
If :
Otherwise:
...i.e if then
used in place of
.
Vector of predator midlength for each lengthgroup
Vector of stock midlength for each lengthgroup
..
Function parameter p0 .. p4
Function parameter p5, if unspecified uses , Vector of predator midlength for each lengthgroup.
NB: Specifying is equivalent to using the
andersenfleet
function in gadget2.
A simplified version of g3_suitability_andersen
, suitable for predation by fleets,
as the defaults do not rely on the predator's length.
This is a suitability function that is more suitable for use when considering the predation by a fleet,
where the parameter would represent the size of the mesh used by the fleet (specified in centimetres).
Vector of stock midlength for each lengthgroup
Function parameter alpha
Function parameter beta
Function parameter gamma
This is a suitability function that is more suitable for use when
considering the predation by a fleet, where the parameter
would represent the size of the mesh used by the fleet (specified in
centimetres).
This is a suitability function that has a logarithmic dependence on both the length of the predator and the length of the prey as given by the following equation:
Vector of predator midlength for each lengthgroup
Vector of stock midlength for each lengthgroup
Function parameter alpha
Function parameter beta
Function parameter gamma
Function parameter delta
Returns a formula for use in predation function's suitabilities argument:
Vector of stock midlength for each lengthgroup
Function parameter alpha
Function parameter beta
Returns a formula for use in predation function's suitabilities argument:
Function parameter suit, i.e. the "prey.predator.suit" model parameter by default
Returns a formula for use in predation function's suitabilities argument:
Vector of predator midlength for each lengthgroup
Vector of stock midlength for each lengthgroup
..
Function parameter p0 .. p4
This is an extension to g3_suitability_exponential.
https://gadget-framework.github.io/gadget2/userguide/chap-stock.html#sec-suitability,
ling_imm <- g3_stock(c(species = 'ling', 'imm'), seq(20, 156, 4)) %>% g3s_age(3, 10) ling_mat <- g3_stock(c(species = 'ling', 'mat'), seq(20, 156, 4)) %>% g3s_age(5, 15) igfs <- g3_fleet('igfs') igfs_landings <- structure(expand.grid(year=1990:1994, step=2, area=1, total_weight=1), area_group = list(`1` = 1)) # Generate a fleet predation action using g3_suitability_exponentiall50 predate_action <- g3a_predate_fleet( igfs, list(ling_imm, ling_mat), suitabilities = list( ling_imm = g3_suitability_exponentiall50( g3_parameterized('lln.alpha', by_stock = 'species'), g3_parameterized('lln.l50', by_stock = 'species')), ling_mat = g3_suitability_exponentiall50( g3_parameterized('lln.alpha', by_stock = 'species'), g3_parameterized('lln.l50', by_stock = 'species'))), catchability = g3a_predate_catchability_totalfleet( g3_timeareadata('igfs_landings', igfs_landings))) # You can use g3_eval to directly calculate values for a stock: g3_eval( g3_suitability_exponentiall50(alpha = 0.2, l50 = 60), stock = g3_stock('x', seq(0, 100, 10)) ) ## Plots suit_plot <- function ( suit_f, stock = g3_stock('x', seq(0, 100, 5)), predator_length = 140, cols = rainbow(5) ) { par(mar = c(2,2,2,2), cex.main = 1) for (a in seq_along(cols)) curve( g3_eval( suit_f, a = a, stock = stock, predator_length = predator_length )[x %/% g3_stock_def(stock, 'dl')[[1]] + 1], from = min(g3_stock_def(stock, 'minlen')), to = max(g3_stock_def(stock, 'minlen')), col = cols[[a]], main = deparse1(sys.call()[[2]]), xlab = "", ylab = "", add = (a != 1) ) } suit_plot(g3_suitability_exponentiall50(alpha = ~a * 0.1, l50 = 50)) suit_plot(g3_suitability_andersen(0, log(2), 1, p3 = ~a * 0.1, 0.1, 140)) suit_plot(g3_suitability_andersen(0, log(2), 1, 0.1, p4 = ~a * 0.1, 140)) suit_plot(g3_suitability_gamma(alpha = ~2 + a * 0.1, beta = 1, gamma = 40)) suit_plot(g3_suitability_exponential(0, ~0.01 * a, 0, 1)) suit_plot(g3_suitability_straightline(alpha = 0.1, beta = ~0.01 * a)) suit_plot(g3_suitability_constant(~a * 0.1)) suit_plot(g3_suitability_richards(0, 0.05, 0, 1, ~0.1 * a))
ling_imm <- g3_stock(c(species = 'ling', 'imm'), seq(20, 156, 4)) %>% g3s_age(3, 10) ling_mat <- g3_stock(c(species = 'ling', 'mat'), seq(20, 156, 4)) %>% g3s_age(5, 15) igfs <- g3_fleet('igfs') igfs_landings <- structure(expand.grid(year=1990:1994, step=2, area=1, total_weight=1), area_group = list(`1` = 1)) # Generate a fleet predation action using g3_suitability_exponentiall50 predate_action <- g3a_predate_fleet( igfs, list(ling_imm, ling_mat), suitabilities = list( ling_imm = g3_suitability_exponentiall50( g3_parameterized('lln.alpha', by_stock = 'species'), g3_parameterized('lln.l50', by_stock = 'species')), ling_mat = g3_suitability_exponentiall50( g3_parameterized('lln.alpha', by_stock = 'species'), g3_parameterized('lln.l50', by_stock = 'species'))), catchability = g3a_predate_catchability_totalfleet( g3_timeareadata('igfs_landings', igfs_landings))) # You can use g3_eval to directly calculate values for a stock: g3_eval( g3_suitability_exponentiall50(alpha = 0.2, l50 = 60), stock = g3_stock('x', seq(0, 100, 10)) ) ## Plots suit_plot <- function ( suit_f, stock = g3_stock('x', seq(0, 100, 5)), predator_length = 140, cols = rainbow(5) ) { par(mar = c(2,2,2,2), cex.main = 1) for (a in seq_along(cols)) curve( g3_eval( suit_f, a = a, stock = stock, predator_length = predator_length )[x %/% g3_stock_def(stock, 'dl')[[1]] + 1], from = min(g3_stock_def(stock, 'minlen')), to = max(g3_stock_def(stock, 'minlen')), col = cols[[a]], main = deparse1(sys.call()[[2]]), xlab = "", ylab = "", add = (a != 1) ) } suit_plot(g3_suitability_exponentiall50(alpha = ~a * 0.1, l50 = 50)) suit_plot(g3_suitability_andersen(0, log(2), 1, p3 = ~a * 0.1, 0.1, 140)) suit_plot(g3_suitability_andersen(0, log(2), 1, 0.1, p4 = ~a * 0.1, 140)) suit_plot(g3_suitability_gamma(alpha = ~2 + a * 0.1, beta = 1, gamma = 40)) suit_plot(g3_suitability_exponential(0, ~0.01 * a, 0, 1)) suit_plot(g3_suitability_straightline(alpha = 0.1, beta = ~0.01 * a)) suit_plot(g3_suitability_constant(~a * 0.1)) suit_plot(g3_suitability_richards(0, 0.05, 0, 1, ~0.1 * a))
Convert time-based data into a formula to lookup values
g3_timeareadata(lookup_name, df, value_field = "total_weight", areas = NULL)
g3_timeareadata(lookup_name, df, value_field = "total_weight", areas = NULL)
lookup_name |
A unique name for this lookup, e.g. |
df |
A data.frame with any of columns out of age, area, year and step, finally value_field. |
value_field |
Column name that contains output value. |
areas |
Named integer vector of area names to integer values. See |
A formula object that looks up value_field for the current
values of age
, area
, cur_year
and cur_step
,
depending on the columns in df. If there's no match, return 0.
ling_imm <- g3_stock(c(species = 'ling', 'imm'), seq(20, 156, 4)) %>% g3s_age(3, 10) ling_mat <- g3_stock(c(species = 'ling', 'mat'), seq(20, 156, 4)) %>% g3s_age(5, 15) igfs <- g3_fleet('igfs') igfs_landings <- structure(expand.grid(year=1990:1994, step=2, area=1, total_weight=1), area_group = list(`1` = 1)) # Generate a fleet predation action, use g3_timeareadata to supply landings # NB: Since igfs_landings only contains values for step=2, there will be no # predation on other steps (since g3_timeareadata will return 0). predate_action <- g3a_predate_fleet( igfs, list(ling_imm, ling_mat), suitabilities = list( ling_imm = g3_suitability_exponentiall50( g3_parameterized('lln.alpha', by_stock = 'species'), g3_parameterized('lln.l50', by_stock = 'species')), ling_mat = g3_suitability_exponentiall50( g3_parameterized('lln.alpha', by_stock = 'species'), g3_parameterized('lln.l50', by_stock = 'species'))), catchability = g3a_predate_catchability_totalfleet( g3_timeareadata('igfs_landings', igfs_landings)))
ling_imm <- g3_stock(c(species = 'ling', 'imm'), seq(20, 156, 4)) %>% g3s_age(3, 10) ling_mat <- g3_stock(c(species = 'ling', 'mat'), seq(20, 156, 4)) %>% g3s_age(5, 15) igfs <- g3_fleet('igfs') igfs_landings <- structure(expand.grid(year=1990:1994, step=2, area=1, total_weight=1), area_group = list(`1` = 1)) # Generate a fleet predation action, use g3_timeareadata to supply landings # NB: Since igfs_landings only contains values for step=2, there will be no # predation on other steps (since g3_timeareadata will return 0). predate_action <- g3a_predate_fleet( igfs, list(ling_imm, ling_mat), suitabilities = list( ling_imm = g3_suitability_exponentiall50( g3_parameterized('lln.alpha', by_stock = 'species'), g3_parameterized('lln.l50', by_stock = 'species')), ling_mat = g3_suitability_exponentiall50( g3_parameterized('lln.alpha', by_stock = 'species'), g3_parameterized('lln.l50', by_stock = 'species'))), catchability = g3a_predate_catchability_totalfleet( g3_timeareadata('igfs_landings', igfs_landings)))
Switch formula based on current time step
g3_timevariable(lookup_name, fs)
g3_timevariable(lookup_name, fs)
lookup_name |
A unique name for this lookup, e.g. |
fs |
A list of formula objects, named with either "init", "(year)" or "(year)-(step)". When the matching time step is reached, the value of the lookup will be changed. |
This is mostly for backwards compatibility with gadget2, before using this,
consider other simpler options, e.g. g3_timeareadata
or the
by_year option in g3_parameterized
.
A formula object that will switch values at the given time points.
ling_imm <- g3_stock('ling_imm', seq(20, 156, 4)) %>% g3s_age(3, 10) naturalmortality_action <- g3a_naturalmortality(ling_imm, g3a_naturalmortality_exp( g3_timevariable("lingimm.M", list( # Start off using lingimm.M.early "init" = g3_parameterized("lingimm.M.early"), # At 2005 step 2, switch to lingimm.M.mid "2005-02" = g3_parameterized("lingimm.M.mid"), # At 2010 step 1, switch to lingimm.M.late "2010" = g3_parameterized("lingimm.M.late")))))
ling_imm <- g3_stock('ling_imm', seq(20, 156, 4)) %>% g3s_age(3, 10) naturalmortality_action <- g3a_naturalmortality(ling_imm, g3a_naturalmortality_exp( g3_timevariable("lingimm.M", list( # Start off using lingimm.M.early "init" = g3_parameterized("lingimm.M.early"), # At 2005 step 2, switch to lingimm.M.mid "2005-02" = g3_parameterized("lingimm.M.mid"), # At 2010 step 1, switch to lingimm.M.late "2010" = g3_parameterized("lingimm.M.late")))))