atomica.programs.ProgramSet

class atomica.programs.ProgramSet(name='default', framework=None, data=None, tvec=None)[source]

Bases: NamedItem

Representation of a single program

A ProgramSet object is the code representation of a program book. It provides an interface for reading and writing the program book, as well as retrieving program outcomes (due to interactions between programs, they must be computed using the entire collection of programs).

Parameters:
  • name – Optionally specify the name of the ProgramSet

  • tvec – Optionally specify the years for data entry

NamedItem constructor

A name must be a string

Parameters:

name

Methods

add_comp

Add a compartment

add_par

Add a parameter

add_pop

Add a population to the ProgramSet

add_program

Add a program to the ProgramSet

copy

from_spreadsheet

Instantiate a ProgramSet from a spreadsheet

get_alloc

Return the spending allocation for each program

get_capacities

Return timestep capacity for all programs

get_outcomes

Get program outcomes given fractional coverage

get_prop_coverage

Return dimensionless (timestep) fractional coverage

new

Generate a new progset with blank data

remove_comp

Remove a compartment

remove_par

Remove a parameter

remove_pop

Remove a population from the ProgramSet

remove_program

Remove a program from the ProgramSet

sample

Perturb programs based on uncertainties

save

to_spreadsheet

Return content as a Sciris Spreadsheet

to_workbook

Return an open workbook for the ProgramSet

validate

Perform basic validation checks

add_comp(code_name, full_name, pop_type=None)[source]

Add a compartment

The primary use case would be when an existing project has a change made to the framework and it’s desired to update an already filled out program book.

Parameters:
  • code_name (str) – Code name of the compartment to add

  • full_name (str) – Full name of the compartment to add

Return type:

None

add_par(code_name, full_name, pop_type=None)[source]

Add a parameter

The primary use case would be when an existing project has a change made to the framework and it’s desired to update an already filled out program book.

Parameters:
  • code_name (str) – Code name of the parameter to add

  • full_name (str) – Full name of the parameter to add

  • pop_type (str) – Code name of the population type

Return type:

None

add_pop(code_name, full_name, pop_type=None)[source]

Add a population to the ProgramSet

At this level, we can add any arbitrarily named population. When the progbook is loaded in, the populations contained in the ProgramSet will be validated against the specified ProjectData instance.

Parameters:
  • code_name (str) – The code name of the new population

  • full_name (str) – The full name of the new population

Return type:

None

add_program(code_name, full_name)[source]

Add a program to the ProgramSet

Parameters:
  • code_name (str) – The code name of the new program

  • full_name (str) – The full name of the new program

Return type:

None

classmethod from_spreadsheet(spreadsheet=None, framework=None, data=None, project=None, name=None, _allow_missing_data=False)[source]

Instantiate a ProgramSet from a spreadsheet

To load a spreadsheet, need to either pass in

  • A Project containing a framework and data

  • ProjectFramework and ProjectData instances without a project

Parameters:
  • spreadsheet – A string file path, or an sc.Spreadsheet

  • framework – A ProjectFramework instance

  • data – A ProjectData instance

  • project – A Project instance

  • name – Optionally specify the name of the ProgramSet to create

  • _allow_missing_data – Internal only - optionally allow missing unit costs and spending (used for loading template progbook files)

Returns:

A ProgramSet

get_alloc(tvec, instructions=None)[source]

Return the spending allocation for each program

This method fuses the spending data entered in the program book with any overwrites that are present in the instructions. The spending values returned by this method thus reflect any budget scenarios that may be present.

Parameters:
  • tvec – array of times (in years) - this is required to interpolate time-varying spending values

  • instructions – optionally specify instructions, which can supply a spending overwrite

Return type:

dict

Returns:

Dict like {prog_name: np.array()} with spending on each program (in units of ‘$/year’ or currency equivalent)

get_capacities(tvec, dt, instructions=None)[source]

Return timestep capacity for all programs

For convenience, this method automatically calls ProgramSet.get_alloc() to retrieve the spending values that are used to compute capacity. Thus, this method fuses the program capacity computed with the inclusion of any budget scenarios, with any capacity overwrites that are present in the instructions.

Parameters:
  • tvec – array of times (in years) - this is required to interpolate time-varying unit costs and capacity_constraint constraints

  • dt – scalar timestep size - this is required to adjust spending on incidence-type programs

  • instructions – optionally specify instructions, which can supply a spending overwrite

Return type:

dict

Returns:

Dict like {prog_name: np.array()} with program capacity at each timestep (in units of people)

get_outcomes(prop_coverage)[source]

Get program outcomes given fractional coverage

Since the modality interactions in Covout.get_outcome() assume that the coverage is scalar, this function will also only work for scalar coverage. Therefore, the prop coverage would normally come from ProgramSet.get_prop_coverage(tvec,…) where tvec was only one year.

