def run_model(sim, **options):
    """
    Run a simulation using the parameters read from the file "I_f_curve.json"

    :param sim: the PyNN backend module to be used.
    :param options: should contain a keyword "simulator" which is the name of the PyNN backend module used.
    :return: a tuple (`data`, `times`) where `data` is a Neo Block containing the recorded spikes
             and `times` is a dict containing the time taken for different phases of the simulation.
    """
    
    import json
    from pyNN.utility import Timer

    timer = Timer()

    g = open("I_f_curve.json", 'r')
    d = json.load(g)
    
    N = d['param']['N']
    max_current = d['param']['max_current']
    tstop = d['param']['tstop']

    if options['simulator'] == "hardware.brainscales":
        hardware_preset = d['setup'].pop('hardware_preset', None)
        if hardware_preset:
            d['setup']['hardware'] = sim.hardwareSetup[hardware_preset]

    timer.start()
    sim.setup(**d['setup'])

    popcell = sim.Population(N, sim.IF_cond_exp, d['IF_cond_exp'])

    #current_source = []
    #for i in xrange(N):
    #    current_source.append(sim.DCSource(amplitude=(max_current*(i+1)/N)))
    #    popcell[i:(i+1)].inject(current_source[i])
    i_offset = max_current * (1 + np.arange(N))/N
    popcell.tset("i_offset", i_offset)

    if PYNN07:
        popcell.record()
    else:
        popcell.record('spikes')
        #popcell[0, 1, N-2, N-1].record('v')  # debug

    setup_time = timer.diff()
    sim.run(tstop)
    run_time = timer.diff()

    if PYNN07:
        spike_array = popcell.getSpikes()
        data = spike_array_to_neo(spike_array, popcell, tstop)
    else:
        data = popcell.get_data()

    sim.end()

    closing_time = timer.diff()
    times = {'setup_time': setup_time, 'run_time': run_time, 'closing_time': closing_time}

    return data, times
