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.
- process_bigraph-1.8.4/PKG-INFO +308 -0
- process_bigraph-1.8.4/README.md +282 -0
- {process_bigraph-1.8.2 → process_bigraph-1.8.4}/process_bigraph/__init__.py +4 -1
- {process_bigraph-1.8.2 → process_bigraph-1.8.4}/process_bigraph/artifacts.py +1 -1
- {process_bigraph-1.8.2 → process_bigraph-1.8.4}/process_bigraph/composite.py +267 -31
- {process_bigraph-1.8.2 → process_bigraph-1.8.4}/process_bigraph/composite_generator.py +27 -19
- {process_bigraph-1.8.2 → process_bigraph-1.8.4}/process_bigraph/composite_spec.py +118 -5
- process_bigraph-1.8.4/process_bigraph/draft_process.py +135 -0
- {process_bigraph-1.8.2 → process_bigraph-1.8.4}/process_bigraph/emitter.py +308 -48
- {process_bigraph-1.8.2 → process_bigraph-1.8.4}/process_bigraph/experiments/minimal_gillespie.py +1 -1
- process_bigraph-1.8.4/process_bigraph/nextflow.py +775 -0
- process_bigraph-1.8.4/process_bigraph/nextflow_deploy.py +140 -0
- {process_bigraph-1.8.2 → process_bigraph-1.8.4}/process_bigraph/processes/__init__.py +11 -0
- {process_bigraph-1.8.2 → process_bigraph-1.8.4}/process_bigraph/processes/bigraphical_reactive_system.py +1 -1
- {process_bigraph-1.8.2 → process_bigraph-1.8.4}/process_bigraph/processes/examples.py +4 -2
- {process_bigraph-1.8.2 → process_bigraph-1.8.4}/process_bigraph/processes/reaction.py +30 -4
- {process_bigraph-1.8.2 → process_bigraph-1.8.4}/process_bigraph/protocols/__init__.py +11 -1
- {process_bigraph-1.8.2 → process_bigraph-1.8.4}/process_bigraph/protocols/clusters/__init__.py +1 -1
- {process_bigraph-1.8.2 → process_bigraph-1.8.4}/process_bigraph/protocols/clusters/ec2_ssm.py +2 -3
- {process_bigraph-1.8.2 → process_bigraph-1.8.4}/process_bigraph/protocols/git.py +1 -3
- {process_bigraph-1.8.2 → process_bigraph-1.8.4}/process_bigraph/protocols/parallel.py +4 -24
- {process_bigraph-1.8.2 → process_bigraph-1.8.4}/process_bigraph/protocols/pool.py +1 -1
- {process_bigraph-1.8.2 → process_bigraph-1.8.4}/process_bigraph/protocols/ray.py +9 -42
- {process_bigraph-1.8.2 → process_bigraph-1.8.4}/process_bigraph/protocols/rest.py +3 -11
- {process_bigraph-1.8.2 → process_bigraph-1.8.4}/process_bigraph/protocols/session.py +1 -1
- process_bigraph-1.8.4/process_bigraph/run_composite.py +254 -0
- {process_bigraph-1.8.2 → process_bigraph-1.8.4}/process_bigraph/run_step.py +10 -1
- {process_bigraph-1.8.2 → process_bigraph-1.8.4}/process_bigraph/scheduling.py +1 -2
- {process_bigraph-1.8.2 → process_bigraph-1.8.4}/process_bigraph/server/rest.py +25 -5
- process_bigraph-1.8.4/process_bigraph/types/__init__.py +10 -0
- {process_bigraph-1.8.2 → process_bigraph-1.8.4}/process_bigraph/types/process.py +6 -6
- process_bigraph-1.8.4/process_bigraph/wiring_translator.py +236 -0
- process_bigraph-1.8.4/process_bigraph/workflow/__init__.py +11 -0
- process_bigraph-1.8.4/process_bigraph/workflow/backend.py +165 -0
- process_bigraph-1.8.4/process_bigraph/workflow/provision.py +51 -0
- process_bigraph-1.8.4/process_bigraph/workflow/recipe.py +249 -0
- process_bigraph-1.8.4/process_bigraph/workflow/tasks.py +428 -0
- process_bigraph-1.8.4/process_bigraph.egg-info/PKG-INFO +308 -0
- {process_bigraph-1.8.2 → process_bigraph-1.8.4}/process_bigraph.egg-info/SOURCES.txt +13 -1
- {process_bigraph-1.8.2 → process_bigraph-1.8.4}/process_bigraph.egg-info/requires.txt +1 -1
- {process_bigraph-1.8.2 → process_bigraph-1.8.4}/pyproject.toml +21 -11
- process_bigraph-1.8.4/tests/test_process_decorator.py +182 -0
- process_bigraph-1.8.4/tests/test_reaction_step.py +80 -0
- process_bigraph-1.8.4/tests/test_units.py +50 -0
- process_bigraph-1.8.2/PKG-INFO +0 -182
- process_bigraph-1.8.2/README.md +0 -156
- process_bigraph-1.8.2/process_bigraph/nextflow.py +0 -438
- process_bigraph-1.8.2/process_bigraph/types/__init__.py +0 -2
- process_bigraph-1.8.2/process_bigraph.egg-info/PKG-INFO +0 -182
- {process_bigraph-1.8.2 → process_bigraph-1.8.4}/AUTHORS.md +0 -0
- {process_bigraph-1.8.2 → process_bigraph-1.8.4}/LICENSE +0 -0
- {process_bigraph-1.8.2 → process_bigraph-1.8.4}/process_bigraph/bundle.py +0 -0
- {process_bigraph-1.8.2 → process_bigraph-1.8.4}/process_bigraph/composite_discovery.py +0 -0
- {process_bigraph-1.8.2 → process_bigraph-1.8.4}/process_bigraph/config_helpers.py +0 -0
- {process_bigraph-1.8.2 → process_bigraph-1.8.4}/process_bigraph/core_introspection.py +0 -0
- {process_bigraph-1.8.2 → process_bigraph-1.8.4}/process_bigraph/experiments/__init__.py +0 -0
- {process_bigraph-1.8.2 → process_bigraph-1.8.4}/process_bigraph/plumbing.py +0 -0
- {process_bigraph-1.8.2 → process_bigraph-1.8.4}/process_bigraph/processes/cached.py +0 -0
- {process_bigraph-1.8.2 → process_bigraph-1.8.4}/process_bigraph/processes/dynamic_structure.py +0 -0
- {process_bigraph-1.8.2 → process_bigraph-1.8.4}/process_bigraph/processes/growth_division.py +0 -0
- {process_bigraph-1.8.2 → process_bigraph-1.8.4}/process_bigraph/processes/parameter_scan.py +0 -0
- {process_bigraph-1.8.2 → process_bigraph-1.8.4}/process_bigraph/processes/simulation.py +0 -0
- {process_bigraph-1.8.2 → process_bigraph-1.8.4}/process_bigraph/protocols/_git_worker.py +0 -0
- {process_bigraph-1.8.2 → process_bigraph-1.8.4}/process_bigraph/run.py +0 -0
- {process_bigraph-1.8.2 → process_bigraph-1.8.4}/process_bigraph/server/__init__.py +0 -0
- {process_bigraph-1.8.2 → process_bigraph-1.8.4}/process_bigraph/server/start.py +0 -0
- {process_bigraph-1.8.2 → process_bigraph-1.8.4}/process_bigraph/templates.py +0 -0
- {process_bigraph-1.8.2 → process_bigraph-1.8.4}/process_bigraph/visualization.py +0 -0
- {process_bigraph-1.8.2 → process_bigraph-1.8.4}/process_bigraph/visualizations/__init__.py +0 -0
- {process_bigraph-1.8.2 → process_bigraph-1.8.4}/process_bigraph/visualizations/distribution.py +0 -0
- {process_bigraph-1.8.2 → process_bigraph-1.8.4}/process_bigraph/visualizations/heatmap.py +0 -0
- {process_bigraph-1.8.2 → process_bigraph-1.8.4}/process_bigraph/visualizations/param_vs_observable.py +0 -0
- {process_bigraph-1.8.2 → process_bigraph-1.8.4}/process_bigraph/visualizations/phase_space.py +0 -0
- {process_bigraph-1.8.2 → process_bigraph-1.8.4}/process_bigraph/visualizations/time_series.py +0 -0
- {process_bigraph-1.8.2 → process_bigraph-1.8.4}/process_bigraph/visualizations/timeseries_from_observables.py +0 -0
- {process_bigraph-1.8.2 → process_bigraph-1.8.4}/process_bigraph.egg-info/dependency_links.txt +0 -0
- {process_bigraph-1.8.2 → process_bigraph-1.8.4}/process_bigraph.egg-info/top_level.txt +0 -0
- {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
|
+
[](https://pypi.org/project/process-bigraph/)
|
|
30
|
+
[](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
|
+
[](https://pypi.org/project/process-bigraph/)
|
|
4
|
+
[](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
|