Example #1
0
def simulate_STN_GPe_population(params):

    pid = os.getpid()
    b2.set_device(
        'cpp_standalone',
        #   build_on_run=False,
        directory=join("output", f"standalone-{pid}"))

    # b2.start_scope()

    par_s = params['par_s']
    par_g = params['par_g']
    par_syn = params['par_syn']
    par_sim = params['par_sim']

    if par_sim['standalone_mode']:
        b2.get_device().reinit()
        b2.get_device().activate(
            # build_on_run=False,
            directory=join("output", f"standalone-{pid}"))

    b2.defaultclock.dt = par_sim['dt']

    eqs_s = '''

    minf = 1/(1+exp(-(vs-thetam*mV)/(sigmam*mV))) : 1
    hinf = 1/(1+exp(-(vs-thetah*mV)/(sigmah*mV))) : 1 
    ninf = 1/(1+exp(-(vs-thetan*mV)/(sigman*mV))) : 1
    ainf = 1/(1+exp(-(vs-thetaa*mV)/(sigmaa*mV))) : 1
    binf = 1/(1+exp((r-thetab)/sigmab))-1/(1+exp(-thetab/sigmab)) : 1
    rinf = 1/(1+exp(-(vs-thetar*mV)/(sigmar*mV))) : 1
    sinf = 1/(1+exp(-(vs-thetas*mV)/(sigmas*mV))) : 1
    taun = taun0+taun1/(1+exp(-(vs-thn*mV)/(sigmant*mV))) : second
    tauh = tauh0+tauh1/(1+exp(-(vs-thh*mV)/(sigmaht*mV))) : second
    taur = taur0+taur1/(1+exp(-(vs-thr*mV)/(sigmart*mV))) : second

    il = gl * (vs - vl) : amp
    ina = gna * minf ** 3 * h * (vs - vna) : amp
    ik = gk * n ** 4 * (vs - vk) : amp
    iahp = gahp * ca / (ca + k1) * (vs - vk) : amp 
    ica = gca * sinf ** 2 * (vs - vca) : amp 
    it = gt * ainf ** 3 * binf ** 2 * (vs - vca) : amp 
    i_exts : amp 
    i_syn_GtoS : amp
    s_GtoS_sum : 1

    tmp2 = vs - thetag_s *mV : volt
    # Hinf_s = 1 / (1 + exp(-(tmp2 - thetas*mV) / (sigmas*mV))) : 1
    Hinf_s = 1 / (1 + exp(-(tmp2 - thetagH_s*mV) / (sigmagH_s*mV))) : 1
    ds_StoG/dt = alphas * Hinf_s * (1 - s_StoG) - betas * s_StoG : 1

    dh/dt  = phi * (hinf - h) / tauh  : 1
    dn/dt  = phi * (ninf - n) / taun  : 1
    dr/dt  = phir * (rinf - r) / taur : 1
    dca/dt = eps * ((-ica - it)/pA - kca* ca) : 1 
    membrane_Im = -(il + ina + ik + it + ica + iahp)+i_exts+i_syn_GtoS:amp
        
    dvs/dt = membrane_Im/C : volt
    '''
    eqs_g = '''
    i_extg : amp

    ainfg = 1 / (1 + exp(-(vg - thetaag*mV) / (sigag*mV))) : 1
    sinfg = 1 / (1 + exp(-(vg - thetasg*mV) / (sigsg*mV))) : 1
    rinfg = 1 / (1 + exp(-(vg - thetarg*mV) / (sigrg*mV))) : 1
    minfg = 1 / (1 + exp(-(vg - thetamg*mV) / (sigmg*mV))) : 1
    ninfg = 1 / (1 + exp(-(vg - thetang*mV) / (signg*mV))) : 1
    hinfg = 1 / (1 + exp(-(vg - thetahg*mV) / (sighg*mV))) : 1
    taung = taun0g + taun1g / (1 + exp(-(vg - thngt*mV) / (sng*mV))) : second
    tauhg = tauh0g + tauh1g / (1 + exp(-(vg - thhgt*mV) / (shg*mV))) : second

    dhg/dt = phihg*(hinfg-hg)/tauhg : 1
    dng/dt = phing*(ninfg-ng)/taung : 1
    drg/dt = phig*(rinfg-rg)/taurg  : 1
    dcag/dt= epsg*((-icag-itg)/pA - kcag*cag) : 1 
    dvg/dt = membrane_Im / C : volt

    tmp1 = vg - thetag_g *mV : volt
    # Hinf_g = 1 / (1 + exp(-(tmp1 - thetasg*mV) / (sigsg*mV))) : 1
    Hinf_g = 1 / (1 + exp(-(tmp1 - thetagH_g*mV) / (sigmagH_g*mV))) : 1
    ds_GtoS/dt = alphag * (1 - s_GtoS) * Hinf_g - betag * s_GtoS : 1

    itg = gtg * (ainfg ** 3) * rg * (vg - vcag) : amp
    inag = gnag * (minfg ** 3) * hg * (vg - vnag) : amp
    ikg = gkg * (ng ** 4) * (vg - vkg) : amp
    iahpg = gahpg * (vg - vkg) * cag / (cag + k1g) : amp
    icag = gcag * (sinfg ** 2) * (vg - vcag) : amp
    ilg = glg * (vg - vlg) : amp

    s_StoG_sum : 1
    i_syn_StoG : amp
    i_syn_GtoG : amp

    membrane_Im =-(itg+inag+ikg+iahpg+icag+ilg)+i_extg+i_syn_StoG+i_syn_GtoG : amp 
    '''

    eqs_syn_GtoS = '''
    i_syn_GtoS_post = g_GtoS*s_GtoS_pre*(v_rev_GtoS-vs):amp (summed)
    '''
    eqs_syn_StoG = '''
    i_syn_StoG_post = g_StoG*s_StoG_pre*(v_rev_StoG-vg):amp (summed)
    '''
    eqs_syn_GtoG = '''
    i_syn_GtoG_post = g_GtoG*s_GtoS_pre*(v_rev_GtoG-vg):amp (summed)
    '''

    #---------------------------------------------------------------#
    neurons_s = b2.NeuronGroup(
        par_s['num'],
        eqs_s,
        method=par_sim['integration_method'],
        dt=par_sim['dt'],
        threshold='vs>-20*mV',
        refractory='vs>-20*mV',
        namespace={
            **par_s,
            **par_syn
        },
    )

    #---------------------------------------------------------------#
    neurons_g = b2.NeuronGroup(
        par_g['num'],
        eqs_g,
        method=par_sim['integration_method'],
        dt=par_sim['dt'],
        threshold='vg>-20*mV',
        refractory='vg>-20*mV',
        namespace={
            **par_g,
            **par_syn
        },
    )
    # ---------------------------------------------------------------
    syn_GtoS = b2.Synapses(neurons_g,
                           neurons_s,
                           eqs_syn_GtoS,
                           method=par_sim['integration_method'],
                           dt=par_sim['dt'],
                           namespace=par_syn)
    # ---------------------------------------------------------------
    cols, rows = np.nonzero(par_syn['adj_GtoS'])
    syn_GtoS.connect(i=rows, j=cols)

    # syn_GtoS.connect(j='i')
    # syn_GtoS.connect(j='k for k in range(i-1, i+2)', skip_if_invalid=True)

    # ---------------------------------------------------------------
    syn_StoG = b2.Synapses(neurons_s,
                           neurons_g,
                           eqs_syn_StoG,
                           method=par_sim['integration_method'],
                           dt=par_sim['dt'],
                           namespace=par_syn)
    syn_StoG.connect(j='i')

    # ---------------------------------------------------------------
    syn_GtoG = b2.Synapses(neurons_g,
                           neurons_g,
                           eqs_syn_GtoG,
                           method=par_sim['integration_method'],
                           dt=par_sim['dt'],
                           namespace=par_syn)
    # figure 5, T2002
    cols, rows = np.nonzero(par_syn['adj_GtoG'])
    syn_GtoG.connect(i=rows, j=cols)
    # syn_GtoG.connect(p=par_syn['p_GtoG'], condition='i != j')
    # ---------------------------------------------------------------

    neurons_s.vs = par_s['v0']
    neurons_s.h = "hinf"
    neurons_s.n = "ninf"
    neurons_s.r = "rinf"
    neurons_s.ca = 0
    neurons_s.i_exts = par_s['i_ext']

    neurons_g.vg = par_g['v0']
    neurons_g.hg = "hinfg"
    neurons_g.ng = "ninfg"
    neurons_g.rg = "rinfg"
    neurons_g.cag = 0
    neurons_g.i_extg = par_g['i_ext']

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

    state_mon_s = b2.StateMonitor(neurons_s, ["vs", "i_syn_GtoS", "ca"],
                                  record=True)
    state_mon_g = b2.StateMonitor(neurons_g, ["vg", "i_syn_StoG", "cag"],
                                  record=True)
    spike_mon_s = b2.SpikeMonitor(neurons_s)
    spike_mon_g = b2.SpikeMonitor(neurons_g)

    lfp_stn = b2.PopulationRateMonitor(neurons_s)
    lfp_gpe = b2.PopulationRateMonitor(neurons_g)

    net = b2.Network(neurons_s, neurons_g, state_mon_g, spike_mon_s,
                     state_mon_s, spike_mon_g)

    net.add(syn_GtoS)
    net.add(syn_StoG)
    net.add(syn_GtoG)
    net.add(lfp_gpe)
    net.add(lfp_stn)

    net.run(par_sim['simulation_time'])

    # if par_sim['standalone_mode']:
    #     b2.get_device().build(directory="output",
    #                           compile=True,
    #                           run=True,
    #                           debug=False)
    monitors = {
        "state_stn": state_mon_s,
        "state_gpe": state_mon_g,
        "spike_stn": spike_mon_s,
        "spike_gpe": spike_mon_g,
        "lfp_stn": lfp_stn,
        "lfp_gpe": lfp_gpe,
    }

    return monitors
        weightMatrix = get_matrix_from_file(weight_path + '../random/' + connName + ending + '.npy')
        model = 'w : 1'
        pre = 'g%s_post += w' % conn_type[0]
        post = ''
        if ee_STDP_on:
            if 'ee' in recurrent_conn_names:
                model += eqs_stdp_ee
                pre += '; ' + eqs_stdp_pre_ee
                post = eqs_stdp_post_ee
        connections[connName] = b2.Synapses(neuron_groups[connName[0:2]], neuron_groups[connName[2:4]],
                                                    model=model, on_pre=pre, on_post=post)
        connections[connName].connect(True) # all-to-all connection
        connections[connName].w = weightMatrix[connections[connName].i, connections[connName].j]

    print 'create monitors for', name
    rate_monitors[name+'e'] = b2.PopulationRateMonitor(neuron_groups[name+'e'])
    rate_monitors[name+'i'] = b2.PopulationRateMonitor(neuron_groups[name+'i'])
    spike_counters[name+'e'] = b2.SpikeMonitor(neuron_groups[name+'e'])

    if record_spikes:
        spike_monitors[name+'e'] = b2.SpikeMonitor(neuron_groups[name+'e'])
        spike_monitors[name+'i'] = b2.SpikeMonitor(neuron_groups[name+'i'])


