Example #1
0
def density_thresholding(conn_matrix, thr, max_iters=10000, interval=0.01):
    """
    Iteratively apply an absolute threshold to achieve a target density.

    Parameters
    ----------
    conn_matrix : np.ndarray
        Weighted connectivity matrix
    thr : float
        Density value between 0-1.
    max_iters : int
        Maximum number of iterations for performing absolute thresholding. Default is 1000.
    interval : float
        Interval for increasing the absolute threshold for each iteration. Default is 0.01.

    Returns
    -------
    conn_matrix : np.ndarray
        Thresholded connectivity matrix

    References
    ----------
    .. [1] van Wijk, B. C. M., Stam, C. J., & Daffertshofer, A. (2010).
      Comparing brain networks of different size and connectivity
      density using graph theory. PLoS ONE.
      https://doi.org/10.1371/journal.pone.0013701
    .. [2] Complex network measures of brain connectivity: Uses and interpretations.
      Rubinov M, Sporns O (2010) NeuroImage 52:1059-69.

    """
    from pynets.core import thresholding
    np.fill_diagonal(conn_matrix, 0)

    work_thr = 0
    i = 1
    density = nx.density(nx.from_numpy_matrix(conn_matrix))
    if float(thr) < float(density):
        while float(i) < max_iters and float(work_thr) < float(1):
            work_thr = float(work_thr) + float(interval)
            density = nx.density(
                nx.from_numpy_matrix(
                    thresholding.threshold_absolute(conn_matrix, work_thr)))
            print("%s%d%s%.2f%s%.2f%s" %
                  ('Iteration ', i, ' -- with Thresh: ', float(work_thr),
                   ' and Density: ', float(density), '...'))
            if float(thr) >= float(density):
                conn_matrix = thresholding.threshold_absolute(
                    conn_matrix, work_thr)
                break
            i = i + 1
    else:
        print(
            'Density of raw matrix is already greater than or equal to the target density requested'
        )

    return conn_matrix
Example #2
0
def density_thresholding(conn_matrix, thr, max_iters=10000, interval=0.01):
    """
    Iteratively apply an absolute threshold to achieve a target density.

    Parameters
    ----------
    conn_matrix : np.ndarray
        Weighted connectivity matrix
    thr : float
        Density value between 0-1.
    max_iters : int
        Maximum number of iterations for performing absolute thresholding. Default is 1000.
    interval : float
        Interval for increasing the absolute threshold for each iteration. Default is 0.01.

    Returns
    -------
    conn_matrix : np.ndarray
        Thresholded connectivity matrix

    References
    ----------
    .. Adapted from Adapted from bctpy
    """
    from pynets.core import thresholding
    np.fill_diagonal(conn_matrix, 0)

    work_thr = 0
    i = 1
    density = nx.density(nx.from_numpy_matrix(conn_matrix))
    if float(thr) < float(density):
        while float(i) < max_iters and float(work_thr) < float(1):
            work_thr = float(work_thr) + float(interval)
            density = nx.density(
                nx.from_numpy_matrix(
                    thresholding.threshold_absolute(conn_matrix, work_thr)))
            print("%s%d%s%.2f%s%.2f%s" %
                  ('Iteration ', i, ' -- with Thresh: ', float(work_thr),
                   ' and Density: ', float(density), '...'))
            if float(thr) >= float(density):
                conn_matrix = thresholding.threshold_absolute(
                    conn_matrix, work_thr)
                break
            i = i + 1
    else:
        print(
            'Density of raw matrix is already greater than or equal to the target density requested'
        )

    return conn_matrix
Example #3
0
 def test_thr2prob(x, thr):
     s = thresholding.threshold_absolute(thresholding.normalize(x), thr)
     s[0][0] = 0.0000001
     t = thresholding.thr2prob(s)
     assert float(len(t[np.logical_and(t < 0.001, t > 0)])) == float(0.0)
Example #4
0
 def test_density(x, thr):
     d_known = thresholding.est_density(
         thresholding.threshold_absolute(x, thr, copy=True))
     x = thresholding.density_thresholding(x, d_known)
     d_test = thresholding.est_density(x)
     assert np.equal(np.round(d_known, 1), np.round(d_test, 1))
