Releases: sizespectrum/mizer
Release list
mizer 3.2.0
This release overhauls how species and resource parameters are set, makes the
extension framework composable regardless of load order, adds a new
adjustSizeGrid() function and cheatsheets, and includes a range of smaller
improvements and bug fixes.
For an overview see the
release announcement
on the mizer blog.
Resource setting
-
Assigning to
resource_params()(or one of its components, e.g.
resource_params(params)$kappa <- ...) now immediately rebuilds the
size-dependent resource rate (rr_pp) and capacity (cc_pp) arrays from the
scalars, leaving any manually set (frozen) arrays untouched, exactly as
species_params<-feeds the species rates. As a result changing the
rate-side scalarsr_ppornnow takes effect (previously the value was
silently discarded), and successive scalar edits accumulate instead of
overwriting each other. Assigning toresource_params()no longer balances
the resource; balancing to preserve the steady state is now solely a feature
ofsetResource(). -
The
resource_rate<-,resource_capacity<-,resource_level<-and
resource_dynamics<-setters gained abalanceargument (default
unchanged) so it can be switched off, e.g.
resource_capacity(params, balance = FALSE) <- my_capacity. -
setResource()no longer silently overwrites a manually set (frozen) rate
or capacity array when balancing: the frozen array wins and a warning is
issued. The one exception to the frozen-array protection is thatsteady()
will rebalance the resource_capacity in order to return a steady state,
ignoring any freeze.
These changes and how to adapt existing code are described in the new
vignette("upgrading") ("Upgrading mizer").
Species parameter changes
-
Modifying species parameters via
species_params<-()now automatically
detects your changes, records them ingiven_species_paramsso they are
protected from being overwritten by defaults in the future, and silently
triggers the recalculation of any dependent parameters and rate arrays.
Previously,species_params<-()bypassed thegiven_species_params
protection and didn't trigger recalculations. This restores expected
behaviour and makesspecies_params<-()the recommended setter for scripts. -
The
given_species_params<-()setter remains as an explicit alternative
that is particularly useful during interactive sessions, because it issues
warnings if you change a parameter whose effect is overridden by another
parameter that has already been given. -
Each species parameter default now has a single home: the rate-setting
function that uses the parameter.validSpeciesParams()now only fills in
defaults for parameters that no single rate setter owns, namelyw_max,
w_repro_max,w_mat,w_min,alpha,n,a,bandis_background.
The defaults forp,k,z_ext,d,E_ext,D_extand
interaction_resourceare supplied bysetMetabolicRate(),setExtMort(),
setExtEncounter(),setExtDiffusion()andsetInteraction()respectively,
where they were already being set. Built models are unaffected, because
setParams()calls all the rate-setting functions, but
validSpeciesParams()applied to a bare species parameter data frame now
returns fewer columns. See thedefault_parametersvignette. -
The
pargument ofsetMetabolicRate()is deprecated (#459). It never had
any effect on aMizerParamsobject: such an object always has apcolumn
already, and the argument was only ever used to fill in a missing one, so it
was silently ignored. Set the species parameter instead, with
species_params(params)$p <- value. Thepargument of
newMultispeciesParams()is a different argument and is not affected. -
The default for the metabolic exponent
pis nownrather than3/4in
setMetabolicRate(), which is where the default now lives;
validSpeciesParams()no longer setsp. No model changes as a result.
Models built withnewMultispeciesParams()takepfrom its ownp
argument (default0.7), which is injected into the species parameter table
before validation and is untouched by this change, so neither of these
defaults fires for them. ThevalidSpeciesParams()default (p = n) only
ever applied when it was called directly on a bare species parameter data
frame, which now returns nopcolumn, and it shadowed the
setMetabolicRate()default whenever both were in play. -
Default values for the
a(0.01) andb(3) species parameters (for the
weight-length relationship) are now saved inspecies_paramsinstead of
being calculated internally byl2w()andw2l()only when needed. -
The
species_paramsdata frame is now an S3 subclass ofdata.frame
(class = c("species_params", "data.frame")). It supports class-preserving
subsetting and subassignment S3 methods, making it safer to use and paving
the way for future auto-recalculations. -
Columns accessed via
$on aspecies_paramsorgear_paramsobject now
return named vectors, where the names are the species names (or "species,
gear" row names forgear_params). For example,
species_params(params)$w_matnow returns a named vector making it easier
to identify entries. Thespeciesvector is left unnamed. -
When
sel_funcis set on agear_paramsobject, any argument columns
required by that selectivity function (other thanw,species_params, and
...) are now automatically added asNAcolumns. This means, for example,
that settinggp$sel_func <- "sigmoid_length"immediately creates thel25
andl50columns, ready to be filled in (#431). -
Misspelled column names in the
gear_paramsandspecies_paramsdata
frames are now detected by fuzzy matching against the recognised parameter
names. A near miss such assel_fun(instead ofsel_func) triggers a
warning that suggests the intended name, rather than being silently ignored
(#442). Columns are only flagged, never renamed, so legitimate custom
columns are left untouched.
See the new vignette("upgrading") ("Upgrading mizer") for how to adapt
existing code to these changes.
Extension framework
-
An installed extension package is now recognised as a dispatching extension
from the S3 methods it registers for its marker class (e.g.
getEncounter.mizerMR), rather than only from a statically defined S4 marker
class. This lets extension packages omit the static
setClass("mizerFoo", contains = "MizerParams")and instead let mizer create
the marker class dynamically when the package is loaded, inserting it at the
correct place in the S4 hierarchy relative to any other extensions loaded in
the session. As a result, two independently developed extension packages
(for example mizerReef and mizerMR) can now be chained in either load order,
which a static sibling-of-MizerParamsclass prevented. -
recordExtension()now prepends a genuinely new extension to the front of the
object's@extensionschain, keeping it ordered outermost-first to match
registerExtension(). Existing entries stay in place.
New functions
-
New
adjustSizeGrid()function (an S3 generic) adjusts the size grid of
aMizerParamsobject to a new minimum and/or maximum size. It can both
expand and truncate (shrink) the grid. For each species it warns if
truncation discards a non-negligible fraction of the species' biomass, of
the diet of its smallest individuals, or of the diet of its largest
individuals. -
Added a
callbackparameter toproject()to allow user-defined functions
to be called at each saved time step.
Other improvements
-
Mizer plots no longer produce the unhelpful warning "log-10 transformation
introduced infinite values" when a logged axis contains zero values (#463). -
setColours()andsetLinetypes()now also update thelinecolourand
linetypeentries inspecies_paramsandgiven_species_paramswhenever a
name being set coincides with a species name, so that the choice persists
with the species rather than only living in the plotting slot. -
library(mizer)now prints a one-line startup message the first time you
load a new mizer version, pointing you tonews(package = "mizer"). It is
shown at most once per version and never interrupts a session more than
that. -
compareParams()now checks that the number of size bins, species and gears
agree before comparing the array-valued slots. When they differ it reports the
mismatch instead of erroring while trying to compare arrays of incompatible
dimensions. It also compares the species-parameter tables by matching species
and parameters by name, so differing species no longer produce a long list of
per-column length mismatches, and duplicated messages are no longer repeated. -
Error messages that referred to
w_maxas a species' "maximum size" now
correctly describe it as the upper size-grid boundary, consistent withw_max
being a purely computational parameter. -
newSingleSpeciesParams(),newTraitParams()andnewCommunityParams()now
document why they place the size-grid boundary at the maximum size
(w_max = w_repro_max): because they do not yet set up stochastic growth by
diffusion, no individual grows beyondw_repro_max, so no headroom above it is
needed. This will be revisited when the constructors gain a diffusion parameter
(#339). -
print()onArraySpeciesBySize,ArrayTimeBySpecies,ArrayResourceBySize,
ArrayTimeByResourceBySizeandArrayTimeBySpeciesBySizeobjects (as
returned bygetEncounter(),getBiomass(),getResourceMort(),NResource(),
getFMort()and similar functions) now prints the array's actual values
instead of a per-species min/mean/max summary, truncating large arrays to
fit the console: species are shown as a leading ...
mizer 3.1.0
Version 3.1.0 builds on 3.0.0 with an experimental second-order accurate
numerical scheme in size, additional higher-order time-stepping options, and a
range of smaller improvements and bug fixes. Unless you opt in to the
experimental scheme, results are unchanged from 3.0.0.
For an overview see the release announcement on the mizer blog.
Experimental second-order in w accuracy
mizer gains an optional, experimental second-order accurate finite-volume scheme
in the size variable w. It is controlled by a new second_order_w slot and is
switched off by default, so all default results are unchanged (the first-order
path is byte-identical to previous mizer). Enabling it shifts size-integrated
diagnostics and the resource spectrum by O(Δw) (more on coarse grids), so
calibrated models may need recalibrating. See ?second_order_w and the
"Numerical Details" vignette.
-
The
second_order_wslot is a named list with a character entryflux
("upwind","van_leer"or"centred") selecting the advective
reconstruction, and a logical entrybin_averageselecting the bin-averaged
rate quadratures. A fully second-order scheme needs both. Use the new
second_order_w()/second_order_w<-()accessors to get and set them. The
setter accepts a single logical, which sets both entries —flux = "van_leer"
(a TVD reconstruction that keeps abundances non-negative) and
bin_average = TRUE— or a named vector for individual control, e.g.
second_order_w(params) <- c(flux = "centred")for the unlimited flux that is
genuinely second order even at extrema. Setting it re-runssetParams()to
rebuild the precomputed arrays. The defaultflux = "upwind",
bin_average = FALSEis the original first-order upwind scheme. Old objects
are upgraded automatically. -
newMultispeciesParams(),newTraitParams(),newCommunityParams()and
newSingleSpeciesParams()gain asecond_order_wargument (defaultFALSE,
accepting the same values as the setter) that builds the new model with the
scheme already selected. Underbin_averagethe resource and abundance power
laws are constructed bin-averaged from the start; the construction-time
steady-state solve always uses the robust upwind flux, and the chosen flux is
activated only for the returned model. (#379) -
When
bin_averageisTRUE, every point-sampled power law and quadrature that
feeds the finite-volume update is replaced by its exact bin average over each
size bin (the bin straddlingw_pp_cutoffreceiving the partial average), so
the sinks, sources and capacities are consistent with the bin-integrated
encounter convolution (#374):- the external mortality \eqn{z_{ext} w^d} (
setExtMort()) and external
diffusion \eqn{D_{ext} w^{n+1}} (setExtDiffusion()); - the auto-calculated resource intrinsic growth \eqn{r_p w^{n-1}} and carrying
capacity \eqn{\kappa w^{-\lambda}} (setResource(); user-supplied full
vectors are left untouched), together with the matching initial resource
abundance \eqn{\kappa w^{-\lambda}} used both for the initial spectrum and
for the temporary prey spectra behind the defaultgamma/f0and consumer
abundances; - the predation kernels, which are now predator- and prey-bin averaged (via
trapezoid folds), sogetEncounter(),getPredRate(),getPredMort(),
getResourceMort()andgetDiffusion()become second order with no change
to the rate functions and no extra runtime cost. The predation-diffusion
integral uses a dedicated Fourier kernel held in the newft_pred_kernel_d
slot, which carries the extra power of prey size (\eqn{w_p^2 dw_p}, the
\eqn{\beta^{3s}} Jacobian) that the diffusion integrand needs; in the
first-order scheme it equalsft_pred_kernel_e, so existing models are
byte-identical. (#384) - the gear selectivity (
calc_selectivity()), so a knife-edge gear gets the
exact fraction of the straddling bin above the knife edge and fishing
mortality is second order; - the per-capita reproductive investment \eqn{\psi(w) E_r(w)} in
mizerRDI()
(the full investment averaged together, notpsialone), making
density-independent reproduction second order.
- the external mortality \eqn{z_{ext} w^d} (
-
The advective growth flux uses the chosen
fluxreconstruction ("van_leer"
or"centred") for a second-order transport step. Combined with the
bin-averaged diffusion fromgetDiffusion(), the full growth-transport step is
second order. The diffusion coefficient is consumed fromgetDiffusion()
directly rather than being re-averaged by the transport routine. -
Size-integrated and size-resolved diagnostics are placed and weighted
consistently with the finite-volume scheme whenbin_averageisTRUE:- the summary integrals
getBiomass(),getSSB(),getYield(),
getYieldGear(),getDiet()andgetTrophicLevel()use the trapezoidal
bin-average of the size weight (getN()is already exact); - the size-resolved bin-average diagnostics — the mortalities
getPredMort(),
getFMort(),getMort(),getExtMort()and the reproductive investment
getERepro()— are reported at the geometric bin centre
\eqn{\sqrt{w_j w_{j+1}}}, the location where a bin average actually lives,
while point-valued quantities (encounter, growth) stay on the grid nodes.
TheArraySpeciesBySize/ArrayTimeBySpeciesBySizeclasses carry a
representationtag ("point"/"average") recording this. (#382) - the spectrum plots
plotSpectra(),plotlySpectra(),
plotSpectraRelative()andanimateSpectra()evaluate both thew^power
weight and the marker location at the geometric bin centre
\eqn{w^* = w \sqrt{\beta}}, placing each marker as a point on the continuous
N w^powercurve instead of misplacing it at the bin edge (the error grows
withpower, worst for the commonpower = 2Sheldon plot). (#383)
- the summary integrals
Higher-order time-stepping
-
project()gains a new time-stepping optionmethod = "tr_bdf2". This is an
L-stable, second-order TR-BDF2 scheme that retains the second-order accuracy of
method = "predictor_corrector"while damping the oscillations the
Crank-Nicolson corrector can show at large time steps. Like the other methods
it only requires tridiagonal solves. See the "Numerical Details" vignette. -
Under the second-order methods (
"predictor_corrector"and"tr_bdf2") the
resource is now advanced with midpoint resource mortality rather than the
start-of-step value, and the other components (set viasetComponent()) now
also receive a corrector step with the midpoint rates. So the resource and the
other components are integrated to the same second-order accuracy in time as
the consumer spectra. The"euler"method and the steady states are unchanged.
Other improvements
-
Extension packages can now upgrade their own data in saved model objects
independently of the mizer version. The@extensionsslot can record, for
each extension, the version of the extension package that the object conforms
to (write entries with the newrecordExtension()).needs_upgrading()flags
an object when an extension's recorded version is missing or older than the
installed package version, andvalidParams()then calls the extension's own
upgrade()method (an S3 method onutils::upgrade(), registered with
@exportS3Method utils::upgrade). The core mizer upgrade is now itself the
upgrade.MizerParams()/upgrade.MizerSim()method. See the "Upgrading
objects across versions of your extension" section of
vignette("creating-extension-packages"). -
getDiet()gains aMizerSimmethod andplotDiet()for aMizerSimnow
accepts atime_rangeargument, computing the diet from the simulated
abundances at the requested times rather than always using the initial
abundances. As for the otherMizerSimplotting functions,time_range
defaults to the final saved time step. When a range spanning several saved
time steps is given, the consumption rates are averaged over the range and
then normalised to proportions (rather than averaging the per-step
proportions, which are normalised independently). (#357) -
New
getFluxGradient()function returns the flux divergence
\eqn{(J_{j+1} - J_j)/\Delta w_j} that appears as the transport term in the
discretised size-spectrum equation. The bin-boundary fluxes are obtained from
getFlux(), so the advective-flux scheme stored in thefluxentry of the
second_order_wslot is used, with the largest size class closed by the
boundary condition \eqn{N_{K+1} = 0}. LikegetFlux(), it has both
MizerParamsandMizerSimmethods, returning anArraySpeciesBySizeor
ArrayTimeBySpeciesBySizeobject respectively. -
getDiffusion()now works with a custom predation kernel that depends on
predator and prey size separately rather than only on their ratio. As for
getEncounter(), when such a kernel has been set (with
setPredKernel(params, pred_kernel = ...)) the diffusion integral is
evaluated by direct summation over the full predation kernel instead of via
the FFT method, which assumes a ratio-only kernel. (#373) -
getTrophicLevel()andgetTrophicLevelBySpecies()now assign the resource a
size-dependent trophic level
\eqn{T_R(w) = \max(1, 1 + \log(w / w_R) / \log(\beta_R))} instead of treating
it as trophic level 0. The neww_R(average primary-producer size) and
beta_R(average resource predator/prey mass ratio) arguments control this. -
Resource functions now return classed objects that support the same
convenientprint(),summary(),plot()andas.data.frame()methods as
the consumer rate functions.getResourceMort(),initialNResource(),
finalNResource(),resource_rate(),resource_capacity()and
resource_level()return an `ArrayRes...
mizer 3.0.0
This release brings new biological realism, improved numerics, a richer
interactive analysis experience, and a composable extension framework.
For an overview see the
blog post
pre-announcing the release.
Diffusion in mizer
The McKendrick-von Foerster equation now supports a diffusion term, allowing
individual variability in growth to be modelled.
-
New
getDiffusion()calculates the total diffusion rate D(w) (g²/year) for
each species, combining the predation-induced diffusion from the jump-growth
equation and any externally specified diffusion set viasetExtDiffusion().
It has bothMizerParamsandMizerSimmethods and returns an
ArraySpeciesBySizeorArrayTimeBySpeciesBySizeobject respectively,
consistent with the other rate-getter functions. -
The external diffusion coefficient is held in a new
ext_diffusionslot in
MizerParams. UsesetExtDiffusion()/ext_diffusion()/
ext_diffusion<-()to set and retrieve it. The new species parameterD_ext
(default 0) sets the coefficient of an external diffusion power law;
setExtDiffusion()calculates the default array from species parameters when
no custom array is supplied, following the same pattern as
setExtEncounter(). -
MizerParamsgains ause_predation_diffusionslot (logical, default
FALSE). WhenFALSE(the default),mizerDiffusion()omits the
predation-induced diffusion term, preserving the behaviour of previous mizer
versions. Set toTRUEvia the newuse_predation_diffusion()accessor to
enable the jump-growth diffusion term. -
New
getFlux()function calculates the flux of individuals entering each
size class, combining the advective flux from somatic growth and the
diffusive flux. It has apowerargument, similar to that ofplotSpectra(),
for multiplying the flux by a power of the weight;power = 1gives the flux
of biomass. -
getRequiredRDD()is exported. It calculates the recruitment rate needed
to maintain a given initial abundance, accounting for both growth and
diffusion. -
steadySingleSpecies()correctly preserves the steady state under
project(), including when diffusion is non-zero. -
The vignette cohort dynamics
demonstrates the effect of diffusion in an example.
Higher-order numerical scheme
-
project(),projectToSteady()andsteady()gain amethodargument for
choosing the consumer density time-stepper. The default"euler"preserves
the existing semi-implicit update, while"predictor_corrector"uses a new
second-order predictor-corrector method. The accuracy of the two methods is
compared in the numerical details
vignette. -
MizerSimobjects now have asim_paramsslot (a named list) that records
the projection parameters — currentlymethodanddt— passed to
project()orprojectToSteady(). The newgetSimParams()accessor
retrieves this list. Whenproject()is called on an existingMizerSim
object it defaultsdtandmethodfrom the storedsim_params, with a
warning if the supplied values differ. Older objects are upgraded
automatically byvalidSim(), withsim_paramsset to an empty list. -
project_n()andproject_n_2(2)are new exported functions, factored out of
project_simple(), that projects the abundance spectrum forward in time with
the different methods.
Convenient plot methods for mizer return values
-
New
ArraySpeciesBySizeS3 class for the species × size arrays returned by
many mizer functions. AnArraySpeciesBySizeobject behaves like a regular
matrix for arithmetic and subsetting but carries a human-readable
value_nameandunitsattribute and provides enhancedprint(),
summary(),plot(), andas.data.frame()methods. Theplot()method
acceptslog_y,wlim, andylimarguments for controlling the y-axis
scale and limits. -
New
ArrayTimeBySpeciesS3 class for the time × species arrays returned by
getBiomass(),getSSB(),getN(), andgetYield()when called on a
MizerSimobject. LikeArraySpeciesBySize, it carriesvalue_nameand
unitsattributes and provides enhancedprint(),summary(),plot(),
andas.data.frame()methods. Theplot()method acceptslogandylim
arguments. -
New
ArrayTimeBySpeciesBySizeS3 class for the time × species × size arrays.
TheN()accessor on aMizerSimobject now returns an
ArrayTimeBySpeciesBySizeobject. Many rate-getter functions —
getEGrowth(),getEReproAndGrowth(),getPredMort(),getFMort(),
getMort(),getFeedingLevel(),getEncounter(),getPredRate(),
getRDI(),getRDD()— now also accept aMizerSimobject and return an
ArrayTimeBySpeciesBySize. Ananimate()method allows interactive
playback. Subsetting anArrayTimeBySpeciesBySizeobject returns an
ArraySpeciesBySizeobject when a single time is selected, and an
ArrayTimeBySpeciesobject when a single size is selected. -
New
plot2()generic with methods for comparing two compatible mizer array
objects in one plot, with species or group shown by colour and model by
linetype. TheplotSpectra2()helper has moved frommizerExperimentalinto
mizer for comparing two abundance spectra. -
New
plotRelative()generic with methods for plotting the symmetric relative
difference between two compatible mizer array objects. The
plotSpectraRelative()andplotlySpectraRelative()helpers have moved from
mizerExperimentalinto mizer. -
New
plotCDF()andplotCDF2()generics for plotting cumulative abundance
or biomass distributions fromMizerParamsandMizerSimobjects, together
withplotlyCDF()andplotlyCDF2()wrappers. -
New
plotHover()generic with methods forArraySpeciesBySize,
ArrayTimeBySpecies,ArrayTimeBySpeciesBySize, andmizer_plotconverts
mizer plots into hover-enabled plotly figures. -
New
addPlot()generic with methods for addingArraySpeciesBySizeand
ArrayTimeBySpeciesvalues as extra lines on an existing compatible ggplot. -
The
animate()methods produces animated plots showing the time evolution
during a simulation. It can take aMizerSimandArrayTimeBySpeciesBySize
argument and supports axis range settings (xlim,ylim), timing controls,
interpolation options, argumentslog_xlog_yandlogto control which
axis is log-transformed, andtotalandbackgroundarguments, consistent
withplotSpectra(). -
Plotting functions now consistently expose
log_x,log_yandlog
arguments. In all cases, when supplied,logoverrideslog_xandlog_y.
plotBiomass()andplotYield()keep support for logicallogvalues for
backward compatibility. -
Time-filtering is now consistent across all time-series plot functions via a
newtlimparameter (analogous towlimandylim): a length-two numeric
vectorc(start, end)that restricts the plotted time window.plotYield(),
plotYieldGear(), andanimate()gain this parameter for the first time.
plotBiomass()andanimate.MizerSim()now usetlimin place of the
formerstart_time/end_timeandtime_rangeparameters respectively;
the old parameters are deprecated and will be removed in a future release. -
Size-based plots now accept
size_axis = "l"to show length in cm on the
size axis instead of weight in grams, using the species' allometric
weight-length relationship. -
Size-based plots with a
size_axisargument now acceptllim, the
length-axis equivalent ofwlim, for filtering and limiting plots when
size_axis = "l".
Extracting model state from a simulation
-
A shift in interpretation of a MizerParams object from just a specification
of the model to a representation of its state, consisting of both model
parameters and current values of the state variables (the abundances). -
getParams(sim, time_range, geometric_mean = FALSE)now extracts the
ecosystem state from aMizerSimobject at a particular time or averaged
over a time range. When notime_rangeis given, the state at the final time
step is extracted. NewfinalParams(sim)andinitialParams(sim)return the
states at the initial and final times of a simulation respectively. -
Once a state has been extracted from a simulation, it can be analysed by all
the existing mizer functions. For that purpose the indicator functions
getProportionOfLargeFish(),getMeanWeight(),getMeanMaxWeight(), and
getCommunitySlope()now also accept aMizerParamsobject and return a
single value (or named vector forgetMeanMaxWeight()with
measure = "both") calculated from that state. Closes #262. -
setInitialValues()is deprecated. Replace
setInitialValues(params, sim)withfinalParams(sim)(or
getParams(sim, time_range, geometric_mean)when averaging over a time
range).
New extension mechanism allowing extension chains
-
Many functions are now S3 generics with methods for
MizerParamsorMizerSimobjects, and users can define their own subclass
methods to modify mizer behaviour (#330). -
New composable extension chain infrastructure:
registerExtensions(),
getRegisteredExtensions(),coerceToExtensionClass(),
clearExtensionChain(), andregisterExtension(). Extension classes are S3
marker classes;MizerSimderives its extension chain from
sim@params@extensions. Extensions that do not provide a marker class remain
metadata-only and do not trigger the S3 projection-rate dispatch path. -
S3 projection hooks have been added for all standard mizer rate functions.
Extension-aware projections dispatch throughprojectRates(),
projectEncounter(),projectFeedingLevel(), `project...
v2.5.4
- New function
renameGear()to rename gears in a MizerParams object, similar
torenameSpecies(). addSpecies()now proceeds with a warning instead of an error when species
growth stops after maturity (#315).matchBiomasses()andmatchNumbers()now provide more informative error
messages.plotDiet()now restricts the plot to size ranges with meaningful biomass
density (#317).- The
wlimandylimarguments in plotting functions now set the actual axis
limits instead of just zooming (#320). - The legend in
plotlyFeedingLevel()is improved when critical feeding level
is included. speciesandgearscolumns are now never factors, so no longer need to
callas.character()so often.validParams()also callsvalidGearParams().validParams()checks thatw_minis valid for all species and increases it
if necessary.validSpeciesParams()now also sets default forpto be equal ton.species_params<-()andgiven_species_params<-()now check that species
names match.- The
paramsargument inl2w()andw2l()has been renamed tospecies_params
to follow mizer's convention thatparamsrefers to a MizerParams object.
Bug fixes
animateSpectra()now uses consistent colours and preserves colour identity
across frames (#321).getReproductionProportion()no longer returns incorrect proportions > 1 (#299)setResource()now correctly applies thew_pp_cutoffparameter to the
carrying capacity and initial resource abundance when changed without
providingresource_capacity(#306).- Predation kernels are now truncated as documented.
given_species_params()no longer makes unwanted changes to the species
parameters.steadySingleSpecies()no longer changestime_modified.
Full Changelog: v2.5.3...v2.5.4
v2.5.3
This is a patch release with many small fixes and improvements since the v2.5.0 release.
validSpeciesParams()has extra checks on consistency of species parameters.validParams()checks that rate arrays contain finite numeric values.validSim()checks that simulation results are finite and truncates the
simulation if they are not.- Fixed bug that had led
newCommunityParams()to set up resource parameters
differently since version 2.4.0 (#293). addSpecies()now correctly preserves allspecies_paramsof the existing
model.addSpecies()no longer requires new species to grow to maximum size, only
maturity size is required.- Now
validGivenSpeciesParams()validates the given species parameters without
adding defaults andvalidSpeciesParams()validates and returns a completed
species parameter dataframe. - New species parameter
w_repro_maxgiving the size at which a species
invests 100% of its energy into reproduction. Set tow_maxby default. removeSpecies()now also removes species parameters that are NA for
all of the remaining species.- Changing
w_maxnow also correctly updatesft_mask(#296). compareParams()now also spells out differences in given species parameters.getDiet()now also includes the contribution of the external encounter rate
to the diet.setPredKernel()now throws an error if some of the required predation kernel
parameters are NA.- In
plotYieldGear()one can select a subset of gears with a newgears
argument. - New helper function
valid_gears_arg()to check thegearsargument in
functions that take agearsargument. - Improved scaling of the y-axis in
plotGrowthCurves(). steadySingleSpecies()no longer requires species to grow tow_max.matchGrowth()now also rescales the external encounter rate.setExtEncounter()no longer resets the external encounter rate to zero when
called without theext_encounterargument.- The function
plotBiomassObservedVsModel()now plots the ratio of modelled
to observed biomass as default (ratio = TRUE). - The
time_modifiedfield is now updated correctly bysteadySingleSpecies(),
setColours()andsetLinetypes(). - Deprecated
matchYields()andcalibrateYield(). project()andprojectToSteady(..., return_sim = TRUE)now correctly
returns also the other components of the MizerSim object stored inn_other.
#285- Improved some unit tests.
- Some improvements to documentation.
mizer 2.5.0
This release introduces a change that requires you to upgrade your old
MizerParams and MizerSim objects with upgradeParams() or upgradeSim().
External encounter rate
Now the model can include an external encounter rate that represents the
rate at which a predator encounters food that is not explicitly modelled.
This encounter rate is set with setExtEncounter() or ext_encounter<-()
and can be read with getExtEncounter() or ext_encounter(). So this is
similar to how external mortality is handled.
Given versus calculated species parameters
You can now use given_species_params() to see the species parameter
values that you have explicitly specified and calculated_species_params()
to see the species parameter values that mizer has calculated automatically or
set to defaults. You can continue to use species_params() to get all
species parameters, irrespective of whether they were given or calculated.
You can still set parameter values with species_params<-(), but you can also
use the stronger given_species_params<-() which not only sets the values you
give but also triggers a re-calculation of the calculated species parameters.
Using given_species_params<-() is therefore usually the better option.
New mizer course
There is now a three-part mizer course at https://mizer.course.sizespectrum.org
with each part consisting of several tutorials, including code and exercises:
-
Part 1: Understand
You will gain an understanding of size spectra and their dynamics by exploring simple example systems hands-on with mizer. -
Part 2: Build
You will build your own multi-species mizer model for the Celtic sea, following our example. You can also create a model for your own area of interest. -
Part 3: Use
You will explore the effects of changes in fishing and changes in resource dynamics on the fish community and the fisheries yield. You will run your own model scenarios.
Other improvements
- Warnings are given if user gives irrelevant species parameter values.
- Some messages have been converted to warnings and some to signals that are not
shown as frequently. - Frequent warnings are avoided when length-based and weight-based parameters
are both given and are inconsistent. #277 - Documentation of
effortargument inproject()is improved. - An error message is given if a predation kernel returns negative values or
is everywhere zero. #283
Bug fixes
mizer 2.4.0
This release introduces a change that requires you to upgrade your old
MizerParams and MizerSim objects with upgradeParams() or upgradeSim():
Avoid confusion between maximum size and von Bertalanffy asymptotic size
For an explanation see blog post at
https://blog.mizer.sizespectrum.org/posts/2022-11-30-dont-use-von-bertalanffy-growth-parameters/
The species parameter that specifies the size at which also the largest fish stop
growing is renamed from w_inf to w_max. The parameter w_inf is now
reserved for the von Bertalanffy asymptotic size parameter. If you upgrade
your existing MizerParams object with upgradeParams() the w_inf column is
copied over to the w_max column automatically, but you may want to change
the values yourself if they do not currently reflect the maximum size of the
species. Otherwise the size distributions predicted by mizer will not match
observations.
Set resource abundance rather than carrying capacity
The resource parameters kappa and lambda are now used to set the abundance
of the resource in the steady state rather than the carrying capacity, because
the latter is not observable.
While tuning the steady state using the steady() function the resource
abundance is now being kept fixed at the chosen value. Then the resource
dynamics can be switched on later with setResource() without changing the
steady state. At that stage you only choose either the resource intrinsic
growth rate or the resource carrying capacity and the other is determined by
setResource() in such a way that the resource replenishes at the same rate at
which it is consumed. If you want to keep the old behaviour and switch off this
automatic balancing you have to add the balance = FALSE argument when calling
setResource().
You can also choose between semichemostat dynamics resource_semichemostat()
or logistic dynamics resource_logistic() or you can write your own function
implementing more sophisticated resource dynamics.
The setParams() function no longer includes the arguments for setting the
resource parameters. Instead you set these separately with setResource().
Automatically match growth rates
As explained in the blog post at https://blog.mizer.sizespectrum.org/posts/2022-11-30-dont-use-von-bertalanffy-growth-parameters/,
the von Bertalanffy curves fitted to size-at-age
data are not suitable for estimating the size-dependent growth rates in mizer.
It is therefore now recommended that instead of von Bertalanffy parameters you
supply the age at maturity in the age_mat column of the species parameter
data frame. This is then used by mizer to calculate a default for the
maximum intake rate parameter h if you do not supply this.
In the past, whenever you changed any model parameters, you needed to re-tune
other parameters to keep the growth rates in line with observations. There is
now a new function matchGrowth() that automatically scales the search volume,
the maximum consumption rate and the metabolic rate all by the same factor in
order to achieve a growth rate that allows individuals to reach their maturity
size by their maturity age while keeping the feeding level and the critical
feeding level unchanged. This function does not however preserve the steady
state, so you will need to also call steady() after matching the growth rates.
Other improvements
- New function
steadySingleSpecies()that only balances the size-spectrum
dynamics while ignoring multi-species effects. In other words, it calculates
the steady-state size spectrum of each species as it would be if the abundance
of prey and predators could be kept constant at their current values. plotGrowthCurves()can now superimpose a scatterplot of size-at-age data
if you supply this via the newsize_at_ageargument.- New functions
calibrateNumber()andmatchNumbers()that are like
calibrateBiomass()andmatchBiomasses()but work with observed numbers
instead of observed biomasses. - New function
age_mat()to calculate the age at maturity from the growth
rate and the size at maturity. - If an effort vector or effort array contains NA's, these are now replaced by
the default effort value. #230 - The entries of the interaction matrix and of interaction_resource are no
longer restricted to be less or equal to 1. #232 - If user supplies no row names in the interaction matrix but gives column names
then the column names are also used as row names. #247 project()now also works when called with a MizerSim object with additional
components.steady()now preserves the RDD function in the MizerParams object rather
than always setting it to "BevertonHoltRDD".- When averaging abundances over time in
plotSpectra()orsetInitialValues()
the user can now choose geometric averaging withgeometric_mean = TRUE. - The
w_mat25species parameter is no longer filled in automatically if it is
not supplied. This makes it easier to changew_matwithout having to change
w_mat25at the same time. compareParams()now also checks the validity of its second argument.- Hide the printing of messages about chosen defaults in
newTraitParams(). - Higher values for the
info_levelargument innewMultispeciesParams()now
leads to more messages. - Giving more helpful messages in
validSpeciesParams(). #136 - New helper functions
l2w()andw2l()for converting between length-based
and weight-based species parameters. #258 - Check that assessor functions for MizerSim slots are called with a MizerSim
object. - Add
styleargument toplotDataFrame()to facilitate producing area plots. - Add
wrap_scaleargument toplotDataFrame()to control scaling of axes in
faceted plots. plotDiet()can now show diets of several predator species in a faceted
plot. #267- Change from
sizetolinewidthaesthetic to avoid warnings in new version
of ggplot2. - Better error message when functions are called with no valid species selected.
#251 - If there are no differences then
compareParams()says so clearly. getReproductionLevel()works as long asR_maxis set. #252- Converted several unit tests to edition 3 of testthat package.
- Improved documentation for
gear_params(). - Improved defaults can now be implemented while keeping backwards compatibility
viadefaults_edition(). #186 - New defaults edition 2: catchability = 0.3 instead of 1, initial effort = 1
instead of 0. #243 - In defaults edition 2,
get_gamma_default()ensures a feeding level off0
for larvae also ifinteraction_resourceis not equal to 1. #238 - Set default linecolour and linetype for external mortality.
Bug fixes
- Restored the line colours to
NS_params - Comment field now preserved by
set_species_default(). #268 - Comment on
w_infno longer leads to error inplyr::aaply(). #269 - Can now again set
urlfield in metadata. - Correct species now listed in the legend of
plotYieldObservedVsModel()and
plotBiomassObservedVsModel(). #266 - Standard order for legend in
plotDiet()restored after change toggplot2
package. #265 - Fix handling of column names when interaction matrix is read from .csv file.
#263
mizer 2.3.1
- Resolved conflict in
mizerPredRate()between the argumenttand the
functionbase::t(). - Assert that upgradeParams() must be called with a MizerParams object and
upgradeSim()with a MizerSim object. - Errors changed to warnings in
getRequiredRDD() renameSpecies()no longer fails when linecolour and linetype are of
different lengths.- matchYields() now also works for a model with only a single species.
setInitialValues()can now average over a time_range.getSSB(),getBiomass(),getN(),getYieldGear()andgetYield()
can now be called with a MizerParams object as well as with a MizerSim
object. (#200)- Updated the shiny app in inst/shiny/selectivity_effects to current mizer
version.
v2.3.0
New features
- New plots
plotBiomassObservedVsModel()andplotYieldObservedVsModel()
contributed by @SamikDatta., together with their plotly counterparts. - New
calibrateBiomass(),calibrateYield()to set the model scale to agree
with total observed biomass or total observed yield. Uses the new
scaleModel(). - New
matchBiomasses()andmatchYields()will try to adjust the abundances
of the species to produce the observed biomasses or yields.
See blog post at https://bit.ly/2YqXESV . - There are now accessor and replacement functions for rates. So for example
instead ofparams <- setReproduction(params, maturity = my_maturity)one
can simply usematurity(params) <- my_maturity. These are documented
together with the setter functions. #213 - New
setMetadata()to add information to a MizerParams object describing
the model, for example a title, a description, the author or list of
authors, a url and a doi. This will be particularly useful for sharing your
models with others - New
saveParams()for saving a MizerParams object to a file and
readParams()for reading it back in. The resulting files can be shared
with others who want to run your model. - A MizerParams object now registers the mizer version under which the model was
last saved. Should the model not be working as expected in the current version
of mizer, you can go back to the older version under which presumably it was
working. This helps with the reproducibility of your research. - A MizerParams object registers the time when it was created and the time it
was last modified. SeegetMetadata(). This helps you keep track of
different versions of your model. steady()now has apreserveargument with possible valueserepro,
R_maxorreproduction_levelto specify which quantity to preserve.
This means that one can continue to usesteady()also
once one has started to tune the density dependence in reproduction. #208- Our website is now using the nice new mizer logo designed by Kira Askaroff
(www.kiraaskaroff.com) - There is a new mizer extension package
mizerMR
allowing you to include multiple resource spectra in your model.
Small improvements
- The rownames of
gear_paramsare now set to "species, gear", so that one
can access individual entries with for example
gear_params(NS_params)["Cod, Otter", "catchability"]. #212 - The
z0argument ofsetExtMort()has been deprecated in favour of
ext_mortin order to avoid confusion with the species parameterz0. setColours()andsetLinetypes()now issue warnings when invalid values
are given and ignores NAs.- The experimental
commentarguments to the setter functions have been
removed. #214 - The setter functions have a new
resetargument which, when set toTRUE
will recalculate the rates from the species_, gear_ and resource_params even
when custom values had been set. #214 - The
speciesargument to various functions, which is checked with
valid_species_arg(), now does not throw an error even when there is no
valid species included. Only a warning is issued. That means that for
exampleplotSpectra(NS_params, species = list(), total = TRUE)is now
allowed. getComponent()from the mizer extension mechanism now returns NULL when
asked for a non-existent component instead of giving an error. This gives
an easy way to check for the existence of a component.- The example interaction matrix
interfor the North Sea model now has the
alternative nameNS_interaction, with the old name deprecated. - Species added with
addSpecies()are now by default given a reproduction
level of 1/4 instead of 0, because at the low densities at which they are
introduced there would otherwise not be enough density dependence to
stabilise them. - The size range arguments
min_w,max_w,min_landmax_lused in some
summary functions and processed byget_size_range_array()accept vector
values setting different limits for different species. - The resource dynamics function is now also passed the
resource_rateand the
resource_capacityas arguments, which makes it easier to use them in
extension packages. - Species names are now always coerced to strings, even if the user gives them
as numbers. #202 - There is a new system for informing the user about how defaults were set by
newMultispeciesParams(), #199 - Many improvements in the documentation.
- Many small improvements to code quality and testing.
- Better social media cards, especially for twitter.
- mizer can be run on binder, https://mybinder.org/v2/gh/sizespectrum/mizer/HEAD?urlpath=rstudio
Bug fixes
- Changing
linecolourorlinetypein the species parameters now actually
changes the linecolours and linetypes as intended. - Growth curves calculated with
getGrowthCurves()and plotted with
plotGrowthCurves()are now correct, and no longer extend above the
asymptotic size. plotGrowthCurves()withspecies_panel = TRUEnow respects thespecies
argument to only show growth curves for selected species, it works with
a MizerParams object as well as a MizerSim object, and it shows the panels
in the correct order. #201- Reinstated the example .csv files that were missing from the package because
the vignettes are no longer included.