def test_magic_scope(): ''' Check that `start_scope` works as expected. ''' G1 = NeuronGroup(1, 'v:1', name='G1') G2 = NeuronGroup(1, 'v:1', name='G2') objs1 = {obj.name for obj in collect()} start_scope() G3 = NeuronGroup(1, 'v:1', name='G3') G4 = NeuronGroup(1, 'v:1', name='G4') objs2 = {obj.name for obj in collect()} assert objs1=={'G1', 'G2'} assert objs2=={'G3', 'G4'}
def collect_and_run(NTWK, verbose=False, INTERMEDIATE_INSTRUCTIONS=[]): """ /!\ When you add a new object, THINK ABOUT ADDING IT TO THE COLLECTION ! /!\ """ NTWK['dt'], NTWK['tstop'] = NTWK['Model']['dt'], NTWK['Model']['tstop'] brian2.defaultclock.dt = NTWK['dt'] * brian2.ms net = brian2.Network(brian2.collect()) OBJECT_LIST = [] for key in [ 'POPS', 'REC_SYNAPSES', 'RASTER', 'POP_ACT', 'VMS', 'ISYNe', 'ISYNi', 'GSYNe', 'GSYNi', 'PRE_SPIKES', 'PRE_SYNAPSES' ]: if key in NTWK.keys(): net.add(NTWK[key]) if verbose: print('running simulation [...]') current_t = 0 for instrct in INTERMEDIATE_INSTRUCTIONS: # we run the simulation until that instruction tdur = instrct['time'] - current_t net.run(tdur * brian2.ms) # execute instruction: instrct['function'](NTWK) current_t = instrct['time'] net.run((NTWK['tstop'] - current_t) * brian2.ms) if verbose: print('-> done !') return net
def test_magic_collect(): ''' Make sure all expected objects are collected in a magic network ''' P = PoissonGroup(10, rates=100*Hz) G = NeuronGroup(10, 'v:1', threshold='False') S = Synapses(G, G, '') state_mon = StateMonitor(G, 'v', record=True) spike_mon = SpikeMonitor(G) rate_mon = PopulationRateMonitor(G) objects = collect() assert len(objects) == 6, ('expected %d objects, got %d' % (6, len(objects)))
def test_magic_collect(): ''' Make sure all expected objects are collected in a magic network ''' P = PoissonGroup(10, rates=100*Hz) G = NeuronGroup(10, 'v:1') S = Synapses(G, G, '') G_runner = G.custom_operation('') S_runner = S.custom_operation('') state_mon = StateMonitor(G, 'v', record=True) spike_mon = SpikeMonitor(G) rate_mon = PopulationRateMonitor(G) objects = collect() assert len(objects) == 8, ('expected %d objects, got %d' % (8, len(objects)))
def test_magic_collect(): ''' Make sure all expected objects are collected in a magic network ''' P = PoissonGroup(10, rates=100 * Hz) G = NeuronGroup(10, 'v:1') S = Synapses(G, G, '') G_runner = G.custom_operation('') S_runner = S.custom_operation('') state_mon = StateMonitor(G, 'v', record=True) spike_mon = SpikeMonitor(G) rate_mon = PopulationRateMonitor(G) objects = collect() assert len(objects) == 8, ('expected %d objects, got %d' % (8, len(objects)))
def collect_and_run(NTWK, verbose=False): """ collecting all the Brian2 objects and running the simulation """ NTWK['dt'], NTWK['tstop'] = NTWK['Model']['dt'], NTWK['Model']['tstop'] brian2.defaultclock.dt = NTWK['dt'] * brian2.ms net = brian2.Network(brian2.collect()) OBJECT_LIST = [] for key in [ 'POPS', 'REC_SYNAPSES', 'RASTER', 'POP_ACT', 'VMS', 'PRE_SPIKES', 'PRE_SYNAPSES' ]: if key in NTWK.keys(): net.add(NTWK[key]) print('running simulation [...]') net.run(NTWK['tstop'] * brian2.ms) return net
def simulate(runtime=0.5*b2.second, N=1): b2.start_scope() namespace['sigma'] = 2 * b2.mV namespace['tau_m_E'] = namespace['C_m_E'] / namespace['g_m_E'] # I_1 = -2*b2.namp # I_2 = -20*b2.namp I_1 = namespace['g_m_E'] * (namespace['V_L'] - (2.5*b2.mV + namespace['V_thr'])) I_2 = namespace['g_m_E'] * (namespace['V_L'] - (-2.5*b2.mV + namespace['V_thr'])) eqn = """ dV/dt = (- g_m_E * (V - V_L) - I) / C_m_E + sigma*xi*tau_m_E**-0.5: volt (unless refractory) I : amp """ N1 = b2.NeuronGroup( N, eqn, threshold='V>V_thr', reset='V = V_reset', refractory=namespace['tau_rp_E'], method='euler') N1.V = namespace['V_reset'] N1.I = I_1 N2 = b2.NeuronGroup( N, eqn, threshold='V>V_thr', reset='V = V_reset', refractory=namespace['tau_rp_E'], method='euler') N2.V = namespace['V_reset'] N2.I = I_2 st1 = b2.StateMonitor(N1, variables='V', record=True, name='st1') st2 = b2.StateMonitor(N2, variables='V', record=True, name='st2') sp1 = b2.SpikeMonitor(N1, name='sp1') sp2 = b2.SpikeMonitor(N2, name='sp2') net = b2.Network(b2.collect()) net.run(runtime, namespace=namespace, report='stdout') return net
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, coherence=0.2, stim_on=100 * b2.ms, stim_off=900 * b2.ms, runtime=2 * b2.second, **namespace_kwargs # use for repeated simulations? ): 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_input = C_ext increment1 = 0.05 * (1 + coherence) * namespace['rate_ext'] increment2 = 0.05 * (1 - coherence) * namespace['rate_ext'] sigma_rate = 0.05 * namespace['rate_ext'] input1 = b2.PoissonGroup(N_input, rates=0. * b2.Hz) input1_syn = b2.Synapses(input1, P_E[N_non:N_non + N_sub], model='', on_pre='s_AMPA_ext_post += 1') input1_syn.connect() input2 = b2.PoissonGroup(N_input, rates=0. * b2.Hz) input2_syn = b2.Synapses(input2, P_E[N_non + N_sub:N_non + 2 * N_sub], model='', on_pre='s_AMPA_ext_post += 1') input2_syn.connect() @b2.network_operation(dt=50 * b2.ms, when='start') def update_inputs(t): if t < stim_on or t >= stim_off: input1.rates = 0. * b2.Hz input2.rates = 0. * b2.Hz else: input1.rates = (np.random.randn() * sigma_rate + increment1) # input1.rates = increment1 input2.rates = (np.random.randn() * sigma_rate + increment2) # input2.rates = increment2 # ri1 = b2.PopulationRateMonitor(input1_syn, name='ri1') # ri2 = b2.PopulationRateMonitor(input2_syn, name='ri2') r0 = b2.PopulationRateMonitor(P_E[:N_non], name='r0') r1 = b2.PopulationRateMonitor(P_E[N_non:N_non + N_sub], name='r1') r2 = b2.PopulationRateMonitor(P_E[N_non + N_sub:N_non + 2 * N_sub], name='r2') rI = b2.PopulationRateMonitor(P_I, name='rI') net = b2.Network(b2.collect()) net.store('initialised') net.restore('initialised') net.run(duration=runtime, report='stdout', namespace=namespace) return net
eqs_synapses, on_pre='ge += w\n' + on_pre, on_post=on_post) synapse_mu.connect() synapse_mu.w = 'rand() * w_max' # for i in range(N_out): synapse_mu.mu = f'(j / {float(N_out)})' mon = b2.StateMonitor(synapse_mu, 'w', record=[0, 1]) mu_vals = np.array(synapse_mu.mu) # print(mu_vals.shape) # b2.plot(mu_vals[synapse_mu.i == 0]) # b2.show() net = b2.Network(b2.collect()) net.store('initialised') # not used... net.run(100 * b2.second, report='stdout') b2.plot(mon.t / b2.second, mon.w.T / w_max) b2.show() weights_rates = b2.array(synapse_rates.w) rates_weight_histograms = b2.empty((N_bins, N_out)) for i in range(N_out): # brian2 uses i->j synapse syntax, while I use j->i mask = synapse_rates.j == i rates_weight_histograms[:, i] = np.histogram(weights_rates[mask] / w_max, bins=N_bins,
S1.connect(j='i') # one-to-one S1.w[:] = 1 S2 = Synapses(EXT2, P_E, model='w : 1', on_pre='s_ext2 += w', method='euler') S2.connect(j='i') # one-to-one S2.w[:] = 0 # ============================================================================= # ============================================================================= M = StateMonitor(P_E, ('v_soma', 'v_dend1', 'v_dend2'), record=True) # SIMULATION RUNNING net = Network(collect()) net.add(M) net.run(simtime, report='stdout') # ============================================================================= # A N A L Y S I S o f t h e S I M U L A T I O N # ============================================================================= plt.figure(1) plt.plot(M.t/ms, M[0].v_soma, label='soma') plt.plot(M.t/ms, M[0].v_dend1, label='dend1') plt.plot(M.t/ms, M[0].v_dend2, label='dend2') plt.xlabel("Time [ms]") plt.ylabel("Voltage [mV]") plt.legend(['soma', 'dendrite 1', 'dendrite 2'])
dv/dt = -sign(v)*v0/tau0 : volt (unless refractory) ''' eq1 = ''' dv/dt=v0/tau : volt (unless refractory) ''' v0 = 1 * brian2.mvolt tau = 1 * brian2.second tau0 = 5 * brian2.second neuron1 = brian2.NeuronGroup(1, eq1, threshold='v>0.01*v0', reset='v=0*v0', refractory=15 * brian2.ms, method='euler') neuron2 = brian2.NeuronGroup(1, eq2, threshold='abs(v)>0.02*v0', reset='v=0*v0', refractory=20 * brian2.ms, method='euler') #S = brian2.Synapses(neuron1, neuron2, on_pre='v_post+=0.01*v0') S = brian2.Synapses(neuron1, neuron2, on_pre='v_post-=0.01*v0') S.connect(j='i') M1 = brian2.StateMonitor(neuron1, 'v', record=True) M2 = brian2.StateMonitor(neuron2, 'v', record=True) network = brian2.Network(brian2.collect()) network.add(M1, M2) network.run(500 * brian2.ms) plt.plot(M2.t / brian2.ms, M2.v[0]) plt.plot(M1.t / brian2.ms, M1.v[0]) plt.show()
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