Example #1
0
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)
Example #2
0
    def __init__(self, N, clock, params=default_params):
        # x=input
        # r=firing rate
        # a=adaptation signal
        # e=efficacy
        # tau_r1 = firing rate rise time constant
        # tau_r2 = firing rate decay rate
        # tau_ar = adaptation rate
        # tau_a = adaptation recovery rate
        # eta = rate - adaptation gain
        eqs=Equations('''
            dr/dt=x/tau_r1-r/tau_r2      : 1
            da/dt=(eta*r)/tau_ar-a/tau_a : 1
            e=1.0-a                      : 1
            tau_a                        : second
            tau_r1                       : second
            tau_r2                       : second
            tau_ar                       : second
            eta                          : 1
            x                            : 1
        ''')
        NeuronGroup.__init__(self, N, model=eqs, compile=True, freeze=True, clock=clock)

        self.N=N
        self.params=params
        self.tau_a=self.params.tau_a
        self.tau_r1=self.params.tau_r1
        self.tau_r2=self.params.tau_r2
        self.tau_ar=self.params.tau_ar
        self.eta=self.params.eta
 def __init__(self, P, V, I, clock=None):
     eqs = Equations('''
     record : units_record
     command : units_command
     ''', units_record=P.unit(V), units_command=P.unit(I))
     NeuronGroup.__init__(self, len(P), model=eqs, clock=clock)
     self._P = P
     self._V = V
     self._I = I
Example #4
0
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 __init__(self, P, V, I, clock=None):
     eqs = Equations('''
     record : units_record
     command : units_command
     ''',
                     units_record=P.unit(V),
                     units_command=P.unit(I))
     NeuronGroup.__init__(self, len(P), model=eqs, clock=clock)
     self._P = P
     self._V = V
     self._I = I
Example #6
0
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'))
Example #7
0
 def __getattr__(self, x):
     if (x != 'morphology') and ((x in self.morphology._namedkid)
                                 or all([c in 'LR123456789'
                                         for c in x])):  # subtree
         return self[x]
     else:
         return NeuronGroup.__getattr__(self, x)
Example #8
0
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()
Example #9
0
    def __init__(self, morphology=None, model=None, threshold=None, reset=NoReset(),
                 refractory=0 * ms, level=0,
                 clock=None, unit_checking=True,
                 compile=False, freeze=False, cm=0.9 * uF / cm ** 2, Ri=150 * ohm * cm):
        clock = guess_clock(clock)
        N = len(morphology) # number of compartments

        # Equations for morphology
        eqs_morphology = Equations("""
        diameter : um
        length : um
        x : um
        y : um
        z : um
        area : um**2
        """)

        # Create the state updater
        if isinstance(model, str):
            model = Equations(model, level=level + 1)
        model += Equations('''
        v:volt # membrane potential
        #Im:amp/cm**2 # membrane current (should we have it?)
        ''')
        full_model = model + eqs_morphology
        Group.__init__(self, full_model, N, unit_checking=unit_checking)
        self._eqs = model
        self._state_updater = SpatialStateUpdater(model, clock)
        var_names = full_model._diffeq_names
        self.cm = cm # could be a vector?
        self.Ri = Ri
        S0 = {}
        # Fill missing units
        for key, value in full_model._units.iteritems():
            if not key in S0:
                S0[key] = 0 * value
        self._S0 = [0] * len(var_names)
        for var, i in zip(var_names, count()):
            self._S0[i] = S0[var]

        NeuronGroup.__init__(self, N, model=self._state_updater, threshold=threshold, reset=reset, refractory=refractory,
                             level=level + 1, clock=clock, unit_checking=unit_checking)

        # Insert morphology
        self.morphology = morphology
        self.morphology.compress(diameter=self.diameter, length=self.length, x=self.x, y=self.y, z=self.z, area=self.area)
