Example #1
0
def test_ExportDevice_options():
    """
    Test the run and build options of ExportDevice
    """
    # test1
    set_device('exporter')
    grp = NeuronGroup(10, 'eqn = 1:1', method='exact')
    run(100 * ms)
    _ = StateMonitor(grp, 'eqn', record=False)
    with pytest.raises(RuntimeError):
        run(100 * ms)

    # test2
    device.reinit()
    with pytest.raises(RuntimeError):
        device.build()

    # test3
    start_scope()
    net = Network()
    set_device('exporter', build_on_run=False)
    grp = NeuronGroup(10, 'eqn = 1:1', method='exact')
    net.add(grp)
    net.run(10 * ms)
    pogrp = PoissonGroup(10, rates=10 * Hz)
    net.add(pogrp)
    net.run(10 * ms)
    mon = StateMonitor(grp, 'eqn', record=False)
    net.add(mon)
    net.run(10 * ms)
    device.build()
    device.reinit()
Example #2
0
def cramer_noise(tr, GExc: NeuronGroup, GInh: NeuronGroup) -> [BrianObject]:
    """
        Noise inspired by Cramer et al. 2020 (preprint) where a certain number Kext of incoming
        connections to each neuron is replaced by external noise.

        Related parameters:

        - :data:`net.standard_params.cramer_noise_active`
        - :data:`net.standard_params.cramer_noise_Kext`
        - :data:`net.standard_params.cramer_noise_rate`
    """

    namespace = tr.netw.f_to_dict(short_names=True, fast_access=True)
    N = tr.N_e
    Kext = tr.cramer_noise_Kext
    p_ee_target = tr.p_ee / (1 - Kext)
    p_ie_target = tr.p_ie / (1 - Kext)
    conductance_prefix = "" if tr.syn_cond_mode == "exp" else "x"

    GNoise = PoissonGroup(N, rates=tr.cramer_noise_rate, dt=0.1 * ms)
    SynNoiseE = Synapses(source=GNoise,
                         target=GExc,
                         on_pre=f"{conductance_prefix}ge_post += a_ee",
                         namespace=namespace)
    SynNoiseE.connect(p=Kext * p_ee_target)
    SynNoiseI = Synapses(source=GNoise,
                         target=GInh,
                         on_pre=f"{conductance_prefix}ge_post += a_ie",
                         namespace=namespace)
    SynNoiseI.connect(p=Kext * p_ie_target)

    return [GNoise, SynNoiseE, SynNoiseI]
Example #3
0
def echo_spike(p, tStim, tTot):
    start_scope()
    prefs.codegen.target = "numpy"

    ################################
    # Compute properties
    ################################
    dvInpSpike = p['nu_DV']   # Voltage increase per noise spike
    dvExcSpike = p['LIF_DV']  # Voltage increase per lateral spike
    # dvExcSpike = p['LIF_T_0'] / (1.0 * p['N'] * p['p_conn'])  # Voltage increase per lateral spike

    print("typical spike threshold", p['LIF_T_0'])
    print("typical potential change per noise spike", dvInpSpike)
    print("typical potential change per lateral spike", dvExcSpike)

    ################################
    # Create input population
    ################################
    nTStimPost = int(tTot / tStim) - 1  # After input switched off, 0-input will be repeated nTStimPost*tStim timesteps
    patternInp = (np.random.uniform(0, 1, p['N']) < p['nu_p']).astype(int)
    pattern0 = np.zeros(p['N'])
    rates_all = np.array([patternInp] + [pattern0]*nTStimPost) * p['nu_FREQ']
    rateTimedArray = TimedArray(rates_all, dt=tStim)
    gInp = PoissonGroup(p['N'], rates="rateTimedArray(t, i)")
    # gInp = PoissonGroup(p['N'], p['nu_FREQ'])

    ################################
    # Create reservoir population
    ################################
    gExc = brian2wrapper.NeuronGroupLIF(p['N'], p['LIF_V_0'], p['LIF_T_0'], p['LIF_V_TAU'])

    ################################
    # Create synapses
    ################################
    sInpExc = Synapses(gInp, gExc, on_pre='v_post += dvInpSpike', method='exact')
    sExcExc = Synapses(gExc, gExc, on_pre='v_post += dvExcSpike', method='exact')

    ################################
    # Connect synapses
    ################################
    # * Input and LIF one-to-one
    # * LIF neurons to each other sparsely
    sInpExc.connect(j='i')
    sExcExc.connect(p=p['p_conn'])

    ################################
    # Init Monitors
    ################################
    #spikemonInp = SpikeMonitor(gInp)
    spikemonExc = SpikeMonitor(gExc)

    ################################
    # Run simulation
    ################################
    run(tTot)

    return np.array(spikemonExc.i), np.array(spikemonExc.t)
    def construct_headings_cosine(self, h, v):
        headings = cx_spiking.inputs.compute_cos_headings(h,
                                                          N=self.N_TL2,
                                                          vmin=5,
                                                          vmax=100)

        self.headings_hz = headings * Hz
        self.P_HEADING = PoissonGroup(self.N_TL2,
                                      rates=self.headings_hz[0, :],
                                      name='P_HEADING')

        return self.P_HEADING
    def initialise_memory_accumulator(self):
        self.CPU4_memory_stimulus = CPU_MEMORY_starting_value * np.ones(
            (self.T, self.N_CPU4)) * Hz
        self.P_CPU4_MEMORY = PoissonGroup(
            self.N_CPU4,
            rates=self.CPU4_memory_stimulus[0, :],
            name='P_CPU4_MEMORY')

        self.SPM_CPU4_MEMORY = SpikeMonitor(self.P_CPU4_MEMORY,
                                            name='SPM_P_CPU4_MEMORY')

        return [self.P_CPU4_MEMORY, self.SPM_CPU4_MEMORY]
Example #6
0
def test_simple_syntax():
    """
    Simple example
    """
    set_device('markdown')
    N = 10
    tau = 10 * ms
    v_th = 0.9 * volt
    v_rest = -79 * mV
    eqn = 'dv/dt = (v_th - v)/tau :volt'
    refractory = 'randn() * tau / N'
    rates = 'rand() * 5 * Hz'
    group = NeuronGroup(N, eqn, method='euler', threshold='v > v_th',
                        reset='v = v_rest; v = rand() * v_rest',
                        refractory=refractory,
                        events={'custom': 'v > v_th + 10 * mV',
                        'custom_1': 'v > v_th - 10 * mV'})
    group.run_on_event('custom', 'v = v_rest')
    group.run_on_event('custom_1', 'v = v_rest - 0.001 * mV')
    spikegen = SpikeGeneratorGroup(N, [0, 1, 2], [1, 2, 3] * ms,
                                   period=5 * ms)
    po_grp = PoissonGroup(N - 1, rates=rates)
    syn = Synapses(spikegen, group, model='w :volt',
                   on_pre='v = rand() * w + v_th; v = rand() * w',
                   on_post='v = rand() * w + v_rest; v = rand() * w',
                   delay=tau, method='euler')
    group.v[:] = v_rest
    group.v['i%2 == 0'] = 'rand() * v_rest'
    group.v[0:5] = 'v_rest + 10 * mV'
    condition = 'abs(i-j)<=5'
    syn.connect(condition=condition, p=0.999, n=2)
    syn.w = '1 * mV'
    net = Network(group, spikegen, po_grp, syn)
    mon = StateMonitor(syn, 'w', record=True)
    mon2 = SpikeMonitor(po_grp)
    mon3 = EventMonitor(group, 'custom')
    net.add(mon, mon2, mon3)
    net.run(0.01 * ms)
    md_str = device.md_text
    assert _markdown_lint(md_str)
    check = 'randn({sin({$w$}|$v_rest$ - $v$|/{\tau}})})'
    assert _markdown_lint(check)
    # check invalid strings
    with pytest.raises(SyntaxError):
        check = '**Initializing values at starting:*'
        assert _markdown_lint(check)
        check = '- Variable v$ of with $-79. mV$ to all members'
        assert _markdown_lint(check)
        check = 'randn({sin(})})'
        assert _markdown_lint(check)
        check = 'randn({sin({$w$}|$v_rest$ - $v$|/{\tau})})'
        assert _markdown_lint(check)
    device.reinit()
    def construct_headings_vonmises(self, h, v):
        headings = cx_spiking.inputs.compute_headings(h,
                                                      N=self.N_TL2 // 2,
                                                      vmin=5,
                                                      vmax=100)
        headings = np.tile(headings, 2)

        self.headings_hz = headings * Hz
        self.P_HEADING = PoissonGroup(self.N_TL2,
                                      rates=self.headings_hz[0, :],
                                      name='P_HEADING')

        return self.P_HEADING
Example #8
0
def test_magic_collect():
    '''
    Make sure all expected objects are collected in a magic network
    '''
    P = PoissonGroup(10, rates=100*Hz)
    G = NeuronGroup(10, 'v:1', threshold='False')
    S = Synapses(G, G, '')

    state_mon = StateMonitor(G, 'v', record=True)
    spike_mon = SpikeMonitor(G)
    rate_mon = PopulationRateMonitor(G)

    objects = collect()

    assert len(objects) == 6, ('expected %d objects, got %d' % (6, len(objects)))
    def construct_flow(self, h, v):
        # Convert velocity into optical flow responses
        flow = cx_spiking.inputs.compute_flow(h,
                                              v,
                                              baseline=50,
                                              vmin=0,
                                              vmax=50)
        # flow = np.concatenate((flow, np.zeros((self.T_inbound, flow.shape[1]))), axis=0)

        self.flow_hz = flow * Hz
        self.P_FLOW = PoissonGroup(self.N_TN2,
                                   rates=self.flow_hz[0, :],
                                   name='P_FLOW')

        return self.P_FLOW
Example #10
0
def test_spikemonitor():
    """
    Test collector function for SpikeMonitor
    """

    # example 1
    grp = NeuronGroup(5,
                      '''dv/dt = (v0 - v)/tau :volt''',
                      method='exact',
                      threshold='v > v_th',
                      reset='v = v0',
                      name="My_Neurons")
    tau = 10 * ms
    v0 = -70 * mV
    v_th = 800 * mV
    mon = SpikeMonitor(grp, 'v', record=[0, 4])
    mon_dict = collect_SpikeMonitor(mon)

    assert mon_dict['source'] == 'My_Neurons'
    assert mon_dict['variables'].sort() == ['i', 't', 'v'].sort()
    assert mon_dict['record'] == [0, 4]
    assert mon_dict['event'] == 'spike'
    assert mon_dict['when'] == 'thresholds'
    assert mon_dict['order'] == 1

    # example 2
    pos = PoissonGroup(5, rates=100 * Hz)
    smon = SpikeMonitor(pos, record=[0, 1, 2, 3, 4])
    smon_dict = collect_SpikeMonitor(smon)

    assert smon_dict['source'] == pos.name
    assert 'i' in smon_dict['variables']

    assert smon_dict['record'] == [0, 1, 2, 3, 4]
    assert smon_dict['when'] == 'thresholds'
    assert smon_dict['order'] == 1

    # example 3
    spk = SpikeGeneratorGroup(10, [2, 6, 8], [5 * ms, 10 * ms, 15 * ms])
    spkmon = SpikeMonitor(spk, ['t', 'i'], record=0)
    smon_dict = collect_SpikeMonitor(spkmon)

    assert smon_dict['record'] == np.array([0])
    assert 't' in smon_dict['variables']
    assert smon_dict['source'] == spk.name
    assert smon_dict['when'] == 'thresholds'
    assert smon_dict['order'] == 1
Example #11
0
def test_magic_collect():
    '''
    Make sure all expected objects are collected in a magic network
    '''
    P = PoissonGroup(10, rates=100 * Hz)
    G = NeuronGroup(10, 'v:1')
    S = Synapses(G, G, '')
    G_runner = G.custom_operation('')
    S_runner = S.custom_operation('')

    state_mon = StateMonitor(G, 'v', record=True)
    spike_mon = SpikeMonitor(G)
    rate_mon = PopulationRateMonitor(G)

    objects = collect()

    assert len(objects) == 8, ('expected %d objects, got %d' %
                               (8, len(objects)))
Example #12
0
def test_custom_expander():
    """
    Test custom expander class
    """
    class Custom(MdExpander):

        def expand_NeuronGroup(self, grp_dict):
            idt = self.expand_identifiers(grp_dict['identifiers'])
            return "This is my custom neurongroup: " + grp_dict['name'] + idt

        def expand_StateMonitor(self, mon_dict):
            return "I monitor " + mon_dict['source']

        def expand_identifiers(self, identifiers):
            return 'Identifiers are not shown'

    custom_expander = Custom(brian_verbose=True)
    set_device('markdown', expander=custom_expander)
    # check custom expander
    v_rest = -79 * mV
    rate = 10 * Hz
    grp = NeuronGroup(10, 'v = v_rest:volt')
    mon = StateMonitor(grp, 'v', record=True)
    pog = PoissonGroup(10, rates=rate)
    run(0.1*ms)
    text = device.md_text
    assert _markdown_lint(text)
    # brian_verbose check
    assert 'NeuronGroup' in text
    assert 'StateMonitor' in text
    assert 'Activity recorder' not in text
    assert 'Initializing' in text
    assert 'Identifiers are not shown' in text
    assert 'I monitor ' in text
    assert 'This is my custom neurongroup: neurongroup' in text
    device.reinit()
def test_poissongroup():
    """
    Test standard dictionary representation of PoissonGroup
    """

    # example1
    N = 10
    rates = numpy.arange(1, 11, step=1) * Hz

    poisongrp = PoissonGroup(N, rates)
    poisson_dict = collect_PoissonGroup(poisongrp, get_local_namespace(0))

    assert poisson_dict['N'] == N

    assert (poisson_dict['rates'] == rates).all()
    assert poisson_dict['rates'].has_same_dimensions(5 * Hz)
    assert poisson_dict['rates'].dtype == float

    with pytest.raises(KeyError):
        assert poisson_dict['run_regularly']

    # example2
    F = 10 * Hz
    three = 3 * Hz
    two = 2 * Hz
    poisongrp = PoissonGroup(N, rates='F + two')
    poisongrp.run_regularly('F = F + three', dt=10 * ms,
                            name="Run_at_0_01")
    poisson_dict = collect_PoissonGroup(poisongrp, get_local_namespace(0))

    assert poisson_dict['rates'] == 'F + two'
    assert poisson_dict['run_regularly'][0]['name'] == 'Run_at_0_01'
    assert poisson_dict['run_regularly'][0]['code'] == 'F = F + three'
    assert poisson_dict['run_regularly'][0]['dt'] == 10 * ms
    assert poisson_dict['run_regularly'][0]['when'] == 'start'
    assert poisson_dict['run_regularly'][0]['order'] == 0

    assert poisson_dict['identifiers']['three'] == three
    assert poisson_dict['identifiers']['two'] == two

    with pytest.raises(IndexError):
        poisson_dict['run_regularly'][1]
