Skip to contents

SPoRC models are assembled through a pipeline of Setup_Mod_* functions (for the estimation model) and Setup_Sim_* functions (for the operating model / simulation). Each function appends to an input_list (or sim_list) that accumulates data, parameter starting values, and RTMB factor maps. This vignette catalogues every user-facing option across that pipeline. Where both an integer code and a string alias exist, either is accepted. Strings are generally preferred for readability. When n_sexes > 1, the first sex index is always female. When n_pop > 1, populations follow the order in which they are defined. Throughout this document, the notation [p × r × y × τ × a × s] is shorthand for array dimensions: population, region, year, seasons, age, sex.

Parameter sharing conventions

Many hyperparameters throughout the pipeline (process-error standard deviations, catchability, natural mortality, tag reporting rates, …) are controlled by a _spec string argument that follows the same convention: a single named dimension (e.g. region, season, fleet, sex) is either estimated independently for every level, shared across some subset of levels, or fixed. Concretely, for a hyperparameter varying across dimensions abbreviated r (region), seas (season), and f (fleet), the accepted strings are:

String Meaning
"est_all" Independent parameter for every combination of dimensions
"est_shared_r" Shared across regions; independent per remaining dimension
"est_shared_seas" Shared across seasons
"est_shared_f" Shared across fleets
"est_shared_r_seas", "est_shared_r_f", "est_shared_seas_f" Shared across the named pair of dimensions
"est_shared_r_seas_f" A single parameter shared across everything
"fix" Held at its starting value (not estimated)

Which dimension abbreviations are valid, and in what order they can be combined, depends on the specific parameter (see each section below for its abbreviations, e.g. sigmaC_spec additionally has a y (year) dimension). sigmaF_spec, sigmaC_spec, sigmaR_spec, and Fdev_rho_spec all follow this convention via a single shared internal helper (build_pe_map/build_shared_spec_map), so they behave identically. Other _spec arguments using the same string vocabulary (e.g. sigmaC_pop_spec, and selectivity’s fish_fixed_sel_pars_spec, fishsel_pe_pars_spec, fish_sel_devs_spec, and their retention/survey equivalents) are implemented separately with their own hand-written logic, and some additionally support a fleet-sharing escape hatch, "est_shared_f_<n>", which copies the sharing structure of fleet <n> wholesale rather than collapsing a dimension.


Spatial and Demographic Structure

Everything starts with Setup_Mod_Dim() (estimation model) or Setup_Sim_Dim() (operating model; simulation). These functions define the skeleton that every subsequent setup call validates against.

Core dimensions

Argument Type Description
years integer vector Calendar years included in the assessment (length determines nyn_y)
ages integer vector Modelled age classes; the final element is the plus group
lens numeric vector or NULL Length-bin midpoints; NULL disables length-based features
n_regions integer Spatial regions
n_sexes integer 1 (aggregated) or 2 (sex-structured)
n_fish_fleets integer Fishery fleets
n_srv_fleets integer Survey fleets

Multi-population structure

SPoRC decouples biological populations from spatial regions. Populations have their own stock–recruit dynamics and natal assignment; regions define the arena through which all populations move.

Argument Type Description
n_pop integer Number of biological populations (default 1)
natal_region integer vector (length n_pop) Maps each population to its home region. Inferred automatically when n_pop == n_regions (one-to-one) or n_regions == 1 (all share region 1). Must be supplied explicitly otherwise

When n_pop > n_regions, multiple populations share a natal region — a contingent-population or mixed-stock structure. When n_pop < n_regions, the model represents a single population spread across more regions than there are spawning origins.

Seasonal sub-stepping

Argument Type Description
n_seas integer Seasons per year (default 1)
seasdur numeric vector (length n_seas) Duration of each season as a fraction of the year (must sum to 1). Defaults to equal-length seasons

Within each year, processes execute in sequence: recruitment → movement → mortality (with age advancement at the end of the final season).

Other dimension controls (EM only)

Argument Description
n_proj_yrs_devs How many projection-year slots to pre-allocate for deviation parameters (ln_RecDevs, move_devs, selectivity deviations). Default 0
store_config If TRUE, archives all Setup_Mod_* arguments inside input_list$config for reproducibility

Additional simulation dimensions (OM only)

Argument Description
n_sims Number of Monte Carlo replicates
n_yrs Projection horizon (years)
n_obs_ages Number of observed age bins (can differ from n_ages when compositions pool ages differently)
run_feedback TRUE for closed-loop MSE; FALSE (default) for open-loop simulation
feedback_start_yr First year of feedback when run_feedback = TRUE

Population Initialisation

Controlled via Setup_Mod_Rec() (argument init_age_strc) and Setup_Sim_Rec().

