Commit 9556ecd6 authored by Miroslav Kratochvil's avatar Miroslav Kratochvil
Browse files

implement extensive math, clean up epsilons in the tests

parent 538c20de
......@@ -100,3 +100,33 @@ initial_concentrations(m::SBML.Model; convert_amounts = false) = (
nothing
end for (k, s) in m.species
)
"""
extensive_kinetic_math(m::SBML.Model, formula::SBML.Math)
Convert a SBML math `formula` to "extensive" kinetic laws, where the references
to species that are marked as not having only substance units are converted
from amounts to concentrations.
Handling of units in the conversion process is ignored in this version.
"""
function extensive_kinetic_math(m::SBML.Model, formula::SBML.Math)
conv(x::SBML.MathIdent) = begin
haskey(m.species, x.id) || return x
sp = m.species[x.id]
sp.only_substance_units && return x
sz = m.compartments[sp.compartment].size
isnothing(sz) && throw(
DomainError(
formula,
"Non-substance-only-unit reference to species `$(x.id)' in an unsized compartment `$(sp.compartment)'.",
),
)
SBML.MathApply("/", [x, SBML.MathVal(sz)])
end
conv(x::SBML.MathApply) = SBML.MathApply(x.fn, conv.(x.args))
conv(x::SBML.Math) = x
conv(formula)
end
......@@ -32,7 +32,7 @@ sbmlfiles = [
4,
3,
),
# a cool model with `initialConcentration` from SBML testsuite
# another model from SBML suite, with initial concentrations
(
joinpath(@__DIR__, "data", "sbml00374.xml"),
"https://raw.githubusercontent.com/sbmlteam/sbml-test-suite/master/cases/semantic/00374/00374-sbml-l3v2.xml",
......@@ -82,15 +82,29 @@ end
@test all(isnothing(ic) for (k, ic) in SBML.initial_concentrations(m))
@test length(SBML.initial_amounts(m)) == 4
@test sum(ia for (sp, ia) in SBML.initial_amounts(m)) == 0.001
@test sum(ic for (sp, ic) in SBML.initial_concentrations(m, convert_amounts = true)) ==
0.001
@test isapprox(sum(ia for (sp, ia) in SBML.initial_amounts(m)), 0.001)
@test isapprox(
sum(ic for (sp, ic) in SBML.initial_concentrations(m, convert_amounts = true)),
0.001,
)
m = readSBML(joinpath(@__DIR__, "data", "sbml00374.xml"))
@test all(isnothing(ic) for (k, ic) in SBML.initial_amounts(m))
@test length(SBML.initial_concentrations(m)) == 4
@test sum(ic for (sp, ic) in SBML.initial_concentrations(m)) == 0.0020800000000000003
@test sum(ia for (sp, ia) in SBML.initial_amounts(m, convert_concentrations = true)) ==
0.25 * 0.0020800000000000003
@test isapprox(sum(ic for (sp, ic) in SBML.initial_concentrations(m)), 0.00208)
@test isapprox(
sum(ia for (sp, ia) in SBML.initial_amounts(m, convert_concentrations = true)),
0.25 * 0.00208,
)
end
@testset "Extensive kinetic math" begin
m = readSBML(joinpath(@__DIR__, "data", "sbml00852.xml"))
subterm =
SBML.extensive_kinetic_math(m, m.reactions["reaction1"].kinetic_math).args[1].args[2]
@test subterm.fn == "/"
@test subterm.args[1] == SBML.MathIdent("S1")
@test isapprox(subterm.args[2].val, 1.0)
end
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment