Skip to content

Commit a5ce511

Browse files
mmsuarezcostamnjowetbhallett
authored
Param Revamp - Prostate Cancer (#1666)
* fix analysis file * param revamp * update param labeling * tox fix * fix linting errors * update param labeling * change init prob to local * add comment documenting discrepancy in values and parameters * Change param name to 'months' to reflect true value, update comment * remove junk files saved by accident * updates from TH * fix typo and improve error handling * fix linting error --------- Co-authored-by: Emmanuel Mnjowe <[email protected]> Co-authored-by: Tim Hallett <[email protected]>
1 parent 12e207f commit a5ce511

File tree

4 files changed

+85
-24
lines changed

4 files changed

+85
-24
lines changed
Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,3 @@
11
version https://git-lfs.github.com/spec/v1
2-
oid sha256:9a991f1aad62b3fef036accd8d95edeff0d22e4e3260ee799c838a05a05dcb20
3-
size 1199
2+
oid sha256:561d9d990599546f87c7ccbb72e1a6753e5570e260ea260ac14e8e87e9d5279b
3+
size 2953

src/scripts/prostate_cancer_analyses/prostate_cancer_analyses.py

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,16 +22,19 @@
2222
contraception,
2323
demography,
2424
enhanced_lifestyle,
25+
epi,
2526
healthburden,
2627
healthseekingbehaviour,
2728
healthsystem,
29+
hiv,
2830
labour,
2931
newborn_outcomes,
3032
oesophagealcancer,
3133
postnatal_supervisor,
3234
pregnancy_supervisor,
3335
prostate_cancer,
3436
symptommanager,
37+
tb,
3538
)
3639

3740
# Where will outputs go
@@ -71,7 +74,10 @@ def run_sim(service_availability):
7174
pregnancy_supervisor.PregnancySupervisor(),
7275
oesophagealcancer.OesophagealCancer(),
7376
prostate_cancer.ProstateCancer(),
74-
postnatal_supervisor.PostnatalSupervisor()
77+
postnatal_supervisor.PostnatalSupervisor(),
78+
epi.Epi(),
79+
tb.Tb(),
80+
hiv.Hiv(),
7581
)
7682

7783
# Run the simulation

src/tlo/core.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -347,7 +347,9 @@ def load_parameters_from_dataframe(self, resource: pd.DataFrame) -> None:
347347
# For each parameter, raise error if the value can't be coerced
348348
parameter_value, prior_min, prior_max = resource.loc[parameter_name, ['value', 'prior_min', 'prior_max']]
349349
parameter_label = resource.at[parameter_name, 'param_label']
350-
assert parameter_label in acceptable_labels, f'unrecognised parameter label {parameter_label}'
350+
assert parameter_label in acceptable_labels, (
351+
f'unrecognised parameter label for {parameter_name}: {parameter_label}'
352+
)
351353

352354
error_message = (
353355
f"some values are not of type {parameter_definition.type_.name} and "

src/tlo/methods/prostate_cancer.py

Lines changed: 73 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -153,6 +153,51 @@ def __init__(self, name=None):
153153
"sensitivity_of_biopsy_for_prostate_ca": Parameter(
154154
Types.REAL, "sensitivity of biopsy for prostate cancer"
155155
),
156+
"odds_ratio_health_seeking_urinary": Parameter(
157+
Types.REAL, "odds ratio for health seeking in adults with urinary symptoms"
158+
),
159+
"odds_ratio_health_seeking_pelvic_pain": Parameter(
160+
Types.REAL, "odds ratio for health seeking in adults with pelvic pain symptoms"
161+
),
162+
"no_health_seeking_urinary_children": Parameter(
163+
Types.BOOL, "whether children seek healthcare for urinary symptoms"
164+
),
165+
"no_health_seeking_pelvic_pain_children": Parameter(
166+
Types.BOOL, "whether children seek healthcare for pelvic pain symptoms"
167+
),
168+
"min_age_prostate_cancer": Parameter(
169+
Types.INT, "minimum age for prostate cancer risk"
170+
),
171+
"mid_age_threshold_prostate_cancer": Parameter(
172+
Types.INT, "middle age threshold for prostate cancer (lower bound of middle age group)"
173+
),
174+
"high_age_threshold_prostate_cancer": Parameter(
175+
Types.INT, "high age threshold for prostate cancer (lower bound of high age group)"
176+
),
177+
"max_age_prostate_cancer": Parameter(
178+
Types.INT, "maximum age for prostate cancer modeling"
179+
),
180+
"months_between_polling_events": Parameter(
181+
Types.INT, "months between main polling events"
182+
),
183+
"months_to_post_treatment_check": Parameter(
184+
Types.INT, "months from treatment to first post-treatment check"
185+
),
186+
"months_between_followup_appointments": Parameter(
187+
Types.INT, "months between follow-up appointments after treatment"
188+
),
189+
"months_between_palliative_care": Parameter(
190+
Types.INT, "months between palliative care appointments"
191+
),
192+
"weeks_palliative_care_schedule_window": Parameter(
193+
Types.INT, "weeks for palliative care appointment window"
194+
),
195+
"treatment_beddays": Parameter(
196+
Types.INT, "number of general bed days required for treatment"
197+
),
198+
"palliative_care_beddays": Parameter(
199+
Types.INT, "number of general bed days required for palliative care"
200+
),
156201
}
157202

