Skip to content

Commit 2f16e28

Browse files
mnjowetamuritbhallettmatt-grahamjoehcollins
authored
Updates to Lifestyle Module (#545)
Co-authored-by: Asif Tamuri <[email protected]> Co-authored-by: Tim Hallett <[email protected]> Co-authored-by: Matt Graham <[email protected]> Co-authored-by: joehcollins <[email protected]>
1 parent 25dce3d commit 2f16e28

9 files changed

+2815
-987
lines changed
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,3 @@
11
version https://git-lfs.github.com/spec/v1
2-
oid sha256:945e620bb0ce47d61623791bafd884282b1c8b3643b0b38652c8210277c7ae69
3-
size 4149998
2+
oid sha256:fb953d8b31023d90a258701bf943bc13fed91f2e2741a233d973cc25b1e92cc0
3+
size 4153552

src/scripts/enhanced_lifestyle_analyses/enhanced_lifestyle_analyses.py

+493-20
Large diffs are not rendered by default.

src/scripts/enhanced_lifestyle_analyses/enhanced_lifestyle_calibrations.py

+716
Large diffs are not rendered by default.

src/tlo/methods/cardio_metabolic_disorders.py

+5-1
Original file line numberDiff line numberDiff line change
@@ -1151,7 +1151,11 @@ def apply(self, person_id):
11511151
return
11521152
else:
11531153
if self.module.rng.random_sample() < self.module.parameters['pr_bmi_reduction']:
1154-
df.at[person_id, 'li_bmi'] -= 1
1154+
# for bmi equal to 1, we decrease it to np.nan to avoid a new category error
1155+
if not df.at[person_id, 'li_bmi'] > 1:
1156+
df.at[person_id, 'li_bmi'] = np.nan
1157+
else:
1158+
df.at[person_id, 'li_bmi'] -= 1
11551159
df.at[person_id, 'nc_weight_loss_worked'] = True
11561160

11571161

src/tlo/methods/enhanced_lifestyle.py

+1,510-954
Large diffs are not rendered by default.

src/tlo/methods/simplified_births.py

+3-2
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
is that every pregnancy results in a birth."""
55

66
import json
7+
from pathlib import Path
78

89
import pandas as pd
910

@@ -105,12 +106,12 @@ def read_parameters(self, data_folder):
105106
"""Load parameters for probability of pregnancy/birth and breastfeeding status for newborns"""
106107

107108
self.parameters['age_specific_fertility_rates'] = \
108-
pd.read_csv(self.resourcefilepath / 'demography' / 'ResourceFile_ASFR_WPP.csv')
109+
pd.read_csv(Path(self.resourcefilepath) / 'demography' / 'ResourceFile_ASFR_WPP.csv')
109110

110111
self.parameters['months_between_pregnancy_and_delivery'] = 9
111112

112113
# Breastfeeding status for newborns (importing from the Newborn resourcefile)
113-
rf = pd.read_excel(self.resourcefilepath / 'ResourceFile_NewbornOutcomes.xlsx')
114+
rf = pd.read_excel(Path(self.resourcefilepath) / 'ResourceFile_NewbornOutcomes.xlsx')
114115
param_as_string = rf.loc[rf.parameter_name == 'prob_breastfeeding_type']['value'].iloc[0]
115116
parameter = json.loads(param_as_string)[0]
116117
self.parameters['prob_breastfeeding_type'] = parameter

tests/test_enhanced_lifestyle.py

+83-6
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,18 @@
1-
1+
""""
2+
This is a test file for Lifestyle Module. It contains a number of checks to ensure everything is running as expected
3+
"""
24
import os
35
from pathlib import Path
46

7+
import numpy as np
8+
import pandas as pd
59
import pytest
610

7-
from tlo import Date, Simulation
11+
from tlo import Date, DateOffset, Module, Simulation
12+
from tlo.events import PopulationScopeEventMixin, RegularEvent
813
from tlo.methods import demography, enhanced_lifestyle
914

15+
resourcefilepath = Path(os.path.dirname(__file__)) / '../resources'
1016
start_date = Date(2010, 1, 1)
1117
end_date = Date(2012, 4, 1)
1218
popsize = 10000
@@ -22,14 +28,15 @@ def simulation(seed):
2228
return sim
2329

2430

25-
def __check_properties(df):
31+
def check_properties(df):
2632
# no one under 15 can be overweight, low exercise, tobacco, excessive alcohol, married
2733
under15 = df.age_years < 15
28-
assert not (under15 & df.li_bmi > 0).any()
34+
assert not (under15 & pd.notna(df.li_bmi)).any()
2935
assert not (under15 & df.li_low_ex).any()
3036
assert not (under15 & df.li_tob).any()
3137
assert not (under15 & df.li_ex_alc).any()
3238
assert not (under15 & (df.li_mar_stat != 1)).any()
39+
3340
# education: no one 0-5 should be in education
3441
assert not ((df.age_years < 5) & (df.li_in_ed | (df.li_ed_lev != 1))).any()
3542

@@ -50,10 +57,80 @@ def __check_properties(df):
5057

5158
def test_properties_and_dtypes(simulation):
5259
simulation.make_initial_population(n=popsize)
53-
__check_properties(simulation.population.props)
60+
check_properties(simulation.population.props)
5461
simulation.simulate(end_date=end_date)
55-
__check_properties(simulation.population.props)
62+
check_properties(simulation.population.props)
5663
# check types of columns
5764
df = simulation.population.props
5865
orig = simulation.population.new_row
5966
assert (df.dtypes == orig.dtypes).all()
67+
68+
69+
def test_assign_rural_urban_by_district(simulation):
70+
""" test linear model integrity in assigning individual rural urban status based on their districts """
71+
# make an initial population
72+
simulation.make_initial_population(n=1)
73+
74+
# Make this individual rural
75+
df = simulation.population.props
76+
df.loc[0, 'is_alive'] = True
77+
df.loc[0, 'is_urban'] = False
78+
df.loc[0, 'district_of_residence'] = 'Lilongwe'
79+
80+
# confirm an individual is rural
81+
assert not df.loc[0, 'li_urban']
82+
83+
# reset district of residence to an urban district(Here we choose a district of residence with 1.0 urban
84+
# probability i.e Lilongwe City), run the rural urban linear model and check the individual is now urban.
85+
df.loc[0, 'district_of_residence'] = 'Lilongwe City'
86+
rural_urban_lm = enhanced_lifestyle.LifestyleModels(simulation.modules['Lifestyle']).rural_urban_linear_model()
87+
df.loc[df.is_alive, 'li_urban'] = rural_urban_lm.predict(df.loc[df.is_alive], rng=np.random)
88+
89+
# check an individual is now urban
90+
assert df.loc[0, 'li_urban']
91+
92+
93+
def test_check_properties_daily_event():
94+
""" A test that seeks to test the integrity of lifestyle properties. It contains a dummy module with an event that
95+
runs daily to ensure properties what they are expected """
96+
class DummyModule(Module):
97+
""" a dummy module for testing lifestyle properties """
98+
def read_parameters(self, data_folder):
99+
pass
100+
101+
def initialise_population(self, population):
102+
pass
103+
104+
def initialise_simulation(self, sim):
105+
event = DummyLifestyleEvent(self)
106+
sim.schedule_event(event, sim.date)
107+
108+
def on_birth(self, mother, child):
109+
pass
110+
111+
class DummyLifestyleEvent(RegularEvent, PopulationScopeEventMixin):
112+
""" An event that runs daily to check the integrity of lifestyle properties """
113+
114+
def __init__(self, module):
115+
"""schedule to run everyday
116+
"""
117+
self.repeat_months = 1
118+
self.module = module
119+
super().__init__(module, frequency=DateOffset(days=1))
120+
121+
def apply(self, population):
122+
""" Apply this event to the population.
123+
:param population: the current population
124+
"""
125+
# check lifestyle properties
126+
check_properties(population.props)
127+
128+
# Create simulation:
129+
sim = Simulation(start_date=start_date)
130+
sim.register(
131+
demography.Demography(resourcefilepath=resourcefilepath),
132+
enhanced_lifestyle.Lifestyle(resourcefilepath=resourcefilepath),
133+
DummyModule()
134+
)
135+
sim.make_initial_population(n=2000)
136+
sim.simulate(end_date=end_date)

tests/test_labour.py

+2-1
Original file line numberDiff line numberDiff line change
@@ -230,8 +230,9 @@ def test_event_scheduling_for_care_seeking_during_home_birth(seed):
230230
mni[mother_id]['sought_care_labour_phase'] = 'none'
231231
sim.date = sim.date + pd.DateOffset(days=5)
232232

233-
# force a complication
233+
# force a complication and care seeking
234234
params['prob_pph_uterine_atony'] = 1.0
235+
params['prob_careseeking_for_complication_pn'] = 1.0
235236

236237
# run postpartum home event
237238
home_birth_pp = labour.BirthAndPostnatalOutcomesEvent(mother_id=mother_id, module=sim.modules['Labour'])

tests/test_module_dependencies.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@
2525
resourcefilepath = "resources"
2626

2727
simulation_start_date = Date(2010, 1, 1)
28-
simulation_end_date = Date(2010, 4, 1)
28+
simulation_end_date = Date(2010, 9, 1)
2929
simulation_initial_population = 1000
3030

3131

0 commit comments

Comments
 (0)