# sbmlutils > Python utilities for the Systems Biology Markup Language (SBML) The complete documentation from https://matthiaskoenig.github.io/sbmlutils, one section per page. --- ![](images/sbmlutils-logo-small.png) # sbmlutils: python utilities for SBML [![GitHub Actions CI/CD Status](https://github.com/matthiaskoenig/sbmlutils/actions/workflows/ci-cd.yml/badge.svg)](https://github.com/matthiaskoenig/sbmlutils/actions/workflows/ci-cd.yml) [![Documentation](https://img.shields.io/badge/docs-sbmlutils-008080.svg)](https://matthiaskoenig.github.io/sbmlutils) [![Version](https://img.shields.io/pypi/v/sbmlutils.svg)](https://pypi.org/project/sbmlutils/) [![Python Versions](https://img.shields.io/pypi/pyversions/sbmlutils.svg)](https://pypi.org/project/sbmlutils/) [![MIT License](https://img.shields.io/pypi/l/sbmlutils.svg)](https://opensource.org/licenses/MIT) [![DOI](https://zenodo.org/badge/DOI/10.5281/zenodo.597149.svg)](https://doi.org/10.5281/zenodo.597149) `sbmlutils` is a collection of python utilities for working with models in the [Systems Biology Markup Language](https://sbml.org) (SBML), built on [libsbml](https://sbml.org/software/libsbml/). The source code is available from [https://github.com/matthiaskoenig/sbmlutils](https://github.com/matthiaskoenig/sbmlutils). ## Background SBML is the exchange format for computational models in systems biology ([Keating *et al.* 2020](references.md#sbml), [Hucka *et al.* 2019](references.md#sbml)), and libsbml is the reference implementation for reading and writing it. Working with libsbml directly is verbose: every element is created on the model, every attribute is set through a setter, and every call returns a status code which has to be checked. A compartment with a unit and an annotation is a dozen statements. `sbmlutils` is the layer above it. A model is written as a python object — a `Model` holding `Compartment`, `Species`, `Parameter` and `Reaction` objects — and `create_model` turns that definition into a validated SBML file. The definition is data, so it can be composed, parameterized and generated, and the units, annotations and notes belong to the element they describe instead of being applied afterwards. Around this core the package collects the tasks which come with SBML models: validating them, merging them, flattening a hierarchical model, converting them to other formats, and describing them in a human readable report. ## Features - **[Model creation](creation.md)** — define a model as python objects and write it as SBML with `create_model`, with support for the `comp`, `fbc`, `distrib` and `layout` packages. - **[Units](units.md)** — units are written as strings (`mmole/min/l`), parsed with [pint](https://pint.readthedocs.io) and converted into SBML unit definitions; the model is checked for unit consistency. - **[Annotations](annotations.md)** — MIRIAM annotations and SBO terms on every element, either in the model definition or applied to an existing model from an annotation spreadsheet. - **[Notes](notes.md)** — element documentation written as markdown, converted to the XHTML notes SBML requires. - **[Validation](validation.md)** — the libsbml checks with a readable report and configurable consistency options. - **[Model composition](comp.md)** — hierarchical models with the `comp` package: submodels, ports, replacements, and flattening into a single model. - **[Flux balance constraints](fbc.md)** — `fbc` models with flux bounds, objectives, gene products and user defined constraints, and a bridge to [cobrapy](https://cobrapy.readthedocs.io). - **[COMBINE archives](omex.md)** — models packaged as OMEX archives through [pymetadata](https://github.com/matthiaskoenig/pymetadata). - **[Reports](reports.md)** — the complete content of a model as JSON, the basis of the reports on [sbml4humans.de](https://sbml4humans.de). - **[Converters](converters.md)** — SBML to an ODE system (python, R, julia, markdown, latex), XPP/XPPAUT `.ode` files to SBML, and antimony in both directions. - **[Interpolation](interpolation.md)** — a table of data points as an SBML model, with constant, linear and cubic spline interpolation. - **[Visualization](visualization.md)** — models rendered as a network in [Cytoscape](https://cytoscape.org). The specifications behind the language and its packages are cited in [References](references.md). ## Quickstart A model is a python object, `create_model` writes it as SBML: ```python from pathlib import Path from sbmlutils.factory import ( Compartment, Model, ModelUnits, Parameter, Reaction, Species, UnitDefinition, Units, create_model, ) class U(Units): """Units of the model.""" min = UnitDefinition("min") mmole = UnitDefinition("mmole") litre = UnitDefinition("l", "liter") mM = UnitDefinition("mM", "mmole/liter") mmole_per_min = UnitDefinition("mmole_per_min", "mmole/min") model = Model( sid="glucose_uptake", name="glucose uptake", units=U, model_units=ModelUnits( time=U.min, substance=U.mmole, extent=U.mmole, volume=U.litre ), compartments=[Compartment("cell", value=1.0, unit=U.litre, name="cell")], species=[ Species( "glc", initialConcentration=5.0, compartment="cell", substanceUnit=U.mmole ), Species( "g6p", initialConcentration=0.0, compartment="cell", substanceUnit=U.mmole ), ], parameters=[Parameter("Vmax", 1.0, U.mmole_per_min), Parameter("Km", 0.1, U.mM)], reactions=[ Reaction( "GLUT", equation="glc -> g6p", formula=("Vmax * glc / (Km + glc)", U.mmole_per_min), name="glucose transport", ) ], ) result = create_model(model=model, filepath=Path("glucose_uptake.xml")) ``` Existing models are read, validated and described: ```python from sbmlutils.io import read_sbml, validate_sbml from sbmlutils.report.sbmlinfo import SBMLDocumentInfo doc = read_sbml("glucose_uptake.xml") validate_sbml("glucose_uptake.xml") info = SBMLDocumentInfo.from_sbml("glucose_uptake.xml") print(info.to_json()[:200]) ``` Continue with [Installation](installation.md) and the [model creation guide](creation.md). ## How to cite [![DOI](https://zenodo.org/badge/DOI/10.5281/zenodo.597149.svg)](https://doi.org/10.5281/zenodo.597149) If you use `sbmlutils` please cite the archived software on [Zenodo](https://doi.org/10.5281/zenodo.597149): > König, M. (2026). *sbmlutils: Python utilities for SBML* (Version 0.10.0) [Computer software]. Zenodo. https://doi.org/10.5281/zenodo.22646678 ```bibtex @software{konig_sbmlutils, author = {König, Matthias}, title = {sbmlutils: Python utilities for SBML}, year = {2026}, month = sep, version = {0.10.0}, publisher = {Zenodo}, doi = {10.5281/zenodo.22646678}, url = {https://doi.org/10.5281/zenodo.22646678}, } ``` ## License - Source Code: [MIT](https://opensource.org/license/MIT) - Documentation: [CC BY-SA 4.0](http://creativecommons.org/licenses/by-sa/4.0/) ## Funding Matthias König is supported by the German Research Foundation (DFG) within the Research Unit Programme FOR 5151 "QuaLiPerF (Quantifying Liver Perfusion-Function Relationship in Complex Resection — A Systems Medicine Approach)" by grant number 436883643 and by grant number 465194077 (Priority Programme SPP 2311, Subproject SimLivA). Matthias König was supported by the Federal Ministry of Education and Research (BMBF, Germany) within the research network Systems Medicine of the Liver (**LiSyM**, grant number 031L0054). SBML4Humans was funded as part of [Google Summer of Code 2021](https://summerofcode.withgoogle.com/). Matthias König has received funding from the EOSCsecretariat.eu which has received funding from the European Union's Horizon Programme call H2020-INFRAEOSC-05-2018-2019, grant Agreement number 831644. --- # Installation `sbmlutils` requires python >= 3.11 and is available from [pypi](https://pypi.python.org/pypi/sbmlutils). It is tested on Linux, macOS and Windows. ## With uv [uv](https://docs.astral.sh/uv/) is the recommended way to install the package. In a project it is added as a dependency, which resolves and locks it together with the rest of the environment: ```bash uv add sbmlutils ``` Into an existing virtual environment it is installed through the pip interface of uv: ```bash uv venv --python 3.14 uv pip install sbmlutils ``` ## With pip ```bash pip install sbmlutils ``` ## Development version The current state of the `develop` branch is installed directly from GitHub: ```bash uv add "sbmlutils @ git+https://github.com/matthiaskoenig/sbmlutils.git@develop" ``` or, with pip, ```bash pip install git+https://github.com/matthiaskoenig/sbmlutils.git@develop ``` To work on the repository itself, with the test and documentation tooling, see [Development](development.md). ## Extras `sbmlutils` reads, writes, annotates and validates models; it neither simulates nor plots, so the packages for that are not installed with it. Three extras add what a specific feature needs: | extra | install | what it adds | | --- | --- | --- | | `cytoscape` | `pip install sbmlutils[cytoscape]` | `py4cytoscape` for the [visualization](visualization.md) in a running [Cytoscape](https://cytoscape.org) | | `cobra` | `pip install sbmlutils[cobra]` | `cobra` for the [flux balance analysis](fbc.md#cobrapy) of `sbmlutils.fbc.cobra` | | `examples` | `pip install sbmlutils[examples]` | `libroadrunner` and `matplotlib`, which the [examples](https://github.com/matthiaskoenig/sbmlutils/tree/develop/examples) simulate and plot with | Several are combined as usual: `pip install sbmlutils[cytoscape,examples]`. The development environment installs `cytoscape` and `examples` with `uv sync --extra dev`, see [Development](development.md). Without the `cytoscape` extra `sbmlutils.cytoscape` still imports; its functions log a warning and do nothing, just as they do when Cytoscape is not running. ## Logging `sbmlutils` does not configure logging. It logs to loggers below the `sbmlutils` logger and leaves handlers, levels and formatting to the application, so the messages of the package stay under your control: ```python import logging logging.basicConfig(level=logging.INFO) logging.getLogger("sbmlutils").setLevel(logging.WARNING) ``` For scripts and interactive work the rich output of the package can be turned on explicitly: ```python from sbmlutils import log log.enable_rich_logging() ``` --- # Model creation A model is a python object. `Model` holds the elements of the model — compartments, species, parameters, reactions, rules, events — and `create_model` turns that definition into an SBML file. ## The model definition ```python from pathlib import Path from sbmlutils.factory import ( Compartment, Model, ModelUnits, Parameter, Reaction, Species, UnitDefinition, Units, create_model, ) class U(Units): """Units of the model.""" min = UnitDefinition("min") mmole = UnitDefinition("mmole") l = UnitDefinition("l", "liter") mM = UnitDefinition("mM", "mmole/liter") mmole_per_min = UnitDefinition("mmole_per_min", "mmole/min") model = Model( sid="glycolysis", name="minimal glycolysis model", notes=""" # Minimal glycolysis model Glucose is taken up and phosphorylated. """, units=U, model_units=ModelUnits(time=U.min, extent=U.mmole, substance=U.mmole, volume=U.l), compartments=[ Compartment("cell", value=1.0, unit=U.l, name="cell", constant=True), ], species=[ Species( "glc", initialConcentration=5.0, compartment="cell", substanceUnit=U.mmole ), Species( "g6p", initialConcentration=0.0, compartment="cell", substanceUnit=U.mmole ), ], parameters=[ Parameter("Vmax", 1.0, U.mmole_per_min), Parameter("Km", 0.1, U.mM), ], reactions=[ Reaction( "GK", name="glucokinase", equation="glc -> g6p", formula=("Vmax * glc / (Km + glc)", U.mmole_per_min), ), ], ) result = create_model(model=model, filepath=Path("glycolysis.xml")) ``` `create_model` returns a `FactoryResult` with the `sbml_path` it wrote and the created `Model`. It validates the model by default, see [Validation](validation.md). The created model can be serialized to additional formats next to the SBML file, which makes the result easy to inspect: `create_antimony=True` writes the [antimony](io.md#antimony) notation of the model to `glycolysis.ant`, and `create_markdown=True` writes the ODE system as markdown to `glycolysis.md`, see [Converters](converters.md). Both are off by default; the paths of the written files are on the result as `antimony_path` and `markdown_path`. ```python result = create_model( model=model, filepath=Path("glycolysis.xml"), create_antimony=True, create_markdown=True, ) ``` The elements can be passed to the constructor or assigned afterwards, which is useful when they are built programmatically: ```python model.species += [ Species( f"s{k}", initialConcentration=0.0, compartment="cell", substanceUnit=U.mmole ) for k in range(10) ] ``` `objects=[...]` accepts elements of any kind in one list; they are sorted into the right collection by their type. ## The elements | element | what it is | | --- | --- | | `Compartment` | a compartment, `value` is its size | | `Species` | a species, given as `initialConcentration` or `initialAmount` | | `Parameter` | a parameter, `value` is a number or a formula | | `Reaction` | a reaction, with an `equation` and a rate `formula` | | `InitialAssignment` | the initial value of a symbol as a formula | | `AssignmentRule`, `RateRule`, `AlgebraicRule` | the rules of the model | | `Event` | a discrete event with a trigger and assignments | | `Function` | a function definition | | `Constraint` | a constraint on the state of the model | | `Objective`, `FluxObjective`, `GeneProduct` | the [fbc](fbc.md) elements | | `Submodel`, `Port`, `ReplacedElement`, `ReplacedBy`, `Deletion` | the [comp](comp.md) elements | | `Uncertainty`, `UncertParameter`, `UncertSpan` | the [distrib](distrib.md) elements | Every element is an `Sbase` and accepts the attributes every SBML element has: `sid`, `name`, `metaId`, `sboTerm`, `notes`, `annotations`, `port`, `uncertainties` and `keyValuePairs`. ## Reactions The stoichiometry of a reaction is written as an equation string, which is parsed by `sbmlutils.reaction_equation`: ```python Reaction("R1", equation="2 glc + atp -> g6p + adp") # stoichiometries Reaction("R2", equation="glc <-> g6p") # reversible, `->` is irreversible Reaction("R3", equation="glc -> g6p [enzyme]") # modifiers in brackets Reaction("R4", equation="fS glc -> g6p") # variable stoichiometry Reaction("R5", equation="=> cit") # no reactants Reaction("R6", equation="acoa =>") # no products ``` The rate is given as `formula`, either as a plain string or as a `(formula, unit)` tuple, which is what makes the [unit check](units.md#unit-consistency) meaningful. The full grammar of the equations is documented in `sbmlutils.reaction_equation`. ## Packages SBML packages are activated on the model and their elements are then available: ```python from sbmlutils.factory import Model, Package model = Model( sid="example", packages=[Package.COMP_V1, Package.FBC_V3, Package.DISTRIB_V1] ) ``` | package | guide | | --- | --- | | `Package.COMP_V1` | [Model composition](comp.md) | | `Package.FBC_V2`, `Package.FBC_V3` | [Flux balance constraints](fbc.md) | | `Package.DISTRIB_V1` | [Distributions and uncertainties](distrib.md) | The layout package needs no entry in `packages`: assigning `model.layouts` with the objects of `sbmlutils.layout` activates it. ## Several models at once `create_model` accepts an iterable of models, which are merged into one before the file is written. This keeps a large model in several files: ```python from examples import compartments, reactions, species create_model( model=[compartments.model, species.model, reactions.model], filepath="model.xml" ) ``` The later model wins where the definitions overlap, which is how a base model is parameterized for a specific case. ## Examples The [`examples/`](https://github.com/matthiaskoenig/sbmlutils/tree/develop/examples) directory of the repository holds a runnable model for every concept: species in amounts and concentrations, reactions with units, assignments and rules, events, annotations, notes, and complete models from a small demo to a whole body physiological model. They are run as modules from the root of the repository: ```bash python -m examples.species python -m examples.tutorial.minimal_model ``` --- # Units Every quantity in a model has a unit, and SBML requires those units to be declared as `UnitDefinition` elements built from base unit kinds, exponents, scales and multipliers. Writing them out by hand is tedious and easy to get wrong. `sbmlutils` lets you write a unit as the string you would say out loud — `mmole/min/l` — and parses it with [pint](https://pint.readthedocs.io) into the SBML representation. ## Defining units Units are collected in a class which subclasses `Units`. Every attribute is a `UnitDefinition` with an id and, unless the id is already a unit expression, the expression it stands for: ```python from sbmlutils.factory import UnitDefinition, Units class U(Units): """Units of the model.""" min = UnitDefinition("min") s = UnitDefinition("s", "second") mmole = UnitDefinition("mmole") l = UnitDefinition("l", "liter") mM = UnitDefinition("mM", "mmole/liter") per_min = UnitDefinition("per_min", "1/min") mmole_per_min = UnitDefinition("mmole_per_min", "mmole/min") mmole_per_min_l = UnitDefinition("mmole_per_min_l", "mmole/min/l") m2 = UnitDefinition("m2", "meter^2") m3 = UnitDefinition("m3", "meter^3") ``` The id of a unit definition must be a valid SBML identifier and must **not** be the name of an SBML base unit kind. `UnitDefinition("litre")` is invalid for that reason; give the definition another id and put the base unit in the expression, e.g. `UnitDefinition("l", "liter")`. The class is passed to the model as `units=U` and its definitions are written into the SBML model. ## The units of the model The model level units say what a quantity without an explicit unit means. They are set with `ModelUnits`: ```python from sbmlutils.factory import Model, ModelUnits model = Model( sid="example", units=U, model_units=ModelUnits( time=U.min, extent=U.mmole, substance=U.mmole, length=U.meter, area=U.m2, volume=U.l, ), ) ``` ## Units on elements Every element carries the unit of its value: ```python from sbmlutils.factory import Compartment, Parameter, Reaction, Species Compartment("cell", value=1.0, unit=U.l) Parameter("Vmax", value=1.0, unit=U.mmole_per_min) Species("glc", initialConcentration=5.0, compartment="cell", substanceUnit=U.mmole) Reaction( "R1", equation="glc -> g6p", formula=("Vmax * glc / (Km + glc)", U.mmole_per_min) ) ``` A reaction formula is a `(formula, unit)` tuple: the unit is the unit of the rate, which is what the unit consistency check compares the formula against. ## Unit consistency `create_model` validates the model and, by default, checks unit consistency: ```python from sbmlutils.factory import ValidationOptions, create_model create_model( model=model, filepath="model.xml", validation_options=ValidationOptions(units_consistency=True), ) ``` Unit errors are reported like any other validation problem, see [Validation](validation.md). A model which is not unit consistent is still written; the check reports, it does not block. ## Rendering a unit `sbmlutils.report.units.udef_to_string` renders a libsbml `UnitDefinition` as a readable string or as latex, which is what the [reports](reports.md) use: ```python 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}' ``` --- # Annotations An element named `glc` means nothing to a machine. MIRIAM annotations attach a qualifier — *what is the relation?* — and a resource — *which database entry?* — to a model element: "this species **is** [CHEBI:17234](https://identifiers.org/CHEBI:17234)". `sbmlutils` uses the annotation data structures of [pymetadata](https://matthiaskoenig.github.io/pymetadata) and offers two ways to apply them: in the model definition, or from a spreadsheet onto an existing model. ## In the model definition Every element accepts `annotations` as a list of `(qualifier, resource)` tuples and an `sboTerm`: ```python from sbmlutils.factory import Compartment, Species from sbmlutils.metadata import BQB, SBO Compartment( sid="cyto", value=1.0, name="cytosol", sboTerm=SBO.PHYSICAL_COMPARTMENT, annotations=[ (BQB.IS, "go/GO:0005829"), # cytosol (BQB.IS, "https://en.wikipedia.org/wiki/Cytosol"), ], ) Species( sid="glc", compartment="cyto", initialConcentration=5.0, sboTerm=SBO.SIMPLE_CHEMICAL, annotations=[ (BQB.IS, "chebi/CHEBI:17234"), # glucose (BQB.IS, "vmhmetabolite/glc_D"), ], ) ``` A resource is written as `collection/term` (`chebi/CHEBI:17234`), as an identifiers.org URL, as a `urn:miriam:*` URN or as an arbitrary URL. pymetadata normalizes it to an identifiers.org compact identifier and validates the term against the [identifiers.org](https://identifiers.org) registry. ## Qualifiers `BQB` (biological) and `BQM` (model) are the MIRIAM qualifiers, re-exported from pymetadata: ```python from sbmlutils.metadata import BQB, BQM BQB.IS, BQB.IS_VERSION_OF, BQB.HAS_PART, BQB.IS_PART_OF, BQB.OCCURS_IN BQM.IS, BQM.IS_DESCRIBED_BY, BQM.IS_DERIVED_FROM ``` Use `BQB` for what a thing *is* in biology and `BQM` for what the *model* is, e.g. `(BQM.IS_DESCRIBED_BY, "pubmed/12345678")` on the model itself. ## SBO terms The systems biology ontology says what role an element plays. The terms come from pymetadata and carry their label and definition, so an editor shows what a term means while it is completed: ```python from sbmlutils.metadata import SBO SBO.SIMPLE_CHEMICAL # 'SBO_0000247' SBO.SIMPLE_CHEMICAL.label # 'simple chemical' SBO.SIMPLE_CHEMICAL.curie # 'SBO:0000247' ``` An `sboTerm` is written both as the `sboTerm` attribute and as an RDF annotation of the element. ## Creators The people behind a model are recorded on the model: ```python from sbmlutils.factory import Creator, Model model = Model( sid="example", creators=[ Creator( familyName="König", givenName="Matthias", email="koenigmx@hu-berlin.de", organization="Humboldt-University Berlin", site="https://livermetabolism.com", orcid="0000-0003-1725-179X", ) ], ) ``` ## From a spreadsheet Annotating an existing model, or keeping the annotations of a large model outside the code, is done with an annotation file — an Excel sheet, a csv or a tsv — with one annotation per row: | pattern | sbml_type | annotation_type | qualifier | resource | name | | --- | --- | --- | --- | --- | --- | | | document | rdf | BQM_IS | sbo/SBO:0000293 | non-spatial continuous framework | | `^demo_\d+$` | model | rdf | BQM_IS | go/GO:0008152 | metabolic process | | `^glc$` | species | rdf | BQB_IS | chebi/CHEBI:17234 | glucose | | `^glc$` | species | formula | | C6H12O6 | | | `^atp$` | species | charge | | -4 | | - `pattern` is a regular expression matched against the ids of the elements of `sbml_type`, so one row annotates many elements. It is empty for the document. - `sbml_type` is `document`, `model`, `unit`, `reaction`, `transporter`, `species`, `compartment`, `parameter`, `rule` or `fbc:geneproduct`. - `annotation_type` is `rdf` for a MIRIAM annotation, or `formula` and `charge`, which write the chemical formula and the charge through the fbc species plugin. - `name` is a comment for the reader, it is not written into the model. The file is applied to a model with `annotate_sbml`: ```python from pathlib import Path from sbmlutils.metadata.annotator import annotate_sbml annotate_sbml( source=Path("model.xml"), annotations_path=Path("annotations.xlsx"), filepath=Path("model_annotated.xml"), ) ``` `create_model` takes the same file directly, so a model is annotated while it is created: ```python from sbmlutils.factory import create_model create_model( model=model, filepath=Path("model.xml"), annotations=Path("annotations.xlsx") ) ``` ## Validating annotations `validate_sbml_annotations` checks every annotation of a model against the identifiers.org registry and returns the ones which do not resolve: ```python from sbmlutils.metadata.validator import validate_sbml_annotations df = validate_sbml_annotations("model.xml") print(df) ``` This queries the registry, so it needs network access on the first run; pymetadata caches the responses. --- # Notes SBML notes are the human readable description of an element. The specification requires them to be valid XHTML, which is unpleasant to write by hand. `sbmlutils` accepts markdown and converts it, so the description is written the way documentation is written: ```python from sbmlutils.factory import Model, Species model = Model( sid="example", notes=""" # Example model A model which demonstrates **notes**. ## Units - time: min - substance: mmole See [the SBML specification](https://sbml.org/documents/specifications/) for details. """, species=[ Species( "glc", compartment="cell", initialConcentration=5.0, notes="D-glucose, the substrate of the model.", ), ], ) ``` The conversion uses [markdown-it-py](https://markdown-it-py.readthedocs.io) and supports the usual markdown: headings, lists, tables, links, emphasis and code. The result is wrapped in the `` element SBML expects. ## Notes directly `Notes` converts a string on its own, which is useful when notes are set on an existing libsbml object: ```python from sbmlutils.notes import Notes, NotesFormat notes = Notes("# Heading\n\nSome *text*.") sbase.setNotes(notes.xml) ``` `NotesFormat.HTML` passes the string through unchanged when it is already XHTML: ```python Notes("

