Title: | State-Space Mass-Balance Model for Marine Ecosystems |
---|---|
Description: | Fits a state-space mass-balance model for marine ecosystems, which implements dynamics derived from `Ecopath with Ecosim` (`EwE`) <https://ecopath.org/> while fiting to time-series of fishery catch, biomass indices, age-composition samples, and weight-at-age data. `Ecostate` fits biological parameters (e.g., equilibrium mass) and measurement parameters (e.g., catchability coefficients) jointly with residual variation in process errors, and can include Bayesian priors for parameters. |
Authors: | James T. Thorson [aut, cre] |
Maintainer: | James T. Thorson <[email protected]> |
License: | GPL-3 |
Version: | 0.2.0 |
Built: | 2024-11-25 16:38:18 UTC |
Source: | https://github.com/james-thorson-noaa/ecostate |
Third-order Adams-Bashford-Moulton predictor-corrector method.
abm3pc_sys(f, a, b, y0, n, Pars, ...)
abm3pc_sys(f, a, b, y0, n, Pars, ...)
f |
function in the differential equation |
a |
starting time for the interval to integrate |
b |
ending time for the interval to integrate. |
y0 |
starting values at time |
n |
number of steps |
Pars |
named list of parameters passed to f |
... |
additional inputs to function |
Combined Adams-Bashford and Adams-Moulton (or: multi-step) method of third order with corrections according to the predictor-corrector approach. Copied from pracma under GPL-3, with small modifications to work with RTMB
List with components x for grid points between a and b and y an n-by-m matrix with solutions for variables in columns, i.e. each row contains one time stamp.
Compute equilibrium values
add_equilibrium(ecoparams, scale_solver, noB_i, type_i)
add_equilibrium(ecoparams, scale_solver, noB_i, type_i)
ecoparams |
list of parameters |
scale_solver |
Whether to solve for ecotrophic efficiency EE given biomass B
( |
noB_i |
Boolean vector indicating which taxa have no B value |
type_i |
character vector indicating whether a taxon is "hetero", "auto", or "detritus" |
Replaces NA values in ecotrophic efficiency and/or biomass with equilibrium solution, and then calculates equilibrium consumption, natural mortality, and other rates.
the list of parameters with missing values in ecoparams$B_i
and/or
ecoparams$EE_i
filled in, as well as additional values Qe_ij
,
m0_i
, and GE_i
Compute negative log-likelihood for EcoState model
compute_nll( p, taxa, years, noB_i, type_i, n_species, project_vars, DC_ij, Bobs_ti, Cobs_ti, Nobs_ta_g2, Wobs_ta_g2, log_prior, fit_eps, fit_nu, stanza_data, settings, control )
compute_nll( p, taxa, years, noB_i, type_i, n_species, project_vars, DC_ij, Bobs_ti, Cobs_ti, Nobs_ta_g2, Wobs_ta_g2, log_prior, fit_eps, fit_nu, stanza_data, settings, control )
p |
list of parameters |
taxa |
Character vector of taxa included in model. |
years |
Integer-vector of years included in model |
noB_i |
Boolean vector indicating which taxa have no B value |
type_i |
character vector indicating whether a taxon is "hetero", "auto", or "detritus" |
n_species |
number of species |
project_vars |
function to integrate differential equation |
DC_ij |
Diet projections matrix |
Bobs_ti |
formatted matrix of biomass data |
Cobs_ti |
formatted matrix of catch data |
Nobs_ta_g2 |
formatted list of age-comp data |
Wobs_ta_g2 |
formatted list of weight-at-age data |
log_prior |
A user-provided function that takes as input the list of
parameters |
fit_eps |
Character-vector listing |
fit_nu |
Character-vector listing |
stanza_data |
output from |
settings |
Output from |
control |
output from ecostate_control |
Given a list of parameters, calculates the joint negative log-likelihood, where the Laplace approximation is then used to marginalize across random effects to calculate the log-marginal likelihood of fixed effects. The joint likelihood includes the fit to fishery catches, biomass indices, age-composition data, weight-at-age data, priors, and the distribution for random effects.
The joint negative log-likelihood including contribution of priors and fit to data.
Calculate how a tracer propagates through consumption.
compute_tracer( Q_ij, inverse_method = c("Penrose_moore", "Standard"), type_i, tracer_i = rep(1, nrow(Q_ij)) )
compute_tracer( Q_ij, inverse_method = c("Penrose_moore", "Standard"), type_i, tracer_i = rep(1, nrow(Q_ij)) )
Q_ij |
Consumption of each prey i by predator j in units biomass. |
inverse_method |
whether to use pseudoinverse or standard inverse |
type_i |
character vector indicating whether a taxon is "hetero", "auto", or "detritus" |
tracer_i |
an indicator matrix specifying the traver value |
Trophic level for each predator
is defined as:
where is the proportion consumption for each predator (column)
of different prey (rows). We identify primary producers as any taxa with no
consumption (a column of 0s), and assign them as the first trophic level.
More generically, a tracer might be used to track movement of biomass through
consumption. For example, if we have a tracer that is 1 for the
base of the pelagic food chain, and 0 otherwise, then we can calculate
the proportion of pelagic vs. nonpelagic biomass for each taxon:
This then allows us to separate alternative components of the foodweb.
The vector
resulting from tracer
Compute system of differential equations representing EcoState dynamics derived from EcoSim.
dBdt( Time, State, Pars, type_i, n_species, F_type = "integrated", what = "dBdt" )
dBdt( Time, State, Pars, type_i, n_species, F_type = "integrated", what = "dBdt" )
Time |
not used |
State |
vector of state variables to integrate |
Pars |
list of parameters governing the ODE |
type_i |
type for each taxon |
n_species |
number of species |
F_type |
whether to integrate catches along with biomass ( |
what |
what output to produce |
This function has syntax designed to match pracma
solvers.
An object (list) of ranges. Elements include:
Biomass growth per time
Biomass growth per time per biomass
Consumptive mortality per time
Consumptive mortality per time per biomass
Natural mortality per time
Natural mortality per time per biomass (i.e., m2_i + m0_i)
Consumption per time for prey (rows) by predator (columns)
Allows data-weighting as parameter
ddirmult(x, prob, ln_theta, log = TRUE)
ddirmult(x, prob, ln_theta, log = TRUE)
x |
numeric vector of observations across categories |
prob |
numeric vector of category probabilities |
ln_theta |
logit-ratio of effective and input sample size |
log |
whether to return the log-probability or not |
The log-likelihood resulting from the Dirichlet-multinomial distribution
library(RTMB) prob = rep(0.1,10) x = rmultinom( n=1, prob=prob, size=20 )[,1] f = function( ln_theta ) ddirmult(x, prob, ln_theta) f( 0 ) F = MakeTape(f, 0) F$jacfun()(0)
library(RTMB) prob = rep(0.1,10) x = rmultinom( n=1, prob=prob, size=20 )[,1] f = function( ln_theta ) ddirmult(x, prob, ln_theta) f( 0 ) F = MakeTape(f, 0) F$jacfun()(0)
Data used to demonstrate a Model of Intermediate Complexity (MICE)
for the eastern Bering Sea.
data(eastern_bering_sea)
loads a list that includes four components:
Survey
is a long-form data-frame with three columns, providing the Year,
Mass (in relative units for most taxa, and million metric tons for Pollock,
Cod, Arrowtooth, and NFS), and Taxon for each year with available data
Catch
is a long-form data-frame with three columns, providing the Year,
Mass (in million metric tons), and Taxon for each year with available data
P_over_B
is a numeric vector with the unitless ratio of biomass production to
population biomass for each taxon
Q_over_B
is a numeric vector with the unitless ratio of biomass consumption to
population biomass for each taxon
Diet_proportions
is a numeric matrix where each column lists the
proportion of biomass consumed that is provided by each prey (row)
data(eastern_bering_sea)
data(eastern_bering_sea)
The data compiled come from a variety of sources:
Northern fur seal (NFS) survey is an absolute index, corrected for proportion of time spent in the eastern Bering Sea. NFS QB is developed from a bioenergetic model and also corrected for seasonal residency. Both are provided by Elizabeth McHuron. It is post-processed in a variety of ways, and not to be treated as an index of abundance for NFS for other uses.
Pollock, cod, and arrowtooth surveys are from a bottom trawl survey, and cod and arrowtooth are treated as an absolute index.
Copepod and other zooplankton are from an oblique tow bongo net survey, with data provided by Dave Kimmel. It is then post-processed to account for spatially and seaonally imbalanced data.
Other P_over_B, Q_over_B and Diet_proportions values are derived from Rpath models, provided by Andy Whitehouse.
Primary producers is an annual index of relative biomass, developed from monthly satellite measurements and provided by Jens Nielsen. See Thorson et al. (In review) for more details regarding data standardization and sources
Estimate parameters for an EcoState model
ecostate( taxa, years, catch = data.frame(Year = numeric(0), Mass = numeric(0), Taxon = numeric(0)), biomass = data.frame(Year = numeric(0), Mass = numeric(0), Taxon = numeric(0)), agecomp = list(), weight = list(), PB, QB, B, DC, EE, X, type, U, fit_B = vector(), fit_Q = vector(), fit_B0 = vector(), fit_EE = vector(), fit_PB = vector(), fit_QB = vector(), fit_eps = vector(), fit_nu = vector(), log_prior = function(p) 0, settings = stanza_settings(taxa = taxa), control = ecostate_control() )
ecostate( taxa, years, catch = data.frame(Year = numeric(0), Mass = numeric(0), Taxon = numeric(0)), biomass = data.frame(Year = numeric(0), Mass = numeric(0), Taxon = numeric(0)), agecomp = list(), weight = list(), PB, QB, B, DC, EE, X, type, U, fit_B = vector(), fit_Q = vector(), fit_B0 = vector(), fit_EE = vector(), fit_PB = vector(), fit_QB = vector(), fit_eps = vector(), fit_nu = vector(), log_prior = function(p) 0, settings = stanza_settings(taxa = taxa), control = ecostate_control() )
taxa |
Character vector of taxa included in model. |
years |
Integer-vector of years included in model |
catch |
long-form data frame with columns |
biomass |
long-form data frame with columns |
agecomp |
a named list, with names corresponding to |
weight |
a named list, with names corresponding to |
PB |
numeric-vector with names matching |
QB |
numeric-vector with names matching |
B |
numeric-vector with names matching |
DC |
numeric-matrix with rownames and colnames matching |
EE |
numeric-vector with names matching |
X |
numeric-matrix with rownames and colnames matching |
type |
character-vector with names matching |
U |
numeric-vector with names matching |
fit_B |
Character-vector listing |
fit_Q |
Character-vector listing |
fit_B0 |
Character-vector listing |
fit_EE |
Character-vector listing |
fit_PB |
Character-vector listing |
fit_QB |
Character-vector listing |
fit_eps |
Character-vector listing |
fit_nu |
Character-vector listing |
log_prior |
A user-provided function that takes as input the list of
parameters |
settings |
Output from |
control |
Output from |
All taxa
must be included in QB
, PB
, B
, and DC
,
but additional taxa can be in QB
, PB
, B
, and DC
that
are not in taxa
. So taxa
can be used to redefine the set of modeled
species without changing other inputs
An object (list) of S3-class ecostate
. Elements include:
RTMB object from MakeADFun
The list of inputs passed to MakeADFun
The output from nlminb
The output from sdreport
Objects useful for package function, i.e., all arguments passed during the call
report file, including matrix B_ti
for biomass in each year
t
and taxon i
, g_ti
for growth rate per biomass,
and see dBdt
for other quantities reported by year
derived quantity estimates and standard errors, for rep
objects as requested
function call record
Total runtime
This S3 class then has functions summary
, print
, and
logLik
Introducing the state-space mass-balance model:
Thorson, J. Kristensen, K., Aydin, K., Gaichas, S., Kimmel, D.G., McHuron, E.A., Nielsen, J.N., Townsend, H., Whitehouse, G.A (In press). The benefits of hierarchical ecosystem models: demonstration using a new state-space mass-balance model EcoState. Fish and Fisheries.
Define a list of control parameters.
ecostate_control( nlminb_loops = 1, newton_loops = 0, eval.max = 1000, iter.max = 1000, getsd = TRUE, silent = getOption("ecostate.silent", TRUE), trace = getOption("ecostate.trace", 0), verbose = getOption("ecostate.verbose", FALSE), profile = c("logF_ti", "log_winf_z", "s50_z", "srate_z"), random = c("epsilon_ti", "alpha_ti", "nu_ti", "phi_tg2"), tmb_par = NULL, map = NULL, getJointPrecision = FALSE, integration_method = c("ABM", "RK4", "ode23", "rk4", "lsoda"), process_error = c("epsilon", "alpha"), n_steps = 10, F_type = c("integrated", "averaged"), derived_quantities = c("h_g2", "B_ti", "B0_i"), scale_solver = c("joint", "simple"), inverse_method = c("Standard", "Penrose_moore"), tmbad.sparse_hessian_compress = 1, start_tau = 0.001 )
ecostate_control( nlminb_loops = 1, newton_loops = 0, eval.max = 1000, iter.max = 1000, getsd = TRUE, silent = getOption("ecostate.silent", TRUE), trace = getOption("ecostate.trace", 0), verbose = getOption("ecostate.verbose", FALSE), profile = c("logF_ti", "log_winf_z", "s50_z", "srate_z"), random = c("epsilon_ti", "alpha_ti", "nu_ti", "phi_tg2"), tmb_par = NULL, map = NULL, getJointPrecision = FALSE, integration_method = c("ABM", "RK4", "ode23", "rk4", "lsoda"), process_error = c("epsilon", "alpha"), n_steps = 10, F_type = c("integrated", "averaged"), derived_quantities = c("h_g2", "B_ti", "B0_i"), scale_solver = c("joint", "simple"), inverse_method = c("Standard", "Penrose_moore"), tmbad.sparse_hessian_compress = 1, start_tau = 0.001 )
nlminb_loops |
Integer number of times to call |
newton_loops |
Integer number of Newton steps to do after running
|
eval.max |
Maximum number of evaluations of the objective function
allowed. Passed to |
iter.max |
Maximum number of iterations allowed. Passed to |
getsd |
Boolean indicating whether to call |
silent |
Disable terminal output for inner optimizer? |
trace |
Parameter values are printed every |
verbose |
Output additional messages about model steps during fitting? |
profile |
parameters that are profiled across,
passed to |
random |
parameters that are treated as random effects,
passed to |
tmb_par |
list of parameters for starting values, with shape identical
to |
map |
list of mapping values, passed to RTMB::MakeADFun |
getJointPrecision |
whether to get the joint precision matrix. Passed
to |
integration_method |
What numerical integration method to use. |
process_error |
Whether to include process error as a continuous rate
(i.e., an "innovation" parameterization, |
n_steps |
number of steps used in the ODE solver for biomass dynamics |
F_type |
whether to integrate catches along with biomass ( |
derived_quantities |
character-vector listing objects to ADREPORT |
scale_solver |
Whether to solve for ecotrophic efficiency EE given biomass B
( |
inverse_method |
whether to use pseudoinverse or standard inverse |
tmbad.sparse_hessian_compress |
passed to |
start_tau |
Starting value for the standard deviation of process errors |
An S3 object of class "ecostate_control" that specifies detailed model settings, allowing user specification while also specifying default values
Extend MASS:ginv
to work with RTMB
ginv(x)
ginv(x)
x |
Matrix used to compute pseudoinverse |
Extract the (marginal) log-likelihood of a ecostate model
## S3 method for class 'ecostate' logLik(object, ...)
## S3 method for class 'ecostate' logLik(object, ...)
object |
Output from |
... |
Not used |
object of class logLik
with attributes
val |
log-likelihood |
df |
number of parameters |
Returns an object of class logLik. This has attributes
"df" (degrees of freedom) giving the number of (estimated) fixed effects
in the model, abd "val" (value) giving the marginal log-likelihood.
This class then allows AIC
to work as expected.
Runge-Kutta (2, 3)-method with variable step size, resp
ode23(f, a, b, y0, n, Pars, rtol = 0.001, atol = 1e-06)
ode23(f, a, b, y0, n, Pars, rtol = 0.001, atol = 1e-06)
f |
function in the differential equation |
a |
starting time for the interval to integrate |
b |
ending time for the interval to integrate. |
y0 |
starting values at time |
n |
Not used |
Pars |
named list of parameters passed to f |
rtol |
relative tolerance. |
atol |
absolute tolerance. |
Copied from pracma under GPL-3, with small modifications to work with RTMB. This can be used to simulate dynamics, but not during estimation
List with components t for time points between a and b and y an n-by-m matrix with solutions for variables in columns, i.e. each row contains one time stamp.
Plot consumption as a directed graph including all taxa (vertices) and biomass consumed (arrows). Taxa are located using tracers, where by default the y-axis is trophic level. #'
plot_foodweb( Q_ij, type_i, xtracer_i, ytracer_i = rep(1, nrow(Q_ij)), B_i = rep(1, nrow(Q_ij)), taxa_labels = letters[1:nrow(Q_ij)], xloc, yloc )
plot_foodweb( Q_ij, type_i, xtracer_i, ytracer_i = rep(1, nrow(Q_ij)), B_i = rep(1, nrow(Q_ij)), taxa_labels = letters[1:nrow(Q_ij)], xloc, yloc )
Q_ij |
Consumption of each prey i by predator j in units biomass. |
type_i |
character vector indicating whether a taxon is "hetero", "auto", or "detritus" |
xtracer_i |
tracer to use when computing x-axis values |
ytracer_i |
tracer to use when computing y-axis values |
B_i |
biomass to use when weighting taxa in plot |
taxa_labels |
character vector of labels to use for each taxon |
xloc |
x-axis location (overrides calculation using |
yloc |
y-axis location (overrides calculation using |
Trophic level for each predator
is defined as:
where is the proportion consumption for each predator (column)
of different prey (rows). We identify primary producers as any taxa with no
consumption (a column of 0s), and assign them as the first trophic level.
invisibly return ggplot
object for foodweb
Prints parameters defining EcoSim dynamics
print_ecopars(x, silent = FALSE)
print_ecopars(x, silent = FALSE)
x |
Output from |
silent |
whether to print to terminal |
invisibly returns table printed
Prints output from fitted ecostate model
## S3 method for class 'ecostate' print(x, ...)
## S3 method for class 'ecostate' print(x, ...)
x |
Output from |
... |
Not used |
No return value, called to provide clean terminal output when calling fitted object in terminal.
Classical Runge-Kutta of order 4.
rk4sys(f, a, b, y0, n, Pars, ...)
rk4sys(f, a, b, y0, n, Pars, ...)
f |
function in the differential equation |
a |
starting time for the interval to integrate |
b |
ending time for the interval to integrate. |
y0 |
starting values at time |
n |
the number of steps from a to b. |
Pars |
named list of parameters passed to f |
... |
additional inputs to function |
Classical Runge-Kutta of order 4 for (systems of) ordinary differential equations with fixed step size. Copied from pracma under GPL-3, with small modifications to work with RTMB
List with components x for grid points between a and b and y an n-by-m matrix with solutions for variables in columns, i.e. each row contains one time stamp.
Define a list of control parameters.
stanza_settings( taxa, stanza_groups, K, d, Wmat, Amax, SpawnX, Leading, fit_K = c(), fit_d = c(), fit_phi = vector(), Amat = NULL, Wmatslope, STEPS_PER_YEAR = 1, comp_weight = c("multinom", "dir", "dirmult") )
stanza_settings( taxa, stanza_groups, K, d, Wmat, Amax, SpawnX, Leading, fit_K = c(), fit_d = c(), fit_phi = vector(), Amat = NULL, Wmatslope, STEPS_PER_YEAR = 1, comp_weight = c("multinom", "dir", "dirmult") )
taxa |
Character vector of taxa included in model. |
stanza_groups |
character-vector with names corresponding to |
K |
numeric-vector with names matching |
d |
numeric-vector with names matching |
Wmat |
numeric-vector with names matching |
Amax |
numeric-vector with names matching |
SpawnX |
numeric-vector with names matching |
Leading |
Boolean vector with names matching |
fit_K |
Character-vector listing |
fit_d |
Character-vector listing |
fit_phi |
Character-vector listing |
Amat |
numeric-vector with names matching |
Wmatslope |
numeric-vector with names matching |
STEPS_PER_YEAR |
integer number of Euler steps per year for calculating integrating individual weight-at-age |
comp_weight |
method used for weighting age-composition data |
An S3 object of class "stanza_settings" that specifies detailed model settings related to age-structured dynamics (e.g., stanzas), allowing user specification while also specifying default values
All Rpath inputs from Whitehouse et al. 2021
data(whitehouse_2021)
data(whitehouse_2021)