diff --git a/test/parameters.jl b/test/parameters.jl index 6bcaf355..04b5b76c 100644 --- a/test/parameters.jl +++ b/test/parameters.jl @@ -1,19 +1,41 @@ import AIBECS: units, @units import AIBECS: prior, @prior +import AIBECS: limits, @limits import AIBECS: initial_value, @initial_value import AIBECS: flattenable, @flattenable import AIBECS: description, @description -@initial_value @units @description @prior @flattenable struct TestParameters{T} <: AbstractParameters{T} - xgeo::T | 2.17 | u"mmol/m^3" | "Geological mean P concentration" | LogNormal(0,1) | true - τgeo::T | 1.0 | u"Myr" | "Geological restoring timescale" | LogNormal(0,1) | false - k::T | 10.0 | u"μmol/m^3" | "Half-saturation constant (Michaelis-Menten)" | LogNormal(0,1) | true - w₀::T | 1.0 | u"m/d" | "Sinking velocity at surface" | LogNormal(0,1) | true - w′::T | 0.22 | u"m/d/m" | "Vertical gradient of sinking velocity" | Normal(0,1) | true - τDOP::T | 0.25 | u"yr" | "Remineralization timescale (DOP to DIP)" | LogNormal(0,1) | true - τPOP::T | 5.25 | u"d" | "Dissolution timescale (POP to DOP)" | LogNormal(0,1) | true - σ::T | 1/3 | NoUnits | "Fraction of quick local uptake recycling" | Uniform(0,1) | true - τDIP::T | 30.0 | u"d" | "Uptake maximum timescale (DIP to POP)" | LogNormal(0,1) | true +const ∞ = Inf +@initial_value @units @description @limits @flattenable struct TestParameters{T} <: AbstractParameters{T} + xgeo::T | 2.17 | u"mmol/m^3" | "Geological mean P concentration" | (0,∞) | true + τgeo::T | 1.0 | u"Myr" | "Geological restoring timescale" | (0,∞) | false + k::T | 10.0 | u"μmol/m^3" | "Half-saturation constant (Michaelis-Menten)" | (0,∞) | true + w₀::T | 1.0 | u"m/d" | "Sinking velocity at surface" | (0,∞) | true + w′::T | 0.22 | u"m/d/m" | "Vertical gradient of sinking velocity" | (-∞,∞) | true + τDOP::T | 0.25 | u"yr" | "Remineralization timescale (DOP to DIP)" | (0,∞) | true + τPOP::T | 5.25 | u"d" | "Dissolution timescale (POP to DOP)" | (0,∞) | true + σ::T | 1/3 | NoUnits | "Fraction of quick local uptake recycling" | (0,1) | true + τDIP::T | 30.0 | u"d" | "Uptake maximum timescale (DIP to POP)" | (0,∞) | true end +function prior(::Type{T}, s::Symbol) where {T<:AbstractParameters} + if flattenable(T, s) + U = units(T, s) + if limits(T, s) == (0,∞) + μ = log(ustrip(upreferred(initial_value(T, s) * U))) + return LogNormal(μ, 1.0) + elseif limits(T, s) == (-∞,∞) + μ = ustrip(upreferred(initial_value(T, s) * U)) + σ = ustrip(upreferred(10.0U)) # Assumes that a sensible unit is chosen! + return Normal(μ, σ) + elseif limits(T, s) == (0,1) + return Uniform(0,1) + end + else + return nothing + end +end +prior(::T, s::Symbol) where {T<:AbstractParameters} = prior(T,s) +prior(::Type{T}) where {T<:AbstractParameters} = Tuple(prior(T,s) for s in AIBECS.symbols(T)) +prior(::T) where {T<:AbstractParameters} = prior(T) Distributions.gradlogpdf(::Uniform, x::T) where {T<:Real} = zero(T) # Required for these tests because undefined in Distributions... p = TestParameters()