mnch
Maternal, newborn, and child health (MNCH) example modules.
Demonstrates how to model congenital infection, neonatal mortality, and fetal health outcomes on top of ss.Pregnancy and ss.PrenatalNet. See the folder README for a walkthrough of how these modules fit together.
Classes
| Name | Description |
|---|---|
| CongenitalDisease | Simple disease with congenital outcomes via the generic framework. |
| FetalHealth | Track fetal health outcomes during pregnancy. |
| NeonatalSepsis | Minimal neonatal sepsis model. |
| fetal_infection | Connect a disease to fetal health outcomes during pregnancy. |
| treat_pregnant | Treat infected pregnant women and partially reverse fetal damage. |
CongenitalDisease
library.mnch.CongenitalDisease(pars=None, **kwargs)Simple disease with congenital outcomes via the generic framework.
Infected mothers transmit to their unborn via PrenatalNet. At transmission, the base set_congenital() samples an outcome (stillborn, congenital, normal) and schedules it for delivery time. step_congenital() in step_state() executes those scheduled events.
Parameters
| Name | Type | Description | Default |
|---|---|---|---|
| birth_outcome_keys | list | outcome names — each needs a ti_<key> state |
required |
| birth_outcomes | objdict |
ss.choice distributions keyed by category; use ‘default’ for a single distribution applied to all infections |
required |
Attributes
| Name | Type | Description |
|---|---|---|
| ti_stillborn | FloatArr | timestep when stillbirth fires (triggers request_death) |
| ti_congenital | FloatArr | timestep when congenital infection fires (sets BoolArr) |
| ti_normal | FloatArr | timestep when normal outcome fires (no effect) |
| congenital | BoolArr | True if agent has congenital infection |
| cs_outcome | FloatArr | index into birth_outcome_keys for each agent |
FetalHealth
library.mnch.FetalHealth(pars=None, **kwargs)Track fetal health outcomes during pregnancy.
Works alongside the Pregnancy module to model birth weight outcomes (low birth weight, small for gestational age) based on fetal growth restriction. Disease-agnostic by design: external modules (connectors, interventions) modify fetal health via the public API methods.
Preterm classification is handled by the Pregnancy module (based on gestational age at birth). This module focuses on the weight/growth axis.
Integrates with Pregnancy via callbacks: Pregnancy calls on_conception when new pregnancies begin and on_delivery when births occur. External modules (e.g. disease connectors) can register their own callbacks via add_conception_callback to act on new pregnancies after baseline initialization.
During pregnancy, weight_percentile, growth_restriction, timing_shift, and n_exposures are tracked on the mother. At delivery, birth_weight, lbw, vlbw, and sga are stored on the newborn.
Each pregnancy gets a baseline weight percentile drawn at conception. Two modification levers are available:
1. **Delivery timing**: bring `ti_delivery` forward (preterm birth risk)
2. **Growth restriction**: accumulate fractional weight reduction
At delivery: birth_weight = baseline_for_GA × percentile × (1 - restriction)
Parameters
| Name | Type | Description | Default |
|---|---|---|---|
| weight_by_ga | array | Nx2 array of [gestational_age_weeks, weight_grams] | required |
| interp_fn | callable | interpolation function with signature (x, xp, fp) -> array (default np.interp) | required |
| sga_ratio | float | fraction of GA-appropriate weight below which SGA is declared | required |
| lbw_threshold | float | birth weight in grams below which LBW is declared | required |
| vlbw_threshold | float | birth weight in grams below which VLBW is declared | required |
| min_ga | dur | floor for timing shifts (delivery can’t be brought before this GA) | required |
| percentile_dist | Dist | distribution for baseline fetal weight percentile | required |
Examples
import starsim as ss
sim = ss.Sim(
demographics=[ss.Pregnancy(fertility_rate=10), ss.Deaths(death_rate=10)],
modules=ssl.mnch.FetalHealth(),
networks=ss.PrenatalNet(),
)
sim.run()Methods
| Name | Description |
|---|---|
| add_conception_callback | Register a function to be called when new pregnancies are detected. |
| apply_growth_restriction | Apply fractional growth restriction (cumulative, diminishing). |
| apply_timing_shift | Bring delivery forward for pregnant women. |
| compute_birth_weight | Compute birth weight at delivery. |
| init_pre | Register callbacks with the Pregnancy module |
| on_conception | Initialize fetal health for new pregnancies (called by Pregnancy) |
| on_delivery | Classify birth outcomes (called by Pregnancy). |
| reverse_growth_restriction | Reverse a specific amount of growth restriction. |
| reverse_timing_shift | Recover a fraction of the accumulated delivery timing shift. |
add_conception_callback
library.mnch.FetalHealth.add_conception_callback(fn)Register a function to be called when new pregnancies are detected. The function receives (uids,) after baseline initialization.
apply_growth_restriction
library.mnch.FetalHealth.apply_growth_restriction(uids, penalty)Apply fractional growth restriction (cumulative, diminishing).
Positive penalties use diminishing returns: current + (1-current) * penalty. Negative penalties (growth boost, e.g. GDM macrosomia) are additive.
Parameters
| Name | Type | Description | Default |
|---|---|---|---|
| uids | UIDs of pregnant women | required | |
| penalty | float | fractional weight reduction; negative = growth boost | required |
apply_timing_shift
library.mnch.FetalHealth.apply_timing_shift(uids, shift_weeks)Bring delivery forward for pregnant women.
Uses a one-way ratchet: delivery can only be brought forward, never pushed back. The actual shift applied is tracked in timing_shift.
Parameters
| Name | Type | Description | Default |
|---|---|---|---|
| uids | UIDs of pregnant women | required | |
| shift_weeks | float / array | shift in weeks; positive = earlier delivery | required |
compute_birth_weight
library.mnch.FetalHealth.compute_birth_weight(uids)Compute birth weight at delivery.
Override this method to customize the birth weight formula. The interpolation function can be swapped via pars.interp_fn.
Returns
| Name | Type | Description |
|---|---|---|
| tuple | (birth_weights, ga_weeks) arrays |
init_pre
library.mnch.FetalHealth.init_pre(sim)Register callbacks with the Pregnancy module
on_conception
library.mnch.FetalHealth.on_conception(uids)Initialize fetal health for new pregnancies (called by Pregnancy)
on_delivery
library.mnch.FetalHealth.on_delivery(mother_uids, newborn_uids)Classify birth outcomes (called by Pregnancy).
Birth weight is computed from the mother’s pregnancy-time states (weight_percentile, growth_restriction). Outcomes (birth_weight, lbw, vlbw, sga) are stored on the newborn agents.
reverse_growth_restriction
library.mnch.FetalHealth.reverse_growth_restriction(uids, amount)Reverse a specific amount of growth restriction.
Parameters
| Name | Type | Description | Default |
|---|---|---|---|
| uids | UIDs of pregnant women | required | |
| amount | float / array | amount to reverse | required |
reverse_timing_shift
library.mnch.FetalHealth.reverse_timing_shift(uids, fraction)Recover a fraction of the accumulated delivery timing shift.
Parameters
| Name | Type | Description | Default |
|---|---|---|---|
| uids | UIDs of pregnant women | required | |
| fraction | float / array | fraction to recover (0-1) | required |
NeonatalSepsis
library.mnch.NeonatalSepsis(pars=None, **kwargs)Minimal neonatal sepsis model.
Infects newborns at birth with probability init_prev, then kills a fraction (p_death) within a short window (dur_inf). Useful for testing passive neonatal death detection in the Pregnancy module.
Parameters
| Name | Type | Description | Default |
|---|---|---|---|
| beta | float | transmission rate — set to 0 since infection is only at birth | required |
| init_prev | Dist | fraction of newborns infected at birth | required |
| dur_inf | Dist | time from infection to death (for those who die) | required |
| p_death | Dist | case fatality rate among infected neonates | required |
Methods
| Name | Description |
|---|---|
| init_post | Exempt the initial population from being treated as newborns |
| set_prognoses | Set prognoses — only apply lethal outcomes to neonates (age < 28 days). |
| step | Infect newly born agents. |
init_post
library.mnch.NeonatalSepsis.init_post()Exempt the initial population from being treated as newborns
set_prognoses
library.mnch.NeonatalSepsis.set_prognoses(uids, sources=None)Set prognoses — only apply lethal outcomes to neonates (age < 28 days).
Non-neonates who get infected (via init_prev at sim start) just recover normally via the base SIR logic.
step
library.mnch.NeonatalSepsis.step()Infect newly born agents.
init_prev only seeds the initial population, so newborns have to be infected explicitly. Each agent is screened once, the first timestep after they are born.
fetal_infection
library.mnch.fetal_infection(**kwargs)Connect a disease to fetal health outcomes during pregnancy.
Monitors for infections in pregnant women and applies fetal damage: - Timing shift: brings delivery forward (increases preterm birth risk). Drawn from a lognormal distribution per affected pregnancy. - Growth restriction: reduces birth weight by a fixed fractional penalty.
Damage is applied at two points: 1. At conception, if the mother is already infected (via a conception callback registered with FetalHealth). 2. During pregnancy, when a new infection occurs (detected in step() by checking ti_infected == self.ti).
Requires ssl.mnch.FetalHealth() in custom and an SIR disease in diseases.
Parameters
| Name | Type | Description | Default |
|---|---|---|---|
| timing_shift | Dist | weeks to shift delivery forward per infection (default: lognormal mean=3, std=1) | required |
| growth_penalty | float | fractional birth weight reduction per infection (default: 0.15 = 15%) | required |
To adapt for a different disease::
class my_fetal_connector(fetal_infection):
def init_pre(self, sim):
# Register with FetalHealth, but check for your disease instead
...
def _apply_damage(self, uids):
# Custom damage logic, e.g. stage-dependent penalties
fh = self.sim.custom['fetal_health']
disease = self.sim.diseases.my_disease
severe = disease.severe[uids]
mild_uids = uids[~severe]
severe_uids = uids[severe]
fh.apply_growth_restriction(mild_uids, 0.05)
fh.apply_growth_restriction(severe_uids, 0.25)
...
Methods
| Name | Description |
|---|---|
| step | Each timestep, check for new infections in pregnant women and apply damage |
step
library.mnch.fetal_infection.step()Each timestep, check for new infections in pregnant women and apply damage
treat_pregnant
library.mnch.treat_pregnant(
disease='sir',
start_year=None,
end_year=None,
**kwargs,
)Treat infected pregnant women and partially reverse fetal damage.
Each timestep, identifies pregnant women infected with the target disease, treats a fraction of them (curing infection), and reverses a portion of the accumulated fetal damage (growth restriction and timing shift).
Treatment only applies between start_year and end_year. If not specified, defaults to the full simulation period.
Parameters
| Name | Type | Description | Default |
|---|---|---|---|
| disease | str | name of the target disease (default: ‘sir’) | 'sir' |
| start_year | float | first year treatment is available (default: sim start) | None |
| end_year | float | last year treatment is available (default: sim end) | None |
| p_treat | Dist | par: probability of treating an eligible woman per timestep | required |
| tx_growth_reversal | float | par: fraction of growth restriction to reverse (0-1) | required |
| tx_timing_reversal | float | par: fraction of timing shift to reverse (0-1) | required |
Attributes
| Name | Type | Description |
|---|---|---|
| ti_treated | FloatArr | timestep when each agent was treated |
Example — treatment starting in 2025 with 50% coverage::
ssl.mnch.treat_pregnant(disease='sir', start_year=2025, p_treat=ss.bernoulli(p=0.5))