SPoRC offers four methods for deriving equilibrium numbers-at-age. All methods project a constant recruitment (R0R_0, or a separate ln_rinit scalar when use_rinit = 1) through seasonal mortality, fishing, and (optionally) movement until the age structure stabilises. After the equilibrium is computed, multiplicative log-scale initial deviations (ln_InitDevs) are applied to ages 2,,A2, \ldots, A.

When use_rinit = 1, the regional recruitment scalar feeding the equilibrium calculation is bias-corrected: ζp,rrinitpexp(σRec,early2/2)\zeta_{p,r}\,\text{rinit}_p\exp(-\sigma_{\text{Rec,early}}^2/2), treating ln_rinit as the median of the assumed lognormal recruitment process and converting to the corresponding mean before it is used as a deterministic (non-stochastic) equilibrium seed. This mirrors the same correction applied to Setup_Sim_Rec()’s equivalent rinit_input pathway during simulation, so fitted and simulated equilibria remain on a consistent scale.

Equilibrium solution method (init_age_strc)

Value String How the equilibrium is solved
0 "iterative" Brute-force iteration: runs the full seasonal cycle nages×10n_\text{ages} \times 10 times
1 "scalar_no_move" Closed-form geometric series assuming no movement at any age. Plus group: NA+=NA1eZA1/(1eZA+)N_{A^+} = N_{A-1} e^{-Z_{A-1}} / (1 - e^{-Z_{A^+}})
2 "matrix" Builds seasonal transition matrices 𝐓a=τ𝐌a,τ𝐒a,τ\mathbf{T}_a = \prod_\tau \mathbf{M}_{a,\tau} \mathbf{S}_{a,\tau} that combine movement and survival, then solves 𝐍A+=(𝐈𝐓A+)1𝐓A1𝐍A1\mathbf{N}_{A^+} = (\mathbf{I} - \mathbf{T}_{A^+})^{-1} \mathbf{T}_{A-1} \mathbf{N}_{A-1}. Default
3 "scalar_plus_only" Hybrid: uses the matrix approach for ages below the plus group but switches to the scalar geometric-series for the plus group itself

Initial deviation structure (equil_init_age_strc)

Value String Which ages receive initial deviations
0 "equil" None — strict equilibrium
1 "stoch_no_plus" All ages except the plus group. Default
2 "stoch_all" All ages including the plus group
3 "stoch_shared_ages" User-defined age sharing via init_age_devs_shared

init_F_prop (array [n_regions × n_seas × n_fish_fleets]) optionally introduces fishing mortality into the equilibrium calculation, producing a fished initial condition.


Recruitment

Controlled via Setup_Mod_Rec() (EM) or Setup_Sim_Rec() (OM).

Stock–recruit function (rec_model)

String Description
"mean_rec" Estimate mean lnR0\ln R_0 with annual deviations; no SSB feedback
"bh_rec" Beverton–Holt: R=4hR0SSB/[(1h)S0+(5h1)SSB]R = 4hR_0 \cdot \text{SSB} / \left[(1-h)S_0 + (5h-1)\text{SSB}\right]. Unfished spawning biomass per recruit (S0S_0) is computed internally by projecting a single recruit through all ages and seasons with movement

Density dependence scope (rec_dd)

String When to use
"local" SSB and S0S_0 computed per population and/or per region. Required when n_pop > 1 with BH recruitment
"global" SSB summed across all regions before entering the SRR. Single-population only

Spawning timing

Argument Description
spawn_seas Season index in which spawning occurs
t_spawn Fraction of the spawning season elapsed before spawning occurs (0 = start, 0.5 = midpoint)
rec_lag Delay (in seasons) between spawning and recruitment entry. 1 (default): recruitment driven by SSB from rec_lag seasons prior, may enter in any season. 0: age-0 recruitment – recruitment driven by that same year’s own SSB. Since that SSB isn’t known until spawn_seas is reached, recruits may only enter in spawn_seas itself or a later season in the same year (rec_seas_prop must be zero for every season before spawn_seas), and the recruit age class must have zero maturity everywhere

Recruitment allocation

Argument Description
rec_region_prop_spec How regional recruitment proportions are estimated/fixed
rec_seas_prop_spec How seasonal recruitment proportions are estimated. Default "fix" (all recruitment enters in season 1)
sexratio_spec Sex ratio at recruitment estimation. Default "fix" (equal or user-supplied)
sexratio_blocks Time blocks for sex-ratio parameters, specified as "none_Pop_<p>_Region_<r>" or "Block_<b>_Year_<s>-<e>_Pop_<p>_Region_<r>"

Recruitment and Initial age deviations

