Getting started - Requirements#
Python (π): This assumes that you have a python environment installed.
To install FPsim, you first need to clone or download a copy of the source code from fpsim/fpsim
git clone -b <branch> --single-branch https://github.com/fpsim/fpsim.git
cd fpsim
pip install -e .
If it worked, you should be able to import fpsim with import fpsim as fp
.
Getting started with FPsim#
The basic design philosophy of FPsim is: common modelling tasks should be simple. For example:
Defining parameters
Running a simulation
Plotting results
This tutorial walks you through how to define parameters and run the simulation. The next tutorial will show you how to plot the results of a simulation.
An interactive version of this notebook is available on Google Colab or Binder.
To create, run, and plot a sim with default options is just:
[1]:
import fpsim as fp
sim = fp.Sim()
sim.run()
fig = sim.plot()
/home/docs/checkouts/readthedocs.org/user_builds/institute-for-disease-modeling-fpsim/envs/latest/lib/python3.11/site-packages/tqdm/auto.py:21: TqdmWarning: IProgress not found. Please update jupyter and ipywidgets. See https://ipywidgets.readthedocs.io/en/stable/user_install.html
from .autonotebook import tqdm as notebook_tqdm
Location not supplied: using parameters from Senegal
Initializing sim with 1000 agents
Running 2000.01.01 ( 0/241) (0.00 s) ββββββββββββββββββββ 0%
Running 2001.01.01 (12/241) (0.12 s) β’βββββββββββββββββββ 5%
Running 2002.01.01 (24/241) (0.28 s) β’β’ββββββββββββββββββ 10%
Running 2003.01.01 (36/241) (0.44 s) β’β’β’βββββββββββββββββ 15%
Running 2004.01.01 (48/241) (0.60 s) β’β’β’β’ββββββββββββββββ 20%
Running 2005.01.01 (60/241) (0.76 s) β’β’β’β’β’βββββββββββββββ 25%
Running 2006.01.01 (72/241) (0.93 s) β’β’β’β’β’β’ββββββββββββββ 30%
Running 2007.01.01 (84/241) (1.10 s) β’β’β’β’β’β’β’βββββββββββββ 35%
Running 2008.01.01 (96/241) (1.27 s) β’β’β’β’β’β’β’β’ββββββββββββ 40%
Running 2009.01.01 (108/241) (1.44 s) β’β’β’β’β’β’β’β’β’βββββββββββ 45%
Running 2010.01.01 (120/241) (1.64 s) β’β’β’β’β’β’β’β’β’β’ββββββββββ 50%
Running 2011.01.01 (132/241) (1.81 s) β’β’β’β’β’β’β’β’β’β’β’βββββββββ 55%
Running 2012.01.01 (144/241) (2.01 s) β’β’β’β’β’β’β’β’β’β’β’β’ββββββββ 60%
Running 2013.01.01 (156/241) (2.19 s) β’β’β’β’β’β’β’β’β’β’β’β’β’βββββββ 65%
Running 2014.01.01 (168/241) (2.37 s) β’β’β’β’β’β’β’β’β’β’β’β’β’β’ββββββ 70%
Running 2015.01.01 (180/241) (2.55 s) β’β’β’β’β’β’β’β’β’β’β’β’β’β’β’βββββ 75%
Running 2016.01.01 (192/241) (2.73 s) β’β’β’β’β’β’β’β’β’β’β’β’β’β’β’β’ββββ 80%
Running 2017.01.01 (204/241) (2.92 s) β’β’β’β’β’β’β’β’β’β’β’β’β’β’β’β’β’βββ 85%
Running 2018.01.01 (216/241) (3.10 s) β’β’β’β’β’β’β’β’β’β’β’β’β’β’β’β’β’β’ββ 90%
Running 2019.01.01 (228/241) (3.29 s) β’β’β’β’β’β’β’β’β’β’β’β’β’β’β’β’β’β’β’β 95%
Running 2020.01.01 (240/241) (3.50 s) β’β’β’β’β’β’β’β’β’β’β’β’β’β’β’β’β’β’β’β’ 100%

