def run_simulation_with_input(args, BIN=5):

    t = np.arange(int(args.tstop/args.DT))*args.DT
    
    input_rate = sinewave(t, args.t0, args.freq/1e3, args.amp)

    M = get_connectivity_and_synapses_matrix(args.CONFIG.split('--')[2])
    ext_drive = M[0,0]['ext_drive']

    time_array, rate_array, fe, fi = run_simulation(\
                    NRN_exc=args.CONFIG.split('--')[0],\
                    NRN_inh=args.CONFIG.split('--')[1],\
                    NTWK=args.CONFIG.split('--')[2],
                    kick_value=0, kick_duration=args.kick_duration,
                    DT=args.DT, tstop=args.tstop, SEED=args.SEED,\
                    ext_drive=ext_drive,input_rate=input_rate, \
                    full_recording=False)

    # binning it !
    # fe = bin_array(fe, BIN, time_array)
    # fi = bin_array(fi, BIN, time_array)
    # rate_array = bin_array(rate_array, BIN, time_array)
    # time_array = bin_array(time_array, BIN, time_array)
    ## NO NEED TO BIN !!
    
    # now simulation
    
    np.save(args.file, [args, time_array, rate_array, fe, fi])
def run_simulation_with_input(args, BIN=5):

    t = np.arange(int(args.tstop/args.DT))*args.DT
    
    input_rate = double_gaussian(t, args.t0, args.T1, args.T2, args.amp)

    M = get_connectivity_and_synapses_matrix(args.CONFIG.split('--')[2])
    ext_drive = M[0,0]['ext_drive']

    time_array, rate_array, fe, fi = run_simulation(\
                    NRN_exc=args.CONFIG.split('--')[0],\
                    NRN_inh=args.CONFIG.split('--')[1],\
                    NTWK=args.CONFIG.split('--')[2],
                    kick_value=0, kick_duration=args.kick_duration,
                    DT=args.DT, tstop=args.tstop, SEED=args.SEED,\
                    ext_drive=ext_drive,input_rate=input_rate, \
                    full_recording=False)

    # binning it !
    fe = bin_array(fe, BIN, time_array)
    fi = bin_array(fi, BIN, time_array)
    rate_array = bin_array(rate_array, BIN, time_array)
    time_array = bin_array(time_array, BIN, time_array)
    
    # now simulation
    def rate_func(t):
        return double_gaussian(t, 1e-3*args.t0, 1e-3*args.T1, 1e-3*args.T2, args.amp)

    t_th, fe_th, fi_th = run_mean_field(args.CONFIG.split('--')[0],\
                               args.CONFIG.split('--')[1],args.CONFIG.split('--')[2],\
                               rate_func,
                               tstop=args.tstop*1e-3)
    
    np.save(args.file, [time_array, rate_array, fe, fi, t_th, fe_th, fi_th])
Beispiel #3
0
def run_mean_field_extended(NRN1, NRN2, NTWK, array_func,\
                            Ne=8000, Ni=2000, T=5e-3,\
                            afferent_exc_fraction=0.,
                            dt=1e-4, tstop=2, extended_output=False,\
                            ext_drive_change=0.):

    # find external drive
    M = get_connectivity_and_synapses_matrix(NTWK, SI_units=True)
    ext_drive = M[0,0]['ext_drive']
    if afferent_exc_fraction<0.5:
        afferent_exc_fraction = M[0,0]['afferent_exc_fraction']
    
    X0 = find_fixed_point(NRN1, NRN2, NTWK, exc_aff=ext_drive+ext_drive_change,\
                          Ne=Ne, Ni=Ni,
                          verbose=True)

    TF1, TF2 = load_transfer_functions(NRN1, NRN2, NTWK)

    t = np.arange(int(tstop/dt))*dt
    
    def dX_dt_scalar(X, t=0):
        exc_aff = ext_drive+ext_drive_change+(1-afferent_exc_fraction)*array_func(t)
        pure_exc_aff = (2*afferent_exc_fraction-1)*array_func(t) # what needs to be added
        return build_up_differential_operator(TF1, TF2, Ne=Ne, Ni=Ni, T=T)(X,\
                                      exc_aff=exc_aff, pure_exc_aff=pure_exc_aff)


    X = np.zeros((len(t), len(X0)))
    X[0,:] = X0
    for i in range(len(t)-1):
        exc_aff = ext_drive+ext_drive_change+(1-afferent_exc_fraction)*array_func(t[i])
        pure_exc_aff = (2*afferent_exc_fraction-1)*array_func(t[i]) # what needs to be added
        # X[i+1,:] = X[i,:] + dt*dX_dt_scalar(X[i,:], t=t[i])
        X[i+1,:] = X[i,:] + (t[1]-t[0])*build_up_differential_operator(TF1, TF2,\
                Ne=Ne, Ni=Ni)(X[i,:], exc_aff=exc_aff, pure_exc_aff=pure_exc_aff)
    
    fe, fi = X[:,0], X[:,1]
    sfe, sfei, sfi = [np.sqrt(X[:,i]) for i in range(2,5)]

    if extended_output:
        params = get_neuron_params(NRN2, SI_units=True)
        reformat_syn_parameters(params, M)

        exc_aff = ext_drive+ext_drive_change+(1-afferent_exc_fraction)*array_func(t)
        pure_exc_aff = (2*afferent_exc_fraction-1)*array_func(t) # what needs to be added


        # excitatory neurons have more excitation
        muV_e, sV_e, muGn_e, TvN_e = get_fluct_regime_vars(\
                                                           fe+exc_aff+pure_exc_aff,\
                                                           fi, *pseq_params(params))
        muV_i, sV_i, muGn_i, TvN_i = get_fluct_regime_vars(\
                                                           fe+exc_aff,\
                                                           fi, *pseq_params(params))
        muV, sV, muGn, TvN = .8*muV_e+.2*muV_i, .8*sV_e+.2*sV_i,\
                                        .8*muGn_e+.2*muGn_i, .8*TvN_e+.2*TvN_i,
            
        return t, fe, fi, sfe, sfei, sfi, muV, sV, muGn, TvN
    else:
        return t, fe, fi, sfe, sfei, sfi
