int(200 / 0.1))

        # ######################
        # ## ----- Plot ----- ##
        # ######################

        # # # afferent excitation onto cortical excitation and inhibition
        for i, tpop in enumerate(['RecExc', 'RecInh', 'DsInh'
                                  ]):  # both on excitation and inhibition
            ntwk.construct_feedforward_input(NTWK,
                                             tpop,
                                             'AffExc',
                                             t_array,
                                             faff,
                                             verbose=True)

        ################################################################
        ## --------------- Initial Condition ------------------------ ##
        ################################################################
        ntwk.initialize_to_rest(NTWK)

        #####################
        ## ----- Run ----- ##
        #####################
        network_sim = ntwk.collect_and_run(NTWK, verbose=True)

        ntwk.write_as_hdf5(NTWK, filename='CellRep2019_data.h5')
        print('Results of the simulation are stored as:',
              'CellRep2019_data.h5')
        print('--> Run \"python CellRep2019.py plot\" to plot the results')
def run_sim(Model,
            with_Vm=0,
            with_synaptic_currents=False,
            firing_rate_only=False,
            tdiscard=100):

    if 'RATES' in Model.keys():
        RATES = Model['RATES']
    else:
        RATES = {}
        for pop in Model['POP_STIM']:
            RATES['F_' + pop] = Model['F_' + pop]

    if tdiscard >= Model['tstop']:
        print('discard time higher than simulation time -> set to 0')
        tdiscard = 0

    t_array = np.arange(int(Model['tstop'] / Model['dt'])) * Model['dt']

    ############################################################################
    # everything is reformatted to have it compatible with the network framework
    ############################################################################

    aff_pops_discard_self = []
    for p in Model['POP_STIM']:
        if p != Model['NRN_KEY']:
            aff_pops_discard_self.append(p)

    # note that number of neurons become number of different seeds
    NTWK = ntwk.build_populations(
        Model, [Model['NRN_KEY']],
        NEURONS=[{
            'name': Model['NRN_KEY'],
            'N': Model['N_SEED']
        }],
        AFFERENT_POPULATIONS=aff_pops_discard_self,
        with_Vm=with_Vm,
        with_raster=True,
        with_synaptic_currents=with_synaptic_currents)

    ntwk.initialize_to_rest(
        NTWK)  # (fully quiescent State as initial conditions)

    SPKS, SYNAPSES, PRESPKS = [], [], []

    for i, afferent_pop in enumerate(Model['POP_STIM']):
        rate_array = RATES['F_' + afferent_pop] + 0. * t_array
        ntwk.construct_feedforward_input(NTWK,
                                         Model['NRN_KEY'],
                                         afferent_pop,
                                         t_array,
                                         rate_array,
                                         SEED=i + Model['SEED'])

    sim = ntwk.collect_and_run(NTWK)

    # calculating firing rate
    vec = np.zeros(Model['N_SEED'])
    ispikes = np.array(NTWK['RASTER'][0].i)
    tspikes = np.array(NTWK['RASTER'][0].t / ntwk.ms)
    for nrn in range(Model['N_SEED']):
        i0 = np.argwhere(ispikes == nrn).flatten()
        ts = tspikes[i0]
        fout = 1e3 * len(ts[ts > tdiscard]) / (Model['tstop'] - tdiscard
                                               )  # from ms to Hz
        vec[nrn] = fout

    if firing_rate_only:
        return vec.mean(), vec.std()
    else:
        output = {
            'ispikes': np.array(NTWK['RASTER'][0].i),
            'tspikes': np.array(NTWK['RASTER'][0].t / ntwk.ms),
            'Model': Model,
            'fout_mean': vec.mean(),
            'fout_std': vec.std()
        }
        if with_Vm:
            output['i_prespikes'] = NTWK['iRASTER_PRE']
            output['t_prespikes'] = [
                vv / ntwk.ms for vv in NTWK['tRASTER_PRE']
            ]
            output['Vm'] = np.array([vv.V / ntwk.mV for vv in NTWK['VMS'][0]])
        if with_synaptic_currents:
            output['Ie'] = np.array(
                [vv.Ie / ntwk.pA for vv in NTWK['ISYNe'][0]])
            output['Ii'] = np.array(
                [vv.Ii / ntwk.pA for vv in NTWK['ISYNi'][0]])
        return output