Skip to content

Commit ea7011d

Browse files
authored
Merge pull request #141 from The-Strategy-Unit/initial-routing
Initial routing
2 parents 4f9ff69 + 978d002 commit ea7011d

File tree

4 files changed

+244
-52
lines changed

4 files changed

+244
-52
lines changed

renal_capacity_model/config.py

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -65,17 +65,21 @@ def __init__(
6565
]
6666
self.death_post_transplant = config_dict["death_post_transplant"]
6767
self.death_post_dialysis_modality = config_dict["death_post_dialysis_modality"]
68-
68+
self.death_post_dialysis_modality_incident = config_dict[
69+
"death_post_dialysis_modality_incident"
70+
]
6971
self.pre_emptive_transplant_live_donor_dist = config_dict[
7072
"pre_emptive_transplant_live_donor_dist"
7173
]
7274

7375
self.pre_emptive_transplant_cadaver_donor_dist = config_dict[
7476
"pre_emptive_transplant_cadaver_donor_dist"
7577
]
78+
self.death_post_transplant_glm = config_dict["death_post_transplant_glm"]
7679
# time to event distribution parameters (these are the same regardless of geography)
7780
self.ttd_con_care = ttd_con_care_values
7881
self.tw_before_dialysis = tw_before_dialysis_values
82+
7983
self.time_to_event_curves = load_time_to_event_curves(
8084
path_to_time_to_event_curves
8185
)

renal_capacity_model/config_values.py

