Skip to content

Simulator

simulator

Simulation orchestration for flepimop2.

Simulator(system, engine, backend, *, target=None, simulate_config=None, system_config=None, engine_config=None, backend_config=None, parameter_configs=None, axes=None)

Build and run a single simulation from configuration models.

Attributes:

Name Type Description
system SystemABC

The built system instance.

engine EngineABC

The built engine instance.

backend BackendABC

The built backend instance.

target str | None

Optional target simulate config to use.

simulate_config SimulateSpecificationModel | None

The resolved simulation specification.

system_config ModuleConfigurationValue | None

The resolved system configuration dict.

engine_config ModuleConfigurationValue | None

The resolved engine configuration dict.

backend_config ModuleConfigurationValue | None

The resolved backend configuration dict.

Initialize the simulator with resolved components.

Parameters:

Name Type Description Default
system SystemABC

The built system instance.

required
engine EngineABC

The built engine instance.

required
backend BackendABC

The built backend instance.

required
target str | None

Optional target simulate config to use.

None
simulate_config SimulateSpecificationModel | None

The resolved simulation specification, if available.

None
system_config ModuleConfigurationValue | None

The resolved system configuration model, if available.

None
engine_config ModuleConfigurationValue | None

The resolved engine configuration model, if available.

None
backend_config ModuleConfigurationValue | None

The resolved backend configuration model, if available.

None
parameter_configs dict[IdentifierString, ModuleConfigurationValue] | None

The resolved parameter configuration values, if available.

None
axes AxisCollection | None

The resolved runtime axis collection for the simulation.

None

Raises:

Type Description
Flepimop2ValidationError

If the engine is incompatible with the system.

Source code in src/flepimop2/simulator.py
def __init__(  # noqa: PLR0913
    self,
    system: SystemABC,
    engine: EngineABC,
    backend: BackendABC,
    *,
    target: str | None = None,
    simulate_config: SimulateSpecificationModel | None = None,
    system_config: ModuleConfigurationValue | None = None,
    engine_config: ModuleConfigurationValue | None = None,
    backend_config: ModuleConfigurationValue | None = None,
    parameter_configs: dict[IdentifierString, ModuleConfigurationValue]
    | None = None,
    axes: AxisCollection | None = None,
) -> None:
    """
    Initialize the simulator with resolved components.

    Args:
        system: The built system instance.
        engine: The built engine instance.
        backend: The built backend instance.
        target: Optional target simulate config to use.
        simulate_config: The resolved simulation specification, if available.
        system_config: The resolved system configuration model, if available.
        engine_config: The resolved engine configuration model, if available.
        backend_config: The resolved backend configuration model, if available.
        parameter_configs: The resolved parameter configuration values, if
            available.
        axes: The resolved runtime axis collection for the simulation.

    Raises:
        Flepimop2ValidationError: If the engine is incompatible with the system.

    """
    self.target = target
    self.simulate_config = simulate_config
    self.system_config = system_config
    self.engine_config = engine_config
    self.backend_config = backend_config
    self.parameter_configs = parameter_configs
    self.axes = axes or AxisCollection()
    self.system = system
    self.engine = engine
    self.backend = backend

    if issues := self.engine.validate_system(self.system):
        raise Flepimop2ValidationError(issues)

from_configuration_model(config_model, target=None) classmethod

Build a simulator from a configuration model.

Returns:

Type Description
Simulator

The constructed simulator instance.

Source code in src/flepimop2/simulator.py
@classmethod
def from_configuration_model(
    cls,
    config_model: ConfigurationModel,
    target: str | None = None,
) -> "Simulator":
    """
    Build a simulator from a configuration model.

    Returns:
        The constructed simulator instance.

    """
    simulate_config = _get_config_target(
        config_model.simulate,
        target,
        "simulate",
    )

    system_config = config_model.systems[simulate_config.system]
    engine_config = config_model.engines[simulate_config.engine]
    backend_config = config_model.backends[simulate_config.backend]

    system = build_system(system_config)
    engine = build_engine(engine_config)
    backend = build_backend(backend_config)

    return cls(
        system,
        engine,
        backend,
        target=target,
        simulate_config=simulate_config,
        system_config=system_config,
        engine_config=engine_config,
        backend_config=backend_config,
        parameter_configs=config_model.parameters,
        axes=AxisCollection.from_config(config_model.axes),
    )

resolve_inputs()

Resolve configured parameters into an initial state and stepper inputs.

Returns:

Type Description
tuple[dict[IdentifierString, ParameterValue], dict[IdentifierString, ParameterValue]]

Structured initial-state entries and structured stepper parameters.

Raises:

Type Description
KeyError

If a required parameter is missing from configuration.

ValueError

If model state cannot be resolved for the system.

Source code in src/flepimop2/simulator.py
def resolve_inputs(
    self,
) -> tuple[
    dict[IdentifierString, ParameterValue],
    dict[IdentifierString, ParameterValue],
]:
    """
    Resolve configured parameters into an initial state and stepper inputs.

    Returns:
        Structured initial-state entries and structured stepper parameters.

    Raises:
        KeyError: If a required parameter is missing from configuration.
        ValueError: If model state cannot be resolved for the system.
    """
    state_spec = self.system.model_state(self.axes)
    if state_spec is None:
        msg = "System did not declare model_state."
        raise ValueError(msg)

    state_samples = {
        name: self._sample_parameter(name, request)
        for name, request in state_spec.requests().items()
    }
    resolved_params: dict[IdentifierString, ParameterValue] = {}
    for name, request in self.system.requested_parameters(self.axes).items():
        if self.parameter_configs is None or name not in self.parameter_configs:
            if request.optional:
                continue
            msg = f"Required parameter '{name}' was requested but not configured."
            raise KeyError(msg)
        resolved_params[name] = self._sample_parameter(name, request)

    return state_samples, resolved_params

run(initial_state=None, params=None, meta=None)

Run the simulation and persist results via the backend.

Parameters:

Name Type Description Default
initial_state dict[IdentifierString, ParameterValue] | None

Structured initial-state entries for the simulation.

None
params dict[IdentifierString, ParameterValue] | None

Structured stepper parameters for the simulation.

None
meta RunMeta | None

Metadata about the simulation run.

None

Returns:

Type Description
Float64NDArray

The simulation result array.

Raises:

Type Description
ValueError

If simulate_config is not set.

Source code in src/flepimop2/simulator.py
def run(
    self,
    initial_state: dict[IdentifierString, ParameterValue] | None = None,
    params: dict[IdentifierString, ParameterValue] | None = None,
    meta: RunMeta | None = None,
) -> Float64NDArray:
    """
    Run the simulation and persist results via the backend.

    Args:
        initial_state: Structured initial-state entries for the simulation.
        params: Structured stepper parameters for the simulation.
        meta: Metadata about the simulation run.

    Returns:
        The simulation result array.

    Raises:
        ValueError: If `simulate_config` is not set.

    """
    if self.simulate_config is None:
        msg = "simulate_config must be set before running the simulator."
        raise ValueError(msg)
    model_state = self.system.model_state(self.axes)
    if model_state is None:
        msg = "System did not declare model_state."
        raise ValueError(msg)
    if initial_state is None and params is None:
        initial_state, params = self.resolve_inputs()
    elif initial_state is None or params is None:
        msg = (
            "initial_state and params must either both be "
            "provided or both be omitted."
        )
        raise ValueError(msg)
    res = self.engine.run(
        self.system,
        self.simulate_config.t_eval,
        initial_state,
        params,
        model_state=model_state,
    )
    meta = meta or RunMeta()
    self.backend.save(res, meta)
    return res