From 9a018668e054d46f9632e5d8a7cda450db851c74 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Mos=C3=A8=20Giordano?=
Date: Wed, 22 Jun 2022 18:48:28 +0100
Subject: [PATCH] Add support for more reaction attributes to `writeSBML`
---
src/writesbml.jl | 122 +++++++++++++++++++----------
test/data/Dasgupta2020-written.xml | 76 ++++++++++++++++++
2 files changed, 157 insertions(+), 41 deletions(-)
diff --git a/src/writesbml.jl b/src/writesbml.jl
index 1f749992..484d3946 100644
--- a/src/writesbml.jl
+++ b/src/writesbml.jl
@@ -6,6 +6,50 @@ const WRITESBML_PKG_DEFAULT_LEVEL = 3
const WRITESBML_PKG_DEFAULT_VERSION = 1
const WRITESBML_PKG_DEFAULT_PKGVERSION = 2
+function get_parameter_ptr!(parameter_ptr::VPtr, id::String, parameter::Parameter)::VPtr
+ ccall(sbml(:Parameter_setId), Cint, (VPtr, Cstring), parameter_ptr, id)
+ isnothing(parameter.name) || ccall(
+ sbml(:Parameter_setName),
+ Cint,
+ (VPtr, Cstring),
+ parameter_ptr,
+ parameter.name,
+ )
+ isnothing(parameter.value) || ccall(
+ sbml(:Parameter_setValue),
+ Cint,
+ (VPtr, Cdouble),
+ parameter_ptr,
+ parameter.value,
+ )
+ isnothing(parameter.units) || ccall(
+ sbml(:Parameter_setUnits),
+ Cint,
+ (VPtr, Cstring),
+ parameter_ptr,
+ parameter.units,
+ )
+ isnothing(parameter.constant) || ccall(
+ sbml(:Parameter_setConstant),
+ Cint,
+ (VPtr, Cint),
+ parameter_ptr,
+ Cint(parameter.constant),
+ )
+ return parameter_ptr
+end
+
+function get_parameter_ptr(id::String, parameter::Parameter)::VPtr
+ parameter_ptr = ccall(
+ sbml(:Parameter_create),
+ VPtr,
+ (Cuint, Cuint),
+ WRITESBML_DEFAULT_LEVEL,
+ WRITESBML_DEFAULT_VERSION,
+ )
+ return get_parameter_ptr!(parameter_ptr, id, parameter)
+end
+
function model_to_sbml!(doc::VPtr, mdl::Model)::VPtr
# Create the model pointer
model = ccall(sbml(:SBMLDocument_createModel), VPtr, (VPtr,), doc)
@@ -25,43 +69,8 @@ function model_to_sbml!(doc::VPtr, mdl::Model)::VPtr
# Add parameters
for (id, parameter) in mdl.parameters
- parameter_t = ccall(
- sbml(:Parameter_create),
- VPtr,
- (Cuint, Cuint),
- WRITESBML_DEFAULT_LEVEL,
- WRITESBML_DEFAULT_VERSION,
- )
- ccall(sbml(:Parameter_setId), Cint, (VPtr, Cstring), parameter_t, id)
- isnothing(parameter.name) || ccall(
- sbml(:Parameter_setName),
- Cint,
- (VPtr, Cstring),
- parameter_t,
- parameter.name,
- )
- isnothing(parameter.value) || ccall(
- sbml(:Parameter_setValue),
- Cint,
- (VPtr, Cdouble),
- parameter_t,
- parameter.value,
- )
- isnothing(parameter.units) || ccall(
- sbml(:Parameter_setUnits),
- Cint,
- (VPtr, Cstring),
- parameter_t,
- parameter.units,
- )
- isnothing(parameter.constant) || ccall(
- sbml(:Parameter_setConstant),
- Cint,
- (VPtr, Cint),
- parameter_t,
- Cint(parameter.constant),
- )
- res = ccall(sbml(:Model_addParameter), Cint, (VPtr, VPtr), model, parameter_t)
+ parameter_ptr = get_parameter_ptr(id, parameter)
+ res = ccall(sbml(:Model_addParameter), Cint, (VPtr, VPtr), model, parameter_ptr)
!iszero(res) &&
@warn "Failed to add parameter \"$(id)\": $(OPERATION_RETURN_VALUES[res])"
end
@@ -330,11 +339,42 @@ function model_to_sbml!(doc::VPtr, mdl::Model)::VPtr
true,
)
end
- # TODO: add kinetic parameters
- # TODO: add lower bound
- # TODO: add upper bound
+ if !isempty(reaction.kinetic_parameters) || !isnothing(reaction.kinetic_math)
+ kinetic_law_ptr =
+ ccall(sbml(:Reaction_createKineticLaw), VPtr, (VPtr,), reaction_ptr)
+ for (id, parameter) in reaction.kinetic_parameters
+ error()
+ parameter_ptr =
+ ccall(sbml(:KineticLaw_createParameter), VPtr, (VPtr,), kinetic_law_ptr)
+ get_parameter_ptr!(parameter_ptr, id, parameter)
+ end
+ isnothing(reaction.kinetic_math) || ccall(
+ sbml(:KineticLaw_setMath),
+ Cint,
+ (VPtr, VPtr),
+ kinetic_law_ptr,
+ get_astnode_ptr(reaction.kinetic_math),
+ )
+ end
+ if !isnothing(reaction.lower_bound) || !isnothing(reaction.upper_bound)
+ reaction_fbc_ptr =
+ ccall(sbml(:SBase_getPlugin), VPtr, (VPtr, Cstring), reaction_ptr, "fbc")
+ isnothing(reaction.lower_bound) || ccall(
+ sbml(:FbcReactionPlugin_setLowerFluxBound),
+ Cint,
+ (VPtr, Cstring),
+ reaction_fbc_ptr,
+ reaction.lower_bound,
+ )
+ isnothing(reaction.upper_bound) || ccall(
+ sbml(:FbcReactionPlugin_setUpperFluxBound),
+ Cint,
+ (VPtr, Cstring),
+ reaction_fbc_ptr,
+ reaction.upper_bound,
+ )
+ end
# TODO: add gene product association
- # TODO: add kinetic math
isnothing(reaction.notes) || ccall(
sbml(:SBase_setNotesString),
Cint,
diff --git a/test/data/Dasgupta2020-written.xml b/test/data/Dasgupta2020-written.xml
index 682636c1..0b56d9a9 100644
--- a/test/data/Dasgupta2020-written.xml
+++ b/test/data/Dasgupta2020-written.xml
@@ -414,31 +414,107 @@ response to activation both in 2D and in 3D
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+