Example #14
0
def mk_sencircuit_2cplastic(task_info):
    """
    Creates balanced network representing sensory circuit with 2c model in the excitatory neurons.

    returns:
        groups, synapses, subgroups

    groups and synapses have to be added to the "Network" in order to run the simulation
    subgroups is used for establishing connections between the sensory and integration circuit;
    do not add subgroups to the "Network"


    psr following the published Brian1 code in DB model from Wimmer et al. 2015
    - brain2 code
    - two-compartmental model following Naud & Sprekeler 2018
    - implementation runs in cpp_standalone mode, compatible with SNEP
    """
    from numpy import log as np_log

    # -------------------------------------
    # Sensory circuit parameters
    # -------------------------------------
    # populations
    N_E = task_info['sen']['populations']['N_E']  # total number of E neurons
    sub = task_info['sen']['populations']['sub']  # fraction corresponding to subpops 1,2
    N_E1 = int(N_E * sub)  # size of exc subpops that responds to the stimuli
    N_I = task_info['sen']['populations']['N_I']  # total number of I neurons
    N_X = task_info['sen']['populations']['N_X']  # size of external pop

    # local recurrent connections
    eps = task_info['sen']['connectivity']['eps']  # connection probability for EE, EI, IE and II
    w_p = task_info['sen']['connectivity']['w_p']  # relative synaptic strength within pop E1 and E2
    w_m = 2 - w_p  # relative synaptic strength across pop E1 and E2
    gEEs = task_info['sen']['2c']['gEEs']  # weight of EE synapses, prev: 0.7589*nS
    gEI = task_info['sen']['connectivity']['gEI']  # weight of EI synapses, prev: 1.5179*nS
    gIEs = task_info['sen']['2c']['gIEs']  # weight of IE synapses, prev: 12.6491*nS
    gII = task_info['sen']['connectivity']['gII']  # weight of II synapses
    gmax = task_info['sen']['connectivity']['gmax']  # maximum synaptic weight
    dE = '0.5*ms + rand()*1.0*ms'  # range of transmission delays of E synapses, (0.5:1.5)
    dI = '0.1*ms + rand()*0.8*ms'  # range of transmission delays of I synapses, (0.1:0.9)

    # external connections
    epsX = task_info['sen']['connectivity']['epsX']         # connection probability for ext synapses
    alphaX = task_info['sen']['connectivity']['alphaX']     # 0: global input, 1: local input
    gXEs = task_info['sen']['2c']['gXEs']                   # weight of ext to E synapses of soma
    gXI = task_info['sen']['connectivity']['gXI']           # weight of ext to I synapses
    dX = '0.5*ms + rand()*1.0*ms'  # range of transmission delays of X synapses, (0.5:1.5)

    # neuron model
    CmI = task_info['sen']['neuron']['CmI']  # membrane capacitance of I neurons
    gleakI = task_info['sen']['neuron']['gleakI']  # leak conductance of I neurons
    Vl = task_info['sen']['neuron']['Vl']  # reversal potential
    Vt = task_info['sen']['neuron']['Vt']  # threshold potential
    Vr = task_info['sen']['neuron']['Vr']  # reset potential, only for inh
    tau_refI = task_info['sen']['neuron']['tau_refI']  # absolute refractory period of I neurons
    nu_ext = task_info['sen']['neuron']['nu_ext']  # rate of external Poisson neurons, prev: 12.5*Hz

    # soma
    taus = task_info['sen']['2c']['taus']  # timescale of membrane potential
    Cms = task_info['sen']['2c']['Cms']  # capacitance
    gleakEs = Cms/taus
    tauws = task_info['sen']['2c']['tauws']  # timescale of recovery ("slow") variable
    bws = task_info['sen']['2c']['bws']  # strength of spike-triggered facilitation (bws < 0)
    gCas = task_info['sen']['2c']['gCas']  # strenght of forward calcium spike propagation
    tau_refE = task_info['sen']['2c']['tau_refE']  # refractory period

    # dendrite
    taud = task_info['sen']['2c']['taud']
    Cmd = task_info['sen']['2c']['Cmd']
    gleakEd = Cmd/taud
    tauwd = task_info['sen']['2c']['tauwd']  # timescale of recovery ("slow") variable
    awd = task_info['sen']['2c']['awd']  # stregth of subthreshold facilitations (awd < 0)
    gCad = task_info['sen']['2c']['gCad']  # strength of local regenerative activity
    bpA = task_info['sen']['2c']['bpA']  # strength of backpropagation activity (c variable)
    k1 = task_info['sen']['2c']['k1']  # rectangular kernel for backpropagating activity
    k2 = task_info['sen']['2c']['k2']  # if t in [0.5, 2.0] we'll have backpropagating current
    muOUs = task_info['sen']['2c']['muOUs']    # OU parameters for background noise of soma
    #muOUd = task_info['sen']['2c']['muOUd']    # OU parameters for background noise of dendrites
    sigmaOU = task_info['sen']['2c']['sigmaOU']
    tauOU = task_info['sen']['2c']['tauOU']

    # synapse models
    VrevE = task_info['sen']['synapse']['VrevE']  # reversal potential for E synapses
    VrevI = task_info['sen']['synapse']['VrevI']  # reversal potential for I synapses in inh
    tau_decay = task_info['sen']['synapse']['tau_decay']  # decay constant of AMPA, GABA
    tau_rise = task_info['sen']['synapse']['tau_rise']    # rise constant of AMPA, GABA  for inh
    VrevIsd = task_info['sen']['synapse']['VrevIsd'] # rev potential for I synapses in soma, dend

    # plasticity in dendrites
    eta0 = task_info['sen']['2c']['eta0']
    tauB = task_info['sen']['2c']['tauB']
    targetB = task_info['targetB']
    B0 = tauB*targetB
    tau_update = task_info['sen']['2c']['tau_update']
    eta = eta0 * tau_update / tauB
    validburst = task_info['sen']['2c']['validburst']      # if tau_burst = 4*ms, at 16 ms stopburst = 0.0183
    min_burst_stop = task_info['sen']['2c']['min_burst_stop']   # thus, we will set it at critrefburst = 0.02
    tau_burst = -validburst / np_log(min_burst_stop) * second

    param2c = {'gEE': gEEs, 'gEI': gEI, 'gIE': gIEs, 'gII': gII, 'gmax': gmax, 'gXEs': gXEs, 'gXI': gXI,
               'gleakEs': gleakEs, 'gleakEd': gleakEd, 'gleakI': gleakI, 'Cms': Cms, 'Cmd': Cmd, 'CmI': CmI,
               'Vl': Vl, 'Vt': Vt, 'Vr': Vr, 'VrevE': VrevE, 'VrevIsd': VrevIsd, 'VrevI': VrevI,
               'taus': taus, 'taud': taud, 'tau_refE': tau_refE, 'tau_refI': tau_refI,
               'tau_decay': tau_decay, 'tau_rise': tau_rise, 'tau_ws': tauws, 'tau_wd': tauwd,
               'bws': bws, 'awd': awd, 'gCas': gCas, 'gCad': gCad, 'bpA': bpA, 'k1': k1, 'k2': k2,
               'muOUs': muOUs, 'tauOU': tauOU, 'sigmaOU': sigmaOU,
               'w_p': w_p, 'w_m': w_m, 'sub': sub, 'eps': eps, 'epsX': epsX, 'alphaX': alphaX,
               'eta': eta, 'B0': B0, 'tauB': tauB, 'tau_burst': tau_burst, 'min_burst_stop': min_burst_stop}

    # numerical integration method
    nummethod = task_info['simulation']['nummethod']

    # -------------------------------------
    # Set up model and connections
    # -------------------------------------
    # neuron equations
    eqss = '''
        dV/dt = (-g_ea*(V-VrevE) -g_i*(V-VrevIsd) -(V-Vl))/tau + (gCas/(1+exp(-(V_d/mV + 38)/6)) + w_s + I)/Cm : volt (unless refractory)
        dg_ea/dt = (-g_ea + x_ea) / tau_decay   : 1
        dx_ea/dt  = -x_ea / tau_rise            : 1
        dg_i/dt  = (-g_i + x_i) / tau_decay     : 1
        dx_i/dt  = -x_i / tau_rise              : 1
        dw_s/dt = -w_s / tau_ws                 : amp
        tau = taus      : second
        Cm  = Cms       : farad
        I = Irec(t, i)  : amp
        V_d             : volt (linked)
        B               : 1 (linked)
        burst_start     : 1 (linked)
        burst_stop      : 1 (linked)
        muOUd           : amp (linked)
    '''
        # dIbg/dt = (muOUs - Ibg) / tauOU + (sigmaOU * xi) / sqrt(tauOU / 2)  : amp --> they have I_Ext

    eqsd = '''
        dV_d/dt = (-g_ea*(V_d-VrevE) -(V_d-Vl))/tau + (gCad/(1+exp(-(V_d/mV + 38)/6)) + w_d + K + Ibg)/Cm : volt
        dg_ea/dt = (-g_ea + x_ea) / tau_decay          : 1
        dx_ea/dt  = -x_ea / tau_rise                   : 1
        dw_d/dt = (-w_d + awd*(V_d - Vl))/tau_wd       : amp
        dIbg/dt = (muOUd - Ibg) / tauOU + (sigmaOU * xi) / sqrt(tauOU / 2)  : amp
        K = bpA * (((t-lastspike_soma) >= k1) * ((t-lastspike_soma) <= k2))   : amp
        dB/dt = -B / tauB                              : 1
        dburst_start/dt = -burst_start / tau_burst     : 1 (unless refractory)
        dburst_stop/dt = -burst_stop / tau_burst       : 1
        tau = taud      : second
        Cm  = Cmd       : farad
        muOUd           : amp
        lastspike_soma  : second (linked)
    '''

    eqsI = '''
        dV/dt = (-g_ea*(V-VrevE) -g_i*(V-VrevI) -(V-Vl))/tau  + I/Cm : volt (unless refractory)
        dg_ea/dt = (-g_ea + x_ea) / tau_decay   : 1
        dx_ea/dt = -x_ea / tau_rise             : 1
        dg_i/dt = (-g_i + x_i) / tau_decay      : 1
        dx_i/dt = -x_i / tau_rise               : 1
        tau = CmI/gleakI    : second
        Cm = CmI            : farad
        I : amp
    '''

    # neuron groups
    soma = NeuronGroup(N_E, model=eqss, method=nummethod, threshold='V>=Vt',
                       reset='''V = Vl
                                w_s += bws
                                burst_start += 1
                                burst_stop = 1''',
                       refractory=tau_refE, namespace=param2c, name='soma')
    dend = NeuronGroup(N_E, model=eqsd, method=nummethod, threshold='burst_start > 1 + min_burst_stop',
                       reset='''B += 1
                                burst_start = 0''',
                       refractory='burst_stop >= min_burst_stop',
                       namespace=param2c, name='dend')
    senI = NeuronGroup(N_I, model=eqsI, method=nummethod, threshold='V>=Vt', reset='V=Vr',
                       refractory=tau_refI, namespace=param2c, name='senI')

    # linked variables
    soma.V_d = linked_var(dend, 'V_d')
    soma.B = linked_var(dend, 'B')
    soma.burst_start = linked_var(dend, 'burst_start')
    soma.burst_stop = linked_var(dend, 'burst_stop')
    soma.muOUd = linked_var(dend, 'muOUd')
    dend.lastspike_soma = linked_var(soma, 'lastspike')

    # subgroups
    soma1 = soma[:N_E1]
    dend1 = dend[:N_E1]
    soma2 = soma[N_E1:]
    dend2 = dend[N_E1:]

    # update muOUd with plasticity rule
    dend1.muOUd = '-50*pA - rand()*100*pA'   # random initialisation of weights -50:-150 pA
    dend1.run_regularly('muOUd = clip(muOUd - eta * (B - B0), -100*amp, 0)', dt=tau_update)
    # TODO: check the target vs burst rate convergence
    # TODO: try tau_B = 50,000 sec, but mayb\e this is not the case because you do reach the target

    # synapses
    # weight according the different subgroups
    condsame = '(i<N_pre*sub and j<N_post*sub) or (i>=N_pre*sub and j>=N_post*sub)'
    conddiff = '(i<N_pre*sub and j>=N_post*sub) or (i>=N_pre*sub and j<N_post*sub)'

    # AMPA: exc --> exc
    synSESE = Synapses(soma, soma, model='w : 1', method=nummethod,
                       on_pre='''x_ea += w
                                 w = clip(w, 0, gmax)''',
                       namespace=param2c, name='synSESE')
    synSESE.connect(p='eps')
    synSESE.w[condsame] = 'w_p * gEE/gleakEs * (1 + randn()*0.5)'
    synSESE.w[conddiff] = 'w_m * gEE/gleakEs * (1 + randn()*0.5)'
    synSESE.delay = dE

    # AMPA: exc --> inh
    synSESI = Synapses(soma, senI, model='w : 1', method=nummethod,
                       on_pre='''x_ea += w
                                 w = clip(w, 0, gmax)''',
                       namespace=param2c, name='synSESI')
    synSESI.connect(p='eps')
    synSESI.w = 'gEI/gleakI * (1 + randn()*0.5)'
    synSESI.delay = dE

    # GABA: inh --> exc
    synSISE = Synapses(senI, soma, model='w : 1', method=nummethod,
                       on_pre='''x_i += w
                                 w = clip(w, 0, gmax)''',
                       namespace=param2c, name='synSISE')
    synSISE.connect(p='eps')
    synSISE.w = 'gIE/gleakEs * (1 + randn()*0.5)'
    synSISE.delay = dI

    # GABA: inh --> inh
    synSISI = Synapses(senI, senI, model='w : 1', method=nummethod,
                       on_pre='''x_i += w
                                 w = clip(w, 0, gmax)''',
                       namespace=param2c, name='synSISI')
    synSISI.connect(p='eps')
    synSISI.w = 'gII/gleakI * (1 + randn()*0.5)'
    synSISI.delay = dI

    # external inputs and synapses
    extS = PoissonGroup(N_X, rates=nu_ext)

    synSXSEs = Synapses(extS, soma, model='w : 1', method=nummethod,
                       on_pre='''x_ea += w
                                 w = clip(w, 0, gmax)''',
                       namespace=param2c, name='synSXSEs')
    synSXSEs.connect(condition=condsame, p='epsX * (1 + alphaX)')
    synSXSEs.connect(condition=conddiff, p='epsX * (1 - alphaX)')
    synSXSEs.w = 'gXEs/gleakEs * (1 + randn()*0.5)'
    synSXSEs.delay = dX

    synSXSI = Synapses(extS, senI, model='w : 1', method=nummethod,
                       on_pre='''x_ea += w
                                 w = clip(w, 0, gmax)''',
                       namespace=param2c, name='synSXSI')
    synSXSI.connect(p='epsX')
    synSXSI.w = 'gXI/gleakI * (1 + randn()*0.5)'
    synSXSI.delay = dX

    # external inputs to dendrites mimicking decision circuit
    subDE = 240
    rateDE = 40*Hz   # TODO: lower rate --> 40 or 30
    d = 1*ms
    wDS = 0.06
    XDE = PoissonGroup(subDE, rates=rateDE)

    synXDEdend = Synapses(XDE, dend1, model='w : 1', method=nummethod, delay=d,
                          on_pre='x_ea += w',
                          namespace=param2c, name='synXDEdend')
    synXDEdend.connect(p=0.2)
    synXDEdend.w = 'wDS'

    # variables to return
    groups = {'soma': soma, 'dend': dend, 'SI': senI, 'SX': extS, 'XDE': XDE}
    subgroups = {'soma1': soma1, 'soma2': soma2,
                 'dend1': dend1, 'dend2': dend2}
    synapses = {'synSESE': synSESE, 'synSESI': synSESI,
                'synSISE': synSISE, 'synSISI': synSISI,
                'synSXSI': synSXSI, 'synSXSEs': synSXSEs,
                'synXDEdend': synXDEdend}

    return groups, synapses, subgroups
Example #15
0
def mk_sencircuit(task_info):
    """
    Creates balanced network representing sensory circuit.

    returns:
        groups, synapses, subgroups

    groups and synapses have to be added to the "Network" in order to run the simulation
    subgroups is used for establishing connections between the sensory and integration circuit;
    do not add subgroups to the "Network"


    psr following the published Brian1 code in DB model from Wimmer et al. 2015
    - brain2 code
    - implementation runs in cpp_standalone mode, compatible with SNEP
    """
    # -------------------------------------
    # Sensory circuit parameters
    # -------------------------------------
    # populations
    N_E = task_info['sen']['populations']['N_E']  # total number of E neurons
    sub = task_info['sen']['populations']['sub']  # fraction corresponding to subpops 1,2
    N_E1 = int(N_E * sub)  # size of exc subpops that responds to the stimuli
    N_I = task_info['sen']['populations']['N_I']  # total number of I neurons
    N_X = task_info['sen']['populations']['N_X']  # size of external pop

    # local recurrent connections
    eps = task_info['sen']['connectivity']['eps']  # connection probability for EE, EI, IE and II
    w_p = task_info['sen']['connectivity']['w_p']  # relative synaptic strength within pop E1 and E2
    w_m = 2 - w_p  # relative synaptic strength across pop E1 and E2
    gEE = task_info['sen']['connectivity']['gEE']  # weight of EE synapses, prev: 0.7589*nS
    gEI = task_info['sen']['connectivity']['gEI']  # weight of EI synapses, prev: 1.5179*nS
    gIE = task_info['sen']['connectivity']['gIE']  # weight of IE synapses, prev: 12.6491*nS
    gII = task_info['sen']['connectivity']['gII']  # weight of II synapses
    gmax = task_info['sen']['connectivity']['gmax']  # maximum synaptic weight
    dE = '0.5*ms + rand()*1.0*ms'  # range of transmission delays of E synapses, (0.5:1.5)
    dI = '0.1*ms + rand()*0.8*ms'  # range of transmission delays of I synapses, (0.1:0.9)

    # external connections
    epsX = task_info['sen']['connectivity']['epsX']  # connection probability for ext synapses
    alphaX = task_info['sen']['connectivity']['alphaX']  # 0: global input, 1: local input
    gXE = task_info['sen']['connectivity']['gXE']  # weight of ext to E synapses
    gXI = task_info['sen']['connectivity']['gXI']  # weight of ext to I synapses
    dX = '0.5*ms + rand()*1.0*ms'  # range of transmission delays of X synapses, (0.5:1.5)

    # neuron models
    CmE = task_info['sen']['neuron']['CmE']  # membrane capacitance of E neurons
    CmI = task_info['sen']['neuron']['CmI']  # membrane capacitance of I neurons
    gleakE = task_info['sen']['neuron']['gleakE']  # leak conductance of E neurons
    gleakI = task_info['sen']['neuron']['gleakI']  # leak conductance of I neurons
    Vl = task_info['sen']['neuron']['Vl']  # resting potential
    Vt = task_info['sen']['neuron']['Vt']  # spiking threshold
    Vr = task_info['sen']['neuron']['Vr']  # reset potential
    tau_refE = task_info['sen']['neuron']['tau_refE']  # absolute refractory period of E neurons
    tau_refI = task_info['sen']['neuron']['tau_refI']  # absolute refractory period of I neurons
    nu_ext = task_info['sen']['neuron']['nu_ext']  # rate of external Poisson neurons, prev: 12.5*Hz

    # synapse models
    VrevE = task_info['sen']['synapse']['VrevE']  # reversal potential for E synapses
    VrevI = task_info['sen']['synapse']['VrevI']  # reversal potential for I synapses
    tau_decay = task_info['sen']['synapse']['tau_decay']  # decay constants of AMPA and GABA conductances
    tau_rise = task_info['sen']['synapse']['tau_rise']  # rise constants of AMPA and GABA conductances

    # namespace with params
    paramsen = {'gEE': gEE, 'gEI': gEI, 'gIE': gIE, 'gII': gII, 'gmax': gmax, 'gXE': gXE, 'gXI': gXI,
                'gleakE': gleakE, 'gleakI': gleakI, 'CmE': CmE, 'CmI': CmI, 'Vl': Vl, 'Vt': Vt, 'Vr': Vr,
                'VrevE': VrevE, 'VrevI': VrevI, 'tau_decay': tau_decay, 'tau_rise': tau_rise,
                'w_p': w_p, 'w_m': w_m, 'sub': sub, 'eps': eps, 'epsX': epsX, 'alphaX': alphaX}

    # numerical integration method
    nummethod = task_info['simulation']['nummethod']

    # -------------------------------------
    # Set up the model and connections
    # -------------------------------------
    # neuron equations
    eqsE = '''
        dV/dt = (-g_ea*(V-VrevE) - g_i*(V-VrevI) - (V-Vl)) / tau  + I/Cm : volt (unless refractory)
        dg_ea/dt = (-g_ea + x_ea) / tau_decay   : 1
        dx_ea/dt  = -x_ea / tau_rise            : 1
        dg_i/dt  = (-g_i + x_i) / tau_decay     : 1
        dx_i/dt  = -x_i / tau_rise              : 1
        tau = CmE/gleakE    : second
        Cm = CmE            : farad
        I = Irec(t, i)      : amp
    '''

    eqsI = '''
        dV/dt = (-g_ea*(V-VrevE) - g_i*(V-VrevI) - (V-Vl)) / tau  + I/Cm : volt (unless refractory)
        dg_ea/dt = (-g_ea + x_ea) / tau_decay   : 1
        dx_ea/dt  = -x_ea / tau_rise            : 1
        dg_i/dt  = (-g_i + x_i) / tau_decay     : 1
        dx_i/dt  = -x_i / tau_rise              : 1
        tau = CmI/gleakI    : second
        Cm = CmI            : farad
        I : amp
    '''

    # neuron groups
    senE = NeuronGroup(N_E, model=eqsE, method=nummethod, threshold='V>=Vt', reset='V=Vr',
                       refractory=tau_refE, namespace=paramsen, name='senE')
    senE1 = senE[:N_E1]
    senE2 = senE[N_E1:]

    senI = NeuronGroup(N_I, model=eqsI, method=nummethod, threshold='V>=Vt', reset='V=Vr',
                       refractory=tau_refI, namespace=paramsen, name='senI')

    # synapses
    # weight according the different subgroups
    condsame = '(i<N_pre*sub and j<N_post*sub) or (i>=N_pre*sub and j>=N_post*sub)'
    conddiff = '(i<N_pre*sub and j>=N_post*sub) or (i>=N_pre*sub and j<N_post*sub)'

    # AMPA: exc --> exc
    synSESE = Synapses(senE, senE, model='w : 1', method=nummethod,
                       on_pre='''x_ea += w
                                 w = clip(w, 0, gmax)''',
                       namespace=paramsen, name='synSESE')
    synSESE.connect(p='eps')
    synSESE.w[condsame] = 'w_p * gEE/gleakE * (1 + randn()*0.5)'
    synSESE.w[conddiff] = 'w_m * gEE/gleakE * (1 + randn()*0.5)'
    synSESE.delay = dE

    # AMPA: exc --> inh
    synSESI = Synapses(senE, senI, model='w : 1', method=nummethod,
                       on_pre='''x_ea += w
                                 w = clip(w, 0, gmax)''',
                       namespace=paramsen, name='synSESI')
    synSESI.connect(p='eps')
    synSESI.w = 'gEI/gleakI * (1 + randn()*0.5)'
    synSESI.delay = dE

    # GABA: inh --> exc
    synSISE = Synapses(senI, senE, model='w : 1', method=nummethod,
                       on_pre='''x_i += w
                                 w = clip(w, 0, gmax)''',
                       namespace=paramsen, name='synSISE')
    synSISE.connect(p='eps')
    synSISE.w = 'gIE/gleakE * (1 + randn()*0.5)'
    synSISE.delay = dI

    # GABA: inh --> inh
    synSISI = Synapses(senI, senI, model='w : 1', method=nummethod,
                       on_pre='''x_i += w
                                 w = clip(w, 0, gmax)''',
                       namespace=paramsen, name='synSISI')
    synSISI.connect(p='eps')
    synSISI.w = 'gII/gleakI * (1 + randn()*0.5)'
    synSISI.delay = dI

    # external inputs and synapses
    extS = PoissonGroup(N_X, rates=nu_ext)

    synSXSE = Synapses(extS, senE, model='w : 1', method=nummethod,
                       on_pre='''x_ea += w
                                 w = clip(w, 0, gmax)''',
                       namespace=paramsen, name='synSXSE')
    synSXSE.connect(condition=condsame, p='epsX * (1 + alphaX)')
    synSXSE.connect(condition=conddiff, p='epsX * (1 - alphaX)')
    synSXSE.w = 'gXE/gleakE * (1 + randn()*0.5)'
    synSXSE.delay = dX

    synSXSI = Synapses(extS, senI, model='w : 1', method=nummethod,
                       on_pre='''x_ea += w
                                 w = clip(w, 0, gmax)''',
                       namespace=paramsen, name='synSXSI')
    synSXSI.connect(p='epsX')
    synSXSI.w = 'gXI/gleakI * (1 + randn()*0.5)'
    synSXSI.delay = dX

    # variables to return
    groups = {'SE': senE, 'SI': senI, 'SX': extS}
    subgroups = {'SE1': senE1, 'SE2': senE2}
    synapses = {'synSESE': synSESE, 'synSESI': synSESI,
                'synSISE': synSISE, 'synSISI': synSISI,
                'synSXSI': synSXSI, 'synSXSE': synSXSE}

    return groups, synapses, subgroups
