Skip to main content

Process-Bigraph

PyPI GitHub Pages

Process-Bigraph is a compositional runtime and protocol for building and executing multiscale biological models from interoperable processes.

It provides a shared architectural layer for:

  • declaring process interfaces
  • wiring processes through typed shared state
  • orchestrating execution across heterogeneous timescales
  • supporting dynamic structure (workflows, division, graph rewrites)

Process-Bigraph is the execution core of Vivarium 2.0, designed to integrate models built with different formalisms—including ODEs, FBA, agent-based models, spatial solvers, and machine-learning components—into a single coherent simulation.

Process Bigraph composition framework


🧩 What is a Process Bigraph?

A process bigraph combines:

  • Typed stores — hierarchical, schema-validated state defined with bigraph-schema
  • Processes — executable components with explicit input/output ports
  • Composites — encapsulated sub-simulations with their own internal structure
  • Orchestration patterns — multi-timestepping, directed workflows, and event-driven rewrites

Processes do not mutate state directly. Instead, they emit typed deltas that are merged by the runtime.

This allows:

  • numerical updates
  • structural rewrites
  • scheduling and orchestration

to coexist under a single execution semantics.

In this sense, Process-Bigraph is a composition protocol, not a domain-specific simulator.


📄 Paper reference

The conceptual framework and formal semantics of process bigraphs are introduced in:

Agmon, E. & Spangler, R. K.
Process Bigraphs and the Architecture of Compositional Systems Biology
https://arxiv.org/abs/2512.23754


🚀 Getting Started

Installation

pip install process-bigraph

Quickstart — composites, drafts & templates in code

A runnable five-minute tour of the core concepts. Every block below runs as-is against process-bigraph ≥ 1.8.3. Concepts explained in docs/concepts/composites-and-templates.md.

1. A process wired into a composite over a shared store. A composite is a state map of typed nodes; processes couple only by reading/writing shared stores.

from process_bigraph import Composite, Process, allocate_core
from process_bigraph.emitter import emitter_from_wires, gather_emitter_results

class Grow(Process):                                  # a Process = ports + an update
    config_schema = {'rate': 'float'}
    def inputs(self):  return {'level': 'float'}
    def outputs(self): return {'level': 'float'}
    def update(self, state, interval):
        return {'level': state['level'] * self.config['rate'] * interval}  # a delta

core = allocate_core()
core.register_link('Grow', Grow)                      # register it in the local registry

composite = Composite({'state': {
    'level': 1.0,                                     # a shared store
    'grow': {'_type': 'process', 'address': 'local:Grow', 'config': {'rate': 0.5},
             'interval': 1.0, 'inputs': {'level': ['level']}, 'outputs': {'level': ['level']}},
    'emitter': emitter_from_wires({'level': ['level'], 'time': ['global_time']}),
}}, core=core)
composite.run(5.0)
print(gather_emitter_results(composite))
# {('emitter',): [{'level': 1.0, 'time': 0.0}, {'level': 1.5, ...}, ... {'level': 7.59, 'time': 5.0}]}

2. A draft process — a present-but-inert placeholder node. It declares a contract (ports + description) but has no update, so a composite containing it still runs; the draft just no-ops. Complementary to a site (step 3): a draft is a node that is there but inert, a site is an empty hole.

from process_bigraph import DraftProcess, draft_process

@draft_process(name="PTH secretion",
    inputs={'ca_sense': 'float'}, outputs={'pth_out': 'float'},
    contract={'summary': 'senses serum Ca, secretes PTH', 'senses': 'calcium', 'makes': 'PTH'})
class PTHSecretion(DraftProcess):
    pass

core.register_link('PTHSecretion', PTHSecretion)
print(PTHSecretion({}, core=core).describe())
# DRAFT — senses serum Ca, secretes PTH  ·  makes: PTH  ·  senses: calcium  ·  status: draft - no update dynamics yet

A module-scope draft auto-registers, so it appears in the vivarium-workbench dashboard (Modules → Processes) marked DRAFT with its ports and contract — no code change needed. Replace it with a real Process once the mechanism is committed.