Argument Description
RecDevs_spec Estimation structure for annual ln(RecDevs)\ln(\text{RecDevs})
InitDevs_spec Estimation structure for initial age deviations
sigmaR_spec Recruitment variability: "est_all", "fix_early_est_late", "est_shared_all", "fix"
sigmaR_switch Year index separating the early and late σR\sigma_R periods
do_rec_bias_ramp Methot & Taylor bias adjustment (0 = off, 1 = on)
bias_year, max_bias_ramp_fct Bias ramp breakpoints and maximum correction factor
dont_est_recdev_last Number of terminal-year recruitment deviations to fix at zero
init_age_devs_shared Integer vector of length n_ages - 1 specifying age-sharing for ln_InitDevs. Positions with the same value share a single estimated parameter (e.g. c(1:42, rep(42, 9))). Required when equil_init_age_strc = 3; NULL (default) uses standard behaviour
use_rinit 0 = population initialised using ln_global_R0 (default); 1 = separate ln_rinit used for initialisation, with ln_global_R0 governing only the recruitment relationship.

Steepness priors

When rec_model = "bh_rec", steepness (hh) can be penalised with a Beta distribution scaled to [0.2, 1]:

Argument Description
Use_h_prior 0 = no prior, 1 = apply prior
h_prior Data frame with columns pop, region, mu, sd
h_spec Estimation structure for steepness parameters

R0 priors

A lognormal prior on R0R_0 can be applied per population:

Argument Description
use_r0_prior 0 = no prior (default), 1 = apply lognormal prior on lnR0\ln R_0
r0_prior Data frame with columns pop (population index), mu (prior mean on natural scale), and sd (prior SD on log scale). Required when use_r0_prior = 1

Population straying

When n_pop > 1, a fraction of recruits produced by population pp can “stray” and recruit into regions associated with other populations.

Argument Description
stray_rate_spec "fix" (default), "est_all", etc.
stray_rate_blocks Time blocks: "none_Pop_<p>" or "Block_<b>_Year_<s>-<e>_Pop_<p>"
use_stray_rate_prior 0/1 toggle for Beta priors on stray rates
stray_rate_prior Data frame with columns pop, block, mu (in (0,1)), sd

Spawning movement (single-season, multi-population)

When n_pop > 1 and n_seas == 1, individuals cannot physically move to their natal region within the seasonal cycle, so a separate spawning-movement matrix (sgl_seas_spawning_movement) routes SSB back to natal regions for the SRR calculation. If not supplied, SPoRC defaults to 100% natal homing.


Selectivity

Selectivity configuration is shared across fishery fleets (Setup_Mod_Fishsel_and_Q()), survey fleets (Setup_Mod_Srvsel_and_Q()), and retention curves (ret_sel_model within Setup_Mod_Fishsel_and_Q()). All three accept the same functional forms and time-varying structures.

Functional forms

Specified as character strings following the pattern "<form>_Fleet_<f>" (constant across all time blocks) or "<form>_Fleet_<f>_Block_<b>" (block-specific). The available forms are:

String Functional form Free parameters
"logist1" Ascending logistic: 1/(1+exp(k(bina50)))1 / (1 + \exp(-k(\text{bin} - a_{50}))) 2 (lna50\ln a_{50}, lnk\ln k)
"logist2" Ascending logistic using a50a_{50} and a95a_{95}: 1/(1+19(a50bin)/a95)1 / (1 + 19^{(a_{50} - \text{bin})/a_{95}}) 2 (lna50\ln a_{50}, lna95\ln a_{95})
"gamma" Dome-shaped gamma: (b/amax)amax/pexp((amaxb)/p)(b/a_\text{max})^{a_\text{max}/p} \exp((a_\text{max} - b)/p) 2 (lnamax\ln a_\text{max}, lnδ\ln \delta)
"exponential" Descending power: 1/binβ1/\text{bin}^\beta 1 (lnβ\ln \beta)
"dbnrml" Double-normal with ascending and descending widths, plateau, and endpoint control 6
"nonpar" Non-parametric: one logit-scale parameter per bin, transformed via logit1\text{logit}^{-1} nbinsn_\text{bins}
"asymplogist1" Logistic with asymptote α(0,1)\alpha \in (0,1): α/(1+exp(k(bina50)))\alpha / (1 + \exp(-k(\text{bin} - a_{50}))) 3 (logit(α)\text{logit}(\alpha), lna50\ln a_{50}, lnk\ln k)
"asymplogist2" Logistic with asymptote, a50/a95a_{50}/a_{95} parameterisation 3 (logit(α)\text{logit}(\alpha), lna50\ln a_{50}, lna95\ln a_{95})
"bicubic" Bicubic natural-cubic-spline surface over a bin-node ×\times year-node grid nbin_nodes×nyr_nodesn_\text{bin\_nodes} \times n_\text{yr\_nodes} (see below)