class NetworkModel(object):
    def __init__(self, params, comm):

        self.params = params
        self.debug_connectivity = True
        self.comm = comm
        if self.comm != None:
            self.pc_id, self.n_proc = self.comm.rank, self.comm.size
            print "USE_MPI: yes", "\tpc_id, n_proc:", self.pc_id, self.n_proc
        else:
            self.pc_id, self.n_proc = 0, 1
            print "MPI not used"

        np.random.seed(params["np_random_seed"] + self.pc_id)

        if self.params["with_short_term_depression"]:
            self.short_term_depression = SynapseDynamics(
                fast=TsodyksMarkramMechanism(U=0.95, tau_rec=10.0, tau_facil=0.0)
            )

    def import_pynn(self):
        """
        This function needs only be called when this class is used in another script as imported module
        """
        import pyNN

        exec ("from pyNN.%s import *" % self.params["simulator"])
        print "import pyNN\npyNN.version: ", pyNN.__version__

    def setup(self, load_tuning_prop=False, times={}):

        self.projections = {}
        self.projections["ee"] = []
        self.projections["ei"] = []
        self.projections["ie"] = []
        self.projections["ii"] = []
        if not load_tuning_prop:
            self.tuning_prop_exc = utils.set_tuning_prop(
                self.params, mode="hexgrid", cell_type="exc"
            )  # set the tuning properties of exc cells: space (x, y) and velocity (u, v)
            self.tuning_prop_inh = utils.set_tuning_prop(
                self.params, mode="hexgrid", cell_type="inh"
            )  # set the tuning properties of exc cells: space (x, y) and velocity (u, v)
        else:
            self.tuning_prop_exc = np.loadtxt(self.params["tuning_prop_means_fn"])
            self.tuning_prop_inh = np.loadtxt(self.params["tuning_prop_inh_fn"])

        indices, distances = utils.sort_gids_by_distance_to_stimulus(
            self.tuning_prop_exc, self.params["motion_params"], self.params
        )  # cells in indices should have the highest response to the stimulus
        if self.pc_id == 0:
            print "Saving tuning_prop to file:", self.params["tuning_prop_means_fn"]
            np.savetxt(self.params["tuning_prop_means_fn"], self.tuning_prop_exc)
            print "Saving tuning_prop to file:", self.params["tuning_prop_inh_fn"]
            np.savetxt(self.params["tuning_prop_inh_fn"], self.tuning_prop_inh)
            print "Saving gids to record to: ", self.params["gids_to_record_fn"]
            np.savetxt(self.params["gids_to_record_fn"], indices[: self.params["n_gids_to_record"]], fmt="%d")

        #        np.savetxt(params['gids_to_record_fn'], indices[:params['n_gids_to_record']], fmt='%d')

        if self.comm != None:
            self.comm.Barrier()
        from pyNN.utility import Timer

        self.timer = Timer()
        self.timer.start()
        self.times = times
        self.times["t_all"] = 0
        # # # # # # # # # # # #
        #     S E T U P       #
        # # # # # # # # # # # #
        (delay_min, delay_max) = self.params["delay_range"]
        setup(timestep=0.1, min_delay=delay_min, max_delay=delay_max, rng_seeds_seed=self.params["seed"])
        rng_v = NumpyRNG(
            seed=sim_cnt * 3147 + self.params["seed"], parallel_safe=True
        )  # if True, slower but does not depend on number of nodes
        self.rng_conn = NumpyRNG(
            seed=self.params["seed"], parallel_safe=True
        )  # if True, slower but does not depend on number of nodes

        # # # # # # # # # # # # # # # # # # # # # # # # #
        #     R A N D O M    D I S T R I B U T I O N S  #
        # # # # # # # # # # # # # # # # # # # # # # # # #
        self.v_init_dist = RandomDistribution(
            "normal",
            (self.params["v_init"], self.params["v_init_sigma"]),
            rng=rng_v,
            constrain="redraw",
            boundaries=(-80, -60),
        )

        self.times["t_setup"] = self.timer.diff()
        self.times["t_calc_conns"] = 0
        if self.comm != None:
            self.comm.Barrier()

        self.torus = space.Space(
            axes="xy", periodic_boundaries=((0.0, self.params["torus_width"]), (0.0, self.params["torus_height"]))
        )

    def create_neurons_with_limited_tuning_properties(self):
        n_exc = self.tuning_prop_exc[:, 0].size
        n_inh = 0
        if self.params["neuron_model"] == "IF_cond_exp":
            self.exc_pop = Population(n_exc, IF_cond_exp, self.params["cell_params_exc"], label="exc_cells")
            self.inh_pop = Population(
                self.params["n_inh"], IF_cond_exp, self.params["cell_params_inh"], label="inh_pop"
            )
        elif self.params["neuron_model"] == "IF_cond_alpha":
            self.exc_pop = Population(n_exc, IF_cond_alpha, self.params["cell_params_exc"], label="exc_cells")
            self.inh_pop = Population(
                self.params["n_inh"], IF_cond_alpha, self.params["cell_params_inh"], label="inh_pop"
            )
        elif self.params["neuron_model"] == "EIF_cond_exp_isfa_ista":
            self.exc_pop = Population(n_exc, EIF_cond_exp_isfa_ista, self.params["cell_params_exc"], label="exc_cells")
            self.inh_pop = Population(
                self.params["n_inh"], EIF_cond_exp_isfa_ista, self.params["cell_params_inh"], label="inh_pop"
            )
        else:
            print "\n\nUnknown neuron model:\n\t", self.params["neuron_model"]

        # set cell positions, required for isotropic connections
        cell_pos_exc = np.zeros((3, self.params["n_exc"]))
        cell_pos_exc[0, :] = self.tuning_prop_exc[:, 0]
        cell_pos_exc[1, :] = self.tuning_prop_exc[:, 1]
        self.exc_pop.positions = cell_pos_exc

        cell_pos_inh = np.zeros((3, self.params["n_inh"]))
        cell_pos_inh[0, :] = self.tuning_prop_inh[:, 0]
        cell_pos_inh[1, :] = self.tuning_prop_inh[:, 1]
        self.inh_pop.positions = cell_pos_inh

        self.local_idx_exc = get_local_indices(self.exc_pop, offset=0)

        if not input_created:
            self.spike_times_container = [[] for i in xrange(len(self.local_idx_exc))]
            self.spike_times_container = [[] for i in xrange(len(self.local_idx_exc))]
        print "Debug, pc_id %d has local %d exc indices:" % (self.pc_id, len(self.local_idx_exc)), self.local_idx_exc
        self.exc_pop.initialize("v", self.v_init_dist)

        self.local_idx_inh = get_local_indices(self.inh_pop, offset=self.params["n_exc"])
        print "Debug, pc_id %d has local %d inh indices:" % (self.pc_id, len(self.local_idx_inh)), self.local_idx_inh
        self.inh_pop.initialize("v", self.v_init_dist)
        self.times["t_create"] = self.timer.diff()

    def create(self, input_created=False):
        """
            # # # # # # # # # # # #
            #     C R E A T E     #
            # # # # # # # # # # # #
        """
        if self.params["neuron_model"] == "IF_cond_exp":
            self.exc_pop = Population(
                self.params["n_exc"], IF_cond_exp, self.params["cell_params_exc"], label="exc_cells"
            )
            self.inh_pop = Population(
                self.params["n_inh"], IF_cond_exp, self.params["cell_params_inh"], label="inh_pop"
            )
        elif self.params["neuron_model"] == "IF_cond_alpha":
            self.exc_pop = Population(
                self.params["n_exc"], IF_cond_alpha, self.params["cell_params_exc"], label="exc_cells"
            )
            self.inh_pop = Population(
                self.params["n_inh"], IF_cond_alpha, self.params["cell_params_inh"], label="inh_pop"
            )
        elif self.params["neuron_model"] == "EIF_cond_exp_isfa_ista":
            self.exc_pop = Population(
                self.params["n_exc"], EIF_cond_exp_isfa_ista, self.params["cell_params_exc"], label="exc_cells"
            )
            self.inh_pop = Population(
                self.params["n_inh"], EIF_cond_exp_isfa_ista, self.params["cell_params_inh"], label="inh_pop"
            )
        else:
            print "\n\nUnknown neuron model:\n\t", self.params["neuron_model"]
        self.local_idx_exc = get_local_indices(self.exc_pop, offset=0)
        print "Debug, pc_id %d has local %d exc indices:" % (self.pc_id, len(self.local_idx_exc)), self.local_idx_exc

        cell_pos_exc = np.zeros((3, self.params["n_exc"]))
        cell_pos_exc[0, :] = self.tuning_prop_exc[:, 0]
        cell_pos_exc[1, :] = self.tuning_prop_exc[:, 1]
        self.exc_pop.positions = cell_pos_exc

        cell_pos_inh = np.zeros((3, self.params["n_inh"]))
        cell_pos_inh[0, :] = self.tuning_prop_inh[:, 0]
        cell_pos_inh[1, :] = self.tuning_prop_inh[:, 1]
        self.inh_pop.positions = cell_pos_inh

        if not input_created:
            self.spike_times_container = [[] for i in xrange(len(self.local_idx_exc))]

        self.exc_pop.initialize("v", self.v_init_dist)

        self.local_idx_inh = get_local_indices(self.inh_pop, offset=self.params["n_exc"])
        print "Debug, pc_id %d has local %d inh indices:" % (self.pc_id, len(self.local_idx_inh)), self.local_idx_inh
        self.inh_pop.initialize("v", self.v_init_dist)

        self.times["t_create"] = self.timer.diff()

    def connect(self):
        if self.params["n_exc"] > 5000:
            save_output = False
        else:
            save_output = True

        self.connect_input_to_exc()
        self.connect_populations("ee")
        self.connect_populations("ei")
        self.connect_populations("ie")
        self.connect_populations("ii")
        self.connect_noise()
        self.times["t_calc_conns"] = self.timer.diff()
        if self.comm != None:
            self.comm.Barrier()

    def create_input(self, load_files=False, save_output=False):

        if load_files:
            if self.pc_id == 0:
                print "Loading input spiketrains..."
            for i_, tgt in enumerate(self.local_idx_exc):
                try:
                    fn = self.params["input_st_fn_base"] + str(tgt) + ".npy"
                    spike_times = np.load(fn)
                except:  # this cell does not get any input
                    print "Missing file: ", fn
                    spike_times = []
                self.spike_times_container[i_] = spike_times
        else:
            if self.pc_id == 0:
                print "Computing input spiketrains..."
            nprnd.seed(self.params["input_spikes_seed"])
            dt = self.params["dt_rate"]  # [ms] time step for the non-homogenous Poisson process
            time = np.arange(0, self.params["t_sim"], dt)
            blank_idx = np.arange(
                1.0 / dt * self.params["t_before_blank"],
                1.0 / dt * (self.params["t_before_blank"] + self.params["t_blank"]),
            )
            before_stim_idx = np.arange(0, self.params["t_start"] * 1.0 / dt)
            blank_idx = np.concatenate((blank_idx, before_stim_idx))

            my_units = self.local_idx_exc
            n_cells = len(my_units)
            L_input = np.zeros((n_cells, time.shape[0]))

            # get the input signal
            print "Calculating input signal"
            for i_time, time_ in enumerate(time):
                L_input[:, i_time] = utils.get_input(
                    self.tuning_prop_exc[my_units, :], self.params, time_ / self.params["t_stimulus"]
                )
                L_input[:, i_time] *= self.params["f_max_stim"]
                if i_time % 500 == 0:
                    print "t:", time_
            #                    print 'L_input[:, %d].max()', L_input[:, i_time].max()
            # blanking
            for i_time in blank_idx:
                #                L_input[:, i_time] = 0.
                L_input[:, i_time] = np.random.permutation(L_input[:, i_time])

            # create the spike trains
            print "Creating input spiketrains for unit"
            for i_, unit in enumerate(my_units):
                print unit,
                rate_of_t = np.array(L_input[i_, :])
                # each cell will get its own spike train stored in the following file + cell gid
                n_steps = rate_of_t.size
                spike_times = []
                for i in xrange(n_steps):
                    r = nprnd.rand()
                    if r <= ((rate_of_t[i] / 1000.0) * dt):  # rate is given in Hz -> 1/1000.
                        spike_times.append(i * dt)
                self.spike_times_container[i_] = spike_times
                if save_output:
                    output_fn = self.params["input_rate_fn_base"] + str(unit) + ".npy"
                    np.save(output_fn, rate_of_t)
                    output_fn = self.params["input_st_fn_base"] + str(unit) + ".npy"
                    np.save(output_fn, np.array(spike_times))

        self.times["create_input"] = self.timer.diff()
        return self.spike_times_container

    def connect_input_to_exc(self):
        """
            # # # # # # # # # # # # # # # # # # # # # #
            #     C O N N E C T    I N P U T - E X C  #
            # # # # # # # # # # # # # # # # # # # # # #
        """
        if self.pc_id == 0:
            print "Connecting input spiketrains..."

        #        self.stimulus = Population(len(self.local_idx_exc), SpikeSourceArray)
        #            self.exc_pop = Population(n_exc, IF_cond_exp, self.params['cell_params_exc'], label='exc_cells')
        #                prj = Projection(src_pop, tgt_pop, connector, target=syn_type)
        #            self.projections[conn_type].append(prj)

        #        self.projections['stim'] = []
        #        self.stimuli = []
        #        self.pop_views = []
        #        conn = OneToOneConnector(weights=self.params['w_input_exc'])
        for i_, unit in enumerate(self.local_idx_exc):
            spike_times = self.spike_times_container[i_]
            #            ssa = create(SpikeSourceArray, {'spike_times': spike_times})
            ssa = Population(1, SpikeSourceArray, {"spike_times": spike_times})
            #            ssa.set({'spike_times' : spike_times})
            #            self.stimuli.append(ssa)

            #            if self.params['with_short_term_depression']:

            #                connect(ssa, self.exc_pop[unit], self.params['w_input_exc'], synapse_type='excitatory', synapse_dynamics=self.short_term_depression)
            #                selector = np.zeros(self.params['n_exc'], dtype=np.bool)
            #                selector[unit] = True
            #                print 'debug unit', unit, type(unit)
            #                w[i_] = 1.#self.params['w_input_exc']
            #                tgt = PopulationView(self.exc_pop, np.array([unit]))
            #                self.pop_views.append(tgt)
            #                prj = Projection(ssa, tgt, conn, target='excitatory', synapse_dynamics=self.short_term_depression)
            #                prj = Projection(self.stimuli[-1], self.pop_views[-1], conn, target='excitatory', synapse_dynamics=self.short_term_depression)
            #                self.projections['stim'].append(prj)
            #            else:
            connect(ssa, self.exc_pop[unit], self.params["w_input_exc"], synapse_type="excitatory")
        self.times["connect_input"] = self.timer.diff()

    def resolve_src_tgt(self, conn_type):
        """
        Deliver the correct source and target parameters based on conn_type
        """

        if conn_type == "ee":
            n_src, n_tgt = self.params["n_exc"], self.params["n_exc"]
            src_pop, tgt_pop = self.exc_pop, self.exc_pop
            tgt_cells = self.local_idx_exc
            tp_src = self.tuning_prop_exc
            tp_tgt = self.tuning_prop_exc
            syn_type = "excitatory"

        elif conn_type == "ei":
            n_src, n_tgt = self.params["n_exc"], self.params["n_inh"]
            src_pop, tgt_pop = self.exc_pop, self.inh_pop
            tgt_cells = self.local_idx_inh
            tp_src = self.tuning_prop_exc
            tp_tgt = self.tuning_prop_inh
            syn_type = "excitatory"

        elif conn_type == "ie":
            n_src, n_tgt = self.params["n_inh"], self.params["n_exc"]
            src_pop, tgt_pop = self.inh_pop, self.exc_pop
            tgt_cells = self.local_idx_exc
            tp_src = self.tuning_prop_inh
            tp_tgt = self.tuning_prop_exc
            syn_type = "inhibitory"

        elif conn_type == "ii":
            n_src, n_tgt = self.params["n_inh"], self.params["n_inh"]
            src_pop, tgt_pop = self.inh_pop, self.inh_pop
            tgt_cells = self.local_idx_inh
            tp_src = self.tuning_prop_inh
            tp_tgt = self.tuning_prop_inh
            syn_type = "inhibitory"

        return (n_src, n_tgt, src_pop, tgt_pop, tp_src, tp_tgt, tgt_cells, syn_type)

    def connect_anisotropic(self, conn_type):
        """
        conn_type = ['ee', 'ei', 'ie', 'ii']
        """
        if self.pc_id == 0:
            print "Connect anisotropic %s - %s" % (conn_type[0].capitalize(), conn_type[1].capitalize())

        (n_src, n_tgt, src_pop, tgt_pop, tp_src, tp_tgt, tgt_cells, syn_type) = self.resolve_src_tgt(conn_type)

        if self.debug_connectivity:
            conn_list_fn = self.params["conn_list_%s_fn_base" % conn_type] + "%d.dat" % (self.pc_id)

        n_src_cells_per_neuron = int(round(self.params["p_%s" % conn_type] * n_src))
        (delay_min, delay_max) = self.params["delay_range"]
        local_connlist = np.zeros((n_src_cells_per_neuron * len(tgt_cells), 4))
        for i_, tgt in enumerate(tgt_cells):
            if self.params["direction_based_conn"]:
                p, latency = CC.get_p_conn_vec_xpred(
                    tp_src,
                    tp_tgt[tgt, :],
                    self.params["w_sigma_x"],
                    self.params["w_sigma_v"],
                    self.params["connectivity_radius"],
                )
            else:
                p, latency = CC.get_p_conn_vec(
                    tp_src,
                    tp_tgt[tgt, :],
                    self.params["w_sigma_x"],
                    self.params["w_sigma_v"],
                    self.params["connectivity_radius"],
                    self.params["maximal_latency"],
                )
            if conn_type[0] == conn_type[1]:
                p[tgt], latency[tgt] = 0.0, 0.0
            # random delays? --> np.permutate(latency) or latency[sources] * self.params['delay_scale'] * np.rand

            sorted_indices = np.argsort(p)
            if conn_type[0] == "e":
                sources = sorted_indices[-n_src_cells_per_neuron:]
            else:  # source = inhibitory
                if conn_type[0] == conn_type[1]:
                    sources = sorted_indices[
                        1 : n_src_cells_per_neuron + 1
                    ]  # shift indices to avoid self-connection, because p_ii = .0
                else:
                    sources = sorted_indices[:n_src_cells_per_neuron]

            #            eta = 1e-9
            eta = 0
            w = (self.params["w_tgt_in_per_cell_%s" % conn_type] / (p[sources].sum() + eta)) * p[sources]
            #            print 'debug p', i_, tgt, p[sources]
            #            print 'debug sources', i_, tgt, sources
            #            print 'debug w', i_, tgt, w

            delays = np.minimum(
                np.maximum(latency[sources] * self.params["delay_scale"], delay_min), delay_max
            )  # map the delay into the valid range
            conn_list = np.array((sources, tgt * np.ones(n_src_cells_per_neuron), w, delays))
            local_connlist[i_ * n_src_cells_per_neuron : (i_ + 1) * n_src_cells_per_neuron, :] = conn_list.transpose()
            connector = FromListConnector(conn_list.transpose())
            if self.params["with_short_term_depression"]:
                prj = Projection(
                    src_pop, tgt_pop, connector, target=syn_type, synapse_dynamics=self.short_term_depression
                )
            else:
                prj = Projection(src_pop, tgt_pop, connector, target=syn_type)
            self.projections[conn_type].append(prj)

        if self.debug_connectivity:
            if self.pc_id == 0:
                print "DEBUG writing to file:", conn_list_fn
            np.savetxt(conn_list_fn, local_connlist, fmt="%d\t%d\t%.4e\t%.4e")

    def connect_ee_random(self):
        """
            # # # # # # # # # # # # # # # # # # # # # # # # # # # #
            #     C O N N E C T    E X C - E X C    R A N D O M   #
            # # # # # # # # # # # # # # # # # # # # # # # # # # # #
        """

        if self.pc_id == 0:
            print "Drawing random connections"
        sigma_x, sigma_v = self.params["w_sigma_x"], self.params["w_sigma_v"]
        (delay_min, delay_max) = self.params["delay_range"]
        if self.debug_connectivity:
            conn_list_fn = self.params["conn_list_ee_fn_base"] + "%d.dat" % (self.pc_id)
            conn_file = open(conn_list_fn, "w")
            output = ""
        for tgt in self.local_idx_exc:
            p = np.zeros(self.params["n_exc"], dtype="float32")
            latency = np.zeros(self.params["n_exc"], dtype="float32")
            for src in xrange(self.params["n_exc"]):
                if src != tgt:
                    p[src], latency[src] = CC.get_p_conn(
                        self.tuning_prop_exc[src, :],
                        self.tuning_prop_exc[tgt, :],
                        sigma_x,
                        sigma_v,
                        params["connectivity_radius"],
                    )  #                            print 'debug pc_id src tgt ', self.pc_id, src, tgt#, int(ID) < self.params['n_exc']
            sources = random.sample(xrange(self.params["n_exc"]), int(self.params["n_src_cells_per_neuron"]))
            idx = p[sources] > 0
            non_zero_idx = np.nonzero(idx)[0]
            p_ = p[sources][non_zero_idx]
            l_ = latency[sources][non_zero_idx] * self.params["delay_scale"]

            w = utils.linear_transformation(p_, self.params["w_min"], self.params["w_max"])
            for i in xrange(len(p_)):
                #                        w[i] = max(self.params['w_min'], min(w[i], self.params['w_max']))
                delay = min(max(l_[i], delay_min), delay_max)  # map the delay into the valid range
                connect(self.exc_pop[non_zero_idx[i]], self.exc_pop[tgt], w[i], delay=delay, synapse_type="excitatory")
                if self.debug_connectivity:
                    output += "%d\t%d\t%.2e\t%.2e\n" % (
                        non_zero_idx[i],
                        tgt,
                        w[i],
                        delay,
                    )  #                    output += '%d\t%d\t%.2e\t%.2e\t%.2e\n' % (sources[i], tgt, w[i], latency[sources[i]], p[sources[i]])

        if self.debug_connectivity:
            if self.pc_id == 0:
                print "DEBUG writing to file:", conn_list_fn
            conn_file.write(output)
            conn_file.close()

    def connect_isotropic(self, conn_type="ee"):
        """
        conn_type must be 'ee', 'ei', 'ie' or 'ii'
        Connect cells in a distant dependent manner:
            p_ij = exp(- d_ij / (2 * w_sigma_x**2))

        This will give a 'convergence constrained' connectivity, i.e. each cell will have the same sum of incoming weights
        ---> could be problematic for outlier cells
        """
        if self.pc_id == 0:
            print "Connect isotropic %s - %s" % (conn_type[0].capitalize(), conn_type[1].capitalize())

        (n_src, n_tgt, src_pop, tgt_pop, tp_src, tp_tgt, tgt_cells, syn_type) = self.resolve_src_tgt(conn_type)
        if conn_type == "ee":
            w_ = self.params["w_max"]
            w_tgt_in = params["w_tgt_in_per_cell_%s" % conn_type]
            n_max_conn = n_src * n_tgt - n_tgt

        elif conn_type == "ei":
            w_ = self.params["w_ei_mean"]
            w_tgt_in = params["w_tgt_in_per_cell_%s" % conn_type]
            n_max_conn = n_src * n_tgt

        elif conn_type == "ie":
            w_ = self.params["w_ie_mean"]
            w_tgt_in = params["w_tgt_in_per_cell_%s" % conn_type]
            n_max_conn = n_src * n_tgt

        elif conn_type == "ii":
            w_ = self.params["w_ii_mean"]
            w_tgt_in = params["w_tgt_in_per_cell_%s" % conn_type]
            n_max_conn = n_src * n_tgt - n_tgt

        if self.debug_connectivity:
            conn_list_fn = self.params["conn_list_%s_fn_base" % conn_type] + "%d.dat" % (self.pc_id)
        #            conn_file = open(conn_list_fn, 'w')
        #            output = ''
        #            output_dist = ''

        w_mean = w_tgt_in / (self.params["p_%s" % conn_type] * n_max_conn / n_tgt)
        w_sigma = self.params["w_sigma_distribution"] * w_mean

        w_dist = RandomDistribution(
            "normal", (w_mean, w_sigma), rng=self.rng_conn, constrain="redraw", boundaries=(0, w_mean * 10.0)
        )
        delay_dist = RandomDistribution(
            "normal",
            (self.params["standard_delay"], self.params["standard_delay_sigma"]),
            rng=self.rng_conn,
            constrain="redraw",
            boundaries=(self.params["delay_range"][0], self.params["delay_range"][1]),
        )

        p_max = utils.get_pmax(self.params["p_%s" % conn_type], self.params["w_sigma_isotropic"], conn_type)
        connector = DistanceDependentProbabilityConnector(
            "%f * exp(-d/(2*%f**2))" % (p_max, params["w_sigma_isotropic"]),
            allow_self_connections=False,
            weights=w_dist,
            delays=delay_dist,
            space=self.torus,
        )  # , n_connections=n_conn_ee)
        print "p_max for %s" % conn_type, p_max
        if self.params["with_short_term_depression"]:
            prj = Projection(src_pop, tgt_pop, connector, target=syn_type, synapse_dynamics=self.short_term_depression)
        else:
            prj = Projection(src_pop, tgt_pop, connector, target=syn_type)  # , synapse_dynamics=self.STD)
        self.projections[conn_type].append(prj)
        if self.debug_connectivity:
            #                if self.pc_id == 0:
            #                    print 'DEBUG writing to file:', conn_list_fn
            prj.saveConnections(self.params["conn_list_%s_fn_base" % conn_type] + ".dat", gather=True)

    #            prj.saveConnections(self.params['conn_list_%s_fn_base' % conn_type] + 'gid%d.dat' % tgt, gather=False)
    #                conn_file.close()

    #            w = np.zeros(n_src, dtype='float32')
    #            delays = np.zeros(n_src, dtype='float32')
    #            for src in xrange(n_src):
    #                if conn_type[0] == conn_type[1]:
    #                    if (src != tgt): # no self-connections / autapses
    #                        d_ij = utils.torus_distance2D(tp_src[src, 0], tp_tgt[tgt, 0], tp_src[src, 1], tp_tgt[tgt, 1])
    #                        p_ij = p_max * np.exp(-d_ij**2 / (2 * params['w_sigma_isotropic']**2))
    #                        if np.random.rand() <= p_ij:
    #                            w[src] = w_
    #                            delays[src] = d_ij * params['delay_scale']
    #                else:
    #                    d_ij = utils.torus_distance2D(tp_src[src, 0], tp_tgt[tgt, 0], tp_src[src, 1], tp_tgt[tgt, 1])
    #                    p_ij = p_max * np.exp(-d_ij**2 / (2 * params['w_sigma_isotropic']**2))
    #                    if np.random.rand() <= p_ij:
    #                        w[src] = w_
    #                        delays[src] = d_ij * params['delay_scale']
    #            w *= w_tgt_in / w.sum()
    #            srcs = w.nonzero()[0]
    #            weights = w[srcs]
    #            for src in srcs:
    #                if w[src] > self.params['w_thresh_connection']:
    #                delay = min(max(delays[src], self.params['delay_range'][0]), self.params['delay_range'][1])  # map the delay into the valid range
    #                connect(src_pop[int(src)], tgt_pop[int(tgt)], w[src], delay=delay, synapse_type=syn_type)
    #                output += '%d\t%d\t%.2e\t%.2e\n' % (src, tgt, w[src], delay)

    #        if self.debug_connectivity:
    #            if self.pc_id == 0:
    #                print 'DEBUG writing to file:', conn_list_fn
    #            conn_file.write(output)
    #            conn_file.close()

    def connect_random(self, conn_type):
        """
        There exist different possibilities to draw random connections:
        1) Calculate the weights as for the anisotropic case and sample sources randomly
        2) Load a file which stores some random connectivity --> # connector = FromFileConnector(self.params['conn_list_.... ']
        3) Create a random distribution with similar parameters as the non-random connectivition distribution

        connector_ee = FastFixedProbabilityConnector(self.params['p_ee'], weights=w_ee_dist, delays=self.delay_dist)
        prj_ee = Projection(self.exc_pop, self.exc_pop, connector_ee, target='excitatory')

        conn_list_fn = self.params['random_weight_list_fn'] + str(sim_cnt) + '.dat'
        print "Connecting exc - exc from file", conn_list_fn
        connector_ee = FromFileConnector(conn_list_fn)
        prj_ee = Projection(self.exc_pop, self.exc_pop, connector_ee, target='excitatory')
        """
        if self.pc_id == 0:
            print "Connect random connections %s - %s" % (conn_type[0].capitalize(), conn_type[1].capitalize())
        (n_src, n_tgt, src_pop, tgt_pop, tp_src, tp_tgt, tgt_cells, syn_type) = self.resolve_src_tgt(conn_type)
        w_mean = self.params["w_tgt_in_per_cell_%s" % conn_type] / (n_src * self.params["p_%s" % conn_type])
        w_sigma = self.params["w_sigma_distribution"] * w_sigma

        weight_distr = RandomDistribution(
            "normal", (w_mean, w_sigma), rng=self.rng_conn, constrain="redraw", boundaries=(0, w_mean * 10.0)
        )

        delay_dist = RandomDistribution(
            "normal",
            (self.params["standard_delay"], self.params["standard_delay_sigma"]),
            rng=self.rng_conn,
            constrain="redraw",
            boundaries=(self.params["delay_range"][0], self.params["delay_range"][1]),
        )

        connector = FastFixedProbabilityConnector(
            self.params["p_%s" % conn_type], weights=weight_distr, delays=delay_dist
        )
        if self.params["with_short_term_depression"]:
            prj = Projection(src_pop, tgt_pop, connector, target=syn_type, synapse_dynamics=self.short_term_depression)
        else:
            prj = Projection(src_pop, tgt_pop, connector, target=syn_type)

        conn_list_fn = self.params["conn_list_%s_fn_base" % conn_type] + "%d.dat" % (self.pc_id)
        print "Saving random %s connections to %s" % (conn_type, conn_list_fn)
        prj.saveConnections(conn_list_fn, gather=False)

    def connect_populations(self, conn_type):
        """
            # # # # # # # # # # # #
            #     C O N N E C T   #
            # # # # # # # # # # # #
            Calls the right according to the flag set in simultation_parameters.py
        """
        if self.params["connectivity_%s" % conn_type] == "anisotropic":
            self.connect_anisotropic(conn_type)
        elif self.params["connectivity_%s" % conn_type] == "isotropic":
            self.connect_isotropic(conn_type)
        elif self.params["connectivity_%s" % conn_type] == "random":
            self.connect_random(conn_type)
        else:  # populations do not get connected
            pass

    def connect_noise(self):
        """
            # # # # # # # # # # # # # # # #
            #     N O I S E   I N P U T   #
            # # # # # # # # # # # # # # # #
        """
        if self.pc_id == 0:
            print "Connecting noise - exc ... "
        noise_pop_exc = []
        noise_pop_inh = []
        for tgt in self.local_idx_exc:
            # new
            if self.params["simulator"] == "nest":  # for nest one can use the optimized Poisson generator
                noise_exc = create(native_cell_type("poisson_generator"), {"rate": self.params["f_exc_noise"]})
                noise_inh = create(native_cell_type("poisson_generator"), {"rate": self.params["f_inh_noise"]})
            else:
                noise_exc = create(SpikeSourcePoisson, {"rate": self.params["f_exc_noise"]})
                noise_inh = create(SpikeSourcePoisson, {"rate": self.params["f_inh_noise"]})
            connect(
                noise_exc, self.exc_pop[tgt], weight=self.params["w_exc_noise"], synapse_type="excitatory", delay=1.0
            )
            connect(
                noise_inh, self.exc_pop[tgt], weight=self.params["w_inh_noise"], synapse_type="inhibitory", delay=1.0
            )

        if self.pc_id == 0:
            print "Connecting noise - inh ... "
        for tgt in self.local_idx_inh:
            if self.params["simulator"] == "nest":  # for nest one can use the optimized Poisson generator
                noise_exc = create(native_cell_type("poisson_generator"), {"rate": self.params["f_exc_noise"]})
                noise_inh = create(native_cell_type("poisson_generator"), {"rate": self.params["f_inh_noise"]})
            else:
                noise_exc = create(SpikeSourcePoisson, {"rate": self.params["f_exc_noise"]})
                noise_inh = create(SpikeSourcePoisson, {"rate": self.params["f_inh_noise"]})
            connect(
                noise_exc, self.inh_pop[tgt], weight=self.params["w_exc_noise"], synapse_type="excitatory", delay=1.0
            )
            connect(
                noise_inh, self.inh_pop[tgt], weight=self.params["w_inh_noise"], synapse_type="inhibitory", delay=1.0
            )
        self.times["connect_noise"] = self.timer.diff()

    def run_sim(self, sim_cnt, record_v=True):
        # # # # # # # # # # # # # # # # # # # #
        #     P R I N T    W E I G H T S      #
        # # # # # # # # # # # # # # # # # # # #
        #    print 'Printing weights to :\n  %s\n  %s\n  %s' % (self.params['conn_list_ei_fn'], self.params['conn_list_ie_fn'], self.params['conn_list_ii_fn'])
        #    exc_inh_prj.saveConnections(self.params['conn_list_ei_fn'])
        #    inh_exc_prj.saveConnections(self.params['conn_list_ie_fn'])
        #    inh_inh_prj.saveConnections(self.params['conn_list_ii_fn'])
        #    self.times['t_save_conns'] = self.timer.diff()

        # # # # # # # # # # # #
        #     R E C O R D     #
        # # # # # # # # # # # #
        #    print "Recording spikes to file: %s" % (self.params['exc_spiketimes_fn_merged'] + '%d.ras' % sim_cnt)
        #    for cell in xrange(self.params['n_exc']):
        #        record(self.exc_pop[cell], self.params['exc_spiketimes_fn_merged'] + '%d.ras' % sim_cnt)
        record_exc = True
        if os.path.exists(self.params["gids_to_record_fn"]):
            gids_to_record = np.loadtxt(self.params["gids_to_record_fn"], dtype="int")[
                : self.params["n_gids_to_record"]
            ]
            record_exc = True
            n_rnd_cells_to_record = 2
        else:
            n_cells_to_record = 5  # self.params['n_exc'] * 0.02
            gids_to_record = np.random.randint(0, self.params["n_exc"], n_cells_to_record)

        if record_v:
            self.exc_pop_view = PopulationView(self.exc_pop, gids_to_record, label="good_exc_neurons")
            self.exc_pop_view.record_v()
            self.inh_pop_view = PopulationView(
                self.inh_pop,
                np.random.randint(0, self.params["n_inh"], self.params["n_gids_to_record"]),
                label="random_inh_neurons",
            )
            self.inh_pop_view.record_v()

        self.inh_pop.record()
        self.exc_pop.record()
        self.times["t_record"] = self.timer.diff()

        # # # # # # # # # # # # # #
        #     R U N N N I N G     #
        # # # # # # # # # # # # # #
        if self.pc_id == 0:
            print "Running simulation ... "
        run(self.params["t_sim"])
        self.times["t_sim"] = self.timer.diff()

    def print_results(self, print_v=True):
        """
            # # # # # # # # # # # # # # # # #
            #   P R I N T    R E S U L T S  #
            # # # # # # # # # # # # # # # # #
        """
        if print_v:
            if self.pc_id == 0:
                print "print_v to file: %s.v" % (self.params["exc_volt_fn_base"])
            self.exc_pop_view.print_v("%s.v" % (self.params["exc_volt_fn_base"]), compatible_output=False)
            if self.pc_id == 0:
                print "Printing inhibitory membrane potentials"
            self.inh_pop_view.print_v("%s.v" % (self.params["inh_volt_fn_base"]), compatible_output=False)

        if self.pc_id == 0:
            print "Printing excitatory spikes"
        self.exc_pop.printSpikes(self.params["exc_spiketimes_fn_merged"] + ".ras")
        if self.pc_id == 0:
            print "Printing inhibitory spikes"
        self.inh_pop.printSpikes(self.params["inh_spiketimes_fn_merged"] + ".ras")

        self.times["t_print"] = self.timer.diff()
        if self.pc_id == 0:
            print "calling pyNN.end() ...."
        end()
        self.times["t_end"] = self.timer.diff()

        if self.pc_id == 0:
            self.times["t_all"] = 0.0
            for k in self.times.keys():
                self.times["t_all"] += self.times[k]

            self.n_cells = {}
            self.n_cells["n_exc"] = self.params["n_exc"]
            self.n_cells["n_inh"] = self.params["n_inh"]
            self.n_cells["n_cells"] = self.params["n_cells"]
            self.n_cells["n_proc"] = self.n_proc
            output = {"times": self.times, "n_cells_proc": self.n_cells}
            print "Proc %d Simulation time: %d sec or %.1f min for %d cells (%d exc %d inh)" % (
                self.pc_id,
                self.times["t_sim"],
                (self.times["t_sim"]) / 60.0,
                self.params["n_cells"],
                self.params["n_exc"],
                self.params["n_inh"],
            )
            print "Proc %d Full pyNN run time: %d sec or %.1f min for %d cells (%d exc %d inh)" % (
                self.pc_id,
                self.times["t_all"],
                (self.times["t_all"]) / 60.0,
                self.params["n_cells"],
                self.params["n_exc"],
                self.params["n_inh"],
            )
            fn = utils.convert_to_url(params["folder_name"] + "times_dict_np%d.py" % self.n_proc)
            output = ntp.ParameterSet(output)
            output.save(fn)
