Introduction
The sbt package implements the southern bluefin tuna stock assessment model in RTMB (Kristensen et al. 2016; Kristensen 2026). Its public examples use a fully simulated dataset returned by sbt_example_data(), rather than the CCSBT assessment source datasets.
The simulated example retains the dimensions, biological structure, fleet timing, and observation types needed to exercise the ESC31 model. Its catches, indices, compositions, sample sizes, and tagging and close-kin outcomes were simulated. It is therefore useful for learning and testing the complete model, but it is not a CCSBT assessment dataset and its fitted values are not stock assessment results.
Data interfaces
The public example and the private assessment workflow have deliberately different interfaces.
| Interface | Returns | Intended use |
|---|---|---|
sbt_example_data() |
A complete, processed, simulated model-data list | Public examples, vignettes, and tests |
sbtdata::sbt_load_data("2026") |
Frozen source objects for the named release | Authorised assessment work |
get_data(data_in) |
A processed model-data list made from an explicit high-level input list | Assessment configuration and sensitivity analyses |
sbt_fit(data_in = data_in) |
A staged fit containing the processed data and model configuration | Fitting a configured assessment |
The private sbtdata package does not return the processed list used by the model. It returns the individual frozen source objects. The assessment project selects those objects, writes all switches and configuration values explicitly in data_in, and passes that list to get_data() or sbt_fit().
The full assessment configuration belongs in the private assessment repository; it is not reproduced in this public package.
Source datasets and simulated counterparts
The assessment source datasets that were formerly exposed as package-level objects have been removed from sbt. The public example retains a simulated, processed counterpart for every observation stream and biological input needed by the model. The names below are useful when translating a private data_in configuration into the processed list described on this page.
| Private source object | What it supplies | Simulated processed counterpart |
|---|---|---|
length_mean |
Mean length by year, season, and age | length_mu_ysa |
length_sd |
Standard deviation of length by age | length_sd_a |
catch |
Reported catch by year and fishery | catch_obs_ysf |
catch_UA |
Unaccounted catch additions | Included in catch_obs_ysf after processing |
scenarios_surface, scenarios_LL1
|
Historical catch-scenario multipliers | Applied before catch_obs_ysf is created |
POPs |
Parent–offspring matches and comparisons | pop_obs |
paly |
Probability of age given length and year | paly |
HSPs |
Half-sibling matches and comparisons | hsp_obs |
GTs |
Gene-tag releases, samples, and matches | gt_obs |
aerial_survey |
Juvenile aerial-survey observations | aerial_survey |
aerial_cov |
Aerial-survey covariance matrix | aerial_cov |
troll |
Trolling-survey index and uncertainty |
troll_years, troll_obs, and troll_sd
|
cpue |
Longline CPUE index and uncertainty |
cpue_years, cpue_obs, and cpue_sd
|
age_freq |
Fishery age compositions and effective sample sizes |
af_obs, af_n, af_year, and fishery and age bounds |
length_freq |
Fishery and CPUE length compositions |
lf_obs, lf_n, cpue_lfs, and associated year and fishery indices |
tag_reporting |
Conventional-tag reporting rates | tag_rep_rates_ya |
tag_releases |
Conventional-tag releases | tag_release_cta |
tag_recaptures |
Conventional-tag recaptures | tag_recap_ctaa |
The legacy objects POPs_v1, data_csv1, data_labrep1, and data_par1 are also no longer part of the public package. They support historical ADMB comparisons and belong with the private assessment and comparison material, rather than the current public example. Selectivity timing, likelihood switches, priors, bounds, and other model configuration are ordinary elements of the processed list and can be inspected with names(data) below.
The Cape Town procedure controls returned by sbt_ctp_controls() remain public because they define an algorithm; they are not stock-assessment observations.
Simulating the example
The simulated data are generated from an sbt operating model. The model is first evaluated at its generating parameters to obtain expected compositions, abundance indices, tagging outcomes, and close-kin probabilities. Observation error is then applied using the corresponding model sampling distributions: multinomial draws for compositions, lognormal draws for abundance indices, binomial draws for close-kin and gene-tagging outcomes, and Dirichlet-multinomial draws for conventional-tag recaptures. Catch histories and sampling designs are also simulated inputs.
sbt_example_simulate() performs those draws when this page is rendered. Its default reproduces the bundled realisation exactly; supplying a seed produces a new observation realisation from the same operating model. The returned data have already been processed, so they can be supplied directly to sbt_fit().
The simulated population trajectory covers 1931–2025, and the catch histories cover 1952–2025. The data include all major observation types used by the model, including the conventional-tag likelihood.
The catch histories retain broad fleet timing and smooth assessment-like shapes, but use independent round-number fleet totals and reproducible annual perturbations of up to 10%. They do not reproduce observed annual or aggregate catch values.
| Data stream | Processed object | Number of records |
|---|---|---|
| Catch | catch_obs_ysf | 395 |
| CPUE index | cpue_obs | 57 |
| Aerial survey | aerial_survey | 20 |
| Trolling index | troll_obs | 29 |
| Age compositions | af_obs | 88 |
| Fishery length compositions | lf_obs | 213 |
| CPUE length compositions | cpue_lfs | 57 |
| Parent--offspring pairs | pop_obs | 9005 |
| Half-sibling pairs | hsp_obs | 116 |
| Gene tagging | gt_obs | 8 |
| Conventional tagging | tag_release_cta / tag_recap_ctaa | 73 |
The processed object contains the observations alongside the dimensions, indices, biological arrays, switches, and priors required by the RTMB model.
names(data) [1] "last_yr" "M_switch" "age_increase_M"
[4] "length_m50" "length_m95" "paly"
[7] "aerial_survey" "aerial_cov" "harvest_wall_strength"
[10] "harvest_wall_onset" "harvest_wall_ceiling" "harvest_wall_scale"
[13] "removal_switch_f" "sel_min_age_f" "sel_max_age_f"
[16] "sel_end_f" "af_switch" "lf_switch"
[19] "lf_minbin" "cpue_switch" "cpue_a1"
[22] "cpue_a2" "cpue_sel_fishery" "cpue_lf_switch"
[25] "cpue_lf_sel_fishery" "aerial_switch" "troll_switch"
[28] "pop_switch" "hsp_switch" "hsp_false_negative"
[31] "gt_switch" "tag_switch" "tag_var_factor"
[34] "first_yr" "n_year" "n_season"
[37] "min_age" "max_age" "n_age"
[40] "n_length" "n_fishery" "age_a"
[43] "length_mu_ysa" "length_sd_a" "weight_fya"
[46] "first_yr_catch" "first_yr_catch_f" "n_catch"
[49] "catch_year" "catch_obs_ysf" "sel_change_year_fy"
[52] "pop_obs" "hsp_obs" "gt_obs"
[55] "troll_years" "troll_obs" "troll_sd"
[58] "cpue_years" "cpue_obs" "cpue_sd"
[61] "cpue_q_yrs" "cpue_q_years" "af_min_age"
[64] "af_max_age" "n_af" "af_year"
[67] "af_fishery" "af_obs" "af_n"
[70] "dl_l" "alk_ysal" "lf_year"
[73] "lf_fishery" "lf_season" "lf_obs"
[76] "lf_n" "lf_raw" "lf_slices"
[79] "af_sliced" "af_sliced_ysfa" "cpue_lfs"
[82] "cpue_lf_years" "cpue_n" "tag_shed_immediate"
[85] "tag_shed_continuous" "tag_rep_rates_ya" "tag_rel_min_age"
[88] "tag_rel_max_age" "tag_release_cta" "tag_recap_ctaa"
[91] "tag_recap_max_age" "min_K" "n_K"
[94] "n_T" "n_I" "n_J"
[97] "priors"
Fleet structure
The six catch fleets retain the assessment model’s timing and selectivity structure. A seventh selectivity block is used for the CPUE index, but does not have catch.
| Fishery | Main component | Model season | Catch-year accounting |
|---|---|---|---|
| LL1 | Japanese longline | 2 | January–December |
| LL2 | Korean and Taiwanese longline | 2 | January–December |
| LL3 | Other longline | 1 | July–June |
| LL4 | Spawning-ground longline | 1 | July–June |
| Indonesia | Indonesian spawning-ground fishery | 1 | July–June |
| Australia | Surface fishery | 1 | July–June |
| CPUE block | Selectivity used by the CPUE likelihood | 2 | Index year; no catch |
The model season identifies where the fleet operates within the two-step annual population dynamics; it is distinct from the reporting interval for its catch.
Inspecting the processed inputs
The following code converts selected arrays in the processed data list into tidy data frames. The public vignettes no longer rely on package-level source datasets.
Catch and abundance indices
ggplot(catch_plot_data, aes(x = Year, y = Catch)) +
geom_line(colour = fit_expected_colour, linewidth = 0.45) +
facet_wrap(~Fishery, scales = "free_y", ncol = 2) +
labs(x = "Year", y = "Catch") +
scale_x_continuous(breaks = pretty_breaks()) +
scale_y_continuous(limits = c(0, NA), expand = expansion(mult = c(0, 0.05)))
ggplot(index_plot_data, aes(x = Year, y = Value)) +
geom_line(colour = fit_expected_colour, linewidth = 0.45) +
geom_point(colour = fit_expected_colour, size = 1) +
facet_wrap(~Series, scales = "free_y", ncol = 2) +
labs(x = "Year", y = "Simulated index") +
scale_x_continuous(breaks = pretty_breaks()) +
scale_y_continuous(limits = c(0, NA), expand = expansion(mult = c(0, 0.05)))Composition data
ggplot(length_snapshot, aes(x = Length, y = Proportion, colour = factor(Year))) +
geom_line(linewidth = 0.5) +
facet_wrap(~Fishery, scales = "free_y", ncol = 2) +
labs(x = "Fork length (cm)", y = "Proportion", colour = "Year") +
scale_x_continuous(breaks = pretty_breaks(n = 5)) +
scale_y_continuous(limits = c(0, NA), expand = expansion(mult = c(0, 0.05)))
ggplot(age_snapshot, aes(x = Age, y = Proportion, colour = factor(Year))) +
geom_line(linewidth = 0.55) +
geom_point(size = 0.9) +
facet_wrap(~Fishery, scales = "free_y", ncol = 1) +
labs(x = "Age", y = "Proportion", colour = "Year") +
scale_x_continuous(breaks = pretty_breaks(n = 7)) +
scale_y_continuous(limits = c(0, NA), expand = expansion(mult = c(0, 0.05)))Biological inputs
These plotting functions work directly from the processed model-data list.
plot_length_at_age(data, years = growth_plot_years)
plot_weight_at_age(data, years = growth_plot_years)
plot_paly(data)From data to a fit
Pass the processed simulated object directly to sbt_fit(). The model vignette continues from this point, fits this exact simulated realisation, and compares the fitted relative TRO with the generating truth.
fit <- sbt_fit(data)The full optimisation is deliberately not repeated while rendering the data page. It is run as follows, and the resulting fit is bundled for the model vignette.
fit <- sbt_optimise(
fit,
n_passes = 2L,
control = list(eval.max = 10000L, iter.max = 10000L),
check = TRUE
)