#------------------------------------------------------------------------------
# create input population and connections from input populations
#------------------------------------------------------------------------------
pop_values = [0,0,0]
for i,name in enumerate(input_population_names):
    input_groups[name+'e'] = b2.PoissonGroup(n_input, 0*Hz)
    rate_monitors[name+'e'] = b2.PopulationRateMonitor(input_groups[name+'e'])
def simulate():

    common_params = {  # Parameters common to all neurons.
        'C': 100 * b2.pfarad,
        'tau_m': 10 * b2.ms,
        'EL': -60 * b2.mV,
        'DeltaT': 2 * b2.mV,
        'Vreset': -65,  # *b2.mV
        'VTmean': -50 * b2.mV,
        'VTsd': 2 * b2.mV
    }

    common_params['gL'] = common_params['C'] / common_params['tau_m']

    E_cell_params = dict(
        common_params, **{
            'Ncells': num_E_cells,
            'IXmean': 30 * b2.pA,
            'IXsd': 20 * b2.pA
        })

    eqs = Equations("""
        Im = IX + 
            gL * (EL - vm) + 
            gL * DeltaT * exp((vm - VT) / DeltaT) - 
            ge * (vm - Erev_e) - 
            gi * (vm - Erev_i) - 
            gx * (vm - Erev_x) : amp
        dgi/dt = (1*nsiemens-gi)/Tau_i - gi/Tau_i : siemens
        dgx/dt = (1*nsiemens-gx)/Tau_x - gx/Tau_x : siemens
        dge/dt = (1*nsiemens-ge)/Tau_e - ge/Tau_e : siemens
        VT : volt
        IX : amp
        dvm/dt = Im / C : volt
        """)

    param_E_syn = {
        "Erev_i": 0.0 * b2.mV,
        "Erev_x": 0.0 * b2.mV,
        "Erev_e": -80.0 * b2.mV,
        "Tau_i": 3.0 * b2.ms,
        "Tau_e": 4.0 * b2.ms,
        "Tau_x": 4.0 * b2.ms,
        "w_i": 0.6,  # *b2.nsiemens,  # Peak conductance
        # *b2.nsiemens,  # Peak conductance  (1 in paper)
        "w_x": 1.4,
        "w_e": 0.1,  # *b2.nsiemens,  # Peak conductance
        "p_i": 0.1,  # ./I_cell_params['Ncells'],  # ! 200
        "p_e": 0.05,  # /E_cell_params['Ncells'],  # ! 400
    }

    if state == "beta":
        param_E_syn['w_x'] = 0.55 * b2.nS
        param_E_syn['Tau_x'] = 12 * b2.ms
        param_E_syn['w_e'] = 0.05 * b2.nS
        param_E_syn['Tau_e'] = 12 * b2.ms
        param_E_syn['w_i'] = 0.1 * b2.nS
        param_E_syn['Tau_i'] = 15 * b2.ms

    E_cells = b2.NeuronGroup(E_cell_params['Ncells'],
                             model=eqs,
                             method=integration_method,
                             threshold="vm > 0.*mV",
                             reset="vm={}*mV".format(E_cell_params['Vreset']),
                             refractory="vm > 0.*mV",
                             namespace={
                                 **common_params,
                                 **param_E_syn,
                             })

    # Poisson_to_E = b2.PoissonGroup(
    #     E_cell_params['Ncells'], rates=input_rates())  # ! input_rates

    cEE = b2.Synapses(E_cells,
                      E_cells,
                      on_pre='ge+={}*nsiemens'.format(param_E_syn["w_e"]))
    # cEX = b2.Synapses(Poisson_to_E,
    #                   E_cells,
    #                   method=integration_method,
    #                   on_pre="gx += {}*nsiemens".format(param_E_syn["w_x"]))
    # cEX.connect(j='i')

    # Initialise random parameters.

    E_cells.VT = (randn(len(E_cells)) * E_cell_params['VTsd'] +
                  E_cell_params['VTmean'])
    E_cells.IX = (randn(len(E_cells)) * E_cell_params['IXsd'] +
                  E_cell_params['IXmean'])

    spike_monitor_E = b2.SpikeMonitor(E_cells)

    rate_monitor_E = b2.PopulationRateMonitor(E_cells)

    state_monitor_E = state_monitor_I = None
    if record_volrages:
        state_monitor_E = b2.StateMonitor(E_cells, "vm", record=True)
        state_monitor_I = b2.StateMonitor(I_cells, "vm", record=True)

    net = b2.Network(E_cells)
    if record_volrages:
        net.add(state_monitor_E)
    net.add(spike_monitor_E)
    net.add(rate_monitor_E)
    # net.add(cEX)
    # Randomise initial membrane potentials.
    E_cells.vm = randn(len(E_cells)) * 10 * b2.mV - 60 * b2.mV

    print('Simulation running...')

    start_time = time.time()
    b2.run(sim_duration * b2.ms)

    duration = time.time() - start_time
    print('Simulation time:', duration, 'seconds')
