Store

The file system for storing and updating state variables during an experiment.

class vivarium.core.store.Store(config, outer=None, source=None)[source]

Bases: object

Holds a subset of the overall model state

The total state of the model can be broken down into stores, each of which is represented by an instance of this Store class. The store’s state is a set of variables, each of which is defined by a set of schema key-value pairs. The valid schema keys are listed in schema_keys, and they are:

  • _default (Type should match the variable value): The default value of the variable.

  • _updater (str): The name of the updater to use. By default this is accumulate.

  • _divider (str): The name of the divider to use. Note that _divider is not included in the schema_keys set because it can be applied to any node in the hierarchy, not just leaves (which represent variables).

  • _value (Type should match the variable value): The current value of the variable. This is None by default.

  • _properties (dict): Extra properties of the variable that don’t have a specific schema key. This is an empty dictionary by default.

  • _emit (bool): Whether to emit the variable to the emitter. This is False by default.

  • _serializer (vivarium.core.registry.Serializer or str): Serializer (or name of serializer) whose serialize method should be called on data in this store before emitting and whose deserialize method should be called when repopulating this store from serialized data. Only define if it is necessary to serialize and deserialize data in this store differently from other data of the same type.

add(added)[source]
add_node(path, node)[source]

Add a node instance at the provided path

apply_defaults()[source]

If value is None, set to default.

apply_update(update, state=None)[source]

Given an arbitrary update, map all the values in that update to their positions in the tree where they apply, and update these values using each node’s _updater.

Parameters
  • update – The update being applied.

  • state – The state at the start of the time step.

There are five topology update methods, which use the following special update keys:

  • _add - Adds states into the subtree, given a list of dicts

    containing:

    • path - Path to the added state key.

    • state - The value of the added state.

  • _move - Moves a node from a source to a target location in the tree. This uses an update to an outer port, which contains both the source and target node locations. Can move multiple nodes according to a list of dicts containing:

    • source - the source path from an outer process port

    • target - the location where the node will be placed.

  • _generate - The value has four keys, which are essentially the arguments to the generate() function:

    • path - Path into the tree to generate this subtree.

    • processes - Tree of processes to generate.

    • topology - Connections of all the process’s ports_schema().

    • initial_state - Initial state for this new subtree.

  • _divide - Performs cell division by constructing two new daughter cells and removing the mother. Takes a dict with two keys:

    • mother - The id of the mother (for removal)

    • daughters - List of two new daughter generate directives, of the

      same form as the _generate value above.

  • _delete - The value here is a list of paths (tuples) to delete from the tree.

Additional special update keys for different update operations:

  • _updater - Override the default updater with any updater you want.

  • _reduce - This allows a reduction over the entire subtree from some point downward. Its three keys are:

    • from - What point to start the reduction.

    • initial - The initial value of the reduction.

    • reducer - A function of three arguments, which is called on every node from the from point in the tree down:

      • value - The current accumulated value of the reduction.

      • path - The path to this point in the tree

      • node - The actual node being visited.

      This function returns the next value for the reduction. The result of the reduction will be assigned to this point in the tree.

build_topology_views()[source]
connect(path, value, absolute=False)[source]

Wire a store’s process to another store.

This function must not be used unless self holds a process.

Parameters
  • path – Path of the port to connect.

  • value – The store (or the path to the store) to connect to the port at path.

Raises
create(path, value=None, absolute=False, **kwargs)[source]
delete(key, here=None)[source]
depth(path=(), filter_function=None)[source]

Create a mapping of every path in the tree to the node living at that path in the tree. An optional filter argument is a function that can declares the instances that will be returned, for example: * filter=lambda x: isinstance(x.value, Process)

divide(divide)[source]
divide_value()[source]

Apply the divider for each node to the value in that node to assemble two parallel divided states of this subtree.

emit_data()[source]

Emit the value at this Store.

Obeys the schema (namely emits only if _emit is true). Also applies serializers and converts units as necessary.

Returns

The value to emit, or None if nothing should be emitted.

generate(path, processes, steps, flow, topology, initial_state)[source]

Generate a subtree of this store at the given path. The processes will be mapped into locations in the tree by the topology, and once everything is constructed the initial_state will be applied.

generate_value(value)[source]

generate the structure for this value that don’t exist, but don’t overwrite any existing values.

get_config(sources=False)[source]

Assemble a dictionary representation of the config for this node. A desired property is that the node can be exactly recreated by applying the resulting config to an empty node again.

get_flow()[source]

