demographics
HPV-specific demographic modules.
AgeMigration pins the agent age pyramid to a target population trajectory. Sits alongside ss.Births and ss.Deaths in hpv.Sim’s default demographics list.
Algorithm — once per year: 1. Look up the target age pyramid for the current year (pop_by_age). 2. Compute scale = sim.n_agents / pop_at_sim_start (from pop_total). 3. For each (sex, integer age): count_sim = alive sim agents at this age and sex count_target = target_pyramid[sex][age] * scale diff = round(count_target - count_sim) if diff > 0: add diff immigrants at this age (HPV-naive) if diff < 0: weight-pick |diff| agents at this age and request their removal (treated as emigration)
Annual cadence is enforced by dt=ss.year in __init__: ss.Loop only fires step() at times in this module’s t.tvec, so it runs once per integer year regardless of sim.dt.
AnnualBirths uses the same annual-cadence trick to fire births once per calendar year in a single pulse.
Classes
| Name | Description |
|---|---|
| AgeMigration | Age-pyramid pinning to a target population trajectory. |
| AnnualBirths | Annual-pulse births: one birth cohort per calendar year. |
| Births | ss.Births that excludes fine multiscale agents from reproducing. |
AgeMigration
demographics.AgeMigration(
pars=None,
pop_total=None,
pop_by_age=None,
v2_compat=False,
**kwargs,
)Age-pyramid pinning to a target population trajectory.
Fires once per integer year and forces the sim’s age x sex composition to match the target pyramid by adding immigrants (HPV-naive) or requesting removal of emigrants.
Data can be supplied explicitly via pop_total / pop_by_age, or loaded automatically from the sim’s location parameter.
Parameters
| Name | Type | Description | Default |
|---|---|---|---|
| pop_total | DataFrame |
columns [year, pop_size]. If None, loaded from country data. | None |
| pop_by_age | DataFrame |
columns [year, age, male, female]. If None, loaded from country data. | None |
Methods
| Name | Description |
|---|---|
| step | Pin age x sex pyramid to the target for the current year. |
| update_results | Store immigrant/emigrant counts for this timestep. |
step
demographics.AgeMigration.step()Pin age x sex pyramid to the target for the current year.
Called once per integer year (module dt=ss.year gates firing via Loop).
update_results
demographics.AgeMigration.update_results()Store immigrant/emigrant counts for this timestep.
AnnualBirths
demographics.AnnualBirths(pars=None, **kwargs)Annual-pulse births: one birth cohort per calendar year.
Standard ss.Births distributes births evenly across all steps. This subclass fires a single birth pulse at each integer year boundary by giving the module an annual Timeline (dt=ss.year). ss.Loop then only calls step() once per calendar year, and because self.t.dt equals ss.years(1), get_births() naturally computes the full annual probability rather than a per-quarter fraction.
With dt=0.25 (4 steps per year) the total number of births over any full year is statistically identical between ss.Births (4 steps × ¼ rate) and AnnualBirths (1 step × full rate). Only the timing changes: every year’s cohort is born on the same calendar step instead of being spread across four quarterly sub-cohorts.
Opt-in only — default ss.Births behavior (continuous births) is unchanged. Activate by passing demographics=[hpv.AnnualBirths(...), ...] to hpv.Sim.
Parameters
| Name | Type | Description | Default |
|---|---|---|---|
| birth_rate | birth rate data passed through to ss.Births. |
required | |
| kwargs | forwarded to ss.Births.__init__. |
{} |
Example::
import hpvsim as hpv
import starsim as ss
sim = hpv.Sim(
location='nigeria',
demographics=[
hpv.AnnualBirths(),
ss.Deaths(),
hpv.AgeMigration(),
],
)
sim.run()
Births
demographics.Births()ss.Births that excludes fine multiscale agents from reproducing.
Births are an independent per-agent Bernoulli, so dropping fine agents from the drawn birth_uids is statistically identical to excluding them from the eligible pool; only non-fine (level0) agents reproduce.