def simulate_STN_GPe_population(params): pid = os.getpid() b2.set_device( 'cpp_standalone', # build_on_run=False, directory=join("output", f"standalone-{pid}")) # b2.start_scope() par_s = params['par_s'] par_g = params['par_g'] par_syn = params['par_syn'] par_sim = params['par_sim'] if par_sim['standalone_mode']: b2.get_device().reinit() b2.get_device().activate( # build_on_run=False, directory=join("output", f"standalone-{pid}")) b2.defaultclock.dt = par_sim['dt'] eqs_s = ''' minf = 1/(1+exp(-(vs-thetam*mV)/(sigmam*mV))) : 1 hinf = 1/(1+exp(-(vs-thetah*mV)/(sigmah*mV))) : 1 ninf = 1/(1+exp(-(vs-thetan*mV)/(sigman*mV))) : 1 ainf = 1/(1+exp(-(vs-thetaa*mV)/(sigmaa*mV))) : 1 binf = 1/(1+exp((r-thetab)/sigmab))-1/(1+exp(-thetab/sigmab)) : 1 rinf = 1/(1+exp(-(vs-thetar*mV)/(sigmar*mV))) : 1 sinf = 1/(1+exp(-(vs-thetas*mV)/(sigmas*mV))) : 1 taun = taun0+taun1/(1+exp(-(vs-thn*mV)/(sigmant*mV))) : second tauh = tauh0+tauh1/(1+exp(-(vs-thh*mV)/(sigmaht*mV))) : second taur = taur0+taur1/(1+exp(-(vs-thr*mV)/(sigmart*mV))) : second il = gl * (vs - vl) : amp ina = gna * minf ** 3 * h * (vs - vna) : amp ik = gk * n ** 4 * (vs - vk) : amp iahp = gahp * ca / (ca + k1) * (vs - vk) : amp ica = gca * sinf ** 2 * (vs - vca) : amp it = gt * ainf ** 3 * binf ** 2 * (vs - vca) : amp i_exts : amp i_syn_GtoS : amp s_GtoS_sum : 1 tmp2 = vs - thetag_s *mV : volt # Hinf_s = 1 / (1 + exp(-(tmp2 - thetas*mV) / (sigmas*mV))) : 1 Hinf_s = 1 / (1 + exp(-(tmp2 - thetagH_s*mV) / (sigmagH_s*mV))) : 1 ds_StoG/dt = alphas * Hinf_s * (1 - s_StoG) - betas * s_StoG : 1 dh/dt = phi * (hinf - h) / tauh : 1 dn/dt = phi * (ninf - n) / taun : 1 dr/dt = phir * (rinf - r) / taur : 1 dca/dt = eps * ((-ica - it)/pA - kca* ca) : 1 membrane_Im = -(il + ina + ik + it + ica + iahp)+i_exts+i_syn_GtoS:amp dvs/dt = membrane_Im/C : volt ''' eqs_g = ''' i_extg : amp ainfg = 1 / (1 + exp(-(vg - thetaag*mV) / (sigag*mV))) : 1 sinfg = 1 / (1 + exp(-(vg - thetasg*mV) / (sigsg*mV))) : 1 rinfg = 1 / (1 + exp(-(vg - thetarg*mV) / (sigrg*mV))) : 1 minfg = 1 / (1 + exp(-(vg - thetamg*mV) / (sigmg*mV))) : 1 ninfg = 1 / (1 + exp(-(vg - thetang*mV) / (signg*mV))) : 1 hinfg = 1 / (1 + exp(-(vg - thetahg*mV) / (sighg*mV))) : 1 taung = taun0g + taun1g / (1 + exp(-(vg - thngt*mV) / (sng*mV))) : second tauhg = tauh0g + tauh1g / (1 + exp(-(vg - thhgt*mV) / (shg*mV))) : second dhg/dt = phihg*(hinfg-hg)/tauhg : 1 dng/dt = phing*(ninfg-ng)/taung : 1 drg/dt = phig*(rinfg-rg)/taurg : 1 dcag/dt= epsg*((-icag-itg)/pA - kcag*cag) : 1 dvg/dt = membrane_Im / C : volt tmp1 = vg - thetag_g *mV : volt # Hinf_g = 1 / (1 + exp(-(tmp1 - thetasg*mV) / (sigsg*mV))) : 1 Hinf_g = 1 / (1 + exp(-(tmp1 - thetagH_g*mV) / (sigmagH_g*mV))) : 1 ds_GtoS/dt = alphag * (1 - s_GtoS) * Hinf_g - betag * s_GtoS : 1 itg = gtg * (ainfg ** 3) * rg * (vg - vcag) : amp inag = gnag * (minfg ** 3) * hg * (vg - vnag) : amp ikg = gkg * (ng ** 4) * (vg - vkg) : amp iahpg = gahpg * (vg - vkg) * cag / (cag + k1g) : amp icag = gcag * (sinfg ** 2) * (vg - vcag) : amp ilg = glg * (vg - vlg) : amp s_StoG_sum : 1 i_syn_StoG : amp i_syn_GtoG : amp membrane_Im =-(itg+inag+ikg+iahpg+icag+ilg)+i_extg+i_syn_StoG+i_syn_GtoG : amp ''' eqs_syn_GtoS = ''' i_syn_GtoS_post = g_GtoS*s_GtoS_pre*(v_rev_GtoS-vs):amp (summed) ''' eqs_syn_StoG = ''' i_syn_StoG_post = g_StoG*s_StoG_pre*(v_rev_StoG-vg):amp (summed) ''' eqs_syn_GtoG = ''' i_syn_GtoG_post = g_GtoG*s_GtoS_pre*(v_rev_GtoG-vg):amp (summed) ''' #---------------------------------------------------------------# neurons_s = b2.NeuronGroup( par_s['num'], eqs_s, method=par_sim['integration_method'], dt=par_sim['dt'], threshold='vs>-20*mV', refractory='vs>-20*mV', namespace={ **par_s, **par_syn }, ) #---------------------------------------------------------------# neurons_g = b2.NeuronGroup( par_g['num'], eqs_g, method=par_sim['integration_method'], dt=par_sim['dt'], threshold='vg>-20*mV', refractory='vg>-20*mV', namespace={ **par_g, **par_syn }, ) # --------------------------------------------------------------- syn_GtoS = b2.Synapses(neurons_g, neurons_s, eqs_syn_GtoS, method=par_sim['integration_method'], dt=par_sim['dt'], namespace=par_syn) # --------------------------------------------------------------- cols, rows = np.nonzero(par_syn['adj_GtoS']) syn_GtoS.connect(i=rows, j=cols) # syn_GtoS.connect(j='i') # syn_GtoS.connect(j='k for k in range(i-1, i+2)', skip_if_invalid=True) # --------------------------------------------------------------- syn_StoG = b2.Synapses(neurons_s, neurons_g, eqs_syn_StoG, method=par_sim['integration_method'], dt=par_sim['dt'], namespace=par_syn) syn_StoG.connect(j='i') # --------------------------------------------------------------- syn_GtoG = b2.Synapses(neurons_g, neurons_g, eqs_syn_GtoG, method=par_sim['integration_method'], dt=par_sim['dt'], namespace=par_syn) # figure 5, T2002 cols, rows = np.nonzero(par_syn['adj_GtoG']) syn_GtoG.connect(i=rows, j=cols) # syn_GtoG.connect(p=par_syn['p_GtoG'], condition='i != j') # --------------------------------------------------------------- neurons_s.vs = par_s['v0'] neurons_s.h = "hinf" neurons_s.n = "ninf" neurons_s.r = "rinf" neurons_s.ca = 0 neurons_s.i_exts = par_s['i_ext'] neurons_g.vg = par_g['v0'] neurons_g.hg = "hinfg" neurons_g.ng = "ninfg" neurons_g.rg = "rinfg" neurons_g.cag = 0 neurons_g.i_extg = par_g['i_ext'] #---------------------------------------------------------------# state_mon_s = b2.StateMonitor(neurons_s, ["vs", "i_syn_GtoS", "ca"], record=True) state_mon_g = b2.StateMonitor(neurons_g, ["vg", "i_syn_StoG", "cag"], record=True) spike_mon_s = b2.SpikeMonitor(neurons_s) spike_mon_g = b2.SpikeMonitor(neurons_g) lfp_stn = b2.PopulationRateMonitor(neurons_s) lfp_gpe = b2.PopulationRateMonitor(neurons_g) net = b2.Network(neurons_s, neurons_g, state_mon_g, spike_mon_s, state_mon_s, spike_mon_g) net.add(syn_GtoS) net.add(syn_StoG) net.add(syn_GtoG) net.add(lfp_gpe) net.add(lfp_stn) net.run(par_sim['simulation_time']) # if par_sim['standalone_mode']: # b2.get_device().build(directory="output", # compile=True, # run=True, # debug=False) monitors = { "state_stn": state_mon_s, "state_gpe": state_mon_g, "spike_stn": spike_mon_s, "spike_gpe": spike_mon_g, "lfp_stn": lfp_stn, "lfp_gpe": lfp_gpe, } return monitors
weightMatrix = get_matrix_from_file(weight_path + '../random/' + connName + ending + '.npy') model = 'w : 1' pre = 'g%s_post += w' % conn_type[0] post = '' if ee_STDP_on: if 'ee' in recurrent_conn_names: model += eqs_stdp_ee pre += '; ' + eqs_stdp_pre_ee post = eqs_stdp_post_ee connections[connName] = b2.Synapses(neuron_groups[connName[0:2]], neuron_groups[connName[2:4]], model=model, on_pre=pre, on_post=post) connections[connName].connect(True) # all-to-all connection connections[connName].w = weightMatrix[connections[connName].i, connections[connName].j] print 'create monitors for', name rate_monitors[name+'e'] = b2.PopulationRateMonitor(neuron_groups[name+'e']) rate_monitors[name+'i'] = b2.PopulationRateMonitor(neuron_groups[name+'i']) spike_counters[name+'e'] = b2.SpikeMonitor(neuron_groups[name+'e']) if record_spikes: spike_monitors[name+'e'] = b2.SpikeMonitor(neuron_groups[name+'e']) spike_monitors[name+'i'] = b2.SpikeMonitor(neuron_groups[name+'i']) #------------------------------------------------------------------------------ # create input population and connections from input populations #------------------------------------------------------------------------------ pop_values = [0,0,0] for i,name in enumerate(input_population_names): input_groups[name+'e'] = b2.PoissonGroup(n_input, 0*Hz) rate_monitors[name+'e'] = b2.PopulationRateMonitor(input_groups[name+'e'])
def simulate(): common_params = { # Parameters common to all neurons. 'C': 100 * b2.pfarad, 'tau_m': 10 * b2.ms, 'EL': -60 * b2.mV, 'DeltaT': 2 * b2.mV, 'Vreset': -65, # *b2.mV 'VTmean': -50 * b2.mV, 'VTsd': 2 * b2.mV } common_params['gL'] = common_params['C'] / common_params['tau_m'] E_cell_params = dict( common_params, **{ 'Ncells': num_E_cells, 'IXmean': 30 * b2.pA, 'IXsd': 20 * b2.pA }) eqs = Equations(""" Im = IX + gL * (EL - vm) + gL * DeltaT * exp((vm - VT) / DeltaT) - ge * (vm - Erev_e) - gi * (vm - Erev_i) - gx * (vm - Erev_x) : amp dgi/dt = (1*nsiemens-gi)/Tau_i - gi/Tau_i : siemens dgx/dt = (1*nsiemens-gx)/Tau_x - gx/Tau_x : siemens dge/dt = (1*nsiemens-ge)/Tau_e - ge/Tau_e : siemens VT : volt IX : amp dvm/dt = Im / C : volt """) param_E_syn = { "Erev_i": 0.0 * b2.mV, "Erev_x": 0.0 * b2.mV, "Erev_e": -80.0 * b2.mV, "Tau_i": 3.0 * b2.ms, "Tau_e": 4.0 * b2.ms, "Tau_x": 4.0 * b2.ms, "w_i": 0.6, # *b2.nsiemens, # Peak conductance # *b2.nsiemens, # Peak conductance (1 in paper) "w_x": 1.4, "w_e": 0.1, # *b2.nsiemens, # Peak conductance "p_i": 0.1, # ./I_cell_params['Ncells'], # ! 200 "p_e": 0.05, # /E_cell_params['Ncells'], # ! 400 } if state == "beta": param_E_syn['w_x'] = 0.55 * b2.nS param_E_syn['Tau_x'] = 12 * b2.ms param_E_syn['w_e'] = 0.05 * b2.nS param_E_syn['Tau_e'] = 12 * b2.ms param_E_syn['w_i'] = 0.1 * b2.nS param_E_syn['Tau_i'] = 15 * b2.ms E_cells = b2.NeuronGroup(E_cell_params['Ncells'], model=eqs, method=integration_method, threshold="vm > 0.*mV", reset="vm={}*mV".format(E_cell_params['Vreset']), refractory="vm > 0.*mV", namespace={ **common_params, **param_E_syn, }) # Poisson_to_E = b2.PoissonGroup( # E_cell_params['Ncells'], rates=input_rates()) # ! input_rates cEE = b2.Synapses(E_cells, E_cells, on_pre='ge+={}*nsiemens'.format(param_E_syn["w_e"])) # cEX = b2.Synapses(Poisson_to_E, # E_cells, # method=integration_method, # on_pre="gx += {}*nsiemens".format(param_E_syn["w_x"])) # cEX.connect(j='i') # Initialise random parameters. E_cells.VT = (randn(len(E_cells)) * E_cell_params['VTsd'] + E_cell_params['VTmean']) E_cells.IX = (randn(len(E_cells)) * E_cell_params['IXsd'] + E_cell_params['IXmean']) spike_monitor_E = b2.SpikeMonitor(E_cells) rate_monitor_E = b2.PopulationRateMonitor(E_cells) state_monitor_E = state_monitor_I = None if record_volrages: state_monitor_E = b2.StateMonitor(E_cells, "vm", record=True) state_monitor_I = b2.StateMonitor(I_cells, "vm", record=True) net = b2.Network(E_cells) if record_volrages: net.add(state_monitor_E) net.add(spike_monitor_E) net.add(rate_monitor_E) # net.add(cEX) # Randomise initial membrane potentials. E_cells.vm = randn(len(E_cells)) * 10 * b2.mV - 60 * b2.mV print('Simulation running...') start_time = time.time() b2.run(sim_duration * b2.ms) duration = time.time() - start_time print('Simulation time:', duration, 'seconds')
def build_populations(Model, POPULATIONS, AFFERENT_POPULATIONS=[], with_raster=False, with_pop_act=False, with_Vm=0, with_synaptic_currents=False, with_synaptic_conductances=False, NEURONS=None, verbose=False): """ sets up the neuronal populations and construct a network object containing everything """ ## NEURONS AND CONNECTIVITY MATRIX if NEURONS is None: NEURONS = [] for pop in POPULATIONS: NEURONS.append({'name': pop, 'N': Model['N_' + pop]}) ######################################################################## #### TO BE WRITTEN ######################################################################## NTWK = { 'NEURONS': NEURONS, 'Model': Model, 'POPULATIONS': np.array(POPULATIONS), 'AFFERENT_POPULATIONS': np.array(AFFERENT_POPULATIONS), 'M': get_syn_and_conn_matrix(Model, POPULATIONS, AFFERENT_POPULATIONS=AFFERENT_POPULATIONS, verbose=verbose) } NTWK['POPS'] = [] for ii, nrn in enumerate(NEURONS): neuron_params = built_up_neuron_params(Model, nrn['name'], N=nrn['N']) NTWK['POPS'].append( get_membrane_equation( neuron_params, NTWK['M'][:, ii], with_synaptic_currents=with_synaptic_currents, with_synaptic_conductances=with_synaptic_conductances, verbose=verbose)) nrn['params'] = neuron_params if with_pop_act: NTWK['POP_ACT'] = [] for pop in NTWK['POPS']: NTWK['POP_ACT'].append(brian2.PopulationRateMonitor(pop)) if with_raster: NTWK['RASTER'] = [] for pop in NTWK['POPS']: NTWK['RASTER'].append(brian2.SpikeMonitor(pop)) if with_Vm > 0: NTWK['VMS'] = [] for pop in NTWK['POPS']: NTWK['VMS'].append( brian2.StateMonitor(pop, 'V', record=np.arange(with_Vm))) if with_synaptic_currents: NTWK['ISYNe'], NTWK['ISYNi'] = [], [] for pop in NTWK['POPS']: NTWK['ISYNe'].append( brian2.StateMonitor(pop, 'Ie', record=np.arange(max([1, with_Vm])))) NTWK['ISYNi'].append( brian2.StateMonitor(pop, 'Ii', record=np.arange(max([1, with_Vm])))) if with_synaptic_conductances: NTWK['GSYNe'], NTWK['GSYNi'] = [], [] for pop in NTWK['POPS']: NTWK['GSYNe'].append( brian2.StateMonitor(pop, 'Ge', record=np.arange(max([1, with_Vm])))) NTWK['GSYNi'].append( brian2.StateMonitor(pop, 'Gi', record=np.arange(max([1, with_Vm])))) NTWK['PRE_SPIKES'], NTWK['PRE_SYNAPSES'] = [], [ ] # in case of afferent inputs return NTWK
def build_populations(Model, POPULATIONS, AFFERENT_POPULATIONS=[], with_Vm=2, verbose=False): """ sets up the neuronal populations and construct a network object containing everything: NTWK """ ## NEURONS AND CONNECTIVITY MATRIX NEURONS = [] for pop in POPULATIONS: NEURONS.append({'name': pop, 'N': Model['N_' + pop]}) NTWK = { 'NEURONS': NEURONS, 'Model': Model, 'POPULATIONS': np.array(POPULATIONS), 'M': get_syn_and_conn_matrix(Model, POPULATIONS, AFFERENT_POPULATIONS=AFFERENT_POPULATIONS, verbose=verbose) } ######################################################################## #### Setting up ######################################################################## NTWK['POPS'] = [] for ii, nrn in enumerate(NEURONS): neuron_params = built_up_neuron_params(Model, nrn['name'], N=nrn['N']) NTWK['POPS'].append( get_membrane_equation(neuron_params, NTWK['M'][:, ii], verbose=verbose)) nrn['params'] = neuron_params ######################################################################## #### Recordings ######################################################################## NTWK['POP_ACT'] = [] for pop in NTWK['POPS']: NTWK['POP_ACT'].append(brian2.PopulationRateMonitor(pop)) NTWK['RASTER'] = [] for pop in NTWK['POPS']: NTWK['RASTER'].append(brian2.SpikeMonitor(pop)) if with_Vm > 0: NTWK['VMS'] = [] for pop in NTWK['POPS']: NTWK['VMS'].append( brian2.StateMonitor(pop, 'V', record=np.arange(with_Vm))) NTWK['PRE_SPIKES'], NTWK['PRE_SYNAPSES'] = [], [ ] # for future afferent inputs return NTWK
def run_model( N=N, p=p, f=f, N_E=N_E, N_I=N_I, w_plus=w_plus, w_minus=w_minus, N_sub=N_sub, N_non=N_non, C_ext=C_ext, C_E=C_E, C_I=C_I, namespace=namespace, net=None, use_conductance=True, **namespace_kwargs # use for repeated simulations? ): """ Code taken primarily from https://brian2.readthedocs.io/en/stable/examples/frompapers.Brunel_Wang_2001.html """ if net is None: b2.start_scope() s_AMPA_initial_ext = namespace['rate_ext'] * C_ext * namespace[ 'tau_AMPA'] # update namespace with computed variables namespace['tau_m_E'] = namespace['C_m_E'] / namespace['g_m_E'] namespace['tau_m_I'] = namespace['C_m_I'] / namespace['g_m_I'] P_E = b2.NeuronGroup( N_E, eqs_conductance_E if use_conductance else eqs_current_E, threshold='v > V_thr', reset='v = V_reset', refractory='tau_rp_E', method='euler', name='P_E') P_E.v = namespace['V_L'] P_E.s_AMPA_ext = s_AMPA_initial_ext # estimated 4.8 P_I = b2.NeuronGroup( N_E, eqs_conductance_I if use_conductance else eqs_current_I, threshold='v > V_thr', reset='v = V_reset', refractory='tau_rp_I', method='euler', name='P_I') P_I.v = namespace['V_L'] P_I.s_AMPA_ext = s_AMPA_initial_ext C_E_E = b2.Synapses( P_E, P_E, model=eqs_glut, # equations for NMDA on_pre=eqs_pre_glut, on_post=eqs_post_glut, method='euler', name='C_E_E') C_E_E.connect('i != j') C_E_E.w[:] = 1.0 for pi in range(N_non, N_non + p * N_sub, N_sub): # internal other subpopulation to current nonselective # brian synapses are i->j C_E_E.w[C_E_E.indices[:, pi:pi + N_sub]] = w_minus # internal current subpopulation to current subpopulation C_E_E.w[C_E_E.indices[pi:pi + N_sub, pi:pi + N_sub]] = w_plus C_E_I = b2.Synapses(P_E, P_I, model=eqs_glut, on_pre=eqs_pre_glut, on_post=eqs_post_glut, method='euler', name='C_E_I') C_E_I.connect() C_E_I.w[:] = 1.0 C_I_I = b2.Synapses(P_I, P_I, on_pre=eqs_pre_gaba, method='euler', name='C_I_I') C_I_I.connect('i != j') C_I_E = b2.Synapses(P_I, P_E, on_pre=eqs_pre_gaba, method='euler', name='C_I_E') C_I_E.connect() C_P_E = b2.PoissonInput(P_E, target_var='s_AMPA_ext', N=C_ext, rate=namespace['rate_ext'], weight=1.) C_P_I = b2.PoissonInput(P_I, target_var='s_AMPA_ext', N=C_ext, rate=namespace['rate_ext'], weight=1.) # TODO: change the stimulus to match the task C_selection = int(f * C_ext) rate_selection = 25. * b2.Hz if 'stimulus1' not in namespace: stimtimestep = 25 * b2.ms stimtime = 1 stimuli1 = b2.TimedArray(np.r_[np.zeros(8), np.ones(stimtime), np.zeros(100)], dt=stimtimestep) namespace['stimuli1'] = stimuli1 input1 = b2.PoissonInput(P_E[N_non:N_non + N_sub], target_var='s_AMPA_ext', N=C_selection, rate=rate_selection, weight='stimuli1(t)') N_activity_plot = 15 # number of neurons to rasterplot # spike monitors sp_E_sels = [ b2.SpikeMonitor(P_E[pi:pi + N_activity_plot], name=f'sp_E_{int((pi-N_non)/N_sub) + 1}') for pi in range(N_non, N_non + p * N_sub, N_sub) ] sp_E = b2.SpikeMonitor(P_E[:N_activity_plot], name=f'sp_E_non') sp_I = b2.SpikeMonitor(P_I[:N_activity_plot], name=f'sp_I') # rate monitors r_E_sels = [ b2.PopulationRateMonitor(P_E[pi:pi + N_sub], name=f'r_E_{int((pi-N_non)/N_sub) + 1}') for pi in range(N_non, N_non + p * N_sub, N_sub) ] r_E = b2.PopulationRateMonitor(P_E[:N_non], name=f'r_E_non') r_I = b2.PopulationRateMonitor(P_I, name=f'r_I') # state monitors st_E_sels = [ b2.StateMonitor(P_E[pi:pi + N_activity_plot], variables=True, record=True, name=f'st_E_{int((pi-N_non)/N_sub) + 1}') for pi in range(N_non, N_non + p * N_sub, N_sub) ] st_E = b2.StateMonitor(P_E[:N_activity_plot], variables=True, record=True, name=f'st_E_non') st_I = b2.StateMonitor(P_I[:N_activity_plot], variables=True, record=True, name=f'st_I') net = b2.Network(b2.collect()) # add lists of monitors independently because # `b2.collect` doesn't search nested objects net.add(sp_E_sels) net.add(r_E_sels) net.add(st_E_sels) net.store('initialised') # runtime=runtime*b2.second net.restore('initialised') net.run(duration=runtime * b2.second, report='stdout', namespace=namespace) return net, namespace
def set_rate_monitor(self): """yep""" self.mon_rate_e = bb.PopulationRateMonitor(self.Pe) self.mon_rate_i = bb.PopulationRateMonitor(self.Pi) self.network.add(self.mon_rate_e, self.mon_rate_i)