Example #10
0
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()
Example #11
0
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 __init__(self, params=default_params, pyr_params=pyr_params(), inh_params=inh_params(),
                 background_input=None, task_inputs=None, clock=defaultclock):
        self.params=params
        self.pyr_params=pyr_params
        self.inh_params=inh_params
        self.background_input=background_input
        self.task_inputs=task_inputs

        ## Set up equations

        # Exponential integrate-and-fire neuron
        eqs = exp_IF(params.C, params.gL, params.EL, params.VT, params.DeltaT)

        eqs += Equations('g_muscimol : nS')
        # AMPA conductance - recurrent input current
        eqs += exp_synapse('g_ampa_r', params.tau_ampa, siemens)
        eqs += Current('I_ampa_r=g_ampa_r*(E-vm): amp', E=params.E_ampa)

        # AMPA conductance - background input current
        eqs += exp_synapse('g_ampa_b', params.tau_ampa, siemens)
        eqs += Current('I_ampa_b=g_ampa_b*(E-vm): amp', E=params.E_ampa)

        # AMPA conductance - task input current
        eqs += exp_synapse('g_ampa_x', params.tau_ampa, siemens)
        eqs += Current('I_ampa_x=g_ampa_x*(E-vm): amp', E=params.E_ampa)

        # Voltage-dependent NMDA conductance
        eqs += biexp_synapse('g_nmda', params.tau1_nmda, params.tau2_nmda, siemens)
        eqs += Equations('g_V = 1/(1+(Mg/3.57)*exp(-0.062 *vm/mV)) : 1 ', Mg=params.Mg)
        eqs += Current('I_nmda=g_V*g_nmda*(E-vm): amp', E=params.E_nmda)

        # GABA-A conductance
        eqs += exp_synapse('g_gaba_a', params.tau_gaba_a, siemens)
        eqs += Current('I_gaba_a=g_gaba_a*(E-vm): amp', E=params.E_gaba_a)

        eqs +=InjectedCurrent('I_dcs: amp')

        NeuronGroup.__init__(self, params.network_group_size, model=eqs, threshold=-20*mV, refractory=1*ms,
            reset=params.Vr, compile=True, freeze=True, clock=clock)

        self.init_subpopulations()

        self.init_connectivity(clock)
Example #13
0
    def __init__(self, source, n_per_channel=1, params=None):
        params = ZhangSynapse._get_parameters(params)
        c_0, c_1 = params['c_0'], params['c_1']
        s_0, s_1 = params['s_0'], params['s_1']
        R_A = params['R_A']
        eqs =  '''
        # time-varying discharge rate, input into this model
        s : Hz
        
        # discharge-history effect (Equation 20 in differential equation form)        
        H = c_0*e_0 + c_1*e_1 : 1
        de_0/dt = -e_0/s_0    : 1
        de_1/dt = -e_1/s_1    : 1

        # final time-varying discharge rate for the Poisson process, equation 19
        R = s * (1 - H) : Hz
        '''
        
        def reset_func(P, spikes):
            P.e_0[spikes] = 1.0
            P.e_1[spikes] = 1.0

        # make sure that the s value is first updated in
        # ZhangSynapseRate, then this NeuronGroup is
        # updated
        clock=Clock(dt=source.clock.dt, t=source.clock.t,
                    order=source.clock.order + 1)
        
        @network_operation(clock=clock, when='start')
        def distribute_input():
            self.s[:] = source.s.repeat(n_per_channel)
        
        NeuronGroup.__init__(self, len(source) * n_per_channel,
                             model=eqs,
                             threshold=PoissonThreshold('R'),
                             reset=CustomRefractoriness(resetfun=reset_func,
                                                        period=R_A),
                             clock=clock
                             )
        
        self.contained_objects += [distribute_input]
Example #14
0
 def __getattr__(self, name):
     if name == 'var_index':
         raise AttributeError
     if not hasattr(self, 'var_index'):
         raise AttributeError
     if (name=='delay_pre') or (name=='delay'): # default: delay is presynaptic delay
         if len(self._delay_pre)>1:
             return [SynapticDelayVariable(delay_pre,self,name) for delay_pre in self._delay_pre]
         else:
             return SynapticDelayVariable(self._delay_pre[0],self,name)
     elif name=='delay_post':
         return SynapticDelayVariable(self._delay_post,self,name)
     try:
         x=self.state(name)
         return SynapticVariable(x,self,name)
     except KeyError:
         return NeuronGroup.__getattr__(self,name)
