The Network object

We’ll familiarize ourselves with the Network object by interactively building the elements of the network one by one.

Usually, we’d initialize all the elements of the network at once by providing the full 'network' tree as an argument to the Network class during initialization.

In this tutorial we:

  1. Initialize an empty Network object
  2. Initialize all the elements of the network using the Network.build_* methods
    1. Models (neuron models, recorder models, synapse models
    2. Layers
    3. Projection models
    4. Individual projections
    5. Population and projection recorders
  3. Create the network in NEST
  4. Access the network elements (GIDs, etc)
  5. Export and reuse the parameter tree allowing us to replicate the network
[1]:
import nest
import yaml
from pathlib import Path
from pprint import pprint
[2]:
from denest import *
import denest
[3]:
PARAMS_DIR = Path('./data/params/network')

Initialize an empty network

When initialized without argument or with an empty tree as an argument, all the expected subtrees are initialized as empty.

When building the elements interactively, the network’s parameters are updated.

[4]:
net = Network()
2020-06-30 13:42:37,794 [denest.utils.validation] INFO: 'None' tree: adding empty child neuron_models
2020-06-30 13:42:37,795 [denest.utils.validation] INFO: 'None' tree: adding empty child synapse_models
2020-06-30 13:42:37,796 [denest.utils.validation] INFO: 'None' tree: adding empty child layers
2020-06-30 13:42:37,797 [denest.utils.validation] INFO: 'None' tree: adding empty child projection_models
2020-06-30 13:42:37,799 [denest.utils.validation] INFO: 'None' tree: adding empty child topology
2020-06-30 13:42:37,800 [denest.utils.validation] INFO: 'None' tree: adding empty child recorder_models
2020-06-30 13:42:37,803 [denest.utils.validation] INFO: 'None' tree: adding empty child recorders
2020-06-30 13:42:37,806 [denest.network] INFO: Build N=0 ``Model`` objects
2020-06-30 13:42:37,809 [denest.network] INFO: Build N=0 ``SynapseModel`` objects
2020-06-30 13:42:37,809 [denest.network] INFO: Build N=0 ``Model`` objects
2020-06-30 13:42:37,812 [denest.network] INFO: Build N=0 ``Layer`` or ``InputLayer`` objects.
2020-06-30 13:42:37,814 [denest.network] INFO: Build N=0 ``ProjectionModel`` objects
2020-06-30 13:42:37,815 [denest.utils.validation] INFO: Object `topology`: params: using default value for optional parameters:
{'projections': []}
2020-06-30 13:42:37,816 [denest.network] INFO: Build N=0 ``TopoProjection`` objects
2020-06-30 13:42:37,819 [denest.utils.validation] INFO: Object `recorders`: params: using default value for optional parameters:
{'population_recorders': [], 'projection_recorders': []}
2020-06-30 13:42:37,823 [denest.network] INFO: Build N=0 population recorders.
2020-06-30 13:42:37,824 [denest.network] INFO: Build N=0 projection recorders.

The Network’s parameter tree is empty:

[5]:
net.tree
[5]:
ParamsTree(name='None', parent=None)
  params: {}
  nest_params: {}
  neuron_models:
    params: {}
    nest_params: {}
  synapse_models:
    params: {}
    nest_params: {}
  layers:
    params: {}
    nest_params: {}
  projection_models:
    params: {}
    nest_params: {}
  topology:
    params: {}
    nest_params: {}
  recorder_models:
    params: {}
    nest_params: {}
  recorders:
    params: {}
    nest_params: {}

Build the network components (models, layers, projections, recorders)

Define new models

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:

Initalize Network.neuron_models with the Network.build_neuron_models method

[6]:
neuron_models_tree = ParamsTree.read(PARAMS_DIR/'models.yml').children['neuron_models']
pprint(neuron_models_tree)
ParamsTree(name='neuron_models', parent='None')
  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

[7]:
net.build_neuron_models(neuron_models_tree)
2020-06-30 13:42:38,050 [denest.network] INFO: Build N=2 ``Model`` objects
[8]:
# The neuron models are saved as an attribute for the Network object
print("\n``Network.neuron_models`` :")
pprint(net.neuron_models)

``Network.neuron_models`` :
{'l1_exc': Model(l1_exc, {'nest_model': 'ht_neuron'}, {'V_m': -44.0, 'g_KL': 1.0, 'g_NaL': 1.0}),
 'l1_inh': Model(l1_inh, {'nest_model': 'ht_neuron'}, {'V_m': -55.0, 'g_KL': 1.0, 'g_NaL': 1.0})}
[9]:
pprint(net.neuron_models['l1_exc'])
pprint(net.neuron_models['l1_exc'].params)
pprint(net.neuron_models['l1_exc'].nest_params)
Model(l1_exc, {'nest_model': 'ht_neuron'}, {'V_m': -44.0, 'g_KL': 1.0, 'g_NaL': 1.0})
{'nest_model': 'ht_neuron'}
{'V_m': -44.0, 'g_KL': 1.0, 'g_NaL': 1.0}

'recorder_models' tree

Initalize Network.recorder_models with the Network.build_recorder_models method, as with neuron models:

[10]:
# ``Network.build_*`` methods accept as argument ``ParamsTree`` objects, but also tree-like dictionaries
recorder_models_tree = ParamsTree.read(PARAMS_DIR/'models.yml').children['recorder_models']
recorder_models_tree
[10]:
ParamsTree(name='recorder_models', parent='None')
  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: {}

[11]:
# ``Network.build_*`` methods accept as argument ``ParamsTree`` objects, but also tree-like dictionaries
recorder_models_tree = recorder_models_tree.asdict()
recorder_models_tree
[11]:
{'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': {}}}
[12]:
net.build_recorder_models(recorder_models_tree)
2020-06-30 13:42:38,389 [denest.network] INFO: Build N=3 ``Model`` objects
[13]:
print("\n``Network.recorder_models`` :")
pprint(net.recorder_models)

``Network.recorder_models`` :
{'my_multimeter': Model(my_multimeter, {'nest_model': 'multimeter'}, {'interval': 20.0, 'record_from': ['V_m'], 'record_to': ['memory', 'file']}),
 'my_spike_detector': Model(my_spike_detector, {'nest_model': 'spike_detector'}, {'record_to': ['memory', 'file']}),
 'weight_recorder': Model(weight_recorder, {'nest_model': 'weight_recorder'}, {'record_to': ['memory', 'file']})}

'synapse_model' tree

Initalize Network.synapse_models with the Network.build_synapse_model method.

  • Same 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.
[14]:
synapse_models_tree = ParamsTree.read(PARAMS_DIR/'models.yml').children['synapse_models']
synapse_models_tree
[14]:
ParamsTree(name='synapse_models', parent='None')
  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: {}

[15]:
net.build_synapse_models(synapse_models_tree)
2020-06-30 13:42:38,570 [denest.network] INFO: Build N=2 ``SynapseModel`` objects
[16]:
print("\n``Network.synapse_models`` :")
pprint(net.synapse_models)

``Network.synapse_models`` :
{'my_AMPA_synapse': SynapseModel(my_AMPA_synapse, {'nest_model': 'ht_synapse'}, {'receptor_type': 1}),
 'my_GABAA_synapse': SynapseModel(my_GABAA_synapse, {'nest_model': 'ht_synapse'}, {'receptor_type': 3})}

Note that the receptor_type nest_parameter was inferred

Define layers

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

'layers' tree

[17]:
layer_tree = ParamsTree.read(PARAMS_DIR/'layers.yml')
layer_tree
[17]:
ParamsTree(name='None', parent=None)
  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: {}

[18]:
net.build_layers(layer_tree)
2020-06-30 13:42:38,801 [denest.network] INFO: Build N=2 ``Layer`` or ``InputLayer`` objects.
[19]:
pprint(net.layers)
{'input_layer': InputLayer(input_layer, {'add_parrots': True,
 'populations': {'parrot_neuron': 1, 'spike_generator': 1},
 'type': 'InputLayer'}, {'columns': 5,
 'edge_wrap': True,
 'elements': ('spike_generator', 1, 'parrot_neuron', 1),
 'extent': [5.0, 5.0],
 'rows': 5}),
 'l1': Layer(l1, {'populations': {'l1_exc': 4, 'l1_inh': 2}, 'type': None}, {'columns': 5,
 'edge_wrap': True,
 'elements': ('l1_exc', 4, 'l1_inh', 2),
 'extent': [5.0, 5.0],
 'rows': 5})}
