Skip to content

Commit e878f51

Browse files
authored
Merge pull request #27 from pythonhealthdatascience/dev
PATCH: v3.0.1. Trauma and non trauma pathway fixes
2 parents 2539a1f + 47a3515 commit e878f51

File tree

2 files changed

+124
-57
lines changed

2 files changed

+124
-57
lines changed

CHANGES.md

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,12 @@
11
# Change Log
22

3+
## v3.0.1
4+
5+
2nd May 2024
6+
7+
* PATCH: Trauma patient treatment fixed to use the correct distribution and parameters
8+
* PATCH: Tramna and non-trauma pathways updated to self internal instance of `Scenario` class as opposed to module level variable.
9+
310
## v3.0.0
411

512
22nd April 2024

model.py

Lines changed: 117 additions & 57 deletions
Original file line numberDiff line numberDiff line change
@@ -333,35 +333,114 @@ def sample(self, size=None):
333333
class Scenario:
334334
'''
335335
Container class for scenario parameters/arguments
336-
337-
For convienience a container class is used to hold the large number of model
338-
parameters. The `Scenario` class includes defaults these can easily be
339-
changed and at runtime to experiments with different designs.
340336
341337
Passed to a model and its process classes
342338
'''
343-
def __init__(self, random_number_set=DEFAULT_RNG_SET):
339+
def __init__(self, random_number_set=DEFAULT_RNG_SET,
340+
n_triage=DEFAULT_N_TRIAGE,
341+
n_reg=DEFAULT_N_REG,
342+
n_exam=DEFAULT_N_EXAM,
343+
n_trauma=DEFAULT_N_TRAUMA,
344+
n_cubicles_1=DEFAULT_N_CUBICLES_1,
345+
n_cubicles_2=DEFAULT_N_CUBICLES_2,
346+
triage_mean=DEFAULT_TRIAGE_MEAN,
347+
reg_mean=DEFAULT_REG_MEAN,
348+
reg_var=DEFAULT_REG_VAR,
349+
exam_mean=DEFAULT_EXAM_MEAN,
350+
exam_var=DEFAULT_EXAM_VAR,
351+
trauma_mean=DEFAULT_TRAUMA_MEAN,
352+
trauma_treat_mean=DEFAULT_TRAUMA_TREAT_MEAN,
353+
trauma_treat_var=DEFAULT_TRAUMA_TREAT_VAR,
354+
non_trauma_treat_mean=DEFAULT_NON_TRAUMA_TREAT_MEAN,
355+
non_trauma_treat_var=DEFAULT_NON_TRAUMA_TREAT_VAR,
356+
non_trauma_treat_p=DEFAULT_NON_TRAUMA_TREAT_P,
357+
prob_trauma=DEFAULT_PROB_TRAUMA):
344358
'''
345-
The init method sets up our defaults.
359+
Create a scenario to parameterise the simulation model
346360
347361
Parameters:
348362
-----------
349363
random_number_set: int, optional (default=DEFAULT_RNG_SET)
350364
Set to control the initial seeds of each stream of pseudo
351365
random numbers used in the model.
366+
367+
n_triage: int
368+
The number of triage cubicles
369+
370+
n_reg: int
371+
The number of registration clerks
372+
373+
n_exam: int
374+
The number of examination rooms
375+
376+
n_trauma: int
377+
The number of trauma bays for stablisation
378+
379+
n_cubicles_1: int
380+
The number of non-trauma treatment cubicles
381+
382+
n_cubicles_2: int
383+
The number of trauma treatment cubicles
384+
385+
triage_mean: float
386+
Mean duration of the triage distribution (Exponential)
387+
388+
reg_mean: float
389+
Mean duration of the registration distribution (Lognormal)
390+
391+
reg_var: float
392+
Variance of the registration distribution (Lognormal)
393+
394+
exam_mean: float
395+
Mean of the examination distribution (Normal)
396+
397+
exam_var: float
398+
Variance of the examination distribution (Normal)
399+
400+
trauma_mean: float
401+
Mean of the trauma stabilisation distribution (Exponential)
402+
403+
trauma_treat_mean: float
404+
Mean of the trauma cubicle treatment distribution (Lognormal)
405+
406+
trauma_treat_var: float
407+
Variance of the trauma cubicle treatment distribution (Lognormal)
408+
409+
non_trauma_treat_mean: float
410+
Mean of the non trauma treatment distribution
411+
412+
non_trauma_treat_var: float
413+
Variance of the non trauma treatment distribution
414+
415+
non_trauma_treat_p: float
416+
Probability non trauma patient requires treatment
417+
418+
prob_trauma: float
419+
probability that a new arrival is a trauma patient.
352420
'''
353421
# sampling
354422
self.random_number_set = random_number_set
355-
356-
# count of each type of resource
357-
self.init_resourse_counts()
358-
359-
# pathway variables
360-
self.init_pathway_variables()
361-
362-
# sampling distributions
423+
424+
# store parameters for sampling
425+
self.triage_mean = triage_mean
426+
self.reg_mean = reg_mean
427+
self.reg_var = reg_var
428+
self.exam_mean= exam_mean
429+
self.exam_var = exam_var
430+
self.trauma_mean = trauma_mean
431+
self.trauma_treat_mean = trauma_treat_mean
432+
self.trauma_treat_var = trauma_treat_var
433+
self.non_trauma_treat_mean = non_trauma_treat_mean
434+
self.non_trauma_treat_var = non_trauma_treat_var
435+
self.non_trauma_treat_p = non_trauma_treat_p
436+
self.prob_trauma = prob_trauma
437+
363438
self.init_sampling()
364-
439+
440+
# count of each type of resource
441+
self.init_resourse_counts(n_triage, n_reg, n_exam, n_trauma,
442+
n_cubicles_1, n_cubicles_2)
443+
365444
def set_random_no_set(self, random_number_set):
366445
'''
367446
Controls the random sampling
@@ -374,53 +453,40 @@ def set_random_no_set(self, random_number_set):
374453
self.random_number_set = random_number_set
375454
self.init_sampling()
376455

377-
def init_resourse_counts(self):
456+
def init_resourse_counts(self, n_triage, n_reg, n_exam, n_trauma,
457+
n_cubicles_1, n_cubicles_2):
378458
'''
379459
Init the counts of resources to default values...
380460
'''
381-
self.n_triage = DEFAULT_N_TRIAGE
382-
self.n_reg = DEFAULT_N_REG
383-
self.n_exam = DEFAULT_N_EXAM
384-
self.n_trauma = DEFAULT_N_TRAUMA
461+
self.n_triage = n_triage
462+
self.n_reg = n_reg
463+
self.n_exam = n_exam
464+
self.n_trauma = n_trauma
385465

386466
# non-trauma (1), trauma (2) treatment cubicles
387-
self.n_cubicles_1 = DEFAULT_N_CUBICLES_1
388-
self.n_cubicles_2 = DEFAULT_N_CUBICLES_2
389-
390-
def init_pathway_variables(self):
391-
# trauma pathway
392-
self.prob_trauma = DEFAULT_PROB_TRAUMA
393-
self.treat_trauma_mean = DEFAULT_TRAUMA_TREAT_MEAN
394-
self.treat_trauma_var = DEFAULT_TRAUMA_TREAT_VAR
395-
396-
#non trauma pathway
397-
self.exam_mean = DEFAULT_EXAM_MEAN
398-
self.exam_var = DEFAULT_EXAM_VAR
399-
400-
self.nt_treat_prob = DEFAULT_NON_TRAUMA_TREAT_P
401-
self.nt_treat_mean = DEFAULT_NON_TRAUMA_TREAT_MEAN
402-
self.nt_treat_var = DEFAULT_NON_TRAUMA_TREAT_VAR
467+
self.n_cubicles_1 = n_cubicles_1
468+
self.n_cubicles_2 = n_cubicles_2
403469

404470
def init_sampling(self):
405471
'''
406472
Create the distributions used by the model and initialise
407473
the random seeds of each.
408-
'''
474+
'''
409475
# MODIFICATION. Better method for producing n non-overlapping streams
410476
seed_sequence = np.random.SeedSequence(self.random_number_set)
411477