already xhtml

", format=NotesFormat.HTML) ``` ## Reusable text blocks Notes are plain strings, so shared text is a variable. The examples keep the terms of use in `examples/templates.py` and append it to the notes of every model: ```python from examples import templates model = Model(sid="example", notes="# Example model\n" + templates.terms_of_use) ``` --- # Validation libsbml validates a document against the SBML specification and reports what it finds as a list of errors. `sbmlutils` runs those checks, groups the results and prints a report which says what is wrong and where. ## Validating a file ```python from sbmlutils.io import validate_sbml results = validate_sbml("model.xml") print(results.error_count, results.warning_count, results.all_count) print(results.is_valid()) ``` `validate_sbml` accepts a path, an SBML string or an `SBMLDocument` and returns a `ValidationResult` with the errors and warnings and a count of each severity. `validate_doc` does the same for a document which is already read. ## Consistency checks Which checks run is configured with `ValidationOptions`: ```python from sbmlutils.validation import ValidationOptions options = ValidationOptions( general_consistency=True, # the SBML language constructs identifier_consistency=True, # the identifiers used in the model units_consistency=True, # the units of every quantity and formula mathml_consistency=True, # the syntax of the MathML sbo_consistency=True, # the SBO terms overdetermined_model=True, # whether the model is overdetermined modeling_practice=True, # style recommendations internal_consistency=True, # the model as consistent XML log_errors=True, # log what was found ) ``` Every check is on by default. The unit check is the expensive and the interesting one: it recomputes the units of every formula and reports where they do not add up. A model which is still being written is validated faster with `ValidationOptions(units_consistency=False)`. `modeling_practice` reports style recommendations (an unset unit, a parameter which is never used) rather than errors, so it is the first one to turn off when the report gets noisy. ## While the model is created `create_model` validates what it writes: ```python from sbmlutils.factory import ValidationOptions, create_model create_model( model=model, filepath="model.xml", validate=True, validation_options=ValidationOptions(units_consistency=False), ) ``` Validation reports, it does not block: the file is written either way, and the result tells you what to fix. `validate=False` skips the check. ## The report The report of a validation lists the counts per category and then every message with its severity, its category, the line it is on and the explanation from the specification: ``` ──────────────────────────────── Validate SBML ───────────────────────────────── model.xml valid : FALSE validation error(s) : 1 validation warnings(s) : 0 general : True identifier : True mathml : True overdetermined : True sbo : True units : True check time (s) : 0.012 ──────────────────────────────────────────────────────────────────────────────── ``` The messages go through the logging of the package, so an application decides where they end up, see [Installation](installation.md#logging). ## Checking a libsbml call `check` is the helper the package itself uses around libsbml calls, which return a status code instead of raising: ```python from sbmlutils.validation import check check(species.setId("glc"), "set id on species") ``` It returns `True` when the call succeeded and logs what failed otherwise. --- # Reading and writing `sbmlutils.io` wraps the libsbml reader and writer, so a model is read from a path, a string or a URL and written with the metadata SBML expects. ## Reading ```python from sbmlutils.io import read_sbml doc = read_sbml("model.xml") # a path doc = read_sbml(sbml_str) # an SBML string doc = read_sbml("https://.../model.xml") # a URL ``` `read_sbml` returns a libsbml `SBMLDocument`. It validates on request: ```python from sbmlutils.validation import ValidationOptions doc = read_sbml( "model.xml", validate=True, validation_options=ValidationOptions(units_consistency=False), ) ``` Compressed files are read as they are: a `.xml.gz` path is decompressed transparently. ## Writing ```python from sbmlutils.io import write_sbml write_sbml(doc, filepath="model.xml") sbml_str = write_sbml(doc, filepath=None) # returns the SBML as a string ``` `write_sbml` records how the file was created in the notes of the document, and validates the result when asked to. ## Reading a model definition back `sbml_to_model` parses an SBML file into the `Model` object of the [model creation](creation.md), which is the inverse of `create_model`: ```python from sbmlutils.parser import sbml_to_model model = sbml_to_model("model.xml") print(model.species[0].sid) ``` This is how an existing model is brought into a python definition which can be edited, composed or generated from. ## Antimony [Antimony](https://tellurium.readthedocs.io/en/latest/antimony.html) is a compact text notation for models. `sbmlutils.parser` converts it to SBML, and to a model definition: ```python from sbmlutils.parser import antimony_to_model, antimony_to_sbml sbml_str = antimony_to_sbml(""" model example J0: S1 -> S2; k1*S1 S1 = 10; S2 = 0; k1 = 0.1 end """) model = antimony_to_model("model.ant") ``` Both accept the antimony as a string or as a path to an `.ant` file. The other direction, SBML to antimony, is `sbml_to_antimony` in `sbmlutils.io`, which accepts an SBML string or the path to an SBML file. `create_model` writes it next to the SBML file with `create_antimony=True`, see [Model creation](creation.md). ```python from sbmlutils.io import sbml_to_antimony ant_str = sbml_to_antimony(Path("model.xml")) ``` ## Promoting local parameters Local parameters of a kinetic law are invisible to most tools. `promote_local_variables` lifts them to the model, with the reaction id as a prefix: ```python from sbmlutils.io.sbml import promote_local_variables doc = promote_local_variables(doc, suffix="_promoted") ``` ## Downloading from BioModels `sbmlutils.biomodels` fetches models from [BioModels](https://www.ebi.ac.uk/biomodels/), as SBML or as a COMBINE archive: ```python from pathlib import Path from sbmlutils.biomodels import ( download_biomodel_omex, download_biomodel_sbml, query_curated_biomodels, ) # the OMEX archive of a model download_biomodel_omex("BIOMD0000000012", Path("BIOMD0000000012.omex")) # the SBML files inside it, written into a directory paths = download_biomodel_sbml("BIOMD0000000012", Path("models")) # the ids of all curated models biomodel_ids = query_curated_biomodels() ``` --- # Model composition Large models are built from smaller ones. The SBML [comp](https://sbml.org/documents/specifications/level-3/version-1/comp/) package makes this explicit: a model includes other models as *submodels*, exposes elements through *ports*, and connects them by *replacing* an element of a submodel with one of the parent model. ## Ports A port is the interface of a model — the elements another model is allowed to connect to. Any element is exported by setting `port=True`: ```python from sbmlutils.factory import Compartment, Model, Package, Species model = Model( sid="cell", packages=[Package.COMP_V1], compartments=[Compartment("cell", value=1.0, port=True)], species=[Species("S1", initialConcentration=10.0, compartment="cell", port=True)], ) ``` The port of an element gets the id of the element plus `PORT_SUFFIX` (`_port`), so the port of `cell` is `cell_port`. A unit port uses `PORT_UNIT_SUFFIX` (`_unit_port`). A `Port` object is created explicitly when the id or the reference has to be different. ## Submodels A submodel refers to a model definition, which is either inside the same file (`ModelDefinition`) or in another file (`ExternalModelDefinition`): ```python from sbmlutils.factory import ExternalModelDefinition, Submodel model.external_model_definitions = [ ExternalModelDefinition(sid="emd0", source="cell.xml", modelRef="cell"), ] model.submodels = [Submodel(sid="submodel0", modelRef="emd0")] ``` ## Replacements A replacement says that an element of the parent model *is* an element of a submodel, so the two are one element after flattening: ```python from sbmlutils.factory import PORT_SUFFIX, ReplacedElement model.replaced_elements = [ ReplacedElement( sid="cell0_RE", metaId="cell0_RE", elementRef="cell0", # the element of this model submodelRef="submodel0", # the submodel it replaces in portRef=f"cell{PORT_SUFFIX}", # the port of the submodel ), ] ``` `ReplacedBy` is the other direction — an element of this model is replaced *by* one of a submodel — and `Deletion` removes an element of a submodel. ## A grid of coupled cells Because the model definition is python, a composite model is built in a loop. This couples `n_cells` copies of the same model through a transport reaction: ```python n_cells = 5 model = Model(sid="coupled_cells", packages=[Package.COMP_V1]) model.compartments = [Compartment(sid=f"cell{k}", value=1.0) for k in range(n_cells)] model.species = [ Species( sid=f"S{k}", initialConcentration=10.0 if k == 0 else 0.0, compartment=f"cell{k}", ) for k in range(n_cells) ] model.parameters = [Parameter("D", 0.01)] model.reactions = [ Reaction( sid=f"J{k}", equation=f"S{k} <-> S{k + 1}", formula=f"D * (S{k} - S{k + 1})" ) for k in range(n_cells - 1) ] model.external_model_definitions = [ ExternalModelDefinition(sid=f"emd{k}", source="cell.xml", modelRef="cell") for k in range(n_cells) ] model.submodels = [ Submodel(sid=f"submodel{k}", modelRef=f"emd{k}") for k in range(n_cells) ] model.replaced_elements = [ ReplacedElement( sid=f"S{k}_RE", metaId=f"S{k}_RE", elementRef=f"S{k}", submodelRef=f"submodel{k}", portRef=f"S1{PORT_SUFFIX}", ) for k in range(n_cells) ] ``` The complete example is `examples/tutorial/minimal_model_comp.py`, the whole body physiological model in `examples/icg/` shows the same pattern at scale. ## Flattening Most simulators do not read comp models. `flatten_sbml` resolves the submodels, applies the replacements and writes a single flat model: ```python from sbmlutils.comp import flatten_sbml flatten_sbml(sbml_path="model_comp.xml", sbml_flat_path="model_flat.xml") ``` `leave_ports=False` removes the ports from the flat model as well. `flatten_sbml_doc` does the same for a document which is already read. External model definitions are resolved relative to the file they are referenced from, so the comp model and the models it includes stay together. ## Merging models Merging is the other way to combine models: several independent models become the submodels of one comp model, without ports or replacements. ```python from pathlib import Path from sbmlutils.manipulation import merge_models model_paths = { "BIOMD0000000001": Path("BIOMD0000000001.xml"), "BIOMD0000000002": Path("BIOMD0000000002.xml"), } doc = merge_models(model_paths, output_dir=Path("merged")) ``` This is what `create_model` does when it is given several model definitions, see [Model creation](creation.md#several-models-at-once). --- # Flux balance constraints The SBML [fbc](https://sbml.org/documents/specifications/level-3/version-1/fbc/) package turns a reaction network into a constraint based model: every reaction gets a lower and an upper flux bound, an objective says what to optimize, and gene products link reactions to the genes which encode them. `sbmlutils` supports fbc version 2 and version 3 ([Olivier *et al.* 2026](references.md#sbml-packages)). ## Flux bounds Bounds are parameters, referenced by their id on the reaction: ```python from sbmlutils.factory import Model, Package, Parameter, Reaction, Units, UnitDefinition class U(Units): """Units of the model.""" hr = UnitDefinition("hr") mmole = UnitDefinition("mmole") mmole_per_hr = UnitDefinition("mmole_per_hr", "mmole/hr") model = Model(sid="fbc_example", packages=[Package.FBC_V3], units=U) model.parameters = [ Parameter("zero", 0.0, U.mmole_per_hr, constant=True, sboTerm="SBO:0000612"), Parameter( "ub_inf", float("inf"), U.mmole_per_hr, constant=True, sboTerm="SBO:0000612" ), Parameter( "lb_inf", -float("inf"), U.mmole_per_hr, constant=True, sboTerm="SBO:0000612" ), ] model.reactions = [ Reaction( sid="v1", equation="9.46 Glcxt + 12.92 O2 => X []", lowerFluxBound="zero", upperFluxBound="ub_inf", ), ] ``` `add_default_flux_bounds` adds the bounds to a model which has none, which is what a model needs before cobrapy will read it: ```python from sbmlutils.fbc.fbc import add_default_flux_bounds add_default_flux_bounds(doc, lower=-1000.0, upper=1000.0) ``` ## Exchange reactions An exchange reaction is the boundary of the model: it lets a species enter or leave the system. `ExchangeReaction` creates it from the species id, with the `EX_` prefix the field expects: ```python from sbmlutils.factory import ExchangeReaction model.reactions.extend( [ ExchangeReaction( species_id="Glcxt", lowerFluxBound="lb_glc", upperFluxBound="zero" ), ExchangeReaction( species_id="X", lowerFluxBound="lb_inf", upperFluxBound="ub_inf" ), ] ) ``` ## Objective The objective says which combination of fluxes is optimized and in which direction: ```python from sbmlutils.factory import Objective model.objectives = [ Objective( sid="biomass_max", objectiveType="maximize", active=True, fluxObjectives={"v1": 1.0, "v2": 1.0, "v3": 1.0, "v4": 1.0}, ) ] ``` `fluxObjectives` maps a reaction id to its coefficient. Several objectives can be defined, exactly one is `active`. ## Gene products Gene products and the association of a reaction with them record which genes carry a reaction: ```python from sbmlutils.factory import GeneProduct, Reaction model.gene_products = [ GeneProduct("g_b3670", label="b3670", name="b3670"), GeneProduct("g_b3671", label="b3671", name="b3671"), ] Reaction( sid="v1", equation="A => B", geneProductAssociation="g_b3670 AND g_b3671", ) ``` The association is a boolean expression over the gene product ids, with `AND` and `OR`. ## Chemical formula and charge The formula and the charge of a species are fbc attributes and are set in the model definition or from an [annotation file](annotations.md#from-a-spreadsheet): ```python from sbmlutils.factory import Species Species( sid="glc", compartment="cell", initialConcentration=0.0, chemicalFormula="C6H12O6", charge=0, ) ``` `sbmlutils.fbc.cobra.check_mass_balance` reports the reactions which are not balanced. ## User defined constraints (fbc v3) fbc version 3 adds constraints over several fluxes at once: ```python from sbmlutils.factory import Parameter, UserDefinedConstraint model.parameters += [ Parameter("uc1", 5.0), # the bound of the constraint Parameter("coef_plus_one", 1.0), # the coefficients of the components Parameter("coef_minus_one", -1.0), ] model.user_defined_constraints = [ UserDefinedConstraint( lowerBound="uc1", upperBound="uc1", components={"RGLX": "coef_plus_one", "RXLG": "coef_minus_one"}, variableType="linear", ), ] ``` The bounds and the coefficients are references to parameters, not numbers: fbc version 3 declares them as `SIdRef`, so the constraint above reads as `uc1 <= 1.0 * RGLX - 1.0 * RXLG <= uc1`. ## cobrapy [cobrapy](https://cobrapy.readthedocs.io) does the flux balance analysis. It is not a dependency of `sbmlutils`; install it with the `cobra` extra: ```bash pip install sbmlutils[cobra] ``` ```python from sbmlutils.fbc.cobra import cobra_reaction_info, read_cobra_model model = read_cobra_model("fbc_model.xml") solution = model.optimize() print(solution.objective_value) df = cobra_reaction_info(model) # bounds and objective coefficients as a DataFrame ``` The complete examples are in `examples/fbc/`: `fbc_v2.py`, `fbc_v3.py`, `fbc_mass_charge.py` and `fbc_userdefinedconstraints.py`. --- # Distributions and uncertainties A parameter of a model is rarely a single number. It is a mean with a standard deviation, a range from the literature, or a value drawn from a distribution. The SBML [distrib](https://sbml.org/documents/specifications/level-3/version-1/distrib/) package records this next to the value instead of in a comment ([Smith *et al.* 2020](references.md#sbml-packages)). ## Uncertainty on an element Every element accepts `uncertainties`, a list of `Uncertainty` objects. An uncertainty holds `UncertParameter` values (a mean, a standard deviation, a variance) and `UncertSpan` values (a range, a confidence interval): ```python import libsbml from sbmlutils.factory import ( Model, Package, Parameter, UncertParameter, UncertSpan, Uncertainty, ) model = Model( sid="uncertainty_example", packages=[Package.DISTRIB_V1], parameters=[ Parameter( "p1", value=5.0, uncertainties=[ Uncertainty( sid="p1_uncertainty", uncertParameters=[ UncertParameter( type=libsbml.DISTRIB_UNCERTTYPE_MEAN, value=5.0 ), UncertParameter( type=libsbml.DISTRIB_UNCERTTYPE_STANDARDDEVIATION, value=0.3 ), ], uncertSpans=[ UncertSpan( type=libsbml.DISTRIB_UNCERTTYPE_RANGE, valueLower=2.0, valueUpper=8.0, ), ], ) ], ), ], ) ``` The types are the `libsbml.DISTRIB_UNCERTTYPE_*` constants: `MEAN`, `MEDIAN`, `STANDARDDEVIATION`, `VARIANCE`, `COEFFIACIENTOFVARIATION`, `SKEWNESS`, `RANGE`, `INTERQUARTILERANGE`, `CONFIDENCEINTERVAL`, `CREDIBLEINTERVAL`, `DISTRIBUTION` and `EXTERNALPARAMETER`. An uncertainty also carries a definition URL, which is how a distribution from [ProbOnto](https://probonto.org) is referenced: ```python UncertParameter( type=libsbml.DISTRIB_UNCERTTYPE_EXTERNALPARAMETER, value=0.4, definitionURL="http://www.probonto.org/ontology#PROB_k0000789", ) ``` ## Distributions in formulas distrib also adds distribution functions to MathML, which are written in a formula like any other function: ```python from sbmlutils.factory import InitialAssignment, Model, Package, Parameter model = Model( sid="distrib_assignment", packages=[Package.DISTRIB_V1], parameters=[Parameter("p1", value=0.0)], assignments=[InitialAssignment("p1", "normal(0, 1)")], ) ``` The supported functions are `normal`, `uniform`, `bernoulli`, `binomial`, `cauchy`, `chisquare`, `exponential`, `gamma`, `laplace`, `lognormal`, `poisson` and `rayleigh`, with the truncated forms taking the bounds as additional arguments, e.g. `normal(0, 1, -2, 2)`. The unit of the arguments matters as much as anywhere else, so a value with a unit is written as `normal(0 mM, 1 mM)`. ## Examples - `examples/distrib/distrib_distributions.py` — every distribution function in an assignment - `examples/distrib/distrib_uncertainties.py` — uncertainties on the elements of a model - `examples/distrib/distrib_comp.py` — uncertainties in a hierarchical model - `examples/distrib/distrib_packages_examples.py` — the raw libsbml distrib elements --- # COMBINE archives A model is rarely the whole story: a study consists of one or more models, the simulation experiments which were run on them, the data and the figures. The [COMBINE archive](https://combinearchive.org/) (OMEX) packages all of it into one file with a `manifest.xml` which says what every entry is. `sbmlutils` uses [pymetadata](https://matthiaskoenig.github.io/pymetadata/omex/) for archives; it is a dependency, so nothing extra has to be installed. ## Creating an archive ```python from pathlib import Path from pymetadata.omex import EntryFormat, ManifestEntry, Omex from sbmlutils.factory import create_model # create the models sbml_path = Path("model.xml") create_model(model=model, filepath=sbml_path) # package them omex = Omex() omex.add_entry( entry_path=sbml_path, entry=ManifestEntry( location="./models/model.xml", format=EntryFormat.SBML_L3V1, master=True, ), ) omex.to_omex(Path("study.omex")) ``` `location` is the path of the entry inside the archive, `format` is the identifiers.org URI of the format, and `master` marks the entry a tool should start with. ## Reading an archive ```python from pymetadata.omex import Omex with Omex.from_omex(Path("study.omex")) as omex: print(omex.manifest["./models/model.xml"].format) for entry in omex.entries_by_format("sbml"): print(entry.location, omex.get_path(entry.location)) ``` The context manager removes the temporary directory the archive was extracted into. `Omex.from_url` reads an archive directly from a URL, which is how the models of [BioModels](https://www.ebi.ac.uk/biomodels/) are fetched, see [Reading and writing](io.md#downloading-from-biomodels). ## Reports for an archive `SBMLDocumentInfo` describes a single model. For an archive, iterate the SBML entries and describe each of them, which is what the [report](reports.md) does: ```python from pymetadata.omex import Omex from sbmlutils.report.sbmlinfo import SBMLDocumentInfo with Omex.from_omex(Path("study.omex")) as omex: for entry in omex.entries_by_format("sbml"): info = SBMLDocumentInfo.from_sbml(omex.get_path(entry.location)) print(entry.location, len(info.to_json())) ``` ## Example `examples/combine_archive/omex_models.py` creates two models, flattens the hierarchical one and packages all three into an archive: ```bash python -m examples.combine_archive.omex_models ``` --- # 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](https://sbml4humans.de) renders it in the browser. ## The content of a model `SBMLDocumentInfo` walks a document and collects everything about it: ```python 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. ## Math as latex The math of a model is rendered as latex, which is what the report displays: ```python 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](units.md#rendering-a-unit): ```python 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 [sbml4humans.de](https://sbml4humans.de) and shuts the server down afterwards: ```python from pathlib import Path from sbmlutils.report.sbmlreport import create_online_report create_online_report(sbml_path=Path("model.xml")) ``` The model is served from your machine for the duration of `fileserver_duration` (10 seconds by default) so that the site can fetch it; nothing is uploaded permanently. `server="localhost:3456"` points it at a local instance of the frontend. The frontend and the http api behind sbml4humans.de live in [matthiaskoenig/sbml4humans](https://github.com/matthiaskoenig/sbml4humans); the report itself, i.e. `SBMLDocumentInfo`, is part of sbmlutils and is what that api serves. --- # Converters An SBML model is a description, not a program. The converters turn it into something else: the ODE system as code, a model from another format, or a file another tool understands. ## SBML to an ODE system `SBML2ODE` derives the ordinary differential equations of a model and writes them as code: ```python from pathlib import Path from sbmlutils.converters.odefac import SBML2ODE factory = SBML2ODE.from_file(sbml_file=Path("model.xml")) factory.to_python(py_file=Path("model.py")) factory.to_R(r_file=Path("model.R")) factory.to_julia(jl_file=Path("model.jl")) factory.to_markdown(md_file=Path("model.md")) factory.to_tex(tex_file=Path("model.tex")) ``` Every method returns the generated code as a string as well, so the file argument is optional. The generated python is a self contained module with the identifiers, the initial conditions, the parameters and the right hand side, ready for an integrator such as `scipy.integrate.odeint`: ```python def f_dxdt(x: np.ndarray, t: float, p: np.ndarray) -> np.ndarray: """Right hand side of the ODE system.""" ... def f_y(x: np.ndarray, t: float, p: np.ndarray) -> np.ndarray: """Assignment rules of the model.""" ... ``` The markdown and latex output are the equations for a paper or a model description: the state variables, the assignments and the ODEs, with the units. The conversion resolves the assignment rules in dependency order, which is why an assignment which depends on another one comes out in the right place. The templates behind the generation are in `sbmlutils/resources/converters/`; `to_custom_template` renders the same model through a template of your own. ## XPP to SBML [XPP/XPPAUT](http://www.math.pitt.edu/~bard/xpp/xpp.html) models are `.ode` files. `xpp2sbml` converts one to SBML: ```python from pathlib import Path from sbmlutils.converters import xpp xpp.xpp2sbml(xpp_file=Path("model.ode"), sbml_file=Path("model.xml")) ``` The parameters, initial conditions, ODEs, auxiliary variables, functions, markov chains and global (event) statements of the ode file become the corresponding SBML elements. `force_lower=True` lowercases the identifiers, which some ode files rely on. All three packaged ode files (`PLoSCompBiol_Fig1`, `112836_HH-ext` and `SkM_AP_KCa`, in `sbmlutils/resources/testdata/xpp/`) convert to models which validate without an error or a warning; `tests/converters/test_xpp.py` checks this. Two of them do not integrate with the default solver of roadrunner, which is a property of those stiff Hodgkin-Huxley models and their initial conditions, not of the conversion. `examples/converters/xpp.py` converts a packaged ode file and simulates the result: ```bash python -m examples.converters.xpp ``` ## Antimony [Antimony](https://tellurium.readthedocs.io/en/latest/antimony.html) is a compact text notation for models, see [Reading and writing](io.md#antimony): ```python from sbmlutils.parser import antimony_to_model, antimony_to_sbml sbml_str = antimony_to_sbml("J0: S1 -> S2; k1*S1; S1 = 10; S2 = 0; k1 = 0.1") model = antimony_to_model("model.ant") ``` `sbml_to_antimony` in `sbmlutils.io` converts an SBML file or string back to antimony. `create_model` writes the antimony and the markdown of the ODE system next to the SBML file with `create_antimony=True` and `create_markdown=True`, see [Model creation](creation.md). ## COPASI COPASI displays the name of an element, not its id, which makes a model whose elements have no names unreadable in it. `write_ids_to_names` copies the ids into the names: ```python from pathlib import Path from sbmlutils.converters.copasi import write_ids_to_names write_ids_to_names(input_path=Path("model.xml"), output_path=Path("model_copasi.xml")) ``` ## Model definition from SBML `sbml_to_model` reads an SBML file back into the `Model` object of the [model creation](creation.md), which is the converter towards sbmlutils itself: ```python from sbmlutils.parser import sbml_to_model model = sbml_to_model("model.xml") ``` --- # Interpolation A model often has to follow measured data: a plasma concentration over time, a dose response curve, an input which was recorded rather than computed. `sbmlutils.data.interpolation` turns a table of data points into an SBML model which evaluates the interpolation, so the data can be used inside a simulation like any other quantity. ## From a data frame ```python import pandas as pd from sbmlutils.data.interpolation import INTERPOLATION_LINEAR, Interpolation data = pd.DataFrame( { "time": [0.0, 1.0, 2.0, 3.0, 4.0, 5.0], "y": [0.0, 2.0, 1.0, 1.5, 2.5, 3.5], "z": [10.0, 5.0, 2.5, 1.25, 0.6, 0.3], } ) interpolation = Interpolation(data=data, method=INTERPOLATION_LINEAR) interpolation.write_sbml_to_file("interpolation.xml") ``` The first column is the independent variable, every other column is interpolated against it. Each becomes a parameter with an assignment rule which evaluates the interpolation, so simulating the model at time `t` gives the interpolated `y` and `z`. `from_csv` and `from_tsv` read the data from a file: ```python interpolation = Interpolation.from_csv("data.csv", method="linear") interpolation = Interpolation.from_tsv("data.tsv") ``` `write_sbml_to_string()` returns the SBML instead of writing a file. ## The methods The methods are the module constants of `sbmlutils.data.interpolation`: | method | value | what it does | | --- | --- | --- | | `INTERPOLATION_CONSTANT` | `"constant"` | the value of the previous data point, a step function | | `INTERPOLATION_LINEAR` | `"linear"` | a straight line between two data points | | `INTERPOLATION_CUBIC_SPLINE` | `"cubic spline"` | a natural cubic spline through all data points | All three go exactly through the data points; they differ in what happens between them. The formulas are piecewise expressions over the independent variable, so the model is valid SBML which any simulator evaluates. The data is checked when the `Interpolation` is created: it needs at least two columns and three rows, and the first column has to be ascending. A table which is not sorted is sorted, with a warning. ## Simulating an interpolation ```python import roadrunner interpolation.write_sbml_to_file("interpolation.xml") r = roadrunner.RoadRunner("interpolation.xml") r.timeCourseSelections = ["time", "y", "z"] s = r.simulate(0, 5, steps=50) ``` ## Examples `examples/interpolation/` interpolates the same data with all three methods and plots the simulated result against the data points: ```bash python -m examples.interpolation.interpolation python -m examples.interpolation.pancreas ``` Both write their figure into the current working directory; no window is opened. --- # Visualization A reaction network is easier to check as a picture than as XML. `sbmlutils.cytoscape` sends a model to a running [Cytoscape](https://cytoscape.org) instance and renders it as a network. ## Requirements The visualization needs two things which do not come with `sbmlutils`: ```bash pip install sbmlutils[cytoscape] ``` installs [py4cytoscape](https://py4cytoscape.readthedocs.io), which talks to the CyREST interface, and Cytoscape itself has to be **running** on the machine — download it from [cytoscape.org](https://cytoscape.org). The [cy3sbml](https://github.com/matthiaskoenig/cy3sbml) app reads the SBML, install it from the Cytoscape app store. If py4cytoscape is not installed, or Cytoscape is not reachable, the functions log a warning and return `None`; they do not raise, so a model creation script which visualizes at the end still finishes. ## Visualizing a model ```python from pathlib import Path from sbmlutils.cytoscape import visualize_sbml visualize_sbml(sbml_path=Path("model.xml")) ``` `delete_session=True` closes what is open in Cytoscape before the model is loaded, which keeps a script from piling up networks: ```python visualize_sbml(sbml_path=Path("model.xml"), delete_session=True) ``` Antimony is visualized without writing an SBML file first: ```python from sbmlutils.cytoscape import visualize_antimony visualize_antimony("J0: S1 -> S2; k1*S1; S1 = 10; S2 = 0; k1 = 0.1") ``` Most model examples end with a call to `visualize_sbml`, so running one shows the network it just built. ## Layout The positions of the nodes are read from and applied to a network: ```python from sbmlutils.cytoscape import apply_layout, read_layout_xml layout = read_layout_xml(sbml_path=Path("model.xml"), xml_path=Path("layout.xml")) apply_layout(layout) ``` `read_layout_xml` returns the positions as a `DataFrame`, so a layout is edited, generated or stored like any other table. ## Annotations on the canvas Shapes and text are drawn on the canvas of the network, e.g. to group a pathway or to label a compartment: ```python from sbmlutils.cytoscape import ( AnnotationShape, AnnotationShapeType, AnnotationText, add_annotations, ) add_annotations( [ AnnotationShape( type=AnnotationShapeType.ROUND_RECTANGLE, x_pos=100, y_pos=100, width=400, height=300, fill_color="#EEEEEE", ), AnnotationText(text="cytosol", x_pos=120, y_pos=110, font_size=24), ] ) ``` ## Exporting an image ```python from sbmlutils.cytoscape import export_image export_image(image_path=Path("network.png"), format="PNG") ``` ## The SBML layout package The positions of a model can also be stored *in* the model, with the SBML layout package. `sbmlutils.layout` provides the objects for it — `Layout`, `SpeciesGlyph`, `ReactionGlyph`, `CompartmentGlyph` — which are assigned to `model.layouts`: ```python import sbmlutils.layout as layout model.layouts = [ layout.Layout( sid="layout_1", name="Layout 1", width=700, height=700, compartment_glyphs=[ layout.CompartmentGlyph("glyph_c", compartment="c", x=5, y=5, w=690, h=690) ], ) ] ``` `examples/tiny/tiny.py` builds a complete layout this way. --- # References `sbmlutils` implements the specifications of the Systems Biology Markup Language. These are the publications behind the language and behind the packages the library supports; cite them when you describe a model, and cite `sbmlutils` itself as described in [Home](index.md#how-to-cite). ## SBML **SBML Level 3.** The format and the package mechanism which the whole library builds on. > Keating SM, Waltemath D, König M, Zhang F, Dräger A, Chaouiya C, Bergmann FT, Finney A, Gillespie CS, Helikar T, Hoops S, Malik-Sheriff RS, Moodie SL, Moraru II, Myers CJ, Naldi A, Olivier BG, Sahle S, Schaff JC, Smith LP, Swat MJ, Thieffry D, Watanabe L, Wilkinson DJ, Blinov ML, Begley K, Faeder JR, Gómez HF, Hamm TM, Inagaki Y, Liebermeister W, Lister AL, Lucio D, Mjolsness E, Proctor CJ, Raman K, Rodriguez N, Shaffer CA, Shapiro BE, Stelling J, Swainston N, Tanimura N, Wagner J, Meier-Schellersheim M, Sauro HM, Palsson B, Bolouri H, Kitano H, Funahashi A, Hermjakob H, Doyle JC, Hucka M; SBML Level 3 Community members. > **SBML Level 3: an extensible format for the exchange and reuse of biological models.** > *Molecular Systems Biology.* 2020 Aug;16(8):e9110. > [doi:10.15252/msb.20199110](https://doi.org/10.15252/msb.20199110) · PMID: [32845085](https://pubmed.ncbi.nlm.nih.gov/32845085/) · PMCID: [PMC8411907](https://www.ncbi.nlm.nih.gov/pmc/articles/PMC8411907/) **SBML Level 3 Version 2 Core.** The language specification itself, i.e., what a compartment, a species, a reaction, a rule and an event mean. See [Model creation](creation.md). > Hucka M, Bergmann FT, Chaouiya C, Dräger A, Hoops S, Keating SM, König M, Novère NL, Myers CJ, Olivier BG, Sahle S, Schaff JC, Sheriff R, Smith LP, Waltemath D, Wilkinson DJ, Zhang F. > **The Systems Biology Markup Language (SBML): Language Specification for Level 3 Version 2 Core Release 2.** > *Journal of Integrative Bioinformatics.* 2019 Jun 20;16(2):20190021. > [doi:10.1515/jib-2019-0021](https://doi.org/10.1515/jib-2019-0021) · PMID: [31219795](https://pubmed.ncbi.nlm.nih.gov/31219795/) · PMCID: [PMC6798823](https://www.ncbi.nlm.nih.gov/pmc/articles/PMC6798823/) ## SBML packages **Flux balance constraints (fbc), version 3.** Flux bounds, objectives, gene products and user defined constraints. See [Flux balance constraints](fbc.md). > Olivier BG, Bergmann FT, Keating S, König M. > **SBML level 3 package: flux balance constraints version 3.** > *Journal of Integrative Bioinformatics.* 2026 Aug 13. Epub ahead of print. > [doi:10.1515/jib-2026-0006](https://doi.org/10.1515/jib-2026-0006) · PMID: [42590802](https://pubmed.ncbi.nlm.nih.gov/42590802/) **Distributions (distrib), version 1.** Uncertainties on an element and distributions in a formula. See [Distributions and uncertainties](distrib.md). > Smith LP, Moodie SL, Bergmann FT, Gillespie C, Keating SM, König M, Myers CJ, Swat MJ, Wilkinson DJ, Hucka M. > **Systems Biology Markup Language (SBML) Level 3 Package: Distributions, Version 1, Release 1.** > *Journal of Integrative Bioinformatics.* 2020 Jul 20;17(2-3):20200018. > [doi:10.1515/jib-2020-0018](https://doi.org/10.1515/jib-2020-0018) · PMID: [32750035](https://pubmed.ncbi.nlm.nih.gov/32750035/) · PMCID: [PMC7756622](https://www.ncbi.nlm.nih.gov/pmc/articles/PMC7756622/) ## Specifications The current specifications of the language and of every package are published at [sbml.org/documents/specifications](https://sbml.org/documents/specifications/), including the packages `sbmlutils` supports beyond the ones above: [comp](https://sbml.org/documents/specifications/level-3/version-1/comp/) for [model composition](comp.md) and [layout](https://sbml.org/documents/specifications/level-3/version-1/layout/) for the [layout information](visualization.md#the-sbml-layout-package) of a model. --- # API reference The API reference is generated from the docstrings of the package. ## sbmlutils The top level modules: the model definition, reading and writing, validation and the shared output. | module | description | | --- | --- | | [factory](factory.md) | the model definition and `create_model`, the entry point of the package | | [io](io.md) | reading and writing SBML | | [validation](validation.md) | validation of a document against the SBML specification | | [parser](parser.md) | SBML and antimony into a model definition | | [notes](notes.md) | element documentation written as markdown | | [reaction_equation](reaction_equation.md) | the stoichiometry of a reaction as a string | | [biomodels](biomodels.md) | models from the BioModels database | | [cytoscape](cytoscape.md) | models rendered as a network in Cytoscape | | [console](console.md) | shared rich console | | [log](log.md) | logging of the package | | [utils](utils.md) | meta ids and the frozen base class | ## sbmlutils.comp Hierarchical models with the comp package, see [Model composition](../comp.md). | module | description | | --- | --- | | [comp.comp](comp.comp.md) | ports, external model definitions and replacements | | [comp.flatten](comp.flatten.md) | flattening a comp model into a single model | ## sbmlutils.converters Conversion of a model into another representation, see [Converters](../converters.md). | module | description | | --- | --- | | [converters.odefac](converters.odefac.md) | the ODE system as python, R, julia, markdown or latex | | [converters.xpp](converters.xpp.md) | XPP/XPPAUT ode files to SBML | | [converters.copasi](converters.copasi.md) | ids written into the names for COPASI | | [converters.mathml](converters.mathml.md) | evaluation of MathML | ## sbmlutils.data | module | description | | --- | --- | | [data.interpolation](data.interpolation.md) | data points as an SBML model, see [Interpolation](../interpolation.md) | ## sbmlutils.fbc Constraint based models, see [Flux balance constraints](../fbc.md). | module | description | | --- | --- | | [fbc.fbc](fbc.fbc.md) | flux bounds and boundary conditions | | [fbc.cobra](fbc.cobra.md) | the bridge to cobrapy, the optional `cobra` extra | ## sbmlutils.layout | module | description | | --- | --- | | [layout.layout](layout.layout.md) | layout information in the model, see [Visualization](../visualization.md) | ## sbmlutils.manipulation | module | description | | --- | --- | | [manipulation.merge](manipulation.merge.md) | merging models into one comp model | ## sbmlutils.metadata Annotation of models, see [Annotations](../annotations.md). The qualifiers `BQB`, `BQM` and the ontology terms `SBO` are re-exported from [pymetadata](https://matthiaskoenig.github.io/pymetadata). | module | description | | --- | --- | | [metadata.annotator](metadata.annotator.md) | annotations from a file applied to a model | | [metadata.validator](metadata.validator.md) | validation of the annotations of a model | | [metadata.miriam](metadata.miriam.md) | the MIRIAM qualifiers of libsbml | ## sbmlutils.report The content of a model for a human reader, see [Reports](../reports.md). | module | description | | --- | --- | | [report.sbmlinfo](report.sbmlinfo.md) | the complete content of a document as JSON | | [report.sbmlreport](report.sbmlreport.md) | a report on sbml4humans.de | | [report.units](report.units.md) | unit definitions rendered as a string or latex | | [report.mathml](report.mathml.md) | math rendered as latex | --- # sbmlutils.factory Factory for creating SBML objects. This module provides definitions of helper functions for the creation of SBML objects. These are the low level helpers to create models from scratch and are used in the higher level SBML factories. The general workflow to create new SBML models isto create a lists/iterables of SBMLObjects by using the respective classes in this module, e.g. Compartment, Parameter, Species. The actual SBase objects are than created in the SBMLDocument/Model by calling create_objects(model, objects) These functions DO NOT take care of the order of the creation, but the order must be correct in the model definition files. To create complete models one should use the modelcreator functionality, which takes care of the order of object creation. ## class `AlgebraicRule(sid: 'str', value: 'str | float', unit: 'UnitType' = , name: 'str | None' = None, sboTerm: 'str | None' = None, metaId: 'str | None' = None, annotations: 'OptionalAnnotationsType' = None, notes: 'str | None' = None, keyValuePairs: 'list[KeyValuePair] | None' = None, port: 'Any' = None, uncertainties: 'list[Uncertainty] | None' = None, replacedBy: 'Any | None' = None)` AlgebraicRule. ### `AlgebraicRule.check_model_for_rule(self, model: 'libsbml.Model') -> 'None'` Check model for rule requirements. Creates a required parameter if the symbol for the initial assignment does not exist in the model. ### `AlgebraicRule.create_key_value_pairs(self, sbase: 'libsbml.SBase') -> 'list[libsbml.KeyValuePair] | None'` Create fbc:keyValuePair. ### `AlgebraicRule.create_port(self, model: 'libsbml.Model') -> 'libsbml.Port | None'` Create port if existing. ### `AlgebraicRule.create_replaced_by(self, sbase: 'libsbml.SBase', model: 'libsbml.Model') -> 'libsbml.ReplacedBy | None'` Create comp:ReplacedBy. ### `AlgebraicRule.create_sbml(self, model: 'libsbml.Model') -> 'libsbml.AlgebraicRule'` Create AlgebraicRule. ### `AlgebraicRule.create_uncertainties(self, obj: 'libsbml.SBase', model: 'libsbml.Model') -> 'list[libsbml.Uncertainty] | None'` Create distrib:Uncertainty objects. ### `AlgebraicRule.get_notes_xml(self) -> 'str | None'` Get notes xml string. ## class `AssignmentRule(variable: 'str', value: 'str | float', unit: 'UnitType' = , sid: 'str | None' = None, name: 'str | None' = None, sboTerm: 'str | None' = None, metaId: 'str | None' = None, annotations: 'OptionalAnnotationsType' = None, notes: 'str | None' = None, keyValuePairs: 'list[KeyValuePair] | None' = None, port: 'Any' = None, uncertainties: 'list[Uncertainty] | None' = None, replacedBy: 'Any | None' = None)` AssignmentRule. The unit attribute is only for the case where a parameter must be created (which has the unit). In case of an initialAssignment of a value the units have to be defined in the math. ### `AssignmentRule.check_model_for_rule(self, model: 'libsbml.Model') -> 'None'` Check model for rule requirements. Creates a required parameter if the symbol for the initial assignment does not exist in the model. ### `AssignmentRule.create_key_value_pairs(self, sbase: 'libsbml.SBase') -> 'list[libsbml.KeyValuePair] | None'` Create fbc:keyValuePair. ### `AssignmentRule.create_port(self, model: 'libsbml.Model') -> 'libsbml.Port | None'` Create port if existing. ### `AssignmentRule.create_replaced_by(self, sbase: 'libsbml.SBase', model: 'libsbml.Model') -> 'libsbml.ReplacedBy | None'` Create comp:ReplacedBy. ### `AssignmentRule.create_sbml(self, model: 'libsbml.Model') -> 'libsbml.AssignmentRule'` Create AssignmentRule. ### `AssignmentRule.create_uncertainties(self, obj: 'libsbml.SBase', model: 'libsbml.Model') -> 'list[libsbml.Uncertainty] | None'` Create distrib:Uncertainty objects. ### `AssignmentRule.get_notes_xml(self) -> 'str | None'` Get notes xml string. ## class `Compartment(sid: 'str', value: 'str | float', unit: 'UnitType' = None, constant: 'bool' = True, spatialDimensions: 'float' = 3, name: 'str | None' = None, sboTerm: 'str | None' = None, metaId: 'str | None' = None, annotations: 'OptionalAnnotationsType' = None, notes: 'str | None' = None, keyValuePairs: 'list[KeyValuePair] | None' = None, port: 'Any' = None, uncertainties: 'list[Uncertainty] | None' = None, replacedBy: 'Any | None' = None)` Compartment. ### `Compartment.create_key_value_pairs(self, sbase: 'libsbml.SBase') -> 'list[libsbml.KeyValuePair] | None'` Create fbc:keyValuePair. ### `Compartment.create_port(self, model: 'libsbml.Model') -> 'libsbml.Port | None'` Create port if existing. ### `Compartment.create_replaced_by(self, sbase: 'libsbml.SBase', model: 'libsbml.Model') -> 'libsbml.ReplacedBy | None'` Create comp:ReplacedBy. ### `Compartment.create_sbml(self, model: 'libsbml.Model') -> 'libsbml.Compartment'` Create Compartment SBML in model. ### `Compartment.create_uncertainties(self, obj: 'libsbml.SBase', model: 'libsbml.Model') -> 'list[libsbml.Uncertainty] | None'` Create distrib:Uncertainty objects. ### `Compartment.get_notes_xml(self) -> 'str | None'` Get notes xml string. ## class `Constraint(sid: 'str', math: 'str', message: 'str | None' = None, name: 'str | None' = None, sboTerm: 'str | None' = None, metaId: 'str | None' = None, annotations: 'OptionalAnnotationsType' = None, notes: 'str | None' = None, keyValuePairs: 'list[KeyValuePair] | None' = None, port: 'Any' = None, uncertainties: 'list[Uncertainty] | None' = None, replacedBy: 'Any | None' = None)` Constraint. The Constraint object is a mechanism for stating the assumptions under which a model is designed to operate. The constraints are statements about permissible values of different quantities in a model. The message must be well formated XHTML, e.g., message='ATP must be non-negative' ### `Constraint.create_key_value_pairs(self, sbase: 'libsbml.SBase') -> 'list[libsbml.KeyValuePair] | None'` Create fbc:keyValuePair. ### `Constraint.create_port(self, model: 'libsbml.Model') -> 'libsbml.Port | None'` Create port if existing. ### `Constraint.create_replaced_by(self, sbase: 'libsbml.SBase', model: 'libsbml.Model') -> 'libsbml.ReplacedBy | None'` Create comp:ReplacedBy. ### `Constraint.create_sbml(self, model: 'libsbml.Model') -> 'libsbml.Constraint'` Create Constraint SBML in model. ### `Constraint.create_uncertainties(self, obj: 'libsbml.SBase', model: 'libsbml.Model') -> 'list[libsbml.Uncertainty] | None'` Create distrib:Uncertainty objects. ### `Constraint.get_notes_xml(self) -> 'str | None'` Get notes xml string. ## class `Deletion(sid: 'str', submodelRef: 'str', portRef: 'str | None' = None, idRef: 'str | None' = None, unitRef: 'str | None' = None, metaIdRef: 'str | None' = None, name: 'str | None' = None, sboTerm: 'str | None' = None, metaId: 'str | None' = None, annotations: 'OptionalAnnotationsType' = None, notes: 'str | None' = None, keyValuePairs: 'list[KeyValuePair] | None' = None)` Deletion. ### `Deletion.create_key_value_pairs(self, sbase: 'libsbml.SBase') -> 'list[libsbml.KeyValuePair] | None'` Create fbc:keyValuePair. ### `Deletion.create_port(self, model: 'libsbml.Model') -> 'libsbml.Port | None'` Create port if existing. ### `Deletion.create_replaced_by(self, sbase: 'libsbml.SBase', model: 'libsbml.Model') -> 'libsbml.ReplacedBy | None'` Create comp:ReplacedBy. ### `Deletion.create_sbml(self, model: 'libsbml.Model') -> 'libsbml.Deletion'` Create SBML Deletion. ### `Deletion.create_uncertainties(self, obj: 'libsbml.SBase', model: 'libsbml.Model') -> 'list[libsbml.Uncertainty] | None'` Create distrib:Uncertainty objects. ### `Deletion.get_notes_xml(self) -> 'str | None'` Get notes xml string. ## class `Document(model: 'Model', sid: 'str | None' = None, name: 'str | None' = None, sboTerm: 'str | None' = None, metaId: 'str | None' = None, annotations: 'OptionalAnnotationsType' = None, notes: 'str | None' = None, keyValuePairs: 'list[KeyValuePair] | None' = None, sbml_level: 'int' = 3, sbml_version: 'int' = 1)` Document. ### `Document.create_key_value_pairs(self, sbase: 'libsbml.SBase') -> 'list[libsbml.KeyValuePair] | None'` Create fbc:keyValuePair. ### `Document.create_port(self, model: 'libsbml.Model') -> 'libsbml.Port | None'` Create port if existing. ### `Document.create_replaced_by(self, sbase: 'libsbml.SBase', model: 'libsbml.Model') -> 'libsbml.ReplacedBy | None'` Create comp:ReplacedBy. ### `Document.create_sbml(self) -> 'libsbml.SBMLDocument'` Create SBML model. ### `Document.create_uncertainties(self, obj: 'libsbml.SBase', model: 'libsbml.Model') -> 'list[libsbml.Uncertainty] | None'` Create distrib:Uncertainty objects. ### `Document.get_json(self) -> 'str'` Get JSON representation. ### `Document.get_notes_xml(self) -> 'str | None'` Get notes xml string. ### `Document.get_sbml(self) -> 'str'` Return SBML string of the model. :return: SBML string ## class `Event(sid: 'str', trigger: 'str', assignments: 'dict[str, str | float] | None' = None, trigger_persistent: 'bool' = True, trigger_initialValue: 'bool' = False, useValuesFromTriggerTime: 'bool' = True, priority: 'str | None' = None, delay: 'str | None' = None, name: 'str | None' = None, sboTerm: 'str | None' = None, metaId: 'str | None' = None, annotations: 'OptionalAnnotationsType' = None, notes: 'str | None' = None, keyValuePairs: 'list[KeyValuePair] | None' = None, port: 'Any' = None, uncertainties: 'list[Uncertainty] | None' = None, replacedBy: 'Any | None' = None)` Event. Trigger have the format of a logical expression: time%200 == 0 Assignments have the format sid = value ### `Event.create_key_value_pairs(self, sbase: 'libsbml.SBase') -> 'list[libsbml.KeyValuePair] | None'` Create fbc:keyValuePair. ### `Event.create_port(self, model: 'libsbml.Model') -> 'libsbml.Port | None'` Create port if existing. ### `Event.create_replaced_by(self, sbase: 'libsbml.SBase', model: 'libsbml.Model') -> 'libsbml.ReplacedBy | None'` Create comp:ReplacedBy. ### `Event.create_sbml(self, model: 'libsbml.Model') -> 'libsbml.Event'` Create Event SBML in model. ### `Event.create_uncertainties(self, obj: 'libsbml.SBase', model: 'libsbml.Model') -> 'list[libsbml.Uncertainty] | None'` Create distrib:Uncertainty objects. ### `Event.get_notes_xml(self) -> 'str | None'` Get notes xml string. ## class `ExchangeReaction(species_id: 'str', compartment: 'str | None' = None, fast: 'bool' = False, reversible: 'bool' = True, lowerFluxBound: 'str | None' = None, upperFluxBound: 'str | None' = None, geneProductAssociation: 'str | None' = None, name: 'str | None' = None, metaId: 'str | None' = None, annotations: 'OptionalAnnotationsType' = None, notes: 'str | None' = None, keyValuePairs: 'list[KeyValuePair] | None' = None, port: 'Any' = None, uncertainties: 'list[Uncertainty] | None' = None, replacedBy: 'Any | None' = None)` Exchange reactions define substances which can be exchanged. This is important for FBC models. EXCHANGE_IMPORT (-INF, 0): is defined as negative flux through the exchange reaction, i.e. the upper bound must be 0, the lower bound some negative value, e.g. -INF EXCHANGE_EXPORT (0, INF): is defined as positive flux through the exchange reaction, i.e. the lower bound must be 0, the upper bound some positive value, e.g. INF ### `ExchangeReaction.create_key_value_pairs(self, sbase: 'libsbml.SBase') -> 'list[libsbml.KeyValuePair] | None'` Create fbc:keyValuePair. ### `ExchangeReaction.create_port(self, model: 'libsbml.Model') -> 'libsbml.Port | None'` Create port if existing. ### `ExchangeReaction.create_replaced_by(self, sbase: 'libsbml.SBase', model: 'libsbml.Model') -> 'libsbml.ReplacedBy | None'` Create comp:ReplacedBy. ### `ExchangeReaction.create_sbml(self, model: 'libsbml.Model') -> 'libsbml.Reaction'` Create Reaction SBML in model. ### `ExchangeReaction.create_uncertainties(self, obj: 'libsbml.SBase', model: 'libsbml.Model') -> 'list[libsbml.Uncertainty] | None'` Create distrib:Uncertainty objects. ### `ExchangeReaction.get_notes_xml(self) -> 'str | None'` Get notes xml string. ### `ExchangeReaction.set_kinetic_law(model: 'libsbml.Model', reaction: 'libsbml.Reaction', formula: 'str') -> 'libsbml.KineticLaw'` Set the kinetic law in reaction based on given formula. ## class `ExternalModelDefinition(sid: 'str', source: 'str', modelRef: 'str', md5: 'str | None' = None, name: 'str | None' = None, sboTerm: 'str | None' = None, metaId: 'str | None' = None, annotations: 'OptionalAnnotationsType' = None, notes: 'str | None' = None, keyValuePairs: 'list[KeyValuePair] | None' = None)` ExternalModelDefinition. ### `ExternalModelDefinition.create_key_value_pairs(self, sbase: 'libsbml.SBase') -> 'list[libsbml.KeyValuePair] | None'` Create fbc:keyValuePair. ### `ExternalModelDefinition.create_port(self, model: 'libsbml.Model') -> 'libsbml.Port | None'` Create port if existing. ### `ExternalModelDefinition.create_replaced_by(self, sbase: 'libsbml.SBase', model: 'libsbml.Model') -> 'libsbml.ReplacedBy | None'` Create comp:ReplacedBy. ### `ExternalModelDefinition.create_sbml(self, model: 'libsbml.Model') -> 'libsbml.ExternalModelDefinition'` Create ExternalModelDefinition. ### `ExternalModelDefinition.create_uncertainties(self, obj: 'libsbml.SBase', model: 'libsbml.Model') -> 'list[libsbml.Uncertainty] | None'` Create distrib:Uncertainty objects. ### `ExternalModelDefinition.get_notes_xml(self) -> 'str | None'` Get notes xml string. ## class `FactoryResult(model: 'Model', sbml_path: 'Path', antimony_path: 'Path | None' = None, markdown_path: 'Path | None' = None) -> None` Data structure for model creation. ## class `FluxObjective(reaction: 'str', coefficient: 'float', variableType: 'str', sid: 'str | None' = None, name: 'str | None' = None, sboTerm: 'str | None' = None, metaId: 'str | None' = None, annotations: 'OptionalAnnotationsType' = None, notes: 'str | None' = None, keyValuePairs: 'list[KeyValuePair] | None' = None, port: 'Any' = None, uncertainties: 'list[Uncertainty] | None' = None, replacedBy: 'Any | None' = None)` FluxObjective. ### `FluxObjective.create_key_value_pairs(self, sbase: 'libsbml.SBase') -> 'list[libsbml.KeyValuePair] | None'` Create fbc:keyValuePair. ### `FluxObjective.create_port(self, model: 'libsbml.Model') -> 'libsbml.Port | None'` Create port if existing. ### `FluxObjective.create_replaced_by(self, sbase: 'libsbml.SBase', model: 'libsbml.Model') -> 'libsbml.ReplacedBy | None'` Create comp:ReplacedBy. ### `FluxObjective.create_sbml(self, objective: 'libsbml.Objective') -> 'libsbml.FluxObjective'` Create Objective. ### `FluxObjective.create_uncertainties(self, obj: 'libsbml.SBase', model: 'libsbml.Model') -> 'list[libsbml.Uncertainty] | None'` Create distrib:Uncertainty objects. ### `FluxObjective.get_notes_xml(self) -> 'str | None'` Get notes xml string. ## class `Formula(value, unit)` Formula(value, unit) ## class `Function(sid: 'str', value: 'str', name: 'str | None' = None, sboTerm: 'str | None' = None, metaId: 'str | None' = None, annotations: 'OptionalAnnotationsType' = None, notes: 'str | None' = None, keyValuePairs: 'list[KeyValuePair] | None' = None, port: 'Any' = None, uncertainties: 'list[Uncertainty] | None' = None, replacedBy: 'Any | None' = None)` SBML FunctionDefinitions. FunctionDefinitions consist of a lambda expression in the value field, e.g., lambda(x,y, piecewise(x,gt(x,y),y) ) # definition of minimum function lambda(x, sin(x) ) ### `Function.create_key_value_pairs(self, sbase: 'libsbml.SBase') -> 'list[libsbml.KeyValuePair] | None'` Create fbc:keyValuePair. ### `Function.create_port(self, model: 'libsbml.Model') -> 'libsbml.Port | None'` Create port if existing. ### `Function.create_replaced_by(self, sbase: 'libsbml.SBase', model: 'libsbml.Model') -> 'libsbml.ReplacedBy | None'` Create comp:ReplacedBy. ### `Function.create_sbml(self, model: 'libsbml.Model') -> 'libsbml.FunctionDefinition'` Create FunctionDefinition SBML in model. ### `Function.create_uncertainties(self, obj: 'libsbml.SBase', model: 'libsbml.Model') -> 'list[libsbml.Uncertainty] | None'` Create distrib:Uncertainty objects. ### `Function.get_notes_xml(self) -> 'str | None'` Get notes xml string. ## class `GeneProduct(sid: 'str', label: 'str', associatedSpecies: 'str | None' = None, name: 'str | None' = None, sboTerm: 'str | None' = None, metaId: 'str | None' = None, annotations: 'OptionalAnnotationsType' = None, notes: 'str | None' = None, keyValuePairs: 'list[KeyValuePair] | None' = None, port: 'Any' = None, uncertainties: 'list[Uncertainty] | None' = None, replacedBy: 'Any | None' = None)` GeneProduct. GeneProduct is a new FBC class derived from SBML SBase that inherits metaid and sboTerm, as well as the subcomponents for Annotation and Notes. The purpose of this class is to define a single gene product. It implements two required attributes id and label as well as two optional attributes name and associatedSpecies. ### `GeneProduct.create_key_value_pairs(self, sbase: 'libsbml.SBase') -> 'list[libsbml.KeyValuePair] | None'` Create fbc:keyValuePair. ### `GeneProduct.create_port(self, model: 'libsbml.Model') -> 'libsbml.Port | None'` Create port if existing. ### `GeneProduct.create_replaced_by(self, sbase: 'libsbml.SBase', model: 'libsbml.Model') -> 'libsbml.ReplacedBy | None'` Create comp:ReplacedBy. ### `GeneProduct.create_sbml(self, model: 'libsbml.Model') -> 'libsbml.GeneProduct'` Create GeneProduct. ### `GeneProduct.create_uncertainties(self, obj: 'libsbml.SBase', model: 'libsbml.Model') -> 'list[libsbml.Uncertainty] | None'` Create distrib:Uncertainty objects. ### `GeneProduct.get_notes_xml(self) -> 'str | None'` Get notes xml string. ## class `InitialAssignment(symbol: 'str', value: 'str | float', unit: 'UnitType' = , sid: 'str | None' = None, name: 'str | None' = None, sboTerm: 'str | None' = None, metaId: 'str | None' = None, annotations: 'OptionalAnnotationsType' = None, notes: 'str | None' = None, keyValuePairs: 'list[KeyValuePair] | None' = None, port: 'Any' = None, uncertainties: 'list[Uncertainty] | None' = None, replacedBy: 'Any | None' = None)` InitialAssignments. The unit attribute is only for the case where a parameter must be created (which has the unit). In case of an initialAssignment of a value the units have to be defined in the math. ### `InitialAssignment.create_key_value_pairs(self, sbase: 'libsbml.SBase') -> 'list[libsbml.KeyValuePair] | None'` Create fbc:keyValuePair. ### `InitialAssignment.create_port(self, model: 'libsbml.Model') -> 'libsbml.Port | None'` Create port if existing. ### `InitialAssignment.create_replaced_by(self, sbase: 'libsbml.SBase', model: 'libsbml.Model') -> 'libsbml.ReplacedBy | None'` Create comp:ReplacedBy. ### `InitialAssignment.create_sbml(self, model: 'libsbml.Model') -> 'libsbml.InitialAssignment'` Create InitialAssignment. Creates a required parameter if the symbol for the initial assignment does not exist in the model. ### `InitialAssignment.create_uncertainties(self, obj: 'libsbml.SBase', model: 'libsbml.Model') -> 'list[libsbml.Uncertainty] | None'` Create distrib:Uncertainty objects. ### `InitialAssignment.get_notes_xml(self) -> 'str | None'` Get notes xml string. ## class `KeyValuePair(key: 'str', value: 'str | None', uri: 'str | None', sid: 'str | None' = None, name: 'str | None' = None, sboTerm: 'str | None' = None, metaId: 'str | None' = None, notes: 'str | None' = None, annotations: 'OptionalAnnotationsType' = None, keyValuePairs: 'list[KeyValuePair] | None' = None, port: 'Any' = None, uncertainties: 'list[Uncertainty] | None' = None, replacedBy: 'Any | None' = None)` KeyValuePair. ### `KeyValuePair.create_key_value_pairs(self, sbase: 'libsbml.SBase') -> 'list[libsbml.KeyValuePair] | None'` Create fbc:keyValuePair. ### `KeyValuePair.create_port(self, model: 'libsbml.Model') -> 'libsbml.Port | None'` Create port if existing. ### `KeyValuePair.create_replaced_by(self, sbase: 'libsbml.SBase', model: 'libsbml.Model') -> 'libsbml.ReplacedBy | None'` Create comp:ReplacedBy. ### `KeyValuePair.create_sbml(self, sbase: 'libsbml.SBase') -> 'libsbml.KeyValuePair'` Create KeyValuePair on object. ### `KeyValuePair.create_uncertainties(self, obj: 'libsbml.SBase', model: 'libsbml.Model') -> 'list[libsbml.Uncertainty] | None'` Create distrib:Uncertainty objects. ### `KeyValuePair.get_notes_xml(self) -> 'str | None'` Get notes xml string. ## class `Model(sid: 'str', name: 'str | None' = None, sboTerm: 'str | None' = None, metaId: 'str | None' = None, annotations: 'OptionalAnnotationsType' = None, notes: 'str | None' = None, keyValuePairs: 'list[KeyValuePair] | None' = None, packages: 'list[Package] | None' = None, creators: 'list[Creator] | None' = None, model_units: 'ModelUnits | None' = None, units: 'type[Units] | None' = None, objects: 'list[Sbase] | None' = None, external_model_definitions: 'list[ExternalModelDefinition] | None' = None, model_definitions: 'list[ModelDefinition] | None' = None, submodels: 'list[Submodel] | None' = None, functions: 'list[Function] | None' = None, compartments: 'list[Compartment] | None' = None, species: 'list[Species] | None' = None, parameters: 'list[Parameter] | None' = None, assignments: 'list[InitialAssignment] | None' = None, rules: 'list[AssignmentRule] | None' = None, rate_rules: 'list[RateRule] | None' = None, algebraic_rules: 'list[AlgebraicRule] | None' = None, reactions: 'list[Reaction] | None' = None, events: 'list[Event] | None' = None, constraints: 'list[Constraint] | None' = None, ports: 'list[Port] | None' = None, replaced_elements: 'list[ReplacedElement] | None' = None, deletions: 'list[Deletion] | None' = None, user_defined_constraints: 'list[UserDefinedConstraint] | None' = None, objectives: 'list[Objective] | None' = None, gene_products: 'list[GeneProduct] | None' = None, layouts: 'list | None' = None) -> None` Model. ### `Model.check_packages(self, packages: 'list[Package] | None') -> 'list[Package]'` Check that all provided packages are supported. ### `Model.create_key_value_pairs(self, sbase: 'libsbml.SBase') -> 'list[libsbml.KeyValuePair] | None'` Create fbc:keyValuePair. ### `Model.create_port(self, model: 'libsbml.Model') -> 'libsbml.Port | None'` Create port if existing. ### `Model.create_replaced_by(self, sbase: 'libsbml.SBase', model: 'libsbml.Model') -> 'libsbml.ReplacedBy | None'` Create comp:ReplacedBy. ### `Model.create_sbml(self, doc: 'libsbml.SBMLDocument') -> 'libsbml.Model'` Create Model. To create the complete SBMLDocument with the model use: doc = Document(model=model).create_sbml() ### `Model.create_uncertainties(self, obj: 'libsbml.SBase', model: 'libsbml.Model') -> 'list[libsbml.Uncertainty] | None'` Create distrib:Uncertainty objects. ### `Model.get_notes_xml(self) -> 'str | None'` Get notes xml string. ### `Model.get_sbml(self) -> 'str'` Create SBML model. ### `Model.merge_models(models: 'Iterable[Model]') -> 'Model'` Merge information from multiple models. ## class `ModelDefinition(sid: 'str', name: 'str | None' = None, sboTerm: 'str | None' = None, metaId: 'str | None' = None, annotations: 'OptionalAnnotationsType' = None, notes: 'str | None' = None, keyValuePairs: 'list[KeyValuePair] | None' = None, units: 'type[Units] | None' = None, compartments: 'list[Compartment] | None' = None, species: 'list[Species] | None' = None)` ModelDefinition. ### `ModelDefinition.create_key_value_pairs(self, sbase: 'libsbml.SBase') -> 'list[libsbml.KeyValuePair] | None'` Create fbc:keyValuePair. ### `ModelDefinition.create_port(self, model: 'libsbml.Model') -> 'libsbml.Port | None'` Create port if existing. ### `ModelDefinition.create_replaced_by(self, sbase: 'libsbml.SBase', model: 'libsbml.Model') -> 'libsbml.ReplacedBy | None'` Create comp:ReplacedBy. ### `ModelDefinition.create_sbml(self, model: 'libsbml.Model') -> 'libsbml.ModelDefinition'` Create ModelDefinition. ### `ModelDefinition.create_uncertainties(self, obj: 'libsbml.SBase', model: 'libsbml.Model') -> 'list[libsbml.Uncertainty] | None'` Create distrib:Uncertainty objects. ### `ModelDefinition.get_notes_xml(self) -> 'str | None'` Get notes xml string. ## class `ModelDict` ModelDict. The ModelDict allows to define the Model as dictionary and then use: md: ModelDict Model(**md) For model construction. If possible use the Model object directly. ## class `ModelUnits(time: 'UnitType' = None, extent: 'UnitType' = None, substance: 'UnitType' = None, length: 'UnitType' = None, area: 'UnitType' = None, volume: 'UnitType' = None)` Class for storing model units information. The ModelUnits define globally the units for `time`, `extent`, `substance`, `length`, `area` and `volume`. The following SBML Level 3 base units can be used. ampere farad joule lux radian volt avogadro gram katal metre second watt becquerel gray kelvin mole siemens weber candela henry kilogram newton sievert coulomb hertz litre ohm steradian dimensionless item lumen pascal tesla ### `ModelUnits.set_model_units(model: 'libsbml.Model', model_units: 'ModelUnits') -> 'None'` Set the main units in model from dictionary. Setting the model units is important for understanding the model dynamics. Allowed keys are: time extent substance length area volume :param model: SBMLModel :param model_units: dict of units :return: ## class `Objective(sid: 'str', objectiveType: 'str' = 0, active: 'bool' = True, fluxObjectives: 'list[FluxObjective] | dict[str, float] | None' = None, variableType: 'str' = 0, name: 'str | None' = None, sboTerm: 'str | None' = None, metaId: 'str | None' = None, annotations: 'OptionalAnnotationsType' = None, notes: 'str | None' = None, keyValuePairs: 'list[KeyValuePair] | None' = None, port: 'Any' = None, uncertainties: 'list[Uncertainty] | None' = None, replacedBy: 'Any | None' = None)` Objective. ### `Objective.create_key_value_pairs(self, sbase: 'libsbml.SBase') -> 'list[libsbml.KeyValuePair] | None'` Create fbc:keyValuePair. ### `Objective.create_port(self, model: 'libsbml.Model') -> 'libsbml.Port | None'` Create port if existing. ### `Objective.create_replaced_by(self, sbase: 'libsbml.SBase', model: 'libsbml.Model') -> 'libsbml.ReplacedBy | None'` Create comp:ReplacedBy. ### `Objective.create_sbml(self, model: 'libsbml.Model') -> 'libsbml.Objective'` Create Objective. ### `Objective.create_uncertainties(self, obj: 'libsbml.SBase', model: 'libsbml.Model') -> 'list[libsbml.Uncertainty] | None'` Create distrib:Uncertainty objects. ### `Objective.get_notes_xml(self) -> 'str | None'` Get notes xml string. ## class `Package(*values)` Supported/tested packages. ## class `Parameter(sid: 'str', value: 'str | float | None' = None, unit: 'UnitType' = None, constant: 'bool' = True, name: 'str | None' = None, sboTerm: 'str | None' = None, metaId: 'str | None' = None, annotations: 'OptionalAnnotationsType' = None, notes: 'str | None' = None, keyValuePairs: 'list[KeyValuePair] | None' = None, port: 'Any' = None, uncertainties: 'list[Uncertainty] | None' = None, replacedBy: 'Any | None' = None)` Parameter. ### `Parameter.create_key_value_pairs(self, sbase: 'libsbml.SBase') -> 'list[libsbml.KeyValuePair] | None'` Create fbc:keyValuePair. ### `Parameter.create_port(self, model: 'libsbml.Model') -> 'libsbml.Port | None'` Create port if existing. ### `Parameter.create_replaced_by(self, sbase: 'libsbml.SBase', model: 'libsbml.Model') -> 'libsbml.ReplacedBy | None'` Create comp:ReplacedBy. ### `Parameter.create_sbml(self, model: 'libsbml.Model') -> 'libsbml.Parameter'` Create Parameter SBML in model. ### `Parameter.create_uncertainties(self, obj: 'libsbml.SBase', model: 'libsbml.Model') -> 'list[libsbml.Uncertainty] | None'` Create distrib:Uncertainty objects. ### `Parameter.get_notes_xml(self) -> 'str | None'` Get notes xml string. ## class `Port(sid: 'str', portRef: 'str | None' = None, idRef: 'str | None' = None, unitRef: 'str | None' = None, metaIdRef: 'str | None' = None, portType: 'PortType | None' = , name: 'str | None' = None, sboTerm: 'str | None' = None, metaId: 'str | None' = None, annotations: 'OptionalAnnotationsType' = None, notes: 'str | None' = None, keyValuePairs: 'list[KeyValuePair] | None' = None)` Port. Ports are stored in an optional child ListOfPorts object, which, if present, must contain one or more Port objects. All of the Ports present in the ListOfPorts collectively define the 'port interface' of the Model. ### `Port.create_key_value_pairs(self, sbase: 'libsbml.SBase') -> 'list[libsbml.KeyValuePair] | None'` Create fbc:keyValuePair. ### `Port.create_port(self, model: 'libsbml.Model') -> 'libsbml.Port | None'` Create port if existing. ### `Port.create_replaced_by(self, sbase: 'libsbml.SBase', model: 'libsbml.Model') -> 'libsbml.ReplacedBy | None'` Create comp:ReplacedBy. ### `Port.create_sbml(self, model: 'libsbml.Model') -> 'libsbml.Port'` Create SBML for Port. ### `Port.create_uncertainties(self, obj: 'libsbml.SBase', model: 'libsbml.Model') -> 'list[libsbml.Uncertainty] | None'` Create distrib:Uncertainty objects. ### `Port.get_notes_xml(self) -> 'str | None'` Get notes xml string. ## class `PortType(*values)` Supported port types. ## class `RateRule(variable: 'str', value: 'str | float', unit: 'UnitType' = , sid: 'str | None' = None, name: 'str | None' = None, sboTerm: 'str | None' = None, metaId: 'str | None' = None, annotations: 'OptionalAnnotationsType' = None, notes: 'str | None' = None, keyValuePairs: 'list[KeyValuePair] | None' = None, port: 'Any' = None, uncertainties: 'list[Uncertainty] | None' = None, replacedBy: 'Any | None' = None)` RateRule. ### `RateRule.check_model_for_rule(self, model: 'libsbml.Model') -> 'None'` Check model for rule requirements. Creates a required parameter if the symbol for the initial assignment does not exist in the model. ### `RateRule.create_key_value_pairs(self, sbase: 'libsbml.SBase') -> 'list[libsbml.KeyValuePair] | None'` Create fbc:keyValuePair. ### `RateRule.create_port(self, model: 'libsbml.Model') -> 'libsbml.Port | None'` Create port if existing. ### `RateRule.create_replaced_by(self, sbase: 'libsbml.SBase', model: 'libsbml.Model') -> 'libsbml.ReplacedBy | None'` Create comp:ReplacedBy. ### `RateRule.create_sbml(self, model: 'libsbml.Model') -> 'libsbml.RateRule'` Create RateRule. ### `RateRule.create_uncertainties(self, obj: 'libsbml.SBase', model: 'libsbml.Model') -> 'list[libsbml.Uncertainty] | None'` Create distrib:Uncertainty objects. ### `RateRule.get_notes_xml(self) -> 'str | None'` Get notes xml string. ## class `Reaction(sid: 'str', equation: 'ReactionEquation | str', formula: 'Formula | tuple[str, UnitType] | str | None' = None, pars: 'list[Parameter] | None' = None, rules: 'list[AssignmentRule] | None' = None, compartment: 'str | None' = None, fast: 'bool' = False, reversible: 'bool | None' = None, lowerFluxBound: 'str | None' = None, upperFluxBound: 'str | None' = None, geneProductAssociation: 'str | None' = None, name: 'str | None' = None, sboTerm: 'str | None' = None, metaId: 'str | None' = None, annotations: 'OptionalAnnotationsType' = None, notes: 'str | None' = None, keyValuePairs: 'list[KeyValuePair] | None' = None, port: 'Any' = None, uncertainties: 'list[Uncertainty] | None' = None, replacedBy: 'Any | None' = None)` Reaction. Class for creating libsbml.Reaction. Equations are of the form '1.0 S1 + 2 S2 => 2.0 P1 + 2 P2 [M1, M2]' The equation consists of - substrates concatenated via '+' on the left side (with optional stoichiometric coefficients) - separation characters separating the left and right equation sides: '<=>' or '<->' for reversible reactions, '=>' or '->' for irreversible reactions (irreversible reactions are written from left to right) - products concatenated via '+' on the right side (with optional stoichiometric coefficients) - optional list of modifiers within brackets [] separated by ',' Examples of valid equations are: '1.0 S1 + 2 S2 => 2.0 P1 + 2 P2 [M1, M2]', 'c__gal1p => c__gal + c__phos', 'e__h2oM <-> c__h2oM', '3 atp + 2.0 phos + ki <-> 16.98 tet', 'c__gal1p => c__gal + c__phos [c__udp, c__utp]', 'A_ext => A []', '=> cit', 'acoa =>', ### `Reaction.create_key_value_pairs(self, sbase: 'libsbml.SBase') -> 'list[libsbml.KeyValuePair] | None'` Create fbc:keyValuePair. ### `Reaction.create_port(self, model: 'libsbml.Model') -> 'libsbml.Port | None'` Create port if existing. ### `Reaction.create_replaced_by(self, sbase: 'libsbml.SBase', model: 'libsbml.Model') -> 'libsbml.ReplacedBy | None'` Create comp:ReplacedBy. ### `Reaction.create_sbml(self, model: 'libsbml.Model') -> 'libsbml.Reaction'` Create Reaction SBML in model. ### `Reaction.create_uncertainties(self, obj: 'libsbml.SBase', model: 'libsbml.Model') -> 'list[libsbml.Uncertainty] | None'` Create distrib:Uncertainty objects. ### `Reaction.get_notes_xml(self) -> 'str | None'` Get notes xml string. ### `Reaction.set_kinetic_law(model: 'libsbml.Model', reaction: 'libsbml.Reaction', formula: 'str') -> 'libsbml.KineticLaw'` Set the kinetic law in reaction based on given formula. ## class `ReplacedBy(sid: 'str', elementRef: 'str', submodelRef: 'str', portRef: 'str | None' = None, idRef: 'str | None' = None, unitRef: 'str | None' = None, metaIdRef: 'str | None' = None, name: 'str | None' = None, sboTerm: 'str | None' = None, metaId: 'str | None' = None, annotations: 'OptionalAnnotationsType' = None, notes: 'str | None' = None, keyValuePairs: 'list[KeyValuePair] | None' = None)` ReplacedBy. ### `ReplacedBy.create_key_value_pairs(self, sbase: 'libsbml.SBase') -> 'list[libsbml.KeyValuePair] | None'` Create fbc:keyValuePair. ### `ReplacedBy.create_port(self, model: 'libsbml.Model') -> 'libsbml.Port | None'` Create port if existing. ### `ReplacedBy.create_replaced_by(self, sbase: 'libsbml.SBase', model: 'libsbml.Model') -> 'libsbml.ReplacedBy | None'` Create comp:ReplacedBy. ### `ReplacedBy.create_sbml(self, sbase: 'libsbml.SBase', model: 'libsbml.Model') -> 'libsbml.ReplacedBy'` Create SBML ReplacedBy. ### `ReplacedBy.create_uncertainties(self, obj: 'libsbml.SBase', model: 'libsbml.Model') -> 'list[libsbml.Uncertainty] | None'` Create distrib:Uncertainty objects. ### `ReplacedBy.get_notes_xml(self) -> 'str | None'` Get notes xml string. ## class `ReplacedElement(sid: 'str', elementRef: 'str', submodelRef: 'str', deletion: 'str | None' = None, conversionFactor: 'str | None' = None, portRef: 'str | None' = None, idRef: 'str | None' = None, unitRef: 'str | None' = None, metaIdRef: 'str | None' = None, name: 'str | None' = None, sboTerm: 'str | None' = None, metaId: 'str | None' = None, annotations: 'OptionalAnnotationsType' = None, notes: 'str | None' = None, keyValuePairs: 'list[KeyValuePair] | None' = None)` ReplacedElement. ### `ReplacedElement.create_key_value_pairs(self, sbase: 'libsbml.SBase') -> 'list[libsbml.KeyValuePair] | None'` Create fbc:keyValuePair. ### `ReplacedElement.create_port(self, model: 'libsbml.Model') -> 'libsbml.Port | None'` Create port if existing. ### `ReplacedElement.create_replaced_by(self, sbase: 'libsbml.SBase', model: 'libsbml.Model') -> 'libsbml.ReplacedBy | None'` Create comp:ReplacedBy. ### `ReplacedElement.create_sbml(self, model: 'libsbml.Model') -> 'libsbml.ReplacedElement'` Create SBML ReplacedElement. ### `ReplacedElement.create_uncertainties(self, obj: 'libsbml.SBase', model: 'libsbml.Model') -> 'list[libsbml.Uncertainty] | None'` Create distrib:Uncertainty objects. ### `ReplacedElement.get_notes_xml(self) -> 'str | None'` Get notes xml string. ## class `RuleWithVariable()` Rule. ### `RuleWithVariable.check_model_for_rule(self, model: 'libsbml.Model') -> 'None'` Check model for rule requirements. Creates a required parameter if the symbol for the initial assignment does not exist in the model. ## class `Sbase(sid: 'str | None' = None, name: 'str | None' = None, sboTerm: 'str | None' = None, metaId: 'str | None' = None, annotations: 'OptionalAnnotationsType' = None, notes: 'str | None' = None, keyValuePairs: 'list[KeyValuePair] | None' = None, port: 'Any' = None, uncertainties: 'list[Uncertainty] | None' = None, replacedBy: 'Any | None' = None)` Base class of all SBML objects. ### `Sbase.create_key_value_pairs(self, sbase: 'libsbml.SBase') -> 'list[libsbml.KeyValuePair] | None'` Create fbc:keyValuePair. ### `Sbase.create_port(self, model: 'libsbml.Model') -> 'libsbml.Port | None'` Create port if existing. ### `Sbase.create_replaced_by(self, sbase: 'libsbml.SBase', model: 'libsbml.Model') -> 'libsbml.ReplacedBy | None'` Create comp:ReplacedBy. ### `Sbase.create_uncertainties(self, obj: 'libsbml.SBase', model: 'libsbml.Model') -> 'list[libsbml.Uncertainty] | None'` Create distrib:Uncertainty objects. ### `Sbase.get_notes_xml(self) -> 'str | None'` Get notes xml string. ## class `SbaseRef(sid: 'str', portRef: 'str | None' = None, idRef: 'str | None' = None, unitRef: 'str | None' = None, metaIdRef: 'str | None' = None, name: 'str | None' = None, sboTerm: 'str | None' = None, metaId: 'str | None' = None, annotations: 'OptionalAnnotationsType' = None, notes: 'str | None' = None, keyValuePairs: 'list[KeyValuePair] | None' = None)` SBaseRef. ### `SbaseRef.create_key_value_pairs(self, sbase: 'libsbml.SBase') -> 'list[libsbml.KeyValuePair] | None'` Create fbc:keyValuePair. ### `SbaseRef.create_port(self, model: 'libsbml.Model') -> 'libsbml.Port | None'` Create port if existing. ### `SbaseRef.create_replaced_by(self, sbase: 'libsbml.SBase', model: 'libsbml.Model') -> 'libsbml.ReplacedBy | None'` Create comp:ReplacedBy. ### `SbaseRef.create_uncertainties(self, obj: 'libsbml.SBase', model: 'libsbml.Model') -> 'list[libsbml.Uncertainty] | None'` Create distrib:Uncertainty objects. ### `SbaseRef.get_notes_xml(self) -> 'str | None'` Get notes xml string. ## class `Species(sid: 'str', compartment: 'str', initialAmount: 'float | None' = None, initialConcentration: 'float | None' = None, substanceUnit: 'UnitType' = None, hasOnlySubstanceUnits: 'bool' = False, constant: 'bool' = False, boundaryCondition: 'bool' = False, charge: 'float | None' = None, chemicalFormula: 'str | None' = None, conversionFactor: 'str | None' = None, name: 'str | None' = None, sboTerm: 'str | None' = None, metaId: 'str | None' = None, annotations: 'OptionalAnnotationsType' = None, notes: 'str | None' = None, keyValuePairs: 'list[KeyValuePair] | None' = None, port: 'Any' = None, uncertainties: 'list[Uncertainty] | None' = None, replacedBy: 'Any | None' = None)` Species. ### `Species.create_key_value_pairs(self, sbase: 'libsbml.SBase') -> 'list[libsbml.KeyValuePair] | None'` Create fbc:keyValuePair. ### `Species.create_port(self, model: 'libsbml.Model') -> 'libsbml.Port | None'` Create port if existing. ### `Species.create_replaced_by(self, sbase: 'libsbml.SBase', model: 'libsbml.Model') -> 'libsbml.ReplacedBy | None'` Create comp:ReplacedBy. ### `Species.create_sbml(self, model: 'libsbml.Model') -> 'libsbml.Species'` Create Species SBML in model. ### `Species.create_uncertainties(self, obj: 'libsbml.SBase', model: 'libsbml.Model') -> 'list[libsbml.Uncertainty] | None'` Create distrib:Uncertainty objects. ### `Species.get_notes_xml(self) -> 'str | None'` Get notes xml string. ## class `Submodel(sid: 'str', modelRef: 'str | None' = None, timeConversionFactor: 'str | None' = None, extentConversionFactor: 'str | None' = None, name: 'str | None' = None, sboTerm: 'str | None' = None, metaId: 'str | None' = None, annotations: 'OptionalAnnotationsType' = None, notes: 'str | None' = None, keyValuePairs: 'list[KeyValuePair] | None' = None)` Submodel. ### `Submodel.create_key_value_pairs(self, sbase: 'libsbml.SBase') -> 'list[libsbml.KeyValuePair] | None'` Create fbc:keyValuePair. ### `Submodel.create_port(self, model: 'libsbml.Model') -> 'libsbml.Port | None'` Create port if existing. ### `Submodel.create_replaced_by(self, sbase: 'libsbml.SBase', model: 'libsbml.Model') -> 'libsbml.ReplacedBy | None'` Create comp:ReplacedBy. ### `Submodel.create_sbml(self, model: 'libsbml.Model') -> 'libsbml.Submodel'` Create SBML Submodel. ### `Submodel.create_uncertainties(self, obj: 'libsbml.SBase', model: 'libsbml.Model') -> 'list[libsbml.Uncertainty] | None'` Create distrib:Uncertainty objects. ### `Submodel.get_notes_xml(self) -> 'str | None'` Get notes xml string. ## class `UncertParameter(type: 'str', value: 'float | None' = None, var: 'str | None' = None, unit: 'UnitType' = None)` UncertParameter. FIXME: This is an SBase! ## class `UncertSpan(type: 'str', valueLower: 'float | None' = None, varLower: 'str | None' = None, valueUpper: 'float | None' = None, varUpper: 'str | None' = None, unit: 'UnitType' = None)` UncertSpan. FIXME: This is an SBase! ## class `Uncertainty(sid: 'str | None' = None, formula: 'str | None' = None, uncertParameters: 'list[UncertParameter] | None' = None, uncertSpans: 'list[UncertSpan] | None' = None, name: 'str | None' = None, sboTerm: 'str | None' = None, metaId: 'str | None' = None, annotations: 'OptionalAnnotationsType' = None, notes: 'str | None' = None, keyValuePairs: 'list[KeyValuePair] | None' = None, port: 'Any' = None, replacedBy: 'Any | None' = None)` Uncertainty. Uncertainty information for Sbase. ### `Uncertainty.create_key_value_pairs(self, sbase: 'libsbml.SBase') -> 'list[libsbml.KeyValuePair] | None'` Create fbc:keyValuePair. ### `Uncertainty.create_port(self, model: 'libsbml.Model') -> 'libsbml.Port | None'` Create port if existing. ### `Uncertainty.create_replaced_by(self, sbase: 'libsbml.SBase', model: 'libsbml.Model') -> 'libsbml.ReplacedBy | None'` Create comp:ReplacedBy. ### `Uncertainty.create_sbml(self, sbase: 'libsbml.SBase', model: 'libsbml.Model') -> 'libsbml.Uncertainty'` Create libsbml Uncertainty. :param sbase: :param model: :return: ### `Uncertainty.create_uncertainties(self, obj: 'libsbml.SBase', model: 'libsbml.Model') -> 'list[libsbml.Uncertainty] | None'` Create distrib:Uncertainty objects. ### `Uncertainty.get_notes_xml(self) -> 'str | None'` Get notes xml string. ## class `UnitDefinition(sid: 'str', definition: 'str | None' = None, name: 'str | None' = None, sboTerm: 'str | None' = None, metaId: 'str | None' = None, annotations: 'OptionalAnnotationsType' = None, notes: 'str | None' = None, keyValuePairs: 'list[KeyValuePair] | None' = None, port: 'Any' = None, replacedBy: 'Any | None' = None)` Unit. Corresponds to the information in the libsbml.UnitDefinition. ### `UnitDefinition.create_key_value_pairs(self, sbase: 'libsbml.SBase') -> 'list[libsbml.KeyValuePair] | None'` Create fbc:keyValuePair. ### `UnitDefinition.create_port(self, model: 'libsbml.Model') -> 'libsbml.Port | None'` Create port if existing. ### `UnitDefinition.create_replaced_by(self, sbase: 'libsbml.SBase', model: 'libsbml.Model') -> 'libsbml.ReplacedBy | None'` Create comp:ReplacedBy. ### `UnitDefinition.create_sbml(self, model: 'libsbml.Model') -> 'libsbml.UnitDefinition | None'` Create libsbml.UnitDefinition. ### `UnitDefinition.create_uncertainties(self, obj: 'libsbml.SBase', model: 'libsbml.Model') -> 'list[libsbml.Uncertainty] | None'` Create distrib:Uncertainty objects. ### `UnitDefinition.get_notes_xml(self) -> 'str | None'` Get notes xml string. ### `UnitDefinition.get_uid_for_unit(unit: 'UnitDefinition | str') -> 'str | None'` Get unit id for given definition string. ## class `Units()` Base class for unit definitions. ## class `UserDefinedConstraint(lowerBound: 'str', upperBound: 'str', components: 'list[UserDefinedConstraintComponent] | dict[str, str] | None' = None, variableType: 'str' = 0, sid: 'str | None' = None, name: 'str | None' = None, sboTerm: 'str | None' = None, metaId: 'str | None' = None, annotations: 'OptionalAnnotationsType' = None, notes: 'str | None' = None, keyValuePairs: 'list[KeyValuePair] | None' = None, port: 'Any' = None, uncertainties: 'list[Uncertainty] | None' = None, replacedBy: 'Any | None' = None)` UserDefinedConstraint. The FBC UserDefinedConstraint class is derived from SBML SBase and inherits metaid and sboTerm, as well as the subcomponents for Annotation and Notes. It’s purpose is to define non-stoichiometric constraints, that is constraints that are not necessarily defined by the stoichiometrically coupled reaction network. In order to achieve, we defined a new type of linear constraint, the UserDefinedConstraint ### `UserDefinedConstraint.create_key_value_pairs(self, sbase: 'libsbml.SBase') -> 'list[libsbml.KeyValuePair] | None'` Create fbc:keyValuePair. ### `UserDefinedConstraint.create_port(self, model: 'libsbml.Model') -> 'libsbml.Port | None'` Create port if existing. ### `UserDefinedConstraint.create_replaced_by(self, sbase: 'libsbml.SBase', model: 'libsbml.Model') -> 'libsbml.ReplacedBy | None'` Create comp:ReplacedBy. ### `UserDefinedConstraint.create_sbml(self, model: 'libsbml.Model') -> 'libsbml.UserDefinedConstraint'` Create UserDefinedConstraint. ### `UserDefinedConstraint.create_uncertainties(self, obj: 'libsbml.SBase', model: 'libsbml.Model') -> 'list[libsbml.Uncertainty] | None'` Create distrib:Uncertainty objects. ### `UserDefinedConstraint.get_notes_xml(self) -> 'str | None'` Get notes xml string. ## class `UserDefinedConstraintComponent(coefficient: 'str', variable: 'str', variableType: 'str | None' = None, sid: 'str | None' = None, name: 'str | None' = None, sboTerm: 'str | None' = None, metaId: 'str | None' = None, annotations: 'OptionalAnnotationsType' = None, notes: 'str | None' = None, keyValuePairs: 'list[KeyValuePair] | None' = None, port: 'Any' = None, uncertainties: 'list[Uncertainty] | None' = None, replacedBy: 'Any | None' = None)` UserDefinedConstraintComponent. ### `UserDefinedConstraintComponent.create_key_value_pairs(self, sbase: 'libsbml.SBase') -> 'list[libsbml.KeyValuePair] | None'` Create fbc:keyValuePair. ### `UserDefinedConstraintComponent.create_port(self, model: 'libsbml.Model') -> 'libsbml.Port | None'` Create port if existing. ### `UserDefinedConstraintComponent.create_replaced_by(self, sbase: 'libsbml.SBase', model: 'libsbml.Model') -> 'libsbml.ReplacedBy | None'` Create comp:ReplacedBy. ### `UserDefinedConstraintComponent.create_sbml(self, constraint: 'libsbml.UserDefinedConstraint') -> 'libsbml.UserDefinedConstraintComponent'` Create Objective. ### `UserDefinedConstraintComponent.create_uncertainties(self, obj: 'libsbml.SBase', model: 'libsbml.Model') -> 'list[libsbml.Uncertainty] | None'` Create distrib:Uncertainty objects. ### `UserDefinedConstraintComponent.get_notes_xml(self) -> 'str | None'` Get notes xml string. ## class `Value(sid: 'str | None', value: 'str | float | None', name: 'str | None' = None, sboTerm: 'str | None' = None, metaId: 'str | None' = None, annotations: 'OptionalAnnotationsType' = None, notes: 'str | None' = None, keyValuePairs: 'list[KeyValuePair] | None' = None, port: 'Any' = None, uncertainties: 'list[Uncertainty] | None' = None, replacedBy: 'Any | None' = None)` Helper class. The value field is a helper storage field which is used differently by different subclasses. ### `Value.create_key_value_pairs(self, sbase: 'libsbml.SBase') -> 'list[libsbml.KeyValuePair] | None'` Create fbc:keyValuePair. ### `Value.create_port(self, model: 'libsbml.Model') -> 'libsbml.Port | None'` Create port if existing. ### `Value.create_replaced_by(self, sbase: 'libsbml.SBase', model: 'libsbml.Model') -> 'libsbml.ReplacedBy | None'` Create comp:ReplacedBy. ### `Value.create_uncertainties(self, obj: 'libsbml.SBase', model: 'libsbml.Model') -> 'list[libsbml.Uncertainty] | None'` Create distrib:Uncertainty objects. ### `Value.get_notes_xml(self) -> 'str | None'` Get notes xml string. ## class `ValueWithUnit(sid: 'str', value: 'str | float | None', unit: 'UnitType' = , name: 'str | None' = None, sboTerm: 'str | None' = None, metaId: 'str | None' = None, annotations: 'OptionalAnnotationsType' = None, notes: 'str | None' = None, keyValuePairs: 'list[KeyValuePair] | None' = None, port: 'Any' = None, uncertainties: 'list[Uncertainty] | None' = None, replacedBy: 'Any | None' = None)` Helper class. The value field is a helper storage field which is used differently by different subclasses. ### `ValueWithUnit.create_key_value_pairs(self, sbase: 'libsbml.SBase') -> 'list[libsbml.KeyValuePair] | None'` Create fbc:keyValuePair. ### `ValueWithUnit.create_port(self, model: 'libsbml.Model') -> 'libsbml.Port | None'` Create port if existing. ### `ValueWithUnit.create_replaced_by(self, sbase: 'libsbml.SBase', model: 'libsbml.Model') -> 'libsbml.ReplacedBy | None'` Create comp:ReplacedBy. ### `ValueWithUnit.create_uncertainties(self, obj: 'libsbml.SBase', model: 'libsbml.Model') -> 'list[libsbml.Uncertainty] | None'` Create distrib:Uncertainty objects. ### `ValueWithUnit.get_notes_xml(self) -> 'str | None'` Get notes xml string. ## function `ast_node_from_formula(model: 'libsbml.Model', formula: 'str') -> 'libsbml.ASTNode'` Parse the ASTNode from given formula string with model. :param model: SBMLModel instance :param formula: formula str :return: astnode ## function `create_model(model: 'Model | Iterable[Model]', filepath: 'Path', sbml_level: 'int' = 3, sbml_version: 'int' = 1, validate: 'bool' = True, validation_options: 'ValidationOptions | None' = None, show_sbml: 'bool' = False, annotations: 'Path | None' = None, create_antimony: 'bool' = False, create_markdown: 'bool' = False) -> 'FactoryResult'` Create SBML model from models. This is the entry point for creating models. If multiple models are provided these are merged in the process of model creation. See `merge_models` for more details. Additional model annotations can be provided via a file. The created SBML can be serialized to additional formats for inspection, which are written next to the SBML file: the antimony serialization of the model (`create_antimony`, `*.ant`) and the markdown overview of the ODE system (`create_markdown`, `*.md`, see `sbmlutils.converters.odefac`). :param model: Model or iterable of Model instances which are merged in single model :param filepath: Path to write the SBML model to :param sbml_level: set SBML level for model generation :param sbml_version: set SBML version for model generation :param validate: boolean flag to validate the SBML file :param validation_options: options for model validation :param show_sbml: boolean flag to show SBML :param annotations: Path to annotations file :param create_antimony: write the antimony serialization to `*.ant` :param create_markdown: write the markdown overview of the ODE system to `*.md` :return: FactoryResult ## function `create_objects(model: 'libsbml.Model', obj_iter: 'list[Any]', key: 'str | None' = None) -> 'dict[str, libsbml.SBase]'` Create the objects in the model. This function calls the respective create_sbml function of all objects in the order of the objects. :param model: SBMLModel instance :param obj_iter: iterator of given model object classes like Parameter, ... :param key: object key :return: dictionary of SBML objects ## function `date_now() -> 'libsbml.Date'` Get current time stamp for history. :return: current libsbml Date ## function `set_model_history(sbase: 'libsbml.SBase', creators: 'list[Creator]', set_timestamps: 'bool' = True) -> 'None'` Set the model history from given creators. :param sbase: SBML model :param creators: list of creators :param set_timestamps: boolean flag to set timestamps on history. :return: ## function `set_notes(sbase: 'libsbml.SBase', notes: 'str', format: 'NotesFormat' = ) -> 'None'` Set notes information on SBase. :param sbase: SBase :param notes: notes information (xml string) :return: --- # sbmlutils.io Helper functions for input/output (IO). --- # sbmlutils.validation Helpers for validation and checking of SBML and libsbml operations. ## class `ValidationOptions(log_errors: bool = True, internal_consistency: bool = True, general_consistency: bool = True, identifier_consistency: bool = True, mathml_consistency: bool = True, units_consistency: bool = True, sbo_consistency: bool = True, overdetermined_model: bool = True, modeling_practice: bool = True) -> None` Options for SBML validator. Controls the consistency checks that are performed when SBMLDocument.checkConsistency() is called. * `general_consistency`: Correctness and consistency of specific SBML language constructs. Performing this set of checks is highly recommended. With respect to the SBML specification, these concern failures in applying the validation rules numbered 2xxxx in the Level 2 Versions 2-4 and Level 3 Versions 1-2 specifications. * `ìdentifier_consistency`: Correctness and consistency of identifiers used for model entities. An example of inconsistency would be using a species identifier in a reaction rate formula without first having declared the species. With respect to the SBML specification, these concern failures in applying the validation rules numbered 103xx in the Level 2 Versions 2-4 and Level 3 Versions 1-2 specifications. * `units_consistency`: Consistency of measurement units associated with quantities in a model. With respect to the SBML specification, these concern failures in applying the validation rules numbered 105xx in the Level 2 Versions 2-4 and Level 3 Versions 1-2 specifications. * `mathml_consistency`: Syntax of MathML constructs. With respect to the SBML specification, these concern failures in applying the validation rules numbered 102xx in the Level 2 Versions 2-4 and Level 3 Versions 1-2 specifications. * `sbo_consistency`: Consistency and validity of SBO identifiers (if any) used in the model. With respect to the SBML specification, these concern failures in applying the validation rules numbered 107xx in the Level 2 Versions 2-4 and Level 3 Versions 1-2 specifications. * `overdetermined_model`: Static analysis of whether the system of equations implied by a model is mathematically overdetermined. With respect to the SBML specification, this is validation rule #10601 in the Level 2 Versions 2-4 and Level 3 Versions 1-2 specifications. * `modeling_practise`: Additional checks for recommended good modeling practice. (These are tests performed by libSBML and do not have equivalent SBML validation rules.) By default, all validation checks are applied to the model in an SBMLDocument object unless SBMLDocument.setConsistencyChecks() is called to indicate that only a subset should be applied. Further, this default (i.e., performing all checks) applies separately to each new SBMLDocument object created. In other words, each time a model is read using SBMLReader.readSBML(), SBMLReader.readSBMLFromString(), or the global functions readSBML() and readSBMLFromString(), a new SBMLDocument is created and for that document, a call to SBMLDocument.checkConsistency() will default to applying all possible checks. Calling programs must invoke SBMLDocument.setConsistencyChecks() for each such new model if they wish to change the consistency checks applied. * `internal_consistency`: Additional checks that model is consistent XML. * `log_errors` Boolean flag to log errors. ## class `ValidationResult(errors: list[libsbml.SBMLError] | None = None, warnings: list[libsbml.SBMLError] | None = None)` Results of an SBMLDocument validation. ### `ValidationResult.from_results(results: collections.abc.Iterable['ValidationResult']) -> 'ValidationResult'` Parse from ValidationResult. ### `ValidationResult.is_perfect(self) -> bool` Get perfect status (perfect model), i.e., no errors and warnings. ### `ValidationResult.is_valid(self) -> bool` Get valid status (valid model), i.e., no errors. ### `ValidationResult.log(self) -> None` Log errors and warnings. ## function `check(value: int, message: str) -> bool` Check the libsbml return value and prints message if something happened. If 'value' is None, prints an error message constructed using 'message' and then exits with status code 1. If 'value' is an integer, it assumes it is a libSBML return status code. If the code value is LIBSBML_OPERATION_SUCCESS, returns without further action; if it is not, prints an error message constructed using 'message' along with text from libSBML explaining the meaning of the code, and exits with status code 1. ## function `error_string(error: libsbml.SBMLError, index: int | None = None) -> tuple` Get string representation and severity of SBMLError. ## function `log_sbml_error(error: libsbml.SBMLError, index: int | None = None) -> None` Log SBMLError. ## function `log_sbml_errors_for_doc(doc: libsbml.SBMLDocument) -> None` Log errors of current SBMLDocument. ## function `validate_doc(doc: libsbml.SBMLDocument, options: sbmlutils.validation.ValidationOptions | None = None, title: str | None = None) -> sbmlutils.validation.ValidationResult` Validate SBMLDocument. :param doc: SBMLDocument to check :param title: identifier or path for validation report :param options: validation options and settings. :return: ValidationResult --- # sbmlutils.parser Parse Models in internal model format. FIXME: no support for notes FIXME: no support for modelHistory ## function `antimony_to_model(source: pathlib.Path | str, validate: bool = False, promote: bool = False, validation_options: sbmlutils.validation.ValidationOptions | None = None) -> sbmlutils.factory.Model` Parse antimony model. ## function `antimony_to_sbml(source: pathlib.Path | str) -> str` Parse antimony model to SBML string. ## function `sbml_to_model(source: pathlib.Path | str, validate: bool = False, promote: bool = False, validation_options: sbmlutils.validation.ValidationOptions | None = None) -> sbmlutils.factory.Model` Parse SBML model. --- # sbmlutils.notes Module for notes. Notes can be either written in markdown or HTML. Markdown -> HTML conversion is performed using `markdown-it-py` for the conversion. No styles for the display are inserted here. ## class `Notes(notes: str, format: sbmlutils.notes.NotesFormat = )` SBML notes. ## class `NotesFormat(*values)` Supported formats for Notes. --- # sbmlutils.reaction_equation Module for parsing reaction equation strings. Various string formats are allowed which are subsequently brought into an internal standard format. Equations are of the form '1.0 S1 + 2 S2 => 2.0 P1 + 2 P2 [M1, M2]' The equation consists of - substrates concatenated via '+' on the left side (with optional stoichiometric coefficients) - separation characters separating the left and right equation sides: '<=>' or '<->' for reversible reactions, '=>' or '->' for irreversible reactions (irreversible reactions are written from left to right) - products concatenated via '+' on the right side (with optional stoichiometric coefficients) - optional list of modifiers within brackets [] separated by ',' Examples of valid equations are: '1.0 S1 + 2 S2 => 2.0 P1 + 2 P2 [M1, M2]', 'c__gal1p => c__gal + c__phos', 'e__h2oM <-> c__h2oM', '3 atp + 2.0 phos + ki <-> 16.98 tet', 'c__gal1p => c__gal + c__phos [c__udp, c__utp]', 'A_ext => A []', '=> cit', 'acoa =>', In addition, variable stoichiometries can be used, by providing sids as stoichiometries. Examples of valid equations with variable stoichiometries are: 'fS1 S1 + 2 S2 => 2.0 P1 + 2 P2 [M1, M2]', 'f1 c__gal1p => f1 c__gal + f1 c__phos', 'f1 * e__h2oM <-> f1 * c__h2oM', '3 atp + 2.0 phos + ki <-> stet tet', 'f * c__gal1p => f * c__gal + f * c__phos [c__udp, c__utp]', 'A_ext => f * A []', '=> f * cit', 'f * acoa =>', ## class `EquationPart(species: 'str', stoichiometry: 'float | None' = None, sid: 'str | None' = None, constant: 'bool' = True, metaId: 'str | None' = None, sboTerm: 'str | None' = None, name: 'str | None' = None, annotations: 'list | None' = None, notes: 'str | None' = None, keyValuePairs: 'list[Any] | None' = None) -> None` EquationPart. # FIXME: this must be a SpeciesReference, but circular imports! An equation consists of parts which define species with their respective stoichiometries. The stoichiometries could be constant or vary over time. The sid may be target of an InitialAssignment, EventAssignment or Rule. Two main cases exists: 1. `stoichiometry=float, constant=True` The EquationPart has a constant stoichiometry and does not change in the simulation. It could be set via an InitialAssignment if an sid is provided. 2. `stoichiometry=None, constant=False, sid=str` ## class `ReactionEquation(reactants: 'list[EquationPart] | None' = None, products: 'list[EquationPart] | None' = None, modifiers: 'list[str] | None' = None, reversible: 'bool' = True)` Representation of stoichiometric equations with modifiers. ### `ReactionEquation.EquationException` Exception in Equation. ### `ReactionEquation.from_str(equation_str: 'str') -> 'ReactionEquation'` Parse components of equation string. ### `ReactionEquation.help() -> 'str'` Get help information string. ### `ReactionEquation.info(self) -> 'None'` Print overview of parsed equation. ### `ReactionEquation.to_string(self, modifiers: 'bool' = False) -> 'str'` Get string representation of equation. --- # sbmlutils.biomodels Utilities for downloading biomodel models. The downloads go through the shared session of [pymetadata](https://matthiaskoenig.github.io/pymetadata/api/webservices.webservice/), which retries the transient error responses (429, 500, 502, 503, 504) with an exponential backoff and times out after 30 seconds, so a single hiccup of the BioModels service does not fail a download. ## function `download_biomodel_omex(biomodel_id: str, omex_path: pathlib.Path) -> pathlib.Path` Download omex for biomodel id. This downloads the latest version of the OMEX from biomodels via the rest service. :returns: path to omex Raises :class:`HTTPError`, if one occurred, i.e. if the model does not exist. ## function `download_biomodel_sbml(biomodel_id: str, output_dir: pathlib.Path, output_format: str = 'sbml') -> list[str]` Download SBML file for biomodel. Retrieves the archive from biomodels and gets the SBML files from it. Stores the raw SBML files for output_format='sbml' or creates an OMEX archive in case of output_format='omex'. :param output_format: 'sbml' or 'omex' :return: list of location strings Raises :class:`HTTPError`, if one occurred, i.e. if the model does not exist. Raises :class:`ValueError`, if invalid format string is provided. ## function `download_file(url: str, path: pathlib.Path) -> pathlib.Path` Download a file. A transient error response is retried, see the module documentation. Args: url: url to download from path: file the content is written to Returns: The path the content was written to. Raises: HTTPError: if the server answered with an error status RequestException: if the server could not be reached ## function `query_curated_biomodels() -> list[str]` Query the identifiers of the curated biomodels. A transient error response is retried, see the module documentation. Returns: The sorted identifiers of the manually curated models. Raises: HTTPError: if the server answered with an error status RequestException: if the server could not be reached --- # sbmlutils.cytoscape Module for visualization in Cytoscape. Supports loading of networks, annotations and storing of images. The visualization talks to a running [Cytoscape](https://cytoscape.org) through [py4cytoscape](https://py4cytoscape.readthedocs.io), which is the optional `cytoscape` extra (`pip install sbmlutils[cytoscape]`). Without it, and without a running Cytoscape, the functions log a warning and do nothing instead of raising, so a model creation script which visualizes at the end still finishes. ## class `AnnotationBoundedText(type: sbmlutils.cytoscape.AnnotationShapeType, text: str, x_pos: int, y_pos: int, height: int, width: int, fill_color: str = '#000000', opacity: int = 100, border_thickness: int = 1, border_color: str = '#FFFFFF', border_opacity: int = 100, font_size: int = 12, font_family: str = 'Arial', font_style: str = 'bold', color: str = '#000000', angle: float = 0, canvas: str = 'background') -> None` Text annotation inside a shape on the cytoscape canvas. ## class `AnnotationShape(type: sbmlutils.cytoscape.AnnotationShapeType, x_pos: int, y_pos: int, height: int, width: int, fill_color: str = '#000000', opacity: int = 100, border_thickness: int = 1, border_color: str = '#FFFFFF', border_opacity: int = 100, canvas: str = 'background', z_order: int = 0) -> None` Shape annotation on the cytoscape canvas. ## class `AnnotationShapeType(*values)` Shape of an annotation on the cytoscape canvas. ## class `AnnotationText(text: str, x_pos: int, y_pos: int, font_size: int = 12, font_family: str = 'Arial', font_style: str = 'bold', color: str = '#000000', angle: float = 0, canvas: str = 'background') -> None` Text annotation on the cytoscape canvas. ## function `add_annotations(annotations: collections.abc.Iterable, network: int | None = None) -> None` Add annotations to the network. ## function `apply_layout(layout: pandas.core.frame.DataFrame, network: int | None = None) -> None` Apply layout information from Cytoscape to SBML networks. ## function `export_image(image_path: pathlib.Path, format: str = 'PNG', fit_content: bool = False, hide_labels: bool = False) -> None` Helper for exporting cytoscape images. format (str): Type of image to export, e.g., PNG (default), JPEG, PDF, SVG, PS (PostScript). ## function `read_layout_xml(sbml_path: pathlib.Path, xml_path: pathlib.Path) -> pandas.core.frame.DataFrame` Read own xml layout information form cytoscape. ## function `visualize_antimony(source: pathlib.Path | str, delete_session: bool = False) -> Any` Visualize antimony in cytoscape. ## function `visualize_sbml(sbml_path: pathlib.Path, delete_session: bool = False) -> int | None` Visualize SBML networks in cytoscape. Returns dictionary with "networks" and "views". --- # sbmlutils.console Shared rich console. The console is used for the output of scripts and examples; library code logs instead of printing, see `sbmlutils.log`. ```python from sbmlutils.console import console console.print(model) console.rule("Section", style="white") ``` Importing this module has no side effects on the interpreter. To get rich representations in an interactive session, install them explicitly with `rich.pretty.install()`. --- # sbmlutils.log Logging of the package. `sbmlutils` follows the convention for libraries: it only gets loggers and logs to them, it does not configure logging. Handlers, levels and formatting are left to the application, which keeps the messages of the package under the control of whoever uses it. Modules get their logger from the standard library with ```python import logging logger = logging.getLogger(__name__) ``` All loggers are therefore below the `sbmlutils` logger, so an application configures them in one place: ```python import logging logging.getLogger("sbmlutils").setLevel(logging.WARNING) ``` For scripts and interactive work the rich formatting of the package can be enabled explicitly, which is what the examples do: ```python from sbmlutils import log log.enable_rich_logging() ``` ## function `enable_rich_logging(level: int = 20, console: rich.console.Console | None = None) -> logging.Logger` Log the messages of the package on a rich console. This configures logging and is meant for scripts, examples and interactive work. Applications should configure logging themselves instead of calling this. Calling it repeatedly replaces the handler instead of adding a second one. Args: level: level from which messages are logged console: console to log on, the console of the package by default Returns: The `sbmlutils` logger. --- # sbmlutils.utils Utility functions. ## class `FrozenClass()` FrozenClass. After freezing no additional attributes can be added. ## function `create_hash_id(sbase: libsbml.SBase) -> str` Create hash code. ## function `create_metaid(sbase: libsbml.SBase) -> str` Create a globally unique meta id. Meta ids are required to store annotations on elements. --- # sbmlutils.comp.comp Utilities for the creation and work with comp models. Simplifies the port linking, submodel generation, ... Heavily used in the dynamic FBA simulator. Mainly in the model creation process. But the flattening parts also during the simulation of the dynamic FBA models. ## function `add_submodel_from_emd(model_comp: libsbml.CompModelPlugin, submodel_id: str, emd: libsbml.ExternalModelDefinition) -> libsbml.Submodel` Add submodel to the model from given ExternalModelDefinition. :param model_comp: Model comp plugin :param submodel_id: :param emd: :return: ## function `create_ExternalModelDefinition(doc_comp: libsbml.CompSBMLDocumentPlugin, emd_id: str, source: str) -> libsbml.ExternalModelDefinition` Create comp ExternalModelDefinition. :param doc_comp: SBMLDocument comp plugin :param emd_id: id of external model definition :param source: source :return: ## function `create_ports(model: libsbml.Model, portRefs: Any | None = None, idRefs: Any | None = None, unitRefs: Any | None = None, metaIdRefs: Any | None = None, portType: sbmlutils.factory.PortType = , suffix: str = '_port') -> list[libsbml.Port]` Create ports for given model. Helper function to create port creation. :param model: SBML model :param portRefs: dict of the form {pid:portRef} :param idRefs: dict of the form {pid:idRef} :param unitRefs: dict of the form {pid:unitRef} :param metaIdRefs: dict of the form {pid:metaIdRef} :param portType: type of port :param suffix: suffix to use in port generation :return: ## function `get_submodel_frameworks(doc: libsbml.SBMLDocument) -> dict[str, typing.Any]` Read the SBO terms of the submodels. These are used to distinguish the different frameworks of the submodels. :param doc: SBMLDocument :return: ## function `replace_element_in_submodels(model: libsbml.Model, sid: str, ref_type: str, submodels: list[str]) -> None` Replace elements submodels with the identical id. For instance to replace all the units in the submodels. :param model: :param sid: :param ref_type: :param submodels: :return: ## function `replace_elements(model: libsbml.Model, sid: str, ref_type: str, replaced_elements: dict[str, list[str]]) -> None` Replace elements in comp. :param model: :param sid: :param ref_type: :param replaced_elements: :return: ## function `replaced_by(model: libsbml.Model, sid: str, ref_type: str, submodel: str, replaced_by: str) -> libsbml.ReplacedBy` Create a ReplacedBy element. The element with sid in the model is replaced by the replacing_id in the submodel with submodel_id. --- # sbmlutils.comp.flatten Helpers for model flattening. ## function `flatten_external_model_definitions(doc: libsbml.SBMLDocument, validate: bool = False) -> libsbml.SBMLDocument` Convert all ExternalModelDefinitions to ModelDefinitions. I.e. the definition of models in external files are read and directly included in the top model. The resulting comp model consists than only of a single file. The model refs in the submodel do not change in the process, so no need to update the submodels. :param doc: SBMLDocument :param validate: validation flag :return: SBMLDocument with ExternalModelDefinitions replaced ## function `flatten_sbml(sbml_path: pathlib.Path, sbml_flat_path: pathlib.Path, leave_ports: bool = True) -> libsbml.SBMLDocument` Flatten given SBML file. :param sbml_path: input path to SBML file to flatten (should be a comp model) :param sbml_flat_path: output path for flat SBML :param leave_ports: boolean flag to leave ports in flattened model. :return: flattened SBMLDocument ## function `flatten_sbml_doc(doc: libsbml.SBMLDocument, sbml_flat_path: pathlib.Path | None = None, leave_ports: bool = True) -> libsbml.SBMLDocument` Flatten SBMLDocument. Validation should be performed before the flattening and is not part of the flattening routine. If an output path is provided the file is written to the output path. :param doc: SBMLDocument to flatten. :param sbml_flat_path: Path to write flattended SBMLDocument to :param leave_ports: flag to leave ports :return: SBMLDocument --- # sbmlutils.converters.odefac Convert SBML models to ODE systems for various programming languages. This allows easy integration with existing workflows by rendering respective code templates. Currently supported code generation: - python: scipy - R: desolve - R: dmod The following SBML core constructs are currently NOT supported: - ConversionFactors - FunctionDefinitions - InitialAssignments - Events - Piecewise functions - Dynamical changing compartments - Species with AssignmentRules ## class `SBML2ODE(doc: 'libsbml.SBMLDocument')` SBML to ODE converter. Writes out python or R ODE files which can be solved with standard integrators like scipy odeint or R desolve. ### `SBML2ODE.dependency_graph(y: 'dict[str, libsbml.ASTNode | str]', filtered_ids: 'set[str]') -> 'dict[str, set]'` Create dependency graph from given dictionary. :param y: { variable: astnode } dictionary :param filtered_ids: ids which are defined elsewhere and not part of dependency tree :return: ### `SBML2ODE.info(self) -> 'None'` Print information on ODE system to console. ### `SBML2ODE.to_R(self, r_file: 'Path | None' = None) -> 'str'` Write ODEs to R. ### `SBML2ODE.to_custom_template(self, template_file: 'Path', output_file: 'Path | None' = None) -> 'str'` Write ODEs to custom template. ### `SBML2ODE.to_julia(self, jl_file: 'Path | None' = None) -> 'str'` Write ODEs to julia. Generated files can be used as an input for DifferentialEquations.jl https://docs.sciml.ai/DiffEqDocs/stable/ ### `SBML2ODE.to_markdown(self, md_file: 'Path | None' = None) -> 'str'` Write ODEs to markdown. ### `SBML2ODE.to_python(self, py_file: 'Path | None' = None) -> 'str'` Write ODEs to python. ### `SBML2ODE.to_tex(self, tex_file: 'Path | None' = None) -> 'str'` Write ODEs to tex/latex. --- # sbmlutils.converters.xpp XPP ode to SBML file converter. XPP file format is described here http://www.math.pitt.edu/~bard/bardware/tut/newstyle.html Every ODE file consists of a series of lines that start with a keyword followed by numbers, names, and formulas or declare a named formula such as a differential equation or auxiliary quantity. Only the first letter of the keyword is important; e.g. the parser treats "parameter" and "punxatawney" exactly the same. The parser can understand lines up to 256 characters. You can use line continuation by adding a backslash character. The first line of the file cannot be a number (as this tells XPP that the file is in the old-style) but can be any other charcter or declaration. It is standard form to make the first line a comment which has the name of the file, but this is optional. ! Variables have to be case sensitive !. These issues can easily be fixed based on validator output. Only supports subset of features. Not supported: - table - sum, - shift - set - boundary - ran - arrays shift(var,expr) This operator evaluates the expression expr converts it to an integer and then uses this to indirectly address a variable whose address is that of var plus the integer value of the expression. This is a way to imitate arrays in XPP. For example if you defined the sequence of 5 variables, u0,u1,u2,u3,u4 one right after another, then shift(u0,2) would return the value of u2. sum(ex1,ex2)of(ex3) is a way of summing up things. The expressions ex1>, are evaluated and their integer parts are used as the lower and upper limits of the sum. The index of the sum is i' so that you cannot have double sums since there is only one index. ex3 is the expression to be summed and will generally involve i' For example sum(1,10)of(i') will be evaluated to 55. Another example combines the sum with the shift operator. sum(0,4)of(shift(u0,i')) will sum up u0 and the next four variables that were defined after it. ## function `escape_string(info: str) -> str` Escape string. ## function `parse_keyword(xpp_id: str) -> str | None` Parse the keyword and returns the xpp keyword type. :param xpp_id: :return: ## function `parts_from_expression(expression: str) -> list[str]` Return the parts of given expression. The parts can be whitespace or comma separated. V1=-0.75 R1=0.26 CA1=0.1 H1=0.1 V1=-0.75, R1=0.26, CA1=0.1, H1=0.1 but there can also be commas in function definitions vex=vex(t,freq,vext) :return: list of cleaned parts ## function `sid_value_from_part(part: str) -> tuple[str, str]` Get sid, value tuple from given part of expression. :param part: :return: ## function `xpp2sbml(xpp_file: pathlib.Path, sbml_file: pathlib.Path, force_lower: bool = False, validate: bool = True, debug: bool = False) -> libsbml.SBMLDocument` Read given xpp_file and converts to SBML file. :param debug: :param xpp_file: xpp input ode file :param sbml_file: sbml output file :param force_lower: force lower case for all lines :param validate: perform validation on the generated SBML file :return: --- # sbmlutils.converters.copasi Helpers to work with COPASI files. ## function `write_ids_to_names(input_path: pathlib.Path, output_path: pathlib.Path) -> None` Write SBML ids as names. --- # sbmlutils.converters.mathml Helper functions for evaluation of mathml expressions. In this namespace all the possible names occuring in formula strings have to be defined. In build in python are *, /, +, - and, or, not ## function `evaluableMathML(astnode: libsbml.ASTNode, variables: dict | None = None) -> str` Create evaluable python formula string from ASTNode. ## function `evaluateMathML(astnode: libsbml.ASTNode, variables: dict | None = None) -> Any` Evaluate MathML string with given set of variable and parameter values. :param astnode: astnode of MathML string :param variables: dictionary of var : value :return: value of evaluated MathML ## function `piecewise(*args: float) -> float` Piecewise calculation. ## function `product(*args: float) -> float` Product calculation. ## function `root(a: float, b: float) -> float` Root calculation. ## function `sqr(x: float) -> float` Square calculation. ## function `xor(*args: float) -> int` XOR calculation. --- # sbmlutils.data.interpolation Create files for interpolation of datasets. https://github.com/allyhume/SBMLDataTools https://github.com/allyhume/SBMLDataTools.git TODO: fix composition with existing models TODO: support coupling with existing models via comp The functionality is very useful, but only if this can be applied to existing models in a simple manner. ## class `Interpolation(data: 'pd.DataFrame', method: 'str' = 'linear')` Create SBML model which interpolates the given data. The second to last components are interpolated against the first component. ### `Interpolation.add_interpolator_to_model(interpolator: 'Interpolator', model: 'libsbml.Model') -> 'None'` Add interpolator to model. The parameters, formulas and rules have to be added to the SBML model. :param interpolator: :param model: Model :return: ### `Interpolation.create_interpolators(data: 'pd.DataFrame', method: 'str') -> 'list[Interpolator]'` Create all interpolators for the given data set. The columns 1, ... (Ncol-1) are interpolated against column 0. ### `Interpolation.from_csv(csv_file: 'Path | str', method: 'str' = 'linear', sep: 'str' = ',') -> 'Interpolation'` Interpolation object from csv file. ### `Interpolation.from_tsv(tsv_file: 'Path | str', method: 'str' = 'linear') -> 'Interpolation'` Interpolate object from tsv file. ### `Interpolation.validate_data(self) -> 'None'` Validate the input data. * The data is expected to have at least 2 columns. * The data is expected to have at least three data rows. * The first column should be in ascending order. :return: :rtype: ### `Interpolation.write_sbml_to_file(self, sbml_out: 'Path') -> 'None'` Write the SBML file. :param sbml_out: Path to SBML file :return: ### `Interpolation.write_sbml_to_string(self) -> 'str | None'` Write the SBML file. :return: SBML str ## class `Interpolator(x: 'pd.Series', y: 'pd.Series', method: 'str' = 'constant')` Interpolator class handles the 2D interpolation of given data series. Two data series and the type of interpolation are provided. ### `Interpolator.formula(self) -> 'str'` Get formula string. --- # sbmlutils.fbc.fbc Helper functions for working with FBC and cobrapy models. ## function `add_default_flux_bounds(doc: libsbml.SBMLDocument, lower: float = -100.0, upper: float = 100.0) -> None` Add default flux bounds to SBMLDocument. :param doc: SBMLDocument :param lower: lower flux bound :param upper: upper flux bound :return: ## function `set_boundary_conditions_false(doc: libsbml.SBMLDocument) -> None` Set all boundaryConditions to False in the model. ## function `set_flux_bounds(reaction: libsbml.Reaction, lb: float, ub: float) -> None` Set flux bounds on given reaction. --- # sbmlutils.fbc.cobra cobrapy based helper methods. cobrapy is not a dependency of sbmlutils, it is the optional `cobra` extra (`pip install sbmlutils[cobra]`). `cobra` is `None` when it is not installed, which is what the tests of this module skip on. ## function `check_mass_balance(sbml_path: pathlib.Path) -> dict[str, typing.Any]` Check mass and charge balance of the model. Args: sbml_path: path of the SBML model Returns: The unbalanced reactions, keyed by reaction id. ## function `cobra_reaction_info(cobra_model: 'cobra.core.Model') -> pandas.core.frame.DataFrame` Create data frame with bound and objective information. :param cobra_model: :return: pandas DataFrame ## function `read_cobra_model(sbml_path: pathlib.Path) -> 'cobra.core.Model'` Load cobra model from path. Sets default flux bounds to allow loading and changes all boundaryConditions to False. :param sbml_path: str path :return: cobra model --- # sbmlutils.layout.layout Utilities for the creation and work with layout models. ## class `CompartmentGlyph(sid: str, compartment: str, x: float, y: float, z: float = 0, w: float = 200, h: float = 200, d: float = 0, text: str | None = None, name: str | None = None, sboTerm: str | None = None, metaId: str | None = None)` CompartmentGlyph. ## class `Layout(sid: str, width: float, height: float, compartment_glyphs: list[sbmlutils.layout.layout.CompartmentGlyph] | None = None, species_glyphs: list[sbmlutils.layout.layout.SpeciesGlyph] | None = None, reaction_glyphs: list[sbmlutils.layout.layout.ReactionGlyph] | None = None, depth: int = 0, name: str | None = None, sboTerm: str | None = None, metaId: str | None = None)` Layout. ### `Layout.create_sbml(self, model: libsbml.Model) -> libsbml.Layout` Create SBML in model. ## class `ReactionGlyph(sid: str, reaction: str, x: float, y: float, z: float = 0, species_glyphs: dict[str, str] | None = None, w: float = 20, h: float = 20, d: float = 0, text: str | None = None, name: str | None = None, sboTerm: str | None = None, metaId: str | None = None)` ReactionGlyph. ## class `SpeciesGlyph(sid: str, species: str, x: float, y: float, z: float = 0, w: float = 50, h: float = 20, d: float = 0, text: str | None = None, name: str | None = None, sboTerm: str | None = None, metaId: str | None = None)` SpeciesGlyph. --- # sbmlutils.manipulation.merge Merging of SBML models. The following is a helper function for merging multiple SBML models into a single model. ## function `merge_models(model_paths: dict[str, pathlib.Path], output_dir: pathlib.Path, merged_id: str = 'merged', flatten: bool = True, validate: bool = True, validate_input: bool = True, validation_options: sbmlutils.validation.ValidationOptions | None = None, sbml_level: int = 3, sbml_version: int = 1) -> libsbml.SBMLDocument` Merge SBML models. Merges SBML models given in `model_paths` in the `output_dir`. Models are provided as dictionary { 'model1_id': model1_path, 'model2_id': model2_path, ... } The model ids are used as ids for the ExternalModelDefinitions. Relative paths are set in the merged models. The created model is either in SBML L3V1 (default) or SBML L3V2. :param model_paths: absolute paths to models :param output_dir: output directory for merged model :param merged_id: model id of the merged model :param flatten: flattens the merged model :param validate: boolean flag to validate the merged model :param validate_input: boolean flag to validate the input models :param validation_options: ValidationOptions :param sbml_level: SBML Level of the merged model in [3] :param sbml_version: SBML Version of the merged model in [1, 2] :return: SBMLDocument of the merged models --- # sbmlutils.metadata.annotator Annotation of SBML models. Handle the XML annotations and notes in SBML. Annotate models from information in annotation csv files. Thereby a model can be fully annotated from information stored in a separate annotation store. Annotation is performed via searching for ontology terms which describe the model and model components. A standard workflow is looking up the components for instance in things like OLS ontology lookup service. ## class `ExternalAnnotation(d: dict[str, typing.Any])` Class for handling SBML annotations defined in external source. This corresponds to a single entry in the external annotation file. Allows to handle more complex annotation scenarios, e.g. patterns for identifiers. The columns are: pattern sbml_type annotation_type qualifier resource name ### `ExternalAnnotation.check(self) -> None` Check for valid choices. :raise: ValueError ## class `ModelAnnotator(doc: libsbml.SBMLDocument, annotations: collections.abc.Iterable[sbmlutils.metadata.annotator.ExternalAnnotation])` Helper class for annotating SBML models. ### `ModelAnnotator.annotate_model(self) -> None` Annotate the model with the given annotations. ### `ModelAnnotator.annotate_sbase(sbase: libsbml.SBase, annotation: pymetadata.core.annotation.RDFAnnotation) -> None` Annotate SBase based on given annotation data. :param sbase: libsbml.SBase :param annotation: Annotation :return: ### `ModelAnnotator.get_SBMLQualifier(qualifier_str: str, qualifier_type: str) -> str` Lookup of SBMLQualifier for given qualifier string. :param qualifier_type: BQB or BQM :return: SBML qualifier string ### `ModelAnnotator.read_annotations(file_path: pathlib.Path, file_format: str = '*') -> list[sbmlutils.metadata.annotator.ExternalAnnotation]` Read annotations from given file into DataFrame. Supports "xlsx", "tsv", "csv", "json", "*" :param file_path: either path to file, or data in dict format :param file_format: annotation file format :return: list of annotation objects ### `ModelAnnotator.read_annotations_df(file_path: pathlib.Path, file_format: str = '*') -> pandas.core.frame.DataFrame` Read annotations from given file into DataFrame. Supports "xlsx", "tsv", "csv", "json", "*" :param file_path: either path to file, or data in dict format :param file_format: annotation file format :return: pandas.DataFrame ## function `annotate_sbml(source: pathlib.Path | str, annotations_path: pathlib.Path, filepath: pathlib.Path) -> libsbml.SBMLDocument` Annotate a given SBML file with the provided annotations. :param source: SBML to annotation :param annotations_path: external file with annotations :param filepath: annotated SBML file :return: annotated SBMLDocument ## function `annotate_sbml_doc(doc: libsbml.SBMLDocument, external_annotations: list['ExternalAnnotation']) -> libsbml.SBMLDocument` Annotates given SBML document using the annotations file. :param doc: SBMLDocument :param external_annotations: ModelAnnotations :return: annotated SBMLDocument --- # sbmlutils.metadata.validator Validation of the annotations of a model against the registry. ## function `validate_sbml_annotations(source: pathlib.Path | str) -> pandas.core.frame.DataFrame` Validate annotations in a given SBML file. :param source: SBML to check :return: DataFrame of invalid annotations --- # sbmlutils.metadata.miriam MIRIAM qualifiers of libsbml. libsbml reports the qualifier of a `CVTerm` as an integer, these maps resolve the integers to the names of the qualifiers. The qualifiers used to annotate a model are `BQB` and `BQM`, see `sbmlutils.metadata`. --- # sbmlutils.report.sbmlinfo Creates dictionary of information for given model. The model dictionary can be used for rendering the HTML report. The information can be serialized to JSON for later rendering in web app. ## class `SBMLDocumentInfo(doc: 'libsbml.SBMLDocument')` Class for collecting information in JSON on an SBMLDocument to create reports. A single document can contain multiple models or be a hierarchical model (comp package). ### `SBMLDocumentInfo.add_compartment_links(self, compartments: 'list[dict[str, Any]]', species: 'list[dict[str, Any]]', reactions: 'list[dict[str, Any]]') -> 'None'` Add species and reaction links to compartment. ### `SBMLDocumentInfo.add_species_links(self, species: 'list[dict[str, Any]]', reactions: 'list[dict[str, Any]]') -> 'None'` Add reaction links to species. ### `SBMLDocumentInfo.compartments(self, model: 'libsbml.Model', assignments: 'dict[str, dict[str, str]]') -> 'list[dict]'` Information for Compartments. :return: list of info dictionaries for Compartments ### `SBMLDocumentInfo.constraints(self, model: 'libsbml.Model') -> 'list[dict[str, Any]]'` Information for Constraints. :return: list of info dictionaries for Constraints ### `SBMLDocumentInfo.create_info(self) -> 'dict[str, Any]'` Create information dictionary for report rendering. ### `SBMLDocumentInfo.document(self, doc: 'libsbml.SBMLDocument') -> 'dict[str, str]'` Info for SBMLDocument. :param doc: SBMLDocument :return: information dictionary for SBMLDocument ### `SBMLDocumentInfo.events(self, model: 'libsbml.Model') -> 'list[dict[str, Any]]'` Information dictionaries for Events. :return: list of info dictionaries for Events ### `SBMLDocumentInfo.from_sbml(source: 'Path | str') -> 'SBMLDocumentInfo'` Read model info from SBML. ### `SBMLDocumentInfo.function_definitions(self, model: 'libsbml.Model') -> 'list'` Information dictionaries for FunctionDefinitions. :return: list of info dictionaries for FunctionDefinitions ### `SBMLDocumentInfo.gene_products(self, model: 'libsbml.Model') -> 'list[dict[str, Any]]'` Information dictionaries for GeneProducts. :return: list of info dictionaries for Reactions ### `SBMLDocumentInfo.initial_assignments(self, model: 'libsbml.Model') -> 'list'` Information for InitialAssignments. :return: list of info dictionaries for InitialAssignments ### `SBMLDocumentInfo.model(self, model: 'libsbml.Model') -> 'dict[str, str]'` Info for SBML Model. :param model: Model :return: information dictionary for Model ### `SBMLDocumentInfo.model_definitions(self) -> 'dict'` Information for comp:ModelDefinitions. :return: list of info dictionaries for comp:ModelDefinitions ### `SBMLDocumentInfo.model_dict(self, model: 'libsbml.Model | libsbml.ModelDefinition') -> 'dict[str, Any]'` Create information for a given model. ### `SBMLDocumentInfo.objectives(self, model: 'libsbml.Model') -> 'list[dict[str, Any]]'` Information dictionaries for Objectives. :return: list of info dictionaries for Objectives ### `SBMLDocumentInfo.parameters(self, model: 'libsbml.Model', assignments: 'dict[str, dict[str, str]]') -> 'list[dict]'` Information for SBML Parameters. :return: list of info dictionaries for Reactions ### `SBMLDocumentInfo.ports(self, model: 'libsbml.Model') -> 'list'` Information for comp:Ports. :return: list of info dictionaries for comp:Ports ### `SBMLDocumentInfo.reactions(self, model: 'libsbml.Model') -> 'list[dict[str, Any]]'` Information dictionaries for ListOfReactions. :return: list of info dictionaries for Reactions -- take a look at local parameter once ### `SBMLDocumentInfo.rules(self, model: 'libsbml.Model') -> 'dict'` Information for Rules. :return: list of info dictionaries for Rules ### `SBMLDocumentInfo.sbaseref_dict(self, sbaseref: 'libsbml.SBaseRef') -> 'dict[str, Any]'` Info dictionary for SBaseRef. :param sbaseref: SBaseRef instance for which information dictionary is created :return: information dictionary for SBaseRef ### `SBMLDocumentInfo.species(self, model: 'libsbml.Model', assignments: 'dict[str, dict[str, str]]') -> 'list[dict]'` Information for Species. :return: list of info dictionaries for Species ### `SBMLDocumentInfo.submodels(self, model: 'libsbml.Model') -> 'list[dict[str, Any]]'` Information dictionaries for comp:Submodels. :return: list of info dictionaries for comp:Submodels ### `SBMLDocumentInfo.to_json(self, strip: 'bool' = True, indent: 'int' = 2) -> 'str'` Serialize to JSON representation. ### `SBMLDocumentInfo.unit_definitions(self, model: 'libsbml.Model') -> 'list'` Information for UnitDefinitions. :return: list of info dictionaries for UnitDefinitions ## function `clean_empty(d: 'dict | list | str') -> 'dict | list | str'` Remove empty fields from JSON. Reducing to core information. --- # sbmlutils.report.sbmlreport SBML report using https://sbml4humans.de. ## function `create_online_report(sbml_path: pathlib.Path, server: str = 'https://sbml4humans.de', fileserver_duration: int = 10, fileserver_port: int = 5115) -> None` Create sbml4humans report. The SBML file can be validated during report generation. Local parameters can be promoted during report generation. :param sbml_path: path to SBML file :param server: server to use for report, for local development use `localhost:3456` :param fileserver_duration: duration of file server in seconds :param fileserver_port: port of file server :return: None ## function `start_server(path: pathlib.Path, port: int = 5115) -> None` Start a simple webserver serving path on port. --- # sbmlutils.report.units Helper functions for formating and rendering units. ## function `udef_to_string(udef: libsbml.UnitDefinition | str | None, model: libsbml.Model | None = None, format: str = 'latex') -> str | None` Render formatted string for units. Format can be either 'str' or 'latex' Units have the general format (multiplier * 10^scale *ukind)^exponent (m * 10^s *k)^e Returns None if udef is None or no units in UnitDefinition. :param udef: unit definition which is to be converted to string --- # sbmlutils.report.mathml Rendering of formulas and Content MathML. A common problem in rendering MathML is that the content MathML is difficult to read. The presentation MathML has a much better rendering and improves understandability. This module uses stylesheets for the conversion of content MathMl -> presentation MathML. see also: https://docs.sympy.org/dev/modules/printing.html#module-sympy.printing.mathml ## function `astnode_to_latex(astnode: libsbml.ASTNode) -> str` Convert ASTNode to Latex using XSLT transformation. ## function `cmathml_to_astnode(cmathml: str) -> libsbml.ASTNode` Convert Content MathML string to ASTNode. :param cmathml: SBML Content MathML string :return: libsbml.ASTNode ## function `formula_to_astnode(formula: str, model: libsbml.Model | None = None) -> libsbml.ASTNode` Convert formula string to ASTNode. :param formula: SBML formula string :param model: libsbml.Model :return: libsbml.ASTNode ## function `formula_to_latex(formula: str, model: libsbml.Model | None = None) -> str` Convert formula string to latex. ## function `symbol_to_latex(symbol: str) -> str` Convert symbol to latex by packing in mathit and escaping underscores. --- # Development Contributions are welcome. The repository is [matthiaskoenig/sbmlutils](https://github.com/matthiaskoenig/sbmlutils); development happens against the `develop` branch via pull requests. ## Setup development environment Development needs [uv](https://docs.astral.sh/uv/) and a checkout of the repository: ```bash git clone https://github.com/matthiaskoenig/sbmlutils.git cd sbmlutils ``` A single sync creates the virtual environment in `.venv`, installs `sbmlutils` into it in editable mode and adds the complete tooling: ```bash uv sync --extra dev ``` The `dev` extra contains everything used below, i.e., pytest, ruff, ty, tox, pre-commit, zensical and bump-my-version, so nothing has to be installed separately. The python version is taken from `.python-version` (currently 3.14); to work against the oldest supported version instead use `uv sync --extra dev --python 3.11`, which replaces the environment. The tools are then run either with `uv run `, which uses the environment without activating it, or from the activated environment: ```bash source .venv/bin/activate # Linux and macOS .venv\Scripts\activate # Windows ``` The commands in this document are written without the `uv run` prefix; prepend it if the environment is not activated. The last step installs the git hook: ```bash uv run pre-commit install # install the hook, once per checkout uv run pre-commit run --all-files # check the current state of the repository ``` From now on every commit is checked with ruff (lint and format) and ty, i.e., the same checks that run in continuous integration. On a commit only the changed files are looked at, `--all-files` checks the whole repository and is what a newly added hook should be tried with. ## Testing The tests are written with pytest, tox runs them against every supported python version. The tox environments are named after the interpreter (`py3.11` to `py3.14`, see `envlist` in `tox.ini`), a single one is run with ```bash tox r -e py3.14 ``` and the complete matrix, including the `ty` environment, in parallel with ```bash tox run-parallel ``` This needs the interpreters to be available, which uv installs with `uv python install 3.11 3.12 3.13 3.14`. Continuous integration runs the same environments as `uvx --with tox-uv tox -e py3.14`. To run the tests directly against the development environment use ```bash pytest # the full suite pytest tests/test_factory.py # a single module pytest tests/test_factory.py::test_model_units # a single test ``` The `conftest.py` at the root of the repository selects the non-interactive matplotlib backend for the session and puts the repository on `sys.path`, so that `tests/examples/` can import the examples. Some tests are skipped unless what they need is there: the models of the [SBML test suite](https://github.com/sbmlteam/sbml-test-suite) and the biomodels archives are only present in a checkout, `tests/fbc/test_cobra.py` needs cobrapy (the `cobra` extra), and `tests/test_biomodels.py` queries the live BioModels service. The downloads of `sbmlutils.biomodels` go through the retrying session of pymetadata, which retries the transient error responses (429, 500, 502, 503, 504) with an exponential backoff and times out after 30 seconds; `test_download_file_retries_transient_error` covers this against a local server and needs no network. What retrying cannot fix is a service which is unreachable or which refuses the request — BioModels answers the GitHub runners with `403 Forbidden` — so those tests probe the service first and are skipped rather than failed. ## Linting and formatting Linting and formatting use [ruff](https://docs.astral.sh/ruff/): ```bash ruff check # lint ruff format # format ``` The model definitions of the examples are written against the names of `sbmlutils.factory`, which they import with a star import. This is the documented style, so `F403`/`F405` are ignored for `examples/` and `tests/` in `.ruff.toml` instead of globally. ## Type checking Type checking is performed with [ty](https://docs.astral.sh/ty/): ```bash tox r -e ty ``` Or directly in the working tree: ```bash uvx ty check ``` The configuration lives in `[tool.ty]` in `pyproject.toml`. Warnings are treated as errors, so the codebase is kept free of diagnostics. Suppress an unavoidable diagnostic with a rule specific `# ty: ignore[rule-name]` rather than a blanket comment. libsbml has no type stubs and creates its objects through a SWIG layer, so ty sees an untyped API. Annotate the libsbml objects (`doc: libsbml.SBMLDocument = ...`) and use the explicit getters (`getVariable()`) rather than the attributes the SWIG layer synthesizes (`variable`), which the type checker cannot see. ## Examples The examples are runnable scripts in `examples/`, they are not part of the package. They are run as modules from the root of the repository: ```bash python -m examples.species python -m examples.tutorial.minimal_model ``` An example writes what it creates into the current working directory and never opens a window: a plotting example saves its figure to a file. `tests/examples/` builds every model definition and runs the example scripts in a temporary directory, so a broken example fails the test suite. See `examples/README.md`. ## Documentation The documentation is built with [Zensical](https://zensical.org/), the static site generator of the Material for MkDocs authors. The sources are markdown files in `docs/`, the site is configured in `zensical.toml` in the repository root. Nothing rendered is committed: the site is built by the `documentation` workflow on every push and published to [matthiaskoenig.github.io/sbmlutils](https://matthiaskoenig.github.io/sbmlutils) from the `develop` branch. Build the site into `site/`: ```bash uv run zensical build --clean ``` For writing, the preview rebuilds on save: ```bash uv run zensical serve ``` The API reference is rendered from the docstrings by [mkdocstrings](https://mkdocstrings.github.io/); a page in `docs/api/` only contains the module directive: ```markdown # factory ::: sbmlutils.factory ``` Docstrings are therefore the place to document functions and classes, the markdown files provide the narrative around them. Adding a module to the reference means adding such a page and an entry to `nav` in `zensical.toml`. ### Files for agents { #files-for-agents } Agents and language models read markdown, not rendered html. `scripts/llms_txt.py` writes the files of the [llms.txt convention](https://llmstxt.org/) into the built site, i.e., [llms.txt](https://matthiaskoenig.github.io/sbmlutils/llms.txt) as an annotated index of all pages, [llms-full.txt](https://matthiaskoenig.github.io/sbmlutils/llms-full.txt) with the complete documentation in a single file, and the markdown of every page next to its html (`/creation.md` for `/creation/`). The markdown of the API reference is generated from the docstrings with `inspect`, since the pages themselves only contain the mkdocstrings directive. ```bash uv run zensical build --clean uv run python scripts/llms_txt.py ``` The `documentation` workflow runs both steps, so the files are regenerated with every push. `docs/robots.txt` points crawlers at the sitemap and at these files. Zensical will provide agent context files itself at some point, then this script can go. ## Release A release is made from `develop`: 1. write the release notes for the version in `release-notes/` 2. make sure everything passes: `tox run-parallel`, `ruff check`, `tox r -e ty` 3. check the version bump: `uvx bump-my-version bump [major|minor|patch] --dry-run -vv` 4. bump the version: `uvx bump-my-version bump [major|minor|patch]`, which updates `src/sbmlutils/__init__.py` and `CITATION.cff`, commits and tags 5. `git push --tags`, which triggers the release workflow publishing to [pypi](https://pypi.org/project/sbmlutils/), followed by `git push` 6. test the installation from pypi in a fresh environment: ```bash uv venv --python 3.14 uv pip install sbmlutils ``` 7. once Zenodo has archived the release, update the citation information, i.e., `date-released` in `CITATION.cff` and the version, date and version DOI of the release in the citation of `README.md` and `docs/index.md`. `bump-my-version` only updates the version, not the date and the DOI, which are only known after the release