NEST SONATA network


Run this example as a Jupyter notebook:

See our guide for more information and troubleshooting.


This script builds and simulates a network of point neurons represented by the SONATA format [1]. The network model consists of 300 internal nodes (explicitly simulated) and 100 external nodes (only provide inputs to the simulated system). The SONATA files can be found in the pynest/examples/sonata_example/300_pointneurons directory.

See the NEST SONATA guide for details on the NEST support of the SONATA format.

References

Import all necessary packages for simulation, analysis and plotting.

from pathlib import Path

import matplotlib.pyplot as plt
import nest

nest.set_verbosity("M_ERROR")
nest.ResetKernel()

Specify the path to the SONATA .json configuration file(s). The 300_pointneurons model has two configuration files: One circuit and one simulation configuration file. We locate the configuration files relative to this example script.

base_path = Path(__file__).resolve().parent
sonata_path = base_path / "300_pointneurons"
net_config = sonata_path / "circuit_config.json"
sim_config = sonata_path / "simulation_config.json"

SONATA networks are built and simulated through the SonataNetwork class. SONATA config files are passed to the class constructor. Passing a second config is optional and only relevant if the network and simulation configurations are specified separately.

First, we instantiate the class.

sonata_net = nest.SonataNetwork(net_config, sim_config=sim_config)

Next, we build the network. The network nodes are created by the membership function Create() and their connections by the membership function Connect(). For convenience, we only need to call the membership function BuildNetwork() which internally calls Create() and Connect()

For large networks, the edges HDF5 files might not fit into memory in their entirety. In the NEST kernel, the edges HDF5 datasets are therefore read sequentially in blocks of contiguous hyperslabs. The hyperslab size is modifiable through the keyword argument hdf5_hyperslab_size. This allows the user to control the balance between the number of read operations and memory overhead.

BuildNetwork() returns a dictionary containing the created NodeCollections. The population names are the dictionary keys.

node_collections = sonata_net.BuildNetwork(hdf5_hyperslab_size=2**20)

We can now verify whether the built network has the expected number of nodes and connections.

print(f'Network built from SONATA specifications in directory "{sonata_path.name}"')
print(f"  Number of nodes      : {nest.network_size}")
print(f"  Number of connections: {nest.num_connections}")

NEST does not currently support SONATA Spike Train Reports or utilize other output components in the SONATA config. This means that recording devices must be created and connected manually.

Here, we create a spike_recorder to record the spiking events of neurons. We wish to connect the spike recorder to the internal population and only record from a subset of the neurons in the population. We extract the internal population’s NodeCollection from the node_collections dictionary by using the internal population’s name. Then we slice the NodeCollection with a list specifying the node ids of the neurons we wish to record from.

s_rec = nest.Create("spike_recorder")
pop_name = "internal"
record_node_ids = [1, 80, 160, 240, 270]
nest.Connect(node_collections[pop_name][record_node_ids], s_rec)

Finally, we call the membership function Simulate() to simulate the network. Note that the simulation time and resolution are expected to be provided in the SONATA config.

sonata_net.Simulate()

After the simulation has finished, we can obtain the data recorded by the spike recorder for further analysis.

nest.raster_plot.from_device(s_rec)
plt.show()

Gallery generated by Sphinx-Gallery