Basic workflow

This page demonstrates how to perform basic operations in Atomica. First, we will set up the notebook environment - the commands below are typically not required in user scripts:

[1]:
%load_ext autoreload
%autoreload 2
%matplotlib inline
import sys
sys.path.append('..')

To start with, import Atomica itself. It is often also useful to import numpy and matplotlib

[2]:
import atomica as at
import numpy as np
import matplotlib.pyplot as plt

Starting an application

The first step in starting a new application is to write a Framework file. This can be done by copying one of the templates in the atomica/library folder (either framework_template.xlsx or framework_template_advanced.xlsx) and implementing your model. Further guidance on this is provided separately in the framework documentation.

After writing the Framework, the next step is to generate a databook. This is performed in three steps

  1. Load the framework into a ProjectFramework Python instance

  2. Use the framework to make a new ProjectData instance

  3. Save the ProjectData instance to a spreadsheet

In this example, we will load an existing framework from the library. You can use at.LIBRARY_PATH to refer to the folder containing the library Excel files shipped with Atomica:

[3]:
F = at.ProjectFramework(at.LIBRARY_PATH / 'tb_framework.xlsx') # Load the Framework
D = at.ProjectData.new(F,pops=2, tvec=np.arange(2000,2018), transfers=0)
D.save('new_databook.xlsx')
Object saved to /home/runner/work/atomica/atomica/docs/examples/new_databook.xlsx.

The ProjectData class in Python can be thought of as an equivalent representation of the databook - you can edit the databook in Excel, which will result in changes to the ProjectData variable when the spreadsheet is loaded, and you can modify the ProjectData in Python and then write a modified spreadsheet. ProjectData has a number of methods that you can use to modify the databook, to do things like

  • Add or remove populations

  • Change the time span of the databook

To perform these operations, you can load in a databook using ProjectData.from_spreadsheet(). This lets you load in a databook given a particular framework. It is not required that the databook be completed prior to loading - you only need to complete the databook in its entirity if you want to use the databook in a project. So for example, to add an additional population and a transfer to this newly created databook, we could use:

[4]:
D = at.ProjectData.from_spreadsheet('new_databook.xlsx', framework=F)
D.add_pop('pris','Prisoners')
D.add_transfer('aging','Aging')
D.save('new_databook_2.xlsx')
Object saved to /home/runner/work/atomica/atomica/docs/examples/new_databook_2.xlsx.

Creating a project

Once you have completed the framework file and databook, you can create a project that can be used to run simulations and analyses. To do this, simply create a Project instance, passing in the file names for the framework and databook. Here we will use a pre-filled databook from the library:

[5]:
P = at.Project(framework=at.LIBRARY_PATH / 'tb_framework.xlsx', databook=at.LIBRARY_PATH / 'tb_databook.xlsx')
Elapsed time for running "default": 0.195s

When you create a project, a default simulation is automatically run. You can subsequently run simulations using P.run_sim()

[6]:
res = P.run_sim(parset='default', result_name='Default parset')
P.results.keys()
Elapsed time for running "default": 0.196s
[6]:
['parset_default']

When you run a simulation, by default it is automatically copied into the project, as well as being returned. Specifying the result name is optional, but recommended because it helps to keep track of the simulations when comparing and plotting them. We can now plot the result to show the compartment sizes:

[7]:
d = at.PlotData(res,pops='0-4',project=P)
at.plot_series(d,plot_type='stacked', data=P.data, legend_mode='separate');
../_images/examples_Basic-workflow_13_0.svg
../_images/examples_Basic-workflow_13_1.svg

For full details on plotting, please refer to the full plotting documentation here.

Calibrating the model

Model calibration can be performed in one of two ways - either manually, or automatically

Manual calibration

Manual calibration of the model proceeds in three steps

  1. Make a new ParameterSet (e.g., by copying an existing one)

  2. Modify the calibration scale factors in that ParameterSet

  3. Run a simulation using the new parameter set

The commands to do this are shown below, for an example where the force of infection has been decreased:

[8]:
new_parset = P.parsets.copy('default','manually_calibrated')
new_parset.pars['foi_out'].meta_y_factor = 0.8 # Decrease infectiousness of all populations
new_parset.pars['foi_in'].y_factor['0-4'] = 2.0 # Increase susceptibility of young children
res_manually_calibrated = P.run_sim(parset='manually_calibrated', result_name='Manually calibrated')
d = at.PlotData([res,res_manually_calibrated],outputs='ac_inf',project=P)
at.plot_series(d, axis='results');
Elapsed time for running "default": 0.197s
../_images/examples_Basic-workflow_16_1.svg
../_images/examples_Basic-workflow_16_2.svg
../_images/examples_Basic-workflow_16_3.svg
../_images/examples_Basic-workflow_16_4.svg
../_images/examples_Basic-workflow_16_5.svg

Automatic calibration

To perform an automatic calibration, simply use P.calibrate() specifying the amount of time to run the calibration for, and the name of the new calibrated parset to create.

[9]:
P.calibrate(max_time=10, parset='default', new_name="auto_calibrated", save_to_project=True);
ASD: Launching with random seed None
Elapsed time for running "default": 0.121s
Elapsed time for running "default": 0.278s
    step=1 choice=102, par=102, pm=0.0, origval=1.0, newval=1.1
     step 1 (0.3 s) -- (orig:10.14 | best:10.14 | new:10.14 | diff:0)
Elapsed time for running "default": 0.123s
    step=2 choice=174, par=44, pm=1.0, origval=1.0, newval=0.9
     step 2 (0.4 s) -- (orig:10.14 | best:10.14 | new:10.27 | diff:0.1384)
Elapsed time for running "default": 0.123s
    step=3 choice=20, par=20, pm=0.0, origval=1.0, newval=1.1
     step 3 (0.5 s) -- (orig:10.14 | best:10.14 | new:10.14 | diff:0.001523)
Elapsed time for running "default": 0.127s
    step=4 choice=151, par=21, pm=1.0, origval=1.0, newval=0.9
     step 4 (0.7 s) ++ (orig:10.14 | best:10.14 | new:10.13 | diff:-0.005646)
Elapsed time for running "default": 0.125s
    step=5 choice=230, par=100, pm=1.0, origval=1.0, newval=0.9
     step 5 (0.8 s) -- (orig:10.14 | best:10.13 | new:10.13 | diff:0)
Elapsed time for running "default": 0.128s
    step=6 choice=161, par=31, pm=1.0, origval=1.0, newval=0.9
     step 6 (0.9 s) -- (orig:10.14 | best:10.13 | new:10.14 | diff:0.01364)
Elapsed time for running "default": 0.124s
    step=7 choice=27, par=27, pm=0.0, origval=1.0, newval=1.1
     step 7 (1.0 s) -- (orig:10.14 | best:10.13 | new:10.17 | diff:0.03587)
Elapsed time for running "default": 0.125s
    step=8 choice=180, par=50, pm=1.0, origval=1.0, newval=0.9
     step 8 (1.2 s) ++ (orig:10.14 | best:10.13 | new:10.11 | diff:-0.01652)
Elapsed time for running "default": 0.125s
    step=9 choice=186, par=56, pm=1.0, origval=1.0, newval=0.9
     step 9 (1.3 s) ++ (orig:10.14 | best:10.11 | new:10.11 | diff:-0.0007969)
Elapsed time for running "default": 0.321s
    step=10 choice=139, par=9, pm=1.0, origval=1.0, newval=0.9
     step 10 (1.6 s) -- (orig:10.14 | best:10.11 | new:10.12 | diff:0.002474)
Elapsed time for running "default": 0.124s
    step=11 choice=183, par=53, pm=1.0, origval=1.0, newval=0.9
     step 11 (1.8 s) ++ (orig:10.14 | best:10.11 | new:10.08 | diff:-0.02985)
Elapsed time for running "default": 0.125s
    step=12 choice=7, par=7, pm=0.0, origval=1.0, newval=1.1
     step 12 (1.9 s) -- (orig:10.14 | best:10.08 | new:10.94 | diff:0.8543)
Elapsed time for running "default": 0.122s
    step=13 choice=180, par=50, pm=1.0, origval=0.9, newval=0.75
     step 13 (2.0 s) ++ (orig:10.14 | best:10.08 | new:10.06 | diff:-0.02479)
Elapsed time for running "default": 0.121s
    step=14 choice=44, par=44, pm=0.0, origval=1.0, newval=1.1
     step 14 (2.1 s) ++ (orig:10.14 | best:10.06 | new:9.928 | diff:-0.1302)
