Skip to content

Commit 0914625

Browse files
authored
Prevent people having Hiv_DecisionToContinueTreatment events at inappropriate times (#1129)
1 parent 3f1115b commit 0914625

File tree

5 files changed

+69
-55
lines changed

5 files changed

+69
-55
lines changed

resources/ResourceFile_HIV.xlsx

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,3 @@
11
version https://git-lfs.github.com/spec/v1
2-
oid sha256:b7613f565d446cdf31f7360cc3d72d2deae6545294a41d3b0580430bec63f7d5
3-
size 158138
2+
oid sha256:d20e316c9b00816da27cc8c104b70cec214787f0d96c80a437f8690806c5e2fb
3+
size 158196

src/scripts/hiv/projections_jan2023/analysis_full_model.py

+5-6
Original file line numberDiff line numberDiff line change
@@ -23,14 +23,14 @@
2323

2424
# %% Run the simulation
2525
start_date = Date(2010, 1, 1)
26-
end_date = Date(2018, 1, 1)
26+
end_date = Date(2020, 1, 1)
2727
popsize = 5000
28-
scenario = 0
28+
# scenario = 0
2929

3030
# set up the log config
3131
# add deviance measure logger if needed
3232
log_config = {
33-
"filename": "tb_transmission_runs",
33+
"filename": "hiv_test_runs",
3434
"directory": outputpath,
3535
"custom_levels": {
3636
"*": logging.WARNING,
@@ -55,12 +55,11 @@
5555
"SymptomManager": {"spurious_symptoms": True},
5656
"HealthSystem": {"disable": False,
5757
"service_availability": ["*"],
58-
"mode_appt_constraints": 0, # no constraints, no squeeze factor
58+
"mode_appt_constraints": 1,
5959
"cons_availability": "default",
6060
"beds_availability": "all",
6161
"ignore_priority": False,
62-
"use_funded_or_actual_staffing": "funded_plus",
63-
"capabilities_coefficient": 1.0},
62+
"use_funded_or_actual_staffing": "actual"},
6463
},
6564
))
6665

src/scripts/hiv/projections_jan2023/analysis_logged_deviance.py

+5-5
Original file line numberDiff line numberDiff line change
@@ -35,9 +35,9 @@
3535
# %% Run the simulation
3636
start_date = Date(2010, 1, 1)
3737
end_date = Date(2015, 1, 1)
38-
popsize = 500
38+
popsize = 5000
3939

40-
scenario = 1
40+
# scenario = 1
4141

4242
# set up the log config
4343
log_config = {
@@ -69,11 +69,11 @@
6969
healthsystem.HealthSystem(
7070
resourcefilepath=resourcefilepath,
7171
service_availability=["*"], # all treatment allowed
72-
mode_appt_constraints=0, # mode of constraints to do with officer numbers and time
72+
mode_appt_constraints=1, # mode of constraints to do with officer numbers and time
7373
cons_availability="default", # mode for consumable constraints (if ignored, all consumables available)
7474
ignore_priority=False, # do not use the priority information in HSI event to schedule
7575
capabilities_coefficient=1.0, # multiplier for the capabilities of health officers
76-
use_funded_or_actual_staffing="funded_plus", # actual: use numbers/distribution of staff available currently
76+
use_funded_or_actual_staffing="actual", # actual: use numbers/distribution of staff available currently
7777
disable=False, # disables the healthsystem (no constraints and no logging) and every HSI runs
7878
disable_and_reject_all=False, # disable healthsystem and no HSI runs
7979
),
@@ -90,7 +90,7 @@
9090
# sim.modules["Hiv"].parameters["beta"] = 0.129671
9191
# sim.modules["Tb"].parameters["scaling_factor_WHO"] = 1.5
9292
# sim.modules["Tb"].parameters["scenario"] = scenario
93-
sim.modules["Tb"].parameters["scenario_start_date"] = Date(2010, 1, 1)
93+
# sim.modules["Tb"].parameters["scenario_start_date"] = Date(2010, 1, 1)
9494
# sim.modules["Tb"].parameters["scenario_SI"] = "z"
9595

9696
# sim.modules["Tb"].parameters["rr_tb_hiv"] = 5 # default 13

src/scripts/hiv/projections_jan2023/output_plots.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -519,7 +519,7 @@ def make_plot(model=None, data_mid=None, data_low=None, data_high=None, title_st
519519
# latest_path = sim.log_filepath
520520
# tlo.methods.deviance_measure.log written after log file below:
521521
# outputs\deviance__2022-01-20T105927.log
522-
# latest_path = "outputs\tb_transmission_runs__2023-01-23T132304.log"
522+
latest_path = "outputs/hiv_test_runs__2023-11-03T160819.log"
523523
death_compare = compare_number_of_deaths(latest_path, resourcefilepath)
524524

525525
# include all ages and both sexes

src/tlo/methods/hiv.py

+56-41
Original file line numberDiff line numberDiff line change
@@ -126,6 +126,7 @@ def __init__(self, name=None, resourcefilepath=None, run_with_checks=False):
126126
"hv_last_test_date": Property(Types.DATE, "Date of last HIV test"),
127127
"hv_date_inf": Property(Types.DATE, "Date infected with HIV"),
128128
"hv_date_treated": Property(Types.DATE, "date hiv treatment started"),
129+
"hv_date_last_ART": Property(Types.DATE, "date of last ART dispensation"),
129130
}
130131

131132
PARAMETERS = {
@@ -374,6 +375,10 @@ def __init__(self, name=None, resourcefilepath=None, run_with_checks=False):
374375
Types.REAL,
375376
"probability of death if aids and tb, person on treatment for tb",
376377
),
378+
"dispensation_period_months": Parameter(
379+
Types.REAL,
380+
"length of prescription for ARVs in months, same for all PLHIV",
381+
),
377382
}
378383