Bicubic spline selectivity ("bicubic")

Unlike the other functional forms above, "bicubic" selectivity is specified with its own extended syntax:

"bicubic_Bin_<n_bin_nodes>_Yr_<n_yr_nodes>_Fleet_<f>[_Block_<b>][_SelStyr_<year>][_NSelBins_<n>]"

A smooth 2-dimensional selectivity-at-bin-and-year surface is built from a small grid of nbin_nodes×nyr_nodesn_\text{bin\_nodes} \times n_\text{yr\_nodes} freely estimated log-scale node values (fish_fixed_sel_pars / srv_fixed_sel_pars, flattened column-major into a [yr_node × bin_node] matrix). Two natural-cubic-spline weight matrices are precomputed once at setup:

  • 𝐖bin\mathbf{W}^{\text{bin}} (nbins×nbin_nodesn_\text{bins} \times n_\text{bin\_nodes}), mapping bin-node values onto every bin,
  • 𝐖yr\mathbf{W}^{\text{yr}} (nyrs×nyr_nodesn_\text{yrs} \times n_\text{yr\_nodes}), mapping year-node values onto every year,

and combined via a two-pass tensor product (bin-node values spline-interpolated across bins for every year-node, then those curves spline-interpolated across years) to give the full log-selectivity surface, which is then exponentiated. Setting n_yr_nodes = 1 collapses the surface to a time-invariant bin-only spline; combining n_yr_nodes = 1 with fish_sel_blocks/srv_sel_blocks re-fits an independent bin-only spline within each block.

Two optional suffixes restrict the fitted region of the surface, edge-holding (flat-lining) outside it:

  • _SelStyr_<year>: a calendar year within the block. Only years from SelStyr through the block’s end are actually spline-fit across the year dimension; years within the block before SelStyr are held constant at the SelStyr year’s fitted curve (“previous years are filled”).
  • _NSelBins_<n>: restricts the spline fit to the first n bins (ages or lengths, per fish_selex_type/srv_selex_type). Bins beyond n are held constant at the last fitted bin’s value (a plateau), rather than continuing the spline extrapolation.

Both suffixes only change which years/bins are considered part of the fitted surface; they do not change the total number of estimated node parameters.

Temporal variation

SPoRC provides two mutually exclusive mechanisms for time-varying selectivity within a fleet. You can use discrete blocks or continuous deviations, but not both on the same fleet.

Discrete blocks (fish_sel_blocks / srv_sel_blocks / ret_sel_blocks): defined as "Block_<b>_Year_<s>-<e>_Fleet_<f>" or "Block_<b>_Year_<s>-terminal_Fleet_<f>". Blocks must be non-overlapping and collectively span all model years. Each block gets its own set of fixed-effect selectivity parameters (and can even use a different functional form).

Continuous deviations (cont_tv_fish_sel / cont_tv_srv_sel / cont_tv_ret_sel): specified as "<type>_Fleet_<f>". For parametric forms ("logist1", "gamma", etc.), IID and random-walk deviations act multiplicatively on the transformed base parameters. For semi-parametric forms ("3dmarg", "3dcond", "2dar1"), deviations act multiplicatively on the selectivity curve at the bin level.

String Description
"none" Time-invariant (default)
"iid" Independent annual deviations on selectivity parameters
"rw" Random walk on selectivity parameters
"3dmarg" 3D Gaussian Markov random field — marginal variance parameterisation
"3dcond" 3D GMRF — conditional variance parameterisation
"2dar1" Separable 2D AR(1) over bin × year

Ancillary controls for continuous time-variation include fishsel_pe_pars_spec (hyperparameter estimation), fish_sel_devs_spec (deviation estimation structure), fishsel_devs_shared_bins (bin grouping for shared deviations), and corr_opt_semipar (which correlation components to suppress in semi-parametric forms).

Parameter sharing and fixing

The fish_fixed_sel_pars_spec / srv_fixed_sel_pars_spec argument controls how base selectivity parameters are estimated:

String Meaning
"est_all" Fully region-, sex-, and fleet-specific
"est_shared_r" Shared across regions
"est_shared_s" Shared across sexes
"est_shared_r_s" Shared across both regions and sexes
"fix" Fixed at starting values

Normalisation and length-based selectivity

Selectivity can be normalised relative to a specific bin, to the maximum, or to the mean across a bin range. When fit_lengths = 1, selectivity operates on length bins and is mapped to age-space via a user-supplied size–age transition matrix (SizeAgeTrans).

Selectivity priors