Elapsed time for running "default": 0.121s
    step=15 choice=245, par=115, pm=1.0, origval=1.0, newval=0.9
     step 15 (2.3 s) ++ (orig:10.14 | best:9.928 | new:9.904 | diff:-0.02432)
Elapsed time for running "default": 0.120s
    step=16 choice=12, par=12, pm=0.0, origval=1.0, newval=1.1
     step 16 (2.4 s) -- (orig:10.14 | best:9.904 | new:10.17 | diff:0.2704)
Elapsed time for running "default": 0.121s
    step=17 choice=252, par=122, pm=1.0, origval=1.0, newval=0.9
     step 17 (2.5 s) ++ (orig:10.14 | best:9.904 | new:9.350 | diff:-0.5543)
Elapsed time for running "default": 0.120s
    step=18 choice=198, par=68, pm=1.0, origval=1.0, newval=0.9
     step 18 (2.6 s) ++ (orig:10.14 | best:9.350 | new:9.328 | diff:-0.02196)
Elapsed time for running "default": 0.123s
    step=19 choice=176, par=46, pm=1.0, origval=1.0, newval=0.9
     step 19 (2.7 s) -- (orig:10.14 | best:9.328 | new:9.333 | diff:0.005324)
Elapsed time for running "default": 0.314s
    step=20 choice=221, par=91, pm=1.0, origval=1.0, newval=0.9
     step 20 (3.1 s) -- (orig:10.14 | best:9.328 | new:9.328 | diff:0)
Elapsed time for running "default": 0.123s
    step=21 choice=32, par=32, pm=0.0, origval=1.0, newval=1.1
     step 21 (3.2 s) -- (orig:10.14 | best:9.328 | new:9.328 | diff:0.0002671)
Elapsed time for running "default": 0.127s
    step=22 choice=107, par=107, pm=0.0, origval=1.0, newval=1.1
     step 22 (3.3 s) -- (orig:10.14 | best:9.328 | new:9.328 | diff:0)
Elapsed time for running "default": 0.121s
    step=23 choice=84, par=84, pm=0.0, origval=1.0, newval=1.1
     step 23 (3.4 s) ++ (orig:10.14 | best:9.328 | new:9.116 | diff:-0.2119)
Elapsed time for running "default": 0.120s
    step=24 choice=215, par=85, pm=1.0, origval=1.0, newval=0.9
     step 24 (3.6 s) ++ (orig:10.14 | best:9.116 | new:9.066 | diff:-0.04988)
Elapsed time for running "default": 0.121s
    step=25 choice=186, par=56, pm=1.0, origval=0.9, newval=0.75
     step 25 (3.7 s) ++ (orig:10.14 | best:9.066 | new:9.065 | diff:-0.001160)
Elapsed time for running "default": 0.122s
    step=26 choice=52, par=52, pm=0.0, origval=1.0, newval=1.1
     step 26 (3.8 s) -- (orig:10.14 | best:9.065 | new:9.226 | diff:0.1609)
Elapsed time for running "default": 0.123s
    step=27 choice=41, par=41, pm=0.0, origval=1.0, newval=1.1
     step 27 (3.9 s) -- (orig:10.14 | best:9.065 | new:9.135 | diff:0.06990)
Elapsed time for running "default": 0.126s
    step=28 choice=63, par=63, pm=0.0, origval=1.0, newval=1.1
     step 28 (4.1 s) -- (orig:10.14 | best:9.065 | new:9.065 | diff:0.000000000000001776)
Elapsed time for running "default": 0.334s
    step=29 choice=36, par=36, pm=0.0, origval=1.0, newval=1.1
     step 29 (4.4 s) -- (orig:10.14 | best:9.065 | new:9.065 | diff:0)
Elapsed time for running "default": 0.128s
    step=30 choice=40, par=40, pm=0.0, origval=1.0, newval=1.1
     step 30 (4.5 s) -- (orig:10.14 | best:9.065 | new:9.095 | diff:0.02982)
Elapsed time for running "default": 0.129s
    step=31 choice=159, par=29, pm=1.0, origval=1.0, newval=0.9
     step 31 (4.7 s) -- (orig:10.14 | best:9.065 | new:9.071 | diff:0.006486)
Elapsed time for running "default": 0.126s
    step=32 choice=232, par=102, pm=1.0, origval=1.0, newval=0.9
     step 32 (4.8 s) -- (orig:10.14 | best:9.065 | new:9.065 | diff:0)
Elapsed time for running "default": 0.123s
    step=33 choice=3, par=3, pm=0.0, origval=1.0, newval=1.1
     step 33 (4.9 s) -- (orig:10.14 | best:9.065 | new:9.112 | diff:0.04711)
Elapsed time for running "default": 0.124s
    step=34 choice=48, par=48, pm=0.0, origval=1.0, newval=1.1
     step 34 (5.1 s) ++ (orig:10.14 | best:9.065 | new:9.059 | diff:-0.006352)
Elapsed time for running "default": 0.122s
    step=35 choice=37, par=37, pm=0.0, origval=1.0, newval=1.1
     step 35 (5.2 s) ++ (orig:10.14 | best:9.059 | new:9.058 | diff:-0.00004267)
Elapsed time for running "default": 0.128s
    step=36 choice=101, par=101, pm=0.0, origval=1.0, newval=1.1
     step 36 (5.3 s) -- (orig:10.14 | best:9.058 | new:9.058 | diff:0)
Elapsed time for running "default": 0.124s
    step=37 choice=100, par=100, pm=0.0, origval=1.0, newval=1.1
     step 37 (5.4 s) -- (orig:10.14 | best:9.058 | new:9.058 | diff:0)
Elapsed time for running "default": 0.121s
    step=38 choice=216, par=86, pm=1.0, origval=1.0, newval=0.9
     step 38 (5.6 s) ++ (orig:10.14 | best:9.058 | new:8.945 | diff:-0.1130)
Elapsed time for running "default": 0.395s
    step=39 choice=187, par=57, pm=1.0, origval=1.0, newval=0.9
     step 39 (6.0 s) ++ (orig:10.14 | best:8.945 | new:8.930 | diff:-0.01557)
Elapsed time for running "default": 0.127s
    step=40 choice=42, par=42, pm=0.0, origval=1.0, newval=1.1
     step 40 (6.1 s) -- (orig:10.14 | best:8.930 | new:9.507 | diff:0.5771)
Elapsed time for running "default": 0.128s
    step=41 choice=245, par=115, pm=1.0, origval=0.9, newval=0.75
     step 41 (6.2 s) ++ (orig:10.14 | best:8.930 | new:8.896 | diff:-0.03401)
Elapsed time for running "default": 0.123s
    step=42 choice=205, par=75, pm=1.0, origval=1.0, newval=0.9
     step 42 (6.3 s) ++ (orig:10.14 | best:8.896 | new:8.896 | diff:-0.000000002236)
Elapsed time for running "default": 0.123s
    step=43 choice=79, par=79, pm=0.0, origval=1.0, newval=1.1
     step 43 (6.5 s) -- (orig:10.14 | best:8.896 | new:8.896 | diff:0.000002031)
Elapsed time for running "default": 0.124s
    step=44 choice=146, par=16, pm=1.0, origval=1.0, newval=0.9
     step 44 (6.6 s) -- (orig:10.14 | best:8.896 | new:8.896 | diff:0)
Elapsed time for running "default": 0.120s
    step=45 choice=43, par=43, pm=0.0, origval=1.0, newval=1.1
     step 45 (6.7 s) -- (orig:10.14 | best:8.896 | new:8.948 | diff:0.05220)
Elapsed time for running "default": 0.121s
    step=46 choice=250, par=120, pm=1.0, origval=1.0, newval=0.9
     step 46 (6.8 s) ++ (orig:10.14 | best:8.896 | new:8.480 | diff:-0.4162)
Elapsed time for running "default": 0.122s
    step=47 choice=227, par=97, pm=1.0, origval=1.0, newval=0.9
     step 47 (7.0 s) -- (orig:10.14 | best:8.480 | new:8.571 | diff:0.09090)
Elapsed time for running "default": 0.337s
    step=48 choice=167, par=37, pm=1.0, origval=1.1, newval=1.0
     step 48 (7.3 s) -- (orig:10.14 | best:8.480 | new:8.480 | diff:0.00003138)
Elapsed time for running "default": 0.125s
    step=49 choice=178, par=48, pm=1.0, origval=1.1, newval=1.0
     step 49 (7.4 s) -- (orig:10.14 | best:8.480 | new:8.485 | diff:0.005217)
