Skip to content

Commit

Permalink
🚧 GrowthRate Upgraded.
Browse files Browse the repository at this point in the history
  • Loading branch information
iago-lito committed Oct 24, 2024
1 parent 5e7c75e commit 1609a56
Show file tree
Hide file tree
Showing 10 changed files with 65 additions and 55 deletions.
1 change: 1 addition & 0 deletions src/components/allometry.jl
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
include("./allometry_api.jl")
include("./allometry_identifiers.jl")
using .AllometryApi
export Allometry

# Check the given parameters against a template (typically a default value)
# so as to reject missing or unexpected values.
Expand Down
4 changes: 3 additions & 1 deletion src/components/blueprint_modules.jl
Original file line number Diff line number Diff line change
Expand Up @@ -5,14 +5,16 @@ using SparseArrays
using EcologicalNetworksDynamics
const EN = EcologicalNetworksDynamics
const F = EcologicalNetworksDynamics.Framework
import EcologicalNetworksDynamics:
import .EN:
AliasingDicts,
Blueprint,
Internals,
SparseMatrix,
Topologies,
check_template,
imap,
sparse_nodes_allometry,
sparse_nodes_allometry,
@get,
@ref
import .F: @blueprint, checkfails, Brought, checkrefails
Expand Down
6 changes: 3 additions & 3 deletions src/components/body_mass.jl
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
# ==========================================================================================
# Blueprints.

module BM
module BodyMass_
include("blueprint_modules.jl")
include("blueprint_modules_identifiers.jl")
import .EcologicalNetworksDynamics: _Species, Species, _Foodweb, Foodweb
Expand Down Expand Up @@ -105,7 +105,7 @@ end
# ==========================================================================================
# Component and generic constructors.

@component BodyMass{Internal} requires(Species) blueprints(BM)
@component BodyMass{Internal} requires(Species) blueprints(BodyMass_)
export BodyMass

(::_BodyMass)(M::Real) = BodyMass.Flat(M)
Expand All @@ -132,7 +132,7 @@ end
ref(raw -> raw._foodweb.M)
get(BodyMasses{Float64}, "species")
write!((raw, rhs::Real, i) -> begin
BM.check(rhs, i)
BodyMass_.check(rhs, i)
rhs
end)
end
Expand Down
4 changes: 2 additions & 2 deletions src/components/foodweb.jl
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
# ==========================================================================================
# Blueprints.

module FoodwebBlueprints
module Foodweb_
include("blueprint_modules.jl")
include("blueprint_modules_identifiers.jl")
import .EN: _Species, Species
Expand Down Expand Up @@ -126,7 +126,7 @@ end
# ==========================================================================================
# Component and generic constructors.

@component Foodweb{Internal} requires(Species) blueprints(FoodwebBlueprints)
@component Foodweb{Internal} requires(Species) blueprints(Foodweb_)
# Consistency alias.
const (TrophicLayer, _TrophicLayer) = (Foodweb, _Foodweb)
export Foodweb, TrophicLayer
Expand Down
21 changes: 9 additions & 12 deletions src/components/growth_rate.jl
Original file line number Diff line number Diff line change
Expand Up @@ -11,16 +11,13 @@
# (reassure JuliaLS)
(false) && (local GrowthRate, _GrowthRate)

# HERE: test after fixing JuliaLS.

# ==========================================================================================
# Blueprints.

module GR
module GrowthRate_
include("blueprint_modules.jl")
include("blueprint_modules_identifiers.jl")
import .EcologicalNetworksDynamics:
Species, _Species, BodyMass, MetabolicClass, _Temperature
import .EN: Species, _Species, BodyMass, MetabolicClass, _Temperature

#-------------------------------------------------------------------------------------------
# From raw values.
Expand Down Expand Up @@ -84,7 +81,7 @@ function F.late_check(raw, bp::Map)
(; r) = bp
index = @ref raw.species.index
prods = @ref raw.producers.mask
@check_list_refs r :species index template(prods)
@check_list_refs r :producer index template(prods)
for (sp, m) in r
check(m, sp)
end
Expand Down Expand Up @@ -116,7 +113,7 @@ export Allometric

function F.early_check(bp::Allometric)
(; allometry) = bp
@check_template allometry miele2019_growth_allometry_rates() "growth rates"
check_template(allometry, miele2019_growth_allometry_rates(), "growth rates")
end

function F.expand!(raw, bp::Allometric)
Expand Down Expand Up @@ -152,9 +149,9 @@ export Temperature

