Skip to content

Commit

Permalink
Added overview paragraph with pseudocode for each module
Browse files Browse the repository at this point in the history
  • Loading branch information
confunguido committed Aug 16, 2024
1 parent 7b9eeca commit aa2fb86
Showing 1 changed file with 90 additions and 56 deletions.
146 changes: 90 additions & 56 deletions examples/basic_infection/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,81 +18,115 @@ The first infection attempt is scheduled at time 0. Infection events are schedul
Infected individuals schedule their recovery at time `t + infected period`. The infection status of recovered individuals remains as recovered for the rest of the simulation.

### Infection state transitions
```mermaid
flowchart LR
S(Susceptible) --FoI--> I(Infected) --inf. period--> R(Recovered)
```
## Simulation architecture
The simulation executaion first initializes the model parameters and prepares the simulation modules.

### Initialization and modules
## Main simulation
The simulation is set and run by a main simulation routine. The main routine loads the required modules and executes the simulation. The first module to be loaded is the parameters modul. Then, the population manager creates a population of individuals with unique person ids and a person property determining their infection status, which is initially set as Susceptible. After the population is created, the transmission manager module is loaded. In the transmission manager, new infections occur at a rate determined by a constant force of infection, which doesn't require interactions among individuals (e.g., food-borne disease). The transmission manager is initialized by creating a new random generator number for transmission events and scheduling an infection attempt on day 0. Each infection attempt selects a random person in the population. This random person is only infected if its current infection status is Susceptible. After an infection attempt is made, a new infection attempt is scheduled for a time drawn from an exponential distribution with mean value of `1/infection_rate`. Finally, in the main simulation routine, the infection manager module is loaded. This module is initialized by subscribing to events related to changes in person properties, particularly when a person's infection status is set to Infected (handled by `handle_infection_status_change`). The purpose of the function `handle_infection_status_change` is to schedule the recovery of an infected individual for a time `t + infection_period` where `infection_period` comes from an exponential distribution. The simulation ends when there aren't more events or plans scheduled in the context.

- *parameters module*: this module manages data for parameter values for population size, force of infection, and infection period. At initialization, all parameter variables are set to a specific value.
- *person module*: contains a unique ID for each person that identifies each person in the simulation.
- *`person_infection_status` module*: this module connects each person ID with a specific value for a person's infection status, which could be one of Susceptible, Infected, or Recovered.
- *population manager module*: The population manager module is in charge of setting up the population. At initialization, the module reads the population size (N) parameter and creates N persons with unique ids (1..N) and sets their initial infection status to Susceptible.
- *transmission module*: This module is in charge of spreading the infection through the population. At initialization, it schedules an infection attempt for time 0. An infection attempt consists of choosing at random a susceptible individual from the population and setting their infection status to **infected**. Each infection attempt, also schedules the next infection attempt, which time is based on the force of infection.
- *infection manager module*: This module controls the infection status of each person. Transmission of pathogen is not handled in this module, only individual's infection status. Specifically, it handles the progression of newly infected persons by scheduling recovery, which is drawn from an exponential distribution based on the infection period parameter from the parameters module.
- *reports module*: This module reports changes in infection status.
- *random_number_generator module*: Two random number generators are required. One to control the sequence of susceptible persons drawn in the transmission module, and another to control the specific times of recovery in the infection manager module.

### Control flow
#### Trasmission manager
- Module data: This modules doesn't hold any specific data
- Dependencies:
- Main
```
context, parameters, random number generator, person infection status, person, population manager
load context
load parameters module // includes force of infection, population size, and infection period.
load population_manager module // it requires parameters module to read population size
load transmission_manager module
load infection_manager module
context.execute()
```
- Initialization:

- parameters module
```
init(context) {
context.add_rng(id = transmission);
context.add_plan(attempt_infection(context), time = 0);
}
parameters = struct(
population_size = 1000,
foi = 0.04,
infection_period = 5)
init(context) {
context.create_data_container(parameters)
}
```
- Methods:

- Population module: The population module depends on the person module, the parameters module, and the infection properties module. Within the population manager, a number of persons are created and given a unique person id (from 0 to `population_size`). At person creation, an infection status is defined as a property for each individual with an initial value of Susceptible, indicating that everyone in the simulation could be infected at the beginning of the simulation. The context stores the person properties as a data structure for each individual as well as an set containing the population defined by a `person_id`.

