def scenario4(sim): """ Network with spatial structure """ init_logging(logfile=None, debug=True) sim.setup() rng = NumpyRNG(seed=76454, parallel_safe=False) input_layout = RandomStructure(boundary=Cuboid(width=500.0, height=500.0, depth=100.0), origin=(0, 0, 0), rng=rng) inputs = sim.Population(100, sim.SpikeSourcePoisson(rate=RandomDistribution('uniform', [3.0, 7.0], rng=rng)), structure=input_layout, label="inputs") output_layout = Grid3D(aspect_ratioXY=1.0, aspect_ratioXZ=5.0, dx=10.0, dy=10.0, dz=10.0, x0=0.0, y0=0.0, z0=200.0) outputs = sim.Population(200, sim.EIF_cond_exp_isfa_ista(), initial_values = {'v': RandomDistribution('normal', [-65.0, 5.0], rng=rng), 'w': RandomDistribution('normal', [0.0, 1.0], rng=rng)}, structure=output_layout, # 10x10x2 grid label="outputs") logger.debug("Output population positions:\n %s", outputs.positions) DDPC = sim.DistanceDependentProbabilityConnector input_connectivity = DDPC("0.5*exp(-d/100.0)", rng=rng) recurrent_connectivity = DDPC("sin(pi*d/250.0)**2", rng=rng) depressing = sim.TsodyksMarkramSynapse(weight=RandomDistribution('normal', (0.1, 0.02), rng=rng), delay="0.5 + d/100.0", U=0.5, tau_rec=800.0, tau_facil=0.0) facilitating = sim.TsodyksMarkramSynapse(weight=0.05, delay="0.2 + d/100.0", U=0.04, tau_rec=100.0, tau_facil=1000.0) input_connections = sim.Projection(inputs, outputs, input_connectivity, receptor_type='excitatory', synapse_type=depressing, space=Space(axes='xy'), label="input connections") recurrent_connections = sim.Projection(outputs, outputs, recurrent_connectivity, receptor_type='inhibitory', synapse_type=facilitating, space=Space(periodic_boundaries=((-100.0, 100.0), (-100.0, 100.0), None)), # should add "calculate_boundaries" method to Structure classes label="recurrent connections") outputs.record('spikes') outputs.sample(10, rng=rng).record('v') sim.run(1000.0) data = outputs.get_data() sim.end() return data
def runNetwork(Be, Bi, nn_stim, show_gui=True, dt = defaultParams.dt, N_rec_v = 5, save=False, simtime = defaultParams.Tpost+defaultParams.Tstim+defaultParams.Tblank+defaultParams.Ttrans, extra = {}, kernelseed = 123): exec("from pyNN.%s import *" % simulator_name) in globals() timer = Timer() rec_conn={'EtoE':1, 'EtoI':1, 'ItoE':1, 'ItoI':1} print('####################') print('### (Be, Bi, nn_stim): ', Be, Bi, nn_stim) print('####################') Bee, Bei = Be, Be Bie, Bii = Bi, Bi N = defaultParams.N NE = defaultParams.NE NI = defaultParams.NI print('\n # -----> Num cells: %s, size of pert. inh: %s; base rate %s; pert rate %s'% (N, nn_stim, defaultParams.r_bkg, defaultParams.r_stim)) r_extra = np.zeros(N) r_extra[NE:NE+nn_stim] = defaultParams.r_stim rr1 = defaultParams.r_bkg*np.random.uniform(.75,1.25, N) rr2 = rr1 + r_extra rank = setup(timestep=dt, max_delay=defaultParams.delay_default, reference='ISN', save_format='hdf5', **extra) print("rank =", rank) nump = num_processes() print("num_processes =", nump) import socket host_name = socket.gethostname() print("Host #%d is on %s" % (rank+1, host_name)) if 'threads' in extra: print("%d Initialising the simulator with %d threads..." % (rank, extra['threads'])) else: print("%d Initialising the simulator with single thread..." % rank) timer.start() # start timer on construction print("%d Setting up random number generator using seed %s" % (rank, kernelseed)) ks = open('kernelseed','w') ks.write('%i'%kernelseed) ks.close() rng = NumpyRNG(kernelseed, parallel_safe=True) nesp = defaultParams.neuron_params_default cell_parameters = { 'cm': nesp['C_m']/1000, # Capacitance of the membrane in nF 'tau_refrac': nesp['t_ref'], # Duration of refractory period in ms. 'v_spike': 0.0 , # Spike detection threshold in mV. https://github.com/nest/nest-simulator/blob/master/models/aeif_cond_alpha.cpp 'v_reset': nesp['V_reset'], # Reset value for V_m after a spike. In mV. 'v_rest': nesp['E_L'], # Resting membrane potential (Leak reversal potential) in mV. 'tau_m': nesp['C_m']/nesp['g_L'], # Membrane time constant in ms = cm/tau_m*1000.0, C_m/g_L 'i_offset': nesp['I_e']/1000, # Offset current in nA 'a': 0, # Subthreshold adaptation conductance in nS. 'b': 0, # Spike-triggered adaptation in nA 'delta_T': 2 , # Slope factor in mV. See https://github.com/nest/nest-simulator/blob/master/models/aeif_cond_alpha.cpp 'tau_w': 144.0, # Adaptation time constant in ms. See https://github.com/nest/nest-simulator/blob/master/models/aeif_cond_alpha.cpp 'v_thresh': nesp['V_th'], # Spike initiation threshold in mV 'e_rev_E': nesp['E_ex'], # Excitatory reversal potential in mV. 'tau_syn_E': nesp['tau_syn_ex'], # Rise time of excitatory synaptic conductance in ms (alpha function). 'e_rev_I': nesp['E_in'], # Inhibitory reversal potential in mV. 'tau_syn_I': nesp['tau_syn_in'], # Rise time of the inhibitory synaptic conductance in ms (alpha function). } print("%d Creating population with %d neurons." % (rank, N)) celltype = EIF_cond_alpha_isfa_ista(**cell_parameters) celltype.default_initial_values['v'] = cell_parameters['v_rest'] # Setting default init v, useful for NML2 export layer_volume = Cuboid(1000,100,1000) layer_structure = RandomStructure(layer_volume, origin=(0,0,0)) layer_structure_input = RandomStructure(layer_volume, origin=(0,-150,0)) default_cell_radius = 15 stim_cell_radius = 10 #EI_pop = Population(N, celltype, structure=layer_structure, label="EI") E_pop = Population(NE, celltype, structure=layer_structure, label='E_pop') E_pop.annotate(color='1 0 0') E_pop.annotate(radius=default_cell_radius) E_pop.annotate(type='E') # temp indicator to use for connection arrowhead #print("%d Creating pop %s." % (rank, E_pop)) I_pop = Population(NI, celltype, structure=layer_structure, label='I_pop') I_pop.annotate(color='0 0 .9') I_pop.annotate(radius=default_cell_radius) I_pop.annotate(type='I') # temp indicator to use for connection arrowhead #print("%d Creating pop %s." % (rank, I_pop)) I_pert_pop = PopulationView(I_pop, np.array(range(0,nn_stim)),label='I_pert_pop') I_nonpert_pop = PopulationView(I_pop, np.array(range(nn_stim,NI)),label='I_nonpert_pop') p_rate = defaultParams.r_bkg print("%d Creating excitatory Poisson generator with rate %g spikes/s." % (rank, p_rate)) source_typeA_E = SpikeSourcePoisson(rate=p_rate, start=0,duration=defaultParams.Ttrans+defaultParams.Tblank+defaultParams.Tstim+defaultParams.Tpost) expoissonA_E = Population(NE, source_typeA_E, structure=layer_structure_input, label="stim_E") print("%d Creating excitatory Poisson generator with rate %g spikes/s." % (rank, p_rate)) source_typeA_I = SpikeSourcePoisson(rate=p_rate, start=0,duration=defaultParams.Ttrans+defaultParams.Tblank) expoissonA_I = Population(NI, source_typeA_I, structure=layer_structure_input, label="pre_pert_stim_I") print("%d Creating excitatory Poisson generator with rate %g spikes/s." % (rank, p_rate)) source_typeB = SpikeSourcePoisson(rate=p_rate, start=defaultParams.Ttrans+defaultParams.Tblank,duration=defaultParams.Tstim+defaultParams.Tpost) #expoissonB_E = Population(NE, source_typeB, label="non_pert_stim_E") expoissonB_I = Population(len(I_nonpert_pop), source_typeB, structure=layer_structure_input, label="non_pert_stim_I") p_rate = defaultParams.r_bkg+defaultParams.r_stim print("%d Creating excitatory Poisson generator with rate %g spikes/s." % (rank, p_rate)) source_typeC = SpikeSourcePoisson(rate=p_rate, start=defaultParams.Ttrans+defaultParams.Tblank, duration=defaultParams.Tstim) expoissonC = Population(nn_stim, source_typeC, structure=layer_structure_input, label="pert_stim") p_rate = defaultParams.r_bkg print("%d Creating excitatory Poisson generator with rate %g spikes/s." % (rank, p_rate)) source_typeD = SpikeSourcePoisson(rate=p_rate, start=defaultParams.Ttrans+defaultParams.Tblank+defaultParams.Tstim, duration=defaultParams.Tpost) expoissonD = Population(nn_stim, source_typeD, structure=layer_structure_input, label="pert_poststim") for p in [expoissonA_E,expoissonA_I,expoissonB_I,expoissonC,expoissonD]: p.annotate(color='0.8 0.8 0.8') p.annotate(radius=stim_cell_radius) progress_bar = ProgressBar(width=20) connector_E = FixedProbabilityConnector(0.15, rng=rng, callback=progress_bar) connector_I = FixedProbabilityConnector(1, rng=rng, callback=progress_bar) EE_syn = StaticSynapse(weight=0.001*Bee, delay=defaultParams.delay_default) EI_syn = StaticSynapse(weight=0.001*Bei, delay=defaultParams.delay_default) II_syn = StaticSynapse(weight=0.001*Bii, delay=defaultParams.delay_default) IE_syn = StaticSynapse(weight=0.001*Bie, delay=defaultParams.delay_default) #I_syn = StaticSynapse(weight=JI, delay=delay) ext_Connector = OneToOneConnector(callback=progress_bar) ext_syn_bkg = StaticSynapse(weight=0.001*defaultParams.Be_bkg, delay=defaultParams.delay_default) ext_syn_stim = StaticSynapse(weight=0.001*defaultParams.Be_stim, delay=defaultParams.delay_default) E_to_E = Projection(E_pop, E_pop, connector_E, EE_syn, receptor_type="excitatory") print("E --> E\t\t", len(E_to_E), "connections") E_to_I = Projection(E_pop, I_pop, connector_E, EI_syn, receptor_type="excitatory") print("E --> I\t\t", len(E_to_I), "connections") I_to_I = Projection(I_pop, I_pop, connector_I, II_syn, receptor_type="inhibitory") print("I --> I\t\t", len(I_to_I), "connections") I_to_E = Projection(I_pop, E_pop, connector_I, IE_syn, receptor_type="inhibitory") print("I --> E\t\t", len(I_to_E), "connections") input_A_E = Projection(expoissonA_E, E_pop, ext_Connector, ext_syn_bkg, receptor_type="excitatory") print("input --> %s cells pre pert\t"%len(E_pop), len(input_A_E), "connections") input_A_I = Projection(expoissonA_I, I_pop, ext_Connector, ext_syn_bkg, receptor_type="excitatory") print("input --> %s cells pre pert\t"%len(I_pop), len(input_A_I), "connections") ##input_B_E = Projection(expoissonB_E, E_pop, ext_Connector, ext_syn_bkg, receptor_type="excitatory") ##print("input --> %s cells post pert\t"%len(E_pop), len(input_B_E), "connections") input_B_I = Projection(expoissonB_I, I_nonpert_pop, ext_Connector, ext_syn_bkg, receptor_type="excitatory") print("input --> %s cells post pert\t"%len(I_nonpert_pop), len(input_B_I), "connections") input_C = Projection(expoissonC, I_pert_pop, ext_Connector, ext_syn_stim, receptor_type="excitatory") print("input --> %s cells pre pert\t"%len(I_pert_pop), len(input_C), "connections") input_D = Projection(expoissonD, I_pert_pop, ext_Connector, ext_syn_stim, receptor_type="excitatory") print("input --> %s cells pre pert\t"%len(I_pert_pop), len(input_D), "connections") # Can't be used for connections etc. as NeuroML export not (yet) supported EI_pop = Assembly(E_pop, I_pop, label='EI') # Record spikes print("%d Setting up recording in excitatory population." % rank) EI_pop.record('spikes') if N_rec_v>0: EI_pop[0:min(N,N_rec_v)].record('v') # read out time used for building buildCPUTime = timer.elapsedTime() # === Run simulation =========================================================== # run, measure computer time timer.start() # start timer on construction print("%d Running simulation in %s for %g ms (dt=%sms)." % (rank, simulator_name, simtime, dt)) run(simtime) print("Done") simCPUTime = timer.elapsedTime() # write data to file if save and not simulator_name=='neuroml': for pop in [EI_pop]: filename="ISN-%s-%s-%i.gdf"%(simulator_name, pop.label, rank) ff = open(filename, 'w') spikes = pop.get_data('spikes', gather=False) spiketrains = spikes.segments[0].spiketrains print('Saving data recorded for %i spiketrains in pop %s, indices: %s, ids: %s to %s'% \ (len(spiketrains), pop.label, [s.annotations['source_index'] for s in spiketrains], [s.annotations['source_id'] for s in spiketrains], filename)) for spiketrain_i in range(len(spiketrains)): spiketrain = spiketrains[spiketrain_i] source_id = spiketrain.annotations['source_id'] source_index = spiketrain.annotations['source_index'] #print("Writing spike data for cell %s[%s] (gid: %i): %i spikes: [%s,...,%s] "%(pop.label,source_index, source_id, len(spiketrain),spiketrain[0],spiketrain[-1])) for t in spiketrain: ff.write('%s\t%i\n'%(t.magnitude,spiketrain_i)) ff.close() vs = pop.get_data('v', gather=False) for segment in vs.segments: for i in range(len(segment.analogsignals[0].transpose())): filename="ISN-%s-%s-cell%i.dat"%(simulator_name, pop.label, i) print('Saving cell %i in %s to %s'%(i,pop.label,filename)) vm = segment.analogsignals[0].transpose()[i] tt = np.array([t*dt/1000. for t in range(len(vm))]) times_vm = np.array([tt, vm/1000.]).transpose() np.savetxt(filename, times_vm , delimiter = '\t', fmt='%s') spike_data = {} spike_data['senders'] = [] spike_data['times'] = [] index_offset = 1 for pop in [EI_pop]: if rank == 0: spikes = pop.get_data('spikes', gather=False) #print(spikes.segments[0].all_data) num_rec = len(spikes.segments[0].spiketrains) print("Extracting spike info (%i) for %i cells in %s"%(num_rec,pop.size,pop.label)) #assert(num_rec==len(spikes.segments[0].spiketrains)) for i in range(num_rec): ss = spikes.segments[0].spiketrains[i] for s in ss: index = i+index_offset #print("Adding spike at %s in %s[%i] (cell %i)"%(s,pop.label,i,index)) spike_data['senders'].append(index) spike_data['times'].append(s) index_offset+=pop.size print("Build time : %g s" % buildCPUTime) print("Simulation time : %g s" % simCPUTime) # === Clean up and quit ======================================================== end()
def setup(self, sim) : # Create matrix of synaptic weights self.w = create_weight_matrix() model = getattr(sim, 'IF_curr_exp') script_rng = NumpyRNG(seed=6508015, parallel_safe=parallel_safe) distr = RandomDistribution('normal', [V0_mean, V0_sd], rng=script_rng) # Create cortical populations self.pops = {} layer_structures = {} total_cells = 0 x_dim_scaled = x_dimension * math.sqrt(N_scaling) z_dim_scaled = z_dimension * math.sqrt(N_scaling) default_cell_radius = 10 # for visualisation default_input_radius = 5 # for visualisation for layer in layers: self.pops[layer] = {} for pop in pops: y_offset = 0 if layer == 'L6': y_offset = layer_thicknesses['L6']/2 if layer == 'L5': y_offset = layer_thicknesses['L6']+layer_thicknesses['L5']/2 if layer == 'L4': y_offset = layer_thicknesses['L6']+layer_thicknesses['L5']+layer_thicknesses['L4']/2 if layer == 'L23': y_offset = layer_thicknesses['L6']+layer_thicknesses['L5']+layer_thicknesses['L4']+layer_thicknesses['L23']/2 layer_volume = Cuboid(x_dim_scaled,layer_thicknesses[layer],z_dim_scaled) layer_structures[layer] = RandomStructure(layer_volume, origin=(0,y_offset,0)) self.pops[layer][pop] = sim.Population(int(N_full[layer][pop] * \ N_scaling), model, cellparams=neuron_params, \ structure=layer_structures[layer], label='%s_%s'%(layer,pop)) self.pops[layer][pop].initialize(v=distr) # Store whether population is inhibitory or excitatory self.pops[layer][pop].annotate(type=pop) self.pops[layer][pop].annotate(radius=default_cell_radius) self.pops[layer][pop].annotate(structure=str(layer_structures[layer])) this_pop = self.pops[layer][pop] color='0 0 0' radius = 10 try: import opencortex.utils.color as occ if layer == 'L23': if pop=='E': color = occ.L23_PRINCIPAL_CELL if pop=='I': color = occ.L23_INTERNEURON if layer == 'L4': if pop=='E': color = occ.L4_PRINCIPAL_CELL if pop=='I': color = occ.L4_INTERNEURON if layer == 'L5': if pop=='E': color = occ.L5_PRINCIPAL_CELL if pop=='I': color = occ.L5_INTERNEURON if layer == 'L6': if pop=='E': color = occ.L6_PRINCIPAL_CELL if pop=='I': color = occ.L6_INTERNEURON self.pops[layer][pop].annotate(color=color) except: # Don't worry about it, it's just metadata pass print("Created population %s with %i cells (color: %s)"%(this_pop.label,this_pop.size, color)) total_cells += this_pop.size # Spike recording if record_fraction: num_spikes = int(round(this_pop.size * frac_record_spikes)) else: num_spikes = n_record this_pop[0:num_spikes].record('spikes') # Membrane potential recording if record_v: if record_fraction: num_v = int(round(this_pop.size * frac_record_v)) else: num_v = n_record_v this_pop[0:num_v].record('v') print("Finished creating all cell populations (%i cells)"%total_cells) # Create thalamic population if thalamic_input: print("Adding thalamic input") layer_volume = Cuboid(x_dimension,layer_thicknesses['thalamus'],z_dimension) layer_structure = RandomStructure(layer_volume, origin=(0,thalamus_offset,0)) self.thalamic_population = sim.Population( thal_params['n_thal'], sim.SpikeSourcePoisson, {'rate': thal_params['rate'], 'start': thal_params['start'], 'duration': thal_params['duration']}, structure=layer_structure, label='thalamic_input') # Compute DC input before scaling if input_type == 'DC': self.DC_amp = {} for target_layer in layers: self.DC_amp[target_layer] = {} for target_pop in pops: self.DC_amp[target_layer][target_pop] = bg_rate * \ K_ext[target_layer][target_pop] * w_mean * neuron_params['tau_syn_E'] / 1000. else: self.DC_amp = {'L23': {'E': 0., 'I': 0.}, 'L4' : {'E': 0., 'I': 0.}, 'L5' : {'E': 0., 'I': 0.}, 'L6' : {'E': 0., 'I': 0.}} # Scale and connect # In-degrees of the full-scale model K_full = scaling.get_indegrees() if K_scaling != 1 : self.w, self.w_ext, self.K_ext, self.DC_amp = scaling.adjust_w_and_ext_to_K(K_full, K_scaling, self.w, self.DC_amp) else: self.w_ext = w_ext self.K_ext = K_ext if sim.rank() == 0: print('w: %s' % self.w) net_generation_rng = NumpyRNG(12345, parallel_safe=True) for target_layer in layers : for target_pop in pops : target_index = structure[target_layer][target_pop] this_pop = self.pops[target_layer][target_pop] # External inputs if input_type == 'DC' or K_scaling != 1 : this_pop.set(i_offset=self.DC_amp[target_layer][target_pop]) if input_type == 'poisson': poisson_generator = sim.Population(this_pop.size, sim.SpikeSourcePoisson, {'rate': bg_rate * self.K_ext[target_layer][target_pop]}, structure=layer_structures[target_layer], label='input_%s_%s'%(target_layer,target_pop)) poisson_generator.annotate(color='0.5 0.5 0') poisson_generator.annotate(radius=default_input_radius) conn = sim.OneToOneConnector() syn = sim.StaticSynapse(weight=self.w_ext) sim.Projection(poisson_generator, this_pop, conn, syn, receptor_type='excitatory') if thalamic_input: # Thalamic inputs if sim.rank() == 0 : print('Creating thalamic connections to %s%s' % (target_layer, target_pop)) C_thal=thal_params['C'][target_layer][target_pop] n_target=N_full[target_layer][target_pop] K_thal=round(np.log(1 - C_thal) / np.log((n_target * thal_params['n_thal'] - 1.) / (n_target * thal_params['n_thal']))) / n_target FixedTotalNumberConnect(sim, self.thalamic_population, this_pop, K_thal, w_ext, w_rel * w_ext, d_mean['E'], d_sd['E'], rng=net_generation_rng) # Recurrent inputs for source_layer in layers : for source_pop in pops : source_index=structure[source_layer][source_pop] if sim.rank() == 0: print('Creating connections from %s%s to %s%s' % (source_layer, source_pop, target_layer, target_pop)) weight=self.w[target_index][source_index] if source_pop == 'E' and source_layer == 'L4' and target_layer == 'L23' and target_pop == 'E': w_sd=weight * w_rel_234 else: w_sd=abs(weight * w_rel) FixedTotalNumberConnect(sim, self.pops[source_layer][source_pop], self.pops[target_layer][target_pop],\ K_full[target_index][source_index] * K_scaling, weight, w_sd, d_mean[source_pop], d_sd[source_pop], rng=net_generation_rng)