def test_ConnectPrePostParams(self): """Connect pre to post with a params dict""" # OneToOneConnect([pre], [post], params) nest.ResetKernel() pre = nest.Create("iaf_neuron", 2) post = nest.Create("iaf_neuron", 2) nest.OneToOneConnect(pre, post, {"weight": 2.0}) connections = nest.FindConnections(pre) weights = nest.GetStatus(connections, "weight") self.assertEqual(weights, (2.0, 2.0)) # OneToOneConnect([pre], [post], [params]) nest.ResetKernel() pre = nest.Create("iaf_neuron", 2) post = nest.Create("iaf_neuron", 2) nest.OneToOneConnect(pre, post, [{"weight": 2.0}]) connections = nest.FindConnections(pre) weights = nest.GetStatus(connections, "weight") self.assertEqual(weights, (2.0, 2.0)) # OneToOneConnect([pre], [post], [params, params]) nest.ResetKernel() pre = nest.Create("iaf_neuron", 2) post = nest.Create("iaf_neuron", 2) nest.OneToOneConnect(pre, post, [{"weight": 2.0}, {"weight": 3.0}]) connections = nest.FindConnections(pre) weights = nest.GetStatus(connections, "weight") self.assertEqual(weights, (2.0, 3.0))
def test_CSA_OneToOne_params(self): """One-to-one connectivity""" nest.ResetKernel() n = 4 # number of neurons pop0 = nest.LayoutNetwork("iaf_neuron", [n]) pop1 = nest.LayoutNetwork("iaf_neuron", [n]) cs = csa.cset(csa.oneToOne, 10000.0, 1.0) nest.CGConnect(pop0, pop1, cs, {"weight": 0, "delay": 1}) sources = nest.GetLeaves(pop0)[0] targets = nest.GetLeaves(pop1)[0] for i in xrange(n): conns = nest.GetStatus(nest.FindConnections([sources[i]]), 'target') self.assertEqual(len(conns), 1) self.assertEqual(conns[0], targets[i]) conns = nest.GetStatus(nest.FindConnections([targets[i]]), 'target') self.assertEqual(len(conns), 0)
def test_CSA_OneToOne_subnet_1d(self): """One-to-one connectivity with 1-dim subnets""" nest.ResetKernel() n = 4 # number of neurons pop0 = nest.LayoutNetwork("iaf_neuron", [n]) pop1 = nest.LayoutNetwork("iaf_neuron", [n]) cg = csa.cset(csa.oneToOne) nest.CGConnect(pop0, pop1, cg) sources = nest.GetLeaves(pop0)[0] targets = nest.GetLeaves(pop1)[0] for i in range(n): conns = nest.GetStatus(nest.FindConnections([sources[i]]), 'target') self.assertEqual(len(conns), 1) self.assertEqual(conns[0], targets[i]) conns = nest.GetStatus(nest.FindConnections([targets[i]]), 'target') self.assertEqual(len(conns), 0)
def test_ConnectPrePostWD(self): """Connect pre to post with a weight and delay""" # OneToOneConnect([pre], [post], w, d) nest.ResetKernel() pre = nest.Create("iaf_neuron", 2) post = nest.Create("iaf_neuron", 2) nest.OneToOneConnect(pre, post, 2.0, 2.0) connections = nest.FindConnections(pre) weights = nest.GetStatus(connections, "weight") self.assertEqual(weights, (2.0, 2.0)) # OneToOneConnect([pre], [post], [w], [d]) nest.ResetKernel() pre = nest.Create("iaf_neuron", 2) post = nest.Create("iaf_neuron", 2) nest.OneToOneConnect(pre, post, (2.0, ), (2.0, )) connections = nest.FindConnections(pre) weights = nest.GetStatus(connections, "weight") delays = nest.GetStatus(connections, "delay") self.assertEqual(weights, (2.0, 2.0)) self.assertEqual(delays, (2.0, 2.0)) # OneToOneConnect([pre], [post], [w, w], [d, d]) nest.ResetKernel() pre = nest.Create("iaf_neuron", 2) post = nest.Create("iaf_neuron", 2) nest.OneToOneConnect(pre, post, (2.0, 3.0), (2.0, 3.0)) connections = nest.FindConnections(pre) weights = nest.GetStatus(connections, "weight") delays = nest.GetStatus(connections, "delay") self.assertEqual(weights, (2.0, 3.0)) self.assertEqual(delays, (2.0, 3.0))
def getConnMatrix(self, popType): ''' Return all *input* connections to neuron with index post from the specified popType. Parameters ---------- popType : string, 'E' or 'I' Type of the population. If popType == 'E', return connection weights for AMPA connections only. The NMDA connections will be a fraction of the AMPA connection strength specified by the NMDA_amount parameter. If popType == 'I' the connection weights returned will be for GABA_A connections. output : a 2D numpy array An array containing the connections. The shape is (post, pre)/(target, source). ''' EStart = np.min(self.E_pop) IStart = np.min(self.I_pop) print("EStart: {0}".format(EStart)) print("IStart: {0}".format(IStart)) print("len(self.E_pop): {0}".format(len(self.E_pop))) print("len(self.I_pop): {0}".format(len(self.I_pop))) if popType == 'E': W_IE = np.zeros((len(self.I_pop), len(self.E_pop))) for e in xrange(len(self.E_pop)): print("E neuron {0} --> I neurons".format(e)) conns = nest.FindConnections([self.E_pop[e]]) for i in xrange(len(conns)): target = nest.GetStatus([conns[i]], 'target') if target[0] in self.I_pop: W_IE[target[0] - IStart, e] = \ nest.GetStatus([conns[i]], 'weight')[0] return W_IE elif popType == 'I': W_EI = np.zeros((len(self.E_pop), len(self.I_pop))) for i in xrange(len(self.I_pop)): print("I neuron {0} --> E neurons".format(i)) conns = nest.FindConnections([self.I_pop[i]]) for e in xrange(len(conns)): target = nest.GetStatus([conns[e]], 'target') if target[0] in self.E_pop: W_EI[target[0] - EStart, i] = \ nest.GetStatus([conns[e]], 'weight')[0] return W_EI else: msg = 'popType must be either \'E\' or \'I\'. Got {0}' raise ValueError(msg.format(popType))
def plot_network(nodes, filename, ext_conns=False): """ Plot the given nodes and the connections that originate from them. Note that connections to targets not in nodea are not drawn if ext_conns is False. If it is True, they are drawn to a node named 'ext'. """ adjlist = [[j, nest.GetStatus(nest.FindConnections([j]), 'target')] for j in nodes] gr = pydot.Dot() for n in nodes: gr.add_node(pydot.Node(name=str(n))) for cl in adjlist: if not ext_conns: cl[1] = [i for i in cl[1] if i in nodes] else: tmp = [] for i in cl[1]: if i in nodes: tmp.append(i) else: tmp.append("external") cl[1] = tmp for t in cl[1]: gr.add_edge(pydot.Edge(str(cl[0]), str(t))) gr.write_pdf(filename)
def GetConn(soruces, targets): c = [] for s in soruces: for t in targets: c.extend(nest.GetStatus(nest.FindConnections([s], [t]))) return c
def test_FindConnections(self): """FindConnections""" nest.ResetKernel() a=nest.Create("iaf_neuron", 3) nest.DivergentConnect(a,a) c1=nest.FindConnections(a) c2=nest.FindConnections(a, synapse_model="static_synapse") self.assertEqual(c1, c2) d1=[{"weight": w} for w in [2.0, 3.0, 4.0]] c3=nest.FindConnections(a, a) nest.SetStatus(c3, d1) s1=nest.GetStatus(c3, "weight") self.assertEqual(s1, [w["weight"] for w in d1])
def test_DivergentConnect(self): """DivergentConnect pre to post""" nest.ResetKernel() pre = nest.Create("iaf_neuron", 1) post = nest.Create("iaf_neuron", 3) nest.DivergentConnect(pre, post) connections = nest.FindConnections(pre) targets = nest.GetStatus(connections, "target") self.assertEqual(targets, post)
def test_ConnectPrePost(self): """Connect pre to post""" # OneToOneConnect([pre], [post]) nest.ResetKernel() pre = nest.Create("iaf_neuron", 2) post = nest.Create("iaf_neuron", 2) nest.OneToOneConnect(pre, post) connections = nest.FindConnections(pre) targets = nest.GetStatus(connections, "target") self.assertEqual(targets, post)
def test_ConvergentConnect(self): """ConvergentConnect pre to post""" nest.ResetKernel() pre = nest.Create("iaf_neuron", 3) post = nest.Create("iaf_neuron", 1) nest.ConvergentConnect(pre, post) expected_targets = tuple(post[0] for _ in range(len(pre))) connections = nest.FindConnections(pre) targets = nest.GetStatus(connections, "target") self.assertEqual(expected_targets, targets)
def test_CSA_OneToOne_idrange(self): """One-to-one connectivity with id ranges""" nest.ResetKernel() n = 4 # number of neurons sources = nest.Create("iaf_neuron", n) targets = nest.Create("iaf_neuron", n) cg = csa.cset(csa.oneToOne) nest.CGConnect(sources, targets, cg) for i in range(n): conns = nest.GetStatus(nest.FindConnections([sources[i]]), 'target') self.assertEqual(len(conns), 1) self.assertEqual(conns[0], targets[i]) conns = nest.GetStatus(nest.FindConnections([targets[i]]), 'target') self.assertEqual(len(conns), 0)
def _getIPCConnections(self): IStart = self.I_pop[0] W = np.zeros((len(self.I_pop), len(self.IPC))) for pcn in xrange(len(self.IPC)): print("IPC {0} --> I neurons".format(pcn)) conns = nest.FindConnections([self.IPC[pcn]]) for i in xrange(len(conns)): target = nest.GetStatus([conns[i]], 'target') if target[0] in self.I_pop: W[target[0] - IStart, pcn] = nest.GetStatus([conns[i]], 'weight')[0] else: print("Target not in I_pop!") return W
def test_DivergentConnectWD(self): """DivergentConnect pre to post with weight and delay""" nest.ResetKernel() pre = nest.Create("iaf_neuron", 1) post = nest.Create("iaf_neuron", 3) nest.DivergentConnect(pre, post, weight=(2.0, 2.0, 2.0), delay=(1.0, 2.0, 3.0)) connections = nest.FindConnections(pre) weights = nest.GetStatus(connections, "weight") delays = nest.GetStatus(connections, "delay") self.assertEqual(weights, (2.0, 2.0, 2.0)) self.assertEqual(delays, (1.0, 2.0, 3.0))
def find_connections(self): ''' FindConnections(self) Find connections for each node in layer ''' # Clear self.connections = {} for node in self.ids: self.connections[str(node)] = [ target for target in nest.GetStatus( nest.FindConnections([node]), 'target') if target not in self.sd + self.mm ]
def get_conn_par(self, type='delay'): ''' Get all connections parameter values for type ''' conn_par = {} if not self.connections: self.Find_connections() for source, targets in self.connections.iteritems(): conn_par[source] = [ nest.GetStatus(nest.FindConnections([int(source)], [target]), 'delay')[0] for target in targets ] return conn_par
def test_ThreadsFindConnections(self): """FindConnections with threads""" if not self.nest_multithreaded(): return nest.ResetKernel() nest.SetKernelStatus({'local_num_threads': 8}) pre = nest.Create("iaf_neuron") post = nest.Create("iaf_neuron", 6) nest.DivergentConnect(pre, post) conn = nest.FindConnections(pre) # Because of threading, targets may be in a different order than # in post, so we sort the vector. targets = nest.GetStatus(conn, "target") targets.sort() self.assertEqual(targets, post)
def gaussian_conn_par(self, type='delay', std_rel=0.1, sead=None): ''' GaussianConnPar(self, type='delay', std_rel=0.1, sead=None) Make connection parameters gaussian distributed ''' #! Used identical sead. if sead: random.seed(sead) if not self.connections: self.FindConnections() for source, targets in self.connections.iteritems(): for target in targets: conn = nest.FindConnections([int(source)], [target]) val = nest.GetStatus(conn, type)[0] nest.SetStatus( conn, params={type: numpy.abs(random.gauss(val, std_rel * val))})
def mean_weights(self): ''' Return a dictionary with mean_weights for each synapse type with mean weight and receptor type ''' print 'Calculating mean weights', self.models syn_dict = {} # container weights per synapse type rev_rt = {} # receptor type number dictionary rt_nb = [] # receptor type numbers for source in self.ids: # retrieve all weights per synapse type for conn in nest.GetStatus(nest.FindConnections([source])): st = conn['synapse_type'] if syn_dict.has_key(st): syn_dict[st]['weights'].append(conn['weight']) else: syn_dict[st] = {} syn_dict[st]['weights'] = [conn['weight']] syn_dict[st]['receptor_type'] = { st: nest.GetDefaults(st)['receptor_type'] } mw = {} # container mean weights per synapse type for key, val in syn_dict.iteritems(): if len(val['weights']) > 0: syn_dict[key]['mean_weight'] = sum(val['weights']) / len( val['weights']) # calculate mean weight syn_dict[key]['weights'] = numpy.array( syn_dict[key]['weights']) syn_dict[key]['nb_conn'] = len(val['weights']) else: syn_dict[key]['mean_weight'] = 0 syn_dict[key]['nb_conn'] = 0 return syn_dict
def get_neuron1_prop(property_name): return str( nest.GetStatus(nest.FindConnections( neuron1, synapse_model="sero"))[0][property_name])
def test_stdp(): ''' a simple simulation to test stdp - produces a plot of weight change as a function of t_post-t_pre i.e. the standard STDP plot.''' global eP1 global dw_prepost,dt_prepost, dw_postpre, dt_postpre prepost_dts = arange(1.0,30.0) dw_prepost = numpy.zeros_like(prepost_dts) dt_prepost = numpy.zeros_like(prepost_dts) # pre post protocol print 'pre->post' for i in xrange(len(prepost_dts)): print i setup_stdp() # second spike needs to be there that effect due to # post synaptic spike is caluclated nest.SetStatus([eP1], {'spike_times':numpy.array([50.82-prepost_dts[i],300.0])}) nest.Simulate(320.0) # get voltage fname = nest.GetStatus([cD],"filenames")[0][0] data = load(fname) v = data[1,:] t = data[0,:] # get spikes [de] = [nest.GetStatus([sD],'events')[0]['times']] # convert from timesteps to ms espikes = de.astype(float)*dt del de # determine exact dt_prepost dt_prepost[i] = espikes[0]-50.82+prepost_dts[i]-dt conn = nest.FindConnections([eP1], synapse_type='stdp_triplet_synapse_S') dw_prepost[i] = nest.GetStatus(conn,'weight')[0] -2.0 postpre_dts = arange(1.0,30.0) dw_postpre = numpy.zeros_like(postpre_dts) dt_postpre = numpy.zeros_like(postpre_dts) # pre post protocol print 'post->pre' for i in xrange(len(postpre_dts)): print i setup_stdp() # no second spike needed as for pre->post nest.SetStatus([eP1], {'spike_times':numpy.array([50.82+postpre_dts[i]])}) nest.Simulate(100.0) # get voltage fname = nest.GetStatus([cD],"filenames")[0][0] data = load(fname) v = data[1,:] t = data[0,:] # get spikes [de] = [nest.GetStatus([sD],'events')[0]['times']] # convert from timesteps to ms espikes = de.astype(float)*dt del de # determine exact dt_prepost dt_postpre[i] = -(postpre_dts[i]+dt - (espikes[0]-50.82)) conn = nest.FindConnections([eP1], synapse_type='stdp_triplet_synapse_S') dw_prepost[i] = nest.GetStatus(conn,'weight')[0] -2.0 figure() plot(dt_postpre,dw_postpre,'b',lw=2) plot(dt_prepost,dw_prepost,'r',lw=2) plot([-30.0,30.0],[0.0,0.0],'g--',lw=2) xticks(size=16) yticks(size=16) xlabel(r'$t_{\rm{post}}-t_{\rm{pre}}\ \rm{\left[ms\right]}$',size=20) ylabel(r'$\Delta w\ \left[nS\right]$',size=20)
def test_quad(): ''' a simple simulation to test triplet stdp Two pre-post pairs (i.e. a quad) are simulated with NEST and computed analystically using dw_theo_quad() to compare the NEST results to the analytical results. local variables: dt_prepost - seperation between pre and post tau - seperation between quads (pre to pre) results are in: dw_theo, dw_prepost, and binned by tau. ''' global eP1 global dw_prepost,dw_theo,tau rho = numpy.array([2.0,10.0,20.0,30.0,40.0,50.0,60.0,80.0]) tau = 1.0/rho*1000.0 dw_prepost = numpy.zeros_like(tau) dw_theo = numpy.zeros_like(tau) dt_prepost = 10.0 # pre post protocol print 'pre->post' for i in xrange(len(tau)): print i setup_stdp() dw_theo[i] = dw_theo_quad(dt_prepost,tau[i]) # pre synaptic spike time is caluclated (50.0 + 0.82 (onset delay of postsynaptic spike) - dt_prepost) # last spike at approx 3000.0 is there to trigger STDP calculation # as NEST computes STDP only at pre-synaptic spike arrivals. nest.SetStatus([eP1], {'spike_times':numpy.array([50.82-dt_prepost,50.82+tau[i]-dt_prepost,3000.0+tau[i]])}) # postsynaptic spikes (induced by stong input weight at eP) nest.SetStatus([eP], {'spike_times':numpy.array([50.0,50.0+tau[i]])}) nest.Simulate(3020.0+tau[i]) # get voltage #fname = nest.GetStatus([cD],"filenames")[0][0] #data = load(fname) #v = data[1,:] #t = data[0,:] # get spikes [de] = [nest.GetStatus([sD],'events')[0]['times']] # convert from timesteps to ms espikes = de.astype(float)*dt del de # determine exact dt_prepost #dt_prepost[i] = espikes[0]-50.82+prepost_dts[i]-dt conn = nest.FindConnections([eP1], synapse_type='stdp_triplet_synapse_S') dw_prepost[i] = nest.GetStatus(conn,'weight')[0] -2.0
nest.CopyModel("static_synapse", "static", {"delay": delay}) nest.Connect(dopa_neuron, vt, model="static") nest.Connect(neuron1, neuron2, model="dopa") if nest.GetStatus(neuron2)[0]['local']: filename = 'weight.gdf' fname = open(filename, 'w') else: raise T = 1000.0 dt = 10.0 weight = None for t in np.arange(0, T + dt, dt): if nest.GetStatus(neuron2)[0]['local']: conns = nest.FindConnections(neuron1, synapse_model="dopa") weight = nest.GetStatus(conns)[0]['weight'] print(weight) weightstr = str(weight) timestr = str(t) data = timestr + ' ' + weightstr + '\n' fname.write(data) nest.Simulate(dt) if nest.GetStatus(neuron2)[0]['local']: print("expected weight at T=1000 ms: 28.6125 pA") print("weight at last event: " + str(weight) + " pA") fname.close()
def plot_network(nodes, filename, ext_conns=False, plot_modelnames=False): """Plot the given nodes and the connections that originate from them. This function depends on the availability of the pydot module. Parameters ---------- nodes : list Global ids of nodes to plot filename : str Filename to save the plot to. Can end either in .pdf or .png to determine the type of the output. ext_conns : bool, optional Draw connections to targets that are not in nodes. If it is True, these are drawn to a node named 'ext'. plot_modelnames : bool, optional Description Raises ------ nest.NESTError """ if len(nodes) == 0: nest.NESTError("nodes must at least contain one node") nodes_types = map(lambda x: type(x), nodes) homogeneous = reduce(lambda x, y: x == y and x or None, nodes_types) == nodes_types[0] if not homogeneous: raise nest.NESTError("nodes must either contain only integers \ or only list of integers") def get_name(node): if plot_modelnames: return "%i\\n%s" % (node, nest.GetStatus([node], "model")[0]) else: return "%i" % node graph = pydot.Dot(rankdir='LR', ranksep='5') def add_nodes(node_list, name): """ We draw one Subgraph for each list we get. This allows us to influence the layout of the graph to a certain extent. """ subgraph = pydot.Subgraph(name) for node in node_list: subgraph.add_node(pydot.Node(name=get_name(node))) graph.add_subgraph(subgraph) if nodes_types[0] not in (types.TupleType, types.ListType): nodes = [nodes] for i, node_list in enumerate(nodes): add_nodes(node_list, str(i)) # Flatten nodes nodes = [node for node_list in nodes for node in node_list] adjlist = [[j, nest.GetStatus(nest.FindConnections([j]), 'target')] for j in nodes] for cl in adjlist: if not ext_conns: cl[1] = [i for i in cl[1] if i in nodes] else: tmp = [] for i in cl[1]: if i in nodes: tmp.append(i) else: tmp.append("external") cl[1] = tmp for t in cl[1]: graph.add_edge(pydot.Edge(str(cl[0]), str(t))) filetype = filename.rsplit(".", 1)[1] if filetype == "pdf": graph.write_pdf(filename) elif filetype == "png": graph.write_png(filename) else: raise nest.NESTError("Filename must end in '.png' or '.pdf'.")
nest.Connect(dopa_neuron, vt, model="static") nest.Connect(neuron1, neuron2, model="dopa") if nest.GetStatus(neuron2)[0]['local']: filename = 'weight_dopa.gdf' fname = open(filename, 'w') else: raise weight_list = [] weight = None for t in np.arange(0, T + dt, dt): if nest.GetStatus(neuron2)[0]['local']: weight = nest.GetStatus( nest.FindConnections(neuron1, synapse_model="dopa"))[0]['weight'] print(weight) weight_list.append((t, weight)) weightstr = str(weight) timestr = str(t) data = timestr + ' ' + weightstr + '\n' fname.write(data) nest.Simulate(dt) if nest.GetStatus(neuron2)[0]['local']: print("expected weight at T=1000 ms: 28.6125 pA") print("weight at last event: " + str(weight) + " pA") fname.close() plot_weights(weight_list, "Neurons currents of 3 neurons " + neuron_model)
def RCC(pre, post, n, params={ 'd_mu': [], 'w_mu': [], 'd_rel_std': 0.0, 'w_rel_std': 0.0 }, model='static_synapse'): ''' As NEST RandomDivergentConnect, except it can take severals models and make same connections for both models. This can be used to connect same source with target with both AMPA and NMDA.Mean and standard deviation for delays and weights can be given. Mean as a list of values one for each model and standard deviation as single values applied to all synapse models. Inputs: pre - list of source ids post - list of target ids n - number of neurons each source neuron connects to params[ 'd_mu' ] - mean delay for each model params[ 'w_mu' ] - mean weight for each model params[ 'd_rel_std' ] - relative mean standard deviation delays params[ 'w_rel_std' ] - relative mean standard deviation weights model - synapse model, can be a list of models ''' rn = rand.normal # copy function for generation of normal distributed random numbers for key, val in params.iteritems(): exec '%s = %s' % (key, str(val) ) # params dictionary entries as variables if isinstance(model, str): model = [model] # if model is a string put into a list if not d_mu: d_mu = [nest.GetDefaults(m)['delay'] for m in model] # get mean delays d_mu d_sigma = [d_rel_std * mu for mu in d_mu] # get delay standard deviation if not w_mu: w_mu = [nest.GetDefaults(m)['weight'] for m in model] # get mean weights w_mu w_sigma = [w_rel_std * mu for mu in w_mu] # get weight standard deviation delays = [ rand.normal( mu, sigma, [len(pre), n]) # calculate delays, randomized if sigma != 0 if sigma else numpy.ones((len(pre), n)) * mu for mu, sigma in zip(d_mu, d_sigma) ] weights = [ rand.normal( mu, sigma, [len(pre), n]) # calculate weights, randomized if sigma != 0 if sigma else numpy.ones((len(pre), n)) * mu for mu, sigma in zip(w_mu, w_sigma) ] for i, pre_id in enumerate(pre): j = 0 if d_sigma[j]: d = rn(d_mu[j], d_sigma[j], [1, n])[0] # if sigma len( targets ) randomized delays else: d = numpy.ones((1, n))[0] * d_mu[j] # else no randomized delays if w_sigma[j]: w = rn(w_mu[j], w_sigma[j], [1, n])[0] # if signa len( targets ) randomized weights else: w = numpy.ones((1, n))[0] * w_mu[j] # else no randomized weights d, w = list(d), list(w) # as lists nest.RandomDivergentConnect( [pre_id], post, n, weight=w, # connect with model[0] delay=d, model=model[0]) if len(model) > 1: targets = [ conn['target'] for conn in # find connections made by RandomDivergentConnect nest.GetStatus(nest.FindConnections([pre_id])) if conn['synapse_type'] == model[0] ] nt = len(targets) for j, m in enumerate( model[1:], start=1): # pre -> post with model[1], model[2] etc if d_sigma[j]: d = rn(d_mu[j], d_sigma[j], [1, nt ])[0] # if sigma len( targets ) randomized delays else: d = numpy.ones( (1, nt))[0] * d_mu[j] # else no randomized delays if w_sigma[j]: w = rn(w_mu[j], w_sigma[j], [1, nt ])[0] # if signa len( targets ) randomized delays else: w = numpy.ones((1, nt))[0] * w_mu[j] # else not d, w = list(d), list(w) nest.ConvergentConnect([pre_id], targets, weight=w, delay=d, model=m)
nest.Connect(stim, neuronA) nest.Connect(neuronA, neuronB, float(startWeight) / 15.0 * Wmax, delay, model=modelName) #nest.Connect(neuronA, recorder) #nest.Connect(neuronB, recorder) nest.Simulate(50.0) weightTrace = [] for run in range(len(spikesIn)): nest.Simulate(timeBetweenPairs) connections = nest.FindConnections(neuronA) for i in range(len(connections)): if nest.GetStatus([connections[i]])[0]['synapse_model'] == modelName: weightTrace.append([ run, nest.GetStatus([connections[i]])[0]['weight'], nest.GetStatus([connections[i]])[0]['a_causal'], nest.GetStatus([connections[i]])[0]['a_acausal'] ]) ############ # analysis # weightTrace = np.array(weightTrace) weightTraceMod36pre = weightTrace[35::36] #just before theoretical updates weightTraceMod36 = weightTrace[::36] #just after theoretical updates
def run(self, do_only_setup=False): """Run a simulation in nest :param do_only_setup: only do network setup, do not simulation. This can be useul for debugging or to run theory predictions :return: """ if self.params["gen"] == None: self.params["gen"] = gen_params_baserate print "Using network: %s (E: %s, I: %s)" % ( self.handler.network, self.handler.network.e.neuron_model.name, self.handler.network.i.neuron_model.name) self.reset() nest.ResetKernel() n_e = int(self.handler.p_e[npr.C_E]) n_i = int(self.handler.p_i[npr.C_I]) n_threads = self.cores nest.SetKernelStatus({ 'print_time': True, 'local_num_threads': n_threads }) N_vp = nest.GetKernelStatus(['total_num_virtual_procs'])[0] # create models # excitatory neurons neuron_params = { 'V_reset': self.handler.p_e[npr.VRES], # hardcoded in the model 'V_th': -50mV, 't_ref': self.handler.p_e[npr.TAU_RP], 'E_L': self.handler.p_e[npr.VL], 'g_L': self.handler.p_e[npr.GM], 'C_m': self.handler.p_e[npr.CM], 'AMPA_g_peak': self.handler.p_e[npr.G_AMPA], 'AMPA_Tau_1': self.handler.p_e[npr.TAU_AMPA], 'GABA_g_peak': self.handler.p_e[npr.G_GABA], 'GABA_Tau_1': self.handler.p_e[npr.TAU_GABA], # WE RESCALE THE NMDA CONDUCTANCE BY THE CONNECTIVITY, multiplies everything and leaves weights as they are 'NMDA_g_peak': self.handler.p_e[npr.G_NMDA] / self.params["gen"][mpr.P_EE], 'NMDA_Tau_1': self.handler.p_e[npr.TAU_NMDA] } nest.CopyModel(self.handler.network.e.neuron_model.name, 'ht_neuron_ex', params=neuron_params) # inhibitory neurons neuron_params = { 'V_reset': self.handler.p_i[npr.VRES], # hardcoded in the model 'V_th': -50mV, 't_ref': self.handler.p_i[npr.TAU_RP], 'E_L': self.handler.p_i[npr.VL], 'g_L': self.handler.p_i[npr.GM], 'C_m': self.handler.p_i[npr.CM], 'AMPA_g_peak': self.handler.p_i[npr.G_AMPA], 'AMPA_Tau_1': self.handler.p_i[npr.TAU_AMPA], 'GABA_Tau_1': self.handler.p_i[npr.TAU_GABA], 'GABA_g_peak': self.handler.p_i[npr.G_GABA], 'NMDA_g_peak': self.handler.p_i[npr.G_NMDA], 'NMDA_Tau_1': self.handler.p_i[npr.TAU_NMDA], } nest.CopyModel(self.handler.network.i.neuron_model.name, 'ht_neuron_in', params=neuron_params) # get receptor ID information, so we can connect to the # different synapses ex_receptors = nest.GetDefaults('ht_neuron_ex')['receptor_types'] in_receptors = nest.GetDefaults('ht_neuron_in')['receptor_types'] # CREATE NEURON POPULATIONS ----------------------- # ex_cells = tp.CreateLayer({ 'rows': 1, 'columns': n_e, 'elements': 'ht_neuron_ex', 'extent': [2. * np.pi, 1.], 'edge_wrap': True }) in_cells = tp.CreateLayer({ 'rows': 1, 'columns': n_i, 'elements': 'ht_neuron_in', 'extent': [2. * np.pi, 1.], 'edge_wrap': True }) nu_ext_e = self.handler.p_e[npr.NU_EXT] * 1e3 nu_ext_i = self.handler.p_i[npr.NU_EXT] * 1e3 # create Poisson generators ex_noise = nest.Create( 'poisson_generator', 1, params={'rate': nu_ext_e * self.handler.p_e[npr.C_EXT]}) in_noise = nest.Create( 'poisson_generator', 1, params={'rate': nu_ext_i * self.handler.p_i[npr.C_EXT]}) nest.OneToOneConnect(ex_noise * n_e, nest.GetNodes(ex_cells)[0], params={ 'weight': 1., 'receptor_type': ex_receptors['AMPA'] }, model='static_synapse') nest.OneToOneConnect(in_noise * n_i, nest.GetNodes(in_cells)[0], params={ 'weight': 1., 'receptor_type': in_receptors['AMPA'] }, model='static_synapse') # signal initiators if self.params["gen"]["sig_len"] > 0: start = self.params["gen"]["sig_start"] stop = self.params["gen"]["sig_start"] + self.params["gen"][ "sig_len"] print "Creating poisson signal from t=%i to t=%i" % ( self.params["gen"]["sig_start"], self.params["gen"]["sig_start"] + self.params["gen"]["sig_len"]) sig_len = int(self.params["gen"]["sig_width"] * n_e) sig_range = get_cue_neurons(self.params["gen"]["sig_width"], self.params["gen"]["sig_center"], n_e) print "Signal (width %g) will be sent to %i neurons centered at %g" % ( self.params["gen"]["sig_width"], len(sig_range), self.params["gen"]["sig_center"]) ex_neurons = nest.GetNodes(ex_cells)[0] # WATCH OUT, setting range to length. sometimes due to rounding this # was not equal sig_range = sig_range[:sig_len] if self.params["gen"]["sig_fade"]: print "Using fading poisson signal." ex_signal = nest.Create('poisson_generator', 1, params={ 'rate': self.params["gen"]["sig_rate"], 'start': start, 'stop': start + self.params["gen"]["sig_len"] / 2. }) nest.OneToOneConnect(ex_signal * sig_len, [ex_neurons[i] for i in sig_range], params={ 'weight': self.params["gen"]["sig_weight"], 'receptor_type': ex_receptors['AMPA'] }, model='static_synapse') ex_signal = nest.Create( 'poisson_generator', 1, params={ 'rate': 0.5 * self.params["gen"]["sig_rate"], 'start': start + self.params["gen"]["sig_len"] / 2., 'stop': stop }) nest.OneToOneConnect(ex_signal * sig_len, [ex_neurons[i] for i in sig_range], params={ 'weight': self.params["gen"]["sig_weight"], 'receptor_type': ex_receptors['AMPA'] }, model='static_synapse') else: print "Using non-fading poisson signal." ex_signal = nest.Create('poisson_generator', 1, params={ 'rate': self.params["gen"]["sig_rate"], 'start': start, 'stop': start + self.params["gen"]["sig_len"] }) nest.OneToOneConnect(ex_signal * sig_len, [ex_neurons[i] for i in sig_range], params={ 'weight': self.params["gen"]["sig_weight"], 'receptor_type': ex_receptors['AMPA'] }, model='static_synapse') # STP CONNECTIONS if self.handler.network.i.nmda_synapse.is_stp: print "Using E->I stp (%s) with params: U=%f tau_r=%f rau_f=%f" % ( tsodyks_model, self.handler.network.i.nmda_synapse.U, self.handler.network.i.nmda_synapse.tau_r, self.handler.network.i.nmda_synapse.tau_f) nest.CopyModel( tsodyks_model, 'NMDA_EI', { 'U': self.handler.network.i.nmda_synapse.U, 'tau_fac': self.handler.network.i.nmda_synapse.tau_f, 'tau_rec': self.handler.network.i.nmda_synapse.tau_r, 'receptor_type': in_receptors['NMDA'] }) # REGULAR CONNECTIONS else: print "Using E->I static synapses" nest.CopyModel('static_synapse', 'NMDA_EI', {'receptor_type': in_receptors['NMDA']}) # E->I all to all connected conndict_EI = { "connection_type": "divergent", "synapse_model": "NMDA_EI", "mask": { "grid": { "rows": 1, "columns": n_i } }, "weights": 1., "kernel": 1., "allow_autapses": False } tp.ConnectLayers(ex_cells, in_cells, conndict_EI) # I->I all to all connected nest.CopyModel('static_synapse', 'GABA_II', {'receptor_type': in_receptors['GABA']}) conndict_II = { "connection_type": "divergent", "synapse_model": "GABA_II", "mask": { "grid": { "rows": 1, "columns": n_i } }, "weights": 1., "kernel": 1., "allow_autapses": False } tp.ConnectLayers(in_cells, in_cells, conndict_II) # I->E all to all connected nest.CopyModel('static_synapse', 'GABA_IE', {'receptor_type': ex_receptors['GABA']}) conndict_IE = { "connection_type": "divergent", "synapse_model": "GABA_IE", "mask": { "grid": { "rows": 1, "columns": n_e } }, "weights": 1., "kernel": 1., "allow_autapses": False } tp.ConnectLayers(in_cells, ex_cells, conndict_IE) nest.SetKernelStatus({ 'rng_seeds': range(self.params["gen"]["base_seed"] + N_vp + 1, self.params["gen"]["base_seed"] + 2 * N_vp + 1) }) nest.SetKernelStatus( {'grng_seed': self.params["gen"]["base_seed"] + N_vp}) print "Seed for connectivity (should stay the same): ", nest.GetKernelStatus( )["rng_seeds"] # noise on membrane parameters if self.params["gen"][mpr.EL_NOISE] > 0. or not self.params["gen"][ mpr.EL_NOISE_ARRAY] == None: print "Using nonzero leak noise:" if not self.params["gen"][mpr.EL_NOISE_ARRAY] == None: leak_variance = self.params["gen"][mpr.EL_NOISE_ARRAY] print "Setting variable leak currents with given noise array, mean: %.2f, std: %.2f" % ( np.mean(leak_variance), np.std(leak_variance)) assert len(leak_variance) == n_e, "noise array has wrong size" else: np.random.seed(self.params["gen"]["base_seed"] + N_vp) self.params["gen"][ mpr.EL_SEED] = self.params["gen"]["base_seed"] + N_vp leak_variance = np.random.normal( self.handler.p_e[npr.VL], self.params["gen"][mpr.EL_NOISE], n_e) self.params["gen"][mpr.EL_NOISE_ARRAY] = leak_variance print "Setting variable leak currents: mean %.1f, std %.1f (seed=%i)" % ( np.mean(leak_variance), np.std(leak_variance), self.params["gen"][mpr.EL_SEED]) print leak_variance[:10], "..." nest.SetStatus(nest.GetNodes(ex_cells)[0], "E_L", leak_variance) # EE CONNECTIONS ################################## # TO SAVE CONNECTIONS WE DO AMPA DIST DEPENDENT CONNS WITH THE SAME SEED if self.params["gen"]["return_w_mat"]: print "Using fake synapses for weight matrix output" nest.CopyModel('static_synapse', 'NMDA_EE', {'receptor_type': ex_receptors['AMPA']}) else: # STP CONNECTIONS if self.handler.network.e.nmda_synapse.is_stp: print "Using E->E stp (%s) with params: U=%f tau_r=%f rau_f=%f" % ( tsodyks_model, self.handler.network.e.nmda_synapse.U, self.handler.network.e.nmda_synapse.tau_r, self.handler.network.e.nmda_synapse.tau_f) nest.CopyModel( tsodyks_model, 'NMDA_EE', { 'U': self.handler.network.e.nmda_synapse.U, 'tau_fac': self.handler.network.e.nmda_synapse.tau_f, 'tau_rec': self.handler.network.e.nmda_synapse.tau_r, 'receptor_type': ex_receptors['NMDA'] }) # REGULAR CONNECTIONS else: print "Using static synapses" nest.CopyModel('static_synapse', 'NMDA_EE', {'receptor_type': ex_receptors['NMDA']}) if self.params["gen"][mpr.P_EE] < 1.: print "Using connecticity p_ee: %f" % self.params["gen"][mpr.P_EE] if self.params["gen"][mpr.W_NOISE] > 0.: print "Using w noise with level (multiplied after by w1:%f): %f" % ( self.params["gen"][mpr.W_NOISE], self.handler.p_e[npr.W_1]) print "Using w parameters - w_j: %.2f --> w_0: %.2f, w_1: %.2f, w_sigma: %.2f" % ( self.handler.p_mf[mpr.W_J], self.handler.p_e[npr.W_0], self.handler.p_e[npr.W_1], self.handler.p_e[npr.W_SIGMA]) conndict_EE = { "connection_type": "divergent", "synapse_model": "NMDA_EE", "mask": { "grid": { "rows": 1, "columns": n_e } }, "weights": { "gaussian_noisy": { "c": self.handler.p_e[npr.W_0], "p_center": self.handler.p_e[npr.W_1], "sigma": self.handler.p_e[npr.W_SIGMA], "sigma_noise": self.params["gen"][mpr.W_NOISE] * self.handler.p_e[npr.W_1] } }, "kernel": self.params["gen"][mpr.P_EE], "allow_autapses": False } if self.params["gen"][mpr.P_EE] < 1.: conndict_EE["kernel"] = self.params["gen"][mpr.P_EE] nest.SetKernelStatus({ 'rng_seeds': range(self.params["gen"]["base_seed"] + N_vp + 1, self.params["gen"]["base_seed"] + 2 * N_vp + 1) }) nest.SetKernelStatus( {'grng_seed': self.params["gen"]["base_seed"] + N_vp}) tp.ConnectLayers(ex_cells, ex_cells, conndict_EE) if self.params["gen"]["return_w_mat"]: w_mat = np.zeros((n_e, n_e)) cids = nest.GetNodes(ex_cells)[0] conns = nest.FindConnections(cids, synapse_type="NMDA_EE") stats = nest.GetStatus(conns) id_min = min(cids) id_max = max(cids) assert id_max - id_min == n_e - 1, "something is wrong with weight estimation" for stat in stats: pre = stat['source'] - id_min post = stat['target'] - id_min weight = stat['weight'] w_mat[post, pre] = weight return w_mat if self.params["gen"]["show_weights"]: target = [] weight = [] a = nest.GetNodes(ex_cells)[0][0] b = nest.FindConnections([a]) for con in b: aha = nest.GetStatus([con])[0] if aha['target'] < n_e: target.append(aha['target']) weight.append(aha['weight']) print "Total weight is: %f" % (np.sum(weight) / float(n_e)) pl.figure() pl.scatter((np.array(target) / float(n_e) * 360.), weight) tmp = np.zeros(n_e) for i in range(n_e): tmp[i] = self.handler.p_e[npr.W_0] + self.handler.p_e[ npr.W_1] * np.exp(-((i - n_e - 2) / (1. * n_e / (2 * np.pi)))**2 / 2. / (self.handler.p_e[npr.W_SIGMA])**2) pl.plot((np.arange(n_e) / float(n_e) * 360.), tmp, 'r') pl.show() print "Targets (should stay constant)" print target if self.params["gen"]["base_seed_run"] is not None: print "Using preset seed for run: %i" % self.params["gen"][ "base_seed_run"] msd = self.params["gen"]["base_seed_run"] else: print "Using random seed for run: seeding by time." np.random.seed(int(time.time())) msd = np.random.randint(100000000000) self.params["gen"]["base_seed_run"] = msd nest.SetKernelStatus( {'rng_seeds': range(msd + N_vp + 1, msd + 2 * N_vp + 1)}) nest.SetKernelStatus({'grng_seed': msd + N_vp}) # READOUTS ----------------------- # # spike detectors ex_spikes = nest.Create("spike_detector") nest.SetStatus(ex_spikes, [{ "label": "ex", "withtime": True, "withgid": True }]) nest.ConvergentConnect(nest.GetNodes(ex_cells)[0], ex_spikes, model="static_synapse") in_spikes = nest.Create("spike_detector") nest.SetStatus(in_spikes, [{ "label": "in", "withtime": True, "withgid": True }]) nest.ConvergentConnect(nest.GetNodes(in_cells)[0], in_spikes, model="static_synapse") spikes = nest.Create("spike_detector") nest.SetStatus(spikes, [{"withtime": True, "withgid": True}]) nest.ConvergentConnect(nest.GetNodes(ex_cells)[0], spikes, model="static_synapse") nest.ConvergentConnect(nest.GetNodes(in_cells)[0], spikes, model="static_synapse") # write cell ids to object self.ex_cells = np.array(nest.GetNodes(ex_cells)[0]) self.in_cells = np.array(nest.GetNodes(in_cells)[0]) if do_only_setup: return True # SIMULATE ----------------------- # print "Seeds for run: ", nest.GetKernelStatus()["rng_seeds"] print "Running %.1f ms" % self.params["gen"]["tmax"] starttime = time.time() # COOLDOWN FIRST ########### if self.params["gen"]["do_bistab_pert"]: ex_signal_init = nest.Create('poisson_generator', 1, params={ 'rate': 1500., 'start': 1000., 'stop': 1500. }) sig_range = [] d = 4 for i in range(d): sig_range += get_cue_neurons(.025, i / float(d), n_e) sig_len = len(sig_range) nest.OneToOneConnect(ex_signal_init * sig_len, [ex_neurons[i] for i in sig_range], params={ 'weight': 2., 'receptor_type': ex_receptors['AMPA'] }, model='static_synapse') # FULL SIM ########### nest.Simulate(self.params["gen"]["tmax"]) print "Done (%.2fs): " % ((time.time() - starttime)), # Output --------------------------- # ex_ev = nest.GetStatus(ex_spikes, "events")[0] self.spikes["e"] = process_spikes(ex_ev, self.params["gen"]["tmax"]) in_ev = nest.GetStatus(in_spikes, "events")[0] self.spikes["i"] = process_spikes(in_ev, self.params["gen"]["tmax"]) all_ev = nest.GetStatus(spikes, "events")[0] self.spikes["all"] = process_spikes(all_ev, self.params["gen"]["tmax"]) window = 100. ex_spiketrains = self.spikes["e"]["spike_trains"].spiketrains kernel, norm, m_idx = analysis.make_kernel('exp', window, 1) act_len = len(self.ex_cells) act = np.zeros((act_len, int(self.params["gen"]["tmax"]))) for l, spktr in enumerate(ex_spiketrains): nrnid = np.where(self.ex_cells == spktr)[0] if len(nrnid) == 0: continue taxis, raxis = ex_spiketrains[spktr].instantaneous_rate(1, kernel, norm, m_idx, trim=False) act[nrnid, :] = raxis # end of bump activity only bump_t_end = self.params["gen"]["tmax"] - self.params["gen"][ "bump_shape_enddist"] bump_t_start = self.params["gen"]["sig_start"] + self.params["gen"][ "sig_len"] + 1000. # 1s of buffer between start and avg if bump_t_end <= bump_t_start: bump_t_start_old = bump_t_start bump_t_start = self.params["gen"]["sig_start"] + self.params[ "gen"]["sig_len"] print "Run is not long enough (t_max: %.1f, bump_t_start: %.1f, bump_t_end: %.1f). Setting bump_t_start = %.1f" % ( self.params["gen"]["tmax"], bump_t_start_old, bump_t_end, bump_t_start) dir_vec = np.exp(2. * 1.j * np.pi * np.arange(act_len, dtype=float) / float(act_len)) dirs = (np.angle(np.dot(np.transpose(act), dir_vec))) / np.pi * act_len / 2. % act_len act_bump = act[:, int(bump_t_start):int(bump_t_end)] dirs_bump = dirs[int(bump_t_start):int(bump_t_end)] # rectify bump to center and fit gauss curve shift_n = (len(act_bump) / 2. - dirs_bump).round().astype(int) out_means = [] points = np.arange(0, act_bump.shape[1], 20) for j in points: out_means.append(np.roll(act_bump[:, j], shift_n[j], 0)) out_means = np.array(out_means).T if self.params["gen"]["show_results"] or self.params["gen"][ "show_spikes"]: nest.raster_plot.from_device(ex_spikes, hist=True) pl.title("Exctitatory Population") pl.savefig('lastrun_spikes_e.pdf') nest.raster_plot.from_device(in_spikes, hist=True) pl.title("Inhibitory Population") pl.savefig('lastrun_spikes_i.pdf') return { "shape_mean": np.mean(out_means, 1), "shape_std": np.std(out_means, 1), "shape": out_means, "dirs": dirs, "bump_rate": act, "spikes": self.spikes, "pop_rate": self.get_rates(bump_t_start, bump_t_end) }
#! output directly generated by NEST. The absence of an error message in this #! place shows that network construction and simulation went through. #! Inspecting the connections actually created #! ::::::::::::::::::::::::::::::::::::::::::: #! The following block of messy and makeshift code plots the targets of the #! center neuron of the B/E population in the B/E and the B/I populations. B_top = nest.GetStatus(RG, 'topology')[0] ctr_id = topo.GetElement(RG, [B_top['rows'] / 2, B_top['columns'] / 2]) # find excitatory element in B E_id = [gid for gid in ctr_id if nest.GetStatus([gid], 'model')[0] == 'E'] # get all targets, split into excitatory and inhibitory alltgts = nest.GetStatus( nest.FindConnections(E_id, synapse_model='static_synapse'), 'target') Etgts = [t for t in alltgts if nest.GetStatus([t], 'model')[0] == 'E'] Itgts = [t for t in alltgts if nest.GetStatus([t], 'model')[0] == 'I'] # obtain positions of targets Etpos = zip(*topo.GetPosition(Etgts)) Itpos = zip(*topo.GetPosition(Itgts)) # plot excitatory pylab.clf() pylab.subplot(121) pylab.scatter(Etpos[0], Etpos[1]) ctrpos = pylab.array(topo.GetPosition(E_id)[0]) ax = pylab.gca() ax.add_patch( pylab.Circle(ctrpos, radius=0.02, zorder=99, fc='r', alpha=0.4, ec='none'))
def connections(self): if self._connections is None: self.sources = numpy.unique(self.sources) self._connections = nest.FindConnections(self.sources, synapse_type=self.synapse_model) return self._connections