Skip to content

Commit 94be99c

Browse files
committed
Add resource animation examples
1 parent 735d502 commit 94be99c

16 files changed

Lines changed: 2232 additions & 2766 deletions

animation_examples/output_generate_animation_df.csv

Lines changed: 210 additions & 454 deletions
Large diffs are not rendered by default.

animation_examples/output_reshape_for_animations.csv

Lines changed: 210 additions & 454 deletions
Large diffs are not rendered by default.
Lines changed: 99 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,99 @@
1+
from vidigi.logging import EventLogger
2+
from vidigi.utils import EventPosition, create_event_position_df
3+
from vidigi.animation import animate_activity_log, generate_animation
4+
from vidigi.prep import generate_animation_df, reshape_for_animations
5+
from vidigi.resources import VidigiStore
6+
import simpy
7+
import numpy as np
8+
9+
class g:
10+
n_cubicles =5
11+
12+
class Patient:
13+
def __init__(self, p_id):
14+
self.id = p_id
15+
16+
class SimpleActivityModel:
17+
def __init__(self, master_seed=42):
18+
self.env = simpy.Environment()
19+
self.patient_counter = 0
20+
self.patient_inter = 2
21+
self.logger = EventLogger(env=self.env)
22+
23+
# Seed setup using numpy's SeedSequence
24+
self.master_seed = master_seed
25+
self.seed_seq = np.random.SeedSequence(master_seed)
26+
self.rng = np.random.default_rng(self.seed_seq)
27+
28+
self.cubicles = VidigiStore(self.env, num_resources=g.n_cubicles)
29+
30+
def generate_arrivals(self):
31+
while True:
32+
self.patient_counter += 1
33+
p = Patient(self.patient_counter)
34+
self.logger.log_arrival(entity_id=p.id)
35+
self.env.process(self.patient_journey(p))
36+
sampled_inter = self.rng.exponential(scale=self.patient_inter)
37+
yield self.env.timeout(sampled_inter)
38+
39+
def patient_journey(self, patient):
40+
self.logger.log_queue(entity_id=patient.id, event="wait_here")
41+
42+
with self.cubicles.request() as req:
43+
cubicle = yield req
44+
45+
self.logger.log_resource_use_start(
46+
entity_id=patient.id,
47+
event="start_treatment",
48+
resource_id=cubicle.id_attribute
49+
)
50+
51+
yield self.env.timeout(self.rng.uniform(low=1, high=10))
52+
53+
self.logger.log_resource_use_end(
54+
entity_id=patient.id,
55+
event="end_treatment",
56+
resource_id=cubicle.id_attribute
57+
)
58+
59+
self.logger.log_departure(entity_id=patient.id)
60+
61+
def run(self):
62+
self.env.process(self.generate_arrivals())
63+
self.env.run(until=180)
64+
65+
model = SimpleActivityModel()
66+
model.run()
67+
event_log = model.logger.to_dataframe()
68+
# event_log.to_csv("test_log.csv")
69+
70+
event_position_df = create_event_position_df([
71+
EventPosition(event="wait_here", x=150 , y=150 , label="Wait Here!"),
72+
EventPosition(event="start_treatment", x=150 , y=75 , resource="n_cubicles", label="Be Treated"),
73+
EventPosition(event="depart", x=150, y=5, label="Exit")
74+
])
75+
76+
animate_activity_log(
77+
event_log = event_log,
78+
event_position_df = event_position_df,
79+
scenario=g(),
80+
every_x_time_units=1,
81+
limit_duration=60,
82+
override_x_max=300,
83+
override_y_max=250,
84+
plotly_height=600,
85+
plotly_width=1100,
86+
display_stage_labels=True,
87+
gap_between_entities=20,
88+
entity_icon_size=40,
89+
wrap_queues_at=10,
90+
gap_between_resources=30,
91+
gap_between_queue_rows=30,
92+
resource_icon_size=80,
93+
simulation_time_unit="minutes",
94+
custom_resource_icon="☐",
95+
resource_opacity=0.7,
96+
debug_write_intermediate_objects=True
97+
).update_layout(
98+
plot_bgcolor='white',
99+
)
Lines changed: 99 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,99 @@
1+
from vidigi.logging import EventLogger
2+
from vidigi.utils import EventPosition, create_event_position_df
3+
from vidigi.animation import animate_activity_log, generate_animation
4+
from vidigi.prep import generate_animation_df, reshape_for_animations
5+
from vidigi.resources import VidigiStore
6+
import simpy
7+
import numpy as np
8+
9+
class g:
10+
n_cubicles = 1
11+
12+
class Patient:
13+
def __init__(self, p_id):
14+
self.id = p_id
15+
16+
class SimpleActivityModel:
17+
def __init__(self, master_seed=42):
18+
self.env = simpy.Environment()
19+
self.patient_counter = 0
20+
self.patient_inter = 2
21+
self.logger = EventLogger(env=self.env)
22+
23+
# Seed setup using numpy's SeedSequence
24+
self.master_seed = master_seed
25+
self.seed_seq = np.random.SeedSequence(master_seed)
26+
self.rng = np.random.default_rng(self.seed_seq)
27+
28+
self.cubicles = VidigiStore(self.env, num_resources=g.n_cubicles)
29+
30+
def generate_arrivals(self):
31+
while True:
32+
self.patient_counter += 1
33+
p = Patient(self.patient_counter)
34+
self.logger.log_arrival(entity_id=p.id)
35+
self.env.process(self.patient_journey(p))
36+
sampled_inter = self.rng.exponential(scale=self.patient_inter)
37+
yield self.env.timeout(sampled_inter)
38+
39+
def patient_journey(self, patient):
40+
self.logger.log_queue(entity_id=patient.id, event="wait_here")
41+
42+
with self.cubicles.request() as req:
43+
cubicle = yield req
44+
45+
self.logger.log_resource_use_start(
46+
entity_id=patient.id,
47+
event="start_treatment",
48+
resource_id=cubicle.id_attribute
49+
)
50+
51+
yield self.env.timeout(self.rng.uniform(low=1, high=10))
52+
53+
self.logger.log_resource_use_end(
54+
entity_id=patient.id,
55+
event="end_treatment",
56+
resource_id=cubicle.id_attribute
57+
)
58+
59+
self.logger.log_departure(entity_id=patient.id)
60+
61+
def run(self):
62+
self.env.process(self.generate_arrivals())
63+
self.env.run(until=180)
64+
65+
model = SimpleActivityModel()
66+
model.run()
67+
event_log = model.logger.to_dataframe()
68+
# event_log.to_csv("test_log.csv")
69+
70+
event_position_df = create_event_position_df([
71+
EventPosition(event="wait_here", x=150 , y=150 , label="Wait Here!"),
72+
EventPosition(event="start_treatment", x=150 , y=75 , resource="n_cubicles", label="Be Treated"),
73+
EventPosition(event="depart", x=150, y=5, label="Exit")
74+
])
75+
76+
animate_activity_log(
77+
event_log = event_log,
78+
event_position_df = event_position_df,
79+
scenario=g(),
80+
every_x_time_units=1,
81+
limit_duration=60,
82+
override_x_max=300,
83+
override_y_max=250,
84+
plotly_height=600,
85+
plotly_width=1100,
86+
display_stage_labels=True,
87+
gap_between_entities=20,
88+
entity_icon_size=40,
89+
wrap_queues_at=10,
90+
gap_between_resources=30,
91+
gap_between_queue_rows=30,
92+
resource_icon_size=80,
93+
simulation_time_unit="minutes",
94+
custom_resource_icon="☐",
95+
resource_opacity=0.7,
96+
debug_write_intermediate_objects=True
97+
).update_layout(
98+
plot_bgcolor='white',
99+
)

0 commit comments

Comments
 (0)