def test_incorrect_pre_reference(): G = NeuronGroup(1, '''v : 1 x : 1''', threshold='v>1', reset='v=0') G.v = 1.1 # spikes G2 = NeuronGroup(10, '') # The pre-synaptic x variable should be 10 in the end, because 10 synapses # were created and all of them increase the pre-synaptic variable by 1. # This does not work in Brian 1 (but it does work in Brian 2), we therefore # only throw an error to avoid this problem. assert_raises(ValueError, lambda: Synapses(G, G2, pre='x_pre += 1'))
def run_stdp(NE,NI,v_init,C_e,C_ii,C_ie,mon_bin,dt): from brian.neurongroup import NeuronGroup from brian.monitor import PopulationRateMonitor from brian.stdunits import mV, ms, nS, pF, pA, Hz from brian.units import second from brian.equations import Equations from brian.network import Network from brian.connections import Connection from brian.stdp import STDP from brian.clock import Clock runtime = 10*second eta = 1e-2 # Learning rate tau_stdp = 20*ms # STDP time constant alpha = 3*Hz*tau_stdp*2 # Target rate parameter gmax = 100 # Maximum inhibitory weight eqs_neurons=''' dv/dt=(-gl*(v-el)-(g_ampa*w*v+g_gaba*(v-er)*w)+bgcurrent)/memc : volt dg_ampa/dt = -g_ampa/tau_ampa : 1 dg_gaba/dt = -g_gaba/tau_gaba : 1 ''' namespace = {'tau_ampa':5.0*ms,'tau_gaba':10.0*ms, 'bgcurrent':200*pA,'memc':200.0*pF, 'el':-60*mV,'w':1.*nS,'gl':10.0*nS,'er':-80*mV} eqs_neurons = Equations(eqs_neurons, ** namespace) clock = Clock(dt) neurons=NeuronGroup(NE+NI,model=eqs_neurons,clock=clock, threshold=-50.*mV,reset=-60*mV,refractory=5*ms) neurons.v = v_init Pe=neurons.subgroup(NE) Pi=neurons.subgroup(NI) rme = PopulationRateMonitor(Pe,mon_bin) rmi = PopulationRateMonitor(Pi,mon_bin) con_e = Connection(Pe,neurons,'g_ampa') con_ie = Connection(Pi,Pe,'g_gaba') con_ii = Connection(Pi,Pi,'g_gaba') con_e.connect_from_sparse(C_e, column_access=True) con_ie.connect_from_sparse(C_ie, column_access=True) con_ii.connect_from_sparse(C_ii, column_access=True) eqs_istdp = ''' dA_pre/dt=-A_pre/tau_stdp : 1 dA_post/dt=-A_post/tau_stdp : 1 ''' stdp_params = {'tau_stdp':tau_stdp, 'eta':eta, 'alpha':alpha} eqs_istdp = Equations(eqs_istdp, **stdp_params) stdp_ie = STDP(con_ie, eqs=eqs_istdp, pre='''A_pre+=1. w+=(A_post-alpha)*eta''', post='''A_post+=1. w+=A_pre*eta''', wmax=gmax) net = Network(neurons, con_e, con_ie, con_ii, stdp_ie, rme, rmi) net.run(runtime,report='text') return (rme.times,rme.rate), (rmi.times,rmi.rate)
def test_construction_multiple_synapses(): ''' Test the construction of synapses with multiple synapses per connection. ''' G = NeuronGroup(20, model='v:1', threshold=NoThreshold()) subgroup1, subgroup2 = G[:10], G[10:] syn = Synapses(subgroup1, subgroup2, model='w:1', pre='v += w') # create all-to-all connections with three synapses per connection syn[:, :] = 3 assert len(syn) == 3 * 10 * 10 # set the weights to the same value for all synapses syn.w[:, :] = 2 # set the delays syn.delay[:, :] = 1 * ms all_weights = np.array([ syn.w[i, j, syn_idx] for i in xrange(len(subgroup1)) for j in xrange(len(subgroup2)) for syn_idx in xrange(3) ]) assert (all_weights == 2).all() all_delays = np.array([ syn.delay[i, j, syn_idx] for i in xrange(len(subgroup1)) for j in xrange(len(subgroup2)) for syn_idx in xrange(3) ]) assert (all_delays == 1 * ms).all()
def test_max_delay(): '''Test that changing delays after compression works. ''' reinit_default_clock() inp = SpikeGeneratorGroup(1, [(0, 1 * ms)]) G = NeuronGroup(1, model='v:1') mon = StateMonitor(G, 'v', record=True) # one synapse syn = Synapses(inp, G, model='w:1', pre='v+=w', max_delay=5 * ms) syn[:, :] = 1 syn.w[:, :] = 1 syn.delay[:, :] = 0 * ms net = Network(inp, G, syn, mon) net.run(defaultclock.dt) syn.delay[:, :] = 5 * ms net.run(6.5 * ms) # spike should arrive at 5 + 1 ms assert (mon[0][mon.times >= 6 * ms] == 1).all() assert (mon[0][mon.times < 6 * ms] == 0).all() # same as above but with two synapses reinit_default_clock() mon.reinit() G.reinit() syn = Synapses(inp, G, model='w:1', pre='v+=w', max_delay=5 * ms) syn[:, :] = 2 syn.w[:, :] = 1 syn.delay[:, :] = [0 * ms, 0 * ms] net = Network(inp, G, syn, mon) net.run(defaultclock.dt) syn.delay[:, :] = [5 * ms, 5 * ms] net.run(6.5 * ms) # spike should arrive at 5 + 1 ms assert (mon[0][mon.times >= 6 * ms] == 2).all() assert (mon[0][mon.times < 6 * ms] == 0).all()
def create_netobjs(stim, params): C = params['Cap'] KappaN = params['Kappan'] KappaP = params['Kappap'] I0N = params['I0n'] I0P = params['I0p'] Ut = params['Ut'] Delta_t = (Ut / KappaP) #Feed-Forward parameters i_inj = params['i_inj'] i_injinh1 = params['i_injinh1'] i_injinh2 = params['i_injinh2'] i_injinh3 = params['i_injinh3'] i_injinh4 = params['i_injinh4'] i_leak = params['i_leak'] tau_syn_E = params['tau_syn_E'] tau_syn_I = params['tau_syn_I'] tau_synloc_E = params['tau_synloc_E'] tau_synloc_IE = params['tau_synloc_IE'] v_thresh = params['v_thresh'] w_syn_E1 = params['w_syn_E1'] w_syn_E2 = params['w_syn_E2'] w_syn_I = params['w_syn_I'] w_synloc_E = params['w_synloc_E'] w_synloc_EE = params['w_synloc_EE'] w_synloc_EI = params['w_synloc_EI'] w_synloc_IE = params['w_synloc_IE'] w_synloc_S = params['w_synloc_S'] ##Feed-Back parameters #w =dict() #w['e'] =1e-11 #w['i'] =5e-11/N_IP1 #w['ei'] =2e-11/N_EP1 eqs = Equations(''' dV/dt=(-I_lk + I_fb + I_in + Ia + Iloce - Iloci - Ii)/C: volt I_fb = I0P*exp((V-v_thresh)/Delta_t) : amp I_in : amp I_lk = i_leak : amp dIa/dt=-Ia/tau_syn_E: amp dIloce/dt=-Iloce/tau_synloc_E: amp dIloci/dt=-Iloci/tau_synloc_IE: amp dIi/dt=-Ii/tau_syn_I: amp ''') EIP = NeuronGroup(N, model=eqs, reset=0, threshold=1.5, refractory=.001) EP1 = EIP[:N_EP1] IP1 = EIP[N_EP1:] EP1.I_in = np.random.normal(1, sigma_mismatch, N_EP1) * i_inj IP1.I_in = np.random.normal(1,sigma_mismatch,N_IP1)*\ np.array([i_injinh1, i_injinh2, i_injinh3, i_injinh4]) #Create connections between population v_loclat = np.zeros([N_EP1]) v_loclat[N_EP1 / 2] = w_synloc_S v_loclat[[N_EP1 / 2 - 1, N_EP1 / 2 + 1]] = w_synloc_E v_loclat[[N_EP1 / 2 - 2, N_EP1 / 2 + 2]] = w_synloc_EE v_loclat[[N_EP1 / 2 - 3, N_EP1 / 2 + 3]] = w_synloc_EE / 2 v_loclat = np.roll(v_loclat, -N_EP1 / 2) W = np.array([np.roll(v_loclat, i) for i in range(N_EP1)]) W *= np.random.normal(1, sigma_mismatch, W.shape) ConnE = Connection(EP1, EP1, 'Iloce') ConnE.connect(EP1, EP1, W) ConnEI = Connection(EP1, IP1, 'Iloce') ConnEI.connect( EP1, IP1, W=w_synloc_EI * np.random.normal(1, sigma_mismatch, [len(EP1), len(IP1)])) ConnIE = Connection(IP1, EP1, 'Iloci') ConnIE.connect( IP1, EP1, W=w_synloc_IE * np.random.normal(1, sigma_mismatch, [len(IP1), len(EP1)])) M_EIP = SpikeMonitor(EIP) MV_EIP = StateMonitor(EIP, 'V', record=range(0, N), timestep=int(1 * ms / defaultclock.dt)) @network_operation def update_mpot(): EIP.V[EIP.V < 0.] = 0. # ME_EP1= StateMonitor(EP1,'Ie',record=range(0,N_EP1),timestep=int(1*ms/defaultclock.dt)) # MI_EP1= StateMonitor(EP1,'Ii',record=range(0,N_EP1),timestep=int(1*ms/defaultclock.dt)) # MW_EP1= StateMonitor(EP1,'Ia',record=range(0,N_EP1),timestep=int(1*ms/defaultclock.dt)) netobjs = { 'EIP': EIP, 'update_mpot': update_mpot, 'ConnE': ConnE, 'ConnEI': ConnEI, 'ConnIE': ConnIE, #'M_In1': M_In1, 'M_EIP': M_EIP, 'MV_EIP': MV_EIP } return netobjs, M_EIP, MV_EIP
self._P.state(self._I)[:] = -self.record # Inject if self._estimation: I = 2. * (rand() - .5) * self._amp + self._DC self.record = -I # Record self._Vrec.append(V[0]) self._Irec.append(I) if self._compensation: # Compensate self._lastI[self._posI] = -self.record[0] self._posI = (self._posI - 1) % self._ktail V[0] = V[0] - sum( self.Ke * self._lastI[range(self._posI, self._ktail) + range(0, self._posI)]) self._J += self.clock._dt * self._gain2 * (self.command - V) self.record = -(self._gain * (self.command - V) + self._J) if __name__ == '__main__': from brian import * taum = 20 * ms gl = 20 * nS Cm = taum * gl eqs = Equations('dv/dt=(-gl*v+i_inj)/Cm : volt') + electrode( 50 * Mohm, 10 * pF, vm='v', i_cmd=.5 * nA) neuron = NeuronGroup(1, model=eqs) M = StateMonitor(neuron, 'v_el', record=True) run(100 * ms) plot(M.times / ms, M[0] / mV) show()
def test_model_definition(): ''' Tests various ways of defining models. Note that this test only checks for whether the interface accepts what it is supposed to accept, not whether the Synapses class actually does what it is supposed to do... ''' G = NeuronGroup(1, model='v:1', threshold=NoThreshold()) # model, pre and post string syn = Synapses(G, model='w:1', pre='v+=w', post='v+=w') # list of pre codes syn = Synapses(G, model='w:1', pre=['v+=w', 'v+=1']) # an equation object model = SynapticEquations('w:1') syn = Synapses(G, model=model, pre='v+=w') ############################################################################ # Some more complex examples from the docs ############################################################################ # event-driven simulations model = '''w:1 dApre/dt=-Apre/taupre : 1 (event-driven) dApost/dt=-Apost/taupost : 1 (event-driven)''' syn = Synapses(G, model=model) model = '''w : 1 p : 1''' syn = Synapses(G, model=model, pre="v+=w*(rand()<p)") syn = Synapses(G, model='''x : 1 u : 1 w : 1''', pre='''u=U+(u-U)*exp(-(t-lastupdate)/tauf) x=1+(x-1)*exp(-(t-lastupdate)/taud) i+=w*u*x x*=(1-u) u+=U*(1-u)''') # lumped variables a = 1 / (10 * ms) b = 1 / (20 * ms) c = 1 / (30 * ms) neurons = NeuronGroup(1, model="""dv/dt=(gtot-v)/(10*ms) : 1 gtot : 1""") S = Synapses(neurons, model='''dg/dt=-a*g+b*x*(1-g) : 1 dx/dt=-c*x : 1 w : 1 # synaptic weight ''', pre='x+=w') neurons.gtot = S.g v0 = 0 tau = 5 * ms neurons = NeuronGroup(1, model='''dv/dt=(v0-v+Igap)/tau : 1 Igap : 1''') S = Synapses(neurons, model='''w:1 # gap junction conductance Igap=w*(v_pre-v_post): 1''') neurons.Igap = S.Igap # static equations in synaptic model V_L = -70 * mV C_m = 0.5 * nF g_m = 25 * nS V_E1 = 0 * mV V_E2 = -20 * mV g_1 = 0.1 * nS g_2 = 0.2 * nS tau1 = 5 * ms tau2 = 50 * ms neurons = NeuronGroup( 1, model='''dV/dt = (-1/C_m)*((g_m)*(V-V_L) + I_tot) : volt I_tot : amp''', reset=-55 * mV, threshold=-50 * mV) S = Synapses(neurons, model='''I_tot = I_1 + I_2 : amp I_1 = sI_1*g_1*(V_post-V_E1) : amp dsI_1/dt = -sI_1 / tau1 : 1 I_2 = sI_2*g_2*(V_post-V_E2) : amp dsI_2/dt = -sI_2 / tau1 : 1 ''', pre='sI_1 += 1; sI_2 += 1') S[:, :] = True neurons.I_tot = S.I_tot
def test_construction_and_access(): ''' Test various ways of constructing and accessing synapses. ''' G = NeuronGroup(20, model='v:1', threshold=NoThreshold()) subgroup1, subgroup2 = G[:10], G[10:] syn = Synapses(subgroup1, subgroup2, model='w:1', pre='v += w') # single synaptic indices syn[3, 4] = True syn.w[3, 4] = 0.25 syn.delay[3, 4] = 1 * ms for i in xrange(len(subgroup1)): for j in xrange(len(subgroup2)): if i == 3 and j == 4: assert syn.w[i, j] == 0.25 assert syn.delay[i, j] == 1 * ms else: assert len(syn.w[i, j]) == 0 assert len(syn.delay[i, j]) == 0 # illegal target index def illegal_index(): syn[3, 10] = True assert_raises(ValueError, illegal_index) # illegal source index def illegal_index(): #@DuplicatedSignature syn[10, 4] = True assert_raises(ValueError, illegal_index) # target slice syn = Synapses(subgroup1, subgroup2, model='w:1', pre='v += w') syn[3, :] = True syn.w[3, :] = 0.25 syn.delay[3, :] = 1 * ms for i in xrange(len(subgroup1)): for j in xrange(len(subgroup2)): if i == 3: assert syn.w[i, j] == 0.25 assert syn.delay[i, j] == 1 * ms else: assert len(syn.w[i, j]) == 0 assert len(syn.delay[i, j]) == 0 # access with slice assert (syn.w[3, :] == 0.25).all() assert (syn.delay[3, :] == 1 * ms).all() # source slice syn = Synapses(subgroup1, subgroup2, model='w:1', pre='v += w') syn[:, 4] = True syn.w[:, 4] = 0.25 syn.delay[:, 4] = 1 * ms for i in xrange(len(subgroup1)): for j in xrange(len(subgroup2)): if j == 4: assert syn.w[i, j] == 0.25 assert syn.delay[i, j] == 1 * ms else: assert len(syn.w[i, j]) == 0 assert len(syn.delay[i, j]) == 0 # access with slice assert (syn.w[:, 4] == 0.25).all() assert (syn.delay[:, 4] == 1 * ms).all() # Use string initialization for synaptic variable syn = Synapses(subgroup1, subgroup2, model='w:1', pre='v += w') syn[:, 4] = True # synapses from even source index have weight 1, uneven --> weight 0.5 # same for delays (1ms and 0.5ms) syn.w[:, 4] = '(i % 2 == 0) * 0.5 + 0.5' syn.delay[:, 4] = '(i % 2 == 0) * 0.5 * ms + 0.5 * ms' assert (syn.w[::2, 4] == 1).all() assert (syn.w[1::2, 4] == 0.5).all() assert (syn.delay[::2, 4] == 1 * ms).all() assert (syn.delay[1::2, 4] == 0.5 * ms).all() # Use string initialization with a numpy function and constant syn = Synapses(subgroup1, subgroup2, model='w:1', pre='v += w') syn[:, 4] = True syn.w[:, 4] = '0.5 + 0.5 * np.cos(i / (1.0 * n) * np.pi)' syn.delay[:, 4] = '0.0005 + 0.0005 * np.cos(i / (1.0 * n) * np.pi)' assert (syn.w[:, 4] == 0.5 + 0.5 * np.cos(np.arange(len(subgroup1)) / (1.0 * len(subgroup1)) * np.pi)).all() # possible delays are always multiples of dt delays = 0.5 * ms + 0.5 * ms * np.cos( np.arange(len(subgroup1)) / (1.0 * len(subgroup1)) * np.pi) delays_rounded_to_dt = (delays / defaultclock.dt).astype( np.int) * defaultclock.dt assert (syn.delay[:, 4] == delays_rounded_to_dt).all()
def test_construction_single_synapses(): ''' Test the construction of synapses with a single synapse per connection. ''' G = NeuronGroup(20, model='v:1', threshold=NoThreshold()) # specifying only one group should use it as source and target syn = Synapses(G, model='w:1') assert syn.source is syn.target # specifying source and target with subgroups subgroup1, subgroup2 = G[:10], G[10:] syn = Synapses(subgroup1, subgroup2, model='w:1', pre='v += w') assert syn.source is subgroup1 assert syn.target is subgroup2 # create all-to-all connections syn[:, :] = True assert len(syn) == 10 * 10 # deleting a synapse should not work def delete_synapse(): syn[0, 0] = False assert_raises(ValueError, delete_synapse) # set the weights syn.w[:, :] = 2 # set the delays syn.delay[:, :] = 1 * ms all_weights = np.array([ syn.w[i, j] for i in xrange(len(subgroup1)) for j in xrange(len(subgroup2)) ]) assert (all_weights == 2).all() all_delays = np.array([ syn.delay[i, j] for i in xrange(len(subgroup1)) for j in xrange(len(subgroup2)) ]) assert (all_delays == 1 * ms).all() # create one-to-one connections syn = Synapses(subgroup1, subgroup2, model='w:1', pre='v += w') syn[:, :] = 'i == j' syn.w[:, :] = 2 assert len(syn) == len(subgroup1) for i in xrange(len(subgroup1)): for j in xrange(len(subgroup2)): if i == j: assert syn.w[i, j] == 2 else: assert len(syn.w[i, j]) == 0 net = Network(G, syn) net.run(defaultclock.dt) # adding synapses should not work after the simulation has already been run def adding_a_synapse(): syn[0, 1] = True assert_raises(AttributeError, adding_a_synapse) syn = Synapses(subgroup1, subgroup2, model='w:1', pre='v += w') syn.connect_one_to_one(subgroup1, subgroup2) syn.w[:, :] = 2 assert len(syn) == len(subgroup1) for i in xrange(len(subgroup1)): for j in xrange(len(subgroup2)): if i == j: assert syn.w[i, j] == 2 else: assert len(syn.w[i, j]) == 0 # Calling connect_one_to_one without specifying groups should use the full # source or target group syn = Synapses(subgroup1, subgroup2, model='w:1', pre='v += w') syn.connect_one_to_one(subgroup1) assert len(syn) == len(subgroup1) syn = Synapses(subgroup1, subgroup2, model='w:1', pre='v += w') syn.connect_one_to_one(post=subgroup2) assert len(syn) == len(subgroup1) syn = Synapses(subgroup1, subgroup2, model='w:1', pre='v += w') syn.connect_one_to_one() assert len(syn) == len(subgroup1) # connect_one_to_one should only work with subgroups of the same size assert_raises(TypeError, lambda: syn.connect_one_to_one(G[:2], G[:1])) # create random connections # the only two cases that can be tested exactly are 0 and 100% connection # probability syn = Synapses(subgroup1, subgroup2, model='w:1', pre='v += w') # floats are interpreted as connection probabilities syn[:, :] = 0.0 assert len(syn) == 0 syn = Synapses(subgroup1, subgroup2, model='w:1', pre='v += w') syn.connect_random(subgroup1, subgroup2, 0.0) assert len(syn) == 0 syn = Synapses(subgroup1, subgroup2, model='w:1', pre='v += w') syn[:, :] = 1.0 assert len(syn) == 10 * 10 # set the weights syn.w[:, :] = 2 # set the delays syn.delay[:, :] = 1 * ms all_weights = np.array([ syn.w[i, j] for i in xrange(len(subgroup1)) for j in xrange(len(subgroup2)) ]) assert (all_weights == 2).all() all_delays = np.array([ syn.delay[i, j] for i in xrange(len(subgroup1)) for j in xrange(len(subgroup2)) ]) assert (all_delays == 1 * ms).all() syn = Synapses(subgroup1, subgroup2, model='w:1', pre='v += w') syn.connect_random(subgroup1, subgroup2, 1.0) assert len(syn) == 10 * 10 # set the weights syn.w[:, :] = 2 # set the delays syn.delay[:, :] = 1 * ms all_weights = np.array([ syn.w[i, j] for i in xrange(len(subgroup1)) for j in xrange(len(subgroup2)) ]) assert (all_weights == 2).all() all_delays = np.array([ syn.delay[i, j] for i in xrange(len(subgroup1)) for j in xrange(len(subgroup2)) ]) assert (all_delays == 1 * ms).all() # Calling connect_random without specifying groups should use the full # source or target group syn = Synapses(subgroup1, subgroup2, model='w:1', pre='v += w') syn.connect_random(subgroup1, sparseness=1.0) assert len(syn) == 10 * 10 syn = Synapses(subgroup1, subgroup2, model='w:1', pre='v += w') syn.connect_random(post=subgroup2, sparseness=1.0) assert len(syn) == 10 * 10 syn = Synapses(subgroup1, subgroup2, model='w:1', pre='v += w') syn.connect_random(sparseness=1.0) assert len(syn) == 10 * 10 # Just test that probabilities between zero and one work at all syn = Synapses(subgroup1, subgroup2, model='w:1', pre='v += w') syn.connect_random(subgroup1, subgroup2, 0.3) syn = Synapses(subgroup1, subgroup2, model='w:1', pre='v += w') syn[:, :] = 0.3 # Test that probabilities outside of the legal range raise an error syn = Synapses(subgroup1, subgroup2, model='w:1', pre='v += w') assert_raises(ValueError, lambda: syn.connect_random(subgroup1, subgroup2, 1.3)) assert_raises(ValueError, lambda: syn.connect_random(subgroup1, subgroup2, -.3)) def wrong_probability(): syn[:, :] = -0.3 assert_raises(ValueError, wrong_probability) def wrong_probability(): #@DuplicatedSignature syn[:, :] = 1.3 assert_raises(ValueError, wrong_probability) # this test requires python 2.6 if sys.version_info[0] >= 2 and sys.version_info[1] >= 6: # Running a model with a synapses object with 0 synapses should raise a warning syn = Synapses(subgroup1, subgroup2, model='w:1', pre='v += w') with warnings.catch_warnings(record=True) as w: # Cause all warnings to always be triggered. warnings.simplefilter("always") # Trigger a warning. syn.compress() # Verify some things assert len(w) == 1 # use arrays as neuron indices instead of slices or ints syn = Synapses(subgroup1, subgroup2, model='w:1', pre='v += w') syn[np.arange(5), np.arange(5)] = True syn.w[np.arange(5), np.arange(5)] = 2 syn.delay[np.arange(5), np.arange(5)] = 5 * ms assert len(syn) == 5 * 5 assert all([syn.w[i, j] == 2 for i in xrange(5) for j in xrange(5)]) assert all( [syn.delay[i, j] == 5 * ms for i in xrange(5) for j in xrange(5)]) assert all([ len(syn.w[i, j]) == 0 for i in xrange(5, len(subgroup1)) for j in xrange(5, len(subgroup2)) ]) assert all([ len(syn.delay[i, j]) == 0 for i in xrange(5, len(subgroup1)) for j in xrange(5, len(subgroup2)) ]) # Create a synapse without a model (e.g. a simple connection with constant # weights syn = Synapses(subgroup1, subgroup2, model='', pre='v+=1')