How ToUse a BioWorld

How to Use a BioWorld

Use BioWorld when you want to register modules, validate connections, run the graph for a duration, and read outputs or snapshots afterward.

Create a world

import biosimulant as biosim
 
world = biosim.BioWorld(communication_step=0.1)

Inspect module ports

Check what a module accepts and emits before you wire it:

from src.vision_demo import Eye, LGN, SuperiorColliculus
 
eye = Eye()
print(eye.inputs())
print(eye.outputs())

Both return dict[str, SignalSpec]. For a packaged model, the manifest’s io block should match these ports.

Add modules with WiringBuilder

builder = biosim.WiringBuilder(world)
builder.add("eye", eye)
builder.add("lgn", LGN())
builder.add("sc", SuperiorColliculus())

Wire connections

builder.connect("eye.visual_stream", ["lgn.retina"])
builder.connect("lgn.thalamus", ["sc.vision"])
builder.apply()
⚠️

Always pass destinations as a list such as ["target.port"].

Run the simulation

world.run(duration=10.0)

The world drains ONCE_BEFORE_RUN modules, advances EACH_WINDOW modules across the communication windows, then drains ONCE_AFTER_RUN modules. The legacy external tick parameter is not part of the current runtime API.

Read outputs

outputs = world.get_outputs("lgn")
signal = outputs["thalamus"]
print(signal.value, signal.emitted_at)

Outputs are typed signals such as ScalarSignal, ArraySignal, RecordSignal, or EventSignal. For events, visuals, and pause or stop controls, see the BioWorld API.

Propagate final outputs

Legacy downstream temporal modules only observe outputs after those outputs are committed at a communication boundary. Settle those modules after the run when needed:

world.run(duration=10.0)
world.settle(steps=1)

Settling calls downstream modules with advance_window(current_time, current_time) and does not advance simulated time. Execute-style modules do not run during settling; use ONCE_AFTER_RUN for finite report, export, or visualisation modules.

Rerun and sweep parameters

There is no kernel-level reset method. To rerun the same modules from the same starting state, take a snapshot after setup and restore it before each run:

world.setup()
baseline = world.snapshot()
 
for _ in range(3):
    world.restore(baseline)
    world.run(duration=5.0)

To sweep constructor parameters, build a fresh world for each point:

import biosimulant as biosim
from src.linear_growth import LinearGrowth
 
 
def build_world(rate: float):
    world = biosim.BioWorld(communication_step=1.0)
    module = LinearGrowth(rate=rate, initial_value=1.0)
    world.add_biomodule("growth", module)
    return world, module
 
 
results = []
for rate in [0.05, 0.1, 0.2, 0.4]:
    world, module = build_world(rate)
    world.run(duration=100.0)
    results.append({"rate": rate, "final_state": module.snapshot()})

Next steps