Lognormal priors on selectivity parameters are toggled via Use_fish_selex_prior / Use_srv_selex_prior, with hyperparameters supplied in a data frame (fish_selex_prior / srv_selex_prior) containing region, fleet, block, sex, par, mu, and sd.

Selectivity smoothness penalty weights

All selectivity smoothness/regularisation penalty weights are configured in a single place, Setup_Mod_Weighting(), via the fish_sel_pen_wts, ret_sel_pen_wts, and srv_sel_pen_wts arguments (one list per selectivity surface). Each is a named list/vector; unset names default to 0 (off), except the three legacy terms below, whose default (1 if any deviation-based penalty is active, 0 otherwise) reproduces pre-existing behaviour when pen_wts = NULL.

Name Applies to Description
yr_devs Continuous time-varying deviations (cont_tv_*_sel, process error models 1–2) First-difference penalty across years on deviation parameters
bin_curve Semi-parametric deviations (process error models 3–5) Second-difference (curvature) penalty across bins on log-selectivity
yr_curve Semi-parametric deviations (process error models 3–5) Second-difference (curvature) penalty across years on log-selectivity
smooth_dome Any selectivity form (see below) Hinge penalty discouraging decreases across adjacent bins (dome-shape control)
smooth_bin_curve Any selectivity form (see below) Second-difference penalty across bins, normalised by the number of fitted bins
smooth_bin_diff Any selectivity form (see below) Unconditional first-difference penalty across bins (both increases and decreases contribute, unlike smooth_dome), normalised by the number of fitted bins
smooth_yr_diff Any selectivity form (see below) First-difference penalty across years, normalised by the number of fitted years
smooth_yr_curve Any selectivity form (see below) Second-difference penalty across years, normalised by the number of fitted years
smooth_mean_center Any selectivity form (see below) Penalises the per-year mean of log-selectivity away from zero; resolves the scale indeterminacy of the bicubic surface (a uniform per-year shift in log-selectivity otherwise trades off exactly against that year’s fishing mortality)

The six smooth_* terms are evaluated directly on a fleet’s realized selectivity-at-bin-at-year surface.


Catchability

Configured alongside selectivity in Setup_Mod_Fishsel_and_Q() / Setup_Mod_Srvsel_and_Q().

Estimation structure (fish_q_spec / srv_q_spec)

String Description
"est_all" Free parameter for each region × fleet combination
"est_shared_r" One parameter shared across regions (per fleet)
"fix" Held at user-supplied value

Time blocks (fish_q_blocks / srv_q_blocks)

Same syntax as selectivity blocks: "none_Fleet_<f>" for a single block, or "Block_<b>_Year_<s>-<e>_Fleet_<f>" for structured change points.

Priors

Argument Description
Use_fish_q_prior / Use_srv_q_prior 0/1 toggle
fish_q_prior / srv_q_prior Data frame with region, fleet, block, mu (natural scale), sd (log scale). Penalty: Normal(ln(μ),σ)\text{Normal}(\ln(\mu), \sigma)

Natural Mortality

Controlled via Setup_Mod_Biologicals().

Estimation vs. fixing (M_spec)

String Description
"est_ln_M" Estimate lnM\ln M across the defined block structure
"fix" Fix at values supplied via Fixed_natmort (array [p × r × y × a × s])

Block structure

Natural mortality parameters can be shared or made specific along any combination of five axes. Each argument takes either 'constant' (all levels pooled) or a list of integer vectors defining blocks:

Argument Axis Example
M_popblk_spec Population list(c(1,2), 3) → pops 1–2 share MM, pop 3 is separate
M_regionblk_spec Region list(1:3, 4:5)
M_yearblk_spec Year list(1:20, 21:40)
M_ageblk_spec Age list(1:5, 6:30) → young vs. old
M_sexblk_spec Sex list(1, 2) → sex-specific MM

All block specifications are crossed to produce unique MM parameters. For instance, two age blocks × two sex blocks = four estimated lnM\ln M values (assuming everything else is 'constant').

Priors

Lognormal priors on MM are activated via Use_M_prior = 1, supplying a data frame with columns popblk, regionblk, yearblk, ageblk, sexblk, mu, and sd.


Movement

Configured via Setup_Mod_Movement() (EM) or Setup_Sim_Movement() (OM).

SPoRC implements two movement parameterisations, plus a fixed-matrix escape hatch.

Movement type (move_type)

Value Description
0 Unstructured Markov. Transition probabilities estimated via multinomial logit (softmax), with region 1 as the implicit reference category. Supports blocking along population, age, year, season, and sex dimensions
1 CTMC. A continuous-time Markov chain builds an instantaneous rate matrix Q=D+ZQ = D + Z from diffusion (DD, isotropic dispersal scaled by region area) and taxis (ZZ, directional preference). Transition probabilities are obtained by matrix exponentiation: 𝐏=exp(Q)\mathbf{P} = \exp(Q)

