def get_centrality_opt(timeseries_data,
                       method_options,
                       weight_options,
                       memory_allocated,
                       threshold,
                       scans,
                       r_value=None):
    """
    Method to calculate degree and eigen vector centrality. 
    This method takes into consideration the amount of memory
    allocated by the user to calculate degree centrality.
    
    Parameters
    ----------
    timeseries_data : numpy array
        timeseries of the input subject
    weight_options : string (list of boolean)
        list of two booleans for binarize and weighted options respectively
    method_options : string (list of boolean)
        list of two booleans for binarize and weighted options respectively
    memory_allocated : a string
        amount of memory allocated to degree centrality
    scans : an integer
        number of scans in the subject
    r_value :a float
        threshold value
    
    Returns
    -------
    out_list : string (list of tuples)
        list of tuple containing output name to be used to store nifti image
        for centrality and centrality matrix 
    
    Raises
    ------
    Exception
    """

    import numpy as np
    from CPAC.network_centrality import load_mat,\
                                        calc_corrcoef,\
                                        calc_blocksize,\
                                        calc_eigenV,\
                                        calc_threshold
    #from scipy.sparse import dok_matrix

    try:
        out_list = []
        timeseries = load_mat(timeseries_data)
        shape = timeseries.shape
        try:
            block_size = calc_blocksize(shape, memory_allocated)
        except:
            raise Exception("Error in calculating block size")

        r_matrix = None

        if method_options[0]:
            if weight_options[0]:
                degree_mat_binarize = np.zeros(shape[0], dtype=np.float32)
                out_list.append(
                    ('degree_centrality_binarize', degree_mat_binarize))

            if weight_options[1]:
                degree_mat_weighted = np.zeros(shape[0], dtype=np.float32)
                out_list.append(
                    ('degree_centrality_weighted', degree_mat_weighted))

        if method_options[1]:
            r_matrix = np.zeros((shape[0], shape[0]), dtype=np.float32)

        j = 0
        i = block_size

        while i <= timeseries.shape[0]:

            print "running block -> ", i + j

            try:
                corr_matrix = np.nan_to_num(
                    calc_corrcoef(timeseries[j:i].T, timeseries.T))
            except:
                raise Exception(
                    "Error in calcuating block wise correlation for the block %,%"
                    % (j, i))

            if r_value == None:
                r_value = calc_threshold(1,
                                         threshold,
                                         scans,
                                         corr_matrix,
                                         full_matrix=False)

            if method_options[1]:
                r_matrix[j:i] = corr_matrix

            if method_options[0]:
                if weight_options[0]:
                    degree_mat_binarize[j:i] = np.sum(
                        (corr_matrix > r_value).astype(np.float32), axis=1) - 1
                if weight_options[1]:
                    degree_mat_weighted[j:i] = np.sum(
                        corr_matrix *
                        (corr_matrix > r_value).astype(np.float32),
                        axis=1) - 1

            j = i
            if i == timeseries.shape[0]:
                break
            elif (i + block_size) > timeseries.shape[0]:
                i = timeseries.shape[0]
            else:
                i += block_size

        try:
            if method_options[1]:
                out_list.extend(calc_eigenV(r_matrix, r_value, weight_options))
        except Exception:
            print "Error in calcuating eigen vector centrality"
            raise

        return out_list

    except Exception:
        print "Error in calcuating Centrality"
        raise
