Skip to main content

library.mnch

library.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.

Used with: agents; coded modules

Classes

Name Description
CongenitalDisease Simple disease with congenital outcomes, scheduled around delivery
FetalHealth Track fetal health outcomes during pregnancy.
NeonatalSepsis Minimal neonatal sepsis model.
PregnancyTreatment What treat_pregnant delivers: a cure of the infection, and a partial reversal of the fetal damage
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, scheduled around delivery

Infected mothers transmit to their unborn via PrenatalNet. At transmission, set_congenital() samples an outcome (stillborn, congenital, normal) and schedules it for delivery time. step_congenital() in step_state() executes those scheduled events.

Note: CRN safe.

Parameters

Name Type Description Default
birth_outcome_keys list outcome names — each needs a ti_<key> state
birth_outcomes objdict ss.choice distributions keyed by category; use ‘default’ for a single distribution applied to all infections
pars dict the same parameters, as a dict None

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

Methods

Name Description
set_congenital Assign congenital outcomes during in-utero infection (called when
step_congenital Execute scheduled congenital events whose ti_<key> has arrived.
set_congenital
library.mnch.CongenitalDisease.set_congenital(target_uids, sources=None)

Assign congenital outcomes during in-utero infection (called when transmission occurs via PrenatalNet).

Does nothing unless the disease defines birth_outcome_keys and birth_outcomes in its pars. Diseases that need fully custom logic (e.g. syphilis, which has stage-dependent outcomes) can override this method entirely.

To use it, define in the disease’s __init__:

self.define_pars(
    birth_outcome_keys = ['stillborn', 'congenital', 'normal'],
    birth_outcomes     = sc.obj(default=ss.choice(a=3, p=[0.3, 0.4, 0.3])),  # Illustrative placeholder
)

Each outcome name needs a matching ti_<name> FloatArr state; non-lethal outcomes also need a BoolArr of the same name. Death outcomes (‘miscarriage’, ‘neonatal_death’, ‘stillborn’) fire via request_death; others set a bool state.

Outcomes are scheduled for the mother’s delivery timestep, except for fetal losses (‘miscarriage’, ‘stillborn’), which are scheduled one timestep earlier so that they occur before the fetus is delivered and are classified as fetal losses rather than neonatal deaths. A fetus infected within one timestep of delivery is therefore born alive, and a lethal outcome for it counts as a neonatal death.

For state- or GA-dependent probabilities, provide multiple keyed distributions in birth_outcomes and override _assign_congenital_outcomes.

Call step_congenital from the disease’s step_state() to execute the scheduled events each timestep.

Parameters
Name Type Description Default
target_uids array the unborn agents infected, by their mothers (people.parent), over ss.PrenatalNet required
sources array who infected them (their mothers), if known; not used here None
step_congenital
library.mnch.CongenitalDisease.step_congenital()

Execute scheduled congenital events whose ti_<key> has arrived.

Does nothing unless the disease defines birth_outcome_keys in its pars. Call from the disease’s step_state(); see set_congenital for setup details.

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 its callbacks (add_callback()): Pregnancy calls on_conception when new pregnancies begin and on_delivery when births occur. External modules (e.g. disease connectors) can register their own on preg.conception, after this module’s, 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 the delivery (`ti_exit_P`) forward (preterm birth risk)
2. **Growth restriction**: accumulate fractional weight reduction

At delivery: birth_weight = baseline_for_GA × percentile × (1 - restriction)

The results are counts of births and outcomes on each step, and means and rates over a step’s births (mean_birth_weight, lbw_rate, …), which are NaN on a step with no births, and are left out of a mean over time (e.g. res.mean_birth_weight.resample('year')).

Note: CRN safe.

Parameters

Name Type Description Default
weight_by_ga array Nx2 array of [gestational_age_weeks, weight_grams]
interp_fn callable interpolation function with signature (x, xp, fp) -> array (default np.interp)
sga_ratio float fraction of GA-appropriate weight below which SGA is declared
lbw_threshold float birth weight in grams below which LBW is declared
vlbw_threshold float birth weight in grams below which VLBW is declared
min_ga dur floor for timing shifts (delivery can’t be brought before this GA)
percentile_dist Dist distribution for baseline fetal weight percentile
pars dict the same parameters, as a dict None

Examples

import starsim as ss
import starsim.library as ssl

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
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.
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.

Parameters
Name Type Description Default
uids array the mother of each newborn required
Returns
Name Type Description
tuple (birth_weights, ga_weeks) arrays
init_pre
library.mnch.FetalHealth.init_pre(sim)

Register callbacks with the Pregnancy module

Parameters
Name Type Description Default
sim Sim the sim being initialized required
on_conception
library.mnch.FetalHealth.on_conception(uids)

Initialize fetal health for new pregnancies (called by Pregnancy)

Parameters
Name Type Description Default
uids array the women who conceived required
on_delivery
library.mnch.FetalHealth.on_delivery(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.

Parameters
Name Type Description Default
newborn_uids array the newborns required
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 p_at_birth, then kills a fraction (p_death) within a short window (dur_inf). Useful for testing passive neonatal death detection in the Pregnancy module.

Note: CRN safe.

Parameters

Name Type Description Default
beta float transmission rate — set to 0 since infection is only at birth
p_at_birth Dist fraction of newborns infected at birth
init_prev Dist fraction of the people at the start who are infected (none by default)
dur_inf Dist time from infection to death (for those who die)
p_death Dist case fatality rate among infected neonates
pars dict the same parameters, as a dict None

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 (e.g. via init_prev at sim start) just recover normally via the base SIR logic.

Parameters
Name Type Description Default
uids array the agents infected required
sources array the agents who infected them None
step
library.mnch.NeonatalSepsis.step()

Infect newly born agents.

Newborns are infected explicitly, each with p_at_birth. Each agent is screened once, the first timestep after they are born.

PregnancyTreatment

library.mnch.PregnancyTreatment(delivery, **kwargs)

What treat_pregnant delivers: a cure of the infection, and a partial reversal of the fetal damage

fetal_infection

library.mnch.fetal_infection(pars=None, **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 the pregnancy, after FetalHealth’s). 2. During pregnancy, when a new infection occurs (detected in step() by checking ti_infected == self.ti - 1, since transmission happens after connectors).

Requires ssl.mnch.FetalHealth() in modules and an SIR disease written as code (ssl.AgentSIR(name="sir")) in diseases.

Note: CRN safe.

Parameters

Name Type Description Default
timing_shift Dist weeks to shift delivery forward per infection (default: lognormal mean=3, std=1)
growth_penalty float fractional birth weight reduction per infection (default: 0.15 = 15%)
pars dict the same parameters, as a dict None

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.fh
        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)
        ...

Attributes

Name Description
fh Shortcut to the FetalHealth module

Methods

Name Description
init_post Register a callback so we can apply damage at conception for women who are already infected when they become pregnant: after FetalHealth’s (registered in its init_pre()), which sets the baseline
init_pre Check that the sim has what the connector needs
step Each timestep, check for new infections in pregnant women and apply damage
init_post
library.mnch.fetal_infection.init_post()

Register a callback so we can apply damage at conception for women who are already infected when they become pregnant: after FetalHealth’s (registered in its init_pre()), which sets the baseline

init_pre
library.mnch.fetal_infection.init_pre(sim)

Check that the sim has what the connector needs

Parameters
Name Type Description Default
sim Sim the sim being initialized required
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',
    coverage=0.9,
    who=None,
    when=None,
    growth_reversal=0.7,
    timing_reversal=0.7,
    name=None,
    **kwargs,
)

