diff --git a/resources/ResourceFile_PostnatalSupervisor/parameter_values.csv b/resources/ResourceFile_PostnatalSupervisor/parameter_values.csv index ac0f082139..71fd352237 100644 --- a/resources/ResourceFile_PostnatalSupervisor/parameter_values.csv +++ b/resources/ResourceFile_PostnatalSupervisor/parameter_values.csv @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:8dac89c4cc638a6f65cc21effb521380e3d6ca06600af737244e41ef0f71b4a9 -size 3573 +oid sha256:87e58ac0c0a3aa81e2c8c0609dd1d59789c44a2dd057cbe7c7e4768d3989fc78 +size 7415 diff --git a/src/tlo/methods/postnatal_supervisor.py b/src/tlo/methods/postnatal_supervisor.py index 109b7d5694..c29e63f9d7 100644 --- a/src/tlo/methods/postnatal_supervisor.py +++ b/src/tlo/methods/postnatal_supervisor.py @@ -134,6 +134,8 @@ def __init__(self, name=None): Types.LIST, 'case fatality rate of severe pre-eclampsia in the postnatal period'), 'weekly_prob_death_severe_gest_htn': Parameter( Types.LIST, 'weekly risk of death from severe hypertension in the postnatal period'), + 'bmi_obesity': Parameter( + Types.LIST, 'BMI for obesity classification'), # ANAEMIA 'baseline_prob_anaemia_per_week': Parameter( @@ -205,7 +207,37 @@ def __init__(self, name=None): Types.LIST, 'Treatment effect of chlorhexidine cord care on early onset neonatal sepsis risk'), 'treatment_effect_anti_htns_progression_pn': Parameter( Types.LIST, 'Treatment effect of oral anti hypertensives on progression from mild/mod to severe gestational' - 'hypertension') + 'hypertension'), + + # TIMING AND SCHEDULING PARAMETERS + 'main_polling_event_frequency_weeks': Parameter( + Types.INT, ' PostnatalSupervisorEvent polling frequency in weeks'), + 'fistula_repair_min_days': Parameter( + Types.LIST, 'Minimum days after birth to schedule obstetric fistula repair'), + 'fistula_repair_max_days': Parameter( + Types.LIST, 'Maximum days after birth to schedule obstetric fistula repair'), + 'fistula_repair_appointment_window_days': Parameter( + Types.LIST, 'Number of days for fistula repair appointment scheduling window'), + 'emergency_postnatal_care_appointment_window_days': Parameter( + Types.LIST, 'Number of days for emergency postnatal care appointment scheduling window'), + 'pnc_one_maternal_appt_max_days_without_complications': Parameter( + Types.LIST, 'Maximum number of days from current date for pnc_one_maternal_appt if no complications'), + 'pnc_one_maternal_appt_window_days': Parameter( + Types.LIST, 'Number of days for pnc_one_maternal_appt scheduling window'), + 'postnatal_check_sepsis_appt_window_days': Parameter( + Types.LIST, 'Number of days for postnatal check if sepsis - scheduling window'), + 'pnc_one_neonatal_sepsis_appt_window_days': Parameter( + Types.LIST, 'Number of days for pnc_one_neonatal if sepsis - scheduling window'), + 'final_week_postnatal_period': Parameter( + Types.INT, 'Final week of the postnatal period - week 6'), + 'postnatal_reset_week': Parameter( + Types.INT, 'Week at which postnatal variables are reset overall: Changes made 2 weeks after' + 'the end of the postnatal and neonatal period in case either the ' + 'mother or newborn are receiving treatment following the last PNC visit '), + 'obstetric_fistula_repair_beddays': Parameter( + Types.INT, 'Number of beddays required for obstetric fistula repair'), + 'neonatal_period_end_days': Parameter( + Types.INT, 'End of neonatal period in days') } PROPERTIES = { @@ -254,8 +286,7 @@ def initialise_simulation(self, sim): pregnancy_helper_functions.update_current_parameter_dictionary(self, list_position=0) # Schedule the first instance of the PostnatalSupervisorEvent - sim.schedule_event(PostnatalSupervisorEvent(self), - sim.date + DateOffset(days=0)) + sim.schedule_event(PostnatalSupervisorEvent(self), sim.date) # Register dx_tests used as assessment for postnatal conditions during PNC visits params = self.current_parameters @@ -365,12 +396,14 @@ def further_on_birth_postnatal_supervisor(self, mother_id): if care_seeking_for_repair: repair_hsi = HSI_PostnatalSupervisor_TreatmentForObstetricFistula( self, person_id=mother_id) - repair_date = self.sim.date + DateOffset(days=(self.rng.randint(7, 42))) + repair_date = self.sim.date + DateOffset(days=(self.rng.randint( + params['fistula_repair_min_days'], params['fistula_repair_max_days']))) self.sim.modules['HealthSystem'].schedule_hsi_event(repair_hsi, - priority=0, - topen=repair_date, - tclose=repair_date + DateOffset(days=7)) + priority=0, + topen=repair_date, + tclose=repair_date + + DateOffset(days=params['fistula_repair_appointment_window_days'])) # ======================= CONTINUATION OF COMPLICATIONS INTO THE POSTNATAL PERIOD ========================= # Certain conditions experienced in pregnancy are liable to continue into the postnatal period @@ -676,23 +709,26 @@ def log_new_progressed_cases(disease): self.sim.modules['Labour'], person_id=person) self.sim.modules['HealthSystem'].schedule_hsi_event(postnatal_check, - priority=0, - topen=self.sim.date, - tclose=self.sim.date + DateOffset(days=2)) + priority=0, + topen=self.sim.date, + tclose=self.sim.date + + DateOffset(days=params['emergency_postnatal_care_appointment_window_days'])) # For women who do not seek care we immediately apply risk of death due to complications for person in care_seekers.loc[~care_seekers].index: self.apply_risk_of_maternal_or_neonatal_death_postnatal(mother_or_child='mother', individual_id=person) - if week == 6: + if week == params['final_week_postnatal_period']: # Here we reset any remaining pregnancy variables (as some are used as predictors in models in the postnatal # period) - week_6_women = df.is_alive & df.la_is_postpartum & (df.pn_postnatal_period_in_weeks == 6) + final_week_postnatal_period_women = (df.is_alive & + df.la_is_postpartum & + (df.pn_postnatal_period_in_weeks == params['final_week_postnatal_period'])) self.sim.modules['PregnancySupervisor'].pregnancy_supervisor_property_reset( - id_or_index=week_6_women.loc[week_6_women].index) + id_or_index=final_week_postnatal_period_women.loc[final_week_postnatal_period_women].index) self.sim.modules['CareOfWomenDuringPregnancy'].care_of_women_in_pregnancy_property_reset( - id_or_index=week_6_women.loc[week_6_women].index) + id_or_index=final_week_postnatal_period_women.loc[final_week_postnatal_period_women].index) def apply_risk_of_neonatal_complications_in_week_one(self, child_id, mother_id): """ @@ -768,9 +804,10 @@ def set_postnatal_complications_neonates(self, upper_and_lower_day_limits): self.sim.modules['NewbornOutcomes'], person_id=person) self.sim.modules['HealthSystem'].schedule_hsi_event(postnatal_check, - priority=0, - topen=self.sim.date, - tclose=self.sim.date + DateOffset(days=1)) + priority=0, + topen=self.sim.date, + tclose=self.sim.date + + DateOffset(days=params['postnatal_check_sepsis_appt_window_days'])) # And apply risk of death for newborns for which care is not sought for person in care_seeking.loc[~care_seeking].index: @@ -860,10 +897,12 @@ class PostnatalSupervisorEvent(RegularEvent, PopulationScopeEventMixin): event ensures that the relevant postnatal/neonatal variables are reset for those who survive. """ def __init__(self, module, ): - super().__init__(module, frequency=DateOffset(weeks=1)) + p = module.parameters + super().__init__(module, frequency=DateOffset(weeks=p['main_polling_event_frequency_weeks'])) def apply(self, population): df = population.props + params = self.module.parameters store_dalys_in_mni = pregnancy_helper_functions.store_dalys_in_mni mni = self.sim.modules['PregnancySupervisor'].mother_and_newborn_info mnh_counter = self.sim.modules['PregnancySupervisor'].mnh_outcome_counter @@ -900,28 +939,32 @@ def apply(self, population): # newborn are receiving treatment following the last PNC visit (around day 42) # Maternal variables - week_8_postnatal_women_htn = \ - df.is_alive & df.la_is_postpartum & (df.pn_postnatal_period_in_weeks == 8) & \ - (df.pn_htn_disorders.str.contains('gest_htn|severe_gest_htn|mild_pre_eclamp|severe_pre_eclamp|eclampsia')) + reset_week_postnatal_women_htn = \ + (df.is_alive & df.la_is_postpartum & + (df.pn_postnatal_period_in_weeks == params['postnatal_reset_week']) & + (df.pn_htn_disorders.str.contains('gest_htn|severe_gest_htn|mild_pre_eclamp|severe_pre_eclamp|eclampsia'))) # Schedule date of resolution for any women with hypertension - for person in week_8_postnatal_women_htn.loc[week_8_postnatal_women_htn].index: + for person in reset_week_postnatal_women_htn.loc[reset_week_postnatal_women_htn].index: if not pd.isnull(mni[person]['hypertension_onset']): store_dalys_in_mni(person, mni, 'hypertension_resolution', self.sim.date) - week_8_postnatal_women_anaemia = \ - df.is_alive & df.la_is_postpartum & (df.pn_postnatal_period_in_weeks == 8) & \ - (df.pn_anaemia_following_pregnancy != 'none') + reset_week_postnatal_women_anaemia = \ + (df.is_alive & df.la_is_postpartum & + (df.pn_postnatal_period_in_weeks == params['postnatal_reset_week']) & + (df.pn_anaemia_following_pregnancy != 'none')) # Schedule date of resolution for any women with anaemia - for person in week_8_postnatal_women_anaemia.loc[week_8_postnatal_women_anaemia].index: + for person in reset_week_postnatal_women_anaemia.loc[reset_week_postnatal_women_anaemia].index: store_dalys_in_mni(person, mni, f'{df.at[person, "pn_anaemia_following_pregnancy"]}_anaemia' f'_pp_resolution', self.sim.date) - week_8_postnatal_women = df.is_alive & df.la_is_postpartum & (df.pn_postnatal_period_in_weeks == 8) + reset_week_postnatal_women = (df.is_alive & + df.la_is_postpartum & + (df.pn_postnatal_period_in_weeks == params['postnatal_reset_week'])) # Set mni[person]['delete_mni'] to True meaning after the next DALY event each womans MNI dict is deleted - for person in week_8_postnatal_women.loc[week_8_postnatal_women].index: + for person in reset_week_postnatal_women.loc[reset_week_postnatal_women].index: pn_checks = df.at[person, 'la_pn_checks_maternal'] mni[person]['delete_mni'] = True @@ -940,19 +983,20 @@ def apply(self, population): 'visits': df.at[person, 'la_pn_checks_maternal'], 'anaemia': df.at[person, 'pn_anaemia_following_pregnancy']}) - df.loc[week_8_postnatal_women, 'pn_postnatal_period_in_weeks'] = 0 - df.loc[week_8_postnatal_women, 'la_is_postpartum'] = False - df.loc[week_8_postnatal_women, 'la_pn_checks_maternal'] = 0 - df.loc[week_8_postnatal_women, 'pn_sepsis_late_postpartum'] = False - df.loc[week_8_postnatal_women, 'pn_postpartum_haem_secondary'] = False + df.loc[reset_week_postnatal_women, 'pn_postnatal_period_in_weeks'] = 0 + df.loc[reset_week_postnatal_women, 'la_is_postpartum'] = False + df.loc[reset_week_postnatal_women, 'la_pn_checks_maternal'] = 0 + df.loc[reset_week_postnatal_women, 'pn_sepsis_late_postpartum'] = False + df.loc[reset_week_postnatal_women, 'pn_postpartum_haem_secondary'] = False - df.loc[week_8_postnatal_women, 'pn_htn_disorders'] = 'none' - df.loc[week_8_postnatal_women, 'pn_anaemia_following_pregnancy'] = 'none' + df.loc[reset_week_postnatal_women, 'pn_htn_disorders'] = 'none' + df.loc[reset_week_postnatal_women, 'pn_anaemia_following_pregnancy'] = 'none' # For the neonates we now determine if they will develop any long term neurodevelopmental impairment following # survival of the neonatal period - week_5_postnatal_neonates = df.is_alive & (df.age_days > 28) & (df.age_days < 36) & (df.date_of_birth > - self.sim.start_date) + week_5_postnatal_neonates = (df.is_alive & (df.age_days > params['neonatal_period_end_days']) + & (df.age_days <= params['neonatal_period_end_days'] +7) & + (df.date_of_birth > self.sim.start_date)) for person in week_5_postnatal_neonates.loc[week_5_postnatal_neonates].index: pn_checks = df.at[person, 'nb_pnc_check'] @@ -1157,7 +1201,8 @@ def log_new_progressed_cases(disease): params['prob_care_seeking_postnatal_emergency']): self.sim.modules['HealthSystem'].schedule_hsi_event( - pnc_one_maternal, priority=0, topen=self.sim.date, tclose=self.sim.date + pd.DateOffset(days=2)) + pnc_one_maternal, priority=0, topen=self.sim.date, tclose=self.sim.date + + pd.DateOffset(days=params['pnc_one_maternal_appt_window_days'])) # If she will not receive treatment for her complications we apply risk of death now else: @@ -1166,9 +1211,12 @@ def log_new_progressed_cases(disease): else: # Women without complications in week one are scheduled to attend PNC in the future if mni[individual_id]['will_receive_pnc'] == 'late': - appt_date = self.sim.date + pd.DateOffset(self.module.rng.randint(0, 35)) + appt_date = (self.sim.date + + pd.DateOffset(self.module.rng.randint(0, + params['pnc_one_maternal_appt_max_days_without_complications']))) self.sim.modules['HealthSystem'].schedule_hsi_event( - pnc_one_maternal, priority=0, topen=appt_date, tclose=appt_date + pd.DateOffset(days=2)) + pnc_one_maternal, priority=0, topen=appt_date, tclose=appt_date + + pd.DateOffset(days= params['pnc_one_maternal_appt_window_days'])) class PostnatalWeekOneNeonatalEvent(Event, IndividualScopeEventMixin): @@ -1216,9 +1264,10 @@ def apply(self, individual_id): 'emergency_neonate'])): self.sim.modules['HealthSystem'].schedule_hsi_event(pnc_one_neonatal, - priority=0, - topen=self.sim.date, - tclose=self.sim.date + pd.DateOffset(days=1)) + priority=0, + topen=self.sim.date, + tclose=self.sim.date + + pd.DateOffset(days=params['pnc_one_neonatal_sepsis_appt_window_days'])) else: # Apply risk of death for those who wont seek care self.module.apply_risk_of_maternal_or_neonatal_death_postnatal(mother_or_child='child', @@ -1249,7 +1298,8 @@ def __init__(self, module, person_id): self.EXPECTED_APPT_FOOTPRINT = self.make_appt_footprint({'MajorSurg': 1}) self.ACCEPTED_FACILITY_LEVEL = '1b' self.ALERT_OTHER_DISEASES = [] - self.BEDDAYS_FOOTPRINT = self.make_beddays_footprint({'general_bed': 5}) + self.BEDDAYS_FOOTPRINT = ( + self.make_beddays_footprint({'general_bed': module.parameters['obstetric_fistula_repair_beddays']})) def apply(self, person_id, squeeze_factor): df = self.sim.population.props diff --git a/src/tlo/methods/postnatal_supervisor_lm.py b/src/tlo/methods/postnatal_supervisor_lm.py index 80ff41c758..e5abad49eb 100644 --- a/src/tlo/methods/postnatal_supervisor_lm.py +++ b/src/tlo/methods/postnatal_supervisor_lm.py @@ -63,7 +63,7 @@ def predict_gest_htn_pn(self, df, rng=None, **externals): params = self.parameters result = pd.Series(data=params['weekly_prob_gest_htn_pn'], index=df.index) - result[df.li_bmi > 3] *= params['rr_gest_htn_obesity'] + result[df.li_bmi > params['bmi_obesity']] *= params['rr_gest_htn_obesity'] return result @@ -76,7 +76,7 @@ def predict_pre_eclampsia_pn(self, df, rng=None, **externals): params = self.module.current_parameters result = pd.Series(data=params['weekly_prob_pre_eclampsia_pn'], index=df.index) - result[df.li_bmi > 3] *= params['rr_gest_htn_obesity'] + result[df.li_bmi > params['bmi_obesity']] *= params['rr_gest_htn_obesity'] if 'CardioMetabolicDisorders' in self.module.sim.modules: result[df.nc_hypertension] *= params['rr_pre_eclampsia_chronic_htn']