process-bigraph 1.8.2__tar.gz → 1.8.4__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.
Files changed (78) hide show
  1. process_bigraph-1.8.4/PKG-INFO +308 -0
  2. process_bigraph-1.8.4/README.md +282 -0
  3. {process_bigraph-1.8.2 → process_bigraph-1.8.4}/process_bigraph/__init__.py +4 -1
  4. {process_bigraph-1.8.2 → process_bigraph-1.8.4}/process_bigraph/artifacts.py +1 -1
  5. {process_bigraph-1.8.2 → process_bigraph-1.8.4}/process_bigraph/composite.py +267 -31
  6. {process_bigraph-1.8.2 → process_bigraph-1.8.4}/process_bigraph/composite_generator.py +27 -19
  7. {process_bigraph-1.8.2 → process_bigraph-1.8.4}/process_bigraph/composite_spec.py +118 -5
  8. process_bigraph-1.8.4/process_bigraph/draft_process.py +135 -0
  9. {process_bigraph-1.8.2 → process_bigraph-1.8.4}/process_bigraph/emitter.py +308 -48
  10. {process_bigraph-1.8.2 → process_bigraph-1.8.4}/process_bigraph/experiments/minimal_gillespie.py +1 -1
  11. process_bigraph-1.8.4/process_bigraph/nextflow.py +775 -0
  12. process_bigraph-1.8.4/process_bigraph/nextflow_deploy.py +140 -0
  13. {process_bigraph-1.8.2 → process_bigraph-1.8.4}/process_bigraph/processes/__init__.py +11 -0
  14. {process_bigraph-1.8.2 → process_bigraph-1.8.4}/process_bigraph/processes/bigraphical_reactive_system.py +1 -1
  15. {process_bigraph-1.8.2 → process_bigraph-1.8.4}/process_bigraph/processes/examples.py +4 -2
  16. {process_bigraph-1.8.2 → process_bigraph-1.8.4}/process_bigraph/processes/reaction.py +30 -4
  17. {process_bigraph-1.8.2 → process_bigraph-1.8.4}/process_bigraph/protocols/__init__.py +11 -1
  18. {process_bigraph-1.8.2 → process_bigraph-1.8.4}/process_bigraph/protocols/clusters/__init__.py +1 -1
  19. {process_bigraph-1.8.2 → process_bigraph-1.8.4}/process_bigraph/protocols/clusters/ec2_ssm.py +2 -3
  20. {process_bigraph-1.8.2 → process_bigraph-1.8.4}/process_bigraph/protocols/git.py +1 -3
  21. {process_bigraph-1.8.2 → process_bigraph-1.8.4}/process_bigraph/protocols/parallel.py +4 -24
  22. {process_bigraph-1.8.2 → process_bigraph-1.8.4}/process_bigraph/protocols/pool.py +1 -1
  23. {process_bigraph-1.8.2 → process_bigraph-1.8.4}/process_bigraph/protocols/ray.py +9 -42
  24. {process_bigraph-1.8.2 → process_bigraph-1.8.4}/process_bigraph/protocols/rest.py +3 -11
  25. {process_bigraph-1.8.2 → process_bigraph-1.8.4}/process_bigraph/protocols/session.py +1 -1
  26. process_bigraph-1.8.4/process_bigraph/run_composite.py +254 -0
  27. {process_bigraph-1.8.2 → process_bigraph-1.8.4}/process_bigraph/run_step.py +10 -1
  28. {process_bigraph-1.8.2 → process_bigraph-1.8.4}/process_bigraph/scheduling.py +1 -2
  29. {process_bigraph-1.8.2 → process_bigraph-1.8.4}/process_bigraph/server/rest.py +25 -5
  30. process_bigraph-1.8.4/process_bigraph/types/__init__.py +10 -0
  31. {process_bigraph-1.8.2 → process_bigraph-1.8.4}/process_bigraph/types/process.py +6 -6
  32. process_bigraph-1.8.4/process_bigraph/wiring_translator.py +236 -0
  33. process_bigraph-1.8.4/process_bigraph/workflow/__init__.py +11 -0
  34. process_bigraph-1.8.4/process_bigraph/workflow/backend.py +165 -0
  35. process_bigraph-1.8.4/process_bigraph/workflow/provision.py +51 -0
  36. process_bigraph-1.8.4/process_bigraph/workflow/recipe.py +249 -0
  37. process_bigraph-1.8.4/process_bigraph/workflow/tasks.py +428 -0
  38. process_bigraph-1.8.4/process_bigraph.egg-info/PKG-INFO +308 -0
  39. {process_bigraph-1.8.2 → process_bigraph-1.8.4}/process_bigraph.egg-info/SOURCES.txt +13 -1
  40. {process_bigraph-1.8.2 → process_bigraph-1.8.4}/process_bigraph.egg-info/requires.txt +1 -1
  41. {process_bigraph-1.8.2 → process_bigraph-1.8.4}/pyproject.toml +21 -11
  42. process_bigraph-1.8.4/tests/test_process_decorator.py +182 -0
  43. process_bigraph-1.8.4/tests/test_reaction_step.py +80 -0
  44. process_bigraph-1.8.4/tests/test_units.py +50 -0
  45. process_bigraph-1.8.2/PKG-INFO +0 -182
  46. process_bigraph-1.8.2/README.md +0 -156
  47. process_bigraph-1.8.2/process_bigraph/nextflow.py +0 -438
  48. process_bigraph-1.8.2/process_bigraph/types/__init__.py +0 -2
  49. process_bigraph-1.8.2/process_bigraph.egg-info/PKG-INFO +0 -182
  50. {process_bigraph-1.8.2 → process_bigraph-1.8.4}/AUTHORS.md +0 -0
  51. {process_bigraph-1.8.2 → process_bigraph-1.8.4}/LICENSE +0 -0
  52. {process_bigraph-1.8.2 → process_bigraph-1.8.4}/process_bigraph/bundle.py +0 -0
  53. {process_bigraph-1.8.2 → process_bigraph-1.8.4}/process_bigraph/composite_discovery.py +0 -0
  54. {process_bigraph-1.8.2 → process_bigraph-1.8.4}/process_bigraph/config_helpers.py +0 -0
  55. {process_bigraph-1.8.2 → process_bigraph-1.8.4}/process_bigraph/core_introspection.py +0 -0
  56. {process_bigraph-1.8.2 → process_bigraph-1.8.4}/process_bigraph/experiments/__init__.py +0 -0
  57. {process_bigraph-1.8.2 → process_bigraph-1.8.4}/process_bigraph/plumbing.py +0 -0
  58. {process_bigraph-1.8.2 → process_bigraph-1.8.4}/process_bigraph/processes/cached.py +0 -0
  59. {process_bigraph-1.8.2 → process_bigraph-1.8.4}/process_bigraph/processes/dynamic_structure.py +0 -0
  60. {process_bigraph-1.8.2 → process_bigraph-1.8.4}/process_bigraph/processes/growth_division.py +0 -0
  61. {process_bigraph-1.8.2 → process_bigraph-1.8.4}/process_bigraph/processes/parameter_scan.py +0 -0
  62. {process_bigraph-1.8.2 → process_bigraph-1.8.4}/process_bigraph/processes/simulation.py +0 -0
  63. {process_bigraph-1.8.2 → process_bigraph-1.8.4}/process_bigraph/protocols/_git_worker.py +0 -0
  64. {process_bigraph-1.8.2 → process_bigraph-1.8.4}/process_bigraph/run.py +0 -0
  65. {process_bigraph-1.8.2 → process_bigraph-1.8.4}/process_bigraph/server/__init__.py +0 -0
  66. {process_bigraph-1.8.2 → process_bigraph-1.8.4}/process_bigraph/server/start.py +0 -0
  67. {process_bigraph-1.8.2 → process_bigraph-1.8.4}/process_bigraph/templates.py +0 -0
  68. {process_bigraph-1.8.2 → process_bigraph-1.8.4}/process_bigraph/visualization.py +0 -0
  69. {process_bigraph-1.8.2 → process_bigraph-1.8.4}/process_bigraph/visualizations/__init__.py +0 -0
  70. {process_bigraph-1.8.2 → process_bigraph-1.8.4}/process_bigraph/visualizations/distribution.py +0 -0
  71. {process_bigraph-1.8.2 → process_bigraph-1.8.4}/process_bigraph/visualizations/heatmap.py +0 -0
  72. {process_bigraph-1.8.2 → process_bigraph-1.8.4}/process_bigraph/visualizations/param_vs_observable.py +0 -0
  73. {process_bigraph-1.8.2 → process_bigraph-1.8.4}/process_bigraph/visualizations/phase_space.py +0 -0
  74. {process_bigraph-1.8.2 → process_bigraph-1.8.4}/process_bigraph/visualizations/time_series.py +0 -0
  75. {process_bigraph-1.8.2 → process_bigraph-1.8.4}/process_bigraph/visualizations/timeseries_from_observables.py +0 -0
  76. {process_bigraph-1.8.2 → process_bigraph-1.8.4}/process_bigraph.egg-info/dependency_links.txt +0 -0
  77. {process_bigraph-1.8.2 → process_bigraph-1.8.4}/process_bigraph.egg-info/top_level.txt +0 -0
  78. {process_bigraph-1.8.2 → process_bigraph-1.8.4}/setup.cfg +0 -0
