vivarium.core.experiment module

Experiment and Store Classes

class vivarium.core.experiment.Defer(defer, f, args)[source]

Bases: object

get()[source]
class vivarium.core.experiment.Electron(parameters=None)[source]

Bases: vivarium.core.process.Process

defaults = {'spin': '-1/2', 'time_step': 1.0}
name = 'electron'
next_update(timestep, states)[source]
ports_schema()[source]
class vivarium.core.experiment.Experiment(config)[source]

Bases: object

Defines simulations

Parameters

config (dict) –

A dictionary of configuration options. The required options are:

  • processes (dict): A dictionary that

    maps process names to process objects. You will usually get this from the processes attribute of the dictionary from vivarium.core.experiment.Compartment.generate().

  • topology (dict): A dictionary that

    maps process names to sub-dictionaries. These sub-dictionaries map the process’s port names to tuples that specify a path through the tree from the compartment root to the store that will be passed to the process for that port.

The following options are optional:

  • experiment_id (uuid.UUID or

    str): A unique identifier for the experiment. A UUID will be generated if none is provided.

  • description (str): A description of

    the experiment. A blank string by default.

  • initial_state (dict): By default an

    empty dictionary, this is the initial state of the simulation.

  • emitter (dict): An emitter

    configuration which must conform to the specification in the documentation for vivarium.core.emitter.get_emitter(). The experiment ID will be added to the dictionary you provide as the value for the key experiment_id.

apply_update(update, process_topology, state)[source]
emit_configuration()[source]
emit_data()[source]
end()[source]
invoke_process(process, path, interval, states)[source]
process_update(path, state, interval)[source]
run_derivers(derivers)[source]
send_updates(update_tuples, derivers=None)[source]
update(interval)[source]

Run each process for the given interval and update the related states.

class vivarium.core.experiment.InvokeProcess(process, interval, states)[source]

Bases: object

get(timeout=0)[source]
class vivarium.core.experiment.MultiInvoke(pool)[source]

Bases: object

invoke(process, interval, states)[source]
class vivarium.core.experiment.Proton(parameters=None)[source]

Bases: vivarium.core.process.Process

defaults = {'radius': 0.0, 'time_step': 1.0}
name = 'proton'
next_update(timestep, states)[source]
ports_schema()[source]
class vivarium.core.experiment.Sine(parameters=None)[source]

Bases: vivarium.core.process.Process

defaults = {'initial_phase': 0.0}
name = 'sine'
next_update(timestep, states)[source]
ports_schema()[source]
class vivarium.core.experiment.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.

apply_config(config, source=None)[source]

Expand the tree by applying additional config.

Special keys for the config are: * _default - Default value for this node. * _properties - An arbitrary map of keys to values. This can be used

