Unverified Commit 6ac1c0cb authored by Miroslav Kratochvil's avatar Miroslav Kratochvil Committed by GitHub
Browse files

Merge pull request #123 from giordano/mg/read-from-string

Add function to read SBML model from a string
parents 04c03e1c e96c8f4e
......@@ -18,7 +18,7 @@ include("utils.jl")
sbml(sym::Symbol) = dlsym(SBML_jll.libsbml_handle, sym)
export readSBML, getS, getLBs, getUBs, getOCs
export readSBML, readSBMLFromString, getS, getLBs, getUBs, getOCs
export set_level_and_version, libsbml_convert, convert_simplify_math
end # module
......@@ -71,6 +71,34 @@ function get_optional_double(x::VPtr, is_sym, get_sym)::Maybe{Float64}
end
end
function _readSBML(
symbol::Symbol,
fn::String,
sbml_conversion,
report_severities,
)::SBML.Model
doc = ccall(sbml(symbol), VPtr, (Cstring,), fn)
try
get_error_messages(
doc,
AssertionError("Opening SBML document has reported errors"),
report_severities,
)
sbml_conversion(doc)
if 0 == ccall(sbml(:SBMLDocument_isSetModel), Cint, (VPtr,), doc)
throw(AssertionError("SBML document contains no model"))
end
model = ccall(sbml(:SBMLDocument_getModel), VPtr, (VPtr,), doc)
return extractModel(model)
finally
ccall(sbml(:SBMLDocument_free), Nothing, (VPtr,), doc)
end
end
"""
readSBML(
fn::String,
......@@ -89,6 +117,8 @@ single parameter, which is the C pointer to the loaded SBML document (C type
`report_severities` switches on and off reporting of certain errors; see the
documentation of [`get_error_messages`](@ref) for details.
To read from a string instead of a file, use [`readSBMLFromString`](@ref).
# Example
```
m = readSBML("my_model.xml", doc -> begin
......@@ -97,32 +127,29 @@ m = readSBML("my_model.xml", doc -> begin
end)
```
"""
function readSBML(
readSBML(
fn::String,
sbml_conversion = document -> nothing;
report_severities = ["Fatal", "Error"],
)::SBML.Model
doc = ccall(sbml(:readSBML), VPtr, (Cstring,), fn)
try
get_error_messages(
doc,
AssertionError("Opening SBML document has reported errors"),
report_severities,
)
)::SBML.Model = _readSBML(:readSBML, fn, sbml_conversion, report_severities)
sbml_conversion(doc)
if 0 == ccall(sbml(:SBMLDocument_isSetModel), Cint, (VPtr,), doc)
throw(AssertionError("SBML document contains no model"))
end
"""
readSBML(
str::String,
sbml_conversion = document -> nothing;
report_severities = ["Fatal", "Error"],
)::SBML.Model
model = ccall(sbml(:SBMLDocument_getModel), VPtr, (VPtr,), doc)
Read the SBML from the string `str` and return the contained `SBML.Model`.
return extractModel(model)
finally
ccall(sbml(:SBMLDocument_free), Nothing, (VPtr,), doc)
end
end
For the other arguments see the docstring of [`readSBML`](@ref), which can be
used to read from a file instead of a string.
"""
readSBMLFromString(
str::AbstractString,
sbml_conversion = document -> nothing;
report_severities = ["Fatal", "Error"],
)::SBML.Model = _readSBML(:readSBMLFromString, String(str), sbml_conversion, report_severities)
get_notes(x::VPtr)::Maybe{String} = get_optional_string(x, :SBase_getNotesString)
get_annotation(x::VPtr)::Maybe{String} = get_optional_string(x, :SBase_getAnnotationString)
......
......@@ -74,7 +74,7 @@ sbmlfiles = [
),
]
@testset "Loading of models from various sources" begin
@testset "Loading of models from various sources - $(reader)" for reader in (readSBML, readSBMLFromString)
for (sbmlfile, url, hash, expected_mets, expected_rxns) in sbmlfiles
if !isfile(sbmlfile)
Downloads.download(url, sbmlfile)
......@@ -86,7 +86,11 @@ sbmlfiles = [
end
@testset "Loading of $sbmlfile" begin
mdl = readSBML(sbmlfile)
mdl = if reader === readSBML
readSBML(sbmlfile)
else
readSBMLFromString(readchomp(sbmlfile))
end
@test typeof(mdl) == Model
......@@ -98,6 +102,10 @@ sbmlfiles = [
end
end
@testset "readSBMLFromString" begin
@test_logs (:error, r"^SBML reported error") @test_throws AssertionError readSBMLFromString("")
end
@testset "Time variables in math" begin
# this test is here mainly for keeping a magical constant that we need for
# parsing time synced with libsbml source
......
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