Skip to content

Latest commit

 

History

4 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

laser-dengue

Four cocirculating dengue serotypes with per-agent history tracking and antibody-dependent enhancement (ADE), on a spatial 5×5 grid with vital dynamics. Reproduces the empirically observed serotype rotation pattern: each serotype dominates for a period, then another takes over.

Status: prototype; not calibrated to any real-world dataset. Parameters were chosen from published dengue literature (Wearing-Rohani 2006, Ferguson 1999, Adams 2006, Reich 2013), then subjected to a 1D per-parameter sensitivity sweep — see sensitivity/SENSITIVITY.md.

What this model shows

Four cocirculating dengue serotypes with per-agent history tracking and antibody-dependent enhancement (ADE) reproduce the empirically observed "serotype rotation" pattern.

Per-agent state:

  • history (uint8) — bitmask of past serotype exposures (bit k = had DENVk+1)
  • current_st (int8) — serotype currently active in E or I (-1 if none)
  • is_secondary (uint8) — 1 if this infection is at least the second distinct-serotype exposure

Transmission dynamics (per serotype k):

λ_k(t) = β · seas(t) · (IPrim_k + φ · ISec_k) / N

IPrim_k = count of DENV-k infections in previously naïve hosts. ISec_k = count of DENV-k infections in hosts with prior heterotypic exposure. Secondary infections are φ=2× more infectious (ADE).

Once infected with DENV-k, an agent goes E → I → R. In R, cross-protection against all four serotypes decays over ~CROSS_IMMUNITY_DAYS. On waning, the agent returns to S — but their history mask permanently excludes DENV-k. Four exposures → superimmune.

Gallery

Laos (admin-1, 17 provinces + Vientiane Prefecture, ~7.27M population, 20-year run)

Real-geography demonstration on Laos' 18 admin-1 units (17 provinces plus the Vientiane Prefecture). Boundaries come from GADM and populations from WorldPop 2020 via the laser-init microservices; the cached responses ship under laser_dengue/data/laos/ so the runner works fully offline.

All 4 DENV serotypes cocirculate in the Greater Mekong Subregion (Wangdi et al 2019). The central-south Mekong corridor (Vientiane → Savannakhét → Champasak) is the highest-burden zone; northern mountainous provinces are lower burden but not free of transmission. Serotypes are staggered across four corridor provinces in year 1, matching the historical pattern in which each serotype tends to enter via a different border crossing / trade route. Not calibrated to Laos-specific case data.

dengue on Laos — 20y run, 18 admin-1 units, staggered DENV1-4 introductions

Six panels: per-serotype aggregate active-I over time; total-N growth; per-serotype daily incidence (90-day smoothed, log-y); cumulative-infections-per-capita choropleth at end; dominant-serotype-per-province choropleth at end; host-exposure histogram (fraction of living hosts with 0/1/2/3/4 distinct serotypes in history).

Animations:

Runtime is heavier than the synthetic grid — ~15-20 min for a full 20-year Laos run at 7.27M agents.

Synthetic 5×5 grid (25-patch, ~210k population, 40-year run)

Same model on a synthetic 5×5 grid. Useful for isolating rotation dynamics without the confound of real-geography population imbalances.

dengue rotation — 40y run over a 5×5 grid with vital dynamics

Cummings et al 2009 documented multi-year serotype rotation in Thailand from 1980 to 2000, with each serotype dominant for 2-6 years. The simulation shows the same qualitative pattern; the sensitivity analysis quantifies which parameters most control rotation frequency, coexistence, and secondary-infection burden.

Install + run

pip install .[geo]      # Laos runner needs geopandas + shapely + requests
python -c "from laser_dengue.run_laos import run_laos; r = run_laos({'YEARS': 3}, verbose=True); print(len(r['scenario']))"

Or as scripts:

laser-dengue-laos --years 20 --out out_laos.png    # real Laos geography (~15-20 min)
laser-dengue      --years 20 --seed 42               # synthetic 5×5 grid

Public API

from laser_dengue import DEFAULTS, run_model, metrics

result = run_model(overrides={"PHI_ADE": 2.5, "YEARS": 30}, verbose=True)
model = result["model"]              # laser-generic Model instance
print(metrics(result))

Unknown keys in overrides raise KeyError early. metrics extracts six outcome scalars used by the sensitivity harness: rotation-transition count, all-4-serotype coexistence-year fraction, secondary-infection fraction over the last 5 years, endemic prevalence at the final tick, superimmune-host fraction, and final total N.

Parameter table

From published dengue literature; not calibrated to any specific dataset. See sensitivity/SENSITIVITY.md for the per-parameter perturbation study.