Example #16
0
def sim_decision_making_network_full(
    N_Excit=400,
    N_Inhib=100,
    weight_scaling_factor=5.33,
    t_stimulus_start=100 * b2.ms,
    t_stimulus_duration=9999 * b2.ms,
    coherence_level=0.0,
    stimulus_update_interval=30 * b2.ms,
    mu0_mean_stimulus_Hz=40.,
    stimulus_std_Hz=10.,
    N_extern=1000,
    firing_rate_extern=9.8 * b2.Hz,
    w_pos=2.4,
    f_Subpop_size=0.25,  # .15 in publication [1]
    max_sim_time=2000. * b2.ms,
    stop_condition_rate=20 * b2.Hz,
    monitored_subset_size=512,
):
    # print('Simulation starts')
    startting_time = time.time()
    t_stimulus_end = t_stimulus_start + t_stimulus_duration

    N_Group_A = int(
        N_Excit * f_Subpop_size
    )  # size of the excitatory subpopulation sensitive to stimulus A
    N_Group_B = N_Group_A  # size of the excitatory subpopulation sensitive to stimulus B
    N_Group_Z = N_Excit - N_Group_A - N_Group_B  # (1-2f)Ne excitatory neurons do not respond to either stimulus.

    Cm_excit = 0.5 * b2.nF  # membrane capacitance of excitatory neurons
    G_leak_excit = 25.0 * b2.nS  # leak conductance
    E_leak_excit = -70.0 * b2.mV  # reversal potential
    v_spike_thr_excit = -50.0 * b2.mV  # spike condition
    v_reset_excit = -55.0 * b2.mV  # reset voltage after spike
    t_abs_refract_excit = 2.0 * b2.ms  # absolute refractory period

    # specify the inhibitory interneurons:
    # N_Inhib = 200
    Cm_inhib = 0.2 * b2.nF
    G_leak_inhib = 20.0 * b2.nS
    E_leak_inhib = -70.0 * b2.mV
    v_spike_thr_inhib = -50.0 * b2.mV
    v_reset_inhib = -55.0 * b2.mV
    t_abs_refract_inhib = 1.0 * b2.ms

    # specify the AMPA synapses
    E_AMPA = 0.0 * b2.mV
    tau_AMPA = 2.0 * b2.ms

    # specify the GABA synapses
    E_GABA = -70.0 * b2.mV
    tau_GABA = 2.0 * b2.ms

    # specify the NMDA synapses

    # projections from the external population
    g_AMPA_extern2inhib = 1.62 * b2.nS
    g_AMPA_extern2excit = 2.1 * b2.nS

    # projectsions from the inhibitory populations
    g_GABA_inhib2inhib = weight_scaling_factor * 1.25 * b2.nS
    g_GABA_inhib2excit = weight_scaling_factor * 1.60 * b2.nS

    # projections from the excitatory population
    g_AMPA_excit2excit = 2.1 * weight_scaling_factor * 0.012 * b2.nS
    g_AMPA_excit2inhib = 0.14 * weight_scaling_factor * 0.015 * b2.nS

    # weights and "adjusted" weights.
    w_neg = 1. - f_Subpop_size * (w_pos - 1.) / (1. - f_Subpop_size)
    w_ext2inhib = g_AMPA_extern2inhib / g_AMPA_excit2inhib
    w_ext2excit = g_AMPA_extern2excit / g_AMPA_excit2excit
    # other weights are 1

    # Define the inhibitory population
    # dynamics:
    inhib_lif_dynamics = """
        dv/dt = (
        - G_leak_inhib * (v-E_leak_inhib)
        - g_AMPA_excit2inhib * s_AMPA * (v-E_AMPA)
        - g_GABA_inhib2inhib * s_GABA * (v-E_GABA)
        )/Cm_inhib : volt (unless refractory)
        ds_AMPA/dt = -s_AMPA/tau_AMPA : 1
        ds_GABA/dt = -s_GABA/tau_GABA : 1
    """

    inhib_pop = NeuronGroup(N_Inhib,
                            model=inhib_lif_dynamics,
                            threshold="v>v_spike_thr_inhib",
                            reset="v=v_reset_inhib",
                            refractory=t_abs_refract_inhib,
                            method="rk2")
    # initialize with random voltages:
    inhib_pop.v = rnd.uniform(v_spike_thr_inhib / b2.mV - 4.,
                              high=v_spike_thr_inhib / b2.mV - 1.,
                              size=N_Inhib) * b2.mV

    # Specify the excitatory population:
    # dynamics:
    excit_lif_dynamics = """
        dv/dt = (
        - G_leak_excit * (v-E_leak_excit)
        - g_AMPA_excit2excit * s_AMPA * (v-E_AMPA)
        - g_GABA_inhib2excit * s_GABA * (v-E_GABA)
        )/Cm_excit : volt (unless refractory)
        ds_AMPA/dt = -s_AMPA/tau_AMPA : 1
        ds_GABA/dt = -s_GABA/tau_GABA : 1
    """

    # define the three excitatory subpopulations.
    # A: subpop receiving stimulus A
    excit_pop_A = NeuronGroup(N_Group_A,
                              model=excit_lif_dynamics,
                              threshold="v > v_spike_thr_excit",
                              reset="v = v_reset_excit",
                              refractory=t_abs_refract_excit,
                              method="rk2")
    excit_pop_A.v = rnd.uniform(E_leak_excit / b2.mV,
                                high=E_leak_excit / b2.mV + 5.,
                                size=excit_pop_A.N) * b2.mV

    # B: subpop receiving stimulus B
    excit_pop_B = NeuronGroup(N_Group_B,
                              model=excit_lif_dynamics,
                              threshold="v > v_spike_thr_excit",
                              reset="v = v_reset_excit",
                              refractory=t_abs_refract_excit,
                              method="rk2")
    excit_pop_B.v = rnd.uniform(E_leak_excit / b2.mV,
                                high=E_leak_excit / b2.mV + 5.,
                                size=excit_pop_B.N) * b2.mV
    # Z: non-sensitive
    excit_pop_Z = NeuronGroup(N_Group_Z,
                              model=excit_lif_dynamics,
                              threshold="v>v_spike_thr_excit",
                              reset="v=v_reset_excit",
                              refractory=t_abs_refract_excit,
                              method="rk2")
    excit_pop_Z.v = rnd.uniform(v_reset_excit / b2.mV,
                                high=v_spike_thr_excit / b2.mV - 1.,
                                size=excit_pop_Z.N) * b2.mV

    # now define the connections:
    # projections FROM EXTERNAL POISSON GROUP: ####################################################
    poisson2Inhib = PoissonInput(target=inhib_pop,
                                 target_var="s_AMPA",
                                 N=N_extern,
                                 rate=firing_rate_extern,
                                 weight=w_ext2inhib)
    poisson2A = PoissonInput(target=excit_pop_A,
                             target_var="s_AMPA",
                             N=N_extern,
                             rate=firing_rate_extern,
                             weight=w_ext2excit)

    poisson2B = PoissonInput(target=excit_pop_B,
                             target_var="s_AMPA",
                             N=N_extern,
                             rate=firing_rate_extern,
                             weight=w_ext2excit)
    poisson2Z = PoissonInput(target=excit_pop_Z,
                             target_var="s_AMPA",
                             N=N_extern,
                             rate=firing_rate_extern,
                             weight=w_ext2excit)

    ###############################################################################################

    # GABA projections FROM INHIBITORY population: ################################################
    syn_inhib2inhib = Synapses(inhib_pop,
                               target=inhib_pop,
                               on_pre="s_GABA += 1.0",
                               delay=0.5 * b2.ms)
    syn_inhib2inhib.connect(p=1.)
    syn_inhib2A = Synapses(inhib_pop,
                           target=excit_pop_A,
                           on_pre="s_GABA += 1.0",
                           delay=0.5 * b2.ms)
    syn_inhib2A.connect(p=1.)
    syn_inhib2B = Synapses(inhib_pop,
                           target=excit_pop_B,
                           on_pre="s_GABA += 1.0",
                           delay=0.5 * b2.ms)
    syn_inhib2B.connect(p=1.)
    syn_inhib2Z = Synapses(inhib_pop,
                           target=excit_pop_Z,
                           on_pre="s_GABA += 1.0",
                           delay=0.5 * b2.ms)
    syn_inhib2Z.connect(p=1.)
    ###############################################################################################

    # AMPA projections FROM EXCITATORY A: #########################################################
    syn_AMPA_A2A = Synapses(excit_pop_A,
                            target=excit_pop_A,
                            on_pre="s_AMPA += w_pos",
                            delay=0.5 * b2.ms)
    syn_AMPA_A2A.connect(p=1.)
    syn_AMPA_A2B = Synapses(excit_pop_A,
                            target=excit_pop_B,
                            on_pre="s_AMPA += w_neg",
                            delay=0.5 * b2.ms)
    syn_AMPA_A2B.connect(p=1.)
    syn_AMPA_A2Z = Synapses(excit_pop_A,
                            target=excit_pop_Z,
                            on_pre="s_AMPA += w_neg",
                            delay=0.5 * b2.ms)
    syn_AMPA_A2Z.connect(p=1.)
    syn_AMPA_A2inhib = Synapses(excit_pop_A,
                                target=inhib_pop,
                                on_pre="s_AMPA += 1.0",
                                delay=0.5 * b2.ms)
    syn_AMPA_A2inhib.connect(p=1.)
    ###############################################################################################

    # AMPA projections FROM EXCITATORY B: #########################################################
    syn_AMPA_B2A = Synapses(excit_pop_B,
                            target=excit_pop_A,
                            on_pre="s_AMPA += w_neg",
                            delay=0.5 * b2.ms)
    syn_AMPA_B2A.connect(p=1.)
    syn_AMPA_B2B = Synapses(excit_pop_B,
                            target=excit_pop_B,
                            on_pre="s_AMPA += w_pos",
                            delay=0.5 * b2.ms)
    syn_AMPA_B2B.connect(p=1.)
    syn_AMPA_B2Z = Synapses(excit_pop_B,
                            target=excit_pop_Z,
                            on_pre="s_AMPA += w_neg",
                            delay=0.5 * b2.ms)
    syn_AMPA_B2Z.connect(p=1.)
    syn_AMPA_B2inhib = Synapses(excit_pop_B,
                                target=inhib_pop,
                                on_pre="s_AMPA += 1.0",
                                delay=0.5 * b2.ms)
    syn_AMPA_B2inhib.connect(p=1.)
    ###############################################################################################

    # AMPA projections FROM EXCITATORY Z: #########################################################
    syn_AMPA_Z2A = Synapses(excit_pop_Z,
                            target=excit_pop_A,
                            on_pre="s_AMPA += w_neg",
                            delay=0.5 * b2.ms)
    syn_AMPA_Z2A.connect(p=1.)
    syn_AMPA_Z2B = Synapses(excit_pop_Z,
                            target=excit_pop_B,
                            on_pre="s_AMPA += w_neg",
                            delay=0.5 * b2.ms)
    syn_AMPA_Z2B.connect(p=1.)
    syn_AMPA_Z2Z = Synapses(excit_pop_Z,
                            target=excit_pop_Z,
                            on_pre="s_AMPA += 1.0",
                            delay=0.5 * b2.ms)
    syn_AMPA_Z2Z.connect(p=1.)
    syn_AMPA_Z2inhib = Synapses(excit_pop_Z,
                                target=inhib_pop,
                                on_pre="s_AMPA += 1.0",
                                delay=0.5 * b2.ms)
    syn_AMPA_Z2inhib.connect(p=1.)
    ###############################################################################################

    # Define the stimulus: two PoissonInput with time time-dependent mean.
    poissonStimulus2A = PoissonGroup(N_Group_A, 0. * b2.Hz)
    syn_Stim2A = Synapses(poissonStimulus2A,
                          excit_pop_A,
                          on_pre="s_AMPA+=w_ext2excit")
    syn_Stim2A.connect(j="i")
    poissonStimulus2B = PoissonGroup(N_Group_B, 0. * b2.Hz)
    syn_Stim2B = Synapses(poissonStimulus2B,
                          excit_pop_B,
                          on_pre="s_AMPA+=w_ext2excit")
    syn_Stim2B.connect(j="i")

    @network_operation(dt=stimulus_update_interval)
    def update_poisson_stimulus(t):
        if t >= t_stimulus_start and t < t_stimulus_end:
            offset_A = mu0_mean_stimulus_Hz * (1 + 0.01 * coherence_level)
            offset_B = mu0_mean_stimulus_Hz * (1 - 0.01 * coherence_level)

            rate_A = numpy.random.normal(offset_A, stimulus_std_Hz)
            rate_A = (max(0, rate_A)) * b2.Hz  # avoid negative rate
            rate_B = numpy.random.normal(offset_B, stimulus_std_Hz)
            rate_B = (max(0, rate_B)) * b2.Hz

            poissonStimulus2A.rates = rate_A
            poissonStimulus2B.rates = rate_B
        else:
            poissonStimulus2A.rates = 0.
            poissonStimulus2B.rates = 0.

    ###############################################################################################

    def get_monitors(pop, monitored_subset_size):
        monitored_subset_size = min(monitored_subset_size, pop.N)
        idx_monitored_neurons = sample(range(pop.N), monitored_subset_size)
        rate_monitor = PopulationRateMonitor(pop)
        spike_monitor = SpikeMonitor(pop, record=idx_monitored_neurons)
        voltage_monitor = StateMonitor(pop, "v", record=idx_monitored_neurons)
        return rate_monitor, spike_monitor, voltage_monitor, idx_monitored_neurons

    # collect data of a subset of neurons:
    rate_monitor_inhib, spike_monitor_inhib, voltage_monitor_inhib, idx_monitored_neurons_inhib = \
        get_monitors(inhib_pop, monitored_subset_size)

    rate_monitor_A, spike_monitor_A, voltage_monitor_A, idx_monitored_neurons_A = \
        get_monitors(excit_pop_A, monitored_subset_size)

    rate_monitor_B, spike_monitor_B, voltage_monitor_B, idx_monitored_neurons_B = \
        get_monitors(excit_pop_B, monitored_subset_size)

    rate_monitor_Z, spike_monitor_Z, voltage_monitor_Z, idx_monitored_neurons_Z = \
        get_monitors(excit_pop_Z, monitored_subset_size)

    if stop_condition_rate is None:
        b2.run(max_sim_time)
    else:
        sim_sum = 0. * b2.ms
        sim_batch = 25. * b2.ms
        samples_in_batch = int(floor(sim_batch / b2.defaultclock.dt))
        avg_rate_in_batch = 0
        while (sim_sum < max_sim_time) and (avg_rate_in_batch <
                                            stop_condition_rate):
            b2.run(sim_batch)
            avg_A = numpy.mean(rate_monitor_A.rate[-samples_in_batch:])
            avg_B = numpy.mean(rate_monitor_B.rate[-samples_in_batch:])
            avg_rate_in_batch = max(avg_A, avg_B)
            sim_sum += sim_batch

    print("Time elapsed =", time.time() - startting_time, 'seconds')
    ret_vals = dict()

    ret_vals["rate_monitor_A"] = rate_monitor_A
    ret_vals["spike_monitor_A"] = spike_monitor_A
    ret_vals["voltage_monitor_A"] = voltage_monitor_A
    ret_vals["idx_monitored_neurons_A"] = idx_monitored_neurons_A

    ret_vals["rate_monitor_B"] = rate_monitor_B
    ret_vals["spike_monitor_B"] = spike_monitor_B
    ret_vals["voltage_monitor_B"] = voltage_monitor_B
    ret_vals["idx_monitored_neurons_B"] = idx_monitored_neurons_B

    ret_vals["rate_monitor_Z"] = rate_monitor_Z
    ret_vals["spike_monitor_Z"] = spike_monitor_Z
    ret_vals["voltage_monitor_Z"] = voltage_monitor_Z
    ret_vals["idx_monitored_neurons_Z"] = idx_monitored_neurons_Z

    ret_vals["rate_monitor_inhib"] = rate_monitor_inhib
    ret_vals["spike_monitor_inhib"] = spike_monitor_inhib
    ret_vals["voltage_monitor_inhib"] = voltage_monitor_inhib
    ret_vals["idx_monitored_neurons_inhib"] = idx_monitored_neurons_inhib

    return ret_vals
Example #17
0
def mk_sencircuit_2c(task_info):
    """
    Creates balanced network representing sensory circuit with 2c model in the excitatory neurons.

    returns:
        groups, synapses, subgroups

    groups and synapses have to be added to the "Network" in order to run the simulation
    subgroups is used for establishing connections between the sensory and integration circuit;
    do not add subgroups to the "Network"


    psr following the published Brian1 code in DB model from Wimmer et al. 2015
    - brain2 code
    - two-compartmental model following Naud & Sprekeler 2018
    - implementation runs in cpp_standalone mode, compatible with SNEP
    """
    # -------------------------------------
    # Sensory circuit parameters
    # -------------------------------------
    # populations
    N_E = task_info['sen']['populations']['N_E']  # total number of E neurons
    sub = task_info['sen']['populations']['sub']  # fraction corresponding to subpops 1,2
    N_E1 = int(N_E * sub)  # size of exc subpops that responds to the stimuli
    N_I = task_info['sen']['populations']['N_I']  # total number of I neurons
    N_X = task_info['sen']['populations']['N_X']  # size of external pop

    # local recurrent connections
    eps = task_info['sen']['connectivity']['eps']  # connection probability for EE, EI, IE and II
    w_p = task_info['sen']['connectivity']['w_p']  # relative synaptic strength within pop E1 and E2
    w_m = 2 - w_p  # relative synaptic strength across pop E1 and E2
    gEEs = task_info['sen']['2c']['gEEs']  # weight of EE synapses, prev: 0.7589*nS
    gEI = task_info['sen']['connectivity']['gEI']  # weight of EI synapses, prev: 1.5179*nS
    gIEs = task_info['sen']['2c']['gIEs']  # weight of IE synapses, prev: 12.6491*nS
    gII = task_info['sen']['connectivity']['gII']  # weight of II synapses
    gmax = task_info['sen']['connectivity']['gmax']  # maximum synaptic weight
    dE = '0.5*ms + rand()*1.0*ms'  # range of transmission delays of E synapses, (0.5:1.5)
    dI = '0.1*ms + rand()*0.8*ms'  # range of transmission delays of I synapses, (0.1:0.9)

    # external connections
    epsX = task_info['sen']['connectivity']['epsX']         # connection probability for ext synapses
    alphaX = task_info['sen']['connectivity']['alphaX']     # 0: global input, 1: local input
    gXEs = task_info['sen']['2c']['gXEs']                   # weight of ext to E synapses of soma
    gXI = task_info['sen']['connectivity']['gXI']           # weight of ext to I synapses
    dX = '0.5*ms + rand()*1.0*ms'  # range of transmission delays of X synapses, (0.5:1.5)

    # neuron model
    CmI = task_info['sen']['neuron']['CmI']  # membrane capacitance of I neurons
    gleakI = task_info['sen']['neuron']['gleakI']  # leak conductance of I neurons
    Vl = task_info['sen']['neuron']['Vl']  # reversal potential
    Vt = task_info['sen']['neuron']['Vt']  # threshold potential
    Vr = task_info['sen']['neuron']['Vr']  # reset potential, only for inh
    tau_refI = task_info['sen']['neuron']['tau_refI']  # absolute refractory period of I neurons
    nu_ext = task_info['sen']['neuron']['nu_ext']  # rate of external Poisson neurons, prev: 12.5*Hz

    # soma
    taus = task_info['sen']['2c']['taus']  # timescale of membrane potential
    Cms = task_info['sen']['2c']['Cms']  # capacitance
    gleakEs = Cms/taus
    tauws = task_info['sen']['2c']['tauws']  # timescale of recovery ("slow") variable
    bws = task_info['sen']['2c']['bws']  # strength of spike-triggered facilitation (bws < 0)
    gCas = task_info['sen']['2c']['gCas']  # strenght of forward calcium spike propagation
    tau_refE = task_info['sen']['2c']['tau_refE']  # refractory period

    # dendrite
    taud = task_info['sen']['2c']['taud']
    Cmd = task_info['sen']['2c']['Cmd']
    gleakEd = Cmd/taud
    tauwd = task_info['sen']['2c']['tauwd']  # timescale of recovery ("slow") variable
    awd = task_info['sen']['2c']['awd']  # stregth of subthreshold facilitations (awd < 0)
    gCad = task_info['sen']['2c']['gCad']  # strength of local regenerative activity
    bpA = task_info['sen']['2c']['bpA']  # strength of backpropagation activity (c variable)
    k1 = task_info['sen']['2c']['k1']  # rectangular kernel for backpropagating activity
    k2 = task_info['sen']['2c']['k2']  # if t in [0.5, 2.0] we'll have backpropagating current
    muOUd = task_info['sen']['2c']['muOUd']    # OU parameters for background noise of dendrites
    sigmaOU = task_info['sen']['2c']['sigmaOU']
    tauOU = task_info['sen']['2c']['tauOU']

    # synapse models
    VrevE = task_info['sen']['synapse']['VrevE']  # reversal potential for E synapses
    VrevI = task_info['sen']['synapse']['VrevI']  # reversal potential for I synapses in inh
    tau_decay = task_info['sen']['synapse']['tau_decay']  # decay constant of AMPA, GABA
    tau_rise = task_info['sen']['synapse']['tau_rise']    # rise constant of AMPA, GABA  for inh
    VrevIsd = task_info['sen']['synapse']['VrevIsd'] # rev potential for I synapses in soma, dend
    #tau_decayE = task_info['sen']['synapse']['tau_decaysd']  # rise constants of AMPA conductances
    # in Wimmer are decayE = decayI = 5, Naud decayE = 1, decayI = 5 !
    # TODO: try both approaches and decide which one to use.

    param2c = {'gEE': gEEs, 'gEI': gEI, 'gIE': gIEs, 'gII': gII, 'gmax': gmax, 'gXEs': gXEs, 'gXI': gXI,
               'gleakEs': gleakEs, 'gleakEd': gleakEd, 'gleakI': gleakI, 'Cms': Cms, 'Cmd': Cmd, 'CmI': CmI,
               'Vl': Vl, 'Vt': Vt, 'Vr': Vr, 'VrevE': VrevE, 'VrevIsd': VrevIsd, 'VrevI': VrevI,
               'taus': taus, 'taud': taud, 'tau_refE': tau_refE, 'tau_refI': tau_refI,
               'tau_decay': tau_decay, 'tau_rise': tau_rise, 'tau_ws': tauws, 'tau_wd': tauwd,
               'bws': bws, 'awd': awd, 'gCas': gCas, 'gCad': gCad, 'bpA': bpA, 'k1': k1, 'k2': k2,
               'muOUd': muOUd, 'tauOU': tauOU, 'sigmaOU': sigmaOU,
               'w_p': w_p, 'w_m': w_m, 'sub': sub, 'eps': eps, 'epsX': epsX, 'alphaX': alphaX}

    # numerical integration method
    nummethod = task_info['simulation']['nummethod']

    # -------------------------------------
    # Set up model and connections
    # -------------------------------------
    # neuron equations
    eqss = '''
        dV/dt = (-g_ea*(V-VrevE) -g_i*(V-VrevIsd) -(V-Vl))/tau + (gCas/(1+exp(-(V_d/mV + 38)/6)) + w_s + I)/Cm : volt (unless refractory)
        dg_ea/dt = (-g_ea + x_ea) / tau_decay   : 1
        dx_ea/dt  = -x_ea / tau_rise            : 1
        dg_i/dt  = (-g_i + x_i) / tau_decay     : 1
        dx_i/dt  = -x_i / tau_rise              : 1
        dw_s/dt = -w_s / tau_ws                 : amp
        tau = taus      : second
        Cm  = Cms       : farad
        I = Irec(t, i)  : amp
        V_d : volt (linked)
    '''

    eqsd = '''
        dV_d/dt = (-g_ea*(V_d-VrevE) -(V_d-Vl))/tau + (gCad/(1+exp(-(V_d/mV + 38)/6)) + w_d + K + Ibg)/Cm : volt
        dg_ea/dt = (-g_ea + x_ea) / tau_decay   : 1
        dx_ea/dt  = -x_ea / tau_rise            : 1
        dw_d/dt = (-w_d + awd*(V_d - Vl))/tau_wd : amp
        dIbg/dt = (muOUd - Ibg) / tauOU + (sigmaOU * xi) / sqrt(tauOU / 2)  : amp
        K = bpA * (((t-lastspike_soma) >= k1) * ((t-lastspike_soma) <= k2)) : amp
        tau = taud      : second
        Cm  = Cmd       : farad
        muOUd           : amp
        lastspike_soma  : second (linked)
        
    '''

    eqsI = '''
        dV/dt = (-g_ea*(V-VrevE) -g_i*(V-VrevI) -(V-Vl))/tau  + I/Cm : volt (unless refractory)
        dg_ea/dt = (-g_ea + x_ea) / tau_decay   : 1
        dx_ea/dt = -x_ea / tau_rise             : 1
        dg_i/dt = (-g_i + x_i) / tau_decay      : 1
        dx_i/dt = -x_i / tau_rise               : 1
        tau = CmI/gleakI    : second
        Cm = CmI            : farad
        I : amp
    '''

    # neuron groups
    soma = NeuronGroup(N_E, model=eqss, method=nummethod, threshold='V>=Vt',
                       reset='''V = Vl
                                w_s += bws''',
                       refractory=tau_refE, namespace=param2c, name='soma')
    dend = NeuronGroup(N_E, model=eqsd, method=nummethod, namespace=param2c, name='dend')
    senI = NeuronGroup(N_I, model=eqsI, method=nummethod, threshold='V>=Vt', reset='V=Vr',
                       refractory=tau_refI, namespace=param2c, name='senI')

    # linked variables
    soma.V_d = linked_var(dend, 'V_d')
    dend.lastspike_soma = linked_var(soma, 'lastspike')

    # subgroups
    soma1 = soma[:N_E1]
    dend1 = dend[:N_E1]
    soma2 = soma[N_E1:]
    dend2 = dend[N_E1:]

    # synapses
    # weight according the different subgroups
    condsame = '(i<N_pre*sub and j<N_post*sub) or (i>=N_pre*sub and j>=N_post*sub)'
    conddiff = '(i<N_pre*sub and j>=N_post*sub) or (i>=N_pre*sub and j<N_post*sub)'

    # AMPA: exc --> exc
    synSESE = Synapses(soma, soma, model='w : 1', method=nummethod,
                       on_pre='''x_ea += w
                                 w = clip(w, 0, gmax)''',
                       namespace=param2c, name='synSESE')
    synSESE.connect(p='eps')
    synSESE.w[condsame] = 'w_p * gEE/gleakEs * (1 + randn()*0.5)'
    synSESE.w[conddiff] = 'w_m * gEE/gleakEs * (1 + randn()*0.5)'
    synSESE.delay = dE

    # AMPA: exc --> inh
    synSESI = Synapses(soma, senI, model='w : 1', method=nummethod,
                       on_pre='''x_ea += w
                                 w = clip(w, 0, gmax)''',
                       namespace=param2c, name='synSESI')
    synSESI.connect(p='eps')
    synSESI.w = 'gEI/gleakI * (1 + randn()*0.5)'
    synSESI.delay = dE

    # GABA: inh --> exc
    synSISE = Synapses(senI, soma, model='w : 1', method=nummethod,
                       on_pre='''x_i += w
                                 w = clip(w, 0, gmax)''',
                       namespace=param2c, name='synSISE')
    synSISE.connect(p='eps')
    synSISE.w = 'gIE/gleakEs * (1 + randn()*0.5)'
    synSISE.delay = dI

    # GABA: inh --> inh
    synSISI = Synapses(senI, senI, model='w : 1', method=nummethod,
                       on_pre='''x_i += w
                                 w = clip(w, 0, gmax)''',
                       namespace=param2c, name='synSISI')
    synSISI.connect(p='eps')
    synSISI.w = 'gII/gleakI * (1 + randn()*0.5)'
    synSISI.delay = dI

    # external inputs and synapses
    extS = PoissonGroup(N_X, rates=nu_ext)

    synSXSEs = Synapses(extS, soma, model='w : 1', method=nummethod,
                       on_pre='''x_ea += w
                                 w = clip(w, 0, gmax)''',
                       namespace=param2c, name='synSXSEs')
    synSXSEs.connect(condition=condsame, p='epsX * (1 + alphaX)')
    synSXSEs.connect(condition=conddiff, p='epsX * (1 - alphaX)')
    synSXSEs.w = 'gXEs/gleakEs * (1 + randn()*0.5)'
    synSXSEs.delay = dX

    synSXSI = Synapses(extS, senI, model='w : 1', method=nummethod,
                       on_pre='''x_ea += w
                                 w = clip(w, 0, gmax)''',
                       namespace=param2c, name='synSXSI')
    synSXSI.connect(p='epsX')
    synSXSI.w = 'gXI/gleakI * (1 + randn()*0.5)'
    synSXSI.delay = dX

    # variables to return
    groups = {'soma': soma, 'dend': dend, 'SI': senI, 'SX': extS}
    subgroups = {'soma1': soma1, 'soma2': soma2,
                 'dend1': dend1, 'dend2': dend2}
    synapses = {'synSESE': synSESE, 'synSESI': synSESI,
                'synSISE': synSISE, 'synSISI': synSISI,
                'synSXSI': synSXSI, 'synSXSEs': synSXSEs}

    return groups, synapses, subgroups
