BioWorld API
BioWorld is the communication-step orchestrator. It advances every registered module across the same window, commits outputs atomically at the boundary, and routes signals through validated connections.
Creating a world
import biosimulant as biosim
world = biosim.BioWorld(communication_step=0.1)communication_step is required. It defines the synchronization cadence for inter-module exchange.
Execution model
- Every run advances in windows
[t, t + communication_step]. - Inputs for a window are collected from the committed signal store at the start boundary.
- The world calls
set_inputs()andadvance_window(start, end)on every module across the same window. - The world normalizes and commits all outputs atomically at the end boundary.
- The kernel has no execution-order scheduling contract. Tied-time ordering is intentionally not part of the public semantics.
Outputs produced during one window are visible to downstream modules on a later communication turn. This keeps tied-time behavior order-independent.
Running a simulation
world.run(duration=10.0)duration is the simulation-time horizon. The world does not accept the legacy external tick parameter.
If the world has not been set up yet, run() calls setup() automatically before the first window.
Final propagation
world.run(duration=10.0)
world.settle(steps=1)settle() performs zero-time communication turns after the requested duration.
It schedules only modules downstream of outputs published at the last boundary,
delivers their committed inputs, calls advance_window(current_time, current_time),
and commits any outputs they publish as the next propagation frontier.
Use settling for downstream report, export, or visualization modules that should
consume final producer outputs. Settling does not advance simulation time and is
not run automatically by BioWorld.run().
Runtime events
from biosimulant import WorldEvent
def listener(event, payload):
print(event.value, payload)
world.on(listener)
world.run(duration=1.0)
world.off(listener)| Event | When |
|---|---|
STARTED | Before the first communication window |
STEP | After each committed communication window |
FINISHED | After the run exits, including stopped runs |
PAUSED | When a paused run reaches a pause boundary |
RESUMED | When a paused run resumes |
STOPPED | When a cooperative stop request is honored |
ERROR | When an exception escapes the run loop |
STEP payloads include progress fields such as t, window_start, window_end, start, end, duration, progress, progress_pct, and remaining.
Control flow
world.request_pause()
world.request_resume()
world.request_stop()These controls are cooperative. They take effect at communication boundaries, not mid-window.
Snapshots and branching
baseline = world.snapshot()
world.run(duration=5.0)
world.restore(baseline)
branch = world.branch()
branch.run(duration=5.0)Snapshots capture:
- current simulation time
- committed signal store
- per-connection event and stale-read delivery state
- per-module snapshot payloads
- setup config
BioWorld does not expose a kernel-level reset() method. For repeatable reruns, restore a snapshot or build a fresh world.
Signal semantics
- Source timestamps are preserved as
emitted_at. - State signals are held until that source module publishes a non-empty replacement mapping.
- Event signals persist in the store but are delivered once per connection per source timestamp.
- Staleness is checked against the consuming port’s
SignalSpec.max_ageandstale_policy.
Visuals
visuals = world.collect_visuals()
for entry in visuals:
print(entry["module"], len(entry["visuals"]))Modules that implement visualize() can publish transport-safe visualization specs for SimUI and platform consumers.
If a visualization is produced by a separate downstream module, run enough settle turns for that module to receive final committed inputs before collecting visuals.