def build_populations(Model,
                      POPULATIONS,
                      AFFERENT_POPULATIONS=[],
                      with_raster=False,
                      with_pop_act=False,
                      with_Vm=0,
                      with_synaptic_currents=False,
                      with_synaptic_conductances=False,
                      NEURONS=None,
                      verbose=False):
    """
    sets up the neuronal populations
    and  construct a network object containing everything
    """

    ## NEURONS AND CONNECTIVITY MATRIX
    if NEURONS is None:
        NEURONS = []
        for pop in POPULATIONS:
            NEURONS.append({'name': pop, 'N': Model['N_' + pop]})

    ########################################################################
    ####    TO BE WRITTEN
    ########################################################################

    NTWK = {
        'NEURONS':
        NEURONS,
        'Model':
        Model,
        'POPULATIONS':
        np.array(POPULATIONS),
        'AFFERENT_POPULATIONS':
        np.array(AFFERENT_POPULATIONS),
        'M':
        get_syn_and_conn_matrix(Model,
                                POPULATIONS,
                                AFFERENT_POPULATIONS=AFFERENT_POPULATIONS,
                                verbose=verbose)
    }

    NTWK['POPS'] = []
    for ii, nrn in enumerate(NEURONS):
        neuron_params = built_up_neuron_params(Model, nrn['name'], N=nrn['N'])
        NTWK['POPS'].append(
            get_membrane_equation(
                neuron_params,
                NTWK['M'][:, ii],
                with_synaptic_currents=with_synaptic_currents,
                with_synaptic_conductances=with_synaptic_conductances,
                verbose=verbose))
        nrn['params'] = neuron_params

    if with_pop_act:
        NTWK['POP_ACT'] = []
        for pop in NTWK['POPS']:
            NTWK['POP_ACT'].append(brian2.PopulationRateMonitor(pop))
    if with_raster:
        NTWK['RASTER'] = []
        for pop in NTWK['POPS']:
            NTWK['RASTER'].append(brian2.SpikeMonitor(pop))
    if with_Vm > 0:
        NTWK['VMS'] = []
        for pop in NTWK['POPS']:
            NTWK['VMS'].append(
                brian2.StateMonitor(pop, 'V', record=np.arange(with_Vm)))
    if with_synaptic_currents:
        NTWK['ISYNe'], NTWK['ISYNi'] = [], []
        for pop in NTWK['POPS']:
            NTWK['ISYNe'].append(
                brian2.StateMonitor(pop,
                                    'Ie',
                                    record=np.arange(max([1, with_Vm]))))
            NTWK['ISYNi'].append(
                brian2.StateMonitor(pop,
                                    'Ii',
                                    record=np.arange(max([1, with_Vm]))))
    if with_synaptic_conductances:
        NTWK['GSYNe'], NTWK['GSYNi'] = [], []
        for pop in NTWK['POPS']:
            NTWK['GSYNe'].append(
                brian2.StateMonitor(pop,
                                    'Ge',
                                    record=np.arange(max([1, with_Vm]))))
            NTWK['GSYNi'].append(
                brian2.StateMonitor(pop,
                                    'Gi',
                                    record=np.arange(max([1, with_Vm]))))

    NTWK['PRE_SPIKES'], NTWK['PRE_SYNAPSES'] = [], [
    ]  # in case of afferent inputs

    return NTWK
