Commit 26d61e06 authored by MARTINEZ Thierry 's avatar MARTINEZ Thierry

load sbml

parent cf1322a5
MODULES=$(shell sed -n -E 's/^- (.*\.pl)$$/\1/p' toc.org) ADDITIONAL_MODULES=modules/sbml/sbml_utils.pl
MODULES=$(shell sed -n -E 's/^- (.*\.pl)$$/\1/p' toc.org) $(ADDITIONAL_MODULES)
# load_test_files/1 should make this useless, but I cannot find how to use it # load_test_files/1 should make this useless, but I cannot find how to use it
TEST_MODULES=$(wildcard $(MODULES:.pl=.plt)) TEST_MODULES=$(wildcard $(MODULES:.pl=.plt))
...@@ -9,7 +10,7 @@ $(foreach var, CC PLBASE PLCFLAGS PLLDFLAGS PLLIB, \ ...@@ -9,7 +10,7 @@ $(foreach var, CC PLBASE PLCFLAGS PLLDFLAGS PLLIB, \
grep ^$(var)= | \ grep ^$(var)= | \
sed -E 's/="/=/;s/";$$//'))) sed -E 's/="/=/;s/";$$//')))
INCLUDEDIRS=modules/graphviz $(PLBASE)/include INCLUDEDIRS=modules/graphviz modules/sbml $(PLBASE)/include
CFLAGS=$(addprefix -I, $(INCLUDEDIRS)) $(PLCFLAGS) CFLAGS=$(addprefix -I, $(INCLUDEDIRS)) $(PLCFLAGS)
...@@ -17,17 +18,19 @@ LDFLAGS=$(PLLDFLAGS) $(addprefix -L, $(dir $(wildcard $(PLBASE)/lib/*/))) ...@@ -17,17 +18,19 @@ LDFLAGS=$(PLLDFLAGS) $(addprefix -L, $(dir $(wildcard $(PLBASE)/lib/*/)))
LDLIBS=$(PLLIB) `pkg-config --libs libgvc libsbml` LDLIBS=$(PLLIB) `pkg-config --libs libgvc libsbml`
SWIPL=$(PWD)/swipl-biocham
all: biocham biocham_debug test doc all: biocham biocham_debug test doc
.PHONY: test doc clean .PHONY: test doc clean
biocham: platform/current swipl-biocham $(MODULES) toc.org Makefile biocham: platform/current swipl-biocham $(MODULES) toc.org Makefile
$(PWD)/swipl-biocham -o biocham \ $(SWIPL) -o biocham \
--goal=start --toplevel=toplevel -c $(MODULES) --goal=start --toplevel=toplevel -c $(MODULES)
biocham_debug: platform/current swipl-biocham $(MODULES) $(TEST_MODULES) \ biocham_debug: platform/current swipl-biocham $(MODULES) $(TEST_MODULES) \
toc.org Makefile toc.org Makefile
$(PWD)/swipl-biocham -o biocham_debug \ $(SWIPL) -o biocham_debug \
--goal=initialize -c $(MODULES) $(TEST_MODULES) --goal=initialize -c $(MODULES) $(TEST_MODULES)
swipl-biocham: swipl-biocham.o \ swipl-biocham: swipl-biocham.o \
...@@ -52,8 +55,8 @@ test: biocham_tests ...@@ -52,8 +55,8 @@ test: biocham_tests
doc: biocham doc: biocham
./biocham --generate-doc ./biocham --generate-doc
biocham_tests: $(MODULES) $(TEST_MODULES) Makefile biocham_tests: swipl-biocham $(MODULES) $(TEST_MODULES) Makefile
swipl -o biocham_tests \ $(SWIPL) -o biocham_tests \
--goal="call_cleanup((run_tests, halt(0)), halt(1))" \ --goal="call_cleanup((run_tests, halt(0)), halt(1))" \
-c $(MODULES) $(TEST_MODULES) -c $(MODULES) $(TEST_MODULES)
......
This diff is collapsed.
#!/bin/bash #!/bin/bash
set -e set -e
i=1 i="$1"
if [ "$i" = "" ]; then
i=1
fi
while true; do while true; do
filename=`printf BIOMD%.10d $i` filename=`printf BIOMD%.10d $i`
url="https://www.ebi.ac.uk/biomodels-main/download?mid=$filename" url="https://www.ebi.ac.uk/biomodels-main/download?mid=$filename"
if ! curl $url >$filename.xml; then if ! curl $url >$filename.xml; then
rm -f $filename.xml
break break
fi fi
((i++)) ((i++))
......
...@@ -32,7 +32,8 @@ ...@@ -32,7 +32,8 @@
list_ids/2, list_ids/2,
delete_item/1, delete_item/1,
delete_items/1, delete_items/1,
add_dependency/2 add_dependency/2,
add_file_suffix/2
] ]
). ).
...@@ -195,6 +196,7 @@ get_model_name(Id, Name) :- ...@@ -195,6 +196,7 @@ get_model_name(Id, Name) :-
load_all(Suffix, InputFile) :- load_all(Suffix, InputFile) :-
current_models(OldCurrentModels),
findall( findall(
Id, Id,
( (
...@@ -204,9 +206,33 @@ load_all(Suffix, InputFile) :- ...@@ -204,9 +206,33 @@ load_all(Suffix, InputFile) :-
current_models(Ids), current_models(Ids),
member(Id, Ids) member(Id, Ids)
), ),
NewCurrentModels
),
(
NewCurrentModels = []
->
restore_current_models(OldCurrentModels)
;
set_current_models(NewCurrentModels)
).
restore_current_models(OldCurrentModels) :-
findall(
Model,
(
member(Model, OldCurrentModels),
once(item([id: Model]))
),
CurrentModels CurrentModels
), ),
set_current_models(CurrentModels). (
CurrentModels = []
->
new_model
;
set_current_models(CurrentModels)
).
add_all(Suffix, InputFile) :- add_all(Suffix, InputFile) :-
...@@ -225,32 +251,29 @@ add_all(Suffix, InputFile) :- ...@@ -225,32 +251,29 @@ add_all(Suffix, InputFile) :-
). ).
load(Bc, Filename) :- load(Suffix, Filename) :-
(
Bc = '.bc'
;
Bc = ''
),
!,
new_model, new_model,
set_model_name(Filename), set_model_name(Filename),
add_biocham_file(Filename). add(Suffix, Filename).
load(Suffix, _Filename) :-
throw(error(unknown_suffix(Suffix))).
add(Suffix, Filename) :-
add(Bc, Filename) :-
( (
Bc = '.bc' add_file_suffix(Suffix, Functor)
->
call(Functor, Filename)
; ;
Bc = '' throw(error(unknown_suffix(Suffix)))
), ).
!,
add_biocham_file(Filename).
add(Suffix, _Filename) :- :- multifile(add_file_suffix/2).
throw(error(unknown_suffix(Suffix))).
add_file_suffix('', add_biocham_file).
add_file_suffix('.bc', add_biocham_file).
add_biocham_file(Filename) :- add_biocham_file(Filename) :-
...@@ -290,7 +313,13 @@ current_models(Models) :- ...@@ -290,7 +313,13 @@ current_models(Models) :-
set_current_models(Models) :- set_current_models(Models) :-
nb_setval(current_models, Models). (
Models = []
->
throw(error(cannot_select_no_models))
;
nb_setval(current_models, Models)
).
new_model(Id) :- new_model(Id) :-
......
...@@ -8,4 +8,13 @@ ...@@ -8,4 +8,13 @@
:- use_module('../sbml'). :- use_module('../sbml').
echo(Filename) :- echo(Filename) :-
readSBML(Filename, _SBML). readSBML(Filename, SBML),
sbmlDocument_getNumErrors(SBML, Errors),
(
Errors > 0
->
sbmlDocument_printErrors(SBML, user_error),
throw(error(sbml_errors))
;
true
).
...@@ -7,13 +7,15 @@ ...@@ -7,13 +7,15 @@
sbmlDocument_getModel/2, sbmlDocument_getModel/2,
sbmlDocument_free/1, sbmlDocument_free/1,
model_getListOfReactions/2, model_getListOfReactions/2,
model_getListOfSpecies/2,
model_getSpeciesById/3,
listOf_get/3, listOf_get/3,
listOf_size/2, listOf_size/2,
reaction_getKineticLaw/2, reaction_getKineticLaw/2,
reaction_getListOfReactants/2, reaction_getListOfReactants/2,
reaction_getListOfModifiers/2, reaction_getListOfModifiers/2,
reaction_getListOfProducts/2, reaction_getListOfProducts/2,
reaction_isSetReversible/1, reaction_isSetReversible/2,
kineticsLaw_getMath/2, kineticsLaw_getMath/2,
speciesReference_getSpecies/2, speciesReference_getSpecies/2,
speciesReference_getStoichiometry/2, speciesReference_getStoichiometry/2,
......
:- use_module(library(plunit)).
:- use_module(sbml).
:- use_module('examples/echo').
:- begin_tests(sbml).
test(echo) :-
echo('../../biomodels/BIOMD0000000001.xml').
:- end_tests(sbml).
...@@ -81,7 +81,7 @@ pl_sbmlDocument_getNumErrors(term_t document_term, term_t numErrors_term) { ...@@ -81,7 +81,7 @@ pl_sbmlDocument_getNumErrors(term_t document_term, term_t numErrors_term) {
char *filename; char *filename;
unsigned int numErrors; unsigned int numErrors;
PL_check(PL_get_sbmlDocument(document_term, &document)); PL_check(PL_get_sbmlDocument(document_term, &document));
PL_check(numErrors = SBMLDocument_getNumErrors(document)); numErrors = SBMLDocument_getNumErrors(document);
PL_check(PL_unify_integer(numErrors_term, numErrors)); PL_check(PL_unify_integer(numErrors_term, numErrors));
PL_succeed; PL_succeed;
} }
...@@ -124,6 +124,30 @@ pl_model_getListOfReactions(term_t model_term, term_t listOfReactions_term) { ...@@ -124,6 +124,30 @@ pl_model_getListOfReactions(term_t model_term, term_t listOfReactions_term) {
PL_succeed; PL_succeed;
} }
static foreign_t
pl_model_getListOfSpecies(term_t model_term, term_t listOfSpecies_term) {
Model_t *model;
ListOf_t *listOfSpecies;
PL_check(PL_get_model(model_term, &model));
PL_check(listOfSpecies = Model_getListOfSpecies(model));
PL_check(PL_unify_pointer(listOfSpecies_term, listOfSpecies));
PL_succeed;
}
static foreign_t
pl_model_getSpeciesById(
term_t model_term, term_t id_term, term_t species_term
) {
Model_t *model;
char *id;
Species_t *species;
PL_check(PL_get_model(model_term, &model));
PL_check(PL_get_atom_chars(id_term, &id));
PL_check(species = Model_getSpeciesById(model, id));
PL_check(PL_unify_pointer(species_term, species));
PL_succeed;
}
static foreign_t static foreign_t
pl_listOf_get(term_t list_term, term_t index_term, term_t base_term) { pl_listOf_get(term_t list_term, term_t index_term, term_t base_term) {
ListOf_t *list; ListOf_t *list;
...@@ -291,13 +315,15 @@ PL_extension sbml_predicates[] = { ...@@ -291,13 +315,15 @@ PL_extension sbml_predicates[] = {
{ "sbmlDocument_getModel", 2, pl_sbmlDocument_getModel, 0 }, { "sbmlDocument_getModel", 2, pl_sbmlDocument_getModel, 0 },
{ "sbmlDocument_free", 1, pl_sbmlDocument_free, 0 }, { "sbmlDocument_free", 1, pl_sbmlDocument_free, 0 },
{ "model_getListOfReactions", 2, pl_model_getListOfReactions, 0 }, { "model_getListOfReactions", 2, pl_model_getListOfReactions, 0 },
{ "model_getListOfSpecies", 2, pl_model_getListOfSpecies, 0 },
{ "model_getSpeciesById", 3, pl_model_getSpeciesById, 0 },
{ "listOf_get", 3, pl_listOf_get, 0 }, { "listOf_get", 3, pl_listOf_get, 0 },
{ "listOf_size", 2, pl_listOf_size, 0 }, { "listOf_size", 2, pl_listOf_size, 0 },
{ "reaction_getKineticLaw", 2, pl_reaction_getKineticLaw, 0 }, { "reaction_getKineticLaw", 2, pl_reaction_getKineticLaw, 0 },
{ "reaction_getListOfReactants", 2, pl_reaction_getListOfReactants, 0 }, { "reaction_getListOfReactants", 2, pl_reaction_getListOfReactants, 0 },
{ "reaction_getListOfModifiers", 2, pl_reaction_getListOfModifiers, 0 }, { "reaction_getListOfModifiers", 2, pl_reaction_getListOfModifiers, 0 },
{ "reaction_getListOfProducts", 2, pl_reaction_getListOfProducts, 0 }, { "reaction_getListOfProducts", 2, pl_reaction_getListOfProducts, 0 },
{ "reaction_isSetReversible", 1, pl_reaction_isSetReversible, 0 }, { "reaction_isSetReversible", 2, pl_reaction_isSetReversible, 0 },
{ "kineticsLaw_getMath", 2, pl_kineticsLaw_getMath, 0 }, { "kineticsLaw_getMath", 2, pl_kineticsLaw_getMath, 0 },
{ "speciesReference_getSpecies", 2, pl_speciesReference_getSpecies, 0 }, { "speciesReference_getSpecies", 2, pl_speciesReference_getSpecies, 0 },
{ "speciesReference_getStoichiometry", 2, { "speciesReference_getStoichiometry", 2,
......
:- module(
sbml_utils,
[
member_listof/2,
model_reaction/2,
reaction_reactant/2,
reaction_modifier/2,
reaction_product/2
]
).
member_listof(Item, ListOf) :-
listOf_size(ListOf, N),
M is N - 1,
between(0, M, Index),
listOf_get(ListOf, Index, Item).
model_reaction(Model, Reaction) :-
model_getListOfReactions(Model, ListOfReactions),
member_listof(Reaction, ListOfReactions).
reaction_reactant(Reaction, Reactant) :-
reaction_getListOfReactants(Reaction, ListOfReactants),
member_listof(Reactant, ListOfReactants).
reaction_modifier(Reaction, Modifier) :-
reaction_getListOfModifiers(Reaction, ListOfModifiers),
member_listof(Modifier, ListOfModifiers).
reaction_product(Reaction, Product) :-
reaction_getListOfProducts(Reaction, ListOfProducts),
member_listof(Product, ListOfProducts).
...@@ -57,20 +57,20 @@ reaction(Item, Kinetics, Reactants, Products, Reversible) :- ...@@ -57,20 +57,20 @@ reaction(Item, Kinetics, Reactants, Products, Reversible) :-
( (
Body = (Left =[ Catalyst ]=> Right) Body = (Left =[ Catalyst ]=> Right)
-> ->
Reversible = no Reversible = false
; ;
Body = (Left <=[ Catalyst ]=> Right) Body = (Left <=[ Catalyst ]=> Right)
-> ->
Reversible = yes Reversible = true
; ;
Body = (Left => Right) Body = (Left => Right)
-> ->
Reversible = no, Reversible = false,
Catalyst = '_' Catalyst = '_'
; ;
Body = (Left <=> Right) Body = (Left <=> Right)
-> ->
Reversible = yes, Reversible = true,
Catalyst = '_' Catalyst = '_'
), ),
solution_to_list(Left, LeftMolecules), solution_to_list(Left, LeftMolecules),
...@@ -82,7 +82,7 @@ reaction(Item, Kinetics, Reactants, Products, Reversible) :- ...@@ -82,7 +82,7 @@ reaction(Item, Kinetics, Reactants, Products, Reversible) :-
reaction(Item, Kinetics, Reactants, Products) :- reaction(Item, Kinetics, Reactants, Products) :-
reaction(Item, PairKinetics, LeftMolecules, RightMolecules, Reversible), reaction(Item, PairKinetics, LeftMolecules, RightMolecules, Reversible),
( (
Reversible = yes Reversible = true
-> ->
pair_kinetics(PairKinetics, ForwardKinetics, BackwardKinetics), pair_kinetics(PairKinetics, ForwardKinetics, BackwardKinetics),
( (
...@@ -147,6 +147,9 @@ list_to_solution([Head | Tail], CoefficientObject, Solution) :- ...@@ -147,6 +147,9 @@ list_to_solution([Head | Tail], CoefficientObject, Solution) :-
coefficient_object(1 * Object, Object) :- coefficient_object(1 * Object, Object) :-
!. !.
coefficient_object(1.0 * Object, Object) :-
!.
coefficient_object(CoefficientObject, CoefficientObject). coefficient_object(CoefficientObject, CoefficientObject).
...@@ -252,7 +255,7 @@ make_reaction(Kinetics, Left, Catalyst, Right, Reversible, Reaction) :- ...@@ -252,7 +255,7 @@ make_reaction(Kinetics, Left, Catalyst, Right, Reversible, Reaction) :-
list_to_solution(Catalyst, CatalystSolution), list_to_solution(Catalyst, CatalystSolution),
list_to_solution(Right, RightSolution), list_to_solution(Right, RightSolution),
( (
Reversible = yes Reversible = true
-> ->
( (
CatalystSolution = '_' CatalystSolution = '_'
......
...@@ -26,7 +26,7 @@ reaction_graph :- ...@@ -26,7 +26,7 @@ reaction_graph :-
format(atom(ReactionCounter), 'reaction~d', [ReactionCount]), format(atom(ReactionCounter), 'reaction~d', [ReactionCount]),
transition([ReactionCounter]), transition([ReactionCounter]),
( (
Reversible = yes Reversible = true
-> ->
set_attribute([ReactionCounter], reversible: Reversible) set_attribute([ReactionCounter], reversible: Reversible)
; ;
...@@ -41,11 +41,11 @@ reaction_graph :- ...@@ -41,11 +41,11 @@ reaction_graph :-
), ),
\+ ( \+ (
( (
member(Stochiometry * Object, Reactants), member(Stoichiometry * Object, Reactants),
From = Object, From = Object,
To = ReactionCounter To = ReactionCounter
; ;
member(Stochiometry * Object, Products), member(Stoichiometry * Object, Products),
From = ReactionCounter, From = ReactionCounter,
To = Object To = Object
), ),
...@@ -53,22 +53,22 @@ reaction_graph :- ...@@ -53,22 +53,22 @@ reaction_graph :-
place([Object]), place([Object]),
add_edge([From -> To]), add_edge([From -> To]),
( (
get_attribute((From -> To), stochiometry: OldStochiometry) get_attribute((From -> To), stoichiometry: OldStoichiometry)
-> ->
NewStochiometry is OldStochiometry + Stochiometry NewStoichiometry is OldStoichiometry + Stoichiometry
; ;
NewStochiometry is Stochiometry NewStoichiometry is Stoichiometry
), ),
( (
NewStochiometry = 1 NewStoichiometry = 1
-> ->
catch( catch(
delete_attribute([From -> To], stochiometry), delete_attribute([From -> To], stoichiometry),
error(unknown_item), error(unknown_item),
true true
) )
; ;
set_attribute([From -> To], stochiometry: NewStochiometry) set_attribute([From -> To], stoichiometry: NewStoichiometry)
) )
) )
) )
...@@ -219,7 +219,7 @@ make_reactions :- ...@@ -219,7 +219,7 @@ make_reactions :-
get_kinetics(Reaction, Kinetics), get_kinetics(Reaction, Kinetics),
get_reversible(Reaction, Reversible), get_reversible(Reaction, Reversible),
findall( findall(
Stochiometry * Reactant, Stoichiometry * Reactant,
( (
vertex_place(Reactant), vertex_place(Reactant),
item([ item([
...@@ -228,12 +228,12 @@ make_reactions :- ...@@ -228,12 +228,12 @@ make_reactions :-
item: (Reactant -> Reaction), item: (Reactant -> Reaction),
id: EdgeId id: EdgeId
]), ]),
get_stochiometry(EdgeId, Stochiometry) get_stoichiometry(EdgeId, Stoichiometry)
), ),
Left Left
), ),
findall( findall(
Stochiometry * Product, Stoichiometry * Product,
( (
vertex_place(Product), vertex_place(Product),
item([ item([
...@@ -242,7 +242,7 @@ make_reactions :- ...@@ -242,7 +242,7 @@ make_reactions :-
item: (Reaction -> Product), item: (Reaction -> Product),
id: EdgeId id: EdgeId
]), ]),
get_stochiometry(EdgeId, Stochiometry) get_stoichiometry(EdgeId, Stoichiometry)
), ),
Right Right
), ),
...@@ -267,25 +267,25 @@ get_reversible(Vertex, Reversible) :- ...@@ -267,25 +267,25 @@ get_reversible(Vertex, Reversible) :-
-> ->
( (
( (
Reversible = yes Reversible = true
; ;
Reversible = no Reversible = false
) )
-> ->
true true
; ;
throw(error(reversible_attribute_yes_no)) throw(error(reversible_attribute_boolean))
) )
; ;
Reversible = no Reversible = false
). ).
get_stochiometry(Vertex, Stochiometry) :- get_stoichiometry(Vertex, Stoichiometry) :-
( (
get_attribute(Vertex, stochiometry: Stochiometry) get_attribute(Vertex, stoichiometry: Stoichiometry)
-> ->
true true
; ;
Stochiometry = 1 Stoichiometry = 1
). ).
...@@ -8,8 +8,8 @@ test( ...@@ -8,8 +8,8 @@ test(
'reaction_graph', 'reaction_graph',
[true(( [true((
Edges == ['A' -> 'reaction0', 'reaction0' -> 'B'], Edges == ['A' -> 'reaction0', 'reaction0' -> 'B'],
Reversible == yes, Reversible == true,
Stochiometry == 2, Stoichiometry == 2,
Kinetics == 'MA'(3) Kinetics == 'MA'(3)
))] ))]
) :- ) :-
...@@ -20,7 +20,7 @@ test( ...@@ -20,7 +20,7 @@ test(
all_items([parent: GraphId, kind: edge], Edges), all_items([parent: GraphId, kind: edge], Edges),
once(get_attribute('reaction0', reversible: Reversible)), once(get_attribute('reaction0', reversible: Reversible)),
once(get_attribute('reaction0', kinetics: Kinetics)), once(get_attribute('reaction0', kinetics: Kinetics)),
once(get_attribute(('reaction0' -> 'B'), stochiometry: Stochiometry)). once(get_attribute(('reaction0' -> 'B'), stoichiometry: Stoichiometry)).
test( test(
'import_reactions_from_graph', 'import_reactions_from_graph',
...@@ -29,7 +29,7 @@ test( ...@@ -29,7 +29,7 @@ test(
clear_model, clear_model,
new_graph, new_graph,
command(transition('reaction0')), command(transition('reaction0')),
command(set_attribute('reaction0', reversible: yes)), command(set_attribute('reaction0', reversible: true)),
command( command(
add_edge( add_edge(
'a' -> 'reaction0', 'a' -> 'reaction0',
...@@ -40,8 +40,8 @@ test( ...@@ -40,8 +40,8 @@ test(
) )
), ),
command(set_attribute('reaction1', kinetics: 'MA'(2))), command(set_attribute('reaction1', kinetics: 'MA'(2))),
command(set_attribute(('c' -> 'reaction1'), stochiometry: 3)), command(set_attribute(('c' -> 'reaction1'), stoichiometry: 3)),
command(set_attribute(('reaction1' -> 'd'), stochiometry: 2)), command(set_attribute(('reaction1' -> 'd'), stoichiometry: 2)),
import_reactions_from_graph, import_reactions_from_graph,
all_items([kind: reaction], Reactions). all_items([kind: reaction], Reactions).
......
:- module(
sbml_files,
[
load_sbml/1,
add_sbml/1,
add_sbml_file/1
]
).
:- devdoc('\\section{Commands}').
load_sbml(InputFile) :-
biocham_command,
type(InputFile, input_file),
doc('
act as \\command{load_biocham/1} but importing reactions, parameters and
initial state (and only that!) from an SBML .xml file.
'),
load_all('.xml', InputFile).
add_sbml(InputFile) :-
biocham_command,
type(InputFile, input_file),
doc('
act as \\command{add_biocham/1} but importing reactions, parameters and
initial state (and only that!) from an SBML .xml file.
'),
add_all('.xml', InputFile).
:- devdoc('\\section{Public API}').
models:add_file_suffix('.xml', add_sbml_file).
add_sbml_file(Filename) :-
automatic_suffix(Filename, '.xml', read, FilenameXML),
setup_call_cleanup(
readSBML(FilenameXML, SBML),
add_sbml_document(SBML),
sbmlDocument_free(SBML)
).