Elapsed time for running "default": 0.129s
    step=50 choice=23, par=23, pm=0.0, origval=1.0, newval=1.1
     step 50 (7.6 s) -- (orig:10.14 | best:8.480 | new:8.484 | diff:0.003888)
Elapsed time for running "default": 0.129s
    step=51 choice=1, par=1, pm=0.0, origval=1.0, newval=1.1
     step 51 (7.7 s) -- (orig:10.14 | best:8.480 | new:8.542 | diff:0.06195)
Elapsed time for running "default": 0.122s
    step=52 choice=92, par=92, pm=0.0, origval=1.0, newval=1.1
     step 52 (7.8 s) -- (orig:10.14 | best:8.480 | new:8.480 | diff:0)
Elapsed time for running "default": 0.125s
    step=53 choice=95, par=95, pm=0.0, origval=1.0, newval=1.1
     step 53 (7.9 s) ++ (orig:10.14 | best:8.480 | new:8.403 | diff:-0.07675)
Elapsed time for running "default": 0.119s
    step=54 choice=151, par=21, pm=1.0, origval=0.9, newval=0.75
     step 54 (8.1 s) ++ (orig:10.14 | best:8.403 | new:8.395 | diff:-0.007777)
Elapsed time for running "default": 0.118s
    step=55 choice=60, par=60, pm=0.0, origval=1.0, newval=1.1
     step 55 (8.2 s) -- (orig:10.14 | best:8.395 | new:8.395 | diff:0.000000008043)
Elapsed time for running "default": 0.125s
    step=56 choice=212, par=82, pm=1.0, origval=1.0, newval=0.9
     step 56 (8.3 s) ++ (orig:10.14 | best:8.395 | new:8.190 | diff:-0.2049)
Elapsed time for running "default": 0.120s
    step=57 choice=83, par=83, pm=0.0, origval=1.0, newval=1.1
     step 57 (8.4 s) -- (orig:10.14 | best:8.190 | new:8.240 | diff:0.04996)
Elapsed time for running "default": 0.365s
    step=58 choice=183, par=53, pm=1.0, origval=0.9, newval=0.75
     step 58 (8.8 s) ++ (orig:10.14 | best:8.190 | new:8.150 | diff:-0.04018)
Elapsed time for running "default": 0.153s
    step=59 choice=130, par=0, pm=1.0, origval=1.0, newval=0.9
     step 59 (9.0 s) ++ (orig:10.14 | best:8.150 | new:8.129 | diff:-0.02160)
Elapsed time for running "default": 0.154s
    step=60 choice=106, par=106, pm=0.0, origval=1.0, newval=1.1
     step 60 (9.1 s) -- (orig:10.14 | best:8.129 | new:8.129 | diff:0)
Elapsed time for running "default": 0.129s
    step=61 choice=92, par=92, pm=0.0, origval=1.0, newval=1.05
     step 61 (9.2 s) -- (orig:10.14 | best:8.129 | new:8.129 | diff:0)
Elapsed time for running "default": 0.124s
    step=62 choice=184, par=54, pm=1.0, origval=1.0, newval=0.9
     step 62 (9.4 s) -- (orig:10.14 | best:8.129 | new:8.178 | diff:0.04949)
Elapsed time for running "default": 0.127s
    step=63 choice=175, par=45, pm=1.0, origval=1.0, newval=0.9
     step 63 (9.5 s) -- (orig:10.14 | best:8.129 | new:8.134 | diff:0.005194)
Elapsed time for running "default": 0.123s
    step=64 choice=151, par=21, pm=1.0, origval=0.75, newval=0.5249999999999999
     step 64 (9.6 s) ++ (orig:10.14 | best:8.129 | new:8.117 | diff:-0.01149)
Elapsed time for running "default": 0.148s
    step=65 choice=55, par=55, pm=0.0, origval=1.0, newval=1.1
     step 65 (9.8 s) -- (orig:10.14 | best:8.117 | new:8.117 | diff:0.0001221)
Elapsed time for running "default": 0.132s
    step=66 choice=212, par=82, pm=1.0, origval=0.9, newval=0.75
     step 66 (9.9 s) ++ (orig:10.14 | best:8.117 | new:7.896 | diff:-0.2209)
Elapsed time for running "default": 0.374s
    step=67 choice=205, par=75, pm=1.0, origval=0.9, newval=0.75
     step 67 (10.3 s) -- (orig:10.14 | best:7.896 | new:7.896 | diff:0.00000001312)
===  Time limit reached (10.29 > 10.00) (67 steps, orig: 10.14 | best: 7.896 | ratio: 1.2836970145646118) ===

You can then run a simulation with the calibrated parset by passing the name of the new parset to run_sim

[10]:
res_auto_calibrated = P.run_sim(parset='auto_calibrated',result_name='Automatically calibrated')
Elapsed time for running "default": 0.223s

Adding programs

The programs system allows parameter values to be overwritten based on spending on a set of programs. To get started, you will first need a program spreadsheet (progbook). The progbook is specific to a framework and a databook, because it refers to both the compartments and parameters of the model (from the framework) as well as the populations (from the databook).

You can make a new progbook using the .make_progbook() method of the project:

[11]:
P.make_progbook(progbook_path='example_progbook.xlsx', progs=4, data_start=2014, data_end=2018)
Object saved to /home/runner/work/atomica/atomica/docs/examples/example_progbook.xlsx.
[11]:
'/home/runner/work/atomica/atomica/docs/examples/example_progbook.xlsx'

After filling out the progbook, you can load it into the project using the .load_progbook() method. Here, we will load in a pre-filled progbook from the library:

[12]:
P.load_progbook(at.LIBRARY_PATH / 'tb_progbook.xlsx')
[12]:
<atomica.programs.ProgramSet at 0x7fd2ce698690>
[<class 'atomica.programs.ProgramSet'>, <class 'atomica.utils.NamedItem'>]
————————————————————————————————————————————————————————————————————————
Methods:
  _get_code_name()        add_pop()               remove_par()
  _normalize_inputs()     add_program()           remove_pop()
  _read_effects()         copy()                  remove_program()
  _read_spending()        from_spreadsheet()      sample()
  _read_targeting()       get_alloc()             save()
  _write_effects()        get_capacities()        to_spreadsheet()
  _write_spending()       get_outcomes()          to_workbook()
  _write_targeting()      get_prop_coverage()     validate()
  add_comp()              new()                   add_par()
  remove_comp()
————————————————————————————————————————————————————————————————————————
      _book: None
   _formats: None
 _pop_types: ['default']