Example #18
0
def test_ExportDevice_basic():
    """
    Test the components and structure of the dictionary exported
    by ExportDevice
    """
    start_scope()
    set_device('exporter')

    grp = NeuronGroup(10,
                      'dv/dt = (1-v)/tau :1',
                      method='exact',
                      threshold='v > 0.5',
                      reset='v = 0',
                      refractory=2 * ms)
    tau = 10 * ms
    rate = '1/tau'
    grp.v['i > 2 and i < 5'] = -0.2
    pgrp = PoissonGroup(10, rates=rate)
    smon = SpikeMonitor(pgrp)
    smon.active = False
    netobj = Network(grp, pgrp, smon)
    netobj.run(100 * ms)
    dev_dict = device.runs
    # check the structure and components in dev_dict
    assert dev_dict[0]['duration'] == 100 * ms
    assert dev_dict[0]['inactive'][0] == smon.name
    components = dev_dict[0]['components']
    assert components['spikemonitor'][0]
    assert components['poissongroup'][0]
    assert components['neurongroup'][0]
    initializers = dev_dict[0]['initializers_connectors']
    assert initializers[0]['source'] == grp.name
    assert initializers[0]['variable'] == 'v'
    assert initializers[0]['index'] == 'i > 2 and i < 5'
    # TODO: why not a Quantity type?
    assert initializers[0]['value'] == '-0.2'
    with pytest.raises(KeyError):
        initializers[0]['identifiers']
    device.reinit()

    start_scope()
    set_device('exporter', build_on_run=False)
    tau = 10 * ms
    v0 = -70 * mV
    vth = 800 * mV
    grp = NeuronGroup(10,
                      'dv/dt = (v0-v)/tau :volt',
                      method='exact',
                      threshold='v > vth',
                      reset='v = v0',
                      refractory=2 * ms)
    v0 = -80 * mV
    grp.v[:] = 'v0 + 2 * mV'
    smon = StateMonitor(grp, 'v', record=True)
    smon.active = False
    net = Network(grp, smon)
    net.run(10 * ms)  # first run
    v0 = -75 * mV
    grp.v[3:8] = list(range(3, 8)) * mV
    smon.active = True
    net.run(20 * ms)  # second run
    v_new = -5 * mV
    grp.v['i >= 5'] = 'v0 + v_new'
    v_new = -10 * mV
    grp.v['i < 5'] = 'v0 - v_new'
    spikemon = SpikeMonitor(grp)
    net.add(spikemon)
    net.run(5 * ms)  # third run
    dev_dict = device.runs
    # check run1
    assert dev_dict[0]['duration'] == 10 * ms
    assert dev_dict[0]['inactive'][0] == smon.name
    components = dev_dict[0]['components']
    assert components['statemonitor'][0]
    assert components['neurongroup'][0]
    initializers = dev_dict[0]['initializers_connectors']
    assert initializers[0]['source'] == grp.name
    assert initializers[0]['variable'] == 'v'
    assert initializers[0]['index']
    assert initializers[0]['value'] == 'v0 + 2 * mV'
    assert initializers[0]['identifiers']['v0'] == -80 * mV
    with pytest.raises(KeyError):
        initializers[0]['identifiers']['mV']
    # check run2
    assert dev_dict[1]['duration'] == 20 * ms
    initializers = dev_dict[1]['initializers_connectors']
    assert initializers[0]['source'] == grp.name
    assert initializers[0]['variable'] == 'v'
    assert (initializers[0]['index'] == grp.indices[slice(3, 8, None)]).all()
    assert (initializers[0]['value'] == list(range(3, 8)) * mV).all()
    with pytest.raises(KeyError):
        dev_dict[1]['inactive']
        initializers[1]['identifiers']
    # check run3
    assert dev_dict[2]['duration'] == 5 * ms
    with pytest.raises(KeyError):
        dev_dict[2]['inactive']
    assert dev_dict[2]['components']['spikemonitor']
    initializers = dev_dict[2]['initializers_connectors']
    assert initializers[0]['source'] == grp.name
    assert initializers[0]['variable'] == 'v'
    assert initializers[0]['index'] == 'i >= 5'
    assert initializers[0]['value'] == 'v0 + v_new'
    assert initializers[0]['identifiers']['v0'] == -75 * mV
    assert initializers[0]['identifiers']['v_new'] == -5 * mV
    assert initializers[1]['index'] == 'i < 5'
    assert initializers[1]['value'] == 'v0 - v_new'
    assert initializers[1]['identifiers']['v_new'] == -10 * mV
    with pytest.raises(IndexError):
        initializers[2]
        dev_dict[3]
    device.reinit()
