Give the resource a weight-length relationship - #539
Merged
Conversation
`plotSpectra(params, size_axis = "l")` used to drop the resource silently, because the length conversion needs an allometric weight-length relationship and only the species had one. `resource_params()` now carries `a` and `b`, defaulting to the equivalent spherical diameter of an organism with the density of water, `a = pi/6` and `b = 3`. That is the convention plankton ecology uses for a composite of many taxa, and on a mizer grid it puts the smallest resource sizes below a micrometre and a milligram organism at about a millimetre. The resource therefore appears on length-based spectra, and the resource array classes gain `size_axis` and `llim`, `animate()` included. The parameters feed none of the rates, so they are not arguments of `setResource()`; it fills them in as defaults so that `resource_params()` shows them, and they are also defaulted at the point of use so that models saved before they existed need no upgrade. Note that the resource then sits on the length axis at its own convention: a fish of a given weight is about 3.7 times longer than a sphere of that weight. That difference is real rather than an artefact — a 1 mg copepod really is shorter than a 1 mg fish larva — but it does mean the resource and the species are measured differently. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This was referenced Aug 15, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Stacked on #538 — review that one first; this PR's diff is against
array-type-attribute.Summary
plotSpectra(params, size_axis = "l")used to drop the resource silently — 79 rows on the weight axis, 0 on the length axis, no message — because the length conversion needs an allometric weight-length relationship and only the species had one.resource_params()now carriesaandb, defaulting to the equivalent spherical diameter of an organism with the density of water,a = pi/6 ≈ 0.524,b = 3. ESD is the standard convention in plankton ecology precisely because it is geometric rather than taxonomic, so it degrades gracefully across a composite of many taxa. On a mizer grid it gives sensible sizes throughout:w(g)w_pp_cutoff)The resource therefore appears on length-based spectra, and the resource array classes gain
size_axisandllim,animate()included — it used to raise "a length axis is not available for resource arrays".The convention caveat
The resource sits on the length axis at its own convention: a fish of a given weight is about 3.7× longer than a sphere of that weight. Two things about that:
b = 3, the change is a pure translation on a log-length axis: the resource curve keeps its shape and slope.It is also not a new kind of compromise — a length axis is already per-species, since each species converts with its own
a,b.Design
The parameters feed none of the rates, so they are deliberately not arguments of
setResource(). Instead:setResource()fills them in as defaults, so every newly built model shows them inresource_params()and users can change them there;resource_length_params()), so a model saved before they existed needs no upgrade — andrepair_params()andvalidation_key()stay untouched, which would otherwise have meant addingresource_paramsto the fingerprint of every object.resource_params<-()validates them when present.The one shared change is
plot_length_params(), which replaces the inlinespecies_paramslookup inconvert_plot_size_axis()and the Jacobian inconvert_plot_density_axis(). It returnsa/bper row — from the species, from the resource, orNAfor anything else — so both the coordinate conversion and the density Jacobian handle the resource through one place.Testing
Full suite: 4288 passing, 0 failures. New tests cover the default and the fallback for old objects, validation, the ESD sanity check (µm at 1e-12 g, mm at 1e-3 g, the 3.741 fish/ESD ratio), the resource on a length axis with the Jacobian and
llim, and the resource joining a length-axisplotSpectra(). One existing test asserted that bothResourceandTotalare hidden on a length axis; it now asserts thatResourceappears andTotalstill does not — the latter is the next PR.🤖 Generated with Claude Code