66# ' may not wish to do if being set elsewhere - such as done in \code{runner()}).
77# ' Default is TRUE.
88# '
9- # ' @importFrom simmer get_mon_arrivals get_mon_resources simmer wrap
9+ # ' @importFrom dplyr filter mutate rowwise ungroup
10+ # ' @importFrom simmer add_resource get_mon_arrivals get_mon_resources simmer
11+ # ' @importFrom simmer wrap
1012# ' @importFrom utils capture.output
1113# '
1214# ' @return TBC
@@ -20,17 +22,27 @@ model <- function(run_number, param, set_seed = TRUE) {
2022 }
2123
2224 # Determine whether to get verbose activity logs
23- verbose <- any(c(param [[" log_to_console" ]], param [[" log_to_file" ]]))
25+ param [[" verbose" ]] <- any(c(param [[" log_to_console" ]],
26+ param [[" log_to_file" ]]))
2427
2528 # Transform LOS parameters to lognormal scale
2629 param [[" asu_los_lnorm" ]] <- transform_to_lnorm(param [[" asu_los" ]])
2730 param [[" rehab_los_lnorm" ]] <- transform_to_lnorm(param [[" rehab_los" ]])
2831
2932 # Create simmer environment - set verbose to FALSE as using custom logs
30- env <- simmer(" simulation" , verbose = FALSE )
33+ # (but can change to TRUE if want to see default simmer logs as well)
34+ env <- simmer(" simulation" , verbose = FALSE ,
35+ log_level = if (param [[" verbose" ]]) 1L else 0L )
3136
3237 # Add ASU and rehab direct admission patient generators
3338 for (unit in c(" asu" , " rehab" )) {
39+
40+ # Add beds resource with inifinite capacity (required so we can get metrics
41+ # on occupancy etc. based on count of patients with each resource)
42+ env <- add_resource(
43+ .env = env , name = paste0(unit , " _bed" ), capacity = Inf
44+ )
45+
3446 for (patient_type in names(param [[paste0(unit , " _arrivals" )]])) {
3547
3648 # Create patient trajectory
@@ -41,27 +53,26 @@ model <- function(run_number, param, set_seed = TRUE) {
4153 }
4254
4355 # Add patient generator using the created trajectory
44- sim_log <- capture.output(
45- env <- add_patient_generator( # nolint
46- env = env ,
47- trajectory = traj ,
48- unit = unit ,
49- patient_type = patient_type ,
50- param = param
51- )
56+ env <- add_patient_generator(
57+ env = env ,
58+ trajectory = traj ,
59+ unit = unit ,
60+ patient_type = patient_type ,
61+ param = param
5262 )
5363 }
5464 }
5565
5666 # Run the model
67+ sim_length <- param [[" data_collection_period" ]] + param [[" warm_up_period" ]]
5768 sim_log <- capture.output(
5869 env <- env | > # nolint
59- simmer :: run(20L ) | >
70+ simmer :: run(sim_length ) | >
6071 wrap()
6172 )
6273
6374 # Save and/or display the log
64- if (isTRUE(verbose )) {
75+ if (isTRUE(param [[ " verbose" ]] )) {
6576 # Create full log message by adding parameters
6677 param_string <- paste(names(param ), param , sep = " =" , collapse = " ;\n " )
6778 full_log <- append(c(" Parameters:" , param_string , " Log:" ), sim_log )
@@ -75,12 +86,39 @@ model <- function(run_number, param, set_seed = TRUE) {
7586 }
7687 }
7788
78- # Extract the monitored arrivals and resources information from the simmer
79- # environment object
80- result <- list (
81- arrivals = get_mon_arrivals(env , per_resource = TRUE , ongoing = TRUE ),
82- resources = get_mon_resources(env )
83- )
89+ # Extract the monitored arrivals info from the simmer environment object.
90+ # Remove patients with start time of -1, as they are patients whose arrival
91+ # was sampled but falls after the end of the simulation.
92+ arrivals <- get_mon_arrivals(env , per_resource = TRUE , ongoing = TRUE ) | >
93+ filter(.data [[" start_time" ]] != - 1L )
94+
95+ # Create sequence of days from 0 to end of simulation
96+ days <- seq(0L , ceiling(sim_length ))
97+
98+ # Calculate occupancy at end of each day (i.e. at time 1, 2, 3, 4...)
99+ # Make dataframe with one row per resource per day to count patients
100+ occupancy <- expand.grid(
101+ resource = unique(arrivals [[" resource" ]]),
102+ time = days
103+ ) | >
104+ rowwise() | >
105+ mutate(
106+ # For each resource and day, count patients who:
107+ # - Arrived on or before this day (start_time <= time)
108+ # - Have not yet left by this day (end_time > time), or have NA end_time
109+ # (still present at simulation end)
110+ occupancy = sum(
111+ arrivals [[" resource" ]] == .data [[" resource" ]] &
112+ arrivals [[" start_time" ]] < = .data [[" time" ]] &
113+ (is.na(arrivals [[" end_time" ]]) |
114+ arrivals [[" end_time" ]] > .data [[" time" ]])
115+ )
116+ ) | >
117+ ungroup()
118+
119+ # Set replication
120+ arrivals <- mutate(arrivals , replication = run_number )
121+ occupancy <- mutate(occupancy , replication = run_number )
84122
85- return (result )
123+ return (list ( arrivals = arrivals , occupancy = occupancy ) )
86124}
0 commit comments