pynn.Projection(input_interface, reservoir,
                pynn.AllToAllConnector(weights=0.5, delays=1))

pynn.Projection(reservoir, readout_neurons,
                pynn.AllToAllConnector(weights=0.5, delays=1))

readout_neurons.record()
readout_neurons.record_v()

# run the network and measure the time it takes
timer.start()

pynn.run(simulation_time)

simCPUTime = timer.diff()

spikes = readout_neurons.getSpikes()

pynn.end()

# Plot
import pylab

spike_times = [spike[1] for spike in spikes]
spike_ids = [spike[0] for spike in spikes]

pylab.plot(spike_times, spike_ids, ".")
pylab.xlabel('Time (ms)')
pylab.ylabel('Neuron ID')
pylab.title('Spike Plot')
Example #4
0
def test(cases=[1]):

    sp = Space(periodic_boundaries=((0, 1), (0, 1), None), axes='xy')
    safe = False
    callback = progress_bar.set_level
    autapse = False
    parallel_safe = True
    render = True
    to_file = True

    for case in cases:
        #w = RandomDistribution('uniform', (0,1))
        w = "0.2 + d/0.2"
        #w = 0.1
        #w = lambda dist : 0.1 + numpy.random.rand(len(dist[0]))*sqrt(dist[0]**2 + dist[1]**2)

        #delay = RandomDistribution('uniform', (0.1,5.))
        #delay = "0.1 + d/0.2"
        delay = 0.1
        #delay = lambda distances : 0.1 + numpy.random.rand(len(distances))*distances

        d_expression = "exp(-d**2/(2*0.1**2))"
        #d_expression = "(d[0] < 0.05) & (d[1] < 0.05)"
        #d_expression = "(d[0]/(0.05**2) + d[1]/(0.1**2)) < 100*numpy.random.rand()"

        timer = Timer()
        np = num_processes()
        timer.start()

        synapse = StaticSynapse(weight=w, delay=delay)
        rng = NumpyRNG(23434, parallel_safe=parallel_safe)

        if case is 1:
            conn = DistanceDependentProbabilityConnector(
                d_expression,
                safe=safe,
                callback=callback,
                allow_self_connections=autapse,
                rng=rng)
            fig_name = "DistanceDependent_%s_np_%d.png" % (simulator_name, np)
        elif case is 2:
            conn = FixedProbabilityConnector(0.02,
                                             safe=safe,
                                             callback=callback,
                                             allow_self_connections=autapse,
                                             rng=rng)
            fig_name = "FixedProbability_%s_np_%d.png" % (simulator_name, np)
        elif case is 3:
            conn = AllToAllConnector(delays=delay,
                                     safe=safe,
                                     callback=callback,
                                     allow_self_connections=autapse)
            fig_name = "AllToAll_%s_np_%d.png" % (simulator_name, np)
        elif case is 4:
            conn = FixedNumberPostConnector(50,
                                            safe=safe,
                                            callback=callback,
                                            allow_self_connections=autapse,
                                            rng=rng)
            fig_name = "FixedNumberPost_%s_np_%d.png" % (simulator_name, np)
        elif case is 5:
            conn = FixedNumberPreConnector(50,
                                           safe=safe,
                                           callback=callback,
                                           allow_self_connections=autapse,
                                           rng=rng)
            fig_name = "FixedNumberPre_%s_np_%d.png" % (simulator_name, np)
        elif case is 6:
            conn = OneToOneConnector(safe=safe, callback=callback)
            fig_name = "OneToOne_%s_np_%d.png" % (simulator_name, np)
        elif case is 7:
            conn = FromFileConnector(files.NumpyBinaryFile(
                'Results/connections.dat', mode='r'),
                                     safe=safe,
                                     callback=callback,
                                     distributed=True)
            fig_name = "FromFile_%s_np_%d.png" % (simulator_name, np)
        elif case is 8:
            conn = SmallWorldConnector(degree=0.1,
                                       rewiring=0.,
                                       safe=safe,
                                       callback=callback,
                                       allow_self_connections=autapse)
            fig_name = "SmallWorld_%s_np_%d.png" % (simulator_name, np)

        print "Generating data for %s" % fig_name

        prj = Projection(x, x, conn, synapse, space=sp)

        mytime = timer.diff()
        print "Time to connect the cell population:", mytime, 's'
        print "Nb synapses built", prj.size()

        if to_file:
            if not (os.path.isdir('Results')):
                os.mkdir('Results')
            print "Saving Connections...."
            prj.save('all',
                     files.NumpyBinaryFile('Results/connections.dat',
                                           mode='w'),
                     gather=True)

        mytime = timer.diff()
        print "Time to save the projection:", mytime, 's'

        if render and to_file:
            print "Saving Positions...."
            x.save_positions('Results/positions.dat')
        end()

        if node_id == 0 and render and to_file:
            figure()
            print "Generating and saving %s" % fig_name
            positions = numpy.loadtxt('Results/positions.dat')

            positions[:, 0] -= positions[:, 0].min()
            connections = files.NumpyBinaryFile('Results/connections.dat',
                                                mode='r').read()
            print positions.shape, connections.shape
            connections[:, 0] -= connections[:, 0].min()
            connections[:, 1] -= connections[:, 1].min()
            idx_pre = connections[:, 0].astype(int)
            idx_post = connections[:, 1].astype(int)
            d = distances(positions[idx_pre, 1:3], positions[idx_post, 1:3], 1)
            subplot(231)
            title('Cells positions')
            plot(positions[:, 1], positions[:, 2], '.')
            subplot(232)
            title('Weights distribution')
            hist(connections[:, 2], 50)
            subplot(233)
            title('Delay distribution')
            hist(connections[:, 3], 50)
            subplot(234)
            numpy.random.seed(74562)
            ids = numpy.random.permutation(positions[:, 0])[0:6]
            colors = ['k', 'r', 'b', 'g', 'c', 'y']
            for count, cell in enumerate(ids):
                draw_rf(cell, positions, connections, colors[count])
            subplot(235)
            plot(d, connections[:, 2], '.')

            subplot(236)
            plot(d, connections[:, 3], '.')
            savefig("Results/" + fig_name)
            #os.remove('Results/connections.dat')
            #os.remove('Results/positions.dat')
            show()
simulator_name = 'nest'
from pyNN.nest import *
#exec("from pyNN.%s import *" % simulator_name)
try:
    from mpi4py import MPI
    USE_MPI = True
    comm = MPI.COMM_WORLD
    node_id, n_proc = comm.rank, comm.size
    print "USE_MPI:", USE_MPI, 'pc_id, n_proc:', node_id, n_proc
except:
    USE_MPI = False
    node_id, n_proc, comm = 0, 1, None
    print "MPI not used"

from pyNN.random import NumpyRNG, RandomDistribution
times['t_import'] = timer.diff()

# === DEFINE PARAMETERS
benchmark = "COBA"
rngseed = 98765
parallel_safe = True
np = num_processes()
folder_name = 'Results_PyNN_FixedNumberPost_np%d/' % (np)
gather = False  # gather spikes and membrane potentials on one process
times_fn = 'pynn_times_FixedNumberPost_gather%d_np%d.dat' % (gather, np)

n_cells = 200 * np
r_ei = 4.0  # number of excitatory cells:number of inhibitory cells
n_exc = int(round((n_cells * r_ei / (1 + r_ei))))  # number of excitatory cells
n_inh = n_cells - n_exc  # number of inhibitory cells
n_cells_to_record = np
def test(cases=[1]):

    sp = Space(periodic_boundaries=((0, 1), (0, 1), None), axes="xy")
    safe = False
    callback = progress_bar.set_level
    autapse = False
    parallel_safe = True
    render = True
    to_file = True

    for case in cases:
        # w = RandomDistribution('uniform', (0,1))
        w = "0.2 + d/0.2"
        # w = 0.1
        # w = lambda dist : 0.1 + numpy.random.rand(len(dist[0]))*sqrt(dist[0]**2 + dist[1]**2)

        # delay = RandomDistribution('uniform', (0.1,5.))
        # delay = "0.1 + d/0.2"
        delay = 0.1
        # delay = lambda distances : 0.1 + numpy.random.rand(len(distances))*distances

        d_expression = "exp(-d**2/(2*0.1**2))"
        # d_expression = "(d[0] < 0.05) & (d[1] < 0.05)"
        # d_expression = "(d[0]/(0.05**2) + d[1]/(0.1**2)) < 100*numpy.random.rand()"

        timer = Timer()
        np = num_processes()
        timer.start()

        synapse = StaticSynapse(weight=w, delay=delay)
        rng = NumpyRNG(23434, parallel_safe=parallel_safe)

        if case is 1:
            conn = DistanceDependentProbabilityConnector(
                d_expression, safe=safe, callback=callback, allow_self_connections=autapse, rng=rng
            )
            fig_name = "DistanceDependent_%s_np_%d.png" % (simulator_name, np)
        elif case is 2:
            conn = FixedProbabilityConnector(
                0.02, safe=safe, callback=callback, allow_self_connections=autapse, rng=rng
            )
            fig_name = "FixedProbability_%s_np_%d.png" % (simulator_name, np)
        elif case is 3:
            conn = AllToAllConnector(delays=delay, safe=safe, callback=callback, allow_self_connections=autapse)
            fig_name = "AllToAll_%s_np_%d.png" % (simulator_name, np)
        elif case is 4:
            conn = FixedNumberPostConnector(50, safe=safe, callback=callback, allow_self_connections=autapse, rng=rng)
            fig_name = "FixedNumberPost_%s_np_%d.png" % (simulator_name, np)
        elif case is 5:
            conn = FixedNumberPreConnector(50, safe=safe, callback=callback, allow_self_connections=autapse, rng=rng)
            fig_name = "FixedNumberPre_%s_np_%d.png" % (simulator_name, np)
        elif case is 6:
            conn = OneToOneConnector(safe=safe, callback=callback)
            fig_name = "OneToOne_%s_np_%d.png" % (simulator_name, np)
        elif case is 7:
            conn = FromFileConnector(
                files.NumpyBinaryFile("Results/connections.dat", mode="r"),
                safe=safe,
                callback=callback,
                distributed=True,
            )
            fig_name = "FromFile_%s_np_%d.png" % (simulator_name, np)
        elif case is 8:
            conn = SmallWorldConnector(
                degree=0.1, rewiring=0.0, safe=safe, callback=callback, allow_self_connections=autapse
            )
            fig_name = "SmallWorld_%s_np_%d.png" % (simulator_name, np)

        print "Generating data for %s" % fig_name

        prj = Projection(x, x, conn, synapse, space=sp)

        mytime = timer.diff()
        print "Time to connect the cell population:", mytime, "s"
        print "Nb synapses built", prj.size()

        if to_file:
            if not (os.path.isdir("Results")):
                os.mkdir("Results")
            print "Saving Connections...."
            prj.save("all", files.NumpyBinaryFile("Results/connections.dat", mode="w"), gather=True)

        mytime = timer.diff()
        print "Time to save the projection:", mytime, "s"

        if render and to_file:
            print "Saving Positions...."
            x.save_positions("Results/positions.dat")
        end()

        if node_id == 0 and render and to_file:
            figure()
            print "Generating and saving %s" % fig_name
            positions = numpy.loadtxt("Results/positions.dat")

            positions[:, 0] -= positions[:, 0].min()
            connections = files.NumpyBinaryFile("Results/connections.dat", mode="r").read()
            print positions.shape, connections.shape
            connections[:, 0] -= connections[:, 0].min()
            connections[:, 1] -= connections[:, 1].min()
            idx_pre = connections[:, 0].astype(int)
            idx_post = connections[:, 1].astype(int)
            d = distances(positions[idx_pre, 1:3], positions[idx_post, 1:3], 1)
            subplot(231)
            title("Cells positions")
            plot(positions[:, 1], positions[:, 2], ".")
            subplot(232)
            title("Weights distribution")
            hist(connections[:, 2], 50)
            subplot(233)
            title("Delay distribution")
            hist(connections[:, 3], 50)
            subplot(234)
            numpy.random.seed(74562)
            ids = numpy.random.permutation(positions[:, 0])[0:6]
            colors = ["k", "r", "b", "g", "c", "y"]
            for count, cell in enumerate(ids):
                draw_rf(cell, positions, connections, colors[count])
            subplot(235)
            plot(d, connections[:, 2], ".")

            subplot(236)
            plot(d, connections[:, 3], ".")
            savefig("Results/" + fig_name)
            # os.remove('Results/connections.dat')
            # os.remove('Results/positions.dat')
            show()