[20]:
print("'l1' layer")
pprint(net.layers['l1'].params)
pprint(net.layers['l1'].nest_params)
'l1' layer
{'populations': {'l1_exc': 4, 'l1_inh': 2}, 'type': None}
{'columns': 5,
 'edge_wrap': True,
 'elements': ('l1_exc', 4, 'l1_inh', 2),
 'extent': [5.0, 5.0],
 'rows': 5}

Define projections

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

Define templates from the projection_models tree

[21]:
proj_model_tree = ParamsTree.read(PARAMS_DIR/'projections.yml').children['projection_models']
proj_model_tree
[21]:
ParamsTree(name='projection_models', parent='None')
  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

[22]:
net.build_projection_models(proj_model_tree)
2020-06-30 13:42:39,014 [denest.utils.validation] INFO: Object `proj_1_AMPA`: params: using default value for optional parameters:
{'type': 'topological'}
2020-06-30 13:42:39,021 [denest.utils.validation] INFO: Object `proj_2_GABAA`: params: using default value for optional parameters:
{'type': 'topological'}
2020-06-30 13:42:39,022 [denest.network] INFO: Build N=2 ``ProjectionModel`` objects
[23]:
net.projection_models
[23]:
{'proj_1_AMPA': ProjectionModel(proj_1_AMPA,
  {'type': 'topological'}{'connection_type': 'divergent',
   'mask': {'circular': {'radius': 2.0}},
   'kernel': 1.0,
   'synapse_model': 'my_AMPA_synapse',
   'weights': 1.0}),
 'proj_2_GABAA': ProjectionModel(proj_2_GABAA,
  {'type': 'topological'}{'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

[24]:
conns_tree = ParamsTree.read(PARAMS_DIR/'projections.yml').children['topology']
conns_tree
[24]:
ParamsTree(name='topology', parent='None')
  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: {}

[25]:
net.projection_models
[25]:
{'proj_1_AMPA': ProjectionModel(proj_1_AMPA,
  {'type': 'topological'}{'connection_type': 'divergent',
   'mask': {'circular': {'radius': 2.0}},
   'kernel': 1.0,
   'synapse_model': 'my_AMPA_synapse',
   'weights': 1.0}),
 'proj_2_GABAA': ProjectionModel(proj_2_GABAA,
  {'type': 'topological'}{'connection_type': 'divergent',
   'mask': {'circular': {'radius': 2.0}},
   'kernel': 1.0,
   'synapse_model': 'my_GABAA_synapse',
   'weights': 2.0})}
[26]:
net.build_projections(conns_tree)
2020-06-30 13:42:39,277 [denest.network] INFO: Build N=3 ``TopoProjection`` objects
[27]:
net.projections
[27]:
[TopoProjection(proj_1_AMPA-input_layer-parrot_neuron-l1-l1_exc,
  {'type': 'topological'}{'connection_type': 'divergent',
   'mask': {'circular': {'radius': 2.0}},
   'kernel': 1.0,
   'synapse_model': 'my_AMPA_synapse',
   'weights': 1.0,
   'sources': {'model': 'parrot_neuron'},
   'targets': {'model': 'l1_exc'}}),
 TopoProjection(proj_1_AMPA-l1-l1_exc-l1-l1_inh,
  {'type': 'topological'}{'connection_type': 'divergent',
   'mask': {'circular': {'radius': 2.0}},
   'kernel': 1.0,
   'synapse_model': 'my_AMPA_synapse',
   'weights': 1.0,
   'sources': {'model': 'l1_exc'},
   'targets': {'model': 'l1_inh'}}),
 TopoProjection(proj_2_GABAA-l1-l1_inh-l1-l1_exc,
  {'type': 'topological'}{'connection_type': 'divergent',
   'mask': {'circular': {'radius': 2.0}},
   'kernel': 1.0,
   'synapse_model': 'my_GABAA_synapse',
   'weights': 2.0,
   'sources': {'model': 'l1_inh'},
   'targets': {'model': 'l1_exc'}})]

Define recorders from the recorders tree

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

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

See the documentation for 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).

[28]:
recorders_tree = ParamsTree.read(PARAMS_DIR/'recorders.yml').children['recorders']
recorders_tree
[28]:
ParamsTree(name='recorders', parent='None')
  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: {}

[29]:
net.build_recorders(recorders_tree)
2020-06-30 13:42:39,443 [denest.network] INFO: Build N=2 population recorders.
2020-06-30 13:42:39,444 [denest.network] INFO: Build N=1 projection recorders.
[30]:
net.population_recorders
[30]:
[PopulationRecorder(my_multimeter_l1_l1_exc,  {}{}),
 PopulationRecorder(my_spike_detector_input_layer_parrot_neuron,  {}{})]
[31]:
net.projection_recorders
[31]:
[ProjectionRecorder(weight_recorder_proj_1_AMPA-l1-l1_exc-l1-l1_inh,  {}{})]

Create the network

[32]:
nest.ResetKernel()
nest.SetKernelStatus({'overwrite_files': True})
[33]:
net.create()
2020-06-30 13:42:39,792 [denest.network] INFO: Creating neuron models...
100%|██████████| 2/2 [00:00<00:00, 1881.70it/s]
2020-06-30 13:42:39,804 [denest.network] INFO: Creating synapse models...
100%|██████████| 2/2 [00:00<00:00, 1215.21it/s]
2020-06-30 13:42:39,811 [denest.network] INFO: Creating recorder models...
100%|██████████| 3/3 [00:00<00:00, 1383.80it/s]
2020-06-30 13:42:39,839 [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,  9.04it/s]
2020-06-30 13:42:40,070 [denest.network] INFO: Creating population recorders...
100%|██████████| 2/2 [00:00<00:00, 54.77it/s]
2020-06-30 13:42:40,123 [denest.network] INFO: Creating projection recorders...
100%|██████████| 1/1 [00:00<00:00, 139.27it/s]
2020-06-30 13:42:40,145 [denest.network] INFO: Connecting layers...
100%|██████████| 3/3 [00:00<00:00, 137.19it/s]
2020-06-30 13:42:40,182 [denest.network] INFO: Network size (including recorders and parrot neurons):
Number of nodes: 206
Number of projections: 6650

Examine the network

deNEST provides convenient ways of accessing the objects in NEST.

Check the defaults of the created models

[34]:
print("`l1_exc` neuron models `nest_params`: ", net.neuron_models['l1_exc'].nest_params)
`l1_exc` neuron models `nest_params`:  {'g_KL': 1.0, 'g_NaL': 1.0, 'V_m': -44.0}
[35]:
print('Corresponding params of the `l1_exc` model in nest:', nest.GetDefaults('l1_exc', list(net.neuron_models['l1_exc'].nest_params.keys())))
Corresponding params of the `l1_exc` model in nest: (1.0, 1.0, -44.0)

Access the layers’ units

[36]:
print('Layer `l1` shape: ', net.layers['l1'].layer_shape)
print('Population shapes: ', net.layers['l1'].population_shape)
Layer `l1` shape:  (5, 5)
Population shapes:  {'l1_exc': (5, 5, 4), 'l1_inh': (5, 5, 2)}
[37]:
net.layers['l1'].gids(location=(0, 0), population='l1_exc')
[37]:
[53, 78, 103, 128]

Access the projections created in NEST

[38]:
conn = net.projections[0]
conn
[38]:
TopoProjection(proj_1_AMPA-input_layer-parrot_neuron-l1-l1_exc,
{'type': 'topological'}{'connection_type': 'divergent',
 'mask': {'circular': {'radius': 2.0}},
 'kernel': 1.0,
 'synapse_model': 'my_AMPA_synapse',
 'weights': 1.0,
 'sources': {'model': 'parrot_neuron'},
 'targets': {'model': 'l1_exc'}})
[39]:
nest_conns = nest.GetConnections(
    source=conn.source.gids(conn.source_population),
    target=conn.target.gids(conn.target_population),
    synapse_model=conn.nest_params['synapse_model']
)
nest_conns[0:5]
[39]:
(array('l', [27, 53, 0, 68, 0]),
 array('l', [27, 88, 0, 68, 1]),
 array('l', [27, 83, 0, 68, 2]),
 array('l', [27, 152, 0, 68, 3]),
 array('l', [27, 84, 0, 68, 4]))

Access the recorders

[40]:
rec = net.population_recorders[0]
print(rec, rec.gid, rec.model, rec.layer, rec.population_name)
my_multimeter_l1_l1_exc (203,) my_multimeter l1 l1_exc
[41]:
connrec = net.projection_recorders[0]
print(connrec, connrec.gid, connrec.model)
weight_recorder_proj_1_AMPA-l1-l1_exc-l1-l1_inh (205,) weight_recorder

Save and replicate the network

When building each of the network’s elements using the Network.build_* methods, the Network.tree parameters were updated.

[42]:
net.tree
[42]:
ParamsTree(name='None', 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

  ... [117 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: {}

We can save the parameter tree defining the whole network…

[43]:
net.tree.write(PARAMS_DIR/'network_tree.yml')
[43]:
PosixPath('data/params/network/network_tree.yml')

And use it to recreate another identical network.

[44]:
net2 = Network(ParamsTree.read(PARAMS_DIR/'network_tree.yml'))
2020-06-30 13:42:41,016 [denest.network] INFO: Build N=2 ``Model`` objects
2020-06-30 13:42:41,017 [denest.network] INFO: Build N=2 ``SynapseModel`` objects
2020-06-30 13:42:41,018 [denest.network] INFO: Build N=3 ``Model`` objects
2020-06-30 13:42:41,019 [denest.network] INFO: Build N=2 ``Layer`` or ``InputLayer`` objects.
2020-06-30 13:42:41,021 [denest.utils.validation] INFO: Object `proj_1_AMPA`: params: using default value for optional parameters:
{'type': 'topological'}
2020-06-30 13:42:41,024 [denest.utils.validation] INFO: Object `proj_2_GABAA`: params: using default value for optional parameters:
{'type': 'topological'}
2020-06-30 13:42:41,025 [denest.network] INFO: Build N=2 ``ProjectionModel`` objects
2020-06-30 13:42:41,030 [denest.network] INFO: Build N=3 ``TopoProjection`` objects
2020-06-30 13:42:41,033 [denest.network] INFO: Build N=2 population recorders.
2020-06-30 13:42:41,034 [denest.network] INFO: Build N=1 projection recorders.
[45]:
nest.ResetKernel()
net2.create()
2020-06-30 13:42:41,185 [denest.network] INFO: Creating neuron models...
100%|██████████| 2/2 [00:00<00:00, 134.07it/s]
2020-06-30 13:42:41,215 [denest.network] INFO: Creating synapse models...
100%|██████████| 2/2 [00:00<00:00, 1224.97it/s]
2020-06-30 13:42:41,234 [denest.network] INFO: Creating recorder models...
100%|██████████| 3/3 [00:00<00:00, 1727.24it/s]
2020-06-30 13:42:41,249 [denest.network] INFO: Creating layers...
100%|██████████| 2/2 [00:00<00:00, 10.27it/s]
2020-06-30 13:42:41,474 [denest.network] INFO: Creating population recorders...
100%|██████████| 2/2 [00:00<00:00, 24.22it/s]
2020-06-30 13:42:41,596 [denest.network] INFO: Creating projection recorders...
100%|██████████| 1/1 [00:00<00:00, 55.00it/s]
2020-06-30 13:42:41,616 [denest.network] INFO: Connecting layers...
100%|██████████| 3/3 [00:00<00:00, 184.37it/s]
2020-06-30 13:42:41,645 [denest.network] INFO: Network size (including recorders and parrot neurons):
Number of nodes: 206
Number of projections: 6650
[46]:
print(net.layers['l1'].gids(location=(0, 0), population='l1_exc'))
print(net2.layers['l1'].gids(location=(0, 0), population='l1_exc'))
[53, 78, 103, 128]
[53, 78, 103, 128]