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