Example #7
0
def run_model(sim, **options):
    """
    Run a simulation using the parameters read from the file "spike_train_statistics.json"

    :param sim: the PyNN backend module to be used.
    :param options: should contain a keyword "simulator" which is the name of the PyNN backend module used.
    :return: a tuple (`data`, `times`) where `data` is a Neo Block containing the recorded spikes
             and `times` is a dict containing the time taken for different phases of the simulation.
    """

    import json
    from pyNN.utility import Timer

    print("Running")

    timer = Timer()

    g = open("spike_train_statistics.json", 'r')
    d = json.load(g)

    N = d['param']['N']
    max_rate = d['param']['max_rate']
    tstop = d['param']['tstop']
    d['SpikeSourcePoisson'] = {
        "duration": tstop
    }

    if options['simulator'] == "hardware.brainscales":
        hardware_preset = d['setup'].pop('hardware_preset', None)
        if hardware_preset:
            d['setup']['hardware'] = sim.hardwareSetup[hardware_preset]
        d['SpikeSourcePoisson']['random'] = True
        place = mapper.place()

    timer.start()
    sim.setup(**d['setup'])

    spike_sources = sim.Population(N, sim.SpikeSourcePoisson, d['SpikeSourcePoisson'])
    delta_rate = max_rate/N
    rates = numpy.linspace(delta_rate, max_rate, N)
    print("Firing rates: %s" % rates)
    if PYNN07:
        spike_sources.tset("rate", rates)
    else:
        spike_sources.set(rate=rates)

    if options['simulator'] == "hardware.brainscales":
        for i, spike_source in enumerate(spike_sources):
            place.to(spike_source, hicann=i//8, neuron=i%64)
        place.commit()

    if PYNN07:
        spike_sources.record()
    else:
        spike_sources.record('spikes')

    setup_time = timer.diff()
    sim.run(tstop)
    run_time = timer.diff()

    if PYNN07:
        spike_array = spike_sources.getSpikes()
        data = spike_array_to_neo(spike_array, spike_sources, tstop)
    else:
        data = spike_sources.get_data()

    sim.end()

    closing_time = timer.diff()
    times = {'setup_time': setup_time, 'run_time': run_time, 'closing_time': closing_time}

    return data, times
## Start
## The asynchronous irregular network dynamics of the model published in
## Vogels and Abbott (2005) without inhibitory plasticity.
## Original simulation time: 1 min (60000 ms)

excPopulation.record('spikes')
pattern1.record('spikes')
pattern1_stim.record('spikes')
pattern2.record('spikes')
pattern2_stim.record('spikes')
patternIntersection.record('spikes')
controlPopulation.record('spikes')
inhibPopulation.record('spikes')

buildCPUTime = timer.diff()

print("\n\nTime to build the network: %s seconds" % buildCPUTime)

print("\n--- Pre-simulation ---")
print("\nPre-simulation time: %s milliseconds" % timePreSim)

run(timePreSim)

simCPUTime_pre = timer.diff()

print("\nTime to perform the pre-simulation: %d seconds (%0.2f minutes)" % (simCPUTime_pre, simCPUTime_pre / 60))

excSpikes = excPopulation.get_data('spikes', clear="true")
pattern1Spikes = pattern1.get_data('spikes')
pattern1_stimSpikes = pattern1_stim.get_data('spikes', clear="true")
## 	The asynchronous irregular network dynamics of the model published in
## 	Vogels and Abbott (2005) without inhibitory plasticity.
## 	Original simulation time: 1 min (60000 ms)


excPopulation.record('spikes')
pattern1.record('spikes')
pattern1_stim.record('spikes')
pattern2.record('spikes')
pattern2_stim.record('spikes')
patternIntersection.record('spikes')
controlPopulation.record('spikes')
inhibPopulation.record('spikes')


buildCPUTime = timer.diff()

print("\n\nTime to build the network: %s seconds" %buildCPUTime)

print("\n--- Pre-simulation ---")
print("\nPre-simulation time: %s milliseconds" %timePreSim)


run(timePreSim)


simCPUTime_pre = timer.diff()

print("\nTime to perform the pre-simulation: %d seconds (%0.2f minutes)" %(simCPUTime_pre, simCPUTime_pre/60))

excSpikes			= 	excPopulation.get_data(		'spikes', clear="true")
## 	The asynchronous irregular network dynamics of the model published in
## 	Vogels and Abbott (2005) without inhibitory plasticity.
## 	Original simulation time: 1 min (60000 ms)


excPopulation.record('spikes')
pattern1.record('spikes')
pattern1_stim.record('spikes')
pattern2.record('spikes')
pattern2_stim.record('spikes')
patternIntersection.record('spikes')
controlPopulation.record('spikes')
inhibPopulation.record('spikes')


buildCPUTime = timer.diff()

print("\n\nTime to build the network: %s seconds" %buildCPUTime)

print("\n--- Pre-simulation ---")
print("\nPre-simulation time: %s milliseconds" %timePreSim)


run(timePreSim)


simCPUTime_pre = timer.diff()

print("\nTime to perform the pre-simulation: %d seconds (%0.2f minutes)" %(simCPUTime_pre, simCPUTime_pre/60))

excSpikes			= 	excPopulation.get_data(		'spikes', clear="true")
time = np.arange(0, params['t_stimulus'], params['dt_rate'])

#print 'Prepare spike trains'
#L_input = np.zeros((params['n_exc'], time.shape[0]))
#for i_time, time_ in enumerate(time):
#    if (i_time % 100 == 0):
#        print "t:", time_
#    L_input[:, i_time] = utils.get_input(tuning_prop, params, time_/params['t_sim'])
#    L_input[:, i_time] *= params['f_max_stim']

# ===============
#    S E T U P 
# ===============
(delay_min, delay_max) = params['delay_range']
setup(timestep=0.1, min_delay=delay_min, max_delay=delay_max, rng_seeds_seed=sim_cnt)
times['t_setup'] = timer.diff()
exc_pop = Population(params['n_exc'], IF_cond_exp, params['cell_params_exc'], label='exc_cells')
times['t_create'] = timer.diff()

rng_v = NumpyRNG(seed = sim_cnt*3147 + params['seed'])
v_init_dist = RandomDistribution('normal',
        (params['v_init'], params['v_init_sigma']),
        rng=rng_v,
        constrain='redraw',
        boundaries=(-80, -60))
exc_pop.initialize('v', v_init_dist)

# ==================================
#    C O N N E C T    I N P U T 
# ==================================
for tgt in xrange(params['n_exc']):
simulator_name = 'nest'
from pyNN.nest import *
#exec("from pyNN.%s import *" % simulator_name)
try:
    from mpi4py import MPI
    USE_MPI = True
    comm = MPI.COMM_WORLD
    node_id, n_proc = comm.rank, comm.size
    print "USE_MPI:", USE_MPI, 'pc_id, n_proc:', node_id, n_proc
except:
    USE_MPI = False
    node_id, n_proc, comm = 0, 1, None
    print "MPI not used"

from pyNN.random import NumpyRNG, RandomDistribution
times['t_import'] = timer.diff()

# === DEFINE PARAMETERS 
benchmark = "COBA"
rngseed  = 98765
parallel_safe = True
np = num_processes()
folder_name = 'Results_PyNN_FixedNumberPost_np%d/' % (np)
gather = False # gather spikes and membrane potentials on one process
times_fn = 'pynn_times_FixedNumberPost_gather%d_np%d.dat' % (gather, np)

n_cells  = 200 * np 
r_ei     = 4.0   # number of excitatory cells:number of inhibitory cells
n_exc = int(round((n_cells*r_ei/(1+r_ei)))) # number of excitatory cells   
n_inh = n_cells - n_exc                     # number of inhibitory cells
n_cells_to_record = np
Example #13
0
        # Write AMPA weights
        ampa_weight_writer("%s/connection_%u_e_e_ampa.npy" % (folder, i))

        # Write NMDA weights to correct folder
        if mode == Mode.train_asymmetrical:
            nmda_weight_writer("%s/connection_%u_e_e_nmda_asymmetrical.npy" %
                               (folder, i))
        else:
            nmda_weight_writer("%s/connection_%u_e_e_nmda_symmetrical.npy" %
                               (folder, i))

    # Loop through the HCU results and save data to pickle format
    for i, (hcu_e_data_writer, ) in enumerate(hcu_results):
        hcu_e_data_writer("%s/hcu_%u_e_data.pkl" % (folder, i))

    logger.info("Download time %gs", timer.diff())

    # Once data is read, end simulation
    end_simulation()
else:
    # Testing parameters
    testing_simtime = 6000.0  # simulation time [ms]

    ampa_nmda_ratio = 4.795918367
    tau_ca2 = 300.0

    if mode == Mode.test_symmetrical:
        i_alpha = 0.7
        gain_per_hcu = 1.3
    else:
        i_alpha = 0.15
Example #14
0
class NetworkModel(object):

    def __init__(self, params, comm):

        self.params = params
        self.debug_connectivity = True
        self.comm = comm
        if self.comm != None:
            self.pc_id, self.n_proc = self.comm.rank, self.comm.size
            print "USE_MPI: yes", '\tpc_id, n_proc:', self.pc_id, self.n_proc
        else:
            self.pc_id, self.n_proc = 0, 1
            print "MPI not used"

        np.random.seed(params['np_random_seed'] + self.pc_id)

        if self.params['with_short_term_depression']:
            self.short_term_depression = SynapseDynamics(fast=TsodyksMarkramMechanism(U=0.95, tau_rec=10.0, tau_facil=0.0))

    def import_pynn(self):
        """
        This function needs only be called when this class is used in another script as imported module
        """
        import pyNN

        exec("from pyNN.%s import *" % self.params['simulator'])
        print 'import pyNN\npyNN.version: ', pyNN.__version__



    def setup(self, load_tuning_prop=False, times={}):

        self.projections = {}
        self.projections['ee'] = []
        self.projections['ei'] = []
        self.projections['ie'] = []
        self.projections['ii'] = []
        if not load_tuning_prop:
            self.tuning_prop_exc = utils.set_tuning_prop(self.params, mode='hexgrid', cell_type='exc')        # set the tuning properties of exc cells: space (x, y) and velocity (u, v)
            self.tuning_prop_inh = utils.set_tuning_prop(self.params, mode='hexgrid', cell_type='inh')        # set the tuning properties of exc cells: space (x, y) and velocity (u, v)
        else:
            self.tuning_prop_exc = np.loadtxt(self.params['tuning_prop_means_fn'])
            self.tuning_prop_inh = np.loadtxt(self.params['tuning_prop_inh_fn'])

        indices, distances = utils.sort_gids_by_distance_to_stimulus(self.tuning_prop_exc, self.params) # cells in indices should have the highest response to the stimulus
        if self.pc_id == 0:
            print "Saving tuning_prop to file:", self.params['tuning_prop_means_fn']
            np.savetxt(self.params['tuning_prop_means_fn'], self.tuning_prop_exc)
            print "Saving tuning_prop to file:", self.params['tuning_prop_inh_fn']
            np.savetxt(self.params['tuning_prop_inh_fn'], self.tuning_prop_inh)
            print 'Saving gids to record to: ', self.params['gids_to_record_fn']
            np.savetxt(self.params['gids_to_record_fn'], indices[:self.params['n_gids_to_record']], fmt='%d')

#        np.savetxt(params['gids_to_record_fn'], indices[:params['n_gids_to_record']], fmt='%d')

        if self.comm != None:
            self.comm.Barrier()
        from pyNN.utility import Timer
        self.timer = Timer()
        self.timer.start()
        self.times = times
        self.times['t_all'] = 0
        # # # # # # # # # # # #
        #     S E T U P       #
        # # # # # # # # # # # #
        (delay_min, delay_max) = self.params['delay_range']
        setup(timestep=0.1, min_delay=delay_min, max_delay=delay_max, rng_seeds_seed=self.params['seed'])
        rng_v = NumpyRNG(seed = sim_cnt*3147 + self.params['seed'], parallel_safe=True) #if True, slower but does not depend on number of nodes
        self.rng_conn = NumpyRNG(seed = self.params['seed'], parallel_safe=True) #if True, slower but does not depend on number of nodes

        # # # # # # # # # # # # # # # # # # # # # # # # #
        #     R A N D O M    D I S T R I B U T I O N S  #
        # # # # # # # # # # # # # # # # # # # # # # # # #
        self.v_init_dist = RandomDistribution('normal',
                (self.params['v_init'], self.params['v_init_sigma']),
                rng=rng_v,
                constrain='redraw',
                boundaries=(-80, -60))

        self.times['t_setup'] = self.timer.diff()
        self.times['t_calc_conns'] = 0
        if self.comm != None:
            self.comm.Barrier()

        self.torus = space.Space(axes='xy', periodic_boundaries=((0., self.params['torus_width']), (0., self.params['torus_height'])))

    def create_neurons_with_limited_tuning_properties(self):
        n_exc = self.tuning_prop_exc[:, 0].size
        n_inh = 0
        if self.params['neuron_model'] == 'IF_cond_exp':
            self.exc_pop = Population(n_exc, IF_cond_exp, self.params['cell_params_exc'], label='exc_cells')
            self.inh_pop = Population(self.params['n_inh'], IF_cond_exp, self.params['cell_params_inh'], label="inh_pop")
        elif self.params['neuron_model'] == 'IF_cond_alpha':
            self.exc_pop = Population(n_exc, IF_cond_alpha, self.params['cell_params_exc'], label='exc_cells')
            self.inh_pop = Population(self.params['n_inh'], IF_cond_alpha, self.params['cell_params_inh'], label="inh_pop")
        elif self.params['neuron_model'] == 'EIF_cond_exp_isfa_ista':
            self.exc_pop = Population(n_exc, EIF_cond_exp_isfa_ista, self.params['cell_params_exc'], label='exc_cells')
            self.inh_pop = Population(self.params['n_inh'], EIF_cond_exp_isfa_ista, self.params['cell_params_inh'], label="inh_pop")
        else:
            print '\n\nUnknown neuron model:\n\t', self.params['neuron_model']

        # set cell positions, required for isotropic connections
        cell_pos_exc = np.zeros((3, self.params['n_exc']))
        cell_pos_exc[0, :] = self.tuning_prop_exc[:, 0]
        cell_pos_exc[1, :] = self.tuning_prop_exc[:, 1]
        self.exc_pop.positions = cell_pos_exc

        cell_pos_inh = np.zeros((3, self.params['n_inh']))
        cell_pos_inh[0, :] = self.tuning_prop_inh[:, 0]
        cell_pos_inh[1, :] = self.tuning_prop_inh[:, 1]
        self.inh_pop.positions = cell_pos_inh

        self.local_idx_exc = get_local_indices(self.exc_pop, offset=0)

        if not input_created:
            self.spike_times_container = [ [] for i in xrange(len(self.local_idx_exc))]
            self.spike_times_container = [ [] for i in xrange(len(self.local_idx_exc))]
        print 'Debug, pc_id %d has local %d exc indices:' % (self.pc_id, len(self.local_idx_exc)), self.local_idx_exc
        self.exc_pop.initialize('v', self.v_init_dist)

        self.local_idx_inh = get_local_indices(self.inh_pop, offset=self.params['n_exc'])
        print 'Debug, pc_id %d has local %d inh indices:' % (self.pc_id, len(self.local_idx_inh)), self.local_idx_inh
        self.inh_pop.initialize('v', self.v_init_dist)
        self.times['t_create'] = self.timer.diff()


    def create(self, input_created=False):
        """
            # # # # # # # # # # # #
            #     C R E A T E     #
            # # # # # # # # # # # #
        """
        if self.params['neuron_model'] == 'IF_cond_exp':
            self.exc_pop = Population(self.params['n_exc'], IF_cond_exp, self.params['cell_params_exc'], label='exc_cells')
            self.inh_pop = Population(self.params['n_inh'], IF_cond_exp, self.params['cell_params_inh'], label="inh_pop")
        elif self.params['neuron_model'] == 'IF_cond_alpha':
            self.exc_pop = Population(self.params['n_exc'], IF_cond_alpha, self.params['cell_params_exc'], label='exc_cells')
            self.inh_pop = Population(self.params['n_inh'], IF_cond_alpha, self.params['cell_params_inh'], label="inh_pop")
        elif self.params['neuron_model'] == 'EIF_cond_exp_isfa_ista':
            self.exc_pop = Population(self.params['n_exc'], EIF_cond_exp_isfa_ista, self.params['cell_params_exc'], label='exc_cells')
            self.inh_pop = Population(self.params['n_inh'], EIF_cond_exp_isfa_ista, self.params['cell_params_inh'], label="inh_pop")
        else:
            print '\n\nUnknown neuron model:\n\t', self.params['neuron_model']
        self.local_idx_exc = get_local_indices(self.exc_pop, offset=0)
        print 'Debug, pc_id %d has local %d exc indices:' % (self.pc_id, len(self.local_idx_exc)), self.local_idx_exc

        cell_pos_exc = np.zeros((3, self.params['n_exc']))
        cell_pos_exc[0, :] = self.tuning_prop_exc[:, 0]
        cell_pos_exc[1, :] = self.tuning_prop_exc[:, 1]
        self.exc_pop.positions = cell_pos_exc

        cell_pos_inh = np.zeros((3, self.params['n_inh']))
        cell_pos_inh[0, :] = self.tuning_prop_inh[:, 0]
        cell_pos_inh[1, :] = self.tuning_prop_inh[:, 1]
        self.inh_pop.positions = cell_pos_inh


        if not input_created:
            self.spike_times_container = [ [] for i in xrange(len(self.local_idx_exc))]

        self.exc_pop.initialize('v', self.v_init_dist)

        self.local_idx_inh = get_local_indices(self.inh_pop, offset=self.params['n_exc'])
        print 'Debug, pc_id %d has local %d inh indices:' % (self.pc_id, len(self.local_idx_inh)), self.local_idx_inh
        self.inh_pop.initialize('v', self.v_init_dist)

        self.times['t_create'] = self.timer.diff()


    def connect(self):
        if self.params['n_exc'] > 5000:
            save_output = False
        else:
            save_output = True

        self.connect_input_to_exc()
        self.connect_populations('ee')
        self.connect_populations('ei')
        self.connect_populations('ie')
        self.connect_populations('ii')
        self.connect_noise()
        self.times['t_calc_conns'] = self.timer.diff()
        if self.comm != None:
            self.comm.Barrier()

    def get_motion_params_from_protocol(self, time):
        """

        """

        predictor_interval = int(time / self.params['predictor_interval_duration'])
        # based on the motion_protocol calculate the stimulus position and direction etc --> predictor_params
        if self.params['motion_protocol'] == 'congruent':
            x0, y0, u0, v0, theta = self.params['motion_params'][0], self.params['motion_params'][1],  self.params['motion_params'][2],  self.params['motion_params'][3], self.params['motion_params'][4]
            x, y = (x0 + u0 * time) % self.params['torus_width'], (y0 + v0 * time) % self.params['torus_height'] # current position of the blob at time t assuming a perfect translation
            predictor_params = (x, y, u0, v0, theta)

        elif self.params['motion_protocol'] == 'incongruent':
        # incongruent protocol means having oriented bar as stimulus that its orientation is flipped inside the CRF        
            predictor_params = self.params['motion_params']
#            if (t_check < time < t_stop_check):
#                orientation = sp.params['motion_params'][:,4] + np.pi/2.0

        # Missing CRF protocol includes a moving oriented bar which approches to CRF and disappears inside CRF     
        # --> we give noise as input
        # --> we shuffle the stimulus among all cells to get an incoherent input (the output of the CRF will be very small)
        elif protocol == 'Missing CRF':
            predictor_params = self.params['motion_params']
#            if (t_check < t < t_stop_check):
#                L = np.random.permutation(stimulus)

        # CRF only protocol includes an oriented bar which moves for a short period only inside CRF        
        elif protocol == 'CRF only':
            predictor_params = self.params['motion_params']
#            if (t_check < t < t_stop_check):
#                L = stimulus
#            else:
#                L = np.random.permutation(stimulus)
#                 L = 0

        elif self.params['motion_protocol'] == 'random predictor':
            predictor_params = self.params['motion_params']
            # we create a random sequence of orientations and segment the trajectory
#            orientation = np.random.rand(self.params['n_random_predictor_orientations']) * np.pi

        return predictor_params


    def create_input(self, load_files=False, save_output=False):


        if load_files:
            if self.pc_id == 0:
                print "Loading input spiketrains..."
            for i_, tgt in enumerate(self.local_idx_exc):
                try:
                    fn = self.params['input_st_fn_base'] + str(tgt) + '.npy'
                    spike_times = np.load(fn)
                except: # this cell does not get any input
                    print "Missing file: ", fn
                    spike_times = []
                self.spike_times_container[i_] = spike_times
        else:
            if self.pc_id == 0:
                print "Computing input spiketrains..."
            nprnd.seed(self.params['input_spikes_seed'])
            dt = self.params['dt_rate'] # [ms] time step for the non-homogenous Poisson process
            time = np.arange(0, self.params['t_sim'], dt)
            blank_idx = np.arange(1./dt * self.params['t_before_blank'], 1. / dt * (self.params['t_before_blank'] + self.params['t_blank']))
            before_stim_idx = np.arange(0, self.params['t_start'] * 1./dt)
            blank_idx = np.concatenate((blank_idx, before_stim_idx))

            my_units = self.local_idx_exc
            n_cells = len(my_units)
            L_input = np.zeros((n_cells, time.shape[0]))

            # get the input signal
            print 'Calculating input signal'
            for i_time, time_ in enumerate(time):
                predictor_params = self.get_motion_params_from_protocol(time_ / self.params['t_stimulus'])
                L_input[:, i_time] = utils.get_input(self.tuning_prop_exc[my_units, :], self.params, predictor_params, motion = self.params['motion_type'])
                L_input[:, i_time] *= self.params['f_max_stim']
                if (i_time % 500 == 0):
                    print "t:", time_

            # blanking
            for i_time in blank_idx:
                L_input[:, i_time] = np.random.permutation(L_input[:, i_time])
#                L_input[:, i_time] = 0.

            # create the spike trains
            print 'Creating input spiketrains for unit'
            for i_, unit in enumerate(my_units):
                rate_of_t = np.array(L_input[i_, :])
                # each cell will get its own spike train stored in the following file + cell gid
                n_steps = rate_of_t.size
                spike_times = []
                for i in xrange(n_steps):
                    r = nprnd.rand()
                    if (r <= ((rate_of_t[i]/1000.) * dt)): # rate is given in Hz -> 1/1000.
                        spike_times.append(i * dt)
                self.spike_times_container[i_] = spike_times
                if save_output:
                    output_fn = self.params['input_rate_fn_base'] + str(unit) + '.npy'
                    np.save(output_fn, rate_of_t)
                    output_fn = self.params['input_st_fn_base'] + str(unit) + '.npy'
                    np.save(output_fn, np.array(spike_times))

        self.times['create_input'] = self.timer.diff()
        return self.spike_times_container



    def connect_input_to_exc(self):
        """
            # # # # # # # # # # # # # # # # # # # # # #
            #     C O N N E C T    I N P U T - E X C  #
            # # # # # # # # # # # # # # # # # # # # # #
        """
        if self.pc_id == 0:
            print "Connecting input spiketrains..."
        
#        self.stimulus = Population(len(self.local_idx_exc), SpikeSourceArray)
#            self.exc_pop = Population(n_exc, IF_cond_exp, self.params['cell_params_exc'], label='exc_cells')
#                prj = Projection(src_pop, tgt_pop, connector, target=syn_type)
#            self.projections[conn_type].append(prj)

#        self.projections['stim'] = []
#        self.stimuli = []
#        self.pop_views = [] 
#        conn = OneToOneConnector(weights=self.params['w_input_exc'])
        for i_, unit in enumerate(self.local_idx_exc):
            spike_times = self.spike_times_container[i_]
#            ssa = create(SpikeSourceArray, {'spike_times': spike_times})
            ssa = Population(1, SpikeSourceArray, {'spike_times': spike_times})
#            ssa.set({'spike_times' : spike_times})
#            self.stimuli.append(ssa)

#            if self.params['with_short_term_depression']:

#                connect(ssa, self.exc_pop[unit], self.params['w_input_exc'], synapse_type='excitatory', synapse_dynamics=self.short_term_depression)
#                selector = np.zeros(self.params['n_exc'], dtype=np.bool)
#                selector[unit] = True
#                print 'debug unit', unit, type(unit)
#                w[i_] = 1.#self.params['w_input_exc']
#                tgt = PopulationView(self.exc_pop, np.array([unit]))
#                self.pop_views.append(tgt)
#                prj = Projection(ssa, tgt, conn, target='excitatory', synapse_dynamics=self.short_term_depression)
#                prj = Projection(self.stimuli[-1], self.pop_views[-1], conn, target='excitatory', synapse_dynamics=self.short_term_depression)
#                self.projections['stim'].append(prj)
#            else:
            connect(ssa, self.exc_pop[unit], self.params['w_input_exc'], synapse_type='excitatory')
        self.times['connect_input'] = self.timer.diff()


    def resolve_src_tgt(self, conn_type):
        """
        Deliver the correct source and target parameters based on conn_type
        """

        if conn_type == 'ee':
            n_src, n_tgt = self.params['n_exc'], self.params['n_exc']
            src_pop, tgt_pop = self.exc_pop, self.exc_pop
            tgt_cells = self.local_idx_exc
            tp_src = self.tuning_prop_exc
            tp_tgt = self.tuning_prop_exc
            syn_type = 'excitatory'

        elif conn_type == 'ei':
            n_src, n_tgt = self.params['n_exc'], self.params['n_inh']
            src_pop, tgt_pop = self.exc_pop, self.inh_pop
            tgt_cells = self.local_idx_inh
            tp_src = self.tuning_prop_exc
            tp_tgt = self.tuning_prop_inh
            syn_type = 'excitatory'

        elif conn_type == 'ie':
            n_src, n_tgt = self.params['n_inh'], self.params['n_exc']
            src_pop, tgt_pop = self.inh_pop, self.exc_pop
            tgt_cells = self.local_idx_exc
            tp_src = self.tuning_prop_inh
            tp_tgt = self.tuning_prop_exc
            syn_type = 'inhibitory'

        elif conn_type == 'ii':
            n_src, n_tgt = self.params['n_inh'], self.params['n_inh']
            src_pop, tgt_pop = self.inh_pop, self.inh_pop
            tgt_cells = self.local_idx_inh
            tp_src = self.tuning_prop_inh
            tp_tgt = self.tuning_prop_inh
            syn_type = 'inhibitory'

        return (n_src, n_tgt, src_pop, tgt_pop, tp_src, tp_tgt, tgt_cells, syn_type)


    def connect_anisotropic(self, conn_type):
        """
        conn_type = ['ee', 'ei', 'ie', 'ii']
        """
        if self.pc_id == 0:
            print 'Connect anisotropic %s - %s' % (conn_type[0].capitalize(), conn_type[1].capitalize())

        (n_src, n_tgt, src_pop, tgt_pop, tp_src, tp_tgt, tgt_cells, syn_type) = self.resolve_src_tgt(conn_type)

        if self.debug_connectivity:
            conn_list_fn = self.params['conn_list_%s_fn_base' % conn_type] + '%d.dat' % (self.pc_id)

        n_src_cells_per_neuron = int(round(self.params['p_%s' % conn_type] * n_src))
        (delay_min, delay_max) = self.params['delay_range']
        local_connlist = np.zeros((n_src_cells_per_neuron * len(tgt_cells), 4))
        for i_, tgt in enumerate(tgt_cells):
            if self.params['conn_conf'] == 'direction-based':
                p, latency = CC.get_p_conn_direction_based(tp_src, tp_tgt[tgt, :], self.params['w_sigma_x'], self.params['w_sigma_v'], self.params['connectivity_radius'])
            elif self.params['conn_conf'] == 'motion-based':
                p, latency = CC.get_p_conn_motion_based(tp_src, tp_tgt[tgt, :], self.params['w_sigma_x'], self.params['w_sigma_v'], self.params['connectivity_radius'])
            elif self.params['conn_conf'] == 'orientation-direction':
                p, latency = CC.get_p_conn_direction_and_orientation_based(tp_src, tp_tgt[tgt, :], self.params['w_sigma_x'], self.params['w_sigma_v'], self.params['w_sigma_theta'], self.params['connectivity_radius'])
            else:
                print '\n\nERROR! Wrong connection configutation conn_conf parameter provided\nShould be direction-based, motion-based or orientation-direction\n'
                exit(1)

            if conn_type[0] == conn_type[1]:
                p[tgt], latency[tgt] = 0., 0.
            # random delays? --> np.permutate(latency) or latency[sources] * self.params['delay_scale'] * np.rand

            sorted_indices = np.argsort(p)
            if conn_type[0] == 'e':
                sources = sorted_indices[-n_src_cells_per_neuron:]
            else: # source = inhibitory
                if conn_type[0] == conn_type[1]:
                    sources = sorted_indices[1:n_src_cells_per_neuron+1]  # shift indices to avoid self-connection, because p_ii = .0
                else:
                    sources = sorted_indices[:n_src_cells_per_neuron]

            eta = 1e-12
            w = (self.params['w_tgt_in_per_cell_%s' % conn_type] / (p[sources].sum() + eta)) * p[sources]
            w_ = np.minimum(np.maximum(w, self.params['w_thresh_min']), self.params['w_thresh_max'])

            delays = np.minimum(np.maximum(latency[sources] * self.params['delay_scale'], delay_min), delay_max)  # map the delay into the valid range
            conn_list = np.array((sources, tgt * np.ones(n_src_cells_per_neuron), w_, delays))
            local_connlist[i_ * n_src_cells_per_neuron : (i_ + 1) * n_src_cells_per_neuron, :] = conn_list.transpose()
            connector = FromListConnector(conn_list.transpose())
            if self.params['with_short_term_depression']:
                prj = Projection(src_pop, tgt_pop, connector, target=syn_type, synapse_dynamics=self.short_term_depression)
            else:
                prj = Projection(src_pop, tgt_pop, connector, target=syn_type)
            self.projections[conn_type].append(prj)

        if self.debug_connectivity:
            if self.pc_id == 0:
                print 'DEBUG writing to file:', conn_list_fn
            np.savetxt(conn_list_fn, local_connlist, fmt='%d\t%d\t%.4e\t%.4e')


    def connect_ee_random(self):
        """
            # # # # # # # # # # # # # # # # # # # # # # # # # # # #
            #     C O N N E C T    E X C - E X C    R A N D O M   #
            # # # # # # # # # # # # # # # # # # # # # # # # # # # #
        """

        if self.pc_id == 0:
            print 'Drawing random connections'
        sigma_x, sigma_v = self.params['w_sigma_x'], self.params['w_sigma_v']
        (delay_min, delay_max) = self.params['delay_range']
        if self.debug_connectivity:
            conn_list_fn = self.params['conn_list_ee_fn_base'] + '%d.dat' % (self.pc_id)
            conn_file = open(conn_list_fn, 'w')
            output = ''
        for tgt in self.local_idx_exc:
            p = np.zeros(self.params['n_exc'], dtype='float32')
            latency = np.zeros(self.params['n_exc'], dtype='float32')
            for src in xrange(self.params['n_exc']):
                if (src != tgt):
                    p[src], latency[src] = CC.get_p_conn(self.tuning_prop_exc[src, :], self.tuning_prop_exc[tgt, :], sigma_x, sigma_v, params['connectivity_radius']) #                            print 'debug pc_id src tgt ', self.pc_id, src, tgt#, int(ID) < self.params['n_exc']
            sources = random.sample(xrange(self.params['n_exc']), int(self.params['n_src_cells_per_neuron']))
            idx = p[sources] > 0
            non_zero_idx = np.nonzero(idx)[0]
            p_ = p[sources][non_zero_idx]
            l_ = latency[sources][non_zero_idx] * self.params['delay_scale']

            w = utils.linear_transformation(p_, self.params['w_min'], self.params['w_max'])
            for i in xrange(len(p_)):
#                        w[i] = max(self.params['w_min'], min(w[i], self.params['w_max']))
                delay = min(max(l_[i], delay_min), delay_max)  # map the delay into the valid range
                connect(self.exc_pop[non_zero_idx[i]], self.exc_pop[tgt], w[i], delay=delay, synapse_type='excitatory')
                if self.debug_connectivity:
                    output += '%d\t%d\t%.2e\t%.2e\n' % (non_zero_idx[i], tgt, w[i], delay) #                    output += '%d\t%d\t%.2e\t%.2e\t%.2e\n' % (sources[i], tgt, w[i], latency[sources[i]], p[sources[i]])

        if self.debug_connectivity:
            if self.pc_id == 0:
                print 'DEBUG writing to file:', conn_list_fn
            conn_file.write(output)
            conn_file.close()

    def connect_isotropic(self, conn_type='ee'):
        """
        conn_type must be 'ee', 'ei', 'ie' or 'ii'
        Connect cells in a distant dependent manner:
            p_ij = exp(- d_ij / (2 * w_sigma_x**2))

        This will give a 'convergence constrained' connectivity, i.e. each cell will have the same sum of incoming weights
        ---> could be problematic for outlier cells
        """
        if self.pc_id == 0:
            print 'Connect isotropic %s - %s' % (conn_type[0].capitalize(), conn_type[1].capitalize())

        (n_src, n_tgt, src_pop, tgt_pop, tp_src, tp_tgt, tgt_cells, syn_type) = self.resolve_src_tgt(conn_type)
        if conn_type == 'ee':
            w_ = self.params['w_max']
            w_tgt_in = params['w_tgt_in_per_cell_%s' % conn_type]
            n_max_conn = n_src * n_tgt - n_tgt

        elif conn_type == 'ei':
            w_ = self.params['w_ei_mean']
            w_tgt_in = params['w_tgt_in_per_cell_%s' % conn_type]
            n_max_conn = n_src * n_tgt

        elif conn_type == 'ie':
            w_ = self.params['w_ie_mean']
            w_tgt_in = params['w_tgt_in_per_cell_%s' % conn_type]
            n_max_conn = n_src * n_tgt

        elif conn_type == 'ii':
            w_ = self.params['w_ii_mean']
            w_tgt_in = params['w_tgt_in_per_cell_%s' % conn_type]
            n_max_conn = n_src * n_tgt - n_tgt

        if self.debug_connectivity:
            conn_list_fn = self.params['conn_list_%s_fn_base' % conn_type] + '%d.dat' % (self.pc_id)
#            conn_file = open(conn_list_fn, 'w')
#            output = ''
#            output_dist = ''

        w_mean = w_tgt_in / (self.params['p_%s' % conn_type] * n_max_conn / n_tgt)
        w_sigma = self.params['w_sigma_distribution'] * w_mean

        w_dist = RandomDistribution('normal',
                (w_mean, w_sigma),
                rng=self.rng_conn,
                constrain='redraw',
                boundaries=(0, w_mean * 10.))
        delay_dist = RandomDistribution('normal',
                (self.params['standard_delay'], self.params['standard_delay_sigma']),
                rng=self.rng_conn,
                constrain='redraw',
                boundaries=(self.params['delay_range'][0], self.params['delay_range'][1]))

        p_max = utils.get_pmax(self.params['p_%s' % conn_type], self.params['w_sigma_isotropic'], conn_type)
        connector = DistanceDependentProbabilityConnector('%f * exp(-d/(2*%f**2))' % (p_max, params['w_sigma_isotropic']), allow_self_connections=False, \
                weights=w_dist, delays=delay_dist, space=self.torus)#, n_connections=n_conn_ee)
        if self.params['with_short_term_depression']:
            prj = Projection(src_pop, tgt_pop, connector, target=syn_type, synapse_dynamics=self.short_term_depression)
        else:
            prj = Projection(src_pop, tgt_pop, connector, target=syn_type)#, synapse_dynamics=self.STD)
        self.projections[conn_type].append(prj)
        if self.debug_connectivity:
#                if self.pc_id == 0:
#                    print 'DEBUG writing to file:', conn_list_fn
            prj.saveConnections(self.params['conn_list_%s_fn_base' % conn_type] + '.dat', gather=True)
#            prj.saveConnections(self.params['conn_list_%s_fn_base' % conn_type] + 'gid%d.dat' % tgt, gather=False)
#                conn_file.close()


#            w = np.zeros(n_src, dtype='float32')
#            delays = np.zeros(n_src, dtype='float32')
#            for src in xrange(n_src):
#                if conn_type[0] == conn_type[1]:
#                    if (src != tgt): # no self-connections / autapses
#                        d_ij = utils.torus_distance2D(tp_src[src, 0], tp_tgt[tgt, 0], tp_src[src, 1], tp_tgt[tgt, 1])
#                        p_ij = p_max * np.exp(-d_ij**2 / (2 * params['w_sigma_isotropic']**2))
#                        if np.random.rand() <= p_ij:
#                            w[src] = w_
#                            delays[src] = d_ij * params['delay_scale']
#                else:
#                    d_ij = utils.torus_distance2D(tp_src[src, 0], tp_tgt[tgt, 0], tp_src[src, 1], tp_tgt[tgt, 1])
#                    p_ij = p_max * np.exp(-d_ij**2 / (2 * params['w_sigma_isotropic']**2))
#                    if np.random.rand() <= p_ij:
#                        w[src] = w_
#                        delays[src] = d_ij * params['delay_scale']
#            w *= w_tgt_in / w.sum()
#            srcs = w.nonzero()[0]
#            weights = w[srcs]
#            for src in srcs:
#                if w[src] > self.params['w_thresh_connection']:
#                delay = min(max(delays[src], self.params['delay_range'][0]), self.params['delay_range'][1])  # map the delay into the valid range
#                connect(src_pop[int(src)], tgt_pop[int(tgt)], w[src], delay=delay, synapse_type=syn_type)
#                output += '%d\t%d\t%.2e\t%.2e\n' % (src, tgt, w[src], delay)

#        if self.debug_connectivity:
#            if self.pc_id == 0:
#                print 'DEBUG writing to file:', conn_list_fn
#            conn_file.write(output)
#            conn_file.close()


    def connect_random(self, conn_type):
        """
        There exist different possibilities to draw random connections:
        1) Calculate the weights as for the anisotropic case and sample sources randomly
        2) Load a file which stores some random connectivity --> # connector = FromFileConnector(self.params['conn_list_.... ']
        3) Create a random distribution with similar parameters as the non-random connectivition distribution

        connector_ee = FastFixedProbabilityConnector(self.params['p_ee'], weights=w_ee_dist, delays=self.delay_dist)
        prj_ee = Projection(self.exc_pop, self.exc_pop, connector_ee, target='excitatory')

        conn_list_fn = self.params['random_weight_list_fn'] + str(sim_cnt) + '.dat'
        print "Connecting exc - exc from file", conn_list_fn
        connector_ee = FromFileConnector(conn_list_fn)
        prj_ee = Projection(self.exc_pop, self.exc_pop, connector_ee, target='excitatory')
        """
        if self.pc_id == 0:
            print 'Connect random connections %s - %s' % (conn_type[0].capitalize(), conn_type[1].capitalize())
        (n_src, n_tgt, src_pop, tgt_pop, tp_src, tp_tgt, tgt_cells, syn_type) = self.resolve_src_tgt(conn_type)
        if conn_type == 'ee':
            w_ = self.params['w_max']
            w_tgt_in = params['w_tgt_in_per_cell_%s' % conn_type]
            n_max_conn = n_src * n_tgt - n_tgt

        elif conn_type == 'ei':
            w_ = self.params['w_ei_mean']
            w_tgt_in = params['w_tgt_in_per_cell_%s' % conn_type]
            n_max_conn = n_src * n_tgt

        elif conn_type == 'ie':
            w_ = self.params['w_ie_mean']
            w_tgt_in = params['w_tgt_in_per_cell_%s' % conn_type]
            n_max_conn = n_src * n_tgt

        elif conn_type == 'ii':
            w_ = self.params['w_ii_mean']
            w_tgt_in = params['w_tgt_in_per_cell_%s' % conn_type]
            n_max_conn = n_src * n_tgt - n_tgt

        if self.debug_connectivity:
            conn_list_fn = self.params['conn_list_%s_fn_base' % conn_type] + '%d.dat' % (self.pc_id)
#            conn_file = open(conn_list_fn, 'w')
#            output = ''
#            output_dist = ''

        w_mean = w_tgt_in / (self.params['p_%s' % conn_type] * n_max_conn / n_tgt)
        w_sigma = self.params['w_sigma_distribution'] * w_mean

        weight_distr = RandomDistribution('normal',
                (w_mean, w_sigma),
                rng=self.rng_conn,
                constrain='redraw',
                boundaries=(0, w_mean * 10.))

        delay_dist = RandomDistribution('normal',
                (self.params['standard_delay'], self.params['standard_delay_sigma']),
                rng=self.rng_conn,
                constrain='redraw',
                boundaries=(self.params['delay_range'][0], self.params['delay_range'][1]))

        connector= FastFixedProbabilityConnector(self.params['p_%s' % conn_type], weights=weight_distr, delays=delay_dist)
        if self.params['with_short_term_depression']:
            prj = Projection(src_pop, tgt_pop, connector, target=syn_type, synapse_dynamics=self.short_term_depression)
        else:
            prj = Projection(src_pop, tgt_pop, connector, target=syn_type)

        conn_list_fn = self.params['conn_list_%s_fn_base' % conn_type] + '%d.dat' % (self.pc_id)
        print 'Saving random %s connections to %s' % (conn_type, conn_list_fn)
        prj.saveConnections(conn_list_fn, gather=False)



    def connect_populations(self, conn_type):
        """
            # # # # # # # # # # # #
            #     C O N N E C T   #
            # # # # # # # # # # # #
            Calls the right according to the flag set in simultation_parameters.py
        """
        if self.params['connectivity_%s' % conn_type] == 'anisotropic':
            self.connect_anisotropic(conn_type)
        elif self.params['connectivity_%s' % conn_type] == 'isotropic':
            self.connect_isotropic(conn_type)
        elif self.params['connectivity_%s' % conn_type] == 'random':
            self.connect_random(conn_type)
        else: # populations do not get connected
            pass


    def connect_noise(self):
        """
            # # # # # # # # # # # # # # # #
            #     N O I S E   I N P U T   #
            # # # # # # # # # # # # # # # #
        """
        if self.pc_id == 0:
            print "Connecting noise - exc ... "
        noise_pop_exc = []
        noise_pop_inh = []
        for tgt in self.local_idx_exc:
            #new
            if (self.params['simulator'] == 'nest'): # for nest one can use the optimized Poisson generator
                noise_exc = create(native_cell_type('poisson_generator'), {'rate' : self.params['f_exc_noise']})
                noise_inh = create(native_cell_type('poisson_generator'), {'rate' : self.params['f_inh_noise']})
            else:
                noise_exc = create(SpikeSourcePoisson, {'rate' : self.params['f_exc_noise']})
                noise_inh = create(SpikeSourcePoisson, {'rate' : self.params['f_inh_noise']})
            connect(noise_exc, self.exc_pop[tgt], weight=self.params['w_exc_noise'], synapse_type='excitatory', delay=1.)
            connect(noise_inh, self.exc_pop[tgt], weight=self.params['w_inh_noise'], synapse_type='inhibitory', delay=1.)

        if self.pc_id == 0:
            print "Connecting noise - inh ... "
        for tgt in self.local_idx_inh:
            if (self.params['simulator'] == 'nest'): # for nest one can use the optimized Poisson generator
                noise_exc = create(native_cell_type('poisson_generator'), {'rate' : self.params['f_exc_noise']})
                noise_inh = create(native_cell_type('poisson_generator'), {'rate' : self.params['f_inh_noise']})
            else:
                noise_exc = create(SpikeSourcePoisson, {'rate' : self.params['f_exc_noise']})
                noise_inh = create(SpikeSourcePoisson, {'rate' : self.params['f_inh_noise']})
            connect(noise_exc, self.inh_pop[tgt], weight=self.params['w_exc_noise'], synapse_type='excitatory', delay=1.)
            connect(noise_inh, self.inh_pop[tgt], weight=self.params['w_inh_noise'], synapse_type='inhibitory', delay=1.)
        self.times['connect_noise'] = self.timer.diff()




    def run_sim(self, sim_cnt, record_v=False):
        # # # # # # # # # # # # # # # # # # # #
        #     P R I N T    W E I G H T S      #
        # # # # # # # # # # # # # # # # # # # #
    #    print 'Printing weights to :\n  %s\n  %s\n  %s' % (self.params['conn_list_ei_fn'], self.params['conn_list_ie_fn'], self.params['conn_list_ii_fn'])
    #    exc_inh_prj.saveConnections(self.params['conn_list_ei_fn'])
    #    inh_exc_prj.saveConnections(self.params['conn_list_ie_fn'])
    #    inh_inh_prj.saveConnections(self.params['conn_list_ii_fn'])
    #    self.times['t_save_conns'] = self.timer.diff()

        # # # # # # # # # # # #
        #     R E C O R D     #
        # # # # # # # # # # # #
    #    print "Recording spikes to file: %s" % (self.params['exc_spiketimes_fn_merged'] + '%d.ras' % sim_cnt)
    #    for cell in xrange(self.params['n_exc']):
    #        record(self.exc_pop[cell], self.params['exc_spiketimes_fn_merged'] + '%d.ras' % sim_cnt)

        record_exc = True
        if os.path.exists(self.params['gids_to_record_fn']):
            gids_to_record = np.loadtxt(self.params['gids_to_record_fn'], dtype='int')[:self.params['n_gids_to_record']]
            record_exc = True
            n_rnd_cells_to_record = 2
        
        else:
            n_cells_to_record = 5# self.params['n_exc'] * 0.02
            gids_to_record = np.random.randint(0, self.params['n_exc'], n_cells_to_record)
        
        

        if ps.params['anticipatory_mode']:
            record_gids, pops = utils.select_well_tuned_cells(self.tuning_prop_exc, self.params, self.params['n_gids_to_record'], 1)
            np.savetxt(self.params['gids_to_record_fn'], record_gids)
            self.exc_pop_view_anticipation = PopulationView(self.exc_pop, record_gids, label='anticipation')
            self.exc_pop_view_anticipation.record_v()
            self.exc_pop_view_anticipation.record_gsyn()
            self.anticipatory_record = True
              ###################################
              ###################################
              
              
        if record_v:
            self.exc_pop_view = PopulationView(self.exc_pop, gids_to_record, label='good_exc_neurons')
            self.exc_pop_view.record_v()
            self.inh_pop_view = PopulationView(self.inh_pop, np.random.randint(0, self.params['n_inh'], self.params['n_gids_to_record']), label='random_inh_neurons')
            self.inh_pop_view.record_v()


        self.inh_pop.record()
        self.exc_pop.record()
        self.times['t_record'] = self.timer.diff()

        # # # # # # # # # # # # # #
        #     R U N N N I N G     #
        # # # # # # # # # # # # # #
        if self.pc_id == 0:
            print "Running simulation ... "
        run(self.params['t_sim'])
        self.times['t_sim'] = self.timer.diff()

    def print_results(self, print_v=True):
        """
            # # # # # # # # # # # # # # # # #
            #   P R I N T    R E S U L T S  #
            # # # # # # # # # # # # # # # # #
        """
        if print_v:
            if self.pc_id == 0:
                print 'print_v to file: %s.v' % (self.params['exc_volt_fn_base'])
            self.exc_pop_view.print_v("%s.v" % (self.params['exc_volt_fn_base']), compatible_output=False)
            if self.pc_id == 0:
                print "Printing inhibitory membrane potentials"
            self.inh_pop_view.print_v("%s.v" % (self.params['inh_volt_fn_base']), compatible_output=False)

        print 'DEBUG printing anticipatory cells', self.anticipatory_record
        if self.anticipatory_record == True:   
            print 'print_v to file: %s' % (self.params['exc_volt_anticipation'])
            self.exc_pop_view_anticipation.print_v("%s" % (self.params['exc_volt_anticipation']), compatible_output=False)
            print 'print_gsyn to file: %s' % (self.params['exc_gsyn_anticipation'])
            self.exc_pop_view_anticipation.print_gsyn("%s" % (self.params['exc_gsyn_anticipation']), compatible_output=False)


        if self.pc_id == 0:
            print "Printing excitatory spikes"
        self.exc_pop.printSpikes(self.params['exc_spiketimes_fn_merged'] + '.ras')
        if self.pc_id == 0:
            print "Printing inhibitory spikes"
        self.inh_pop.printSpikes(self.params['inh_spiketimes_fn_merged'] + '.ras')

        self.times['t_print'] = self.timer.diff()
        if self.pc_id == 0:
            print "calling pyNN.end() ...."
        end()
        self.times['t_end'] = self.timer.diff()

        if self.pc_id == 0:
            self.times['t_all'] = 0.
            for k in self.times.keys():
                self.times['t_all'] += self.times[k]

            self.n_cells = {}
            self.n_cells['n_exc'] = self.params['n_exc']
            self.n_cells['n_inh'] = self.params['n_inh']
            self.n_cells['n_cells'] = self.params['n_cells']
            self.n_cells['n_proc'] = self.n_proc
            output = {'times' : self.times, 'n_cells_proc' : self.n_cells}
            print "Proc %d Simulation time: %d sec or %.1f min for %d cells (%d exc %d inh)" % (self.pc_id, self.times['t_sim'], (self.times['t_sim'])/60., self.params['n_cells'], self.params['n_exc'], self.params['n_inh'])
            print "Proc %d Full pyNN run time: %d sec or %.1f min for %d cells (%d exc %d inh)" % (self.pc_id, self.times['t_all'], (self.times['t_all'])/60., self.params['n_cells'], self.params['n_exc'], self.params['n_inh'])
            fn = utils.convert_to_url(params['folder_name'] + 'times_dict_np%d.py' % self.n_proc)
Example #15
0
                                          ext_conn,
                                          ext_syn,
                                          receptor_type='excitatory')
    connections['ext2i'] = sim.Projection(ext_stim,
                                          inh_cells,
                                          ext_conn,
                                          ext_syn,
                                          receptor_type='excitatory')