Example #19
0
def run_net(tr):

    # prefs.codegen.target = 'numpy'
    # prefs.codegen.target = 'cython'
    if tr.n_threads > 1:
        prefs.devices.cpp_standalone.openmp_threads = tr.n_threads

    set_device('cpp_standalone',
               directory='./builds/%.4d' % (tr.v_idx),
               build_on_run=False)

    # set brian 2 and numpy random seeds
    seed(tr.random_seed)
    np.random.seed(tr.random_seed + 11)

    print("Started process with id ", str(tr.v_idx))

    T = tr.T1 + tr.T2 + tr.T3 + tr.T4 + tr.T5

    namespace = tr.netw.f_to_dict(short_names=True, fast_access=True)
    namespace['idx'] = tr.v_idx

    defaultclock.dt = tr.netw.sim.dt

    # collect all network components dependent on configuration
    # (e.g. poisson vs. memnoise) and add them to the Brian 2
    # network object later
    netw_objects = []

    if tr.external_mode == 'memnoise':
        neuron_model = tr.condlif_memnoise
    elif tr.external_mode == 'poisson':
        raise NotImplementedError
        #neuron_model = tr.condlif_poisson

    if tr.syn_cond_mode == 'exp':
        neuron_model += tr.syn_cond_EE_exp
        print("Using EE exp mode")
    elif tr.syn_cond_mode == 'alpha':
        neuron_model += tr.syn_cond_EE_alpha
        print("Using EE alpha mode")
    elif tr.syn_cond_mode == 'biexp':
        neuron_model += tr.syn_cond_EE_biexp
        namespace['invpeakEE'] = (tr.tau_e / tr.tau_e_rise) ** \
            (tr.tau_e_rise / (tr.tau_e - tr.tau_e_rise))
        print("Using EE biexp mode")

    if tr.syn_cond_mode_EI == 'exp':
        neuron_model += tr.syn_cond_EI_exp
        print("Using EI exp mode")
    elif tr.syn_cond_mode_EI == 'alpha':
        neuron_model += tr.syn_cond_EI_alpha
        print("Using EI alpha mode")
    elif tr.syn_cond_mode_EI == 'biexp':
        neuron_model += tr.syn_cond_EI_biexp
        namespace['invpeakEI'] = (tr.tau_i / tr.tau_i_rise) ** \
            (tr.tau_i_rise / (tr.tau_i - tr.tau_i_rise))
        print("Using EI biexp mode")

    GExc = NeuronGroup(
        N=tr.N_e,
        model=neuron_model,
        threshold=tr.nrnEE_thrshld,
        reset=tr.nrnEE_reset,  #method=tr.neuron_method,
        name='GExc',
        namespace=namespace)
    GInh = NeuronGroup(
        N=tr.N_i,
        model=neuron_model,
        threshold='V > Vt',
        reset='V=Vr_i',  #method=tr.neuron_method,
        name='GInh',
        namespace=namespace)

    if tr.external_mode == 'memnoise':
        # GExc.mu, GInh.mu = [0.*mV] + (tr.N_e-1)*[tr.mu_e], tr.mu_i
        # GExc.sigma, GInh.sigma = [0.*mV] + (tr.N_e-1)*[tr.sigma_e], tr.sigma_i
        GExc.mu, GInh.mu = tr.mu_e, tr.mu_i
        GExc.sigma, GInh.sigma = tr.sigma_e, tr.sigma_i

    GExc.Vt, GInh.Vt = tr.Vt_e, tr.Vt_i
    GExc.V , GInh.V  = np.random.uniform(tr.Vr_e/mV, tr.Vt_e/mV,
                                         size=tr.N_e)*mV, \
                       np.random.uniform(tr.Vr_i/mV, tr.Vt_i/mV,
                                         size=tr.N_i)*mV

    netw_objects.extend([GExc, GInh])

    if tr.external_mode == 'poisson':

        if tr.PInp_mode == 'pool':
            PInp = PoissonGroup(tr.NPInp,
                                rates=tr.PInp_rate,
                                namespace=namespace,
                                name='poissongroup_exc')
            sPN = Synapses(target=GExc,
                           source=PInp,
                           model=tr.poisson_mod,
                           on_pre='gfwd_post += a_EPoi',
                           namespace=namespace,
                           name='synPInpExc')

            sPN_src, sPN_tar = generate_N_connections(N_tar=tr.N_e,
                                                      N_src=tr.NPInp,
                                                      N=tr.NPInp_1n)

        elif tr.PInp_mode == 'indep':
            PInp = PoissonGroup(tr.N_e,
                                rates=tr.PInp_rate,
                                namespace=namespace)
            sPN = Synapses(target=GExc,
                           source=PInp,
                           model=tr.poisson_mod,
                           on_pre='gfwd_post += a_EPoi',
                           namespace=namespace,
                           name='synPInp_inhInh')
            sPN_src, sPN_tar = range(tr.N_e), range(tr.N_e)

        sPN.connect(i=sPN_src, j=sPN_tar)

        if tr.PInp_mode == 'pool':

            PInp_inh = PoissonGroup(tr.NPInp_inh,
                                    rates=tr.PInp_inh_rate,
                                    namespace=namespace,
                                    name='poissongroup_inh')

            sPNInh = Synapses(target=GInh,
                              source=PInp_inh,
                              model=tr.poisson_mod,
                              on_pre='gfwd_post += a_EPoi',
                              namespace=namespace)

            sPNInh_src, sPNInh_tar = generate_N_connections(N_tar=tr.N_i,
                                                            N_src=tr.NPInp_inh,
                                                            N=tr.NPInp_inh_1n)

        elif tr.PInp_mode == 'indep':

            PInp_inh = PoissonGroup(tr.N_i,
                                    rates=tr.PInp_inh_rate,
                                    namespace=namespace)

            sPNInh = Synapses(target=GInh,
                              source=PInp_inh,
                              model=tr.poisson_mod,
                              on_pre='gfwd_post += a_EPoi',
                              namespace=namespace)

            sPNInh_src, sPNInh_tar = range(tr.N_i), range(tr.N_i)

        sPNInh.connect(i=sPNInh_src, j=sPNInh_tar)

        netw_objects.extend([PInp, sPN, PInp_inh, sPNInh])

    if tr.syn_noise:

        if tr.syn_noise_type == 'additive':
            synEE_mod = '''%s 
                           %s''' % (tr.synEE_noise_add, tr.synEE_mod)

            synEI_mod = '''%s 
                           %s''' % (tr.synEE_noise_add, tr.synEE_mod)

        elif tr.syn_noise_type == 'multiplicative':
            synEE_mod = '''%s 
                           %s''' % (tr.synEE_noise_mult, tr.synEE_mod)

            synEI_mod = '''%s 
                           %s''' % (tr.synEE_noise_mult, tr.synEE_mod)

    else:
        synEE_mod = '''%s 
                       %s''' % (tr.synEE_static, tr.synEE_mod)

        synEI_mod = '''%s 
                       %s''' % (tr.synEE_static, tr.synEE_mod)

    if tr.scl_active:
        synEE_mod = '''%s
                       %s''' % (synEE_mod, tr.synEE_scl_mod)
        synEI_mod = '''%s
                       %s''' % (synEI_mod, tr.synEI_scl_mod)

    if tr.syn_cond_mode == 'exp':
        synEE_pre_mod = mod.synEE_pre_exp
    elif tr.syn_cond_mode == 'alpha':
        synEE_pre_mod = mod.synEE_pre_alpha
    elif tr.syn_cond_mode == 'biexp':
        synEE_pre_mod = mod.synEE_pre_biexp

    synEE_post_mod = mod.syn_post

    if tr.stdp_active:
        synEE_pre_mod = '''%s 
                            %s''' % (synEE_pre_mod, mod.syn_pre_STDP)
        synEE_post_mod = '''%s 
                            %s''' % (synEE_post_mod, mod.syn_post_STDP)

    if tr.synEE_rec:
        synEE_pre_mod = '''%s 
                            %s''' % (synEE_pre_mod, mod.synEE_pre_rec)
        synEE_post_mod = '''%s 
                            %s''' % (synEE_post_mod, mod.synEE_post_rec)

    # E<-E advanced synapse model
    SynEE = Synapses(target=GExc,
                     source=GExc,
                     model=synEE_mod,
                     on_pre=synEE_pre_mod,
                     on_post=synEE_post_mod,
                     namespace=namespace,
                     dt=tr.synEE_mod_dt)

    if tr.istdp_active and tr.istdp_type == 'dbexp':

        if tr.syn_cond_mode_EI == 'exp':
            EI_pre_mod = mod.synEI_pre_exp
        elif tr.syn_cond_mode_EI == 'alpha':
            EI_pre_mod = mod.synEI_pre_alpha
        elif tr.syn_cond_mode_EI == 'biexp':
            EI_pre_mod = mod.synEI_pre_biexp

        synEI_pre_mod = '''%s 
                            %s''' % (EI_pre_mod, mod.syn_pre_STDP)
        synEI_post_mod = '''%s 
                            %s''' % (mod.syn_post, mod.syn_post_STDP)

    elif tr.istdp_active and tr.istdp_type == 'sym':

        if tr.syn_cond_mode_EI == 'exp':
            EI_pre_mod = mod.synEI_pre_sym_exp
        elif tr.syn_cond_mode_EI == 'alpha':
            EI_pre_mod = mod.synEI_pre_sym_alpha
        elif tr.syn_cond_mode_EI == 'biexp':
            EI_pre_mod = mod.synEI_pre_sym_biexp

        synEI_pre_mod = '''%s 
                            %s''' % (EI_pre_mod, mod.syn_pre_STDP)
        synEI_post_mod = '''%s 
                            %s''' % (mod.synEI_post_sym, mod.syn_post_STDP)

    if tr.istdp_active and tr.synEI_rec:

        synEI_pre_mod = '''%s 
                            %s''' % (synEI_pre_mod, mod.synEI_pre_rec)
        synEI_post_mod = '''%s 
                            %s''' % (synEI_post_mod, mod.synEI_post_rec)

    if tr.istdp_active:
        SynEI = Synapses(target=GExc,
                         source=GInh,
                         model=synEI_mod,
                         on_pre=synEI_pre_mod,
                         on_post=synEI_post_mod,
                         namespace=namespace,
                         dt=tr.synEE_mod_dt)

    else:
        model = '''a : 1
                   syn_active : 1'''
        SynEI = Synapses(target=GExc,
                         source=GInh,
                         model=model,
                         on_pre='gi_post += a',
                         namespace=namespace)

    #other simple
    SynIE = Synapses(target=GInh,
                     source=GExc,
                     on_pre='ge_post += a_ie',
                     namespace=namespace)

    SynII = Synapses(target=GInh,
                     source=GInh,
                     on_pre='gi_post += a_ii',
                     namespace=namespace)

    sEE_src, sEE_tar = generate_full_connectivity(tr.N_e, same=True)
    SynEE.connect(i=sEE_src, j=sEE_tar)
    SynEE.syn_active = 0
    SynEE.taupre, SynEE.taupost = tr.taupre, tr.taupost

    if tr.istdp_active and tr.istrct_active:
        print('istrct active')
        sEI_src, sEI_tar = generate_full_connectivity(Nsrc=tr.N_i,
                                                      Ntar=tr.N_e,
                                                      same=False)
        SynEI.connect(i=sEI_src, j=sEI_tar)
        SynEI.syn_active = 0

    else:
        print('istrct not active')
        if tr.weight_mode == 'init':
            sEI_src, sEI_tar = generate_connections(tr.N_e, tr.N_i, tr.p_ei)
            # print('Index Zero will not get inhibition')
            # sEI_src, sEI_tar = np.array(sEI_src), np.array(sEI_tar)
            # sEI_src, sEI_tar = sEI_src[sEI_tar > 0],sEI_tar[sEI_tar > 0]

        elif tr.weight_mode == 'load':

            fpath = os.path.join(tr.basepath, tr.weight_path)

            with open(fpath + 'synei_a.p', 'rb') as pfile:
                synei_a_init = pickle.load(pfile)

            sEI_src, sEI_tar = synei_a_init['i'], synei_a_init['j']

        SynEI.connect(i=sEI_src, j=sEI_tar)

    if tr.istdp_active:
        SynEI.taupre, SynEI.taupost = tr.taupre_EI, tr.taupost_EI

    sIE_src, sIE_tar = generate_connections(tr.N_i, tr.N_e, tr.p_ie)
    sII_src, sII_tar = generate_connections(tr.N_i, tr.N_i, tr.p_ii, same=True)

    SynIE.connect(i=sIE_src, j=sIE_tar)
    SynII.connect(i=sII_src, j=sII_tar)

    tr.f_add_result('sEE_src', sEE_src)
    tr.f_add_result('sEE_tar', sEE_tar)
    tr.f_add_result('sIE_src', sIE_src)
    tr.f_add_result('sIE_tar', sIE_tar)
    tr.f_add_result('sEI_src', sEI_src)
    tr.f_add_result('sEI_tar', sEI_tar)
    tr.f_add_result('sII_src', sII_src)
    tr.f_add_result('sII_tar', sII_tar)

    if tr.syn_noise:
        SynEE.syn_sigma = tr.syn_sigma
        SynEE.run_regularly('a = clip(a,0,amax)',
                            when='after_groups',
                            name='SynEE_noise_clipper')

    if tr.syn_noise and tr.istdp_active:
        SynEI.syn_sigma = tr.syn_sigma
        SynEI.run_regularly('a = clip(a,0,amax)',
                            when='after_groups',
                            name='SynEI_noise_clipper')

    SynEE.insert_P = tr.insert_P
    SynEE.p_inactivate = tr.p_inactivate
    SynEE.stdp_active = 1
    print('Setting maximum EE weight threshold to ', tr.amax)
    SynEE.amax = tr.amax

    if tr.istdp_active:
        SynEI.insert_P = tr.insert_P_ei
        SynEI.p_inactivate = tr.p_inactivate_ei
        SynEI.stdp_active = 1
        SynEI.amax = tr.amax

    SynEE.syn_active, SynEE.a = init_synapses('EE', tr)
    SynEI.syn_active, SynEI.a = init_synapses('EI', tr)

    # recording of stdp in T4
    SynEE.stdp_rec_start = tr.T1 + tr.T2 + tr.T3
    SynEE.stdp_rec_max = tr.T1 + tr.T2 + tr.T3 + tr.stdp_rec_T

    if tr.istdp_active:
        SynEI.stdp_rec_start = tr.T1 + tr.T2 + tr.T3
        SynEI.stdp_rec_max = tr.T1 + tr.T2 + tr.T3 + tr.stdp_rec_T

    # synaptic scaling
    if tr.netw.config.scl_active:

        if tr.syn_scl_rec:
            SynEE.scl_rec_start = tr.T1 + tr.T2 + tr.T3
            SynEE.scl_rec_max = tr.T1 + tr.T2 + tr.T3 + tr.scl_rec_T
        else:
            SynEE.scl_rec_start = T + 10 * second
            SynEE.scl_rec_max = T

        if tr.sig_ATotalMax == 0.:
            GExc.ANormTar = tr.ATotalMax
        else:
            GExc.ANormTar = np.random.normal(loc=tr.ATotalMax,
                                             scale=tr.sig_ATotalMax,
                                             size=tr.N_e)

        SynEE.summed_updaters['AsumEE_post']._clock = Clock(
            dt=tr.dt_synEE_scaling)
        synee_scaling = SynEE.run_regularly(tr.synEE_scaling,
                                            dt=tr.dt_synEE_scaling,
                                            when='end',
                                            name='synEE_scaling')

    if tr.istdp_active and tr.netw.config.iscl_active:

        if tr.syn_iscl_rec:
            SynEI.scl_rec_start = tr.T1 + tr.T2 + tr.T3
            SynEI.scl_rec_max = tr.T1 + tr.T2 + tr.T3 + tr.scl_rec_T
        else:
            SynEI.scl_rec_start = T + 10 * second
            SynEI.scl_rec_max = T

        if tr.sig_iATotalMax == 0.:
            GExc.iANormTar = tr.iATotalMax
        else:
            GExc.iANormTar = np.random.normal(loc=tr.iATotalMax,
                                              scale=tr.sig_iATotalMax,
                                              size=tr.N_e)

        SynEI.summed_updaters['AsumEI_post']._clock = Clock(
            dt=tr.dt_synEE_scaling)

        synei_scaling = SynEI.run_regularly(tr.synEI_scaling,
                                            dt=tr.dt_synEE_scaling,
                                            when='end',
                                            name='synEI_scaling')

    # # intrinsic plasticity
    # if tr.netw.config.it_active:
    #     GExc.h_ip = tr.h_ip
    #     GExc.run_regularly(tr.intrinsic_mod, dt = tr.it_dt, when='end')

    # structural plasticity
    if tr.netw.config.strct_active:
        if tr.strct_mode == 'zero':
            if tr.turnover_rec:
                strct_mod = '''%s 
                                %s''' % (tr.strct_mod, tr.turnover_rec_mod)
            else:
                strct_mod = tr.strct_mod

            strctplst = SynEE.run_regularly(strct_mod,
                                            dt=tr.strct_dt,
                                            when='end',
                                            name='strct_plst_zero')

        elif tr.strct_mode == 'thrs':
            if tr.turnover_rec:
                strct_mod_thrs = '''%s 
                                %s''' % (tr.strct_mod_thrs,
                                         tr.turnover_rec_mod)
            else:
                strct_mod_thrs = tr.strct_mod_thrs

            strctplst = SynEE.run_regularly(strct_mod_thrs,
                                            dt=tr.strct_dt,
                                            when='end',
                                            name='strct_plst_thrs')

    if tr.istdp_active and tr.netw.config.istrct_active:
        if tr.strct_mode == 'zero':
            if tr.turnover_rec:
                strct_mod_EI = '''%s 
                                   %s''' % (tr.strct_mod,
                                            tr.turnoverEI_rec_mod)
            else:
                strct_mod_EI = tr.strct_mod

            strctplst_EI = SynEI.run_regularly(strct_mod_EI,
                                               dt=tr.strct_dt,
                                               when='end',
                                               name='strct_plst_EI')

        elif tr.strct_mode == 'thrs':
            raise NotImplementedError

    netw_objects.extend([SynEE, SynEI, SynIE, SynII])

    # keep track of the number of active synapses
    sum_target = NeuronGroup(1, 'c : 1 (shared)', dt=tr.csample_dt)

    sum_model = '''NSyn : 1 (constant)
                   c_post = (1.0*syn_active_pre)/NSyn : 1 (summed)'''
    sum_connection = Synapses(target=sum_target,
                              source=SynEE,
                              model=sum_model,
                              dt=tr.csample_dt,
                              name='get_active_synapse_count')
    sum_connection.connect()
    sum_connection.NSyn = tr.N_e * (tr.N_e - 1)

    if tr.adjust_insertP:
        # homeostatically adjust growth rate
        growth_updater = Synapses(sum_target, SynEE)
        growth_updater.run_regularly('insert_P_post *= 0.1/c_pre',
                                     when='after_groups',
                                     dt=tr.csample_dt,
                                     name='update_insP')
        growth_updater.connect(j='0')

        netw_objects.extend([sum_target, sum_connection, growth_updater])

    if tr.istdp_active and tr.istrct_active:

        # keep track of the number of active synapses
        sum_target_EI = NeuronGroup(1, 'c : 1 (shared)', dt=tr.csample_dt)

        sum_model_EI = '''NSyn : 1 (constant)
                          c_post = (1.0*syn_active_pre)/NSyn : 1 (summed)'''
        sum_connection_EI = Synapses(target=sum_target_EI,
                                     source=SynEI,
                                     model=sum_model_EI,
                                     dt=tr.csample_dt,
                                     name='get_active_synapse_count_EI')
        sum_connection_EI.connect()
        sum_connection_EI.NSyn = tr.N_e * tr.N_i

        if tr.adjust_EI_insertP:
            # homeostatically adjust growth rate
            growth_updater_EI = Synapses(sum_target_EI, SynEI)
            growth_updater_EI.run_regularly('insert_P_post *= 0.1/c_pre',
                                            when='after_groups',
                                            dt=tr.csample_dt,
                                            name='update_insP_EI')
            growth_updater_EI.connect(j='0')

            netw_objects.extend(
                [sum_target_EI, sum_connection_EI, growth_updater_EI])

    # -------------- recording ------------------

    GExc_recvars = []
    if tr.memtraces_rec:
        GExc_recvars.append('V')
    if tr.vttraces_rec:
        GExc_recvars.append('Vt')
    if tr.getraces_rec:
        GExc_recvars.append('ge')
    if tr.gitraces_rec:
        GExc_recvars.append('gi')
    if tr.gfwdtraces_rec and tr.external_mode == 'poisson':
        GExc_recvars.append('gfwd')

    GInh_recvars = GExc_recvars

    GExc_stat = StateMonitor(GExc,
                             GExc_recvars,
                             record=list(range(tr.nrec_GExc_stat)),
                             dt=tr.GExc_stat_dt)
    GInh_stat = StateMonitor(GInh,
                             GInh_recvars,
                             record=list(range(tr.nrec_GInh_stat)),
                             dt=tr.GInh_stat_dt)

    # SynEE stat
    SynEE_recvars = []
    if tr.synee_atraces_rec:
        SynEE_recvars.append('a')
    if tr.synee_activetraces_rec:
        SynEE_recvars.append('syn_active')
    if tr.synee_Apretraces_rec:
        SynEE_recvars.append('Apre')
    if tr.synee_Aposttraces_rec:
        SynEE_recvars.append('Apost')

    SynEE_stat = StateMonitor(SynEE,
                              SynEE_recvars,
                              record=range(tr.n_synee_traces_rec),
                              when='end',
                              dt=tr.synEE_stat_dt)

    if tr.istdp_active:
        # SynEI stat
        SynEI_recvars = []
        if tr.synei_atraces_rec:
            SynEI_recvars.append('a')
        if tr.synei_activetraces_rec:
            SynEI_recvars.append('syn_active')
        if tr.synei_Apretraces_rec:
            SynEI_recvars.append('Apre')
        if tr.synei_Aposttraces_rec:
            SynEI_recvars.append('Apost')

        SynEI_stat = StateMonitor(SynEI,
                                  SynEI_recvars,
                                  record=range(tr.n_synei_traces_rec),
                                  when='end',
                                  dt=tr.synEI_stat_dt)
        netw_objects.append(SynEI_stat)

    if tr.adjust_insertP:

        C_stat = StateMonitor(sum_target,
                              'c',
                              dt=tr.csample_dt,
                              record=[0],
                              when='end')
        insP_stat = StateMonitor(SynEE,
                                 'insert_P',
                                 dt=tr.csample_dt,
                                 record=[0],
                                 when='end')
        netw_objects.extend([C_stat, insP_stat])

    if tr.istdp_active and tr.adjust_EI_insertP:

        C_EI_stat = StateMonitor(sum_target_EI,
                                 'c',
                                 dt=tr.csample_dt,
                                 record=[0],
                                 when='end')
        insP_EI_stat = StateMonitor(SynEI,
                                    'insert_P',
                                    dt=tr.csample_dt,
                                    record=[0],
                                    when='end')
        netw_objects.extend([C_EI_stat, insP_EI_stat])

    GExc_spks = SpikeMonitor(GExc)
    GInh_spks = SpikeMonitor(GInh)

    GExc_rate = PopulationRateMonitor(GExc)
    GInh_rate = PopulationRateMonitor(GInh)

    if tr.external_mode == 'poisson':
        PInp_spks = SpikeMonitor(PInp)
        PInp_rate = PopulationRateMonitor(PInp)
        netw_objects.extend([PInp_spks, PInp_rate])

    if tr.synee_a_nrecpoints == 0 or tr.sim.T2 == 0 * second:
        SynEE_a_dt = 2 * (tr.T1 + tr.T2 + tr.T3 + tr.T4 + tr.T5)
    else:
        SynEE_a_dt = tr.sim.T2 / tr.synee_a_nrecpoints

        # make sure that choice of SynEE_a_dt does lead
        # to execessively many recordings - this can
        # happen if t1 >> t2.
        estm_nrecs = int(T / SynEE_a_dt)
        if estm_nrecs > 3 * tr.synee_a_nrecpoints:
            print('''Estimated number of EE weight recordings (%d)
            exceeds desired number (%d), increasing 
            SynEE_a_dt''' % (estm_nrecs, tr.synee_a_nrecpoints))

            SynEE_a_dt = T / tr.synee_a_nrecpoints

    SynEE_a = StateMonitor(SynEE, ['a', 'syn_active'],
                           record=range(tr.N_e * (tr.N_e - 1)),
                           dt=SynEE_a_dt,
                           when='end',
                           order=100)

    if tr.istrct_active:
        record_range = range(tr.N_e * tr.N_i)
    else:
        record_range = range(len(sEI_src))

    if tr.synei_a_nrecpoints > 0 and tr.sim.T2 > 0 * second:
        SynEI_a_dt = tr.sim.T2 / tr.synei_a_nrecpoints

        estm_nrecs = int(T / SynEI_a_dt)
        if estm_nrecs > 3 * tr.synei_a_nrecpoints:
            print('''Estimated number of EI weight recordings
            (%d) exceeds desired number (%d), increasing 
            SynEI_a_dt''' % (estm_nrecs, tr.synei_a_nrecpoints))

            SynEI_a_dt = T / tr.synei_a_nrecpoints

        SynEI_a = StateMonitor(SynEI, ['a', 'syn_active'],
                               record=record_range,
                               dt=SynEI_a_dt,
                               when='end',
                               order=100)

        netw_objects.append(SynEI_a)

    netw_objects.extend([
        GExc_stat, GInh_stat, SynEE_stat, SynEE_a, GExc_spks, GInh_spks,
        GExc_rate, GInh_rate
    ])

    if (tr.synEEdynrec
            and (2 * tr.syndynrec_npts * tr.syndynrec_dt < tr.sim.T2)):
        SynEE_dynrec = StateMonitor(SynEE, ['a'],
                                    record=range(tr.N_e * (tr.N_e - 1)),
                                    dt=tr.syndynrec_dt,
                                    name='SynEE_dynrec',
                                    when='end',
                                    order=100)
        SynEE_dynrec.active = False
        netw_objects.extend([SynEE_dynrec])

    if (tr.synEIdynrec
            and (2 * tr.syndynrec_npts * tr.syndynrec_dt < tr.sim.T2)):
        SynEI_dynrec = StateMonitor(SynEI, ['a'],
                                    record=record_range,
                                    dt=tr.syndynrec_dt,
                                    name='SynEI_dynrec',
                                    when='end',
                                    order=100)
        SynEI_dynrec.active = False
        netw_objects.extend([SynEI_dynrec])

    net = Network(*netw_objects)

    def set_active(*argv):
        for net_object in argv:
            net_object.active = True

    def set_inactive(*argv):
        for net_object in argv:
            net_object.active = False

    ### Simulation periods

    # --------- T1 ---------
    # initial recording period,
    # all recorders active

    T1T3_recorders = [
        GExc_spks, GInh_spks, SynEE_stat, GExc_stat, GInh_stat, GExc_rate,
        GInh_rate
    ]

    if tr.istdp_active:
        T1T3_recorders.append(SynEI_stat)

    set_active(*T1T3_recorders)

    if tr.external_mode == 'poisson':
        set_active(PInp_spks, PInp_rate)

    net.run(tr.sim.T1, report='text', report_period=300 * second, profile=True)

    # --------- T2 ---------
    # main simulation period
    # only active recordings are:
    #   1) turnover 2) C_stat 3) SynEE_a

    set_inactive(*T1T3_recorders)

    if tr.T2_spks_rec:
        set_active(GExc_spks, GInh_spks)

    if tr.external_mode == 'poisson':
        set_inactive(PInp_spks, PInp_rate)

    run_T2_syndynrec(net, tr, netw_objects)

    # --------- T3 ---------
    # second recording period,
    # all recorders active

    set_active(*T1T3_recorders)

    if tr.external_mode == 'poisson':
        set_active(PInp_spks, PInp_rate)

    run_T3_split(net, tr)

    # --------- T4 ---------
    # record STDP and scaling weight changes to file
    # through the cpp models

    set_inactive(*T1T3_recorders)

    if tr.external_mode == 'poisson':
        set_inactive(PInp_spks, PInp_rate)

    run_T4(net, tr)

    # --------- T5 ---------
    # freeze network and record Exc spikes
    # for cross correlations

    if tr.scl_active:
        synee_scaling.active = False
    if tr.istdp_active and tr.netw.config.iscl_active:
        synei_scaling.active = False
    if tr.strct_active:
        strctplst.active = False
    if tr.istdp_active and tr.istrct_active:
        strctplst_EI.active = False
    SynEE.stdp_active = 0
    if tr.istdp_active:
        SynEI.stdp_active = 0

    set_active(GExc_rate, GInh_rate)
    set_active(GExc_spks, GInh_spks)

    run_T5(net, tr)

    SynEE_a.record_single_timestep()
    if tr.synei_a_nrecpoints > 0 and tr.sim.T2 > 0. * second:
        SynEI_a.record_single_timestep()

    device.build(directory='builds/%.4d' % (tr.v_idx),
                 clean=True,
                 compile=True,
                 run=True,
                 debug=False)

    # -----------------------------------------

    # save monitors as raws in build directory
    raw_dir = 'builds/%.4d/raw/' % (tr.v_idx)

    if not os.path.exists(raw_dir):
        os.makedirs(raw_dir)

    with open(raw_dir + 'namespace.p', 'wb') as pfile:
        pickle.dump(namespace, pfile)

    with open(raw_dir + 'gexc_stat.p', 'wb') as pfile:
        pickle.dump(GExc_stat.get_states(), pfile)
    with open(raw_dir + 'ginh_stat.p', 'wb') as pfile:
        pickle.dump(GInh_stat.get_states(), pfile)

    with open(raw_dir + 'synee_stat.p', 'wb') as pfile:
        pickle.dump(SynEE_stat.get_states(), pfile)

    if tr.istdp_active:
        with open(raw_dir + 'synei_stat.p', 'wb') as pfile:
            pickle.dump(SynEI_stat.get_states(), pfile)

    if ((tr.synEEdynrec or tr.synEIdynrec)
            and (2 * tr.syndynrec_npts * tr.syndynrec_dt < tr.sim.T2)):

        if tr.synEEdynrec:
            with open(raw_dir + 'syneedynrec.p', 'wb') as pfile:
                pickle.dump(SynEE_dynrec.get_states(), pfile)
        if tr.synEIdynrec:
            with open(raw_dir + 'syneidynrec.p', 'wb') as pfile:
                pickle.dump(SynEI_dynrec.get_states(), pfile)

    with open(raw_dir + 'synee_a.p', 'wb') as pfile:
        SynEE_a_states = SynEE_a.get_states()
        if tr.crs_crrs_rec:
            SynEE_a_states['i'] = list(SynEE.i)
            SynEE_a_states['j'] = list(SynEE.j)
        pickle.dump(SynEE_a_states, pfile)

    if tr.synei_a_nrecpoints > 0 and tr.sim.T2 > 0. * second:
        with open(raw_dir + 'synei_a.p', 'wb') as pfile:
            SynEI_a_states = SynEI_a.get_states()
            if tr.crs_crrs_rec:
                SynEI_a_states['i'] = list(SynEI.i)
                SynEI_a_states['j'] = list(SynEI.j)
            pickle.dump(SynEI_a_states, pfile)

    if tr.adjust_insertP:
        with open(raw_dir + 'c_stat.p', 'wb') as pfile:
            pickle.dump(C_stat.get_states(), pfile)

        with open(raw_dir + 'insP_stat.p', 'wb') as pfile:
            pickle.dump(insP_stat.get_states(), pfile)

    if tr.istdp_active and tr.adjust_EI_insertP:
        with open(raw_dir + 'c_EI_stat.p', 'wb') as pfile:
            pickle.dump(C_EI_stat.get_states(), pfile)

        with open(raw_dir + 'insP_EI_stat.p', 'wb') as pfile:
            pickle.dump(insP_EI_stat.get_states(), pfile)

    with open(raw_dir + 'gexc_spks.p', 'wb') as pfile:
        pickle.dump(GExc_spks.get_states(), pfile)
    with open(raw_dir + 'ginh_spks.p', 'wb') as pfile:
        pickle.dump(GInh_spks.get_states(), pfile)

    if tr.external_mode == 'poisson':
        with open(raw_dir + 'pinp_spks.p', 'wb') as pfile:
            pickle.dump(PInp_spks.get_states(), pfile)

    with open(raw_dir + 'gexc_rate.p', 'wb') as pfile:
        pickle.dump(GExc_rate.get_states(), pfile)
        if tr.rates_rec:
            pickle.dump(GExc_rate.smooth_rate(width=25 * ms), pfile)
    with open(raw_dir + 'ginh_rate.p', 'wb') as pfile:
        pickle.dump(GInh_rate.get_states(), pfile)
        if tr.rates_rec:
            pickle.dump(GInh_rate.smooth_rate(width=25 * ms), pfile)

    if tr.external_mode == 'poisson':
        with open(raw_dir + 'pinp_rate.p', 'wb') as pfile:
            pickle.dump(PInp_rate.get_states(), pfile)
            if tr.rates_rec:
                pickle.dump(PInp_rate.smooth_rate(width=25 * ms), pfile)

    # ----------------- add raw data ------------------------
    fpath = 'builds/%.4d/' % (tr.v_idx)

    from pathlib import Path

    Path(fpath + 'turnover').touch()
    turnover_data = np.genfromtxt(fpath + 'turnover', delimiter=',')
    os.remove(fpath + 'turnover')

    with open(raw_dir + 'turnover.p', 'wb') as pfile:
        pickle.dump(turnover_data, pfile)

    Path(fpath + 'turnover_EI').touch()
    turnover_EI_data = np.genfromtxt(fpath + 'turnover_EI', delimiter=',')
    os.remove(fpath + 'turnover_EI')

    with open(raw_dir + 'turnover_EI.p', 'wb') as pfile:
        pickle.dump(turnover_EI_data, pfile)

    Path(fpath + 'spk_register').touch()
    spk_register_data = np.genfromtxt(fpath + 'spk_register', delimiter=',')
    os.remove(fpath + 'spk_register')

    with open(raw_dir + 'spk_register.p', 'wb') as pfile:
        pickle.dump(spk_register_data, pfile)

    Path(fpath + 'spk_register_EI').touch()
    spk_register_EI_data = np.genfromtxt(fpath + 'spk_register_EI',
                                         delimiter=',')
    os.remove(fpath + 'spk_register_EI')

    with open(raw_dir + 'spk_register_EI.p', 'wb') as pfile:
        pickle.dump(spk_register_EI_data, pfile)

    Path(fpath + 'scaling_deltas').touch()
    scaling_deltas_data = np.genfromtxt(fpath + 'scaling_deltas',
                                        delimiter=',')
    os.remove(fpath + 'scaling_deltas')

    with open(raw_dir + 'scaling_deltas.p', 'wb') as pfile:
        pickle.dump(scaling_deltas_data, pfile)

    Path(fpath + 'scaling_deltas_EI').touch()
    scaling_deltas_data = np.genfromtxt(fpath + 'scaling_deltas_EI',
                                        delimiter=',')
    os.remove(fpath + 'scaling_deltas_EI')

    with open(raw_dir + 'scaling_deltas_EI.p', 'wb') as pfile:
        pickle.dump(scaling_deltas_data, pfile)

    with open(raw_dir + 'profiling_summary.txt', 'w+') as tfile:
        tfile.write(str(profiling_summary(net)))

    # --------------- cross-correlations ---------------------

    if tr.crs_crrs_rec:

        GExc_spks = GExc_spks.get_states()
        synee_a = SynEE_a_states
        wsize = 100 * pq.ms

        for binsize in [1 * pq.ms, 2 * pq.ms, 5 * pq.ms]:

            wlen = int(wsize / binsize)

            ts, idxs = GExc_spks['t'], GExc_spks['i']
            idxs = idxs[ts > tr.T1 + tr.T2 + tr.T3 + tr.T4]
            ts = ts[ts > tr.T1 + tr.T2 + tr.T3 + tr.T4]
            ts = ts - (tr.T1 + tr.T2 + tr.T3 + tr.T4)

            sts = [
                neo.SpikeTrain(ts[idxs == i] / second * pq.s,
                               t_stop=tr.T5 / second * pq.s)
                for i in range(tr.N_e)
            ]

            crs_crrs, syn_a = [], []

            for f, (i, j) in enumerate(zip(synee_a['i'], synee_a['j'])):
                if synee_a['syn_active'][-1][f] == 1:

                    crs_crr, cbin = cch(BinnedSpikeTrain(sts[i],
                                                         binsize=binsize),
                                        BinnedSpikeTrain(sts[j],
                                                         binsize=binsize),
                                        cross_corr_coef=True,
                                        border_correction=True,
                                        window=(-1 * wlen, wlen))

                    crs_crrs.append(list(np.array(crs_crr).T[0]))
                    syn_a.append(synee_a['a'][-1][f])

            fname = 'crs_crrs_wsize%dms_binsize%fms_full' % (wsize / pq.ms,
                                                             binsize / pq.ms)

            df = {
                'cbin': cbin,
                'crs_crrs': np.array(crs_crrs),
                'syn_a': np.array(syn_a),
                'binsize': binsize,
                'wsize': wsize,
                'wlen': wlen
            }

            with open('builds/%.4d/raw/' % (tr.v_idx) + fname + '.p',
                      'wb') as pfile:
                pickle.dump(df, pfile)

        GInh_spks = GInh_spks.get_states()
        synei_a = SynEI_a_states
        wsize = 100 * pq.ms

        for binsize in [1 * pq.ms, 2 * pq.ms, 5 * pq.ms]:

            wlen = int(wsize / binsize)

            ts_E, idxs_E = GExc_spks['t'], GExc_spks['i']
            idxs_E = idxs_E[ts_E > tr.T1 + tr.T2 + tr.T3 + tr.T4]
            ts_E = ts_E[ts_E > tr.T1 + tr.T2 + tr.T3 + tr.T4]
            ts_E = ts_E - (tr.T1 + tr.T2 + tr.T3 + tr.T4)

            ts_I, idxs_I = GInh_spks['t'], GInh_spks['i']
            idxs_I = idxs_I[ts_I > tr.T1 + tr.T2 + tr.T3 + tr.T4]
            ts_I = ts_I[ts_I > tr.T1 + tr.T2 + tr.T3 + tr.T4]
            ts_I = ts_I - (tr.T1 + tr.T2 + tr.T3 + tr.T4)

            sts_E = [
                neo.SpikeTrain(ts_E[idxs_E == i] / second * pq.s,
                               t_stop=tr.T5 / second * pq.s)
                for i in range(tr.N_e)
            ]

            sts_I = [
                neo.SpikeTrain(ts_I[idxs_I == i] / second * pq.s,
                               t_stop=tr.T5 / second * pq.s)
                for i in range(tr.N_i)
            ]

            crs_crrs, syn_a = [], []

            for f, (i, j) in enumerate(zip(synei_a['i'], synei_a['j'])):
                if synei_a['syn_active'][-1][f] == 1:

                    crs_crr, cbin = cch(BinnedSpikeTrain(sts_I[i],
                                                         binsize=binsize),
                                        BinnedSpikeTrain(sts_E[j],
                                                         binsize=binsize),
                                        cross_corr_coef=True,
                                        border_correction=True,
                                        window=(-1 * wlen, wlen))

                    crs_crrs.append(list(np.array(crs_crr).T[0]))
                    syn_a.append(synei_a['a'][-1][f])

            fname = 'EI_crrs_wsize%dms_binsize%fms_full' % (wsize / pq.ms,
                                                            binsize / pq.ms)

            df = {
                'cbin': cbin,
                'crs_crrs': np.array(crs_crrs),
                'syn_a': np.array(syn_a),
                'binsize': binsize,
                'wsize': wsize,
                'wlen': wlen
            }

            with open('builds/%.4d/raw/' % (tr.v_idx) + fname + '.p',
                      'wb') as pfile:
                pickle.dump(df, pfile)

    # -----------------  clean up  ---------------------------
    shutil.rmtree('builds/%.4d/results/' % (tr.v_idx))
    shutil.rmtree('builds/%.4d/static_arrays/' % (tr.v_idx))
    shutil.rmtree('builds/%.4d/brianlib/' % (tr.v_idx))
    shutil.rmtree('builds/%.4d/code_objects/' % (tr.v_idx))

    # ---------------- plot results --------------------------

    #os.chdir('./analysis/file_based/')

    if tr.istdp_active:
        from src.analysis.overview_winh import overview_figure
        overview_figure('builds/%.4d' % (tr.v_idx), namespace)
    else:
        from src.analysis.overview import overview_figure
        overview_figure('builds/%.4d' % (tr.v_idx), namespace)

    from src.analysis.synw_fb import synw_figure
    synw_figure('builds/%.4d' % (tr.v_idx), namespace)
    if tr.istdp_active:
        synw_figure('builds/%.4d' % (tr.v_idx), namespace, connections='EI')

    from src.analysis.synw_log_fb import synw_log_figure
    synw_log_figure('builds/%.4d' % (tr.v_idx), namespace)
    if tr.istdp_active:
        synw_log_figure('builds/%.4d' % (tr.v_idx),
                        namespace,
                        connections='EI')
