Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Git LFS file not shown
138 changes: 94 additions & 44 deletions src/tlo/methods/postnatal_supervisor.py
Original file line number Diff line number Diff line change
Expand Up @@ -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(
Expand Down Expand Up @@ -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 = {
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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):
"""
Expand Down Expand Up @@ -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:
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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
Expand All @@ -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']
Expand Down Expand Up @@ -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:
Expand All @@ -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):
Expand Down Expand Up @@ -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',
Expand Down Expand Up @@ -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
Expand Down
4 changes: 2 additions & 2 deletions src/tlo/methods/postnatal_supervisor_lm.py
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand All @@ -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']
Expand Down