def setUp(self): sim.setup() self.p1 = sim.Population(7, sim.IF_cond_exp()) self.p2 = sim.Population(4, sim.IF_cond_exp()) self.p3 = sim.Population(5, sim.IF_curr_alpha()) self.syn1 = sim.StaticSynapse(weight=0.123, delay=0.5) self.syn2 = sim.StaticSynapse(weight=0.456, delay=0.4) self.random_connect = sim.FixedNumberPostConnector(n=2) self.all2all = sim.AllToAllConnector()
def build_network(sim, order=1000, epsilon=0.1, delay=1.5, J=0.1, theta=20.0, tau=20.0, tau_syn=0.1, tau_refrac=2.0, v_reset=10.0, R=1.5, g=5, eta=2, seed=None): NE = 4 * order NI = 1 * order CE = int(epsilon * NE) # number of excitatory synapses per neuron CI = int(epsilon * NI) # number of inhibitory synapses per neuron CMem = tau/R J_unit = psp_height(tau, R, tau_syn) J_ex = J / J_unit J_in = -g * J_ex nu_th = theta / (J_ex * CE * R * tau_syn) nu_ex = eta * nu_th p_rate = 1000.0 * nu_ex * CE assert seed is not None rng = NumpyRNG(seed) neuron_params = { "nrn_tau": tau, "nrn_v_threshold": theta, "nrn_refractory_period": tau_refrac, "nrn_v_reset": v_reset, "nrn_R": R, "syn_tau": tau_syn } celltype = Dynamics(name='iaf', subnodes={'nrn': read("sources/BrunelIaF.xml")['BrunelIaF'], 'syn': read("sources/AlphaPSR.xml")['AlphaPSR']}) celltype.connect_ports('syn.i_synaptic', 'nrn.i_synaptic') exc = sim.Population(NE, nineml_cell_type('BrunelIaF', celltype, {'syn': 'syn_weight'})(**neuron_params)) inh = sim.Population(NI, nineml_cell_type('BrunelIaF', celltype, {'syn': 'syn_weight'})(**neuron_params)) all = exc + inh all.initialize(v=RandomDistribution('uniform', (0.0, theta), rng=rng)) stim = sim.Population(NE + NI, nineml_cell_type('Poisson', read("sources/Poisson.xml")['Poisson'], {})(rate=p_rate)) print("Connecting network") exc_synapse = sim.StaticSynapse(weight=J_ex, delay=delay) inh_synapse = sim.StaticSynapse(weight=J_in, delay=delay) input_connections = sim.Projection(stim, all, sim.OneToOneConnector(), exc_synapse, receptor_type="syn") exc_connections = sim.Projection(exc, all, sim.FixedNumberPreConnector(n=CE), exc_synapse, receptor_type="syn") # check is Pre not Post inh_connections = sim.Projection(inh, all, sim.FixedNumberPreConnector(n=CI), inh_synapse, receptor_type="syn") return stim, exc, inh
ee_srcs = lintfix(ee_srcs) ee_tgs = lintfix(ee_tgs) ii_srcs = all_cells[ii_srcs] ii_tgs = all_cells[list(ii_tgs)] ee_srcs = all_cells[list(ee_srcs)] ee_tgs = all_cells[list(ee_tgs)] ei_srcs = all_cells[list(ei_srcs)] ei_tgs = all_cells[list(ei_tgs)] ie_srcs = all_cells[list(ie_srcs)] ie_tgs = all_cells[list(ie_tgs)] exc_distr = RandomDistribution('normal', [3.125, 10e-2], rng=rng) exc_syn = sim.StaticSynapse(weight=exc_distr, delay=delay_distr) #if numpy.any(self.conn_list[:, 0] >= projection.pre.size): assert np.any(internal_conn_ee.conn_list[:, 0]) < ee_srcs.size prj_exc_exc = sim.Projection(all_cells, all_cells, internal_conn_ee, exc_syn, receptor_type='excitatory') inh_distr = RandomDistribution('normal', [5, 2.1e-4], rng=rng) inh_syn = sim.StaticSynapse(weight=inh_distr, delay=delay_distr) iis = all_cells[[e[0] for e in IIlist]] iit = all_cells[[e[1] for e in IIlist]]
import pyNN.neuron as sim # can of course replace `neuron` with `nest`, `brian`, etc. import matplotlib.pyplot as plt import numpy as np sim.setup(timestep=0.01) p_in = sim.Population(10, sim.SpikeSourcePoisson(rate=10.0), label="input") p_out = sim.Population(10, sim.EIF_cond_exp_isfa_ista(), label="AdExp neurons") syn = sim.StaticSynapse(weight=0.05) random = sim.FixedProbabilityConnector(p_connect=0.5) connections = sim.Projection(p_in, p_out, random, syn, receptor_type='excitatory') p_in.record('spikes') p_out.record('spikes') # record spikes from all neurons p_out[0:2].record(['v', 'w', 'gsyn_exc']) # record other variables from first two neurons sim.run(500.0) spikes_in = p_in.get_data() data_out = p_out.get_data() fig_settings = { 'lines.linewidth': 0.5, 'axes.linewidth': 0.5, 'axes.labelsize': 'small', 'legend.fontsize': 'small', 'font.size': 8 } plt.rcParams.update(fig_settings) plt.figure(1, figsize=(6, 8))
def sim_runner(wgf): wg = wgf import pyNN.neuron as sim nproc = sim.num_processes() node = sim.rank() print(nproc) import matplotlib matplotlib.use('Agg') import matplotlib.pyplot as plt import matplotlib as mpl mpl.rcParams.update({'font.size':16}) #import mpi4py #threads = sim.rank() threads = 1 rngseed = 98765 parallel_safe = False #extra = {'threads' : threads} import os import pandas as pd import sys import numpy as np from pyNN.neuron import STDPMechanism import copy from pyNN.random import RandomDistribution, NumpyRNG import pyNN.neuron as neuron from pyNN.neuron import h from pyNN.neuron import StandardCellType, ParameterSpace from pyNN.random import RandomDistribution, NumpyRNG from pyNN.neuron import STDPMechanism, SpikePairRule, AdditiveWeightDependence, FromListConnector, TsodyksMarkramSynapse from pyNN.neuron import Projection, OneToOneConnector from numpy import arange import pyNN from pyNN.utility import get_simulator, init_logging, normalized_filename import random import socket #from neuronunit.optimization import get_neab import networkx as nx sim = pyNN.neuron # Get some hippocampus connectivity data, based on a conversation with # academic researchers on GH: # https://github.com/Hippocampome-Org/GraphTheory/issues?q=is%3Aissue+is%3Aclosed # scrape hippocamome connectivity data, that I intend to use to program neuromorphic hardware. # conditionally get files if they don't exist. path_xl = '_hybrid_connectivity_matrix_20171103_092033.xlsx' if not os.path.exists(path_xl): os.system('wget https://github.com/Hippocampome-Org/GraphTheory/files/1657258/_hybrid_connectivity_matrix_20171103_092033.xlsx') xl = pd.ExcelFile(path_xl) dfEE = xl.parse() dfEE.loc[0].keys() dfm = dfEE.as_matrix() rcls = dfm[:,:1] # real cell labels. rcls = rcls[1:] rcls = { k:v for k,v in enumerate(rcls) } # real cell labels, cast to dictionary import pickle with open('cell_names.p','wb') as f: pickle.dump(rcls,f) import pandas as pd pd.DataFrame(rcls).to_csv('cell_names.csv', index=False) filtered = dfm[:,3:] filtered = filtered[1:] rng = NumpyRNG(seed=64754) delay_distr = RandomDistribution('normal', [2, 1e-1], rng=rng) weight_distr = RandomDistribution('normal', [45, 1e-1], rng=rng) sanity_e = [] sanity_i = [] EElist = [] IIlist = [] EIlist = [] IElist = [] for i,j in enumerate(filtered): for k,xaxis in enumerate(j): if xaxis == 1 or xaxis == 2: source = i sanity_e.append(i) target = k if xaxis ==-1 or xaxis == -2: sanity_i.append(i) source = i target = k index_exc = list(set(sanity_e)) index_inh = list(set(sanity_i)) import pickle with open('cell_indexs.p','wb') as f: returned_list = [index_exc, index_inh] pickle.dump(returned_list,f) import numpy a = numpy.asarray(index_exc) numpy.savetxt('pickles/'+str(k)+'excitatory_nunber_labels.csv', a, delimiter=",") import numpy a = numpy.asarray(index_inh) numpy.savetxt('pickles/'+str(k)+'inhibitory_nunber_labels.csv', a, delimiter=",") for i,j in enumerate(filtered): for k,xaxis in enumerate(j): if xaxis==1 or xaxis == 2: source = i sanity_e.append(i) target = k delay = delay_distr.next() weight = 1.0 if target in index_inh: EIlist.append((source,target,delay,weight)) else: EElist.append((source,target,delay,weight)) if xaxis==-1 or xaxis == -2: sanity_i.append(i) source = i target = k delay = delay_distr.next() weight = 1.0 if target in index_exc: IElist.append((source,target,delay,weight)) else: IIlist.append((source,target,delay,weight)) internal_conn_ee = sim.FromListConnector(EElist) ee = internal_conn_ee.conn_list ee_srcs = ee[:,0] ee_tgs = ee[:,1] internal_conn_ie = sim.FromListConnector(IElist) ie = internal_conn_ie.conn_list ie_srcs = set([ int(e[0]) for e in ie ]) ie_tgs = set([ int(e[1]) for e in ie ]) internal_conn_ei = sim.FromListConnector(EIlist) ei = internal_conn_ei.conn_list ei_srcs = set([ int(e[0]) for e in ei ]) ei_tgs = set([ int(e[1]) for e in ei ]) internal_conn_ii = sim.FromListConnector(IIlist) ii = internal_conn_ii.conn_list ii_srcs = set([ int(e[0]) for e in ii ]) ii_tgs = set([ int(e[1]) for e in ii ]) for e in internal_conn_ee.conn_list: assert e[0] in ee_srcs assert e[1] in ee_tgs for i in internal_conn_ii.conn_list: assert i[0] in ii_srcs assert i[1] in ii_tgs ml = len(filtered[1])+1 pre_exc = [] post_exc = [] pre_inh = [] post_inh = [] rng = NumpyRNG(seed=64754) delay_distr = RandomDistribution('normal', [2, 1e-1], rng=rng) plot_EE = np.zeros(shape=(ml,ml), dtype=bool) plot_II = np.zeros(shape=(ml,ml), dtype=bool) plot_EI = np.zeros(shape=(ml,ml), dtype=bool) plot_IE = np.zeros(shape=(ml,ml), dtype=bool) for i in EElist: plot_EE[i[0],i[1]] = int(0) #plot_ss[i[0],i[1]] = int(1) if i[0]!=i[1]: # exclude self connections plot_EE[i[0],i[1]] = int(1) pre_exc.append(i[0]) post_exc.append(i[1]) assert len(pre_exc) == len(post_exc) for i in IIlist: plot_II[i[0],i[1]] = int(0) if i[0]!=i[1]: plot_II[i[0],i[1]] = int(1) pre_inh.append(i[0]) post_inh.append(i[1]) for i in IElist: plot_IE[i[0],i[1]] = int(0) if i[0]!=i[1]: # exclude self connections plot_IE[i[0],i[1]] = int(1) pre_inh.append(i[0]) post_inh.append(i[1]) for i in EIlist: plot_EI[i[0],i[1]] = int(0) if i[0]!=i[1]: plot_EI[i[0],i[1]] = int(1) pre_exc.append(i[0]) post_exc.append(i[1]) plot_excit = plot_EI + plot_EE plot_inhib = plot_IE + plot_II assert len(pre_inh) == len(post_inh) num_exc = [ i for i,e in enumerate(plot_excit) if sum(e) > 0 ] num_inh = [ y for y,i in enumerate(plot_inhib) if sum(i) > 0 ] # the network is dominated by inhibitory neurons, which is unusual for modellers. assert num_inh > num_exc assert np.sum(plot_inhib) > np.sum(plot_excit) assert len(num_exc) < ml assert len(num_inh) < ml # # Plot all the Projection pairs as a connection matrix (Excitatory and Inhibitory Connections) import pickle with open('graph_inhib.p','wb') as f: pickle.dump(plot_inhib,f, protocol=2) import pickle with open('graph_excit.p','wb') as f: pickle.dump(plot_excit,f, protocol=2) #with open('cell_names.p','wb') as f: # pickle.dump(rcls,f) import pandas as pd pd.DataFrame(plot_EE).to_csv('ee.csv', index=False) import pandas as pd pd.DataFrame(plot_IE).to_csv('ie.csv', index=False) import pandas as pd pd.DataFrame(plot_II).to_csv('ii.csv', index=False) import pandas as pd pd.DataFrame(plot_EI).to_csv('ei.csv', index=False) from scipy.sparse import coo_matrix m = np.matrix(filtered[1:]) bool_matrix = np.add(plot_excit,plot_inhib) with open('bool_matrix.p','wb') as f: pickle.dump(bool_matrix,f, protocol=2) if not isinstance(m, coo_matrix): m = coo_matrix(m) Gexc_ud = nx.Graph(plot_excit) avg_clustering = nx.average_clustering(Gexc_ud)#, nodes=None, weight=None, count_zeros=True)[source] rc = nx.rich_club_coefficient(Gexc_ud,normalized=False) print('This graph structure as rich as: ',rc[0]) gexc = nx.DiGraph(plot_excit) gexcc = nx.betweenness_centrality(gexc) top_exc = sorted(([ (v,k) for k, v in dict(gexcc).items() ]), reverse=True) in_degree = gexc.in_degree() top_in = sorted(([ (v,k) for k, v in in_degree.items() ])) in_hub = top_in[-1][1] out_degree = gexc.out_degree() top_out = sorted(([ (v,k) for k, v in out_degree.items() ])) out_hub = top_out[-1][1] mean_out = np.mean(list(out_degree.values())) mean_in = np.mean(list(in_degree.values())) mean_conns = int(mean_in + mean_out/2) k = 2 # number of neighbouig nodes to wire. p = 0.25 # probability of instead wiring to a random long range destination. ne = len(plot_excit)# size of small world network small_world_ring_excit = nx.watts_strogatz_graph(ne,mean_conns,0.25) k = 2 # number of neighbouring nodes to wire. p = 0.25 # probability of instead wiring to a random long range destination. ni = len(plot_inhib)# size of small world network small_world_ring_inhib = nx.watts_strogatz_graph(ni,mean_conns,0.25) nproc = sim.num_processes() nproc = 8 host_name = socket.gethostname() node_id = sim.setup(timestep=0.01, min_delay=1.0)#, **extra) print("Host #%d is on %s" % (node_id + 1, host_name)) rng = NumpyRNG(seed=64754) #pop_size = len(num_exc)+len(num_inh) #num_exc = [ i for i,e in enumerate(plot_excit) if sum(e) > 0 ] #num_inh = [ y for y,i in enumerate(plot_inhib) if sum(i) > 0 ] #pop_exc = sim.Population(len(num_exc), sim.Izhikevich(a=0.02, b=0.2, c=-65, d=8, i_offset=0)) #pop_inh = sim.Population(len(num_inh), sim.Izhikevich(a=0.02, b=0.25, c=-65, d=2, i_offset=0)) #index_exc = list(set(sanity_e)) #index_inh = list(set(sanity_i)) all_cells = sim.Population(len(index_exc)+len(index_inh), sim.Izhikevich(a=0.02, b=0.2, c=-65, d=8, i_offset=0)) #all_cells = None #all_cells = pop_exc + pop_inh pop_exc = sim.PopulationView(all_cells,index_exc) pop_inh = sim.PopulationView(all_cells,index_inh) #print(pop_exc) #print(dir(pop_exc)) for pe in pop_exc: print(pe) #import pdb pe = all_cells[pe] #pdb.set_trace() #pe = all_cells[i] r = random.uniform(0.0, 1.0) pe.set_parameters(a=0.02, b=0.2, c=-65+15*r, d=8-r**2, i_offset=0) #pop_exc.append(pe) #pop_exc = sim.Population(pop_exc) for pi in index_inh: pi = all_cells[pi] #print(pi) #pi = all_cells[i] r = random.uniform(0.0, 1.0) pi.set_parameters(a=0.02+0.08*r, b=0.25-0.05*r, c=-65, d= 2, i_offset=0) #pop_inh.append(pi) #pop_inh = sim.Population(pop_inh) ''' for pe in pop_exc: r = random.uniform(0.0, 1.0) pe.set_parameters(a=0.02, b=0.2, c=-65+15*r, d=8-r**2, i_offset=0) for pi in pop_inh: r = random.uniform(0.0, 1.0) pi.set_parameters(a=0.02+0.08*r, b=0.25-0.05*r, c=-65, d= 2, i_offset=0) ''' NEXC = len(num_exc) NINH = len(num_inh) exc_syn = sim.StaticSynapse(weight = wg, delay=delay_distr) assert np.any(internal_conn_ee.conn_list[:,0]) < ee_srcs.size prj_exc_exc = sim.Projection(all_cells, all_cells, internal_conn_ee, exc_syn, receptor_type='excitatory') prj_exc_inh = sim.Projection(all_cells, all_cells, internal_conn_ei, exc_syn, receptor_type='excitatory') inh_syn = sim.StaticSynapse(weight = wg, delay=delay_distr) delay_distr = RandomDistribution('normal', [1, 100e-3], rng=rng) prj_inh_inh = sim.Projection(all_cells, all_cells, internal_conn_ii, inh_syn, receptor_type='inhibitory') prj_inh_exc = sim.Projection(all_cells, all_cells, internal_conn_ie, inh_syn, receptor_type='inhibitory') inh_distr = RandomDistribution('normal', [1, 2.1e-3], rng=rng) def prj_change(prj,wg): prj.setWeights(wg) prj_change(prj_exc_exc,wg) prj_change(prj_exc_inh,wg) prj_change(prj_inh_exc,wg) prj_change(prj_inh_inh,wg) def prj_check(prj): for w in prj.weightHistogram(): for i in w: print(i) prj_check(prj_exc_exc) prj_check(prj_exc_inh) prj_check(prj_inh_exc) prj_check(prj_inh_inh) #print(rheobase['value']) #print(float(rheobase['value']),1.25/1000.0) '''Old values that worked noise = sim.NoisyCurrentSource(mean=0.85/1000.0, stdev=5.00/1000.0, start=0.0, stop=2000.0, dt=1.0) pop_exc.inject(noise) #1000.0 pA noise = sim.NoisyCurrentSource(mean=1.740/1000.0, stdev=5.00/1000.0, start=0.0, stop=2000.0, dt=1.0) pop_inh.inject(noise) #1750.0 pA ''' noise = sim.NoisyCurrentSource(mean=0.74/1000.0, stdev=4.00/1000.0, start=0.0, stop=2000.0, dt=1.0) pop_exc.inject(noise) #1000.0 pA noise = sim.NoisyCurrentSource(mean=1.440/1000.0, stdev=4.00/1000.0, start=0.0, stop=2000.0, dt=1.0) pop_inh.inject(noise) ## # Setup and run a simulation. Note there is no current injection into the neuron. # All cells in the network are in a quiescent state, so its not a surprise that xthere are no spikes ## sim = pyNN.neuron arange = np.arange import re all_cells.record(['v','spikes']) # , 'u']) all_cells.initialize(v=-65.0, u=-14.0) # === Run the simulation ===================================================== tstop = 2000.0 sim.run(tstop) data = None data = all_cells.get_data().segments[0] #print(len(data.analogsignals[0].times)) with open('pickles/qi'+str(wg)+'.p', 'wb') as f: pickle.dump(data,f) # make data none or else it will grow in a loop all_cells = None data = None noise = None
if hasattr(i, "__len__"): return [gen() for j in i] else: return gen() assert generate_spike_times(0).max() > simtime spike_source = sim.Population( n, sim.SpikeSourceArray(spike_times=generate_spike_times)) spike_source.record('spikes') cells.record('spikes') cells[0:2].record('m') syn = sim.StaticSynapse(weight=w, delay=syn_delay) input_conns = sim.Projection(spike_source, cells, sim.FixedProbabilityConnector(0.5), syn, receptor_type="default") # === Run simulation =========================================================== sim.run(simtime) filename = normalized_filename("Results", "nrn_artificial_cell", "pkl", "neuron", sim.num_processes()) cells.write_data(filename, annotations={'script_name': __file__}) print("Mean firing rate: ", cells.mean_spike_count() * 1000.0 / simtime, "Hz")
p = sim.Population(1, sim.IF_curr_alpha(**cell_parameters)) p.initialize(v=0.0) rate = 20 stim = sim.Population( 1, nineml_cell_type('Poisson', read("../sources/Poisson.xml")['Poisson'], {})(rate=rate)) stim.initialize(t_next=numpy.random.exponential(1000 / rate)) weight = 0.1 delay = 0.5 prj = sim.Projection(stim, p, sim.AllToAllConnector(), sim.StaticSynapse(weight=weight, delay=delay), receptor_type='excitatory') stim.record('spikes') p.record('v') sim.run(t_stop) nrn_data = p.get_data().segments[0] stim_data = stim.get_data().segments[0] print("Expected spike count: {}".format(t_stop * rate / 1000)) print("Actual spike count: {}".format(stim.mean_spike_count())) Figure( Panel(stim_data.spiketrains, markersize=0.5, xlim=(0, t_stop)),
# PyNN/NineML simulation sim.setup(timestep=dt) celltype = Dynamics(name='iaf', subnodes={'nrn': read("../sources/BrunelIaF.xml")['BrunelIaF'], 'syn': read("../sources/AlphaPSR.xml")['AlphaPSR']}) celltype.connect_ports('syn.i_synaptic', 'nrn.i_synaptic') p = sim.Population(2, nineml_cell_type('BrunelIaF', celltype, {'syn': 'syn_weight'})(**cell_parameters)) stim = sim.Population(1, sim.SpikeSourceArray(spike_times=spike_times)) prj = sim.Projection(stim, p, sim.AllToAllConnector(), sim.StaticSynapse(weight=w_eff, delay=delay), receptor_type='syn') p.record(['nrn_v', 'syn_a', 'syn_b']) sim.run(t_stop) nrn_data = p.get_data().segments[0] expected = np.zeros((1 + int(round(t_stop/dt)),)) tau_syn = cell_parameters["syn_tau"] tp = np.arange(0, t_stop - spike_times[0] - delay, dt)/tau_syn expected[1 + int(round((spike_times[0] + delay)/dt)):] = w_eff * tp * np.exp(-tp) synaptic_current = nrn_data.filter(name='syn_a')[0] # for convenience of plotting, we overwrite the synaptic current recorded from the second neuron
# -*- coding: utf-8 -*- """ Created on Mon Dec 28 14:36:30 2015 @author: Hari """ import pyNN.neuron as sim import matplotlib.pyplot as plt import numpy as np sim.setup(timestep=0.01) p_in = sim.Population(10, sim.SpikeSourcePoisson(rate=10.0), label="input") p_out = sim.Population(10, sim.EIF_cond_exp_isfa_ista(), label="AdExp neurons") syn = sim.StaticSynapse(weight=0.05, delay=0.0) random = sim.FixedProbabilityConnector(p_connect=0.5) connections = sim.Projection(p_in, p_out, random, syn, receptor_type='excitatory') p_in.record('spikes') p_out.record('spikes') # record spikes from all neurons # record other things from first two neurons p_out[0:2].record(['v', 'w', 'gsyn_exc']) sim.run(500.0) spikes_in = p_in.get_data() data_out = p_out.get_data() fig_settings = {
tau_refrac=2.0, v_reset=10.0, v_rest=0.0, cm=tau/1.5, tau_syn_E=tau_syn, tau_syn_I=tau_syn) ext_stim = sim.SpikeSourcePoisson(rate=input_rate) exc_cells = sim.Population(Ne, celltype, initial_values={'v': v_init}, label="Exc") inh_cells = sim.Population(Ni, celltype, initial_values={'v': v_init}, label="Inh") external = sim.Population(int(Cext), ext_stim, label="Ext") all_cells = exc_cells + inh_cells all_to_all = sim.AllToAllConnector(callback=ProgressBar()) random_uniform = sim.FixedProbabilityConnector(p_connect=epsilon, callback=ProgressBar()) static_ext = sim.StaticSynapse(delay=delay, weight=Jext) static_exc = sim.StaticSynapse(delay=delay, weight=Je) static_inh = sim.StaticSynapse(delay=delay, weight=Ji) input_prj = sim.Projection(external, all_cells, all_to_all, synapse_type=static_ext, receptor_type="excitatory", label="External") exc_prj = sim.Projection(exc_cells, all_cells, random_uniform, synapse_type=static_exc, receptor_type="excitatory", label="Excitation") inh_prj = sim.Projection(inh_cells, all_cells, random_uniform, synapse_type=static_inh, receptor_type="inhibitory", label="Inhibition") external.sample(50).record("spikes") all_cells.sample(50).record("spikes")