예제 #1
0
def perform_thresholding(conn_matrix, thr, min_span_tree, dens_thresh,
                         disp_filt):
    """

    References
    ----------
    .. [1] Fornito, A., Zalesky, A., & Bullmore, E. T. (2016).
      Fundamentals of Brain Network Analysis. In Fundamentals of Brain Network
      Analysis. https://doi.org/10.1016/C2012-0-06036-X

    """
    import numpy as np
    import networkx as nx
    from pynets.core import thresholding

    thr_perc = 100 - np.abs(100 * float(thr))

    if min_span_tree is True:
        print("Using local thresholding from the "
              "Minimum Spanning Tree (MST)...\n")
        if dens_thresh is True:
            print("Ignoring -dt flag since local density thresholding is not"
                  " currently supported.")
        thr_type = "MST"
        edge_threshold = f"{str(thr_perc)}%"
        conn_matrix_thr = thresholding.local_thresholding_prop(
            conn_matrix, thr)
    elif disp_filt is True:

        thr_type = "DISPARITY"
        edge_threshold = f"{str(thr_perc)}%"
        G1 = thresholding.disparity_filter(
            nx.from_numpy_array(np.abs(conn_matrix)))
        print(f"Computing edge disparity significance with alpha = {thr}")
        print(f"Filtered graph: nodes = {G1.number_of_nodes()}, "
              f"edges = {G1.number_of_edges()}")
        conn_matrix_bin = thresholding.binarize(
            nx.to_numpy_array(G1,
                              nodelist=sorted(G1.nodes()),
                              dtype=np.float64))
        # Enforce original dimensionality by padding with zeros.
        conn_matrix_thr = np.multiply(conn_matrix, conn_matrix_bin)
    else:
        if dens_thresh is False:
            thr_type = "PROP"
            edge_threshold = f"{str(thr_perc)}{'%'}"
            print(f"\nThresholding proportionally at: {thr_perc}% ...\n")
            conn_matrix_thr = thresholding.threshold_proportional(
                conn_matrix, float(thr))
        else:
            thr_type = "DENS"
            edge_threshold = None
            print(f"\nThresholding to achieve density of: {thr_perc}% ...\n")
            conn_matrix_thr = thresholding.density_thresholding(
                conn_matrix, float(thr))
    return thr_type, edge_threshold, conn_matrix_thr
예제 #2
0
def plot_conn_mat(conn_matrix,
                  labels,
                  out_path_fig,
                  cmap,
                  binarized=False,
                  dpi_resolution=300):
    """
    Plot a connectivity matrix.

    Parameters
    ----------
    conn_matrix : array
        NxN matrix.
    labels : list
        List of string labels corresponding to ROI nodes.
    out_path_fig : str
        File path to save the connectivity matrix image as a .png figure.
    """
    import matplotlib

    matplotlib.use("agg")
    from matplotlib import pyplot as plt
    from nilearn.plotting import plot_matrix
    from pynets.core import thresholding
    import matplotlib.ticker as mticker

    conn_matrix = thresholding.standardize(conn_matrix)
    conn_matrix_bin = thresholding.binarize(conn_matrix)
    conn_matrix_plt = np.nan_to_num(np.multiply(conn_matrix, conn_matrix_bin))

    try:
        plot_matrix(
            conn_matrix_plt,
            figure=(10, 10),
            labels=labels,
            vmax=np.percentile(conn_matrix_plt[conn_matrix_plt > 0], 95),
            vmin=np.min(conn_matrix_plt) - 0.000001,
            reorder="average",
            auto_fit=True,
            grid=False,
            colorbar=False,
            cmap=cmap,
        )
    except RuntimeWarning:
        print("Connectivity matrix too sparse for plotting...")

    if len(labels) > 40:
        tick_interval = int(np.around(len(labels) / 40))
    else:
        tick_interval = int(np.around(len(labels)))
    plt.axes().yaxis.set_major_locator(mticker.MultipleLocator(tick_interval))
    plt.axes().xaxis.set_major_locator(mticker.MultipleLocator(tick_interval))
    plt.savefig(out_path_fig, dpi=dpi_resolution)
    plt.close()
    return
