def create_connectivity(self, conn_type):
        """
        This function (re-) creates the network connectivity.
        """

        # distribute the cell ids among involved processes
        (n_src, n_tgt, self.tp_src, self.tp_tgt) = utils.resolve_src_tgt_with_tp(conn_type, self.params)

        print 'Connect anisotropic %s - %s' % (conn_type[0].capitalize(), conn_type[1].capitalize())

        gid_tgt_min, gid_tgt_max = utils.distribute_n(n_tgt, self.n_proc, self.pc_id)
        print 'Process %d deals with target GIDS %d - %d' % (self.pc_id, gid_tgt_min, gid_tgt_max)
        gid_src_min, gid_src_max = utils.distribute_n(n_src, self.n_proc, self.pc_id)
        print 'Process %d deals with source GIDS %d - %d' % (self.pc_id, gid_src_min, gid_src_max)
        n_my_tgts = gid_tgt_max - gid_tgt_min

        # data structure for connection storage
        self.target_adj_list = [ [] for i in xrange(n_my_tgts)]

        n_src_cells_per_neuron = int(round(self.params['p_%s' % conn_type] * n_src))

        # compute all pairwise connection probabilities
        for i_, tgt in enumerate(range(gid_tgt_min, gid_tgt_max)):
            if (i_ % 20) == 0:
                print '%.2f percent complete' % (i_ / float(n_my_tgts) * 100.)
            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(self.tp_src[src, :], self.tp_tgt[tgt, :], params['w_sigma_x'], params['w_sigma_v'], params['connectivity_radius'])
                else: # different populations --> same indices mean different cells, no check for src != tgt
                    p[src], latency[src] = CC.get_p_conn(self.tp_src[src, :], self.tp_tgt[tgt, :], params['w_sigma_x'], params['w_sigma_v'], params['connectivity_radius'])
            # sort connection probabilities and select remaining connections
            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']:
                    delay = min(max(latency[sources[i]] * self.params['delay_scale'], self.params['delay_range'][0]), self.params['delay_range'][1])  # map the delay into the valid range
                    # create adjacency list for all local cells and store connection in class container
                    self.target_adj_list[i_].append(sources[i])


        # communicate the resulting target_adj_list to the root process
        self.send_list_to_root(self.target_adj_list)
    def plot_tuning_vs_conn_cg(self, conn_type, show=False):
        """
        For each source cell, loop through all target connections and compute the
        scalar (dot) product between the preferred direction of the source cell and the center of gravity of the connection vector
        (both in the spatial domain and the direction domain)
        c_x_i = sum_j w_ij * (x_i - x_j) # x_ are position vectors of the cell
        c_v_i = sum_j w_ij * (v_i - v_j) # v_ are preferred directions
        """
        (n_src, n_tgt, tp_src, tp_tgt) = utils.resolve_src_tgt_with_tp(conn_type, self.params)
        fn = self.params['merged_conn_list_%s' % conn_type]
        print 'Loading:', fn
        if not os.path.exists(fn):
            print 'Merging connlists ...'
            cmd = 'python merge_connlists.py %s' % self.params['params_fn']
            os.system(cmd)

        conn_list = np.loadtxt(fn)

#        conn_mat_fn = self.params['conn_mat_fn_base'] + '%s.dat' % (conn_type)
#        if os.path.exists(conn_mat_fn):
#            print 'Loading', conn_mat_fn
#            w = np.loadtxt(conn_mat_fn)
#        else:
#            w, delays = utils.convert_connlist_to_matrix(params['merged_conn_list_%s' % conn_type], n_src, n_tgt)
#            print 'Saving:', conn_mat_fn
#            np.savetxt(conn_mat_fn, w)

        # for all source cells store the length of the vector:
        # (connection centroid - preferred direction)
        diff_conn_centroid_x_vsrc = np.zeros(n_src)
        diff_conn_centroid_v_vsrc = np.zeros(n_src)
        angles_x = np.zeros(n_src)
        angles_v = np.zeros(n_src)
        # deprecated
#        cx_ = np.zeros(n_src) # stores the scalar products
#        cv_ = np.zeros(n_src) # stores the scalar products
        for i in xrange(n_src):
            src_gid = i
            targets = utils.get_targets(conn_list, src_gid)
            weights = targets[:, 2]
            targets = np.array(targets[:, 1], dtype=np.int)
