Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
24 commits
Select commit Hold shift + click to select a range
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
3 changes: 3 additions & 0 deletions resources/ResourceFile_HIV/art_coverage_pregnant_women.csv
Git LFS file not shown
4 changes: 2 additions & 2 deletions resources/ResourceFile_HIV/parameters.csv
Git LFS file not shown
Git LFS file not shown
4 changes: 2 additions & 2 deletions resources/ResourceFile_Schisto/ESPEN_MDA.csv
Git LFS file not shown
4 changes: 2 additions & 2 deletions resources/ResourceFile_Schisto/MDA_historical_Coverage.csv
Git LFS file not shown
4 changes: 2 additions & 2 deletions resources/demography/ResourceFile_Population_2010.csv
Git LFS file not shown
Git LFS file not shown
Git LFS file not shown
Git LFS file not shown
Git LFS file not shown
Git LFS file not shown
Git LFS file not shown
Git LFS file not shown
Git LFS file not shown
Git LFS file not shown
4 changes: 2 additions & 2 deletions resources/malaria/ResourceFile_malaria/MAP_IRSrates.csv
Git LFS file not shown
4 changes: 2 additions & 2 deletions resources/malaria/ResourceFile_malaria/MAP_ITNrates.csv
Git LFS file not shown
4 changes: 2 additions & 2 deletions resources/malaria/ResourceFile_malaria/parameters.csv
Git LFS file not shown
4 changes: 2 additions & 2 deletions resources/malaria/ResourceFile_malaria_ClinInc_expanded.csv
Git LFS file not shown
4 changes: 2 additions & 2 deletions resources/malaria/ResourceFile_malaria_InfInc_expanded.csv
Git LFS file not shown
4 changes: 2 additions & 2 deletions resources/malaria/ResourceFile_malaria_SevInc_expanded.csv
Git LFS file not shown
4 changes: 3 additions & 1 deletion src/tlo/methods/enhanced_lifestyle.py
Original file line number Diff line number Diff line change
Expand Up @@ -692,7 +692,9 @@ def predict_rural_urban_status(self, df, rng=None, **externals) -> pd.Series:
# check all districts have been corectly mapped to their rural urban proportions
assert not rural_urban_props.isnull().any(), 'some districts are not mapped to their rural urban values'
# check urban rural proportion is greater or equal to 0 but less or equal to 1
assert rural_urban_props.apply(lambda x: 0.0 <= x <= 1.0).any(), 'proportion less than 0 or greater than 1'
rural_urban_props = df['district_of_residence'].map(p['init_p_urban']['prop_urban']).astype(float)
assert rural_urban_props.between(0.0, 1.0).all(), 'proportion less than 0 or greater than 1'
# assert rural_urban_props.apply(lambda x: 0.0 <= x <= 1.0).any(), 'proportion less than 0 or greater than 1'

# get individual's rural urban status
rural_urban = rural_urban_props > rnd_draw
Expand Down
52 changes: 42 additions & 10 deletions src/tlo/methods/hiv.py
Original file line number Diff line number Diff line change
Expand Up @@ -113,11 +113,13 @@ def __init__(self, name=None, run_with_checks=False):
),
"hv_on_cotrimoxazole": Property(
Types.BOOL,
"Whether the person is currently taking and receiving a malaria-protective effect from cotrimoxazole",
"Whether the person is currently taking and receiving a malaria-protective "
"effect from cotrimoxazole",
),
"hv_is_on_prep": Property(
Types.BOOL,
"Whether the person is currently taking and receiving a protective effect from Pre-Exposure Prophylaxis",
"Whether the person is currently taking and receiving a protective effect "
"from Pre-Exposure Prophylaxis",
),
"hv_behaviour_change": Property(
Types.BOOL,
Expand All @@ -140,6 +142,7 @@ def __init__(self, name=None, run_with_checks=False):
Types.DATA_FRAME, "prob of time since infection for baseline adult pop"
),
"art_coverage": Parameter(Types.DATA_FRAME, "coverage of ART at baseline"),
"art_coverage_pregnant_women": Parameter(Types.REAL, "coverage of pregnant women on ART at baseline"),
"treatment_cascade": Parameter(Types.DATA_FRAME, "spectrum estimates of treatment cascade"),
# Natural history - transmission - overall rates
"beta": Parameter(Types.REAL, "Transmission rate"),
Expand Down Expand Up @@ -431,9 +434,20 @@ def read_parameters(self, resourcefilepath: Optional[Path] = None):
# Shortcut to parameters dict
p = self.parameters

workbook = read_csv_files(resourcefilepath/'ResourceFile_HIV', files=None)
workbook = read_csv_files(resourcefilepath / 'ResourceFile_HIV', files=None)
self.load_parameters_from_dataframe(workbook["parameters"])