예제 #3
0
def test_weighted_transitivity(binarize):
    """ Test weighted_transitivity computation
    """
    from pynets.core.thresholding import binarize

    base_dir = str(Path(__file__).parent/"examples")
    est_path = f"{base_dir}/miscellaneous/sub-0021001_rsn-Default_nodetype-parc_model-sps_template-MNI152_T1_thrtype-DENS_thr-0.19.npy"

    in_mat = np.load(est_path)
    if binarize:
        in_mat = binarize(in_mat)

    G = nx.from_numpy_array(in_mat)

    transitivity = netstats.weighted_transitivity(G)

    assert transitivity <= 3
    assert transitivity >= 0
예제 #4
0
def plot_conn_mat(conn_matrix, labels, out_path_fig, cmap, dpi_resolution=300):
    """
    Plot a connectivity matrix.

    Parameters
    ----------
    conn_matrix : array
        NxN matrix.
    labels : list
        List of string labels corresponding to ROI nodes.
    out_path_fig : str
        File path to save the connectivity matrix image as a .png figure.
    """
    import matplotlib

    matplotlib.use("agg")
    from matplotlib import pyplot as plt
    from nilearn.plotting import plot_matrix
    from pynets.core import thresholding

    conn_matrix_bin = thresholding.binarize(conn_matrix)
    conn_matrix = thresholding.standardize(conn_matrix)
    conn_matrix_plt = np.nan_to_num(np.multiply(conn_matrix, conn_matrix_bin))

    try:
        plot_matrix(
            conn_matrix_plt,
            figure=(10, 10),
            labels=labels,
            vmax=np.abs(np.max(conn_matrix_plt)),
            vmin=-np.abs(np.max(conn_matrix_plt)),
            reorder="average",
            auto_fit=True,
            grid=False,
            colorbar=False,
            cmap=cmap,
        )
    except RuntimeWarning:
        print("Connectivity matrix too sparse for plotting...")
    plt.savefig(out_path_fig, dpi=dpi_resolution)
    plt.close()
    return
예제 #5
0
 def test_binarize(x, thr, cp):
     y = thresholding.threshold_proportional(x, thr, copy=cp)
     s = thresholding.binarize(y)
     assert np.sum(s) == np.count_nonzero(y)
예제 #6
0
def plot_community_conn_mat(conn_matrix,
                            labels,
                            out_path_fig_comm,
                            community_aff,
                            cmap,
                            dpi_resolution=300):
    """
    Plot a community-parcellated connectivity matrix.

    Parameters
    ----------
    conn_matrix : array
        NxN matrix.
    labels : list
        List of string labels corresponding to ROI nodes.
    out_path_fig_comm : str
        File path to save the community-parcellated connectivity matrix image
        as a .png figure.
    community_aff : array
        Community-affiliation vector.
    """
    import warnings
    warnings.filterwarnings("ignore")
    from matplotlib import pyplot as plt
    matplotlib.use("agg")
    import mplcyberpunk
    plt.style.use("cyberpunk")
    import matplotlib.patches as patches
    import matplotlib.ticker as mticker
    matplotlib.use("agg")
    from nilearn.plotting import plot_matrix
    from pynets.core import thresholding

    plt.style.use("cyberpunk")

    conn_matrix_bin = thresholding.binarize(conn_matrix)
    conn_matrix = thresholding.standardize(conn_matrix)
    conn_matrix_plt = np.nan_to_num(np.multiply(conn_matrix, conn_matrix_bin))

    sorting_array = sorted(range(len(community_aff)),
                           key=lambda k: community_aff[k])
    sorted_conn_matrix = conn_matrix[sorting_array, :]
    sorted_conn_matrix = sorted_conn_matrix[:, sorting_array]
    rois_num = sorted_conn_matrix.shape[0]
    if rois_num < 100:
        try:
            plot_matrix(
                conn_matrix_plt,
                figure=(10, 10),
                labels=labels,
                vmax=np.percentile(conn_matrix_plt[conn_matrix_plt > 0], 95),
                vmin=0,
                reorder=False,
                auto_fit=True,
                grid=False,
                colorbar=False,
                cmap=cmap,
            )
        except RuntimeWarning:
            print("Connectivity matrix too sparse for plotting...")
    else:
        try:
            plot_matrix(
                conn_matrix_plt,
                figure=(10, 10),
                vmax=np.abs(np.max(conn_matrix_plt)),
                vmin=0,
                auto_fit=True,
                grid=False,
                colorbar=False,
                cmap=cmap,
            )
        except RuntimeWarning:
            print("Connectivity matrix too sparse for plotting...")

    ax = plt.gca()
    total_size = 0
    for community in np.unique(community_aff):
        size = sum(sorted(community_aff) == community)
        ax.add_patch(
            patches.Rectangle(
                (total_size, total_size),
                size,
                size,
                fill=False,
                edgecolor="white",
                alpha=None,
                linewidth=1,
            ))
        total_size += size

    if len(labels) > 500:
        tick_interval = 5
    elif len(labels) > 100:
        tick_interval = 4
    elif len(labels) > 50:
        tick_interval = 2
    else:
        tick_interval = 1

    plt.axes().yaxis.set_major_locator(mticker.MultipleLocator(tick_interval))
    plt.axes().xaxis.set_major_locator(mticker.MultipleLocator(tick_interval))
    for param in ['figure.facecolor', 'axes.facecolor', 'savefig.facecolor']:
        plt.rcParams[param] = '#000000'
    plt.savefig(out_path_fig_comm, dpi=dpi_resolution)
    plt.close()
    return