# === Setup recording ==========================================================
print "%s Setting up recording..." % node_id
exc_cells.record('spikes')
inh_cells.record('spikes')
exc_cells[0, 1].record('v')

buildCPUTime = timer.diff()

# === Save connections to file =================================================

#for prj in connections.keys():
#connections[prj].saveConnections('Results/VAbenchmark_%s_%s_%s_np%d.conn' % (benchmark, prj, options.simulator, np))
saveCPUTime = timer.diff()

# === Run simulation ===========================================================
print "%d Running simulation..." % node_id

sim.run(tstop)

simCPUTime = timer.diff()

E_count = exc_cells.mean_spike_count()
    # Save weights for all connections
    for i, (ampa_weight_writer, nmda_weight_writer) in enumerate(connection_results):
        # Write AMPA weights
        ampa_weight_writer("%s/connection_%u_e_e_ampa.npy" % (folder, i))

        # Write NMDA weights to correct folder
        if mode == Mode.train_asymmetrical:
            nmda_weight_writer("%s/connection_%u_e_e_nmda_asymmetrical.npy" % (folder, i))
        else:
            nmda_weight_writer("%s/connection_%u_e_e_nmda_symmetrical.npy" % (folder, i))

    # Loop through the HCU results and save data to pickle format
    for i, (hcu_e_data_writer,) in enumerate(hcu_results):
        hcu_e_data_writer("%s/hcu_%u_e_data.pkl" % (folder, i))

    logger.info("Download time %gs", timer.diff())

    # Once data is read, end simulation
    end_simulation()