#            weights = w[src_gid, targets]
            if weights.size > 0:
                c_x, c_v = self.get_cg_vec(tp_src[src_gid, :], tp_tgt[targets, :], weights)
            else:
                c_x, c_v = [(0, 0), (0, 0)]

            (x_src, y_src, vx_src, vy_src) = tp_src[src_gid, :]
#            cx_[i] = np.abs(np.dot(c_x, (vx_src, vy_src)))
#            cv_[i] = np.abs(np.dot(c_v, (vx_src, vy_src)))

            vector_conn_centroid_x_minus_vsrc = (c_x[0] - vx_src, c_x[1] - vy_src)
            vector_conn_centroid_v_minus_vsrc = (c_v[0] - vx_src, c_v[1] - vy_src)
#            angles_x[i] = np.arc((c_x[
            diff_conn_centroid_x_vsrc[i] = np.sqrt(np.dot(vector_conn_centroid_x_minus_vsrc, vector_conn_centroid_x_minus_vsrc))
            diff_conn_centroid_v_vsrc[i] = np.sqrt(np.dot(vector_conn_centroid_v_minus_vsrc, vector_conn_centroid_v_minus_vsrc))


        print 'diff_conn_centroid_x_vsrc mean %.2e +- %.2e' % (diff_conn_centroid_x_vsrc.mean(), diff_conn_centroid_x_vsrc.std())
        print 'diff_conn_centroid_v_vsrc mean %.2e +- %.2e' % (diff_conn_centroid_v_vsrc.mean(), diff_conn_centroid_v_vsrc.std())
#        cx_mean = cx_.mean()
#        cx_sem = cx_.std() / np.sqrt(cx_.size)
#        cv_mean = cv_.mean()
#        cv_sem = cv_.std() / np.sqrt(cv_.size)
        cx_mean = diff_conn_centroid_x_vsrc.mean()
        cx_sem = diff_conn_centroid_x_vsrc.std() / np.sqrt(n_src)
        cv_mean = diff_conn_centroid_v_vsrc.mean()
        cv_sem = diff_conn_centroid_v_vsrc.std() / np.sqrt(n_src)

        output_fn = self.params['data_folder'] + 'mean_length_of_vector_diff_tuning_prop_minus_cgxv.dat'
        output_data = np.array((diff_conn_centroid_x_vsrc, diff_conn_centroid_v_vsrc)).transpose()
#        output_data = np.array((diff_conn_centroid_x_vsrc, diff_conn_centroid_v_vsrc, cx_, cv_)).transpose()
        print 'Saving to:', output_fn
        np.savetxt(output_fn, output_data)

        fig = pylab.figure(figsize=(12, 10))
        pylab.subplots_adjust(hspace=0.35)
        ax1 = fig.add_subplot(211)
        ax2 = fig.add_subplot(212)
        x = range(n_src)
        ax1.set_xlabel('source cell')
        ax1.set_ylabel('$|\\vec{v}_i - \\vec{c}_i^X|$')
        title = '$\langle|\\vec{v}_i - \\vec{c}_i^X| \\rangle = %.2e \pm %.1e$' % (cx_mean, cx_sem)
        ax1.bar(x, diff_conn_centroid_x_vsrc)
        ax1.set_title('Length of difference vector: preferred direction $\\vec{v}_i$ and connection centroid $\\vec{c}_i^x$\n%s' % title)
        ax1.set_xlim((0, n_src))
#        ax1.legend()

        ax2.bar(x, diff_conn_centroid_v_vsrc)
        ax2.set_xlabel('source cell')
        ax1.set_ylabel('$|\\vec{v}_i - \\vec{c}_i^V|$')
        title = '$\langle|\\vec{v}_i - \\vec{c}_i^V| \\rangle = %.2e \pm %.1e$' % (cv_mean, cv_sem)
        ax2.set_title(title)
        ax2.set_xlim((0, n_src))
#        ax2.legend()
        output_fig = self.params['figures_folder'] + 'mean_length_of_vector_diff_tuning_prop_minus_cgxv.png'
        print 'Saving to:', output_fig
        pylab.savefig(output_fig)
        if show:
            pylab.show()