예제 #7
0
def plot_conn_mat(conn_matrix,
                  labels,
                  out_path_fig,
                  cmap,
                  binarized=False,
                  dpi_resolution=300):
    """
    Plot a connectivity matrix.

    Parameters
    ----------
    conn_matrix : array
        NxN matrix.
    labels : list
        List of string labels corresponding to ROI nodes.
    out_path_fig : str
        File path to save the connectivity matrix image as a .png figure.
    """
    import warnings
    warnings.filterwarnings("ignore")
    import matplotlib
    import mplcyberpunk
    from matplotlib import pyplot as plt
    matplotlib.use("agg")
    plt.style.use("cyberpunk")
    from matplotlib import pyplot as plt
    from nilearn.plotting import plot_matrix
    from pynets.core import thresholding
    import matplotlib.ticker as mticker

    conn_matrix = thresholding.standardize(conn_matrix)
    conn_matrix_bin = thresholding.binarize(conn_matrix)
    conn_matrix_plt = np.nan_to_num(np.multiply(conn_matrix, conn_matrix_bin))

    try:
        plot_matrix(
            conn_matrix_plt,
            figure=(10, 10),
            labels=labels,
            vmax=np.percentile(conn_matrix_plt[conn_matrix_plt > 0], 95),
            vmin=0,
            reorder="average",
            auto_fit=True,
            grid=False,
            colorbar=False,
            cmap=cmap,
        )
    except RuntimeWarning:
        print("Connectivity matrix too sparse for plotting...")

    if len(labels) > 500:
        tick_interval = 5
    elif len(labels) > 100:
        tick_interval = 4
    elif len(labels) > 50:
        tick_interval = 2
    else:
        tick_interval = 1

    plt.axes().yaxis.set_major_locator(mticker.MultipleLocator(tick_interval))
    plt.axes().xaxis.set_major_locator(mticker.MultipleLocator(tick_interval))
    for param in ['figure.facecolor', 'axes.facecolor', 'savefig.facecolor']:
        plt.rcParams[param] = '#000000'
    plt.savefig(out_path_fig, dpi=dpi_resolution)
    plt.close()
    return
