API reference

Entry points

BayesBiont.bayesfitFunction
bayesfit(data::GrowthData, spec::BayesianModelSpec[, opts::BayesFitOptions]; group=nothing)

Fit each curve in data Bayesianly under spec. Returns BayesianGrowthFitResults.

v0.1 fits each curve independently. The group= kwarg is reserved for hierarchical pooling in v0.2 and errors today.

For multi-model spec (more than one candidate model), v0.1 fits only the first model per curve. Model comparison via LOO/WAIC lands in v0.3.

Example

using BayesBiont, Kinbiont, Statistics

times = collect(0.0:0.25:24.0)
curve = 1.0 .* exp.(-exp.(-0.4 .* (times .- 5.0)))
data  = GrowthData(reshape(curve, 1, :), times, ["well1"])

spec  = BayesianModelSpec([MODEL_REGISTRY["NL_Gompertz"]])
post  = bayesfit(data, spec, BayesFitOptions(n_chains=2, n_warmup=400, n_samples=400))

r = post[1]
mean(r.growth_rate), quantile(r.growth_rate, [0.025, 0.975])
source

Spec and options

BayesBiont.BayesianModelSpecType
BayesianModelSpec(models; priors=nothing, sigma_prior=Exponential(0.1))

Specifies which Kinbiont models to fit Bayesianly and (optionally) their priors.

  • models::Vector{<:AbstractGrowthModel}: candidate models, typically from Kinbiont.MODEL_REGISTRY.
  • priors::Union{Nothing, Vector}: one prior NamedTuple per model, keyed by parameter name (Symbol). When nothing, BayesBiont derives weakly-informative LogNormal priors from model.guess(data_mat) at fit time.
  • sigma_prior::Distribution: prior on the observation-noise scale σ.
source
BayesBiont.BayesFitOptionsType
BayesFitOptions(; kwargs...)

Configuration for Bayesian fitting.

  • method::Symbol = :nuts: inference algorithm. :nuts for calibrated posteriors, :advi for fast variational approximation (mean-field; underestimates uncertainty but typically 10–100× faster — useful for plate-scale screening, follow up with NUTS on wells of interest).
  • likelihood::Symbol = :lognormal: :lognormal, :normal, or :proportional.
  • n_chains::Int = 4, n_warmup::Int = 1000, n_samples::Int = 1000 — NUTS only.
  • target_accept::Float64 = 0.95: NUTS dual-averaging target.
  • max_treedepth::Int = 10: NUTS only.
  • advi_n_iters::Int = 5000: ADVI optimisation iterations.
  • advi_samples_per_step::Int = 10: ADVI ELBO Monte Carlo samples per gradient step.
  • jitter::Float64 = 0.1: log-space jitter around model.guess() for per-chain init.
  • rng_seed::Union{Nothing, Int} = nothing: deterministic seed when set.
  • adbackend::Symbol = :forwarddiff: :forwarddiff (default) or :reversediff.
source

Results

BayesBiont.BayesianCurveFitResultType
BayesianCurveFitResult(label, model, chains, times, observed, likelihood)

Bayesian fit result for a single growth curve. Field access shortcut: result.param_name returns a flat sample vector for any parameter in the underlying Chains. likelihood records which observation model was used (needed for waic, loo, posterior_predict).

source
BayesBiont.BayesianGrowthFitResultsType
BayesianGrowthFitResults(data, results)

Container for per-curve Bayesian fits. Iterable; indexable by integer; carries the input GrowthData for downstream reference.

source
BayesBiont.HierarchicalBayesianFitResultsType
HierarchicalBayesianFitResults

Result of a hierarchical bayesfit with group=. Holds:

  • data — original GrowthData
  • model — Kinbiont model fitted
  • group_labels — group string per row of data
  • groups — ordered unique group names
  • chains — single big Chains with all parameters
  • times, observed_per_curve — input data echoed for downstream evaluation
source

Posterior predictive and contrasts

BayesBiont.posterior_predictFunction
posterior_predict(result::BayesianCurveFitResult; n_draws=200) -> Matrix{Float64}

Posterior predictive curve samples on result.times. Returns an n_draws × n_timepoints matrix; row i is the deterministic curve evaluated at posterior draw i. Use vec(mean(out, dims=1)) for the posterior mean curve and mapslices(c -> quantile(c, [0.025, 0.975]), out; dims=1) for pointwise 95% bands.