Example #15
0
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
Example #16
0
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()
Example #17
0
    def __init__(self,
                 params=default_params,
                 pyr_params=pyr_params(),
                 inh_params=inh_params(),
                 plasticity_params=plasticity_params(),
                 background_input=None,
                 task_inputs=None,
                 clock=defaultclock):
        self.params = params
        self.pyr_params = pyr_params
        self.inh_params = inh_params
        self.plasticity_params = plasticity_params
        self.background_input = background_input
        self.task_inputs = task_inputs

        ## Set up equations

        # Exponential integrate-and-fire neuron
        eqs = exp_IF(params.C, params.gL, params.EL, params.VT, params.DeltaT)

        eqs += Equations('g_muscimol : nS')
        # AMPA conductance - recurrent input current
        eqs += exp_synapse('g_ampa_r', params.tau_ampa, siemens)
        eqs += Current('I_ampa_r=g_ampa_r*(E-vm): amp', E=params.E_ampa)

        # AMPA conductance - background input current
        eqs += exp_synapse('g_ampa_b', params.tau_ampa, siemens)
        eqs += Current('I_ampa_b=g_ampa_b*(E-vm): amp', E=params.E_ampa)

        # AMPA conductance - task input current
        eqs += exp_synapse('g_ampa_x', params.tau_ampa, siemens)
        eqs += Current('I_ampa_x=g_ampa_x*(E-vm): amp', E=params.E_ampa)

        # Voltage-dependent NMDA conductance
        eqs += biexp_synapse('g_nmda', params.tau1_nmda, params.tau2_nmda,
                             siemens)
        eqs += Equations('g_V = 1/(1+(Mg/3.57)*exp(-0.062 *vm/mV)) : 1 ',
                         Mg=params.Mg)
        eqs += Current('I_nmda=g_V*g_nmda*(E-vm): amp', E=params.E_nmda)

        # GABA-A conductance
        eqs += exp_synapse('g_gaba_a', params.tau_gaba_a, siemens)
        eqs += Current('I_gaba_a=(g_gaba_a+g_muscimol)*(E-vm): amp',
                       E=params.E_gaba_a)

        eqs += InjectedCurrent('I_dcs: amp')

        # Total synaptic conductance
        eqs += Equations(
            'g_syn=g_ampa_r+g_ampa_x+g_ampa_b+g_V*g_nmda+g_gaba_a : siemens')
        eqs += Equations(
            'g_syn_exc=g_ampa_r+g_ampa_x+g_ampa_b+g_V*g_nmda : siemens')
        # Total synaptic current
        eqs += Equations(
            'I_abs=(I_ampa_r**2)**.5+(I_ampa_b**2)**.5+(I_ampa_x**2)**.5+(I_nmda**2)**.5+(I_gaba_a**2)**.5 : amp'
        )

        NeuronGroup.__init__(self,
                             params.network_group_size,
                             model=eqs,
                             threshold=-20 * mV,
                             refractory=1 * ms,
                             reset=params.Vr,
                             compile=True,
                             freeze=True,
                             clock=clock)

        self.init_subpopulations()

        self.init_connectivity(clock)
Example #18
0
	def __init__(self, morphology=None, model=None, threshold=None, reset=NoReset(),
				refractory=0 * ms, level=0,
				clock=None, unit_checking=True,
				compile=False, freeze=False, implicit=True, Cm=0.9 * uF / cm ** 2, Ri=150 * ohm * cm,
				bc_type = 2, diffeq_nonzero=True):
		clock = guess_clock(clock)
		N = len(morphology) # number of compartments
		
		if isinstance(model, str):
			model = Equations(model, level=level + 1)
		
		model += Equations('''
		v:volt # membrane potential
		''')

		# Process model equations (Im) to extract total conductance and the remaining current
		if use_sympy:
			try:
				membrane_eq=model._string['Im'] # the membrane equation
			except:
				raise TypeError,"The transmembrane current Im must be defined"
			# Check conditional linearity
			ids=get_identifiers(membrane_eq)
			_namespace=dict.fromkeys(ids,1.) # there is a possibility of problems here (division by zero)
			_namespace['v']=AffineFunction()
			eval(membrane_eq,model._namespace['v'],_namespace)
			try:
				eval(membrane_eq,model._namespace['v'],_namespace)
			except: # not linear
				raise TypeError,"The membrane current must be linear with respect to v"
			# Extracts the total conductance from Im, and the remaining current
			z=symbolic_eval(membrane_eq)
			symbol_v=sympy.Symbol('v')
			b=z.subs(symbol_v,0)
			a=-sympy.simplify(z.subs(symbol_v,1)-b)
			gtot_str="_gtot="+str(a)+": siemens/cm**2"
			I0_str="_I0="+str(b)+": amp/cm**2"
			model+=Equations(gtot_str+"\n"+I0_str,level=level+1) # better: explicit insertion with namespace of v
		else:
			raise TypeError,"The Sympy package must be installed for SpatialNeuron"
		
		# Equations for morphology (isn't it a duplicate??)
		eqs_morphology = Equations("""
		diameter : um
		length : um
		x : um
		y : um
		z : um
		area : um**2
		""")
		
		full_model = model + eqs_morphology
		
		NeuronGroup.__init__(self, N, model=full_model, threshold=threshold, reset=reset, refractory=refractory,
							level=level + 1, clock=clock, unit_checking=unit_checking, implicit=implicit)
		self.model_with_diffeq_nonzero = diffeq_nonzero
		self._state_updater = SpatialStateUpdater(self, clock)
		self.Cm = ones(len(self))*Cm
		self.Ri = Ri
		self.bc_type = bc_type #default boundary condition on leaves
		self.bc = ones(len(self)) # boundary conditions on branch points
		self.changed = True
		
		# Insert morphology
		self.morphology = morphology
		self.morphology.compress(diameter=self.diameter, length=self.length, x=self.x, y=self.y, z=self.z, area=self.area)
