Source code for fpsim.demographics

"""
Methods and functions related to basic demographics such as urban and
age at first partnership.
"""

# %% Imports
import numpy as np  # Needed for a few things not provided by pl
import sciris as sc
import starsim as ss


# %% Deaths module
[docs] class DeathPars(ss.Pars): """ Parameters for the deaths module. """ def __init__(self, **kwargs): super().__init__(**kwargs) self.age_mortality = None self.rate_units = 1 self.rel_death = 1 self.update(kwargs) return
[docs] def make_death_pars(): """ Shortcut for making a new instance of ContraPars """ return DeathPars()
[docs] class Deaths(ss.Deaths): """ Subclass of ss.Deaths to handle FPsim's specific mortality implementation Use of this is optional, and FPsim should run with the base class as well. """ def __init__(self, pars=None, **kwargs): super().__init__() default_pars = DeathPars() self.define_pars(**default_pars) self.update_pars(pars, **kwargs) return def make_p_death(self): sim = self.sim ppl = sim.people death_rate = np.zeros(ppl.uid.raw.shape, dtype=ss.dtypes.float) ind = sc.findnearest(self.pars['age_mortality']['year'], self.t.now('year')) trend_val = self.pars['age_mortality']['probs'][ind] age_mort = self.pars['age_mortality'] f_spline = age_mort['f_spline'] * trend_val m_spline = age_mort['m_spline'] * trend_val over_one = ppl.age >= 1 female = (over_one & ppl.female).uids male = (over_one & ppl.male).uids f_ages = ppl.int_age(female) m_ages = ppl.int_age(male) death_rate[male] = m_spline[m_ages] death_rate[female] = f_spline[f_ages] death_rate *= self.pars.rate_units * self.pars.rel_death death_rate = death_rate[ppl.alive.raw] # Only apply to alive people # Scale from rate to probability death_rate = ss.peryear(death_rate) p_death = death_rate.to_prob(self.t.dt) # Convert to probability per timestep return p_death
# %% Initialization methods
[docs] def init_partnership_states(ppl): """ Initialize partnership status and expected age at first partnership by rural/urban status """ # Get init values for these sociodemographic states partnered, partnership_age = get_partnership_init_vals(ppl) # Populate states ppl.partnered = partnered ppl.partnership_age = partnership_age
[docs] def get_partnership_init_vals(ppl): """Get initial distribution of age at first partnership from location-specific data""" partnership_data = ppl.pars['age_partnership'] n = len(ppl) partnered = np.zeros(n, dtype=bool) partnership_age = np.zeros(n, dtype=float) # Get female agents indices and ages f_inds = sc.findinds(ppl.is_female) f_ages = ppl.age[f_inds] # Select age at first partnership partnership_age[f_inds] = np.random.choice(partnership_data['age'], size=len(f_inds), p=partnership_data['partnership_probs']) # Check if age at first partnership => than current age to set partnered p_inds = sc.findinds((f_ages >= partnership_age[f_inds])) partnered[f_inds[p_inds]] = True return partnered, partnership_age