def logging(self): """ Write runtime and memory for the first 30 MPI processes to file. """ d = { 'time_prepare': self.time_prepare, 'time_network_local': self.time_network_local, 'time_network_global': self.time_network_global, 'time_init': self.time_init, 'time_simulate': self.time_simulate, 'base_memory': self.base_memory, 'network_memory': self.network_memory, 'init_memory': self.init_memory, 'total_memory': self.total_memory, 'time_create': self.time_create, 'time_connect': self.time_connect, 'num_connections': nest.GetKernelStatus('num_connections'), 'local_spike_counter': nest.GetKernelStatus('local_spike_counter') } print(d) if nest.Rank() < 30: fn = os.path.join( self.data_dir, 'recordings', '_'.join( (self.label, 'logfile', str(nest.Rank())))) with open(fn, 'w') as f: json.dump(d, f)
def create_dc_generator(self): """ Creates a DC input generator. If DC input is provided, the DC generators are created and the necessary parameters are passed to them. """ if self.stim_dict['dc_input']: if nest.Rank() == 0: print('DC generator created') dc_amp_stim = self.net_dict['K_ext'] * self.stim_dict['dc_amp'] self.dc = [] if nest.Rank() == 0: print('DC_amp_stim', dc_amp_stim) for i, target_pop in enumerate(self.pops): dc = nest.Create( 'dc_generator', params={ 'amplitude': dc_amp_stim[i], 'start': self.stim_dict['dc_start'], 'stop': ( self.stim_dict['dc_start'] + self.stim_dict['dc_dur'] ) } ) self.dc.append(dc)
def create_devices(self): """ Creates the recording devices. Only devices which are given in net_dict['rec_dev'] are created. """ self.spike_detector = [] self.voltmeter = [] for i, pop in enumerate(self.pops): if 'spike_detector' in self.net_dict['rec_dev']: recdict = { 'record_to': 'ascii', 'label': os.path.join(self.data_path, 'spike_detector') } dummy = nest.Create('spike_detector', params=recdict) self.spike_detector.append(dummy) if 'voltmeter' in self.net_dict['rec_dev']: recdictmem = { 'interval': self.sim_dict['rec_V_int'], 'record_to': 'ascii', 'label': os.path.join(self.data_path, 'voltmeter'), 'record_from': ['V_m'], } volt = nest.Create('voltmeter', params=recdictmem) self.voltmeter.append(volt) if 'spike_detector' in self.net_dict['rec_dev']: if nest.Rank() == 0: print('Spike detectors created') if 'voltmeter' in self.net_dict['rec_dev']: if nest.Rank() == 0: print('Voltmeters created')
def create_thalamic_input(self): """ This function creates the thalamic neuronal population if this is specified in stimulus_params.py. """ if self.stim_dict['thalamic_input']: if nest.Rank() == 0: print('Thalamic input provided') self.thalamic_population = nest.Create('parrot_neuron', self.stim_dict['n_thal']) self.thalamic_weight = get_weight(self.stim_dict['PSP_th'], self.net_dict) self.stop_th = (self.stim_dict['th_start'] + self.stim_dict['th_duration']) self.poisson_th = nest.Create('poisson_generator') self.poisson_th.set({ 'rate': self.stim_dict['th_rate'], 'start': self.stim_dict['th_start'], 'stop': self.stop_th }) nest.Connect(self.poisson_th, self.thalamic_population) self.nr_synapses_th = synapses_th_matrix(self.net_dict, self.stim_dict) if self.K_scaling != 1: self.thalamic_weight = self.thalamic_weight / (self.K_scaling** 0.5) self.nr_synapses_th = (self.nr_synapses_th * self.K_scaling) else: if nest.Rank() == 0: print('Thalamic input not provided')
def update_growth_rate(self): if nest.Rank() == 0: growth_rate_dict = self.observe_growth_rate_slot.growth_rate_dict else: growth_rate_dict = 0 growth_rate_dict = self.comm.bcast(growth_rate_dict, root=0) for x in range(0, self.regions): if nest.Rank() == 0: print("GR" + str(growth_rate_dict[x])) synaptic_elements_e = { 'growth_rate': growth_rate_dict[x], } synaptic_elements_i = { 'growth_rate': -growth_rate_dict[x], } nest.SetStatus(self.nodes_e[x], 'synaptic_elements_param', {'Den_in' + str(x): synaptic_elements_i}) nest.SetStatus(self.nodes_e[x], 'synaptic_elements_param', {'Den_ex' + str(x): synaptic_elements_e}) nest.SetStatus(self.nodes_e[x], 'synaptic_elements_param', {'Axon_ex' + str(x): synaptic_elements_e}) nest.SetStatus(self.nodes_i[x], 'synaptic_elements_param', {'Axon_in' + str(x): synaptic_elements_e}) nest.SetStatus(self.nodes_i[x], 'synaptic_elements_param', {'Den_in' + str(x): synaptic_elements_i}) nest.SetStatus(self.nodes_i[x], 'synaptic_elements_param', {'Den_ex' + str(x): synaptic_elements_e})
def create_dc_generator(self): """ Creates a DC input generator. If DC input is provided, the DC generators are created and the necessary parameters are passed to them. """ if self.stim_dict['dc_input']: if nest.Rank() == 0: print('DC generator created') # Scale DC input strengths according to the number of inputs a given population recieves dc_amp_stim = self.net_dict['K_ext'] * self.stim_dict['dc_amp'] if nest.Rank() == 0: print('DC_amp_stim', dc_amp_stim) # Initialise DC store self.dc = [] # Loop over populations for i, target_pop in enumerate(self.pops): # Create a DC generator dc = nest.Create('dc_generator', params={ 'amplitude': dc_amp_stim[i], 'start': self.stim_dict['dc_start'], 'stop': (self.stim_dict['dc_start'] + self.stim_dict['dc_dur']) }) self.dc.append(dc)
def __create_recording_devices(self): """ Creates one recording device of each kind per population. Only devices which are given in ``sim_dict['rec_dev']`` are created. """ if nest.Rank() == 0: print('Creating recording devices.') if 'spike_recorder' in self.sim_dict['rec_dev']: if nest.Rank() == 0: print(' Creating spike recorders.') sd_dict = { 'record_to': 'ascii', 'label': os.path.join(self.data_path, 'spike_recorder') } self.spike_recorders = nest.Create('spike_recorder', n=self.num_pops, params=sd_dict) if 'voltmeter' in self.sim_dict['rec_dev']: if nest.Rank() == 0: print(' Creating voltmeters.') vm_dict = { 'interval': self.sim_dict['rec_V_int'], 'record_to': 'ascii', 'record_from': ['V_m'], 'label': os.path.join(self.data_path, 'voltmeter') } self.voltmeters = nest.Create('voltmeter', n=self.num_pops, params=vm_dict)
def setup_nest(self): nest.ResetKernel() master_seed = self.sim_dict['master_seed'] if nest.Rank() == 0: print('Master seed: %i ' % master_seed) nest.SetKernelStatus( {'local_num_threads': self.sim_dict['local_num_threads']}) N_tp = nest.GetKernelStatus(['total_num_virtual_procs'])[0] if nest.Rank() == 0: print('Number of total processes: %i' % N_tp) rng_seeds = list( range(master_seed + 1 + N_tp, master_seed + 1 + (2 * N_tp))) grng_seed = master_seed + N_tp if nest.Rank() == 0: print( 'Seeds for random number generators of virtual processes: %r' % rng_seeds) print('Global random number generator seed: %i' % grng_seed) self.pyrngs = [ np.random.RandomState(s) for s in list(range(master_seed, master_seed + N_tp)) ] self.sim_resolution = self.sim_dict['sim_resolution'] kernel_dict = { 'resolution': self.sim_resolution, 'grng_seed': grng_seed, 'rng_seeds': rng_seeds, 'overwrite_files': self.sim_dict['overwrite_files'], 'print_time': self.sim_dict['print_time'], } nest.SetKernelStatus(kernel_dict)
def log(self, value): if nest.Rank() < self.max_rank_log: line = '{lc} {rank} {value} \n'.format( lc=self.line_counter, rank=nest.Rank(), value=value) self.f.write(line) self.line_counter += 1 if nest.Rank() < self.max_rank_cout: print(str(nest.Rank()) + ' ' + value + '\n', file=sys.stdout) print(str(nest.Rank()) + ' ' + value + '\n', file=sys.stderr)
def __enter__(self): if nest.Rank() < self.max_rank_log: # convert rank to string, prepend 0 if necessary to make # numbers equally wide for all ranks rank = '{:0' + str(len(str(self.max_rank_log))) + '}' fn = '{fn}_{rank}.dat'.format( fn=self.file_name, rank=rank.format(nest.Rank())) self.f = open(fn, 'w') return self
def create_homogenous_connection(dic_layer, param_connection, save=False, init=None): ''' creation of homogeneous connections or inside population :param dic_layer: Dictionary with all the layer :param param_connection: Parameter for the connections :param save: option for saving or not the connection between neurons :param init: option for the initialisation of parameter for the connection :return: nothing ''' if init == None: (conn_params_ex_inside, conn_params_in_inside, list_layer_ex, list_layer_in, weights, delays) = init_connection(dic_layer, param_connection) else: (conn_params_ex_inside, conn_params_in_inside, list_layer_ex, list_layer_in, weights, delays) = init #connection inside population of neurons for i in range(len(list_layer_ex)): if nest.Rank() == 0: tic = time.time() print('homogenous connection between population not mesh :' + str(i), file=sys.stderr) nest.Connect(list_layer_ex[i]['region'], list_layer_ex[i]['region'], conn_spec=conn_params_ex_inside, syn_spec="excitatory_inside") nest.Connect(list_layer_ex[i]['region'], list_layer_in[i]['region'], conn_spec=conn_params_ex_inside, syn_spec="excitatory_inside") nest.Connect(list_layer_in[i]['region'], list_layer_ex[i]['region'], conn_spec=conn_params_in_inside, syn_spec="inhibitory_inside") nest.Connect( list_layer_in[i]['region'], list_layer_in[i]['region'], conn_spec=conn_params_in_inside, syn_spec="inhibitory_inside") #no link between inhibitory neurons if nest.Rank() == 0: toc = time.time() - tic print("Time: %.2f s" % toc, file=sys.stderr) if save: np.save( param_connection['path_homogeneous'] + str(nest.Rank()) + '.npy', np.array(nest.GetConnections())[:, :2])
def create_devices(self): """ Creates the recording devices. Only devices which are given in net_dict['rec_dev'] are created. """ self.spike_detector = [] self.voltmeter = [] for i, pop in enumerate(self.pops): if 'spike_detector' in self.net_dict['rec_dev']: recdict = { 'withgid': True, 'withtime': True, 'to_memory': False, 'to_file': True, 'label': os.path.join(self.data_path, 'spikes-pop' + str(i)) } dummy = nest.Create('spike_detector', params=recdict) self.spike_detector.append(dummy) if 'voltmeter' in self.net_dict['rec_dev']: recdictmem = { 'interval': self.sim_dict['rec_V_int'], 'withgid': True, 'withtime': True, 'to_memory': False, 'to_file': True, 'label': os.path.join(self.data_path, 'voltmeter'), 'record_from': ['V_m'], } volt = nest.Create('voltmeter', params=recdictmem) self.voltmeter.append(volt) if 'multimeter' in self.net_dict['rec_dev']: recdictmulti = { 'withgid': True, 'withtime': True, 'to_memory': False, 'to_file': True, "record_from": ["V_m", "I_syn_ex", "I_syn_in"], 'label': os.path.join(self.data_path, 'multimeter' + str(i)) } self.multimeter = nest.Create('multimeter', params=recdictmulti) if 'spike_detector' in self.net_dict['rec_dev']: if nest.Rank() == 0: print('Spike detectors created') if 'voltmeter' in self.net_dict['rec_dev']: if nest.Rank() == 0: print('Voltmeters created') if 'multimeter' in self.net_dict['rec_dev']: if nest.Rank() == 0: print('Multimeters created')
def __create_neuronal_populations(self): """ Creates the neuronal populations. The neuronal populations are created and the parameters are assigned to them. The initial membrane potential of the neurons is drawn from normal distributions dependent on the parameter ``V0_type``. The first and last neuron id of each population is written to file. """ if nest.Rank() == 0: print('Creating neuronal populations.') self.pops = [] for i in np.arange(self.num_pops): population = nest.Create(self.net_dict['neuron_model'], self.num_neurons[i]) population.set( tau_syn_ex=self.net_dict['neuron_params']['tau_syn'], tau_syn_in=self.net_dict['neuron_params']['tau_syn'], E_L=self.net_dict['neuron_params']['E_L'], V_th=self.net_dict['neuron_params']['V_th'], V_reset=self.net_dict['neuron_params']['V_reset'], t_ref=self.net_dict['neuron_params']['t_ref'], I_e=self.DC_amp[i]) if self.net_dict['V0_type'] == 'optimized': population.set(V_m=nest.random.normal( self.net_dict['neuron_params']['V0_mean']['optimized'][i], self.net_dict['neuron_params']['V0_std']['optimized'][i])) elif self.net_dict['V0_type'] == 'original': population.set(V_m=nest.random.normal( self.net_dict['neuron_params']['V0_mean']['original'], self.net_dict['neuron_params']['V0_std']['original'])) else: raise ValueError( 'V0_type is incorrect. ' + 'Valid options are "optimized" and "original".') self.pops.append(population) # write node ids to file if nest.Rank() == 0: fn = os.path.join(self.data_path, 'population_nodeids.dat') with open(fn, 'w+') as f: for pop in self.pops: f.write('{} {}\n'.format(pop[0].global_id, pop[-1].global_id))
def __setup_nest(self): """ Initializes the NEST kernel. Reset the NEST kernel and pass parameters to it. The number of seeds for random number generation are computed based on the total number of virtual processes (number of MPI processes x number of threads per MPI process). """ nest.ResetKernel() # set seeds for random number generation nest.SetKernelStatus( {'local_num_threads': self.sim_dict['local_num_threads']}) N_vp = nest.GetKernelStatus('total_num_virtual_procs') rng_seed = self.sim_dict['rng_seed'] if nest.Rank() == 0: print('RNG seed: {} '.format(rng_seed)) print(' Total number of virtual processes: {}'.format(N_vp)) # pass parameters to NEST kernel self.sim_resolution = self.sim_dict['sim_resolution'] kernel_dict = { 'resolution': self.sim_resolution, 'rng_seed': rng_seed, 'overwrite_files': self.sim_dict['overwrite_files'], 'print_time': self.sim_dict['print_time'] } nest.SetKernelStatus(kernel_dict)
def record_connectivity(self): if nest.Rank() == 0: msg = float_vector_message() print nest.GetConnections(self.nodes_i[0], self.nodes_e[0]) for x in range(0, self.regions): syn_elems_e = nest.GetStatus(self.loc_e[x], 'synaptic_elements') syn_elems_i = nest.GetStatus(self.loc_i[x], 'synaptic_elements') sum_neurons = sum(neuron['Axon_in' + str(x)]['z_connected'] for neuron in syn_elems_i) sum_neurons = self.comm.gather(sum_neurons, root=0) if nest.Rank() == 0: self.total_connections_i[x] = (sum(sum_neurons)) msg.value.append(sum(sum_neurons)) if nest.Rank() == 0: self.last_connections_msg = msg self.total_connections_slot_out.send(msg.SerializeToString())
def get_my_process_id(self): ''' Return the id-number of this process. ''' import nest return nest.Rank()
def evaluate(self, raster_plot_interval, firing_rates_interval): """ Displays simulation results. Creates a spike raster plot. Calculates the firing rate of each population and displays them as a box plot. Parameters ---------- raster_plot_interval Times (in ms) to start and stop loading spike times for raster plot (included). firing_rates_interval Times (in ms) to start and stop lading spike times for computing firing rates (included). Returns ------- None """ if nest.Rank() == 0: print( 'Interval to plot spikes: {} ms'.format(raster_plot_interval)) helpers.plot_raster(self.data_path, 'spike_recorder', raster_plot_interval[0], raster_plot_interval[1], self.net_dict['N_scaling']) print('Interval to compute firing rates: {} ms'.format( firing_rates_interval)) helpers.firing_rates(self.data_path, 'spike_recorder', firing_rates_interval[0], firing_rates_interval[1]) helpers.boxplot(self.data_path, self.net_dict['populations'])
def store_connectivity(self): if nest.Rank() == 0: f = open('connectivity_'+'.bin', "wb")#+ str(datetime.datetime.now().strftime("%Y%m%d-%H%M%S")) +'.bin', "wb") for x in range(0,self.regions) : connections = nest.GetStatus(nest.GetConnections(self.loc_e[x])) f.write(str(connections)) f.close()
def setUp(self): nest.ResetKernel() nest.set_verbosity('M_ERROR') self.num_procs = 1 if mpi_test: self.comm = MPI.COMM_WORLD self.rank = self.comm.Get_rank() assert(nest.Rank() == self.rank) self.num_procs = 2 self.exclude_synapse_model = [ 'stdp_dopamine_synapse', 'stdp_dopamine_synapse_lbl', 'stdp_dopamine_synapse_hpc', 'stdp_dopamine_synapse_hpc_lbl', 'rate_connection_instantaneous', 'rate_connection_instantaneous_lbl', 'rate_connection_delayed', 'rate_connection_delayed_lbl', 'gap_junction', 'gap_junction_lbl', 'diffusion_connection', 'diffusion_connection_lbl', 'clopath_synapse', 'clopath_synapse_lbl', 'clopath_synapse_hpc' ]
def store_current_connections(self): if nest.Rank() == 0: f = open( 'current_connectivity_' + '.bin', "wb" ) #+ str(datetime.datetime.now().strftime("%Y%m%d-%H%M%S")) +'.bin', "wb") f.write(str(self.total_connections_i)) f.close()
def run(): vc = VirtualConnectome() vc.prepare_simulation() vc.create_nodes() vc.connect_external_input() vc.connect_inter_region() nest.EnableStructuralPlasticity() if nest.Rank() == 0: vc.send_num_regions() while vc.get_quit_state() == False: while vc.get_pause_state() == False: vc.simulate() if nest.Rank() == 0: print 'iteration done' if vc.get_save_state() == True: vc.save_state()
def save_state(self): if nest.Rank() != 0: return update_interval = self.observe_update_interval_slot.get_last_message() growth_rate = self.observe_growth_rate_slot.get_last_message() eta_state = self.observe_eta_slot.get_last_message() if update_interval != None: f = open( 'update_interval_' + str(datetime.datetime.now().strftime("%Y%m%d-%H%M%S")) + '.bin', "wb") f.write(update_interval.SerializeToString()) f.close() if growth_rate != None: f = open( 'growth_rate_' + str(datetime.datetime.now().strftime("%Y%m%d-%H%M%S")) + '.bin', "wb") f.write(growth_rate.SerializeToString()) f.close() if eta_state != None: f = open( 'eta_state_' + str(datetime.datetime.now().strftime("%Y%m%d-%H%M%S")) + '.bin', "wb") f.write(eta_state.SerializeToString()) f.close()
def connect_dc_generator(self): """ Connects the DC generator to the microcircuit.""" if nest.Rank() == 0: print('DC Generator connection established') for i, target_pop in enumerate(self.pops): if self.stim_dict['dc_input']: nest.Connect(self.dc[i], target_pop)
def create_poisson(self): """ Creates the Poisson generators. If Poissonian input is provided, the Poissonian generators are created and the parameters needed are passed to the Poissonian generator. """ if nest.Rank() == 0: print('Poisson background input created') rate_ext = self.net_dict['network_rate'] * self.K_ext self.poisson = [] for i, target_pop in enumerate(self.pops): poisson = nest.Create('poisson_generator') # exc input nest.SetStatus(poisson, { 'rate': self.net_dict['input_conn_params']['gamma'] * rate_ext[i] }) self.poisson.append(poisson) poisson = nest.Create('poisson_generator') # inh input nest.SetStatus( poisson, { 'rate': (1. - self.net_dict['input_conn_params']['gamma']) * rate_ext[i] }) self.poisson.append(poisson)
def __connect_thalamic_stim_input(self): """ Connects the thalamic input to the neuronal populations.""" if nest.Rank() == 0: print('Connecting thalamic input.') # connect Poisson input to thalamic population nest.Connect(self.poisson_th, self.thalamic_population) # connect thalamic population to neuronal populations for i, target_pop in enumerate(self.pops): conn_dict_th = { 'rule': 'fixed_total_number', 'N': self.num_th_synapses[i] } syn_dict_th = { 'weight': nest.math.redraw(nest.random.normal( mean=self.weight_th, std=self.weight_th * self.net_dict['weight_rel_std']), min=0.0, max=np.Inf), 'delay': nest.math.redraw(nest.random.normal( mean=self.stim_dict['delay_th_mean'], std=(self.stim_dict['delay_th_mean'] * self.stim_dict['delay_th_rel_std'])), min=self.sim_resolution, max=np.Inf) } nest.Connect(self.thalamic_population, target_pop, conn_spec=conn_dict_th, syn_spec=syn_dict_th)
def get_quit_state(self): if nest.Rank() == 0: quit_state = self.observe_quit_slot.state else: quit_state = False quit_state = self.comm.bcast(quit_state, root=0) return quit_state
def connect_thalamus(self): """ Connects the thalamic population to the microcircuit.""" if nest.Rank() == 0: print('Thalamus connection established') for i, target_pop in enumerate(self.pops): conn_dict_th = { 'rule': 'fixed_total_number', 'N': int(self.nr_synapses_th[i]) } syn_dict_th = { 'weight': { 'distribution': 'normal_clipped', 'mu': self.thalamic_weight, 'sigma': ( self.thalamic_weight * self.net_dict['PSP_sd'] ), 'low': 0.0 }, 'delay': { 'distribution': 'normal_clipped', 'mu': self.stim_dict['delay_th'][i], 'sigma': self.stim_dict['delay_th_sd'][i], 'low': self.sim_resolution } } nest.Connect( self.thalamic_population, target_pop, conn_spec=conn_dict_th, syn_spec=syn_dict_th )
def get_pause_state(self): if nest.Rank() == 0: pause_state = self.observe_pause_slot.state else: pause_state = False pause_state = self.comm.bcast(pause_state, root=0) return pause_state
def evaluate(self, raster_plot_time_idx, fire_rate_time_idx): """ Displays output of the simulation. Calculates the firing rate of each population, creates a spike raster plot and a box plot of the firing rates. """ if nest.Rank() == 0: print( 'Interval to compute firing rates: %s ms' % np.array2string(fire_rate_time_idx) ) fire_rate( self.data_path, 'spike_detector', fire_rate_time_idx[0], fire_rate_time_idx[1] ) print( 'Interval to plot spikes: %s ms' % np.array2string(raster_plot_time_idx) ) plot_raster( self.data_path, 'spike_detector', raster_plot_time_idx[0], raster_plot_time_idx[1] ) boxplot(self.net_dict, self.data_path)
def save_state(self): if nest.Rank() != 0: return print 'saving state to disk' time_stamp = str( datetime.datetime.now().strftime("%Y%m%d-%H%M%S") ) #take time stamp only once for all files to make it unique update_interval = self.update_interval growth_rate = self.observe_growth_rate_slot.growth_rate_dict eta_state = self.observe_eta_slot.eta_dict f = open('update_interval_' + str(time_stamp) + '.bin', "wb") f.write(str(update_interval)) f.close() f = open('growth_rate_' + str(time_stamp) + '.bin', "wb") f.write(str(growth_rate)) f.close() f = open('eta_state_' + str(time_stamp) + '.bin', "wb") f.write(str(eta_state)) f.close() self.store_connectivity(time_stamp) self.store_current_connections(time_stamp) self.store_sp_status(time_stamp) print 'saving done'