else:
    # Testing parameters
    testing_simtime = 6000.0   # simulation time [ms]

    ampa_nmda_ratio = 4.795918367
    tau_ca2 = 300.0

    if mode == Mode.test_symmetrical:
        i_alpha = 0.7
        gain_per_hcu = 1.3
    else:
        i_alpha = 0.15
    dy = abs(pos_1[:, 1] - pos_2[:, 1])
    dx = numpy.minimum(dx, N - dx)
    dy = numpy.minimum(dy, N - dy)
    return sqrt(dx * dx + dy * dy)


timer.start()
node_id = setup(timestep=0.1, min_delay=0.1, max_delay=4.0)
print "Creating cells population..."
N = 30

structure = RandomStructure(Cuboid(1, 1, 1), origin=(0.5, 0.5, 0.5), rng=NumpyRNG(2652))
# structure = Grid2D(dx=1/float(N), dy=1/float(N))

x = Population(N ** 2, IF_curr_exp(), structure=structure)
mytime = timer.diff()
print "Time to build the cell population:", mytime, "s"


def test(cases=[1]):

    sp = Space(periodic_boundaries=((0, 1), (0, 1), None), axes="xy")
    safe = False
    callback = progress_bar.set_level
    autapse = False
    parallel_safe = True
    render = True
    to_file = True

    for case in cases:
        # w = RandomDistribution('uniform', (0,1))
