How ToLibraryCreate a Domain Pack

How to Create a Domain Pack

A domain pack is a normal Python package that exports a coherent family of BioModule implementations, presets, and monitors.

Suggested structure

mypack/
  __init__.py
  inputs.py
  populations.py
  interactions.py
  monitors.py
  presets.py

Example input module

import biosimulant as biosim
 
 
class DrugDose(biosim.BioModule):
    def __init__(self, dose_mg: float, schedule: list[float]):
        self.dose_mg = float(dose_mg)
        self.schedule = list(schedule)
        self._outputs = {}
 
    def outputs(self):
        return {
            "drug_concentration": biosim.SignalSpec.scalar(
                dtype="float64",
                emitted_unit="mg/L",
            )
        }
 
    def advance_window(self, start: float, end: float) -> None:
        active = any(abs(t - end) < 1e-9 for t in self.schedule)
        self._outputs = {
            "drug_concentration": biosim.ScalarSignal(
                source="drug",
                name="drug_concentration",
                value=self.dose_mg if active else 0.0,
                emitted_at=end,
                spec=self.outputs()["drug_concentration"],
            )
        }
 
    def get_outputs(self):
        return dict(self._outputs)
 
    def snapshot(self):
        return {}

Example population module

class CellPopulation(biosim.BioModule):
    def __init__(self, n: int, division_rate: float = 0.1):
        self.n = int(n)
        self.division_rate = float(division_rate)
 
    def inputs(self):
        return {"drug_concentration": biosim.SignalSpec.scalar(dtype="float64")}
 
    def outputs(self):
        return {
            "population_state": biosim.SignalSpec.record(
                schema={"count": "int64"},
            )
        }

Export your public surface

from .inputs import DrugDose
from .populations import CellPopulation
from .monitors import GrowthMonitor
 
__all__ = ["DrugDose", "CellPopulation", "GrowthMonitor"]

Use the pack

import biosimulant as biosim
from mypack import DrugDose, CellPopulation, GrowthMonitor
 
world = biosim.BioWorld(communication_step=1.0)
builder = biosim.WiringBuilder(world)
 
builder.add("drug", DrugDose(dose_mg=100, schedule=[0, 24, 48]))
builder.add("cells", CellPopulation(n=1000))
builder.add("monitor", GrowthMonitor())
 
builder.connect("drug.drug_concentration", ["cells.drug_concentration"])
builder.connect("cells.population_state", ["monitor.population_state"])
builder.apply()
 
world.run(duration=72.0)

Domain packs do not need to live under a biosimulant.* namespace. Stable import paths matter more than namespace conventions.

Next steps