```
attempt_infection(context) {
transmission_rng = rng.get_rng(id = transmission);
population = context.get_population();
person_to_infect = transmission_rng.sample_int(from = 0, to = population);
if (context.get_infection_status(person_to_infect) == Susceptible) {
context.set_infection_status(person_to_infect, Infected);
}
foi = parameters.get_parameter(foi);
time_next_infection = transmission_rng.draw_exponential(1/foi);
context.add_plan(attempt_infection(context), time = context.get_time() + time_next_infection);
// Crate a new infection_status and add it as a property
infection_status = enum(Susceptible, Infected, Recovered);
init(context) {
context.define_person_property(infection_status, default = Susceptible);
for (person_id in 0..parameters.get_parameter(population_size)) {
context.create_person(person_id = person_id)
}
}
```

#### Infection manager
- Module data: No specific data for this module.
- Dependencies: random number generator, person infection status, person, context, parameters.
- Initialization: Adds a new random number generator and subscribes to events generated by changes in infection status.
- Transmission manager module:
```
init(context) {
context.add_rng(id = infection);
dependencies: context, parameters, random number generator, person infection status, person, population manager;
//methods
// This function in context should send, time, person_id, and infection status change.
context.observe_infection_status_event(handle_infection_status_change);
attempt_infection(context) {
transmission_rng = rng.get_rng(id = transmission);
population = context.get_population();
person_to_infect = transmission_rng.sample_int(from = 0, to = population);
if (context.get_infection_status(person_to_infect) == Susceptible) {
context.set_infection_status(person_to_infect, Infected);
}
foi = parameters.get_parameter(foi);
time_next_infection = transmission_rng.draw_exponential(1/foi);
context.add_plan(attempt_infection(context), time = context.get_time() + time_next_infection);
}
//initialization
init(context) {
context.add_rng(id = transmission);
context.add_plan(attempt_infection(context), time = 0);
}
```
- Methods:
- Infection manager module: At initialization, this module adds a new random number generator and subscribes to events generated by changes in infection status. This module handles infection events by scheduling recovery for infected individuals.

```
handle_infection_status_change(context, person_id, old_infection_status) {
if (context.get_infection_status(person_id) == Infected) {
infection_rng = context.get_rng(id = infection);
infection_period = parameters.get_parameter(infection_period)
recovery_time = infection_rng.draw_exponential(1/infection_period);
context.add_plan(context.set_infection_status(person_id, Recovered), time = recovery_time);
}
dependencies: random number generator, person infection status, person, context, parameters;
//methods
handle_infection_status_change(context, person_id, old_infection_status) {
if (context.get_infection_status(person_id) == Infected) {
infection_rng = context.get_rng(id = infection);
infection_period = parameters.get_parameter(infection_period)
recovery_time = infection_rng.draw_exponential(1/infection_period);
context.add_plan(context.set_infection_status(person_id, Recovered), time = recovery_time);
}
}
//initialization
init(context) {
context.add_rng(id = infection);
// This function in context should send, time, person_id, and infection status change.
context.observe_infection_status_event(handle_infection_status_change);
}
```
- Infection status transitions
```mermaid
flowchart LR
S(Susceptible) --FoI--> I(Infected) --inf. period--> R(Recovered)
```

## Modules description
- *parameters module*: this module manages data for parameter values for population size, force of infection, and infection period. At initialization, all parameter variables are set to a specific value.
- *person module*: contains a unique ID for each person that identifies each person in the simulation.
- *`person_infection_status` module*: this module connects each person ID with a specific value for a person's infection status, which could be one of Susceptible, Infected, or Recovered.
- *population manager module*: The population manager module is in charge of setting up the population. At initialization, the module reads the population size (N) parameter and creates N persons with unique ids (1..N) and sets their initial infection status to Susceptible.
- *transmission module*: This module is in charge of spreading the infection through the population. At initialization, it schedules an infection attempt for time 0. An infection attempt consists of choosing at random a susceptible individual from the population and setting their infection status to **infected**. Each infection attempt, also schedules the next infection attempt, which time is based on the force of infection.
- *infection manager module*: This module controls the infection status of each person. Transmission of pathogen is not handled in this module, only individual's infection status. Specifically, it handles the progression of newly infected persons by scheduling recovery, which is drawn from an exponential distribution based on the infection period parameter from the parameters module.
- *reports module*: This module reports changes in infection status.
- *random_number_generator module*: Two random number generators are required. One to control the sequence of susceptible persons drawn in the transmission module, and another to control the specific times of recovery in the infection manager module.

### Events and observation
## Events and observation
- Changes in the infection status of individuals release an event that are observed by the simulation context.
- Only events changing from susceptible to infected are handled by scheduling a change in infection status to recovered based on the infected period.

Expand Down

0 comments on commit aa2fb86

Please sign in to comment.