Example #18
0
    dy = numpy.minimum(dy, N - dy)
    return sqrt(dx * dx + dy * dy)


timer.start()
node_id = setup(timestep=0.1, min_delay=0.1, max_delay=4.)
print "Creating cells population..."
N = 30

structure = RandomStructure(Cuboid(1, 1, 1),
                            origin=(0.5, 0.5, 0.5),
                            rng=NumpyRNG(2652))
#structure = Grid2D(dx=1/float(N), dy=1/float(N))

x = Population(N**2, IF_curr_exp(), structure=structure)
mytime = timer.diff()
print "Time to build the cell population:", mytime, 's'


def test(cases=[1]):

    sp = Space(periodic_boundaries=((0, 1), (0, 1), None), axes='xy')
    safe = False
    callback = progress_bar.set_level
    autapse = False
    parallel_safe = True
    render = True
    to_file = True

    for case in cases:
        #w = RandomDistribution('uniform', (0,1))
Example #19
0
connector = FixedProbabilityConnector(pconn, rng=rng, callback=progress_bar)
exc_syn = StaticSynapse(weight=w_exc, delay=delay)
inh_syn = StaticSynapse(weight=w_inh, delay=delay)

connections={}
connections['exc'] = Projection(exc_cells, all_cells, connector, exc_syn, receptor_type='excitatory')
connections['inh'] = Projection(inh_cells, all_cells, connector, inh_syn, receptor_type='inhibitory')
if (benchmark == "COBA"):
    connections['ext'] = Projection(ext_stim, all_cells, ext_conn, ext_syn, receptor_type='excitatory')

# === Setup recording ==========================================================
print "%s Setting up recording..." % node_id
all_cells.record('spikes')
exc_cells[[0, 1]].record('v')

buildCPUTime = timer.diff()

# === Save connections to file =================================================

#print "%s Saving connections to file..." % node_id
#for prj in connections.keys():
#    connections[prj].saveConnections('Results/VAbenchmark_%s_%s_%s_np%d.conn' % (benchmark, prj, simulator_name, np))
#saveCPUTime = timer.diff()

# === Run simulation ===========================================================
print "%d Running simulation..." % node_id

run(tstop)

simCPUTime = timer.diff()
class NetworkModel(object):

    def __init__(self, params, comm):

        self.params = params
        self.debug_connectivity = True
        self.comm = comm
        if self.comm != None:
            self.pc_id, self.n_proc = self.comm.rank, self.comm.size
            print "USE_MPI: yes", '\tpc_id, n_proc:', self.pc_id, self.n_proc
        else:
            self.pc_id, self.n_proc = 0, 1
            print "MPI not used"


    def import_pynn(self):
        """
        This function needs only be called when this class is used in another script as imported module
        """
        import pyNN
        exec("from pyNN.%s import *" % self.params['simulator'])
        print 'import pyNN\npyNN.version: ', pyNN.__version__



    def setup(self, load_tuning_prop=False):

        if load_tuning_prop:
            print 'Loading tuning properties from', self.params['tuning_prop_means_fn']
            self.tuning_prop_exc = np.loadtxt(self.params['tuning_prop_means_fn'])
        else:
            print 'Preparing tuning properties with limited range....'
            x_range = (0, 1.)
            y_range = (0.2, .5)
            u_range = (.05, 1.0)
            v_range = (-.2, .2)
            tp_exc_good, tp_exc_out_of_range = utils.set_limited_tuning_properties(params, y_range, x_range, u_range, v_range, cell_type='exc')
            self.tuning_prop_exc = tp_exc_good
            print 'n_exc within range: ', tp_exc_good[:, 0].size
            print "Saving tuning_prop to file:", params['tuning_prop_means_fn']
            np.savetxt(params['tuning_prop_means_fn'], tp_exc_good)

        indices, distances = utils.sort_gids_by_distance_to_stimulus(self.tuning_prop_exc, self.params['motion_params'], self.params) # cells in indices should have the highest response to the stimulus
        if self.pc_id == 0:
            print "Saving tuning_prop to file:", self.params['tuning_prop_means_fn']
            np.savetxt(self.params['tuning_prop_means_fn'], self.tuning_prop_exc)
            print 'Saving gids to record to: ', self.params['gids_to_record_fn']
            np.savetxt(self.params['gids_to_record_fn'], indices[:self.params['n_gids_to_record']], fmt='%d')

#        np.savetxt(params['gids_to_record_fn'], indices[:params['n_gids_to_record']], fmt='%d')

        if self.comm != None:
            self.comm.Barrier()
        from pyNN.utility import Timer
        self.timer = Timer()
        self.timer.start()
        self.times = {}
        # # # # # # # # # # # # 
        #     S E T U P       #
        # # # # # # # # # # # #
        (delay_min, delay_max) = self.params['delay_range']
        setup(timestep=0.1, min_delay=delay_min, max_delay=delay_max, rng_seeds_seed=self.params['seed'])
        rng_v = NumpyRNG(seed = sim_cnt*3147 + self.params['seed'], parallel_safe=True) #if True, slower but does not depend on number of nodes
        self.rng_conn = NumpyRNG(seed = self.params['seed'], parallel_safe=True) #if True, slower but does not depend on number of nodes

        # # # # # # # # # # # # # # # # # # # # # # # # #
        #     R A N D O M    D I S T R I B U T I O N S  #
        # # # # # # # # # # # # # # # # # # # # # # # # #
        self.v_init_dist = RandomDistribution('normal',
                (self.params['v_init'], self.params['v_init_sigma']),
                rng=rng_v,
                constrain='redraw',
                boundaries=(-80, -60))

        self.times['t_setup'] = self.timer.diff()
        self.times['t_calc_conns'] = 0
        if self.comm != None:
            self.comm.Barrier()

    def create_neurons_with_limited_tuning_properties(self, input_created):
        n_exc = self.tuning_prop_exc[:, 0].size
        n_inh = 0
        if self.params['neuron_model'] == 'IF_cond_exp':
            self.exc_pop = Population(n_exc, IF_cond_exp, self.params['cell_params_exc'], label='exc_cells')
        elif self.params['neuron_model'] == 'EIF_cond_exp_isfa_ista':
            self.exc_pop = Population(n_exc, EIF_cond_exp_isfa_ista, self.params['cell_params_exc'], label='exc_cells')
        else:
            print '\n\nUnknown neuron model:\n\t', self.params['neuron_model']


        self.local_idx_exc = get_local_indices(self.exc_pop, offset=0)
        self.exc_pop.initialize('v', self.v_init_dist)
        if not input_created:
            self.spike_times_container = [ [] for i in xrange(len(self.local_idx_exc))]

#        self.local_idx_inh = get_local_indices(self.inh_pop, offset=self.params['n_exc'])
#        print 'Debug, pc_id %d has local %d inh indices:' % (self.pc_id, len(self.local_idx_inh)), self.local_idx_inh
#        self.inh_pop.initialize('v', self.v_init_dist)
        self.times['t_create'] = self.timer.diff()


    def create(self):
        """
            # # # # # # # # # # # # 
            #     C R E A T E     #
            # # # # # # # # # # # #
        """
        if self.params['neuron_model'] == 'IF_cond_exp':
            self.exc_pop = Population(self.params['n_exc'], IF_cond_exp, self.params['cell_params_exc'], label='exc_cells')
            self.inh_pop = Population(self.params['n_inh'], IF_cond_exp, self.params['cell_params_inh'], label="inh_pop")
#        elif self.params['neuron_model'] == 'EIF_cond_exp_isfa_ista':
        elif self.params['neuron_model'] == 'EIF_cond_alpha_isfa_ista':
            self.exc_pop = Population(self.params['n_exc'], EIF_cond_exp_isfa_ista, self.params['cell_params_exc'], label='exc_cells')
            self.inh_pop = Population(self.params['n_inh'], EIF_cond_exp_isfa_ista, self.params['cell_params_inh'], label="inh_pop")
        else:
            print '\n\nUnknown neuron model:\n\t', self.params['neuron_model']
        self.local_idx_exc = get_local_indices(self.exc_pop, offset=0)

        if not input_created:
            self.spike_times_container = [ [] for i in xrange(len(self.local_idx_exc))]

        self.exc_pop.initialize('v', self.v_init_dist)

        self.local_idx_inh = get_local_indices(self.inh_pop, offset=self.params['n_exc'])
        self.inh_pop.initialize('v', self.v_init_dist)

        self.times['t_create'] = self.timer.diff()


    def connect(self):
        self.connect_input_to_exc()
        self.connect_populations('ee')
#        self.connect_populations('ei')
#        self.connect_populations('ie')
#        self.connect_populations('ii')
        self.connect_noise()
        self.times['t_connect'] = self.timer.diff()
        if self.comm != None:
            self.comm.Barrier()

    def create_input(self, load_files=False, save_output=False):


        if load_files:
            if self.pc_id == 0:
                print "Loading input spiketrains..."
            for i_, tgt in enumerate(self.local_idx_exc):
                try:
                    fn = self.params['input_st_fn_base'] + str(tgt) + '.npy'
                    spike_times = np.load(fn)
                except: # this cell does not get any input
                    print "Missing file: ", fn
                    spike_times = []
                self.spike_times_container[i_] = spike_times
        else:
            if self.pc_id == 0:
                print "Computing input spiketrains..."
            nprnd.seed(self.params['input_spikes_seed'])
            dt = self.params['dt_rate'] # [ms] time step for the non-homogenous Poisson process 
            time = np.arange(0, self.params['t_sim'], dt)
            blank_idx = np.arange(1./dt * self.params['t_before_blank'], 1. / dt * (self.params['t_before_blank'] + self.params['t_blank']))

            my_units = self.local_idx_exc
            n_cells = len(my_units)
            L_input = np.zeros((n_cells, time.shape[0]))
            # get the input signal
            for i_time, time_ in enumerate(time):
                if (i_time % 500 == 0):
                    print "t:", time_
                L_input[:, i_time] = utils.get_input(self.tuning_prop_exc[my_units, :], self.params, time_/1000.)
#                L_input[:, i_time] = utils.get_input(self.tuning_prop_exc[my_units, :], self.params, time_/self.params['t_stimulus'])
                L_input[:, i_time] *= self.params['f_max_stim']
            # blanking 
            for i_time in blank_idx:
                L_input[:, i_time] = 0.

            # create the spike trains
            for i_, unit in enumerate(my_units):
                rate_of_t = np.array(L_input[i_, :]) 
                # each cell will get its own spike train stored in the following file + cell gid
                n_steps = rate_of_t.size
                spike_times = []
                for i in xrange(n_steps):
                    r = nprnd.rand()
                    if (r <= ((rate_of_t[i]/1000.) * dt)): # rate is given in Hz -> 1/1000.
                        spike_times.append(i * dt) 
                self.spike_times_container[i_] = spike_times
                if save_output:
                    output_fn = self.params['input_rate_fn_base'] + str(unit) + '.npy'
                    np.save(output_fn, rate_of_t)
                    output_fn = self.params['input_st_fn_base'] + str(unit) + '.npy'
                    np.save(output_fn, np.array(spike_times))
        self.times['create_input'] = self.timer.diff()
        return self.spike_times_container

    def connect_input_to_exc(self):
        """
            # # # # # # # # # # # # # # # # # # # # # # 
            #     C O N N E C T    I N P U T - E X C  #
            # # # # # # # # # # # # # # # # # # # # # # 
        """
        if self.pc_id == 0:
            print "Connecting input spiketrains..."
        for i_, unit in enumerate(self.local_idx_exc):
            spike_times = self.spike_times_container[i_]
            ssa = create(SpikeSourceArray, {'spike_times': spike_times})
            connect(ssa, self.exc_pop[unit], self.params['w_input_exc'], synapse_type='excitatory')
        self.times['connect_input'] = self.timer.diff()


    def connect_anisotropic(self, conn_type):
        """
        """
        if self.pc_id == 0:
            print 'Connect anisotropic %s - %s' % (conn_type[0].capitalize(), conn_type[1].capitalize())

        (n_src, n_tgt, src_pop, tgt_pop, tp_src, tp_tgt, tgt_cells, syn_type) = self.resolve_src_tgt(conn_type)

        if self.debug_connectivity:
            conn_list_fn = self.params['conn_list_%s_fn_base' % conn_type] + '%d.dat' % (self.pc_id)
            conn_file = open(conn_list_fn, 'w')
            output = ''

        n_src_cells_per_neuron = int(round(self.params['p_%s' % conn_type] * n_src))
        (delay_min, delay_max) = self.params['delay_range']
        for tgt in tgt_cells:
            p = np.zeros(n_src)
            latency = np.zeros(n_src)
            for src in xrange(n_src):
                if conn_type[0] == conn_type[1]: # no self-connection
                    if (src != tgt):
                        p[src], latency[src] = CC.get_p_conn(tp_src[src, :], tp_tgt[tgt, :], params['w_sigma_x'], params['w_sigma_v']) #                            print 'debug pc_id src tgt ', self.pc_id, src, tgt#, int(ID) < self.params['n_exc']
                else: # different populations --> same indices mean different cells, no check for src != tgt
                    p[src], latency[src] = CC.get_p_conn(tp_src[src, :], tp_tgt[tgt, :], params['w_sigma_x'], params['w_sigma_v']) #                            print 'debug pc_id src tgt ', self.pc_id, src, tgt#, int(ID) < self.params['n_exc']

            sorted_indices = np.argsort(p)
            if conn_type[0] == 'e':
                sources = sorted_indices[-n_src_cells_per_neuron:] 
            else:
                if conn_type == 'ii':
                    sources = sorted_indices[1:n_src_cells_per_neuron+1]  # shift indices to avoid self-connection, because p_ii = .0
                else:
                    sources = sorted_indices[:n_src_cells_per_neuron] 
            w = (self.params['w_tgt_in_per_cell_%s' % conn_type] / p[sources].sum()) * p[sources]
            for i in xrange(len(sources)):
                if w[i] > self.params['w_thresh_connection']:
