Commit 80a1c40
authored
update parameters to enable interventions: a simpler and more reader-friendly way (#1081)
* co: more-readable update_params_for_interventions() fnc
diff --git src/tlo/methods/contraception.py src/tlo/methods/contraception.py
index aa1efa2..c3e8f9f 100644
--- src/tlo/methods/contraception.py
+++ src/tlo/methods/contraception.py
@@ -596,122 +596,37 @@ class Contraception(Module):
processed_params = self.processed_params
- 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))
- return np.array(
- [_d[self.sim.modules['Demography'].AGE_RANGE_LOOKUP[_age_year]] for _age_year in ages_by_year]
- )
+ def contraception_initiation_with_interv(p_start_per_month_without_interv):
+ """Increase the probabilities of a woman starting modern contraceptives due to Pop intervention being
+ applied."""
+ # TODO: remove the keys before intervention year
+ p_start_per_month_with_interv = {}
+ for year, age_method_df in p_start_per_month_without_interv.items():
+ p_start_per_month_with_interv[year] = age_method_df * self.parameters['Interventions_Pop'].loc[0]
+ return p_start_per_month_with_interv
- def time_age_trend_in_initiation():
- """The age-specific effect of calendar year on the probability of starting use of contraceptive
- (multiplicative effect). Values are chosen to induce a trend in age-specific fertility consistent with
- the WPP estimates."""
+ def contraception_initiation_after_birth_with_interv(p_start_after_birth_without_interv):
+ """Increase the probabilities of a woman starting modern contraceptives following giving birth due to PPFP
+ intervention being applied."""
+ # Exclude prob of 'not_using'
+ p_start_after_birth_with_interv = p_start_after_birth_without_interv.copy().drop('not_using')
- _years = np.arange(2010, 2101)
- _ages = np.arange(15, 50)
+ # Apply PPFP intervention multipliers (ie increase probs of modern methods)
+ p_start_after_birth_with_interv = \
+ p_start_after_birth_with_interv.mul(self.parameters['Interventions_PPFP'].loc[0])
- _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)
- _init = np.outer(_init_over_time, _init_over_time_modification_by_age)
+ # Return reduced prob of 'not_using'
+ p_start_after_birth_with_interv = pd.Series((1.0 - p_start_after_birth_with_interv.sum()),
+ index=['not_using']).append(p_start_after_birth_with_interv)
- return pd.DataFrame(index=_years, columns=_ages, data=_init)
+ return p_start_after_birth_with_interv
- 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."""
- # 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
- # 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())
-
- # Increase prob of 'female_sterilization' in older women accordingly
- probs_30plus = probs.copy()
- probs_30plus['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())
-
- return probs_below30, probs_30plus
-
- def contraception_initiation_with_interv():
- """Generate the probability per month of a woman initiating onto each contraceptive, by the age (in whole
- years) if FP interventions are applied."""
-
- # 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)
-
- # Effect of age
- age_effect = 1.0 + self.parameters['Initiation_ByAge'].set_index('age')['r_init1_age'].rename_axis(
- "age_years")
-
- # Year effect
- year_effect = time_age_trend_in_initiation()
-
- def apply_intervention_age_year_effects(probs_below30, probs_30plus):
- # Apply Pop intervention
- probs_by_method_below30 = \
- probs_below30.copy().drop('not_using').mul(self.parameters['Interventions_Pop'].loc[0])
- probs_by_method_30plus = \
- probs_30plus.copy().drop('not_using').mul(self.parameters['Interventions_Pop'].loc[0])
- # Assemble into age-specific data-frame:
- p_init = dict()
- 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]
- else:
- p_init_this_year[a] = probs_by_method_30plus * 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 >= 0.0).all().all()
-
- p_init[year] = p_init_this_year_df
-
- return p_init
-
- return apply_intervention_age_year_effects(p_init_by_method_below30, p_init_by_method_30plus)
-
- def contraception_initiation_after_birth_with_interv():
- """Get the probability of a woman starting a contraceptive following giving birth if FP interventions are
- applied. Avoid sterilization in women below 30 years old."""
-
- # Get initiation probabilities of contraception methods after birth from read-in Excel sheet
- p_start_after_birth = self.parameters['Initiation_AfterBirth'].loc[0].drop('not_using')
-
- # Apply PPFP intervention multipliers
- p_start_after_birth = p_start_after_birth.mul(self.parameters['Interventions_PPFP'].loc[0])
-
- # Add 'not_using' to initiation probabilities of contraception methods after birth
- p_start_after_birth = pd.concat(
- (
- pd.Series((1.0 - p_start_after_birth.sum()), index=['not_using']),
- p_start_after_birth
- )
- )
-
- return avoid_sterilization_below30(p_start_after_birth)
-
- processed_params['p_start_per_month'] = contraception_initiation_with_interv()
- processed_params['p_start_after_birth_below30'], processed_params['p_start_after_birth_30plus'] =\
- contraception_initiation_after_birth_with_interv()
+ processed_params['p_start_per_month'] = \
+ contraception_initiation_with_interv(processed_params['p_start_per_month'])
+ processed_params['p_start_after_birth_below30'] = \
+ contraception_initiation_after_birth_with_interv(processed_params['p_start_after_birth_below30'])
+ processed_params['p_start_after_birth_30plus'] = \
+ contraception_initiation_after_birth_with_interv(processed_params['p_start_after_birth_30plus'])
return processed_params
* co: do not save init probs for years before current sim year1 parent 8bdbacc commit 80a1c40
1 file changed
+31
-116
lines changed| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
596 | 596 | | |
597 | 597 | | |
598 | 598 | | |
599 | | - | |
600 | | - | |
601 | | - | |
602 | | - | |
603 | | - | |
604 | | - | |
605 | | - | |
606 | | - | |
607 | | - | |
608 | | - | |
609 | | - | |
610 | | - | |
611 | | - | |
612 | | - | |
613 | | - | |
614 | | - | |
615 | | - | |
616 | | - | |
617 | | - | |
618 | | - | |
619 | | - | |
620 | | - | |
621 | | - | |
622 | | - | |
623 | | - | |
624 | | - | |
625 | | - | |
626 | | - | |
627 | | - | |
628 | | - | |
629 | | - | |
630 | | - | |
631 | | - | |
632 | | - | |
633 | | - | |
634 | | - | |
635 | | - | |
636 | | - | |
637 | | - | |
638 | | - | |
639 | | - | |
640 | | - | |
641 | | - | |
642 | | - | |
643 | | - | |
644 | | - | |
645 | | - | |
646 | | - | |
647 | | - | |
648 | | - | |
649 | | - | |
650 | | - | |
651 | | - | |
652 | | - | |
653 | | - | |
654 | | - | |
655 | | - | |
656 | | - | |
657 | | - | |
658 | | - | |
659 | | - | |
660 | | - | |
661 | | - | |
662 | | - | |
663 | | - | |
664 | | - | |
665 | | - | |
666 | | - | |
667 | | - | |
668 | | - | |
669 | | - | |
670 | | - | |
671 | | - | |
672 | | - | |
673 | | - | |
674 | | - | |
675 | | - | |
676 | | - | |
677 | | - | |
678 | | - | |
679 | | - | |
680 | | - | |
681 | | - | |
682 | | - | |
683 | | - | |
684 | | - | |
685 | | - | |
686 | | - | |
687 | | - | |
688 | | - | |
689 | | - | |
690 | | - | |
691 | | - | |
692 | | - | |
693 | | - | |
694 | | - | |
695 | | - | |
696 | | - | |
697 | | - | |
698 | | - | |
699 | | - | |
700 | | - | |
701 | | - | |
702 | | - | |
703 | | - | |
704 | | - | |
705 | | - | |
706 | | - | |
707 | | - | |
708 | | - | |
709 | | - | |
710 | | - | |
711 | | - | |
712 | | - | |
713 | | - | |
714 | | - | |
| 599 | + | |
| 600 | + | |
| 601 | + | |
| 602 | + | |
| 603 | + | |
| 604 | + | |
| 605 | + | |
| 606 | + | |
| 607 | + | |
| 608 | + | |
| 609 | + | |
| 610 | + | |
| 611 | + | |
| 612 | + | |
| 613 | + | |
| 614 | + | |
| 615 | + | |
| 616 | + | |
| 617 | + | |
| 618 | + | |
| 619 | + | |
| 620 | + | |
| 621 | + | |
| 622 | + | |
| 623 | + | |
| 624 | + | |
| 625 | + | |
| 626 | + | |
| 627 | + | |
| 628 | + | |
| 629 | + | |
715 | 630 | | |
716 | 631 | | |
717 | 632 | | |
| |||
0 commit comments