Treat infected pregnant women and partially reverse fetal damage.

A delivery, as ss.treat() is: by default each pregnant woman infected with the target disease is offered treatment once, with the probability coverage. Treatment cures the infection, and reverses a fraction of the fetal damage accumulated so far (growth restriction and timing shift). who= restricts who among them is offered it, and when= when, as for any delivery (e.g. when=ss.schedule(start=2025)).

Note: CRN safe.

Parameters

Name Type Description Default
disease str name of the target disease (default: ‘sir’), written as code (e.g. ssl.AgentSIR) 'sir'
coverage float the probability that each woman eligible is treated 0.9
who Cond / func who among the infected pregnant women is offered it None
when various when it is offered, as for any delivery (default: on every step, once to each woman when she becomes eligible) None
growth_reversal float the fraction of the growth restriction reversed (0-1) 0.7
timing_reversal float the fraction of the timing shift reversed (0-1) 0.7
kwargs dict passed to ss.Delivery (e.g. capacity=, name=)

Attributes

Name Type Description
ti_treated FloatArr timestep when each agent was treated

Example — treatment from 2025, of half the women eligible::

ssl.mnch.treat_pregnant(disease='sir', start=2025, coverage=0.5)

Methods

Name Description
eligible The pregnant women infected with the disease
init_pre Check that the sim has the disease and ssl.mnch.FetalHealth
eligible
library.mnch.treat_pregnant.eligible(sim)

The pregnant women infected with the disease

init_pre
library.mnch.treat_pregnant.init_pre(sim)

Check that the sim has the disease and ssl.mnch.FetalHealth

Parameters
Name Type Description Default
sim Sim the sim being initialized required