3. A template — a composite with an open site (hole). A template is a document that isn't ground: it has open sites ({"_type": "site"}). Composite refuses to run one until every required site is filled.

from process_bigraph import Step
from process_bigraph.templates import open_sites, is_ground_document, template_document

class ReportCard(Step):                               # a fixed downstream verdict
    config_schema = {'threshold': 'float'}
    def inputs(self):  return {'level': 'float'}
    def outputs(self): return {'verdict': 'string'}
    def update(self, state):
        return {'verdict': 'pass' if state['level'] >= self.config['threshold'] else 'fail'}

core.register_link('ReportCard', ReportCard)
MODEL_FACE = {'_type': 'link', '_inputs': {'level': 'float'}, '_outputs': {'level': 'float'}}

template = core.access({'study': {                     # analysis fixed, the model is a HOLE
    'level': 1.0, 'verdict': 'string',
    'model':  {'_type': 'site', '_sort': MODEL_FACE},
    'report': {'_type': 'step', 'address': 'local:ReportCard', 'config': {'threshold': 2.0},
               'inputs': {'level': ['level']}, 'outputs': {'verdict': ['verdict']}}}})

print(open_sites(template), is_ground_document(template))   # [('study', 'model')] False

def model(rate):                                      # any conforming composite fits the hole
    return core.access({'_type': 'process', 'address': 'local:Grow', 'config': {'rate': rate},
                        'interval': 1.0, 'inputs': {'level': ['level']}, 'outputs': {'level': ['level']}})

sim = Composite({'state': template_document(core, template, {'study/model': model(0.5)})}, core=core)
sim.run(4.0)
print(sim.state['study']['verdict'])                  # pass  (a slower model → fail)
# template_document(core, template, {}) → ValueError: not ground — required site 'study/model'

4. An investigation — one site per member study; gating is filling. Fill a member's site to admit it; leave it open and it is pruned from the built document, so a blocked prerequisite simply never runs.

from process_bigraph.templates import investigation_document

study = lambda: {'level': 1.0, 'verdict': 'string',
    'model':  {'_type': 'site', '_sort': MODEL_FACE},
    'report': {'_type': 'step', 'address': 'local:ReportCard', 'config': {'threshold': 2.0},
               'inputs': {'level': ['level']}, 'outputs': {'verdict': ['verdict']}}}

inv = core.access({'investigation': {'study_A': study(), 'study_B': study()}})
document, blocked = investigation_document(
    core, inv, {'investigation/study_A/model': model(0.5)}, member_depth=2)  # fill A only
print(blocked, sorted(document['investigation']))     # ['investigation/study_B'] ['study_A']

This same template/site machinery is what viva-superpowers uses to compile a whole investigation into a composite (one StudyStep per member). The study/investigation layer is documented in viva-superpowers docs/concepts/composites-templates-and-the-study-investigation-stack.md.

📘 Tutorials

The Process-Bigraph tutorials are executable Jupyter notebooks, rendered to HTML and published automatically on GitHub Pages.

Learning Path (Featured Tutorials)

More tutorials are added continuously and appear automatically in the index.

Architecture

  • The framework, end to end — start here to understand the whole system: what the objects are (documents, sites, handles), how they compose, the higher-order DAG, templates and gating, content-addressed artifacts, the git: protocol, and the laws everything else follows from. docs/architecture.md

Topic Guides

  • Emitters — Recording Simulation Results Built-in emitters (RAM, console, JSON, SQLite), how to wire them, retrieve results, store runs long-term, and write your own. docs/emitters.md

  • Tick lifecycle — how a step network is ordered and advanced, and how a protocol runtime batches remote dispatch. docs/tick_lifecycle.md

  • Distributed lifecycles — running parts of a composite off-process. docs/distributed_lifecycles.md

  • Deploying a Step network to Nextflow — opt-in: compile a composite's Step network into a Nextflow DSL2 workflow and run it on a batch backend (local / SLURM). Nothing changes about Composite.run(). docs/nextflow.md


🧪 Reference Implementation: spatio-flux

Process-Bigraph is exercised end-to-end in spatio-flux, a multiscale reference model built entirely using the process-bigraph protocol.

