So, as mentioned I'm trying to find a way of translating a graphml file (or another format such as xgmml, csv, edgelist), from networkx or igraph (python or R) into this SBML format.
I believe there should be an easy way but...I can't find one. Any ideas?
EDIT: there are some other fomats that can be used to eventually land on SBML planet but still I don't have any ideas about how to export to any of them.
EDIT II: here I posted a question related to SBML and Cytoscape so...might be useful to some else who is interested into the topic.
SBML is mainly encoding process or reaction based models. The corresponding network graph of such models is a bipartite graph, i.e., there are two classes of nodes in the graph (reactions and species) and only edges between species and reaction nodes, but never between a species-species or species-reaction. An important concept in SBML is the stoichiometry in the reaction which is basically an edge attribute defining how the species occur in corresponding reactions.
So for graphs to be convertible to SBML they must follow a certain structure, i.e. they must be bipartite directed graphs with reaction and species nodes with stoichiometry information on the edges.
Such graphs can easily be converted to SBML using for instance libsbml or JSBML (both libraries for the manipulation of SBML). I attached an example below with the python bindings from libsbml.
"""
Converts simple bipartite species-reaction graph to SBML
using python bindings in libsbml
requirements:
pip install python-libsbml networkx
"""
import networkx as nx
import libsbml
'''
Create bipartite networkx graph consisting of species and reaction nodes.
Edges require stoichiometry (or set to 1 otherwise).
'''
G = nx.DiGraph()
# add species nodes
G.add_node("S1", ntype="specie")
G.add_node("S2", ntype="specie")
G.add_node("S3", ntype="specie")
G.add_node("S4", ntype="specie")
G.add_node("S5", ntype="specie")
G.add_node("S6", ntype="specie")
# add reaction nodes (and reaction edges)
G.add_node("r1", ntype="reaction") # 2 S1 -> S2
G.add_edges_from([
("S1", "r1", {'stoichiometry': 2}),
("r1", "S2", {'stoichiometry': 1})])
G.add_node("r2", ntype="reaction") # S2 -> S3
G.add_edges_from([
("S2", "r2", {'stoichiometry': 1}),
("r2", "S3", {'stoichiometry': 1})])
G.add_node("r3", ntype="reaction") # S3 + S4 -> S5 + S6
G.add_edges_from([
("S3", "r3", {'stoichiometry': 1}),
("S4", "r3", {'stoichiometry': 1}),
("r3", "S5", {'stoichiometry': 1}),
("r3", "S6", {'stoichiometry': 1})
])
print(G)
for sid, n in G.nodes.items():
print(sid, n)
for sid, e in G.edges.items():
print(sid, e)
'''
Create SBML model from the graph
'''
doc = libsbml.SBMLDocument() # type: libsbml.SBMLDocument
model = doc.createModel() # type: libsbml.Model
model.setId("graph_model")
# create species
for sid, n in G.nodes.items():
print(sid, n)
if n['ntype'] == "specie":
s = model.createSpecies() # type: libsbml.Species
s.setId(sid)
# create reactions
for sid, n in G.nodes.items():
if n['ntype'] == "reaction":
r = model.createReaction() # type: libsbml.Reaction
r.setId(sid)
for reactant_id in G.predecessors(sid):
stoichiometry = G.edges[reactant_id, sid]['stoichiometry']
reactant = model.getSpecies(reactant_id)
r.addReactant(reactant, stoichiometry)
for product_id in G.successors(sid):
product = model.getSpecies(product_id)
stoichiometry = G.edges[sid, product_id]['stoichiometry']
r.addProduct(product, stoichiometry)
# serialization
sbml_str = libsbml.writeSBMLToString(doc)
print("-" * 80)
print(sbml_str)
libsbml.writeSBMLToFile(doc, "graph2sbml.xml")
with the output
S1 {'ntype': 'specie'}
S2 {'ntype': 'specie'}
S3 {'ntype': 'specie'}
S4 {'ntype': 'specie'}
S5 {'ntype': 'specie'}
S6 {'ntype': 'specie'}
r1 {'ntype': 'reaction'}
r2 {'ntype': 'reaction'}
r3 {'ntype': 'reaction'}
('S1', 'r1') {'stoichiometry': 2}
('S2', 'r2') {'stoichiometry': 1}
('S3', 'r3') {'stoichiometry': 1}
('S4', 'r3') {'stoichiometry': 1}
('r1', 'S2') {'stoichiometry': 1}
('r2', 'S3') {'stoichiometry': 1}
('r3', 'S5') {'stoichiometry': 1}
('r3', 'S6') {'stoichiometry': 1}
S1 {'ntype': 'specie'}
S2 {'ntype': 'specie'}
S3 {'ntype': 'specie'}
S4 {'ntype': 'specie'}
S5 {'ntype': 'specie'}
S6 {'ntype': 'specie'}
r1 {'ntype': 'reaction'}
r2 {'ntype': 'reaction'}
r3 {'ntype': 'reaction'}
--------------------------------------------------------------------------------
<?xml version="1.0" encoding="UTF-8"?>
<sbml xmlns="http://www.sbml.org/sbml/level3/version2/core" level="3" version="2">
<model id="graph_model">
<listOfSpecies>
<species id="S1"/>
<species id="S2"/>
<species id="S3"/>
<species id="S4"/>
<species id="S5"/>
<species id="S6"/>
</listOfSpecies>
<listOfReactions>
<reaction id="r1">
<listOfReactants>
<speciesReference species="S1" stoichiometry="2" constant="true"/>
</listOfReactants>
<listOfProducts>
<speciesReference species="S2" stoichiometry="1" constant="true"/>
</listOfProducts>
</reaction>
<reaction id="r2">
<listOfReactants>
<speciesReference species="S2" stoichiometry="1" constant="true"/>
</listOfReactants>
<listOfProducts>
<speciesReference species="S3" stoichiometry="1" constant="true"/>
</listOfProducts>
</reaction>
<reaction id="r3">
<listOfReactants>
<speciesReference species="S3" stoichiometry="1" constant="true"/>
<speciesReference species="S4" stoichiometry="1" constant="true"/>
</listOfReactants>
<listOfProducts>
<speciesReference species="S5" stoichiometry="1" constant="true"/>
<speciesReference species="S6" stoichiometry="1" constant="true"/>
</listOfProducts>
</reaction>
</listOfReactions>
</model>
</sbml>
The SBML can then be visualized using tools like cy3sbml in Cytoscape