Skip to content

Native BNGL PEtab linter: a petab Model adapter for BNGL (full petablint oracle), toward upstream libpetab-python (PEtab#436) #420

@wshlavacek

Description

@wshlavacek

Why

ADR-0025 made PyBNF a PEtab v2 exporter (a PyBNF/BNGL job → a PEtab v2 problem; chunk 1 = the demo job, commit e9ad581). But the PEtab reference library (libpetab-python / petab 0.8.x) implements only sbml and pysb model loaders — not bngl — so petablint cannot load a BNGL problem (ValueError: Unknown model format: bngl, thrown before any table check). Our exporter is therefore validated only at the table level: the tests build a model-less petab.v2.Problem and run petab's ~13 table-level checks; the ~5 model-cross checks (CheckModel, CheckObservablesDoNotShadowModelEntities, symbol_allowed_in_observable_formula, …) are asserted by hand.

The spec ≠ the tooling: PEtab v2 lists bngl as a model language, but libpetab-python doesn't implement it.

Upstream is primed for this:

  • PEtab v2 was deliberately made model-format-agnostic (PEtab-dev/PEtab PR #538). The petab Model ABC exists for exactly this; SbmlModel/PysbModel implement it; bngl is named but unimplemented.
  • Add support for non-SBML models PEtab-dev/PEtab#436 "Add support for non-SBML models" (open, milestone PEtab 2.0.0) explicitly lists bngl, and the maintainers ask for contributors. A user there hit our exact pain point: BNGL→SBML export is lossy/ugly, so native BNGL is the right fix.
  • The convention the PEtab maintainers settled on for rule-based models — reference named observables/expressions, not species formulas — is exactly ADR-0025's rule (observableFormula = the bare BNGL observable/function name, functions stay in the model). Our design already aligns.

PyBNF is the natural home: it already parses BNGL (pset.BNGLModel, bngsim_model.parsing), and the exporter uses that parse today.

What

Implement a BNGL adapter satisfying the petab Model ABC (~14 introspection methods: parameters + values, observables, functions, species, compartments; has_entity_with_id, is_state_variable, symbol_allowed_in_observable_formula, is_valid, …). Validation needs only parsing, not simulation — so no BNG2.pl/Perl dependency is required to lint.

  • Step A (in PyBNF): a BnglModel(petab Model) backed by PyBNF's existing BNGL parser, registered into petab at runtime (the model_factory is a hardcoded if/elif — slot in 'bngl'). This gives the exporter the full petablint oracle (CheckModel + the model-cross checks), and is the reference implementation. Harden entity enumeration against the formal grammar at BNG_vscode_extension/docs/bngl-grammar.md (derived from bng2/Perl2/).
  • Step B (upstream): propose it to PEtab-dev/libpetab-python as a BnglModel (mirroring PysbModel), with a PEtab-test-suite copy using a BNGL model; track the spec/extension at PEtab#436.

Scope / boundaries

  • Validation-grade first (linting). Simulation (network generation / ODE export so pyPESTO/AMICI can actually fit a BNGL PEtab problem) is a separate, larger effort — via BNGL→SBML (writeSBML) or AMICI-BNGL — explicitly out of scope here.
  • Harden against the grammar's full entity namespaces: compartments, molecule-type/component names, seed-species $ clamp, block aliases (molecules/species/rules), function arguments.

Acceptance

  • Full (model-level) petab validation passes on the chunk-1 demo export, not just the 13 table-level tasks.
  • tests/test_petab_export.py's oracle test upgrades from the table-level task subset to the full validation task set.

Refs: ADR-0025 (docs/adr/0025-…), commit e9ad581, PEtab-dev/PEtab#436, PEtab-dev/libpetab-python.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions