Skip to content

ode2sbml.model

model

ODEModel intermediate representation (IR).

All dataclasses here serve as the language-agnostic IR for ODE systems, serializable to/from JSON via Pydantic.

Compartment

Bases: BaseModel

A compartment in the SBML model.

Source code in ode2sbml/model.py
class Compartment(BaseModel):
    """A compartment in the SBML model."""

    id: str
    size: float = 1.0
    units: str = "litre"
    constant: bool = True

    @field_validator("id")
    @classmethod
    def validate_id(cls, v: str) -> str:
        return _validate_sbml_id(v, "Compartment id")

Species

Bases: BaseModel

A species (state variable) in the SBML model.

Source code in ode2sbml/model.py
class Species(BaseModel):
    """A species (state variable) in the SBML model."""

    id: str
    compartment: str
    initial_value: float
    units: str = "mole"
    has_only_substance_units: bool = True
    boundary_condition: bool = False
    constant: bool = False

    @field_validator("id")
    @classmethod
    def validate_id(cls, v: str) -> str:
        return _validate_sbml_id(v, "Species id")

Parameter

Bases: BaseModel

A parameter in the SBML model.

Source code in ode2sbml/model.py
class Parameter(BaseModel):
    """A parameter in the SBML model."""

    id: str
    value: float
    units: str = "dimensionless"
    constant: bool = True

    @field_validator("id")
    @classmethod
    def validate_id(cls, v: str) -> str:
        return _validate_sbml_id(v, "Parameter id")

RateRule

Bases: BaseModel

A rate rule mapping a species to its ODE RHS.

Source code in ode2sbml/model.py
class RateRule(BaseModel):
    """A rate rule mapping a species to its ODE RHS."""

    variable: str  # must match a Species.id
    formula: str  # SymPy-parseable string expression

AssignmentRule

Bases: BaseModel

An assignment rule mapping an algebraic intermediate.

Source code in ode2sbml/model.py
class AssignmentRule(BaseModel):
    """An assignment rule mapping an algebraic intermediate."""

    variable: str
    formula: str

EventTrigger

Bases: BaseModel

An SBML event with a trigger condition and assignments.

Source code in ode2sbml/model.py
class EventTrigger(BaseModel):
    """An SBML event with a trigger condition and assignments."""

    trigger_formula: str  # e.g. "t >= 10"
    assignments: Dict[str, str]  # {variable_id: formula_string}
    delay: float = 0.0

ODEModel

Bases: BaseModel

The central intermediate representation for an ODE system.

Supports round-trip serialization via Pydantic (JSON/dict).

Source code in ode2sbml/model.py
class ODEModel(BaseModel):
    """
    The central intermediate representation for an ODE system.

    Supports round-trip serialization via Pydantic (JSON/dict).
    """

    id: str
    name: str
    compartments: List[Compartment]
    species: List[Species]
    parameters: List[Parameter]
    rate_rules: List[RateRule]
    assignment_rules: List[AssignmentRule] = Field(default_factory=list)
    events: List[EventTrigger] = Field(default_factory=list)
    time_units: str = "second"
    notes: str = ""

    @field_validator("id")
    @classmethod
    def validate_id(cls, v: str) -> str:
        return _validate_sbml_id(v, "Model id")

    def _collect_ids(self) -> List[str]:
        ids: List[str] = []
        ids.extend(c.id for c in self.compartments)
        ids.extend(s.id for s in self.species)
        ids.extend(p.id for p in self.parameters)
        return ids

    def model_post_init(self, __context: object) -> None:  # noqa: ANN001
        """Validate that there are no duplicate IDs across the model."""
        all_ids = self._collect_ids()
        seen: set = set()
        for eid in all_ids:
            if eid in seen:
                raise ValueError(
                    f"Duplicate ID '{eid}' found across compartments, species, "
                    "and parameters."
                )
            seen.add(eid)

    # ------------------------------------------------------------------
    # Convenience look-ups
    # ------------------------------------------------------------------

    def get_species_ids(self) -> List[str]:
        return [s.id for s in self.species]

    def get_parameter_ids(self) -> List[str]:
        return [p.id for p in self.parameters]

    def get_compartment_ids(self) -> List[str]:
        return [c.id for c in self.compartments]

    # ------------------------------------------------------------------
    # Serialisation helpers
    # ------------------------------------------------------------------

    def to_json(self) -> str:
        """Serialise the model to a JSON string."""
        return self.model_dump_json(indent=2)

    @classmethod
    def from_json(cls, json_str: str) -> "ODEModel":
        """Deserialise a model from a JSON string."""
        return cls.model_validate_json(json_str)

model_post_init(__context)

Validate that there are no duplicate IDs across the model.

Source code in ode2sbml/model.py
def model_post_init(self, __context: object) -> None:  # noqa: ANN001
    """Validate that there are no duplicate IDs across the model."""
    all_ids = self._collect_ids()
    seen: set = set()
    for eid in all_ids:
        if eid in seen:
            raise ValueError(
                f"Duplicate ID '{eid}' found across compartments, species, "
                "and parameters."
            )
        seen.add(eid)

to_json()

Serialise the model to a JSON string.

Source code in ode2sbml/model.py
def to_json(self) -> str:
    """Serialise the model to a JSON string."""
    return self.model_dump_json(indent=2)

from_json(json_str) classmethod

Deserialise a model from a JSON string.

Source code in ode2sbml/model.py
@classmethod
def from_json(cls, json_str: str) -> "ODEModel":
    """Deserialise a model from a JSON string."""
    return cls.model_validate_json(json_str)