Example #19
0
	def __getattr__(self, x):
		if (x != 'morphology') and ((x in self.morphology._namedkid) or all([c in 'LR123456789' for c in x])): # subtree
			return self[x]
		else:
			return NeuronGroup.__getattr__(self, x)
Example #20
0
    def __init__(self, source, target = None, model = None, pre = None, post = None,
             max_delay = 0*ms,
             level = 0,
             clock = None,code_namespace=None,
             unit_checking = True, method = None, freeze = False, implicit = False, order = 1): # model (state updater) related
        
        target=target or source # default is target=source

        # Check clocks. For the moment we enforce the same clocks for all objects
        clock = clock or source.clock
        if source.clock!=target.clock:
            raise ValueError,"Source and target groups must have the same clock"

        if pre is None:
            pre_list=[]
        elif isSequenceType(pre) and not isinstance(pre,str): # a list of pre codes
            pre_list=pre
        else:
            pre_list=[pre]

        pre_list=[flattened_docstring(pre) for pre in pre_list]
        if post is not None:
            post=flattened_docstring(post)

        # Pre and postsynaptic indexes (synapse -> pre/post)
        self.presynaptic=DynamicArray1D(0,dtype=smallest_inttype(len(source))) # this should depend on number of neurons
        self.postsynaptic=DynamicArray1D(0,dtype=smallest_inttype(len(target))) # this should depend on number of neurons

        if not isinstance(model,SynapticEquations):
            model=SynapticEquations(model,level=level+1)
        # Insert the lastupdate variable if necessary (if it is mentioned in pre/post, or if there is event-driven code)
        expr=re.compile(r'\blastupdate\b')
        if (len(model._eventdriven)>0) or \
           any([expr.search(pre) for pre in pre_list]) or \
           (post is not None and expr.search(post) is not None):
            model+='\nlastupdate : second\n'
            pre_list=[pre+'\nlastupdate=t\n' for pre in pre_list]
            if post is not None:
                post=post+'\nlastupdate=t\n'
        
        # Identify pre and post variables in the model string
        # They are identified by _pre and _post suffixes
        # or no suffix for postsynaptic variables
        ids=set()
        for RHS in model._string.itervalues():
            ids.update(get_identifiers(RHS))
        pre_ids = [id[:-4] for id in ids if id[-4:]=='_pre']
        post_ids = [id[:-5] for id in ids if id[-5:]=='_post']
        post_vars = [var for var in source.var_index if isinstance(var,str)] # postsynaptic variables
        post_ids2 = list(ids.intersection(set(post_vars))) # post variables without the _post suffix

        # remember whether our equations refer to any variables in the pre- or
        # postsynaptic group. This is important for the state-updater, e.g. the
        # equations can no longer be solved as linear equations.
        model.refers_others = (len(pre_ids) + len(post_ids) + len(post_ids2) > 0)

        # Insert static equations for pre and post variables
        S=self
        for name in pre_ids:
            model.add_eq(name+'_pre', 'S.source.'+name+'[S.presynaptic[:]]', source.unit(name),
                         global_namespace={'S':S})
        for name in post_ids:
            model.add_eq(name+'_post', 'S.target.'+name+'[S.postsynaptic[:]]', target.unit(name),
                         global_namespace={'S':S})
        for name in post_ids2: # we have to change the name of the variable to avoid problems with equation processing
            if name not in model._string: # check that it is not already defined
                model.add_eq(name, 'S.target.state_(__'+name+')[S.postsynaptic[:]]', target.unit(name),
                             global_namespace={'S':S,'__'+name:name})

        self.source=source
        self.target=target
        
        NeuronGroup.__init__(self, 0,model=model,clock=clock,level=level+1,unit_checking=unit_checking,method=method,freeze=freeze,implicit=implicit,order=order)
        '''
        At this point we have:
        * a state matrix _S with all variables
        * units, state dictionary with each value being a row of _S + the static equations
        * subgroups of synapses
        * link_var (i.e. we can link two synapses objects)
        * __len__
        * __setattr__: we can write S.w=array of values
        * var_index is a dictionary from names to row index in _S
        * num_states()
        
        Things we have that we don't want:
        * LS structure (but it will not be filled since the object does not spike)
        * (from Group) __getattr_ needs to be rewritten
        * a complete state updater, but we need to extract parameters and event-driven parts
        * The state matrix is not dynamic
        
        Things we may need to add:
        * _pre and _post suffixes
        '''       
        self._iscompressed=False # True if compress() has already been called
        
        # Look for event-driven code in the differential equations
        if use_sympy:
            eqs=self._eqs # an Equations object
            #vars=eqs._diffeq_names_nonzero # Dynamic variables
            vars=eqs._eventdriven.keys()
            var_set=set(vars)
            for var,RHS in eqs._eventdriven.iteritems():
                ids=get_identifiers(RHS)
                if len(set(list(ids)+[var]).intersection(var_set))==1:
                    # no external dynamic variable
                    # Now we test if it is a linear equation
                    _namespace=dict.fromkeys(ids,1.) # there is a possibility of problems here (division by zero)
                    # plus units problems? (maybe not since these are identifiers too)
                    # another option is to use random numbers, but that doesn't solve all problems
                    _namespace[var]=AffineFunction()
                    try:
                        eval(RHS,eqs._namespace[var],_namespace)
                    except: # not linear
                        raise TypeError,"Cannot turn equation for "+var+" into event-driven code"
                    z=symbolic_eval(RHS)
                    symbol_var=sympy.Symbol(var)
                    symbol_t=sympy.Symbol('t')-sympy.Symbol('lastupdate')
                    b=z.subs(symbol_var,0)
                    a=sympy.simplify(z.subs(symbol_var,1)-b)
                    if a==0:
                        expr=symbol_var+b*symbol_t
                    else:
                        expr=-b/a+sympy.exp(a*symbol_t)*(symbol_var+b/a)
                    expr=var+'='+str(expr)
                    # Replace pre and post code
                    # N.B.: the differential equations are kept, we will probably want to remove them!
                    pre_list=[expr+'\n'+pre for pre in pre_list]
                    if post is not None:
                        post=expr+'\n'+post
                else:
                    raise TypeError,"Cannot turn equation for "+var+" into event-driven code"
        elif len(self._eqs._eventdriven)>0:
            raise TypeError,"The Sympy package must be installed to produce event-driven code"

        if len(self._eqs._diffeq_names_nonzero)==0:
            self._state_updater=None
        
        # Set last spike to -infinity
        if 'lastupdate' in self.var_index:
            self.lastupdate=-1e6
        # _S is turned to a dynamic array - OK this is probably not good! we may lose references at this point
        S=self._S
        self._S=DynamicArray(S.shape)
        self._S[:]=S

        # Pre and postsynaptic delays (synapse -> delay_pre/delay_post)
        self._delay_pre=[DynamicArray1D(len(self),dtype=np.int16) for _ in pre_list] # max 32767 delays
        self._delay_post=DynamicArray1D(len(self),dtype=np.int16) # Actually only useful if there is a post code!
        
        # Pre and postsynaptic synapses (i->synapse indexes)
        max_synapses=2147483647 # it could be explicitly reduced by a keyword
        # We use a loop instead of *, otherwise only 1 dynamic array is created
        self.synapses_pre=[DynamicArray1D(0,dtype=smallest_inttype(max_synapses)) for _ in range(len(self.source))]
        self.synapses_post=[DynamicArray1D(0,dtype=smallest_inttype(max_synapses)) for _ in range(len(self.target))]

        # Code generation
        self._binomial = lambda n,p:np.random.binomial(np.array(n,dtype=int),p)

        self.contained_objects = []
        self.codes=[]
        self.namespaces=[]
        self.queues=[]
        for i,pre in enumerate(pre_list):
            code,_namespace=self.generate_code(pre,level+1,code_namespace=code_namespace)
            self.codes.append(code)
            self.namespaces.append(_namespace)
            self.queues.append(SpikeQueue(self.source, self.synapses_pre, self._delay_pre[i], max_delay = max_delay))
        
        if post is not None:
            code,_namespace=self.generate_code(post,level+1,direct=True,code_namespace=code_namespace)
            self.codes.append(code)
            self.namespaces.append(_namespace)
            self.queues.append(SpikeQueue(self.target, self.synapses_post, self._delay_post, max_delay = max_delay))

        self.queues_namespaces_codes = zip(self.queues,
                                           self.namespaces,
                                           self.codes)

        self.contained_objects+=self.queues