Defining parameters#
Parameters are defined as a dictionary. In FPsim, we categorize our parameters as:
Basic parameters
Age limits
Demographics (urban/rural, wealth)
Durations
Pregnancy outcomes
Fecundity and exposure
Contraceptive use
Education
The most common category of parameters to change in FPsim is the basic category, which includes the geographic location (i.e. Kenya, Senegal, northern India), the starting population, the starting year, and the initial number of agents. We can define these as:
[2]:
pars = dict(
n_agents = 10_000,
location = 'kenya',
start_year = 2000,
end_year = 2020,
)
Running simulations#
Running a simulation is pretty easy. In fact, running a sim with the parameters we defined above is just:
[3]:
sim = fp.Sim(pars)
sim.run()
Initializing sim with 10000 agents
Running 2000.01.01 ( 0/241) (0.00 s) ββββββββββββββββββββ 0%
Running 2001.01.01 (12/241) (0.51 s) β’βββββββββββββββββββ 5%
Running 2002.01.01 (24/241) (0.98 s) β’β’ββββββββββββββββββ 10%
Running 2003.01.01 (36/241) (1.48 s) β’β’β’βββββββββββββββββ 15%
Running 2004.01.01 (48/241) (1.97 s) β’β’β’β’ββββββββββββββββ 20%
Running 2005.01.01 (60/241) (2.46 s) β’β’β’β’β’βββββββββββββββ 25%
Running 2006.01.01 (72/241) (2.94 s) β’β’β’β’β’β’ββββββββββββββ 30%
Running 2007.01.01 (84/241) (3.42 s) β’β’β’β’β’β’β’βββββββββββββ 35%
Running 2008.01.01 (96/241) (3.91 s) β’β’β’β’β’β’β’β’ββββββββββββ 40%
Running 2009.01.01 (108/241) (4.41 s) β’β’β’β’β’β’β’β’β’βββββββββββ 45%
Running 2010.01.01 (120/241) (4.91 s) β’β’β’β’β’β’β’β’β’β’ββββββββββ 50%
Running 2011.01.01 (132/241) (5.42 s) β’β’β’β’β’β’β’β’β’β’β’βββββββββ 55%
Running 2012.01.01 (144/241) (5.94 s) β’β’β’β’β’β’β’β’β’β’β’β’ββββββββ 60%
Running 2013.01.01 (156/241) (6.44 s) β’β’β’β’β’β’β’β’β’β’β’β’β’βββββββ 65%
Running 2014.01.01 (168/241) (6.98 s) β’β’β’β’β’β’β’β’β’β’β’β’β’β’ββββββ 70%
Running 2015.01.01 (180/241) (7.53 s) β’β’β’β’β’β’β’β’β’β’β’β’β’β’β’βββββ 75%
Running 2016.01.01 (192/241) (8.05 s) β’β’β’β’β’β’β’β’β’β’β’β’β’β’β’β’ββββ 80%
Running 2017.01.01 (204/241) (8.59 s) β’β’β’β’β’β’β’β’β’β’β’β’β’β’β’β’β’βββ 85%
Running 2018.01.01 (216/241) (9.11 s) β’β’β’β’β’β’β’β’β’β’β’β’β’β’β’β’β’β’ββ 90%
Running 2019.01.01 (228/241) (9.78 s) β’β’β’β’β’β’β’β’β’β’β’β’β’β’β’β’β’β’β’β 95%
Running 2020.01.01 (240/241) (10.29 s) β’β’β’β’β’β’β’β’β’β’β’β’β’β’β’β’β’β’β’β’ 100%
[3]:
Sim(n=10000; 2000β2020; connectors=contraception, edu, fp)
Inspecting results#
Running the simulation will generate a results [dictionary] sim.results
. A dictionary is simply collection of items, and you can access the values of results using different βkeyβ words. Almost all of the results relevant for FPsim are stored under the key βfpβ; for example, the number of pregnancies over time can be found using sim.results.fp['pregnancies']
. Execute the code below:
[4]:
sim.results.fp['pregnancies']
[4]:
Result(pregnancies):
array([49. 51. 43. 40. 37. 38. 28. 36. 25. 20. 34. 28. 34. 29. 31. 28. 25. 23.
25. 25. 17. 20. 16. 28. 21. 14. 10. 22. 19. 9. 21. 12. 13. 8. 18. 10.
13. 20. 17. 12. 9. 17. 11. 16. 11. 17. 16. 18. 11. 23. 23. 16. 19. 17.
21. 17. 15. 10. 18. 18. 14. 25. 18. 15. 20. 16. 7. 17. 9. 18. 22. 19.
19. 18. 15. 19. 13. 10. 18. 18. 8. 14. 15. 11. 16. 20. 9. 11. 19. 11.
18. 13. 19. 18. 9. 13. 16. 15. 17. 16. 16. 15. 20. 18. 23. 19. 26. 16.
8. 18. 8. 20. 24. 16. 18. 23. 14. 16. 17. 19. 14. 16. 20. 18. 16. 11.
10. 22. 15. 21. 22. 12. 15. 14. 14. 19. 15. 15. 22. 17. 15. 19. 21. 19.
20. 27. 17. 16. 19. 15. 20. 16. 15. 22. 18. 19. 16. 19. 16. 17. 13. 16.
14. 20. 14. 15. 22. 18. 19. 13. 20. 14. 14. 15. 17. 17. 19. 23. 20. 25.
14. 13. 25. 24. 14. 20. 29. 20. 17. 21. 12. 17. 14. 16. 12. 14. 17. 20.
12. 19. 18. 19. 17. 18. 19. 17. 18. 23. 16. 16. 19. 15. 27. 17. 15. 21.
16. 14. 12. 19. 14. 16. 21. 15. 24. 15. 18. 10. 18. 22. 17. 21. 16. 19.
18. 15. 14. 5. 19. 22. 18.])
If you want to see all the βkeysβ that are available in the results dictionary you can use
[5]:
sim.list_available_results()
Result keys:
contraception.acpr
contraception.cpr
contraception.mcpr
contraception.n_at_risk_non_users
contraception.n_at_risk_users
contraception.n_mod_users
contraception.n_non_users
contraception.n_users
cum_deaths
edu.mean_attainment
edu.mean_objective
edu.n_completed
edu.n_dropped
edu.n_in_school
edu.n_interrupted
edu.n_started
edu.prop_completed
edu.prop_dropped
edu.prop_in_school
fp.abortions
fp.births
fp.contra_access
fp.ever_used_contra
fp.imr
fp.infant_deaths
fp.maternal_deaths
fp.method_failures
fp.miscarriages
fp.mmr
fp.n_ever_used_contra
fp.n_fecund
fp.n_fertile
fp.n_lactating
fp.n_lam
fp.n_on_contra
fp.n_partnered
fp.n_postpartum
fp.n_pregnant
fp.n_sexual_debut
fp.n_sexually_active
fp.new_users
fp.nonpostpartum
fp.p_short_interval
fp.parity0to1
fp.parity2to3
fp.parity4to5
fp.parity6plus
fp.pp0to5
fp.pp12to23
fp.pp6to11
fp.pregnancies
fp.secondary_births
fp.short_intervals
fp.stillbirths
fp.switchers
fp.tfr
fp.total_births
n_alive
n_urban
n_wq1
n_wq2
n_wq3
n_wq4
n_wq5
new_deaths
new_emigrants
Slightly different way of defining parameters#
You can also specify different parameters by specifyuing them directly as arguments in the simulation object:
[6]:
sim = fp.Sim(n_agents=10e3, location='kenya', start_year=2000, end_year=2020)
sim.run()
Initializing sim with 10000 agents
Running 2000.01.01 ( 0/241) (0.00 s) ββββββββββββββββββββ 0%
Running 2001.01.01 (12/241) (0.38 s) β’βββββββββββββββββββ 5%
Running 2002.01.01 (24/241) (0.84 s) β’β’ββββββββββββββββββ 10%
Running 2003.01.01 (36/241) (1.32 s) β’β’β’βββββββββββββββββ 15%
Running 2004.01.01 (48/241) (1.79 s) β’β’β’β’ββββββββββββββββ 20%
Running 2005.01.01 (60/241) (2.26 s) β’β’β’β’β’βββββββββββββββ 25%
Running 2006.01.01 (72/241) (2.74 s) β’β’β’β’β’β’ββββββββββββββ 30%
Running 2007.01.01 (84/241) (3.22 s) β’β’β’β’β’β’β’βββββββββββββ 35%
Running 2008.01.01 (96/241) (3.70 s) β’β’β’β’β’β’β’β’ββββββββββββ 40%
Running 2009.01.01 (108/241) (4.20 s) β’β’β’β’β’β’β’β’β’βββββββββββ 45%
Running 2010.01.01 (120/241) (4.69 s) β’β’β’β’β’β’β’β’β’β’ββββββββββ 50%
Running 2011.01.01 (132/241) (5.19 s) β’β’β’β’β’β’β’β’β’β’β’βββββββββ 55%
Running 2012.01.01 (144/241) (5.72 s) β’β’β’β’β’β’β’β’β’β’β’β’ββββββββ 60%
Running 2013.01.01 (156/241) (6.21 s) β’β’β’β’β’β’β’β’β’β’β’β’β’βββββββ 65%
Running 2014.01.01 (168/241) (6.73 s) β’β’β’β’β’β’β’β’β’β’β’β’β’β’ββββββ 70%
Running 2015.01.01 (180/241) (7.24 s) β’β’β’β’β’β’β’β’β’β’β’β’β’β’β’βββββ 75%
Running 2016.01.01 (192/241) (7.75 s) β’β’β’β’β’β’β’β’β’β’β’β’β’β’β’β’ββββ 80%
Running 2017.01.01 (204/241) (8.45 s) β’β’β’β’β’β’β’β’β’β’β’β’β’β’β’β’β’βββ 85%
Running 2018.01.01 (216/241) (8.98 s) β’β’β’β’β’β’β’β’β’β’β’β’β’β’β’β’β’β’ββ 90%
Running 2019.01.01 (228/241) (9.50 s) β’β’β’β’β’β’β’β’β’β’β’β’β’β’β’β’β’β’β’β 95%
Running 2020.01.01 (240/241) (10.03 s) β’β’β’β’β’β’β’β’β’β’β’β’β’β’β’β’β’β’β’β’ 100%
[6]:
Sim(n=10000; 2000β2020; connectors=contraception, edu, fp)
You can mix and match too β pass in the parameter dictionary (pars
defined above) with some default options, and then include other parameters as arguments to the sim. Doing this overrides the equally named parameters in pars
because (keyword) arguments take precedence). For example:
[7]:
sim = fp.Sim(pars, n_agents=100) # Use parameters defined above, but overrides the value `n_agents` in pars, and uses instead 100 agents, not 10,000
sim.run()
Initializing sim with 100 agents
Running 2000.01.01 ( 0/241) (0.00 s) ββββββββββββββββββββ 0%
Running 2001.01.01 (12/241) (0.09 s) β’βββββββββββββββββββ 5%
Running 2002.01.01 (24/241) (0.19 s) β’β’ββββββββββββββββββ 10%
Running 2003.01.01 (36/241) (0.27 s) β’β’β’βββββββββββββββββ 15%
Running 2004.01.01 (48/241) (0.37 s) β’β’β’β’ββββββββββββββββ 20%
Running 2005.01.01 (60/241) (0.48 s) β’β’β’β’β’βββββββββββββββ 25%
Running 2006.01.01 (72/241) (0.59 s) β’β’β’β’β’β’ββββββββββββββ 30%
Running 2007.01.01 (84/241) (0.69 s) β’β’β’β’β’β’β’βββββββββββββ 35%
Running 2008.01.01 (96/241) (0.77 s) β’β’β’β’β’β’β’β’ββββββββββββ 40%
Running 2009.01.01 (108/241) (0.86 s) β’β’β’β’β’β’β’β’β’βββββββββββ 45%
Running 2010.01.01 (120/241) (0.98 s) β’β’β’β’β’β’β’β’β’β’ββββββββββ 50%
Running 2011.01.01 (132/241) (1.09 s) β’β’β’β’β’β’β’β’β’β’β’βββββββββ 55%
Running 2012.01.01 (144/241) (1.20 s) β’β’β’β’β’β’β’β’β’β’β’β’ββββββββ 60%
Running 2013.01.01 (156/241) (1.30 s) β’β’β’β’β’β’β’β’β’β’β’β’β’βββββββ 65%
Running 2014.01.01 (168/241) (1.42 s) β’β’β’β’β’β’β’β’β’β’β’β’β’β’ββββββ 70%
Running 2015.01.01 (180/241) (1.51 s) β’β’β’β’β’β’β’β’β’β’β’β’β’β’β’βββββ 75%
Running 2016.01.01 (192/241) (1.61 s) β’β’β’β’β’β’β’β’β’β’β’β’β’β’β’β’ββββ 80%
Running 2017.01.01 (204/241) (1.75 s) β’β’β’β’β’β’β’β’β’β’β’β’β’β’β’β’β’βββ 85%
Running 2018.01.01 (216/241) (1.85 s) β’β’β’β’β’β’β’β’β’β’β’β’β’β’β’β’β’β’ββ 90%
Running 2019.01.01 (228/241) (1.95 s) β’β’β’β’β’β’β’β’β’β’β’β’β’β’β’β’β’β’β’β 95%
Running 2020.01.01 (240/241) (2.08 s) β’β’β’β’β’β’β’β’β’β’β’β’β’β’β’β’β’β’β’β’ 100%
[7]:
Sim(n=100; 2000β2020; connectors=contraception, edu, fp)
Now you know how to run a basic simulation in FPsim and change the parameters. Now letβs take a look at the output of the sim.
Explore plotting options for a single simulation#
Letβs take a look at the basic suite of plotting options, once weβve run our initial simulation.
The basic plot function will plot births, deaths, and mcpr over the entire simulation.
There are also pre-defined options that combine similar types of output. For instance, βapoβ stands for adverse pregnancy outcomes, and will plot infant deaths, stillbirths, and abortions.
plot() will take any of the following options:
βcprβ will plot three different ways to define contraceptive prevalence - mCPR, CPR (includes traditional), and aCPR (includes traditional and restricts denominator to sexually active non-pregnant women)
βapoβ will plot adverse pregnancy outcomes, including abortion and miscarriage
βmortalityβ will plot mortality-related outcomes
βmethodβ plots the method mix over time
[8]:
sim.plot() # the default
sim.plot('cpr')


[8]:

In the next tutorial, we will look at some of the new features of FPsim 2.0, including how to define different contraceptive choice options.