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, and RPW Observations

Catch: Cy=Ca,sC_y = \sum{C_{a,s}}

RPN: Iy=qNa,sexp(Za,s/2)va,sI_y = q\sum{N_{a,s}\exp{(-Z_{a,s}/2})v_{a,s}}

RPW: Iy=qNa,sexp(Za,s/2)va,swa,sI_y = q\sum{N_{a,s}\exp{(-Z_{a,s}/2})v_{a,s}w_{a,s}}.

For both surveys qq represents the catchability coefficient for the specific survey and vv represents the survey selectivity. For RPWs, ww 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

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().

Observation Process options

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

Custom Observation Processes

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.