Example #5
0
def build_populations(Model,
                      POPULATIONS,
                      AFFERENT_POPULATIONS=[],
                      with_Vm=2,
                      verbose=False):
    """
    sets up the neuronal populations
    and construct a network object containing everything: NTWK
    """

    ## NEURONS AND CONNECTIVITY MATRIX
    NEURONS = []
    for pop in POPULATIONS:
        NEURONS.append({'name': pop, 'N': Model['N_' + pop]})

    NTWK = {
        'NEURONS':
        NEURONS,
        'Model':
        Model,
        'POPULATIONS':
        np.array(POPULATIONS),
        'M':
        get_syn_and_conn_matrix(Model,
                                POPULATIONS,
                                AFFERENT_POPULATIONS=AFFERENT_POPULATIONS,
                                verbose=verbose)
    }

    ########################################################################
    ####  Setting up
    ########################################################################

    NTWK['POPS'] = []
    for ii, nrn in enumerate(NEURONS):
        neuron_params = built_up_neuron_params(Model, nrn['name'], N=nrn['N'])
        NTWK['POPS'].append(
            get_membrane_equation(neuron_params,
                                  NTWK['M'][:, ii],
                                  verbose=verbose))
        nrn['params'] = neuron_params

    ########################################################################
    #### Recordings
    ########################################################################

    NTWK['POP_ACT'] = []
    for pop in NTWK['POPS']:
        NTWK['POP_ACT'].append(brian2.PopulationRateMonitor(pop))

    NTWK['RASTER'] = []
    for pop in NTWK['POPS']:
        NTWK['RASTER'].append(brian2.SpikeMonitor(pop))

    if with_Vm > 0:
        NTWK['VMS'] = []
        for pop in NTWK['POPS']:
            NTWK['VMS'].append(
                brian2.StateMonitor(pop, 'V', record=np.arange(with_Vm)))

    NTWK['PRE_SPIKES'], NTWK['PRE_SYNAPSES'] = [], [
    ]  # for future afferent inputs

    return NTWK