symbol value source / justification
R0_PRIMARY 2.5 Wearing-Rohani 2006
PHI_ADE 2.0 Ferguson 1999; Adams 2006 report 1.5-3×
EXP_SCALE_DAYS 5 d E period (incubation); Wearing-Rohani 2006
INF_SCALE_DAYS 5 d I period (viremic); Wearing-Rohani 2006
CROSS_IMMUNITY_DAYS 200 d Reich et al 2013 (2 yr in some, less in others)
SEASONALITY_AMP 0.35 annual sinusoid; Adams 2006
BACKGROUND_COUNT 3 cases per background-import event (random serotype); numerical hack that prevents stochastic extinction
BACKGROUND_PERIOD 90 d period between background-import events
CBR 22/1000/yr dengue-endemic tropics
CDR 8/1000/yr net +1.4%/yr population growth
GRID_M × GRID_N 5×5 = 25 patches urban core (40k), ring (15k each), rural periphery (4k each)
YEARS 40 enough to see rotation stabilize
SEED 20260710

Sensitivity

A 1D per-parameter perturbation study (±30% around each science parameter, three stochastic seeds per cell, 20-year sims) landed alongside this repo — see sensitivity/SENSITIVITY.md for the tornado charts and per-parameter interpretation. Rerun the sweep with:

python -m sensitivity.sensitivity --years 20 --seeds 3 --workers 1
python -m sensitivity.make_tornado

Why this is interesting

  • Per-agent state is essential. Compartmental dengue models need to track the joint distribution over exposure histories: 2⁴ = 16 compartments per serotype (susceptible, monotypic-immune to k, etc.), × 4 SEIR states, × 25 patches = 2 000 compartments. The ABM carries the 4-bit history in a single uint8.
  • Serotype replacement dynamics are a real observation. Cummings et al 2009 documented multi-year serotype rotation in Thailand from 1980 to 2000, with each serotype dominant for 2-6 years.
  • ADE as a transmission multiplier — the "vertical" ADE hypothesis (Ferguson 1999). The alternative ("severity" ADE, where φ only affects DHF outcome not transmission) doesn't produce rotation as easily. Adams et al 2006 argued for transmission-side ADE from Thai case-notification data.
  • Vital dynamics are load-bearing. A single-node closed-population version burns out by year 10; adding births refills the susceptible pool for serotypes that had run out and lets rotation persist indefinitely.

Extensions

  • DHF risk tracking — every secondary infection has ~3-5× higher risk of Dengue Hemorrhagic Fever; track a hospitalization/mortality counter over is_secondary==1 transitions.
  • Vector compartment (mosquitoes) — replace β with a two-population coupling; humans⇔mosquitoes, mosquito EIP ~10 days, lifespan ~14 days. See Ferguson 1999 for the full Ross-Macdonald form.
  • Vaccination (Dengvaxia-style) — asymmetric efficacy: high in seropositives, low or negative in seronegatives. Requires per-agent vaccine-status × history-bitmask interaction.
  • More country runners — the Laos runner is a template. Adding e.g. Thailand (THA), Vietnam (VNM), or Cambodia (KHM) at admin-1 is a _laser_init.load_real_scenario("<ISO>", level=1, year=2020) call plus setting SEED_SCHEDULE to the country's likely-introduction corridor.

References

  • Ferguson NM, Anderson RM, Gupta S. 1999. The effect of antibody-dependent enhancement on the transmission dynamics and persistence of multiple-strain pathogens. Phil Trans R Soc B 354:757-768.
  • Adams B et al. 2006. Cross-protective immunity can account for the alternating epidemic pattern of dengue virus serotypes circulating in Bangkok. PNAS 103:14234-14239.
  • Wearing HJ, Rohani P. 2006. Ecological and immunological determinants of dengue epidemics. PNAS 103:11802-11807.
  • Cummings DA et al. 2009. The impact of the demographic transition on dengue in Thailand. PLoS Med 6:e1000139.
  • Reich NG et al. 2013. Interactions between serotypes of dengue. J R Soc Interface 10:20130414.

Implementation notes

  • additional_states=["E0","I0","IPrim0","ISec0", ..., "ISec3"] registers 16 extra per-node vector properties so _initialize_flows propagates X[t] → X[t+1] for each. Missing this step is the bug the fork's author hit first — per-tick delta updates get overwritten and transmission never takes off.
  • DengueTransmission iterates over serotypes in random order each tick to avoid biasing which serotype "wins" if two would happen to hit the same agent on the same tick.
  • The SerotypeImportation component supports both a fixed schedule (initial seeding) and continuous background importation to prevent stochastic extinction of low-prevalence serotypes.
  • Cross-protection is stored per-agent as rtimer (uint16). Agents whose cross-protection wanes but who have all 4 serotypes in history stay in R permanently — checked in DengueWaning.step.
  • DengueSerotypeAwareMortality wraps laser-generic's MortalityByCDR to snapshot per-agent current_st / is_secondary before mortality runs, then patch per-serotype compartments (E{k}, I{k}, IPrim{k}, ISec{k}) so the sub-compartments stay consistent when infected agents die.

About

Dengue 4-serotype ABM with antibody-dependent enhancement (ADE), reproducing serotype rotation.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages