pypfilt.build

The pypfilt.build module builds simulation contexts for simulation instances, in preparation for running estimation and forecasting simulations.

Building simulation contexts

pypfilt.build.build_context(inst: Instance, obs_tables=None)

Return a simulation context for the provided scenario instance.

Parameters:
  • inst (Instance) – The scenario instance.

  • obs_tables – The (optional) dictionary of observation tables; when not provided, these will be constructed from each observation file.

Return type:

Context

class pypfilt.build.Context(scenario_id: str, descriptor: str, settings: Dict[str, Any], source: str | None, data: Dict[str, Any], component: Dict[str, Any], event_handler: Dict[str, Any], all_observations: List[dict])

A simulation context, which contains all of the components, data tables, and scenario settings that are required in order to run estimation passes and forecasts.

Parameters:
  • scenario_id (str) – The scenario identifier for this context.

  • descriptor (str) – The identifier descriptor, which describes the observation model parameter values for this context.

  • settings (Dict[str, Any]) – The dictionary of simulation settings.

  • source (Optional[str]) – The (optional) TOML input for this specification.

  • data (Dict[str, Any]) – The dictionary of data tables.

  • component (Dict[str, Any]) – The dictionary of simulation components.

  • event_handler (Dict[str, list[Callable]]) – The dictionary of event-handler functions.

  • all_observations (List[dict]) – All of the available observations in a single list.

scenario_id: str

Alias for field number 0

descriptor: str

Alias for field number 1

settings: Dict[str, Any]

Alias for field number 2

source: str | None

Alias for field number 3

data: Dict[str, Any]

Alias for field number 4

component: Dict[str, Any]

Alias for field number 5

event_handler: Dict[str, Any]

Alias for field number 6

all_observations: List[dict]

Alias for field number 7

get_setting(keys, default=None)

Return the setting associated with a sequence of keys, if all keys are present, otherwise return default.

Examples:

>>> from pypfilt.build import Context
>>> ctx = Context(
...     scenario_id='fake_scenario',
...     descriptor='',
...     source=None,
...     settings={'a': 1, 'b': {'c': 2}},
...     data={},
...     component={},
...     event_handler={},
...     all_observations=[],
... )
>>> ctx.get_setting(['a'])
1
>>> ctx.get_setting(['b', 'c'])
2
>>> ctx.get_setting(['b', 'd']) is None
True
>>> ctx.get_setting(['b', 'd'], default=42)
42
override_settings(overrides)

Temporarily override settings within a with statement.

This uses override_dict() to override the current settings.

Parameters:

overrides (dict) – The overriding values.

Examples:

>>> from pypfilt.build import Context
>>> ctx = Context(
...     scenario_id='fake_scenario',
...     descriptor='',
...     source=None,
...     settings={'a': 1, 'b': {'c': 2, 'd': 3}},
...     data={},
...     component={},
...     event_handler={},
...     all_observations=[],
... )
>>> ctx.get_setting(['b', 'c'])
2
>>> ctx.get_setting(['b', 'd'])
3
>>> ctx.get_setting(['b', 'e']) is None
True
>>> with ctx.override_settings({'b': {'c': 1, 'e': 2}}):
...     ctx.get_setting(['b', 'c'])
...     # NOTE: 'd' should retain its original value.
...     ctx.get_setting(['b', 'd'])
...     ctx.get_setting(['b', 'e'])
1
3
2
>>> ctx.get_setting(['b', 'c'])
2
>>> ctx.get_setting(['b', 'd'])
3
>>> ctx.get_setting(['b', 'e']) is None
True
install_event_handler(event_name, handler_fn)

Register a function that should be called in response to an event.

Parameters:
  • event_name – The event name.

  • handler_fn – The event-handler function.

call_event_handlers(event)

Call all event-handler functions associated with an event.

Parameters:

event – The event information.

Examples:

>>> from pypfilt.build import Context
>>> ctx = Context(
...     scenario_id='fake_scenario',
...     descriptor='',
...     source=None,
...     settings={},
...     data={},
...     component={},
...     event_handler={},
...     all_observations=[],
... )
>>> class MyEvent:
...     def __init__(self, message):
...         self.message = message
>>> def my_handler(event):
...     print(event.message)
>>> ctx.install_event_handler('MyEvent', my_handler)
>>> ctx.call_event_handlers(MyEvent('Hello world'))
Hello world
prior_table()

Return the prior distribution table for parameters whose values are not contained in external data files.

Examples:

def draw_new_prior_samples(ctx):
    cfg = settings['sampler']
    prng = ctx.component['random']['prior']
    particles = ctx.settings['filter']['particles']
    prior_table = ctx.prior_table()
    external_samples = ctx.external_prior_samples()
    return ctx.component['sampler'].draw_samples(
        cfg, prng, particles, prior_table, external_samples)
external_prior_samples()

Return samples from the prior distribution for parameters whose values are contained in external data files.

Examples:

def draw_new_prior_samples(ctx):
    cfg = settings['sampler']
    prng = ctx.component['random']['prior']
    particles = ctx.settings['filter']['particles']
    prior_table = ctx.prior_table()
    external_samples = ctx.external_prior_samples()
    return ctx.component['sampler'].draw_samples(
        cfg, prng, particles, prior_table, external_samples)
particle_count()

Return the number of particles in the ensemble.

start_time()

Return the start of the simulation period.

If the simulation period has not been defined, this returns None.

end_time()

Return the end of the simulation period.

If the simulation period has not been defined, this returns None.

time_steps()

Return a generator that yields a sequence of time-step numbers and times (represented as tuples) that span the simulation period.

The first time-step is assigned the number 1 and occurs one time-step after the beginning of the simulation period.

time_units()

Return a generator that yields a sequence of time-step numbers and times (represented as tuples) that span the simulation period.

This sequence does not include the start of the simulation period.

summary_times()

Return a generator that yields the sequence of time-step numbers and times (represented as tuples) for which summary statistics will be calculated.

This sequence includes the start of the simulation period, which is assigned the time-step number zero.

summary_count()

Return the number of time-steps for which summary statistics will be calculated.

Internal functions

pypfilt.build.get_chained(table, keys, default=None)

Return the value associated with a sequence of keys, if all keys are present, otherwise return default.

Examples:

>>> from pypfilt.build import get_chained
>>> data = {'a': 1, 'b': {'c': 2}}
>>> get_chained(data, ['a'])
1
>>> get_chained(data, ['b', 'c'])
2
>>> get_chained(data, ['b', 'd']) is None
True
>>> get_chained(data, ['b', 'd'], default=42)
42
pypfilt.build.set_chained(table, keys, value)

Create or update the value associated with a sequence of keys, creating missing keys as needed.

Raises:

ValueError – if a key exists but is not a dictionary.

Examples:

>>> from pypfilt.build import get_chained, set_chained
>>> data = {'a': 1, 'b': {'c': 2}}
>>> set_chained(data, ['b', 'c'], 3)
>>> get_chained(data, ['b', 'c'])
3
>>> set_chained(data, ['x', 'y', 'z'], 'Hello')
>>> get_chained(data, ['x', 'y', 'z'])
'Hello'
>>> try:
...     set_chained(data, ['b', 'c', 'd'], 'Invalid keys')
... except ValueError:
...     print('Cannot replace b.c with a dictionary')
Cannot replace b.c with a dictionary
>>> print(data)
{'a': 1, 'b': {'c': 3}, 'x': {'y': {'z': 'Hello'}}}
pypfilt.build.set_chained_default(table, keys, value)

Insert a missing value associated with a sequence of keys.

Examples:

>>> from pypfilt.build import get_chained, set_chained_default
>>> data = {'a': 1, 'b': {'c': 2}}
>>> set_chained_default(data, ['b', 'c'], 11)
>>> get_chained(data, ['b', 'c'])
2
>>> set_chained_default(data, ['b', 'f', 'g'], 42)
>>> get_chained(data, ['b', 'f', 'g'])
42
>>> try:
...     set_chained_default(data, ['b', 'c', 'd'], 'Invalid keys')
... except ValueError:
...     print('Cannot replace b.c with a dictionary')
Cannot replace b.c with a dictionary
>>> print(data)
{'a': 1, 'b': {'c': 2, 'f': {'g': 42}}}