Plot unit conversions

This notebook demonstrates some examples of different kinds of units, and the circumstances under which they are converted and displayed.

[1]:
%matplotlib inline
import sys
import atomica as at
import matplotlib.pyplot as plt
import numpy as np
import sciris as sc
from IPython.display import display, HTML
Atomica 1.12.1 (2019-08-20) -- (c) the Atomica development team
2019-08-20 07:30:36.988182
[2]:
testdir = at.parent_dir()
P = at.Project(framework='unit_demo_framework.xlsx',databook='unit_demo_databook.xlsx')
P.load_progbook('unit_demo_progbook.xlsx')
res = P.run_sim('default','default',at.ProgramInstructions(start_year=2018))
Elapsed time for running "default": 0.0145s
Elapsed time for running "default": 0.0294s

This test example has examples of parameters with different timescales, and different types of programs.

Parameters

  • recrate - Duration in months

  • infdeath - Weekly probability

  • susdeath - Daily probability

  • foi - Annual probability

[3]:
d = at.PlotData(res,outputs=['recrate','infdeath','susdeath','foi','sus:inf','susdeath:flow','dead'],pops='adults')
at.plot_series(d,axis='pops');
../_images/examples_Plot-Units_4_0.png
../_images/examples_Plot-Units_4_1.png
../_images/examples_Plot-Units_4_2.png
../_images/examples_Plot-Units_4_3.png
../_images/examples_Plot-Units_4_4.png
../_images/examples_Plot-Units_4_5.png
../_images/examples_Plot-Units_4_6.png

Notice that parameters are plotted in their native units. For example, a probability per day is shown as probability per day, matching the numbers that were entered in the databook.

Aggregating these units without specifying the aggregation method will result in either integration or averaging as most appropriate for the units of the underlying quantity:

[4]:
for output in ['recrate','infdeath','susdeath','foi','sus:inf','susdeath:flow','dead']:
    d = at.PlotData(res,outputs=output,pops='adults',t_bins=10)
    at.plot_bars(d);
/opt/hostedtoolcache/Python/3.7.4/x64/lib/python3.7/site-packages/scipy-1.3.1-py3.7-linux-x86_64.egg/scipy/integrate/quadrature.py:251: AccuracyWarning: maxiter (465) exceeded. Latest difference = 3.330955e-02
  AccuracyWarning)
/opt/hostedtoolcache/Python/3.7.4/x64/lib/python3.7/site-packages/scipy-1.3.1-py3.7-linux-x86_64.egg/scipy/integrate/quadrature.py:251: AccuracyWarning: maxiter (465) exceeded. Latest difference = 2.757952e-05
  AccuracyWarning)
/opt/hostedtoolcache/Python/3.7.4/x64/lib/python3.7/site-packages/scipy-1.3.1-py3.7-linux-x86_64.egg/scipy/integrate/quadrature.py:251: AccuracyWarning: maxiter (465) exceeded. Latest difference = 1.424352e-06
  AccuracyWarning)
/opt/hostedtoolcache/Python/3.7.4/x64/lib/python3.7/site-packages/scipy-1.3.1-py3.7-linux-x86_64.egg/scipy/integrate/quadrature.py:251: AccuracyWarning: maxiter (465) exceeded. Latest difference = 5.970597e-05
  AccuracyWarning)
../_images/examples_Plot-Units_6_1.png
../_images/examples_Plot-Units_6_2.png
../_images/examples_Plot-Units_6_3.png
../_images/examples_Plot-Units_6_4.png
../_images/examples_Plot-Units_6_5.png
../_images/examples_Plot-Units_6_6.png
../_images/examples_Plot-Units_6_7.png

Accumulation will result in the units and output name being updated appropriately:

[5]:
d = at.PlotData(res,outputs='sus:inf',pops='adults',accumulate='integrate',project=P)
at.plot_series(d);
d = at.PlotData(res,outputs='sus',pops='adults',accumulate='integrate',project=P)
at.plot_series(d);
../_images/examples_Plot-Units_8_0.png
../_images/examples_Plot-Units_8_1.png

Programs

  • Risk avoidance - Continuous

  • Harm reduction 1 - Continuous

  • Harm reduction 2 - Continuous

  • Treatment 1 - One-off

  • Treatment 2 - One-off

Programs with continuous coverage cover a certain number of people every year:

[6]:
d = at.PlotData.programs(res,outputs='Risk avoidance',quantity='coverage_number')
at.plot_series(d);
../_images/examples_Plot-Units_10_0.png

Programs with one-off coverage cover a number of people at each time step. This is the number that gets returned by Result.get_coverage() but it is automatically annualized for plotting:

[7]:
annual_coverage = res.model.progset.programs['Treatment 1'].spend_data.vals[0]/res.model.progset.programs['Treatment 1'].unit_cost.vals[0]
timestep_coverage = res.get_coverage('number')['Treatment 1'][0]
print('Annual coverage = %g, Timestep coverage = %g' % (annual_coverage, timestep_coverage))
Annual coverage = 29166.7, Timestep coverage = 1142.86
[8]:
d = at.PlotData.programs(res,outputs='Treatment 1',quantity='coverage_number')
at.plot_series(d)
[8]:
[<Figure size 432x288 with 1 Axes>]
../_images/examples_Plot-Units_13_1.png

These units are handled automatically when aggregating. For example, consider computing the number of people covered over a period of time:

[9]:
d = at.PlotData.programs(res,outputs='Treatment 1',quantity='coverage_number',t_bins=[2000,2000.5])
at.plot_bars(d);

d = at.PlotData.programs(res,outputs='Treatment 1',quantity='coverage_number',t_bins=[2000,2002])
at.plot_bars(d);
../_images/examples_Plot-Units_15_0.png
../_images/examples_Plot-Units_15_1.png
[10]:
d = at.PlotData.programs(res,outputs='Treatment 1',quantity='coverage_eligible',t_bins=[2000,2000.5])
at.plot_bars(d);

d = at.PlotData.programs(res,outputs='Treatment 1',quantity='coverage_number',t_bins=[2000,2002])
at.plot_bars(d);
../_images/examples_Plot-Units_16_0.png
../_images/examples_Plot-Units_16_1.png