V-SEIHR
Vaccinated SEIHR: a Susceptible-Exposed-Infected-Hospitalized-Recovered model with a parallel vaccinated branch. Every compartment has a _vax twin, and vaccine efficacy reduces both susceptibility (VE_S) and severity (VE_H). Pair it with the vaccination block to set vaccination rollout schedule, which adds a flow from Susceptible into Susceptible_vax compartments over a campaign window.
Compartments
The preset declares ten compartments: five clinical states, each with an unvaccinated and a vaccinated version.
- Susceptible / Susceptible_vax: can be infected; the
_vaxbranch is exposed at a reduced rate. - Exposed / Exposed_vax: infected but not yet infectious.
- Infected / Infected_vax: currently infectious. Vaccinated infectious individuals transmit at the same per-contact rate as unvaccinated; the reduction sits on susceptibility, not transmissibility.
- Hospitalized / Hospitalized_vax: severe cases under hospital care.
- Recovered / Recovered_vax: recovered and (transiently) immune; waning, if enabled, returns them to the matching susceptible compartment.
Transitions
The unvaccinated and vaccinated branches mirror each other. Vaccinated susceptibles are exposed by both Infected and Infected_vax (same per-contact rate transmission_rate, attenuated by (1 - VE_S)); the hospitalization split is attenuated by (1 - VE_H) for vaccinated infected.
| From | To | Kind | Rate |
|---|---|---|---|
Susceptible | Exposed | mediated by Infected and Infected_vax | transmission_rate |
Exposed | Infected | spontaneous | incubation_rate |
Infected | Recovered | spontaneous | (1 - hosp_proportion) * recovery_rate |
Infected | Hospitalized | spontaneous | hosp_proportion * recovery_rate |
Hospitalized | Recovered | spontaneous | hosp_recovery_rate |
Recovered | Susceptible | spontaneous | waning_rate (0 by default) |
Susceptible_vax | Exposed_vax | mediated by Infected and Infected_vax | transmission_rate_vax = (1 - VE_S) * transmission_rate |
Exposed_vax | Infected_vax | spontaneous | incubation_rate |
Infected_vax | Recovered_vax | spontaneous | (1 - hosp_proportion_vax) * recovery_rate |
Infected_vax | Hospitalized_vax | spontaneous | hosp_proportion_vax * recovery_rate where hosp_proportion_vax = (1 - VE_H) * hosp_proportion |
Hospitalized_vax | Recovered_vax | spontaneous | hosp_recovery_rate |
Recovered_vax | Susceptible_vax | spontaneous | waning_rate |
The Susceptible → Susceptible_vax flow is not part of the preset itself; it is added when the request supplies a vaccination block. Without that block the vaccinated branch stays at zero and the model behaves like plain SEIHR.
Equivalent ODE form
For each age group , the deterministic mean-field counterpart of the transitions above is:
Unvaccinated branch
Vaccinated branch
Age groups couple through the contact matrix in the force of infection:
| Symbol | Shape | Parameter |
|---|---|---|
| per-age | force of infection (depends on = transmission_rate and contact matrix ; see Vaccine efficacy) | |
| scalar | incubation_rate | |
| , | scalar | recovery_rate (in this preset the two I-exit branches share the same total rate; and are kept distinct above only to make the I → R vs I → H split explicit) |
| scalar | hosp_recovery_rate | |
| scalar | waning_rate (zero unless immunity_duration is passed) | |
| per-age | hosp_proportion | |
| per-age | per-day vaccination rate from the vaccination block; zero outside any campaign window and outside that campaign's target_age_groups | |
| , | scalar | VE_S, VE_H |
The simulator is fully stochastic: at each step every source compartment is updated by a competing-risks multinomial draw over its out-edges, with leave probability and destination weights proportional to the per-edge rates. The expected dynamics match the mean-field equations above.
Vaccine efficacy
The preset exposes two efficacy parameters, both unitless and in .
VE_S (efficacy against susceptibility) lowers the force of infection on vaccinated susceptibles, reducing their per-exposure probability of getting infected. A separate efficacy against infectiousness (VE_I) would instead reduce transmission from vaccinated infected; that is not modeled here (see the note below).
where
is the standard age-structured force of infection, is transmission_rate, and is the contact matrix from the resolved population. Vaccinated infectious individuals transmit at the same per-contact rate as unvaccinated; the reduction sits entirely on the susceptibility side. Internally, the preset stores this as the calculated parameter transmission_rate_vax = (1 - VE_S) * transmission_rate.
VE_H (efficacy against hospitalization, given infection) lowers the hospitalization split for vaccinated infected:
stored as hosp_proportion_vax = (1 - VE_H) * hosp_proportion.
Limit cases worth remembering:
- : sterilizing immunity. The vaccinated branch has zero force of infection and never sees breakthrough infections.
- : no protection against susceptibility. The vaccinated branch's transmission dynamics collapse onto the unvaccinated branch's.
- : vaccinated infected never hospitalize (); all flow through
Infected_vax → Recovered_vax. - : vaccinated infected hospitalize at the same rate as unvaccinated.
Parameters
Some parameters can be provided in multiple forms. For example, you can provide infectious_period instead of recovery_rate and it gets automatically converted. If both are sent, the rate form wins and the source is dropped silently. See calculated parameters for the conversion machinery.
| Parameter | Status | Default | Description |
|---|---|---|---|
R0 | Default | 2.5 | Basic reproduction number. |
transmission_rate | Alternative to R0 | derived | . Default: R0 * recovery_rate / CONTACT_MATRIX_EIGENVALUE_ALL. |
incubation_period | Default | 3.0 (days) | Days from exposure to infectiousness. |
incubation_rate | Alternative to incubation_period | derived | E → I rate. Default: 1 / incubation_period. |
infectious_period | Default | 2.5 (days) | Days infectious. |
recovery_rate | Alternative to infectious_period | derived | I exit rate (split into R vs H by hosp_proportion). Default: 1 / infectious_period. |
hosp_duration | Default | 5.0 (days) | Days hospitalized before recovery. |
hosp_recovery_rate | Alternative to hosp_duration | derived | H → R rate. Default: 1 / hosp_duration. |
waning_rate | Default | 0.0 (off) | R → S rate. Waning is off by default. |
immunity_duration | Alternative to waning_rate | unset | Days from R → S. Pass to enable waning via waning_rate = 1 / immunity_duration. |
hosp_proportion | Default | [0.002, 0.005, 0.015, 0.05, 0.18] | Fraction of unvaccinated Infected who progress to Hospitalized (rest go to Recovered). Age-stratified; the five-bin default aligns with the built-in population. Pass a scalar (e.g. 0.05) for homogeneous behavior, or a length-N list to match a population with a different number of age groups. |
VE_S | Default | 0.7 | Vaccine efficacy against susceptibility, in . Lowers the force of infection on vaccinated susceptibles. 0 = no protection, 1 = sterilizing. |
VE_H | Default | 0.85 | Vaccine efficacy against hospitalization given infection, in . |
The derived parameters (transmission_rate_vax, hosp_proportion_vax, I_to_R_rate, I_to_H_rate, Ivax_to_R_rate, Ivax_to_H_rate) are computed automatically from the inputs above and surface in results.parameters when output.include_parameters is set. You can override any of them by passing a matching name in parameters (user-supplied calc-params win on collision).
Examples
All examples below seed 0.1% of the population as Infected at t=0 via an explicit initial_conditions block; the rest of the population starts in Susceptible, and the _vax branch starts at zero. See Initial Conditions for other seeding options.
With a vaccination campaign
V-SEIHR with a flat-count vaccination campaign over a three-month window. VE_S and VE_H drive the protection on the vaccinated branch. See the Campaigns page for the full set of rollout options.
curl -X POST https://epyscenario-api.isi.it/api/v1/simulations \
-H "Content-Type: application/json" \
-d '{
"model": {
"preset": "V-SEIHR",
"parameters": {
"R0": 2.5,
"incubation_period": 3.0,
"infectious_period": 2.5,
"hosp_duration": 5.0,
"hosp_proportion": [0.002, 0.005, 0.015, 0.05, 0.18],
"VE_S": 0.7,
"VE_H": 0.85
}
},
"population": {"name": "United_States"},
"simulation": {"start_date": "2025-01-01", "end_date": "2025-06-30", "Nsim": 10},
"initial_conditions": {
"method": "percentage",
"initial_percentages": {"Infected": 0.1}
},
"vaccination": {
"campaigns": [
{
"start_date": "2025-02-01",
"end_date": "2025-04-30",
"rollout": {"type": "flat_count", "daily_doses": 100000}
}
]
}
}'
Without vaccination
Drop the vaccination block to get the no-intervention baseline (no vaccination rollout). The vaccinated branch stays at zero for the whole run and the model collapses to plain SEIHR (compartments and rates on the unvaccinated branch only). Useful to compare against the vaccinated case above.
curl -X POST https://epyscenario-api.isi.it/api/v1/simulations \
-H "Content-Type: application/json" \
-d '{
"model": {
"preset": "V-SEIHR",
"parameters": {
"R0": 2.5,
"incubation_period": 3.0,
"infectious_period": 2.5,
"hosp_duration": 5.0,
"hosp_proportion": [0.002, 0.005, 0.015, 0.05, 0.18]
}
},
"population": {"name": "United_States"},
"simulation": {"start_date": "2025-01-01", "end_date": "2025-06-30", "Nsim": 10},
"initial_conditions": {
"method": "percentage",
"initial_percentages": {"Infected": 0.1}
}
}'
VE_S and VE_H are omitted here because they only matter once any of the population is in the vaccinated branch; with no campaign and no seeded Susceptible_vax, their values do not affect the trajectory.
With seasonality and a vaccination campaign
Apply seasonality to transmission_rate (peak January 15, trough July 15, per the Northern Hemisphere defaults in Balcan et al., 2010) and run a pre-peak vaccination campaign in autumn so the rollout finishes just before the winter wave hits. Because transmission_rate is itself derived from R0, the seasonal multiplier is applied on top of the evaluated at each step. See parameter transforms for the full transform reference.
curl -X POST https://epyscenario-api.isi.it/api/v1/simulations \
-H "Content-Type: application/json" \
-d '{
"model": {
"preset": "V-SEIHR",
"parameters": {
"R0": 2.5,
"incubation_period": 3.0,
"infectious_period": 2.5,
"hosp_duration": 5.0,
"hosp_proportion": [0.002, 0.005, 0.015, 0.05, 0.18],
"VE_S": 0.7,
"VE_H": 0.85
}
},
"population": {"name": "United_States"},
"simulation": {"start_date": "2025-08-01", "end_date": "2026-07-31", "Nsim": 10},
"initial_conditions": {
"method": "percentage",
"initial_percentages": {"Infected": 0.1}
},
"parameter_transforms": [
{
"target_parameter": "transmission_rate",
"method": "balcan",
"max_date": "2026-01-15",
"min_date": "2026-07-15",
"min_value": 0.85
}
],
"vaccination": {
"campaigns": [
{
"start_date": "2025-10-15",
"end_date": "2025-12-31",
"rollout": {"type": "flat_count", "daily_doses": 100000}
}
]
},
"output": {"include_parameters": true}
}'