Fixed movement (use_fixed_movement = 1)

Bypasses estimation entirely. Supply Fixed_Movement as an array [p × r_\text{from} × r_\text{to} × y × \tau × a × s].

Unstructured Markov block structure (move_type = 0)

Each dimension can be pooled ('constant') or blocked:

Argument Description
Movement_popblk_spec Population blocks
Movement_ageblk_spec Age blocks (e.g., list(1:5, 6:30) for age-dependent movement)
Movement_yearblk_spec Year blocks
Movement_seasblk_spec Season blocks
Movement_sexblk_spec Sex blocks

CTMC configuration (move_type = 1)

Argument Description
ctmc_move_dat Data frame of covariates with required columns pop, regions, years, seas, ages, sexes, plus any variables referenced in the formulas. For projection years, covariate lookups are capped at the last historical year unless extended rows are supplied
diffusion_formula R formula for diffusion (e.g., ~ 1, ~ bs(years, df = 4))
preference_formula R formula for taxis/preference
adjacency_mat Square [n_regions × n_regions] binary connectivity matrix
area_r Numeric vector of region areas (scales diffusion rates)
ctmc_diffusion_bounds 0/1: if 1, shifts diffusion columns to guarantee all off-diagonal generator-matrix entries are non-negative

Continuous movement deviations (cont_vary_movement)

Origin–destination deviations applied multiplicatively to off-diagonal rates (CTMC) or additively on the logit scale (unstructured).

String Deviation structure
"none" No deviations (default)
"iid_y" Year only
"iid_a" Age only
"iid_y_a" Year × age
"iid_y_a_s" Year × age × sex
"iid_y_seas_a_s" Year × season × age × sex
"iid_p_y" Population × year
"iid_p_a" Population × age
"iid_p_y_a" Population × year × age
"iid_p_y_a_s" Population × year × age × sex
"iid_p_y_seas_a_s" Population × year × season × age × sex

Additional movement controls

Argument Description
do_recruits_move 0 = age-1 fish do not move; 1 = recruits follow the movement matrix
Use_Movement_Prior 0/1 toggle for Dirichlet movement priors (unstructured)
Movement_prior Data frame with pop, region_from, year, seas, age, sex, alpha (Dirichlet concentration vector of length n_regions)
Movement_cont_pe_pars_spec Estimation structure for process-error hyperparameters: "none", "fix", "est_all", "est_shared"

Catch, Fishing Mortality, and Discards

Configured via Setup_Mod_Catch_and_F().

Catch conditioning

Argument Description
ObsCatch Observed aggregate catch [r × y × τ × f]
ObsCatch_pop Population-specific catch [p × r × y × τ × f]
catch_units Per-fleet: 0 = abundance, 1 = biomass
Use_F_pen 0/1 toggle for the fishing mortality deviation penalty (Fmort_nLL)
sigmaC_spec / sigmaC_pop_spec Catch observation-error estimation

Fishing mortality process error

ln_F_devs (annual log-scale deviations about ln_F_mean) can follow one of three process-error structures, set via Fdev_model:

String Description
"iid" Independent annual deviations (default)
"rw" Random walk
"ar1" First-order autoregressive

sigmaF_spec controls sharing/fixing of the process-error standard deviation (ln_sigmaF) across region × season × fleet, using the same "est_all" / "est_shared_<dims>" / "fix" convention described in Parameter sharing conventions. Fdev_rho_spec analogously controls the AR1 correlation parameter (Fdev_rho) and is only active when Fdev_model = "ar1"; for "iid" or "rw", Fdev_rho is unused and mapped to NA regardless of what is supplied.

Catch-active years (UseCatch == 1 or any UseCatch_pop == 1) do not need to be contiguous under "rw" or "ar1" — a fishery may close for several years and reopen later. The transition between two active years separated by a gap of dd closed years is taken directly over the elapsed gap (the same marginal transition obtained by estimating deviations for the closed years and integrating them out, without actually estimating them). See [Fishing Mortality Deviations] in vignette("c_model_equations") for the exact equations.

Discard and retention framework

SPoRC decomposes total fishing mortality at age into retained and dead-discard components:

Fp,r,τ,a,s=fFr,τ,f[sela,freta,fretained+sela,f(1reta,f)dmrfdead discards]F_{p,r,\tau,a,s} = \sum_f F_{r,\tau,f} \left[\underbrace{\text{sel}_{a,f} \cdot \text{ret}_{a,f}}_{\text{retained}} + \underbrace{\text{sel}_{a,f} \cdot (1 - \text{ret}_{a,f}) \cdot \text{dmr}_f}_{\text{dead discards}}\right]

Argument Description
ret_sel_model Retention selectivity functional form (same options as fish_sel_model)
ret_sel_blocks Retention selectivity time blocks
cont_tv_ret_sel Continuous time-varying retention selectivity
dmr_mean_spec Estimation structure for dead discard mortality rate means
dmr_dev_spec Estimation structure for DMR deviations
discard_units Per-fleet: 0 = abundance, 1 = biomass, 2 = abundance fraction, 3 = biomass fraction
ObsDiscard / ObsDiscard_pop Observed aggregate and population-specific discards
sigmaD_spec / sigmaD_pop_spec Discard observation-error estimation

Biological Inputs

Supplied via Setup_Mod_Biologicals() (EM) or Setup_Sim_Biologicals() (OM).

Input Dimensions Description
WAA [p × r × y × τ × a × s] Spawning weight-at-age (used for SSB)
WAA_fish [p × r × y × τ × a × s × f] Fishery-specific weight-at-age. Defaults to WAA if NULL
WAA_srv [p × r × y × τ × a × s × f] Survey-specific weight-at-age. Defaults to WAA if NULL
MatAA [p × r × y × τ × a × s] Maturity-at-age (proportions in [0, 1])
AgeingError [a_\text{model} × a_\text{obs}] or [y × a_\text{model} × a_\text{obs}] Row-stochastic matrix mapping true ages to observed bins. Defaults to identity. Supply explicitly when observed ages are a subset of modelled ages
SizeAgeTrans [p × r × y × τ × l × a × s] Size–age transition matrix. Required when fit_lengths = 1
fit_lengths 0/1 Toggle for fitting length compositions

Observation Model: Indices and Compositions

Indices and compositions are configured together for fishery fleets (Setup_Mod_FishIdx_and_Comps()) and survey fleets (Setup_Mod_SrvIdx_and_Comps()).

Indices of abundance

Argument Description
ObsFishIdx / ObsSrvIdx Observed index values
ObsFishIdx_SE / ObsSrvIdx_SE Log-scale standard errors
fish_idx_type / srv_idx_type 0 = abundance, 1 = biomass
ObsFishIdx_pop / ObsSrvIdx_pop Population-specific indices (separate likelihood contribution)
ObsFishIdx_pop_SE / ObsSrvIdx_pop_SE Population-specific index SEs

Composition likelihood families

Age and length compositions each accept one of five likelihood families:

Value Likelihood
0 Multinomial
1 Dirichlet–multinomial (overdispersion parameter θ\theta estimated per fleet)
2 Logistic-normal, independent bins
3 Logistic-normal with AR(1) correlation across bins
4 Logistic-normal with AR(1) bin correlation and constant cross-sex correlation

These are set per data stream via comp_fishage_like, comp_fishlen_like, comp_srvage_like, comp_srvlen_like, and their _pop and _discard variants.

Composition structure types

Each composition data stream has a “type” controlling how data are aggregated:

Value Structure
0 Aggregated across sexes and regions
1 Split by sex and region (no implicit sex-ratio information)
2 Joint across sexes, split by region (preserves sex-ratio information)
999 No data for this fleet/year

Data streams

SPoRC supports a full matrix of composition data streams, each independently configurable:

Category Aggregate Population-specific
Fishery age comp_fishage_like comp_fishage_pop_like
Fishery length comp_fishlen_like comp_fishlen_pop_like
Fishery discard age comp_fishage_discard_like comp_fishage_discard_pop_like
Fishery discard length comp_fishlen_discard_like comp_fishlen_discard_pop_like
Survey age comp_srvage_like comp_srvage_pop_like
Survey length comp_srvlen_like comp_srvlen_pop_like

Each stream carries its own ISS arrays, θ\theta parameters (log-scale overdispersion), and correlation parameters.


Tagging

Configured via Setup_Mod_Tagging() (EM) or Setup_Sim_Tagging() (OM).

SPoRC implements a conventional mark–recapture framework (Brownie-type likelihood) where tagged individuals follow the full seasonal population dynamics — movement, mortality, and fishing — after release.

Feature Description
Release structure Tags released by population, region, season, age, and sex
Recapture structure Fleet-specific recaptures with release-cohort × recapture-year likelihood
Tag shedding Chronic tag-loss rate (estimated or fixed)
Initial tag mortality Immediate post-release mortality parameter
Reporting rates Fleet-specific tag-reporting rates (estimated or fixed)
Population/age/sex attribution Tags can carry population, age, and sex information at release

Reference Points

Computed post-estimation via Get_Reference_Points().

