Quickstart

In this tutorial we do the following :

  1. Examine the 'network' parameter tree
    1. Models (neuron_models, recorder_models, synapse_models)
    2. Layers (layers)
    3. Projections (projection_models and topology subtrees
    4. Population and projection recorders (recorders)
  2. Examine the full simulation parameter tree
    1. network params subtree
    2. kernel params subtree
    3. session_models params subtree
    4. simulation params subtree
  3. Run a full simulation
    1. Load parameter tree from one or multiple files
    2. Using the Simulation object
    3. Using the denest.run() method
    4. From the command line
[1]:
import nest
import yaml
from pathlib import Path
from pprint import pprint

from denest import *
import denest
[2]:
PARAMS_DIR = Path('./data/params')
OUTPUT_DIR = Path('./data/outputs/output')

"network" tree

A full NEST network is represented in deNEST by the Network object.

The Network object is initialized from the full "network" parameter tree. The 'network' tree should have specific children subtree, each used to initialize different elements of the network.

[3]:
net_tree = ParamsTree.read(PARAMS_DIR/'network_tree.yml').children['network']
[4]:
# Full 'network' tree
net_tree
[4]:
ParamsTree(name='network', parent='None')
  params: {}
  nest_params: {}
  neuron_models:
    params: {}
    nest_params: {}
    my_neuron:
      params:
        nest_model: ht_neuron
      nest_params:
        g_KL: 1.0
        g_NaL: 1.0
      l1_exc:
        params: {}
        nest_params:
          V_m: -44.0

  ... [116 lines] ...

      - layers:
        - input_layer
        populations: null
        model: my_spike_detector
      projection_recorders:
      - source_layers:
        - l1
        source_population: l1_exc
        target_layers:
        - l1
        target_population: l1_inh
        projection_model: proj_1_AMPA
        model: weight_recorder
    nest_params: {}

[5]:
print("'network' tree's expected subtrees:", net_tree.children.keys())
'network' tree's expected subtrees: dict_keys(['neuron_models', 'synapse_models', 'layers', 'projection_models', 'topology', 'recorder_models', 'recorders'])

Models ( 'neuron_model', 'synapse_models', 'recorder_models' subtrees)

We can define neuron, recorder, stimulator and synapse models with arbitrary parameters from parameter trees.

Each leaf corresponds to a new (named) model. Its nest_params and params are hierarchically inherited.

The nest_model used is specified in the leaf’s params

'neuron_models' tree

[6]:
net_tree.children['neuron_models']
[6]:
ParamsTree(name='neuron_models', parent='network')
  params: {}
  nest_params: {}
  my_neuron:
    params:
      nest_model: ht_neuron
    nest_params:
      g_KL: 1.0
      g_NaL: 1.0
    l1_exc:
      params: {}
      nest_params:
        V_m: -44.0
    l1_inh:
      params: {}
      nest_params:
        V_m: -55.0

Below are the leaves of the tree. Each initializes a model. The nest_params and params are inherited from ancestor leaves.

[7]:
print("Tree's leaves and their inherited parameters:")
[
    (f'leaf name: {l.name})',
      f'leaf `params`: {dict(l.params)}',
      f'leaf `nest_params`: {dict(l.nest_params)}')
     for l in net_tree.children['neuron_models'].leaves()
]
Tree's leaves and their inherited parameters:
[7]:
[('leaf name: l1_exc)',
  "leaf `params`: {'nest_model': 'ht_neuron'}",
  "leaf `nest_params`: {'g_KL': 1.0, 'g_NaL': 1.0, 'V_m': -44.0}"),
 ('leaf name: l1_inh)',
  "leaf `params`: {'nest_model': 'ht_neuron'}",
  "leaf `nest_params`: {'g_KL': 1.0, 'g_NaL': 1.0, 'V_m': -55.0}")]

'recorder_models' subtree

Same thing as for neuron models:

[8]:
net_tree.children['recorder_models']
[8]:
ParamsTree(name='recorder_models', parent='network')
  params: {}
  nest_params:
    record_to:
    - memory
    - file
  weight_recorder:
    params:
      nest_model: weight_recorder
    nest_params: {}
  my_multimeter:
    params:
      nest_model: multimeter
    nest_params:
      record_from:
      - V_m
  my_spike_detector:
    params:
      nest_model: spike_detector
    nest_params: {}

[9]:
print("Tree's leaves and their inherited parameters:")
[
    (f'leaf name: {l.name})',
      f'leaf `params`: {dict(l.params)}',
      f'leaf `nest_params`: {dict(l.nest_params)}')
     for l in net_tree.children['recorder_models'].leaves()
]
Tree's leaves and their inherited parameters:
[9]:
[('leaf name: weight_recorder)',
  "leaf `params`: {'nest_model': 'weight_recorder'}",
  "leaf `nest_params`: {'record_to': ['memory', 'file']}"),
 ('leaf name: my_multimeter)',
  "leaf `params`: {'nest_model': 'multimeter'}",
  "leaf `nest_params`: {'record_to': ['memory', 'file'], 'record_from': ['V_m']}"),
 ('leaf name: my_spike_detector)',
  "leaf `params`: {'nest_model': 'spike_detector'}",
  "leaf `nest_params`: {'record_to': ['memory', 'file']}")]

'synapse_model' subtree

  • Same thing as for neuron models, with as a bonus a convenient way of specifying the receptor type of the synapse
  • If specifying the receptor_type and target_model in the SynapseModel params, the corresponding port is determined automatically
  • Connection ‘weight’ nest_param should be specified in the projections parameters rather than the synapse parameters
[10]:
pprint(net_tree.children['synapse_models'])
ParamsTree(name='synapse_models', parent='network')
  params: {}
  nest_params: {}
  my_AMPA_synapse:
    params:
      nest_model: ht_synapse
      receptor_type: AMPA
      target_neuron: ht_neuron
    nest_params: {}
  my_GABAA_synapse:
    params:
      nest_model: ht_synapse
      receptor_type: GABA_A
      target_neuron: ht_neuron
    nest_params: {}

[11]:
print("Tree's leaves and their inherited parameters:")
[
    (f'leaf name: {l.name})',
      f'leaf `params`: {dict(l.params)}',
      f'leaf `nest_params`: {dict(l.nest_params)}')
     for l in net_tree.children['synapse_models'].leaves()
]
Tree's leaves and their inherited parameters:
[11]:
[('leaf name: my_AMPA_synapse)',
  "leaf `params`: {'nest_model': 'ht_synapse', 'receptor_type': 'AMPA', 'target_neuron': 'ht_neuron'}",
  'leaf `nest_params`: {}'),
 ('leaf name: my_GABAA_synapse)',
  "leaf `params`: {'nest_model': 'ht_synapse', 'receptor_type': 'GABA_A', 'target_neuron': 'ht_neuron'}",
  'leaf `nest_params`: {}')]

Layers ( 'layers' subtree)

  • As for models, we can create nest.Topology layers from the leaves of a tree.
  • The elements can be nest models with their default parameters, or the ones we just created with custom params
  • For layers of stimulator devices, we can use the InputLayer object, which can automatically create paired parrot neurons for each stimulator units, by adding type: 'InputLayer' to the params
  • The leaves should have a population entry in the params field, that specifies the number of units of each model at each layer location (replaces the elements nest_params)
[12]:
layer_tree = net_tree.children['layers']
layer_tree
[12]:
ParamsTree(name='layers', parent='network')
  params: {}
  nest_params: {}
  layers:
    params:
      type: null
    nest_params:
      rows: 5
      columns: 5
      extent:
      - 5.0
      - 5.0
      edge_wrap: true
    input_layer:
      params:
        type: InputLayer
        add_parrots: true
        populations:
          spike_generator: 1
      nest_params: {}
    l1:
      params:
        populations:
          l1_exc: 4
          l1_inh: 2
      nest_params: {}

[13]:
print("Tree's leaves and their inherited parameters:")
[
    (f'leaf name: {l.name})',
      f'leaf `params`: {dict(l.params)}',
      f'leaf `nest_params`: {dict(l.nest_params)}')
     for l in layer_tree.leaves()
]
Tree's leaves and their inherited parameters:
[13]:
[('leaf name: input_layer)',
  "leaf `params`: {'type': 'InputLayer', 'add_parrots': True, 'populations': {'spike_generator': 1}}",
  "leaf `nest_params`: {'rows': 5, 'columns': 5, 'extent': [5.0, 5.0], 'edge_wrap': True}"),
 ('leaf name: l1)',
  "leaf `params`: {'type': None, 'populations': {'l1_exc': 4, 'l1_inh': 2}}",
  "leaf `nest_params`: {'rows': 5, 'columns': 5, 'extent': [5.0, 5.0], 'edge_wrap': True}")]

Projections ('projection_models' and 'topology' subtrees)

We create projections using a two step process:

  1. Create ProjectionModel objects from a tree. Each named leaf will define a template from which individual projections can inherit their parameters ('projection_models subtree)
  2. Create Projection objects from a list, specifying for each item the source layer x population, target layer x population and the projection model to inherit parameters from ('topology' subtree)

Define templates from the projection_models tree

[14]:
proj_model_tree = net_tree.children['projection_models']
proj_model_tree
[14]:
ParamsTree(name='projection_models', parent='network')
  params: {}
  nest_params:
    connection_type: divergent
    mask:
      circular:
        radius: 2.0
    kernel: 1.0
  proj_1_AMPA:
    params: {}
    nest_params:
      synapse_model: my_AMPA_synapse
      weights: 1.0
  proj_2_GABAA:
    params: {}
    nest_params:
      synapse_model: my_GABAA_synapse
      weights: 2.0

[15]:
print("Tree's leaves and their inherited parameters:")
[
    (f'leaf name: {l.name})',
      f'leaf `params`: {dict(l.params)}',
      f'leaf `nest_params`: {dict(l.nest_params)}')
     for l in net_tree.children['projection_models'].leaves()
]
Tree's leaves and their inherited parameters:
[15]:
[('leaf name: proj_1_AMPA)',
  'leaf `params`: {}',
  "leaf `nest_params`: {'connection_type': 'divergent', 'mask': {'circular': {'radius': 2.0}}, 'kernel': 1.0, 'synapse_model': 'my_AMPA_synapse', 'weights': 1.0}"),
 ('leaf name: proj_2_GABAA)',
  'leaf `params`: {}',
  "leaf `nest_params`: {'connection_type': 'divergent', 'mask': {'circular': {'radius': 2.0}}, 'kernel': 1.0, 'synapse_model': 'my_GABAA_synapse', 'weights': 2.0}")]

Define individual projections from the topology tree

The list of projections is defined in the projections params of the topology tree

Check out the doc of Network.build_projections for expected formatting

For each item in the list, a projection is created for each of the <source_layer> x <target_layer> combinations. The params and nest_params are inherited from the template projection_model

[16]:
topo_tree = net_tree.children['topology']
topo_tree
[16]:
ParamsTree(name='topology', parent='network')
  params:
    projections:
    - source_layers:
      - input_layer
      source_population: parrot_neuron
      target_layers:
      - l1
      target_population: l1_exc
      projection_model: proj_1_AMPA
    - source_layers:
      - l1
      source_population: l1_exc
      target_layers:
      - l1
      target_population: l1_inh
      projection_model: proj_1_AMPA
    - source_layers:
      - l1
      source_population: l1_inh
      target_layers:
      - l1
      target_population: l1_exc
      projection_model: proj_2_GABAA
  nest_params: {}

Recorders (recorders subtree)

Similarly to the topology tree, recorders are defined from lists.

We separate recorders connected to synapses (eg weight recorder) and those connected to units (eg spike detectors), which are defined in the projection_recorders and population_recorders params (resp.) of the recorders tree.

Check out the doc of the Network.build_recorders, Network.build_population_recorders and Network.build_projection_recorders methods for expected formatting

The parameters of the recorders can be changed by using custom recorder models (in the recorder_models tree, see above)

[17]:
recorders_tree = net_tree.children['recorders']
recorders_tree
[17]:
ParamsTree(name='recorders', parent='network')
  params:
    population_recorders:
    - layers:
      - l1
      populations:
      - l1_exc
      model: my_multimeter
    - layers:
      - input_layer
      populations: null
      model: my_spike_detector
    projection_recorders:
    - source_layers:
      - l1
      source_population: l1_exc
      target_layers:
      - l1
      target_population: l1_inh
      projection_model: proj_1_AMPA
      model: weight_recorder
  nest_params: {}

Full parameter tree

A full simulation consists in

  • kernel initialization
  • network creation
  • running the network in multiple ‘sessions’ at the start of which some modifications to the network can be made

The full simulation is represented by the Simulation object, which is initialized from a parameter tree with the following subtrees:

  1. 'network' subtree, passed to Network()
  2. 'kernel' subtree, passed to Simulation.init_kernel()
  3. 'session_models' subtree, defining the parameters for each individual Session
  4. 'simulation' subtree, containing the list of sessions that we run and the input/output directory paths
[18]:
full_tree = ParamsTree.read(PARAMS_DIR/'parameter_tree.yml')
[19]:
full_tree.children.keys()
[19]:
dict_keys(['kernel', 'simulation', 'session_models', 'network'])

'network' subtree

The 'network' subtree is expected to have the following children, as we saw above:

[20]:
net_tree = full_tree.children['network']
net_tree.children.keys()
[20]:
dict_keys(['neuron_models', 'synapse_models', 'layers', 'projection_models', 'topology', 'recorder_models', 'recorders'])

It is used to initialize a Network object, representing the full NEST network.

[21]:
net = Network(net_tree)
2020-06-30 13:51:20,459 [denest.network] INFO: Build N=2 ``Model`` objects
2020-06-30 13:51:20,460 [denest.network] INFO: Build N=2 ``SynapseModel`` objects
2020-06-30 13:51:20,461 [denest.network] INFO: Build N=3 ``Model`` objects
2020-06-30 13:51:20,467 [denest.network] INFO: Build N=2 ``Layer`` or ``InputLayer`` objects.
2020-06-30 13:51:20,469 [denest.utils.validation] INFO: Object `proj_1_AMPA`: params: using default value for optional parameters:
{'type': 'topological'}
2020-06-30 13:51:20,470 [denest.utils.validation] INFO: Object `proj_2_GABAA`: params: using default value for optional parameters:
{'type': 'topological'}
2020-06-30 13:51:20,471 [denest.network] INFO: Build N=2 ``ProjectionModel`` objects
2020-06-30 13:51:20,476 [denest.network] INFO: Build N=3 ``TopoProjection`` objects
2020-06-30 13:51:20,484 [denest.network] INFO: Build N=2 population recorders.
2020-06-30 13:51:20,485 [denest.network] INFO: Build N=1 projection recorders.

'kernel' subtree

The kernel subtree is passed to the Simulation.init_kernel method.

  • All nest_params are passed to nest.SetKernelStatus
  • Two optional params:
    • nest_seed (used to initialize at once the thread-wide and general nest rsg. The msd, grng_seed and rng_seed nest params are reserved)
    • extension_modules (used to call nest.Install())
  • Note the data_path parameter is set automatically from the simulation’s 'output_dir'
[22]:
full_tree.children['kernel']
[22]:
ParamsTree(name='kernel', parent='None')
  params:
    nest_seed: 10
    extension_modules: []
  nest_params:
    resolution: 0.5
    overwrite_files: true

'session_models' subtree

The leaves of the 'session_models' subtree define templates from which the parameters of each Session object can be inherited.

The following params are recognized:

  • simulation_time (float): Duration of the session in ms. (mandatory)
  • reset_network (bool): If true, nest.ResetNetwork() is called during session initialization (default False)
  • record (bool): If false, the start_time field of recorder nodes in NEST is set to the end time of the session, so that no data is recorded during the session (default True)
  • shift_origin (bool): If True, the origin flag of the stimulation devices of all the network’s InputLayer layers is set to the start of the session during initialization. Useful to repeat sessions when the stimulators are eg spike generators.
  • unit_changes (list): List describing the changes applied to certain units before the start of the session. Passed to Network.set_state.
  • synapse_changes (list): List describing the changes applied to certain synapses before the start of the session. Passed to Network.set_state. Refer to that method for a description of how synapse_changes is formatted and interpreted. No changes happen if empty. (default [])
[23]:
full_tree.children['session_models']
[23]:
ParamsTree(name='session_models', parent='None')
  params:
    record: true
    shift_origin: true
    simulation_time: 100.0
  nest_params: {}
  warmup:
    params:
      record: false
    nest_params: {}
  2_spikes:
    params:
      unit_changes:
      - layers:
        - input_layer
        population_name: spike_generator

  ... [3 lines] ...

          - 10.0
    nest_params: {}
  3_spikes:
    params:
      unit_changes:
      - layers:
        - input_layer
        population_name: spike_generator
        nest_params:
          spike_times:
          - 1.0
          - 10.0
          - 20.0
    nest_params: {}

[24]:
print("Tree's leaves and their inherited parameters:")
[
    (f'leaf name: {l.name})',
      f'leaf `params`: {dict(l.params)}',
      f'leaf `nest_params`: {dict(l.nest_params)}')
     for l in full_tree.children['session_models'].leaves()
]
Tree's leaves and their inherited parameters:
[24]:
[('leaf name: warmup)',
  "leaf `params`: {'record': False, 'shift_origin': True, 'simulation_time': 100.0}",
  'leaf `nest_params`: {}'),
 ('leaf name: 2_spikes)',
  "leaf `params`: {'record': True, 'shift_origin': True, 'simulation_time': 100.0, 'unit_changes': [{'layers': ['input_layer'], 'population_name': 'spike_generator', 'nest_params': {'spike_times': [1.0, 10.0]}}]}",
  'leaf `nest_params`: {}'),
 ('leaf name: 3_spikes)',
  "leaf `params`: {'record': True, 'shift_origin': True, 'simulation_time': 100.0, 'unit_changes': [{'layers': ['input_layer'], 'population_name': 'spike_generator', 'nest_params': {'spike_times': [1.0, 10.0, 20.0]}}]}",
  'leaf `nest_params`: {}')]

Check out the set_network_state tutorial or the documentation of the Network.set_state() method for details on how to modify the state of the network at the start of a simulation

'simulation' subtree

The ‘simulation’ subtree contains the following parameters:

  • output_dir (str): Path to the output directory (default ‘output’).
  • input_dir (str): Path to the directory in which input files are searched for for each session. (default ‘input’)
  • sessions (list(str)): Order in which sessions are run. Elements of the list should be the name of session models defined in the session_models parameter subtree (default [])
[25]:
full_tree.children['simulation']
[25]:
ParamsTree(name='simulation', parent='None')
  params:
    output_dir: data/outputs/output
    sessions:
    - warmup
    - 3_spikes
    - 2_spikes
    - 3_spikes
  nest_params: {}

Run a full simulation

Load the full parameter tree

The full parameter tree can be loaded from a single file, or from multiple files which are merged.

From a single file by using the yaml.load or the ParamsTree.read methods:

[26]:
ParamsTree.read(PARAMS_DIR/'parameter_tree.yml')
[26]:
ParamsTree(name='None', parent=None)
  params: {}
  nest_params: {}
  kernel:
    params:
      nest_seed: 10
      extension_modules: []
    nest_params:
      resolution: 0.5
      overwrite_files: true
  simulation:
    params:
      output_dir: data/outputs/output
      sessions:
      - warmup
      - 3_spikes

  ... [169 lines] ...

        - layers:
          - input_layer
          populations: null
          model: my_spike_detector
        projection_recorders:
        - source_layers:
          - l1
          source_population: l1_exc
          target_layers:
          - l1
          target_population: l1_inh
          projection_model: proj_1_AMPA
          model: weight_recorder
      nest_params: {}

By merging multiple files, using the denest.load_trees method:

[27]:
!cat {PARAMS_DIR/'tree_paths.yml'}
- './network_tree.yml'
- './simulation.yml'
- './session_models.yml'
- './kernel.yml'
[28]:
full_tree = load_trees(PARAMS_DIR/'tree_paths.yml')
2020-06-30 13:51:21,241 [denest] INFO: Loading parameter file paths from data/params/tree_paths.yml
2020-06-30 13:51:21,245 [denest] INFO: Finished loading parameter file paths
2020-06-30 13:51:21,260 [denest] INFO: Loading parameters files:
['./network_tree.yml',
 './simulation.yml',
 './session_models.yml',
 './kernel.yml']
[29]:
full_tree
[29]:
ParamsTree(name='data/params/tree_paths.yml', parent=None)
  params: {}
  nest_params: {}
  session_models:
    params:
      record: true
      shift_origin: true
      simulation_time: 100.0
    nest_params: {}
    3_spikes:
      params:
        unit_changes:
        - layers:
          - input_layer
          population_name: spike_generator
          nest_params:

  ... [168 lines] ...

          params:
            populations:
              l1_exc: 4
              l1_inh: 2
          nest_params: {}
  simulation:
    params:
      output_dir: ./data/outputs/output
      sessions:
      - warmup
      - 3_spikes
      - 2_spikes
      - 3_spikes
    nest_params: {}

Run with the Simulation object

We load the full parameter tree:

[30]:
tree = ParamsTree.read(PARAMS_DIR/'parameter_tree.yml')

And then initialize the Simulation:

[31]:
sim = Simulation(tree, output_dir=None, input_dir=None)
2020-06-30 13:51:21,596 [denest.utils.validation] INFO: Object `simulation`: params: using default value for optional parameters:
{'input_dir': 'input'}
2020-06-30 13:51:21,598 [denest.simulation] INFO: Initializing NEST kernel and seeds...
2020-06-30 13:51:21,600 [denest.simulation] INFO:   Resetting NEST kernel...
2020-06-30 13:51:21,609 [denest.simulation] INFO:   Setting NEST kernel status...
2020-06-30 13:51:21,609 [denest.simulation] INFO:     Calling `nest.SetKernelStatus({'resolution': 0.5, 'overwrite_files': True})`
2020-06-30 13:51:21,614 [denest.simulation] INFO:     Calling `nest.SetKernelStatus({'data_path': 'data/outputs/output/data', 'grng_seed': 11, 'rng_seeds': range(12, 13)})
2020-06-30 13:51:21,618 [denest.simulation] INFO:   Finished setting NEST kernel status
2020-06-30 13:51:21,636 [denest.simulation] INFO:   Installing external modules...
2020-06-30 13:51:21,637 [denest.simulation] INFO:   Finished installing external modules
2020-06-30 13:51:21,645 [denest.simulation] INFO: Finished initializing kernel
2020-06-30 13:51:21,646 [denest.simulation] INFO: Build N=3 session models
2020-06-30 13:51:21,650 [denest.simulation] INFO: Build N=4 sessions
2020-06-30 13:51:21,663 [denest.session] INFO: Creating session "00_warmup"
2020-06-30 13:51:21,671 [denest.utils.validation] INFO: Object `00_warmup`: params: using default value for optional parameters:
{'reset_network': False, 'synapse_changes': [], 'unit_changes': []}
2020-06-30 13:51:21,674 [denest.session] INFO: Creating session "01_3_spikes"
2020-06-30 13:51:21,678 [denest.utils.validation] INFO: Object `01_3_spikes`: params: using default value for optional parameters:
{'reset_network': False, 'synapse_changes': []}
2020-06-30 13:51:21,688 [denest.session] INFO: Creating session "02_2_spikes"
2020-06-30 13:51:21,715 [denest.utils.validation] INFO: Object `02_2_spikes`: params: using default value for optional parameters:
{'reset_network': False, 'synapse_changes': []}
2020-06-30 13:51:21,718 [denest.session] INFO: Creating session "03_3_spikes"
2020-06-30 13:51:21,720 [denest.utils.validation] INFO: Object `03_3_spikes`: params: using default value for optional parameters:
{'reset_network': False, 'synapse_changes': []}
2020-06-30 13:51:21,740 [denest.simulation] INFO: Sessions: ['00_warmup', '01_3_spikes', '02_2_spikes', '03_3_spikes']
2020-06-30 13:51:21,744 [denest.simulation] INFO: Building network.
2020-06-30 13:51:21,772 [denest.network] INFO: Build N=2 ``Model`` objects
2020-06-30 13:51:21,778 [denest.network] INFO: Build N=2 ``SynapseModel`` objects
2020-06-30 13:51:21,783 [denest.network] INFO: Build N=3 ``Model`` objects
2020-06-30 13:51:21,787 [denest.network] INFO: Build N=2 ``Layer`` or ``InputLayer`` objects.
2020-06-30 13:51:21,793 [denest.utils.validation] INFO: Object `proj_1_AMPA`: params: using default value for optional parameters:
{'type': 'topological'}
2020-06-30 13:51:21,799 [denest.utils.validation] INFO: Object `proj_2_GABAA`: params: using default value for optional parameters:
{'type': 'topological'}
2020-06-30 13:51:21,803 [denest.network] INFO: Build N=2 ``ProjectionModel`` objects
2020-06-30 13:51:21,819 [denest.network] INFO: Build N=3 ``TopoProjection`` objects
2020-06-30 13:51:21,825 [denest.network] INFO: Build N=2 population recorders.
2020-06-30 13:51:21,831 [denest.network] INFO: Build N=1 projection recorders.
2020-06-30 13:51:21,834 [denest.simulation] INFO: Creating network.
2020-06-30 13:51:21,838 [denest.network] INFO: Creating neuron models...
100%|██████████| 2/2 [00:00<00:00, 2590.68it/s]
2020-06-30 13:51:21,868 [denest.network] INFO: Creating synapse models...
100%|██████████| 2/2 [00:00<00:00, 171.95it/s]
2020-06-30 13:51:21,889 [denest.network] INFO: Creating recorder models...
100%|██████████| 3/3 [00:00<00:00, 345.82it/s]
2020-06-30 13:51:21,921 [denest.network] INFO: Creating layers...
  0%|          | 0/2 [00:00<?, ?it/s]/Users/tom/nest/nest-simulator-2.20.0/lib/python3.7/site-packages/nest/lib/hl_api_helper.py:127: UserWarning:
GetNodes is deprecated and will be removed in NEST 3.0. Use             GIDCollection instead.
100%|██████████| 2/2 [00:00<00:00,  4.88it/s]
2020-06-30 13:51:22,365 [denest.network] INFO: Creating population recorders...
100%|██████████| 2/2 [00:00<00:00, 92.98it/s]
2020-06-30 13:51:22,394 [denest.network] INFO: Creating projection recorders...
100%|██████████| 1/1 [00:00<00:00, 509.39it/s]
2020-06-30 13:51:22,428 [denest.network] INFO: Connecting layers...
100%|██████████| 3/3 [00:00<00:00, 623.69it/s]
2020-06-30 13:51:22,444 [denest.network] INFO: Network size (including recorders and parrot neurons):
Number of nodes: 206
Number of projections: 6650
2020-06-30 13:51:22,446 [denest.simulation] INFO: Finished creating network
2020-06-30 13:51:22,447 [denest.simulation] INFO: Saving simulation metadata...
2020-06-30 13:51:22,448 [denest.simulation] INFO: Creating output directory: data/outputs/output
2020-06-30 13:51:22,451 [denest.io.save] INFO: Clearing directory: data/outputs/output
2020-06-30 13:51:22,462 [denest.io.save] INFO: Clearing directory: data/outputs/output
2020-06-30 13:51:22,463 [denest.io.save] INFO: Clearing directory: data/outputs/output/data
2020-06-30 13:51:22,468 [denest.io.save] INFO: Clearing directory: data/outputs/output/data
2020-06-30 13:51:22,474 [denest.io.save] INFO: Clearing directory: data/outputs/output/data
2020-06-30 13:51:22,481 [denest.io.save] INFO: Clearing directory: data/outputs/output
2020-06-30 13:51:22,566 [denest.simulation] INFO: Finished saving simulation metadata

We can inspect the simulation elements:

[32]:
sim.network
[32]:
Network(params: {}
nest_params: {}
neuron_models:
  params: {}
  nest_params: {}
  my_neuron:
    params:
      nest_model: ht_neuron
    nest_params:
      g_KL: 1.0
      g_NaL: 1.0
    l1_exc:
      params: {}
      nest_params:
        V_m: -44.0
    l1_inh:
      params: {}
      nest_params:
        V_m: -55.0
synapse_models:
  params: {}
  nest_params: {}
  my_AMPA_synapse:
    params:
      nest_model: ht_synapse
      receptor_type: AMPA
      target_neuron: ht_neuron
    nest_params: {}
  my_GABAA_synapse:
    params:
      nest_model: ht_synapse
      receptor_type: GABA_A
      target_neuron: ht_neuron
    nest_params: {}
layers:
  params: {}
  nest_params: {}
  layers:
    params:
      type: null
    nest_params:
      rows: 5
      columns: 5
      extent:
      - 5.0
      - 5.0
      edge_wrap: true
    input_layer:
      params:
        type: InputLayer
        add_parrots: true
        populations:
          spike_generator: 1
      nest_params: {}
    l1:
      params:
        populations:
          l1_exc: 4
          l1_inh: 2
      nest_params: {}
projection_models:
  params: {}
  nest_params:
    connection_type: divergent
    mask:
      circular:
        radius: 2.0
    kernel: 1.0
  proj_1_AMPA:
    params: {}
    nest_params:
      synapse_model: my_AMPA_synapse
      weights: 1.0
  proj_2_GABAA:
    params: {}
    nest_params:
      synapse_model: my_GABAA_synapse
      weights: 2.0
topology:
  params:
    projections:
    - source_layers:
      - input_layer
      source_population: parrot_neuron
      target_layers:
      - l1
      target_population: l1_exc
      projection_model: proj_1_AMPA
    - source_layers:
      - l1
      source_population: l1_exc
      target_layers:
      - l1
      target_population: l1_inh
      projection_model: proj_1_AMPA
    - source_layers:
      - l1
      source_population: l1_inh
      target_layers:
      - l1
      target_population: l1_exc
      projection_model: proj_2_GABAA
  nest_params: {}
recorder_models:
  params: {}
  nest_params:
    record_to:
    - memory
    - file
  weight_recorder:
    params:
      nest_model: weight_recorder
    nest_params: {}
  my_multimeter:
    params:
      nest_model: multimeter
    nest_params:
      record_from:
      - V_m
      interval: 20.0
  my_spike_detector:
    params:
      nest_model: spike_detector
    nest_params: {}
recorders:
  params:
    population_recorders:
    - layers:
      - l1
      populations:
      - l1_exc
      model: my_multimeter
    - layers:
      - input_layer
      populations: null
      model: my_spike_detector
    projection_recorders:
    - source_layers:
      - l1
      source_population: l1_exc
      target_layers:
      - l1
      target_population: l1_inh
      projection_model: proj_1_AMPA
      model: weight_recorder
  nest_params: {}
)
[33]:
sim.network.layers
[33]:
{'input_layer': InputLayer(input_layer,
  {'type': 'InputLayer',
   'add_parrots': True,
   'populations': {'spike_generator': 1, 'parrot_neuron': 1}}{'rows': 5,
   'columns': 5,
   'extent': [5.0, 5.0],
   'edge_wrap': True,
   'elements': ('spike_generator', 1, 'parrot_neuron', 1)}),
 'l1': Layer(l1,
  {'type': None, 'populations': {'l1_exc': 4, 'l1_inh': 2}}{'rows': 5,
   'columns': 5,
   'extent': [5.0, 5.0],
   'edge_wrap': True,
   'elements': ('l1_exc', 4, 'l1_inh', 2)})}
[34]:
sim.sessions
[34]:
[Session(00_warmup, {'record': False,
  'reset_network': False,
  'shift_origin': True,
  'simulation_time': 100.0,
  'synapse_changes': [],
  'unit_changes': []}),
 Session(01_3_spikes, {'record': True,
  'reset_network': False,
  'shift_origin': True,
  'simulation_time': 100.0,
  'synapse_changes': [],
  'unit_changes': [{'layers': ['input_layer'],
                    'nest_params': {'spike_times': [1.0, 10.0, 20.0]},
                    'population_name': 'spike_generator'}]}),
 Session(02_2_spikes, {'record': True,
  'reset_network': False,
  'shift_origin': True,
  'simulation_time': 100.0,
  'synapse_changes': [],
  'unit_changes': [{'layers': ['input_layer'],
                    'nest_params': {'spike_times': [1.0, 10.0]},
                    'population_name': 'spike_generator'}]}),
 Session(03_3_spikes, {'record': True,
  'reset_network': False,
  'shift_origin': True,
  'simulation_time': 100.0,
  'synapse_changes': [],
  'unit_changes': [{'layers': ['input_layer'],
                    'nest_params': {'spike_times': [1.0, 10.0, 20.0]},
                    'population_name': 'spike_generator'}]})]

Finally, we actually run all the sessions in NEST by calling Simulation.run():

[35]:
sim.run()
2020-06-30 13:51:22,828 [denest.simulation] INFO: Running 4 sessions...
2020-06-30 13:51:22,831 [denest.simulation] INFO: Running session: '00_warmup'...
2020-06-30 13:51:22,838 [denest.session] INFO: Initializing session...
2020-06-30 13:51:22,840 [denest.network.recorders] INFO:   Setting status for recorder my_multimeter_l1_l1_exc: {'start': 100.0}
2020-06-30 13:51:22,843 [denest.network.recorders] INFO:   Setting status for recorder my_spike_detector_input_layer_parrot_neuron: {'start': 100.0}
2020-06-30 13:51:22,846 [denest.network.recorders] INFO:   Setting status for recorder weight_recorder_proj_1_AMPA-l1-l1_exc-l1-l1_inh: {'start': 100.0}
2020-06-30 13:51:22,847 [denest.session] INFO: Setting `origin` flag to `0.0` for all stimulation devices in ``InputLayers`` for session `00_warmup`
2020-06-30 13:51:22,863 [denest.session] INFO: Finished initializing session

2020-06-30 13:51:22,864 [denest.session] INFO: Running session '00_warmup' for 100 ms
2020-06-30 13:51:23,077 [denest.session] INFO: Finished running session
2020-06-30 13:51:23,079 [denest.session] INFO: Session '00_warmup' virtual running time: 100 ms
2020-06-30 13:51:23,284 [denest.session] INFO: Session '00_warmup' real running time: 0h:00m:00s
2020-06-30 13:51:23,292 [denest.simulation] INFO: Done running session '00_warmup'
2020-06-30 13:51:23,298 [denest.simulation] INFO: Running session: '01_3_spikes'...
2020-06-30 13:51:23,301 [denest.session] INFO: Initializing session...
2020-06-30 13:51:23,305 [denest.session] INFO: Setting `origin` flag to `100.0` for all stimulation devices in ``InputLayers`` for session `01_3_spikes`
2020-06-30 13:51:23,328 [denest.utils.validation] INFO: Object `Unit changes dictionary`: params: using default value for optional parameters:
{'change_type': 'constant', 'from_array': False}
2020-06-30 13:51:23,330 [denest.network.layers] INFO: Layer='input_layer', pop='spike_generator': Applying 'constant' change, param='spike_times', from single value')
2020-06-30 13:51:23,523 [denest.session] INFO: Finished initializing session

2020-06-30 13:51:23,524 [denest.session] INFO: Running session '01_3_spikes' for 100 ms
2020-06-30 13:51:23,746 [denest.session] INFO: Finished running session
2020-06-30 13:51:23,747 [denest.session] INFO: Session '01_3_spikes' virtual running time: 100 ms
2020-06-30 13:51:23,761 [denest.session] INFO: Session '01_3_spikes' real running time: 0h:00m:00s
2020-06-30 13:51:23,764 [denest.simulation] INFO: Done running session '01_3_spikes'
2020-06-30 13:51:23,772 [denest.simulation] INFO: Running session: '02_2_spikes'...
2020-06-30 13:51:23,777 [denest.session] INFO: Initializing session...
2020-06-30 13:51:23,777 [denest.session] INFO: Setting `origin` flag to `200.0` for all stimulation devices in ``InputLayers`` for session `02_2_spikes`
2020-06-30 13:51:23,791 [denest.utils.validation] INFO: Object `Unit changes dictionary`: params: using default value for optional parameters:
{'change_type': 'constant', 'from_array': False}
2020-06-30 13:51:23,795 [denest.network.layers] INFO: Layer='input_layer', pop='spike_generator': Applying 'constant' change, param='spike_times', from single value')
2020-06-30 13:51:23,985 [denest.session] INFO: Finished initializing session

2020-06-30 13:51:23,986 [denest.session] INFO: Running session '02_2_spikes' for 100 ms
2020-06-30 13:51:24,336 [denest.session] INFO: Finished running session
2020-06-30 13:51:24,337 [denest.session] INFO: Session '02_2_spikes' virtual running time: 100 ms
2020-06-30 13:51:24,338 [denest.session] INFO: Session '02_2_spikes' real running time: 0h:00m:00s
2020-06-30 13:51:24,339 [denest.simulation] INFO: Done running session '02_2_spikes'
2020-06-30 13:51:24,341 [denest.simulation] INFO: Running session: '03_3_spikes'...
2020-06-30 13:51:24,344 [denest.session] INFO: Initializing session...
2020-06-30 13:51:24,345 [denest.session] INFO: Setting `origin` flag to `300.0` for all stimulation devices in ``InputLayers`` for session `03_3_spikes`
2020-06-30 13:51:24,352 [denest.utils.validation] INFO: Object `Unit changes dictionary`: params: using default value for optional parameters:
{'change_type': 'constant', 'from_array': False}
2020-06-30 13:51:24,371 [denest.network.layers] INFO: Layer='input_layer', pop='spike_generator': Applying 'constant' change, param='spike_times', from single value')
2020-06-30 13:51:24,470 [denest.session] INFO: Finished initializing session

2020-06-30 13:51:24,471 [denest.session] INFO: Running session '03_3_spikes' for 100 ms
2020-06-30 13:51:24,579 [denest.session] INFO: Finished running session
2020-06-30 13:51:24,580 [denest.session] INFO: Session '03_3_spikes' virtual running time: 100 ms
2020-06-30 13:51:24,581 [denest.session] INFO: Session '03_3_spikes' real running time: 0h:00m:00s
2020-06-30 13:51:24,597 [denest.simulation] INFO: Done running session '03_3_spikes'
2020-06-30 13:51:24,604 [denest.simulation] INFO: Finished running simulation
[36]:
!ls {sim.output_dir}
data               parameter_tree.yml session_times.yml  versions.txt
[37]:
!ls {Path(sim.output_dir)/'data'}
my_multimeter_l1_l1_exc-203-0.dat
my_multimeter_l1_l1_exc.yml
my_spike_detector_input_layer_parrot_neuron-204-0.gdf
my_spike_detector_input_layer_parrot_neuron.yml
weight_recorder_proj_1_AMPA-l1-l1_exc-l1-l1_inh-205-0.csv
weight_recorder_proj_1_AMPA-l1-l1_exc-l1-l1_inh.yml

Run using the denest.run function

The run function is a shorthand for the above steps:

[38]:
denest.run(PARAMS_DIR/'tree_paths.yml')
2020-06-30 13:51:25,053 [denest] INFO:

=== RUNNING SIMULATION ========================================================

2020-06-30 13:51:25,055 [denest] INFO: Loading parameter file paths from data/params/tree_paths.yml
2020-06-30 13:51:25,061 [denest] INFO: Finished loading parameter file paths
2020-06-30 13:51:25,063 [denest] INFO: Loading parameters files:
['./network_tree.yml',
 './simulation.yml',
 './session_models.yml',
 './kernel.yml']
2020-06-30 13:51:25,119 [denest] INFO: Initializing simulation...
2020-06-30 13:51:25,146 [denest.utils.validation] INFO: Object `simulation`: params: using default value for optional parameters:
{'input_dir': 'input'}
2020-06-30 13:51:25,149 [denest.simulation] INFO: Initializing NEST kernel and seeds...
2020-06-30 13:51:25,149 [denest.simulation] INFO:   Resetting NEST kernel...
2020-06-30 13:51:25,163 [denest.simulation] INFO:   Setting NEST kernel status...
2020-06-30 13:51:25,257 [denest.simulation] INFO:     Calling `nest.SetKernelStatus({'resolution': 0.5, 'overwrite_files': True})`
2020-06-30 13:51:25,263 [denest.simulation] INFO:     Calling `nest.SetKernelStatus({'data_path': 'data/outputs/output/data', 'grng_seed': 11, 'rng_seeds': range(12, 13)})
2020-06-30 13:51:25,304 [denest.simulation] INFO:   Finished setting NEST kernel status
2020-06-30 13:51:25,307 [denest.simulation] INFO:   Installing external modules...
2020-06-30 13:51:25,321 [denest.simulation] INFO:   Finished installing external modules
2020-06-30 13:51:25,334 [denest.simulation] INFO: Finished initializing kernel
2020-06-30 13:51:25,337 [denest.simulation] INFO: Build N=3 session models
2020-06-30 13:51:25,340 [denest.simulation] INFO: Build N=4 sessions
2020-06-30 13:51:25,346 [denest.session] INFO: Creating session "00_warmup"
2020-06-30 13:51:25,349 [denest.utils.validation] INFO: Object `00_warmup`: params: using default value for optional parameters:
{'reset_network': False, 'synapse_changes': [], 'unit_changes': []}
2020-06-30 13:51:25,352 [denest.session] INFO: Creating session "01_3_spikes"
2020-06-30 13:51:25,360 [denest.utils.validation] INFO: Object `01_3_spikes`: params: using default value for optional parameters:
{'reset_network': False, 'synapse_changes': []}
2020-06-30 13:51:25,362 [denest.session] INFO: Creating session "02_2_spikes"
2020-06-30 13:51:25,368 [denest.utils.validation] INFO: Object `02_2_spikes`: params: using default value for optional parameters:
{'reset_network': False, 'synapse_changes': []}
2020-06-30 13:51:25,371 [denest.session] INFO: Creating session "03_3_spikes"
2020-06-30 13:51:25,373 [denest.utils.validation] INFO: Object `03_3_spikes`: params: using default value for optional parameters:
{'reset_network': False, 'synapse_changes': []}
2020-06-30 13:51:25,379 [denest.simulation] INFO: Sessions: ['00_warmup', '01_3_spikes', '02_2_spikes', '03_3_spikes']
2020-06-30 13:51:25,384 [denest.simulation] INFO: Building network.
2020-06-30 13:51:25,408 [denest.network] INFO: Build N=2 ``Model`` objects
2020-06-30 13:51:25,414 [denest.network] INFO: Build N=2 ``SynapseModel`` objects
2020-06-30 13:51:25,417 [denest.network] INFO: Build N=3 ``Model`` objects
2020-06-30 13:51:25,422 [denest.network] INFO: Build N=2 ``Layer`` or ``InputLayer`` objects.
2020-06-30 13:51:25,430 [denest.utils.validation] INFO: Object `proj_2_GABAA`: params: using default value for optional parameters:
{'type': 'topological'}
2020-06-30 13:51:25,434 [denest.utils.validation] INFO: Object `proj_1_AMPA`: params: using default value for optional parameters:
{'type': 'topological'}
2020-06-30 13:51:25,435 [denest.network] INFO: Build N=2 ``ProjectionModel`` objects
2020-06-30 13:51:25,440 [denest.network] INFO: Build N=3 ``TopoProjection`` objects
2020-06-30 13:51:25,450 [denest.network] INFO: Build N=2 population recorders.
2020-06-30 13:51:25,452 [denest.network] INFO: Build N=1 projection recorders.
2020-06-30 13:51:25,453 [denest.simulation] INFO: Creating network.
2020-06-30 13:51:25,456 [denest.network] INFO: Creating neuron models...
100%|██████████| 2/2 [00:00<00:00, 1308.06it/s]
2020-06-30 13:51:25,465 [denest.network] INFO: Creating synapse models...
100%|██████████| 2/2 [00:00<00:00, 1308.06it/s]
2020-06-30 13:51:25,473 [denest.network] INFO: Creating recorder models...
100%|██████████| 3/3 [00:00<00:00, 1403.72it/s]
2020-06-30 13:51:25,483 [denest.network] INFO: Creating layers...
100%|██████████| 2/2 [00:00<00:00,  9.27it/s]
2020-06-30 13:51:25,709 [denest.network] INFO: Creating population recorders...
100%|██████████| 2/2 [00:00<00:00, 92.20it/s]
2020-06-30 13:51:25,736 [denest.network] INFO: Creating projection recorders...
100%|██████████| 1/1 [00:00<00:00, 322.39it/s]
2020-06-30 13:51:25,746 [denest.network] INFO: Connecting layers...
100%|██████████| 3/3 [00:00<00:00, 724.70it/s]
2020-06-30 13:51:25,771 [denest.network] INFO: Network size (including recorders and parrot neurons):
Number of nodes: 206
Number of projections: 6650
2020-06-30 13:51:25,773 [denest.simulation] INFO: Finished creating network
2020-06-30 13:51:25,780 [denest.simulation] INFO: Saving simulation metadata...
2020-06-30 13:51:25,780 [denest.simulation] INFO: Creating output directory: ./data/outputs/output
2020-06-30 13:51:25,786 [denest.io.save] INFO: Clearing directory: data/outputs/output
2020-06-30 13:51:25,795 [denest.io.save] INFO: Clearing directory: data/outputs/output
2020-06-30 13:51:25,804 [denest.io.save] INFO: Clearing directory: data/outputs/output/data
2020-06-30 13:51:25,815 [denest.io.save] INFO: Clearing directory: data/outputs/output/data
2020-06-30 13:51:25,816 [denest.io.save] INFO: Clearing directory: data/outputs/output/data
2020-06-30 13:51:25,832 [denest.io.save] INFO: Clearing directory: data/outputs/output
2020-06-30 13:51:25,912 [denest.simulation] INFO: Finished saving simulation metadata
2020-06-30 13:51:25,914 [denest] INFO: Finished initializing simulation
2020-06-30 13:51:25,915 [denest] INFO: Running simulation...
2020-06-30 13:51:25,922 [denest.simulation] INFO: Running 4 sessions...
2020-06-30 13:51:25,932 [denest.simulation] INFO: Running session: '00_warmup'...
2020-06-30 13:51:25,935 [denest.session] INFO: Initializing session...
2020-06-30 13:51:25,937 [denest.network.recorders] INFO:   Setting status for recorder my_multimeter_l1_l1_exc: {'start': 100.0}
2020-06-30 13:51:25,950 [denest.network.recorders] INFO:   Setting status for recorder my_spike_detector_input_layer_parrot_neuron: {'start': 100.0}
2020-06-30 13:51:25,956 [denest.network.recorders] INFO:   Setting status for recorder weight_recorder_proj_1_AMPA-l1-l1_exc-l1-l1_inh: {'start': 100.0}
2020-06-30 13:51:25,959 [denest.session] INFO: Setting `origin` flag to `0.0` for all stimulation devices in ``InputLayers`` for session `00_warmup`
2020-06-30 13:51:25,974 [denest.session] INFO: Finished initializing session

2020-06-30 13:51:25,976 [denest.session] INFO: Running session '00_warmup' for 100 ms
2020-06-30 13:51:26,173 [denest.session] INFO: Finished running session
2020-06-30 13:51:26,175 [denest.session] INFO: Session '00_warmup' virtual running time: 100 ms
2020-06-30 13:51:26,180 [denest.session] INFO: Session '00_warmup' real running time: 0h:00m:00s
2020-06-30 13:51:26,181 [denest.simulation] INFO: Done running session '00_warmup'
2020-06-30 13:51:26,190 [denest.simulation] INFO: Running session: '01_3_spikes'...
2020-06-30 13:51:26,191 [denest.session] INFO: Initializing session...
2020-06-30 13:51:26,214 [denest.session] INFO: Setting `origin` flag to `100.0` for all stimulation devices in ``InputLayers`` for session `01_3_spikes`
2020-06-30 13:51:26,258 [denest.utils.validation] INFO: Object `Unit changes dictionary`: params: using default value for optional parameters:
{'change_type': 'constant', 'from_array': False}
2020-06-30 13:51:26,260 [denest.network.layers] INFO: Layer='input_layer', pop='spike_generator': Applying 'constant' change, param='spike_times', from single value')
2020-06-30 13:51:26,445 [denest.session] INFO: Finished initializing session

2020-06-30 13:51:26,446 [denest.session] INFO: Running session '01_3_spikes' for 100 ms
2020-06-30 13:51:26,754 [denest.session] INFO: Finished running session
2020-06-30 13:51:26,754 [denest.session] INFO: Session '01_3_spikes' virtual running time: 100 ms
2020-06-30 13:51:26,755 [denest.session] INFO: Session '01_3_spikes' real running time: 0h:00m:00s
2020-06-30 13:51:26,758 [denest.simulation] INFO: Done running session '01_3_spikes'
2020-06-30 13:51:26,762 [denest.simulation] INFO: Running session: '02_2_spikes'...
2020-06-30 13:51:26,764 [denest.session] INFO: Initializing session...
2020-06-30 13:51:26,770 [denest.session] INFO: Setting `origin` flag to `200.0` for all stimulation devices in ``InputLayers`` for session `02_2_spikes`
2020-06-30 13:51:26,815 [denest.utils.validation] INFO: Object `Unit changes dictionary`: params: using default value for optional parameters:
{'change_type': 'constant', 'from_array': False}
2020-06-30 13:51:26,816 [denest.network.layers] INFO: Layer='input_layer', pop='spike_generator': Applying 'constant' change, param='spike_times', from single value')
2020-06-30 13:51:26,885 [denest.session] INFO: Finished initializing session

2020-06-30 13:51:26,886 [denest.session] INFO: Running session '02_2_spikes' for 100 ms
2020-06-30 13:51:27,046 [denest.session] INFO: Finished running session
2020-06-30 13:51:27,047 [denest.session] INFO: Session '02_2_spikes' virtual running time: 100 ms
2020-06-30 13:51:27,048 [denest.session] INFO: Session '02_2_spikes' real running time: 0h:00m:00s
2020-06-30 13:51:27,063 [denest.simulation] INFO: Done running session '02_2_spikes'
2020-06-30 13:51:27,069 [denest.simulation] INFO: Running session: '03_3_spikes'...
2020-06-30 13:51:27,083 [denest.session] INFO: Initializing session...
2020-06-30 13:51:27,091 [denest.session] INFO: Setting `origin` flag to `300.0` for all stimulation devices in ``InputLayers`` for session `03_3_spikes`
2020-06-30 13:51:27,097 [denest.utils.validation] INFO: Object `Unit changes dictionary`: params: using default value for optional parameters:
{'change_type': 'constant', 'from_array': False}
2020-06-30 13:51:27,101 [denest.network.layers] INFO: Layer='input_layer', pop='spike_generator': Applying 'constant' change, param='spike_times', from single value')
2020-06-30 13:51:27,201 [denest.session] INFO: Finished initializing session

2020-06-30 13:51:27,202 [denest.session] INFO: Running session '03_3_spikes' for 100 ms
2020-06-30 13:51:27,455 [denest.session] INFO: Finished running session
2020-06-30 13:51:27,459 [denest.session] INFO: Session '03_3_spikes' virtual running time: 100 ms
2020-06-30 13:51:27,475 [denest.session] INFO: Session '03_3_spikes' real running time: 0h:00m:00s
2020-06-30 13:51:27,517 [denest.simulation] INFO: Done running session '03_3_spikes'
2020-06-30 13:51:27,519 [denest.simulation] INFO: Finished running simulation
2020-06-30 13:51:27,530 [denest] INFO: Finished running simulation
2020-06-30 13:51:27,543 [denest] INFO: Total simulation virtual time: 400.0 ms
2020-06-30 13:51:27,564 [denest] INFO: Total simulation real time: 0h:00m:02s
2020-06-30 13:51:27,567 [denest] INFO: Simulation output written to: /Users/tom/docker/nets-dev/docs/source/tutorials/data/outputs/output

Run from the command line

A simulation can also be run directly from the command line as follows:

python3 -m denest <tree_paths.yml> [-o <output_dir>]