import pandas as pd
# Import the wrapper objects for model interaction.
from examples.example_4_ciw.ex_4_ciw_model import Experiment, multiple_replications
from vidigi.utils import event_log_from_ciw_recs
from vidigi.animation import animate_activity_log
Example 4: A ciw Model
Note that this example is written using ciw 2.x
It will not run with 3.x - but could theoretically be adapted to do so
The ‘logs’ object is the result of running
sim_engine.get_all_records()
However, note that while we run multiple replications, we only pass the records for a single replication to the event_log_from_ciw_recs
function.
The underlying model code is from Monks, T., Harper, A., & Heather, A. (2023). Towards Sharing Tools, Artefacts, and Reproducible Simulation: a ciw model example (v1.0.1). Zenodo. https://doi.org/10.5281/zenodo.10051494
See here for the adaptation embedded within that repo: https://github.com/Bergam0t/ciw-example-animation/tree/main
= 13
N_OPERATORS = 9
N_NURSES = 1000
RESULTS_COLLECTION_PERIOD
= Experiment(n_operators=N_OPERATORS,
user_experiment =N_NURSES,
n_nurses=0.4)
chance_callback
# run multiple replications
= multiple_replications(user_experiment, n_reps=10)
results, logs
# the 'logs' object contains a list, where each entry is the recs object for that run
= logs[0]
logs_run_1
print(len(logs_run_1))
2266
# let's print all of the outputs for a single individual
print(log) for log in logs_run_1 if log.id_number==500]
[
# let's now try turning this into an event log
= event_log_from_ciw_recs(logs_run_1, node_name_list=["operator", "nurse"])
event_log_test
25) event_log_test.head(
Record(id_number=500, customer_class=0, original_customer_class=0, node=1, arrival_date=269.6165843237451, waiting_time=14.514495676004913, service_start_date=284.13107999975, service_time=8.289105946048721, service_end_date=292.4201859457987, time_blocked=0.0, exit_date=292.4201859457987, destination=-1, queue_size_at_arrival=37, queue_size_at_departure=43, server_id=1, record_type='service')
patient | pathway | event_type | event | time | resource_id | |
---|---|---|---|---|---|---|
0 | 1 | Model | arrival_departure | arrival | 0.503707 | NaN |
1 | 1 | Model | queue | operator_wait_begins | 0.503707 | NaN |
2 | 1 | Model | resource_use | operator_begins | 0.503707 | 1.0 |
3 | 1 | Model | resource_use | operator_ends | 6.136387 | 1.0 |
4 | 1 | Model | queue | nurse_wait_begins | 6.136387 | NaN |
5 | 1 | Model | resource_use | nurse_begins | 6.136387 | 1.0 |
6 | 1 | Model | resource_use | nurse_ends | 23.061561 | 1.0 |
7 | 1 | Model | arrival_departure | depart | 23.061561 | NaN |
8 | 2 | Model | arrival_departure | arrival | 1.048958 | NaN |
9 | 2 | Model | queue | operator_wait_begins | 1.048958 | NaN |
10 | 2 | Model | resource_use | operator_begins | 1.048958 | 2.0 |
11 | 2 | Model | resource_use | operator_ends | 8.075635 | 2.0 |
12 | 2 | Model | arrival_departure | depart | 8.075635 | NaN |
13 | 3 | Model | arrival_departure | arrival | 1.392097 | NaN |
14 | 3 | Model | queue | operator_wait_begins | 1.392097 | NaN |
15 | 3 | Model | resource_use | operator_begins | 1.392097 | 3.0 |
16 | 3 | Model | resource_use | operator_ends | 8.482409 | 3.0 |
17 | 3 | Model | queue | nurse_wait_begins | 8.482409 | NaN |
18 | 3 | Model | resource_use | nurse_begins | 8.482409 | 2.0 |
19 | 3 | Model | resource_use | nurse_ends | 19.488025 | 2.0 |
20 | 3 | Model | arrival_departure | depart | 19.488025 | NaN |
21 | 4 | Model | arrival_departure | arrival | 2.280472 | NaN |
22 | 4 | Model | queue | operator_wait_begins | 2.280472 | NaN |
23 | 4 | Model | resource_use | operator_begins | 2.280472 | 4.0 |
24 | 4 | Model | resource_use | operator_ends | 10.076369 | 4.0 |
# Create required event_position_df for vidigi animation
= pd.DataFrame([
event_position_df 'event': 'arrival',
{'x': 30, 'y': 350,
'label': "Arrival"},
'event': 'operator_wait_begins',
{'x': 205, 'y': 270,
'label': "Waiting for Operator"},
'event': 'operator_begins',
{'x': 210, 'y': 210,
'resource':'n_operators',
'label': "Speaking to operator"},
'event': 'nurse_wait_begins',
{'x': 205, 'y': 110,
'label': "Waiting for Nurse"},
'event': 'nurse_begins',
{'x': 210, 'y': 50,
'resource':'n_nurses',
'label': "Speaking to Nurse"},
'event': 'exit',
{'x': 270, 'y': 10,
'label': "Exit"}
])
# Create a suitable class to pass in the resource numbers
class model_params():
= N_OPERATORS
n_operators = N_NURSES n_nurses
# Create animation
animate_activity_log(=event_log_test,
event_log= event_position_df,
event_position_df=model_params(),
scenario=True,
debug_mode=False,
setup_mode=1,
every_x_time_units=True,
include_play_button=20,
icon_and_text_size=8,
gap_between_entities=25,
gap_between_rows=700,
plotly_height=200,
frame_duration=1200,
plotly_width=300,
override_x_max=300,
override_y_max=RESULTS_COLLECTION_PERIOD,
limit_duration=25,
wrap_queues_at=75,
step_snapshot_max="dhm",
time_display_units=True,
display_stage_labels )
Animation function called at 18:07:36
Iteration through minute-by-minute logs complete 18:07:40
Snapshot df concatenation complete at 18:07:40
Reshaped animation dataframe finished construction at 18:07:40
Placement dataframe finished construction at 18:07:40
Output animation generation complete at 18:07:44
Total Time Elapsed: 7.97 seconds
Unable to display output for mime type(s): application/vnd.plotly.v1+json