Example #21
0
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
Example #22
0
    def __init__(self, morphology=None, model=None, threshold=None, reset=NoReset(),
                 refractory=0 * ms, level=0,
                 clock=None, unit_checking=True,
                 compile=False, freeze=False, Cm=0.9 * uF / cm ** 2, Ri=150 * ohm * cm):
        clock = guess_clock(clock)
        N = len(morphology) # number of compartments

        if isinstance(model, str):
            model = Equations(model, level=level + 1)

        model += Equations('''
        v:volt # membrane potential
        ''')

        # Process model equations (Im) to extract total conductance and the remaining current
        if use_sympy:
            try:
                membrane_eq=model._string['Im'] # the membrane equation
            except:
                raise TypeError,"The transmembrane current Im must be defined"
            # Check conditional linearity
            ids=get_identifiers(membrane_eq)
            _namespace=dict.fromkeys(ids,1.) # there is a possibility of problems here (division by zero)
            _namespace['v']=AffineFunction()
            eval(membrane_eq,model._namespace['v'],_namespace)
            try:
                eval(membrane_eq,model._namespace['v'],_namespace)
            except: # not linear
                raise TypeError,"The membrane current must be linear with respect to v"
            # Extracts the total conductance from Im, and the remaining current
            z=symbolic_eval(membrane_eq)
            symbol_v=sympy.Symbol('v')
            b=z.subs(symbol_v,0)
            a=-sympy.simplify(z.subs(symbol_v,1)-b)
            gtot_str="_gtot="+str(a)+": siemens/cm**2"
            I0_str="_I0="+str(b)+": amp/cm**2"
            model+=Equations(gtot_str+"\n"+I0_str,level=level+1) # better: explicit insertion with namespace of v
        else:
            raise TypeError,"The Sympy package must be installed for SpatialNeuron"

        # Equations for morphology (isn't it a duplicate??)
        eqs_morphology = Equations("""
        diameter : um
        length : um
        x : um
        y : um
        z : um
        area : um**2
        """)

        full_model = model + eqs_morphology

        # Create the state updater
        NeuronGroup.__init__(self, N, model=full_model, threshold=threshold, reset=reset, refractory=refractory,
                             level=level + 1, clock=clock, unit_checking=unit_checking, implicit=True)

        #Group.__init__(self, full_model, N, unit_checking=unit_checking, level=level+1)
        #self._eqs = model
        #var_names = full_model._diffeq_names
        self.Cm = Cm # could be a vector?
        self.Ri = Ri
        self._state_updater = SpatialStateUpdater(self, clock)
        #S0 = {}
        # Fill missing units
        #for key, value in full_model._units.iteritems():
        #    if not key in S0:
        #        S0[key] = 0 * value
        #self._S0 = [0] * len(var_names)
        #for var, i in zip(var_names, count()):
        #    self._S0[i] = S0[var]

        # Insert morphology
        self.morphology = morphology
        self.morphology.compress(diameter=self.diameter, length=self.length, x=self.x, y=self.y, z=self.z, area=self.area)
        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()
