Recent Releases of mizer

mizer - 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_w slot is a named list with a character entry flux
    ("upwind", "van_leer" or "centred") selecting the advective
    reconstruction, and a logical entry bin_average selecting 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-runs setParams() to
    rebuild the precomputed arrays. The default flux = "upwind",
    bin_average = FALSE is the original first-order upwind scheme. Old objects
    are upgraded automatically.

  • newMultispeciesParams(), newTraitParams(), newCommunityParams() and
    newSingleSpeciesParams() gain a second_order_w argument (default FALSE,
    accepting the same values as the setter) that builds the new model with the
    scheme already selected. Under bin_average the 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_average is TRUE, 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 straddling w_pp_cutoff receiving 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 default gamma/f0 and consumer
      abundances;
    • the predation kernels, which are now predator- and prey-bin averaged (via
      trapezoid folds), so getEncounter(), getPredRate(), getPredMort(),
      getResourceMort() and getDiffusion() 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 new ft_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 equals ft_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, not psi alone), making
      density-independent reproduction second order.
  • The advective growth flux uses the chosen flux reconstruction ("van_leer"
    or "centred") for a second-order transport step. Combined with the
    bin-averaged diffusion from getDiffusion(), the full growth-transport step is
    second order. The diffusion coefficient is consumed from getDiffusion()
    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 when bin_average is TRUE:

    • the summary integrals getBiomass(), getSSB(), getYield(),
      getYieldGear(), getDiet() and getTrophicLevel() 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.
      The ArraySpeciesBySize / ArrayTimeBySpeciesBySize classes carry a
      representation tag ("point" / "average") recording this. (#382)
    • the spectrum plots plotSpectra(), plotlySpectra(),
      plotSpectraRelative() and animateSpectra() evaluate both the w^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^power curve instead of misplacing it at the bin edge (the error grows
      with power, worst for the common power = 2 Sheldon plot). (#383)

Higher-order time-stepping

  • project() gains a new time-stepping option method = "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 via setComponent()) 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 @extensions slot can record, for
    each extension, the version of the extension package that the object conforms
    to (write entries with the new recordExtension()). needs_upgrading() flags
    an object when an extension's recorded version is missing or older than the
    installed package version, and validParams() then calls the extension's own
    upgrade() method (an S3 method on utils::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 a MizerSim method and plotDiet() for a MizerSim now
    accepts a time_range argument, computing the diet from the simulated
    abundances at the requested times rather than always using the initial
    abundances. As for the other MizerSim plotting 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 the flux entry of the
    second_order_w slot is used, with the largest size class closed by the
    boundary condition \eqn{N_{K+1} = 0}. Like getFlux(), it has both
    MizerParams and MizerSim methods, returning an ArraySpeciesBySize or
    ArrayTimeBySpeciesBySize object 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() and getTrophicLevelBySpecies() 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 new w_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
    convenient print(), summary(), plot() and as.data.frame() methods as
    the consumer rate functions. getResourceMort(), initialNResource(),
    finalNResource(), resource_rate(), resource_capacity() and
    resource_level() return an ArrayResourceBySize object, and NResource()
    returns an ArrayTimeByResourceBySize object, so you can now do e.g.
    plot(getResourceMort(NS_params)) or plot(NResource(NS_sim)).

  • summary() of a MizerSim object now reports the fishing effort that was
    actually used during the simulation rather than the model's initial_effort.
    Gears whose effort varied over time show the mean effort, flagged with a note
    giving the min-max range.

  • Added a new vignette explaining the calculation of default parameter values
    (#189).

Breaking changes

  • The maximum-size species parameters have been clarified (#325). The von
    Bertalanffy asymptotic size w_inf is now the required maximum-size parameter
    and is used as the default for w_repro_max (previously w_max) and w_mat.
    w_max is now purely a computational boundary (the size grid and plot range)
    and defaults to 1.5 * w_inf. w_repro_max is documented as the size at which
    a typical mature individual invests all its energy into reproduction, not as a
    hard ceiling on size. The default value of the external mortality parameter
    z0 is now calculated from w_inf rather than w_max, so the purely
    computational boundary w_max no longer influences any model parameter. For
    backwards compatibility, if w_inf is not supplied it is taken from
    w_repro_max or w_max, so existing models and scripts are unaffected;
    however, new models built from the defaults may differ from 3.0.0.

Bug fixes

  • Fixed a bug in project() where the abundances of other components (set via
    setComponent()) were advanced only once per saved time step instead of once
    per dt time step. Their dynamics are now integrated with the same time step
    as the consumer and resource spectra, so results no longer depend on t_save.

  • getGrowthCurves() no longer emits a cryptic
    collapsing to unique 'x' values warning when a species' w_max lies exactly
    on a grid point. (#413)

  • getRDI(), getRDD() and getFlux() on a MizerSim object now correctly use
    the simulated time-varying effort instead of the initial effort. (#370)

  • plotCDF() / plotlyCDF() now plot each cumulative value on its bin's
    upper edge w_k + dw_k, following the inclusive cumulative-sum convention
    (the sum through bin k is the integral up to that bin's upper edge). This
    corrects a long-standing one-bin location offset and applies in both the
    default and the second-order schemes; under second-order bin-averaging the CDF
    is then second-order accurate in its placement as well as its increments.
    (#383)

  • plotYield() now uses sim2 = NULL instead of missing(sim2) to detect the
    optional second simulation argument, so it works correctly with do.call().
    This is backward-compatible.

  • distanceMaxRelRDI() now returns Inf instead of NaN when a previous RDI
    is zero, so projectToSteady() no longer mistakes a NaN distance for
    convergence.

Biosphere - Marine Life and Fishery - R
Published by gustavdelius 18 days ago

mizer - 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 via setExtDiffusion().
    It has both MizerParams and MizerSim methods and returns an
    ArraySpeciesBySize or ArrayTimeBySpeciesBySize object respectively,
    consistent with the other rate-getter functions.

  • The external diffusion coefficient is held in a new ext_diffusion slot in
    MizerParams. Use setExtDiffusion() / ext_diffusion() /
    ext_diffusion<-() to set and retrieve it. The new species parameter D_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().

  • MizerParams gains a use_predation_diffusion slot (logical, default
    FALSE). When FALSE (the default), mizerDiffusion() omits the
    predation-induced diffusion term, preserving the behaviour of previous mizer
    versions. Set to TRUE via the new use_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 a power argument, similar to that of plotSpectra(),
    for multiplying the flux by a power of the weight; power = 1 gives 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() and steady() gain a method argument 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.

  • MizerSim objects now have a sim_params slot (a named list) that records
    the projection parameters — currently method and dt — passed to
    project() or projectToSteady(). The new getSimParams() accessor
    retrieves this list. When project() is called on an existing MizerSim
    object it defaults dt and method from the stored sim_params, with a
    warning if the supplied values differ. Older objects are upgraded
    automatically by validSim(), with sim_params set to an empty list.

  • project_n() and project_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 ArraySpeciesBySize S3 class for the species × size arrays returned by
    many mizer functions. An ArraySpeciesBySize object behaves like a regular
    matrix for arithmetic and subsetting but carries a human-readable
    value_name and units attribute and provides enhanced print(),
    summary(), plot(), and as.data.frame() methods. The plot() method
    accepts log_y, wlim, and ylim arguments for controlling the y-axis
    scale and limits.

  • New ArrayTimeBySpecies S3 class for the time × species arrays returned by
    getBiomass(), getSSB(), getN(), and getYield() when called on a
    MizerSim object. Like ArraySpeciesBySize, it carries value_name and
    units attributes and provides enhanced print(), summary(), plot(),
    and as.data.frame() methods. The plot() method accepts log and ylim
    arguments.

  • New ArrayTimeBySpeciesBySize S3 class for the time × species × size arrays.
    The N() accessor on a MizerSim object now returns an
    ArrayTimeBySpeciesBySize object. Many rate-getter functions —
    getEGrowth(), getEReproAndGrowth(), getPredMort(), getFMort(),
    getMort(), getFeedingLevel(), getEncounter(), getPredRate(),
    getRDI(), getRDD() — now also accept a MizerSim object and return an
    ArrayTimeBySpeciesBySize. An animate() method allows interactive
    playback. Subsetting an ArrayTimeBySpeciesBySize object returns an
    ArraySpeciesBySize object when a single time is selected, and an
    ArrayTimeBySpecies object 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. The plotSpectra2() helper has moved from mizerExperimental into
    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() and plotlySpectraRelative() helpers have moved from
    mizerExperimental into mizer.

  • New plotCDF() and plotCDF2() generics for plotting cumulative abundance
    or biomass distributions from MizerParams and MizerSim objects, together
    with plotlyCDF() and plotlyCDF2() wrappers.

  • New plotHover() generic with methods for ArraySpeciesBySize,
    ArrayTimeBySpecies, ArrayTimeBySpeciesBySize, and mizer_plot converts
    mizer plots into hover-enabled plotly figures.

  • New addPlot() generic with methods for adding ArraySpeciesBySize and
    ArrayTimeBySpecies values as extra lines on an existing compatible ggplot.

  • The animate() methods produces animated plots showing the time evolution
    during a simulation. It can take aMizerSim and ArrayTimeBySpeciesBySize
    argument and supports axis range settings (xlim, ylim), timing controls,
    interpolation options, arguments log_x log_y and log to control which
    axis is log-transformed, and total and background arguments, consistent
    with plotSpectra().

  • Plotting functions now consistently expose log_x, log_y and log
    arguments. In all cases, when supplied, log overrides log_x and log_y.
    plotBiomass() and plotYield() keep support for logical log values for
    backward compatibility.

  • Time-filtering is now consistent across all time-series plot functions via a
    new tlim parameter (analogous to wlim and ylim): a length-two numeric
    vector c(start, end) that restricts the plotted time window. plotYield(),
    plotYieldGear(), and animate() gain this parameter for the first time.
    plotBiomass() and animate.MizerSim() now use tlim in place of the
    former start_time/end_time and time_range parameters 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_axis argument now accept llim, the
    length-axis equivalent of wlim, 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 a MizerSim object at a particular time or averaged
    over a time range. When no time_range is given, the state at the final time
    step is extracted. New finalParams(sim) and initialParams(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 a MizerParams object and return a
    single value (or named vector for getMeanMaxWeight() with
    measure = "both") calculated from that state. Closes #262.

  • setInitialValues() is deprecated. Replace
    setInitialValues(params, sim) with finalParams(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
    MizerParams or MizerSim objects, and users can define their own subclass
    methods to modify mizer behaviour (#330).

  • New composable extension chain infrastructure: registerExtensions(),
    getRegisteredExtensions(), coerceToExtensionClass(),
    clearExtensionChain(), and registerExtension(). Extension classes are S3
    marker classes; MizerSim derives 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 through projectRates(),
    projectEncounter(), projectFeedingLevel(), projectEReproAndGrowth(),
    projectERepro(), projectEGrowth(), projectDiffusion(),
    projectPredRate(), projectPredMort(), projectFMort(), projectMort(),
    projectRDI(), projectRDD(), and projectResourceMort() — while models
    without extensions continue to use the pre-resolved mizerRates() pipeline
    directly, with no per-step overhead.

  • The MizerSim accessors getParams(),
    validSim(), N(), NResource(), finalN(), finalNResource(),
    idxFinalT(), getTimes(), getEffort(), and are now
    registered as S3 generics with MizerSim methods, making extension-specific
    methods possible. validParams() is also now an S3 generic.

  • saveParams() now serialises extension objects as plain MizerParams
    objects while preserving their extension chain, and readParams() restores
    the appropriate extension class. New saveSim() and readSim() helpers
    provide the same lifecycle for MizerSim objects.

  • Extension installation support now integrates pak for managing missing or
    outdated extension packages.

  • New vignette
    Extending mizer
    documents when to use setRateFunction(), setComponent(), and
    customFunction(), summarises required function signatures and return shapes,
    and gives worked examples for both a custom encounter function and an added
    ecosystem component. A companion vignette
    Using extension packages
    is aimed at users of extension packages, and
    Creating a mizer extension package
    guides extension authors through setting up a new extension package.

  • setRateFunction() now validates the registered function by calling it with
    test inputs and checking that the return value has the correct dimensions,
    catching mismatched custom rate functions at registration time rather than
    during a simulation run. Closes #167.

  • setComponent() now accepts optional colour and linetype arguments and
    applies them via setColours() and setLinetypes() so added components can
    be styled directly in plots.

  • The plot() and summary() methods for MizerParams, MizerSim, and the
    mizer array classes are now registered as S3 methods rather than S4 methods,
    so plot() and summary() remain plain S3 generics when mizer is loaded,
    avoiding interference with S4 method dispatch for other packages.

Species parameters for external mortality, encounter and diffusion rates

See the model description vignette for
the mathematical details.

  • New species parameters z_ext (default 0) and d (default n - 1) add an
    optional power-law term to the external mortality: mu_ext(w) = z0 + z_ext * w^d. When z_ext is zero (the default) the behaviour is unchanged. Closes
    #329.

  • New species parameter E_ext (default 0) sets the coefficient of the
    external encounter rate power law. setExtEncounter() now calculates the
    default external encounter rate as E_ext * w^n when no custom array is
    supplied, matching the pattern of setMaxIntakeRate(). A reset argument is
    also added to setExtEncounter() to force recalculation from species
    parameters.

  • New species parameter D_ext (default 0) sets the coefficient of the
    external diffusion rate power law. setExtDiffusion() calculates the default
    array from species parameters when no custom array is supplied.

Other improvements

  • The MizerSim methods of the rate-getter functions (getEncounter(),
    getFeedingLevel(), getEReproAndGrowth(), getERepro(), getEGrowth(),
    getDiffusion(), getPredRate(), getPredMort(), getMort(), getFMort(),
    getFMortGear(), getRDI(), getRDD() and getFlux()) are now much faster.
    They resolve the rate functions and validate the parameters once and then, at
    each saved time step, calculate only the rates needed (and their
    dependencies) rather than re-resolving and recomputing the whole rate chain.
    The speed-up grows with the depth of the rate chain, e.g. roughly 100× for
    getRDI() and getFlux() on a 50-step simulation.

  • New scaleRates(params, factor) function that rescales all rates in a model
    by a given factor. This is equivalent to a time rescaling: it speeds up or
    slows down all dynamics without affecting the steady state. All rate slots
    (search_vol, intake_max, metab, mu_b, ext_encounter,
    ext_diffusion, catchability, rr_pp) and their associated species
    parameters (gamma, h, ks, k, z0, z_ext, z0pre, E_ext,
    D_ext, R_max) are rescaled consistently.

  • New getTrophicLevel() function returns a matrix (species × size) with the
    trophic level of individuals at each size, accounting for ontogenetic diet
    shifts by integrating the consumption-weighted average prey trophic level
    over the individual's growth trajectory. New getTrophicLevelBySpecies()
    returns the consumption-rate-weighted mean trophic level per species. Both
    functions accept MizerParams and MizerSim objects. Closes #307.

  • New expandSizeGrid() function (an S3 generic) expands the size grid of a
    MizerParams object to a new minimum and/or maximum size while preserving
    all existing species data. Both addSpecies() and expandSizeGrid() now
    preserve the MizerParams subclass. upgradeParams() also preserves
    MizerParams subclasses and their extra slots.

  • compareParams() output is now printed in a human-readable format, with each
    difference as its own block separated by blank lines. When array slots differ,
    the max absolute difference is shown per species. When slots differ only in
    their comment attributes, both comments are displayed. Closes #205.

  • summary() for MizerParams and MizerSim now displays metadata from the
    @metadata slot, including title, description, authors, DOI, URL, mizer
    version, and creation/modification timestamps (when set). Closes #294.

  • New str() methods for MizerParams and MizerSim objects, and the mizer
    array classes (ArraySpeciesBySize, ArrayTimeBySpecies, and
    ArrayTimeBySpeciesBySize), showing a clean, compact overview of their
    structures without dumping large amounts of internal data.

  • A new steady argument to addSpecies() controls whether steady() is
    called after adding the new species.

  • constantEggRDI() now accounts for diffusion across the egg-size boundary,
    including when project() uses the "predictor-corrector" method.

  • setRateFunction() now validates custom RDI functions with the same
    diffusion argument that they receive during projection.

  • Growth is now forced to always be non-negative, preventing unphysical
    shrinkage. No warning is issued when growth stops at or after maturity size.

  • Added info_level argument to projectToSteady(), steady(), setParams(),
    newCommunityParams(), newTraitParams(), matchBiomasses(),
    matchNumbers(), matchYields() and addSpecies()to control the
    verbosity of information messages, consistent with newMultispeciesParams().
    Set info_level = 0 to suppress all messages. Closes #290.

  • t_max and t_save arguments in project() are now respected even when an
    effort array is supplied. When t_max is provided, the simulation extends
    beyond the times in the effort array using the last known effort values. When
    t_save is provided, it controls the save frequency with effort values
    interpolated as needed (#231).

  • getBiomass() now has a use_cutoff argument to restrict the biomass
    calculation to sizes above the biomass_cutoff species parameter.
    plotBiomass() and plotlyBiomass() also gain this argument.

  • setResource() now allows resource_level = 1. When balancing would
    otherwise divide by zero because the resource capacity equals the current
    resource abundance at positive consumption, the capacity is increased
    slightly with a warning instead of failing early.

  • project() now warns when t_max is not a multiple of t_save and ensures
    that the state at t_max is always saved, even if the final save interval is
    shorter than t_save. (#341)

  • New function psi() returns an ArraySpeciesBySize with the population-level
    reproductive proportion.

  • age_mat_vB() is now exported.

  • New Cheatsheet: Analysis and Plotting
    vignette provides a quick reference for all functions that access simulation
    arrays, compute summaries, calculate indicators, and create plots.
    Closes #176.

Bug fixes

  • getFMort() on a MizerSim object was silently dropping the component
    names from n_other when passing it to the rate function and its
    dependencies (getEGrowth(), getPredMort()), causing failures whenever
    rate functions accessed n_other by name (e.g. n_other[["resource"]]).
    The implementation has been refactored to use the same plyr::aaply pattern
    as getFeedingLevel() and getPredMort().

  • getFMort.MizerSim() was not passing the time argument t to user-defined
    fishing mortality functions.

  • plotSpectra() was incorrectly forcing the y-axis lower limit to 1e-20
    (instead of auto-scaling to the data) and was using min(params@w) / 100
    as the default lower w-axis limit even when resource = FALSE, where
    min(params@w) is more appropriate.

  • upgradeParams() was silently dropping some slots (e.g. resource_dynamics)
    and was not preserving MizerParams subclasses and their extra slots when
    upgrading older objects.

  • getMeanMaxWeight() now correctly applies the species selector to the
    denominator.

  • plotDataFrame() now correctly applies custom log-scale x breaks.

  • get_size_range_array() no longer gives an error when no size brackets are
    selected.

Breaking changes

  • The default ratio argument in plotBiomassObservedVsModel() and
    plotlyBiomassObservedVsModel() is now consistently FALSE for all object
    types. Calls that relied on the previous default ratio plot should now set
    ratio = TRUE.

  • The first argument of plotBiomass(), plotYield(), plotYieldGear() and
    their MizerSim methods and plotly* wrappers has been renamed from sim
    to object for consistency with other plot generics. Calls using
    sim = ... as a named argument must be updated to object = ....

  • The names of the dimnames of the arrays returned by getMort(),
    getPredRate() are now sp and w to be in line with other
    functions like getFMort().

  • Functions that return arrays of the form (species x size), (time x species)
    or (time x species x size) now return them with extra attributes and an S3
    class of ArraySpeciesBySize, ArrayTimeBySpecies or
    ArrayTimeBySpeciesBySize. While this does not change their old behaviour,
    the differences will be flagged by functions like is.identical().

  • Because plotDataFrame() now correctly applies custom log-scale x breaks,
    the axis ticks in plots that use this function have changed.

  • plotDiet() no longer accepts a time_range argument.

Biosphere - Marine Life and Fishery - R
Published by gustavdelius about 1 month ago

mizer - v2.5.4

  • New function renameGear() to rename gears in a MizerParams object, similar
    to renameSpecies().
  • addSpecies() now proceeds with a warning instead of an error when species
    growth stops after maturity (#315).
  • matchBiomasses() and matchNumbers() now provide more informative error
    messages.
  • plotDiet() now restricts the plot to size ranges with meaningful biomass
    density (#317).
  • The wlim and ylim arguments 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.
  • species and gears columns are now never factors, so no longer need to
    call as.character() so often.
  • validParams() also calls validGearParams().
  • validParams() checks that w_min is valid for all species and increases it
    if necessary.
  • validSpeciesParams() now also sets default for p to be equal to n.
  • species_params<-() and given_species_params<-() now check that species
    names match.
  • The params argument in l2w() and w2l() has been renamed to species_params
    to follow mizer's convention that params refers 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 the w_pp_cutoff parameter to the
    carrying capacity and initial resource abundance when changed without
    providing resource_capacity(#306).
  • Predation kernels are now truncated as documented.
  • given_species_params() no longer makes unwanted changes to the species
    parameters.
  • steadySingleSpecies() no longer changes time_modified.

Full Changelog: https://github.com/sizespectrum/mizer/compare/v2.5.3...v2.5.4

Biosphere - Marine Life and Fishery - R
Published by gustavdelius 8 months ago

mizer -

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 all species_params of 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 and validSpeciesParams() validates and returns a completed
    species parameter dataframe.
  • New species parameter w_repro_max giving the size at which a species
    invests 100% of its energy into reproduction. Set to w_max by default.
  • removeSpecies() now also removes species parameters that are NA for
    all of the remaining species.
  • Changing w_max now also correctly updates ft_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 new gears
    argument.
  • New helper function valid_gears_arg() to check the gears argument in
    functions that take a gears argument.
  • Improved scaling of the y-axis in plotGrowthCurves().
  • steadySingleSpecies() no longer requires species to grow to w_max.
  • matchGrowth() now also rescales the external encounter rate.
  • setExtEncounter() no longer resets the external encounter rate to zero when
    called without the ext_encounter argument.
  • The function plotBiomassObservedVsModel() now plots the ratio of modelled
    to observed biomass as default (ratio = TRUE).
  • The time_modified field is now updated correctly by steadySingleSpecies(),
    setColours() and setLinetypes().
  • Deprecated matchYields() and calibrateYield().
  • project() and projectToSteady(..., return_sim = TRUE) now correctly
    returns also the other components of the MizerSim object stored in n_other.
    #285
  • Improved some unit tests.
  • Some improvements to documentation.

Biosphere - Marine Life and Fishery - R
Published by gustavdelius over 1 year ago

mizer - 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 effort argument in project() is improved.
  • An error message is given if a predation kernel returns negative values or
    is everywhere zero. #283

Bug fixes

  • When the coefficient h of the maximum intake rate is not given, it is now
    again given a default value. #282
  • matchGrowth() no longer gives an error when there is no w_inf column. #279

Biosphere - Marine Life and Fishery - R
Published by gustavdelius over 2 years ago

mizer - 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 new size_at_age argument.
  • New functions calibrateNumber() and matchNumbers() that are like
    calibrateBiomass() and matchBiomasses() 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() or setInitialValues()
    the user can now choose geometric averaging with geometric_mean = TRUE.
  • The w_mat25 species parameter is no longer filled in automatically if it is
    not supplied. This makes it easier to change w_mat without having to change
    w_mat25 at 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_level argument in newMultispeciesParams() now
    leads to more messages.
  • Giving more helpful messages in validSpeciesParams(). #136
  • New helper functions l2w() and w2l() 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 style argument to plotDataFrame() to facilitate producing area plots.
  • Add wrap_scale argument to plotDataFrame() to control scaling of axes in
    faceted plots.
  • plotDiet() can now show diets of several predator species in a faceted
    plot. #267
  • Change from size to linewidth aesthetic 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 as R_max is 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
    via defaults_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 of f0
    for larvae also if interaction_resource is 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_inf no longer leads to error in plyr::aaply(). #269
  • Can now again set url field in metadata.
  • Correct species now listed in the legend of plotYieldObservedVsModel() and
    plotBiomassObservedVsModel(). #266
  • Standard order for legend in plotDiet() restored after change to ggplot2
    package. #265
  • Fix handling of column names when interaction matrix is read from .csv file.
    #263

Biosphere - Marine Life and Fishery - R
Published by gustavdelius over 3 years ago

mizer - mizer 2.3.1

  • Resolved conflict in mizerPredRate() between the argument t and the
    function base::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() and getYield()
    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.

Biosphere - Marine Life and Fishery - R
Published by gustavdelius about 4 years ago

mizer - v2.3.0

New features

  • New plots plotBiomassObservedVsModel() and plotYieldObservedVsModel()
    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() and matchYields() 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 of params <- setReproduction(params, maturity = my_maturity) one
    can simply use maturity(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. See getMetadata(). This helps you keep track of
    different versions of your model.
  • steady() now has a preserve argument with possible values erepro,
    R_max or reproduction_level to specify which quantity to preserve.
    This means that one can continue to use steady() 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_params are now set to "species, gear", so that one
    can access individual entries with for example
    gear_params(NS_params)["Cod, Otter", "catchability"]. #212
  • The z0 argument of setExtMort() has been deprecated in favour of
    ext_mort in order to avoid confusion with the species parameter z0.
  • setColours() and setLinetypes() now issue warnings when invalid values
    are given and ignores NAs.
  • The experimental comment arguments to the setter functions have been
    removed. #214
  • The setter functions have a new reset argument which, when set to TRUE
    will recalculate the rates from the species_, gear_ and resource_params even
    when custom values had been set. #214
  • The species argument 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
    example plotSpectra(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 inter for the North Sea model now has the
    alternative name NS_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_l and max_l used in some
    summary functions and processed by get_size_range_array() accept vector
    values setting different limits for different species.
  • The resource dynamics function is now also passed the resource_rate and the
    resource_capacity as 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 linecolour or linetype in 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() with species_panel = TRUE now respects the species
    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.

Biosphere - Marine Life and Fishery - R
Published by gustavdelius almost 5 years ago

mizer - v2.2.1

Biosphere - Marine Life and Fishery - R
Published by gustavdelius about 5 years ago

mizer - v2.1.0

Biosphere - Marine Life and Fishery - R
Published by gustavdelius over 5 years ago

mizer - v2.0.4

A maintenance release

Biosphere - Marine Life and Fishery - R
Published by gustavdelius almost 6 years ago

mizer - v2.0.3

A maintenance release.

Biosphere - Marine Life and Fishery - R
Published by gustavdelius almost 6 years ago

mizer - v2.0.2

A maintenance release.

Biosphere - Marine Life and Fishery - R
Published by gustavdelius about 6 years ago

mizer - v2.0.1

A maintenance release.

Biosphere - Marine Life and Fishery - R
Published by gustavdelius about 6 years ago

mizer - v2.0.0

This is a major new release with many new features, an internal refactoring of the code and a new extension mechanism.

Biosphere - Marine Life and Fishery - R
Published by gustavdelius over 6 years ago

mizer -

Biosphere - Marine Life and Fishery - R
Published by gustavdelius over 7 years ago

mizer -

Biosphere - Marine Life and Fishery - R
Published by gustavdelius over 7 years ago

mizer - Performance Improvements

mizer 0.4

  • Improvements made to the speed by evaluating convolution sums via fft,
    removing the bottlenecks in getPhiPrey() and getPredRate().
  • Using C++ for the inner loop in the project method for extra speed.
  • Minor corrections to vignette and documentation to bring them into alignment
    and to document the new home on github and new maintainers.

Biosphere - Marine Life and Fishery - R
Published by gustavdelius over 8 years ago