I ran into what appears to be an important gap between NFsim flag semantics and the behavior one would expect for reactant-side molecularity in bimolecular BNGL rules.
In short:
complex=>1 in BNGL maps to NFsim -cb
-cb turns on complex bookkeeping
- but the actual reactant-side distinct-complex molecularity check appears to require
-bscb, not plain -cb
This matters for models where a top-level + on the LHS is intended to mean "these reactant patterns must come from distinct complexes", as in cyclic crosslinking models.
Why this is surprising
For a bimolecular rule such as
A(a) + B(b) -> A(a!1).B(b!1) k
or, more importantly, for cyclic crosslinking rules where an LHS has separate reactant patterns that should not be matched within the same pre-existing connected complex, I would expect reactant-side molecularity to be enforced when complex bookkeeping is enabled.
However, in current NFsim source, plain -cb appears to be insufficient for that.
Source-level evidence
1. complex=>1 maps to -cb
In BioNetGen 2.9.3:
simulate_nf(..., complex=>1) maps to NFsim -cb
complex=>1 is already the default for simulate_nf
2. NFsim distinguishes -cb from -bscb
In src/NFsim.cpp, -bscb sets blockSameComplexBinding = true, while -cb separately sets turnOnComplexBookkeeping = true.
3. The actual transformation-set molecularity gate is wired to blockSameComplexBinding
In src/NFinput/NFinput.cpp, when reaction rules are initialized, NFsim does:
ts->setComplexBookkeeping( blockSameComplexBinding );
not
ts->setComplexBookkeeping( system_is_using_complex_bookkeeping );
4. ReactionClass::fire() checks molecularity through TransformationSet::checkMolecularity()
and in TransformationSet::checkMolecularity(), the full distinct-complex check is only taken when that transformation-set complex_bookkeeping flag is true.
Otherwise NFsim falls back to a weaker collision / overlap-style check rather than a full "distinct reactant complexes" check.
Practical consequence
For BNGL/NFsim users, this means:
complex=>1 / -cb is not enough if correctness depends on reactant-side distinct-complex enforcement
param=>"-bscb" is required
This is not obvious from the BNGL side, because complex=>1 sounds like it should be the relevant switch.
Minimal reproducer pattern
The problem is especially visible in cyclic crosslinking models, e.g. bivalent ligand / bivalent receptor models where a rule like
L(r!+,r) + R(l) -> L(r!+,r!1).R(l!1) kpx
must not match the R(l) from the same pre-existing complex when the intended chemistry is intermolecular crosslinking rather than an intracomplex closure via a bimolecular reactant match.
Without -bscb, NFsim appears able to admit matches that violate that intended reactant-side molecularity restriction. With -bscb, the resulting dynamics match the corresponding analytical theory much better.
Request
Could you clarify what the intended behavior is?
If the intended behavior is:
-cb = bookkeeping only
-bscb = bookkeeping + reactant-side distinct-complex enforcement
then I think this needs much clearer documentation, because it is very easy for BNGL users to assume that complex=>1 is the molecularity-relevant setting.
If instead the intended behavior is that ordinary reactant-side molecularity should already be enforced under -cb, then this may be a bug in how TransformationSet::setComplexBookkeeping() is wired during rule initialization.
I would be happy to provide a small BNGL reproducer if that would be useful.
I ran into what appears to be an important gap between NFsim flag semantics and the behavior one would expect for reactant-side molecularity in bimolecular BNGL rules.
In short:
complex=>1in BNGL maps to NFsim-cb-cbturns on complex bookkeeping-bscb, not plain-cbThis matters for models where a top-level
+on the LHS is intended to mean "these reactant patterns must come from distinct complexes", as in cyclic crosslinking models.Why this is surprising
For a bimolecular rule such as
or, more importantly, for cyclic crosslinking rules where an LHS has separate reactant patterns that should not be matched within the same pre-existing connected complex, I would expect reactant-side molecularity to be enforced when complex bookkeeping is enabled.
However, in current NFsim source, plain
-cbappears to be insufficient for that.Source-level evidence
1.
complex=>1maps to-cbIn BioNetGen 2.9.3:
simulate_nf(..., complex=>1)maps to NFsim-cbcomplex=>1is already the default forsimulate_nf2. NFsim distinguishes
-cbfrom-bscbIn
src/NFsim.cpp,-bscbsetsblockSameComplexBinding = true, while-cbseparately setsturnOnComplexBookkeeping = true.3. The actual transformation-set molecularity gate is wired to
blockSameComplexBindingIn
src/NFinput/NFinput.cpp, when reaction rules are initialized, NFsim does:ts->setComplexBookkeeping( blockSameComplexBinding );not
ts->setComplexBookkeeping( system_is_using_complex_bookkeeping );4.
ReactionClass::fire()checks molecularity throughTransformationSet::checkMolecularity()and in
TransformationSet::checkMolecularity(), the full distinct-complex check is only taken when that transformation-setcomplex_bookkeepingflag is true.Otherwise NFsim falls back to a weaker collision / overlap-style check rather than a full "distinct reactant complexes" check.
Practical consequence
For BNGL/NFsim users, this means:
complex=>1/-cbis not enough if correctness depends on reactant-side distinct-complex enforcementparam=>"-bscb"is requiredThis is not obvious from the BNGL side, because
complex=>1sounds like it should be the relevant switch.Minimal reproducer pattern
The problem is especially visible in cyclic crosslinking models, e.g. bivalent ligand / bivalent receptor models where a rule like
must not match the
R(l)from the same pre-existing complex when the intended chemistry is intermolecular crosslinking rather than an intracomplex closure via a bimolecular reactant match.Without
-bscb, NFsim appears able to admit matches that violate that intended reactant-side molecularity restriction. With-bscb, the resulting dynamics match the corresponding analytical theory much better.Request
Could you clarify what the intended behavior is?
If the intended behavior is:
-cb= bookkeeping only-bscb= bookkeeping + reactant-side distinct-complex enforcementthen I think this needs much clearer documentation, because it is very easy for BNGL users to assume that
complex=>1is the molecularity-relevant setting.If instead the intended behavior is that ordinary reactant-side molecularity should already be enforced under
-cb, then this may be a bug in howTransformationSet::setComplexBookkeeping()is wired during rule initialization.I would be happy to provide a small BNGL reproducer if that would be useful.