Example #24
0
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')
Example #25
0
    def __init__(self,
                 morphology=None,
                 model=None,
                 threshold=None,
                 reset=NoReset(),
                 refractory=0 * ms,
                 level=0,
                 clock=None,
                 unit_checking=True,
                 compile=False,
                 freeze=False,
                 Cm=0.9 * uF / cm**2,
                 Ri=150 * ohm * cm):
        clock = guess_clock(clock)
        N = len(morphology)  # number of compartments

        if isinstance(model, str):
            model = Equations(model, level=level + 1)

        model += Equations('''
        v:volt # membrane potential
        ''')

        # Process model equations (Im) to extract total conductance and the remaining current
        if use_sympy:
            try:
                membrane_eq = model._string['Im']  # the membrane equation
            except:
                raise TypeError, "The transmembrane current Im must be defined"
            # Check conditional linearity
            ids = get_identifiers(membrane_eq)
            _namespace = dict.fromkeys(
                ids, 1.
            )  # there is a possibility of problems here (division by zero)
            _namespace['v'] = AffineFunction()
            eval(membrane_eq, model._namespace['v'], _namespace)
            try:
                eval(membrane_eq, model._namespace['v'], _namespace)
            except:  # not linear
                raise TypeError, "The membrane current must be linear with respect to v"
            # Extracts the total conductance from Im, and the remaining current
            z = symbolic_eval(membrane_eq)
            symbol_v = sympy.Symbol('v')
            b = z.subs(symbol_v, 0)
            a = -sympy.simplify(z.subs(symbol_v, 1) - b)
            gtot_str = "_gtot=" + str(a) + ": siemens/cm**2"
            I0_str = "_I0=" + str(b) + ": amp/cm**2"
            model += Equations(
                gtot_str + "\n" + I0_str, level=level +
                1)  # better: explicit insertion with namespace of v
        else:
            raise TypeError, "The Sympy package must be installed for SpatialNeuron"

        # Equations for morphology (isn't it a duplicate??)
        eqs_morphology = Equations("""
        diameter : um
        length : um
        x : um
        y : um
        z : um
        area : um**2
        """)

        full_model = model + eqs_morphology

        # Create the state updater
        NeuronGroup.__init__(self,
                             N,
                             model=full_model,
                             threshold=threshold,
                             reset=reset,
                             refractory=refractory,
                             level=level + 1,
                             clock=clock,
                             unit_checking=unit_checking,
                             implicit=True)

        #Group.__init__(self, full_model, N, unit_checking=unit_checking, level=level+1)
        #self._eqs = model
        #var_names = full_model._diffeq_names
        self.Cm = Cm  # could be a vector?
        self.Ri = Ri
        self._state_updater = SpatialStateUpdater(self, clock)
        #S0 = {}
        # Fill missing units
        #for key, value in full_model._units.iteritems():
        #    if not key in S0:
        #        S0[key] = 0 * value
        #self._S0 = [0] * len(var_names)
        #for var, i in zip(var_names, count()):
        #    self._S0[i] = S0[var]

        # Insert morphology
        self.morphology = morphology
        self.morphology.compress(diameter=self.diameter,
                                 length=self.length,
                                 x=self.x,
                                 y=self.y,
                                 z=self.z,
                                 area=self.area)