예제 #8
0
def plot_community_conn_mat(conn_matrix,
                            labels,
                            out_path_fig_comm,
                            community_aff,
                            cmap,
                            dpi_resolution=300):
    """
    Plot a community-parcellated connectivity matrix.

    Parameters
    ----------
    conn_matrix : array
        NxN matrix.
    labels : list
        List of string labels corresponding to ROI nodes.
    out_path_fig_comm : str
        File path to save the community-parcellated connectivity matrix image
        as a .png figure.
    community_aff : array
        Community-affiliation vector.
    """
    import warnings
    warnings.filterwarnings("ignore")
    import sys
    import pkg_resources
    import yaml
    import matplotlib
    import matplotlib.pyplot as plt
    import matplotlib.patches as patches
    import matplotlib.ticker as mticker
    matplotlib.use("agg")
    from nilearn.plotting import plot_matrix
    from pynets.core import thresholding

    conn_matrix_bin = thresholding.binarize(conn_matrix)
    conn_matrix = thresholding.standardize(conn_matrix)
    conn_matrix_plt = np.nan_to_num(np.multiply(conn_matrix, conn_matrix_bin))

    try:
        with open(pkg_resources.resource_filename("pynets", "runconfig.yaml"),
                  "r") as stream:
            hardcoded_params = yaml.load(stream)
            try:
                labeling_atlas = \
                hardcoded_params["plotting"]["labeling_atlas"][0]
            except KeyError:
                print(
                    "ERROR: Plotting configuration not successfully extracted"
                    " from runconfig.yaml")
                sys.exit(0)
        stream.close()
        labels = [i[0][labeling_atlas] for i in labels]
    except BaseException:
        pass

    sorting_array = sorted(range(len(community_aff)),
                           key=lambda k: community_aff[k])
    sorted_conn_matrix = conn_matrix[sorting_array, :]
    sorted_conn_matrix = sorted_conn_matrix[:, sorting_array]
    rois_num = sorted_conn_matrix.shape[0]
    if rois_num < 100:
        try:
            plot_matrix(
                conn_matrix_plt,
                figure=(10, 10),
                labels=labels,
                vmax=np.percentile(conn_matrix_plt[conn_matrix_plt > 0], 95),
                vmin=0,
                reorder=False,
                auto_fit=True,
                grid=False,
                colorbar=False,
                cmap=cmap,
            )
        except RuntimeWarning:
            print("Connectivity matrix too sparse for plotting...")
    else:
        try:
            plot_matrix(
                conn_matrix_plt,
                figure=(10, 10),
                vmax=np.abs(np.max(conn_matrix_plt)),
                vmin=0,
                auto_fit=True,
                grid=False,
                colorbar=False,
                cmap=cmap,
            )
        except RuntimeWarning:
            print("Connectivity matrix too sparse for plotting...")

    ax = plt.gca()
    total_size = 0
    for community in np.unique(community_aff):
        size = sum(sorted(community_aff) == community)
        ax.add_patch(
            patches.Rectangle(
                (total_size, total_size),
                size,
                size,
                fill=False,
                edgecolor="black",
                alpha=None,
                linewidth=1,
            ))
        total_size += size

    tick_interval = int(np.around(len(labels))) / 20
    plt.axes().yaxis.set_major_locator(mticker.MultipleLocator(tick_interval))
    plt.axes().xaxis.set_major_locator(mticker.MultipleLocator(tick_interval))
    plt.savefig(out_path_fig_comm, dpi=dpi_resolution)
    plt.close()
    return
예제 #9
0
def plot_conn_mat(conn_matrix,
                  labels,
                  out_path_fig,
                  cmap,
                  binarized=False,
                  dpi_resolution=300):
    """
    Plot a connectivity matrix.

    Parameters
    ----------
    conn_matrix : array
        NxN matrix.
    labels : list
        List of string labels corresponding to ROI nodes.
    out_path_fig : str
        File path to save the connectivity matrix image as a .png figure.
    """
    import warnings
    warnings.filterwarnings("ignore")
    import matplotlib
    matplotlib.use("agg")
    import sys
    import pkg_resources
    import yaml
    from matplotlib import pyplot as plt
    from nilearn.plotting import plot_matrix
    from pynets.core import thresholding
    import matplotlib.ticker as mticker

    conn_matrix = thresholding.standardize(conn_matrix)
    conn_matrix_bin = thresholding.binarize(conn_matrix)
    conn_matrix_plt = np.nan_to_num(np.multiply(conn_matrix, conn_matrix_bin))

    try:
        with open(pkg_resources.resource_filename("pynets", "runconfig.yaml"),
                  "r") as stream:
            hardcoded_params = yaml.load(stream)
            try:
                labeling_atlas = \
                hardcoded_params["plotting"]["labeling_atlas"][0]
            except KeyError:
                print(
                    "ERROR: Plotting configuration not successfully extracted"
                    " from runconfig.yaml")
                sys.exit(0)
        stream.close()
        labels = [i[0][labeling_atlas] for i in labels]
    except BaseException:
        pass

    try:
        plot_matrix(
            conn_matrix_plt,
            figure=(10, 10),
            labels=labels,
            vmax=np.percentile(conn_matrix_plt[conn_matrix_plt > 0], 95),
            vmin=0,
            reorder="average",
            auto_fit=True,
            grid=False,
            colorbar=False,
            cmap=cmap,
        )
    except RuntimeWarning:
        print("Connectivity matrix too sparse for plotting...")

    tick_interval = int(np.around(len(labels))) / 20
    plt.axes().yaxis.set_major_locator(mticker.MultipleLocator(tick_interval))
    plt.axes().xaxis.set_major_locator(mticker.MultipleLocator(tick_interval))
    plt.savefig(out_path_fig, dpi=dpi_resolution)
    plt.close()
    return
