<jupyter_start><jupyter_text>Demonstration of DCBC evaluation usage in volume spaceThis notebook shows an example of a Distance controlled boundary coefficient (DCBC) evaluation of a striatum parcellation using the Multi-domain task battery (MDTB) functional dataset (glm7).  Installation and RequirmentsEnsure Python version >= 3.6 and pip installed on your system.- Install Python at https://www.python.org/downloads/- Install pip: https://pip.pypa.io/en/stable/installing/ Dependencies`pip install nibabel scipy numpy sklearn matplotlib` UsageBelow is a quick sample script of using the DCBC evaluation for evaluating `Power 2011` left hemisphere.<jupyter_code>import numpy as np
import scipy as sp
from DCBC_vol import compute_dist, compute_DCBC
import nibabel as nb
import mat73
from plotting import plot_single

# Load mask voxel index
vol_ind = mat73.loadmat('D:/data/sc2/encoding/glm7/striatum_avrgDataStruct.mat')['volIndx']
vol_ind = vol_ind.astype(int)<jupyter_output>data type not supported: struct, uint64<jupyter_text>Now, we load the parcellation that we want to evaluate from the file given the volxel indices of the mask.Note: we first need to transfer the vol index to 3d coordinates by F-order. This is because MATLAB uses row-order to perform linear indexing, while numpy uses colume order.<jupyter_code># Load parcellation given the mask file or voxel indices
parcel_mni = nb.load('D:/data/sc2/encoding/glm7/spect/masked_par_choi_7.nii.gz').get_fdata()
coord = np.unravel_index(vol_ind - 1, parcel_mni.shape, 'F')  # Note: the linear indexing in numpy is column-order
parcels = np.rint(parcel_mni[coord[0], coord[1], coord[2]])
print(parcels)<jupyter_output>[5. 0. 5. ... 0. 6. 0.]<jupyter_text>We also need a pairwise distance matrix of all mask voxel indices for DCBC calcluation.<jupyter_code># Compute the distance matrix between voxel pairs using the mask file, numpy default C-order
coord = np.asarray(coord).transpose()
dist = compute_dist(coord, 2)
print(dist)<jupyter_output>[[ 0.         38.05259518 12.16552506 ... 69.3108938  67.94115101
  68.93475176]
 [38.05259518  0.         26.         ... 51.57518783 51.2249939
  50.99019514]
 [12.16552506 26.          0.         ... 62.09669879 60.95900262
  61.6116872 ]
 ...
 [69.3108938  51.57518783 62.09669879 ...  0.          2.
   2.        ]
 [67.94115101 51.2249939  60.95900262 ...  2.          0.
   2.82842712]
 [68.93475176 50.99019514 61.6116872  ...  2.          2.82842712
   0.        ]]<jupyter_text>Here, we load subject functional data for DCBC evaluation and several experiment settings.<jupyter_code># Load functional profile (betas) and several parameters for evaluation settings
T = mat73.loadmat('D:/data/sc2/encoding/glm7/striatum_avrgDataStruct.mat')['T']
returnsubj = [2,3,4,6,8,9,10,12,14,15,17,18,19,20,21,22,24,25,26,27,28,29,30,31]
session, maxDist, binWidth = 1, 90, 5<jupyter_output>data type not supported: struct, uint64<jupyter_text>Now, we start the real DCBC evaluation on the given parcellation using selected subjects and given experiment settings. So here we set the bin width = 5 mm, the maximum distance between any pair of voxels is 90 mm. We only use subjects session 1 data.<jupyter_code>wcorr_array, bcorr_array, dcbc_array = np.array([]), np.array([]), np.array([])
for sub in returnsubj:
    data = T['data'][(T['SN'] == sub) & (T['sess'] == session)].transpose()
    R = compute_DCBC(maxDist=maxDist, func=data, dist=dist, binWidth=binWidth, parcellation=parcels)
    wcorr_array = np.append(wcorr_array, R['corr_within'])
    bcorr_array = np.append(bcorr_array, R['corr_between'])
    dcbc_array = np.append(dcbc_array, R['DCBC'])

# print(wcorr_array, bcorr_array, dcbc_array)<jupyter_output><empty_output><jupyter_text>After we finishe the DCBC evalaution for all subjects, we plot the un-weighted within- and between-correlation curves. A bigger gap between two curves means the given parcellation has higher quality to functionally separate the brain regions. Otherwise, the parcellation cannot functionally separate the brain obviously. In the extrame, the two curves are the same for random parcellations.<jupyter_code>%matplotlib inline
plot_single(within=wcorr_array, between=bcorr_array, maxDist=90, binWidth=5,
                subjects=returnsubj, within_color='k', between_color='r')
print(dcbc_array)<jupyter_output><empty_output>
{'fraction_non_alphanumeric': 0.10137299771167048, 'fraction_numerical': 0.07665903890160183, 'mean_word_length': 4.669260700389105, 'pattern_counts': {'":': 0, '<': 21, '<?xml version=': 0, '>': 22, 'https://': 2, 'lorem ipsum': 0, 'www.': 1, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 1, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'chain_length': '6', 'dir': 'jupyter-structured-clean-dedup', 'id': '625787', 'license': 'MIT', 'n_tokens_mistral': 1676, 'n_tokens_neox': 1429, 'n_words': 442, 'path': 'sample_volume.ipynb', 'repo_name': 'DiedrichsenLab/DCBC', 'size': '4370'}