Skip to content
GitLab
Projects
Groups
Snippets
/
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Sign in
Toggle navigation
Menu
Open sidebar
LCSB-BioCore
SBML.jl
Commits
49ef7951
Unverified
Commit
49ef7951
authored
Jul 19, 2021
by
Miroslav Kratochvil
🚴
Committed by
GitHub
Jul 19, 2021
Browse files
Merge branch 'master' into mg/renamings
parents
41feebfb
6ac1c0cb
Changes
6
Hide whitespace changes
Inline
Side-by-side
src/SBML.jl
View file @
49ef7951
...
...
@@ -18,7 +18,7 @@ include("utils.jl")
sbml
(
sym
::
Symbol
)
=
dlsym
(
SBML_jll
.
libsbml_handle
,
sym
)
export
readSBML
,
stoichiometry_matrix
,
flux_bounds
,
flux_objective
export
readSBML
,
readSBMLFromString
,
stoichiometry_matrix
,
flux_bounds
,
flux_objective
export
set_level_and_version
,
libsbml_convert
,
convert_simplify_math
end
# module
src/converters.jl
View file @
49ef7951
"""
set_level_and_version(level, version)
set_level_and_version(level, version
, report_severities = ["
Fatal
", "
Error
"]
)
A converter to pass into [`readSBML`](@ref) that enforces certain SBML level
and version.
and version. `report_severities` switches on and off reporting of certain
errors; see the documentation of [`get_error_messages`](@ref) for details.
"""
set_level_and_version
(
level
,
version
)
=
set_level_and_version
(
level
,
version
,
report_severities
=
[
"Fatal"
,
"Error"
]
)
=
doc
->
check_errors
(
ccall
(
sbml
(
:
SBMLDocument_setLevelAndVersion
),
...
...
@@ -17,17 +18,20 @@ set_level_and_version(level, version) =
),
doc
,
ErrorException
(
"Setting of level and version did not succeed"
),
report_severities
,
)
"""
libsbml_convert(conversion_options::Vector{Pair{String, Dict{String, String}}})
libsbml_convert(conversion_options::Vector{Pair{String, Dict{String, String}}}
, report_severities = ["
Fatal
", "
Error
"]
)
A converter that runs the SBML conversion routine, with specified conversion
options. The argument is a vector of pairs to allow specifying the order of
conversions.
conversions. `report_severities` switches on and off reporting of certain
errors; see the documentation of [`get_error_messages`](@ref) for details.
"""
libsbml_convert
(
conversion_options
::
AbstractVector
{
<:
Pair
{
String
,
<:
AbstractDict
{
String
,
String
}}},
report_severities
=
[
"Fatal"
,
"Error"
],
)
=
doc
->
begin
for
(
converter
,
options
)
in
conversion_options
...
...
@@ -46,26 +50,33 @@ libsbml_convert(
)
end
check_errors
(
ccall
(
sbml
(
:
SBMLDocument_convert
),
Cint
,
(
VPtr
,
VPtr
),
doc
,
props
),
# `SBMLDocument_convert` returns `LIBSBML_OPERATION_SUCCESS` (== 0) for a
# successful operation, something else when there is a failure.
iszero
(
ccall
(
sbml
(
:
SBMLDocument_convert
),
Cint
,
(
VPtr
,
VPtr
),
doc
,
props
)),
doc
,
ErrorException
(
"Conversion returned errors"
),
report_severities
,
)
end
end
"""
libsbml_convert(converter::String; kwargs...)
libsbml_convert(converter::String
, report_severities = ["
Fatal
", "
Error
"]
; kwargs...)
Quickly construct a single run of a `libsbml` converter from keyword arguments.
`report_severities` switches on and off reporting of certain errors; see the
documentation of [`get_error_messages`](@ref) for details.
# Example
```
readSBML("
example
.
xml
", libsbml_convert("
stripPackage
", package="
layout
"))
```
"""
libsbml_convert
(
converter
::
String
;
kwargs
...
)
=
libsbml_convert
([
converter
=>
Dict
{
String
,
String
}(
string
(
k
)
=>
string
(
v
)
for
(
k
,
v
)
in
kwargs
),
])
libsbml_convert
(
converter
::
String
,
report_severities
=
[
"Fatal"
,
"Error"
];
kwargs
...
)
=
libsbml_convert
([
converter
=>
Dict
{
String
,
String
}(
string
(
k
)
=>
string
(
v
)
for
(
k
,
v
)
in
kwargs
),
],
report_severities
)
"""
convert_simplify_math
...
...
src/math.jl
View file @
49ef7951
...
...
@@ -16,6 +16,25 @@ parse_math_children(ast::VPtr)::Vector{Math} = [
i
=
1
:
ccall
(
sbml
(
:
ASTNode_getNumChildren
),
Cuint
,
(
VPtr
,),
ast
)
]
# Mapping of AST node type value subset to relational operations. Depends on
# `ASTNodeType.h` (also see below the case with AST_NAME_TIME)
const
relational_opers
=
Dict
{
Int32
,
String
}(
308
=>
"eq"
,
309
=>
"geq"
,
310
=>
"gt"
,
311
=>
"leq"
,
312
=>
"lt"
,
313
=>
"neq"
,
)
function
relational_oper
(
t
::
Int
)
haskey
(
relational_opers
,
t
)
||
throw
(
DomainError
(
t
,
"Unknown ASTNodeType value for relational operator"
))
relational_opers
[
t
]
end
"""
parse_math(ast::VPtr)::Math
...
...
@@ -42,11 +61,16 @@ function parse_math(ast::VPtr)::Math
return
MathVal
(
ccall
(
sbml
(
:
ASTNode_getReal
),
Cdouble
,
(
VPtr
,),
ast
))
elseif
ast_is
(
ast
,
:
ASTNode_isFunction
)
return
MathApply
(
get_string
(
ast
,
:
ASTNode_getName
),
parse_math_children
(
ast
))
elseif
ast_is
(
ast
,
:
ASTNode_isOperator
)
||
ast_is
(
ast
,
:
ASTNode_isRelational
)
elseif
ast_is
(
ast
,
:
ASTNode_isOperator
)
return
MathApply
(
string
(
Char
(
ccall
(
sbml
(
:
ASTNode_getCharacter
),
Cchar
,
(
VPtr
,),
ast
))),
parse_math_children
(
ast
),
)
elseif
ast_is
(
ast
,
:
ASTNode_isRelational
)
return
MathApply
(
relational_oper
(
Int
(
ccall
(
sbml
(
:
ASTNode_getType
),
Cint
,
(
VPtr
,),
ast
))),
parse_math_children
(
ast
),
)
elseif
ast_is
(
ast
,
:
ASTNode_isLambda
)
children
=
parse_math_children
(
ast
)
if
!
isempty
(
children
)
...
...
src/readsbml.jl
View file @
49ef7951
...
...
@@ -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
)
...
...
src/symbolics.jl
View file @
49ef7951
...
...
@@ -45,6 +45,7 @@ const default_symbolics_mapping = Dict{String,Any}(
"ln"
=>
:
log
,
"log"
=>
:
sbmlLog
,
"lt"
=>
:<
,
"neq"
=>
:
(
sbmlNeq
),
"piecewise"
=>
:
(
sbmlPiecewise
),
"power"
=>
:^
,
"root"
=>
:
sbmlRoot
,
...
...
@@ -66,6 +67,7 @@ function sbmlPiecewise(args...)
end
end
sbmlNeq
(
a
,
b
)
=
!
isequal
(
a
,
b
)
sbmlLog
(
x
)
=
log
(
x
,
10
)
sbmlLog
(
base
,
x
)
=
log
(
base
,
x
)
...
...
test/loadmodels.jl
View file @
49ef7951
...
...
@@ -56,9 +56,25 @@ sbmlfiles = [
0
,
0
,
),
# this contains a relational operator
(
joinpath
(
@__DIR__
,
"data"
,
"sbml00191.xml"
),
"https://raw.githubusercontent.com/sbmlteam/sbml-test-suite/master/cases/semantic/00191/00191-sbml-l3v2.xml"
,
"c474e94888767d70f9e9e03b32778f18069641563953de60dabac7daa7f481ce"
,
4
,
2
,
),
# expandInitialAssignments converter gives some warning
(
joinpath
(
@__DIR__
,
"data"
,
"01234-sbml-l3v2.xml"
),
"https://raw.githubusercontent.com/sbmlteam/sbml-test-suite/52d94baf97a005b6e1fdbdb6116f5c7b4a8a100c/cases/semantic/01234/01234-sbml-l3v2.xml"
,
"9610ef29f2d767af627042a15bde505b068ab75bbf00b8983823800ea8ef67c8"
,
0
,
0
,
),
]
@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
)
...
...
@@ -70,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
...
...
@@ -82,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
...
...
@@ -162,4 +186,15 @@ end
@test
test_math
.
args
[
2
]
.
fn
==
"sin"
@test
test_math
.
args
[
2
]
.
args
[
1
]
.
val
==
2.1
@test_logs
(
:
warn
,)
(
:
warn
,)
(
:
warn
,)
(
:
warn
,)
readSBML
(
joinpath
(
@__DIR__
,
"data"
,
"01234-sbml-l3v2.xml"
),
doc
->
libsbml_convert
(
"expandInitialAssignments"
,
[
"Fatal"
,
"Error"
,
"Warning"
])(
doc
)
)
end
@testset
"relational operators are decoded correctly"
begin
test_math
=
readSBML
(
joinpath
(
@__DIR__
,
"data"
,
"sbml00191.xml"
))
.
reactions
[
"reaction2"
]
.
kinetic_math
@test
test_math
.
args
[
2
]
.
fn
==
"geq"
end
Write
Preview
Supports
Markdown
0%
Try again
or
attach a new file
.
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment