DESModel

models.DESModel(
    process,
    population=None,
    interventions,
    resources=None,
    horizon,
    discount_rate=0.03,
    n_individuals=1000,
    effect='qaly',
    independent_streams=False,
)

Discrete-event simulation engine wrapping SimPy.

Each process is the user’s own SimPy code with signature process(env, entity, params, intervention, toolkit). entity is that individual’s attribute row, params the iteration’s draw merged with the intervention decision levers, intervention the intervention name, and toolkit the _DESToolkit that accrues cost and effect and logs the trajectory. Per iteration and intervention the engine builds the environment, samples entities, creates the shared resources, runs every process to horizon, collects the per-entity discounted accruals, averages them, and writes one Outcomes row.

Parameters

Name Type Description Default
process ProcessFn The SimPy process factory, fn(env, entity, params, intervention, toolkit) returning a generator. required
population PopulationSpec Attribute sampler fn(rng, n) -> DataFrame, an int count for a featureless population, or None to use n_individuals with no attributes. None
interventions InterventionSpec A sequence of intervention names or heormodel.models.Intervention objects; an Intervention may carry parameter decision levers merged into params for that intervention. Order is preserved in Outcomes. required
resources ResourceFn | None fn(env, params, intervention) -> dict[str, simpy.Resource], built fresh for each run and shared by every entity in it. None for a model with no constrained resources. None
horizon float Time horizon in the environment’s unit; the run stops here. Each process reads it back as toolkit.horizon. required
discount_rate float Annual (per-unit-time) discount rate for costs and effects (0.03 by default). Discounting is continuous (exp(-rate * t)). 0.03
n_individuals int Population size when population is a sampler or None. 1000
effect str Name of the effect column (QALYs by default). 'qaly'
independent_streams bool Give each intervention its own population and streams instead of common random numbers. False

Randomness is supplied by heormodel.run.run_psa at run time, not at construction; the engine holds no seed of its own.

Example

import numpy as np, pandas as pd from heormodel.models import DESModel def process(env, entity, params, intervention, toolkit): … wait = toolkit.rng.exponential(params[“los”]) … toolkit.accrue_rate(params[“day_cost”], 1.0, wait) … yield env.timeout(wait) engine = DESModel( … process=process, population=200, interventions=[“ward”], … horizon=30.0) draws = pd.DataFrame({“los”: [3.0], “day_cost”: [500.0]}, … index=pd.RangeIndex(1, name=“iteration”)) engine.evaluate(draws).interventions [‘ward’]

Methods

Name Description
evaluate Simulate every draw and intervention, averaging entities to Outcomes.
evaluate_streamed Simulate every draw under streams, collecting the collect log.

evaluate

models.DESModel.evaluate(draws)

Simulate every draw and intervention, averaging entities to Outcomes.

This is the narrow heormodel.models.ModelEngine entry point: it seeds each iteration from a fixed default stream, so a direct call is reproducible. Run through heormodel.run.run_psa to choose the seed, to run in parallel, and to collect the event or individual logs.

Parameters

Name Type Description Default
draws pd.DataFrame Parameter draw matrix (rows = iterations). Its index becomes the outcome iteration index. required

Returns

Name Type Description
Outcomes Outcomes indexed by (intervention, draws.index).

Example

import pandas as pd from heormodel.models import DESModel def process(env, entity, params, intervention, toolkit): … toolkit.accrue_cost(params[“visit”]) … yield env.timeout(1.0) engine = DESModel( … process=process, population=50, interventions=[“clinic”], … horizon=5.0) draws = pd.DataFrame({“visit”: [200.0, 210.0]}, … index=pd.RangeIndex(2, name=“iteration”)) engine.evaluate(draws).n_iterations 2

evaluate_streamed

models.DESModel.evaluate_streamed(draws, *, streams, collect=None)

Simulate every draw under streams, collecting the collect log.

Parameters

Name Type Description Default
draws pd.DataFrame Parameter draw matrix (rows = iterations). required
streams SeedManager Root of the per-iteration streams; each iteration draws a stream keyed by its index, so results do not depend on how the run is chunked across workers. required
collect str | None None for outcomes only, "events" for the per-entity event log (columns intervention, iteration, entity, t, event, state, resource), or "individuals" for per-entity cost and effect. None

Returns

Name Type Description
EngineResult An EngineResult whose outcomes is always set and whose
EngineResult events or individuals is set to match collect.