Example #26
0
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
Example #27
0
    def __init__(self,
                 morphology=None,
                 model=None,
                 threshold=None,
                 reset=NoReset(),
                 refractory=0 * ms,
                 level=0,
                 clock=None,
                 unit_checking=True,
                 compile=False,
                 freeze=False,
                 implicit=True,
                 Cm=0.9 * uF / cm**2,
                 Ri=150 * ohm * cm,
                 bc_type=2,
                 diffeq_nonzero=True):
        clock = guess_clock(clock)
        N = len(morphology)  # number of compartments

        if isinstance(model, str):
            model = Equations(model, level=level + 1)

        model += Equations('''
		v:volt # membrane potential
		''')

        # Process model equations (Im) to extract total conductance and the remaining current
        if use_sympy:
            try:
                membrane_eq = model._string['Im']  # the membrane equation
            except:
                raise TypeError, "The transmembrane current Im must be defined"
            # Check conditional linearity
            ids = get_identifiers(membrane_eq)
            _namespace = dict.fromkeys(
                ids, 1.
            )  # there is a possibility of problems here (division by zero)
            _namespace['v'] = AffineFunction()
            eval(membrane_eq, model._namespace['v'], _namespace)
            try:
                eval(membrane_eq, model._namespace['v'], _namespace)
            except:  # not linear
                raise TypeError, "The membrane current must be linear with respect to v"
            # Extracts the total conductance from Im, and the remaining current
            z = symbolic_eval(membrane_eq)
            symbol_v = sympy.Symbol('v')
            b = z.subs(symbol_v, 0)
            a = -sympy.simplify(z.subs(symbol_v, 1) - b)
            gtot_str = "_gtot=" + str(a) + ": siemens/cm**2"
            I0_str = "_I0=" + str(b) + ": amp/cm**2"
            model += Equations(
                gtot_str + "\n" + I0_str, level=level +
                1)  # better: explicit insertion with namespace of v
        else:
            raise TypeError, "The Sympy package must be installed for SpatialNeuron"

        # Equations for morphology (isn't it a duplicate??)
        eqs_morphology = Equations("""
		diameter : um
		length : um
		x : um
		y : um
		z : um
		area : um**2
		""")

        full_model = model + eqs_morphology

        NeuronGroup.__init__(self,
                             N,
                             model=full_model,
                             threshold=threshold,
                             reset=reset,
                             refractory=refractory,
                             level=level + 1,
                             clock=clock,
                             unit_checking=unit_checking,
                             implicit=implicit)
        self.model_with_diffeq_nonzero = diffeq_nonzero
        self._state_updater = SpatialStateUpdater(self, clock)
        self.Cm = ones(len(self)) * Cm
        self.Ri = Ri
        self.bc_type = bc_type  #default boundary condition on leaves
        self.bc = ones(len(self))  # boundary conditions on branch points
        self.changed = True

        # Insert morphology
        self.morphology = morphology
        self.morphology.compress(diameter=self.diameter,
                                 length=self.length,
                                 x=self.x,
                                 y=self.y,
                                 z=self.z,
                                 area=self.area)