Exemple #2
0
def calc_centrality(datafile,
                    template,
                    method_option,
                    threshold_option,
                    threshold,
                    weight_options,
                    allocated_memory):
    '''
    Method to calculate centrality and map them to a nifti file
    
    Parameters
    ----------
    datafile : string (nifti file)
        path to subject data file
    template : string (nifti file)
        path to mask/parcellation unit
    method_option : integer
        0 - degree centrality calculation, 1 - eigenvector centrality calculation, 2 - lFCD calculation
    threshold_option : an integer
        0 for probability p_value, 1 for sparsity threshold, 
        2 for actual threshold value, and 3 for no threshold and fast approach
    threshold : a float
        pvalue/sparsity_threshold/threshold value
    weight_options : list (boolean)
        list of booleans, where, weight_options[0] corresponds to binary counting 
        and weight_options[1] corresponds to weighted counting (e.g. [True,False]) 
    allocated_memory : string
        amount of memory allocated to degree centrality
    
    Returns
    -------
    out_list : list
        list containing out mapped centrality images
    '''
    
    # Import packages
    from CPAC.network_centrality import load,\
                                        get_centrality_by_rvalue,\
                                        get_centrality_by_sparsity,\
                                        get_centrality_fast,\
                                        map_centrality_matrix,\
                                        calc_blocksize,\
                                        convert_pvalue_to_r
    from CPAC.cwas.subdist import norm_cols
    
    # Check for input errors
    if weight_options.count(True) == 0:
        raise Exception("Invalid values in weight options" \
                        "At least one True value is required")
    # If it's sparsity thresholding, check for (0,1]
    if threshold_option == 1:
        if threshold <= 0 or threshold > 1:
            raise Exception('Threshold value must be a positive number'\
                            'greater than 0 and less than or equal to 1.'\
                            '\nCurrently it is set at %d' % threshold)
    if method_option == 2 and threshold_option != 2:
        raise Exception('lFCD must use correlation-type thresholding.'\
                         'Check the pipline configuration has this setting')
    import time
    start = time.clock()
    
    # Init variables
    out_list = []
    ts, aff, mask, t_type, scans = load(datafile, template)
    
    # If we're doing eigenvectory centrality, need entire correlation matrix
    if method_option == 0 and threshold_option == 1:
        block_size = calc_blocksize(ts, memory_allocated=allocated_memory,
                                    sparsity_thresh=threshold)
    elif method_option == 1:
        block_size = calc_blocksize(ts, memory_allocated=allocated_memory,
                                    include_full_matrix=True)
    # Otherwise, compute blocksize with regards to available memory
    else:
        block_size = calc_blocksize(ts, memory_allocated=allocated_memory,
                                    include_full_matrix=False)
    # Normalize the timeseries for easy dot-product correlation calc.
    ts_normd = norm_cols(ts.T)
    
    # P-value threshold centrality
    if threshold_option == 0:
        r_value = convert_pvalue_to_r(scans, threshold)
        centrality_matrix = get_centrality_by_rvalue(ts_normd, 
                                                     mask, 
                                                     method_option, 
                                                     weight_options, 
                                                     r_value, 
                                                     block_size)
    # Sparsity threshold
    elif threshold_option == 1:
        centrality_matrix = get_centrality_by_sparsity(ts_normd, 
                                                       method_option, 
                                                       weight_options, 
                                                       threshold, 
                                                       block_size)
    # R-value threshold centrality
    elif threshold_option == 2:
        centrality_matrix = get_centrality_by_rvalue(ts_normd, 
                                                     mask, 
                                                     method_option, 
                                                     weight_options, 
                                                     threshold, 
                                                     block_size)
    # For fast approach (no thresholding)
    elif threshold_option == 3:
        centrality_matrix = get_centrality_fast(ts, method_option)
    # Otherwise, incorrect input for threshold_option
    else:
        raise Exception('Option must be between 0-3 and not %s, check your '\
                        'pipeline config file' % str(threshold_option))
    
    # Print timing info
    print 'Timing:', time.clock() - start
 
    # Map the arrays back to images
    for mat in centrality_matrix:
        centrality_image = map_centrality_matrix(mat, aff, mask, t_type)
        out_list.append(centrality_image)
    
    # Finally return
    return out_list
