Reports¶
An SBML file is XML: complete, but not readable. A report answers the questions a modeller actually has about a model - which species are there, what is the rate of a reaction, which units does a parameter have, what is it annotated with.
sbmlutils produces the content of such a report as JSON. sbml4humans.de renders it in the browser.
The content of a model¶
SBMLDocumentInfo walks a document and collects everything about it:
from sbmlutils.report.sbmlinfo import SBMLDocumentInfo
info = SBMLDocumentInfo.from_sbml("model.xml")
print(info.to_json())
The result has one entry per model of the document; the elements of a model are grouped by their SBML type:
| key | content |
|---|---|
info.info["doc"] |
the document itself |
info.info["model"] |
the model, its units, its history and its packages |
info.info["modelDefinitions"] |
the comp model definitions |
info.info["externalModelDefinitions"] |
the external model definitions |
The elements of the model are lists under it, one per SBML type:
| key | content |
|---|---|
info.info["model"]["species"] |
every species with its compartment, units and annotations |
info.info["model"]["reactions"] |
every reaction with its equation, its rate and its modifiers |
info.info["model"]["parameters"] |
every parameter with its value and its unit |
info.info["model"]["compartments"], ["rules"], ["events"], ... |
the remaining types |
Every element carries a primary key (pk) which identifies it across the document, so the report can link from a reaction to the species it consumes.
Every element carries what it means, not only what it says: the equation of a reaction as a readable string, the math as latex, the unit as mmol/min/l instead of a chain of unit elements, and the annotations with their qualifier and resource.
to_json(strip=True), the default, removes the empty entries, which is what makes the result readable.
Empty means None, an empty string, or an empty list or dictionary. Numeric zero
and False are preserved because they describe model values and flags.
For large models, skip representations which your application does not need:
from pathlib import Path
info = SBMLDocumentInfo.from_sbml(
"model.xml",
include_derived_units=False,
include_xml=False,
include_math=False,
)
info.write_json(Path("report.json"))
All three flags default to True. Disabling derived units avoids libsbml's unit
analysis, which can dominate memory usage. Disabling XML omits element source
snippets and uses SBMLDocument:document as the document's primary key instead of
hashing its complete XML. Disabling math skips LaTeX rendering; the source model
is unchanged. Missing math is represented by None in a complete report too.
For Level 3 parameters and local parameters, a complete report resolves their declared units directly and reuses the rendered unit within each model. This avoids whole-model unit analysis just to report a parameter's declared unit.
write_json accepts a Path or a text stream and writes JSON incrementally,
without allocating the complete JSON string. strip=False also avoids building
a cleaned copy of the report dictionary. The document and report dictionary
still remain in memory.
Math as latex¶
The math of a model is rendered as latex, which is what the report displays:
from sbmlutils.report.mathml import formula_to_latex
formula_to_latex("Vmax * glc / (Km + glc)")
# ' \\frac{\\mathit{Vmax}·\\mathit{glc}}{\\mathit{Km}+\\mathit{glc}}'
astnode_to_latex does the same for a libsbml ASTNode, cmathml_to_latex for content MathML, and formula_to_astnode parses a formula into an ASTNode.
Units as a string¶
udef_to_string renders a unit definition, see Units:
from sbmlutils.report.units import udef_to_string
udef_to_string(udef, format="str") # 'mmol/min/l'
udef_to_string(udef, format="latex") # '\\frac{mmol}{min \\cdot l}'
A report in the browser¶
create_online_report serves the model on a local port, opens it on an sbml4humans instance running on your machine and shuts the server down afterwards:
from pathlib import Path
from sbmlutils.report.sbmlreport import create_online_report
create_online_report(sbml_path=Path("model.xml"), server="http://localhost:3456")
The model is served from your machine for the duration of fileserver_duration (10 seconds by default) so that the report server can fetch it; nothing is uploaded permanently. The model is served only on the loopback address (127.0.0.1) and only that one file, so the report server must run on the same machine (server parameter, default http://localhost:3456, the local instance of the frontend); a remote server such as sbml4humans.de cannot reach it.
The frontend and the http api behind sbml4humans.de live in matthiaskoenig/sbml4humans; the report itself, i.e. SBMLDocumentInfo, is part of sbmlutils and is what that api serves.