Example #5
0
 def test_threshold_absolute(x, thr, cp):
     s = thresholding.threshold_absolute(x, thr, copy=cp)
     s_test = [val for arr in s for val in arr
               if val >= thr]  # search for value > thr
     assert round(np.sum(s), 10) == round(np.sum(s_test), 10)
Example #6
0
def compare_motifs(struct_mat, func_mat, name, namer_dir, bins=20, N=4):
    '''
    Compare motif structure and population across structural and functional
    graphs to achieve a homeostatic absolute threshold of each that optimizes
    multiplex community detection and analysis.

    Parameters
    ----------
    in_mat : ndarray
        M x M Connectivity matrix
    thr : float
        Absolute threshold [0, 1].
    mlib : list
        List of motif classes.

    Returns
    -------
    mf : ndarray
        1D vector listing the total motifs of size N for each
        class of mlib.

    References
    ----------
    .. [1] Battiston, F., Nicosia, V., Chavez, M., & Latora, V. (2017).
      Multilayer motif analysis of brain networks. Chaos.
      https://doi.org/10.1063/1.4979282

    '''
    from pynets.stats.netmotifs import adaptivethresh
    from pynets.core.thresholding import threshold_absolute
    from pynets.core.thresholding import standardize
    from scipy import spatial
    from nilearn.connectome import sym_matrix_to_vec
    import pandas as pd
    import gc

    mlib = ['1113', '1122', '1223', '2222', '2233', '3333']

    # Standardize structural graph
    struct_mat = standardize(struct_mat)
    dims_struct = struct_mat.shape[0]
    struct_mat[range(dims_struct), range(dims_struct)] = 0
    at_struct = adaptivethresh(struct_mat, float(0.0), mlib, N)
    print("%s%s%s" %
          ('Layer 1 (structural) has: ', np.sum(at_struct), ' total motifs'))

    # Functional graph threshold window
    func_mat = standardize(func_mat)
    dims_func = func_mat.shape[0]
    func_mat[range(dims_func), range(dims_func)] = 0
    tmin_func = func_mat.min()
    tmax_func = func_mat.max()
    threshes_func = np.linspace(tmin_func, tmax_func, bins)

    assert np.all(
        struct_mat == struct_mat.T), "Structural Matrix must be symmetric"
    assert np.all(
        func_mat == func_mat.T), "Functional Matrix must be symmetric"

    # Count motifs
    print("%s%s%s%s" % ('Mining ', N, '-node motifs: ', mlib))
    motif_dict = {}
    motif_dict['struct'] = {}
    motif_dict['func'] = {}

    mat_dict = {}
    mat_dict['struct'] = sym_matrix_to_vec(struct_mat, discard_diagonal=True)
    mat_dict['funcs'] = {}
    for thr_func in threshes_func:
        # Count
        at_func = adaptivethresh(func_mat, float(thr_func), mlib, N)
        motif_dict['struct']["%s%s" %
                             ('thr-', np.round(thr_func, 4))] = at_struct
        motif_dict['func']["%s%s" % ('thr-', np.round(thr_func, 4))] = at_func
        mat_dict['funcs']["%s%s" %
                          ('thr-', np.round(thr_func, 4))] = sym_matrix_to_vec(
                              threshold_absolute(func_mat, thr_func),
                              discard_diagonal=True)

        print("%s%s%s%s%s" %
              ('Layer 2 (functional) with absolute threshold of: ',
               np.round(thr_func,
                        2), ' yields ', np.sum(at_func), ' total motifs'))
        gc.collect()

    df = pd.DataFrame(motif_dict)

    for idx in range(len(df)):
        df.set_value(
            df.index[idx], 'motif_dist',
            spatial.distance.cosine(df['struct'][idx], df['func'][idx]))

    df = df[pd.notnull(df['motif_dist'])]

    for idx in range(len(df)):
        df.set_value(
            df.index[idx], 'graph_dist_cosine',
            spatial.distance.cosine(
                mat_dict['struct'].reshape(-1, 1),
                mat_dict['funcs'][df.index[idx]].reshape(-1, 1)))
        df.set_value(
            df.index[idx], 'graph_dist_correlation',
            spatial.distance.correlation(
                mat_dict['struct'].reshape(-1, 1),
                mat_dict['funcs'][df.index[idx]].reshape(-1, 1)))

    df['struct_func_3333'] = np.zeros(len(df))
    df['struct_func_2233'] = np.zeros(len(df))
    df['struct_func_2222'] = np.zeros(len(df))
    df['struct_func_1223'] = np.zeros(len(df))
    df['struct_func_1122'] = np.zeros(len(df))
    df['struct_func_1113'] = np.zeros(len(df))
    df['struct_3333'] = np.zeros(len(df))
    df['func_3333'] = np.zeros(len(df))
    df['struct_2233'] = np.zeros(len(df))
    df['func_2233'] = np.zeros(len(df))
    df['struct_2222'] = np.zeros(len(df))
    df['func_2222'] = np.zeros(len(df))
    df['struct_1223'] = np.zeros(len(df))
    df['func_1223'] = np.zeros(len(df))
    df['struct_1122'] = np.zeros(len(df))
    df['func_1122'] = np.zeros(len(df))
    df['struct_1113'] = np.zeros(len(df))
    df['func_1113'] = np.zeros(len(df))

    for idx in range(len(df)):
        df.set_value(df.index[idx], 'struct_3333', df['struct'][idx][-1])
        df.set_value(df.index[idx], 'func_3333', df['func'][idx][-1])

        df.set_value(df.index[idx], 'struct_2233', df['struct'][idx][-2])
        df.set_value(df.index[idx], 'func_2233', df['func'][idx][-2])

        df.set_value(df.index[idx], 'struct_2222', df['struct'][idx][-3])
        df.set_value(df.index[idx], 'func_2222', df['func'][idx][-3])

        df.set_value(df.index[idx], 'struct_1223', df['struct'][idx][-4])
        df.set_value(df.index[idx], 'func_1223', df['func'][idx][-4])

        df.set_value(df.index[idx], 'struct_1122', df['struct'][idx][-5])
        df.set_value(df.index[idx], 'func_1122', df['func'][idx][-5])

        df.set_value(df.index[idx], 'struct_1113', df['struct'][idx][-6])
        df.set_value(df.index[idx], 'func_1113', df['func'][idx][-6])

    df['struct_func_3333'] = np.abs(df['struct_3333'] - df['func_3333'])
    df['struct_func_2233'] = np.abs(df['struct_2233'] - df['func_2233'])
    df['struct_func_2222'] = np.abs(df['struct_2222'] - df['func_2222'])
    df['struct_func_1223'] = np.abs(df['struct_1223'] - df['func_1223'])
    df['struct_func_1122'] = np.abs(df['struct_1122'] - df['func_1122'])
    df['struct_func_1113'] = np.abs(df['struct_1113'] - df['func_1113'])

    df = df.drop(columns=['struct', 'func'])

    df = df.loc[~(df == 0).all(axis=1)]

    df = df.sort_values(by=[
        'motif_dist', 'graph_dist_cosine', 'graph_dist_correlation',
        'struct_func_3333', 'struct_func_2233', 'struct_func_2222',
        'struct_func_1223', 'struct_func_1122', 'struct_func_1113',
        'struct_3333', 'func_3333', 'struct_2233', 'func_2233', 'struct_2222',
        'func_2222', 'struct_1223', 'func_1223', 'struct_1122', 'func_1122',
        'struct_1113', 'func_1113'
    ],
                        ascending=[
                            True, True, False, False, False, False, False,
                            False, False, False, False, False, False, False,
                            False, False, False, False, False, False, False
                        ])

    # Take the top 25th percentile
    df = df.head(int(0.25 * len(df)))
    best_threshes = []
    best_mats = []
    best_multigraphs = []
    for key in list(df.index):
        func_mat_tmp = func_mat.copy()
        struct_mat_tmp = struct_mat.copy()
        struct_thr = float(key.split('-')[-1])
        func_thr = float(key.split('-')[-1])
        best_threshes.append(str(func_thr))

        func_mat_tmp[func_mat_tmp < func_thr] = 0
        struct_mat_tmp[struct_mat_tmp < struct_thr] = 0
        best_mats.append((func_mat_tmp, struct_mat_tmp))

        mG = build_mx_multigraph(func_mat, struct_mat, f"{name}_{key}",
                                 namer_dir)
        best_multigraphs.append(mG)

    mg_dict = dict(zip(best_threshes, best_multigraphs))
    g_dict = dict(zip(best_threshes, best_mats))

    return mg_dict, g_dict