def run_simulation(NRN_exc='LIF', NRN_inh='LIF', NTWK='Vogels-Abbott', DT=0.1, tstop=300,\
                   kick_value=50., kick_duration=30., SEED=1, ext_drive=0., input_rate=None,\
                   afferent_exc_fraction=0.,
                   n_rec=3, full_recording=False, filename='data/example_data.npy'):

    seed(SEED % 100)

    M = get_connectivity_and_synapses_matrix(NTWK, number=2)
    if afferent_exc_fraction < .5:
        afferent_exc_fraction = M[0, 0]['afferent_exc_fraction']

    # number of neurons
    Ne, Ni = int(M[0, 0]['Ntot'] * (1 - M[0, 0]['gei'])), int(M[0, 0]['Ntot'] *
                                                              M[0, 0]['gei'])
    Ne = 1
    Ni = 1

    exc_neurons, eqs = get_membrane_equation(get_neuron_params(NRN_exc,
                                                               number=Ne),
                                             M[:, 0],
                                             return_equations=True)
    inh_neurons, eqs = get_membrane_equation(get_neuron_params(NRN_inh,
                                                               number=Ni),
                                             M[:, 1],
                                             return_equations=True)

    ## INITIAL CONDITIONS

    exc_neurons.Gee, exc_neurons.Gie, exc_neurons.V = '0.*nS', '0.*nS', '(-90+30*rand())*mV'
    exc_neurons.p = '.2'
    inh_neurons.Gei, inh_neurons.Gii, inh_neurons.V = '0.*nS', '0.*nS', '(-90+30*rand())*mV'

    group = exc_neurons
    group.V = -65. * mV
    #group.I = '0.7*nA * i / num_neurons'

    group.I0 = 1.7 * nA

    monitor = SpikeMonitor(group)
    trace = StateMonitor(group, 'V', record=0)

    tstop = 1000
    DT = DT
    time_array = np.arange(int(tstop / DT)) * DT
    run(tstop * ms)
    V = trace[0].V[:]
    Varr = array(V / mV)

    plt.plot(time_array, Varr)
    plt.show()
Beispiel #5
0
def run_mean_field(NRN1, NRN2, NTWK, array_func,\
                   T=5e-3, dt=1e-4, tstop=2, extended_output=False,\
                   afferent_exc_fraction=0.,
                   ext_drive_change=0.):

    # find external drive
    M = get_connectivity_and_synapses_matrix(NTWK, SI_units=True)
    ext_drive = M[0,0]['ext_drive']
    if afferent_exc_fraction<0.5:
        afferent_exc_fraction = M[0,0]['afferent_exc_fraction']

    X0 = find_fixed_point_first_order(NRN1, NRN2, NTWK, exc_aff=ext_drive+ext_drive_change,\
                                      verbose=False)

    TF1, TF2 = load_transfer_functions(NRN1, NRN2, NTWK)

    t = np.arange(int(tstop/dt))*dt
    
    def dX_dt_scalar(X, t=0):
        exc_aff = ext_drive+ext_drive_change+(1-afferent_exc_fraction)*array_func(t)
        pure_exc_aff = (2*afferent_exc_fraction-1)*array_func(t) # what needs to be added
        return build_up_differential_operator_first_order(TF1, TF2, T=T)(X,\
                                                exc_aff=exc_aff, pure_exc_aff=pure_exc_aff)
        
    fe, fi = odeint(dX_dt_scalar, X0, t).T

    if extended_output:
        params = get_neuron_params(NRN2, SI_units=True)
        reformat_syn_parameters(params, M)

        exc_aff = ext_drive+ext_drive_change+(1-afferent_exc_fraction)*array_func(t)
        pure_exc_aff = (2*afferent_exc_fraction-1)*array_func(t) # what needs to be added


        # excitatory neurons have more excitation
        muV_e, sV_e, muGn_e, TvN_e = get_fluct_regime_vars(\
                                                           fe+exc_aff+pure_exc_aff,\
                                                           fi, *pseq_params(params))
        muV_i, sV_i, muGn_i, TvN_i = get_fluct_regime_vars(\
                                                           fe+exc_aff,\
                                                           fi, *pseq_params(params))
        muV, sV, muGn, TvN = .8*muV_e+.2*muV_i, .8*sV_e+.2*sV_i,\
                                        .8*muGn_e+.2*muGn_i, .8*TvN_e+.2*TvN_i,
            
        return t, fe, fi, muV, sV, muGn, TvN
    else:
        return t, fe, fi
Beispiel #6
0
def run_simulation_with_input(args, filename='data/1.npy'):

    t = np.arange(int(args.tstop / args.DT)) * args.DT

    input_rate = double_gaussian(t, args.t0, args.T1, args.T2, args.amp)

    M = get_connectivity_and_synapses_matrix(args.CONFIG.split('--')[2])
    ext_drive = M[0, 0]['ext_drive']

    run_simulation(\
                   NRN_exc=args.CONFIG.split('--')[0],
                   NRN_inh=args.CONFIG.split('--')[1],
                   NTWK=args.CONFIG.split('--')[2],
                   kick_value=0, kick_duration=args.kick_duration,
                   DT=args.DT, tstop=args.tstop, SEED=args.SEED,
                   ext_drive=ext_drive,input_rate=input_rate,
                   full_recording=True, n_rec=args.n_rec,
                   afferent_exc_fraction=args.afferent_exc_fraction,
                   filename=filename)
