def set_conductance_monitor(self): """yep""" self.mon_econd_e = bb.StateMonitor(self.Pe, 'ge', record=self.nrn_meas_e) self.mon_icond_e = bb.StateMonitor(self.Pe, 'gi', record=self.nrn_meas_e) self.mon_econd_i = bb.StateMonitor(self.Pi, 'ge', record=self.nrn_meas_i) self.mon_icond_i = bb.StateMonitor(self.Pi, 'gi', record=self.nrn_meas_i) self.network.add(self.mon_econd_e, self.mon_icond_e, self.mon_econd_i, self.mon_icond_i)
def simulate_WORM_neuron(input_current, simulation_time=5 * b2.ms, v_leak=V_LEAK, g_leak=G_LEAK, c_m=C_M, rest_pot=R_POT, tau=MEMBRANE_TIME_SCALE, f_t=FIRING_THRESHOLD): # differential equation of neuron model eqs = """ dv/dt = ( g_leak * (v_leak - v) + input_current(t,i) ) / c_m : volt """ # LIF neuron using Brian2 library neuron = b2.NeuronGroup(2, model=eqs, threshold='v>f_t', method="linear") neuron.v = rest_pot # set initial value # monitoring membrane potential of neuron and injecting current state_monitor = b2.StateMonitor(neuron, ["v"], record=True) S = b2.Synapses(neuron, neuron, model='w : volt', on_pre='v += w') S.connect(i=0, j=1) S.w = 0.01 * b2.mV # run the simulation b2.run(simulation_time) return state_monitor
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 main1(): bs.start_scope() tau = 10 * bs.ms # equations must end with : unit # unit is the SI unit of that variable # the unit is 1 since the number "1" is unitless # v represents voltage, but we just keep it unitless for simplicity # 1/s not part of the unit since the unit represents the unit of the variable itself # rather than the unit of the equation eqs = ''' dv/dt = (1-v)/tau: 1 ''' G = bs.NeuronGroup(1, model=eqs, method='exact') # record : bool, sequence of ints # Which indices to record, nothing is recorded for ``False``, # everything is recorded for ``True`` (warning: may use a great deal of # memory), or a specified subset of indices. M = bs.StateMonitor(G, 'v', record=0) print('Before v = %s' % G.v[0]) bs.run(100 * bs.ms) # runs the simulation for 100ms print('After v = %s' % G.v[0]) plt.plot(M.t / bs.ms, M.v[0]) plt.xlabel('Time (ms)') plt.ylabel('v') plt.show()
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 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 run_brian_sim(stim, dt, init_values, param_dict, method = 'exact'): # Model specification eqs = brian2.Equations("") eqs += brian2.Equations("dV/dt = 1 / C * (Ie(t) + I_0 + I_1 - G * (V - El)) : volt (unless refractory)") eqs += brian2.Equations("dTh_s/dt = -b_s * Th_s : volt (unless refractory)") eqs += brian2.Equations("dTh_v/dt = a_v * (V - El) - b_v * (Th_v - Th_inf) : volt (unless refractory)") eqs += brian2.Equations("dI_0/dt = -k_0 * I_0 : amp (unless refractory)") eqs += brian2.Equations("dI_1/dt = -k_1 * I_1 : amp (unless refractory)") reset = "" reset = "\n".join([reset, "V = a_r * V + b_r"]) reset = "\n".join([reset, "Th_s = Th_s + a_s"]) reset = "\n".join([reset, "Th_v = Th_v"]) reset = "\n".join([reset, "I_0 = R_0 * I_0 * exp(-k_0 * (t_ref - dt)) + A_0"]) reset = "\n".join([reset, "I_1 = R_1 * I_1 * exp(-k_1 * (t_ref - dt)) + A_1"]) threshold = "V > Th_v + Th_s" refractory = param_dict['t_ref'] Ie = brian2.TimedArray(stim, dt=dt) nrn = brian2.NeuronGroup(1, eqs, method=method, reset=reset, threshold=threshold, refractory=refractory, namespace=param_dict) nrn.V = init_values['V'] * brian2.units.volt nrn.Th_s = init_values['Th_s'] * brian2.units.volt nrn.Th_v = init_values['Th_v'] * brian2.units.volt nrn.I_0 = init_values['I_0'] * brian2.units.amp nrn.I_1 = init_values['I_1'] * brian2.units.amp monvars = ['V','Th_s','Th_v','I_0','I_1',] mon = brian2.StateMonitor(nrn, monvars, record=True) num_step = len(stim) brian2.defaultclock.dt = dt brian2.run(num_step * dt) return (mon.t / brian2.units.second, mon.V[0] / brian2.units.volt, mon.Th_s[0] / brian2.units.volt, mon.Th_v[0] / brian2.units.volt, mon.I_0[0] / brian2.units.amp, mon.I_1[0] / brian2.units.amp, )
def set_current_monitor(self): """yep""" self.mon_ecurr_e = bb.StateMonitor(self.Pe, 'Ie', record=self.nrn_meas_e) self.mon_icurr_e = bb.StateMonitor(self.Pe, 'Ii', record=self.nrn_meas_e) self.mon_ecurr_i = bb.StateMonitor(self.Pi, 'Ie', record=self.nrn_meas_i) self.mon_icurr_i = bb.StateMonitor(self.Pi, 'Ii', record=self.nrn_meas_i) self.network.add(self.mon_ecurr_e, self.mon_icurr_e, self.mon_ecurr_i, self.mon_icurr_i)
def neuron_sim(stim_V=0.8): """simulating the neuron using brian2 library""" # initiate stimuli timing stimulus = br2.TimedArray( [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, stim_V, 0, 0, 0, 0, 0, 0, 0, 0, 0], dt=100 * br2.ms) # initiating neurons eqs = ''' dv/dt = (-v + stimulus(t)-0.1*rand()) / tau : 1 tau : second ''' # creating neuron group G = br2.NeuronGroup(10, eqs, dt=0.2 * br2.ms) # creating different tau's for the neuron model G.tau = np.linspace(10, 100, 10) * br2.ms # defining state monitor to record voltage M = br2.StateMonitor(G, 'v', record=True) # creating network net = br2.Network(G, M) # storing initial state net.store() # np array to contain data data = np.zeros(shape=(10, 10000, 4)) # producing four repetitions for trial in range(4): net.restore() # Restore the initial state net.run(2 * br2.second) # store the results data[:, :, trial] = M.v return data
def simulate_GPe_cell(par_g, par_sim): num = par_g['num'] input_current = par_g['i_ext'] b2.defaultclock.dt = par_sim['dt'] eqs = ''' i_extg = input_current(t, i): 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 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 membrane_Im = -(itg + inag + ikg + iahpg + icag + ilg) + i_extg : amp 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 #! pA dvg/dt = membrane_Im / C : volt ''' neuron = b2.NeuronGroup( num, eqs, method=par_sim['integration_method'], dt=par_sim['dt'], threshold='vg>-20*mV', refractory='vg>-20*mV', namespace=par_g, ) neuron.vg = par_g['v0'] neuron.hg = "hinfg" neuron.ng = "ninfg" neuron.rg = "rinfg" neuron.cag = 0 # neuron.i_extg = par_g['iapp'] st_mon = b2.StateMonitor(neuron, ["vg", 'i_extg'], record=True) net = b2.Network(neuron) net.add(st_mon) net.run(par_sim['simulation_time']) return st_mon
def simulate_STN_cell(par, par_sim): num = par['num'] input_current = par['i_ext'] eqs = ''' I_ext = input_current(t, i): amp 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 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 #! pA membrane_Im = -(il + ina + ik + it + ica + iahp) + I_ext : amp dvs/dt = membrane_Im/C : volt ''' neuron = b2.NeuronGroup( num, eqs, method=par_sim['integration_method'], dt=par_sim['dt'], threshold='vs>-20*mV', refractory='vs>-20*mV', namespace=par, ) neuron.vs = par['v0'] neuron.h = "hinf" neuron.n = "ninf" neuron.r = "rinf" neuron.ca = 0 st_mon = b2.StateMonitor(neuron, ["vs", "I_ext"], record=True) net = b2.Network(neuron) net.add(st_mon) net.run(par_sim['simulation_time']) return st_mon
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 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 StateMonitors(neuron_groups, index_str, index_record=0): index = _neuron_group_index(index_str) if index_str == 'input': M = br.StateMonitor(neuron_groups[index], 'v', record=index_record, \ name=(index_str + '_v')) return M elif index_str == 'hidden': Mge = br.StateMonitor(neuron_groups[index][0], 'ge', record=index_record, \ name=(index_str + '_ge' + str(index_record))) Mv = br.StateMonitor(neuron_groups[index][0], 'v', record=index_record, \ name=(index_str + '_v' + str(index_record))) Mu = br.StateMonitor(neuron_groups[index][0], 'u', record=index_record, \ name=(index_str + '_u' + str(index_record))) else: Mge = br.StateMonitor(neuron_groups[index], 'ge', record=index_record, \ name=(index_str + '_ge' + str(index_record))) Mv = br.StateMonitor(neuron_groups[index], 'v', record=index_record, \ name=(index_str + '_v' + str(index_record))) Mu = br.StateMonitor(neuron_groups[index], 'u', record=index_record, \ name=(index_str + '_u' + str(index_record))) return Mv, Mu, Mge
def simulate_Thl_cell_fig3(par, par_sim): num = par_sim['num'] i_sensory_motor = par_sim['I_sm'] # b2.set_device('cpp_standalone') b2.start_scope() eqs = b2.Equations(''' minfthl = 1/(1+exp(-(vt-thtmthl*mV)/(sigmthl*mV))): 1 hinfthl = 1/(1+exp((vt-thththl*mV)/(sighthl*mV))): 1 pinfthl = 1/(1+exp(-(vt-thtpthl*mV)/(sigpthl*mV))) :1 rinfthl = 1/(1+exp((vt-thtrthl*mV)/(sigrthl*mV))) :1 ahthl = ah0thl*exp(-(vt-thtahthl*mV)/(sigahthl*mV)) :1 bhthl = bh0thl/(1+exp(-(vt-thtbhthl*mV)/(sigbhthl*mV))) :1 tauhthl = 1/(ahthl+bhthl) *ms :second taurthl = taur0thl+taur1thl*exp(-(vt-thtrtauthl*mV)/(sigrtauthl*mV)) :second ilthl=glthl*(vt-vlthl):amp inathl=gnathl*minfthl*minfthl*minfthl*hthl*(vt-vnathl) :amp ikthl=gkthl*((0.75*(1-hthl))**4)*(vt-vkthl) :amp itthl=gtthl*pinfthl*pinfthl*rthl*(vt-vtthl) :amp iextthl:amp tmp_thl1 = sin(2*pi*(t-dsmthl)/tmsmthl) :1 tmp_thl2 = sin(2*pi*(t-dsmthl+wsmthl)/tmsmthl) :1 ym_thl1=1/(1+exp(-tmp_thl1/sigym)):1 ym_thl2=1/(1+exp(-tmp_thl2/sigym)):1 ithl_sm=imsmthl*ym_thl1*(1-ym_thl2) :amp membrane_Ithl = -(ilthl+inathl+ikthl+itthl)+iextthl+ithl_sm:amp drthl/dt=phirthl*(rinfthl-rthl)/taurthl :1 dhthl/dt=phihthl*(hinfthl-hthl)/tauhthl :1 dvt/dt = membrane_Ithl/cmthl : volt ''') neuron = b2.NeuronGroup( num, eqs, method=par_sim['integration_method'], dt=par_sim['dt'], threshold='vt>-55*mV', refractory='vt>-55*mV', namespace=par, ) neuron.vt = par['v0'] neuron.hthl = "hinfthl" neuron.rthl = "rinfthl" neuron.iextthl = par['iext'] state_monitor = b2.StateMonitor(neuron, ["vt", "ithl_sm"], record=True) net = b2.Network(neuron) net.add(state_monitor) net.run(par_sim['simulation_time']) return state_monitor
def simulate_HH_neuron(I_e, simulation_time): """A Hodgkin-Huxley neuron implemented in Brian2. Args: I_e: Input current injected into the HH neuron simulation_time (float): Simulation time [seconds] Returns: StateMonitor: Brian2 StateMonitor with recorded field "vm" """ # neuron parameters El = -59. * b2.mV EK = -82. * b2.mV ENa = 45. * b2.mV gl = 0.3 * b2.msiemens gK = 36. * b2.msiemens gNa = 120. * b2.msiemens C = 1. * b2.ufarad # forming HH model with differential equations eqs = """ membrane_Im = I_e + gNa*m**3*h*(ENa-vm) + \ gl*(El-vm) + gK*n**4*(EK-vm) : amp alphan = 0.01/mV * (-60.0*mV - vm) / (exp((-60.0*mV - vm) / (10.0*mV)) - 1.0)/ms: Hz alpham = (vm + 45.0*mV) / (10.0*mV) / (1.0 - exp(-(vm + 45.0*mV) / (10.0*mV)))/ms : Hz alphah = 0.07*exp(-(vm + 70.*mV)/(20.*mV))/ms : Hz betan = 0.125 * exp(-(vm + 70.0*mV) / (80.0*mV))/ms: Hz betam = 4.0 * exp(-(vm + 70.0*mV) / (18.0*mV))/ms: Hz betah = 1. / (exp(-(vm + 40.0*mV) / (10.0*mV)) + 1.0)/ms : Hz dn/dt = alphan*(1-n)-betan*n : 1 dm/dt = alpham*(1-m)-betam*m : 1 dh/dt = alphah*(1-h)-betah*h : 1 dvm/dt = membrane_Im/C : volt """ neuron = b2.NeuronGroup(1, eqs, method="exponential_euler") # parameter initialization [come from x_inf(v) {x:m,n,h}] neuron.vm = -70. * b2.mV neuron.m = 0.05 neuron.h = 0.60 neuron.n = 0.32 # tracking parameters st_mon = b2.StateMonitor(neuron, "vm", record=True) # running the simulation hh_net = b2.Network(neuron) hh_net.add(st_mon) hh_net.run(simulation_time) return st_mon
def simulate_FSI_cell(par, par_sim): pid = os.getpid() b2.set_device('cpp_standalone', directory=join( "output", f"standalone-{pid}")) b2.get_device().reinit() b2.get_device().activate( directory=join("output", f"standalone-{pid}")) num = par['num'] input_current = par['i_ext'] eqs = ''' Iapp = input_current(t, i): amp m_inf = 1.0/(1.0+exp(-(vf+24*mV)/(11.5*mV))):1 h_inf = 1.0/(1.0+exp(-(vf+58.3*mV)/(-6.7*mV))):1 n_inf = 1.0/(1.0+exp(-(vf+12.4*mV)/(6.8*mV))):1 a_inf = 1.0/(1.0+exp(-(vf+50*mV)/(20.*mV))):1 b_inf = 1.0/(1.0+exp(-(vf+70*mV)/(-6.*mV))):1 tau_h=0.5*ms+14.0*ms/(1.0+exp(-(vf+60*mV)/(-12.*mV))):second tau_n=(0.087*ms+11.4*ms/(1.0+exp(-(vf+14.6*mV)/(-8.6*mV)))) *(0.087+11.4/(1.0+exp(-(vf-1.3*mV)/(18.7*mV)))) :second membrain_Im = -gNa*m_inf**3 *h*(vf-50*mV) -gK*(n**power_n)*(vf+90*mV) -gL*(vf+70*mV)-gA*a**3*b*(vf+90*mV)+Iapp:amp dh/dt=(h_inf-h)/tau_h :1 dn/dt=(n_inf-n)/tau_n :1 da/dt=(a_inf-a)/(2.*ms) :1 db/dt=(b_inf-b)/(150.*ms) :1 dvf/dt=membrain_Im/Cm :volt ''' neuron = b2.NeuronGroup(num, eqs, method=par_sim['integration_method'], dt=par_sim['dt'], threshold='vf>-20*mV', refractory='vf>-20*mV', namespace=par, ) neuron.vf = par['v0'] neuron.h = "h_inf" neuron.n = "n_inf" neuron.a = "a_inf" neuron.b = "b_inf" st_mon = b2.StateMonitor(neuron, ["vf", "Iapp"], record=True) net = b2.Network(neuron) net.add(st_mon) net.run(par_sim['simulation_time']) return st_mon
def simulate_HH_neuron(input_current, simulation_time): """A Hodgkin-Huxley neuron implemented in Brian2. Args: input_current (TimedArray): Input current injected into the HH neuron simulation_time (float): Simulation time [seconds] Returns: StateMonitor: Brian2 StateMonitor with recorded fields ["vm", "I_e", "m", "n", "h"] """ # neuron parameters El = 10.6 * b2.mV EK = -12 * b2.mV ENa = 115 * b2.mV gl = 0.3 * b2.msiemens gK = 36 * b2.msiemens gNa = 120 * b2.msiemens C = 1 * b2.ufarad # forming HH model with differential equations eqs = """ I_e = input_current(t,i) : amp membrane_Im = I_e + gNa*m**3*h*(ENa-vm) + \ gl*(El-vm) + gK*n**4*(EK-vm) : amp alphah = .07*exp(-.05*vm/mV)/ms : Hz alpham = .1*(25*mV-vm)/(exp(2.5-.1*vm/mV)-1)/mV/ms : Hz alphan = .01*(10*mV-vm)/(exp(1-.1*vm/mV)-1)/mV/ms : Hz betah = 1./(1+exp(3.-.1*vm/mV))/ms : Hz betam = 4*exp(-.0556*vm/mV)/ms : Hz betan = .125*exp(-.0125*vm/mV)/ms : Hz dh/dt = alphah*(1-h)-betah*h : 1 dm/dt = alpham*(1-m)-betam*m : 1 dn/dt = alphan*(1-n)-betan*n : 1 dvm/dt = membrane_Im/C : volt """ neuron = b2.NeuronGroup(1, eqs, method="exponential_euler") # parameter initialization neuron.vm = 0 neuron.m = 0.05 neuron.h = 0.60 neuron.n = 0.32 # tracking parameters st_mon = b2.StateMonitor(neuron, ["vm", "I_e", "m", "n", "h"], record=True) # running the simulation hh_net = b2.Network(neuron) hh_net.add(st_mon) hh_net.run(simulation_time) return st_mon
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 main2(): # setting synaptic weight bs.start_scope() n_neurons = 3 eqs = ''' dv/dt = (I-v)/tau : 1 (unless refractory) I : 1 tau: second ''' threshold = 'v>1' reset = 'v = 0' refractory = 10 * bs.ms G = bs.NeuronGroup(N=n_neurons, model=eqs, threshold=threshold, reset=reset, method='exact', refractory=refractory) G.I = [2, 0, 0] # represents the I in eqs # driving current should be bigger than the threshold, otherwise it wont spike at all # I = 0 means that the voltage wont change since there is no driving current G.tau = [10, 100, 100] * bs.ms # represents the tau in eqs # unlike last time, the tau is defined with the neuron so we see the effects of different values # model : `str`, `Equations`, optional # The model equations for the synapses. # you need to set this as model= in Synapses in order to incorporate weight synapse_model = 'w : 1' # So in total, what this model says is that whenever two neurons in G are connected by a synapse, # when the source neuron fires a spike the target neuron will have its value of v increased by 0.2. S = bs.Synapses(source=G, target=G, model=synapse_model, on_pre='v_post += w') S.connect(i=0, j=[1, 2]) # So this will give a synaptic connection from 0 to 1 with weight 0.2=0.2*1 and from 0 to 2 with weight 0.4=0.2*2. S.w = 'j*0.2' state_monitor = bs.StateMonitor(G, 'v', record=True) bs.run(100 * bs.ms) plt.plot(state_monitor.t / bs.ms, state_monitor.v[0], label='Neuron 0') plt.plot(state_monitor.t / bs.ms, state_monitor.v[1], label='Neuron 1') plt.plot(state_monitor.t / bs.ms, state_monitor.v[2], label='Neuron 2') plt.xlabel('Time (ms)') plt.ylabel('v') plt.legend() plt.show()
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(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 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 main2(): tau = 10 * bs.ms eqs = ''' dv/dt = (sin(2*pi*100*Hz*t)-v)/tau : 1 ''' G = bs.NeuronGroup(1, eqs, method="euler") G.v = 5 # we can set the initial value M = bs.StateMonitor(G, 'v', record=0) bs.run(60 * bs.ms) plt.plot(M.t / bs.ms, M.v[0]) plt.xlabel('Time (ms)') plt.ylabel('v') plt.show()
def main3(): # introducing delay bs.start_scope() n_neurons = 3 eqs = ''' dv/dt = (I-v)/tau : 1 (unless refractory) I : 1 tau: second ''' threshold = 'v>1' reset = 'v = 0' refractory = 10 * bs.ms G = bs.NeuronGroup(N=n_neurons, model=eqs, threshold=threshold, reset=reset, method='exact', refractory=refractory) G.I = [2, 0, 0] # represents the I in eqs # driving current should be bigger than the threshold, otherwise it wont spike at all # I = 0 means that the voltage wont change since there is no driving current G.tau = [10, 100, 100] * bs.ms # represents the tau in eqs # unlike last time, the tau is defined with the neuron so we see the effects of different values synapse_model = 'w : 1' # So in total, what this model says is that whenever two neurons in G are connected by a synapse, # when the source neuron fires a spike the target neuron will have its value of v increased by 0.2. S = bs.Synapses(source=G, target=G, model=synapse_model, on_pre='v_post += w') S.connect(i=0, j=[1, 2]) S.w = 'j*0.2' S.delay = 'j*2*ms' state_monitor = bs.StateMonitor(G, 'v', record=True) bs.run(100 * bs.ms) plt.plot(state_monitor.t / bs.ms, state_monitor.v[0], label='Neuron 0') plt.plot(state_monitor.t / bs.ms, state_monitor.v[1], label='Neuron 1') plt.plot(state_monitor.t / bs.ms, state_monitor.v[2], label='Neuron 2') plt.xlabel('Time (ms)') plt.ylabel('v') plt.legend() plt.show()
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 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