def run_net(tr):

    # prefs.codegen.target = 'numpy'
    # prefs.codegen.target = 'cython'
    if tr.n_threads > 1:
        prefs.devices.cpp_standalone.openmp_threads = tr.n_threads

    set_device('cpp_standalone',
               directory='./builds/%.4d' % (tr.v_idx),
               build_on_run=False)

    print("Started process with id ", str(tr.v_idx))

    T = tr.T1 + tr.T2 + tr.T3 + tr.T4 + tr.T5

    namespace = tr.netw.f_to_dict(short_names=True, fast_access=True)
    namespace['idx'] = tr.v_idx

    defaultclock.dt = tr.netw.sim.dt

    # collect all network components dependent on configuration
    # (e.g. poisson vs. memnoise) and add them to the Brian 2
    # network object later
    netw_objects = []

    if tr.external_mode == 'memnoise':
        neuron_model = tr.condlif_memnoise
    elif tr.external_mode == 'poisson':
        neuron_model = tr.condlif_poisson

    GExc = NeuronGroup(
        N=tr.N_e,
        model=neuron_model,
        threshold=tr.nrnEE_thrshld,
        reset=tr.nrnEE_reset,  #method=tr.neuron_method,
        namespace=namespace)
    GInh = NeuronGroup(
        N=tr.N_i,
        model=neuron_model,
        threshold='V > Vt',
        reset='V=Vr_i',  #method=tr.neuron_method,
        namespace=namespace)

    if tr.external_mode == 'memnoise':
        GExc.mu, GInh.mu = tr.mu_e, tr.mu_i
        GExc.sigma, GInh.sigma = tr.sigma_e, tr.sigma_i

    GExc.Vt, GInh.Vt = tr.Vt_e, tr.Vt_i
    GExc.V , GInh.V  = np.random.uniform(tr.Vr_e/mV, tr.Vt_e/mV,
                                         size=tr.N_e)*mV, \
                       np.random.uniform(tr.Vr_i/mV, tr.Vt_i/mV,
                                         size=tr.N_i)*mV

    netw_objects.extend([GExc, GInh])

    synEE_pre_mod = mod.synEE_pre
    synEE_post_mod = mod.synEE_post

    if tr.external_mode == 'poisson':

        if tr.PInp_mode == 'pool':
            PInp = PoissonGroup(tr.NPInp,
                                rates=tr.PInp_rate,
                                namespace=namespace,
                                name='poissongroup_exc')
            sPN = Synapses(target=GExc,
                           source=PInp,
                           model=tr.poisson_mod,
                           on_pre='gfwd_post += a_EPoi',
                           namespace=namespace,
                           name='synPInpExc')

            sPN_src, sPN_tar = generate_N_connections(N_tar=tr.N_e,
                                                      N_src=tr.NPInp,
                                                      N=tr.NPInp_1n)

        elif tr.PInp_mode == 'indep':
            PInp = PoissonGroup(tr.N_e,
                                rates=tr.PInp_rate,
                                namespace=namespace)
            sPN = Synapses(target=GExc,
                           source=PInp,
                           model=tr.poisson_mod,
                           on_pre='gfwd_post += a_EPoi',
                           namespace=namespace,
                           name='synPInp_inhInh')
            sPN_src, sPN_tar = range(tr.N_e), range(tr.N_e)

        sPN.connect(i=sPN_src, j=sPN_tar)

        if tr.PInp_mode == 'pool':
            PInp_inh = PoissonGroup(tr.NPInp_inh,
                                    rates=tr.PInp_inh_rate,
                                    namespace=namespace,
                                    name='poissongroup_inh')
            sPNInh = Synapses(target=GInh,
                              source=PInp_inh,
                              model=tr.poisson_mod,
                              on_pre='gfwd_post += a_EPoi',
                              namespace=namespace)
            sPNInh_src, sPNInh_tar = generate_N_connections(N_tar=tr.N_i,
                                                            N_src=tr.NPInp_inh,
                                                            N=tr.NPInp_inh_1n)

        elif tr.PInp_mode == 'indep':

            PInp_inh = PoissonGroup(tr.N_i,
                                    rates=tr.PInp_inh_rate,
                                    namespace=namespace)
            sPNInh = Synapses(target=GInh,
                              source=PInp_inh,
                              model=tr.poisson_mod,
                              on_pre='gfwd_post += a_EPoi',
                              namespace=namespace)
            sPNInh_src, sPNInh_tar = range(tr.N_i), range(tr.N_i)

        sPNInh.connect(i=sPNInh_src, j=sPNInh_tar)

        netw_objects.extend([PInp, sPN, PInp_inh, sPNInh])

    if tr.syn_noise:
        synEE_mod = '''%s 
                       %s''' % (tr.synEE_noise, tr.synEE_mod)
    else:
        synEE_mod = '''%s 
                       %s''' % (tr.synEE_static, tr.synEE_mod)

    if tr.stdp_active:
        synEE_pre_mod = '''%s 
                            %s''' % (synEE_pre_mod, mod.synEE_pre_STDP)
        synEE_post_mod = '''%s 
                            %s''' % (synEE_post_mod, mod.synEE_post_STDP)

    if tr.synEE_rec:
        synEE_pre_mod = '''%s 
                            %s''' % (synEE_pre_mod, mod.synEE_pre_rec)
        synEE_post_mod = '''%s 
                            %s''' % (synEE_post_mod, mod.synEE_post_rec)

    # E<-E advanced synapse model, rest simple
    SynEE = Synapses(target=GExc,
                     source=GExc,
                     model=synEE_mod,
                     on_pre=synEE_pre_mod,
                     on_post=synEE_post_mod,
                     namespace=namespace,
                     dt=tr.synEE_mod_dt)
    SynIE = Synapses(target=GInh,
                     source=GExc,
                     on_pre='ge_post += a_ie',
                     namespace=namespace)
    SynEI = Synapses(target=GExc,
                     source=GInh,
                     on_pre='gi_post += a_ei',
                     namespace=namespace)
    SynII = Synapses(target=GInh,
                     source=GInh,
                     on_pre='gi_post += a_ii',
                     namespace=namespace)

    if tr.strct_active:
        sEE_src, sEE_tar = generate_full_connectivity(tr.N_e, same=True)
        SynEE.connect(i=sEE_src, j=sEE_tar)
        SynEE.syn_active = 0

    else:
        srcs_full, tars_full = generate_full_connectivity(tr.N_e, same=True)
        SynEE.connect(i=srcs_full, j=tars_full)
        SynEE.syn_active = 0

    sIE_src, sIE_tar = generate_connections(tr.N_i, tr.N_e, tr.p_ie)
    sEI_src, sEI_tar = generate_connections(tr.N_e, tr.N_i, tr.p_ei)
    sII_src, sII_tar = generate_connections(tr.N_i, tr.N_i, tr.p_ii, same=True)

    SynIE.connect(i=sIE_src, j=sIE_tar)
    SynEI.connect(i=sEI_src, j=sEI_tar)
    SynII.connect(i=sII_src, j=sII_tar)

    tr.f_add_result('sIE_src', sIE_src)
    tr.f_add_result('sIE_tar', sIE_tar)
    tr.f_add_result('sEI_src', sEI_src)
    tr.f_add_result('sEI_tar', sEI_tar)
    tr.f_add_result('sII_src', sII_src)
    tr.f_add_result('sII_tar', sII_tar)

    if tr.syn_noise:
        SynEE.syn_sigma = tr.syn_sigma

    SynEE.insert_P = tr.insert_P
    SynEE.p_inactivate = tr.p_inactivate
    SynEE.stdp_active = 1

    ATM_vals = np.random.normal(loc=tr.ATotalMax,
                                scale=tr.ATotalMax_sd,
                                size=tr.N_e * (tr.N_e - 1))
    assert np.min(ATM_vals) > 0.
    SynEE.ATotalMax = ATM_vals

    # make randomly chosen synapses active at beginning
    rs = np.random.uniform(size=tr.N_e * (tr.N_e - 1))
    initial_active = (rs < tr.p_ee).astype('int')
    initial_a = initial_active * tr.a_ee
    SynEE.syn_active = initial_active
    SynEE.a = initial_a

    # recording of stdp in T4
    SynEE.stdp_rec_start = tr.T1 + tr.T2 + tr.T3
    SynEE.stdp_rec_max = tr.T1 + tr.T2 + tr.T3 + tr.stdp_rec_T

    # synaptic scaling
    if tr.netw.config.scl_active:

        if tr.syn_scl_rec:
            SynEE.scl_rec_start = tr.T1 + tr.T2 + tr.T3
            SynEE.scl_rec_max = tr.T1 + tr.T2 + tr.T3 + tr.scl_rec_T
        else:
            SynEE.scl_rec_start = T + 10 * second
            SynEE.scl_rec_max = T

        SynEE.summed_updaters['Asum_post']._clock = Clock(
            dt=tr.dt_synEE_scaling)
        synscaling = SynEE.run_regularly(tr.synEE_scaling,
                                         dt=tr.dt_synEE_scaling,
                                         when='end',
                                         name='syn_scaling')

    # # intrinsic plasticity
    # if tr.netw.config.it_active:
    #     GExc.h_ip = tr.h_ip
    #     GExc.run_regularly(tr.intrinsic_mod, dt = tr.it_dt, when='end')

    # structural plasticity
    if tr.netw.config.strct_active:
        if tr.strct_mode == 'zero':
            if tr.turnover_rec:
                strct_mod = '''%s 
                                %s''' % (tr.strct_mod, tr.turnover_rec_mod)
            else:
                strct_mod = tr.strct_mod

            strctplst = SynEE.run_regularly(strct_mod,
                                            dt=tr.strct_dt,
                                            when='end',
                                            name='strct_plst_zero')

        elif tr.strct_mode == 'thrs':
            if tr.turnover_rec:
                strct_mod_thrs = '''%s 
                                %s''' % (tr.strct_mod_thrs,
                                         tr.turnover_rec_mod)
            else:
                strct_mod_thrs = tr.strct_mod_thrs

            strctplst = SynEE.run_regularly(strct_mod_thrs,
                                            dt=tr.strct_dt,
                                            when='end',
                                            name='strct_plst_thrs')

    netw_objects.extend([SynEE, SynEI, SynIE, SynII])

    # keep track of the number of active synapses
    sum_target = NeuronGroup(1, 'c : 1 (shared)', dt=tr.csample_dt)

    sum_model = '''NSyn : 1 (constant)
                   c_post = (1.0*syn_active_pre)/NSyn : 1 (summed)'''
    sum_connection = Synapses(target=sum_target,
                              source=SynEE,
                              model=sum_model,
                              dt=tr.csample_dt,
                              name='get_active_synapse_count')
    sum_connection.connect()
    sum_connection.NSyn = tr.N_e * (tr.N_e - 1)

    if tr.adjust_insertP:
        # homeostatically adjust growth rate
        growth_updater = Synapses(sum_target, SynEE)
        growth_updater.run_regularly('insert_P_post *= 0.1/c_pre',
                                     when='after_groups',
                                     dt=tr.csample_dt,
                                     name='update_insP')
        growth_updater.connect(j='0')

        netw_objects.extend([sum_target, sum_connection, growth_updater])

    # -------------- recording ------------------

    GExc_recvars = []
    if tr.memtraces_rec:
        GExc_recvars.append('V')
    if tr.vttraces_rec:
        GExc_recvars.append('Vt')
    if tr.getraces_rec:
        GExc_recvars.append('ge')
    if tr.gitraces_rec:
        GExc_recvars.append('gi')
    if tr.gfwdtraces_rec and tr.external_mode == 'poisson':
        GExc_recvars.append('gfwd')

    GInh_recvars = GExc_recvars

    GExc_stat = StateMonitor(GExc,
                             GExc_recvars,
                             record=[0, 1, 2],
                             dt=tr.GExc_stat_dt)
    GInh_stat = StateMonitor(GInh,
                             GInh_recvars,
                             record=[0, 1, 2],
                             dt=tr.GInh_stat_dt)

    SynEE_recvars = []
    if tr.synee_atraces_rec:
        SynEE_recvars.append('a')
    if tr.synee_activetraces_rec:
        SynEE_recvars.append('syn_active')
    if tr.synee_Apretraces_rec:
        SynEE_recvars.append('Apre')
    if tr.synee_Aposttraces_rec:
        SynEE_recvars.append('Apost')

    SynEE_stat = StateMonitor(SynEE,
                              SynEE_recvars,
                              record=range(tr.n_synee_traces_rec),
                              when='end',
                              dt=tr.synEE_stat_dt)

    if tr.adjust_insertP:

        C_stat = StateMonitor(sum_target,
                              'c',
                              dt=tr.csample_dt,
                              record=[0],
                              when='end')
        insP_stat = StateMonitor(SynEE,
                                 'insert_P',
                                 dt=tr.csample_dt,
                                 record=[0],
                                 when='end')
        netw_objects.extend([C_stat, insP_stat])

    GExc_spks = SpikeMonitor(GExc)
    GInh_spks = SpikeMonitor(GInh)

    GExc_rate = PopulationRateMonitor(GExc)
    GInh_rate = PopulationRateMonitor(GInh)

    if tr.external_mode == 'poisson':
        PInp_spks = SpikeMonitor(PInp)
        PInp_rate = PopulationRateMonitor(PInp)
        netw_objects.extend([PInp_spks, PInp_rate])

    if tr.synee_a_nrecpoints == 0:
        SynEE_a_dt = 10 * tr.sim.T2
    else:
        SynEE_a_dt = tr.sim.T2 / tr.synee_a_nrecpoints
    SynEE_a = StateMonitor(SynEE, ['a', 'syn_active'],
                           record=range(tr.N_e * (tr.N_e - 1)),
                           dt=SynEE_a_dt,
                           when='end',
                           order=100)

    netw_objects.extend([
        GExc_stat, GInh_stat, SynEE_stat, SynEE_a, GExc_spks, GInh_spks,
        GExc_rate, GInh_rate
    ])

    net = Network(*netw_objects)

    def set_active(*argv):
        for net_object in argv:
            net_object.active = True

    def set_inactive(*argv):
        for net_object in argv:
            net_object.active = False

    ### Simulation periods

    # --------- T1 ---------
    # initial recording period,
    # all recorders active

    set_active(GExc_spks, GInh_spks, SynEE_stat, GExc_stat, GInh_stat,
               GExc_rate, GInh_rate)

    if tr.external_mode == 'poisson':
        set_active(PInp_spks, PInp_rate)

    net.run(tr.sim.T1, report='text', report_period=300 * second, profile=True)

    # --------- T2 ---------
    # main simulation period
    # only active recordings are:
    #   1) turnover 2) C_stat 3) SynEE_a

    set_inactive(GExc_spks, GInh_spks, SynEE_stat, GExc_stat, GInh_stat,
                 GExc_rate, GInh_rate)

    if tr.external_mode == 'poisson':
        set_inactive(PInp_spks, PInp_rate)

    net.run(tr.sim.T2, report='text', report_period=300 * second, profile=True)

    # --------- T3 ---------
    # second recording period,
    # all recorders active

    set_active(GExc_spks, GInh_spks, SynEE_stat, GExc_stat, GInh_stat,
               GExc_rate, GInh_rate)

    if tr.external_mode == 'poisson':
        set_active(PInp_spks, PInp_rate)

    net.run(tr.sim.T3, report='text', report_period=300 * second, profile=True)

    # --------- T4 ---------
    # record STDP and scaling weight changes to file
    # through the cpp models

    set_inactive(GExc_spks, GInh_spks, SynEE_stat, GExc_stat, GInh_stat,
                 GExc_rate, GInh_rate)

    if tr.external_mode == 'poisson':
        set_inactive(PInp_spks, PInp_rate)

    net.run(tr.sim.T4, report='text', report_period=300 * second, profile=True)

    # --------- T5 ---------
    # freeze network and record Exc spikes
    # for cross correlations

    synscaling.active = False
    strctplst.active = False
    SynEE.stdp_active = 0

    set_active(GExc_spks)

    net.run(tr.sim.T5, report='text', report_period=300 * second, profile=True)

    SynEE_a.record_single_timestep()

    device.build(directory='builds/%.4d' % (tr.v_idx),
                 clean=True,
                 compile=True,
                 run=True,
                 debug=False)

    # -----------------------------------------

    # save monitors as raws in build directory
    raw_dir = 'builds/%.4d/raw/' % (tr.v_idx)

    if not os.path.exists(raw_dir):
        os.makedirs(raw_dir)

    with open(raw_dir + 'namespace.p', 'wb') as pfile:
        pickle.dump(namespace, pfile)

    with open(raw_dir + 'gexc_stat.p', 'wb') as pfile:
        pickle.dump(GExc_stat.get_states(), pfile)
    with open(raw_dir + 'ginh_stat.p', 'wb') as pfile:
        pickle.dump(GInh_stat.get_states(), pfile)

    with open(raw_dir + 'synee_stat.p', 'wb') as pfile:
        pickle.dump(SynEE_stat.get_states(), pfile)
    with open(raw_dir + 'synee_a.p', 'wb') as pfile:
        SynEE_a_states = SynEE_a.get_states()
        if tr.crs_crrs_rec:
            SynEE_a_states['i'] = list(SynEE.i)
            SynEE_a_states['j'] = list(SynEE.j)
        pickle.dump(SynEE_a_states, pfile)

    if tr.adjust_insertP:
        with open(raw_dir + 'c_stat.p', 'wb') as pfile:
            pickle.dump(C_stat.get_states(), pfile)

        with open(raw_dir + 'insP_stat.p', 'wb') as pfile:
            pickle.dump(insP_stat.get_states(), pfile)

    with open(raw_dir + 'gexc_spks.p', 'wb') as pfile:
        pickle.dump(GExc_spks.get_states(), pfile)
    with open(raw_dir + 'ginh_spks.p', 'wb') as pfile:
        pickle.dump(GInh_spks.get_states(), pfile)

    if tr.external_mode == 'poisson':
        with open(raw_dir + 'pinp_spks.p', 'wb') as pfile:
            pickle.dump(PInp_spks.get_states(), pfile)

    with open(raw_dir + 'gexc_rate.p', 'wb') as pfile:
        pickle.dump(GExc_rate.get_states(), pfile)
        if tr.rates_rec:
            pickle.dump(GExc_rate.smooth_rate(width=25 * ms), pfile)
    with open(raw_dir + 'ginh_rate.p', 'wb') as pfile:
        pickle.dump(GInh_rate.get_states(), pfile)
        if tr.rates_rec:
            pickle.dump(GInh_rate.smooth_rate(width=25 * ms), pfile)

    if tr.external_mode == 'poisson':
        with open(raw_dir + 'pinp_rate.p', 'wb') as pfile:
            pickle.dump(PInp_rate.get_states(), pfile)
            if tr.rates_rec:
                pickle.dump(PInp_rate.smooth_rate(width=25 * ms), pfile)

    # ----------------- add raw data ------------------------
    fpath = 'builds/%.4d/' % (tr.v_idx)

    from pathlib import Path

    Path(fpath + 'turnover').touch()
    turnover_data = np.genfromtxt(fpath + 'turnover', delimiter=',')
    os.remove(fpath + 'turnover')

    with open(raw_dir + 'turnover.p', 'wb') as pfile:
        pickle.dump(turnover_data, pfile)

    Path(fpath + 'spk_register').touch()
    spk_register_data = np.genfromtxt(fpath + 'spk_register', delimiter=',')
    os.remove(fpath + 'spk_register')

    with open(raw_dir + 'spk_register.p', 'wb') as pfile:
        pickle.dump(spk_register_data, pfile)

    Path(fpath + 'scaling_deltas').touch()
    scaling_deltas_data = np.genfromtxt(fpath + 'scaling_deltas',
                                        delimiter=',')
    os.remove(fpath + 'scaling_deltas')

    with open(raw_dir + 'scaling_deltas.p', 'wb') as pfile:
        pickle.dump(scaling_deltas_data, pfile)

    with open(raw_dir + 'profiling_summary.txt', 'w+') as tfile:
        tfile.write(str(profiling_summary(net)))

    # --------------- cross-correlations ---------------------

    if tr.crs_crrs_rec:

        GExc_spks = GExc_spks.get_states()
        synee_a = SynEE_a_states
        wsize = 100 * pq.ms

        for binsize in [1 * pq.ms, 2 * pq.ms, 5 * pq.ms]:

            wlen = int(wsize / binsize)

            ts, idxs = GExc_spks['t'], GExc_spks['i']
            idxs = idxs[ts > tr.T1 + tr.T2 + tr.T3 + tr.T4]
            ts = ts[ts > tr.T1 + tr.T2 + tr.T3 + tr.T4]
            ts = ts - (tr.T1 + tr.T2 + tr.T3 + tr.T4)

            sts = [
                neo.SpikeTrain(ts[idxs == i] / second * pq.s,
                               t_stop=tr.T5 / second * pq.s)
                for i in range(tr.N_e)
            ]

            crs_crrs, syn_a = [], []

            for f, (i, j) in enumerate(zip(synee_a['i'], synee_a['j'])):
                if synee_a['syn_active'][-1][f] == 1:

                    crs_crr, cbin = cch(BinnedSpikeTrain(sts[i],
                                                         binsize=binsize),
                                        BinnedSpikeTrain(sts[j],
                                                         binsize=binsize),
                                        cross_corr_coef=True,
                                        border_correction=True,
                                        window=(-1 * wlen, wlen))

                    crs_crrs.append(list(np.array(crs_crr).T[0]))
                    syn_a.append(synee_a['a'][-1][f])

            fname = 'crs_crrs_wsize%dms_binsize%fms_full' % (wsize / pq.ms,
                                                             binsize / pq.ms)

            df = {
                'cbin': cbin,
                'crs_crrs': np.array(crs_crrs),
                'syn_a': np.array(syn_a),
                'binsize': binsize,
                'wsize': wsize,
                'wlen': wlen
            }

            with open('builds/%.4d/raw/' % (tr.v_idx) + fname + '.p',
                      'wb') as pfile:
                pickle.dump(df, pfile)

    # -----------------  clean up  ---------------------------
    shutil.rmtree('builds/%.4d/results/' % (tr.v_idx))

    # ---------------- plot results --------------------------

    #os.chdir('./analysis/file_based/')

    from analysis.overview_fb import overview_figure
    overview_figure('builds/%.4d' % (tr.v_idx), namespace)

    from analysis.synw_fb import synw_figure
    synw_figure('builds/%.4d' % (tr.v_idx), namespace)

    from analysis.synw_log_fb import synw_log_figure
    synw_log_figure('builds/%.4d' % (tr.v_idx), namespace)
