Concept Guide๏ƒ

This page describes the core models used by APLUS โ€“ namely, Simulation, Patient, Transition, State, and Utility.

Simulation๏ƒ

For full documentation, see Simulation.

The Simulation class handles all the details of running a simulation. There are four basic methods to know:

  1. Initialize Simulation โ€“ create_from_yaml() or create_from_config()

  2. Initialize Patients โ€“ create_patients_for_simulation()

  3. Run Simulation โ€“ run()

  4. Visualize Workflow โ€“ draw_workflow_diagram()

  1. Initialize Simulation โ€“ create_from_yaml() or create_from_config() โ€“ Create the Simulation object from a YAML configuration file and a CSV file containing patient properties.

1import aplusml
2simulation = aplusml.Simulation.create_from_yaml(PATH_TO_CONFIG_YAML, PATH_TO_PATIENT_PROPERTIES)
3# or
4simulation = aplusml.Simulation.create_from_config(config)

From the config, the Simulation loads the following attributes:

  • metadata (Dict): Configuration metadata for the simulation. A dictionary of strings.

  • variables (Dict[str, Dict]): Variables used in the simulation. A dictionary of variables, keyed by ID.

  • states (Dict[str, State]): States in the workflow. A dictionary of states, keyed by ID.

  1. Initialize Patients โ€“ create_patients_for_simulation() โ€“ Create a list of Patient objects.

 1import aplusml
 2
 3# Create dummy patients
 4patients: List[aplusml.Patient] = [
 5  aplusml.Patient(0,
 6      0, # Unique ID
 7      0, # Start timestep
 8  ),
 9  aplusml.Patient(1,
10      1, # Unique ID
11      0, # Start timestep
12  ),
13  aplusml.Patient(2,
14      2, # Unique ID
15      1, # Start timestep
16  ),
17]
18
19# Initialize patients for simulation.
20# This creates a deep copy of each object in the `patients` array using pickle, sorts them by ID, and then initializes their properties
21patients: List[aplusml.Patient] = simulation.create_patients_for_simulation(patients, random_seed=0)
  1. Run Simulation โ€“ run() โ€“ Run a list of patients through the workflow.

1# Run the simulation
2patients = simulation.run(patients)

During the simulation, the following attributes will be automatically tracked:

  • variable_history (Dict[List[Tuple[int, Any]]]): History of variable values over time. A dictionary of lists of tuples, where each tuple contains a timestep and a dictionary of variable values.

  • current_timestep (int): Current simulation timestep.

  1. Visualize Workflow โ€“ draw_workflow_diagram() โ€“ Display the workflow as a graphviz diagram.

1# Draws workflow diagram. This will save the diagram to './output.png' and print it to your terminal.
2simulation.draw_workflow_diagram(figsize=(30,30), path_to_file='./output.png', is_display=True)

Patient๏ƒ

For full documentation, see Patient.

This class represents a single patient in the simulation. It contains the following attributes:

  • id (str): The unique ID of the patient.

  • start_timestep (int): The timestep at which the patient enters the workflow.

  • properties (Dict[str, Any]): A dictionary of properties for the patient.

  • history (List[History]): A list of history objects, which track the patientโ€™s history through the workflow.

  • current_state (str): The ID of the current state that the patient is in.

The most useful method is the get_sum_utilities() method, which returns the sum of the utilities achieved by the patient over the course of the entire simulation. Each unique utility unit (e.g. โ€œQALYsโ€, โ€œ$โ€, etc.) will get its own key in the returned dictionary.

1# Get the sum of the utilities achieved by the patient over the course of the entire simulation
2sum_utilities: Dict[str, float] = patient.get_sum_utilities(simulation)
3print(sum_utilities)

The most useful attribute is the history attribute. It contains a list of History objects. This allows you to trace the patientโ€™s entire journey through the workflow.

1# Print the patient's history
2print(patient.history)

Transition๏ƒ

For full documentation, see Transition.

Patients move between states through transitions. There are three types of transitions:

  • Deterministic โ€“ A single, predefined transition per state.

  • Probabilistic โ€“ Transitions occur with specified probabilities (e.g., 30% โ€œhigh-riskโ€, 70% โ€œlow-riskโ€).

  • Conditional โ€“ Transitions based on Boolean expressions evaluating patient-level or system-level conditions (e.g., a gene therapy succeeding only for patients with a specific mutation).

You do not need to interact with this class directly.

State๏ƒ

For full documentation, see State.

States are the building blocks of the workflow. Each state has a unique ID, a label, a type, a duration, and a list of transitions.

You do not need to interact with this class directly.

Utility๏ƒ

For full documentation, see Utility.

APLUS supports tracking multiple utility measures to evaluate workflow effectiveness:

  • Time-based (e.g., patient length-of-stay)

  • Clinical (e.g., patient outcomes)

  • Financial (e.g., cost impact)

  • Resource-related (e.g., staff utilization)

Utilities can be conditioned on expressions, allowing individual-level utility analyses based on patient properties.

You do not need to interact with this class directly.

Temporal and Resource Modeling๏ƒ

Time Duration: Each state and transition can have an associated time duration, defining the number of simulation time steps before progression. Example:

  • A hospital workflow where post-surgery patients stay in a โ€œrestโ€ state before daily evaluations.

Resource Constraints: Transitions can alter system-level resources via resource deltas, simulating real-world capacity limits. Example:

  • A transition directing a patient to an MRI scan may decrease MRI capacity by 1.