@@ -0,0 +1,308 @@
1
+ Metadata-Version: 2.4
2
+ Name: process-bigraph
3
+ Version: 1.8.4
4
+ Summary: protocol and execution for compositional systems biology
5
+ Requires-Python: >=3.11
6
+ Description-Content-Type: text/markdown
7
+ License-File: LICENSE
8
+ License-File: AUTHORS.md
9
+ Requires-Dist: bigraph-schema>=1.6.0
10
+ Requires-Dist: matplotlib
11
+ Requires-Dist: pint>=0.24.4
12
+ Requires-Dist: scipy>=1.8
13
+ Requires-Dist: pandas
14
+ Requires-Dist: sympy
15
+ Provides-Extra: ray
16
+ Requires-Dist: ray>=2.10; extra == "ray"
17
+ Provides-Extra: server-rest
18
+ Requires-Dist: fastapi>=0.116.1; extra == "server-rest"
19
+ Requires-Dist: fastapi-utils>=0.8.0; extra == "server-rest"
20
+ Requires-Dist: uvicorn>=0.35.0; extra == "server-rest"
21
+ Requires-Dist: fire; extra == "server-rest"
22
+ Requires-Dist: typing-inspect>=0.9.0; extra == "server-rest"
23
+ Provides-Extra: ec2-ssm
24
+ Requires-Dist: boto3>=1.28; extra == "ec2-ssm"
25
+ Dynamic: license-file
26
+
27
+ # Process-Bigraph
28
+
29
+ [![PyPI](https://img.shields.io/pypi/v/process-bigraph.svg)](https://pypi.org/project/process-bigraph/)
30
+ [![GitHub Pages](https://img.shields.io/badge/GitHub%20Pages-Tutorials-brightgreen)](https://vivarium-collective.github.io/process-bigraph/notebooks/index.html)
31
+
32
+ **Process-Bigraph** is a compositional runtime and protocol for building and executing
33
+ **multiscale biological models from interoperable processes**.
34
+
35
+ It provides a shared architectural layer for:
36
+ - declaring **process interfaces**
37
+ - wiring processes through **typed shared state**
38
+ - orchestrating execution across **heterogeneous timescales**
39
+ - supporting **dynamic structure** (workflows, division, graph rewrites)
40
+
41
+ Process-Bigraph is the execution core of **Vivarium 2.0**, designed to integrate models
42
+ built with different formalisms—including ODEs, FBA, agent-based models, spatial solvers,
43
+ and machine-learning components—into a single coherent simulation.
44
+
45
+ <p align="center">
46
+ <img src="https://github.com/vivarium-collective/process-bigraph/blob/main/docs/_static/composition_framework.png?raw=true"
47
+ width="800"
48
+ alt="Process Bigraph composition framework">
49
+ </p>
50
+
51
+ ---
52
+
53
+ ## 🧩 What is a Process Bigraph?
54
+
55
+ A **process bigraph** combines:
56
+
57
+ - **Typed stores** — hierarchical, schema-validated state defined with
58
+ [**bigraph-schema**](https://github.com/vivarium-collective/bigraph-schema)
59
+ - **Processes** — executable components with explicit input/output ports
60
+ - **Composites** — encapsulated sub-simulations with their own internal structure
61
+ - **Orchestration patterns** — multi-timestepping, directed workflows, and event-driven rewrites
62
+
63
+ Processes do **not** mutate state directly.
64
+ Instead, they emit **typed deltas** that are merged by the runtime.
65
+
66
+ This allows:
67
+ - numerical updates
68
+ - structural rewrites
69
+ - scheduling and orchestration
70
+
71
+ to coexist under a single execution semantics.
72
+
73
+ In this sense, Process-Bigraph is a **composition protocol**, not a domain-specific simulator.
74
+
75
+ ---
76
+
77
+ ## 📄 Paper reference
78
+
79
+ The conceptual framework and formal semantics of process bigraphs are introduced in:
80
+
81
+ > **Agmon, E. & Spangler, R. K.**
82
+ > *Process Bigraphs and the Architecture of Compositional Systems Biology*
83
+ > https://arxiv.org/abs/2512.23754
84
+
85
+ ---
86
+
87
+ ## 🚀 Getting Started
88
+
89
+ ### Installation
90
+
91
+ ```console
92
+ pip install process-bigraph
93
+ ```
94
+
95
+ ### Quickstart — composites, drafts & templates in code
96
+
97
+ A runnable five-minute tour of the core concepts. Every block below runs as-is
98
+ against `process-bigraph ≥ 1.8.3`. Concepts explained in
99
+ [`docs/concepts/composites-and-templates.md`](docs/concepts/composites-and-templates.md).
100
+
101
+ **1. A process wired into a composite over a shared store.** A composite is a `state`
102
+ map of typed nodes; processes couple only by reading/writing shared stores.
103
+
104
+ ```python
105
+ from process_bigraph import Composite, Process, allocate_core
106
+ from process_bigraph.emitter import emitter_from_wires, gather_emitter_results
107
+
108
+ class Grow(Process): # a Process = ports + an update
109
+ config_schema = {'rate': 'float'}
110
+ def inputs(self): return {'level': 'float'}
111
+ def outputs(self): return {'level': 'float'}
112
+ def update(self, state, interval):
113
+ return {'level': state['level'] * self.config['rate'] * interval} # a delta
114
+
115
+ core = allocate_core()
116
+ core.register_link('Grow', Grow) # register it in the local registry
117
+
118
+ composite = Composite({'state': {
119
+ 'level': 1.0, # a shared store
120
+ 'grow': {'_type': 'process', 'address': 'local:Grow', 'config': {'rate': 0.5},
121
+ 'interval': 1.0, 'inputs': {'level': ['level']}, 'outputs': {'level': ['level']}},
122
+ 'emitter': emitter_from_wires({'level': ['level'], 'time': ['global_time']}),
123
+ }}, core=core)
124
+ composite.run(5.0)
125
+ print(gather_emitter_results(composite))
126
+ # {('emitter',): [{'level': 1.0, 'time': 0.0}, {'level': 1.5, ...}, ... {'level': 7.59, 'time': 5.0}]}
127
+ ```
128
+
129
+ **2. A draft process — a present-but-inert placeholder node.** It declares a contract
130
+ (ports + description) but has no `update`, so a composite containing it still runs; the
131
+ draft just no-ops. Complementary to a *site* (step 3): a draft is a node that is *there
132
+ but inert*, a site is an empty *hole*.
133
+
134
+ ```python
135
+ from process_bigraph import DraftProcess, draft_process
136
+
137
+ @draft_process(name="PTH secretion",
138
+ inputs={'ca_sense': 'float'}, outputs={'pth_out': 'float'},
139
+ contract={'summary': 'senses serum Ca, secretes PTH', 'senses': 'calcium', 'makes': 'PTH'})
140
+ class PTHSecretion(DraftProcess):
141
+ pass
142
+
143
+ core.register_link('PTHSecretion', PTHSecretion)
144
+ print(PTHSecretion({}, core=core).describe())
145
+ # DRAFT — senses serum Ca, secretes PTH · makes: PTH · senses: calcium · status: draft - no update dynamics yet
146
+ ```
147
+
148
+ A module-scope draft auto-registers, so it appears in the vivarium-workbench dashboard
149
+ (Modules → Processes) marked **DRAFT** with its ports and contract — no code change
150
+ needed. Replace it with a real `Process` once the mechanism is committed.
151
+
152
+ **3. A template — a composite with an open site (hole).** A template is a document that
153
+ isn't *ground*: it has open **sites** (`{"_type": "site"}`). `Composite` refuses to run
154
+ one until every required site is filled.
155
+
156
+ ```python
157
+ from process_bigraph import Step
158
+ from process_bigraph.templates import open_sites, is_ground_document, template_document
159
+
160
+ class ReportCard(Step): # a fixed downstream verdict
161
+ config_schema = {'threshold': 'float'}
162
+ def inputs(self): return {'level': 'float'}
163
+ def outputs(self): return {'verdict': 'string'}
164
+ def update(self, state):
165
+ return {'verdict': 'pass' if state['level'] >= self.config['threshold'] else 'fail'}
166
+
167
+ core.register_link('ReportCard', ReportCard)
168
+ MODEL_FACE = {'_type': 'link', '_inputs': {'level': 'float'}, '_outputs': {'level': 'float'}}
169
+
170
+ template = core.access({'study': { # analysis fixed, the model is a HOLE
171
+ 'level': 1.0, 'verdict': 'string',
172
+ 'model': {'_type': 'site', '_sort': MODEL_FACE},
173
+ 'report': {'_type': 'step', 'address': 'local:ReportCard', 'config': {'threshold': 2.0},
174
+ 'inputs': {'level': ['level']}, 'outputs': {'verdict': ['verdict']}}}})
175
+
176
+ print(open_sites(template), is_ground_document(template)) # [('study', 'model')] False
177
+
178
+ def model(rate): # any conforming composite fits the hole
179
+ return core.access({'_type': 'process', 'address': 'local:Grow', 'config': {'rate': rate},
180
+ 'interval': 1.0, 'inputs': {'level': ['level']}, 'outputs': {'level': ['level']}})
181
+
182
+ sim = Composite({'state': template_document(core, template, {'study/model': model(0.5)})}, core=core)
183
+ sim.run(4.0)
184
+ print(sim.state['study']['verdict']) # pass (a slower model → fail)
185
+ # template_document(core, template, {}) → ValueError: not ground — required site 'study/model'
186
+ ```
187
+
188
+ **4. An investigation — one site per member study; gating is *filling*.** Fill a
189
+ member's site to admit it; leave it open and it is pruned from the built document, so a
190
+ blocked prerequisite simply never runs.
191
+
192
+ ```python
193
+ from process_bigraph.templates import investigation_document
194
+
195
+ study = lambda: {'level': 1.0, 'verdict': 'string',
196
+ 'model': {'_type': 'site', '_sort': MODEL_FACE},
197
+ 'report': {'_type': 'step', 'address': 'local:ReportCard', 'config': {'threshold': 2.0},
198
+ 'inputs': {'level': ['level']}, 'outputs': {'verdict': ['verdict']}}}
199
+
200
+ inv = core.access({'investigation': {'study_A': study(), 'study_B': study()}})
201
+ document, blocked = investigation_document(
202
+ core, inv, {'investigation/study_A/model': model(0.5)}, member_depth=2) # fill A only
203
+ print(blocked, sorted(document['investigation'])) # ['investigation/study_B'] ['study_A']
204
+ ```
205
+
206
+ > This same template/site machinery is what viva-superpowers uses to compile a whole
207
+ > **investigation into a composite** (one `StudyStep` per member). The study/investigation
208
+ > layer is documented in viva-superpowers
209
+ > `docs/concepts/composites-templates-and-the-study-investigation-stack.md`.
210
+
211
+ ## 📘 Tutorials
212
+
213
+ The Process-Bigraph tutorials are executable Jupyter notebooks,
214
+ rendered to HTML and published automatically on GitHub Pages.
215
+
216
+ - 📚 **Tutorial Index (all tutorials)**
217
+ https://vivarium-collective.github.io/process-bigraph/notebooks/index.html
218
+
219
+ ### Learning Path (Featured Tutorials)
220
+
221
+ - **Tutorial 0 — A Process in 12 Lines (quickstart)**
222
+ *The new front door: define a process with the `@process` decorator, wire and
223
+ run it end-to-end on one screen, and watch a `_units`-bearing port auto-convert*
224
+ https://vivarium-collective.github.io/process-bigraph/notebooks/tutorial_0_quickstart.html
225
+
226
+ - **Tutorial 1 — Process-Bigraph Basics**
227
+ *Processes, Steps, ports, Composites, workflows, and emitters*
228
+ https://vivarium-collective.github.io/process-bigraph/notebooks/tutorial_1.html
229
+
230
+ - **Tutorial 2 — Wrapping an ODE Solver (`odeint`)**
231
+ *How to expose an existing scientific API as a Process*
232
+ https://vivarium-collective.github.io/process-bigraph/notebooks/tutorial_2.html
233
+
234
+ - **Tutorial 3 — Declarative Math**
235
+ *Defining mathematical relationships, signal pipelines, and events using `MathExpressionStep`*
236
+ https://vivarium-collective.github.io/process-bigraph/notebooks/tutorial_3.html
237
+
238
+ - **Tutorial 4 — Composing a Biological Model**
239
+ *The central dogma from four small processes: composition over shared molecular state, biological units in the port types, and adding regulation by adding a wire*
240
+ https://vivarium-collective.github.io/process-bigraph/notebooks/tutorial_4.html
241
+
242
+ More tutorials are added continuously and appear automatically in the index.
243
+
244
+ ### Architecture
245
+
246
+ - **The framework, end to end** — *start here to understand the whole system:
247
+ what the objects are (documents, sites, handles), how they compose, the
248
+ higher-order DAG, templates and gating, content-addressed artifacts, the
249
+ `git:` protocol, and the laws everything else follows from.*
250
+ [docs/architecture.md](docs/architecture.md)
251
+
252
+ ### Topic Guides
253
+
254
+ - **Emitters — Recording Simulation Results**
255
+ *Built-in emitters (RAM, console, JSON, SQLite), how to wire them, retrieve results, store runs long-term, and write your own.*
256
+ [docs/emitters.md](docs/emitters.md)
257
+
258
+ - **Tick lifecycle** — *how a step network is ordered and advanced, and how a
259
+ protocol runtime batches remote dispatch.*
260
+ [docs/tick_lifecycle.md](docs/tick_lifecycle.md)
261
+
262
+ - **Distributed lifecycles** — *running parts of a composite off-process.*
263
+ [docs/distributed_lifecycles.md](docs/distributed_lifecycles.md)
264
+
265
+ - **Deploying a Step network to Nextflow** — *opt-in: compile a composite's
266
+ Step network into a Nextflow DSL2 workflow and run it on a batch backend
267
+ (local / SLURM). Nothing changes about `Composite.run()`.*
268
+ [docs/nextflow.md](docs/nextflow.md)
269
+
270
+ ---
271
+
272
+ ## 🧪 Reference Implementation: spatio-flux
273
+
274
+ Process-Bigraph is exercised end-to-end in **spatio-flux**, a multiscale reference
275
+ model built entirely using the process-bigraph protocol.
276
+
277
+ spatio-flux composes spatial fields, particle dynamics, and metabolic processes
278
+ using typed shared state and declarative orchestration.
279
+
280
+ GitHub: https://github.com/vivarium-collective/spatio-flux
281
+ Live test report: https://vivarium-collective.github.io/spatio-flux/report/index.html
282
+
283
+ ---
284
+
285
+ ## 🔗 Related Resources
286
+
287
+ - **Bigraph Schema Basics**
288
+ https://vivarium-collective.github.io/bigraph-viz/notebooks/basics.html
289
+ *Introduction to the schema language underlying Process-Bigraph*
290
+
291
+ - **Visualization of Bigraph Document** — diagramming and rendering with
292
+ [**bigraph-viz**](https://github.com/vivarium-collective/bigraph-viz)
293
+ https://vivarium-collective.github.io/bigraph-viz/notebooks/format.html
294
+
295
+ - **E. coli Whole-Cell Wiring Diagram**
296
+ https://raw.githubusercontent.com/vivarium-collective/bigraph-viz/main/doc/_static/ecoli.png
297
+
298
+ - **Claude Code skills** — wrap simulators, compose `pbg-*` packages, and
299
+ scaffold process-bigraph research workspaces with the
300
+ [**pbg-superpowers**](https://github.com/vivarium-collective/pbg-superpowers)
301
+ Claude Code plugin (install with `/plugin install pbg-superpowers`).
302
+
303
+ ---
304
+
305
+ ## 📜 License
306
+
307
+ Process-Bigraph is open-source software released under the
308
+ [Apache 2 License](https://github.com/vivarium-collective/process-bigraph/blob/main/LICENSE).
@@ -0,0 +1,282 @@
1
+ # Process-Bigraph
2
+
3
+ [![PyPI](https://img.shields.io/pypi/v/process-bigraph.svg)](https://pypi.org/project/process-bigraph/)
4
+ [![GitHub Pages](https://img.shields.io/badge/GitHub%20Pages-Tutorials-brightgreen)](https://vivarium-collective.github.io/process-bigraph/notebooks/index.html)
5
+
6
+ **Process-Bigraph** is a compositional runtime and protocol for building and executing
7
+ **multiscale biological models from interoperable processes**.
8
+
9
+ It provides a shared architectural layer for:
10
+ - declaring **process interfaces**
11
+ - wiring processes through **typed shared state**
12
+ - orchestrating execution across **heterogeneous timescales**
13
+ - supporting **dynamic structure** (workflows, division, graph rewrites)
14
+
15
+ Process-Bigraph is the execution core of **Vivarium 2.0**, designed to integrate models
16
+ built with different formalisms—including ODEs, FBA, agent-based models, spatial solvers,
17
+ and machine-learning components—into a single coherent simulation.
18
+
19
+ <p align="center">
20
+ <img src="https://github.com/vivarium-collective/process-bigraph/blob/main/docs/_static/composition_framework.png?raw=true"
21
+ width="800"
22
+ alt="Process Bigraph composition framework">
23
+ </p>
24
+
25
+ ---
26
+
27
+ ## 🧩 What is a Process Bigraph?
28
+
29
+ A **process bigraph** combines:
30
+
31
+ - **Typed stores** — hierarchical, schema-validated state defined with
32
+ [**bigraph-schema**](https://github.com/vivarium-collective/bigraph-schema)
33
+ - **Processes** — executable components with explicit input/output ports
34
+ - **Composites** — encapsulated sub-simulations with their own internal structure
35
+ - **Orchestration patterns** — multi-timestepping, directed workflows, and event-driven rewrites
36
+
37
+ Processes do **not** mutate state directly.
38
+ Instead, they emit **typed deltas** that are merged by the runtime.
39
+
40
+ This allows:
41
+ - numerical updates
42
+ - structural rewrites
43
+ - scheduling and orchestration
44
+
45
+ to coexist under a single execution semantics.
46
+
47
+ In this sense, Process-Bigraph is a **composition protocol**, not a domain-specific simulator.
48
+
49
+ ---
50
+
51
+ ## 📄 Paper reference
52
+
53
+ The conceptual framework and formal semantics of process bigraphs are introduced in:
54
+
55
+ > **Agmon, E. & Spangler, R. K.**
56
+ > *Process Bigraphs and the Architecture of Compositional Systems Biology*
57
+ > https://arxiv.org/abs/2512.23754
58
+
59
+ ---
60
+
61
+ ## 🚀 Getting Started
62
+
63
+ ### Installation
64
+
65
+ ```console
66
+ pip install process-bigraph
67
+ ```
68
+
69
+ ### Quickstart — composites, drafts & templates in code
70
+
71
+ A runnable five-minute tour of the core concepts. Every block below runs as-is
72
+ against `process-bigraph ≥ 1.8.3`. Concepts explained in
73
+ [`docs/concepts/composites-and-templates.md`](docs/concepts/composites-and-templates.md).
74
+
75
+ **1. A process wired into a composite over a shared store.** A composite is a `state`
76
+ map of typed nodes; processes couple only by reading/writing shared stores.
77
+
78
+ ```python
79
+ from process_bigraph import Composite, Process, allocate_core
80
+ from process_bigraph.emitter import emitter_from_wires, gather_emitter_results
81
+
82
+ class Grow(Process): # a Process = ports + an update
83
+ config_schema = {'rate': 'float'}
84
+ def inputs(self): return {'level': 'float'}
85
+ def outputs(self): return {'level': 'float'}
86
+ def update(self, state, interval):
87
+ return {'level': state['level'] * self.config['rate'] * interval} # a delta
88
+
89
+ core = allocate_core()
90
+ core.register_link('Grow', Grow) # register it in the local registry
91
+
92
+ composite = Composite({'state': {
93
+ 'level': 1.0, # a shared store
94
+ 'grow': {'_type': 'process', 'address': 'local:Grow', 'config': {'rate': 0.5},
95
+ 'interval': 1.0, 'inputs': {'level': ['level']}, 'outputs': {'level': ['level']}},
96
+ 'emitter': emitter_from_wires({'level': ['level'], 'time': ['global_time']}),
97
+ }}, core=core)
98
+ composite.run(5.0)
99
+ print(gather_emitter_results(composite))
100
+ # {('emitter',): [{'level': 1.0, 'time': 0.0}, {'level': 1.5, ...}, ... {'level': 7.59, 'time': 5.0}]}
101
+ ```
102
+
103
+ **2. A draft process — a present-but-inert placeholder node.** It declares a contract
104
+ (ports + description) but has no `update`, so a composite containing it still runs; the
105
+ draft just no-ops. Complementary to a *site* (step 3): a draft is a node that is *there
106
+ but inert*, a site is an empty *hole*.
107
+
108
+ ```python
109
+ from process_bigraph import DraftProcess, draft_process
110
+
111
+ @draft_process(name="PTH secretion",
112
+ inputs={'ca_sense': 'float'}, outputs={'pth_out': 'float'},
113
+ contract={'summary': 'senses serum Ca, secretes PTH', 'senses': 'calcium', 'makes': 'PTH'})
114
+ class PTHSecretion(DraftProcess):
115
+ pass
116
+
117
+ core.register_link('PTHSecretion', PTHSecretion)
118
+ print(PTHSecretion({}, core=core).describe())
119
+ # DRAFT — senses serum Ca, secretes PTH · makes: PTH · senses: calcium · status: draft - no update dynamics yet
120
+ ```
121
+
122
+ A module-scope draft auto-registers, so it appears in the vivarium-workbench dashboard
123
+ (Modules → Processes) marked **DRAFT** with its ports and contract — no code change
124
+ needed. Replace it with a real `Process` once the mechanism is committed.
125
+
126
+ **3. A template — a composite with an open site (hole).** A template is a document that
127
+ isn't *ground*: it has open **sites** (`{"_type": "site"}`). `Composite` refuses to run
128
+ one until every required site is filled.
129
+
130
+ ```python
131
+ from process_bigraph import Step
132
+ from process_bigraph.templates import open_sites, is_ground_document, template_document
133
+
134
+ class ReportCard(Step): # a fixed downstream verdict
135
+ config_schema = {'threshold': 'float'}
136
+ def inputs(self): return {'level': 'float'}
137
+ def outputs(self): return {'verdict': 'string'}
138
+ def update(self, state):
139
+ return {'verdict': 'pass' if state['level'] >= self.config['threshold'] else 'fail'}
140
+
141
+ core.register_link('ReportCard', ReportCard)
142
+ MODEL_FACE = {'_type': 'link', '_inputs': {'level': 'float'}, '_outputs': {'level': 'float'}}
143
+
144
+ template = core.access({'study': { # analysis fixed, the model is a HOLE
145
+ 'level': 1.0, 'verdict': 'string',
146
+ 'model': {'_type': 'site', '_sort': MODEL_FACE},
147
+ 'report': {'_type': 'step', 'address': 'local:ReportCard', 'config': {'threshold': 2.0},
148
+ 'inputs': {'level': ['level']}, 'outputs': {'verdict': ['verdict']}}}})
149
+
150
+ print(open_sites(template), is_ground_document(template)) # [('study', 'model')] False
151
+
152
+ def model(rate): # any conforming composite fits the hole
153
+ return core.access({'_type': 'process', 'address': 'local:Grow', 'config': {'rate': rate},
154
+ 'interval': 1.0, 'inputs': {'level': ['level']}, 'outputs': {'level': ['level']}})
155
+
156
+ sim = Composite({'state': template_document(core, template, {'study/model': model(0.5)})}, core=core)
157
+ sim.run(4.0)
158
+ print(sim.state['study']['verdict']) # pass (a slower model → fail)
159
+ # template_document(core, template, {}) → ValueError: not ground — required site 'study/model'
160
+ ```
161
+
162
+ **4. An investigation — one site per member study; gating is *filling*.** Fill a
163
+ member's site to admit it; leave it open and it is pruned from the built document, so a
164
+ blocked prerequisite simply never runs.
165
+
166
+ ```python
167
+ from process_bigraph.templates import investigation_document
168
+
169
+ study = lambda: {'level': 1.0, 'verdict': 'string',
170
+ 'model': {'_type': 'site', '_sort': MODEL_FACE},
171
+ 'report': {'_type': 'step', 'address': 'local:ReportCard', 'config': {'threshold': 2.0},
172
+ 'inputs': {'level': ['level']}, 'outputs': {'verdict': ['verdict']}}}
173
+
174
+ inv = core.access({'investigation': {'study_A': study(), 'study_B': study()}})
175
+ document, blocked = investigation_document(
176
+ core, inv, {'investigation/study_A/model': model(0.5)}, member_depth=2) # fill A only
177
+ print(blocked, sorted(document['investigation'])) # ['investigation/study_B'] ['study_A']
178
+ ```
179
+
180
+ > This same template/site machinery is what viva-superpowers uses to compile a whole
181
+ > **investigation into a composite** (one `StudyStep` per member). The study/investigation
182
+ > layer is documented in viva-superpowers
183
+ > `docs/concepts/composites-templates-and-the-study-investigation-stack.md`.
184
+
185
+ ## 📘 Tutorials
186
+
187
+ The Process-Bigraph tutorials are executable Jupyter notebooks,
188
+ rendered to HTML and published automatically on GitHub Pages.
189
+
190
+ - 📚 **Tutorial Index (all tutorials)**
191
+ https://vivarium-collective.github.io/process-bigraph/notebooks/index.html
192
+
193
+ ### Learning Path (Featured Tutorials)
194
+
195
+ - **Tutorial 0 — A Process in 12 Lines (quickstart)**
196
+ *The new front door: define a process with the `@process` decorator, wire and
197
+ run it end-to-end on one screen, and watch a `_units`-bearing port auto-convert*
198
+ https://vivarium-collective.github.io/process-bigraph/notebooks/tutorial_0_quickstart.html
199
+
200
+ - **Tutorial 1 — Process-Bigraph Basics**
201
+ *Processes, Steps, ports, Composites, workflows, and emitters*
202
+ https://vivarium-collective.github.io/process-bigraph/notebooks/tutorial_1.html
203
+
204
+ - **Tutorial 2 — Wrapping an ODE Solver (`odeint`)**
205
+ *How to expose an existing scientific API as a Process*
206
+ https://vivarium-collective.github.io/process-bigraph/notebooks/tutorial_2.html
207
+
208
+ - **Tutorial 3 — Declarative Math**
209
+ *Defining mathematical relationships, signal pipelines, and events using `MathExpressionStep`*
210
+ https://vivarium-collective.github.io/process-bigraph/notebooks/tutorial_3.html
211
+
212
+ - **Tutorial 4 — Composing a Biological Model**
213
+ *The central dogma from four small processes: composition over shared molecular state, biological units in the port types, and adding regulation by adding a wire*
214
+ https://vivarium-collective.github.io/process-bigraph/notebooks/tutorial_4.html
215
+
216
+ More tutorials are added continuously and appear automatically in the index.
217
+
218
+ ### Architecture
219
+
220
+ - **The framework, end to end** — *start here to understand the whole system:
221
+ what the objects are (documents, sites, handles), how they compose, the
222
+ higher-order DAG, templates and gating, content-addressed artifacts, the
223
+ `git:` protocol, and the laws everything else follows from.*
224
+ [docs/architecture.md](docs/architecture.md)
225
+
226
+ ### Topic Guides
227
+
228
+ - **Emitters — Recording Simulation Results**
229
+ *Built-in emitters (RAM, console, JSON, SQLite), how to wire them, retrieve results, store runs long-term, and write your own.*
230
+ [docs/emitters.md](docs/emitters.md)
231
+
232
+ - **Tick lifecycle** — *how a step network is ordered and advanced, and how a
233
+ protocol runtime batches remote dispatch.*
234
+ [docs/tick_lifecycle.md](docs/tick_lifecycle.md)
235
+
236
+ - **Distributed lifecycles** — *running parts of a composite off-process.*
237
+ [docs/distributed_lifecycles.md](docs/distributed_lifecycles.md)
238
+
239
+ - **Deploying a Step network to Nextflow** — *opt-in: compile a composite's
240
+ Step network into a Nextflow DSL2 workflow and run it on a batch backend
241
+ (local / SLURM). Nothing changes about `Composite.run()`.*
242
+ [docs/nextflow.md](docs/nextflow.md)
243
+
244
+ ---
245
+
246
+ ## 🧪 Reference Implementation: spatio-flux
247
+
248
+ Process-Bigraph is exercised end-to-end in **spatio-flux**, a multiscale reference
249
+ model built entirely using the process-bigraph protocol.
250
+
251
+ spatio-flux composes spatial fields, particle dynamics, and metabolic processes
252
+ using typed shared state and declarative orchestration.
253
+
254
+ GitHub: https://github.com/vivarium-collective/spatio-flux
255
+ Live test report: https://vivarium-collective.github.io/spatio-flux/report/index.html
256
+
257
+ ---
258
+
259
+ ## 🔗 Related Resources
260
+
261
+ - **Bigraph Schema Basics**
262
+ https://vivarium-collective.github.io/bigraph-viz/notebooks/basics.html
263
+ *Introduction to the schema language underlying Process-Bigraph*
264
+
265
+ - **Visualization of Bigraph Document** — diagramming and rendering with
266
+ [**bigraph-viz**](https://github.com/vivarium-collective/bigraph-viz)
267
+ https://vivarium-collective.github.io/bigraph-viz/notebooks/format.html
268
+
269
+ - **E. coli Whole-Cell Wiring Diagram**
270
+ https://raw.githubusercontent.com/vivarium-collective/bigraph-viz/main/doc/_static/ecoli.png
271
+
272
+ - **Claude Code skills** — wrap simulators, compose `pbg-*` packages, and
273
+ scaffold process-bigraph research workspaces with the
274
+ [**pbg-superpowers**](https://github.com/vivarium-collective/pbg-superpowers)
275
+ Claude Code plugin (install with `/plugin install pbg-superpowers`).
276
+
277
+ ---
278
+
279
+ ## 📜 License
280
+
281
+ Process-Bigraph is open-source software released under the
282
+ [Apache 2 License](https://github.com/vivarium-collective/process-bigraph/blob/main/LICENSE).
@@ -18,12 +18,14 @@ except ImportError: # pragma: no cover — py<3.8
18
18
 
19
19
  from process_bigraph.composite import ( # noqa: F401
20
20
  Process, Step, Composite, TimingSummary, interval_time_precision, wire_step_layers,
21
+ process, step, as_process, as_step,
21
22
  )
22
23
  from process_bigraph.composite_spec import ( # noqa: F401
23
- CompositeSpec, discover_specs, regenerate_default_state,
24
+ CompositeSpec, discover_specs, register_spec_generator, regenerate_default_state,
24
25
  normalize_type, CANONICAL_TYPES,
25
26
  )
26
27
  from process_bigraph.bundle import load_bundle # noqa: F401
28
+ from process_bigraph.draft_process import DraftProcess, draft_process # noqa: F401
27
29
  from process_bigraph.emitter import Emitter, gather_emitter_results, generate_emitter_state # noqa: F401
28
30
  from process_bigraph.types import StepLink, ProcessLink, CompositeLink # noqa: F401
29
31
  from process_bigraph import core_introspection # noqa: F401
@@ -38,6 +40,7 @@ from process_bigraph.composite_generator import ( # noqa: F401
38
40
  from process_bigraph.composite_discovery import discover_all # noqa: F401
39
41
  from process_bigraph.config_helpers import normalize_config_list # noqa: F401
40
42
  from process_bigraph.visualization import Visualization, as_visualization, render_results # noqa: F401
43
+ from process_bigraph.workflow import run_workflow # noqa: F401
41
44
 
42
45
 
43
46
  import pprint
@@ -22,7 +22,7 @@ import hashlib
22
22
  import json
23
23
  import os
24
24
  from dataclasses import dataclass, field
25
- from typing import Any, Callable
25
+ from typing import Callable
26
26
 
27
27
  # ── content address ─────────────────────────────────────────────────
28
28
  #