Note that this function is mainly aimed at internal usage. Typically, the program-provided parameter values would be best accessed by examining the appropriate output in the Result. For example, if the programs system overwrites the screening rate screen then it would normally be easiest to run a simulation and then use Result.get_variable(popname,'screen')

For computational efficiency, this method returns a flat dictionary keyed by parameter-population pairs that then gets inserted into the appropriate integration objects by Model.update_pars().

Parameters:

prop_coverage (dict) – dict with coverage values {prog_name:val}

Return type:

dict

Returns:

dict {(par,pop):val} containing parameter value overwrites

get_prop_coverage(tvec, dt, capacities, num_eligible, instructions=None)[source]

Return dimensionless (timestep) fractional coverage

Note that this function is primarily for internal usage (i.e. during model integration or reconciliation). Since the proportion covered depends on the number of people eligible for the program (the coverage denominator), retrieving fractional coverage after running the model is best accomplished via Result.get_coverage('fraction') whereas this method is called automatically during integration.

Evaluating the proportion coverage for a ProgramSet is not a straight division because

  • instructions can override the coverage (for coverage scenarios)

  • Programs can contain saturation constraints

Note that while converage overwrites might be specified in ‘/year’ units for one-off programs, this function always returns dimensionless coverage (i.e. not coverage/year). This coverage is also capped at 1.

Parameters:
  • tvec – scalar year, or array of years - this is required to interpolate time-varying saturation values

  • capacities (dict) – dict of program coverages, should match the available programs (typically the output of ProgramSet.get_capacities()) Note that since the capacity and eligible compartment sizes are being compared here, the capacity needs to be in units of ‘people’ (not ‘people/year’) at this point

  • num_eligible (dict) – dict of number of people covered by each program, computed externally and with one entry for each program

  • instructions – optionally specify instructions, which can supply a coverage overwrite

Return type:

dict

Returns:

Dict like {prog_name: np.array()} with fractional coverage values (dimensionless)

static new(name=None, tvec=None, progs=None, project=None, framework=None, data=None)[source]

Generate a new progset with blank data

Parameters:
  • name – the name for the progset

  • tvec – an np.array() with the time values to write

  • progs – This can be - A number of progs - An odict of {code_name:display name} programs

  • project – specify a project to use the project’s framework and data to initialize the comps, pars, and pops

  • framework – specify a framework to use the framework’s comps and pars

  • data – specify a data to use the data’s pops

Returns:

A new ProgramSet instances

remove_comp(name)[source]

Remove a compartment

The primary use case would be when an existing project has a change made to the framework and it’s desired to update an already filled out program book.

Note that removing a compartment also requires removing it as a target compartment from all programs, which is automatically handled by this method.

Parameters:

code_name – Code name or full name of the compartment to remove

Return type:

None

remove_par(name)[source]

Remove a parameter

The primary use case would be when an existing project has a change made to the framework and it’s desired to update an already filled out program book.

Note that removing a parameter also requires removing all of the Covout instances associated with it.

Parameters:

name (str) – Code name or full name of the parameter to remove

Return type:

None

remove_pop(name)[source]

Remove a population from the ProgramSet

This method will remove the population from the ProgramSet, as well as from all program target pops and will also remove the covout objects for the affected population.

Parameters:

name (str) – Code name or full name of the population to remove

Return type:

None

remove_program(name)[source]

Remove a program from the ProgramSet

Parameters:

name (str) – The code name or full name of the program to remove

Return type:

None

sample(constant=True)[source]

Perturb programs based on uncertainties

The covout objects contained within the ProgramSet cache the program outcomes. At construction, the cache corresponds to the values entered in the databook. Calling this function will perturb the caches based on the sigma values. A simulation subsequently run using the ProgramSet will use the perturbed outcomes.

Parameters:

constant (bool) – If True, time series will be perturbed by a single constant offset. If False, an different perturbation will be applied to each time specific value independently.

Returns:

A new ProgramSet with values perturbed by sampling

to_spreadsheet()[source]

Return content as a Sciris Spreadsheet

Return type:

Spreadsheet

Returns:

A sciris.Spreadsheet instance

to_workbook()[source]

Return an open workbook for the ProgramSet

This allows the xlsxwriter workbook to be manipulated prior to closing the filestream e.g. to append extra sheets. This prevents issues related to cached data values when reloading a workbook to append or modify content

Warning - the workbook is backed by a BytesIO instance and needs to be closed. See the usage of this method in the :meth`to_spreadsheet` function.

Return type:

tuple

Returns:

A tuple (bytes, workbook) with a BytesIO instance and a corresponding open xlsxwriter workbook instance

validate()[source]

Perform basic validation checks

Raises:

Exception if anything is invalid

Return type:

None