Repository navigation
network-free: start NFsim and RuleMonkey from the model's species amounts (#1373) - #1385
Merged
Merged
Conversation
…unts (lanl#1373) Model.set_concentration never reached either backend: both are seeded from the XML's <Species> list, so with L(r) set to 0 a run started from the XML's 300. Each run now hands the backend every species the model holds at an amount other than its amount at load, by the XML seed species of the same name, through a new set_species_amounts on both wrappers. Amounts round half-up like every seed and outrank a parameter the seed reads. NFsim writes them into the XML it already rewrites, and refuses an id it could not write; RuleMonkey lays them as pins in apply_seed_rounding. A nonzero amount for a species the XML does not seed is refused.
…r a seed parameter (lanl#1373) Review of lanl#1385. Three ways a run still started somewhere other than the model, each reproduced on the PR's build against SSA: - A fixed ($) seed species was never matched. The .net loader drops the `$` from the name (net_file_loader.cpp) and the XML keeps it (`$X(a)`), so with fixed_seed.{net,xml}: X(a) set to 10 was refused as "no seed species of that name", X(a) set to 0 was dropped as a non-seed species and nf and rm started from the XML's 50, and even set_param("X0", 75) alone was refused, since the model re-derives X(a) from it. xml_seed_species now reads names the way the loader does (`$` at the start or after `@c::`). - A species at its amount at load was not handed on while a parameter its seed reads was. After save_concentrations(), set_param("L0", 0) leaves L(r) at 300 and SSA starts there; nf and rm were handed L0 = 0 alone, re-derived the seed, and started Lfree at 0. Wherever a parameter is handed on, every seed species now goes with it at the model's amount (species_amounts(every_seed=...)). On 58 runs of the tests/data .net/.xml pairs after a parameter write, the trajectories are bit-identical to the PR's. - A -1e-12 amount, which an ODE run can leave, failed both backends ("could not seed species S1", "must be a finite, non-negative molecule count") where SSA rounds it to 0. An amount above -0.5 now goes as at least 0; one that rounds to no count is refused by name. Also: an XML ElementTree cannot read now refuses a changed amount (ModelError), as lanl#1372's review made it refuse a changed parameter, where a 0 was dropped. The user guide still said set_concentration "is not passed on yet (issue lanl#1373)", and "an earlier run" read as though a network-free run moved the model; it does not. 11 new tests, all failing on the PR's Python. Mutations: no `$` strip (5 fail), no `@c::$` strip (1), every_seed off or ignored (2 each), no clamp (2), {} on a parse failure (1), no count check (1).
wshlavacek
added a commit
to Montana/bngsim
that referenced
this pull request
Oct 31, 2026
… $, and say how to undo a moved model Two rough edges left after lanl#1385 (lanl#1373). A fixed species could not be named by its .net name. The .net loader drops the `$` (`$A()` is the model's `A()`, `@CP::$Sink()` its `@CP::Sink()`, net_file_loader.cpp), so `Model.set_concentration("$A()", 7)` raised "Species '$A()' not found in model". BNG2.pl's setConcentration takes either spelling, on a fixed species or not (`$B()` sets a plain `B()`), checked with BNG 2.9.3. `set_concentration`, `get_concentration` and `declare_ic_sensitivity` now try a name that is no species again without its `$`, at the start or after `@c::`, and keep the model's name for the bookkeeping keyed by it (`_declared_ic_sens`, `_ic_write_log`). The `$` stripper moves to `_model.py`, which `_network_free_params` already imports from. The parity replay's `resolve_species_name` drops the `$` the same way, where a `setConcentration("$X()")` sent a multi-segment replay to its single-segment fallback; no corpus protocol has one yet. A network-free run refused after an SSA, PSA or ODE run on the same model gave the wrong advice. That run writes its end state into the model, so the next nf or rm run starts there (lanl#1373), and a complex an XML written without the network does not seed is refused. The message said to rewrite the XML or run SSA. It now names that run, `model.clone()` for it, and `model.reset()`, which the new test shows lets the run go on. The user guide says the same. Tests fail on main: 8 (the `$` names in set/get/declare, under a compartment prefix, the declared row kept under the model's name, the refusal's advice on nf and rm, the parity resolver). Mutations: no `$` retry (3 fail), bookkeeping under the given name (1), the old advice (2), no exact `$`-less match in the resolver (1, a complex), its key taken on the `$` name (1), declare exact only (1). Full suite before the last review round: 17,278 passed.
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.
Closes #1373.
Stacked on #1372 (#1360, parameters), whose fixture and run wiring this extends. Until #1372 merges, this diff also shows its commit; the change here is the second commit.
What was wrong
Model.set_concentrationnever reached NFsim or RuleMonkey. Both are seeded from the BNG XML's<Species>list, so a run started from the XML's amounts, whatever the model held. The issue's repro (model_parameters,L(r)set to 0) gives Lfree(t=0) = 300 on nf and rm, and 0 on SSA, with no warning. The same holds for a write made after theSimulatoris built, and for the end state an SSA or ODE run leaves in the model.The fix
The species-side twin of #1372, built the same way.
_network_free_params.py,_simulator.py,_model.py):Model._loaded_state), and a clone keeps its parent's.<Species id=>whosename=is that species'.netname. BNG2.pl writes the same canonical string in both,$and@c::included.ValueErrorbefore the run. The backend would start that species at 0.set_species_amounts({id: amount})on both wrappers. It replaces the whole map and is folded into the seed-rounding step each wrapper already has. Each amount is rounded half-up like every seed (GH Codegen cache does not invalidate on sensitivity-RHS changes (#41 and #43 were silently inert on warm caches) #51) and outranks a parameter the species'concentration=reads, asModel.set_concentrationdoes on the network.create_systemalready rewrites (seed_count_rounding.hpp). That rewrite is fail-safe and loads the original on any error, so it now reports which ids it wrote, andcreate_systemthrows if any is missing. Otherwise the fail-safe would bring back the silent wrong start.set_initial_amountpins inapply_seed_rounding. That function clears every pin at eachset_param, so a pin set any other way would be lost. A refused id leaves the previous pins in place.Tests (
test_network_free_species_amounts.py, 27: nf and rm each, one without a backend)Simulatoris built, then set back between runsL(r)outranksL0, andL0alone still seeds it (#1372)Mutations
L0=0case, whose amount now arrives as a species amount)Measured
tests/datathat has a.netor.bngl, 78 runs on nf and rm, on network-free: hand NFsim and RuleMonkey the parameters the model has changed (#1360) #1372's build and this one. 42 of 42 that run are bit-identical, and the other 36 are refused the same way on both.pre-commit run --all-files(new files staged) andsphinx -Ware clean.Behaviour that changes