for any properties which exist outside of the operation of the tree (like mass or energy).

  • _updater - Which updater to use. Default is ‘accumulate’ which

    adds the new value to the existing value, but ‘set’ is common as well. You can also provide your own function here instead of a string key into the updater library.

  • _emit - whether or not to emit the values under this point in the tree.

  • _divider - What to do with this node when division happens.

    Default behavior is to leave it alone, but you can also pass ‘split’ here, or a function of your choosing. If you need other values from the state you need to supply a dictionary here containing the updater and the topology for where the other state values are coming from. This has two keys: * divider - a function that takes the existing value and any

    values supplied from the adjoining topology.

    • topology - a mapping of keys to paths where the value for

      those keys will be found. This will be passed in as the second argument to the divider function.

  • _subschema/* - If this node was declared to house an unbounded set

    of related states, the schema for these states is held in this nodes subschema and applied whenever new subkeys are added here.

  • _subtopology - The subschema is informed by the subtopology to

    map the process perspective to the actual tree structure.

apply_defaults()[source]

If value is None, set to default.

apply_subschema(subschema=None, subtopology=None, source=None)[source]

Apply a subschema to all inner nodes (either provided or from this node’s personal subschema) as governed by the given/personal subtopology.

apply_subschema_config(subschema)[source]
apply_subschemas()[source]

Apply all subschemas from all nodes at this point or lower in the tree.

apply_update(update, process_topology=None, 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.

There are five special update keys:

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

  • _delete - The value here is a list of paths to delete from

    the tree.

  • _add - Adds a state into the subtree:
    • path - Path to the added state key.

    • state - The value of the added state.

  • _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

    daugther 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.

  • _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.

check_default(new_default)[source]
check_value(new_value)[source]
delete_path(path)[source]

Delete the subtree at the given path.

depth(path=())[source]

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

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]
establish_path(path, config, source=None)[source]

Create a node at the given path if it does not exist, then apply a config to it.

Paths can include ‘..’ to go up a level (which raises an exception if that level does not exist).

generate(path, processes, 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_paths(processes, topology)[source]
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_in(path)[source]
get_path(path)[source]

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

get_paths(paths)[source]
get_template(template)[source]

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

get_updater(update)[source]
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]
inner_value(key)[source]

Get the value of an inner state

mark_deleted()[source]

When nodes are removed from the tree, they are marked as deleted in case something else has a reference to them.

merge_subtopology(subtopology)[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.

processes(path=())[source]
reduce(reducer, initial=None)[source]

Call the reducer on each node accumulating over the result.

reduce_to(path, reducer, initial=None)[source]
schema_keys = {'_default', '_emit', '_properties', '_serializer', '_updater', '_value'}
schema_topology(schema, topology)[source]

Fill in the structure of the given schema with the values located according to the given topology.

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_ports(schema, topology, source=None)[source]

Distribute a schema into the tree by mapping its ports according to the given topology.

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.

update_subschema(path, subschema)[source]

Merge a new subschema into an existing subschema at the given path.

class vivarium.core.experiment.TestUpdateIn[source]

Bases: object

d = {'bar': {'c': 'd'}, 'foo': {1: {'a': 'b'}}}
test_add_dict()[source]
test_add_leaf()[source]
test_add_to_root()[source]
test_complex_merge()[source]
test_set_root()[source]
test_simple()[source]
vivarium.core.experiment.always_true(x)[source]
vivarium.core.experiment.assoc_path(d, path, value)[source]
vivarium.core.experiment.dissoc(d, removing)[source]
vivarium.core.experiment.generate_state(processes, topology, initial_state)[source]
vivarium.core.experiment.get_in(d, path, default=None)[source]
vivarium.core.experiment.identity(y)[source]
vivarium.core.experiment.inverse_topology(outer, update, topology)[source]

Transform an update from the form its process produced into one aligned to the given topology.

The inverse of this function (using a topology to construct a view for the perspective of a Process ports_schema()) lives in Store, called topology_state. This one stands alone as it does not require a store to calculate.

vivarium.core.experiment.invert_topology(update, args)[source]
vivarium.core.experiment.invoke_process(process, interval, states)[source]
vivarium.core.experiment.key_for_value(d, looking)[source]
vivarium.core.experiment.make_proton(parallel=False)[source]
vivarium.core.experiment.normalize_path(path)[source]
vivarium.core.experiment.pf(x)[source]
vivarium.core.experiment.pp(x)[source]
vivarium.core.experiment.schema_for(port, keys, initial_state, default=0.0, updater='accumulate')[source]
vivarium.core.experiment.test_in()[source]
vivarium.core.experiment.test_inverse_topology()[source]
vivarium.core.experiment.test_multi()[source]
vivarium.core.experiment.test_parallel()[source]
vivarium.core.experiment.test_recursive_store()[source]
vivarium.core.experiment.test_sine()[source]
vivarium.core.experiment.test_timescales()[source]
vivarium.core.experiment.test_topology_ports()[source]
vivarium.core.experiment.timestamp(dt=None)[source]
vivarium.core.experiment.update_in(d, path, f)[source]
vivarium.core.experiment.without(d, removing)[source]