def set_group_spike_monitor(self, ch=0): """ !!! this would not work with random assemblies to be removed in the future """ self.mon_spike_sngl = [ ] # measure spike times from a few single neurons for nrn in self.nrn_meas_e: self.mon_spike_sngl.append(bb.SpikeMonitor(self.Pe[nrn])) self.network.add(self.mon_spike_sngl) self.mon_spike_gr = [ ] # measure spike times from groups (for CV and FF) for gr in self.nrngrp_meas: self.mon_spike_gr.append( bb.SpikeMonitor(self.p_ass[ch][gr][0:self.n_spikeM_gr])) # also control group of neurons which is not included in the ps self.mon_spike_gr.append(bb.SpikeMonitor(\ self.Pe[self.n_ass*self.s_ass:(self.n_ass+1)*self.s_ass] [0:self.n_spikeM_gr])) self.network.add(self.mon_spike_gr) # default spike easure is off for sp in self.mon_spike_gr: sp.record = False
def SpikeMonitor(neuron_groups, index_str): index_a, index_b, index_aux = _neuron_group_index(index_str) if index_b == None and index_aux == None: S = br.SpikeMonitor(neuron_groups[index_a], record=0) elif index_a == 2: S = br.SpikeMonitor(neuron_groups[index_a][index_aux], record=0) elif index_b != None: S = br.SpikeMonitor(neuron_groups[index_a][index_b], record=0) return S
def main4(plot=True): # what if we want to keep the input spike exactly the same throughout different taus? # Solution: We run PoissonGroup once, store all the spikes, and use the stored spikes across the multiple runs bs.start_scope() num_inputs = 100 input_rate = 10 * bs.Hz w = 0.1 tau_range = bs.linspace(1, 10, 30) * bs.ms output_rates = [] P = bs.PoissonGroup(num_inputs, rates=input_rate) p_monitor = bs.SpikeMonitor(P) one_second = 1 * bs.second """ Note that in the code above, we created Network objects. The reason is that in the loop, if we just called run it would try to simulate all the objects, including the Poisson neurons P, and we only want to run that once. We use Network to specify explicitly which objects we want to include. """ net = bs.Network(P, p_monitor) net.run(one_second) # keeps a copy of the spikes that are generated by the PoissonGroup during that explicit run earlier spikes_i = p_monitor.i spikes_t = p_monitor.t # Construct network that we run each time sgg = bs.SpikeGeneratorGroup(num_inputs, spikes_i, spikes_t) eqs = ''' dv/dt = -v/tau : 1 ''' G = bs.NeuronGroup(1, eqs, threshold='v>1', reset='v=0', method='exact') S = bs.Synapses(sgg, G, on_pre='v += w') S.connect() # fully connected network g_monitor = bs.SpikeMonitor(G) # store the current state of the network net = bs.Network(sgg, G, S, g_monitor) net.store() for tau in tau_range: net.restore() net.run(one_second) output_rates.append(g_monitor.num_spikes / bs.second) if plot: plt.clf() plt.plot(tau_range / bs.ms, output_rates) plt.xlabel(r'$\tau$ (ms)') plt.ylabel('Firing Rate (spikes/s)') # there is much less noise compared to before where we used different PoissonGroup everytime plt.show()
def make_classification_network(self, number_of_stimuli, network_name): if network_name not in self.networks: network_size = number_of_stimuli * self.number_of_neurons count_mat = np.zeros((int(self.stimulus_duration / ms * 10), network_size), int) target = b2.NeuronGroup(N=number_of_stimuli, model=self.eqs, threshold='v>threshold', reset='v=0', namespace={'tau': self.tau, 'threshold': self.threshold}) driving = b2.SpikeGeneratorGroup(N=network_size, indices=[0], times=[0 * ms]) # counts = b2.TimedArray(values=_count_mat, dt=b2.defaultclock.dt) synapses = b2.Synapses(source=driving, target=target, model='w: 1', on_pre='v+=w*counts(t, i)') i = np.arange(network_size) j = np.repeat(range(number_of_stimuli), self.number_of_neurons) synapses.connect(j=j, i=i) synapses.w = np.tile(self.weights, reps=number_of_stimuli) spikes = b2.SpikeMonitor(target, record=True) voltage = b2.StateMonitor(target, 'v', record=True) net = b2.Network([target, driving, synapses, spikes, voltage]) net.store() self.networks[network_name] = dict(net=net, count_mat=count_mat, synapses=synapses, v_mon=voltage, spike_mon=spikes, number_of_stimuli=number_of_stimuli, driving=driving) else: self.networks[network_name]['synapses'].w = np.tile(self.weights, reps=number_of_stimuli)
def simulate_LIF_neuron(input_current, simulation_time=5. * b2.ms, dt=0.01, v_rest=-70 * b2.mV, v_reset=-65 * b2.mV, firing_threshold=-50 * b2.mV, membrane_resistance=10. * b2.Mohm, membrane_time_scale=8. * b2.ms, abs_refractory_period=2.0 * b2.ms): b2.defaultclock.dt = dt * b2.ms # differential equation of Leaky Integrate-and-Fire model # eqs = """ # dv/dt = # ( -(v-v_rest) + membrane_resistance * input_current(t,i) ) / membrane_time_scale : volt (unless refractory) # """ eqs = """ dv/dt = ( -(v-v_rest) + membrane_resistance * input_current ) / membrane_time_scale : volt (unless refractory) """ neuron = b2.NeuronGroup(1, model=eqs, reset="v=v_reset", threshold="v>firing_threshold", refractory=abs_refractory_period, method="exact") # "euler" / "exact" neuron.v = v_rest # set initial value network = b2.core.network.Network(neuron) # run before for compiling (JIT compile time out of timing) #network.run(simulation_time, profile=True) spike_monitor = b2.SpikeMonitor(neuron) network.add(spike_monitor) neuron.v = v_rest #start_wallclock = time.time() #start_cpu = time.clock() # timer() network.run(simulation_time, profile=True) #end_cpu = time.clock() # timer() #end_wallclock = time.time() #time_elapsed_wallclock = end_wallclock - start_wallclock #time_elapsed_cpu = end_cpu - start_cpu b2.device.build(directory='output', clean=True, compile=True, run=True, debug=False) print("\n") print("brian2 profiling summary (listed by time consumption):\n") print(b2.profiling_summary()) return spike_monitor, network.get_profiling_info( ) # time_elapsed_wallclock, time_elapsed_cpu,
def calculate_input_seqs(self): """ Calculating input sequence based on the video input. """ b2.set_device('cpp_standalone', directory=os.path.join( self.output_folder, 'Input_cpp_run' + self.output_file_suffix)) # inputdt = b2.defaultclock.dt spikemons = [] n0 = len(self.i_patterns[0].T) frames = self.frames factor = self.factor # tmp_group = b2.NeuronGroup(n0, 'rate = frames(t,i)*factor : Hz', threshold='b2.rand()<rate*dt') tmp_group = b2.NeuronGroup(n0, 'rate = frames(t,i)*factor : Hz', threshold='rand()<rate*dt') tmp_network = b2.Network() tmp_network.add(tmp_group) tmp_mon = b2.SpikeMonitor(tmp_group) tmp_network.add(tmp_mon) spikemons.append(tmp_mon) if self.BaseLine == 0 * second: tmp_network.run(self.duration, report='text') else: tmp_network.run(self.BaseLine) tmp_network.run(self.duration - self.BaseLine) self.save_input_sequence( spikemons, os.path.join(self.output_folder, 'input' + self.output_file_suffix)) shutil.rmtree( os.path.join(self.output_folder, 'Input_cpp_run' + self.output_file_suffix))
def brian_poisson(rate, duration_ms, dt=1 * ms, n=1): """ :param rate: :param duration_ms: :param dt: :param n: :return: """ q = b2.units.fundamentalunits.Quantity if not isinstance(rate, q): if np.isscalar(rate): rate = rate * Hz else: rate = np.array(rate) * Hz if not isinstance(duration_ms, q): if np.isscalar(duration_ms): duration_ms = duration_ms * ms else: duration_ms = np.array(duration_ms) * ms neuron = b2.NeuronGroup(n, "rate : Hz", threshold='rand()<rate*dt', dt=dt) neuron.rate = rate spikes = b2.SpikeMonitor(neuron, record=True) b2.run(duration_ms) if n == 1: trains = spikes.spike_trains()[0] / dt else: trains = [train / dt for train in spikes.spike_trains().values()] return trains
def main3(): # Adding Spikes bs.start_scope() tau = 10 * bs.ms eqs = ''' dv/dt = (1-v)/tau : 1 ''' # conditions for spiking models threshold = 'v>0.8' reset = 'v = -0.8' G = bs.NeuronGroup(1, eqs, threshold=threshold, reset=reset, method='exact') M = bs.StateMonitor(G, 'v', record=0) bs.run(50 * bs.ms) plt.plot(M.t / bs.ms, M.v[0]) plt.xlabel('Time (ms)') plt.ylabel('v') plt.show() # you can also add spike monitor spike_monitor = bs.SpikeMonitor(G) bs.run(50 * bs.ms) print(f"Spike Times: {spike_monitor.t[:]}")
def simulate(tau): b2.start_scope() if standalone_mode: b2.get_device().reinit() b2.get_device().activate(build_on_run=False, directory=directory_name) net = b2.Network() P = b2.PoissonGroup(num_inputs, rates=input_rate) G = b2.NeuronGroup(1, eqs, threshold='v>1', reset='v=0', method='euler') S = b2.Synapses(P, G, on_pre='v += weight') S.connect() M = b2.SpikeMonitor(G) net.add(P) net.add(G) net.add(S) net.add(M) net.run(1000 * b2.ms) if standalone_mode: b2.get_device().build(directory=directory_name, compile=True, run=True, debug=False) return M
def main4(): # Incorporation of refractory period bs.start_scope() tau = 10 * bs.ms # the (unless refractory) is necessary # refer to the documentation for more detail eqs = ''' dv/dt = (1-v)/tau : 1 (unless refractory) ''' equation = bs.Equations(eqs) # conditions for spiking models threshold = 'v>0.8' reset = 'v = -0.8' refractory = 5 * bs.ms G = bs.NeuronGroup(1, eqs, threshold=threshold, reset=reset, method='exact', refractory=refractory) state_monitor = bs.StateMonitor(G, 'v', record=0) spike_monitor = bs.SpikeMonitor(G) bs.run(50 * bs.ms) plt.plot(state_monitor.t / bs.ms, state_monitor.v[0]) plt.xlabel('Time (ms)') plt.ylabel('v') plt.show()
def AllSpikeMonitors(neuron_groups, spike_monitor_names): N = len(neuron_groups) spike_monitors = [] spike_monitors.append( br.SpikeMonitor(neuron_groups[0], name=spike_monitor_names[0])) spike_monitors.append( br.SpikeMonitor(neuron_groups[1][0], name=spike_monitor_names[1])) #spike_monitors.append([]) #for i in range(len(neuron_groups[2])): # spike_monitors[2].append(br.SpikeMonitor(neuron_groups[2][i], \ # record=0, name=spike_monitor_names[2][i])) spike_monitors.append( br.SpikeMonitor(neuron_groups[2], name=spike_monitor_names[2])) return spike_monitors
def plot_fi_curve(self, min_current=0 * pA, max_current=1 * nA, step_size=10 * pA, max_rate=None, plot=True): # Compute current steps steps = np.arange(min_current, max_current, step_size) * amp N_steps = len(steps) # Prepare params and eqs neuron_parameters = self.neuron_parameters refractory_period = neuron_parameters['refractory_period'] eqs = self.get_membrane_equation(substitute_ad_hoc={ 'EXT_CURRENTS': '+ I_ext', 'EXT_CURRENTS_EQS': 'I_ext : amp' }) # Create a neuron group neurons = b2.NeuronGroup(N_steps, model=eqs, namespace=neuron_parameters, reset=self.reset_statements, threshold=self.threshold_condition, refractory=refractory_period, method=self.integration_method) # Set initial values initial_values = self.get_initial_values() neurons.set_states(initial_values) neurons.I_ext = 0 * pA # Set what to monitor #state_monitor = b2.StateMonitor(neurons, self.get_states_to_monitor(), record=True) spike_monitor = b2.SpikeMonitor(neurons) # Run the simulation net = b2.Network(neurons, spike_monitor) net.run(500 * ms) # Add step current neurons.I_ext = steps net.run(1000 * ms) counts = spike_monitor.count # Plot/return the f-I curve if plot is True: plt.plot(steps / pA, counts) plt.title('f-I curve') plt.ylabel('Firing rate [Hz]') plt.xlabel('Current [pA]') if max_rate is not None: plt.ylim([0, max_rate]) plt.show() else: return counts
def make_model(self): # Determine the simulation if self.clamp_type == 'current': eqs_input = '''I_inj = inj_input(t) : amp''' elif self.clamp_type == 'dynamic': eqs_input = '''I_exc = g_exc(t) * (Er_e - v) : amp I_inh = g_inh(t) * (Er_i - v) : amp I_inj = I_exc + I_inh : amp''' tracking = ['v', 'I_inj'] # Model the neuron with differential equations eqs = ''' # Activation gates Na channel m = 1. / (1. + exp(-(v - Vh) / k)) : 1 Vh = 3.223725 * k - 62.615488*mV : volt # Inactivation gates Na channel dh/dt = 5. * (alpha_h * (1 - h)- beta_h * h) : 1 alpha_h = 0.07 * exp(-(v + 58.*mV) / (20.*mV))/ms : Hz beta_h = 1. / (exp(-0.1/mV * (v + 28.*mV)) + 1.)/ms : Hz # Activation gates K channel dn/dt = 5. * (alpha_n * (1. - n) - beta_n * n) : 1 alpha_n = 0.01/mV * 10*mV / exprel(-(v + 34.*mV) / (10.*mV))/ms : Hz beta_n = 0.125 * exp(-(v + 44.*mV) / (80.*mV))/ms : Hz # Activation gates K3.1 channel dn3/dt = alphan3 * (1. - n3) - betan3 * n3 : 1 alphan3 = (1. / exp(((param * ((-0.029 * v + (1.9*mV))/mV)))))/ms : Hz betan3 = (1. / exp(((param * ((0.021 * v + (1.1*mV))/mV)))))/ms : Hz # Currents I_leak = -gL * (v - EL) : amp I_Na = -gNa * m**3 * h * (v - ENa) : amp I_K = -gK * n**4 * (v - EK) : amp I_K3 = -gK3 * n3**4 * (v - EK) : amp dv/dt = (I_leak + I_Na + I_K + I_K3 + I_inj) / Cm : volt ''' # Neuron & parameter initialization neuron = b2.NeuronGroup(1, model=eqs + eqs_input, method='exponential_euler', threshold='m > 0.5', refractory=2 * b2.ms, reset=None, dt=self.dt * b2.ms) neuron.v = -65 * b2.mV # Track the parameters during simulation self.M = b2.StateMonitor(neuron, tracking, record=True) self.S = b2.SpikeMonitor(neuron, record=True) self.neuron = neuron net = b2.Network(neuron) net.add(self.M, self.S) self.network = net
def run(TSTOP=250, group_size=100, g_time=150, neuron_n=1000, linear=True, ext_w=0.2, inh_w=0.2): """Run a simulation and return the resulting spiketrain""" # Basic equation of the model eq = """dv/dt = -gamma*v + I0 : volt Ie : volt Ii : volt """ thetaU = 16 * mV tauM = 8 * ms gamma = 1 / tauM I0 = 17.6 * mV / tauM #Build the group of neuron to use G = br2.NeuronGroup(neuron_n, threshold="v>thetaU", reset="v=0*mV", method='euler', model=eq) #Record the spikes from this group spikes = br2.SpikeMonitor(G) #Build stimulation stim = br2.SpikeGeneratorGroup(1, [0], [g_time]*ms - br2.defaultclock.dt) stim_syn = br2.Synapses(stim, G, on_pre="v += 2*thetaU") stim_syn.connect(i=0, j=np.arange(group_size)) br2.magic_network.schedule = ['start', 'groups', 'synapses', 'thresholds', 'resets', 'end'] connections = np.random.rand(1000, 1000) < 0.3 exc_or_inh = np.random.rand(1000, 1000) < 0.5 exc_i, exc_j = (connections & exc_or_inh).nonzero() inh_i, inh_j = (connections & ~exc_or_inh).nonzero() if linear: G.run_regularly(''' v += Ie + Ii Ie = 0*mV Ii = 0*mV ''', when='after_synapses') else: G.run_regularly(''' v += clip(Ie, 0*mV, 2*mV) + clip(2*(Ie-2*mV), 0*mV, 4*mV) + Ii Ie = 0*mV Ii = 0*mV ''', when='after_synapses') dt = br2.defaultclock.dt exc_syn = br2.Synapses(G, G, on_pre='Ie += %s*mV' % (ext_w), delay=5*ms-dt) inh_syn = br2.Synapses(G, G, on_pre='Ii -= %s*mV' % (inh_w), delay=5*ms-dt) exc_syn.connect(i=exc_i, j=exc_j) inh_syn.connect(i=inh_i, j=inh_j) #Set random initial conditions G.v = np.random.rand(neuron_n) * 16 * mV br2.run(TSTOP * ms) return spikes
def current_pulse_sim_with_opto(args, params=None): if params is None: params = get_neuron_params(args['NRN']) params['Vclamp'] = -80 neurons, eqs = get_membrane_equation(params, [],\ return_equations=True) if args['verbose']: print(eqs) fig, ax = brian2.subplots(figsize=(5,3)) # V value initialization neurons.V = params['El']*brian2.mV trace = brian2.StateMonitor(neurons, 'V', record=0) spikes = brian2.SpikeMonitor(neurons) # rest run brian2.run(args['delay'] * brian2.ms) # first pulse neurons.I0 = args['amp']*brian2.pA brian2.run(args['duration']/3. * brian2.ms) neurons.Gclamp = 1e3*brian2.nS brian2.run(args['duration']/3. * brian2.ms) neurons.Gclamp = 0*brian2.nS brian2.run(args['duration']/3. * brian2.ms) # second pulse neurons.I0 = 0 brian2.run(args['delay'] * brian2.ms) # We draw nicer spikes Vm = trace[0].V[:] for t in spikes.t: ax.plot(t/brian2.ms*np.ones(2), [Vm[int(t/brian2.defaultclock.dt)]/brian2.mV,-10], '--', color=args['color']) ax.plot(trace.t / brian2.ms, Vm / brian2.mV, color=args['color']) if 'NRN' in args.keys(): ax.set_title(args['NRN']) ax.annotate(str(int(params['El']))+'mV', (-50,params['El']-5)) ax.plot([-20], [params['El']], 'k>') ax.plot([0,50], [-50, -50], 'k-', lw=4) ax.plot([0,0], [-50, -40], 'k-', lw=4) ax.annotate('10mV', (-50,-38)) ax.annotate('50ms', (0,-55)) # set_plot(ax, [], xticks=[], yticks=[]) # show() if 'save' in args.keys(): fig.savefig(args['save']) return fig
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 main1(): bs.start_scope() # Parameters area = 20000 * bs.umetre**2 Cm = 1 * bs.ufarad * bs.cm**-2 * area gl = 5e-5 * bs.siemens * bs.cm**-2 * area El = -65 * bs.mV EK = -90 * bs.mV ENa = 50 * bs.mV g_na = 100 * bs.msiemens * bs.cm**-2 * area g_kd = 30 * bs.msiemens * bs.cm**-2 * area VT = -63 * bs.mV # HH stands for Hudgkin-Huxley eqs_HH = ''' dv/dt = (gl*(El-v) - g_na*(m*m*m)*h*(v-ENa) - g_kd*(n*n*n*n)*(v-EK) + I)/Cm : volt dm/dt = 0.32*(mV**-1)*(13.*mV-v+VT)/ (exp((13.*mV-v+VT)/(4.*mV))-1.)/ms*(1-m)-0.28*(mV**-1)*(v-VT-40.*mV)/ (exp((v-VT-40.*mV)/(5.*mV))-1.)/ms*m : 1 dn/dt = 0.032*(mV**-1)*(15.*mV-v+VT)/ (exp((15.*mV-v+VT)/(5.*mV))-1.)/ms*(1.-n)-.5*exp((10.*mV-v+VT)/(40.*mV))/ms*n : 1 dh/dt = 0.128*exp((17.*mV-v+VT)/(18.*mV))/ms*(1.-h)-4./(1+exp((40.*mV-v+VT)/(5.*mV)))/ms*h : 1 I : amp ''' group = bs.NeuronGroup(1, eqs_HH, threshold='v > -40*mV', refractory='v > -40*mV', method='exponential_euler') group.v = El state_monitor = bs.StateMonitor(group, 'v', record=True) spike_monitor = bs.SpikeMonitor(group, variables='v') plt.figure(figsize=(9, 4)) for l in range(5): group.I = bs.rand() * 50 * bs.nA bs.run(10 * bs.ms) bs.axvline(l * 10, ls='--', c='k') bs.axhline(El / bs.mV, ls='-', c='lightgray', lw=3) state_time = state_monitor.t spike_time = spike_monitor.t plt.plot(state_time / bs.ms, spike_monitor.v[0] / bs.mV, '-b') plt.plot(spike_time / bs.ms, spike_monitor.v / bs.mV, 'ob') plt.xlabel('Time (ms)') plt.ylabel('v (mV)') plt.show()
def _create_device(self, group, variable): """Create a Brian2 recording device.""" # Brian2 records in the 'start' scheduling slot by default if variable == 'spikes': self._devices[variable] = brian2.SpikeMonitor(group, record=self.recorded) else: varname = self.population.celltype.state_variable_translations[variable]['translated_name'] neurons_to_record = np.sort(np.fromiter( self.recorded[variable], dtype=int)) - self.population.first_id self._devices[variable] = brian2.StateMonitor(group, varname, record=neurons_to_record, when='end', dt=self.sampling_interval * ms) simulator.state.network.add(self._devices[variable])
def simulate_neuron(self, I_stim=input_factory.get_zero_current(), simulation_time=1000 * ms, **kwargs): """ Simulate/stimulate the neuron :param I_stim: input stimulus (use the input_factory to create the stimulus) :param simulation_time: duration (usually in milliseconds, eg. 3000*ms) :param kwargs: custom neuron parameters can be given as arguments :return: b2.StateMonitor, b2.SpikeMonitor """ neuron_parameters = dict( self.neuron_parameters ) # Make a copy of parameters; otherwise will change object params neuron_parameters.update(kwargs) refractory_period = neuron_parameters['refractory_period'] stim_string = '+ I_stim(t,i)' old_model_defns = dict(self.full_model_defns) self.add_model_definition('EXT_CURRENTS', stim_string) eqs = self.get_membrane_equation() self.full_model_defns = old_model_defns # Create a neuron group neuron = b2.NeuronGroup(1, model=eqs, namespace=neuron_parameters, reset=self.reset_statements, threshold=self.threshold_condition, refractory=refractory_period, method=self.integration_method) # Set initial values initial_values = self.get_initial_values() neuron.set_states(initial_values) # Set what to monitor state_monitor = b2.StateMonitor(neuron, self.get_states_to_monitor(), record=True) spike_monitor = b2.SpikeMonitor(neuron) # Run the simulation net = b2.Network(neuron, state_monitor, spike_monitor) net.run(simulation_time) return state_monitor, spike_monitor
def simulate(self, current=input_factory.get_zero_current(), time=10 * b2.ms, rheo_threshold=None, v_rest=None, v_reset=None, delta_t=None, time_scale=None, resistance=None, threshold=None, adapt_volt_c=None, adapt_tau=None, adapt_incr=None): if (v_rest == None): v_rest = self.rest_pot if (v_reset == None): v_reset = self.reset_pot if (rheo_threshold == None): rheo_threshold = self.rheo_threshold if (delta_t == None): delta_t = self.delta_t if (time_scale == None): time_scale = self.time_scale if (resistance == None): resistance = self.resistance if (threshold == None): threshold = self.threshold if (adapt_volt_c == None): adapt_volt_c = self.adapt_volt_c if (adapt_tau == None): adapt_tau = self.adapt_tau if (adapt_incr == None): adapt_incr = self.adapt_incr v_spike_str = "v>{:f}*mvolt".format(threshold / b2.mvolt) eqs = """ dv/dt = (-(v-v_rest) +delta_t*exp((v-rheo_threshold)/delta_t)+ resistance * current(t,i) - resistance * w)/(time_scale) : volt dw/dt=(adapt_volt_c*(v-v_rest)-w)/adapt_tau : amp """ neuron = b2.NeuronGroup(1, model=eqs, threshold=v_spike_str, reset="v=v_reset;w+=adapt_incr", method="euler") neuron.v = v_rest neuron.w = 0.0 * b2.pA state_monitor = b2.StateMonitor(neuron, ["v", "w"], record=True) spike_monitor = b2.SpikeMonitor(neuron) b2.run(time) return state_monitor, spike_monitor
def __init__(self, xmax, ymax, rmax, dvsSignal): self.xmax = xmax self.ymax = ymax self.rmax = rmax #self.rmin = 2 self.dvsSignal = dvsSignal self.v_update = 0.5 * brian2.mvolt self.group = snn.snn(self.xmax, self.ymax, self.rmax) self.network_op = brian2.NetworkOperation(self.update_func, dt=100 * brian2.ms) #self.synapses = snn.inhibition(self.group) self.spikeM = brian2.SpikeMonitor(self.group) self.network = brian2.Network(self.group, self.network_op, self.spikeM) #, self.synapses)
def main6(): # neurons with parameters n_neurons = 100 tau = 10 * bs.ms v0_max = 3.0 duration = 1000 * bs.ms # v0: 1 declares a new per-neuron parameter v0 eqs = """ dv/dt = (v0-v)/tau: 1 (unless refractory) v0 : 1 """ # conditions for spiking models threshold = 'v>1' reset = 'v = 0' refractory = 5 * bs.ms G = bs.NeuronGroup(N=n_neurons, model=eqs, threshold=threshold, reset=reset, method='exact', refractory=refractory) state_monitor = bs.StateMonitor(G, 'v', record=True) spike_monitor = bs.SpikeMonitor(G) """ The line G.v0 = 'i*v0_max/(N-1)' initialises the value of v0 for each neuron varying from 0 up to v0_max. The symbol i when it appears in strings like this refers to the neuron index. """ G.v0 = 'i*v0_max/(N-1)' bs.run(duration=duration) plt.figure(figsize=(12, 4)) plt.subplot(121) plt.plot(spike_monitor.t / bs.ms, spike_monitor.i, '.k') plt.xlabel('Time (ms)') plt.ylabel('Neuron index') plt.subplot(122) plt.plot(G.v0, spike_monitor.count / duration) plt.xlabel('v0') plt.ylabel('Firing rate (sp/s)') plt.show() plt.clf() # plt.plot(state_monitor.t / bs.ms, state_monitor.v[0]) # plt.plot(state_monitor.t / bs.ms, state_monitor.v[10]) # plt.plot(state_monitor.t / bs.ms, state_monitor.v[50]) plt.plot(state_monitor.t / bs.ms, state_monitor.v[30]) plt.plot(state_monitor.t / bs.ms, state_monitor.v[40]) plt.plot(state_monitor.t / bs.ms, state_monitor.v[70]) plt.xlabel('Time (ms)') plt.ylabel('v') plt.show()
def simulate_exponential_IF_neuron(tau=MEMBRANE_TIME_SCALE_tau, R=MEMBRANE_RESISTANCE_R, v_rest=V_REST, v_reset=V_RESET, v_rheobase=RHEOBASE_THRESHOLD_v_rh, v_spike=FIRING_THRESHOLD_v_spike, delta_T=SHARPNESS_delta_T, I_stim=input_factory.get_zero_current(), simulation_time=200 * b2.ms): """ Implements the dynamics of the exponential Integrate-and-fire model Args: tau (Quantity): Membrane time constant R (Quantity): Membrane resistance v_rest (Quantity): Resting potential v_reset (Quantity): Reset value (vm after spike) v_rheobase (Quantity): Rheobase threshold v_spike (Quantity) : voltage threshold for the spike condition delta_T (Quantity): Sharpness of the exponential term I_stim (TimedArray): Input current simulation_time (Quantity): Duration for which the model is simulated Returns: (voltage_monitor, spike_monitor): A b2.StateMonitor for the variable "v" and a b2.SpikeMonitor """ eqs = """ dv/dt = (-(v-v_rest) +delta_T*exp((v-v_rheobase)/delta_T)+ R * I_stim(t,i))/(tau) : volt """ neuron = b2.NeuronGroup(1, model=eqs, reset="v=v_reset", threshold="v>v_spike", method="euler") neuron.v = v_rest # monitoring membrane potential of neuron and injecting current voltage_monitor = b2.StateMonitor(neuron, ["v"], record=True) spike_monitor = b2.SpikeMonitor(neuron) # run the simulation net = b2.Network(neuron, voltage_monitor, spike_monitor) net.run(simulation_time) return voltage_monitor, spike_monitor
def brian_poisson(rate, duration_ms, dt=1 * ms, n=1): """ Generates a sample of poisson neurons with a specified average frequency. Returns the sample as a list of neurons :param rate: The average firing frequency of each neuron in the sample :param duration_ms: Length of a single "trial" in ms :param dt: The shortest time interval between spikes in the sample :param n: Number of neurons in the sample NOTE: the "rate" and "duration_ms" parameters can also vary between neurons, if this is the desired behaviour, they should be given as a list of length "n" where each entry corresponds to the parameters of a single neuron in the sample :return: List of neurons in the sample stimulus, in each neuron, firing times are specified in milliseconds """ q = b2.units.fundamentalunits.Quantity # Type used to represent units in brian # Check that all parameters comply with units expected by brian if not isinstance(rate, q): # Rate is expected to be given in Hz if np.isscalar(rate): rate = rate * Hz else: rate = np.array(rate) * Hz if not isinstance(duration_ms, q): # Duration is expected to be specified in ms if np.isscalar(duration_ms): duration_ms = duration_ms * ms else: duration_ms = np.array(duration_ms) * ms # Specify properties of brian neuron group neuron = b2.NeuronGroup(n, "rate : Hz", threshold='rand()<rate*dt', dt=dt) neuron.rate = rate spikes = b2.SpikeMonitor( neuron, record=True ) # Set up monitoring (required for gathering spike timing information) b2.run(duration_ms) # Run simulation with the specified parameters # Extract spike timings from brian objects if n == 1: trains = spikes.spike_trains()[0] / dt else: trains = [train / dt for train in spikes.spike_trains().values()] return trains
def make_model(self): # Determine the simulation if self.clamp_type == 'current': eqs_input = '''I_inj = inj_input(t) : amp''' elif self.clamp_type == 'dynamic': eqs_input = '''I_exc = g_exc(t) * (Er_e - v) : amp I_inh = g_inh(t) * (Er_i - v) : amp I_inj = I_exc + I_inh : amp''' tracking = ['v', 'I_inj'] # Model the neuron with differential equations eqs = ''' Vh_m = 3.583881 * k_m - 53.294454*mV : volt m = 1 / (1 + exp(-(v - Vh_m) / k_m)) : 1 h = 1 / (1 + exp((v - Vh_h) / k_h)) : 1 alpha_n = (0.032 * 5. / exprel((15. -v/mV + VT/mV) / 5.))/ms : Hz beta_n = (0.5 * exp((10. - v/mV + VT/mV) / 40.))/ms : Hz dn/dt = alpha_n * (1 - n) - beta_n * n : 1 I_leak = -gL * (v - EL) : amp I_Na = -gNa * m**3 * h * (v - ENa) : amp I_K = -gK * n**4 * (v - EK) : amp dv/dt = (I_leak + I_Na + I_K + I_inj) / Cm : volt ''' # Neuron & parameter initialization neuron = b2.NeuronGroup(1, model=eqs + eqs_input, method='exponential_euler', threshold='m > 0.5', refractory=2 * b2.ms, reset=None, dt=self.dt * b2.ms) neuron.v = -65 * b2.mV # Track the parameters during simulation self.M = b2.StateMonitor(neuron, tracking, record=True) self.S = b2.SpikeMonitor(neuron, record=True) self.neuron = neuron net = b2.Network(neuron) net.add(self.M, self.S) self.network = net
def simulate_LIF_neuron(input_current, simulation_time=5 * b2.ms, v_rest=V_REST, v_reset=V_RESET, firing_threshold=FIRING_THRESHOLD, membrane_resistance=MEMBRANE_RESISTANCE, membrane_time_scale=MEMBRANE_TIME_SCALE, abs_refractory_period=ABSOLUTE_REFRACTORY_PERIOD): """Basic leaky integrate and fire neuron implementation. Args: input_current (TimedArray): TimedArray of current amplitudes. One column per current_injection_location. simulation_time (Quantity): Time for which the dynamics are simulated: 5ms v_rest (Quantity): Resting potential: -70mV v_reset (Quantity): Reset voltage after spike - 65mV firing_threshold (Quantity) Voltage threshold for spiking -50mV membrane_resistance (Quantity): 10Mohm membrane_time_scale (Quantity): 8ms abs_refractory_period (Quantity): 2ms Returns: StateMonitor: Brian2 StateMonitor for the membrane voltage "v" SpikeMonitor: Biran2 SpikeMonitor """ # differential equation of Leaky Integrate-and-Fire model eqs = """ dv/dt = ( -(v-v_rest) + membrane_resistance * input_current(t,i) ) / membrane_time_scale : volt (unless refractory)""" # LIF neuron using Brian2 library neuron = b2.NeuronGroup(1, model=eqs, reset="v=v_reset", threshold="v>firing_threshold", refractory=abs_refractory_period, method="linear") neuron.v = v_rest # set initial value # monitoring membrane potential of neuron and injecting current state_monitor = b2.StateMonitor(neuron, ["v"], record=True) spike_monitor = b2.SpikeMonitor(neuron) # run the simulation b2.run(simulation_time) return state_monitor, spike_monitor
def init_monitors(neurons, connections, monitor_params): """ Initialise Brian objects monitoring state variables in the network. """ monitors = { 'spikes': {}, 'neurons': {}, 'connections': {} } for layer in ['input', 'layer1e']: monitors['spikes'][layer] = b2.SpikeMonitor(neurons[layer]) if 'monitors_dt' not in monitor_params: timestep = None else: timestep = monitor_params['monitors_dt'] monitors['neurons']['layer1e'] = b2.StateMonitor( neurons['layer1e'], ['v', 'ge', 'max_ge', 'theta'], # record=True is currently broken for standalone simulations record=range(len(neurons['layer1e'])), dt=timestep ) if 'layer1vis' in neurons: monitors['neurons']['layer1vis'] = b2.StateMonitor( neurons['layer1vis'], ['v'], # record=True is currently broken for standalone simulations record=range(len(neurons['layer1vis'])), dt=b2.second/60 ) conn = connections['input-layer1e'] n_connections = len(conn.target) * len(conn.source) monitors['connections']['input-layer1e'] = b2.StateMonitor( connections['input-layer1e'], ['w', 'post', 'pre'], record=range(n_connections), dt=timestep ) return monitors
def main7(): # stochastic neurons # multiple neurons n_neurons = 100 tau = 10 * bs.ms v0_max = 3.0 duration = 1000 * bs.ms sigma = 0.2 # v0: 1 declares a new per-neuron parameter v0 # n Brian, we can do this by using the symbol xi in differential equations. # Strictly speaking, this symbol is a “stochastic differential” but you can sort of thinking of it as just a # Gaussian random variable with mean 0 and standard deviation 1. eqs = ''' dv/dt = (v0-v)/tau+sigma*xi*tau**-0.5 : 1 (unless refractory) v0 : 1 ''' # conditions for spiking models threshold = 'v>1' reset = 'v = 0' refractory = 5 * bs.ms G = bs.NeuronGroup(N=n_neurons, model=eqs, threshold=threshold, reset=reset, method='euler', refractory=refractory) state_monitor = bs.StateMonitor(G, 'v', record=True) spike_monitor = bs.SpikeMonitor(G) """ The line G.v0 = 'i*v0_max/(N-1)' initialises the value of v0 for each neuron varying from 0 up to v0_max. The symbol i when it appears in strings like this refers to the neuron index. """ G.v0 = 'i*v0_max/(N-1)' bs.run(duration=duration) plt.figure(figsize=(12, 4)) plt.subplot(121) plt.plot(spike_monitor.t / bs.ms, spike_monitor.i, '.k') plt.xlabel('Time (ms)') plt.ylabel('Neuron index') plt.subplot(122) plt.plot(G.v0, spike_monitor.count / duration) plt.xlabel('v0') plt.ylabel('Firing rate (sp/s)') plt.show()
def simulate_neuron(self, I_stim=input_factory.get_zero_current(), simulation_time=1000 * ms, **kwargs): neuron_parameters = dict( self.neuron_parameters ) # Make a copy of parameters; otherwise will change object params neuron_parameters.update(kwargs) refractory_period = neuron_parameters['refractory_period'] #eqs = self.get_membrane_equation(substitute_ad_hoc={'EXT_CURRENTS': '+ I_stim(t,i)'}) stim_string = '+ I_stim(t,i)' old_model_defns = dict(self.full_model_defns) self.add_model_definition('EXT_CURRENTS', stim_string) eqs = self.get_membrane_equation() self.full_model_defns = old_model_defns # Create a neuron group neuron = b2.NeuronGroup(1, model=eqs, namespace=neuron_parameters, reset=self.reset_statements, threshold=self.threshold_condition, refractory=refractory_period, method=self.integration_method) # Set initial values initial_values = self.get_initial_values() neuron.set_states(initial_values) # Set what to monitor state_monitor = b2.StateMonitor(neuron, self.get_states_to_monitor(), record=True) spike_monitor = b2.SpikeMonitor(neuron) # Run the simulation net = b2.Network(neuron, state_monitor, spike_monitor) net.run(simulation_time) return state_monitor, spike_monitor
def simulate(tau): # These two lines are needed to start a new standalone simulation: b2.device.reinit() b2.device.activate() eqs = ''' dv/dt = -v/tau : 1 ''' net = b2.Network() P = b2.PoissonGroup(num_inputs, rates=input_rate) G = b2.NeuronGroup(1, eqs, threshold='v>1', reset='v=0', method='euler') S = b2.Synapses(P, G, on_pre='v += weight') S.connect() M = b2.SpikeMonitor(G) net.add([P, G, S, M]) net.run(1000 * b2.ms) return M