function F.early_check(bp::Temperature)
(; allometry) = bp
@check_template(
check_template(
allometry,
binzer2016_growth_allometry_rates(),
binzer2016_growth_allometry_rates()[2],
"growth rates (from temperature)",
)
end
Expand All @@ -165,7 +162,7 @@ function F.expand!(raw, bp::Temperature)
M = @ref raw.M
mc = @ref raw.metabolic_classes
prods = @ref raw.producers.mask
r = sparse_nodes_allometry(bp.allometry, prods, M, mc, E_a, T)
r = sparse_nodes_allometry(bp.allometry, prods, M, mc; E_a, T)
expand!(raw, r)
end

Expand All @@ -174,7 +171,7 @@ end
# ==========================================================================================
# Component and generic constructors.

@component GrowthRate{Internal} requires(Foodweb) blueprints(GR)
@component GrowthRate{Internal} requires(Foodweb) blueprints(GrowthRate_)
export GrowthRate

# Construct either variant based on user input,
Expand Down Expand Up @@ -210,7 +207,7 @@ end
get(GrowthRates{Float64}, sparse, "producer")
template(raw -> @ref raw.producers.mask)
write!((raw, rhs::Real, i) -> begin
GR.check(rhs)
GrowthRate_.check(rhs)
rhs = Float64(rhs)
raw.biorates.r[i] = rhs
rhs
Expand Down
6 changes: 3 additions & 3 deletions src/components/hill_exponent.jl
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
# ==========================================================================================
# Blueprints.

module HE
module HillExponent_
include("blueprint_modules.jl")

#-------------------------------------------------------------------------------------------
Expand All @@ -28,7 +28,7 @@ end
# ==========================================================================================
# Component and generic constructors.

@component HillExponent{Internal} blueprints(HE)
@component HillExponent{Internal} blueprints(HillExponent_)
export HillExponent

(::_HillExponent)(h) = HillExponent.Raw(h)
Expand All @@ -38,7 +38,7 @@ export HillExponent
depends(HillExponent)
get(raw -> raw._scratch[:hill_exponent])
set!((raw, rhs::Real) -> begin
HE.check_value(rhs)
HillExponent_.check_value(rhs)
h = Float64(rhs)
raw._scratch[:hill_exponent] = h
# Legacy updates, required because scalars don't alias.
Expand Down
8 changes: 4 additions & 4 deletions src/components/metabolic_class.jl
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
# ==========================================================================================
# Blueprints.

module MC
module MetabolicClass_
include("blueprint_modules.jl")
include("./blueprint_modules_identifiers.jl")
import .EcologicalNetworksDynamics: Species, _Species, Foodweb, _Foodweb
Expand Down Expand Up @@ -136,7 +136,7 @@ end
# ==========================================================================================
# Component and generic constructors.

@component MetabolicClass{Internal} requires(Foodweb) blueprints(MC)
@component MetabolicClass{Internal} requires(Foodweb) blueprints(MetabolicClass_)
export MetabolicClass

(::_MetabolicClass)(favourite::Symbol) = MetabolicClass.Favor(favourite)
Expand All @@ -158,9 +158,9 @@ end
ref_cached(raw -> Symbol.(raw._foodweb.metabolic_class)) # Legacy reverse conversion.
get(MetabolicClasses{Symbol}, "species")
write!((raw, rhs, i) -> begin
rhs = MC.check_value(rhs, i)
rhs = MetabolicClass_.check_value(rhs, i)
is_prod = is_producer(raw, i)
MC.check_against_status(rhs, is_prod, i)
MetabolicClass_.check_against_status(rhs, is_prod, i)
raw._foodweb.metabolic_class[i...] = String(rhs)
rhs
end)
Expand Down
5 changes: 3 additions & 2 deletions src/components/species.jl
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,8 @@
# ==========================================================================================
# Blueprints.

module SpeciesBlueprints
# Name + '_'-suffix is the module defining blueprints for this component.
module Species_
include("blueprint_modules.jl")

#-------------------------------------------------------------------------------------------
Expand Down Expand Up @@ -67,7 +68,7 @@ end
# ==========================================================================================
# Component and generic constructors.

@component Species{Internal} blueprints(SpeciesBlueprints)
@component Species{Internal} blueprints(Species_)
export Species

# Build from a number or default to names.
Expand Down
6 changes: 3 additions & 3 deletions src/components/temperature.jl
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
# ==========================================================================================
# Blueprints.

module T
module Temperature_
include("blueprint_modules.jl")

#-------------------------------------------------------------------------------------------
Expand All @@ -29,7 +29,7 @@ end
# ==========================================================================================
# Component and generic constructors.

@component Temperature{Internal} blueprints(T)
@component Temperature{Internal} blueprints(Temperature_)
export Temperature

(::_Temperature)(T = 293.15) = Temperature.Raw(T)
Expand All @@ -40,7 +40,7 @@ export Temperature
depends(Temperature)
get(raw -> raw.environment.T)
set!((raw, rhs::Real) -> begin
T.check_value(rhs)
Temperature_.check_value(rhs)
raw.environment.T = rhs
end)
end
Expand Down
59 changes: 34 additions & 25 deletions test/user/data_components/growth_rate.jl
Original file line number Diff line number Diff line change
Expand Up @@ -8,27 +8,34 @@
gr = GrowthRate([:c => 3])
m = base + gr
@test m.growth_rate == [0, 0, 3] == m.r
@test typeof(gr) === FR
@test typeof(gr) == GrowthRate.Map

# Only producers indices allowed.
@sysfails(
base + GrowthRate([:a => 1]),
Check(FR),
"Invalid 'producers' node label in 'r'. Expected :c, got instead: :a."
Check(
late,
[GrowthRate.Map],
"Invalid 'producer' node label in 'r': :a. \
Valid nodes labels for this template are:\n [:c]",
)
)

gr = GrowthRate([0, 0, 4])
m = base + gr
@test m.growth_rate == [0, 0, 4] == m.r
@test typeof(gr) === FR
@test typeof(gr) == GrowthRate.Raw

# Only producers values allowed.
@sysfails(
base + GrowthRate([4, 5, 7]),
Check(FR),
"Non-missing value found for 'r' at node index [1] (4.0), \
but the template for 'producers' only allows values \
at the following indices:\n [3]"
Check(
late,
[GrowthRate.Raw],
"Non-missing value found for 'r' at node index [1] (4.0), \
but the template for 'producers' only allows values \
at the following indices:\n [3]",
)
)

#---------------------------------------------------------------------------------------
Expand All @@ -37,49 +44,51 @@
base += BodyMass(; Z = 1) + MetabolicClass(:all_invertebrates)

gr = GrowthRate(:Miele2019)
@test typeof(gr) == FA
@test gr.allometry[:p][:a] == 1
@test gr.allometry[:p][:b] == -1 / 4
@test typeof(gr) == GrowthRate.Allometric

# Alternative explicit input.
@test gr == GrowthRateFromAllometry(; a_p = 1, b_p = -0.25)
@test gr == GrowthRate.Allometric(; a_p = 1, b_p = -0.25)

m = base + gr
@test m.growth_rate == [0, 0, 1]

# Forbid unnecessary allometric parameters.
@sysfails(
base + GrowthRateFromAllometry(; p = (a = 1, b = 0.25, c = 8)),
Check(FA),
"Allometric parameter 'c' (target_exponent) for 'producer' \
is meaningless in the context of calculating growth rates: 8.0."
base + GrowthRate.Allometric(; p = (a = 1, b = 0.25, c = 8)),
Check(
early,
[GrowthRate.Allometric],
"Allometric parameter 'c' (target_exponent) for 'producer' \
is meaningless in the context of calculating growth rates: 8.0.",
)
)
@sysfails(
base + GrowthRateFromAllometry(; p = (a = 1, b = 0.25), i_a = 8),
Check(FA),
"Allometric rates for 'invertebrate' \
are meaningless in the context of calculating growth rates: (a: 8.0)."
base + GrowthRate.Allometric(; p = (a = 1, b = 0.25), i_a = 8),
Check(
early,
[GrowthRate.Allometric],
"Allometric rates for 'invertebrate' \
are meaningless in the context of calculating growth rates: (a: 8.0).",
)
)

#---------------------------------------------------------------------------------------
# Construct from temperature.

gr = GrowthRate(:Binzer2016)
@test typeof(gr) == FT
@test gr.E_a == -0.84 # This one also has an activation energy.
@test gr.allometry == Allometry(; p = (a = 1.5497531357028967e-7, b = -1 / 4))
@test typeof(gr) == GrowthRate.Temperature

# Alternative explicit input.
@test gr == GrowthRateFromTemperature(-0.84; p_a = 1.5497531357028967e-7, p_b = -1 / 4)
@test gr == GrowthRate.Temperature(-0.84; p_a = 1.5497531357028967e-7, p_b = -1 / 4)

m = base + Temperature(298.5) + gr
@test m.growth_rate == [0, 0, 2.812547966878026e-7]

# Forbid if no temperature is available.
@sysfails(
base + gr,
Check(FT),
"blueprint cannot expand without component '$Temperature'."
)
@sysfails(base + gr, Missing(Temperature, nothing, [GrowthRate.Temperature], nothing))

end

0 comments on commit 1609a56

Please sign in to comment.