nomass 1.0.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
nomass-1.0.0/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2022 Aurélien PELISSIER
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
nomass-1.0.0/PKG-INFO ADDED
@@ -0,0 +1,233 @@
1
+ Metadata-Version: 2.4
2
+ Name: nomass
3
+ Version: 1.0.0
4
+ Summary: Non-Markovian Stochastic Simulation: Gillespie-based simulation of reaction networks with arbitrary inter-event time distributions
5
+ Author-email: Aurélien Pélissier <aurelien.pelissier.38@gmail.com>
6
+ License-Expression: MIT
7
+ Project-URL: Homepage, https://github.com/AI-SysBio/NoMaSS
8
+ Project-URL: Documentation, https://github.com/AI-SysBio/NoMaSS/blob/main/docs/api.md
9
+ Project-URL: Repository, https://github.com/AI-SysBio/NoMaSS
10
+ Project-URL: Issues, https://github.com/AI-SysBio/NoMaSS/issues
11
+ Project-URL: Paper, https://doi.org/10.1093/bib/bbag486
12
+ Keywords: gillespie,stochastic simulation,non-markovian,renewal process,systems biology,reaction network,delay,laplace gillespie,mosaic
13
+ Classifier: Development Status :: 5 - Production/Stable
14
+ Classifier: Intended Audience :: Science/Research
15
+ Classifier: Programming Language :: Python :: 3
16
+ Classifier: Programming Language :: Python :: 3 :: Only
17
+ Classifier: Programming Language :: Python :: 3.9
18
+ Classifier: Programming Language :: Python :: 3.10
19
+ Classifier: Programming Language :: Python :: 3.11
20
+ Classifier: Programming Language :: Python :: 3.12
21
+ Classifier: Programming Language :: Python :: 3.13
22
+ Classifier: Topic :: Scientific/Engineering
23
+ Classifier: Topic :: Scientific/Engineering :: Bio-Informatics
24
+ Classifier: Topic :: Scientific/Engineering :: Physics
25
+ Classifier: Operating System :: OS Independent
26
+ Requires-Python: >=3.9
27
+ Description-Content-Type: text/markdown
28
+ License-File: LICENSE
29
+ Requires-Dist: numpy>=1.21
30
+ Requires-Dist: scipy>=1.7
31
+ Requires-Dist: matplotlib>=3.4
32
+ Provides-Extra: test
33
+ Requires-Dist: pytest>=7; extra == "test"
34
+ Provides-Extra: paper
35
+ Requires-Dist: pandas; extra == "paper"
36
+ Requires-Dist: seaborn; extra == "paper"
37
+ Requires-Dist: openpyxl; extra == "paper"
38
+ Requires-Dist: SALib; extra == "paper"
39
+ Dynamic: license-file
40
+
41
+ # NoMaSS: Non-Markovian Stochastic Simulation
42
+
43
+ [![paper](https://img.shields.io/badge/paper-Brief.%20Bioinform.%202026-blue)](https://doi.org/10.1093/bib/bbag486)
44
+ [![license](https://img.shields.io/badge/license-MIT-green)](LICENSE)
45
+ [![pypi](https://img.shields.io/pypi/v/nomass)](https://pypi.org/project/nomass/)
46
+
47
+ <img align="right" src="https://raw.githubusercontent.com/AI-SysBio/NoMaSS/main/figures/NoMaSS.png" width=380>
48
+
49
+ Discrete stochastic processes are widespread in nature and in human-made systems, with applications in physics, biochemistry, epidemiology, social dynamics and finance. In most of these systems the dynamics cannot be described with memoryless (Markovian) interactions, and simulating them requires dedicated numerical tools.
50
+
51
+ NoMaSS is a practical and scalable Gillespie-based framework to simulate non-Markovian reaction networks with arbitrary inter-event time distributions. It implements three exact methods that can be mixed freely in the same model, one per reaction channel:
52
+
53
+ * **MOSAIC** (rejection based, [1, 2]): propose events at an upper bound of the rate and accept them with the ratio of the true hazard to the bound.
54
+ * **Laplace Gillespie** [3]: give every reactant a Poisson rate drawn from the mixing density of its waiting-time distribution.
55
+ * **DelaySSA** [4]: draw the waiting time when a reactant enters a channel and schedule the event in a priority queue.
56
+
57
+ The methods, their accuracy and their speed are described in the accompanying paper [1].
58
+
59
+ &nbsp;
60
+
61
+ ## Installation
62
+
63
+ NoMaSS is deliberately lightweight: the efficiency of the framework lies in the algorithms rather than in compiled extensions, so the engine is pure Python and relies only on the standard scientific stack. Python 3.9 or later is required.
64
+
65
+ ```bash
66
+ pip install nomass
67
+ ```
68
+
69
+ To work on the code or run the scripts of the paper, clone the repository and install it in editable mode:
70
+
71
+ ```bash
72
+ git clone https://github.com/AI-SysBio/NoMaSS.git
73
+ cd NoMaSS
74
+ pip install -e .[test,paper]
75
+ ```
76
+
77
+ Check that everything works with
78
+
79
+ ```bash
80
+ python examples/toy_example.py
81
+ ```
82
+
83
+ ## Quick start
84
+
85
+ The example below ([examples/toy_example.py](examples/toy_example.py)) simulates a small network where each channel uses a different method:
86
+
87
+ ```python
88
+ import nomass
89
+
90
+ # Reaction channels: one waiting-time distribution and one method each
91
+ r1 = nomass.Reaction_channel('A -> B', rate=1, shape_param=20, distribution='Gamma', method='Delay')
92
+ r2 = nomass.Reaction_channel('B -> C + A', rate=4, shape_param=5, distribution='Weibull', method='MOSAIC')
93
+ r3 = nomass.Reaction_channel('C -> 0', rate=0.03, shape_param=0.5, distribution='Gamma', method='Laplace')
94
+ r4 = nomass.Reaction_channel('A + B -> 0', rate=0.03) # two reactants: Poisson process
95
+
96
+ # Initial population (every species must be listed)
97
+ N_init = {'A': 300, 'B': 0, 'C': 0}
98
+
99
+ # Build and run the model
100
+ sim = nomass.Gillespie_simulation(N_init, [r1, r2, r3, r4],
101
+ Tend=10, # length of the simulation
102
+ N_simulations=20, # number of independent realisations
103
+ timepoints=100, # number of recorded time points
104
+ unit='h') # time unit (plots only)
105
+ populations = sim.run_simulations() # array (N_simulations, timepoints, species + total)
106
+
107
+ # Plot the results
108
+ sim.plot_inter_event_time_distribution()
109
+ sim.plot_populations()
110
+ ```
111
+
112
+ The simulation runs in a few seconds and produces the figures below (pass `verbose=False` to silence the progress output).
113
+
114
+ <p align="center">
115
+ <img src="https://raw.githubusercontent.com/AI-SysBio/NoMaSS/main/figures/toy_example.png" width=1000>
116
+ </p>
117
+
118
+ The oscillations created by the nearly deterministic Gamma waiting times are clearly visible. The *theoretical* distributions do not match the *simulated* ones exactly, even with many realisations, and this is expected: species A and B are reactants of two channels at the same time, and the theoretical curve is the distribution the channel would have if it were the only process acting on its reactant. The accuracy of each method is demonstrated in [1] and [2].
119
+
120
+ Reactions are written as strings: `'A + B -> C'`, `'0 -> A'` (creation), `'A -> 0'` (degradation), `'2 A -> B'` (stoichiometry). The plotting methods return their matplotlib figure and axes, so pass `show=False` to customise a figure before displaying it.
121
+
122
+ ## Choosing a method
123
+
124
+ | Method | Set with | Best for | Limitations |
125
+ | --- | --- | --- | --- |
126
+ | MOSAIC (rejection) | `method='MOSAIC'` | Large populations, state-dependent rates, any distribution with a bounded hazard | Hazard must be finite at t = 0 (Gamma and Weibull need a shape ≥ 1) |
127
+ | Laplace Gillespie | `method='Laplace'` | Heavy-tailed or decreasing hazards (Gamma/Weibull with shape < 1, Lomax), state-dependent rates | Only distributions whose survival function is a mixture of exponentials |
128
+ | DelaySSA | `method='Delay'` | Any distribution when rates are constant | Waiting times are frozen when drawn, so rates that change over time are not followed |
129
+
130
+ When `method` is omitted, NoMaSS uses MOSAIC if the hazard is bounded and Laplace Gillespie otherwise. Channels with zero or several reactants are always Poisson processes with propensity `rate × product of the reactant counts`, because the waiting time of an individual is not defined in that case.
131
+
132
+ A Gamma waiting time with an integer shape can also be embedded in a chain of exponential stages (hidden Markov embedding); [examples/erlang_embedding.py](examples/erlang_embedding.py) compares the two descriptions.
133
+
134
+ ## Supported distributions
135
+
136
+ | Distribution | MOSAIC | Laplace | DelaySSA |
137
+ | --- | :---: | :---: | :---: |
138
+ | Exponential | ✅ | ✅ | ✅ |
139
+ | Gamma | ✅ (α ≥ 1) | ✅ (α ≤ 1) | ✅ |
140
+ | Weibull | ✅ (α ≥ 1) | ✅ (α ≤ 1) | ✅ |
141
+ | Gaussian / Normal | ✅ | ❌ | ✅ |
142
+ | Lognormal | ✅ | ❌ | ✅ |
143
+ | Cauchy | ✅ | ❌ | ✅ |
144
+ | Power law, Pareto type I | ✅ | ❌ | ✅ |
145
+ | Power law, Lomax (Pareto type II) | ✅ | ✅ | ✅ |
146
+
147
+ Every distribution is parameterised by a nominal `rate` λ, the inverse of the mean waiting time (or of the median when the mean is undefined), and a dimensionless `shape_param` α (full details in Table S1 of [1]):
148
+
149
+ | Distribution | `rate` | `shape_param` |
150
+ | --- | --- | --- |
151
+ | Exponential | 1 / mean | unused |
152
+ | Gamma | 1 / mean | shape α |
153
+ | Weibull | 1 / mean | shape k |
154
+ | Gaussian | 1 / mean | std / mean |
155
+ | Lognormal | 1 / mean | std / mean |
156
+ | Cauchy | 1 / median | scale / median |
157
+ | Pareto type I | 1 / median | tail index α |
158
+ | Lomax | 1 / median | tail index α |
159
+
160
+ Gaussian and Cauchy waiting times are truncated to non-negative values. Aliases such as `'exp'`, `'norm'`, `'lognorm'` and `'weib'` are accepted. Requesting a combination that a method does not support raises an error at channel creation. [examples/all_distributions.py](examples/all_distributions.py) runs a cycle through all eight distributions.
161
+
162
+ ## State-dependent waiting times
163
+
164
+ Pass `update_function` to change the `rate` or `shape_param` of any channel after every iteration, for example to implement feedback or resource limitation ([examples/state_dependent_rates.py](examples/state_dependent_rates.py)):
165
+
166
+ ```python
167
+ def update_rates(sim):
168
+ N = sim.reactant_population['Cell']
169
+ sim.reaction_channel_list[0].rate = r0 * (1 - N / K) # logistic growth
170
+
171
+ sim = nomass.Gillespie_simulation({'Cell': 5}, [division], Tend=25, update_function=update_rates)
172
+ populations = sim.run_simulations()
173
+ ```
174
+
175
+ MOSAIC and Laplace Gillespie follow such changes exactly (Laplace rates are rescaled when the rate changes and redrawn when the shape changes). Delay-based channels draw their waiting time once, when the reactant enters the channel, so they cannot follow parameters that change afterwards: avoid `method='Delay'` for rapidly changing systems.
176
+
177
+ ## Individual properties
178
+
179
+ Every individual is a `nomass.Reactant` object that can carry arbitrary attributes. The `on_reaction` hook is called after each accepted reaction with the consumed and produced individuals, which is where properties are set or inherited ([examples/individual_properties.py](examples/individual_properties.py)):
180
+
181
+ ```python
182
+ def inherit(sim, channel, consumed, produced):
183
+ if channel is division:
184
+ for daughter in produced:
185
+ daughter.generation = consumed[0].generation + 1
186
+
187
+ sim = nomass.Gillespie_simulation({'Cell': 20}, [division, death], Tend=6, on_reaction=inherit)
188
+ ```
189
+
190
+ Set `transfer_identity=True` on a channel such as `'Gon -> Gon + mRNA'` to keep the same individual (with its properties and the clocks of its other channels) instead of replacing it. For kinetic laws that are not proportional to the reactant counts, subclass `Gillespie_simulation` and override `compute_propensities`; the full API is described in [docs/api.md](docs/api.md), and the hazards, samplers and Laplace mixing densities of all distributions are in [nomass/distributions.py](nomass/distributions.py).
191
+
192
+ ## Repository layout
193
+
194
+ ```
195
+ nomass/ the engine (distributions and simulation)
196
+ docs/ API reference (docs/api.md)
197
+ examples/ short runnable examples
198
+ paper/ scripts, data and precomputed results reproducing the paper's figures
199
+ tests/ pytest suite (pytest -q)
200
+ ```
201
+
202
+ The biochemical systems of the paper (bacterial growth, stem cell differentiation and RNA transcription) live in `paper/`, with a figure-to-script table in [paper/README.md](paper/README.md) and the article with its supplementary material in [paper/Pelissier2026_NoMaSS_main_and_SI.pdf](paper/Pelissier2026_NoMaSS_main_and_SI.pdf).
203
+
204
+ ## Citation
205
+
206
+ If you use NoMaSS, please cite (full text with supplementary material: [paper/Pelissier2026_NoMaSS_main_and_SI.pdf](paper/Pelissier2026_NoMaSS_main_and_SI.pdf))
207
+
208
+ > Pélissier A., Phan M., Beerenwinkel N., Rodríguez Martínez M. *Gillespie-based simulation and inference for non-Markovian stochastic reaction networks.* Briefings in Bioinformatics 27(5), bbag486 (2026). doi:[10.1093/bib/bbag486](https://doi.org/10.1093/bib/bbag486)
209
+
210
+ ```bibtex
211
+ @article{pelissier2026nomass,
212
+ title = {Gillespie-based simulation and inference for non-Markovian stochastic reaction networks},
213
+ author = {P{\'e}lissier, Aur{\'e}lien and Phan, Miroslav and Beerenwinkel, Niko and Rodr{\'i}guez Mart{\'i}nez, Mar{\'i}a},
214
+ journal = {Briefings in Bioinformatics},
215
+ volume = {27},
216
+ number = {5},
217
+ pages = {bbag486},
218
+ year = {2026},
219
+ doi = {10.1093/bib/bbag486}
220
+ }
221
+ ```
222
+
223
+ *Questions are welcome, feel free to open an issue or drop me an email.*
224
+
225
+ ## References
226
+
227
+ [1] Pélissier A., Phan M., Beerenwinkel N., Rodríguez Martínez M. Gillespie-based simulation and inference for non-Markovian stochastic reaction networks. *Briefings in Bioinformatics* **27**(5), bbag486 (2026). doi:[10.1093/bib/bbag486](https://doi.org/10.1093/bib/bbag486)
228
+
229
+ [2] Pélissier A., Phan M., Le Bail D., Beerenwinkel N., Rodríguez Martínez M. Unifying non-Markovian dynamics and agent heterogeneity in scalable stochastic networks. *Nature Communications* **17**, 3345 (2026). doi:[10.1038/s41467-026-69817-y](https://doi.org/10.1038/s41467-026-69817-y)
230
+
231
+ [3] Masuda N., Rocha L. E. C. A Gillespie algorithm for non-Markovian stochastic processes. *SIAM Review* **60**(1), 95-115 (2018). doi:[10.1137/16M1055876](https://doi.org/10.1137/16M1055876)
232
+
233
+ [4] Anderson D. F. A modified next reaction method for simulating chemical systems with time dependent propensities and delays. *The Journal of Chemical Physics* **127**(21), 214107 (2007). doi:[10.1063/1.2799998](https://doi.org/10.1063/1.2799998)
nomass-1.0.0/README.md ADDED
@@ -0,0 +1,193 @@
1
+ # NoMaSS: Non-Markovian Stochastic Simulation
2
+
3
+ [![paper](https://img.shields.io/badge/paper-Brief.%20Bioinform.%202026-blue)](https://doi.org/10.1093/bib/bbag486)
4
+ [![license](https://img.shields.io/badge/license-MIT-green)](LICENSE)
5
+ [![pypi](https://img.shields.io/pypi/v/nomass)](https://pypi.org/project/nomass/)
6
+
7
+ <img align="right" src="https://raw.githubusercontent.com/AI-SysBio/NoMaSS/main/figures/NoMaSS.png" width=380>
8
+
9
+ Discrete stochastic processes are widespread in nature and in human-made systems, with applications in physics, biochemistry, epidemiology, social dynamics and finance. In most of these systems the dynamics cannot be described with memoryless (Markovian) interactions, and simulating them requires dedicated numerical tools.
10
+
11
+ NoMaSS is a practical and scalable Gillespie-based framework to simulate non-Markovian reaction networks with arbitrary inter-event time distributions. It implements three exact methods that can be mixed freely in the same model, one per reaction channel:
12
+
13
+ * **MOSAIC** (rejection based, [1, 2]): propose events at an upper bound of the rate and accept them with the ratio of the true hazard to the bound.
14
+ * **Laplace Gillespie** [3]: give every reactant a Poisson rate drawn from the mixing density of its waiting-time distribution.
15
+ * **DelaySSA** [4]: draw the waiting time when a reactant enters a channel and schedule the event in a priority queue.
16
+
17
+ The methods, their accuracy and their speed are described in the accompanying paper [1].
18
+
19
+ &nbsp;
20
+
21
+ ## Installation
22
+
23
+ NoMaSS is deliberately lightweight: the efficiency of the framework lies in the algorithms rather than in compiled extensions, so the engine is pure Python and relies only on the standard scientific stack. Python 3.9 or later is required.
24
+
25
+ ```bash
26
+ pip install nomass
27
+ ```
28
+
29
+ To work on the code or run the scripts of the paper, clone the repository and install it in editable mode:
30
+
31
+ ```bash
32
+ git clone https://github.com/AI-SysBio/NoMaSS.git
33
+ cd NoMaSS
34
+ pip install -e .[test,paper]
35
+ ```
36
+
37
+ Check that everything works with
38
+
39
+ ```bash
40
+ python examples/toy_example.py
41
+ ```
42
+
43
+ ## Quick start
44
+
45
+ The example below ([examples/toy_example.py](examples/toy_example.py)) simulates a small network where each channel uses a different method:
46
+
47
+ ```python
48
+ import nomass
49
+
50
+ # Reaction channels: one waiting-time distribution and one method each
51
+ r1 = nomass.Reaction_channel('A -> B', rate=1, shape_param=20, distribution='Gamma', method='Delay')
52
+ r2 = nomass.Reaction_channel('B -> C + A', rate=4, shape_param=5, distribution='Weibull', method='MOSAIC')
53
+ r3 = nomass.Reaction_channel('C -> 0', rate=0.03, shape_param=0.5, distribution='Gamma', method='Laplace')
54
+ r4 = nomass.Reaction_channel('A + B -> 0', rate=0.03) # two reactants: Poisson process
55
+
56
+ # Initial population (every species must be listed)
57
+ N_init = {'A': 300, 'B': 0, 'C': 0}
58
+
59
+ # Build and run the model
60
+ sim = nomass.Gillespie_simulation(N_init, [r1, r2, r3, r4],
61
+ Tend=10, # length of the simulation
62
+ N_simulations=20, # number of independent realisations
63
+ timepoints=100, # number of recorded time points
64
+ unit='h') # time unit (plots only)
65
+ populations = sim.run_simulations() # array (N_simulations, timepoints, species + total)
66
+
67
+ # Plot the results
68
+ sim.plot_inter_event_time_distribution()
69
+ sim.plot_populations()
70
+ ```
71
+
72
+ The simulation runs in a few seconds and produces the figures below (pass `verbose=False` to silence the progress output).
73
+
74
+ <p align="center">
75
+ <img src="https://raw.githubusercontent.com/AI-SysBio/NoMaSS/main/figures/toy_example.png" width=1000>
76
+ </p>
77
+
78
+ The oscillations created by the nearly deterministic Gamma waiting times are clearly visible. The *theoretical* distributions do not match the *simulated* ones exactly, even with many realisations, and this is expected: species A and B are reactants of two channels at the same time, and the theoretical curve is the distribution the channel would have if it were the only process acting on its reactant. The accuracy of each method is demonstrated in [1] and [2].
79
+
80
+ Reactions are written as strings: `'A + B -> C'`, `'0 -> A'` (creation), `'A -> 0'` (degradation), `'2 A -> B'` (stoichiometry). The plotting methods return their matplotlib figure and axes, so pass `show=False` to customise a figure before displaying it.
81
+
82
+ ## Choosing a method
83
+
84
+ | Method | Set with | Best for | Limitations |
85
+ | --- | --- | --- | --- |
86
+ | MOSAIC (rejection) | `method='MOSAIC'` | Large populations, state-dependent rates, any distribution with a bounded hazard | Hazard must be finite at t = 0 (Gamma and Weibull need a shape ≥ 1) |
87
+ | Laplace Gillespie | `method='Laplace'` | Heavy-tailed or decreasing hazards (Gamma/Weibull with shape < 1, Lomax), state-dependent rates | Only distributions whose survival function is a mixture of exponentials |
88
+ | DelaySSA | `method='Delay'` | Any distribution when rates are constant | Waiting times are frozen when drawn, so rates that change over time are not followed |
89
+
90
+ When `method` is omitted, NoMaSS uses MOSAIC if the hazard is bounded and Laplace Gillespie otherwise. Channels with zero or several reactants are always Poisson processes with propensity `rate × product of the reactant counts`, because the waiting time of an individual is not defined in that case.
91
+
92
+ A Gamma waiting time with an integer shape can also be embedded in a chain of exponential stages (hidden Markov embedding); [examples/erlang_embedding.py](examples/erlang_embedding.py) compares the two descriptions.
93
+
94
+ ## Supported distributions
95
+
96
+ | Distribution | MOSAIC | Laplace | DelaySSA |
97
+ | --- | :---: | :---: | :---: |
98
+ | Exponential | ✅ | ✅ | ✅ |
99
+ | Gamma | ✅ (α ≥ 1) | ✅ (α ≤ 1) | ✅ |
100
+ | Weibull | ✅ (α ≥ 1) | ✅ (α ≤ 1) | ✅ |
101
+ | Gaussian / Normal | ✅ | ❌ | ✅ |
102
+ | Lognormal | ✅ | ❌ | ✅ |
103
+ | Cauchy | ✅ | ❌ | ✅ |
104
+ | Power law, Pareto type I | ✅ | ❌ | ✅ |
105
+ | Power law, Lomax (Pareto type II) | ✅ | ✅ | ✅ |
106
+
107
+ Every distribution is parameterised by a nominal `rate` λ, the inverse of the mean waiting time (or of the median when the mean is undefined), and a dimensionless `shape_param` α (full details in Table S1 of [1]):
108
+
109
+ | Distribution | `rate` | `shape_param` |
110
+ | --- | --- | --- |
111
+ | Exponential | 1 / mean | unused |
112
+ | Gamma | 1 / mean | shape α |
113
+ | Weibull | 1 / mean | shape k |
114
+ | Gaussian | 1 / mean | std / mean |
115
+ | Lognormal | 1 / mean | std / mean |
116
+ | Cauchy | 1 / median | scale / median |
117
+ | Pareto type I | 1 / median | tail index α |
118
+ | Lomax | 1 / median | tail index α |
119
+
120
+ Gaussian and Cauchy waiting times are truncated to non-negative values. Aliases such as `'exp'`, `'norm'`, `'lognorm'` and `'weib'` are accepted. Requesting a combination that a method does not support raises an error at channel creation. [examples/all_distributions.py](examples/all_distributions.py) runs a cycle through all eight distributions.
121
+
122
+ ## State-dependent waiting times
123
+
124
+ Pass `update_function` to change the `rate` or `shape_param` of any channel after every iteration, for example to implement feedback or resource limitation ([examples/state_dependent_rates.py](examples/state_dependent_rates.py)):
125
+
126
+ ```python
127
+ def update_rates(sim):
128
+ N = sim.reactant_population['Cell']
129
+ sim.reaction_channel_list[0].rate = r0 * (1 - N / K) # logistic growth
130
+
131
+ sim = nomass.Gillespie_simulation({'Cell': 5}, [division], Tend=25, update_function=update_rates)
132
+ populations = sim.run_simulations()
133
+ ```
134
+
135
+ MOSAIC and Laplace Gillespie follow such changes exactly (Laplace rates are rescaled when the rate changes and redrawn when the shape changes). Delay-based channels draw their waiting time once, when the reactant enters the channel, so they cannot follow parameters that change afterwards: avoid `method='Delay'` for rapidly changing systems.
136
+
137
+ ## Individual properties
138
+
139
+ Every individual is a `nomass.Reactant` object that can carry arbitrary attributes. The `on_reaction` hook is called after each accepted reaction with the consumed and produced individuals, which is where properties are set or inherited ([examples/individual_properties.py](examples/individual_properties.py)):
140
+
141
+ ```python
142
+ def inherit(sim, channel, consumed, produced):
143
+ if channel is division:
144
+ for daughter in produced:
145
+ daughter.generation = consumed[0].generation + 1
146
+
147
+ sim = nomass.Gillespie_simulation({'Cell': 20}, [division, death], Tend=6, on_reaction=inherit)
148
+ ```
149
+
150
+ Set `transfer_identity=True` on a channel such as `'Gon -> Gon + mRNA'` to keep the same individual (with its properties and the clocks of its other channels) instead of replacing it. For kinetic laws that are not proportional to the reactant counts, subclass `Gillespie_simulation` and override `compute_propensities`; the full API is described in [docs/api.md](docs/api.md), and the hazards, samplers and Laplace mixing densities of all distributions are in [nomass/distributions.py](nomass/distributions.py).
151
+
152
+ ## Repository layout
153
+
154
+ ```
155
+ nomass/ the engine (distributions and simulation)
156
+ docs/ API reference (docs/api.md)
157
+ examples/ short runnable examples
158
+ paper/ scripts, data and precomputed results reproducing the paper's figures
159
+ tests/ pytest suite (pytest -q)
160
+ ```
161
+
162
+ The biochemical systems of the paper (bacterial growth, stem cell differentiation and RNA transcription) live in `paper/`, with a figure-to-script table in [paper/README.md](paper/README.md) and the article with its supplementary material in [paper/Pelissier2026_NoMaSS_main_and_SI.pdf](paper/Pelissier2026_NoMaSS_main_and_SI.pdf).
163
+
164
+ ## Citation
165
+
166
+ If you use NoMaSS, please cite (full text with supplementary material: [paper/Pelissier2026_NoMaSS_main_and_SI.pdf](paper/Pelissier2026_NoMaSS_main_and_SI.pdf))
167
+
168
+ > Pélissier A., Phan M., Beerenwinkel N., Rodríguez Martínez M. *Gillespie-based simulation and inference for non-Markovian stochastic reaction networks.* Briefings in Bioinformatics 27(5), bbag486 (2026). doi:[10.1093/bib/bbag486](https://doi.org/10.1093/bib/bbag486)
169
+
170
+ ```bibtex
171
+ @article{pelissier2026nomass,
172
+ title = {Gillespie-based simulation and inference for non-Markovian stochastic reaction networks},
173
+ author = {P{\'e}lissier, Aur{\'e}lien and Phan, Miroslav and Beerenwinkel, Niko and Rodr{\'i}guez Mart{\'i}nez, Mar{\'i}a},
174
+ journal = {Briefings in Bioinformatics},
175
+ volume = {27},
176
+ number = {5},
177
+ pages = {bbag486},
178
+ year = {2026},
179
+ doi = {10.1093/bib/bbag486}
180
+ }
181
+ ```
182
+
183
+ *Questions are welcome, feel free to open an issue or drop me an email.*
184
+
185
+ ## References
186
+
187
+ [1] Pélissier A., Phan M., Beerenwinkel N., Rodríguez Martínez M. Gillespie-based simulation and inference for non-Markovian stochastic reaction networks. *Briefings in Bioinformatics* **27**(5), bbag486 (2026). doi:[10.1093/bib/bbag486](https://doi.org/10.1093/bib/bbag486)
188
+
189
+ [2] Pélissier A., Phan M., Le Bail D., Beerenwinkel N., Rodríguez Martínez M. Unifying non-Markovian dynamics and agent heterogeneity in scalable stochastic networks. *Nature Communications* **17**, 3345 (2026). doi:[10.1038/s41467-026-69817-y](https://doi.org/10.1038/s41467-026-69817-y)
190
+
191
+ [3] Masuda N., Rocha L. E. C. A Gillespie algorithm for non-Markovian stochastic processes. *SIAM Review* **60**(1), 95-115 (2018). doi:[10.1137/16M1055876](https://doi.org/10.1137/16M1055876)
192
+
193
+ [4] Anderson D. F. A modified next reaction method for simulating chemical systems with time dependent propensities and delays. *The Journal of Chemical Physics* **127**(21), 214107 (2007). doi:[10.1063/1.2799998](https://doi.org/10.1063/1.2799998)
@@ -0,0 +1,29 @@
1
+ """
2
+ NoMaSS: Non-Markovian Stochastic Simulation.
3
+
4
+ A Gillespie-based framework to simulate reaction networks whose inter-event
5
+ times follow arbitrary distributions, mixing three exact methods per reaction
6
+ channel: MOSAIC (rejection), Laplace Gillespie and DelaySSA.
7
+
8
+ Quick start::
9
+
10
+ import nomass
11
+
12
+ r1 = nomass.Reaction_channel('A -> B', rate=1, shape_param=20, distribution='Gamma')
13
+ sim = nomass.Gillespie_simulation({'A': 300, 'B': 0}, [r1], Tend=10, N_simulations=20, unit='h')
14
+ populations = sim.run_simulations()
15
+ sim.plot_populations()
16
+
17
+ Reference: Pelissier A., Phan M., Beerenwinkel N., Rodriguez Martinez M.
18
+ "Gillespie-based simulation and inference for non-Markovian stochastic reaction
19
+ networks", Briefings in Bioinformatics 27(5), bbag486 (2026). doi:10.1093/bib/bbag486
20
+ """
21
+
22
+ from .simulation import Reaction_channel, Reactant, Gillespie_simulation, parse_reaction, PALETTE
23
+ from .distributions import DISTRIBUTIONS, METHODS
24
+ from . import distributions
25
+
26
+ __version__ = '1.0.0'
27
+
28
+ __all__ = ['Reaction_channel', 'Reactant', 'Gillespie_simulation', 'parse_reaction',
29
+ 'distributions', 'DISTRIBUTIONS', 'METHODS', 'PALETTE', '__version__']