158203
PROPERTIES = {
@@ -208,15 +253,15 @@ def read_parameters(self, resourcefilepath: Optional[Path] = None):
208253
# Register Symptom that this module will use
209254
self.sim.modules['SymptomManager'].register_symptom(
210255
Symptom(name='urinary',
211-
odds_ratio_health_seeking_in_adults=4.00,
212-
no_healthcareseeking_in_children=True)
256+
odds_ratio_health_seeking_in_adults=self.parameters['odds_ratio_health_seeking_urinary'],
257+
no_healthcareseeking_in_children=self.parameters['no_health_seeking_urinary_children'])
213258
)
214259

215260
# Register Symptom that this module will use
216261
self.sim.modules['SymptomManager'].register_symptom(
217262
Symptom(name='pelvic_pain',
218-
odds_ratio_health_seeking_in_adults=4.00,
219-
no_healthcareseeking_in_children=True)
263+
odds_ratio_health_seeking_in_adults=self.parameters['odds_ratio_health_seeking_pelvic_pain'],
264+
no_healthcareseeking_in_children=self.parameters['no_health_seeking_pelvic_pain_children'])
220265
)
221266

222267
def initialise_population(self, population):
@@ -244,9 +289,11 @@ def initialise_population(self, population):
244289
sum(p['init_prop_prostate_ca_stage']),
245290
Predictor('sex').when('M', 1.0).otherwise(0.0),
246291
Predictor('age_years', conditions_are_mutually_exclusive=True)
247-
.when('.between(50,69)', p['rp_prostate_cancer_age5069'])
248-
.when('.between(70,120)', p['rp_prostate_cancer_agege70'])
249-
.when('.between(0,34)', 0.0)
292+
.when(f'.between({p["mid_age_threshold_prostate_cancer"]},{p["high_age_threshold_prostate_cancer"]-1})',
293+
p['rp_prostate_cancer_age5069'])
294+
.when(f'.between({p["high_age_threshold_prostate_cancer"]},{p["max_age_prostate_cancer"]})',
295+
p['rp_prostate_cancer_agege70'])
296+
.when(f'.between(0,{p["min_age_prostate_cancer"]-1})', 0.0)
250297
)
251298

252299
pc_status_ = \
@@ -387,7 +434,8 @@ def initialise_simulation(self, sim):
387434

388435
# ----- SCHEDULE MAIN POLLING EVENTS -----
389436
# Schedule main polling event to happen immediately
390-
sim.schedule_event(ProstateCancerMainPollingEvent(self), sim.date + DateOffset(months=1))
437+
sim.schedule_event(ProstateCancerMainPollingEvent(self), sim.date +
438+
DateOffset(months=self.parameters['months_between_polling_events']))
391439

392440
# ----- LINEAR MODELS -----
393441
# Define LinearModels for the progression of cancer, in each 3 month period
@@ -406,9 +454,11 @@ def initialise_simulation(self, sim):
406454
Predictor('pc_status').when('local_ln', 0),
407455
Predictor('pc_status').when('metastatic', 0),
408456
Predictor('age_years', conditions_are_mutually_exclusive=True)
409-
.when('.between(50,69)', p['rr_prostate_confined_prostate_ca_age5069'])
410-
.when('.between(70,120)', p['rr_prostate_confined_prostate_ca_agege70'])
411-
.when('.between(0,34)', 0.0)
457+
.when(f'.between({p["mid_age_threshold_prostate_cancer"]},{p["high_age_threshold_prostate_cancer"]-1})',
458+
p['rr_prostate_confined_prostate_ca_age5069'])
459+
.when(f'.between({p["high_age_threshold_prostate_cancer"]},{p["max_age_prostate_cancer"]})',
460+
p['rr_prostate_confined_prostate_ca_agege70'])
461+
.when(f'.between(0,{p["min_age_prostate_cancer"]-1})', 0.0)
412462
)
413463

