From 01844de30ec224b44812287550be59dc011b5825 Mon Sep 17 00:00:00 2001 From: mmsuarezcosta Date: Tue, 2 Sep 2025 22:31:49 -0400 Subject: [PATCH 1/9] add prior labels on addt docs --- .../ResourceFile_Contraception/Discontinuation_ByAge.csv | 4 ++-- .../ResourceFile_Contraception/Initiation_ByAge.csv | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/resources/contraception/ResourceFile_Contraception/Discontinuation_ByAge.csv b/resources/contraception/ResourceFile_Contraception/Discontinuation_ByAge.csv index c4b70b9182..82ff7f2152 100644 --- a/resources/contraception/ResourceFile_Contraception/Discontinuation_ByAge.csv +++ b/resources/contraception/ResourceFile_Contraception/Discontinuation_ByAge.csv @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:f3b8d2085d10f1680cf7d521ba415777b194ef26a964c14bca473cbdd76c7982 -size 770 +oid sha256:e743447965ca160e53c0c590e01e3ce9db532c49f6fa84f2a4035b047ba229d3 +size 1439 diff --git a/resources/contraception/ResourceFile_Contraception/Initiation_ByAge.csv b/resources/contraception/ResourceFile_Contraception/Initiation_ByAge.csv index e1bf896912..8d38e6348f 100644 --- a/resources/contraception/ResourceFile_Contraception/Initiation_ByAge.csv +++ b/resources/contraception/ResourceFile_Contraception/Initiation_ByAge.csv @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:bb59b96ca917f218d48b349790092ea04d612c3545669c219ae25a65930a38d1 -size 810 +oid sha256:ae02651b9fb969ff28f5f391b00966e67c6868a2d38fdce40562e69ab952c383 +size 1450 From 0aa142805e84435093c8c80c4a120429a8a838a9 Mon Sep 17 00:00:00 2001 From: mmsuarezcosta Date: Tue, 2 Sep 2025 23:19:05 -0400 Subject: [PATCH 2/9] remove hardcoded values, add documentation of params --- .../Pregnancy_NotUsing_HIVeffect.csv | 4 +- .../Pregnancy_NotUsing_In_2010.csv | 4 +- .../simplified_labour_parameters.csv | 4 +- ...sourceFile_ContraceptionAnalysisParams.csv | 4 +- .../ResourceFile_ContraceptionParams.csv | 4 +- src/tlo/methods/contraception.py | 86 +++++++++++-------- 6 files changed, 60 insertions(+), 46 deletions(-) diff --git a/resources/contraception/ResourceFile_Contraception/Pregnancy_NotUsing_HIVeffect.csv b/resources/contraception/ResourceFile_Contraception/Pregnancy_NotUsing_HIVeffect.csv index bd377c879b..3af330ada6 100644 --- a/resources/contraception/ResourceFile_Contraception/Pregnancy_NotUsing_HIVeffect.csv +++ b/resources/contraception/ResourceFile_Contraception/Pregnancy_NotUsing_HIVeffect.csv @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:f6848831b52ab636cf78cd6c3ddc999ad01a46d9d5471987d0e406c479f75ef0 -size 263 +oid sha256:179dd16b27262395c54ffbdff9048cbd67215c5b788cd8c2932e132cc608a3b2 +size 1155 diff --git a/resources/contraception/ResourceFile_Contraception/Pregnancy_NotUsing_In_2010.csv b/resources/contraception/ResourceFile_Contraception/Pregnancy_NotUsing_In_2010.csv index c05c8a2649..f75833601b 100644 --- a/resources/contraception/ResourceFile_Contraception/Pregnancy_NotUsing_In_2010.csv +++ b/resources/contraception/ResourceFile_Contraception/Pregnancy_NotUsing_In_2010.csv @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:57d060bdd1a4ad87630853291de818144eeb15c5d2a5ba54a4d2507b31f879ff -size 509 +oid sha256:07eb50237174b7ef3d522972f66a4cdbc905832afc206f67cdfb06a6cae3f79e +size 1401 diff --git a/resources/contraception/ResourceFile_Contraception/simplified_labour_parameters.csv b/resources/contraception/ResourceFile_Contraception/simplified_labour_parameters.csv index 38c6f58d9e..641a32a143 100644 --- a/resources/contraception/ResourceFile_Contraception/simplified_labour_parameters.csv +++ b/resources/contraception/ResourceFile_Contraception/simplified_labour_parameters.csv @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:71c1d00707d77dcba8ec87532a9ac3f122cb4bbb2c6cd473d57c0157259b16e3 -size 95 +oid sha256:51abe8f3bdeea948ae1842c12463bd26434fb20ab31490d7967ddcde7d6ced62 +size 171 diff --git a/resources/contraception/ResourceFile_ContraceptionAnalysisParams.csv b/resources/contraception/ResourceFile_ContraceptionAnalysisParams.csv index 9e13abd6f0..8b331dc242 100644 --- a/resources/contraception/ResourceFile_ContraceptionAnalysisParams.csv +++ b/resources/contraception/ResourceFile_ContraceptionAnalysisParams.csv @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:cfadf013d51552ec90b5d03881f09dd8fad1cae28a2dc9ba6116568fcc5fa564 -size 306 +oid sha256:3ee24fb3e65e2dfcfb5c75d23a73def66f9a0279e68598bd06988bf0d0c60cab +size 420 diff --git a/resources/contraception/ResourceFile_ContraceptionParams.csv b/resources/contraception/ResourceFile_ContraceptionParams.csv index ac1caab585..5ee876f77f 100644 --- a/resources/contraception/ResourceFile_ContraceptionParams.csv +++ b/resources/contraception/ResourceFile_ContraceptionParams.csv @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:14205ecc544760aebeff19cdcd23f9a8a3df653b293e1186f48fe17206556069 -size 620 +oid sha256:7e257969d6dd07321a9cc07facceca30caa2bbf5864cd3db1c0669ff54b52552 +size 1184 diff --git a/src/tlo/methods/contraception.py b/src/tlo/methods/contraception.py index 6f56a55cc7..24154460b9 100644 --- a/src/tlo/methods/contraception.py +++ b/src/tlo/methods/contraception.py @@ -102,7 +102,14 @@ class Contraception(Module): " if False: FP interventions (pop & ppfp) are not simulated."), 'interventions_start_date': Parameter( Types.DATE, "The date since which the FP interventions (pop & ppfp) are implemented, if at all (ie, if " - "use_interventions==True") + "use_interventions==True"), + + 'min_age_contraception': Parameter( + Types.INT, "Minimum age for contraception use (inclusive)."), + 'max_age_contraception': Parameter( + Types.INT, "Maximum age for contraception use (inclusive)."), + 'sterilization_age_limit': Parameter( + Types.INT, "Minimum age for sterilization procedures."), } all_contraception_states = { @@ -225,7 +232,8 @@ def initialise_population(self, population): # 2) Assign contraception method # Select females aged 15-49 from population, for current year - females1549 = df.is_alive & (df.sex == 'F') & df.age_years.between(15, 49) + females1549 = df.is_alive & (df.sex == 'F') & df.age_years.between( + self.parameters['min_age_contraception'], self.parameters['max_age_contraception'] - 1) p_method = self.processed_params['initial_method_use'] df.loc[females1549, 'co_contraception'] = df.loc[females1549, 'age_years'].apply( lambda _age_years: self.rng.choice(p_method.columns, p=p_method.loc[_age_years]) @@ -334,34 +342,36 @@ def initial_method_use(): # Check correct format assert set(p_method.columns) == set(self.all_contraception_states) - assert (p_method.index == range(15, 50)).all() + assert (p_method.index == range( + self.parameters['min_age_contraception'], self.parameters['max_age_contraception'])).all() return p_method def avoid_sterilization_below30(probs): - """Prevent women below 30 years having female sterilization and adjust the probability for women 30 and over - to preserve the overall probability of initiating sterilization.""" + """Prevent women below sterilization_age_limit years having female sterilization and adjust the + probability for women at or above the limit to preserve the overall probability of initiating + sterilization.""" # Input 'probs' must include probs for all methods including 'not_using' assert set(probs.index) == set(self.all_contraception_states) - # Prevent women below 30 years having 'female_sterilization' - probs_below30 = probs.copy() - probs_below30['female_sterilization'] = 0.0 + # Prevent women below sterilization_age_limit years having 'female_sterilization' + probs_below_limit = probs.copy() + probs_below_limit['female_sterilization'] = 0.0 # Scale so that the probability of all outcomes sum to 1.0 - probs_below30 = probs_below30 / probs_below30.sum() - assert np.isclose(1.0, probs_below30.sum()) + probs_below_limit = probs_below_limit / probs_below_limit.sum() + assert np.isclose(1.0, probs_below_limit.sum()) # Increase prob of 'female_sterilization' in older women accordingly - probs_30plus = probs.copy() - probs_30plus['female_sterilization'] = ( + probs_limit_plus = probs.copy() + probs_limit_plus['female_sterilization'] = ( probs.loc['female_sterilization'] / self.ratio_n_females_30_49_to_15_49_in_2010 ) # Scale so that the probability of all outcomes sum to 1.0 - probs_30plus = probs_30plus / probs_30plus.sum() - assert np.isclose(1.0, probs_30plus.sum()) + probs_limit_plus = probs_limit_plus / probs_limit_plus.sum() + assert np.isclose(1.0, probs_limit_plus.sum()) - return probs_below30, probs_30plus + return probs_below_limit, probs_limit_plus def contraception_initiation(): """Generate the probability per month of a woman initiating onto each contraceptive, by the age (in whole @@ -370,9 +380,9 @@ def contraception_initiation(): # Probability of initiation by method per month (average over all ages) p_init_by_method = self.parameters['Initiation_ByMethod'].loc[0] - # Prevent women below 30 years having 'female_sterilization' while preserving the overall probability of - # 'female_sterilization' initiation - p_init_by_method_below30, p_init_by_method_30plus = avoid_sterilization_below30(p_init_by_method) + # Prevent women below sterilization_age_limit years having 'female_sterilization' while preserving + # the overall probability of 'female_sterilization' initiation + p_init_by_method_below_limit, p_init_by_method_limit_plus = avoid_sterilization_below30(p_init_by_method) # Effect of age age_effect = 1.0 + self.parameters['Initiation_ByAge'].set_index('age')['r_init1_age'].rename_axis( @@ -381,31 +391,35 @@ def contraception_initiation(): # Year effect year_effect = time_age_trend_in_initiation() - def apply_age_year_effects(probs_below30, probs_30plus): + def apply_age_year_effects(probs_below_limit, probs_limit_plus): # Assemble into age-specific data-frame: - probs_by_method_below30 = probs_below30.copy().drop('not_using') - probs_by_method_30plus = probs_30plus.copy().drop('not_using') + probs_by_method_below_limit = probs_below_limit.copy().drop('not_using') + probs_by_method_limit_plus = probs_limit_plus.copy().drop('not_using') p_init = dict() + p = self.parameters for year in year_effect.index: p_init_this_year = dict() for a in age_effect.index: - if a < 30: - p_init_this_year[a] = probs_by_method_below30 * age_effect.at[a] * year_effect.at[year, a] + if a < p['sterilization_age_limit']: + p_init_this_year[a] = (probs_by_method_below_limit * age_effect.at[a] * + year_effect.at[year, a]) else: - p_init_this_year[a] = probs_by_method_30plus * age_effect.at[a] * year_effect.at[year, a] + p_init_this_year[a] = (probs_by_method_limit_plus * age_effect.at[a] * + year_effect.at[year, a]) p_init_this_year_df = pd.DataFrame.from_dict(p_init_this_year, orient='index') # Check correct format of age/method data-frame assert set(p_init_this_year_df.columns) == set(self.all_contraception_states - {'not_using'}) - assert (p_init_this_year_df.index == range(15, 50)).all() + assert (p_init_this_year_df.index == range( + self.parameters['min_age_contraception'], p['max_age_contraception'])).all() assert (p_init_this_year_df >= 0.0).all().all() p_init[year] = p_init_this_year_df return p_init - return apply_age_year_effects(p_init_by_method_below30, p_init_by_method_30plus) + return apply_age_year_effects(p_init_by_method_below_limit, p_init_by_method_limit_plus) def contraception_switch(): """Get the probability per month of a woman switching to contraceptive method, given that she is currently @@ -419,15 +433,15 @@ def contraception_switch(): # Columns = "current method"; Row = "new method" switching_matrix = self.parameters['Prob_Switch_From_And_To'].set_index('switchfrom').transpose() - # Prevent women below 30 years having 'female_sterilization' - switching_matrix_below30 = switching_matrix.copy() - switching_matrix_below30.loc['female_sterilization', :] = 0.0 - switching_matrix_below30 = switching_matrix_below30.apply(lambda col: col / col.sum()) + # Prevent women below sterilization_age_limit years having 'female_sterilization' + switching_matrix_below_limit = switching_matrix.copy() + switching_matrix_below_limit.loc['female_sterilization', :] = 0.0 + switching_matrix_below_limit = switching_matrix_below_limit.apply(lambda col: col / col.sum()) - assert set(switching_matrix_below30.columns) == ( + assert set(switching_matrix_below_limit.columns) == ( self.all_contraception_states - {"not_using", "female_sterilization"}) - assert set(switching_matrix_below30.index) == (self.all_contraception_states - {"not_using"}) - assert np.isclose(1.0, switching_matrix_below30.sum(axis=0)).all() + assert set(switching_matrix_below_limit.index) == (self.all_contraception_states - {"not_using"}) + assert np.isclose(1.0, switching_matrix_below_limit.sum(axis=0)).all() # Increase prob of 'female_sterilization' in older women accordingly new_fs_probs_30plus = ( @@ -444,7 +458,7 @@ def contraception_switch(): assert set(switching_matrix_30plus.index) == (self.all_contraception_states - {"not_using"}) assert np.isclose(1.0, switching_matrix_30plus.sum(axis=0)).all() - return p_switch_from, switching_matrix_below30, switching_matrix_30plus + return p_switch_from, switching_matrix_below_limit, switching_matrix_30plus def contraception_stop(): """Get the probability per month of a woman stopping use of contraceptive method.""" @@ -842,8 +856,8 @@ class ContraceptionPoll(RegularEvent, PopulationScopeEventMixin): def __init__(self, module, run_do_pregnancy=True, run_update_contraceptive=True): super().__init__(module, frequency=DateOffset(months=1)) - self.age_low = 15 - self.age_high = 49 + self.age_low = module.parameters['min_age_contraception'] + self.age_high = module.parameters['max_age_contraception'] - 1 self.run_do_pregnancy = run_do_pregnancy # (Provided for testing only) self.run_update_contraceptive = run_update_contraceptive # (Provided for testing only) From d2e1d717e28f894e825d8f712cc25702ac550132 Mon Sep 17 00:00:00 2001 From: mmsuarezcosta Date: Tue, 2 Sep 2025 23:42:02 -0400 Subject: [PATCH 3/9] remove hardcoded values, add documentation of params --- .../ResourceFile_ContraceptionParams.csv | 4 +- src/tlo/methods/contraception.py | 70 +++++++++++++++---- 2 files changed, 57 insertions(+), 17 deletions(-) diff --git a/resources/contraception/ResourceFile_ContraceptionParams.csv b/resources/contraception/ResourceFile_ContraceptionParams.csv index 5ee876f77f..41d4c2c188 100644 --- a/resources/contraception/ResourceFile_ContraceptionParams.csv +++ b/resources/contraception/ResourceFile_ContraceptionParams.csv @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:7e257969d6dd07321a9cc07facceca30caa2bbf5864cd3db1c0669ff54b52552 -size 1184 +oid sha256:6e4f692843e3f82eea2048dbd3da34eb4d31b80db58bd6af8c3214acc40549c2 +size 2097 diff --git a/src/tlo/methods/contraception.py b/src/tlo/methods/contraception.py index 24154460b9..acf2e8f204 100644 --- a/src/tlo/methods/contraception.py +++ b/src/tlo/methods/contraception.py @@ -4,7 +4,6 @@ import numpy as np import pandas as pd - from tlo import Date, DateOffset, Module, Parameter, Property, Types, logging from tlo.analysis.utils import flatten_multi_index_series_into_dict_for_logging from tlo.events import Event, IndividualScopeEventMixin, PopulationScopeEventMixin, RegularEvent @@ -110,6 +109,29 @@ class Contraception(Module): Types.INT, "Maximum age for contraception use (inclusive)."), 'sterilization_age_limit': Parameter( Types.INT, "Minimum age for sterilization procedures."), + + 'polling_frequency_months': Parameter( + Types.INT, "Frequency in months for contraception polling and logging events."), + 'min_simulation_year': Parameter( + Types.INT, "Minimum year for simulation time trends."), + 'max_simulation_year': Parameter( + Types.INT, "Maximum year for simulation time trends."), + 'transition_year': Parameter( + Types.INT, "Transition year for time trend calculations (typically 2020)."), + 'initiation_trend_rate_pre_transition': Parameter( + Types.REAL, "Annual rate of increase in contraception initiation before transition year."), + 'initiation_trend_rate_post_transition': Parameter( + Types.REAL, "Annual rate of increase in contraception initiation after transition year."), + 'discontinuation_trend_rate_pre_transition': Parameter( + Types.REAL, "Annual rate of decrease in contraception discontinuation before transition year."), + 'discontinuation_trend_rate_post_transition': Parameter( + Types.REAL, "Annual rate of decrease in contraception discontinuation after transition year."), + 'age_modification_factors': Parameter( + Types.LIST, "Age-specific modification factors for time trends by age group (15-19, 20-24, ..., 45-49)."), + 'reference_year': Parameter( + Types.INT, "Reference year for time trend calculations (typically 2010)."), + 'age_ranges': Parameter( + Types.LIST, "Age range labels for demographic analysis (e.g., ['15-19', '20-24', ...]).") } all_contraception_states = { @@ -327,7 +349,7 @@ def process_params(self): processed_params = dict() def expand_to_age_years(values_by_age_groups, ages_by_year): - _d = dict(zip(['15-19', '20-24', '25-29', '30-34', '35-39', '40-44', '45-49'], values_by_age_groups)) + _d = dict(zip(self.parameters['age_ranges'], values_by_age_groups)) return np.array( [_d[self.sim.modules['Demography'].AGE_RANGE_LOOKUP[_age_year]] for _age_year in ages_by_year] ) @@ -491,12 +513,21 @@ def time_age_trend_in_initiation(): (multiplicative effect). Values are chosen to induce a trend in age-specific fertility consistent with the WPP estimates.""" - _years = np.arange(2010, 2101) - _ages = np.arange(15, 50) + _years = np.arange(self.parameters['min_simulation_year'], self.parameters['max_simulation_year']) + _ages = np.arange(self.parameters['min_age_contraception'], self.parameters['max_age_contraception']) - _init_over_time = np.exp(+0.05 * np.minimum(2020 - 2010, (_years - 2010))) * np.maximum(1.0, np.exp( - +0.01 * (_years - 2020))) - _init_over_time_modification_by_age = 1.0 / expand_to_age_years([1.0, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5], _ages) + pre_transition_years = np.minimum( + self.parameters['transition_year'] - self.parameters['reference_year'], + (_years - self.parameters['reference_year']) + ) + post_transition_years = _years - self.parameters['transition_year'] + + _init_over_time = (np.exp(self.parameters['initiation_trend_rate_pre_transition'] * + pre_transition_years) * + np.maximum(1.0, np.exp(self.parameters['initiation_trend_rate_post_transition'] * + post_transition_years))) + _init_over_time_modification_by_age = 1.0 / expand_to_age_years( + self.parameters['age_modification_factors'], _ages) _init = np.outer(_init_over_time, _init_over_time_modification_by_age) return pd.DataFrame(index=_years, columns=_ages, data=_init) @@ -506,12 +537,21 @@ def time_age_trend_in_stopping(): (multiplicative effect). Values are chosen to induce a trend in age-specific fertility consistent with the WPP estimates.""" - _years = np.arange(2010, 2101) - _ages = np.arange(15, 50) + _years = np.arange(self.parameters['min_simulation_year'], self.parameters['max_simulation_year']) + _ages = np.arange(self.parameters['min_age_contraception'], self.parameters['max_age_contraception']) - _discont_over_time = np.exp(-0.05 * np.minimum(2020 - 2010, (_years - 2010))) * np.minimum(1.0, np.exp( - -0.01 * (_years - 2020))) - _discont_over_time_modification_by_age = expand_to_age_years([1.0, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5], _ages) + pre_transition_years = np.minimum( + self.parameters['transition_year'] - self.parameters['reference_year'], + (_years - self.parameters['reference_year']) + ) + post_transition_years = _years - self.parameters['transition_year'] + + _discont_over_time = (np.exp(self.parameters['discontinuation_trend_rate_pre_transition'] * + pre_transition_years) * + np.minimum(1.0, np.exp(self.parameters['discontinuation_trend_rate_post_transition'] * + post_transition_years))) + _discont_over_time_modification_by_age = expand_to_age_years( + self.parameters['age_modification_factors'], _ages) _discont = np.outer(_discont_over_time, _discont_over_time_modification_by_age) return pd.DataFrame(index=_years, columns=_ages, data=_discont) @@ -531,7 +571,7 @@ def scaling_factor_on_monthly_risk_of_pregnancy(): # first scaling factor is that worked out from the calibration script scaling_factor_as_dict = dict(zip( - ['15-19', '20-24', '25-29', '30-34', '35-39', '40-44', '45-49'], + self.parameters['age_ranges'], self.parameters['scaling_factor_on_monthly_risk_of_pregnancy'] )) @@ -855,7 +895,7 @@ class ContraceptionPoll(RegularEvent, PopulationScopeEventMixin): """ def __init__(self, module, run_do_pregnancy=True, run_update_contraceptive=True): - super().__init__(module, frequency=DateOffset(months=1)) + super().__init__(module, frequency=DateOffset(months=module.parameters['polling_frequency_months'])) self.age_low = module.parameters['min_age_contraception'] self.age_high = module.parameters['max_age_contraception'] - 1 @@ -1124,7 +1164,7 @@ def set_new_pregnancy(self, women_id: list): class ContraceptionLoggingEvent(RegularEvent, PopulationScopeEventMixin): def __init__(self, module): """Logs state of contraceptive usage in the population at a point in time.""" - super().__init__(module, frequency=DateOffset(months=1)) + super().__init__(module, frequency=DateOffset(months=module.parameters['polling_frequency_months'])) def apply(self, population): df = population.props From 5b2cf9fcc05b7ce4bb4edd287f7962cf2482d5da Mon Sep 17 00:00:00 2001 From: mmsuarezcosta Date: Tue, 2 Sep 2025 23:49:56 -0400 Subject: [PATCH 4/9] lint fix --- src/tlo/methods/contraception.py | 1 + 1 file changed, 1 insertion(+) diff --git a/src/tlo/methods/contraception.py b/src/tlo/methods/contraception.py index acf2e8f204..a388650abb 100644 --- a/src/tlo/methods/contraception.py +++ b/src/tlo/methods/contraception.py @@ -4,6 +4,7 @@ import numpy as np import pandas as pd + from tlo import Date, DateOffset, Module, Parameter, Property, Types, logging from tlo.analysis.utils import flatten_multi_index_series_into_dict_for_logging from tlo.events import Event, IndividualScopeEventMixin, PopulationScopeEventMixin, RegularEvent From ede21183a16833f42afeed8df2cb26df90f1ef9c Mon Sep 17 00:00:00 2001 From: mmsuarezcosta Date: Thu, 4 Sep 2025 20:27:50 -0400 Subject: [PATCH 5/9] update param definitions --- src/tlo/methods/contraception.py | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/src/tlo/methods/contraception.py b/src/tlo/methods/contraception.py index a388650abb..76d8e11c7d 100644 --- a/src/tlo/methods/contraception.py +++ b/src/tlo/methods/contraception.py @@ -105,20 +105,20 @@ class Contraception(Module): "use_interventions==True"), 'min_age_contraception': Parameter( - Types.INT, "Minimum age for contraception use (inclusive)."), + Types.INT, "Minimum age for contraception use."), 'max_age_contraception': Parameter( - Types.INT, "Maximum age for contraception use (inclusive)."), + Types.INT, "Maximum age for contraception use."), 'sterilization_age_limit': Parameter( Types.INT, "Minimum age for sterilization procedures."), 'polling_frequency_months': Parameter( - Types.INT, "Frequency in months for contraception polling and logging events."), + Types.INT, "Frequency in months for contraception main polling event."), 'min_simulation_year': Parameter( Types.INT, "Minimum year for simulation time trends."), 'max_simulation_year': Parameter( Types.INT, "Maximum year for simulation time trends."), 'transition_year': Parameter( - Types.INT, "Transition year for time trend calculations (typically 2020)."), + Types.INT, "Transition year for time trend calculations."), 'initiation_trend_rate_pre_transition': Parameter( Types.REAL, "Annual rate of increase in contraception initiation before transition year."), 'initiation_trend_rate_post_transition': Parameter( @@ -128,9 +128,10 @@ class Contraception(Module): 'discontinuation_trend_rate_post_transition': Parameter( Types.REAL, "Annual rate of decrease in contraception discontinuation after transition year."), 'age_modification_factors': Parameter( - Types.LIST, "Age-specific modification factors for time trends by age group (15-19, 20-24, ..., 45-49)."), + Types.LIST, "Age-specific modification factors for time trends by age groups defined " + "in parameter age_ranges."), 'reference_year': Parameter( - Types.INT, "Reference year for time trend calculations (typically 2010)."), + Types.INT, "Reference year for time trend calculations."), 'age_ranges': Parameter( Types.LIST, "Age range labels for demographic analysis (e.g., ['15-19', '20-24', ...]).") } @@ -1165,7 +1166,7 @@ def set_new_pregnancy(self, women_id: list): class ContraceptionLoggingEvent(RegularEvent, PopulationScopeEventMixin): def __init__(self, module): """Logs state of contraceptive usage in the population at a point in time.""" - super().__init__(module, frequency=DateOffset(months=module.parameters['polling_frequency_months'])) + super().__init__(module, frequency=DateOffset(months=1)) def apply(self, population): df = population.props From f96548d0d14e3423204c8eed8211aae2fd7f7814 Mon Sep 17 00:00:00 2001 From: mmsuarezcosta Date: Thu, 4 Sep 2025 21:05:45 -0400 Subject: [PATCH 6/9] update param labeling --- resources/contraception/ResourceFile_ContraceptionParams.csv | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/resources/contraception/ResourceFile_ContraceptionParams.csv b/resources/contraception/ResourceFile_ContraceptionParams.csv index 41d4c2c188..b104df952f 100644 --- a/resources/contraception/ResourceFile_ContraceptionParams.csv +++ b/resources/contraception/ResourceFile_ContraceptionParams.csv @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:6e4f692843e3f82eea2048dbd3da34eb4d31b80db58bd6af8c3214acc40549c2 -size 2097 +oid sha256:5ec243b1a73c0987124a8aa3bbd93ad39b69fac6f666a0e18b46ea306731dcab +size 2114 From 786d430102a43c34b5591287c85fcf072294f693 Mon Sep 17 00:00:00 2001 From: mmsuarezcosta Date: Sun, 9 Nov 2025 16:06:52 -0500 Subject: [PATCH 7/9] update comments, review priors --- .../ResourceFile_Contraception/Discontinuation_ByAge.csv | 4 ++-- .../ResourceFile_Contraception/Initiation_ByAge.csv | 4 ++-- resources/contraception/ResourceFile_ContraceptionParams.csv | 2 +- src/tlo/methods/contraception.py | 4 ++-- 4 files changed, 7 insertions(+), 7 deletions(-) diff --git a/resources/contraception/ResourceFile_Contraception/Discontinuation_ByAge.csv b/resources/contraception/ResourceFile_Contraception/Discontinuation_ByAge.csv index 82ff7f2152..7e9d1b59c7 100644 --- a/resources/contraception/ResourceFile_Contraception/Discontinuation_ByAge.csv +++ b/resources/contraception/ResourceFile_Contraception/Discontinuation_ByAge.csv @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:e743447965ca160e53c0c590e01e3ce9db532c49f6fa84f2a4035b047ba229d3 -size 1439 +oid sha256:3bb6850fe017a2d1a6fb3430eb8fd6c0591da0539dd1786a153f0889a731fef8 +size 1474 diff --git a/resources/contraception/ResourceFile_Contraception/Initiation_ByAge.csv b/resources/contraception/ResourceFile_Contraception/Initiation_ByAge.csv index 8d38e6348f..8c80cb871b 100644 --- a/resources/contraception/ResourceFile_Contraception/Initiation_ByAge.csv +++ b/resources/contraception/ResourceFile_Contraception/Initiation_ByAge.csv @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:ae02651b9fb969ff28f5f391b00966e67c6868a2d38fdce40562e69ab952c383 -size 1450 +oid sha256:af364b872a188337427e286a8c3a2b3615f0290437e7693c0d09210d517245e8 +size 1485 diff --git a/resources/contraception/ResourceFile_ContraceptionParams.csv b/resources/contraception/ResourceFile_ContraceptionParams.csv index b104df952f..fdfc8daecc 100644 --- a/resources/contraception/ResourceFile_ContraceptionParams.csv +++ b/resources/contraception/ResourceFile_ContraceptionParams.csv @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:5ec243b1a73c0987124a8aa3bbd93ad39b69fac6f666a0e18b46ea306731dcab +oid sha256:8fafb0ff2f89602953cbdc4829782196435bdd3c05c0b53682d3368dc2b41c0f size 2114 diff --git a/src/tlo/methods/contraception.py b/src/tlo/methods/contraception.py index 76d8e11c7d..6f7b315c1d 100644 --- a/src/tlo/methods/contraception.py +++ b/src/tlo/methods/contraception.py @@ -378,7 +378,7 @@ def avoid_sterilization_below30(probs): # Input 'probs' must include probs for all methods including 'not_using' assert set(probs.index) == set(self.all_contraception_states) - # Prevent women below sterilization_age_limit years having 'female_sterilization' + # Prevent women below sterilization age limit from having 'female_sterilization' probs_below_limit = probs.copy() probs_below_limit['female_sterilization'] = 0.0 # Scale so that the probability of all outcomes sum to 1.0 @@ -457,7 +457,7 @@ def contraception_switch(): # Columns = "current method"; Row = "new method" switching_matrix = self.parameters['Prob_Switch_From_And_To'].set_index('switchfrom').transpose() - # Prevent women below sterilization_age_limit years having 'female_sterilization' + # Prevent women below sterilization age limit from having 'female_sterilization' switching_matrix_below_limit = switching_matrix.copy() switching_matrix_below_limit.loc['female_sterilization', :] = 0.0 switching_matrix_below_limit = switching_matrix_below_limit.apply(lambda col: col / col.sum()) From 7b4ca702434e973a557618c496f657b549fa81e8 Mon Sep 17 00:00:00 2001 From: mmsuarezcosta Date: Tue, 11 Nov 2025 11:35:58 -0500 Subject: [PATCH 8/9] update simulation params --- resources/contraception/ResourceFile_ContraceptionParams.csv | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/resources/contraception/ResourceFile_ContraceptionParams.csv b/resources/contraception/ResourceFile_ContraceptionParams.csv index fdfc8daecc..5d06403f9b 100644 --- a/resources/contraception/ResourceFile_ContraceptionParams.csv +++ b/resources/contraception/ResourceFile_ContraceptionParams.csv @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:8fafb0ff2f89602953cbdc4829782196435bdd3c05c0b53682d3368dc2b41c0f -size 2114 +oid sha256:204a08f5f3d0a24581821e977aff6e784d58095f41e8697b6ee1c3cd1b1e684f +size 2084 From 0f1316a802d5f7a275dbc0e9b7aa958049d02757 Mon Sep 17 00:00:00 2001 From: mmsuarezcosta Date: Tue, 11 Nov 2025 11:42:00 -0500 Subject: [PATCH 9/9] update scenario params --- resources/contraception/ResourceFile_ContraceptionParams.csv | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/resources/contraception/ResourceFile_ContraceptionParams.csv b/resources/contraception/ResourceFile_ContraceptionParams.csv index 5d06403f9b..26fbfc2adb 100644 --- a/resources/contraception/ResourceFile_ContraceptionParams.csv +++ b/resources/contraception/ResourceFile_ContraceptionParams.csv @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:204a08f5f3d0a24581821e977aff6e784d58095f41e8697b6ee1c3cd1b1e684f -size 2084 +oid sha256:201c2a740f5a7e2c870d4758bf21015102796e6a7183f6c0e11cbae15e8264bb +size 2076