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])
    fig1, [ax1, ax2] = plt.subplots(2, figsize=(3.5, 5))
    plt.subplots_adjust(left=.25, bottom=.25)

    max_f_amp, max_vm_amp = np.zeros(N), np.zeros(N)
    max_f_amp_e, max_f_amp_i = 0 * max_f_amp, 0 * max_f_amp
    amplitudes = np.linspace(0, amp_max, N)

    for i in range(N):
        amp = amplitudes[i]

        def func(t):
            # return step_input(t, 0.02, 1.)*amp
            return double_gaussian(t, t0, T1, T2, amp)
        t, fe, fi, muV, sV, muG, Tv = run_mean_field('RS-cell', 'FS-cell', 'CONFIG1', func, T=5e-3,\
                                                     ext_drive_change=0,
                                                     afferent_exc_fraction=None,
                                                     extended_output=True, tstop=tstop)
        max_f_amp[i] = np.max(.8 * fe + .2 * fi)
        max_f_amp_e[i] = np.max(fe)
        max_f_amp_i[i] = np.max(fi)
        max_vm_amp[i] = np.max(1e2 * np.abs((muV - muV[0]) / muV[0]))

    ax1.plot(amplitudes - amplitudes[0],
             max_f_amp,
             'k-',
             lw=3,
             label='$\\nu(t)$')
    ax1.plot(amplitudes - amplitudes[0],
             max_f_amp_e,
             'g-',
             label='$\\nu_e(t)$')
    args = parser.parse_args()

    if args.sim:
        run_simulation_with_input(args)
    else: # plot
        import matplotlib.pylab as plt
        fig, ax = plt.subplots(2)
        
        # loading the numerical data
        args, t, rate_input, fe, fi = np.load(args.file)
        # now building theoretical estimate
        def rate_func(t):
            return sinewave(t, 1e-3*args.t0, args.freq, 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)

        
        _, f_fitted, coeffs = find_modulus_and_phase_shift(1e-3*t, .8*fe+.2*fi,\
                                                           1e-3*args.t0, args.freq,\
                                                           full_output=True)
        ax[0].plot(t, f_fitted, 'r-', lw=1)

        # ax[0].plot(t[t>300], .8*fe[t>300]+.2*fi[t>300], 'k-')
        # ax[1].plot(t[t>300], rate_input[t>300], 'k-')
        ax[0].plot(t, .8*fe+.2*fi, 'k-', lw=.5, alpha=.4)
        ax[1].plot(t, rate_input, 'k-')
        
        ax[0].plot(1e3*t_th, .8*fe_th+.2*fi_th, 'k-', lw=3)
        ax[1].plot(1e3*t_th, rate_func(t_th), 'k-', lw=3)
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