spatio-flux composes spatial fields, particle dynamics, and metabolic processes using typed shared state and declarative orchestration.

GitHub: https://github.com/vivarium-collective/spatio-flux
Live test report: https://vivarium-collective.github.io/spatio-flux/report/index.html


🔗 Related Resources


📜 License

Process-Bigraph is open-source software released under the
Apache 2 License.

Metadata

Release files for process-bigraph 1.8.4

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for process-bigraph 1.8.4
File Size Uploaded
process_bigraph-1.8.4.tar.gz 216.0 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for process-bigraph 1.8.4
File Interpreter ABI Platform
process_bigraph-1.8.4-py3-none-any.whl Python 3 none any Details

Total release size: 451.0 kB

Release files / process_bigraph-1.8.4.tar.gz

Download URL process_bigraph-1.8.4.tar.gz
Size 216.0 kB
Tags Source
SHA-256 checksum
How to use checksums
f4649771ba5090e9d1a4ad00557f1ed0ab7614eb1e57626f75bc5c62d3f966be
BLAKE2b-256 checksum
How to use checksums
21742f2537f1fa21858be64daad60ded3291ea7b418f151b4e1859e6e29f000c
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Sep 4, 2026.

Transparency log

Release files / process_bigraph-1.8.4-py3-none-any.whl

Download URL process_bigraph-1.8.4-py3-none-any.whl
Size 235.0 kB
Tags Python 3
SHA-256 checksum
How to use checksums
271d8d281dffa5486f9df515eb72a8a133315f67c6f78983b079284cc4e37baa
BLAKE2b-256 checksum
How to use checksums
e8289290d69d2ace293cfa4de660ccc229fe2b49139b36ac7d0b3b54667e5d4f
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Sep 4, 2026.

Transparency log

Release history Release notifications | RSS feed

1.8.5

2 release files

This release

1.8.4 This release

2 release files

1.8.3

2 release files

1.8.2

2 release files

1.8.1

2 release files

1.8.0

2 release files

1.7.1

2 release files

1.5.0

2 release files

1.4.18

2 release files

1.4.16

2 release files

1.4.15

2 release files

1.4.14

2 release files

1.4.12

2 release files

1.4.11

2 release files

1.4.10

2 release files

1.4.9

2 release files

1.4.8

2 release files

1.4.7

2 release files

1.4.6

2 release files

1.4.5

2 release files

1.4.4

2 release files

1.4.3

2 release files

1.4.2

2 release files

1.4.0

2 release files

1.3.1

2 release files

1.3.0

2 release files

1.2.3

2 release files

1.2.2

2 release files

1.2.1

2 release files

1.1.7

2 release files

1.1.6

2 release files

1.1.5

2 release files

1.1.4

2 release files

1.1.3

2 release files

1.1.1

2 release files

1.0.7

2 release files

1.0.6

2 release files

1.0.5

2 release files

1.0.4

2 release files

1.0.2

2 release files

1.0.0

2 release files

0.0.51

2 release files

0.0.50

2 release files

0.0.49

2 release files

0.0.45

2 release files

0.0.44

2 release files

0.0.43

2 release files

0.0.42

1 release file

0.0.41

1 release file

0.0.39

1 release file

0.0.38

1 release file

0.0.37

1 release file

0.0.35

1 release file

0.0.34

1 release file

0.0.33

1 release file

0.0.32

1 release file

0.0.31

1 release file

0.0.30

1 release file

0.0.29

1 release file

0.0.28

1 release file

0.0.27

1 release file

0.0.26

1 release file

0.0.25

1 release file

0.0.24

1 release file

0.0.23

1 release file

0.0.22

1 release file

0.0.21

1 release file

0.0.20

1 release file

0.0.19

1 release file

0.0.18

1 release file

0.0.17

1 release file

0.0.15

1 release file

0.0.14

1 release file

0.0.13

1 release file

0.0.10

1 release file

0.0.9

1 release file

0.0.8

1 release file

0.0.7

1 release file

0.0.5

1 release file

0.0.4

1 release file

0.0.3

1 release file

0.0.2

1 release file

0.0.1

1 release file

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page