예제 #10
0
def perform_thresholding(conn_matrix, coords, labels, thr, thr_perc,
                         min_span_tree, dens_thresh, disp_filt):
    from pynets.core import thresholding
    if min_span_tree is True:
        print(
            'Using local thresholding option with the Minimum Spanning Tree (MST)...\n'
        )
        if dens_thresh is True:
            print(
                'Ignoring -dt flag since local density thresholding is not currently supported.'
            )
        thr_type = 'MST_thr'
        edge_threshold = "%s%s" % (str(thr_perc), '%')
        [conn_matrix_thr, coords, labels
         ] = thresholding.local_thresholding_prop(conn_matrix, coords, labels,
                                                  thr)
    elif disp_filt is True:
        thr_type = 'DISP_alpha'
        edge_threshold = "%s%s" % (str(thr_perc), '%')
        G1 = thresholding.disparity_filter(
            nx.from_numpy_array(np.abs(conn_matrix)))
        # G2 = nx.Graph([(u, v, d) for u, v, d in G1.edges(data=True) if d['alpha'] < thr])
        print('Computing edge disparity significance with alpha = %s' % thr)
        print('Filtered graph: nodes = %s, edges = %s' %
              (G1.number_of_nodes(), G1.number_of_edges()))
        # print('Backbone graph: nodes = %s, edges = %s' % (G2.number_of_nodes(), G2.number_of_edges()))
        # print(G2.edges(data=True))
        conn_matrix_bin = thresholding.binarize(
            nx.to_numpy_array(G1,
                              nodelist=sorted(G1.nodes()),
                              dtype=np.float64))
        # Enforce original dimensionality by padding with zeros.
        if conn_matrix_bin.shape != conn_matrix.shape:
            if conn_matrix.shape[0] > conn_matrix_bin.shape[0]:
                result = np.zeros(conn_matrix.shape)
                result[:conn_matrix_bin.shape[0], :conn_matrix_bin.
                       shape[1]] = conn_matrix_bin
                conn_matrix_thr = np.multiply(conn_matrix, result)
            else:
                result = np.zeros(conn_matrix_bin.shape)
                result[:conn_matrix.shape[0], :conn_matrix.
                       shape[1]] = conn_matrix
                conn_matrix_thr = np.multiply(conn_matrix_bin, result)
        else:
            conn_matrix_thr = np.multiply(conn_matrix, conn_matrix_bin)
    else:
        if dens_thresh is False:
            thr_type = 'prop'
            edge_threshold = "%s%s" % (str(thr_perc), '%')
            print("%s%.2f%s" %
                  ('\nThresholding proportionally at: ', thr_perc, '% ...\n'))
            conn_matrix_thr = thresholding.threshold_proportional(
                conn_matrix, float(thr))
        else:
            thr_type = 'dens'
            edge_threshold = None
            print("%s%.2f%s" % ('\nThresholding to achieve density of: ',
                                thr_perc, '% ...\n'))
            conn_matrix_thr = thresholding.density_thresholding(
                conn_matrix, float(thr))
    return thr_type, edge_threshold, conn_matrix_thr, coords, labels