def get_centrality(timeseries_data, method_options, weight_options, threshold,
                   option, scans, memory_allocated):
    """
    Method to calculate degree and eigen vector centrality
    
    Parameters
    ----------
    weight_options : string (list of boolean)
        list of two booleans for binarize and weighted options respectively
    method_options : string (list of boolean)
        list of two booleans for binarize and weighted options respectively
    threshold_matrix : string (numpy npy file)
        path to file containing thresholded correlation matrix 
    correlation_matrix : string (numpy npy file)
        path to file containing correlation matrix
    template_data : string (numpy npy file)
        path to file containing mask or parcellation unit data    
    
    Returns
    -------
    out_list : string (list of tuples)
        list of tuple containing output name to be used to store nifti image
        for centrality and centrality matrix 
    
    Raises
    ------
    Exception
    """

    import numpy as np
    from CPAC.network_centrality import load_mat,\
                                        calc_corrcoef,\
                                        calc_blocksize,\
                                        calc_threshold,\
                                        calc_eigenV

    out_list = []

    try:

        timeseries = load_mat(timeseries_data)
        shape = timeseries.shape
        block_size = calc_blocksize(shape, memory_allocated)
        corr_matrix = np.zeros((shape[0], shape[0]), dtype=np.float16)
        j = 0
        i = block_size

        while i <= timeseries.shape[0]:
            print "block -> ", i + j
            temp_matrix = np.nan_to_num(
                calc_corrcoef(timeseries[j:i].T, timeseries.T))
            corr_matrix[j:i] = temp_matrix
            j = i
            if i == timeseries.shape[0]:
                break
            elif (i + block_size) > timeseries.shape[0]:
                i = timeseries.shape[0]
            else:
                i += block_size

        r_value = calc_threshold(option,
                                 threshold,
                                 scans,
                                 corr_matrix,
                                 full_matrix=True)

        print "r_value -> ", r_value

        if method_options[0]:

            print "calculating binarize degree centrality matrix..."
            degree_matrix = np.sum(corr_matrix > r_value, axis=1) - 1
            out_list.append(('degree_centrality_binarize', degree_matrix))

            print "calculating weighted degree centrality matrix..."
            degree_matrix = np.sum(corr_matrix * (corr_matrix > r_value),
                                   axis=1) - 1
            out_list.append(('degree_centrality_weighted', degree_matrix))

        if method_options[1]:
            out_list.extend(calc_eigenV(corr_matrix, r_value, weight_options))

    except Exception:
        print "Error while calculating centrality"
        raise

    return out_list