Example #6
0
def run_model(
        N=N,
        p=p,
        f=f,
        N_E=N_E,
        N_I=N_I,
        w_plus=w_plus,
        w_minus=w_minus,
        N_sub=N_sub,
        N_non=N_non,
        C_ext=C_ext,
        C_E=C_E,
        C_I=C_I,
        namespace=namespace,
        net=None,
        use_conductance=True,
        **namespace_kwargs  # use for repeated simulations?
):
    """
    Code taken primarily from
    https://brian2.readthedocs.io/en/stable/examples/frompapers.Brunel_Wang_2001.html
    """
    if net is None:
        b2.start_scope()
        s_AMPA_initial_ext = namespace['rate_ext'] * C_ext * namespace[
            'tau_AMPA']

        # update namespace with computed variables
        namespace['tau_m_E'] = namespace['C_m_E'] / namespace['g_m_E']
        namespace['tau_m_I'] = namespace['C_m_I'] / namespace['g_m_I']

        P_E = b2.NeuronGroup(
            N_E,
            eqs_conductance_E if use_conductance else eqs_current_E,
            threshold='v > V_thr',
            reset='v = V_reset',
            refractory='tau_rp_E',
            method='euler',
            name='P_E')
        P_E.v = namespace['V_L']
        P_E.s_AMPA_ext = s_AMPA_initial_ext  # estimated 4.8

        P_I = b2.NeuronGroup(
            N_E,
            eqs_conductance_I if use_conductance else eqs_current_I,
            threshold='v > V_thr',
            reset='v = V_reset',
            refractory='tau_rp_I',
            method='euler',
            name='P_I')
        P_I.v = namespace['V_L']
        P_I.s_AMPA_ext = s_AMPA_initial_ext

        C_E_E = b2.Synapses(
            P_E,
            P_E,
            model=eqs_glut,  # equations for NMDA
            on_pre=eqs_pre_glut,
            on_post=eqs_post_glut,
            method='euler',
            name='C_E_E')
        C_E_E.connect('i != j')
        C_E_E.w[:] = 1.0

        for pi in range(N_non, N_non + p * N_sub, N_sub):
            # internal other subpopulation to current nonselective
            # brian synapses are i->j
            C_E_E.w[C_E_E.indices[:, pi:pi + N_sub]] = w_minus
            # internal current subpopulation to current subpopulation
            C_E_E.w[C_E_E.indices[pi:pi + N_sub, pi:pi + N_sub]] = w_plus

        C_E_I = b2.Synapses(P_E,
                            P_I,
                            model=eqs_glut,
                            on_pre=eqs_pre_glut,
                            on_post=eqs_post_glut,
                            method='euler',
                            name='C_E_I')
        C_E_I.connect()
        C_E_I.w[:] = 1.0

        C_I_I = b2.Synapses(P_I,
                            P_I,
                            on_pre=eqs_pre_gaba,
                            method='euler',
                            name='C_I_I')
        C_I_I.connect('i != j')

        C_I_E = b2.Synapses(P_I,
                            P_E,
                            on_pre=eqs_pre_gaba,
                            method='euler',
                            name='C_I_E')
        C_I_E.connect()

        C_P_E = b2.PoissonInput(P_E,
                                target_var='s_AMPA_ext',
                                N=C_ext,
                                rate=namespace['rate_ext'],
                                weight=1.)
        C_P_I = b2.PoissonInput(P_I,
                                target_var='s_AMPA_ext',
                                N=C_ext,
                                rate=namespace['rate_ext'],
                                weight=1.)

        # TODO: change the stimulus to match the task
        C_selection = int(f * C_ext)
        rate_selection = 25. * b2.Hz
        if 'stimulus1' not in namespace:
            stimtimestep = 25 * b2.ms
            stimtime = 1
            stimuli1 = b2.TimedArray(np.r_[np.zeros(8),
                                           np.ones(stimtime),
                                           np.zeros(100)],
                                     dt=stimtimestep)
            namespace['stimuli1'] = stimuli1
        input1 = b2.PoissonInput(P_E[N_non:N_non + N_sub],
                                 target_var='s_AMPA_ext',
                                 N=C_selection,
                                 rate=rate_selection,
                                 weight='stimuli1(t)')

        N_activity_plot = 15  # number of neurons to rasterplot
        # spike monitors
        sp_E_sels = [
            b2.SpikeMonitor(P_E[pi:pi + N_activity_plot],
                            name=f'sp_E_{int((pi-N_non)/N_sub) + 1}')
            for pi in range(N_non, N_non + p * N_sub, N_sub)
        ]
        sp_E = b2.SpikeMonitor(P_E[:N_activity_plot], name=f'sp_E_non')
        sp_I = b2.SpikeMonitor(P_I[:N_activity_plot], name=f'sp_I')
        # rate monitors
        r_E_sels = [
            b2.PopulationRateMonitor(P_E[pi:pi + N_sub],
                                     name=f'r_E_{int((pi-N_non)/N_sub) + 1}')
            for pi in range(N_non, N_non + p * N_sub, N_sub)
        ]
        r_E = b2.PopulationRateMonitor(P_E[:N_non], name=f'r_E_non')
        r_I = b2.PopulationRateMonitor(P_I, name=f'r_I')
        # state monitors
        st_E_sels = [
            b2.StateMonitor(P_E[pi:pi + N_activity_plot],
                            variables=True,
                            record=True,
                            name=f'st_E_{int((pi-N_non)/N_sub) + 1}')
            for pi in range(N_non, N_non + p * N_sub, N_sub)
        ]
        st_E = b2.StateMonitor(P_E[:N_activity_plot],
                               variables=True,
                               record=True,
                               name=f'st_E_non')
        st_I = b2.StateMonitor(P_I[:N_activity_plot],
                               variables=True,
                               record=True,
                               name=f'st_I')

        net = b2.Network(b2.collect())
        # add lists of monitors independently because
        # `b2.collect` doesn't search nested objects
        net.add(sp_E_sels)
        net.add(r_E_sels)
        net.add(st_E_sels)

        net.store('initialised')

    # runtime=runtime*b2.second
    net.restore('initialised')
    net.run(duration=runtime * b2.second, report='stdout', namespace=namespace)

    return net, namespace
 def set_rate_monitor(self):
     """yep"""
     self.mon_rate_e = bb.PopulationRateMonitor(self.Pe)
     self.mon_rate_i = bb.PopulationRateMonitor(self.Pi)
     self.network.add(self.mon_rate_e, self.mon_rate_i)