예제 #11
0
def local_thresholding_prop(conn_matrix, coords, labels, thr):
    """
    Threshold the adjacency matrix by building from the minimum spanning tree (MST) and adding
    successive N-nearest neighbour degree graphs to achieve target proportional threshold.

    Parameters
    ----------
    conn_matrix : array
        Weighted NxN matrix.
    thr : float
        A proportional threshold, between 0 and 1, to achieve through local thresholding.

    Returns
    -------
    conn_matrix_thr : array
        Weighted, MST local-thresholded, NxN matrix.
    """
    from pynets.core import thresholding
    from pynets.stats import netstats

    fail_tol = 100
    conn_matrix = np.nan_to_num(conn_matrix)
    G = nx.from_numpy_matrix(np.abs(conn_matrix))
    if not nx.is_connected(G):
        [G, pruned_nodes] = netstats.prune_disconnected(G)
        pruned_nodes.sort(reverse=True)
        coords_pre = list(coords)
        labels_pre = list(labels)
        if len(pruned_nodes) > 0:
            for j in pruned_nodes:
                labels_pre.pop(j)
                coords_pre.pop(j)
            conn_matrix = nx.to_numpy_array(G)
            labels = labels_pre
            coords = coords_pre

    maximum_edges = G.number_of_edges()
    min_t = nx.minimum_spanning_tree(thresholding.weight_to_distance(G),
                                     weight="distance")
    len_edges = min_t.number_of_edges()
    upper_values = np.triu_indices(np.shape(conn_matrix)[0], k=1)
    weights = np.array(conn_matrix[upper_values])
    edgenum = int(float(thr) * float(len(weights[~np.isnan(weights)])))

    if len_edges > edgenum:
        print("%s%s%s" % (
            'Warning: The minimum spanning tree already has: ', len_edges,
            ' edges, select more edges. Local Threshold will be applied by just retaining the Minimum '
            'Spanning Tree'))
        conn_matrix_thr = nx.to_numpy_array(G)
        return conn_matrix_thr, coords, labels

    k = 1
    len_edge_list = []
    while len_edges < edgenum and k <= np.shape(conn_matrix)[0] and (
            len(len_edge_list[-fail_tol:]) -
            len(set(len_edge_list[-fail_tol:]))) < (fail_tol - 1):
        # print(k)
        # print(len_edges)
        len_edge_list.append(len_edges)
        # Create nearest neighbour graph
        nng = thresholding.knn(conn_matrix, k)

        # Remove edges from the NNG that exist already in the new graph/MST
        nng.remove_edges_from(min_t.edges())

        number_before = nng.number_of_edges()
        if nng.number_of_edges() == 0 and number_before >= maximum_edges:
            break

        # Add weights to NNG
        for e in nng.edges():
            nng.edges[e[0], e[1]]['weight'] = float(conn_matrix[e[0], e[1]])

        # Obtain list of edges from the NNG in order of weight
        edge_list = sorted(nng.edges(data=True),
                           key=lambda t: t[2]['weight'],
                           reverse=True)

        # Add edges in order of connectivity strength
        for edge in edge_list:
            # print("%s%s" % ('Adding edge to mst: ', edge))
            min_t.add_edges_from([edge])
            len_edges = min_t.number_of_edges()
            if len_edges >= edgenum:
                print(len_edges)
                break
        k += 1

    conn_matrix_bin = thresholding.binarize(
        nx.to_numpy_array(min_t,
                          nodelist=sorted(min_t.nodes()),
                          dtype=np.float64))

    # Enforce original dimensionality by padding with zeros.
    if conn_matrix_bin.shape != conn_matrix.shape:
        if conn_matrix.shape[0] > conn_matrix_bin.shape[0]:
            result = np.zeros(conn_matrix.shape)
            result[:conn_matrix_bin.shape[0], :conn_matrix_bin.
                   shape[1]] = conn_matrix_bin
            conn_matrix_thr = np.multiply(conn_matrix, result)
        else:
            result = np.zeros(conn_matrix_bin.shape)
            result[:conn_matrix.shape[0], :conn_matrix.shape[1]] = conn_matrix
            conn_matrix_thr = np.multiply(conn_matrix_bin, result)
    else:
        conn_matrix_thr = np.multiply(conn_matrix, conn_matrix_bin)

    return conn_matrix_thr, coords, labels