412478
# Generate n high quality child seeds
413479
self.seeds = seed_sequence.spawn(N_STREAMS)
414-
480+
415481
# create distributions
416482

417483
# Triage duration
418-
self.triage_dist = Exponential(DEFAULT_TRIAGE_MEAN,
484+
self.triage_dist = Exponential(self.triage_mean,
419485
random_seed=self.seeds[0])
420486

421487
# Registration duration (non-trauma only)
422-
self.reg_dist = Lognormal(DEFAULT_REG_MEAN,
423-
np.sqrt(DEFAULT_REG_VAR),
488+
self.reg_dist = Lognormal(self.reg_mean,
489+
np.sqrt(self.reg_var),
424490
random_seed=self.seeds[1])
425491

426492
# Evaluation (non-trauma only)
@@ -429,21 +495,21 @@ def init_sampling(self):
429495
random_seed=self.seeds[2])
430496

431497
# Trauma/stablisation duration (trauma only)
432-
self.trauma_dist = Exponential(DEFAULT_TRAUMA_MEAN,
498+
self.trauma_dist = Exponential(self.trauma_mean,
433499
random_seed=self.seeds[3])
434500

435501
# Non-trauma treatment
436-
self.nt_treat_dist = Lognormal(self.nt_treat_mean,
437-
np.sqrt(self.nt_treat_var),
502+
self.nt_treat_dist = Lognormal(self.non_trauma_treat_mean,
503+
np.sqrt(self.non_trauma_treat_var),
438504
random_seed=self.seeds[4])
439505

440506
# treatment of trauma patients
441-
self.treat_dist = Lognormal(self.treat_trauma_mean,
442-
np.sqrt(self.treat_trauma_var),
507+
self.treat_dist = Lognormal(self.trauma_treat_mean,
508+
np.sqrt(self.trauma_treat_var),
443509
random_seed=self.seeds[5])
444510

445511
# probability of non-trauma patient requiring treatment
446-
self.nt_p_treat_dist = Bernoulli(self.nt_treat_prob,
512+
self.nt_p_treat_dist = Bernoulli(self.non_trauma_treat_p,
447513
random_seed=self.seeds[6])
448514

449515

@@ -453,8 +519,7 @@ def init_sampling(self):
453519

454520
# init sampling for non-stationary poisson process
455521
self.init_nspp()
456-
457-
522+
458523
def init_nspp(self):
459524

460525
# read arrival profile
@@ -571,7 +636,7 @@ def execute(self):
571636
f'{self.env.now:.3f}')
572637

573638
# sample treatment duration.
574-
self.treat_duration = self.args.trauma_dist.sample()
639+
self.treat_duration = self.args.treat_dist.sample()
575640
yield self.env.timeout(self.treat_duration)
576641

577642
self.treatment_complete()
@@ -601,7 +666,7 @@ def treatment_complete(self):
601666
f'waiting time was {self.wait_treat:.3f}')
602667

603668

604-
class NonTraumaPathway(object):
669+
class NonTraumaPathway:
605670
'''
606671
Encapsulates the process a patient with minor injuries and illness.
607672
@@ -743,15 +808,10 @@ def execute(self):
743808
f'waiting time was {self.wait_treat:.3f}')
744809

745810
# total time in system
746-
self.total_time = self.env.now - self.arrival
811+
self.total_time = self.env.now - self.arrival
747812

748813

749814
# ## Main model class
750-
#
751-
752-
753-
# In[ ]:
754-
755815

756816
class TreatmentCentreModel:
757817
'''

0 commit comments

Comments
 (0)