In [1]:
import nest
import random
nest.ResetKernel()
# three input neurons
input_neurons = [nest.Create("iaf_neuron")[0] for x in range(3)]
# single output neuron
output_neuron = nest.Create("iaf_neuron")
for node in input_neurons:
weight = 300 + 200 * random.random()
nest.Connect([node], output_neuron, syn_spec={'weight': weight, 'model': 'static_synapse'})
# inject current / noise to some input neurons
dc = nest.Create("dc_generator", 1)
nest.SetStatus(dc, {'amplitude': 30.0, 'start': 50., 'stop': 100.})
nest.Connect(dc, [input_neurons[0]], syn_spec={'weight': 150.0, 'model': 'static_synapse'})
# record voltage of ouput neuron
voltmeter = nest.Create('multimeter', params={'record_from': ['V_m'], 'withtime': True})
nest.Connect(voltmeter, output_neuron)
# detect spikes from output neuron
detector = nest.Create('spike_detector')
nest.Connect(output_neuron, detector, 'all_to_all')
# simulation
nest.Simulate(200)
In [2]:
import nix
import nix4nest
f = nix.File.open("/tmp/simulation.h5", nix.FileMode.Overwrite)
block = f.create_nest_block("demo", "simulation")
# save neurons / injection devices
for node_id in input_neurons + list(output_neuron) + list(dc):
# give output neuron a special name
name = 'output' if node_id == output_neuron[0] else None
block.dump_node(node_id, name)
# save connections
for source, target in [(i, output_neuron[0]) for i in input_neurons]:
block.dump_connection(source, target)
# save recorded voltage
signal = block.dump_multimeter(voltmeter[0], 'V_m')
# save detected spikes
spiketrains = block.dump_spike_detector(detector[0])
f.close()
In [3]:
from plotting import multiple_time_series
from datetime import datetime
import numpy as np
f = nix.File.open("/tmp/simulation.h5", nix.FileMode.ReadOnly)
block = f.blocks[0]
# get all neurons
neurons = filter(lambda x: x.type == 'neuron', block.nodes)
# get output neuron
output_neuron = filter(lambda x: x.name == 'output', block.nodes)[0]
# explore neuron properties
print output_neuron.properties['model'] # 'iaf_neuron'
print output_neuron.properties['V_th'] # -55.0 (threshold)
print output_neuron.properties['V_reset'] # -70.0 (reset)
print output_neuron.created_at.strftime("%Y-%m-%d %H:%M")
In [4]:
# all signals
block.signals
# signal from particular neuron
voltage = filter(lambda x: x.source and x.source.name == 'output', block.signals)[0]
# plot selected signal with stimulus
dc = filter(lambda x: x.type == 'stimulator', block.nodes)[0]
current = np.zeros(voltage.data.size)
current[dc.properties['start']:dc.properties['stop']] = dc.properties['amplitude']
times = np.arange(0, voltage.data.size, voltage.sampling.sampling_interval)
events = np.array([voltage.data[:], current])
labels = ('output neuron, %s' % voltage.unit, 'injected current')
fig = multiple_time_series(events, labels, times)
In [5]:
# all spiketrains
block.spiketrains
# get spiketrains from a certain neuron
spiketrain = filter(lambda x: x.source and x.source.name == 'output', block.spiketrains)[0]
# plot selected spiketrain with signal
labels = ('spikes', 'output neuron, %s' % voltage.unit)
spikes = np.zeros(voltage.data.size)
for spike_time in [(np.abs(times-x)).argmin() for x in spiketrain.data[:]]:
spikes[spike_time] = 1
fig = multiple_time_series(np.array([spikes, voltage.data[:]]), labels, times)
In [6]:
# all connections
synapses = block.connections
# plot synaptic weights
labels = ['from %s to %s' % (str(x.properties['source']), str(x.properties['target'])) for x in synapses]
x = [x.properties['weight'] for x in synapses]
y = np.arange(len(synapses))
import matplotlib.pyplot as plt
plt.barh(y, x, align='center', alpha=0.4)
plt.yticks(y, labels)
plt.xlabel('Weight')
Out[6]:
In [7]:
f.close()