def get_centrality_opt(timeseries_data,
                       method_options,
                       weight_options,
                       memory_allocated,
                       threshold,
                       scans,
                       r_value = None):
    
    """
    Method to calculate degree and eigen vector centrality. 
    This method takes into consideration the amount of memory
    allocated by the user to calculate degree centrality.
    
    Parameters
    ----------
    timeseries_data : numpy array
        timeseries of the input subject
    weight_options : string (list of boolean)
        list of two booleans for binarize and weighted options respectively
    method_options : string (list of boolean)
        list of two booleans for binarize and weighted options respectively
    memory_allocated : a string
        amount of memory allocated to degree centrality
    scans : an integer
        number of scans in the subject
    r_value :a float
        threshold value
    
    Returns
    -------
    out_list : string (list of tuples)
        list of tuple containing output name to be used to store nifti image
        for centrality and centrality matrix 
    
    Raises
    ------
    Exception
    """
    
    
    import numpy as np
    from CPAC.network_centrality import load_mat,\
                                        calc_corrcoef,\
                                        calc_blocksize,\
                                        calc_eigenV,\
                                        calc_threshold
    #from scipy.sparse import dok_matrix
    
    try:                                    
        out_list =[]
        timeseries = load_mat(timeseries_data)
        shape = timeseries.shape
        try:
            block_size = calc_blocksize(shape, memory_allocated)
        except:
            raise Exception("Error in calculating block size")
        
        r_matrix = None
        
        if method_options[0]:
            if weight_options[0]:
                degree_mat_binarize = np.zeros(shape[0], dtype= np.float32)
                out_list.append(('degree_centrality_binarize', degree_mat_binarize))
    
            if weight_options[1]:
                degree_mat_weighted = np.zeros(shape[0], dtype = np.float32)
                out_list.append(('degree_centrality_weighted', degree_mat_weighted))
            
        if method_options[1]:
            r_matrix = np.zeros((shape[0], shape[0]), dtype = np.float32)
    
        j=0
        i = block_size
        
        while i <= timeseries.shape[0]:
           
            print "running block -> ", i + j
            
            try:
                corr_matrix = np.nan_to_num(calc_corrcoef(timeseries[j:i].T, timeseries.T))
            except:
                raise Exception("Error in calcuating block wise correlation for the block %,%"%(j,i))
           
            if r_value == None:
                r_value = calc_threshold(1, threshold, scans, corr_matrix, full_matrix = False)
                
            if method_options[1]:
                r_matrix[j:i] = corr_matrix 
                
            if method_options[0]:
                if weight_options[0]:
                    degree_mat_binarize[j:i] = np.sum((corr_matrix > r_value).astype(np.float32), axis = 1) -1
                if weight_options[1]:
                    degree_mat_weighted[j:i] = np.sum(corr_matrix*(corr_matrix > r_value).astype(np.float32), axis = 1) -1
        
            j = i   
            if i == timeseries.shape[0]:
                break
            elif (i+block_size) > timeseries.shape[0]: 
                i = timeseries.shape[0] 
            else:
                i += block_size    
        
        try:
            if method_options[1]:
                out_list.extend(calc_eigenV(r_matrix, r_value, weight_options))
        except Exception:
            print "Error in calcuating eigen vector centrality"
            raise
        
        return out_list   
    
    except Exception: 
        print "Error in calcuating Centrality"
        raise
def get_centrality(timeseries_data, 
                   method_options,
                   weight_options,
                   threshold,
                   option,
                   scans,
                   memory_allocated):
    
    """
    Method to calculate degree and eigen vector centrality
    
    Parameters
    ----------
    weight_options : string (list of boolean)
        list of two booleans for binarize and weighted options respectively
    method_options : string (list of boolean)
        list of two booleans for binarize and weighted options respectively
    threshold_matrix : string (numpy npy file)
        path to file containing thresholded correlation matrix 
    correlation_matrix : string (numpy npy file)
        path to file containing correlation matrix
    template_data : string (numpy npy file)
        path to file containing mask or parcellation unit data    
    
    Returns
    -------
    out_list : string (list of tuples)
        list of tuple containing output name to be used to store nifti image
        for centrality and centrality matrix 
    
    Raises
    ------
    Exception
    """
    
    import numpy as np
    from CPAC.network_centrality import load_mat,\
                                        calc_corrcoef,\
                                        calc_blocksize,\
                                        calc_threshold,\
                                        calc_eigenV
    
    
    out_list=[]
    
    try:
        
        timeseries = load_mat(timeseries_data)
        shape = timeseries.shape
        block_size = calc_blocksize(shape, memory_allocated)
        corr_matrix = np.zeros((shape[0], shape[0]), dtype = np.float16)
        j=0
        i = block_size
        
        while i <= timeseries.shape[0]:
            print "block -> ", i + j
            temp_matrix = np.nan_to_num(calc_corrcoef(timeseries[j:i].T, timeseries.T))
            corr_matrix[j:i] = temp_matrix
            j = i   
            if i == timeseries.shape[0]:
                break
            elif (i+block_size) > timeseries.shape[0]: 
                i = timeseries.shape[0] 
            else:
                i += block_size
        
        r_value = calc_threshold(option, 
                                 threshold, 
                                 scans, 
                                 corr_matrix,
                                 full_matrix = True)
        
        print "r_value -> ", r_value
                
        if method_options[0]:
            
            print "calculating binarize degree centrality matrix..."
            degree_matrix = np.sum( corr_matrix > r_value , axis = 1)  -1
            out_list.append(('degree_centrality_binarize', degree_matrix))
            
            print "calculating weighted degree centrality matrix..."
            degree_matrix = np.sum( corr_matrix*(corr_matrix > r_value), axis= 1) -1
            out_list.append(('degree_centrality_weighted', degree_matrix))
            
        
        if method_options[1]:
            out_list.extend(calc_eigenV(corr_matrix, 
                                           r_value, 
                                           weight_options))
    
    except Exception:
        print "Error while calculating centrality"
        raise
    
    return out_list
def calc_centrality(in_file, template, method_option, threshold_option,
                    threshold, allocated_memory):
    '''
    Function to calculate centrality and map them to a nifti file
    
    Parameters
    ----------
    in_file : string (nifti file)
        path to subject data file
    template : string (nifti file)
        path to mask/parcellation unit
    method_option : string
        accepted values are 'degree centrality', 'eigenvector centrality', and
        'lfcd'
    threshold_option : string
        accepted values are: 'significance', 'sparsity', and 'correlation'
    threshold : float
        pvalue/sparsity_threshold/threshold value
    allocated_memory : string
        amount of memory allocated to degree centrality
    
    Returns
    -------
    out_list : list
        list containing out mapped centrality images
    '''

    # Import packages
    from CPAC.network_centrality import load,\
                                        get_centrality_by_rvalue,\
                                        get_centrality_by_sparsity,\
                                        get_centrality_fast,\
                                        map_centrality_matrix,\
                                        calc_blocksize,\
                                        convert_pvalue_to_r
    from CPAC.network_centrality.utils import check_centrality_params
    from CPAC.cwas.subdist import norm_cols

    # First check input parameters and get proper formatted method/thr options
    method_option, threshold_option = \
        check_centrality_params(method_option, threshold_option, threshold)

    # Init variables
    out_list = []
    ts, aff, mask, t_type, scans = load(in_file, template)

    # If we're doing degree sparsity
    if method_option == 'degree' and threshold_option == 'sparsity':
        block_size = calc_blocksize(ts, memory_allocated=allocated_memory,
                                    sparsity_thresh=threshold)
    # Otherwise
    elif method_option == 'eigenvector':
        block_size = calc_blocksize(ts, memory_allocated=allocated_memory,
                                    include_full_matrix=True)
    # Otherwise, compute blocksize with regards to available memory
    else:
        block_size = calc_blocksize(ts, memory_allocated=allocated_memory,
                                    include_full_matrix=False)
    # Normalize the timeseries for easy dot-product correlation calc.
    ts_normd = norm_cols(ts.T)

    # P-value threshold centrality
    if threshold_option == 'significance':
        r_value = convert_pvalue_to_r(in_file, threshold, two_tailed=False)
        centrality_matrix = get_centrality_by_rvalue(ts_normd,
                                                     mask,
                                                     method_option,
                                                     r_value,
                                                     block_size)
    # Sparsity threshold
    elif threshold_option == 'sparsity':
        centrality_matrix = get_centrality_by_sparsity(ts_normd,
                                                       method_option,
                                                       threshold,
                                                       block_size)
    # R-value threshold centrality
    elif threshold_option == 'correlation':
        centrality_matrix = get_centrality_by_rvalue(ts_normd,
                                                     mask,
                                                     method_option,
                                                     threshold,
                                                     block_size)
    # For fast approach (no thresholding)
    elif threshold_option == 3:
        centrality_matrix = get_centrality_fast(ts, method_option)
    # Otherwise, incorrect input for threshold_option
    else:
        err_msg = 'Threshold option: %s not supported for network centrality '\
                  'measure: %s; fix this in the pipeline config'\
                  % (str(threshold_option), str(method_option))
        raise Exception(err_msg)
 
    # Map the arrays back to images
    for mat in centrality_matrix:
        centrality_image = map_centrality_matrix(mat, aff, mask, t_type)
        out_list.append(centrality_image)

    # Finally return
    return out_list
