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
b2f9bb7a
Commit
b2f9bb7a
authored
Jan 28, 2021
by
Miroslav Kratochvil
🚴
Browse files
reimplement the CxxWrapped glue library in Julia ccalls
parent
44888233
Changes
6
Hide whitespace changes
Inline
Side-by-side
Project.toml
View file @
b2f9bb7a
...
...
@@ -4,5 +4,6 @@ authors = ["Mirek Kratochvil <exa.exa@gmail.com>"]
version
=
"0.1.0"
[deps]
CxxWrap
=
"1f15a43c-97ca-5a2a-ae31-89f07a497df4"
Libdl
=
"8f399da3-3557-5675-b5ff-fb832c97cbdb"
Pkg
=
"44cfe95a-1eb2-52ea-b672-e2afdf69b78f"
SBML_jll
=
"bb12108a-f4ef-5f88-8ef3-0b33ff7017f1"
src/SBML.jl
View file @
b2f9bb7a
module
SBML
using
CxxWrap
using
ReadSBML_jll
function
__init__
()
@initcxx
end
@wrapmodule
(
libreadsbml
)
using
SBML_jll
,
Libdl
,
Pkg
include
(
"structs.jl"
)
include
(
"version.jl"
)
include
(
"readsbml.jl"
)
include
(
"utils.jl"
)
sbml
=
(
sym
::
Symbol
)
->
dlsym
(
SBML_jll
.
libsbml_handle
,
sym
)
export
getLibSBMLDottedVersion
,
readSBML
,
Model
,
UnitPart
,
Species
,
Reaction
,
getS
,
getLBs
,
getUBs
,
getOCs
export
SBMLVersion
,
readSBML
,
Model
,
UnitPart
,
Species
,
Reaction
,
getS
,
getLBs
,
getUBs
,
getOCs
end
# module
src/readsbml.jl
View file @
b2f9bb7a
struct
UnitPart
kind
::
String
exponent
::
Int
scale
::
Int
multiplier
::
Float64
UnitPart
(
k
,
e
,
s
,
m
)
=
new
(
k
,
e
,
s
,
m
)
end
const
VPtr
=
Ptr
{
Cvoid
}
struct
Reaction
stoichiometry
::
Dict
{
String
,
Float64
}
lb
::
Tuple
{
Float64
,
String
}
ub
::
Tuple
{
Float64
,
String
}
oc
::
Float64
Reaction
(
s
,
l
,
u
,
o
)
=
new
(
s
,
l
,
u
,
o
)
end
function
readSBML
(
fn
::
String
)
::
Model
doc
=
ccall
(
sbml
(
:
readSBML
),
VPtr
,
(
Cstring
,),
fn
)
try
n_errs
=
ccall
(
sbml
(
:
SBMLDocument_getNumErrors
),
Cuint
,
(
VPtr
,),
doc
)
if
n_errs
>
0
@error
"SBML loading failed"
throw
(
:
IOError
)
end
struct
Species
name
::
String
compartment
::
String
Species
(
n
,
c
)
=
new
(
n
,
c
)
end
if
0
==
ccall
(
sbml
(
:
SBMLDocument_isSetModel
),
Cint
,
(
VPtr
,),
doc
)
@error
"SBML document does not contain a model"
throw
(
:
ValueError
)
end
struct
Model
units
::
Dict
{
String
,
Vector
{
UnitPart
}}
compartments
::
Vector
{
String
}
species
::
Dict
{
String
,
Species
}
reactions
::
Dict
{
String
,
Reaction
}
Model
(
u
,
c
,
s
,
r
)
=
new
(
u
,
c
,
s
,
r
)
end
model
=
ccall
(
sbml
(
:
SBMLDocument_getModel
),
VPtr
,
(
VPtr
,),
doc
)
function
readSBML
(
fn
::
String
)
::
Model
mi
=
readSBML_internal
(
fn
)
if
length
(
errors
(
mi
))
>
0
@error
"Loading failed!"
errors
(
mi
)
return
extractModel
(
model
)
finally
ccall
(
sbml
(
:
SBMLDocument_free
),
Nothing
,
(
VPtr
,),
doc
)
end
end
us
=
Dict
{
String
,
Vector
{
UnitPart
}}()
for
u
in
units
(
mi
)
us
[
unit
(
u
)]
=
Vector
{
UnitPart
}()
end
for
u
in
units
(
mi
)
push!
(
us
[
unit
(
u
)],
UnitPart
(
kind
(
u
),
exponent
(
u
),
scale
(
u
),
multiplier
(
u
)))
function
extractModel
(
mdl
::
VPtr
)
::
Model
units
=
Dict
{
String
,
Vector
{
UnitPart
}}()
for
i
=
0
:
ccall
(
sbml
(
:
Model_getNumUnitDefinitions
),
Cuint
,
(
VPtr
,),
mdl
)
-
1
ud
=
ccall
(
sbml
(
:
Model_getUnitDefinition
),
VPtr
,
(
VPtr
,
Cuint
),
mdl
,
i
)
id
=
unsafe_string
(
ccall
(
sbml
(
:
UnitDefinition_getId
),
Cstring
,
(
VPtr
,),
ud
))
units
[
id
]
=
[
begin
u
=
ccall
(
sbml
(
:
UnitDefinition_getUnit
),
VPtr
,
(
VPtr
,
Cuint
),
ud
,
j
)
UnitPart
(
unsafe_string
(
ccall
(
sbml
(
:
UnitKind_toString
),
Cstring
,
(
Cint
,),
ccall
(
sbml
(
:
Unit_getKind
),
Cint
,
(
VPtr
,),
u
),
),
),
ccall
(
sbml
(
:
Unit_getExponent
),
Cint
,
(
VPtr
,),
u
),
ccall
(
sbml
(
:
Unit_getScale
),
Cint
,
(
VPtr
,),
u
),
ccall
(
sbml
(
:
Unit_getMultiplier
),
Cdouble
,
(
VPtr
,),
u
),
)
end
for
j
=
0
:
ccall
(
sbml
(
:
UnitDefinition_getNumUnits
),
Cuint
,
(
VPtr
,),
ud
)
-
1
]
end
ss
=
Dict
{
String
,
Species
}()
for
s
in
species
(
mi
)
ss
[
id
(
s
)]
=
Species
(
name
(
s
),
compartment
(
s
))
compartments
=
[
unsafe_string
(
ccall
(
sbml
(
:
Compartment_getId
),
Cstring
,
(
VPtr
,),
ccall
(
sbml
(
:
Model_getCompartment
),
VPtr
,
(
VPtr
,
Cuint
),
mdl
,
i
),
),
)
for
i
=
0
:
ccall
(
sbml
(
:
Model_getNumCompartments
),
Cuint
,
(
VPtr
,),
mdl
)
-
1
]
species
=
Dict
{
String
,
Species
}()
for
i
=
0
:
ccall
(
sbml
(
:
Model_getNumSpecies
),
Cuint
,
(
VPtr
,),
mdl
)
-
1
sp
=
ccall
(
sbml
(
:
Model_getSpecies
),
VPtr
,
(
VPtr
,
Cuint
),
mdl
,
i
)
species
[
unsafe_string
(
ccall
(
sbml
(
:
Species_getId
),
Cstring
,
(
VPtr
,),
sp
))]
=
Species
(
unsafe_string
(
ccall
(
sbml
(
:
Species_getName
),
Cstring
,
(
VPtr
,),
sp
)),
unsafe_string
(
ccall
(
sbml
(
:
Species_getCompartment
),
Cstring
,
(
VPtr
,),
sp
)),
)
end
rs
=
Dict
{
String
,
Reaction
}()
for
r
in
reactions
(
mi
)
sts
=
Dict
{
String
,
Float64
}()
for
s
in
species
(
r
)
sts
[
id
(
s
)]
=
stoichiometry
(
s
)
reactions
=
Dict
{
String
,
Reaction
}()
for
i
=
0
:
ccall
(
sbml
(
:
Model_getNumReactions
),
Cuint
,
(
VPtr
,),
mdl
)
-
1
re
=
ccall
(
sbml
(
:
Model_getReaction
),
VPtr
,
(
VPtr
,
Cuint
),
mdl
,
i
)
kl
=
ccall
(
sbml
(
:
Reaction_getKineticLaw
),
VPtr
,
(
VPtr
,),
re
)
lb
=
(
-
Inf
,
""
)
ub
=
(
Inf
,
""
)
oc
=
0.0
for
j
=
0
:
ccall
(
sbml
(
:
KineticLaw_getNumParameters
),
Cuint
,
(
VPtr
,),
kl
)
-
1
p
=
ccall
(
sbml
(
:
KineticLaw_getParameter
),
VPtr
,
(
VPtr
,
Cuint
),
kl
,
j
)
id
=
unsafe_string
(
ccall
(
sbml
(
:
Parameter_getId
),
Cstring
,
(
VPtr
,),
p
))
pval
=
()
->
ccall
(
sbml
(
:
Parameter_getValue
),
Cdouble
,
(
VPtr
,),
p
)
punit
=
()
->
unsafe_string
(
ccall
(
sbml
(
:
Parameter_getUnits
),
Cstring
,
(
VPtr
,),
p
))
if
id
==
"LOWER_BOUND"
lb
=
(
pval
(),
punit
())
elseif
id
==
"UPPER_BOUND"
ub
=
(
pval
(),
punit
())
elseif
id
==
"OBJECTIVE_COEFFICIENT"
oc
=
pval
()
end
end
rs
[
id
(
r
)]
=
Reaction
(
sts
,
lb
(
r
),
ub
(
r
),
oc
(
r
))
end
return
Model
(
us
,
compartments
(
mi
),
ss
,
rs
)
end
stoi
=
Dict
{
String
,
Float64
}()
add_stoi
=
(
sr
,
factor
)
->
stoi
[
unsafe_string
(
ccall
(
sbml
(
:
SpeciesReference_getSpecies
),
Cstring
,
(
VPtr
,),
sr
),
)]
=
ccall
(
sbml
(
:
SpeciesReference_getStoichiometry
),
Cdouble
,
(
VPtr
,),
sr
)
*
factor
#TODO this needs a sparse version and faster row ID lookup
function
getS
(
m
::
Model
)
::
Tuple
{
Vector
{
String
},
Vector
{
String
},
Matrix
{
Float64
}}
rows
=
[
k
for
k
in
keys
(
m
.
species
)]
#TODO this too
cols
=
[
k
for
k
in
keys
(
m
.
reactions
)]
S
=
zeros
(
Float64
,
length
(
rows
),
length
(
cols
))
for
ri
in
1
:
length
(
cols
)
stoi
=
m
.
reactions
[
cols
[
ri
]]
.
stoichiometry
S
[
indexin
(
keys
(
stoi
),
rows
),
ri
]
.=
values
(
stoi
)
end
return
rows
,
cols
,
S
end
for
j
=
0
:
ccall
(
sbml
(
:
Reaction_getNumReactants
),
Cuint
,
(
VPtr
,),
re
)
-
1
sr
=
ccall
(
sbml
(
:
Reaction_getReactant
),
VPtr
,
(
VPtr
,
Cuint
),
re
,
j
)
add_stoi
(
sr
,
-
1
)
end
function
getLBs
(
m
::
Model
)
::
Vector
{
Tuple
{
Float64
,
String
}}
return
broadcast
(
x
->
x
.
lb
,
values
(
m
.
reactions
))
end
for
j
=
0
:
ccall
(
sbml
(
:
Reaction_getNumProducts
),
Cuint
,
(
VPtr
,),
re
)
-
1
sr
=
ccall
(
sbml
(
:
Reaction_getProduct
),
VPtr
,
(
VPtr
,
Cuint
),
re
,
j
)
add_stoi
(
sr
,
1
)
end
function
getUBs
(
m
::
Model
)
::
Vector
{
Tuple
{
Float64
,
String
}}
return
broadcast
(
x
->
x
.
ub
,
values
(
m
.
reactions
)
)
end
reactions
[
unsafe_string
(
ccall
(
sbml
(
:
Reaction_getId
),
Cstring
,
(
VPtr
,),
re
))]
=
Reaction
(
stoi
,
lb
,
ub
,
oc
)
end
function
getOCs
(
m
::
Model
)
::
Vector
{
Float64
}
return
broadcast
(
x
->
x
.
oc
,
values
(
m
.
reactions
))
return
Model
(
units
,
compartments
,
species
,
reactions
)
end
src/structs.jl
0 → 100644
View file @
b2f9bb7a
struct
UnitPart
kind
::
String
exponent
::
Int
scale
::
Int
multiplier
::
Float64
UnitPart
(
k
,
e
,
s
,
m
)
=
new
(
k
,
e
,
s
,
m
)
end
struct
Reaction
stoichiometry
::
Dict
{
String
,
Float64
}
lb
::
Tuple
{
Float64
,
String
}
ub
::
Tuple
{
Float64
,
String
}
oc
::
Float64
Reaction
(
s
,
l
,
u
,
o
)
=
new
(
s
,
l
,
u
,
o
)
end
struct
Species
name
::
String
compartment
::
String
Species
(
n
,
c
)
=
new
(
n
,
c
)
end
struct
Model
units
::
Dict
{
String
,
Vector
{
UnitPart
}}
compartments
::
Vector
{
String
}
species
::
Dict
{
String
,
Species
}
reactions
::
Dict
{
String
,
Reaction
}
Model
(
u
,
c
,
s
,
r
)
=
new
(
u
,
c
,
s
,
r
)
end
src/utils.jl
0 → 100644
View file @
b2f9bb7a
#TODO this will need a sparse version and faster row ID lookup
function
getS
(
m
::
Model
)
::
Tuple
{
Vector
{
String
},
Vector
{
String
},
Matrix
{
Float64
}}
rows
=
[
k
for
k
in
keys
(
m
.
species
)]
#TODO this too
cols
=
[
k
for
k
in
keys
(
m
.
reactions
)]
S
=
zeros
(
Float64
,
length
(
rows
),
length
(
cols
))
for
ri
=
1
:
length
(
cols
)
stoi
=
m
.
reactions
[
cols
[
ri
]]
.
stoichiometry
S
[
indexin
(
keys
(
stoi
),
rows
),
ri
]
.=
values
(
stoi
)
end
return
rows
,
cols
,
S
end
function
getLBs
(
m
::
Model
)
::
Vector
{
Tuple
{
Float64
,
String
}}
return
broadcast
(
x
->
x
.
lb
,
values
(
m
.
reactions
))
end
function
getUBs
(
m
::
Model
)
::
Vector
{
Tuple
{
Float64
,
String
}}
return
broadcast
(
x
->
x
.
ub
,
values
(
m
.
reactions
))
end
function
getOCs
(
m
::
Model
)
::
Vector
{
Float64
}
return
broadcast
(
x
->
x
.
oc
,
values
(
m
.
reactions
))
end
src/version.jl
0 → 100644
View file @
b2f9bb7a
function
SBMLVersion
()
VersionNumber
(
unsafe_string
(
ccall
(
sbml
(
:
getLibSBMLDottedVersion
),
Cstring
,
())))
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