#                        w[i] = max(self.params['w_min'], min(w[i], self.params['w_max']))
                    delay = min(max(latency[sources[i]] * self.params['t_stimulus'], delay_min), delay_max)  # map the delay into the valid range
    #                print 'debug ', delay , ' latency', latency[sources[i]]
    #                delay = min(max(latency[sources[i]] * self.params['delay_scale'], delay_min), delay_max)  # map the delay into the valid range
                    connect(src_pop[sources[i]], tgt_pop[tgt], w[i], delay=delay, synapse_type=syn_type)
                    if self.debug_connectivity:
                        output += '%d\t%d\t%.2e\t%.2e\n' % (sources[i], tgt, w[i], delay) #                    output += '%d\t%d\t%.2e\t%.2e\t%.2e\n' % (sources[i], tgt, w[i], latency[sources[i]], p[sources[i]])


        if self.debug_connectivity:
            if self.pc_id == 0:
                print 'DEBUG writing to file:', conn_list_fn
            conn_file.write(output)
            conn_file.close()



    def resolve_src_tgt(self, conn_type):
        """
        Deliver the correct source and target parameters based on conn_type
        """

        if conn_type == 'ee':
            n_src, n_tgt = self.tuning_prop_exc[:, 0].size, self.tuning_prop_exc[:, 0].size
            src_pop, tgt_pop = self.exc_pop, self.exc_pop
            tgt_cells = self.local_idx_exc
            tp_src = self.tuning_prop_exc
            tp_tgt = self.tuning_prop_exc
            syn_type = 'excitatory'

        elif conn_type == 'ei':
            n_src, n_tgt = self.tuning_prop_exc[:, 0].size, self.tuning_prop_inh[:, 0].size
            src_pop, tgt_pop = self.exc_pop, self.inh_pop
            tgt_cells = self.local_idx_inh
            tp_src = self.tuning_prop_exc
            tp_tgt = self.tuning_prop_inh
            syn_type = 'excitatory'

        elif conn_type == 'ie':
            n_src, n_tgt = self.tuning_prop_inh[:, 0].size, self.tuning_prop_exc[:, 0].size
            src_pop, tgt_pop = self.inh_pop, self.exc_pop
            tgt_cells = self.local_idx_exc
            tp_src = self.tuning_prop_inh
            tp_tgt = self.tuning_prop_exc
            syn_type = 'inhibitory'

        elif conn_type == 'ii':
            n_src, n_tgt = self.tuning_prop_inh[:, 0].size, self.tuning_prop_inh[:, 0].size
            src_pop, tgt_pop = self.inh_pop, self.inh_pop
            tgt_cells = self.local_idx_inh
            tp_src = self.tuning_prop_inh
            tp_tgt = self.tuning_prop_inh
            syn_type = 'inhibitory'

        return (n_src, n_tgt, src_pop, tgt_pop, tp_src, tp_tgt, tgt_cells, syn_type)





    def connect_isotropic(self, conn_type='ee'):
        """
        conn_type must be 'ee', 'ei', 'ie' or 'ii'
        Connect cells in a distant dependent manner:
            p_ij = exp(- d_ij / (2 * w_sigma_x**2))

        This will give a 'convergence constrained' connectivity, i.e. each cell will have the same sum of incoming weights 
        ---> could be problematic for outlier cells
        """
        if self.pc_id == 0:
            print 'Connect isotropic %s - %s' % (conn_type[0].capitalize(), conn_type[1].capitalize())

        (n_src, n_tgt, src_pop, tgt_pop, tp_src, tp_tgt, tgt_cells, syn_type) = self.resolve_src_tgt(conn_type)
        if conn_type == 'ee':
            w_= self.params['w_max']
            w_tgt_in = params['w_tgt_in_per_cell_%s' % conn_type]

        elif conn_type == 'ei':
            w_= self.params['w_ie_mean']
            w_tgt_in = params['w_tgt_in_per_cell_%s' % conn_type]

        elif conn_type == 'ie':
            w_= self.params['w_ie_mean']
            w_tgt_in = params['w_tgt_in_per_cell_%s' % conn_type]

        elif conn_type == 'ii':
            w_= self.params['w_ii_mean']
            w_tgt_in = params['w_tgt_in_per_cell_%s' % conn_type]

        if self.debug_connectivity:
            conn_list_fn = self.params['conn_list_%s_fn_base' % conn_type] + '%d.dat' % (self.pc_id)
            conn_file = open(conn_list_fn, 'w')
            output = ''

        p_max = utils.get_pmax(self.params['p_%s' % conn_type])
        for tgt in tgt_cells:
            w = np.zeros(n_src, dtype='float32') 
            delays = np.zeros(n_src, dtype='float32')
            for src in xrange(n_src):
                if (src != tgt):
#                    d_ij = np.sqrt((tp_src[src, 0] - tp_tgt[tgt, 0])**2 + (tp_src[src, 1] - tp_tgt[tgt, 1])**2)
                    d_ij = utils.torus_distance2D(tp_src[src, 0], tp_tgt[tgt, 0], tp_src[src, 1], tp_tgt[tgt, 1])
                    p_ij = p_max * np.exp(-d_ij / (2 * params['w_sigma_x']**2))
                    if np.random.rand() <= p_ij:
                        w[src] = w_
                        delays[src] = d_ij * self.params['delay_scale']
            w *= w_tgt_in / w.sum()
            srcs = w.nonzero()[0]
            for src in srcs:
                if w[src] > self.params['w_thresh_connection']:
                    delay = min(max(delays[src], self.params['delay_range'][0]), self.params['delay_range'][1])  # map the delay into the valid range
                    connect(src_pop[int(src)], tgt_pop[int(tgt)], w[src], delay=delay, synapse_type=syn_type)
                    output += '%d\t%d\t%.2e\t%.2e\n' % (src, tgt, w[src], delay) 
    #                connect(src_pop[int(src)], tgt_pop[int(tgt)], w[src], delay=params['standard_delay'], synapse_type=syn_type)
    #                output += '%d\t%d\t%.2e\t%.2e\n' % (src, tgt, w[src], params['standard_delay']) 
                    
        if self.debug_connectivity:
            if self.pc_id == 0:
                print 'DEBUG writing to file:', conn_list_fn
            conn_file.write(output)
            conn_file.close()

#   isotropic nearest neighbour code:
#        for tgt in tgt_cells:
#            n_src_to_choose = int(round(p_max * n_src)) # guarantee that all cells have same number of connections
#            dist = np.zeros(n_src, dtype='float32')
#            for src in xrange(n_src):
#                if (src != tgt):
#                    dist[src] = np.sqrt((tp_src[src, 0] - tp_tgt[tgt, 0])**2 + (tp_src[src, 1] - tp_tgt[tgt, 1])**2)
#            src_idx = dist.argsort()[:n_src_to_choose] # choose cells closest to the target
#            for src in src_idx:
#                connect(src_pop[int(src)], tgt_pop[int(tgt)], w_, delay=params['standard_delay'], synapse_type='excitatory')
#                output += '%d\t%d\t%.2e\t%.2e\n' % (src, tgt, w_, params['standard_delay']) 



    def connect_random(self, conn_type):
        """
        There exist different possibilities to draw random connections:
        1) Calculate the weights as for the anisotropic case and sample sources randomly
        2) Load a file which stores some random connectivity --> # connector = FromFileConnector(self.params['conn_list_.... ']
        3) Create a random distribution with similar parameters as the non-random connectivition distribution

        connector_ee = FastFixedProbabilityConnector(self.params['p_ee'], weights=w_ee_dist, delays=self.delay_dist)
        prj_ee = Projection(self.exc_pop, self.exc_pop, connector_ee, target='excitatory')

        conn_list_fn = self.params['random_weight_list_fn'] + str(sim_cnt) + '.dat'
        print "Connecting exc - exc from file", conn_list_fn
        connector_ee = FromFileConnector(conn_list_fn)
        prj_ee = Projection(self.exc_pop, self.exc_pop, connector_ee, target='excitatory')
        """
        if self.pc_id == 0:
            print 'Connect random connections %s - %s' % (conn_type[0].capitalize(), conn_type[1].capitalize())
        (n_src, n_tgt, src_pop, tgt_pop, tp_src, tp_tgt, tgt_cells, syn_type) = self.resolve_src_tgt(conn_type)
        w_mean = self.params['w_tgt_in_per_cell_%s' % conn_type] / (n_src * self.params['p_%s' % conn_type])
        w_sigma = w_mean * .5 * (self.params['w_sigma_x'] + self.params['w_sigma_v'])

        weight_distr = RandomDistribution('normal',
                (w_mean, w_sigma),
                rng=self.rng_conn,
                constrain='redraw',
                boundaries=(0, w_mean * 10.))

        delay_dist = RandomDistribution('normal',
                (self.params['standard_delay'], self.params['standard_delay_sigma']),
                rng=self.rng_conn,
                constrain='redraw',
                boundaries=(self.params['delay_range'][0], self.params['delay_range'][1]))

        connector= FastFixedProbabilityConnector(self.params['p_%s' % conn_type], weights=weight_distr, delays=delay_dist)
        prj = Projection(src_pop, tgt_pop, connector, target=syn_type)

        conn_list_fn = self.params['conn_list_%s_fn_base' % conn_type] + '%d.dat' % (self.pc_id)
        print 'Saving random %s connections to %s' % (conn_type, conn_list_fn)
        prj.saveConnections(conn_list_fn, gather=False)



    def connect_populations(self, conn_type):
        """
            # # # # # # # # # # # # 
            #     C O N N E C T   #
            # # # # # # # # # # # # 
            Calls the right according to the flag set in simultation_parameters.py
        """
        if self.params['connectivity_%s' % conn_type] == 'anisotropic':
            self.connect_anisotropic(conn_type)
        elif self.params['connectivity_%s' % conn_type] == 'isotropic':
            self.connect_isotropic(conn_type)
        elif self.params['connectivity_%s' % conn_type] == 'random':
            self.connect_random(conn_type)
        else: # populations do not get connected
            pass
        self.times['t_calc_conns'] += self.timer.diff()


    def connect_noise(self):
        """
            # # # # # # # # # # # # # # # # 
            #     N O I S E   I N P U T   #
            # # # # # # # # # # # # # # # # 
        """
        if self.pc_id == 0:
            print "Connecting noise - exc ... "
        noise_pop_exc = []
        noise_pop_inh = []
        for tgt in self.local_idx_exc:
            #new
            if (self.params['simulator'] == 'nest'): # for nest one can use the optimized Poisson generator
                noise_exc = create(native_cell_type('poisson_generator'), {'rate' : self.params['f_exc_noise']})
                noise_inh = create(native_cell_type('poisson_generator'), {'rate' : self.params['f_inh_noise']})
            else:
                noise_exc = create(SpikeSourcePoisson, {'rate' : self.params['f_exc_noise']})
                noise_inh = create(SpikeSourcePoisson, {'rate' : self.params['f_inh_noise']})
            connect(noise_exc, self.exc_pop[tgt], weight=self.params['w_exc_noise'], synapse_type='excitatory', delay=1.)
            connect(noise_inh, self.exc_pop[tgt], weight=self.params['w_inh_noise'], synapse_type='inhibitory', delay=1.)

#        if self.pc_id == 0:
#            print "Connecting noise - inh ... "
#        for tgt in self.local_idx_inh:
#            if (self.params['simulator'] == 'nest'): # for nest one can use the optimized Poisson generator
#                noise_exc = create(native_cell_type('poisson_generator'), {'rate' : self.params['f_exc_noise']})
#                noise_inh = create(native_cell_type('poisson_generator'), {'rate' : self.params['f_inh_noise']})
#            else:
#                noise_exc = create(SpikeSourcePoisson, {'rate' : self.params['f_exc_noise']})
#                noise_inh = create(SpikeSourcePoisson, {'rate' : self.params['f_inh_noise']})
#            connect(noise_exc, self.inh_pop[tgt], weight=self.params['w_exc_noise'], synapse_type='excitatory', delay=1.)
#            connect(noise_inh, self.inh_pop[tgt], weight=self.params['w_inh_noise'], synapse_type='inhibitory', delay=1.)





    def run_sim(self, sim_cnt, record_v=True):
        # # # # # # # # # # # # # # # # # # # #
        #     P R I N T    W E I G H T S      # 
        # # # # # # # # # # # # # # # # # # # #
        record_exc = True
        if os.path.exists(self.params['gids_to_record_fn']):
            gids_to_record = np.loadtxt(self.params['gids_to_record_fn'], dtype='int')[:self.params['n_gids_to_record']]
            record_exc = True
            n_rnd_cells_to_record = 2
        else:
            n_cells_to_record = 5# self.params['n_exc'] * 0.02
            gids_to_record = np.random.randint(0, self.params['n_exc'], n_cells_to_record)


        if record_v:
            self.exc_pop_view = PopulationView(self.exc_pop, gids_to_record, label='good_exc_neurons')
            self.exc_pop_view.record_v()

        self.exc_pop.record()
        self.times['t_record'] = self.timer.diff()

        if self.pc_id == 0:
            print "Running simulation ... "
        run(self.params['t_sim'])
        self.times['t_sim'] = self.timer.diff()


    def print_results(self, print_v=True):
        """
            # # # # # # # # # # # # # # # # #
            #     P R I N T    R E S U L T S 
            # # # # # # # # # # # # # # # # #
        """
        if print_v:
            if self.pc_id == 0:
                print 'print_v to file: %s.v' % (self.params['exc_volt_fn_base'])
            self.exc_pop_view.print_v("%s.v" % (self.params['exc_volt_fn_base']), compatible_output=False)

        if self.pc_id == 0:
            print "Printing excitatory spikes"
        self.exc_pop.printSpikes(self.params['exc_spiketimes_fn_merged'] + '.ras')
        # print a dummy file for inhibitory
        np.savetxt(self.params['inh_spiketimes_fn_merged'] + '.ras', np.array([]))

        self.times['t_print'] = self.timer.diff()
        if self.pc_id == 0:
            print "calling pyNN.end() ...."
        end()
        self.times['t_end'] = self.timer.diff()

        if self.pc_id == 0:
            self.times['t_all'] = 0.
            for k in self.times.keys():
                self.times['t_all'] += self.times[k]

            self.n_cells = {}
            self.n_cells['n_exc'] = self.params['n_exc']
            self.n_cells['n_inh'] = self.params['n_inh']
            self.n_cells['n_cells'] = self.params['n_cells']
            self.n_cells['n_proc'] = self.n_proc
            output = {'times' : self.times, 'n_cells_proc' : self.n_cells}
            print "Proc %d Simulation time: %d sec or %.1f min for %d cells (%d exc %d inh)" % (self.pc_id, self.times['t_sim'], (self.times['t_sim'])/60., self.params['n_cells'], self.params['n_exc'], self.params['n_inh'])
            print "Proc %d Full pyNN run time: %d sec or %.1f min for %d cells (%d exc %d inh)" % (self.pc_id, self.times['t_all'], (self.times['t_all'])/60., self.params['n_cells'], self.params['n_exc'], self.params['n_inh'])
            fn = utils.convert_to_url(params['folder_name'] + 'times_dict_np%d.py' % self.n_proc)
            output = ntp.ParameterSet(output)
            output.save(fn)