414464
lm['local_ln'] = LinearModel(
@@ -522,8 +572,9 @@ def initialise_simulation(self, sim):
522572
self.sim.modules['HealthSystem'].schedule_hsi_event(
523573
hsi_event=HSI_ProstateCancer_PalliativeCare(module=self, person_id=person_id),
524574
priority=0,
525-
topen=self.sim.date + DateOffset(months=1),
526-
tclose=self.sim.date + DateOffset(months=1) + DateOffset(weeks=1)
575+
topen=self.sim.date + DateOffset(months=self.parameters['months_between_palliative_care']),
576+
tclose=self.sim.date + DateOffset(months=self.parameters['months_between_palliative_care']) +
577+
DateOffset(weeks=self.parameters['weeks_palliative_care_schedule_window'])
527578
)
528579

529580
def on_birth(self, mother_id, child_id):
@@ -911,7 +962,8 @@ def __init__(self, module, person_id):
911962
self.TREATMENT_ID = "ProstateCancer_Treatment"
912963
self.EXPECTED_APPT_FOOTPRINT = self.make_appt_footprint({"MajorSurg": 1})
913964
self.ACCEPTED_FACILITY_LEVEL = '3'
914-
self.BEDDAYS_FOOTPRINT = self.make_beddays_footprint({"general_bed": 5})
965+
self.BEDDAYS_FOOTPRINT = (
966+
self.make_beddays_footprint({"general_bed": self.module.parameters['treatment_beddays']}))
915967

916968
def apply(self, person_id, squeeze_factor):
917969
df = self.sim.population.props
@@ -973,13 +1025,13 @@ def apply(self, person_id, squeeze_factor):
9731025
df.at[person_id, "pc_date_treatment"] = self.sim.date
9741026
df.at[person_id, "pc_stage_at_which_treatment_given"] = df.at[person_id, "pc_status"]
9751027

976-
# Schedule a post-treatment check for 12 months:
1028+
# Schedule a post-treatment check:
9771029
hs.schedule_hsi_event(
9781030
hsi_event=HSI_ProstateCancer_PostTreatmentCheck(
9791031
module=self.module,
9801032
person_id=person_id,
9811033
),
982-
topen=self.sim.date + DateOffset(months=12),
1034+
topen=self.sim.date + DateOffset(months=self.module.parameters['months_to_post_treatment_check']),
9831035
tclose=None,
9841036
priority=0
9851037
)
@@ -1046,7 +1098,7 @@ def apply(self, person_id, squeeze_factor):
10461098
module=self.module,
10471099
person_id=person_id
10481100
),
1049-
topen=self.sim.date + DateOffset(months=12),
1101+
topen=self.sim.date + DateOffset(years=self.module.parameters['months_between_followup_appointments']),
10501102
tclose=None,
10511103
priority=0
10521104
)
@@ -1069,7 +1121,8 @@ def __init__(self, module, person_id):
10691121
self.TREATMENT_ID = "ProstateCancer_PalliativeCare"
10701122
self.EXPECTED_APPT_FOOTPRINT = self.make_appt_footprint({})
10711123
self.ACCEPTED_FACILITY_LEVEL = '2'
1072-
self.BEDDAYS_FOOTPRINT = self.make_beddays_footprint({'general_bed': 15})
1124+
self.BEDDAYS_FOOTPRINT = (
1125+
self.make_beddays_footprint({'general_bed': self.module.parameters['palliative_care_beddays']}))
10731126

10741127
def apply(self, person_id, squeeze_factor):
10751128
df = self.sim.population.props
@@ -1105,13 +1158,13 @@ def apply(self, person_id, squeeze_factor):
11051158
if pd.isnull(df.at[person_id, "pc_date_palliative_care"]):
11061159
df.at[person_id, "pc_date_palliative_care"] = self.sim.date
11071160

1108-
# Schedule another instance of the event for one month
1161+
# Schedule another instance of the event
11091162
hs.schedule_hsi_event(
11101163
hsi_event=HSI_ProstateCancer_PalliativeCare(
11111164
module=self.module,
11121165
person_id=person_id
11131166
),
1114-
topen=self.sim.date + DateOffset(months=1),
1167+
topen=self.sim.date + DateOffset(months=self.module.parameters['months_between_palliative_care']),
11151168
tclose=None,
11161169
priority=0
11171170
)

0 commit comments

Comments
 (0)