# preg_art_path = resourcefilepath / 'ResourceFile_HIV' / 'art_coverage_pregnant_women.csv'
# preg_art_df = pd.read_csv(preg_art_path)
#
# # Extract the value for 'art_coverage_pregnant_women'
# art_cov_value = preg_art_df.loc[
# preg_art_df['parameter_name'] == 'art_coverage_pregnant_women', 'value'
# ].values[0]
#
# # Assign it to the parameters dictionary
# p['art_coverage_pregnant_women'] = float(art_cov_value)

# Load data on HIV prevalence
p["hiv_prev"] = workbook["hiv_prevalence"]

Expand Down Expand Up @@ -743,6 +757,20 @@ def initialise_baseline_art(self, population):
worksheet.year == 2010, ["year", "single_age", "sex", "prop_coverage"]
]

# hiv_positive_pregnant_women = df[
# df.is_alive &
# (df.sex == "F") &
# df.hv_inf &
# (df["is_pregnant"]) &
# (df.hv_art == "not")].index
# # Randomly assign ART based on coverage parameter
# n = len(hiv_positive_pregnant_women)
# n_to_assign = int(n * params["art_coverage_pregnant_women"])
# assigned_art_preg = self.rng.choice(hiv_positive_pregnant_women, size=n_to_assign, replace=False)
#
# df.loc[assigned_art_preg, "hv_art"] = "on_VL_suppressed"


# merge all susceptible individuals with their coverage probability based on sex and age
prob_art = df.loc[df.is_alive, ["age_years", "sex"]].merge(
art_data,
Expand Down Expand Up @@ -777,6 +805,10 @@ def initialise_baseline_art(self, population):
p["overall_prob_of_art"] = p["scaled_rel_prob_by_time_infected"] * p["prob_art"]
random_draw = self.rng.random_sample(size=len(df))

# art_idx = df.index[
# (random_draw < p["overall_prob_of_art"]) & df.is_alive & df.hv_inf
# ].union(assigned_art_preg)

art_idx = df.index[
(random_draw < p["overall_prob_of_art"]) & df.is_alive & df.hv_inf
]
Expand Down Expand Up @@ -1678,6 +1710,7 @@ def do_at_generic_first_appt(
)
schedule_hsi_event(event, priority=0, topen=self.sim.date)


# ---------------------------------------------------------------------------
# Main Polling Event
# ---------------------------------------------------------------------------
Expand Down Expand Up @@ -2474,7 +2507,6 @@ def apply(self, person_id, squeeze_factor):
# set cap for number of repeat tests
self.counter_for_test_not_available += 1 # The current appointment is included in the count.


if (
self.counter_for_test_not_available
<= self.module.parameters["hiv_healthseekingbehaviour_cap"]
Expand Down Expand Up @@ -2532,7 +2564,7 @@ def apply(self, person_id, squeeze_factor):

# Add used equipment
self.add_equipment({'Drip stand', 'Stool, adjustable height', 'Autoclave',
'Bipolar Diathermy Machine', 'Bed, adult', 'Trolley, patient'})
'Bipolar Diathermy Machine', 'Bed, adult', 'Trolley, patient'})

# Schedule follow-up appts
# schedule first follow-up appt, 3 days from procedure;
Expand Down Expand Up @@ -2744,7 +2776,7 @@ def apply(self, person_id, squeeze_factor):
# check whether person had Rx at least 3 months ago and is now due repeat prescription
# alternate routes into testing/tx may mean person already has recent ARV dispensation
if person['hv_date_last_ART'] > (
self.sim.date - pd.DateOffset(months=self.module.parameters['dispensation_period_months'])):
self.sim.date - pd.DateOffset(months=self.module.parameters['dispensation_period_months'])):
return self.sim.modules["HealthSystem"].get_blank_appt_footprint()

if art_status_at_beginning_of_hsi == "not":
Expand Down Expand Up @@ -2945,13 +2977,13 @@ def get_drugs(self, age_of_person):
self.module.item_codes_for_consumables_required[
"First line ART regimen: young child"
]: dispensation_days
* 2
* 2
},
optional_item_codes={
self.module.item_codes_for_consumables_required[
"First line ART regimen: young child: cotrimoxazole"
]: dispensation_days
* 240
* 240
},
return_individual_results=True,
)
Expand All @@ -2962,7 +2994,7 @@ def get_drugs(self, age_of_person):
item_codes={self.module.item_codes_for_consumables_required[
'First line ART regimen: older child']: dispensation_days * 3},
optional_item_codes={self.module.item_codes_for_consumables_required[
'First line ART regimen: older child: cotrimoxazole']: dispensation_days * 480},
'First line ART regimen: older child: cotrimoxazole']: dispensation_days * 480},
return_individual_results=True)