Lines changed: 113 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -166,75 +166,131 @@
166166
},
167167
"death_post_transplant": {
168168
"live": {
169-
1: 0.05,
170-
2: 0.15,
171-
3: 0.26,
172-
4: 0.38,
173-
5: 0.50,
174-
6: 0.63,
169+
1: 0.08,
170+
2: 0.20,
171+
3: 0.34,
172+
4: 0.50,
173+
5: 0.67,
174+
6: 0.85,
175175
},
176176
"cadaver": {
177-
1: 0.07,
178-
2: 0.17,
179-
3: 0.27,
180-
4: 0.42,
181-
5: 0.54,
182-
6: 0.73,
177+
1: 0.09,
178+
2: 0.21,
179+
3: 0.35,
180+
4: 0.53,
181+
5: 0.68,
182+
6: 0.84,
183183
},
184184
},
185-
"death_post_dialysis_modality": {
185+
"death_post_dialysis_modality": { # prevalent patients
186186
"ichd": {
187187
"early": {
188-
1: 0.08,
189-
2: 0.15,
190-
3: 0.18,
191-
4: 0.25,
192-
5: 0.3,
193-
6: 0.35,
188+
1: 0.18,
189+
2: 0.28,
190+
3: 0.36,
191+
4: 0.48,
192+
5: 0.54,
193+
6: 0.60,
194194
},
195195
"late": {
196-
1: 0.07,
197-
2: 0.14,
198-
3: 0.19,
199-
4: 0.24,
200-
5: 0.31,
201-
6: 0.35,
196+
1: 0.14,
197+
2: 0.28,
198+
3: 0.36,
199+
4: 0.49,
200+
5: 0.53,
201+
6: 0.62,
202202
},
203203
},
204204
"hhd": {
205205
"early": {
206-
1: 0.08,
207-
2: 0.16,
208-
3: 0.17,
209-
4: 0.27,
210-
5: 0.21,
211-
6: 0.28,
206+
1: 0.11,
207+
2: 0.18,
208+
3: 0.27,
209+
4: 0.37,
210+
5: 0.51,
211+
6: 0.51,
212212
},
213213
"late": {
214-
1: 0.07,
214+
1: 0.11,
215+
2: 0.18,
216+
3: 0.27,
217+
4: 0.37,
218+
5: 0.51,
219+
6: 0.51,
220+
},
221+
},
222+
"pd": {
223+
"early": {
224+
1: 0.04,
215225
2: 0.09,
226+
3: 0.15,
227+
4: 0.22,
228+
5: 0.28,
229+
6: 0.42,
230+
},
231+
"late": {
232+
1: 0.04,
233+
2: 0.02,
216234
3: 0.14,
235+
4: 0.24,
236+
5: 0.33,
237+
6: 0.33,
238+
},
239+
},
240+
},
241+
"death_post_dialysis_modality_incident": { # incident patients
242+
"ichd": {
243+
"early": {
244+
1: 0.07,
245+
2: 0.12,
246+
3: 0.16,
217247
4: 0.22,
218-
5: 0.18,
219-
6: 0.22,
248+
5: 0.27,
249+
6: 0.33,
250+
},
251+
"late": {
252+
1: 0.06,
253+
2: 0.13,
254+
3: 0.18,
255+
4: 0.22,
256+
5: 0.27,
257+
6: 0.33,
220258
},
221259
},
222-
"pd": {
260+
"hhd": {
223261
"early": {
224262
1: 0.05,
225-
2: 0.08,
226-
3: 0.14,
263+
2: 0.14,
264+
3: 0.19,
227265
4: 0.24,
228-
5: 0.31,
229-
6: 0.38,
266+
5: 0.20,
267+
6: 0.30,
268+
},
269+
"late": {
270+
1: 0.09,
271+
2: 0.17,
272+
3: 0.15,
273+
4: 0.21,
274+
5: 0.15,
275+
6: 0.29,
276+
},
277+
},
278+
"pd": {
279+
"early": {
280+
1: 0.04,
281+
2: 0.06,
282+
3: 0.11,
283+
4: 0.21,
284+
5: 0.29,
285+
6: 0.36,
230286
},
231287
"late": {
232288
1: 0.04,
233289
2: 0.1,
234-
3: 0.12,
235-
4: 0.24,
236-
5: 0.35,
237-
6: 0.41,
290+
3: 0.11,
291+
4: 0.22,
292+
5: 0.32,
293+
6: 0.40,
238294
},
239295
},
240296
},
@@ -244,6 +300,20 @@
244300
"pre_emptive_transplant_cadaver_donor_dist": {
245301
y: {"early": 0.22, "late": 0.05} for y in range(1, 14)
246302
},
303+
"death_post_transplant_glm": {
304+
"live": {
305+
"intercept": -4.184,
306+
"time_in_system": 0.0003,
307+
"age": 0.6348,
308+
"ref_stat": -0.3346, # early = 0 , late =1
309+
},
310+
"cadaver": {
311+
"intercept": -3.87,
312+
"time_in_system": 0.0003,
313+
"age": 0.562,
314+
"ref_stat": -0.127, # early = 0 , late =1
315+
},
316+
},
247317
}
248318

249319
# Time to death: conservative care

renal_capacity_model/load_scenario.py

Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -731,6 +731,62 @@ def load_scenario_from_excel(
731731
},
732732
},
733733
}
734+
config_from_excel["death_post_dialysis_modality_incident"] = {
735+
"ichd": {
736+
"early": {
737+
1: input_scenario.iat[104, 6],
738+
2: input_scenario.iat[105, 6],
739+
3: input_scenario.iat[106, 6],
740+
4: input_scenario.iat[107, 6],
741+
5: input_scenario.iat[108, 6],
742+
6: input_scenario.iat[109, 6],
743+
},
744+
"late": {
745+
1: input_scenario.iat[110, 6],
746+
2: input_scenario.iat[111, 6],
747+
3: input_scenario.iat[112, 6],
748+
4: input_scenario.iat[113, 6],
749+
5: input_scenario.iat[114, 6],
750+
6: input_scenario.iat[115, 6],
751+
},
752+
},
753+
"hhd": {
754+
"early": {
755+
1: input_scenario.iat[104, 7],
756+
2: input_scenario.iat[105, 7],
757+
3: input_scenario.iat[106, 7],
758+
4: input_scenario.iat[107, 7],
759+
5: input_scenario.iat[108, 7],
760+
6: input_scenario.iat[109, 7],
761+
},
762+
"late": {
763+
1: input_scenario.iat[110, 7],
764+
2: input_scenario.iat[111, 7],
765+
3: input_scenario.iat[112, 7],
766+
4: input_scenario.iat[113, 7],
767+
5: input_scenario.iat[114, 7],
768+
6: input_scenario.iat[115, 7],
769+
},
770+
},
771+
"pd": {
772+
"early": {
773+
1: input_scenario.iat[104, 8],
774+
2: input_scenario.iat[105, 8],
775+
3: input_scenario.iat[106, 8],
776+
4: input_scenario.iat[107, 8],
777+
5: input_scenario.iat[108, 8],
778+
6: input_scenario.iat[109, 8],
779+
},
780+
"late": {
781+
1: input_scenario.iat[110, 8],
782+
2: input_scenario.iat[111, 8],
783+
3: input_scenario.iat[112, 8],
784+
4: input_scenario.iat[113, 8],
785+
5: input_scenario.iat[114, 8],
786+
6: input_scenario.iat[115, 8],
787+
},
788+
},
789+
}
734790
config_from_excel["pre_emptive_transplant_live_donor_dist"] = {
735791
1: {
736792
"early": input_scenario.iat[55, 18],
@@ -902,4 +958,19 @@ def load_scenario_from_excel(
902958
"living_with_transplant": input_scenario.iat[39, 1],
903959
}
904960

961+
config_from_excel["death_post_transplant_glm"] = {
962+
"live": {
963+
"intercept": input_scenario.iat[120, 7],
964+
"time_in_system": input_scenario.iat[121, 7],
965+
"age": input_scenario.iat[122, 7],
966+
"ref_stat": input_scenario.iat[123, 7],
967+
},
968+
"cadaver": {
969+
"intercept": input_scenario.iat[120, 6],
970+
"time_in_system": input_scenario.iat[121, 6],
971+
"age": input_scenario.iat[122, 6],
972+
"ref_stat": input_scenario.iat[123, 6],
973+
},
974+
}
975+
905976
return config_from_excel

renal_capacity_model/model.py

Lines changed: 55 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -504,9 +504,28 @@ def start_transplant(self, patient: Patient) -> Generator:
504504
patient.time_of_transplant = self.env.now
505505
if patient.transplant_type == "live":
506506
# how long the graft lasts depends on where they go next: death or back to start_krt
507+
if patient.patient_flag == "incident":
508+
prob_death_post_tx = 1 / (
509+
1
510+
+ np.exp(
511+
self.config.death_post_transplant_glm["live"]["intercept"]
512+
+ self.config.death_post_transplant_glm["live"][
513+
"time_in_system"
514+
]
515+
* (self.env.now - patient.start_time_in_system)
516+
+ self.config.death_post_transplant_glm["live"]["age"]
517+
* patient.age_group
518+
+ self.config.death_post_transplant_glm["live"]["ref_stat"]
519+
* (0 if patient.referral_type == "early" else 1)
520+
)
521+
)
522+
else:
523+
prob_death_post_tx = self.config.death_post_transplant["live"][
524+
patient.age_group
525+
]
507526
if (
508527
self.rng.uniform(0, 1)
509-
< self.config.death_post_transplant["live"][patient.age_group]
528+
< prob_death_post_tx # self.config.death_post_transplant["live"][patient.age_group]
510529
):
511530
# patient dies after transplant
512531

@@ -583,9 +602,34 @@ def start_transplant(self, patient: Patient) -> Generator:
583602
self.env.process(self.start_krt(patient))
584603
else: # cadaver
585604
# how long the graft lasts depends on where they go next: death or back to start_krt
605+
if patient.patient_flag == "incident":
606+
prob_death_post_tx = 1 / (
607+
1
608+
+ np.exp(
609+
-(
610+
self.config.death_post_transplant_glm["cadaver"][
611+
"intercept"
612+
]
613+
+ self.config.death_post_transplant_glm["cadaver"][
614+
"time_in_system"
615+
]
616+
* (self.env.now - patient.start_time_in_system)
617+
+ self.config.death_post_transplant_glm["cadaver"]["age"]
618+
* patient.age_group
619+
+ self.config.death_post_transplant_glm["cadaver"][
620+
"ref_stat"
621+
]
622+
* (0 if patient.referral_type == "early" else 1)
623+
)
624+
)
625+
)
626+
else:
627+
prob_death_post_tx = self.config.death_post_transplant["cadaver"][
628+
patient.age_group
629+
]
586630
if (
587631
self.rng.uniform(0, 1)
588-
< self.config.death_post_transplant["cadaver"][patient.age_group]
632+
< prob_death_post_tx # self.config.death_post_transplant["cadaver"][patient.age_group]
589633
):
590634
# patient dies after transplant
591635

@@ -753,12 +797,15 @@ def start_dialysis_modality(self, patient: Patient) -> Generator:
753797

754798
# what is the next step modality change, death
755799
# if they're waiting for transplant we'll compare the time generated to patient.time on waiting list
756-
if (
757-
self.rng.uniform(0, 1)
758-
< self.config.death_post_dialysis_modality[patient.dialysis_modality][
759-
patient.referral_type
760-
][patient.age_group]
761-
):
800+
if patient.patient_flag == "incident":
801+
prob_death = self.config.death_post_dialysis_modality_incident[
802+
patient.dialysis_modality
803+
][patient.referral_type][patient.age_group]
804+
else:
805+
prob_death = self.config.death_post_dialysis_modality[
806+
patient.dialysis_modality
807+
][patient.referral_type][patient.age_group]
808+
if self.rng.uniform(0, 1) < prob_death:
762809
# death or transplant
763810
## sampled_time depends on whether patitent is inicident or not
764811
if patient.patient_flag == "incident":

0 commit comments

Comments
 (0)