Get the flow for all steps under this node.

For example:

>>> from vivarium.core.store import Store
>>> from vivarium.core.process import Step
>>> class MyStep(Step):
...     def ports_schema(self):
...         return {
...             'port': ['variable'],
...         }
...     def next_update(self, timestep, states):
...         return {}
>>> schema = {
...     'agent1': {
...         'store': {
...             'variable': {
...                 '_default': 0,
...             },
...         },
...         'step1': {
...             '_value': MyStep(),
...             '_topology': {
...                 'port': ('store',),
...             },
...             '_flow': [],
...         },
...         'step2': {
...             '_value': MyStep(),
...             '_topology': {
...                 'port': ('store',),
...             },
...             '_flow': [('step1',)],
...         },
...     },
... }
>>> store = Store(schema)
>>> store.get_flow()
{'agent1': {'step1': [], 'step2': [('step1',)]}}
get_in(path)[source]

Get the value at path relative to this store.

get_path(path)[source]

Get the node at the given path relative to this node.

get_paths(paths)[source]

Get the nodes at each of the specified paths.

Parameters

paths – Map from keys to paths.

Returns

A dictionary with the same keys as paths. Each key is mapped to the Store object at the associated path.

get_processes()[source]

Get all processes in this store. Does not include steps.

get_steps()[source]

Get all steps under this store.

get_template(template)[source]

Pass in a template dict with None for each value you want to retrieve from the tree!

get_topology()[source]

Get the topology for all processes in this store.

get_value(condition=None, f=None)[source]

Pull the values out of the tree in a structure symmetrical to the tree.

get_values(paths)[source]

Get the values at each of the provided paths.

Parameters

paths – Map from keys to paths.

Returns

A dictionary with the same keys as paths. Each key is mapped to the value at the associated path.

inner_value(key)[source]

Get the value of an inner state

insert(insertion)[source]
move(move, process_store)[source]
outer_path(path, source=None)[source]

Address a topology with the _path keyword if present, establishing a path to this node and using it as the starting point for future path operations.

path_for()[source]

Find the path to this node.

path_to(to)[source]

return a path from self to the given Store

recursive_end_process(value)[source]
schema_keys = {'_default', '_emit', '_properties', '_serializer', '_updater', '_value'}
schema_topology(schema, topology)[source]

Fill in the structure of the given schema with the connected stores according to the given topology.

set_emit_value(path=None, emit=False)[source]

Turn on/off emits for all inner nodes of path.

set_emit_values(paths=None, emit=False)[source]

Turn on/off emits for all inner nodes of the list of paths.

set_path(path, value)[source]

Set a value at a path in the hierarchy.

Parameters
  • path – The path relative to self where the value should be set.

  • value – The value to set. The store node at path will hold value when this function returns.

set_value(value)[source]

Set the value for the given tree elements directly instead of using the updaters from their nodes.

state_for(path, keys)[source]

Get the value of a state at a given path

top()[source]

Find the top of this tree.

topology_state(topology)[source]

Fill in the structure of the given topology with the values at all the paths the topology points at. Essentially, anywhere in the topology that has a tuple path will be filled in with the value at that path.

This is the inverse function of the standalone inverse_topology.

vivarium.core.store.convert_path(path)[source]
vivarium.core.store.generate_state(processes: Dict[str, Any], topology: Dict[str, Union[Tuple[str, ], dict, object]], initial_state: Optional[Dict[str, Any]], steps: Optional[Dict[str, Any]] = None, flow: Optional[Dict[str, Sequence[Tuple[str, ]]]] = None)vivarium.core.store.Store[source]

Initialize a simulation’s state.

Parameters
  • processes – Simulation processes.

  • topology – Topology linking process ports to stores.

  • initial_state – Initial simulation state. Omitted variables will be assigned values based on schema defaults.

Returns

Initialized state.

vivarium.core.store.hierarchy_depth(hierarchy, path=())[source]

Create a mapping of every path in the hierarchy to the node living at that path in the hierarchy.

vivarium.core.store.insert_topology(topology, port_path, target_path)[source]
vivarium.core.store.key_for_value(d, looking)[source]

Get the key associated with a value in a dictionary.

Only top-level keys are searched.

Parameters
  • d – The dictionary.

  • looking – The value to look for.

Returns

The associated key, or None if no key found.

vivarium.core.store.topology_path(topology, path)[source]

get the subtopology at the path inside the given topology.

vivarium.core.store.view_values(states: dict)Dict[str, Any][source]