@@ -611,121 +611,37 @@ def update_params_for_interventions(self):
611
611
612
612
processed_params = self .processed_params
613
613
614
- def expand_to_age_years (values_by_age_groups , ages_by_year ):
615
- _d = dict (zip (['15-19' , '20-24' , '25-29' , '30-34' , '35-39' , '40-44' , '45-49' ], values_by_age_groups ))
616
- return np .array (
617
- [_d [self .sim .modules ['Demography' ].AGE_RANGE_LOOKUP [_age_year ]] for _age_year in ages_by_year ]
618
- )
619
-
620
- def time_age_trend_in_initiation ():
621
- """The age-specific effect of calendar year on the probability of starting use of contraceptive
622
- (multiplicative effect). Values are chosen to induce a trend in age-specific fertility consistent with
623
- the WPP estimates."""
624
-
625
- _years = np .arange (2010 , 2101 )
626
- _ages = np .arange (15 , 50 )
627
-
628
- _init_over_time = np .exp (+ 0.05 * np .minimum (2020 - 2010 , (_years - 2010 ))) * np .maximum (1.0 , np .exp (
629
- + 0.01 * (_years - 2020 )))
630
- _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 )
631
- _init = np .outer (_init_over_time , _init_over_time_modification_by_age )
632
-
633
- return pd .DataFrame (index = _years , columns = _ages , data = _init )
634
-
635
- def avoid_sterilization_below30 (probs ):
636
- """Prevent women below 30 years having female sterilization and adjust the probability for women 30 and over
637
- to preserve the overall probability of initiating sterilization."""
638
- # Input 'probs' must include probs for all methods including 'not_using'
639
- assert set (probs .index ) == set (self .all_contraception_states )
640
-
641
- # Prevent women below 30 years having 'female_sterilization'
642
- probs_below30 = probs .copy ()
643
- probs_below30 ['female_sterilization' ] = 0.0
644
- # Scale so that the probability of all outcomes sum to 1.0
645
- probs_below30 = probs_below30 / probs_below30 .sum ()
646
- assert np .isclose (1.0 , probs_below30 .sum ())
647
-
648
- # Increase prob of 'female_sterilization' in older women accordingly
649
- probs_30plus = probs .copy ()
650
- probs_30plus ['female_sterilization' ] = \
651
- probs .loc ['female_sterilization' ] / \
652
- (self .n_female3049_in_2010 / self .n_female1549_in_2010 )
653
- # Scale so that the probability of all outcomes sum to 1.0
654
- probs_30plus = probs_30plus / probs_30plus .sum ()
655
- assert np .isclose (1.0 , probs_30plus .sum ())
656
-
657
- return probs_below30 , probs_30plus
658
-
659
- def contraception_initiation_with_interv ():
660
- """Generate the probability per month of a woman initiating onto each contraceptive, by the age (in whole
661
- years) if FP interventions are applied."""
662
-
663
- # Probability of initiation by method per month (average over all ages)
664
- p_init_by_method = self .parameters ['Initiation_ByMethod' ].loc [0 ]
665
-
666
- # Prevent women below 30 years having 'female_sterilization' while preserving the overall probability of
667
- # 'female_sterilization' initiation
668
- p_init_by_method_below30 , p_init_by_method_30plus = avoid_sterilization_below30 (p_init_by_method )
669
-
670
- # Effect of age
671
- age_effect = 1.0 + self .parameters ['Initiation_ByAge' ].set_index ('age' )['r_init1_age' ].rename_axis (
672
- "age_years" )
673
-
674
- # Year effect
675
- year_effect = time_age_trend_in_initiation ()
676
-
677
- def apply_intervention_age_year_effects (probs_below30 , probs_30plus ):
678
- # Apply Pop intervention
679
- probs_by_method_below30 = \
680
- probs_below30 .copy ().drop ('not_using' ).mul (self .parameters ['Interventions_Pop' ].loc [0 ])
681
- probs_by_method_30plus = \
682
- probs_30plus .copy ().drop ('not_using' ).mul (self .parameters ['Interventions_Pop' ].loc [0 ])
683
- # Assemble into age-specific data-frame:
684
- p_init = dict ()
685
- for year in year_effect .index :
686
-
687
- p_init_this_year = dict ()
688
- for a in age_effect .index :
689
- if a < 30 :
690
- p_init_this_year [a ] = probs_by_method_below30 * age_effect .at [a ] * year_effect .at [year , a ]
691
- else :
692
- p_init_this_year [a ] = probs_by_method_30plus * age_effect .at [a ] * year_effect .at [year , a ]
693
- p_init_this_year_df = pd .DataFrame .from_dict (p_init_this_year , orient = 'index' )
694
-
695
- # Check correct format of age/method data-frame
696
- assert set (p_init_this_year_df .columns ) == set (self .all_contraception_states - {'not_using' })
697
- assert (p_init_this_year_df .index == range (15 , 50 )).all ()
698
- assert (p_init_this_year_df >= 0.0 ).all ().all ()
699
-
700
- p_init [year ] = p_init_this_year_df
701
-
702
- return p_init
703
-
704
- return apply_intervention_age_year_effects (p_init_by_method_below30 , p_init_by_method_30plus )
705
-
706
- def contraception_initiation_after_birth_with_interv ():
707
- """Get the probability of a woman starting a contraceptive following giving birth if FP interventions are
708
- applied. Avoid sterilization in women below 30 years old."""
709
-
710
- # Get initiation probabilities of contraception methods after birth from read-in Excel sheet
711
- p_start_after_birth = self .parameters ['Initiation_AfterBirth' ].loc [0 ].drop ('not_using' )
712
-
713
- # Apply PPFP intervention multipliers
714
- p_start_after_birth = p_start_after_birth .mul (self .parameters ['Interventions_PPFP' ].loc [0 ])
715
-
716
- # Add 'not_using' to initiation probabilities of contraception methods after birth
717
- p_start_after_birth = pd .concat (
718
- (
719
- pd .Series ((1.0 - p_start_after_birth .sum ()), index = ['not_using' ]),
720
- p_start_after_birth
721
- )
722
- )
723
-
724
- return avoid_sterilization_below30 (p_start_after_birth )
725
-
726
- processed_params ['p_start_per_month' ] = contraception_initiation_with_interv ()
727
- processed_params ['p_start_after_birth_below30' ], processed_params ['p_start_after_birth_30plus' ] = \
728
- contraception_initiation_after_birth_with_interv ()
614
+ def contraception_initiation_with_interv (p_start_per_month_without_interv ):
615
+ """Increase the probabilities of a woman starting modern contraceptives due to Pop intervention being
616
+ applied."""
617
+ # TODO: remove the keys before intervention year
618
+ p_start_per_month_with_interv = {}
619
+ for year , age_method_df in p_start_per_month_without_interv .items ():
620
+ p_start_per_month_with_interv [year ] = age_method_df * self .parameters ['Interventions_Pop' ].loc [0 ]
621
+ return p_start_per_month_with_interv
622
+
623
+ def contraception_initiation_after_birth_with_interv (p_start_after_birth_without_interv ):
624
+ """Increase the probabilities of a woman starting modern contraceptives following giving birth due to PPFP
625
+ intervention being applied."""
626
+ # Exclude prob of 'not_using'
627
+ p_start_after_birth_with_interv = p_start_after_birth_without_interv .copy ().drop ('not_using' )
628
+
629
+ # Apply PPFP intervention multipliers (ie increase probs of modern methods)
630
+ p_start_after_birth_with_interv = \
631
+ p_start_after_birth_with_interv .mul (self .parameters ['Interventions_PPFP' ].loc [0 ])
632
+
633
+ # Return reduced prob of 'not_using'
634
+ p_start_after_birth_with_interv = pd .Series ((1.0 - p_start_after_birth_with_interv .sum ()),
635
+ index = ['not_using' ]).append (p_start_after_birth_with_interv )
636
+
637
+ return p_start_after_birth_with_interv
638
+
639
+ processed_params ['p_start_per_month' ] = \
640
+ contraception_initiation_with_interv (processed_params ['p_start_per_month' ])
641
+ processed_params ['p_start_after_birth_below30' ] = \
642
+ contraception_initiation_after_birth_with_interv (processed_params ['p_start_after_birth_below30' ])
643
+ processed_params ['p_start_after_birth_30plus' ] = \
644
+ contraception_initiation_after_birth_with_interv (processed_params ['p_start_after_birth_30plus' ])
729
645
730
646
return processed_params
731
647
@@ -750,7 +666,6 @@ def get_item_code_for_each_contraceptive(self):
750
666
get_items_from_pkg = self .sim .modules ['HealthSystem' ].get_item_codes_from_package_name
751
667
752
668
_cons_codes = dict ()
753
- # items for each method that requires an HSI to switch to
754
669
_cons_codes ['pill' ] = get_items_from_pkg ('Pill' )
755
670
_cons_codes ['male_condom' ] = get_items_from_pkg ('Male condom' )
756
671
_cons_codes ['other_modern' ] = get_items_from_pkg ('Female Condom' )
@@ -760,7 +675,6 @@ def get_item_code_for_each_contraceptive(self):
760
675
_cons_codes ['implant' ] = get_items_from_pkg ('Implant' )
761
676
_cons_codes ['female_sterilization' ] = get_items_from_pkg ('Female sterilization' )
762
677
assert set (_cons_codes .keys ()) == set (self .states_that_may_require_HSI_to_switch_to )
763
- # items used when initiating a modern reliable method after not using or switching from non-reliable method
764
678
_cons_codes ['co_initiation' ] = get_items_from_pkg ('Contraception initiation' )
765
679
766
680
return _cons_codes
0 commit comments