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 = {} for layer in layers: self.pops[layer] = {} for pop in pops: self.pops[layer][pop] = sim.Population( int(N_full[layer][pop] * N_scaling), model, cellparams=neuron_params) self.pops[layer][pop].initialize(v=distr) # Store whether population is inhibitory or excitatory self.pops[layer][pop].annotate(type=pop) this_pop = self.pops[layer][pop] # 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') # Create thalamic population if thalamic_input: self.thalamic_population = sim.Population( thal_params['n_thal'], sim.SpikeSourcePoisson, { 'rate': thal_params['rate'], 'start': thal_params['start'], 'duration': thal_params['duration'] }) # 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 if sim.rank() == 0: print('w: %s' % self.w) 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] }) 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']) # 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])
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 = {} for layer in layers: self.pops[layer] = {} for pop in pops: self.pops[layer][pop] = sim.Population(int(N_full[layer][pop] * \ N_scaling), model, cellparams=neuron_params) self.pops[layer][pop].initialize(v=distr) # Store whether population is inhibitory or excitatory self.pops[layer][pop].annotate(type=pop) this_pop = self.pops[layer][pop] # 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') # Create thalamic population if thalamic_input: self.thalamic_population = sim.Population( thal_params['n_thal'], sim.SpikeSourcePoisson, {'rate': thal_params['rate'], 'start': thal_params['start'], 'duration': thal_params['duration']}) # 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 if sim.rank() == 0: print('w: %s' % self.w) 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]}) 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']) # 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])
def setup(self, sim, conf): # extract parameters pyseed = conf["params_dict"]["nest"]["pyseed"] parallel_safe = conf["params_dict"]["nest"]["parallel_safe"] input_type = conf["params_dict"]["nest"]["input_type"] layers = conf["layers"] pops = conf["pops"] bg_rate = conf["bg_rate"] w_mean = conf["w_mean"] K_scaling = conf["params_dict"]["nest"]["K_scaling"] N_scaling = conf["params_dict"]["nest"]["N_scaling"] n_record = conf["params_dict"]["nest"]["n_record"] neuron_model = conf["neuron_model"] tau_max = conf["tau_max"] record_corr = conf["params_dict"]["nest"]["record_corr"] n_layers = conf["n_layers"] n_pops_per_layer = conf["n_pops_per_layer"] V0_mean = conf["V0_mean"] n_record_v = conf["params_dict"]["nest"]["n_record_v"] record_v = conf["params_dict"]["nest"]["record_v"] record_fraction = conf["params_dict"]["nest"]["record_fraction"] thalamic_input = conf["thalamic_input"] w_rel = conf["w_rel"] w_rel_234 = conf["w_rel_234"] simulator = conf["simulator"] N_full = conf["N_full"] K_ext = conf["K_ext"] tau_syn_E = conf["neuron_params"]["tau_syn_E"] v_thresh = conf["neuron_params"]["v_thresh"] v_rest = conf["neuron_params"]["v_rest"] neuron_params = conf["neuron_params"] thal_params = conf["thal_params"] structure = conf["structure"] d_mean = conf["d_mean"] d_sd = conf["d_sd"] frac_record_v = conf["params_dict"]["nest"]["frac_record_v"] n_rec = helper_functions.get_n_rec(conf) # if parallel_safe=False, PyNN offsets the seeds by 1 for each rank script_rng = NumpyRNG(seed=pyseed, parallel_safe=parallel_safe) # 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 * tau_syn_E / 1000.0 ) else: self.DC_amp = { "L23": {"E": 0.0, "I": 0.0}, "L4": {"E": 0.0, "I": 0.0}, "L5": {"E": 0.0, "I": 0.0}, "L6": {"E": 0.0, "I": 0.0}, } # In-degrees of the full-scale and scaled models K_full = scaling.get_indegrees(conf) self.K = K_scaling * K_full self.K_ext = {} for layer in layers: self.K_ext[layer] = {} for pop in pops: self.K_ext[layer][pop] = K_scaling * K_ext[layer][pop] self.w = helper_functions.create_weight_matrix(conf) # Network scaling if K_scaling != 1: self.w, self.w_ext, self.DC_amp = scaling.adjust_w_and_ext_to_K( K_full, K_scaling, self.w, self.DC_amp, conf ) else: self.w_ext = w_mean Vthresh = {} for layer in layers: Vthresh[layer] = {} for pop in pops: Vthresh[layer][pop] = v_thresh # Initial membrane potential distributions # The original study used V0_mean = -58 mV, V0_sd = 5 mV. # This is adjusted here to any changes in v_rest and scaling of V. V0_mean = {} V0_sd = {} for layer in layers: V0_mean[layer] = {} V0_sd[layer] = {} for pop in pops: V0_mean[layer][pop] = (v_rest + Vthresh[layer][pop]) / 2.0 V0_sd[layer][pop] = (Vthresh[layer][pop] - v_rest) / 3.0 V_dist = {} for layer in layers: V_dist[layer] = {} for pop in pops: V_dist[layer][pop] = RandomDistribution( "normal", [V0_mean[layer][pop], V0_sd[layer][pop]], rng=script_rng ) model = getattr(sim, neuron_model) if record_corr and simulator == "nest": # Create correlation recording device sim.nest.SetDefaults("correlomatrix_detector", {"delta_tau": 0.5}) self.corr_detector = sim.nest.Create("correlomatrix_detector") sim.nest.SetStatus( self.corr_detector, {"N_channels": n_layers * n_pops_per_layer, "tau_max": tau_max, "Tstart": tau_max} ) if sim.rank() == 0: print "neuron_params:", conf["neuron_params"] print "K: ", self.K print "K_ext: ", self.K_ext print "w: ", self.w print "w_ext: ", self.w_ext print "DC_amp: ", self.DC_amp print "V0_mean: " for layer in layers: for pop in pops: print layer, pop, V0_mean[layer][pop] print "n_rec:" for layer in layers: for pop in pops: print layer, pop, n_rec[layer][pop] if not record_fraction and n_record > int(round(N_full[layer][pop] * N_scaling)): print "Note that requested number of neurons to record", print "exceeds ", layer, pop, " population size" # Create cortical populations self.pops = {} global_neuron_id = 1 self.base_neuron_ids = {} # list containing the GIDs of recording devices, needed for output # bundle device_list = [] for layer in layers: self.pops[layer] = {} for pop in pops: cellparams = neuron_params self.pops[layer][pop] = sim.Population( int(round(N_full[layer][pop] * N_scaling)), model, cellparams=cellparams, label=layer + pop ) this_pop = self.pops[layer][pop] # Provide DC input in the current-based case # DC input is assumed to be absent in the conductance-based # case this_pop.set("i_offset", self.DC_amp[layer][pop]) self.base_neuron_ids[this_pop] = global_neuron_id global_neuron_id += len(this_pop) + 2 this_pop.initialize("v", V_dist[layer][pop]) # Spike recording sd = sim.nest.Create( "spike_detector", params={ "label": "spikes_{0}{1}".format(layer, pop), "withtime": True, "withgid": True, "to_file": True, }, ) device_list.append(sd) sim.nest.Connect(list(this_pop[0 : n_rec[layer][pop]].all_cells), sd) # Membrane potential recording if record_v: if record_fraction: n_rec_v = round(this_pop.size * frac_record_v) else: n_rec_v = n_record_v vm = sim.nest.Create( "voltmeter", params={ "label": "voltages_{0}{1}".format(layer, pop), "withtime": True, "withgid": True, "to_file": True, }, ) device_list.append(vm) sim.nest.Connect(vm, list(this_pop[0:n_rec_v])) # Correlation recording if record_corr and simulator == "nest": index = structure[layer][pop] sim.nest.SetDefaults("static_synapse", {"receptor_type": index}) sim.nest.Connect(list(this_pop.all_cells), self.corr_detector) sim.nest.SetDefaults("static_synapse", {"receptor_type": 0}) if thalamic_input: self.thalamic_population = sim.nest.Create("parrot_neuron", thal_params["n_thal"]) # create and connect a poisson generator for stimulating the # thalamic population thal_pg = sim.nest.Create( "poisson_generator", params={ "rate": thal_params["rate"], "start": thal_params["start"], "stop": thal_params["start"] + thal_params["duration"], }, ) sim.nest.Connect(thal_pg, self.thalamic_population) possible_targets_curr = ["inhibitory", "excitatory"] # Connect for target_layer in layers: for target_pop in pops: target_index = structure[target_layer][target_pop] this_target_pop = self.pops[target_layer][target_pop] w_ext = self.w_ext # External inputs if input_type == "poisson": rate = bg_rate * self.K_ext[target_layer][target_pop] if simulator == "nest": # create only a single Poisson generator for each # population, since the native NEST implementation sends # independent spike trains to all targets if sim.rank() == 0: print "connecting Poisson generator to", print target_layer, target_pop pg = sim.nest.Create("poisson_generator", params={"rate": rate}) conn_dict = {"rule": "all_to_all"} syn_dict = {"model": "static_synapse", "weight": 1000.0 * w_ext, "delay": d_mean["E"]} sim.nest.Connect(pg, list(this_target_pop.all_cells), conn_dict, syn_dict) if thalamic_input: if sim.rank() == 0: print "creating thalamic connections to ", target_layer, print 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.0) / (n_target * thal_params["n_thal"])) ) / n_target * K_scaling ) target_neurons = list(this_target_pop.all_cells) n_syn = int(round(K_thal * len(target_neurons))) conn_dict = {"rule": "fixed_total_number", "N": n_syn} syn_dict = { "model": "static_synapse", "weight": { "distribution": "normal_clipped", "mu": 1000.0 * w_ext, "sigma": 1000.0 * w_rel * w_ext, }, "delay": { "distribution": "normal_clipped", "low": conf["simulator_params"][simulator]["min_delay"], "mu": d_mean["E"], "sigma": d_sd["E"], }, } sim.nest.Connect(self.thalamic_population, target_neurons, conn_dict, syn_dict) # Recurrent inputs for source_layer in layers: for source_pop in pops: source_index = structure[source_layer][source_pop] this_source_pop = self.pops[source_layer][source_pop] weight = self.w[target_index][source_index] possible_targets_curr[int((np.sign(weight) + 1) / 2)] if sim.rank() == 0: print "creating connections from ", source_layer + source_pop + " to " + target_layer + target_pop 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) connectivity.FixedTotalNumberConnect( sim, this_source_pop, this_target_pop, self.K[target_index][source_index], weight, w_sd, d_mean[source_pop], d_sd[source_pop], conf, ) return device_list
def setup(self, sim, conf): # extract parameters pyseed = conf['params_dict']['nest']['pyseed'] parallel_safe = conf['params_dict']['nest']['parallel_safe'] input_type = conf['params_dict']['nest']['input_type'] layers = conf['layers'] pops = conf['pops'] bg_rate = conf['bg_rate'] w_mean = conf['w_mean'] K_scaling = conf['params_dict']['nest']['K_scaling'] N_scaling = conf['params_dict']['nest']['N_scaling'] n_record = conf['params_dict']['nest']['n_record'] neuron_model = conf['neuron_model'] tau_max = conf['tau_max'] record_corr = conf['params_dict']['nest']['record_corr'] n_layers = conf['n_layers'] n_pops_per_layer = conf['n_pops_per_layer'] V0_mean = conf['V0_mean'] n_record_v = conf['params_dict']['nest']['n_record_v'] record_v = conf['params_dict']['nest']['record_v'] record_fraction = conf['params_dict']['nest']['record_fraction'] thalamic_input = conf['thalamic_input'] w_rel = conf['w_rel'] w_rel_234 = conf['w_rel_234'] simulator = conf['simulator'] N_full = conf['N_full'] K_ext = conf['K_ext'] tau_syn_E = conf['neuron_params']['tau_syn_E'] v_thresh = conf['neuron_params']['v_thresh'] v_rest = conf['neuron_params']['v_rest'] neuron_params = conf['neuron_params'] thal_params = conf['thal_params'] structure = conf['structure'] d_mean = conf['d_mean'] d_sd = conf['d_sd'] frac_record_v = conf['params_dict']['nest']['frac_record_v'] n_rec = helper_functions.get_n_rec(conf) # if parallel_safe=False, PyNN offsets the seeds by 1 for each rank script_rng = NumpyRNG(seed=pyseed, parallel_safe=parallel_safe) # 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 * 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. } } # In-degrees of the full-scale and scaled models K_full = scaling.get_indegrees(conf) self.K = K_scaling * K_full self.K_ext = {} for layer in layers: self.K_ext[layer] = {} for pop in pops: self.K_ext[layer][pop] = K_scaling * K_ext[layer][pop] self.w = helper_functions.create_weight_matrix(conf) # Network scaling if K_scaling != 1: self.w, self.w_ext, self.DC_amp = scaling.adjust_w_and_ext_to_K( K_full, K_scaling, self.w, self.DC_amp, conf) else: self.w_ext = w_mean Vthresh = {} for layer in layers: Vthresh[layer] = {} for pop in pops: Vthresh[layer][pop] = v_thresh # Initial membrane potential distributions # The original study used V0_mean = -58 mV, V0_sd = 5 mV. # This is adjusted here to any changes in v_rest and scaling of V. V0_mean = {} V0_sd = {} for layer in layers: V0_mean[layer] = {} V0_sd[layer] = {} for pop in pops: V0_mean[layer][pop] = (v_rest + Vthresh[layer][pop]) / 2. V0_sd[layer][pop] = (Vthresh[layer][pop] - v_rest) / 3. V_dist = {} for layer in layers: V_dist[layer] = {} for pop in pops: V_dist[layer][pop] = RandomDistribution( 'normal', [V0_mean[layer][pop], V0_sd[layer][pop]], rng=script_rng) model = getattr(sim, neuron_model) if record_corr and simulator == 'nest': # Create correlation recording device sim.nest.SetDefaults('correlomatrix_detector', {'delta_tau': 0.5}) self.corr_detector = sim.nest.Create('correlomatrix_detector') sim.nest.SetStatus( self.corr_detector, { 'N_channels': n_layers * n_pops_per_layer, 'tau_max': tau_max, 'Tstart': tau_max, }) if sim.rank() == 0: print 'neuron_params:', conf['neuron_params'] print 'K: ', self.K print 'K_ext: ', self.K_ext print 'w: ', self.w print 'w_ext: ', self.w_ext print 'DC_amp: ', self.DC_amp print 'V0_mean: ' for layer in layers: for pop in pops: print layer, pop, V0_mean[layer][pop] print 'n_rec:' for layer in layers: for pop in pops: print layer, pop, n_rec[layer][pop] if not record_fraction and n_record > \ int(round(N_full[layer][pop] * N_scaling)): print 'Note that requested number of neurons to record', print 'exceeds ', layer, pop, ' population size' # Create cortical populations self.pops = {} global_neuron_id = 1 self.base_neuron_ids = {} # list containing the GIDs of recording devices, needed for output # bundle device_list = [] for layer in layers: self.pops[layer] = {} for pop in pops: cellparams = neuron_params self.pops[layer][pop] = sim.Population(int( round(N_full[layer][pop] * N_scaling)), model, cellparams=cellparams, label=layer + pop) this_pop = self.pops[layer][pop] # Provide DC input in the current-based case # DC input is assumed to be absent in the conductance-based # case this_pop.set('i_offset', self.DC_amp[layer][pop]) self.base_neuron_ids[this_pop] = global_neuron_id global_neuron_id += len(this_pop) + 2 this_pop.initialize('v', V_dist[layer][pop]) # Spike recording sd = sim.nest.Create('spike_detector', params={ 'label': 'spikes_{0}{1}'.format(layer, pop), 'withtime': True, 'withgid': True, 'to_file': True }) device_list.append(sd) sim.nest.Connect(list(this_pop[0:n_rec[layer][pop]].all_cells), sd) # Membrane potential recording if record_v: if record_fraction: n_rec_v = round(this_pop.size * frac_record_v) else: n_rec_v = n_record_v vm = sim.nest.Create('voltmeter', params={ 'label': 'voltages_{0}{1}'.format( layer, pop), 'withtime': True, 'withgid': True, 'to_file': True }) device_list.append(vm) sim.nest.Connect(vm, list(this_pop[0:n_rec_v])) # Correlation recording if record_corr and simulator == 'nest': index = structure[layer][pop] sim.nest.SetDefaults('static_synapse', {'receptor_type': index}) sim.nest.Connect(list(this_pop.all_cells), self.corr_detector) sim.nest.SetDefaults('static_synapse', {'receptor_type': 0}) if thalamic_input: self.thalamic_population = sim.nest.Create('parrot_neuron', thal_params['n_thal']) # create and connect a poisson generator for stimulating the # thalamic population thal_pg = sim.nest.Create('poisson_generator', params={'rate': thal_params['rate'], 'start': thal_params['start'], 'stop': thal_params['start'] \ + thal_params['duration']}) sim.nest.Connect(thal_pg, self.thalamic_population) possible_targets_curr = ['inhibitory', 'excitatory'] # Connect for target_layer in layers: for target_pop in pops: target_index = structure[target_layer][target_pop] this_target_pop = self.pops[target_layer][target_pop] w_ext = self.w_ext # External inputs if input_type == 'poisson': rate = bg_rate * self.K_ext[target_layer][target_pop] if simulator == 'nest': # create only a single Poisson generator for each # population, since the native NEST implementation sends # independent spike trains to all targets if sim.rank() == 0: print 'connecting Poisson generator to', print target_layer, target_pop pg = sim.nest.Create('poisson_generator', params={'rate': rate}) conn_dict = {'rule': 'all_to_all'} syn_dict = { 'model': 'static_synapse', 'weight': 1000. * w_ext, 'delay': d_mean['E'] } sim.nest.Connect(pg, list(this_target_pop.all_cells), conn_dict, syn_dict) if thalamic_input: if sim.rank() == 0: print 'creating thalamic connections to ', target_layer, print 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 * K_scaling target_neurons = list(this_target_pop.all_cells) n_syn = int(round(K_thal * len(target_neurons))) conn_dict = {'rule': 'fixed_total_number', 'N': n_syn} syn_dict = {'model': 'static_synapse', 'weight': {'distribution': 'normal_clipped', 'mu': 1000. * w_ext, 'sigma': 1000. * w_rel * w_ext}, 'delay': {'distribution': 'normal_clipped', 'low': conf['simulator_params'] \ [simulator]['min_delay'], 'mu': d_mean['E'], 'sigma': d_sd['E']}} sim.nest.Connect(self.thalamic_population, target_neurons, conn_dict, syn_dict) # Recurrent inputs for source_layer in layers: for source_pop in pops: source_index = structure[source_layer][source_pop] this_source_pop = self.pops[source_layer][source_pop] weight = self.w[target_index][source_index] possible_targets_curr[int((np.sign(weight) + 1) / 2)] if sim.rank() == 0: print 'creating connections from ', source_layer + \ source_pop + ' to ' + target_layer + target_pop 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) connectivity.FixedTotalNumberConnect( sim, this_source_pop, this_target_pop, self.K[target_index][source_index], weight, w_sd, d_mean[source_pop], d_sd[source_pop], conf) return device_list
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)