Skip to content

AI-generated content

This chapter was automatically generated by an AI agent and has not been reviewed by a human. Read with caution.

Viruses, Tools, and Global Events

This chapter covers the three main mechanisms for injecting behavior into an epiworld simulation beyond state definitions: viruses, tools, and global events.

Viruses

A Virus represents a disease agent that can spread between agents. Creating one involves setting its name, an initial prevalence (or explicit distribution function), and configuring its epidemiological properties.

Creating a Virus

epiworld::Virus<> flu("Influenza", 0.01, true);
flu.set_prob_infecting(0.3);     // Per-contact transmission probability
flu.set_prob_recovery(0.14);     // Daily recovery probability
flu.set_prob_death(0.001);       // Daily mortality probability
flu.set_post_immunity(1.0);      // Probability of immunity after recovery

// Link the virus to model states
flu.set_state(
    infected_state_id,   // State when virus is acquired
    recovered_state_id,  // State after recovery
    removed_state_id     // State on death
);

model.add_virus(flu);
flu <- virus("Influenza", prevalence = 0.01, as_proportion = TRUE)
set_prob_infecting(flu, 0.3)
set_prob_recovery(flu, 0.14)
set_prob_death(flu, 0.001)
add_virus(model, flu)

Virus Distribution

By default, Virus(name, prevalence, as_proportion) seeds the virus uniformly at random. You can supply a custom distribution function for more control:

virus.set_distribution(
    epiworld::distribute_virus_randomly<>(50, false) // 50 agents, not proportion
);

Mutation

Viruses can mutate, creating new variants with altered sequences:

EPI_NEW_MUTFUN(my_mutation, int) {
    if (EPI_RUNIF() < m->par("Mutation rate")) {
        auto seq = *v.get_sequence();
        int idx = std::floor(EPI_RUNIF() * seq.size());
        seq[idx] = !seq[idx];
        v.set_sequence(seq);
        return true;  // Mutation occurred
    }
    return false;
}

virus.set_mutation(my_mutation);

For more on virus and tool distribution strategies see Virus and Tool Distribution.

Tools

A Tool modifies how an agent interacts with the disease process. Common examples include vaccines, masks, and the innate immune system.

Creating a Tool

epiworld::Tool<> vaccine("Vaccine", 0.5, true);
vaccine.set_susceptibility_reduction(0.90);  // 90% reduction
vaccine.set_transmission_reduction(0.50);     // 50% reduction in onward transmission
vaccine.set_recovery_enhancer(0.40);          // 40% boost to recovery
vaccine.set_death_reduction(0.99);            // 99% reduction in mortality

model.add_tool(vaccine);
vax <- tool("Vaccine", prevalence = 0.5, as_proportion = TRUE)
set_susceptibility_reduction(vax, 0.90)
set_transmission_reduction(vax, 0.50)
set_recovery_enhancer(vax, 0.40)
set_death_reduction(vax, 0.99)
add_tool(model, vax)

How Tools Affect Transmission

When a susceptible agent \(i\) is exposed to virus \(v\) from infected agent \(j\), the transmission probability is:

\[ P(\text{Virus } v) = P_v \times (1 - C_r) \times (1 - T_r) \]

where \(P_v\) is the virus's base transmissibility, \(C_r\) is the contagion reduction from \(i\)'s tools, and \(T_r\) is the transmission reduction from \(j\)'s tools. See Contagion for the full mathematical formulation.

Global Events

Global events are model-wide functions that execute at specified times during the simulation. They are useful for implementing interventions, collecting statistics, or modifying parameters mid-run.

Defining a Global Event

A global event is a function with the signature void fun(Model<TSeq>* model):

template<typename TSeq>
void lockdown_event(epiworld::Model<TSeq>* model) {
    double tr = model->par("Transmission rate");
    model->set_param("Transmission rate", tr * 0.5);
}

// Execute on day 30:
model.add_globalevent(lockdown_event<>, "Lockdown", 30);

// Or execute every day (date = -1):
model.add_globalevent(some_daily_event<>, "Daily check", -1);

Example: Introducing a New Variant Mid-Simulation

template<typename TSeq>
void new_variant(epiworld::Model<TSeq>* model) {
    epiworld::Virus<TSeq> variant("Variant B", 0.001, true);
    variant.set_prob_infecting(0.5);
    model->add_virus(variant);
}

model.add_globalevent(new_variant<>, "Introduce Variant B", 60);

Custom Data Collection

The model includes a lightweight user data table that global events can write to. This is handy for recording custom statistics at each time step:

// Declare columns
model.set_user_data({"Prevalence"});

template<typename TSeq>
void record_prevalence(epiworld::Model<TSeq>* model) {
    int infected = 0;
    for (auto& agent : model->get_agents())
        if (agent.get_status() == model->get_state_id("Infected"))
            infected++;
    model->add_user_data(
        0, static_cast<double>(infected) / model->size()
    );
}

model.add_globalevent(record_prevalence<>, "Daily prevalence", -1);

After the simulation you can retrieve or write the data:

model.get_user_data().print();
model.get_user_data().write("prevalence.txt");

What's Next

  • Built-in Models — See how viruses, tools, and events are combined in the library's pre-built models.
  • Examples — Runnable code samples that put these concepts into practice.
  • Data Collection and Analysis — Advanced strategies for recording simulation output.