observation_processes.Rmd
In addition to simulating populations based on demographic
parameters, afscOM can also generate observations of the underlying
population. Currently supported observation types include: catch
observations, relative population abundance indices (RPNs), relative
biomass abundance indices (RPWs), and age compositions (age comps). Each
observation type can be generated for any number of combination of
fishery and survey fleets, based on the obs_pars
list.
Catch, RPN, and RPW index observations are all generated based on a random sample from a lognormal distribution parameterized by a mean value calculated from the current population state, and a user supplied CV. For each type of index observation, the mean is calculated as follow:
Catch:
RPN:
RPW: .
For both surveys
represents the catchability coefficient for the specific survey and
represents the survey selectivity. For RPWs,
represents weight-at-age-and-sex. R functions for computing RPNs and
RPWs according to the above equations are available as
simulate_rpn()
and simulate_rpw()
.
Lognormal samples are each bias corrected
(rlnrom(1, meanlog=log(mu)-sd^2/2
), where the standard
deviation is calculated as sd=sqrt(log(CV+1))
.
Age composition observations are generated based on a random sample
from a multinomial distribution with a user supplied sample size. Age
composition observations from fishery fleets use standardized
catch-at-age (C_a/∑C_a) as the multinomial bin proportions, while age
comp observations from survey fleets use year-end standardized selected
numbers-at-age (N_a v_a/∑N_a v_a). User can optionally specify whether
to generate sex aggregated age composition observations (male and female
individuals combined), and whether for observations to reported as
proportions or in integer values per bin. An R function for computing
age composition predictions is available as
simulate_ac()
.
If simulate_observations=TRUE
, then a set of parameters
that govern how observations are simulated must also be defined. This
option, obs_pars
is a list of vectors, where each vector
has length nfleets+nsurveys
.
Required items in the obs_pars
list are:
Parameter Name | Description | Dimensions | Notes |
---|---|---|---|
is_survey |
Whether each fleet is a survey or fishery fleet | [nfleets+nsurveys] |
|
qs |
Catchability coefficients | [nfleets+nsurveys] |
|
rpn |
Whether to generate an RPN index | [nfleets+nsurveys] |
0 for “no”, 1 for “yes” |
rpw |
Whether to generate an RPW index | [nfleets+nsurveys] |
0 for “no”, 1 for “yes” |
rpn_cv |
A CV to use when genrating RPN indices | [nfleets+nsurveys] |
|
rpw_cv |
A CV to use when genrating RPW indices | [nfleets+nsurveys] |
|
acs |
Whether to generate age composition observations | [nfleets+nsurveys] |
0 for “no”, 1 for “yes” |
ac_samps |
Number of samples to use when generating age comp observations | [nfleets+nsurveys] |
|
ac_as_integers |
Whether to return age comp observations as integers or proportions | [nfleets+nsurveys] |
0 for “proportions”, 1 for “integers” |
acs_agg_sex |
Whether age comp observations should be aggregated by sex | [nfleets+nsurveys] |
0 for “no”, 1 for “yes” |
Below is an example obs_pars
object that generates RPNs
and RPWs for two surveys, and age composition observations for two
fisheries and two surveys. Age compositions are not aggregated by sex
and are returned as integers.
nfleets <- 2
nsurveys <- 2
obs_pars <- list(
is_survey = c(0, 0, 1, 1), # first two fleets are fisheries, last two are surveys
qs = c(0, 0, 6, 0.8), # catchability coefficients
rpn = c(0, 0, 1, 1), # generate RPNs for the two survey fleets
rpw = c(0, 0, 1, 1), # generate RPWs for the two survey fleets
rpn_cv = c(0, 0, 0.1. 0.1), # CV for RPNs
rpw_cv = c(0, 0, 0.1. 0.1), # CV for RPWs
acs = c(1, 1, 1, 1), # generate age comps for all fleets
ac_samps = c(100, 50, 100, 50), # sample sizes for age comps
ac_as_integers = c(1, 1, 1, 1), # return age comps as integers
acs_agg_sex = c(0, 0, 0, 0) # do not aggregate age comps
)
model_options$obs_pars <- obs_pars
The observation submodel currently built-in to afscOM
is
designed to emulate common data sources and data types for NOAA stock
assessment biologists, but does not cover the full scope of possible
observation data types. For example, there is not currently support for
generating fishery CPUE indices or egg productions indices. For more
complex observation processes, users can create custom observation
submodels to generate additional data.
To implement a custom observation submodel, turn off the default
observation model by setting
model_options$simulate_observations=FALSE
(this ensures
that the project
function won’t generate its own
observations). From there, you can define any type of function
necessary, and provide, as input, outputs from the
project()
function. For example:
Below is an example of a custom observation process that generates observations of the population sex ratio from a normal distribution for each year.
model_options$obs_pars$sex_rat$sd <- 0.05
custom_observation_process <- function(naa, model_options){
# return observations of population sex-ratio
n_males <- sum(naa[,,2,,drop=FALSE])
n_females <- sum(naa[,,1,,drop=FALSE])
true_prop_males <- n_males/(n_males+n_females)
# assume its normally distributed (should be a better assumption, since its a proportion)
obs_prop_male <- rnorm(1, mean=true_prop_males, sd=model_options$obs_pars$sex_rat$sd)
return(obs_prop_males)
}
model_options$simulate_observations = FALSE # turn off default simulations
out <- afscOM::project_single(removals, fleet.props, prev_naa, recruitment, options=model_options)
naa <- out$naa_tmp
propmale_obs <- custom_observation_process(naa, model_options)
propmale_obs
If users want to simply augment the current set of observations (as
is being done in the above example), setting
model_options$simulate_observations=FALSE
is not strictly
necessary.
For multiyear simulations, users will need to implement their own multiyear simulation framework with the custom observation model. See the “Multiyear Projections” page for additional information.