How to Use a BioWorld
Use BioWorld when you want to register modules, validate connections, run the graph for a duration, and collect visuals or snapshots afterward.
Create a world
import biosimulant as biosim
world = biosim.BioWorld(communication_step=0.1)Add modules with WiringBuilder
from src.vision_demo import Eye, LGN, SuperiorColliculus
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 advances all modules across the same communication windows. The legacy external tick parameter is not part of the current runtime API.
Propagate final outputs
Downstream modules only observe outputs after those outputs are committed at a communication boundary. If a report, export, or visualisation module should consume outputs produced at the final boundary, settle the graph after the run:
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.
Listen to events
from biosimulant import WorldEvent
def listener(event, payload):
if event == WorldEvent.STEP:
print(f"t={payload['t']:.3f}")
elif event == WorldEvent.FINISHED:
print("done")
world.on(listener)
world.run(duration=1.0)
world.off(listener)Collect visuals
visuals = world.collect_visuals()
for entry in visuals:
print(entry["module"], len(entry["visuals"]))Pause, resume, and stop
world.request_pause()
world.request_resume()
world.request_stop()These are cooperative and take effect at communication boundaries.
Repeatable reruns
There is no kernel-level reset method in the current world API. Use snapshots or build a fresh world.
world.setup()
baseline = world.snapshot()
world.run(duration=5.0)
world.restore(baseline)
world.run(duration=5.0)If you are sweeping constructor parameters rather than just simulation state, prefer a small build_world() factory that creates a fresh world per run.