예제 #12
0
def local_thresholding_prop(conn_matrix, thr):
    """
    Threshold the adjacency matrix by building from the minimum spanning tree (MST) and adding
    successive N-nearest neighbour degree graphs to achieve target proportional threshold.

    Parameters
    ----------
    conn_matrix : array
        Weighted NxN matrix.
    thr : float
        A proportional threshold, between 0 and 1, to achieve through local thresholding.

    Returns
    -------
    conn_matrix_thr : array
        Weighted local-thresholding using MST, NxN matrix.

    References
    ----------
    .. [1] Alexander-Bloch, A. F., Gogtay, N., Meunier, D., Birn, R., Clasen, L.,
      Lalonde, F., … Bullmore, E. T. (2010). Disrupted modularity and local
      connectivity of brain functional networks in childhood-onset schizophrenia.
      Frontiers in Systems Neuroscience. https://doi.org/10.3389/fnsys.2010.00147
    .. [2] Tewarie, P., van Dellen, E., Hillebrand, A., & Stam, C. J. (2015).
      The minimum spanning tree: An unbiased method for brain network analysis.
      NeuroImage. https://doi.org/10.1016/j.neuroimage.2014.10.015

    """
    from pynets.core import thresholding

    fail_tol = 100
    conn_matrix = np.nan_to_num(conn_matrix)
    G = nx.from_numpy_matrix(np.abs(conn_matrix))

    maximum_edges = G.number_of_edges()

    Gcc = sorted(nx.connected_components(G), key=len, reverse=True)
    G0 = G.subgraph(Gcc[0])

    min_t = nx.minimum_spanning_tree(thresholding.weight_to_distance(G0),
                                     weight="distance")
    min_t.add_nodes_from(G.nodes())
    len_edges = min_t.number_of_edges()
    upper_values = np.triu_indices(np.shape(conn_matrix)[0], k=1)
    weights = np.array(conn_matrix[upper_values])
    edgenum = int(float(thr) * float(len(weights[~np.isnan(weights)])))

    if len_edges > edgenum:
        print(
            f"Warning: The minimum spanning tree already has: {len_edges} edges, select more edges. Local Threshold "
            f"will be applied by just retaining the Minimum Spanning Tree")
        conn_matrix_thr = nx.to_numpy_array(G)
        return conn_matrix_thr

    k = 1
    len_edge_list = []
    while (len_edges < edgenum and k <= np.shape(conn_matrix)[0]
           and (len(len_edge_list[-fail_tol:]) -
                len(set(len_edge_list[-fail_tol:]))) < (fail_tol - 1)):
        # print(k)
        # print(len_edges)
        len_edge_list.append(len_edges)
        # Create nearest neighbour graph
        nng = thresholding.knn(conn_matrix, k)

        # Remove edges from the NNG that exist already in the new graph/MST
        nng.remove_edges_from(min_t.edges())

        number_before = nng.number_of_edges()
        if nng.number_of_edges() == 0 and number_before >= maximum_edges:
            break

        # Add weights to NNG
        for e in nng.edges():
            nng.edges[e[0], e[1]]["weight"] = float(conn_matrix[e[0], e[1]])

        # Obtain list of edges from the NNG in order of weight
        edge_list = sorted(nng.edges(data=True),
                           key=lambda t: t[2]["weight"],
                           reverse=True)

        # Add edges in order of connectivity strength
        for edge in edge_list:
            # print(f"Adding edge to mst: {edge}")
            min_t.add_edges_from([edge])
            len_edges = min_t.number_of_edges()
            if len_edges >= edgenum:
                # print(len_edges)
                break
        k += 1

    conn_matrix_bin = thresholding.binarize(
        nx.to_numpy_array(min_t, nodelist=sorted(G.nodes()), dtype=np.float64))

    try:
        conn_matrix_thr = np.multiply(conn_matrix, conn_matrix_bin)
        return conn_matrix_thr

    except ValueError:
        print(
            "MST thresholding failed. Check raw graph output manually for debugging."
        )
예제 #13
0
def plot_community_conn_mat(conn_matrix,
                            labels,
                            out_path_fig_comm,
                            community_aff,
                            cmap,
                            dpi_resolution=300):
    """
    Plot a community-parcellated connectivity matrix.

    Parameters
    ----------
    conn_matrix : array
        NxN matrix.
    labels : list
        List of string labels corresponding to ROI nodes.
    out_path_fig_comm : str
        File path to save the community-parcellated connectivity matrix image as a .png figure.
    community_aff : array
        Community-affiliation vector.
    """
    import matplotlib
    import matplotlib.pyplot as plt
    import matplotlib.patches as patches
    matplotlib.use('agg')
    #from pynets import thresholding
    from nilearn.plotting import plot_matrix
    from pynets.core import thresholding

    conn_matrix_bin = thresholding.binarize(conn_matrix)
    conn_matrix = thresholding.standardize(conn_matrix)
    conn_matrix_plt = np.nan_to_num(np.multiply(conn_matrix, conn_matrix_bin))

    sorting_array = sorted(range(len(community_aff)),
                           key=lambda k: community_aff[k])
    sorted_conn_matrix = conn_matrix[sorting_array, :]
    sorted_conn_matrix = sorted_conn_matrix[:, sorting_array]
    rois_num = sorted_conn_matrix.shape[0]
    if rois_num < 100:
        try:
            plot_matrix(conn_matrix_plt,
                        figure=(10, 10),
                        labels=labels,
                        vmax=np.abs(np.max(conn_matrix_plt)),
                        vmin=-np.abs(np.max(conn_matrix_plt)),
                        reorder=False,
                        auto_fit=True,
                        grid=False,
                        colorbar=False,
                        cmap=cmap)
        except RuntimeWarning:
            print('Connectivity matrix too sparse for plotting...')
    else:
        try:
            plot_matrix(conn_matrix_plt,
                        figure=(10, 10),
                        vmax=np.abs(np.max(conn_matrix_plt)),
                        vmin=-np.abs(np.max(conn_matrix_plt)),
                        auto_fit=True,
                        grid=False,
                        colorbar=False,
                        cmap=cmap)
        except RuntimeWarning:
            print('Connectivity matrix too sparse for plotting...')

    ax = plt.gca()
    total_size = 0
    for community in np.unique(community_aff):
        size = sum(sorted(community_aff) == community)
        ax.add_patch(
            patches.Rectangle((total_size, total_size),
                              size,
                              size,
                              fill=False,
                              edgecolor='black',
                              alpha=None,
                              linewidth=1))
        total_size += size

    plt.savefig(out_path_fig_comm, dpi=dpi_resolution)
    plt.close()
    return