Example #28
0
    def __init__(
        self,
        params=default_params,
        pyr_params=pyr_params(),
        inh_params=inh_params(),
        plasticity_params=plasticity_params(),
        background_input=None,
        task_inputs=None,
        clock=defaultclock,
    ):
        self.params = params
        self.pyr_params = pyr_params
        self.inh_params = inh_params
        self.plasticity_params = plasticity_params
        self.background_input = background_input
        self.task_inputs = task_inputs

        ## Set up equations

        # Exponential integrate-and-fire neuron
        eqs = exp_IF(params.C, params.gL, params.EL, params.VT, params.DeltaT)

        eqs += Equations("g_muscimol : nS")
        # AMPA conductance - recurrent input current
        eqs += exp_synapse("g_ampa_r", params.tau_ampa, siemens)
        eqs += Current("I_ampa_r=g_ampa_r*(E-vm): amp", E=params.E_ampa)

        # AMPA conductance - background input current
        eqs += exp_synapse("g_ampa_b", params.tau_ampa, siemens)
        eqs += Current("I_ampa_b=g_ampa_b*(E-vm): amp", E=params.E_ampa)

        # AMPA conductance - task input current
        eqs += exp_synapse("g_ampa_x", params.tau_ampa, siemens)
        eqs += Current("I_ampa_x=g_ampa_x*(E-vm): amp", E=params.E_ampa)

        # Voltage-dependent NMDA conductance
        eqs += biexp_synapse("g_nmda", params.tau1_nmda, params.tau2_nmda, siemens)
        eqs += Equations("g_V = 1/(1+(Mg/3.57)*exp(-0.062 *vm/mV)) : 1 ", Mg=params.Mg)
        eqs += Current("I_nmda=g_V*g_nmda*(E-vm): amp", E=params.E_nmda)

        # GABA-A conductance
        eqs += exp_synapse("g_gaba_a", params.tau_gaba_a, siemens)
        eqs += Current("I_gaba_a=(g_gaba_a+g_muscimol)*(E-vm): amp", E=params.E_gaba_a)

        eqs += InjectedCurrent("I_dcs: amp")

        # Total synaptic conductance
        eqs += Equations("g_syn=g_ampa_r+g_ampa_x+g_ampa_b+g_V*g_nmda+g_gaba_a : siemens")
        eqs += Equations("g_syn_exc=g_ampa_r+g_ampa_x+g_ampa_b+g_V*g_nmda : siemens")
        # Total synaptic current
        eqs += Equations(
            "I_abs=(I_ampa_r**2)**.5+(I_ampa_b**2)**.5+(I_ampa_x**2)**.5+(I_nmda**2)**.5+(I_gaba_a**2)**.5 : amp"
        )

        NeuronGroup.__init__(
            self,
            params.network_group_size,
            model=eqs,
            threshold=-20 * mV,
            refractory=1 * ms,
            reset=params.Vr,
            compile=True,
            freeze=True,
            clock=clock,
        )

        self.init_subpopulations()

        self.init_connectivity(clock)