def get_centrality_by_thresh(timeseries,
                             template,
                             method_option,
                             weight_options,
                             threshold,
                             r_value,
                             memory_allocated):
    """
    Method to calculate degree and eigen vector centrality. 
    This method takes into consideration the amount of memory
    allocated by the user to calculate degree centrality.
    
    Parameters
    ----------
    timeseries_data : numpy array
        timeseries of the input subject
    template : numpy array
        Mask/ROI template for timeseries of subject
    method_option : integer
        0 - degree centrality calculation, 1 - eigenvector centrality calculation, 2 - lFCD calculation
    weight_options : string (list of boolean)
        list of two booleans for binarize and weighted options respectively
    threshold : float
        p-value threshold for the correlation values (ignored if the r_value option is specified)
    r_value : float
        threshold value in terms of the correlation (this will override the threshold option)
    memory_allocated : a string
        amount of memory allocated to degree centrality
        
    Returns
    -------
    out_list : string (list of tuples)
        list of tuple containing output name to be used to store nifti image
        for centrality and centrality matrix 
    
    Raises
    ------
    Exception
    """
    
    
    import numpy as np
    import os
    from CPAC.network_centrality import calc_blocksize,\
                                        cluster_data,\
                                        convert_pvalue_to_r,\
                                        degree_centrality,\
                                        eigenvector_centrality
    from CPAC.cwas.subdist import norm_cols
    
    try:                         
        # Init variables for use
        out_list = []
        nvoxs = timeseries.shape[0]
        ntpts = timeseries.shape[1]
        
        r_matrix = None             # init correlation matrix
        calc_degree = False         # init degree measure flag to false
        calc_eigen = False          # init eigen measure flag to false
        calc_lfcd= False            # init lFCD measure flag to false
        
        # Select which method we're going to perform
        if method_option == 0:
            calc_degree = True
        elif method_option == 1:
            calc_eigen = True
        elif method_option == 2:
            calc_lfcd = True
        
        # Set weighting parameters
        out_binarize = weight_options[0]
        out_weighted = weight_options[1]
        
        # Calculate the block size (i.e., number of voxels) to compute part of the
        # connectivity matrix at once.
        if calc_eigen:
            # We still use a block size to calculate the whole correlation matrix
            # because of issues in numpy that lead to extra memory usage when
            # computing the dot product.
            # See https://cmi.hackpad.com/Numpy-Memory-Issues-BlV9Pg5nRDM.
            block_size = calc_blocksize(timeseries, memory_allocated, include_full_matrix=True)
        else:
            block_size = calc_blocksize(timeseries, memory_allocated)
        
        if r_value == None:
            print "Calculating threshold"
            r_value = convert_pvalue_to_r(ntpts, threshold)
            print "...%s -> %s" % (threshold, r_value)
        
        print "Setup Intermediates/Outputs"
        # Degree matrix init
        if calc_degree:
            print "...degree"
            if out_binarize:
                degree_binarize = np.zeros(nvoxs, dtype=timeseries.dtype)
                out_list.append(('degree_centrality_binarize', degree_binarize))
            if out_weighted:
                degree_weighted = np.zeros(nvoxs, dtype=timeseries.dtype)
                out_list.append(('degree_centrality_weighted', degree_weighted))
        # Eigen matrix init
        if calc_eigen:
            print "...eigen"
            r_matrix = np.zeros((nvoxs, nvoxs), dtype=timeseries.dtype)
            if out_binarize:
                eigen_binarize = np.zeros(nvoxs, dtype=timeseries.dtype)
                out_list.append(('eigenvector_centrality_binarize', eigen_binarize))
            if out_weighted:
                eigen_weighted = np.zeros(nvoxs, dtype=timeseries.dtype)
                out_list.append(('eigenvector_centrality_weighted', eigen_weighted))
        # lFCD matrix init
        if calc_lfcd:
            print "...degree"
            if out_binarize:
                lfcd_binarize = np.zeros(nvoxs, dtype=timeseries.dtype)
                out_list.append(('lFCD_binarize', lfcd_binarize))
            if out_weighted:
                lfcd_weighted = np.zeros(nvoxs, dtype=timeseries.dtype)
                out_list.append(('lFCD_weighted', lfcd_weighted))
        
        # Normalize the timeseries columns for simple correlation calc via dot product later..
        print "Normalize TimeSeries"
        timeseries = norm_cols(timeseries.T)
        
        # Init blocking indices for correlation matrix calculation
        print "Computing centrality across %i voxels" % nvoxs
        i = block_size
        j = 0
        # Calculate correlation matrix in blocks while loop
        while i <= nvoxs:
            print "running block ->", i, j
           
            try:
                print "...correlating"
                corr_matrix = np.dot(timeseries[:,j:i].T, timeseries)
            except:
                raise Exception("Error in calcuating block wise correlation for the block %i,%i"%(j,i))
                      
            if calc_eigen:
                print "...storing correlation matrix"
                r_matrix[j:i] = corr_matrix
            
            if calc_degree:
                if out_binarize:
                    print "...calculating binarize degree"
                    degree_centrality(corr_matrix, r_value, method="binarize", out=degree_binarize[j:i])
                if out_weighted:
                    print "...calculating weighted degree"
                    degree_centrality(corr_matrix, r_value, method="weighted", out=degree_weighted[j:i])
            
            if calc_lfcd:
                xyz_a = np.argwhere(template)
                krange = corr_matrix.shape[0]
                print "...iterating through seeds in block - lfcd"
                for k in range (0,krange):
                    corr_seed = corr_matrix[k,:]
                    labels = cluster_data(corr_seed,r_value,xyz_a)
                    seed_label = labels[j+k]
                    if out_binarize:
                        if seed_label > 0:
                            lfcd = np.sum(labels==seed_label)
                        else:
                            lfcd = 1
                        lfcd_binarize[j+k] = lfcd
                    if out_weighted:
                        if seed_label > 0:
                            lfcd = np.sum(corr_seed*(labels==seed_label))
                        else:
                            lfcd = 1
                        lfcd_weighted[j+k] = lfcd
                            
            print "...removing temporary correlation matrix"
            del corr_matrix
           
            j = i
            if i == nvoxs:
                break
            elif (i+block_size) > nvoxs:
                i = nvoxs
            else:
                i += block_size
        
        # In case there are any zeros in lfcd matrix, set them to 1
        if calc_lfcd:
            if out_binarize:
                lfcd_binarize[np.argwhere(lfcd_binarize == 0)] = 1
            if out_weighted:
                lfcd_weighted[np.argwhere(lfcd_weighted == 0)] = 1
        
        # Perform eigenvector measures if necessary
        try:
            if calc_eigen:
                if out_binarize:
                    print "...calculating binarize eigenvector"
                    eigen_binarize[:] = eigenvector_centrality(r_matrix, r_value, method="binarize").squeeze()
                if out_weighted:
                    print "...calculating weighted eigenvector"
                    eigen_weighted[:] = eigenvector_centrality(r_matrix, r_value, method="weighted").squeeze()
        except Exception:
            print "Error in calcuating eigen vector centrality"
            raise
        
        if calc_degree:
            print "...removing effect of auto-correlation on degree"
            degree_binarize[degree_binarize!=0] = degree_binarize[degree_binarize!=0] - 1
            degree_weighted[degree_weighted!=0] = degree_weighted[degree_weighted!=0] - 1
        
        return out_list
    
    except Exception: 
        print "Error in calcuating Centrality"
        raise