else:
Expand All @@ -2971,7 +3003,7 @@ def get_drugs(self, age_of_person):
item_codes={self.module.item_codes_for_consumables_required[
'First-line ART regimen: adult']: dispensation_days},
optional_item_codes={self.module.item_codes_for_consumables_required[
'First-line ART regimen: adult: cotrimoxazole']: dispensation_days * 960},
'First-line ART regimen: adult: cotrimoxazole']: dispensation_days * 960},
return_individual_results=True)

# add drug names to dict
Expand Down
2 changes: 1 addition & 1 deletion src/tlo/methods/labour_lm.py
Original file line number Diff line number Diff line change
Expand Up @@ -501,7 +501,7 @@ def predict_postnatal_check(self, df, rng=None, **externals):

result[(df.la_parity > 4)] *= params['or_pnc_parity_>4']

result[(df.ac_total_anc_visits_current_pregnancy > 3)] *= params['or_pnc_anc4+']
result[(df.ac_total_anc_visits_current_pregnancy > 3)] *= params['or_pnc_anc4+'] #changing for DFF

result[externals['mode_of_delivery'] == 'caesarean_section'] *= params['or_pnc_caesarean_delivery']
result[(externals['delivery_setting'] == 'health_centre') | (externals['delivery_setting'] == 'hospital')] \
Expand Down
12 changes: 10 additions & 2 deletions src/tlo/methods/malaria.py
Original file line number Diff line number Diff line change
Expand Up @@ -186,7 +186,9 @@ def __init__(self, name=None):
"scaleup_parameters": Parameter(
Types.DATA_FRAME,
"the parameters and values changed in scenario analysis"
)
),
'iptp_coverage': Parameter(Types.REAL, 'Proportion of eligible pregnant women to receive IPTp this month')

}

PROPERTIES = {
Expand Down Expand Up @@ -296,6 +298,9 @@ def read_parameters(self, resourcefilepath: Optional[Path] = None):
all_inc = all_inc.reset_index()

all_inc['district_num'] = all_inc['admin'].map(mapper_district_name_to_num)

# Filter to only include Rumphi district (district_num = 3)
all_inc = all_inc[all_inc['district_num'] == 3].copy()
assert not all_inc['district_num'].isna().any()

self.all_inc = all_inc.drop(columns=['admin']).set_index(['month', 'district_num', 'llin', 'irs'])
Expand Down Expand Up @@ -930,7 +935,10 @@ def apply(self, population):

p1 = df.index[p1_condition]

for person_index in p1:
selected_for_iptp = self.module.rng.random_sample(len(p1)) < self.module.parameters['iptp_coverage']
p1_selected = p1[selected_for_iptp]

for person_index in p1_selected:
logger.debug(key='message',
data=f'MalariaIPTp: scheduling HSI_Malaria_IPTp for person {person_index}')

Expand Down
40 changes: 39 additions & 1 deletion tests/test_demography.py
Original file line number Diff line number Diff line change
Expand Up @@ -177,7 +177,45 @@ def test_calc_of_scaling_factor(tmpdir, seed):
# Check that the scaling factor is calculated in the log correctly:
output = parse_log_file(sim.log_filepath)
sf = output['tlo.methods.demography']['scaling_factor'].at[0, 'scaling_factor']
assert sf == approx(14.5e6 / popsize, rel=0.10)

# Get the actual total census population (sum of all active districts)
demog = sim.modules['Demography']

# Primary (prefered) approach: pop_2010['Count'] (matches your parameter dump)
total_pop = None
if 'pop_2010' in demog.parameters:
pop_df = demog.parameters['pop_2010']
if isinstance(pop_df, pd.DataFrame) and 'Count' in pop_df.columns:
total_pop = float(pop_df['Count'].sum())

# Fallback: search parameters for anything with "pop" in the key and sum numeric content
if (total_pop is None) or (total_pop == 0):
total_pop = 0.0
for k, v in demog.parameters.items():
if 'pop' not in k.lower():
continue
# DataFrame case
if isinstance(v, pd.DataFrame):
if 'Count' in v.columns:
total_pop += float(v['Count'].sum())
else:
# sum all numeric columns
total_pop += float(v.select_dtypes(include=[np.number]).to_numpy().sum())
# Series case
elif isinstance(v, pd.Series):
# numeric_only for newer pandas
total_pop += float(v.sum(numeric_only=True))
# numeric scalar
else:
try:
total_pop += float(v)
except Exception:
# ignore non-numeric params
pass

assert total_pop > 0, f"Could not determine total population from parameters: {list(demog.parameters.keys())}"

assert sf == approx(total_pop / popsize, rel=0.10)

# Check that the scaling factor is also logged in `tlo.methods.population`
assert output['tlo.methods.demography']['scaling_factor'].at[0, 'scaling_factor'] == \
Expand Down
Loading
Loading