Starsim models are designed to capture disease dynamics within a population of agents, which typically represent people (but may represent animals or other things). In keeping with this, the basic ingredients of a Starsim model are the People class, which store all the relevant attributes about people, a collection of Modules that determine what happens to people on each time step, and the Sim class, which pulls all the components together, runs the simulation, and stores the Results.
Overview of People
More details on the People class are in the separate user guide page, but we give a basic introduction here since people are so central to the model structure. When people are created, by default they come with basic states that are stored for each person. These basic states include age, sex, and whether the person is alive. All of these states are stored as arrays, so the basic structure of the People class can be easily exported to a dataframe, e.g.:
import starsim as sssim = ss.Sim(n_agents=10)sim.init()df = sim.people.to_df()print(df)
Initializing sim with 10 agents
uid slot alive age female ti_dead ti_removed scale
0 0 0 True 25.152369 False NaN NaN 1.0
1 1 1 True 4.988294 True NaN NaN 1.0
2 2 2 True 58.149414 False NaN NaN 1.0
3 3 3 True 0.130237 False NaN NaN 1.0
4 4 4 True 43.819874 False NaN NaN 1.0
5 5 5 True 42.690937 False NaN NaN 1.0
6 6 6 True 54.292294 True NaN NaN 1.0
7 7 7 True 52.604046 False NaN NaN 1.0
8 8 8 True 7.076855 False NaN NaN 1.0
9 9 9 True 27.229174 False NaN NaN 1.0
When a module is added to a sim, this can add additional states to people. Tracking and updating the states of people is one of the main ways in which Starsim models disease dynamics. For example:
Initializing sim with 20 agents
Running 2000.01.01 ( 0/51) (0.00 s) ———————————————————— 2%
Running 2010.01.01 (10/51) (0.26 s) ••••———————————————— 22%
Running 2020.01.01 (20/51) (0.28 s) ••••••••———————————— 41%
Running 2030.01.01 (30/51) (0.30 s) ••••••••••••———————— 61%
Running 2040.01.01 (40/51) (0.32 s) ••••••••••••••••———— 80%
Running 2050.01.01 (50/51) (0.34 s) •••••••••••••••••••• 100%
uid slot alive age female ti_dead ti_removed scale randomnet.participant sis.susceptible sis.infected sis.rel_sus sis.rel_trans sis.ti_infected sis.ti_recovered sis.immunity
0 0 0 True 25.1524 False NaN NaN 1.0 False True False 0.3449 1.0 33.0 42.7465 0.6551
1 1 1 True 4.9883 True NaN NaN 1.0 False False True 0.0000 1.0 42.0 52.0214 1.0051
2 2 2 True 58.1494 False NaN NaN 1.0 False True False 0.6627 1.0 23.0 31.5178 0.3373
3 3 3 True 0.1302 False NaN NaN 1.0 False False True 0.0000 1.0 49.0 59.3261 1.5559
4 4 4 True 43.8199 False NaN NaN 1.0 False True False 0.1787 1.0 38.0 48.7212 0.8213
5 5 5 True 42.6909 False NaN NaN 1.0 False True False 0.3620 1.0 29.0 37.6566 0.6380
6 6 6 True 54.2923 True NaN NaN 1.0 False True False 0.1526 1.0 38.0 47.5738 0.8474
7 7 7 True 52.6040 False NaN NaN 1.0 False True False 0.1201 1.0 39.0 49.7212 0.8799
8 8 8 True 7.0769 False NaN NaN 1.0 False True False 0.6627 1.0 22.0 31.8954 0.3373
9 9 9 True 27.2292 False NaN NaN 1.0 False True False 0.6816 1.0 18.0 28.5382 0.3184
10 10 10 True 4.0500 True NaN NaN 1.0 False True False 0.5393 1.0 29.0 38.6003 0.4607
11 11 11 True 42.6985 False NaN NaN 1.0 False True False 0.7392 1.0 16.0 23.6503 0.2608
12 12 12 True 25.2828 True NaN NaN 1.0 False True False 0.6321 1.0 24.0 33.8575 0.3679
13 13 13 True 27.6266 True NaN NaN 1.0 False True False 0.6454 1.0 23.0 32.7132 0.3546
14 14 14 True 24.6072 False NaN NaN 1.0 False True False 0.5097 1.0 30.0 40.1969 0.4903
15 15 15 True 48.8226 False NaN NaN 1.0 False True False 0.3416 1.0 32.0 42.4071 0.6584
16 16 16 True 16.9486 False NaN NaN 1.0 False True False 0.3998 1.0 31.0 40.2152 0.6002
17 17 17 True 19.6193 True NaN NaN 1.0 False True False 0.5808 1.0 28.0 37.0291 0.4192
18 18 18 True 40.8453 True NaN NaN 1.0 False True False 0.3479 1.0 29.0 39.7353 0.6521
19 19 19 True 25.0690 False NaN NaN 1.0 False False True 0.7392 1.0 50.0 60.8258 1.2608
We can see even in this very simple example with only one disease and 20 agents, a lot of data is generated!
Overview of Modules
Starsim contains the following kinds of modules, listed below in the order that they are typically updated:
Demographics
Diseases
Connectors
Networks
Interventions
Analyzers
Modules typically store parameters (e.g. the transmission probability), states of people (e.g. whether they are susceptible, infected, or recovered), and results (e.g. the number of people infected at each point in time).
Overview of a Sim
The Sim object is responsible for storing assembling, initializing, and running the model. The Sim class contains some top-level parameters (including the number of agents in the simulation, the start and stop times, and the random seed) and results (e.g. the population size over time), but almost all other parameters and results are specific to modules and stored within them. There are more details on the Sim on the linked page.
What happens when you add a module?
When you add a module to a Sim, the module’s parameters, states, and results will be added to the centralized collections of parameters, states, and results that are maintained within the Sim. To illustrate this, let’s create a Sim with an SIR disease module and a random contact network:
import starsim as ss sir = ss.SIR(dur_inf=10, beta=0.2, init_prev=0.4, p_death=0.2)sim = ss.Sim(diseases=sir, networks='random')sim.init() # Initialize the sim to create
The call to sim.init() means that the SIR module gets added to sim.diseases and the RandomNet network gets added to sim.networks. In addition, the following updates are made: * the parameters of the modules are added to the sim’s centralized parameter dictionary, so you can access them via either sim.pars.sir.init_prev or sim.diseases.sir.pars.init_prev * the states specific to each module are added to People, so you can access them via sim.diseases.sir.infected or sim.people.sir.infected * the results specific to each module are added to the centralized Results dictionary of the Sim, so you can access them via sim.diseases.sir.results.n_infected or sim.results.sir.n_infected.
Overview of Results
Once you’ve run a Sim, all the results are stored under sim.results. This is structured similarly to a nested dictionary, with results specific to each module stored in their own dictionaries, like the sim.results.sir.n_infected example above.