given_species_params(params) # only what was supplied explicitly
calculated_species_params(params) # only the values mizer filled in
species_params(params) # the complete table (given + calculated)Introduction & Philosophy
A key design feature of the mizer package is that a multi-species size-spectrum model can be set up using only a small amount of information. This is possible because mizer uses allometric scaling relations and size-based feeding rules to choose sensible default values for parameters that are not explicitly provided by the user.
For example, to set up a model using the newMultispeciesParams() function, the user only needs to provide the von Bertalanffy asymptotic sizes (\(w_{\infty}\)) for the species in the community. Almost all other physiological, ecological, and mortality parameters can be automatically filled in using defaults. (See the section on maximum-size parameters below for the distinction between \(w_{\infty}\), \(w_{\text{repro_max}}\) and \(w_{\text{max}}\).)
This vignette details the philosophy, the relationships, and the mathematical derivations behind the default parameter values calculated by mizer. For a description of the model equations themselves, see The General Mizer Size-spectrum Model.
Given and calculated parameters
Because most species parameters can be filled in with defaults, mizer needs to keep track of which values you supplied and which it calculated for you. Every MizerParams object therefore stores two species-parameter data frames: given_species_params holds only the values that were supplied explicitly (by you, or by a wrapper function such as newMultispeciesParams()), while species_params is the full table that the model actually uses, with all the defaults and derived values filled in.
This distinction governs everything in this vignette, because a default is only calculated for a parameter that was not given. Supplying a value therefore switches off not just its own default but any calculation that would have used it as an input. The Dependency Chain below shows, for instance, that age_mat is only used to calculate a default for h. If you give h directly, age_mat is ignored; if you give gamma, the f0 value is ignored; and so on.
Here is a minimal model set up from nothing but a name and an asymptotic size:
params <- newMultispeciesParams(
data.frame(species = "Cod", w_inf = 5000)
)
# The columns that count as "given":
names(given_species_params(params))[1] "species" "w_inf" "n" "p" "w_min"
# Everything else was calculated, for example:
intersect(c("w_mat", "w_min", "h", "gamma", "ks"),
names(calculated_species_params(params)))[1] "w_mat" "h" "gamma" "ks"
Notice that n and p appear among the given parameters even though we did not put them in the data frame. This is deliberate: some species parameters can also be set through arguments to the constructor functions (here the n and p arguments of newMultispeciesParams()), and any species parameter set from such an argument is recorded as given — even when the argument was left at its default value in the function signature. In other words, “given” means “fixed by the way you called the constructor”, not only “typed into the species parameter data frame”. The practical consequence is that these values count as explicit input and so are not silently changed by later recalculations.
(Constructor arguments that do not directly correspond to a species parameter behave differently. For example z0pre and z0exp are used to compute the external mortality parameter z0, which therefore appears among the calculated parameters rather than the given ones.)
For how to change parameters once a model exists — which accessor to assign to, what mizer recalculates when you do, how to protect a calculated value or hand it back, and how to override a size-dependent rate array directly — see the guide to changing model parameters.
Maximum-size parameters
mizer has three species parameters that all describe a “maximum size” but play distinct roles. Keeping them separate avoids a lot of confusion.
-
w_infis the von Bertalanffy asymptotic size of an average individual. It is the required maximum-size parameter and the one from which the other two are derived by default. It is used to constrain the growth rate and to calculate the age at maturity. -
w_repro_maxis the size at which a typical mature individual invests all of its available energy into reproduction (see [setReproduction()]). It is not a hard ceiling on size: not all individuals are mature atw_repro_max, and diffusion in the growth process lets some individuals grow beyond it. It defaults tow_infbut you can set it independently — there is no expectation that it is larger or smaller thanw_inf, because estimates of the von Bertalanffy parameters are often unreliable. -
w_maxis purely a computational boundary. It sets the upper end of the size grid and the range of the plots; it does not by itself stop growth. It defaults to1.5 * w_inf.
A typical (but not enforced) ordering is therefore \(w_{\text{mat}} < w_{\infty} \approx w_{\text{repro_max}} \le w_{\text{max}}\).
For backwards compatibility, if you supply w_max (or w_repro_max) but not w_inf, then w_inf is taken from those columns and an informational message is issued, so models and scripts written for earlier versions of mizer continue to work unchanged.
These parameters have been handled differently over the history of mizer:
- In mizer 1,
w_infwas the only maximum-size parameter. It was both the size at which all growth stopped and the size beyond which no fish existed, and was set to the von Bertalanffy asymptotic size. - In mizer 2,
w_maxwas introduced to acknowledge that real fish can be larger than the von Bertalanffyw_inf. Existing models were upgraded by renamingw_inftow_max, and the use of von Bertalanffy curves was discouraged. Later in the mizer 2 series,w_repro_maxwas added (the size at which mature fish invest all energy into reproduction) once diffusion made it possible for fish to exceed the size at which the growth rate reaches zero, andw_maxbecame just a computational boundary. - In mizer 3, with diffusion fully integrated, von Bertalanffy growth is again the standard way to constrain growth, and
w_infis once more the first-class maximum-size parameter. Fish are allowed to exist beyond the von Bertalanffy asymptotic size because diffusion can take them there.
Species Parameter Defaults Reference Table
When creating a MizerParams object, validSpeciesParams() (and subsequent setup functions like setSearchVolume(), setMaxIntakeRate(), setMetabolicRate(), setExtMort(), and setReproduction()) check the species parameter data frame and fill in missing parameters.
Where defaults live
Each default has a single home: the rate-setting function that uses the parameter. setMetabolicRate() defaults p and k because it is the only function that reads them; setExtMort() defaults z0, z_ext and d; and so on. This matters because the rate setters are also called directly, without going through setParams(), so a setter has to be able to supply the defaults it needs on its own.
Only parameters that no single rate setter owns are defaulted centrally in validSpeciesParams(). That happens for five reasons:
-
several setters read it —
nis used bysetExtDiffusion(),setExtEncounter(),setExtMort(),setMaxIntakeRate(),setReproduction()andsetSearchVolume(); -
only the projection reads it — no setter touches
alpha; it is used when calculating growth and reproduction; -
the size grid is built from it —
w_minandw_maxare needed before any rate setter runs; -
the length-weight conversion needs it —
aandbare used byvalidSpeciesParams()itself to convert lengths such asl_matinto weights; -
it is only used for reporting —
is_background.
A consequence is that validSpeciesParams() applied to a bare data frame returns only the central defaults. The setter-owned columns appear once the model is built, because setParams() calls every rate-setting function.
Below is a reference of the default values and the functions responsible for calculating them:
| Parameter | Description | Default Value / Formula | Function |
|---|---|---|---|
w_max |
Computational upper size boundary | 1.5 * w_inf |
validSpeciesParams() |
w_repro_max |
Size at which a typical mature fish invests all energy in reproduction | w_inf |
validSpeciesParams() |
w_mat |
Size at maturity | w_inf / 4 |
validSpeciesParams() |
w_min |
Egg size / birth size |
0.001 g |
validSpeciesParams() |
alpha |
Assimilation efficiency | 0.6 |
validSpeciesParams() |
n |
Allometric scaling exponent of intake | 3/4 |
validSpeciesParams() |
a |
Length-weight conversion coefficient | 0.01 |
validSpeciesParams() |
b |
Length-weight conversion exponent | 3 |
validSpeciesParams() |
is_background |
Flag indicating background species | FALSE |
validSpeciesParams() |
h |
Maximum intake rate coefficient | Derived from growth/age at maturity (or 30) |
get_h_default() |
gamma |
Search volume coefficient | Derived from target feeding level \(f_0\) | get_gamma_default() |
q |
Exponent of the search volume | lambda - 2 + n |
setSearchVolume() |
f0 |
Target feeding level |
0.6 (or derived from gamma if given) |
get_f0_default() |
fc |
Critical feeding level | 0.2 |
get_ks_default() |
ks |
Standard metabolic rate coefficient | Derived from critical feeding level \(f_c\) | get_ks_default() |
p |
Allometric scaling exponent of metabolism | n |
setMetabolicRate() |
k |
Activity/movement cost coefficient | 0 |
setMetabolicRate() |
z0 |
Constant external mortality rate | z0pre * w_inf^z0exp |
setExtMort() |
z_ext |
Size-dependent external mortality | 0 |
setExtMort() |
d |
Exponent of size-dependent external mortality | n - 1 |
setExtMort() |
E_ext |
External encounter rate | 0 |
setExtEncounter() |
D_ext |
External diffusion rate | 0 |
setExtDiffusion() |
interaction_resource |
Species interaction strength with resource | 1 |
setInteraction() |
erepro |
Reproduction efficiency | 1 |
setReproduction() |
m |
Exponent of the investment into reproduction | 1 |
setReproduction() |
w_mat25 |
Size at which 25% of individuals are mature | w_mat / 3^(1/10) |
setReproduction() |
beta |
Preferred predator/prey mass ratio | 30 |
default_pred_kernel_params() |
sigma |
Width of predation kernel | 2 |
default_pred_kernel_params() |
The Dependency Chain
Calculating the default physiological parameters follows a sequential dependency chain. One parameter value determines the next, starting from basic size parameters and ending with standard metabolic rates:
[w_min, w_mat, age_mat] (Given or from VB parameters)
│
▼
┌───────────────┐
│ h │ (Maximum intake rate coefficient)
└───────┬───────┘
├──────────────────────────┐
▼ ▼
┌───────────────┐ ┌───────────────┐
│ gamma │ │ ks │ (Metabolic rate coefficient)
└───────────────┘ └───────────────┘
(Search volume coefficient)
-
Age at maturity (\(\text{age}_{\text{mat}}\)) is either supplied directly, or derived from von Bertalanffy parameters via
age_mat_vB(). - Maximum intake rate (\(h\)) is calculated from \(\text{age}_{\text{mat}}\), egg size \(w_{\text{min}}\), maturity size \(w_{\text{mat}}\), and the assimilation parameters.
- Search volume (\(\gamma\)) and metabolism (\(k_s\)) are then both computed using the calculated value of \(h\).
Because the chain runs both ways, changing one parameter rarely changes only that one thing: giving age_mat makes h depend on f0, fc and w_mat, and h carries the change on into gamma and ks. The behavioural consequences — in particular why raising h does not change the feeding level — are described under “Chained derivations and the cancellation trap” in the guide to changing model parameters.
Mathematical Derivations
1. Maximum Intake Rate Coefficient (\(h\))
The maximum intake rate coefficient \(h_i\) for species \(i\) is calculated by get_h_default(). The derivation is based on the idea that an average individual must grow from egg size \(w_{\text{min}}\) to maturity size \(w_{\text{mat}}\) in a given time \(\text{age}_{\text{mat}}\) when feeding at a constant feeding level \(f_0\) (which defaults to \(0.6\)).
By definition, the rate of somatic growth is: \[\frac{dw}{dt} = g(w)\]
Prior to maturation, individuals invest nothing in reproduction (\(\psi(w) = 0\)), so growth is equal to the energy available for growth and reproduction \(E_r(w)\): \[g(w) = \max(0, \alpha f(w) h w^n - \text{metab}(w))\]
Under the default assumptions: * The feeding level is constant: \(f(w) = f_0\). * The activity cost is zero: \(k = 0\), so \(\text{metab}(w) = k_s w^p\). * The metabolic exponent equals the intake exponent: \(p = n\).
Substituting these in gives: \[\frac{dw}{dt} = \alpha f_0 h w^n - k_s w^n = (\alpha f_0 h - k_s) w^n\]
We also define the critical feeding level \(f_c\) as the feeding level at which assimilation exactly balances metabolic costs, i.e., \(g(w) = 0\). This implies: \[\alpha f_c h w^n = k_s w^n \implies k_s = \alpha f_c h\]
Using this expression for \(k_s\) in the growth equation yields: \[\frac{dw}{dt} = (\alpha f_0 h - \alpha f_c h) w^n = \alpha h (f_0 - f_c) w^n\]
We can solve this differential equation by separating variables and integrating from birth (\(t = 0\), \(w = w_{\text{min}}\)) to maturity (\(t = \text{age}_{\text{mat}}\), \(w = w_{\text{mat}}\)): \[\int_{w_{\text{min}}}^{w_{\text{mat}}} w^{-n} \, dw = \alpha h (f_0 - f_c) \int_{0}^{\text{age}_{\text{mat}}} dt\]
Evaluating the integrals: \[\frac{w_{\text{mat}}^{1-n} - w_{\text{min}}^{1-n}}{1-n} = \alpha h (f_0 - f_c) \text{age}_{\text{mat}}\]
Solving for \(h\) gives the formula implemented in get_h_default(): \[h = \frac{w_{\text{mat}}^{1-n} - w_{\text{min}}^{1-n}}{\text{age}_{\text{mat}} (1-n) \alpha (f_0 - f_c)}\]
If the age at maturity is not known, mizer attempts to estimate it from von Bertalanffy parameters using: \[\text{age}_{\text{mat}} = - \frac{\ln\left(1 - \left(\frac{w_{\text{mat}}}{w_{\infty}}\right)^{1/b}\right)}{k_{\text{vb}}} + t_0\] If no growth information is provided at all, mizer defaults to \(h = 30\).
2. Search Volume Coefficient (\(\gamma\))
The search volume coefficient \(\gamma_i\) is calculated by get_gamma_default(). It is selected such that if the prey abundance were described by a power-law resource spectrum: \[N_R(w_p) = \kappa w_p^{-\lambda}\] then the resulting encounter rate would lead to the target feeding level \(f_0\) (default \(0.6\)).
This reference encounter contains only predation on the power-law resource. External encounter and functions registered with other_encounter() — including a component’s encounter_fun — still add to the realised encounter rate, but do not enter the calculation of the gamma and f0 defaults.
The encounter rate \(E_i(w)\) of predator species \(i\) at size \(w\) is: \[E_i(w) = \gamma_i w^q \int \theta_{iR} N_R(w_p) \phi_i(w, w_p) w_p \, dw_p\]
Substituting the power-law resource spectrum: \[E_i(w) = \gamma_i w^q \theta_{iR} \kappa \int w_p^{1-\lambda} \phi_i(w, w_p) \, dw_p\]
If the predation kernel depends only on the predator/prey mass ratio \(x = w/w_p\), then we can substitute \(w_p = w/x\) and \(dw_p = -w/x^2 \, dx\): \[\int w_p^{1-\lambda} \phi_i(w/w_p) \, dw_p = w^{2-\lambda} \int_0^\infty x^{\lambda - 2} \phi_i(x) \, dx\]
Thus, the encounter rate scales with size as: \[E_i(w) = \gamma_i w^{q + 2 - \lambda} \theta_{iR} \kappa \int_0^\infty x^{\lambda - 2} \phi_i(x) \, dx\]
Let us define the size-independent component of the encounter rate as: \[A_{\text{avail}, i} = \theta_{iR} \kappa \int_0^\infty x^{\lambda - 2} \phi_i(x) \, dx\] so that \(E_i(w) = \gamma_i w^{q + 2 - \lambda} A_{\text{avail}, i}\).
The feeding level is given by: \[f_i(w) = \frac{E_i(w)}{E_i(w) + h_i w^n}\]
For the feeding level to be independent of size and equal to \(f_0\), we must require the size scaling exponents of encounter and maximum intake to match: \[q + 2 - \lambda = n \implies q = n + \lambda - 2\] When this holds, the size \(w\) cancels out: \[f_0 = \frac{\gamma_i A_{\text{avail}, i}}{\gamma_i A_{\text{avail}, i} + h_i}\]
Solving this equation for \(\gamma_i\) yields: \[\gamma_i = \frac{h_i}{A_{\text{avail}, i}} \frac{f_0}{1 - f_0}\]
In the code, \(A_{\text{avail}, i}\) is calculated numerically by setting \(\gamma_i = 1\) and evaluating the encounter rate at the maximum size grid point divided by the appropriate power of \(w\): \[\text{avail_energy}_i = \frac{E_{i}|_{\gamma_i=1}(w_{\text{max}})}{w_{\text{max}}^{q + 2 - \lambda}}\] Then, the default \(\gamma\) is: \[\gamma_i = \frac{h_i}{\text{avail_energy}_i} \frac{f_0}{1 - f_0}\]
3. Standard Metabolic Rate Coefficient (\(ks\))
The standard metabolic rate coefficient \(k_{s,i}\) is calculated by get_ks_default(). It is chosen so that the critical feeding level \(f_c\) (default \(0.2\)) is exactly the feeding level required for assimilation to balance metabolism at maturity size \(w_{\text{mat}}\).
At the critical feeding level \(f_c\), the assimilation rate equals metabolic losses. At size \(w_{\text{mat}}\): \[\alpha_i f_c h_i w_{\text{mat}}^n = \text{metab}_i(w_{\text{mat}})\]
Using the default metabolic cost equation \(\text{metab}_i(w) = k_{s,i} w^p\) (with activity \(k = 0\)): \[\alpha_i f_c h_i w_{\text{mat}}^n = k_{s,i} w_{\text{mat}}^p\]
Solving for \(k_{s,i}\) gives the formula: \[k_{s,i} = f_c \alpha_i h_i w_{\text{mat}}^{n - p}\]
If \(n = p\), this simplifies to: \[k_{s,i} = f_c \alpha_i h_i\]
4. Target Feeding Level (\(f_0\))
For models where the search volume coefficient \(\gamma_i\) is provided by the user but the target feeding level \(f_0\) is not, get_f0_default() calculates the inverse of the search volume default.
Using the relationship derived above: \[f_{0,i} = \frac{\gamma_i A_{\text{avail}, i}}{\gamma_i A_{\text{avail}, i} + h_i}\] Since the encounter rate calculated with the given \(\gamma_i\) is \(E_i(w) = \gamma_i w^{q+2-\lambda} A_{\text{avail}, i}\), we evaluate: \[\text{avail_energy}_i = \frac{E_i(w_{\text{max}})}{w_{\text{max}}^{q+2-\lambda}}\] And then calculate: \[f_{0,i} = \frac{1}{h_i / \text{avail_energy}_i + 1}\]
Other Defaults
-
External Mortality (\(z_0\)): Background mortality that is not due to predation or fishing. If not specified, it scales allometrically with the asymptotic size: \[z_{0, i} = z_{0\text{pre}} w_{\infty, i}^{z_{0\text{exp}}}\] where \(z_{0\text{pre}}\) defaults to \(0.6\) and \(z_{0\text{exp}}\) defaults to \(n - 1 = -1/3\). The \(n\) here is the model-wide allometric exponent — the
nargument ofnewMultispeciesParams(), which defaults to \(2/3\), and whichsetExtMort()reads back asresource_params(params)$nwhen it is called on its own. It is not the per-speciesncolumn, so overridingnfor an individual species does not change that species’ \(z_{0\text{exp}}\). -
Predation Kernel: By default,
mizeruses a lognormal predation kernel \(\phi_i(w, w_p)\) with preferred predator-prey mass ratio \(\beta = 30\) and width \(\sigma = 2\). - Maturity Ogive: The proportion of individuals mature at size \(w\) is a sigmoidal function: \[\text{maturity}(w) = \frac{1}{1 + (w/w_{\text{mat}})^{-10}}\]
Defaults Editions
Sometimes improved methods for choosing defaults are added to mizer. To prevent older code from changing behaviour unexpectedly when the package is updated, mizer uses a versioning system controlled by the defaults_edition() function.
- Edition 1 (Current default): Historically chosen default relations.
-
Edition 2 (Available): Catchability is set to \(0.3\) (instead of \(1\)), initial fishing effort is \(1\) (instead of \(0\)), initial abundance is calculated using the steady-state solver instead of a simple power law, and
psiis determined strictly by the maturity ogive and the reproductive investment proportion.
Worked Example
The following code illustrates how mizer automatically calculates defaults when setting up a new model with only the species name and asymptotic size:
# Create species parameter data frame with only w_inf specified
simple_species <- data.frame(
species = c("Species A", "Species B"),
w_inf = c(1000, 8000)
)
# Initialize parameters
params <- newMultispeciesParams(simple_species)ℹ No `a` column so using a = 0.01 in w = a l^b, with w in g and l in cm.
ℹ No `b` column so using the isometric default b = 3 in w = a l^b.
ℹ No h provided for some species, so using age at maturity to calculate it.
ℹ Because you have n != p, the default value for `h` is not very good.
ℹ Because the age at maturity is not known, I need to fall back to using
von Bertalanffy parameters, where available.
ℹ For species where no growth information is available the parameter h has been set to h = 30.
ℹ Using z0 = z0pre * w_inf ^ z0exp for calculated z0 values.
ℹ Using f0, h, lambda, kappa and the predation kernel to calculate gamma.
# Inspect the automatically filled species parameters
species_params(params)[, c("species", "w_mat", "w_min", "h", "gamma", "ks")]An object of class "species_params" containing parameters for 2 species:
species w_mat h ks w_min gamma
Species A 250 30 2.994823 0.001 7.214272e-11
Species B 2000 30 2.794269 0.001 7.214272e-11