Example #21
0
def run_net(tr):

    # prefs.codegen.target = 'numpy'
    # prefs.codegen.target = 'cython'
    set_device('cpp_standalone',
               directory='./builds/%.4d' % (tr.v_idx),
               build_on_run=False)

    print("Started process with id ", str(tr.v_idx))

    T = tr.T1 + tr.T2 + tr.T3

    namespace = tr.netw.f_to_dict(short_names=True, fast_access=True)
    namespace['idx'] = tr.v_idx

    defaultclock.dt = tr.netw.sim.dt

    GExc = NeuronGroup(
        N=tr.N_e,
        model=tr.condlif_sig,
        threshold=tr.nrnEE_thrshld,
        reset=tr.nrnEE_reset,  #method=tr.neuron_method,
        namespace=namespace)
    GInh = NeuronGroup(
        N=tr.N_i,
        model=tr.condlif_sig,
        threshold='V > Vt',
        reset='V=Vr_i',  #method=tr.neuron_method,
        namespace=namespace)

    # set initial thresholds fixed, init. potentials uniformly distrib.
    GExc.sigma, GInh.sigma = tr.sigma_e, tr.sigma_i
    GExc.Vt, GInh.Vt = tr.Vt_e, tr.Vt_i
    GExc.V , GInh.V  = np.random.uniform(tr.Vr_e/mV, tr.Vt_e/mV,
                                         size=tr.N_e)*mV, \
                       np.random.uniform(tr.Vr_i/mV, tr.Vt_i/mV,
                                         size=tr.N_i)*mV

    print("need to fix?")
    synEE_pre_mod = mod.synEE_pre
    synEE_post_mod = mod.synEE_post

    if tr.PInp_mode == 'pool':
        PInp = PoissonGroup(tr.NPInp, rates=tr.PInp_rate, namespace=namespace)
        sPN = Synapses(target=GExc,
                       source=PInp,
                       model=tr.poisson_mod,
                       on_pre='ge_post += a_EPoi',
                       namespace=namespace)

        sPN_src, sPN_tar = generate_connections(N_tar=tr.N_e,
                                                N_src=tr.NPInp,
                                                p=tr.p_EPoi)

    elif tr.PInp_mode == 'indep':
        PInp = PoissonGroup(tr.N_e, rates=tr.PInp_rate, namespace=namespace)
        sPN = Synapses(target=GExc,
                       source=PInp,
                       model=tr.poisson_mod,
                       on_pre='ge_post += a_EPoi',
                       namespace=namespace)
        sPN_src, sPN_tar = range(tr.N_e), range(tr.N_e)

    sPN.connect(i=sPN_src, j=sPN_tar)

    if tr.PInp_mode == 'pool':
        sPNInh = Synapses(target=GInh,
                          source=PInp,
                          model=tr.poisson_mod,
                          on_pre='ge_post += a_EPoi',
                          namespace=namespace)
        sPNInh_src, sPNInh_tar = generate_connections(N_tar=tr.N_i,
                                                      N_src=tr.NPInp,
                                                      p=tr.p_EPoi)

    elif tr.PInp_mode == 'indep':

        PInp_inh = PoissonGroup(tr.N_i,
                                rates=tr.PInp_rate,
                                namespace=namespace)
        sPNInh = Synapses(target=GInh,
                          source=PInp_inh,
                          model=tr.poisson_mod,
                          on_pre='ge_post += a_EPoi',
                          namespace=namespace)
        sPNInh_src, sPNInh_tar = range(tr.N_i), range(tr.N_i)

    sPNInh.connect(i=sPNInh_src, j=sPNInh_tar)

    if tr.stdp_active:
        synEE_pre_mod = '''%s 
                            %s''' % (synEE_pre_mod, mod.synEE_pre_STDP)
        synEE_post_mod = '''%s 
                            %s''' % (synEE_post_mod, mod.synEE_post_STDP)

    if tr.synEE_rec:
        synEE_pre_mod = '''%s 
                            %s''' % (synEE_pre_mod, mod.synEE_pre_rec)
        synEE_post_mod = '''%s 
                            %s''' % (synEE_post_mod, mod.synEE_post_rec)

    # E<-E advanced synapse model, rest simple
    SynEE = Synapses(
        target=GExc,
        source=GExc,
        model=tr.synEE_mod,
        on_pre=synEE_pre_mod,
        on_post=synEE_post_mod,
        #method=tr.synEE_method,
        namespace=namespace)
    SynIE = Synapses(target=GInh,
                     source=GExc,
                     on_pre='ge_post += a_ie',
                     namespace=namespace)
    SynEI = Synapses(target=GExc,
                     source=GInh,
                     on_pre='gi_post += a_ei',
                     namespace=namespace)
    SynII = Synapses(target=GInh,
                     source=GInh,
                     on_pre='gi_post += a_ii',
                     namespace=namespace)

    if tr.strct_active:
        sEE_src, sEE_tar = generate_full_connectivity(tr.N_e, same=True)
        SynEE.connect(i=sEE_src, j=sEE_tar)
        SynEE.syn_active = 0

    else:
        srcs_full, tars_full = generate_full_connectivity(tr.N_e, same=True)
        SynEE.connect(i=srcs_full, j=tars_full)
        SynEE.syn_active = 0

    sIE_src, sIE_tar = generate_connections(tr.N_i, tr.N_e, tr.p_ie)
    sEI_src, sEI_tar = generate_connections(tr.N_e, tr.N_i, tr.p_ei)
    sII_src, sII_tar = generate_connections(tr.N_i, tr.N_i, tr.p_ii, same=True)

    SynIE.connect(i=sIE_src, j=sIE_tar)
    SynEI.connect(i=sEI_src, j=sEI_tar)
    SynII.connect(i=sII_src, j=sII_tar)

    tr.f_add_result('sIE_src', sIE_src)
    tr.f_add_result('sIE_tar', sIE_tar)
    tr.f_add_result('sEI_src', sEI_src)
    tr.f_add_result('sEI_tar', sEI_tar)
    tr.f_add_result('sII_src', sII_src)
    tr.f_add_result('sII_tar', sII_tar)

    SynEE.a = tr.a_ee

    SynEE.insert_P = tr.insert_P
    SynEE.p_inactivate = tr.p_inactivate

    # make synapse active at beginning
    SynEE.run_regularly(tr.synEE_p_activate, dt=T, when='start', order=-100)

    # synaptic scaling
    if tr.netw.config.scl_active:
        SynEE.summed_updaters['Asum_post']._clock = Clock(
            dt=tr.dt_synEE_scaling)
        SynEE.run_regularly(tr.synEE_scaling,
                            dt=tr.dt_synEE_scaling,
                            when='end')

    # intrinsic plasticity
    if tr.netw.config.it_active:
        GExc.h_ip = tr.h_ip
        GExc.run_regularly(tr.intrinsic_mod, dt=tr.it_dt, when='end')

    # structural plasticity
    if tr.netw.config.strct_active:
        if tr.strct_mode == 'zero':
            if tr.turnover_rec:
                strct_mod = '''%s 
                                %s''' % (tr.strct_mod, tr.turnover_rec_mod)
            else:
                strct_mod = tr.strct_mod

            SynEE.run_regularly(strct_mod, dt=tr.strct_dt, when='end')

        elif tr.strct_mode == 'thrs':
            if tr.turnover_rec:
                strct_mod_thrs = '''%s 
                                %s''' % (tr.strct_mod_thrs,
                                         tr.turnover_rec_mod)
            else:
                strct_mod_thrs = tr.strct_mod_thrs

            SynEE.run_regularly(strct_mod_thrs, dt=tr.strct_dt, when='end')

    # -------------- recording ------------------

    #run(tr.sim.preT)

    GExc_recvars = []
    if tr.memtraces_rec:
        GExc_recvars.append('V')
    if tr.vttraces_rec:
        GExc_recvars.append('Vt')
    if tr.getraces_rec:
        GExc_recvars.append('ge')
    if tr.gitraces_rec:
        GExc_recvars.append('gi')

    GInh_recvars = GExc_recvars

    GExc_stat = StateMonitor(GExc,
                             GExc_recvars,
                             record=[0, 1, 2],
                             dt=tr.GExc_stat_dt)
    GInh_stat = StateMonitor(GInh,
                             GInh_recvars,
                             record=[0, 1, 2],
                             dt=tr.GInh_stat_dt)

    SynEE_recvars = []
    if tr.synee_atraces_rec:
        SynEE_recvars.append('a')
    if tr.synee_Apretraces_rec:
        SynEE_recvars.append('Apre')
    if tr.synee_Aposttraces_rec:
        SynEE_recvars.append('Apost')

    SynEE_stat = StateMonitor(SynEE,
                              SynEE_recvars,
                              record=range(tr.n_synee_traces_rec),
                              when='end',
                              dt=tr.synEE_stat_dt)

    GExc_spks = SpikeMonitor(GExc)
    GInh_spks = SpikeMonitor(GInh)
    PInp_spks = SpikeMonitor(PInp)

    GExc_rate = PopulationRateMonitor(GExc)
    GInh_rate = PopulationRateMonitor(GInh)
    PInp_rate = PopulationRateMonitor(PInp)

    SynEE_a = StateMonitor(SynEE, ['a', 'syn_active'],
                           record=range(tr.N_e * (tr.N_e - 1)),
                           dt=T / tr.synee_a_nrecpoints,
                           when='end',
                           order=100)

    if tr.PInp_mode == 'indep':
        net = Network(GExc, GInh, PInp, sPN, sPNInh, SynEE, SynEI, SynIE,
                      SynII, GExc_stat, GInh_stat, SynEE_stat, SynEE_a,
                      GExc_spks, GInh_spks, PInp_spks, GExc_rate, GInh_rate,
                      PInp_rate, PInp_inh)
    else:
        net = Network(GExc, GInh, PInp, sPN, sPNInh, SynEE, SynEI, SynIE,
                      SynII, GExc_stat, GInh_stat, SynEE_stat, SynEE_a,
                      GExc_spks, GInh_spks, PInp_spks, GExc_rate, GInh_rate,
                      PInp_rate)

    net.run(tr.sim.T1, report='text')
    # SynEE_a.record_single_timestep()

    recorders = [
        GExc_spks, GInh_spks, PInp_spks, SynEE_stat, GExc_stat, GInh_stat
    ]
    rate_recorders = [GExc_rate, GInh_rate, PInp_rate]

    for rcc in recorders:
        rcc.active = False

    net.run(tr.sim.T2, report='text')

    recorders = [
        SynEE_stat, GExc_stat, GInh_stat, GExc_rate, GInh_rate, PInp_rate
    ]
    for rcc in recorders:
        rcc.active = True

    if tr.spks_rec:
        GExc_spks.active = True
        GInh_spks.active = True
        # PInp_spks.active=True

    net.run(tr.sim.T3, report='text')

    device.build(directory='../builds/%.4d' % (tr.v_idx), clean=True)

    # save monitors as raws in build directory
    raw_dir = '../builds/%.4d/raw/' % (tr.v_idx)

    if not os.path.exists(raw_dir):
        os.makedirs(raw_dir)

    with open(raw_dir + 'namespace.p', 'wb') as pfile:
        pickle.dump(namespace, pfile)

    with open(raw_dir + 'gexc_stat.p', 'wb') as pfile:
        pickle.dump(GExc_stat.get_states(), pfile)
    with open(raw_dir + 'ginh_stat.p', 'wb') as pfile:
        pickle.dump(GInh_stat.get_states(), pfile)

    with open(raw_dir + 'synee_stat.p', 'wb') as pfile:
        pickle.dump(SynEE_stat.get_states(), pfile)
    with open(raw_dir + 'synee_a.p', 'wb') as pfile:
        pickle.dump(SynEE_a.get_states(), pfile)

    with open(raw_dir + 'gexc_spks.p', 'wb') as pfile:
        pickle.dump(GExc_spks.get_states(), pfile)
    with open(raw_dir + 'ginh_spks.p', 'wb') as pfile:
        pickle.dump(GInh_spks.get_states(), pfile)
    with open(raw_dir + 'pinp_spks.p', 'wb') as pfile:
        pickle.dump(PInp_spks.get_states(), pfile)

    with open(raw_dir + 'gexc_rate.p', 'wb') as pfile:
        pickle.dump(GExc_rate.get_states(), pfile)
        pickle.dump(GExc_rate.smooth_rate(width=25 * ms), pfile)
    with open(raw_dir + 'ginh_rate.p', 'wb') as pfile:
        pickle.dump(GInh_rate.get_states(), pfile)
        pickle.dump(GInh_rate.smooth_rate(width=25 * ms), pfile)
    with open(raw_dir + 'pinp_rate.p', 'wb') as pfile:
        pickle.dump(PInp_rate.get_states(), pfile)
        pickle.dump(PInp_rate.smooth_rate(width=25 * ms), pfile)

    # ----------------- add raw data ------------------------
    fpath = '../builds/%.4d/' % (tr.v_idx)

    from pathlib import Path

    Path(fpath + 'turnover').touch()
    turnover_data = np.genfromtxt(fpath + 'turnover', delimiter=',')
    os.remove(fpath + 'turnover')

    with open(raw_dir + 'turnover.p', 'wb') as pfile:
        pickle.dump(turnover_data, pfile)

    Path(fpath + 'spk_register').touch()
    spk_register_data = np.genfromtxt(fpath + 'spk_register', delimiter=',')
    os.remove(fpath + 'spk_register')

    with open(raw_dir + 'spk_register.p', 'wb') as pfile:
        pickle.dump(spk_register_data, pfile)
plasticity rule.

