This guide gives an overview of how fishing is set up in mizer: gears, selectivity, catchability, and effort. For full documentation of each function, follow the links.
Fishing mortality in mizer is
\[F_{g,i}(w) = S_{g,i}(w)\, Q_{g,i}\, E_g,\]
the product of gear \(g\)’s
selectivity \(S_{g,i}(w)\) for species \(i\) at size \(w\), its catchability
\(Q_{g,i}\) for species \(i\), and its effort \(E_g\). Selectivity and catchability are
configured through the gear_params data
frame and setFishing();
effort is set at run time.
The gear parameter data frame
One row per gear–species combination (a gear that
catches three species contributes three rows). Read and replace the
table with gear_params(params) and
gear_params(params) <- .... Required columns:
| Column | Meaning |
|---|---|
gear |
gear name |
species |
species this row applies to |
sel_func |
name of the selectivity function
(e.g. "sigmoid_length") |
catchability |
scales F for this gear–species pair (default 1) |
Plus one column per parameter of the chosen
sel_func, named exactly like the function’s
argument (see below). Row names follow the pattern
"species, gear".
There is one optional column, yield_observed, holding
the observed annual yield of that gear–species pair in grams per year.
It is not used by any rate calculation; plotYieldObservedVsModel()
sums it over the gears to compare the observations with the model, and
its gear argument restricts that comparison to the catch of
selected gears, for example
plotYieldObservedVsModel(params, gear = "Otter").
Editing an existing gear table. Pull it out, change what you need, and assign it back — the assignment triggers recalculation of the selectivity and catchability arrays:
gp <- gear_params(params)
gp["Cod, Otter", "catchability"] <- 0.8
gear_params(params) <- gp # assignment triggers recalculationSetting one up from scratch. Assign a fresh data
frame with one row per gear–species combination. Only
species is strictly required: gear defaults to
the species name, sel_func to knife_edge,
catchability to 1, and the knife_edge cut-off
to w_mat. You must, however, supply the parameter columns
of whatever sel_func you choose. Here two gears fish cod,
each with its own length-based selectivity:
gear_params(params) <- data.frame(
gear = c("Otter", "Beam"),
species = c("Cod", "Cod"),
sel_func = "sigmoid_length", # recycled to both rows
l50 = c(25, 20), # 50% selected at this length (cm)
l25 = c(20, 15), # 25% selected at this length (cm)
catchability = 1
)This replaces the whole gear table; mizer generates the
"species, gear" row names for you.
If each species is caught by only one gear, you may instead put the
gear columns directly in species_params
when building the model; mizer copies them into
gear_params. Later edits to those
species_params columns will not propagate
— edit gear_params after construction.
Selectivity functions
The selectivity function determines the size-dependence of fishing
mortality. Every selectivity function takes w as its first
argument and returns a value in [0, 1] at each size. Its
other arguments must appear as columns in gear_params.
sel_func |
Parameter column(s) | Shape |
|---|---|---|
knife_edge
(default) |
knife_edge_size |
step from 0 to 1 at that weight (default
w_mat) |
knife_edge_length |
knife_edge_length |
step from 0 to 1 at that length |
sigmoid_length |
l50, l25
|
smooth; lengths (cm) at 50% and 25% selection |
double_sigmoid_length |
l50, l25, l50_right,
l25_right
|
dome-shaped (selects a length band) |
sigmoid_weight |
sigmoidal_weight, sigmoidal_sigma
|
smooth transition in weight |
sigmoid_length is the most commonly used. You can also
supply your own function (first argument w, returns
selectivity at size) and name it in sel_func.
gp <- gear_params(params)
gp$sel_func <- "sigmoid_length"
gp$l50 <- 25 # 50% selected at 25 cm
gp$l25 <- 20 # 25% selected at 20 cm
gear_params(params) <- gpThe selectivity and catchability arrays
Behind the scenes mizer turns the gear_params table into
two numeric arrays, the ones that enter the fishing-mortality formula
directly. You can read them, and — when a sel_func cannot
express the shape you need — set them by hand.
| Function | Returns | Dimensions |
|---|---|---|
catchability(params) |
\(Q_{g,i}\) | gear × species |
selectivity(params) |
\(S_{g,i}(w)\) | gear × species × size |
(getCatchability()
and getSelectivity()
are deprecated aliases of these.) Each has a matching setter that pushes
an array straight into the model (this routes through
setFishing(), so validation still runs):
catchability(params) # gear × species matrix of Q
selectivity(params)["Otter", "Cod", ] # the S curve for one gear–species pair
# Assign a custom selectivity curve that no sel_func produces
sel <- selectivity(params)
sel["Otter", "Cod", ] <- my_curve # length = number of size bins, in [0, 1]
selectivity(params) <- sel # triggers recalculation via setFishing()A direct assignment here is for shapes you cannot obtain from a
selectivity function. Setting an array by hand freezes
it: mizer marks it as manual and stops recalculating it from
gear_params, so later edits to the gear table leave your
array untouched (you will see a message saying so). To discard the
hand-set array and rebuild from gear_params, call
setFishing(params, reset = TRUE).
setFishing()
setFishing(params, selectivity = NULL, catchability = NULL, reset = FALSE, initial_effort = NULL, ...)
recomputes the fishing setup after a change. Assigning
gear_params(params) <- ... already triggers
recalculation, so you usually only call setFishing()
directly when supplying a selectivity or
catchability array, setting a baseline
effort, or rebuilding from scratch:
params <- setFishing(params, initial_effort = c(Otter = 1, Beam = 0.5))
params <- setFishing(params, reset = TRUE) # rebuild arrays from gear_paramsFishing effort
The model stores a baseline effort per gear, used
when project() is
called without an explicit effort argument.
| Function | Use |
|---|---|
initial_effort(params) |
read baseline effort (a named vector) |
initial_effort(params) <- |
set baseline effort |
getEffort(sim) |
effort actually used over time in a simulation |
initial_effort(params) <- c(Industrial = 0, Pelagic = 1, Beam = 0.5, Otter = 0.5)At run time, project() accepts effort in
four forms:
project(params, effort = 1) # scalar: all gears, constant
project(params, effort = c(Otter = 0.5, Beam = 1)) # named vector: per gear, constant
project(params, effort = c(0.5, 1, 0, 0.5)) # vector in gear order, constant
project(params, effort = effort_array) # time × gear array: through timeFor a time-varying scenario, build a time × gear array
with numeric, increasing row names and gear column names:
gears <- names(initial_effort(params))
years <- 2010:2030
effort_array <- array(1, dim = c(length(years), length(gears)),
dimnames = list(time = years, gear = gears))
effort_array[as.character(2020:2030), "Otter"] <- 1.5 # ramp one gear from 2020
sim <- project(params, effort = effort_array)Catchability sets the units of effort
Because \(F = S\,Q\,E\), only the product \(Q\,E\) is pinned down by the fishing mortality — so catchability defines what one unit of effort means. This gives two common conventions:
-
Effort = fishing mortality rate. Set
catchability = 1; then an effort of \(E\) produces \(F = E\) on fully-selected sizes. Simplest when you want to drive the model directly with F values, for example from a stock assessment. - Effort in real-world units (vessel-days, kW-days, …). Fold the conversion into catchability: \(Q\) is the fraction of the selected stock taken per unit of whatever effort you supply. A useful trick is to set each species’ catchability to its \(F\) in a chosen reference year, so an effort of 1 reproduces that year’s fishing mortality and other years’ efforts are relative to it.
Either way, if you rescale catchability you must rescale effort
inversely to keep the same \(F\). This
is why comparing modelled to observed yields with
plotYieldObservedVsModel() depends on the fishing setup
being fixed first.
Inspecting the fishing setup
gear_params(params) # the gear table
catchability(params) # Q array (gear × species)
selectivity(params) # S array (gear × species × size)
initial_effort(params) # baseline effort per gear
plotFMort(params) # realised fishing mortality at size
getFMort(params) # F by species × size
getFMortGear(params) # F by gear × species × size
getYieldGear(sim) # yield by gear (from a MizerSim)getFMort() and
plotFMort()
sum over gears, so a gear with a tiny catchability — a
survey gear you fit against but do not want to fish with — is invisible
in them. Inspect that gear with getFMortGear(),
slicing out its own mortality:
getFMortGear(params)["Survey", , ] # species × size, for one gear onlyQuick reference
# ── Gears and selectivity ─────────────────────────────────────────────────────
gp <- gear_params(params)
gp$sel_func <- "sigmoid_length"
gp$l50 <- 25; gp$l25 <- 20
gp$catchability <- 1
gear_params(params) <- gp
# ── Effort ────────────────────────────────────────────────────────────────────
initial_effort(params) <- c(Otter = 0.5, Beam = 1) # baseline
sim <- project(params, effort = 1) # constant during run
sim <- project(params, effort = effort_array) # time × gear array
# ── Inspect ───────────────────────────────────────────────────────────────────
initial_effort(params)
plotFMort(params)
getFMortGear(params)