def get_centrality_by_sparsity(timeseries, 
                   method_option,
                   weight_options,
                   threshold,
                   memory_allocated):
    
    """
    Method to calculate degree and eigen vector centrality
    
    Parameters
    ----------
    timeseries : numpy array
        timeseries of the input subject
    method_options : string (list of boolean)
        list of two booleans for degree and eigen options respectively
    weight_options : string (list of boolean)
        list of two booleans for binarize and weighted options respectively
    threshold : float
        sparsity threshold for the correlation values
    memory_allocated : a string
        amount of memory allocated to degree centrality
    
    Returns
    -------
    out_list : string (list of tuples)
        list of tuple containing output name to be used to store nifti image
        for centrality and centrality matrix
    
    Raises
    ------
    Exception
    """
    
    import os
    import numpy as np
    from CPAC.network_centrality import calc_blocksize,\
                                        convert_sparsity_to_r,\
                                        degree_centrality,\
                                        eigenvector_centrality
    from CPAC.cwas.subdist import norm_cols
    
    out_list=[]
    
    try:
        # Calculate the block size (i.e., number of voxels) to compute part of the
        # connectivity matrix at once.
        # 
        # We still use a block size to calculate the whole correlation matrix
        # because of issues in numpy that lead to extra memory usage when
        # computing the dot product.
        # See https://cmi.hackpad.com/Numpy-Memory-Issues-BlV9Pg5nRDM.
        block_size  = calc_blocksize(timeseries, memory_allocated, include_full_matrix=True)
        
        nvoxs = timeseries.shape[0]
        ntpts = timeseries.shape[1]
        
        calc_degree = False         # init degree measure flag to false
        calc_eigen = False          # init eigen measure flag to false
        calc_lfcd= False            # init lFCD measure flag to false
        
        # Select which method we're going to perform
        if method_option == 0:
            calc_degree = True
        elif method_option == 1:
            calc_eigen = True
        elif method_option == 2:
            calc_lfcd = True
        
        # Set weighting parameters
        out_binarize = weight_options[0]
        out_weighted = weight_options[1]
        
        corr_matrix = np.zeros((nvoxs, nvoxs), dtype = timeseries.dtype)
        
        
        print "Normalize TimeSeries"
        timeseries  = norm_cols(timeseries.T)
        
        
        print "Computing centrality across %i voxels" % nvoxs
        j = 0
        i = block_size
        while i <= timeseries.shape[1]:
            print "running block ->", i,j
            
            print "...correlating"
            np.dot(timeseries[:,j:i].T, timeseries, out=corr_matrix[j:i])
            
            j = i
            if i == nvoxs:
                break
            elif (i+block_size) > nvoxs:
                i = nvoxs
            else:
                i += block_size
        
        
        print "Calculating threshold"
        r_value = convert_sparsity_to_r(corr_matrix, threshold, full_matrix = True)
        print "r_value ->", r_value
        
        
        if calc_degree:
            if out_binarize:
                print "...calculating binarize degree"
                degree_binarize = degree_centrality(corr_matrix, r_value, method="binarize")
                out_list.append(('degree_centrality_binarize', degree_binarize))
            if out_weighted:
                print "...calculating weighted degree"
                degree_weighted = degree_centrality(corr_matrix, r_value, method="weighted")
                out_list.append(('degree_centrality_weighted', degree_weighted))
        
        
        if calc_eigen:
            if out_binarize:
                print "...calculating binarize eigenvector"
                eigen_binarize = eigenvector_centrality(corr_matrix, r_value, method="binarize")
                out_list.append(('eigenvector_centrality_binarize', eigen_binarize))
            if out_weighted:
                print "...calculating weighted eigenvector"
                eigen_weighted = eigenvector_centrality(corr_matrix, r_value, method="weighted")
                out_list.append(('eigenvector_centrality_weighted', eigen_weighted))            
            
    except Exception:
        print "Error while calculating centrality"
        raise
    
    return out_list