Lazy by design — not cached on result; recompute when you need different n_draws.

source
BayesBiont.contrastFunction
contrast(r::HierarchicalBayesianFitResults, group1, group2; param::Symbol) -> Vector{Float64}

Posterior samples of the native-scale difference exp(μ_pop[group1, param]) - exp(μ_pop[group2, param]). Use mean(out), quantile(out, [0.025, 0.975]), and mean(out .> 0) for the standard "is group1 higher than group2?" probability statement.

source

Model comparison

BayesBiont.looFunction
loo(r::BayesianCurveFitResult) -> (elpd, se, n_obs, pareto_k_max, elpd_pointwise)

Leave-one-out cross-validation expected log predictive density via Pareto-smoothed importance sampling (PSIS-LOO). Returns:

  • elpd: PSIS-LOO ELPD estimate (higher = better fit)
  • se: standard error of the ELPD estimate
  • n_obs: number of observations
  • pareto_k_max: maximum Pareto-k diagnostic. Values > 0.7 indicate the importance-sampling approximation is unreliable for some observation;

    1.0 means PSIS-LOO cannot be trusted on this data.

  • elpd_pointwise: per-observation ELPD contributions (useful for compare).
source
BayesBiont.waicFunction
waic(r::BayesianCurveFitResult) -> (elpd, p_eff, n_obs)

Watanabe–Akaike Information Criterion (WAIC) estimate of out-of-sample predictive performance. Returns:

  • elpd: expected log pointwise predictive density (higher = better fit)
  • p_eff: effective number of parameters (penalty)
  • n_obs: number of observations used

WAIC tends to be unreliable when individual observations strongly influence the posterior — prefer loo (PSIS-LOO) for robust model comparison.

source
BayesBiont.compareFunction
compare(r1, r2) -> (elpd_diff, se_diff, favours)

Compare two BayesianCurveFitResults by PSIS-LOO ELPD. Returns the difference elpd(r1) − elpd(r2), its standard error, and a string naming which model is favoured. A difference of more than ~2 SEs is conventionally treated as a meaningful preference; smaller differences mean the data don't strongly distinguish the two models.

source
BayesBiont.pointwise_loglikFunction
pointwise_loglik(r::BayesianCurveFitResult) -> Matrix{Float64}

Per-(sample, observation) log-likelihood matrix, shape (n_samples, n_obs). Recomputes the model at each posterior draw and applies the same observation density used during fitting (r.likelihood).

source

Priors

BayesBiont.DEFAULT_PRIORSConstant
DEFAULT_PRIORS

Curated weakly-informative LogNormal priors for canonical Kinbiont models, grounded in typical microbial-growth literature ranges (OD scale, bacterial growth at 25–40 °C).

ParameterTypical rangeLogNormal centre × scale
N_max / carrying capacity0.1 – 3.0 ODLogNormal(log(1.0), 0.7) ≈ 95% CI [0.25, 4]
growth rate μ (hr⁻¹)0.05 – 2.0LogNormal(log(0.5), 0.8) ≈ 95% CI [0.10, 2.4]
lag time λ (hr)0 – 24LogNormal(log(5.0), 1.0) ≈ 95% CI [0.7, 35]

These priors are appropriate for plate-reader OD data on typical bacteria. For unusual scales (cell counts, dense cultures, slow-growing organisms) or non-standard time units, supply explicit priors via BayesianModelSpec(...; priors=...).

Models not in this registry fall back to empirical_priors derived from model.guess(data_mat).

source
BayesBiont.default_priorsFunction
default_priors(model, data_mat) -> NamedTuple

Curated biology-grounded priors when model.name is in [DEFAULT_PRIORS]; otherwise empirical LogNormal(log(model.guess(data_mat)), 1.0) per parameter.

source
BayesBiont.empirical_priorsFunction
empirical_priors(model, data_mat) -> NamedTuple

Weakly-informative LogNormal priors derived from model.guess(data_mat). Each parameter gets LogNormal(log(guess_p), 1.0) — a 95% CI spanning ×7 either way.

source

Utilities

BayesBiont.group_from_labelsFunction
group_from_labels(data::GrowthData; pattern=r"^([A-Za-z]+)") -> Vector{String}

Parse a grouping vector from data.labels by extracting the first regex capture group from each label. Default pattern grabs the leading alphabetic prefix (e.g. "WT_1""WT"). Helper for v0.2 hierarchical pooling; usable today for ad-hoc grouping.

source