Holders#

policyengine_core.holders contains the definition of Holder, which is a class whose instances represent variable values in a specific time period.

Holder#

class policyengine_core.holders.holder.Holder(variable: Variable, population: Population)#

Bases: object

A holder keeps tracks of a variable values after they have been calculated, or set as an input.

clone(population: Population, share_arrays: bool = False) → Holder#

Copy the holder just enough to be able to run a new simulation without modifying the original simulation.

With share_arrays, the new holder’s in-memory storage shares this holder’s arrays and copies each one when it is first read, instead of copying them all now (see InMemoryStorage.clone()).

create_disk_storage(directory: str = None, preserve: bool = False) → OnDiskStorage#

Create storage for this holder, or a named directory for a dump.

Independently created temporary storages have distinct directories, even when a clone still reads an earlier holder for this variable. Explicit or preserved storages keep the directory/variable layout.

default_array() → ArrayLike#

Return a new array of the appropriate length for the entity, filled with the variable default values.

delete_arrays(period: Period = None, branch_name: str = 'default') → None#

If period is None, remove all known values of the variable.

If period is not None, only remove all values for any period included in period (e.g. if period is “2017”, values for “2017-01”, “2017-07”, etc. would be removed)

A deleted value set with set_input stops counting as an input, so a value calculated later for the same period is not taken for one.

get_array(period: Period, branch_name: str = 'default') → ArrayLike#

Get the value of the variable for the given period.

If the value is not known, return None.

get_input_periods(branch_name: str = 'default') → List[Period]#

The periods for which the value get_array(period, branch_name) reads is an input rather than a value the simulation calculated (see put_in_cache). Periods stored only under branches this one cannot read are left out.

One pass over the stored keys: for each period, the key get_array reads first (the branch before its ancestors, memory before disk).

get_known_branch_periods() → List[Tuple[str, Period]]#

Get the list of periods the variable value is known for.

get_known_periods() → List[Period]#

Get the list of periods the variable value is known for.

get_memory_usage() → dict#

Get data about the virtual memory usage of the holder.

An array a branch still shares with the simulation it was created from (see Simulation.get_branch()) is counted for both, though it is held in memory once.

Returns:

Memory usage data

Return type:

dict

Example:

>>> holder.get_memory_usage()
>>> {
>>>    'nb_arrays': 12,  # The holder contains the variable values for 12 different periods
>>>    'nb_cells_by_array': 100, # There are 100 entities (e.g. persons) in our simulation
>>>    'cell_size': 8,  # Each value takes 8B of memory
>>>    'dtype': dtype('float64')  # Each value is a float 64
>>>    'total_nb_bytes': 10400  # The holder uses 10.4kB of virtual memory
>>>    'nb_requests': 24  # The variable has been computed 24 times
>>>    'nb_requests_by_array': 2  # Each array stored has been on average requested twice
>>>    }
is_derived(period: Period, branch_name: str = 'default') → bool#

Whether the value get_array(period, branch_name) reads was calculated by the simulation rather than set as an input.

The answer comes from the branch that stores the value read: the branch itself, else its parent_branch ancestors, else default. False if no value is stored for period.

put_in_cache(value: ArrayLike, period: Period, branch_name: str = 'default', derived: bool = False) → None#

Cache value for period.

derived marks a value the simulation calculated rather than took as input: a formula result, a carried, uprated or default value, a twelfth of a yearly flow cached at a month by calculate_divide, or a sum over several sub-periods cached by calculate_add. Auto-carry-over never carries such a value into another period (see is_derived). The mark is stored with the value, for the (branch, period) key written, and any later write to that key replaces it.

A derived value never replaces an input that get_array(period, branch_name) reads: the input is kept and nothing is stored.

set_input(period: Period, array: ArrayLike, branch_name: str = 'default') → None#

Set a variable’s value (array) for a given period (period)

Parameters:
  • array – the input value for the variable

  • period – the period at which the value is setted

Example :

>>> holder.set_input([12, 14], '2018-04')
>>> holder.get_array('2018-04')
>>> [12, 14]

If a set_input property has been set for the variable, this method may accept inputs for periods not matching the definition_period of the variable. To read more about this, check the documentation.

Custom handlers store replayable inputs with holder._set or holder.set_input. Values written through put_in_cache are excluded from input export and reform replay.

set_input_dispatch_by_period#

policyengine_core.holders.helpers.set_input_dispatch_by_period(holder: Holder, period: Period, array: ArrayLike)#

This function can be declared as a set_input attribute of a variable.

In this case, the variable will accept inputs on larger periods that its definition period, and the value for the larger period will be applied to all its subperiods.

Only inputs count as already known. A sub-period whose value the simulation calculated (a formula result, or a default, carried-over or uprated value) takes the new input like a sub-period with no value, so the result does not depend on what was calculated before the input was set.

A sub-period that already has an input keeps it, and that input, not the value given for the larger period, is applied to the sub-periods after it that have none: with 3 set for March, setting 7 for the year gives 7 in January and February and 3 from March to December. The value of a stock known at some month holds for the rest of the period. (Setting the two inputs in the other order gives 7 in every month but March.)

To read more about set_input attributes, check the documentation.

set_input_divide_by_period#

policyengine_core.holders.helpers.set_input_divide_by_period(holder: Holder, period: Period, array: ArrayLike)#

This function can be declared as a set_input attribute of a variable.

In this case, the variable will accept inputs on larger periods that its definition period, and the value for the larger period will be divided between its subperiods.

Sub-periods that already have an input keep it, and what is left of the value is divided between the others. Only inputs count as already known. A sub-period whose value the simulation calculated (a formula result, or a default, carried-over or uprated value) takes its share of the new input like a sub-period with no value, so the result does not depend on what was calculated before the input was set.

To read more about set_input attributes, check the documentation.