예제 #14
0
파일: interfaces.py 프로젝트: dPys/PyNets
    def binarize_graph(self):
        in_mat_bin = thresholding.binarize(self.in_mat)

        # Load numpy matrix as networkx graph
        G_bin = nx.from_numpy_array(in_mat_bin)
        return in_mat_bin, G_bin
예제 #15
0
def perform_thresholding(conn_matrix, thr, min_span_tree, dens_thresh,
                         disp_filt):
    '''

    References
    ----------
    .. [1] Fornito, A., Zalesky, A., & Bullmore, E. T. (2016).
      Fundamentals of Brain Network Analysis. In Fundamentals of Brain Network Analysis.
      https://doi.org/10.1016/C2012-0-06036-X

    '''
    import numpy as np
    import networkx as nx
    from pynets.core import thresholding

    thr_perc = 100 - np.abs(100 * float(thr))

    if min_span_tree is True:
        print(
            'Using local thresholding option with the Minimum Spanning Tree (MST)...\n'
        )
        if dens_thresh is True:
            print(
                'Ignoring -dt flag since local density thresholding is not currently supported.'
            )
        thr_type = 'MST'
        edge_threshold = f"{str(thr_perc)}%"
        conn_matrix_thr = thresholding.local_thresholding_prop(
            conn_matrix, thr)
    elif disp_filt is True:

        thr_type = 'DISPARITY'
        edge_threshold = f"{str(thr_perc)}%"
        G1 = thresholding.disparity_filter(
            nx.from_numpy_array(np.abs(conn_matrix)))
        # G2 = nx.Graph([(u, v, d) for u, v, d in G1.edges(data=True) if d['alpha'] < thr])
        print(f"Computing edge disparity significance with alpha = {thr}")
        print(
            f'Filtered graph: nodes = {G1.number_of_nodes()}, edges = {G1.number_of_edges()}'
        )
        # print(f'Backbone graph: nodes = {G2.number_of_nodes()}, edges = {G2.number_of_edges()}")
        # print(G2.edges(data=True))
        conn_matrix_bin = thresholding.binarize(
            nx.to_numpy_array(G1,
                              nodelist=sorted(G1.nodes()),
                              dtype=np.float64))
        # Enforce original dimensionality by padding with zeros.
        if conn_matrix_bin.shape != conn_matrix.shape:
            if conn_matrix.shape[0] > conn_matrix_bin.shape[0]:
                result = np.zeros(conn_matrix.shape)
                result[:conn_matrix_bin.shape[0], :conn_matrix_bin.
                       shape[1]] = conn_matrix_bin
                conn_matrix_thr = np.multiply(conn_matrix, result)
            else:
                result = np.zeros(conn_matrix_bin.shape)
                result[:conn_matrix.shape[0], :conn_matrix.
                       shape[1]] = conn_matrix
                conn_matrix_thr = np.multiply(conn_matrix_bin, result)
        else:
            conn_matrix_thr = np.multiply(conn_matrix, conn_matrix_bin)
    else:
        if dens_thresh is False:
            thr_type = 'PROP'
            edge_threshold = f"{str(thr_perc)}{'%'}"
            print(f"\nThresholding proportionally at: {thr_perc}% ...\n")
            conn_matrix_thr = thresholding.threshold_proportional(
                conn_matrix, float(thr))
        else:
            thr_type = 'DENS'
            edge_threshold = None
            print(f"\nThresholding to achieve density of: {thr_perc}% ...\n")
            conn_matrix_thr = thresholding.density_thresholding(
                conn_matrix, float(thr))
    return thr_type, edge_threshold, conn_matrix_thr