_references: None
      comps: #0: 'initj':  {'label': 'Initialization population size',
             'type': 'de [...]
    covouts: #0: ('v_num', '0-4'):
                Parameter: v_num
               Population: 0-4
             Baseline  [...]
    created: datetime.datetime(2026, 10, 23, 22, 20, 42, 899146,
             tzinfo=tzutc())
   currency: '$'
    gitinfo: {'branch': 'main', 'hash': 'ec39c2f', 'date':
             '2026-10-24T09:09:37+11 [...]
   modified: datetime.datetime(2026, 10, 23, 22, 20, 43, 465747,
             tzinfo=tzutc())
       name: 'default'
       pars: #0: 'v_num':       {'label': 'Number of vaccinations
             administered', ' [...]
       pops: #0: '0-4':       {'label': 'Children 0-4', 'type':
             'default'}
             #1: '5- [...]
   programs: #0: 'BCG':
             <atomica.programs.Program at 0x7fd2da568770>
             [<class 'atom [...]
       tvec: array([2015., 2016., 2017.])
    version: '1.32.5'
————————————————————————————————————————————————————————————————————————
    Program set name: default
            Programs: ['BCG', 'PCF', 'ACF', 'ACF-p', 'HospDS', 'HospMDR', 'HospXDR', 'AmbDS', 'AmbMDR', 'XDRnew', 'PrisDS', 'PrisDR']
        Date created: 2026-Oct-23 22:20:42 UTC
       Date modified: 2026-Oct-23 22:20:43 UTC
============================================================

This progbook has been added to the list of available progsets:

[13]:
P.progsets.keys()
[13]:
['default']

Running a simulation with programs requires one additional piece of information - a ProgramInstructions instance that specifies

  • What years the programs are active

  • Any overwrites to spending or coverage

In our case, we might just want to run a simulation with programs starting in 2018, so we can create a ProgramInstructions instance accordingly, and then use it to run the simulation:

[14]:
instructions = at.ProgramInstructions(start_year=2018)
res_progs = P.run_sim(parset='default',progset='default',progset_instructions=instructions)
Elapsed time for running "default": 0.280s

Reconciliation

Reconciliation is an operation that aims to change the properties of programs (such as their unit costs) such that the program-calculated parameter values optimally match the databook parameter values in the year the programs become active (or some other specified year). The reconciliation operation can therefore be treated as a mapping from one progset to another. To perform reconciliation, use the reconcile function directly, passing in:

  • the parameter set you want to match

  • the program set to modify

  • the reconciliation year

  • a specification of which aspects of the program set to modify (e.g. unit cost, program outcomes)

The reconcile function returns a new progset, which you can store in the project if desired, or otherwise work with independently:

[15]:
P.progsets['reconciled'] = at.reconcile(project=P, parset='default', progset='default', reconciliation_year=2018, unit_cost_bounds=0.05)[0]
WARNING {reconciliation.py:243} - Reconcilation when parameter is in number units not fully tested
Program set 'default' will be ignored while running project 'default' due to the absence of program set instructions
Elapsed time for running "default": 0.247s
Reconciling in 2018.00, evaluating from 2018.00 up to 2018.25
ASD: Launching with random seed None
    step=1 choice=17, par=5, pm=1.0, origval=7500.0, newval=7125.0
     step 1 (0.0 s) ++ (orig:61.58 | best:61.58 | new:61.50 | diff:-0.08149)
    step=2 choice=23, par=11, pm=1.0, origval=8000.0, newval=7600.0
     step 2 (0.0 s) -- (orig:61.58 | best:61.50 | new:61.50 | diff:0)
    step=3 choice=10, par=10, pm=0.0, origval=5500.0, newval=5775.0
     step 3 (0.0 s) -- (orig:61.58 | best:61.50 | new:61.51 | diff:0.004171)
    step=4 choice=21, par=9, pm=1.0, origval=18000.0, newval=17100.0
     step 4 (0.0 s) ++ (orig:61.58 | best:61.50 | new:61.49 | diff:-0.01364)
    step=5 choice=15, par=3, pm=1.0, origval=2500.0, newval=2375.0
     step 5 (0.0 s) ++ (orig:61.58 | best:61.49 | new:61.48 | diff:-0.005951)
    step=6 choice=1, par=1, pm=0.0, origval=1000.0, newval=1050.0
     step 6 (0.0 s) -- (orig:61.58 | best:61.48 | new:61.49 | diff:0.004431)
    step=7 choice=20, par=8, pm=1.0, origval=4500.0, newval=4275.0
     step 7 (0.0 s) -- (orig:61.58 | best:61.48 | new:61.48 | diff:0)
    step=8 choice=22, par=10, pm=1.0, origval=5500.0, newval=5225.0
     step 8 (0.0 s) -- (orig:61.58 | best:61.48 | new:61.49 | diff:0.003359)
    step=9 choice=23, par=11, pm=1.0, origval=8000.0, newval=7600.0
     step 9 (0.0 s) -- (orig:61.58 | best:61.48 | new:61.48 | diff:0)
    step=10 choice=8, par=8, pm=0.0, origval=4500.0, newval=4725.0
     step 10 (0.0 s) -- (orig:61.58 | best:61.48 | new:61.48 | diff:0)
    step=11 choice=7, par=7, pm=0.0, origval=2700.0, newval=2835.0
     step 11 (0.0 s) -- (orig:61.58 | best:61.48 | new:61.48 | diff:0)
    step=12 choice=16, par=4, pm=1.0, origval=4900.0, newval=4655.0
     step 12 (0.0 s) ++ (orig:61.58 | best:61.48 | new:61.41 | diff:-0.06943)
    step=13 choice=1, par=1, pm=0.0, origval=1000.0, newval=1050.0
     step 13 (0.0 s) -- (orig:61.58 | best:61.41 | new:61.42 | diff:0.004431)
    step=14 choice=6, par=6, pm=0.0, origval=10000.0, newval=10500.0
     step 14 (0.0 s) -- (orig:61.58 | best:61.41 | new:61.44 | diff:0.02744)
    step=15 choice=18, par=6, pm=1.0, origval=10000.0, newval=9500.0
     step 15 (0.0 s) ++ (orig:61.58 | best:61.41 | new:61.38 | diff:-0.02945)
    step=16 choice=9, par=9, pm=0.0, origval=17100.0, newval=18900.0
     step 16 (0.0 s) -- (orig:61.58 | best:61.38 | new:61.41 | diff:0.02538)
    step=17 choice=5, par=5, pm=0.0, origval=7125.0, newval=7875.0
     step 17 (0.0 s) -- (orig:61.58 | best:61.38 | new:61.56 | diff:0.1803)
    step=18 choice=13, par=1, pm=1.0, origval=1000.0, newval=950.0
     step 18 (0.0 s) ++ (orig:61.58 | best:61.38 | new:61.38 | diff:-0.004674)
    step=19 choice=2, par=2, pm=0.0, origval=4000.0, newval=4200.0
     step 19 (0.0 s) -- (orig:61.58 | best:61.38 | new:61.38 | diff:0.00002251)
    step=20 choice=4, par=4, pm=0.0, origval=4655.0, newval=5145.0
     step 20 (0.0 s) -- (orig:61.58 | best:61.38 | new:61.53 | diff:0.1476)
    step=21 choice=12, par=0, pm=1.0, origval=2.5, newval=2.375
     step 21 (0.0 s) ++ (orig:61.58 | best:61.38 | new:61.38 | diff:-0.00002755)
    step=22 choice=4, par=4, pm=0.0, origval=4655.0, newval=4900.0
     step 22 (0.0 s) -- (orig:61.58 | best:61.38 | new:61.45 | diff:0.06943)
    step=23 choice=8, par=8, pm=0.0, origval=4500.0, newval=4725.0
     step 23 (0.0 s) -- (orig:61.58 | best:61.38 | new:61.38 | diff:0)
    step=24 choice=8, par=8, pm=0.0, origval=4500.0, newval=4612.5
     step 24 (0.0 s) -- (orig:61.58 | best:61.38 | new:61.38 | diff:0)
    step=25 choice=0, par=0, pm=0.0, origval=2.375, newval=2.625
     step 25 (0.0 s) -- (orig:61.58 | best:61.38 | new:61.38 | diff:0.00007308)
    step=26 choice=9, par=9, pm=0.0, origval=17100.0, newval=18000.0
     step 26 (0.0 s) -- (orig:61.58 | best:61.38 | new:61.39 | diff:0.01325)
    step=27 choice=6, par=6, pm=0.0, origval=9500.0, newval=10000.0
     step 27 (0.0 s) -- (orig:61.58 | best:61.38 | new:61.41 | diff:0.02945)
    step=28 choice=22, par=10, pm=1.0, origval=5500.0, newval=5225.0
     step 28 (0.0 s) -- (orig:61.58 | best:61.38 | new:61.38 | diff:0.003359)
    step=29 choice=3, par=3, pm=0.0, origval=2375.0, newval=2625.0
     step 29 (0.0 s) -- (orig:61.58 | best:61.38 | new:61.39 | diff:0.01134)
    step=30 choice=0, par=0, pm=0.0, origval=2.375, newval=2.5
     step 30 (0.0 s) -- (orig:61.58 | best:61.38 | new:61.38 | diff:0.00002755)
    step=31 choice=10, par=10, pm=0.0, origval=5500.0, newval=5775.0
     step 31 (0.0 s) -- (orig:61.58 | best:61.38 | new:61.38 | diff:0.004171)
    step=32 choice=11, par=11, pm=0.0, origval=8000.0, newval=8400.0
     step 32 (0.0 s) -- (orig:61.58 | best:61.38 | new:61.38 | diff:0)
    step=33 choice=3, par=3, pm=0.0, origval=2375.0, newval=2500.0
     step 33 (0.0 s) -- (orig:61.58 | best:61.38 | new:61.39 | diff:0.005951)
    step=34 choice=19, par=7, pm=1.0, origval=2700.0, newval=2565.0
     step 34 (0.0 s) -- (orig:61.58 | best:61.38 | new:61.38 | diff:0)
    step=35 choice=9, par=9, pm=0.0, origval=17100.0, newval=17550.0
     step 35 (0.0 s) -- (orig:61.58 | best:61.38 | new:61.39 | diff:0.006771)
    step=36 choice=1, par=1, pm=0.0, origval=950.0, newval=975.0
     step 36 (0.0 s) -- (orig:61.58 | best:61.38 | new:61.38 | diff:0.002367)
    step=37 choice=20, par=8, pm=1.0, origval=4500.0, newval=4275.0
     step 37 (0.0 s) -- (orig:61.58 | best:61.38 | new:61.38 | diff:0)
    step=38 choice=7, par=7, pm=0.0, origval=2700.0, newval=2835.0
     step 38 (0.0 s) -- (orig:61.58 | best:61.38 | new:61.38 | diff:0)
    step=39 choice=14, par=2, pm=1.0, origval=4000.0, newval=3800.0
     step 39 (0.0 s) ++ (orig:61.58 | best:61.38 | new:61.38 | diff:-0.00002487)
    step=40 choice=4, par=4, pm=0.0, origval=4655.0, newval=4777.5
     step 40 (0.0 s) -- (orig:61.58 | best:61.38 | new:61.41 | diff:0.03338)
    step=41 choice=20, par=8, pm=1.0, origval=4500.0, newval=4387.5
     step 41 (0.0 s) -- (orig:61.58 | best:61.38 | new:61.38 | diff:0)
    step=42 choice=23, par=11, pm=1.0, origval=8000.0, newval=7800.0
     step 42 (0.0 s) -- (orig:61.58 | best:61.38 | new:61.38 | diff:0)
    step=43 choice=3, par=3, pm=0.0, origval=2375.0, newval=2437.5
     step 43 (0.0 s) -- (orig:61.58 | best:61.38 | new:61.38 | diff:0.003052)
    step=44 choice=23, par=11, pm=1.0, origval=8000.0, newval=7900.0
     step 44 (0.0 s) -- (orig:61.58 | best:61.38 | new:61.38 | diff:0)
    step=45 choice=9, par=9, pm=0.0, origval=17100.0, newval=17325.0
     step 45 (0.0 s) -- (orig:61.58 | best:61.38 | new:61.38 | diff:0.003424)
    step=46 choice=11, par=11, pm=0.0, origval=8000.0, newval=8400.0
     step 46 (0.0 s) -- (orig:61.58 | best:61.38 | new:61.38 | diff:0)
    step=47 choice=5, par=5, pm=0.0, origval=7125.0, newval=7500.0
     step 47 (0.0 s) -- (orig:61.58 | best:61.38 | new:61.46 | diff:0.08149)
    step=48 choice=10, par=10, pm=0.0, origval=5500.0, newval=5637.5
     step 48 (0.0 s) -- (orig:61.58 | best:61.38 | new:61.38 | diff:0.001094)
    step=49 choice=3, par=3, pm=0.0, origval=2375.0, newval=2406.25
     step 49 (0.0 s) -- (orig:61.58 | best:61.38 | new:61.38 | diff:0.001546)
    step=50 choice=3, par=3, pm=0.0, origval=2375.0, newval=2390.625
     step 50 (0.0 s) -- (orig:61.58 | best:61.38 | new:61.38 | diff:0.0007779)
    step=51 choice=19, par=7, pm=1.0, origval=2700.0, newval=2565.0
     step 51 (0.0 s) -- (orig:61.58 | best:61.38 | new:61.38 | diff:0)
    step=52 choice=0, par=0, pm=0.0, origval=2.375, newval=2.4375
     step 52 (0.0 s) -- (orig:61.58 | best:61.38 | new:61.38 | diff:0.00001114)
    step=53 choice=2, par=2, pm=0.0, origval=3800.0, newval=4000.0
     step 53 (0.0 s) -- (orig:61.58 | best:61.38 | new:61.38 | diff:0.00002487)
    step=54 choice=8, par=8, pm=0.0, origval=4500.0, newval=4556.25
     step 54 (0.0 s) -- (orig:61.58 | best:61.38 | new:61.38 | diff:0)
    step=55 choice=5, par=5, pm=0.0, origval=7125.0, newval=7312.5
     step 55 (0.0 s) -- (orig:61.58 | best:61.38 | new:61.42 | diff:0.03816)
    step=56 choice=10, par=10, pm=0.0, origval=5500.0, newval=5568.75
     step 56 (0.0 s) -- (orig:61.58 | best:61.38 | new:61.38 | diff:0.0002804)
    step=57 choice=4, par=4, pm=0.0, origval=4655.0, newval=4716.25
     step 57 (0.0 s) -- (orig:61.58 | best:61.38 | new:61.40 | diff:0.01632)
    step=58 choice=6, par=6, pm=0.0, origval=9500.0, newval=9750.0
     step 58 (0.0 s) -- (orig:61.58 | best:61.38 | new:61.39 | diff:0.01499)
    step=59 choice=0, par=0, pm=0.0, origval=2.375, newval=2.40625
     step 59 (0.0 s) -- (orig:61.58 | best:61.38 | new:61.38 | diff:0.000004857)
    step=60 choice=9, par=9, pm=0.0, origval=17100.0, newval=17212.5
     step 60 (0.0 s) -- (orig:61.58 | best:61.38 | new:61.38 | diff:0.001722)
    step=61 choice=7, par=7, pm=0.0, origval=2700.0, newval=2767.5
     step 61 (0.0 s) -- (orig:61.58 | best:61.38 | new:61.38 | diff:0)
    step=62 choice=19, par=7, pm=1.0, origval=2700.0, newval=2632.5
     step 62 (0.0 s) -- (orig:61.58 | best:61.38 | new:61.38 | diff:0)
    step=63 choice=0, par=0, pm=0.0, origval=2.375, newval=2.390625
     step 63 (0.0 s) -- (orig:61.58 | best:61.38 | new:61.38 | diff:0.000002243)
    step=64 choice=8, par=8, pm=0.0, origval=4500.0, newval=4528.125
     step 64 (0.0 s) -- (orig:61.58 | best:61.38 | new:61.38 | diff:0)
    step=65 choice=20, par=8, pm=1.0, origval=4500.0, newval=4443.75
     step 65 (0.0 s) -- (orig:61.58 | best:61.38 | new:61.38 | diff:0)
    step=66 choice=11, par=11, pm=0.0, origval=8000.0, newval=8200.0
     step 66 (0.0 s) -- (orig:61.58 | best:61.38 | new:61.38 | diff:0)
    step=67 choice=5, par=5, pm=0.0, origval=7125.0, newval=7218.75
     step 67 (0.0 s) -- (orig:61.58 | best:61.38 | new:61.40 | diff:0.01837)
    step=68 choice=22, par=10, pm=1.0, origval=5500.0, newval=5362.5
     step 68 (0.0 s) -- (orig:61.58 | best:61.38 | new:61.38 | diff:0.001209)
    step=69 choice=1, par=1, pm=0.0, origval=950.0, newval=962.5
     step 69 (0.0 s) -- (orig:61.58 | best:61.38 | new:61.38 | diff:0.001191)
    step=70 choice=5, par=5, pm=0.0, origval=7125.0, newval=7171.875
     step 70 (0.0 s) -- (orig:61.58 | best:61.38 | new:61.39 | diff:0.009000)
    step=71 choice=2, par=2, pm=0.0, origval=3800.0, newval=3900.0
     step 71 (0.0 s) -- (orig:61.58 | best:61.38 | new:61.38 | diff:0.00001275)
    step=72 choice=0, par=0, pm=0.0, origval=2.375, newval=2.3828125
     step 72 (0.0 s) -- (orig:61.58 | best:61.38 | new:61.38 | diff:0.000001074)
    step=73 choice=7, par=7, pm=0.0, origval=2700.0, newval=2733.75
     step 73 (0.0 s) -- (orig:61.58 | best:61.38 | new:61.38 | diff:0)
    step=74 choice=10, par=10, pm=0.0, origval=5500.0, newval=5534.375
     step 74 (0.0 s) -- (orig:61.58 | best:61.38 | new:61.38 | diff:0.00007096)
    step=75 choice=19, par=7, pm=1.0, origval=2700.0, newval=2666.25
     step 75 (0.0 s) -- (orig:61.58 | best:61.38 | new:61.38 | diff:0)
    step=76 choice=11, par=11, pm=0.0, origval=8000.0, newval=8100.0
     step 76 (0.1 s) -- (orig:61.58 | best:61.38 | new:61.38 | diff:0)
    step=77 choice=7, par=7, pm=0.0, origval=2700.0, newval=2716.875
     step 77 (0.1 s) -- (orig:61.58 | best:61.38 | new:61.38 | diff:0)
    step=78 choice=8, par=8, pm=0.0, origval=4500.0, newval=4514.0625
     step 78 (0.1 s) -- (orig:61.58 | best:61.38 | new:61.38 | diff:0)
    step=79 choice=22, par=10, pm=1.0, origval=5500.0, newval=5431.25
     step 79 (0.1 s) -- (orig:61.58 | best:61.38 | new:61.38 | diff:0.0002947)
    step=80 choice=11, par=11, pm=0.0, origval=8000.0, newval=8050.0
     step 80 (0.1 s) -- (orig:61.58 | best:61.38 | new:61.38 | diff:0)
    step=81 choice=11, par=11, pm=0.0, origval=8000.0, newval=8025.0
     step 81 (0.1 s) -- (orig:61.58 | best:61.38 | new:61.38 | diff:0)
    step=82 choice=23, par=11, pm=1.0, origval=8000.0, newval=7950.0
     step 82 (0.1 s) -- (orig:61.58 | best:61.38 | new:61.38 | diff:0)
    step=83 choice=3, par=3, pm=0.0, origval=2375.0, newval=2382.8125
     step 83 (0.1 s) -- (orig:61.58 | best:61.38 | new:61.38 | diff:0.0003902)
    step=84 choice=10, par=10, pm=0.0, origval=5500.0, newval=5517.1875
     step 84 (0.1 s) -- (orig:61.58 | best:61.38 | new:61.38 | diff:0.00001785)
    step=85 choice=9, par=9, pm=0.0, origval=17100.0, newval=17156.25
     step 85 (0.1 s) -- (orig:61.58 | best:61.38 | new:61.38 | diff:0.0008633)
    step=86 choice=23, par=11, pm=1.0, origval=8000.0, newval=7975.0
     step 86 (0.1 s) -- (orig:61.58 | best:61.38 | new:61.38 | diff:0)
    step=87 choice=19, par=7, pm=1.0, origval=2700.0, newval=2683.125
     step 87 (0.1 s) -- (orig:61.58 | best:61.38 | new:61.38 | diff:0)
    step=88 choice=6, par=6, pm=0.0, origval=9500.0, newval=9625.0
     step 88 (0.1 s) -- (orig:61.58 | best:61.38 | new:61.39 | diff:0.007562)
    step=89 choice=15, par=3, pm=1.0, origval=2375.0, newval=2375.0
     step 89 (0.1 s) -- (orig:61.58 | best:61.38 | new:61.38 | diff:0)
    step=90 choice=11, par=11, pm=0.0, origval=8000.0, newval=8012.5
     step 90 (0.1 s) -- (orig:61.58 | best:61.38 | new:61.38 | diff:0)
    step=91 choice=6, par=6, pm=0.0, origval=9500.0, newval=9562.5
     step 91 (0.1 s) -- (orig:61.58 | best:61.38 | new:61.38 | diff:0.003798)
    step=92 choice=11, par=11, pm=0.0, origval=8000.0, newval=8006.25
     step 92 (0.1 s) -- (orig:61.58 | best:61.38 | new:61.38 | diff:0)
    step=93 choice=20, par=8, pm=1.0, origval=4500.0, newval=4471.875
     step 93 (0.1 s) -- (orig:61.58 | best:61.38 | new:61.38 | diff:0)
    step=94 choice=2, par=2, pm=0.0, origval=3800.0, newval=3850.0
     step 94 (0.1 s) -- (orig:61.58 | best:61.38 | new:61.38 | diff:0.000006460)
    step=95 choice=3, par=3, pm=0.0, origval=2375.0, newval=2378.90625
     step 95 (0.1 s) -- (orig:61.58 | best:61.38 | new:61.38 | diff:0.0001954)
    step=96 choice=6, par=6, pm=0.0, origval=9500.0, newval=9531.25
     step 96 (0.1 s) -- (orig:61.58 | best:61.38 | new:61.38 | diff:0.001903)
    step=97 choice=8, par=8, pm=0.0, origval=4500.0, newval=4507.03125
     step 97 (0.1 s) -- (orig:61.58 | best:61.38 | new:61.38 | diff:0)
    step=98 choice=20, par=8, pm=1.0, origval=4500.0, newval=4485.9375
     step 98 (0.1 s) -- (orig:61.58 | best:61.38 | new:61.38 | diff:0)
    step=99 choice=22, par=10, pm=1.0, origval=5500.0, newval=5465.625
     step 99 (0.1 s) -- (orig:61.58 | best:61.38 | new:61.38 | diff:0.00007276)
    step=100 choice=19, par=7, pm=1.0, origval=2700.0, newval=2691.5625
     step 100 (0.1 s) -- (orig:61.58 | best:61.38 | new:61.38 | diff:0)
    step=101 choice=7, par=7, pm=0.0, origval=2700.0, newval=2708.4375
     step 101 (0.1 s) -- (orig:61.58 | best:61.38 | new:61.38 | diff:0)
    step=102 choice=1, par=1, pm=0.0, origval=950.0, newval=956.25
     step 102 (0.1 s) -- (orig:61.58 | best:61.38 | new:61.38 | diff:0.0005974)
    step=103 choice=22, par=10, pm=1.0, origval=5500.0, newval=5482.8125
     step 103 (0.1 s) -- (orig:61.58 | best:61.38 | new:61.38 | diff:0.00001808)
    step=104 choice=2, par=2, pm=0.0, origval=3800.0, newval=3825.0
     step 104 (0.1 s) -- (orig:61.58 | best:61.38 | new:61.38 | diff:0.000003251)
    step=105 choice=8, par=8, pm=0.0, origval=4500.0, newval=4503.515625
     step 105 (0.1 s) -- (orig:61.58 | best:61.38 | new:61.38 | diff:0)
    step=106 choice=6, par=6, pm=0.0, origval=9500.0, newval=9515.625
     step 106 (0.1 s) -- (orig:61.58 | best:61.38 | new:61.38 | diff:0.0009528)
    step=107 choice=8, par=8, pm=0.0, origval=4500.0, newval=4501.7578125
     step 107 (0.1 s) -- (orig:61.58 | best:61.38 | new:61.38 | diff:0)
    step=108 choice=18, par=6, pm=1.0, origval=9500.0, newval=9500.0
     step 108 (0.1 s) -- (orig:61.58 | best:61.38 | new:61.38 | diff:0)
    step=109 choice=20, par=8, pm=1.0, origval=4500.0, newval=4492.96875
     step 109 (0.1 s) -- (orig:61.58 | best:61.38 | new:61.38 | diff:0)
    step=110 choice=14, par=2, pm=1.0, origval=3800.0, newval=3800.0
     step 110 (0.1 s) -- (orig:61.58 | best:61.38 | new:61.38 | diff:0)
    step=111 choice=22, par=10, pm=1.0, origval=5500.0, newval=5491.40625
     step 111 (0.1 s) -- (orig:61.58 | best:61.38 | new:61.38 | diff:0.000004505)
    step=112 choice=16, par=4, pm=1.0, origval=4655.0, newval=4655.0
     step 112 (0.1 s) -- (orig:61.58 | best:61.38 | new:61.38 | diff:0)
    step=113 choice=4, par=4, pm=0.0, origval=4655.0, newval=4685.625
     step 113 (0.1 s) -- (orig:61.58 | best:61.38 | new:61.39 | diff:0.008065)
    step=114 choice=5, par=5, pm=0.0, origval=7125.0, newval=7148.4375
     step 114 (0.1 s) -- (orig:61.58 | best:61.38 | new:61.38 | diff:0.004453)
    step=115 choice=4, par=4, pm=0.0, origval=4655.0, newval=4670.3125
     step 115 (0.1 s) -- (orig:61.58 | best:61.38 | new:61.38 | diff:0.004008)
    step=116 choice=5, par=5, pm=0.0, origval=7125.0, newval=7136.71875
     step 116 (0.1 s) -- (orig:61.58 | best:61.38 | new:61.38 | diff:0.002214)
    step=117 choice=19, par=7, pm=1.0, origval=2700.0, newval=2695.78125
     step 117 (0.1 s) -- (orig:61.58 | best:61.38 | new:61.38 | diff:0)
    step=118 choice=11, par=11, pm=0.0, origval=8000.0, newval=8003.125
     step 118 (0.1 s) -- (orig:61.58 | best:61.38 | new:61.38 | diff:0)
    step=119 choice=5, par=5, pm=0.0, origval=7125.0, newval=7130.859375
     step 119 (0.1 s) -- (orig:61.58 | best:61.38 | new:61.38 | diff:0.001104)
    step=120 choice=4, par=4, pm=0.0, origval=4655.0, newval=4662.65625
     step 120 (0.1 s) -- (orig:61.58 | best:61.38 | new:61.38 | diff:0.001998)
    step=121 choice=10, par=10, pm=0.0, origval=5500.0, newval=5508.59375
     step 121 (0.1 s) -- (orig:61.58 | best:61.38 | new:61.38 | diff:0.000004477)
    step=122 choice=7, par=7, pm=0.0, origval=2700.0, newval=2704.21875
     step 122 (0.1 s) -- (orig:61.58 | best:61.38 | new:61.38 | diff:0)
    step=123 choice=17, par=5, pm=1.0, origval=7125.0, newval=7125.0
     step 123 (0.1 s) -- (orig:61.58 | best:61.38 | new:61.38 | diff:0)
    step=124 choice=15, par=3, pm=1.0, origval=2375.0, newval=2375.0
     step 124 (0.1 s) -- (orig:61.58 | best:61.38 | new:61.38 | diff:0)
    step=125 choice=9, par=9, pm=0.0, origval=17100.0, newval=17128.125
     step 125 (0.1 s) -- (orig:61.58 | best:61.38 | new:61.38 | diff:0.0004323)
    step=126 choice=20, par=8, pm=1.0, origval=4500.0, newval=4496.484375
     step 126 (0.1 s) -- (orig:61.58 | best:61.38 | new:61.38 | diff:0)
    step=127 choice=4, par=4, pm=0.0, origval=4655.0, newval=4658.828125
     step 127 (0.1 s) -- (orig:61.58 | best:61.38 | new:61.38 | diff:0.0009972)
    step=128 choice=0, par=0, pm=0.0, origval=2.375, newval=2.37890625
     step 128 (0.1 s) -- (orig:61.58 | best:61.38 | new:61.38 | diff:0.0000005250)
    step=129 choice=17, par=5, pm=1.0, origval=7125.0, newval=7125.0
     step 129 (0.1 s) -- (orig:61.58 | best:61.38 | new:61.38 | diff:0)
    step=130 choice=7, par=7, pm=0.0, origval=2700.0, newval=2702.109375
     step 130 (0.1 s) -- (orig:61.58 | best:61.38 | new:61.38 | diff:0)
    step=131 choice=19, par=7, pm=1.0, origval=2700.0, newval=2697.890625
     step 131 (0.1 s) -- (orig:61.58 | best:61.38 | new:61.38 | diff:0)
    step=132 choice=1, par=1, pm=0.0, origval=950.0, newval=953.125
     step 132 (0.1 s) -- (orig:61.58 | best:61.38 | new:61.38 | diff:0.0002992)
===  Relative improvement too small (0.000004640 < 0.001000) (132 steps, orig: 61.58 | best: 61.38 | ratio: 1.0033347274753137) ===

You can then run simulations with the modified program set. You can also save the new programset to a progbook if you wish to edit it further in Excel:

[16]:
P.progsets['reconciled'].save('reconciled_progset.xlsx');
Object saved to /home/runner/work/atomica/atomica/docs/examples/reconciled_progset.xlsx.

Scenarios

A scenario involves overriding some aspect of the simulation that would otherwise be specified in the databook or progbook. There are three kinds of scenarios

  • Parameter scenarios, when you want to test the effect of a specific parameter value

  • Budget scenarios, when you want to examine the outcomes of specific spending values

  • Coverage scenarios, when you want to examine the effect of specific program coverages irrespective of spending

Examples of these scenarios are shown below:

Parameter scenarios

[17]:
scvalues = dict()
scvalues['b_rate'] = dict()
scvalues['b_rate']['0-4'] = dict()
scvalues['b_rate']['0-4']["t"] = [2015, 2020, 2035]
scvalues['b_rate']['0-4']["y"] = [270000, 220000, 220000]
scen = P.make_scenario(which='parameter', name="Reduced births", scenario_values=scvalues)
res_par_scen = scen.run(P, P.parsets["default"]);

# Plot the parameter and compare to scenario input values
d = at.PlotData(res_par_scen,outputs='b_rate',pops='0-4')
at.plot_series(d)
plt.scatter(scvalues['b_rate']['0-4']["t"],scvalues['b_rate']['0-4']["y"],color='r')
Elapsed time for running "default": 0.205s
[17]:
<matplotlib.collections.PathCollection at 0x7fd2d93fcad0>
../_images/examples_Basic-workflow_36_2.svg

Budget scenarios

To run a program-related scenario, such as a budget or coverage scenario, it is not necessary to construct a Scenario object. Instead, you can directly create and use the program instructions that define the scenario:

[18]:
alloc = P.progsets[0].get_alloc(2018)
doubled_budget = {x:v*2 for x,v in alloc.items()}
instructions = at.ProgramInstructions(start_year=2018,alloc=doubled_budget)
res_baseline = P.run_sim(parset='default',progset='default',progset_instructions=at.ProgramInstructions(start_year=2018),result_name='Baseline')
res_budget_scen = P.run_sim(parset='default',progset='default',progset_instructions=instructions,result_name='Doubled');

d = at.PlotData.programs([res_baseline,res_budget_scen]).interpolate(2018)
at.plot_bars(d,stack_outputs='all');
Elapsed time for running "default": 0.274s
Elapsed time for running "default": 0.519s
../_images/examples_Basic-workflow_38_1.svg

Alternatively, you can create a full scenario object by storing the instructions in a CombinedScenario. The CombinedScenario optionally allows you to mix parameter and program scenarios.

[19]:
scen = P.make_scenario(which='combined', name="Doubled (scen)", instructions=instructions)
res_combined_scen = scen.run(P, parset='default',progset='default')

d = at.PlotData.programs([res_baseline,res_budget_scen, res_combined_scen]).interpolate(2018)
at.plot_bars(d,stack_outputs='all');
Elapsed time for running "default": 0.282s
../_images/examples_Basic-workflow_40_1.svg

Coverage scenarios

With coverage scenarios, the program instructions override a program’s coverage. Therefore, the spending values and coverage values may not match up with what is entered in the program book. If running coverage scenarios, take care not to use the spending values for such results - typically this is not a problem, because if you did have a particular spending amount in mind, then it would be better to use a budget scenario.

[20]:
half_coverage = {x:0.5 for x in P.progsets[0].programs.keys()}
instructions = at.ProgramInstructions(start_year=2018,coverage=half_coverage)
scen = at.CombinedScenario(name='Reduced coverage',instructions=instructions)
res_cov_scen = scen.run(P,parset='default',progset='default');
Elapsed time for running "default": 0.294s

Optimization

The role of optimization is to produce a set of program spending overwrites that improves the model output in some way. It is thus an operation that maps one set of program instructions to another, where the optimized program instructions contain the optimized allocation. An optimization consists of three parts

  • adjustments that specify what parts of the program instructions to change, and how to change them

  • measurables that define optimality (e.g. reducing new infections, maximizing people alive)

  • constraints that must be satisfied, such as fixed total spending

An Optimization object contains these three items, as well any additional parameters specific to the optimization algorithm (e.g. the optimization method, the maximum run time).

The optimize function uses the Optimization to modify a particular set of program instructions. It therefore takes in

  • A parset and progset to use

  • A program instructions instance to optimize

  • An optimization object, that specifies how to perform the optimization

[21]:
instructions = at.ProgramInstructions(alloc=P.progsets[0],start_year=2020) # Instructions for default spending
adjustments = [at.SpendingAdjustment(x,2020,'rel',0.,2.) for x in instructions.alloc.keys()]
measurables = at.MaximizeCascadeStage(None,2020)
constraints = at.TotalSpendConstraint() # Cap total spending in all years
optimization = at.Optimization(name='default', adjustments=adjustments, measurables=measurables,constraints=constraints,maxtime=10) # Evaluate from 2020 to end of simulation
optimized_instructions = at.optimize(P, optimization, parset=P.parsets["default"], progset=P.progsets['default'], instructions=instructions)
ASD: Launching with random seed None
ASD: Warning, negative objective function starting value (-11728.9) could lead to unexpected behavior
    step=1 choice=11, par=11, pm=0.0, origval=240000.0, newval=264000.0
     step 1 (0.5 s) -- (orig:-11730 | best:-11730 | new:-11730 | diff:0)
ASD: Warning, negative objective function starting value (-11728.9) could lead to unexpected behavior
    step=2 choice=9, par=9, pm=0.0, origval=961200.0, newval=1057320.0
     step 2 (0.8 s) -- (orig:-11730 | best:-11730 | new:-11730 | diff:0)
ASD: Warning, negative objective function starting value (-11728.9) could lead to unexpected behavior
    step=3 choice=22, par=10, pm=1.0, origval=1314500.0, newval=1183050.0
     step 3 (1.1 s) -- (orig:-11730 | best:-11730 | new:-11730 | diff:0)
ASD: Warning, negative objective function starting value (-11728.9) could lead to unexpected behavior
    step=4 choice=4, par=4, pm=0.0, origval=109461100.0, newval=120407210.0
     step 4 (1.4 s) -- (orig:-11730 | best:-11730 | new:-11730 | diff:0)
ASD: Warning, negative objective function starting value (-11728.9) could lead to unexpected behavior
    step=5 choice=16, par=4, pm=1.0, origval=109461100.0, newval=98514990.0
     step 5 (1.7 s) -- (orig:-11730 | best:-11730 | new:-11730 | diff:0)
ASD: Warning, negative objective function starting value (-11728.9) could lead to unexpected behavior
    step=6 choice=2, par=2, pm=0.0, origval=25282133.33333333, newval=27810346.66666666
     step 6 (2.0 s) -- (orig:-11730 | best:-11730 | new:-11730 | diff:0)
ASD: Warning, negative objective function starting value (-11728.9) could lead to unexpected behavior
    step=7 choice=16, par=4, pm=1.0, origval=109461100.0, newval=103988045.0
     step 7 (2.6 s) -- (orig:-11730 | best:-11730 | new:-11730 | diff:0)
ASD: Warning, negative objective function starting value (-11728.9) could lead to unexpected behavior
    step=8 choice=1, par=1, pm=0.0, origval=25568000.0, newval=28124800.0
     step 8 (2.9 s) -- (orig:-11730 | best:-11730 | new:-11730 | diff:0)
ASD: Warning, negative objective function starting value (-11728.9) could lead to unexpected behavior
    step=9 choice=14, par=2, pm=1.0, origval=25282133.33333333, newval=22753919.999999996
     step 9 (3.1 s) -- (orig:-11730 | best:-11730 | new:-11730 | diff:0)
ASD: Warning, negative objective function starting value (-11728.9) could lead to unexpected behavior
    step=10 choice=0, par=0, pm=0.0, origval=345000.0, newval=379500.0
     step 10 (3.4 s) -- (orig:-11730 | best:-11730 | new:-11730 | diff:0)
ASD: Warning, negative objective function starting value (-11728.9) could lead to unexpected behavior
    step=11 choice=21, par=9, pm=1.0, origval=961200.0, newval=865080.0
     step 11 (3.7 s) -- (orig:-11730 | best:-11730 | new:-11730 | diff:0)
ASD: Warning, negative objective function starting value (-11728.9) could lead to unexpected behavior
    step=12 choice=13, par=1, pm=1.0, origval=25568000.0, newval=23011200.0
     step 12 (4.0 s) -- (orig:-11730 | best:-11730 | new:-11730 | diff:0)
ASD: Warning, negative objective function starting value (-11728.9) could lead to unexpected behavior
    step=13 choice=12, par=0, pm=1.0, origval=345000.0, newval=310500.0
     step 13 (4.6 s) -- (orig:-11730 | best:-11730 | new:-11730 | diff:0)
ASD: Warning, negative objective function starting value (-11728.9) could lead to unexpected behavior
    step=14 choice=14, par=2, pm=1.0, origval=25282133.33333333, newval=24018026.66666666
     step 14 (4.8 s) -- (orig:-11730 | best:-11730 | new:-11730 | diff:0)
ASD: Warning, negative objective function starting value (-11728.9) could lead to unexpected behavior
    step=15 choice=16, par=4, pm=1.0, origval=109461100.0, newval=106724572.5
     step 15 (5.1 s) -- (orig:-11730 | best:-11730 | new:-11730 | diff:0)
ASD: Warning, negative objective function starting value (-11728.9) could lead to unexpected behavior
    step=16 choice=22, par=10, pm=1.0, origval=1314500.0, newval=1248775.0
     step 16 (5.4 s) -- (orig:-11730 | best:-11730 | new:-11730 | diff:0)
ASD: Warning, negative objective function starting value (-11728.9) could lead to unexpected behavior
    step=17 choice=21, par=9, pm=1.0, origval=961200.0, newval=913140.0
     step 17 (5.7 s) -- (orig:-11730 | best:-11730 | new:-11730 | diff:0)
ASD: Warning, negative objective function starting value (-11728.9) could lead to unexpected behavior
    step=18 choice=21, par=9, pm=1.0, origval=961200.0, newval=937170.0
     step 18 (6.0 s) -- (orig:-11730 | best:-11730 | new:-11730 | diff:0)
ASD: Warning, negative objective function starting value (-11728.9) could lead to unexpected behavior
    step=19 choice=5, par=5, pm=0.0, origval=8205000.0, newval=9025500.0
     step 19 (6.3 s) -- (orig:-11730 | best:-11730 | new:-11730 | diff:0)
ASD: Warning, negative objective function starting value (-11728.9) could lead to unexpected behavior
    step=20 choice=0, par=0, pm=0.0, origval=345000.0, newval=362250.0
     step 20 (6.8 s) -- (orig:-11730 | best:-11730 | new:-11730 | diff:0)
ASD: Warning, negative objective function starting value (-11728.9) could lead to unexpected behavior
    step=21 choice=15, par=3, pm=1.0, origval=893333.3333333334, newval=804000.0
     step 21 (7.1 s) -- (orig:-11730 | best:-11730 | new:-11730 | diff:0)
ASD: Warning, negative objective function starting value (-11728.9) could lead to unexpected behavior
    step=22 choice=23, par=11, pm=1.0, origval=240000.0, newval=216000.0
     step 22 (7.4 s) -- (orig:-11730 | best:-11730 | new:-11730 | diff:0)
ASD: Warning, negative objective function starting value (-11728.9) could lead to unexpected behavior
    step=23 choice=10, par=10, pm=0.0, origval=1314500.0, newval=1445950.0
     step 23 (7.7 s) -- (orig:-11730 | best:-11730 | new:-11730 | diff:0)
ASD: Warning, negative objective function starting value (-11728.9) could lead to unexpected behavior
    step=24 choice=12, par=0, pm=1.0, origval=345000.0, newval=327750.0
     step 24 (8.0 s) -- (orig:-11730 | best:-11730 | new:-11730 | diff:0)
ASD: Warning, negative objective function starting value (-11728.9) could lead to unexpected behavior
    step=25 choice=0, par=0, pm=0.0, origval=345000.0, newval=353625.0
     step 25 (8.2 s) -- (orig:-11730 | best:-11730 | new:-11730 | diff:0)
ASD: Warning, negative objective function starting value (-11728.9) could lead to unexpected behavior
    step=26 choice=17, par=5, pm=1.0, origval=8205000.0, newval=7384500.0
     step 26 (8.8 s) -- (orig:-11730 | best:-11730 | new:-11730 | diff:0)
ASD: Warning, negative objective function starting value (-11728.9) could lead to unexpected behavior
    step=27 choice=10, par=10, pm=0.0, origval=1314500.0, newval=1380225.0
     step 27 (9.1 s) -- (orig:-11730 | best:-11730 | new:-11730 | diff:0)
ASD: Warning, negative objective function starting value (-11728.9) could lead to unexpected behavior
    step=28 choice=1, par=1, pm=0.0, origval=25568000.0, newval=26846400.0
     step 28 (9.4 s) -- (orig:-11730 | best:-11730 | new:-11730 | diff:0)
ASD: Warning, negative objective function starting value (-11728.9) could lead to unexpected behavior
    step=29 choice=6, par=6, pm=0.0, origval=1246000.0, newval=1370600.0
     step 29 (9.7 s) -- (orig:-11730 | best:-11730 | new:-11730 | diff:0)
ASD: Warning, negative objective function starting value (-11728.9) could lead to unexpected behavior
    step=30 choice=3, par=3, pm=0.0, origval=893333.3333333334, newval=982666.6666666667
     step 30 (10.0 s) -- (orig:-11730 | best:-11730 | new:-11730 | diff:0)
ASD: Warning, negative objective function starting value (-11728.9) could lead to unexpected behavior
    step=31 choice=0, par=0, pm=0.0, origval=345000.0, newval=349312.5
     step 31 (10.3 s) -- (orig:-11730 | best:-11730 | new:-11730 | diff:0)
===  Time limit reached (10.28 > 10.00) (31 steps, orig: -11730 | best: -11730 | ratio: 1.0) ===

The function returns a set of optimized instructions, that can then be used to run a simulation

[22]:
res_optimized = P.run_sim(parset='default',progset='default',progset_instructions=optimized_instructions)
Elapsed time for running "default": 0.596s

For more details on the optimization system, see the general documentation on optimization.