def load_transfer_functions(NRN1, NRN2, NTWK):
    """
    returns the two transfer functions of the mean field model
    """
    print("'../transfer_functions/data/'+NRN1+'_'+NTWK+'_fit.npy'")
    # NTWK
    M = get_connectivity_and_synapses_matrix(NTWK, SI_units=True)

    # NRN1
    params1 = get_neuron_params(NRN1, SI_units=True)
    reformat_syn_parameters(params1, M)
    try:
        P1 = np.load('../transfer_functions/data/' + NRN1 + '_' + NTWK +
                     '_fit.npy')

        #P1=np.load('../transfer_functions/data/'+NRN1+'_'+NTWK+'_DB_fit.npy')

        params1['P'] = P1

        def TF1(fe, fi):
            return TF_my_template(fe, fi, *pseq_params(params1))
    except IOError:
        print('=======================================================')
        print('=====  fit for NRN1 not available  ====================')
        print('=======================================================')

    # NRN1
    params2 = get_neuron_params(NRN2, SI_units=True)
    reformat_syn_parameters(params2, M)
    try:
        P2 = np.load('../transfer_functions/data/' + NRN2 + '_' + NTWK +
                     '_fit.npy')
        params2['P'] = P2

        def TF2(fe, fi):
            return TF_my_template(fe, fi, *pseq_params(params2))
    except IOError:
        print('=======================================================')
        print('=====  fit for NRN2 not available  ====================')
        print('=======================================================')

    return TF1, TF2
                         help="tstop in s")
    parser.add_argument("--dt",type=float, default=5e-5,\
                         help="dt in ms")
    parser.add_argument("--SEED",type=int, default=1,\
                  help="Seed for random number generation (default=1)")

    parser.add_argument("-s", "--save", help="save with the right name",
                         action="store_true")
    
    parser.add_argument("-v", "--verbose", help="increase output verbosity",
                         action="store_true")

    args = parser.parse_args()

    params = get_neuron_params(args.Neuron_Model, SI_units=True)
    M = get_connectivity_and_synapses_matrix(args.Network_Model, SI_units=True)

    reformat_syn_parameters(params, M) # merging those parameters

    if args.save:
        FILE = 'data/'+args.Neuron_Model+'_'+args.Network_Model+'.npy'
    else:
        FILE = 'data/example_data.npy'
        
    generate_transfer_function(params,\
                               verbose=args.verbose,
                               MAXfexc=args.max_Fe, 
                               MINfinh=args.lim_Fi[0], MAXfinh=args.lim_Fi[1],\
                               discret_exc=args.discret_Fe,discret_inh=args.discret_Fi,\
                               filename=FILE,
                               dt=args.dt, tstop=args.tstop,
def plot_ntwk_sim_output_for_waveform(args,\
                                      BIN=5, min_time=200, bar_ms=50,
                                      zoom_conditions=None, vpeak=-35,\
                                      raster_number=400):

    BIN = 8
    time_array, rate_array, rate_exc, rate_inh,\
        Raster_exc, Raster_inh,\
        Vm_exc, Vm_inh, Ge_exc, Ge_inh, Gi_exc, Gi_inh = np.load(args.file,allow_pickle = True)

    rate_exc = rate_exc + 0.2
    print("ee")

    if zoom_conditions is not None:
        z = zoom_conditions
    else:
        z = [time_array[0], time_array[-1]]
    cond_t = (time_array > z[0]) & (time_array < z[1])

    ###### =========================================== ######
    ############# adding the theoretical eval ###############
    ###### =========================================== ######

    t0 = args.t0 - 4 * args.T1

    def rate_func(t):
        return double_gaussian(t, 1e-3 * args.t0, 1e-3 * args.T1,
                               1e-3 * args.T2, args.amp)

    t, fe, fi, sfe, sfei, sfi = run_mean_field_extended(args.CONFIG.split('--')[0],\
                               args.CONFIG.split('--')[1],args.CONFIG.split('--')[2],\
                               rate_func,dt=5e-4,
                               tstop=args.tstop*1e-3)

    tfirst, fefirst, fifirst = run_mean_field(args.CONFIG.split('--')[0],
                                              args.CONFIG.split('--')[1],
                                              args.CONFIG.split('--')[2],
                                              rate_func,
                                              dt=5e-4,
                                              tstop=args.tstop * 1e-3)

    params = get_neuron_params(args.CONFIG.split('--')[0], SI_units=True)
    M = get_connectivity_and_synapses_matrix('CONFIG1', SI_units=True)
    reformat_syn_parameters(params, M)  # merging those parameters
    ext_drive = M[0, 0]['ext_drive']
    afferent_exc_fraction = M[0, 0]['afferent_exc_fraction']

    fe_e, fe_i = fe + ext_drive + rate_func(t), fe + ext_drive
    muV_e, sV_e, muGn_e, TvN_e = get_fluct_regime_vars(fe_e, fi,
                                                       *pseq_params(params))
    muV_i, sV_i, muGn_i, TvN_i = get_fluct_regime_vars(fe_i, fi,
                                                       *pseq_params(params))

    Ne = Raster_inh[1].min()

    FIGS = []
    # plotting
    FIGS.append(plt.figure(figsize=(5, 4)))
    cond = (Raster_exc[0] > z[0]) & (Raster_exc[0] < z[1]) & (
        Raster_exc[1] > Ne - raster_number)
    plt.plot(Raster_exc[0][cond], Raster_exc[1][cond], '.g')
    cond = (Raster_inh[0] > z[0]) & (Raster_inh[0] < z[1]) & (
        Raster_inh[1] < Ne + .2 * raster_number)
    plt.plot(Raster_inh[0][cond], Raster_inh[1][cond], '.r')
    '''
    plt.plot([z[0],z[0]+bar_ms], [Ne, Ne], 'k-', lw=5)
    plt.annotate(str(bar_ms)+'ms', (z[0]+bar_ms, Ne))
    '''
    #set_plot(plt.gca(), ['left'], ylabel='Neuron index', xticks=[])

    FIGS.append(plt.figure(figsize=(5, 5)))
    ax1 = plt.subplot2grid((3, 1), (0, 0), rowspan=2)
    ax2 = plt.subplot2grid((3, 1), (2, 0))
    for i in range(len(Vm_exc)):
        ax1.plot(time_array[cond_t], Vm_exc[i][cond_t], 'g-', lw=.5)
        spk = np.where((Vm_exc[i][cond_t][:-1] > -50)
                       & (Vm_exc[i][cond_t][1:] < -55))[0]
        for ispk in spk:
            ax1.plot(time_array[cond_t][ispk] * np.ones(2),
                     [Vm_exc[i][cond_t][ispk], vpeak], 'g--')
        ax2.plot(time_array[cond_t], Ge_exc[i][cond_t], 'g-', lw=.5)
        ax2.plot(time_array[cond_t], Gi_exc[i][cond_t], 'r-', lw=.5)
    # vm
    ax1.plot(1e3 * t[1e3 * t > t0], 1e3 * muV_e[1e3 * t > t0], 'g-', lw=2)
    ax1.fill_between(1e3*t[1e3*t>t0], 1e3*(muV_e[1e3*t>t0]-sV_e[1e3*t>t0]),\
                     1e3*(muV_e[1e3*t>t0]+sV_e[1e3*t>t0]), color='g', alpha=.4)
    # ge
    ge_th = 1e9 * fe_e[1e3 * t > t0] * params['Qe'] * params['Te'] * (
        1 - params['gei']) * params['pconnec'] * params['Ntot']
    sge_th = 1e9 * params['Qe'] * np.sqrt(
        fe_e[1e3 * t > t0] * params['Te'] *
        (1 - params['gei']) * params['pconnec'] * params['Ntot'])
    ax2.plot(1e3 * t[1e3 * t > t0], ge_th, 'g-', lw=2)
    ax2.fill_between(1e3 * t[1e3 * t > t0],
                     ge_th - sge_th,
                     ge_th + sge_th,
                     color='g',
                     alpha=.4)
    gi_th = 1e9 * fi[1e3 * t > t0] * params['Qi'] * params['Ti'] * params[
        'gei'] * params['pconnec'] * params['Ntot']
    sgi_th = 1e9 * params['Qi'] * np.sqrt(
        fi[1e3 * t > t0] * params['Ti'] * params['gei'] * params['pconnec'] *
        params['Ntot'])
    ax2.plot(1e3 * t[1e3 * t > t0], gi_th, 'r-', lw=2)
    ax2.fill_between(1e3 * t[1e3 * t > t0],
                     gi_th - sgi_th,
                     gi_th + sgi_th,
                     color='r',
                     alpha=.4)

    ax1.plot(time_array[cond_t][0] * np.ones(2), [-65, -55], lw=4, color='k')
    ax1.annotate('10mV', (time_array[cond_t][0], -65))
    #set_plot(ax1, [], xticks=[], yticks=[])
    #set_plot(ax2, ['left'], ylabel='$G$ (nS)', xticks=[])

    FIGS.append(plt.figure(figsize=(5, 5)))
    ax1 = plt.subplot2grid((3, 1), (0, 0), rowspan=2)
    ax2 = plt.subplot2grid((3, 1), (2, 0))
    for i in range(len(Vm_inh)):
        ax1.plot(time_array[cond_t], Vm_inh[i][cond_t], 'r-', lw=.5)
        spk = np.where((Vm_inh[i][cond_t][:-1] > -51)
                       & (Vm_inh[i][cond_t][1:] < -55))[0]
        for ispk in spk:
            ax1.plot(time_array[cond_t][ispk] * np.ones(2),
                     [Vm_inh[i][cond_t][ispk], vpeak], 'r--')
        ax2.plot(time_array[cond_t], Ge_inh[i][cond_t], 'g-', lw=.5)
        ax2.plot(time_array[cond_t], Gi_inh[i][cond_t], 'r-', lw=.5)

    # vm
    ax1.plot(1e3 * t[1e3 * t > t0], 1e3 * muV_i[1e3 * t > t0], 'r-', lw=2)
    ax1.fill_between(1e3*t[1e3*t>t0], 1e3*(muV_i[1e3*t>t0]-sV_i[1e3*t>t0]),\
                     1e3*(muV_i[1e3*t>t0]+sV_i[1e3*t>t0]), color='r', alpha=.4)
    ge_th = 1e9 * fe_i[1e3 * t > t0] * params['Qe'] * params['Te'] * (
        1 - params['gei']) * params['pconnec'] * params['Ntot']
    sge_th = 1e9 * params['Qe'] * np.sqrt(
        fe_i[1e3 * t > t0] * params['Te'] *
        (1 - params['gei']) * params['pconnec'] * params['Ntot'])
    ax2.plot(1e3 * t[1e3 * t > t0], ge_th, 'g-', lw=2)
    ax2.fill_between(1e3 * t[1e3 * t > t0],
                     ge_th - sge_th,
                     ge_th + sge_th,
                     color='g',
                     alpha=.4)
    ax2.plot(1e3 * t[1e3 * t > t0], gi_th, 'r-', lw=2)
    ax2.fill_between(1e3 * t[1e3 * t > t0],
                     gi_th - sgi_th,
                     gi_th + sgi_th,
                     color='r',
                     alpha=.4)

    ax1.plot(time_array[cond_t][0] * np.ones(2), [-65, -55], lw=4, color='k')
    ax1.annotate('10mV', (time_array[cond_t][0], -65))
    #set_plot(ax1, [], xticks=[], yticks=[])
    #set_plot(ax2, ['left'], ylabel='$G$ (nS)', xticks=[])

    fig, AX = plt.subplots(figsize=(5, 3))
    # we bin the population rate
    rate_exc = bin_array(rate_exc[cond_t], BIN, time_array[cond_t])
    rate_inh = bin_array(rate_inh[cond_t], BIN, time_array[cond_t])
    rate_array = bin_array(rate_array[cond_t], BIN, time_array[cond_t])
    time_array = bin_array(time_array[cond_t], BIN, time_array[cond_t])

    AX.plot(time_array, rate_exc, 'g-', lw=.6, label='$\\nu_e(t)$')

    AX.plot(time_array, rate_inh, 'r-', lw=.6, label='$\\nu_i(t)$')
    AX.plot(1000 * tfirst, fifirst, 'r--', lw=.6, label='$\\nu_i(t)$')

    np.save('HH_response', [
        1000 * tfirst, fefirst, fifirst, t, fe, fi, sfe, sfi,
        rate_func(tfirst)
    ])

    #AX.plot(time_array, .8*rate_exc+.2*rate_inh, 'k-', lw=2, label='$\\nu(t)$')

    AX.plot(1e3 * t[1e3 * t > t0], fi[1e3 * t > t0], 'r-', label='num. sim.')
    AX.plot(1e3*t[1e3*t>t0], rate_func(t[1e3*t>t0]), 'k:',\
            lw=2, label='$\\nu_e^{aff}(t)$ \n $\\nu_e^{drive}$')
    AX.plot(1e3 * t[1e3 * t > t0],
            fe[1e3 * t > t0],
            'g-',
            label='mean field \n pred.')
    AX.fill_between(1e3*t[1e3*t>t0], fe[1e3*t>t0]-sfe[1e3*t>t0], fe[1e3*t>t0]+sfe[1e3*t>t0],\
                        color='g', alpha=.3, label='mean field \n pred.')

    AX.fill_between(1e3*t[1e3*t>t0], fi[1e3*t>t0]-sfi[1e3*t>t0], fi[1e3*t>t0]+sfi[1e3*t>t0],\
                        color='r', alpha=.3)
    # AX.plot(1e3*t[1e3*t>t0], .8*fe[1e3*t>t0]+.2*fi[1e3*t>t0], 'k-', label='..')

    AX.legend(prop={'size': 'xx-small'})

    #set_plot(AX, ['left'], ylabel='$\\nu$ (Hz)', xticks=[], num_yticks=3)
    FIGS.append(fig)

    print('excitatory rate: ', rate_exc[len(rate_exc) / 2:].mean(), 'Hz')
    print('inhibitory rate: ', rate_inh[len(rate_exc) / 2:].mean(), 'Hz')
    print(sfe[0], sfe[-1])
    plt.show()
    return FIGS
def plot_ntwk_sim_output(time_array, rate_array, rate_exc, rate_inh,\
                         Raster_exc, Raster_inh,\
                         Vm_exc, Vm_inh, Ge_exc, Ge_inh, Gi_exc, Gi_inh,\
                         BIN=5, min_time=2000):

    BIN = 15.

    cond_t = (time_array > min_time)  # transient behavior after 400 ms

    params = get_neuron_params(args.CONFIG.split('--')[0], SI_units=True)
    M = get_connectivity_and_synapses_matrix('CONFIG1', SI_units=True)
    EXC_AFF = M[0, 0]['ext_drive']

    print('starting fixed point')
    fe0, fi0, sfe, sfie, sfi = find_fixed_point(args.CONFIG.split('--')[0], args.CONFIG.split('--')[1], 'CONFIG1',\
                                                exc_aff=EXC_AFF, Ne=8000, Ni=2000, verbose=True)
    print('end fixed point')

    reformat_syn_parameters(params, M)  # merging those parameters

    xfe = fe0 + np.linspace(-4, 4) * sfe
    fe_pred = gaussian_func(xfe, fe0, sfe)
    xfi = fi0 + np.linspace(-4, 4) * sfi
    fi_pred = gaussian_func(xfi, fi0, sfi)

    mGe, mGi, sGe, sGi = mean_and_var_conductance(fe0 + EXC_AFF, fi0,
                                                  *pseq_params(params))
    muV, sV, muGn, TvN = get_fluct_regime_vars(fe0 + EXC_AFF, fi0,
                                               *pseq_params(params))
    print("eee", muV)
    FE, FI = np.meshgrid(xfe, xfi)
    pFE, pFI = np.meshgrid(fe_pred, fi_pred)
    MUV, SV, _, _ = get_fluct_regime_vars(
        FE + EXC_AFF, FI, *pseq_params(params)) * pFE * pFI / np.sum(pFE * pFI)

    ### MEMBRANE POTENTIAL
    MEAN_VM, STD_VM, KYRT_VM = [], [], []
    for i in range(len(Vm_exc)):
        MEAN_VM.append(Vm_exc[i][(time_array > min_time) & (Vm_exc[i] != -65) &
                                 (Vm_exc[i] < -50)].mean())
        MEAN_VM.append(Vm_inh[i][(time_array > min_time) & (Vm_inh[i] != -65) &
                                 (Vm_inh[i] < -50)].mean())
        for vv in [
                Vm_exc[i][(time_array > min_time)],
                Vm_inh[i][(time_array > min_time)]
        ]:
            i0 = np.where((vv[:-1] > -52) & (vv[1:] < -60))[0]
            print(i0)
            sv = []
            if len(i0) == 0:
                STD_VM.append(vv.std())
            elif len(i0) == 1:
                STD_VM.append(vv[0].std())
            else:
                for i1, i2 in zip(i0[:-1], i0[1:]):
                    if i2 - i1 > 60:
                        sv.append(vv[i1 + 30:i2 - 30].std())
                STD_VM.append(np.array(sv).mean())
        STD_VM.append(Vm_inh[i][(time_array > min_time)
                                & (Vm_inh[i] < -50)].std())

    fig1, AX1 = plt.subplots(1, 3, figsize=(3, 2))  # for means
    fig2, AX2 = plt.subplots(1, 3, figsize=(3, 2))  # for std

    AX1[0].bar([0],
               np.array(MEAN_VM).mean() + 65,
               yerr=np.array(MEAN_VM).std(),
               color='w',
               edgecolor='k',
               lw=3,
               error_kw=dict(elinewidth=3, ecolor='k'))
    AX2[0].bar([0],
               np.array(STD_VM).mean(),
               yerr=np.array(STD_VM).std(),
               color='w',
               edgecolor='k',
               lw=3,
               error_kw=dict(elinewidth=3, ecolor='k'),
               label='$V_m$')
    AX1[0].bar([1], [1e3 * muV + 65], color='gray', alpha=.5, label='$V_m$')
    AX2[0].bar([1], [1e3 * sV], color='gray', alpha=.5)

    #set_plot(AX1[0], ['left'], xticks=[], ylim=[0,11], yticks=[0, 5, 10], yticks_labels=['-65', '-60', '-55'], ylabel='mean (mV)')
    #set_plot(AX2[0], ['left'], xticks=[], ylim=[0,5], yticks=[0, 2, 4], ylabel='std. dev. (mV)')

    ### EXCITATORY CONDUCTANCE
    MEAN_GE, STD_GE, KYRT_GE = [], [], []
    for i in range(len(Ge_exc)):
        MEAN_GE.append(Ge_exc[i][(time_array > min_time)].mean())
        MEAN_GE.append(Ge_inh[i][(time_array > min_time)].mean())
        STD_GE.append(Ge_exc[i][(time_array > min_time)].std())
        STD_GE.append(Ge_inh[i][(time_array > min_time)].std())

    AX1[1].bar([0],
               np.array(MEAN_GE).mean(),
               yerr=np.array(MEAN_GE).std(),
               color='w',
               edgecolor='g',
               lw=3,
               error_kw=dict(elinewidth=3, ecolor='g'),
               label='num. sim.')
    AX2[1].bar([0],
               np.array(STD_GE).mean(),
               yerr=np.array(STD_GE).std(),
               color='w',
               edgecolor='g',
               lw=3,
               error_kw=dict(elinewidth=3, ecolor='g'),
               label='exc.')
    AX1[1].bar([1], [1e9 * mGe], color='g', label='mean field \n pred.')
    AX2[1].bar([1], [1e9 * sGe], color='g', label='exc.')

    #set_plot(AX1[1], ['left'], xticks=[], yticks=[0,15,30], ylabel='mean (nS)')
    #set_plot(AX2[1], ['left'], xticks=[], yticks=[0,5,10], ylabel='std. dev. (nS)')

    ### INHIBITORY CONDUCTANCE
    MEAN_GI, STD_GI, KYRT_GI = [], [], []
    for i in range(len(Gi_exc)):
        MEAN_GI.append(Gi_exc[i][(time_array > min_time)].mean())
        MEAN_GI.append(Gi_inh[i][(time_array > min_time)].mean())
        STD_GI.append(Gi_exc[i][(time_array > min_time)].std())
        STD_GI.append(Gi_inh[i][(time_array > min_time)].std())

    AX1[2].bar([0],
               np.array(MEAN_GI).mean(),
               yerr=np.array(MEAN_GI).std(),
               color='w',
               edgecolor='r',
               lw=3,
               error_kw=dict(elinewidth=3, ecolor='r'),
               label='num. sim.')
    AX2[2].bar([0],
               np.array(STD_GI).mean(),
               yerr=np.array(STD_GI).std(),
               color='w',
               edgecolor='r',
               lw=3,
               error_kw=dict(elinewidth=3, ecolor='r'),
               label='inh.')
    AX1[2].bar([1], [1e9 * mGi], color='r', label='mean field \n pred.')
    AX2[2].bar([1], [1e9 * sGi], color='r', label='inh.')

    #set_plot(AX1[2], ['left'], xticks=[], yticks=[0,15,30], ylabel='mean (nS)')
    #set_plot(AX2[2], ['left'], xticks=[], yticks=[0,5,10], ylabel='std. dev. (nS)')

    ### POPULATION RATE ###

    fig, ax = plt.subplots(figsize=(4, 3))
    # we bin the population rate
    N0 = int(BIN / (time_array[1] - time_array[0]))
    N1 = int((time_array[cond_t][-1] - time_array[cond_t][0]) / BIN)
    time_array = time_array[cond_t][:N0 * N1].reshape((N1, N0)).mean(axis=1)
    rate_exc = rate_exc[cond_t][:N0 * N1].reshape((N1, N0)).mean(axis=1)
    rate_inh = rate_inh[cond_t][:N0 * N1].reshape((N1, N0)).mean(axis=1)
    rate_array = rate_array[cond_t][:N0 * N1].reshape((N1, N0)).mean(axis=1)

    hh, bb = np.histogram(rate_exc, bins=3, normed=True)
    ax.bar(.5 * (bb[:-1] + bb[1:]),
           hh,
           color='w',
           width=bb[1] - bb[0],
           edgecolor='g',
           lw=3,
           label='exc.',
           alpha=.7)
    hh, bb = np.histogram(rate_inh, bins=5, normed=True)
    ax.bar(.5 * (bb[:-1] + bb[1:]),
           hh,
           color='w',
           width=bb[1] - bb[0],
           edgecolor='r',
           lw=3,
           label='inh',
           alpha=.7)

    ax.fill_between(xfe, 0 * fe_pred, fe_pred, color='g', alpha=.8)
    ax.fill_between(xfi, 0 * fi_pred, fi_pred, color='r', alpha=.8)

    #set_plot(plt.gca(), ['bottom', 'left'], xlabel='pop. activity (Hz)', yticks=[], ylabel='density')

    for ax in AX1:
        ax.legend()
    for ax in AX2:
        ax.legend()

    return [fig, fig1, fig2]
Beispiel #11
0
def run_simulation(NRN_exc='LIF', NRN_inh='LIF', NTWK='Vogels-Abbott', DT=0.1, tstop=300,\
                   kick_value=50., kick_duration=30., SEED=1, ext_drive=0., input_rate=None,\
                   afferent_exc_fraction=0.,
                   n_rec=3, full_recording=False, filename='data/example_data.npy'):

    seed(SEED % 100)

    M = get_connectivity_and_synapses_matrix(NTWK, number=2)
    if afferent_exc_fraction < .5:
        afferent_exc_fraction = M[0, 0]['afferent_exc_fraction']

    # number of neurons
    Ne, Ni = int(M[0, 0]['Ntot'] * (1 - M[0, 0]['gei'])), int(M[0, 0]['Ntot'] *
                                                              M[0, 0]['gei'])

    exc_neurons, eqs = get_membrane_equation(get_neuron_params(NRN_exc,
                                                               number=Ne),
                                             M[:, 0],
                                             return_equations=True)
    inh_neurons, eqs = get_membrane_equation(get_neuron_params(NRN_inh,
                                                               number=Ni),
                                             M[:, 1],
                                             return_equations=True)

    ## INITIAL CONDITIONS
    exc_neurons.Gee, exc_neurons.Gie, exc_neurons.V = '0.*nS', '0.*nS', '-65*mV'
    inh_neurons.Gei, inh_neurons.Gii, inh_neurons.V = '0.*nS', '0.*nS', '-65*mV'

    ## FEEDFORWARD EXCITSTORY CONNECTIONS
    time_array = np.arange(int(tstop / DT)) * DT
    rate_array = np.array([kick_value*tt/kick_duration+(tt/kick_duration-1)*ext_drive\
                           if tt<kick_duration else 0. for tt in time_array])+ext_drive

    # input_on_inh, input_on_exc = rate_array, rate_array
    # ### PURE EXC CASE, DELETED !!
    if input_rate is not None:
        input_on_exc, input_on_inh = rate_array+afferent_exc_fraction*input_rate,\
                                     rate_array+(1-afferent_exc_fraction)*input_rate
    else:
        input_on_exc, input_on_inh = rate_array, rate_array

    ## FEEDFORWARD EXCITATION
    input_exc, fdfrwd_to_exc, input_inh, fdfrwd_to_inh = \
        build_up_excitatory_feedforward_connections_for_2_pop(\
                            [exc_neurons, inh_neurons], M,
                            time_array, input_on_exc, input_on_inh,\
                            SEED=(SEED+1)**2)

    ## RECURRENT CONNECTIONS
    exc_exc, exc_inh, inh_exc, inh_inh = \
      build_up_recurrent_connections_for_2_pop([exc_neurons, inh_neurons], M,\
                                               SEED=(SEED+2)**2) # only for 2 pop !

    # setting up the recording
    PRe = PopulationRateMonitor(exc_neurons)
    PRi = PopulationRateMonitor(inh_neurons)
    if full_recording:
        trace_Vm_exc = StateMonitor(exc_neurons, 'V', record=range(n_rec))
        trace_Vm_inh = StateMonitor(inh_neurons, 'V', record=range(n_rec))
        trace_Ge_exc = StateMonitor(exc_neurons, 'Gee', record=range(n_rec))
        trace_Gi_exc = StateMonitor(exc_neurons, 'Gie', record=range(n_rec))
        trace_Ge_inh = StateMonitor(inh_neurons, 'Gei', record=range(n_rec))
        trace_Gi_inh = StateMonitor(inh_neurons, 'Gii', record=range(n_rec))
        raster_exc = SpikeMonitor(exc_neurons)
        raster_inh = SpikeMonitor(inh_neurons)

    # running the simulation
    defaultclock.dt = DT * ms
    run(tstop * ms)

    if full_recording:
        Raster_exc, Raster_inh, Vm_exc, Vm_inh, Ge_exc, Ge_inh, Gi_exc, Gi_inh =\
           transform_to_simple_arrays(trace_Vm_exc, trace_Vm_inh, trace_Ge_exc, trace_Gi_exc,\
                                      trace_Ge_inh, trace_Gi_inh, raster_exc, raster_inh,\
                                      M, n_rec=n_rec)
        np.save(filename,
                [time_array, rate_array, PRe.rate/Hz, PRi.rate/Hz, Raster_exc,\
                 Raster_inh, Vm_exc, Vm_inh, Ge_exc, Ge_inh, Gi_exc, Gi_inh])
        return time_array, rate_array, PRe.rate / Hz, PRi.rate / Hz
    else:
        np.save(filename,
                [time_array, rate_array, PRe.rate / Hz, PRi.rate / Hz])
        return time_array, rate_array, PRe.rate / Hz, PRi.rate / Hz
from synapses_and_connectivity.syn_and_connec_library import get_connectivity_and_synapses_matrix
from transfer_functions.tf_simulation import reformat_syn_parameters
import matplotlib.pylab as plt

from scipy.optimize import fsolve
from scipy.optimize import minimize
import math

NTWK = 'CONFIG1'

NRN1 = 'HH_RS'
NRN2 = 'HH_RS'

TF1, TF2 = load_transfer_functions(NRN1, NRN2, NTWK)

M = get_connectivity_and_synapses_matrix(NTWK, SI_units=True)
params = get_neuron_params(NRN1, SI_units=True)
reformat_syn_parameters(params, M)
paramsinh = get_neuron_params(NRN2, SI_units=True)
reformat_syn_parameters(paramsinh, M)

Qe, Te, Ee = params['Qe'], params['Te'], params['Ee']
Qi, Ti, Ei = params['Qi'], params['Ti'], params['Ei']
Gl, Cm, El = params['Gl'], params['Cm'], params['El']
pconnec, Ntot, gei, ext_drive = params['pconnec'], params['Ntot'], params[
    'gei'], M[0, 0]['ext_drive']

N = 100
freqs = np.linspace(3, 7, N)

frespthEx = 0 * freqs
Beispiel #13
0
def Euler_method_for_ring_model(NRN1, NRN2, NTWK, RING, STIM, BIN=5e-3,\
                                custom_ring_params={}, custom_stim_params={}):
    """
    Given two afferent rate input excitatory and inhibitory respectively
    this function computes the prediction of a first order rate model
    (e.g. Wilson and Cowan in the 70s, or 1st order of El Boustani and
    Destexhe 2009) by implementing a simple Euler method
    IN A 2D GRID WITH LATERAL CONNECTIVITY
    the number of laterally connected units is 'connected_neighbors'
    there is an exponential decay of the strength 'decay_connect'
    ----------------------------------------------------------------
    the core of the formalism is the transfer function, see Zerlaut et al. 2015
    it can also be Kuhn et al. 2004 or Amit & Brunel 1997
    -----------------------------------------------------------------
    nu_0 is the starting value value of the recurrent network activity
    it should be the fixed point of the network dynamics
    -----------------------------------------------------------------
    t is the discretization used to solve the euler method
    BIN is the initial sampling bin that should correspond to the
    markovian time scale where the formalism holds (~5ms)
    
    conduction_velocity=0e-3, in ms per pixel !!!
    """

    print('----- loading parameters [...]')
    M = get_connectivity_and_synapses_matrix(NTWK, SI_units=True)
    ext_drive = M[0, 0]['ext_drive']
    params = get_neuron_params(NRN2, SI_units=True)
    reformat_syn_parameters(params, M)
    afferent_exc_fraction = M[0, 0]['afferent_exc_fraction']

    print('----- ## we look for the fixed point [...]')
    try:
        fe0, fi0, muV0 = np.load("fixed_point_data_TO_BE_REMOVED.npy")
        print(
            "/!\\ STORED FIXED POINT DATA LOADED, check if not a different config /!\\"
        )
    except IOError:
        fe0, fi0 = find_fixed_point_first_order(NRN1,
                                                NRN2,
                                                NTWK,
                                                exc_aff=ext_drive)
        muV0, _, _, _ = get_fluct_regime_vars(fe0 + ext_drive, fi0,
                                              *pseq_params(params))
        np.save('fixed_point_data_TO_BE_REMOVED.npy', [fe0, fi0, muV0])

    print('----- ## we load the transfer functions [...]')
    TF1, TF2 = load_transfer_functions(NRN1, NRN2, NTWK)

    print('----- ## ring initialisation [...]')
    X, Xn_exc, Xn_inh, exc_connected_neighbors, exc_decay_connect, inh_connected_neighbors,\
        inh_decay_connect, conduction_velocity = ring.pseq_ring_params(RING, custom=custom_ring_params)

    print('----- ## stimulation initialisation [...]')
    t, Fe_aff = stim.get_stimulation(X, STIM, custom=custom_stim_params)
    Fi_aff = 0 * Fe_aff  # no afferent inhibition yet

    print('----- ## model initialisation [...]')
    Fe, Fi, muVn = 0 * Fe_aff + fe0, 0 * Fe_aff + fi0, 0 * Fe_aff + muV0

    print('----- starting the temporal loop [...]')
    dt = t[1] - t[0]

    # constructing the Euler method for the activity rate
    for i_t in range(len(t) - 1):  # loop over time

        for i_x in range(len(X)):  # loop over pixels

            # afferent excitation + exc DRIVE
            fe = (1 - afferent_exc_fraction) * Fe_aff[
                i_t, i_x] + ext_drive  # common both to exc and inh
            fe_pure_exc = (2 * afferent_exc_fraction -
                           1) * Fe_aff[i_t, i_x]  # only for excitatory pop
            fi = 0  #  0 for now.. !

            # EXC --- we add the recurrent activity and the lateral interactions
            for i_xn in Xn_exc:  # loop over neighboring excitatory pixels
                # calculus of the weight
                exc_weight = ring.gaussian_connectivity(
                    i_xn, 0., exc_decay_connect)
                # then we have folded boundary conditions (else they donot
                # have all the same number of active neighbors !!)
                i_xC = (i_x + i_xn) % (len(X))

                if i_t > int(abs(i_xn) / conduction_velocity / dt):
                    it_delayed = i_t - int(
                        abs(i_xn) / conduction_velocity / dt)
                else:
                    it_delayed = 0

                fe += exc_weight * Fe[it_delayed, i_xC]

            # INH --- we add the recurrent activity and the lateral interactions
            for i_xn in Xn_inh:  # loop over neighboring inhibitory pixels
                # calculus of the weight
                inh_weight = ring.gaussian_connectivity(
                    i_xn, 0., inh_decay_connect)
                # then we have folded boundary conditions (else they donot
                # have all the same number of active neighbors !!)
                i_xC = (i_x + i_xn) % (len(X))

                if i_t > int(abs(i_xn) / conduction_velocity / dt):
                    it_delayed = i_t - int(
                        abs(i_xn) / conduction_velocity / dt)
                else:
                    it_delayed = 0

                fi += inh_weight * Fi[it_delayed, i_xC]

            ## NOTE THAT NO NEED TO SCALE : fi*= gei*pconnec*Ntot and fe *= (1-gei)*pconnec*Ntot
            ## THIS IS DONE IN THE TRANSFER FUNCTIONS !!!!

            # now we can guess the rate model output
            muVn[i_t + 1,
                 i_x], _, _, _ = get_fluct_regime_vars(fe, fi,
                                                       *pseq_params(params))
            Fe[i_t + 1,
               i_x] = Fe[i_t, i_x] + dt / BIN * (TF1(fe + fe_pure_exc, fi) -
                                                 Fe[i_t, i_x])
            Fi[i_t + 1,
               i_x] = Fi[i_t, i_x] + dt / BIN * (TF2(fe, fi) - Fi[i_t, i_x])

    print('----- temporal loop over !')

    return t, X, Fe_aff, Fe, Fi, np.abs((muVn - muV0) / muV0)
Beispiel #14
0
    if return_equations:
        return neurons, eqs
    else:
        return neurons


if __name__ == '__main__':

    print(__doc__)

    # starting from an example

    # starting from an example

    NTWK = 'CONFIG1'
    M = get_connectivity_and_synapses_matrix(NTWK, number=2)
    NRN_exc = 'HH_RS'

    # number of neurons
    Ne, Ni = int(M[0, 0]['Ntot'] * (1 - M[0, 0]['gei'])), int(M[0, 0]['Ntot'] *
                                                              M[0, 0]['gei'])
    print("EEEE", NRN_exc)
    exc_neurons, eqs = get_membrane_equation(get_neuron_params(NRN_exc,
                                                               number=Ne),
                                             M[:, 0],
                                             return_equations=True)

    neuron = NeuronGroup(1,
                         eqs,
                         threshold='V > -40*mV',
                         refractory='V > -40*mV',