The function accepts a type argument for spatial structure and a what argument for the reference-point method. All methods project a single recruit through the full age, season, and spatial structure to compute SBPR and YPR.

Available methods

type what Description Multi-pop?
"single_region" "SPR" FSPRxF_{\text{SPR}_x} — no movement
"single_region" "BH_MSY" Beverton–Holt FMSYF_\text{MSY} — no movement
"multi_region" "independent_SPR" Per-region FSPRxF_{\text{SPR}_x} ignoring movement
"multi_region" "independent_BH_MSY" Per-region FMSYF_\text{MSY} ignoring movement
"multi_region" "global_SPR" Single FSPRxF_{\text{SPR}_x} applied uniformly across regions, with movement
"multi_region" "global_BH_MSY" Single FMSYF_\text{MSY} with movement (single-pop only)
"multi_region" "local_BH_MSY" Region-specific FMSYF_\text{MSY} values jointly maximising total yield under movement. Uses Newton–Raphson to solve equilibrium recruitment by origin

Controls

Argument Description
SPR_x Target SPR fraction (e.g., 0.4 for B40%B_{40\%})
n_avg_yrs Terminal years to average demographic rates (selectivity, MM, WAA, maturity, movement)
calc_rec_st_yr First year for computing mean historical recruitment
rec_age Recruitment lag used to exclude most-recent years from the mean
is_discard_fleet Integer vector (per fleet) flagging discard-only fleets to exclude from landed yield in MSY calculations
local_bh_msy_newton_steps Newton iterations for the local FMSYF_\text{MSY} solve (default 6)

Simulation and Closed-Loop MSE

The operating-model side uses a parallel set of Setup_Sim_* functions that mirror the estimation-model pipeline but populate a sim_list rather than input_list. Key simulation-specific functions:

Function Purpose
Simulate_Pop_Static() Forward-project the OM without feedback (open-loop)
condition_closed_loop_simulations() Closed-loop MSE: periodically re-fits the EM, applies an HCR, and updates FF
simulation_data_to_SPoRC() Converts OM output (with observation error) to input_list format for the EM
simulation_self_test() Simulation–estimation test: fits the EM back to OM-generated data
get_closed_loop_reference_points() Computes reference points inside the MSE feedback loop

Key closed-loop arguments in condition_closed_loop_simulations():

Argument Description
closed_loop_yrs Year range over which feedback is active
assessment_period Frequency of EM re-fitting (e.g., every 2 years)
use_true_values If TRUE, the HCR uses OM-truth instead of EM estimates (perfect-information benchmark)

Estimation and Optimisation

fit_model() constructs the RTMB automatic-differentiation function, optimises via nlminb, and refines with Newton steps.

Argument Default Description
data input_list$data
parameters input_list$par
mapping input_list$map
random NULL Parameter names to marginalise as random effects (Laplace approximation)
newton_loops 3 Post-convergence Newton steps (Δθ=H1g\Delta\theta = -H^{-1}g) to reduce residual gradients
do_optim TRUE FALSE returns the un-optimised MakeADFun object for debugging
nlminb_control list(iter.max = 1e5, eval.max = 1e5, rel.tol = 1e-15) Passed to stats::nlminb

Diagnostics

Function What it does
do_retrospective() Sequentially peels terminal years and re-fits; reports Mohn’s ρ\rho per quantity
do_jitter() Refits from perturbed starting values to test convergence stability
do_likelihood_profile() Profiles the likelihood surface over user-specified parameters
do_francis_reweighting() Computes Francis TA1.8 weights for composition data
run_francis() Iterative Francis reweighting loop (re-fits after each adjustment)
run_osa() / get_osa() One-step-ahead residuals for composition data
do_runs_test() Runs test for serial correlation in residuals
get_model_rep_from_mcmc() Extracts model report quantities across MCMC posterior draws (compatible with adnuts / tmbstan)
marg_AIC() Marginal AIC for models with random effects

Plotting

Function Output
plot_all_basic() Multi-panel diagnostic overview
get_ts_plot() Time series: SSB, recruitment, FF, catch, depletion
get_idx_fits_plot() Index fits (observed vs. predicted)
get_catch_fits_plot() Catch fits
get_comp_prop() Composition fits (bubble plots / proportion plots)
get_selex_plot() Selectivity-at-age or selectivity-at-length
get_biological_plot() WAA, maturity, natural mortality
get_nLL_plot() Likelihood component breakdown
get_retrospective_plot() Retrospective trajectories
get_data_fitted_plot() Data-availability timeline
plot_resids() Residual diagnostics
get_retrospective_relative_difference() Relative difference plots for retrospective analyses

All plotting functions accept either a single fitted model or a list of models for side-by-side comparison.