Sebastian Schmitt, 2021
"""

import itertools
import numpy as np
import matplotlib.pyplot as plt

from brian2 import TimedArray, PoissonGroup, NeuronGroup, Synapses, StateMonitor, PopulationRateMonitor
from brian2 import defaultclock, run
from brian2 import Hz, ms, second

# The synaptic weight from the steady stimulus is plastic
steady_stimulus = TimedArray([50] * Hz, dt=40 * second)
steady_poisson = PoissonGroup(1, rates='steady_stimulus(t)')

# The synaptic weight from the varying stimulus is static
varying_stimulus = TimedArray([25 * Hz, 50 * Hz, 0 * Hz, 35 * Hz, 0 * Hz],
                              dt=10 * second)
varying_poisson = PoissonGroup(1, rates='varying_stimulus(t)')

# dw_plus/dw_minus determines scales the steady stimulus rate to the target firing rate, must not be larger 1
# the magntude of dw_plus and dw_minus determines the "speed" of the homeostasis
parameters = {
    'tau': 10 * ms,  # membrane time constant
    'dw_plus': 0.05,  # weight increment on pre spike
    'dw_minus': 0.05,  # weight increment on post spike
    'w_max': 2,  # maximum plastic weight
    'w_initial': 0  # initial plastic weight
}
Example #23
0
 def strong_mem_noise_on_group(G: NeuronGroup):
     GNoise = PoissonGroup(G.N, rates=tr.strong_mem_noise_rate)
     SynNoise = Synapses(source=GNoise, target=G, on_pre="V_post += 20*mV")
     SynNoise.connect(condition="i==j")
     return [GNoise, SynNoise]
Example #24
0
 def brian2(self) -> BrianObject:
     return PoissonGroup(self.n, self.rate, name=self.name)
Example #25
0
def sim_decision_making_network(
        N_Excit=384,
        N_Inhib=96,
        weight_scaling_factor=5.33,
        t_stimulus_start=100 * b2.ms,
        t_stimulus_duration=9999 * b2.ms,
        coherence_level=0.,
        stimulus_update_interval=30 * b2.ms,
        mu0_mean_stimulus_Hz=160.,
        stimulus_std_Hz=20.,
        N_extern=1000,
        firing_rate_extern=9.8 * b2.Hz,
        w_pos=1.90,
        f_Subpop_size=0.25,  # .15 in publication [1]
        max_sim_time=1000. * b2.ms,
        stop_condition_rate=None,
        monitored_subset_size=512):
    """

    Args:
        N_Excit (int): total number of neurons in the excitatory population
        N_Inhib (int): nr of neurons in the inhibitory populations
        weight_scaling_factor: When increasing the number of neurons by 2, the weights should be scaled down by 1/2
        t_stimulus_start (Quantity): time when the stimulation starts
        t_stimulus_duration (Quantity): duration of the stimulation
        coherence_level (int): coherence of the stimulus.
            Difference in mean between the PoissonGroups "left" stimulus and "right" stimulus
        stimulus_update_interval (Quantity): the mean of the stimulating PoissonGroups is
            re-sampled at this interval
        mu0_mean_stimulus_Hz (float): maximum mean firing rate of the stimulus if c=+1 or c=-1. Each neuron
            in the populations "Left" and "Right" receives an independent poisson input.
        stimulus_std_Hz (float): std deviation of the stimulating PoissonGroups.
        N_extern (int): nr of neurons in the stimulus independent poisson background population
        firing_rate_extern (int): firing rate of the stimulus independent poisson background population
        w_pos (float): Scaling (strengthening) of the recurrent weights within the
            subpopulations "Left" and "Right"
        f_Subpop_size (float): fraction of the neurons in the subpopulations "Left" and "Right".
            #left = #right = int(f_Subpop_size*N_Excit).
        max_sim_time (Quantity): simulated time.
        stop_condition_rate (Quantity): An optional stopping criteria: If not None, the simulation stops if the
            firing rate of either subpopulation "Left" or "Right" is above stop_condition_rate.
        monitored_subset_size (int): max nr of neurons for which a state monitor is registered.

    Returns:

        A dictionary with the following keys (strings):
        "rate_monitor_A", "spike_monitor_A", "voltage_monitor_A", "idx_monitored_neurons_A", "rate_monitor_B",
         "spike_monitor_B", "voltage_monitor_B", "idx_monitored_neurons_B", "rate_monitor_Z", "spike_monitor_Z",
         "voltage_monitor_Z", "idx_monitored_neurons_Z", "rate_monitor_inhib", "spike_monitor_inhib",
         "voltage_monitor_inhib", "idx_monitored_neurons_inhib"

    """

    print("simulating {} neurons. Start: {}".format(N_Excit + N_Inhib,
                                                    time.ctime()))
    t_stimulus_end = t_stimulus_start + t_stimulus_duration

    N_Group_A = int(
        N_Excit * f_Subpop_size
    )  # size of the excitatory subpopulation sensitive to stimulus A
    N_Group_B = N_Group_A  # size of the excitatory subpopulation sensitive to stimulus B
    N_Group_Z = N_Excit - N_Group_A - N_Group_B  # (1-2f)Ne excitatory neurons do not respond to either stimulus.

    Cm_excit = 0.5 * b2.nF  # membrane capacitance of excitatory neurons
    G_leak_excit = 25.0 * b2.nS  # leak conductance
    E_leak_excit = -70.0 * b2.mV  # reversal potential
    v_spike_thr_excit = -50.0 * b2.mV  # spike condition
    v_reset_excit = -60.0 * b2.mV  # reset voltage after spike
    t_abs_refract_excit = 2. * b2.ms  # absolute refractory period

    # specify the inhibitory interneurons:
    # N_Inhib = 200
    Cm_inhib = 0.2 * b2.nF
    G_leak_inhib = 20.0 * b2.nS
    E_leak_inhib = -70.0 * b2.mV
    v_spike_thr_inhib = -50.0 * b2.mV
    v_reset_inhib = -60.0 * b2.mV
    t_abs_refract_inhib = 1.0 * b2.ms

    # specify the AMPA synapses
    E_AMPA = 0.0 * b2.mV
    tau_AMPA = 2.5 * b2.ms

    # specify the GABA synapses
    E_GABA = -70.0 * b2.mV
    tau_GABA = 5.0 * b2.ms

    # specify the NMDA synapses
    E_NMDA = 0.0 * b2.mV
    tau_NMDA_s = 100.0 * b2.ms
    tau_NMDA_x = 2. * b2.ms
    alpha_NMDA = 0.5 * b2.kHz

    # projections from the external population
    g_AMPA_extern2inhib = 1.62 * b2.nS
    g_AMPA_extern2excit = 2.1 * b2.nS

    # projectsions from the inhibitory populations
    g_GABA_inhib2inhib = weight_scaling_factor * 1.25 * b2.nS
    g_GABA_inhib2excit = weight_scaling_factor * 1.60 * b2.nS

    # projections from the excitatory population
    g_AMPA_excit2excit = weight_scaling_factor * 0.012 * b2.nS
    g_AMPA_excit2inhib = weight_scaling_factor * 0.015 * b2.nS
    g_NMDA_excit2excit = weight_scaling_factor * 0.040 * b2.nS
    g_NMDA_excit2inhib = weight_scaling_factor * 0.045 * b2.nS  # stronger projection to inhib.

    # weights and "adjusted" weights.
    w_neg = 1. - f_Subpop_size * (w_pos - 1.) / (1. - f_Subpop_size)
    # We use the same postsyn AMPA and NMDA conductances. Adjust the weights coming from different sources:
    w_ext2inhib = g_AMPA_extern2inhib / g_AMPA_excit2inhib
    w_ext2excit = g_AMPA_extern2excit / g_AMPA_excit2excit
    # other weights are 1
    # print("w_neg={}, w_ext2inhib={}, w_ext2excit={}".format(w_neg, w_ext2inhib, w_ext2excit))

    # Define the inhibitory population
    # dynamics:
    inhib_lif_dynamics = """
        s_NMDA_total : 1  # the post synaptic sum of s. compare with s_NMDA_presyn
        dv/dt = (
        - G_leak_inhib * (v-E_leak_inhib)
        - g_AMPA_excit2inhib * s_AMPA * (v-E_AMPA)
        - g_GABA_inhib2inhib * s_GABA * (v-E_GABA)
        - g_NMDA_excit2inhib * s_NMDA_total * (v-E_NMDA)/(1.0+1.0*exp(-0.062*v/volt)/3.57)
        )/Cm_inhib : volt (unless refractory)
        ds_AMPA/dt = -s_AMPA/tau_AMPA : 1
        ds_GABA/dt = -s_GABA/tau_GABA : 1
    """

    inhib_pop = NeuronGroup(N_Inhib,
                            model=inhib_lif_dynamics,
                            threshold="v>v_spike_thr_inhib",
                            reset="v=v_reset_inhib",
                            refractory=t_abs_refract_inhib,
                            method="rk2")
    # initialize with random voltages:
    inhib_pop.v = rnd.uniform(v_spike_thr_inhib / b2.mV - 4.,
                              high=v_spike_thr_inhib / b2.mV - 1.,
                              size=N_Inhib) * b2.mV

    # Specify the excitatory population:
    # dynamics:
    excit_lif_dynamics = """
        s_NMDA_total : 1  # the post synaptic sum of s. compare with s_NMDA_presyn
        dv/dt = (
        - G_leak_excit * (v-E_leak_excit)
        - g_AMPA_excit2excit * s_AMPA * (v-E_AMPA)
        - g_GABA_inhib2excit * s_GABA * (v-E_GABA)
        - g_NMDA_excit2excit * s_NMDA_total * (v-E_NMDA)/(1.0+1.0*exp(-0.062*v/volt)/3.57)
        )/Cm_excit : volt (unless refractory)
        ds_AMPA/dt = -s_AMPA/tau_AMPA : 1
        ds_GABA/dt = -s_GABA/tau_GABA : 1
        ds_NMDA/dt = -s_NMDA/tau_NMDA_s + alpha_NMDA * x * (1-s_NMDA) : 1
        dx/dt = -x/tau_NMDA_x : 1
    """

    # define the three excitatory subpopulations.
    # A: subpop receiving stimulus A
    excit_pop_A = NeuronGroup(N_Group_A,
                              model=excit_lif_dynamics,
                              threshold="v>v_spike_thr_excit",
                              reset="v=v_reset_excit",
                              refractory=t_abs_refract_excit,
                              method="rk2")
    excit_pop_A.v = rnd.uniform(E_leak_excit / b2.mV,
                                high=E_leak_excit / b2.mV + 5.,
                                size=excit_pop_A.N) * b2.mV

    # B: subpop receiving stimulus B
    excit_pop_B = NeuronGroup(N_Group_B,
                              model=excit_lif_dynamics,
                              threshold="v>v_spike_thr_excit",
                              reset="v=v_reset_excit",
                              refractory=t_abs_refract_excit,
                              method="rk2")
    excit_pop_B.v = rnd.uniform(E_leak_excit / b2.mV,
                                high=E_leak_excit / b2.mV + 5.,
                                size=excit_pop_B.N) * b2.mV
    # Z: non-sensitive
    excit_pop_Z = NeuronGroup(N_Group_Z,
                              model=excit_lif_dynamics,
                              threshold="v>v_spike_thr_excit",
                              reset="v=v_reset_excit",
                              refractory=t_abs_refract_excit,
                              method="rk2")
    excit_pop_Z.v = rnd.uniform(v_reset_excit / b2.mV,
                                high=v_spike_thr_excit / b2.mV - 1.,
                                size=excit_pop_Z.N) * b2.mV

    # now define the connections:
    # projections FROM EXTERNAL POISSON GROUP: ####################################################
    poisson2Inhib = PoissonInput(target=inhib_pop,
                                 target_var="s_AMPA",
                                 N=N_extern,
                                 rate=firing_rate_extern,
                                 weight=w_ext2inhib)
    poisson2A = PoissonInput(target=excit_pop_A,
                             target_var="s_AMPA",
                             N=N_extern,
                             rate=firing_rate_extern,
                             weight=w_ext2excit)

    poisson2B = PoissonInput(target=excit_pop_B,
                             target_var="s_AMPA",
                             N=N_extern,
                             rate=firing_rate_extern,
                             weight=w_ext2excit)
    poisson2Z = PoissonInput(target=excit_pop_Z,
                             target_var="s_AMPA",
                             N=N_extern,
                             rate=firing_rate_extern,
                             weight=w_ext2excit)

    ###############################################################################################

    # GABA projections FROM INHIBITORY population: ################################################
    syn_inhib2inhib = Synapses(inhib_pop,
                               target=inhib_pop,
                               on_pre="s_GABA += 1.0",
                               delay=0.5 * b2.ms)
    syn_inhib2inhib.connect(p=1.)
    syn_inhib2A = Synapses(inhib_pop,
                           target=excit_pop_A,
                           on_pre="s_GABA += 1.0",
                           delay=0.5 * b2.ms)
    syn_inhib2A.connect(p=1.)
    syn_inhib2B = Synapses(inhib_pop,
                           target=excit_pop_B,
                           on_pre="s_GABA += 1.0",
                           delay=0.5 * b2.ms)
    syn_inhib2B.connect(p=1.)
    syn_inhib2Z = Synapses(inhib_pop,
                           target=excit_pop_Z,
                           on_pre="s_GABA += 1.0",
                           delay=0.5 * b2.ms)
    syn_inhib2Z.connect(p=1.)
    ###############################################################################################

    # AMPA projections FROM EXCITATORY A: #########################################################
    syn_AMPA_A2A = Synapses(excit_pop_A,
                            target=excit_pop_A,
                            on_pre="s_AMPA += w_pos",
                            delay=0.5 * b2.ms)
    syn_AMPA_A2A.connect(p=1.)
    syn_AMPA_A2B = Synapses(excit_pop_A,
                            target=excit_pop_B,
                            on_pre="s_AMPA += w_neg",
                            delay=0.5 * b2.ms)
    syn_AMPA_A2B.connect(p=1.)
    syn_AMPA_A2Z = Synapses(excit_pop_A,
                            target=excit_pop_Z,
                            on_pre="s_AMPA += 1.0",
                            delay=0.5 * b2.ms)
    syn_AMPA_A2Z.connect(p=1.)
    syn_AMPA_A2inhib = Synapses(excit_pop_A,
                                target=inhib_pop,
                                on_pre="s_AMPA += 1.0",
                                delay=0.5 * b2.ms)
    syn_AMPA_A2inhib.connect(p=1.)
    ###############################################################################################

    # AMPA projections FROM EXCITATORY B: #########################################################
    syn_AMPA_B2A = Synapses(excit_pop_B,
                            target=excit_pop_A,
                            on_pre="s_AMPA += w_neg",
                            delay=0.5 * b2.ms)
    syn_AMPA_B2A.connect(p=1.)
    syn_AMPA_B2B = Synapses(excit_pop_B,
                            target=excit_pop_B,
                            on_pre="s_AMPA += w_pos",
                            delay=0.5 * b2.ms)
    syn_AMPA_B2B.connect(p=1.)
    syn_AMPA_B2Z = Synapses(excit_pop_B,
                            target=excit_pop_Z,
                            on_pre="s_AMPA += 1.0",
                            delay=0.5 * b2.ms)
    syn_AMPA_B2Z.connect(p=1.)
    syn_AMPA_B2inhib = Synapses(excit_pop_B,
                                target=inhib_pop,
                                on_pre="s_AMPA += 1.0",
                                delay=0.5 * b2.ms)
    syn_AMPA_B2inhib.connect(p=1.)
    ###############################################################################################

    # AMPA projections FROM EXCITATORY Z: #########################################################
    syn_AMPA_Z2A = Synapses(excit_pop_Z,
                            target=excit_pop_A,
                            on_pre="s_AMPA += 1.0",
                            delay=0.5 * b2.ms)
    syn_AMPA_Z2A.connect(p=1.)
    syn_AMPA_Z2B = Synapses(excit_pop_Z,
                            target=excit_pop_B,
                            on_pre="s_AMPA += 1.0",
                            delay=0.5 * b2.ms)
    syn_AMPA_Z2B.connect(p=1.)
    syn_AMPA_Z2Z = Synapses(excit_pop_Z,
                            target=excit_pop_Z,
                            on_pre="s_AMPA += 1.0",
                            delay=0.5 * b2.ms)
    syn_AMPA_Z2Z.connect(p=1.)
    syn_AMPA_Z2inhib = Synapses(excit_pop_Z,
                                target=inhib_pop,
                                on_pre="s_AMPA += 1.0",
                                delay=0.5 * b2.ms)
    syn_AMPA_Z2inhib.connect(p=1.)
    ###############################################################################################

    # NMDA projections FROM EXCITATORY to INHIB, A,B,Z
    @network_operation()
    def update_nmda_sum():
        sum_sNMDA_A = sum(excit_pop_A.s_NMDA)
        sum_sNMDA_B = sum(excit_pop_B.s_NMDA)
        sum_sNMDA_Z = sum(excit_pop_Z.s_NMDA)
        # note the _ at the end of s_NMDA_total_ disables unit checking
        inhib_pop.s_NMDA_total_ = (1.0 * sum_sNMDA_A + 1.0 * sum_sNMDA_B +
                                   1.0 * sum_sNMDA_Z)
        excit_pop_A.s_NMDA_total_ = (w_pos * sum_sNMDA_A +
                                     w_neg * sum_sNMDA_B + w_neg * sum_sNMDA_Z)
        excit_pop_B.s_NMDA_total_ = (w_neg * sum_sNMDA_A +
                                     w_pos * sum_sNMDA_B + w_neg * sum_sNMDA_Z)
        excit_pop_Z.s_NMDA_total_ = (1.0 * sum_sNMDA_A + 1.0 * sum_sNMDA_B +
                                     1.0 * sum_sNMDA_Z)

    # set a self-recurrent synapse to introduce a delay when updating the intermediate
    # gating variable x
    syn_x_A2A = Synapses(excit_pop_A,
                         excit_pop_A,
                         on_pre="x += 1.",
                         delay=0.5 * b2.ms)
    syn_x_A2A.connect(j="i")
    syn_x_B2B = Synapses(excit_pop_B,
                         excit_pop_B,
                         on_pre="x += 1.",
                         delay=0.5 * b2.ms)
    syn_x_B2B.connect(j="i")
    syn_x_Z2Z = Synapses(excit_pop_Z,
                         excit_pop_Z,
                         on_pre="x += 1.",
                         delay=0.5 * b2.ms)
    syn_x_Z2Z.connect(j="i")
    ###############################################################################################

    # Define the stimulus: two PoissonInput with time time-dependent mean.
    poissonStimulus2A = PoissonGroup(N_Group_A, 0. * b2.Hz)
    syn_Stim2A = Synapses(poissonStimulus2A,
                          excit_pop_A,
                          on_pre="s_AMPA+=w_ext2excit")
    syn_Stim2A.connect(j="i")
    poissonStimulus2B = PoissonGroup(N_Group_B, 0. * b2.Hz)
    syn_Stim2B = Synapses(poissonStimulus2B,
                          excit_pop_B,
                          on_pre="s_AMPA+=w_ext2excit")
    syn_Stim2B.connect(j="i")

    @network_operation(dt=stimulus_update_interval)
    def update_poisson_stimulus(t):
        if t >= t_stimulus_start and t < t_stimulus_end:
            offset_A = mu0_mean_stimulus_Hz * (0.5 + 0.5 * coherence_level)
            offset_B = mu0_mean_stimulus_Hz * (0.5 - 0.5 * coherence_level)

            rate_A = numpy.random.normal(offset_A, stimulus_std_Hz)
            rate_A = (max(0, rate_A)) * b2.Hz  # avoid negative rate
            rate_B = numpy.random.normal(offset_B, stimulus_std_Hz)
            rate_B = (max(0, rate_B)) * b2.Hz

            poissonStimulus2A.rates = rate_A
            poissonStimulus2B.rates = rate_B
            # print("stim on. rate_A= {}, rate_B = {}".format(rate_A, rate_B))
        else:
            # print("stim off")
            poissonStimulus2A.rates = 0.
            poissonStimulus2B.rates = 0.

    ###############################################################################################

    def get_monitors(pop, monitored_subset_size):
        """
        Internal helper.
        Args:
            pop:
            monitored_subset_size:

        Returns:

        """
        monitored_subset_size = min(monitored_subset_size, pop.N)
        idx_monitored_neurons = sample(range(pop.N), monitored_subset_size)
        rate_monitor = PopulationRateMonitor(pop)
        # record parameter: record=idx_monitored_neurons is not supported???
        spike_monitor = SpikeMonitor(pop, record=idx_monitored_neurons)
        voltage_monitor = StateMonitor(pop, "v", record=idx_monitored_neurons)
        return rate_monitor, spike_monitor, voltage_monitor, idx_monitored_neurons

    # collect data of a subset of neurons:
    rate_monitor_inhib, spike_monitor_inhib, voltage_monitor_inhib, idx_monitored_neurons_inhib = \
        get_monitors(inhib_pop, monitored_subset_size)

    rate_monitor_A, spike_monitor_A, voltage_monitor_A, idx_monitored_neurons_A = \
        get_monitors(excit_pop_A, monitored_subset_size)

    rate_monitor_B, spike_monitor_B, voltage_monitor_B, idx_monitored_neurons_B = \
        get_monitors(excit_pop_B, monitored_subset_size)

    rate_monitor_Z, spike_monitor_Z, voltage_monitor_Z, idx_monitored_neurons_Z = \
        get_monitors(excit_pop_Z, monitored_subset_size)

    if stop_condition_rate is None:
        b2.run(max_sim_time)
    else:
        sim_sum = 0. * b2.ms
        sim_batch = 100. * b2.ms
        samples_in_batch = int(floor(sim_batch / b2.defaultclock.dt))
        avg_rate_in_batch = 0
        while (sim_sum < max_sim_time) and (avg_rate_in_batch <
                                            stop_condition_rate):
            b2.run(sim_batch)
            avg_A = numpy.mean(rate_monitor_A.rate[-samples_in_batch:])
            avg_B = numpy.mean(rate_monitor_B.rate[-samples_in_batch:])
            avg_rate_in_batch = max(avg_A, avg_B)
            sim_sum += sim_batch

    print("sim end: {}".format(time.ctime()))
    ret_vals = dict()

    ret_vals["rate_monitor_A"] = rate_monitor_A
    ret_vals["spike_monitor_A"] = spike_monitor_A
    ret_vals["voltage_monitor_A"] = voltage_monitor_A
    ret_vals["idx_monitored_neurons_A"] = idx_monitored_neurons_A

    ret_vals["rate_monitor_B"] = rate_monitor_B
    ret_vals["spike_monitor_B"] = spike_monitor_B
    ret_vals["voltage_monitor_B"] = voltage_monitor_B
    ret_vals["idx_monitored_neurons_B"] = idx_monitored_neurons_B

    ret_vals["rate_monitor_Z"] = rate_monitor_Z
    ret_vals["spike_monitor_Z"] = spike_monitor_Z
    ret_vals["voltage_monitor_Z"] = voltage_monitor_Z
    ret_vals["idx_monitored_neurons_Z"] = idx_monitored_neurons_Z

    ret_vals["rate_monitor_inhib"] = rate_monitor_inhib
    ret_vals["spike_monitor_inhib"] = spike_monitor_inhib
    ret_vals["voltage_monitor_inhib"] = voltage_monitor_inhib
    ret_vals["idx_monitored_neurons_inhib"] = idx_monitored_neurons_inhib

    return ret_vals
from brian2 import Hz, second, ms

from teili import Neurons, Connections, TeiliNetwork
from teili.models.neuron_models import LinearLIF as neuron_model
from teili.models.synapse_models import Exponential as static_synapse_model
from teili.models.synapse_models import ExponentialStdp as plastic_synapse_model

from speed.teili2orca import Speed

# Defining the network
N = 1000
F = 8 * Hz

Net = TeiliNetwork()

input = PoissonGroup(N, rates=F)
neurons = Neurons(2,
                  equation_builder=neuron_model(num_inputs=1),
                  name='neurons')

S = Connections(input,
                neurons,
                equation_builder=plastic_synapse_model(),
                name='stdp_synapse')

S.connect()
S.weight = 1.0
S.w_plast = 'rand()'
S.dApre = 0.01
S.taupre = 20 * ms
S.taupost = 20 * ms