379384
def read_parameters(self, data_folder):
@@ -750,7 +755,7 @@ def split_into_vl_and_notvl(all_idx, prob):
750755
# all those on ART need to have event scheduled for continuation/cessation of treatment
751756
# this window is 1-90 days (3-monthly prescribing)
752757
for person in art_idx:
753-
days = self.rng.randint(low=1, high=90, dtype=np.int64)
758+
days = self.rng.randint(low=1, high=self.parameters['dispensation_period_months'] * 30.5, dtype=np.int64)
754759
self.sim.schedule_event(
755760
Hiv_DecisionToContinueTreatment(person_id=person, module=self),
756761
self.sim.date + pd.to_timedelta(days, unit="days"),
@@ -2438,6 +2443,12 @@ def apply(self, person_id, squeeze_factor):
24382443
# Confirm that the person is diagnosed (this should not run if they are not)
24392444
assert person["hv_diagnosed"]
24402445

2446+
# check whether person had Rx at least 3 months ago and is now due repeat prescription
2447+
# alternate routes into testing/tx may mean person already has recent ARV dispensation
2448+
if person['hv_date_last_ART'] >= (
2449+
self.sim.date - pd.DateOffset(months=self.module.parameters['dispensation_period_months'])):
2450+
return self.sim.modules["HealthSystem"].get_blank_appt_footprint()
2451+
24412452
if art_status_at_beginning_of_hsi == "not":
24422453

24432454
assert person[
@@ -2452,14 +2463,18 @@ def apply(self, person_id, squeeze_factor):
24522463

24532464
# if ART is available (1st item in drugs_were_available dict)
24542465
if drugs_were_available.get('art', False):
2466+
df.at[person_id, 'hv_date_last_ART'] = self.sim.date
2467+
24552468
# If person has been placed/continued on ART, schedule 'decision about whether to continue on Treatment
24562469
self.sim.schedule_event(
24572470
Hiv_DecisionToContinueTreatment(
24582471
person_id=person_id, module=self.module
24592472
),
2460-
self.sim.date + pd.DateOffset(months=3),
2473+
self.sim.date + pd.DateOffset(months=self.module.parameters['dispensation_period_months']),
24612474
)
2475+
24622476
else:
2477+
24632478
# logger for drugs not available
24642479
person_details_for_tx = {
24652480
'age': person['age_years'],
@@ -2471,57 +2486,57 @@ def apply(self, person_id, squeeze_factor):
24712486
}
24722487
logger.info(key='hiv_arv_NA', data=person_details_for_tx)
24732488

2474-
# As drugs were not available, the person will default to being off ART (...if they were on ART at the
2475-
# beginning of the HSI.)
2476-
# NB. If the person was not on ART at the beginning of the HSI, then there is no need to stop them (which
2477-
# causes a new AIDSOnsetEvent to be scheduled.)
2478-
self.counter_for_drugs_not_available += 1 # The current appointment is included in the count.
2489+
# As drugs were not available, the person will default to being off ART (...if they were on ART at the
2490+
# beginning of the HSI.)
2491+
# NB. If the person was not on ART at the beginning of the HSI, then there is no need to stop them (which
2492+
# causes a new AIDSOnsetEvent to be scheduled.)
2493+
self.counter_for_drugs_not_available += 1 # The current appointment is included in the count.
24792494

2480-
if art_status_at_beginning_of_hsi != "not":
2481-
self.module.stops_treatment(person_id)
2495+
if art_status_at_beginning_of_hsi != "not":
2496+
self.module.stops_treatment(person_id)
24822497

2483-
p = self.module.parameters["probability_of_seeking_further_art_appointment_if_drug_not_available"]
2498+
p = self.module.parameters["probability_of_seeking_further_art_appointment_if_drug_not_available"]
24842499

2485-
if self.module.rng.random_sample() >= p:
2500+
if self.module.rng.random_sample() >= p:
24862501

2487-
# add in referral straight back to tx
2488-
# if defaulting, seek another treatment appointment in 6 months
2502+
# add in referral straight back to tx
2503+
# if defaulting, seek another treatment appointment in 6 months
2504+
self.sim.modules["HealthSystem"].schedule_hsi_event(
2505+
hsi_event=HSI_Hiv_StartOrContinueTreatment(
2506+
person_id=person_id, module=self.module,
2507+
facility_level_of_this_hsi="1a",
2508+
),
2509+
topen=self.sim.date + pd.DateOffset(months=6),
2510+
priority=0,
2511+
)
2512+
2513+
else:
2514+
# If person 'decides to' seek another treatment appointment,
2515+
# schedule a new HSI appointment for next month
2516+
# NB. With a probability of 1.0, this will keep occurring,
2517+
# if person has already tried unsuccessfully to get ART at level 1a 2 times
2518+
# then refer to level 1b
2519+
if self.counter_for_drugs_not_available <= 2:
2520+
# repeat attempt for ARVs at level 1a
24892521
self.sim.modules["HealthSystem"].schedule_hsi_event(
24902522
hsi_event=HSI_Hiv_StartOrContinueTreatment(
24912523
person_id=person_id, module=self.module,
2492-
facility_level_of_this_hsi="1a",
2524+
facility_level_of_this_hsi="1a"
24932525
),
2494-
topen=self.sim.date + pd.DateOffset(months=6),
2526+
topen=self.sim.date + pd.DateOffset(months=1),
24952527
priority=0,
24962528
)
24972529

24982530
else:
2499-
# If person 'decides to' seek another treatment appointment,
2500-
# schedule a new HSI appointment for next month
2501-
# NB. With a probability of 1.0, this will keep occurring,
2502-
# if person has already tried unsuccessfully to get ART at level 1a 2 times
2503-
# then refer to level 1b
2504-
if self.counter_for_drugs_not_available <= 2:
2505-
# repeat attempt for ARVs at level 1a
2506-
self.sim.modules["HealthSystem"].schedule_hsi_event(
2507-
hsi_event=HSI_Hiv_StartOrContinueTreatment(
2508-
person_id=person_id, module=self.module,
2509-
facility_level_of_this_hsi="1a"
2510-
),
2511-
topen=self.sim.date + pd.DateOffset(months=1),
2512-
priority=0,
2513-
)
2514-
2515-
else:
2516-
# refer to higher facility level
2517-
self.sim.modules["HealthSystem"].schedule_hsi_event(
2518-
hsi_event=HSI_Hiv_StartOrContinueTreatment(
2519-
person_id=person_id, module=self.module,
2520-
facility_level_of_this_hsi="2"
2521-
),
2522-
topen=self.sim.date + pd.DateOffset(days=1),
2523-
priority=0,
2524-
)
2531+
# refer to higher facility level
2532+
self.sim.modules["HealthSystem"].schedule_hsi_event(
2533+
hsi_event=HSI_Hiv_StartOrContinueTreatment(
2534+
person_id=person_id, module=self.module,
2535+
facility_level_of_this_hsi="2"
2536+
),
2537+
topen=self.sim.date + pd.DateOffset(days=1),
2538+
priority=0,
2539+
)
25252540

25262541
# also screen for tb
25272542
if "Tb" in self.sim.modules:

0 commit comments

Comments
 (0)