Add MathDescription data model to VCML reader/writer#41
Open
jcschaff wants to merge 4 commits into
Open
Conversation
VCell math descriptions are generated by libvcell for each biomodel application (e.g. as a side effect of utils.update_biomodel) but were not exposed in pyvcell's datamodels — the VCML reader skipped the <MathDescription> child of each SimulationSpec and the writer emitted only a dummy placeholder. This adds a MathDescription pydantic model (constants, functions, state variables, compartment/membrane subdomains, ODE/PDE equations, membrane jump conditions, and stochastic/particle constructs) as an optional math_description field on Application, mirroring the VCML structure where MathDescription is a child of SimulationSpec. - models.py: MathDescription and child node types - vcml_reader.py: self-contained MathDescription subtree parser (avoids tag collisions with the existing species-mapping visitor); empty placeholder math descriptions are ignored - vcml_writer.py: faithful MathDescription serializer; the dummy placeholder is still written when no math is present (required by libvcell, which references it from each Simulation) - tests + fixtures covering ODE (nonspatial), PDE (spatial), membrane jump conditions, stochastic jump processes, and particle processes, plus round-trip fidelity Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
The biomodel writer assumed every compartment mapping carried six boundary types and emitted <BoundariesTypes> unconditionally, raising IndexError for nonspatial models (nonspatial membrane mappings legitimately carry none). It also dropped the Application.stochastic flag, since SimulationSpec was written without the Stochastic attribute. - Emit <BoundariesTypes> only when all six faces are present - Write the Stochastic attribute on SimulationSpec Nonspatial ODE and stochastic biomodels, and spatial particle biomodels, now round-trip through the writer; the math round-trip test uses the full biomodel writer (read -> write -> read) across nonspatial and spatial geometries. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Stochastic and particle models specify species initial conditions as molecule counts (<InitialCount>) rather than concentrations (<InitialConcentration>). The reader ignored <InitialCount>, so the initial condition was lost and libvcell rejected the written VCML with "Unrecognizable initial condition". - SpeciesMapping gains an init_count field (and includes it in expressions for field-data extraction) - Reader parses <InitialCount>; writer emits it when present Nonspatial stochastic biomodels now round-trip through both pyvcell and libvcell (to_vcml_str / update_biomodel). Spatial particle (Smoldyn) models round-trip through pyvcell; their libvcell math generation is a separate, deeper mapping gap. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
make check is now clean: pre-commit, mypy (303 files), and deptry all pass. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
VCell math descriptions are generated by libvcell for each biomodel application (e.g. as a side effect of
utils.update_biomodel), but they were not exposed in pyvcell's datamodels. The VCML reader skipped the<MathDescription>child of eachSimulationSpec, and the writer emitted only a dummy placeholder.This PR introduces a
MathDescriptionpydantic data model and wires it into the reader and writer, so the generated math is now a first-class, inspectable part of theApplication— mirroring the VCML structure whereMathDescriptionis a child ofSimulationSpec. Along the way it also fixes pre-existing writer gaps that prevented nonspatial (dim-0) and stochastic biomodels from round-tripping.What's modeled
MathDescription→ constants, functions, state variables (volume/membrane/particle/stochastic/…), andCompartmentSubDomain/MembraneSubDomaincontaining:Element/attribute names follow VCell's
Xmlproducer/XmlReader. Rare constructs (random variables, fast systems, events, filament/point subdomains, post-processing, Langevin specifics) are not modeled yet and are skipped consistently on read; they can be added incrementally.Writer fixes (nonspatial / stochastic / counts)
These resolve pre-existing limitations so nonspatial and stochastic biomodels round-trip:
<BoundariesTypes>was emitted unconditionally, indexing six boundary faces and raisingIndexErrorfor nonspatial models (nonspatial membrane mappings legitimately carry none). Now emitted only when all six faces are present.SimulationSpecwas written without theStochasticattribute, so a stochastic application came back as deterministic. Now written.<InitialCount>species mappings: stochastic/particle models express species initial conditions as molecule counts rather than concentrations. The reader ignored<InitialCount>, so the initial condition was lost and libvcell rejected the written VCML with "Unrecognizable initial condition". AddedSpeciesMapping.init_count(parsed/written; included inexpressionsfor field-data extraction).Implementation notes
vcml_reader.py): theMathDescriptionsubtree is parsed by a dedicated, self-contained parser rather than the global tag-dispatch visitor, to avoid colliding with existing species-mapping handlers (Boundaries/Diffusion/Initial). Empty placeholder math descriptions are ignored.vcml_writer.py): faithfully serializesmath_description. When an application has no math (e.g. an in-memory model), the emptydummy_math_descriptionplaceholder is still written — libvcell requires it because eachSimulationreferences aMathDescription.biomodel == new_biomodelwriter tests pass with math now parsed.Round-trip status
to_vcml_str/update_biomodel)Known follow-up (not in this PR): spatial particle models now pass the initial-condition check but fail inside libvcell's
ParticleMathMapping.refreshMathDescription("failed to generate math: null") — the writer doesn't yet emit everything the Smoldyn math mapping needs. They still round-trip through pyvcell itself.Tests
New
tests/vcml/test_math_description.pyplus fixtures (copied from the vcell repo) covering nonspatial ODE, spatial PDE, membrane jump conditions, nonspatial stochastic, and spatial particle models, including full-biomodel round-trip equality across nonspatial and spatial geometries. Also atest_species_mapping_initial_counttest.mypyandruffclean;pytest tests/vcml tests/sbmlpasses (39 passed, 5 skipped).🤖 Generated with Claude Code