Beispiel #1
0
def calc_map_corr(data_file1,
                  data_file2,
                  atlas_name,
                  roi_name,
                  out_file,
                  map_names1=None,
                  map_names2=None,
                  index=False):
    """
    计算指定atlas的ROI内的data1 maps和data2 maps的相关
    存出的CSV文件的index是map_names1, column是map_names2

    Args:
        data_file1 (str): end with .dscalar.nii
            shape=(n_map1, LR_count_32k)
        data_file2 (str): end with .dscalar.nii
            shape=(n_map2, LR_count_32k)
        atlas_name (str):
        roi_name (str):
        out_file (str):
        map_names1 (list, optional): Defaults to None.
            If is None, use map names in data1_file.
        map_names2 (list, optional): Defaults to None.
            If is None, use map names in data2_file.
        index (bool, optional): Defaults to False.
            Save index of DataFrame or not
    """
    # prepare
    reader1 = CiftiReader(data_file1)
    reader2 = CiftiReader(data_file2)
    data_maps1 = reader1.get_data()
    data_maps2 = reader2.get_data()
    atlas = Atlas(atlas_name)
    assert atlas.maps.shape == (1, LR_count_32k)
    roi_idx_map = atlas.maps[0] == atlas.roi2label[roi_name]
    data_maps1 = data_maps1[:, roi_idx_map]
    data_maps2 = data_maps2[:, roi_idx_map]

    if map_names1 is None:
        map_names1 = reader1.map_names()
    else:
        assert len(map_names1) == data_maps1.shape[0]

    if map_names2 is None:
        map_names2 = reader2.map_names()
    else:
        assert len(map_names2) == data_maps2.shape[0]

    # calculate
    corrs = 1 - cdist(data_maps1, data_maps2, 'correlation')

    # save
    df = pd.DataFrame(corrs, map_names1, map_names2)
    df.to_csv(out_file, index=index)
Beispiel #2
0
def vtx_corr_col(data_file1, atlas_name, roi_name, data_file2, column, idx_col,
                 out_file):
    """
    计算data_file1中指定atlas ROI内的所有顶点序列和data_file2中指定column序列的相关

    Args:
        data_file1 (str): end with .dscalar.nii
            shape=(N, LR_count_32k)
        atlas_name (str):
        roi_name (str):
        data_file2 (str): end with .csv
            shape=(N, n_col)
        column (str):
        idx_col (int): specify index column of csv file
            If None, means no index column.
    """
    # prepare
    reader = CiftiReader(data_file1)
    maps = reader.get_data()
    atlas = Atlas(atlas_name)
    assert atlas.maps.shape == (1, LR_count_32k)
    roi_idx_map = atlas.maps[0] == atlas.roi2label[roi_name]
    maps = maps[:, roi_idx_map]

    df = pd.read_csv(data_file2, index_col=idx_col)
    col_vec = np.array(df[column])
    col_vec = np.expand_dims(col_vec, 0)

    # calculate
    data = np.ones((1, LR_count_32k)) * np.nan
    data[0, roi_idx_map] = 1 - cdist(col_vec, maps.T, 'correlation')[0]

    # save
    save2cifti(out_file, data, reader.brain_models())
Beispiel #3
0
def calc_meas_individual(hemi='lh'):
    import nibabel as nib
    import numpy as np
    import pickle as pkl
    from magicbox.io.io import CiftiReader
    from cxy_hcp_ffa.lib.predefine import hemi2stru, roi2label

    # inputs
    work_dir = pjoin(proj_dir,
                     'analysis/s2/1080_fROI/refined_with_Kevin/tfMRI')
    rois_file = pjoin(proj_dir, 'analysis/s2/1080_fROI/'
                      f'refined_with_Kevin/rois_v3_{hemi}.nii.gz')
    meas_file = pjoin(proj_dir, 'analysis/s2/activation.dscalar.nii')

    # outputs
    out_file = pjoin(work_dir, f'individual_activ_{hemi}.pkl')

    rois = nib.load(rois_file).get_data().squeeze().T
    n_roi = len(roi2label)
    meas_reader = CiftiReader(meas_file)
    meas = meas_reader.get_data(hemi2stru[hemi], True)
    n_subj = meas.shape[0]

    roi_meas = {'shape': 'n_roi x n_subj', 'roi': list(roi2label.keys()),
                'meas': np.ones((n_roi, n_subj)) * np.nan}
    for roi_idx, roi in enumerate(roi_meas['roi']):
        lbl_idx_arr = rois == roi2label[roi]
        for subj_idx in range(n_subj):
            lbl_idx_vec = lbl_idx_arr[subj_idx]
            if np.any(lbl_idx_vec):
                roi_meas['meas'][roi_idx, subj_idx] = np.mean(
                    meas[subj_idx][lbl_idx_vec])
    pkl.dump(roi_meas, open(out_file, 'wb'))
def calc_meas_test(roi_type):
    """
    用45个被试在test或retest中定出的个体FFA去提取各自在test的face selectivity。

    Args:
        roi_type (str): ROI-test or ROI-retest
    """
    import numpy as np
    import pandas as pd
    import nibabel as nib
    from magicbox.io.io import CiftiReader
    from cxy_hcp_ffa.lib.predefine import hemi2stru, roi2label

    # inputs
    hemis = ('lh', 'rh')
    rois = ('pFus-face', 'mFus-face')
    subj_file_45 = pjoin(proj_dir, 'data/HCP/wm/analysis_s2/'
                         'retest/subject_id')
    subj_file_1080 = pjoin(proj_dir, 'analysis/s2/subject_id')
    meas_file = pjoin(proj_dir, 'analysis/s2/activation.dscalar.nii')
    roi_type2file = {
        'ROI-test':
        pjoin(
            proj_dir, 'analysis/s2/1080_fROI/refined_with_Kevin/'
            'rois_v3_{hemi}.nii.gz'),
        'ROI-retest':
        pjoin(
            proj_dir, 'analysis/s2/1080_fROI/refined_with_Kevin/'
            'retest/rois_{hemi}_v2.nii.gz')
    }
    roi_file = roi_type2file[roi_type]

    # outputs
    out_file = pjoin(work_dir, f'activ-test_{roi_type}.csv')

    # prepare
    subj_ids_45 = open(subj_file_45).read().splitlines()
    subj_ids_1080 = open(subj_file_1080).read().splitlines()
    retest_idx_in_1080 = [subj_ids_1080.index(i) for i in subj_ids_45]
    n_subj = len(subj_ids_45)
    out_df = pd.DataFrame(index=range(n_subj))

    # calculate
    meas_reader = CiftiReader(meas_file)
    for hemi in hemis:
        meas_maps = meas_reader.get_data(hemi2stru[hemi],
                                         True)[retest_idx_in_1080]
        roi_maps = nib.load(roi_file.format(hemi=hemi)).get_fdata().squeeze().T
        if roi_type == 'ROI-test':
            roi_maps = roi_maps[retest_idx_in_1080]
        for roi in rois:
            col = f"{hemi}_{roi.split('-')[0]}"
            for idx in range(n_subj):
                roi_idx_map = roi_maps[idx] == roi2label[roi]
                if np.any(roi_idx_map):
                    out_df.loc[idx, col] = np.mean(meas_maps[idx][roi_idx_map])

    # save
    out_df.to_csv(out_file, index=False)
def separate_networks():
    """
    把ColeNetwork的12个网络分到单独的map里。
    每个map的MMP parcel的label保留原来的样子。
    需要注意的是multimodal_glasser的MMP_mpmLR32k.dlabel.nii中,
    ROI label的编号1~180是右脑,181~360是左脑。0对应的是???
    而cortex_parcel_network_assignments.mat中0~359的index是左脑在先
    """
    import numpy as np
    import nibabel as nib
    from scipy.io import loadmat
    from cxy_visual_dev.lib.ColeNet import get_name_label_of_ColeNetwork
    from magicbox.io.io import CiftiReader, save2cifti

    # inputs
    mmp_file = '/nfs/p1/atlases/multimodal_glasser/surface/'\
               'MMP_mpmLR32k.dlabel.nii'
    roi2net_file = pjoin(cole_dir, 'cortex_parcel_network_assignments.mat')

    # outputs
    out_file = pjoin(work_dir, 'networks.dlabel.nii')

    # load
    mmp_reader = CiftiReader(mmp_file)
    mmp_map = mmp_reader.get_data()[0]
    lbl_tab_raw = mmp_reader.label_tables()[0]

    roi2net = loadmat(roi2net_file)['netassignments'][:, 0]
    roi2net = np.r_[roi2net[180:], roi2net[:180]]
    net_labels = np.unique(roi2net)

    # prepare
    data = np.zeros((len(net_labels), len(mmp_map)), dtype=np.uint16)
    map_names = []
    label_tables = []
    net_lbl2name = {}
    for name, lbl in zip(*get_name_label_of_ColeNetwork()):
        net_lbl2name[lbl] = name

    # calculate
    for net_idx, net_lbl in enumerate(net_labels):
        roi_labels = np.where(roi2net == net_lbl)[0] + 1
        lbl_tab = nib.cifti2.cifti2.Cifti2LabelTable()
        lbl_tab[0] = lbl_tab_raw[0]
        for roi_lbl in roi_labels:
            data[net_idx, mmp_map == roi_lbl] = roi_lbl
            lbl_tab[roi_lbl] = lbl_tab_raw[roi_lbl]
        map_names.append(net_lbl2name[net_lbl])
        label_tables.append(lbl_tab)

    # save
    save2cifti(out_file,
               data,
               mmp_reader.brain_models(),
               map_names,
               label_tables=label_tables)
Beispiel #6
0
def calc_meas_individual(hemi='lh', meas='thickness'):
    import nibabel as nib
    import numpy as np
    import pickle as pkl
    from magicbox.io.io import CiftiReader
    from cxy_hcp_ffa.lib.predefine import hemi2stru, roi2label

    rois = ('IOG-face', 'pFus-face', 'mFus-face')
    rois_file = pjoin(
        proj_dir, 'analysis/s2/1080_fROI/'
        f'refined_with_Kevin/rois_v3_{hemi}.nii.gz')
    subj_file = pjoin(proj_dir, 'analysis/s2/subject_id')
    meas_id_file = pjoin(proj_dir, 'data/HCP/subject_id_1096')
    meas2file = {
        'thickness':
        '/nfs/p1/public_dataset/datasets/hcp/DATA/'
        'HCP_S1200_GroupAvg_v1/HCP_S1200_GroupAvg_v1/'
        'S1200.All.thickness_MSMAll.32k_fs_LR.dscalar.nii',
        'myelin':
        '/nfs/p1/public_dataset/datasets/hcp/DATA/'
        'HCP_S1200_GroupAvg_v1/HCP_S1200_GroupAvg_v1/'
        'S1200.All.MyelinMap_BC_MSMAll.32k_fs_LR.dscalar.nii',
        'va':
        '/nfs/p1/public_dataset/datasets/hcp/DATA/'
        'HCP_S1200_GroupAvg_v1/HCP_S1200_GroupAvg_v1/'
        'S1200.All.midthickness_MSMAll_va.32k_fs_LR.dscalar.nii'
    }
    meas_file = meas2file[meas]
    trg_file = pjoin(work_dir, f'rois_v3_{hemi}_{meas}.pkl')

    roi_maps = nib.load(rois_file).get_fdata().squeeze().T
    n_roi = len(rois)
    subj_ids = open(subj_file).read().splitlines()
    n_subj = len(subj_ids)
    meas_reader = CiftiReader(meas_file)
    meas_ids = open(meas_id_file).read().splitlines()
    meas_indices = [meas_ids.index(i) for i in subj_ids]
    meas_maps = meas_reader.get_data(hemi2stru[hemi], True)[meas_indices]

    roi_meas = {
        'shape': 'n_roi x n_subj',
        'roi': rois,
        'meas': np.ones((n_roi, n_subj)) * np.nan
    }
    for roi_idx, roi in enumerate(roi_meas['roi']):
        lbl_idx_arr = roi_maps == roi2label[roi]
        for subj_idx in range(n_subj):
            lbl_idx_vec = lbl_idx_arr[subj_idx]
            meas_map = meas_maps[subj_idx]
            if np.any(lbl_idx_vec):
                if meas == 'va':
                    tmp = np.sum(meas_map[lbl_idx_vec])
                else:
                    tmp = np.mean(meas_map[lbl_idx_vec])
                roi_meas['meas'][roi_idx, subj_idx] = tmp
    pkl.dump(roi_meas, open(trg_file, 'wb'))
def calc_pattern_corr_between_twins(meas_name='thickness'):
    """
    Calculate spatial pattern correlation between each twin pair.
    """
    import pandas as pd
    import nibabel as nib
    from magicbox.io.io import CiftiReader
    from scipy.stats import pearsonr

    twins_id_file = pjoin(work_dir, 'twins_id_1080.csv')
    meas2file = {
        'thickness':
        '/nfs/p1/public_dataset/datasets/hcp/DATA/'
        'HCP_S1200_GroupAvg_v1/HCP_S1200_GroupAvg_v1/'
        'S1200.All.thickness_MSMAll.32k_fs_LR.dscalar.nii',
        'myelin':
        '/nfs/p1/public_dataset/datasets/hcp/DATA/'
        'HCP_S1200_GroupAvg_v1/HCP_S1200_GroupAvg_v1/'
        'S1200.All.MyelinMap_BC_MSMAll.32k_fs_LR.dscalar.nii',
        'activ':
        pjoin(proj_dir, 'analysis/s2/activation.dscalar.nii')
    }
    hemis = ('lh', 'rh')
    hemi2stru = {
        'lh': 'CIFTI_STRUCTURE_CORTEX_LEFT',
        'rh': 'CIFTI_STRUCTURE_CORTEX_RIGHT'
    }
    mpm_file = pjoin(
        proj_dir, 'analysis/s2/1080_fROI/refined_with_Kevin/'
        'MPM_v3_{hemi}_0.25.nii.gz')
    roi2label = {'IOG-face': 1, 'pFus-face': 2, 'mFus-face': 3}
    zyg2label = {'MZ': 1, 'DZ': 2}
    out_file = pjoin(work_dir, f'twins_pattern-corr_{meas_name}.csv')

    df = pd.read_csv(twins_id_file)
    meas_reader = CiftiReader(meas2file[meas_name])
    meas_ids = [int(name.split('_')[0]) for name in meas_reader.map_names()]
    twin1_indices = [meas_ids.index(i) for i in df['twin1']]
    twin2_indices = [meas_ids.index(i) for i in df['twin2']]

    out_df = pd.DataFrame()
    out_df['zygosity'] = df['zygosity']
    out_df['zyg'] = [zyg2label[zyg] for zyg in df['zygosity']]
    for hemi in hemis:
        meas1 = meas_reader.get_data(hemi2stru[hemi], True)[twin1_indices]
        meas2 = meas_reader.get_data(hemi2stru[hemi], True)[twin2_indices]
        mpm = nib.load(mpm_file.format(hemi=hemi)).get_data().squeeze()
        for roi, lbl in roi2label.items():
            idx_vec = mpm == lbl
            out_df[f"{hemi}_{roi.split('-')[0]}"] = [
                pearsonr(i[idx_vec], j[idx_vec])[0]
                for i, j in zip(meas1, meas2)
            ]
    out_df.to_csv(out_file, index=False)
def zscore_data(data_file, out_file):
    """
    对每个被试做全脑zscore

    Args:
        data_file (str): .dscalar.nii
        out_file (str): .dscalar.nii
    """
    reader = CiftiReader(data_file)
    data = reader.get_data()
    data = zscore(data, 1)
    save2cifti(out_file, data, reader.brain_models(), reader.map_names())
Beispiel #9
0
def calc_meas_MPM(hemi='lh'):
    """
    用一半被试的MPM去提取另一半被试的激活值
    如果某个被试没有某个ROI,就不提取该被试该ROI的信号

    Args:
        hemi (str, optional): hemisphere. Defaults to 'lh'.
    """
    import numpy as np
    import pickle as pkl
    import nibabel as nib
    from cxy_hcp_ffa.lib.predefine import hemi2stru, roi2label
    from magicbox.io.io import CiftiReader

    hids = (1, 2)
    hid_file = pjoin(split_dir, 'half_id.npy')
    mpm_file = pjoin(split_dir, 'MPM_half{hid}_{hemi}.nii.gz')
    roi_file = pjoin(proj_dir, 'analysis/s2/1080_fROI/refined_with_Kevin/'
                               f'rois_v3_{hemi}.nii.gz')
    src_file = pjoin(proj_dir, 'analysis/s2/activation.dscalar.nii')
    trg_file = pjoin(work_dir, f'activ_{hemi}.pkl')

    hid_vec = np.load(hid_file)
    n_subj = len(hid_vec)
    roi_maps = nib.load(roi_file).get_data().squeeze().T
    n_roi = len(roi2label)
    meas_reader = CiftiReader(src_file)
    meas = meas_reader.get_data(hemi2stru[hemi], True)

    out_dict = {'shape': 'n_roi x n_subj',
                'roi': list(roi2label.keys()),
                'meas': np.ones((n_roi, n_subj)) * np.nan}
    for hid in hids:
        hid_idx_vec = hid_vec == hid
        mpm = nib.load(mpm_file.format(hid=hid, hemi=hemi)
                       ).get_data().squeeze()
        for roi_idx, roi in enumerate(out_dict['roi']):
            roi_idx_vec = np.any(roi_maps == roi2label[roi], 1)
            valid_idx_vec = np.logical_and(~hid_idx_vec, roi_idx_vec)
            mpm_idx_vec = mpm == roi2label[roi]
            meas_masked = meas[valid_idx_vec][:, mpm_idx_vec]
            out_dict['meas'][roi_idx][valid_idx_vec] = np.mean(meas_masked, 1)
    pkl.dump(out_dict, open(trg_file, 'wb'))
Beispiel #10
0
def calc_mean_meas_map(meas='thickness'):
    """
    得到1080个被试的平均map
    """
    import numpy as np
    from magicbox.io.io import CiftiReader, save2nifti
    from cxy_hcp_ffa.lib.predefine import hemi2stru

    # inputs
    hemis = ('lh', 'rh')
    subj_file = pjoin(proj_dir, 'analysis/s2/subject_id')
    meas_id_file = pjoin(proj_dir, 'data/HCP/subject_id_1096')
    meas2file = {
        'thickness':
        '/nfs/p1/public_dataset/datasets/hcp/DATA/'
        'HCP_S1200_GroupAvg_v1/HCP_S1200_GroupAvg_v1/'
        'S1200.All.thickness_MSMAll.32k_fs_LR.dscalar.nii',
        'myelin':
        '/nfs/p1/public_dataset/datasets/hcp/DATA/'
        'HCP_S1200_GroupAvg_v1/HCP_S1200_GroupAvg_v1/'
        'S1200.All.MyelinMap_BC_MSMAll.32k_fs_LR.dscalar.nii',
        'va':
        '/nfs/p1/public_dataset/datasets/hcp/DATA/'
        'HCP_S1200_GroupAvg_v1/HCP_S1200_GroupAvg_v1/'
        'S1200.All.midthickness_MSMAll_va.32k_fs_LR.dscalar.nii'
    }

    # outputs
    out_file = pjoin(work_dir, '{meas}_mean-1080_{hemi}.nii.gz')

    # prepare
    subj_ids = open(subj_file).read().splitlines()
    meas_reader = CiftiReader(meas2file[meas])
    meas_ids = open(meas_id_file).read().splitlines()
    meas_indices = [meas_ids.index(i) for i in subj_ids]

    # calculate
    for hemi in hemis:
        meas_maps = meas_reader.get_data(hemi2stru[hemi], True)[meas_indices]
        meas_mean = np.mean(meas_maps, 0)
        meas_mean = np.expand_dims(meas_mean, (1, 2))
        save2nifti(out_file.format(meas=meas, hemi=hemi), meas_mean)
def separate_networks():
    """
    把ColeNetwork的12个网络分到单独的map里。
    每个map的MMP parcel的label保留原来的样子。
    需要注意的是multimodal_glasser的MMP_mpmLR32k.dlabel.nii中,
    ROI label的编号1~180是右脑,181~360是左脑。0对应的是???
    而cortex_parcel_network_assignments.mat中0~359的index是左脑在先
    """
    # outputs
    out_file = pjoin(work_dir, 'networks.dlabel.nii')

    # load
    mmp_reader = CiftiReader(mmp_map_file)
    mmp_map = mmp_reader.get_data()[0]
    lbl_tab_raw = mmp_reader.label_tables()[0]

    roi2net = loadmat(cole_net_assignment_file)['netassignments'][:, 0]
    roi2net = np.r_[roi2net[180:], roi2net[:180]]
    net_labels = np.unique(roi2net)

    # prepare
    data = np.zeros((len(net_labels), len(mmp_map)), dtype=np.uint16)
    map_names = []
    label_tables = []

    # calculate
    for net_idx, net_lbl in enumerate(net_labels):
        roi_labels = np.where(roi2net == net_lbl)[0] + 1
        lbl_tab = nib.cifti2.cifti2.Cifti2LabelTable()
        lbl_tab[0] = lbl_tab_raw[0]
        for roi_lbl in roi_labels:
            data[net_idx, mmp_map == roi_lbl] = roi_lbl
            lbl_tab[roi_lbl] = lbl_tab_raw[roi_lbl]
        map_names.append(cole_label2name[net_lbl])
        label_tables.append(lbl_tab)

    # save
    save2cifti(out_file,
               data,
               mmp_reader.brain_models(),
               map_names,
               label_tables=label_tables)
Beispiel #12
0
def polyfit(data_file, info_file, deg, out_file):
    """
    对时间序列进行多项式拟合

    Args:
        data_file (str): .csv | .dscalar.nii
            If is .csv, fit each column with ages.
            If is .dscalar.nii, fit each vertex with ages.
        info_file (str): .csv
        deg (int): degree of polynomial
        out_file (str): file to output
            same postfix with data_file
    """
    # prepare
    if data_file.endswith('.csv'):
        assert out_file.endswith('.csv')
        reader = pd.read_csv(data_file)
        data = np.array(reader)
    elif data_file.endswith('.dscalar.nii'):
        assert out_file.endswith('.dscalar.nii')
        reader = CiftiReader(data_file)
        data = reader.get_data()
    else:
        raise ValueError(1)

    # calculate
    ages = np.array(pd.read_csv(info_file)['age in years'])
    coefs = np.polyfit(ages, data, deg)
    n_row = coefs.shape[0]
    if deg == 1:
        assert n_row == 2
        row_names = ['coef', 'intercept']
    else:
        row_names = [''] * n_row
        raise Warning("Can't provide row names for degree:", deg)

    # save
    if out_file.endswith('.csv'):
        df = pd.DataFrame(coefs, row_names, reader.columns)
        df.to_csv(out_file)
    else:
        save2cifti(out_file, coefs, reader.brain_models(), row_names)
Beispiel #13
0
def get_curvature(hemi='lh'):
    """
    把45个retest被试在retest session的curvature合并成左右脑两个nifti文件,
    主要是为了我那个程序在标定个体ROI的时候读取和显示曲率。
    之前服务器上没有retest的结构数据,我想当然地认为同一个被试的沟回曲率在
    两次测量应该是一模一样的,所以在标定v1和v2版ROI的时候参照的是test session的曲率;
    这次我下了retest的结构数据,决定用retest session的曲率校对一下retest个体ROI。
    """
    import numpy as np
    from magicbox.io.io import CiftiReader, save2nifti
    from cxy_hcp_ffa.lib.predefine import hemi2stru

    # inputs
    hemis = ('lh', 'rh')
    fpath = '/nfs/m1/hcp/retest/{0}/MNINonLinear/fsaverage_LR32k/'\
            '{0}.curvature_MSMAll.32k_fs_LR.dscalar.nii'
    subj_id_file = pjoin(work_dir, 'subject_id')

    # outputs
    out_file = pjoin(work_dir, 'curvature_{hemi}.nii.gz')

    # prepare
    subj_ids = open(subj_id_file).read().splitlines()
    n_subj = len(subj_ids)
    hemi2data = {}
    for hemi in hemis:
        hemi2data[hemi] = np.zeros((32492, 1, 1, n_subj), np.float64)

    # calculate
    for subj_idx, subj_id in enumerate(subj_ids):
        reader = CiftiReader(fpath.format(subj_id))
        for hemi in hemis:
            data_tmp = reader.get_data(hemi2stru[hemi], True)[0]
            hemi2data[hemi][:, 0, 0, subj_idx] = data_tmp
        print(f'Finished: {subj_idx+1}/{n_subj}')

    # save
    for hemi in hemis:
        save2nifti(out_file.format(hemi=hemi), hemi2data[hemi])
Beispiel #14
0
def mask_maps(data_file, atlas_name, roi_name, out_file):
    """
    把data map在指定atlas的ROI以外的部分全赋值为nan

    Args:
        data_file (str): end with .dscalar.nii
            shape=(n_map, LR_count_32k)
        atlas_name (str):
        roi_name (str):
        out_file (str):
    """
    # prepare
    reader = CiftiReader(data_file)
    data = reader.get_data()
    atlas = Atlas(atlas_name)
    assert atlas.maps.shape == (1, LR_count_32k)
    roi_idx_map = atlas.maps[0] == atlas.roi2label[roi_name]

    # calculate
    data[:, ~roi_idx_map] = np.nan

    # save
    save2cifti(out_file, data, reader.brain_models(), reader.map_names())
def calc_meas(meas_name='activ', atlas_name='MPM'):
    import time
    import numpy as np
    import pickle as pkl
    import nibabel as nib
    from magicbox.io.io import CiftiReader
    from cxy_hcp_ffa.lib.predefine import roi2label, hemi2stru

    # inputs
    hemis = ('lh', 'rh')
    rois = ('pFus-face', 'mFus-face')
    subj_file_45 = pjoin(proj_dir, 'data/HCP/wm/analysis_s2/'
                         'retest/subject_id')
    subj_file_1080 = pjoin(proj_dir, 'analysis/s2/subject_id')
    subj_file_1096 = pjoin(proj_dir, 'data/HCP/subject_id_1096')
    meas2file_test = {
        'thickness':
        '/nfs/p1/public_dataset/datasets/hcp/DATA/'
        'HCP_S1200_GroupAvg_v1/HCP_S1200_GroupAvg_v1/'
        'S1200.All.thickness_MSMAll.32k_fs_LR.dscalar.nii',
        'myelin':
        '/nfs/p1/public_dataset/datasets/hcp/DATA/'
        'HCP_S1200_GroupAvg_v1/HCP_S1200_GroupAvg_v1/'
        'S1200.All.MyelinMap_BC_MSMAll.32k_fs_LR.dscalar.nii',
        'activ':
        pjoin(proj_dir, 'analysis/s2/activation.dscalar.nii')
    }
    retest_dir = '/nfs/m1/hcp/retest'
    meas2file_retest = {
        'thickness':
        pjoin(
            retest_dir, '{0}/MNINonLinear/fsaverage_LR32k/'
            '{0}.thickness_MSMAll.32k_fs_LR.dscalar.nii'),
        'myelin':
        pjoin(
            retest_dir, '{0}/MNINonLinear/fsaverage_LR32k/'
            '{0}.MyelinMap_BC_MSMAll.32k_fs_LR.dscalar.nii'),
        'activ':
        pjoin(
            retest_dir, '{0}/MNINonLinear/Results/tfMRI_WM/'
            'tfMRI_WM_hp200_s2_level2_MSMAll.feat/GrayordinatesStats/'
            'cope20.feat/zstat1.dtseries.nii')
    }
    atlas2file = {
        'MPM':
        pjoin(
            proj_dir, 'analysis/s2/1080_fROI/refined_with_Kevin/'
            'MPM_v3_{hemi}_0.25.nii.gz'),
        'ROIv3':
        pjoin(
            proj_dir, 'analysis/s2/1080_fROI/refined_with_Kevin/'
            'rois_v3_{hemi}.nii.gz')
    }

    # outputs
    out_file = pjoin(work_dir, f'{meas_name}_{atlas_name}.pkl')

    # prepare subject IDs
    subj_ids_45 = open(subj_file_45).read().splitlines()
    subj_ids_1080 = open(subj_file_1080).read().splitlines()
    subj_ids_1096 = open(subj_file_1096).read().splitlines()
    retest_idx_in_1080 = [subj_ids_1080.index(i) for i in subj_ids_45]
    retest_idx_in_1096 = [subj_ids_1096.index(i) for i in subj_ids_45]
    n_subj = len(subj_ids_45)

    # prepare atlas
    hemi2atlas = {}
    for hemi in hemis:
        atlas_tmp = nib.load(atlas2file[atlas_name].format(hemi=hemi))
        atlas_tmp = atlas_tmp.get_fdata().squeeze()
        if atlas_name == 'MPM':
            atlas_tmp = np.expand_dims(atlas_tmp, 0)
            hemi2atlas[hemi] = np.repeat(atlas_tmp, n_subj, 0)
        elif atlas_name == 'ROIv3':
            hemi2atlas[hemi] = atlas_tmp.T[retest_idx_in_1080]
        else:
            raise ValueError('Not supported atlas name:', atlas_name)

    # prepare test measurement maps
    if meas_name == 'activ':
        retest_idx_vec = retest_idx_in_1080
    else:
        retest_idx_vec = retest_idx_in_1096
    meas_reader_test = CiftiReader(meas2file_test[meas_name])
    hemi2maps_test = {}
    for hemi in hemis:
        hemi2maps_test[hemi] = meas_reader_test.get_data(
            hemi2stru[hemi], True)[retest_idx_vec]

    # prepare out data
    data = {}
    for hemi in hemis:
        for roi in rois:
            roi_name = roi.split('-')[0]
            data[f"{hemi}_{roi_name}_test"] = np.ones(n_subj) * np.nan
            data[f"{hemi}_{roi_name}_retest"] = np.ones(n_subj) * np.nan

    # calculate
    for subj_idx, subj_id in enumerate(subj_ids_45):
        time1 = time.time()
        meas_reader_retest = CiftiReader(
            meas2file_retest[meas_name].format(subj_id))
        for hemi in hemis:
            meas_map_test = hemi2maps_test[hemi][subj_idx]
            meas_map_retest = meas_reader_retest.get_data(
                hemi2stru[hemi], True)[0]
            atlas_map = hemi2atlas[hemi][subj_idx]
            for roi in rois:
                idx_vec = atlas_map == roi2label[roi]
                if np.any(idx_vec):
                    roi_name = roi.split('-')[0]
                    data[f"{hemi}_{roi_name}_test"][subj_idx] =\
                        np.mean(meas_map_test[idx_vec])
                    data[f"{hemi}_{roi_name}_retest"][subj_idx] =\
                        np.mean(meas_map_retest[idx_vec])
        print(
            f'Finished {subj_idx+1}/{n_subj}: cost {time.time()-time1} seconds'
        )

    # save
    pkl.dump(data, open(out_file, 'wb'))
Beispiel #16
0
def prepare_series_ind(sess=1, run='LR'):
    import numpy as np
    import nibabel as nib
    import pickle as pkl
    from cxy_hcp_ffa.lib.predefine import hemi2stru, roi2label
    from magicbox.io.io import CiftiReader

    # prepare subjects info
    subj_id_file = pjoin(work_dir, 'rfMRI_REST_id')
    subj_file_1080 = pjoin(proj_dir, 'analysis/s2/subject_id')
    subj_ids = open(subj_id_file).read().splitlines()
    subj_ids_1080 = open(subj_file_1080).read().splitlines()
    subj_idx_in_1080 = [subj_ids_1080.index(i) for i in subj_ids]
    n_subj = len(subj_ids)

    # prepare seeds
    seeds = ('IOG-face', 'pFus-face', 'mFus-face')
    n_seed = len(seeds)
    seed_mask_lh_file = pjoin(
        proj_dir, 'analysis/s2/1080_fROI/'
        'refined_with_Kevin/rois_v3_lh.nii.gz')
    seed_mask_rh_file = pjoin(
        proj_dir, 'analysis/s2/1080_fROI/'
        'refined_with_Kevin/rois_v3_rh.nii.gz')
    hemi2seed_mask = {
        'lh':
        nib.load(seed_mask_lh_file).get_fdata().squeeze().T[subj_idx_in_1080],
        'rh':
        nib.load(seed_mask_rh_file).get_fdata().squeeze().T[subj_idx_in_1080]
    }

    # prepare series dictionary
    n_tp = 1200  # the number of time points
    seed_lh_dict = {
        'shape': 'n_subject x n_seed x n_time_point',
        'subject': subj_ids,
        'seed': seeds,
        'rfMRI': np.ones((n_subj, n_seed, n_tp)) * np.nan
    }
    seed_rh_dict = {
        'shape': 'n_subject x n_seed x n_time_point',
        'subject': subj_ids,
        'seed': seeds,
        'rfMRI': np.ones((n_subj, n_seed, n_tp)) * np.nan
    }
    hemi2seed_dict = {'lh': seed_lh_dict, 'rh': seed_rh_dict}

    # prepare outputs
    out_seed_lh = pjoin(work_dir, f'rfMRI{sess}_{run}_ROIv3_lh.pkl')
    out_seed_rh = pjoin(work_dir, f'rfMRI{sess}_{run}_ROIv3_rh.pkl')

    # start
    maps_files = '/nfs/m1/hcp/retest/{0}/MNINonLinear/Results/rfMRI_REST{1}_{2}/'\
                 'rfMRI_REST{1}_{2}_Atlas_MSMAll_hp2000_clean.dtseries.nii'
    for subj_idx, subj_id in enumerate(subj_ids):
        print('Progress: {}/{}'.format(subj_idx + 1, n_subj))

        # prepare maps
        maps_file = maps_files.format(subj_id, sess, run)
        maps_reader = CiftiReader(maps_file)
        hemi2maps = {
            'lh': maps_reader.get_data(hemi2stru['lh'], True),
            'rh': maps_reader.get_data(hemi2stru['rh'], True)
        }

        for hemi in ['lh', 'rh']:

            maps = hemi2maps[hemi]

            # seed dict
            seed_mask = hemi2seed_mask[hemi]
            for seed_idx, seed in enumerate(seeds):
                idx_vec = seed_mask[subj_idx] == roi2label[seed]
                if np.any(idx_vec):
                    hemi2seed_dict[hemi]['rfMRI'][subj_idx, seed_idx] =\
                        np.mean(maps[:, idx_vec], 1)

    # save
    pkl.dump(hemi2seed_dict['lh'], open(out_seed_lh, 'wb'))
    pkl.dump(hemi2seed_dict['rh'], open(out_seed_rh, 'wb'))
Beispiel #17
0
def calc_gdist(method='peak'):
    """Calculate geodesic distance between each two ROIs.

    Args:
        method (str, optional): 'peak' or 'min'
            If 'peak', use the distance between two vertices
            with peak activation values in two ROIs respectively.
            If 'min', use the minimum distance of pair-wise
            vertices between the two ROIs.
            Defaults to 'peak'.
    """
    import os
    import time
    import gdist
    import numpy as np
    import pandas as pd
    import nibabel as nib
    from cxy_hcp_ffa.lib.predefine import roi2label, hemi2stru
    from magicbox.io.io import CiftiReader

    # inputs
    rois = ('IOG-face', 'pFus-face', 'mFus-face')
    hemis = ('lh', 'rh')
    hemi2Hemi = {'lh': 'L', 'rh': 'R'}
    subj_file = pjoin(proj_dir, 'analysis/s2/subject_id')
    roi_file = pjoin(work_dir, 'rois_v3_{}.nii.gz')
    geo_file = '/nfs/m1/hcp/{sid}/T1w/fsaverage_LR32k/' \
               '{sid}.{Hemi}.midthickness_MSMAll.32k_fs_LR.surf.gii'
    activ_file = pjoin(proj_dir, 'analysis/s2/activation.dscalar.nii')

    # outputs
    log_file = pjoin(work_dir, f'gdist_{method}_log')
    out_file = pjoin(work_dir, f'gdist_{method}.csv')

    # preparation
    subj_ids = open(subj_file).read().splitlines()
    n_subj = len(subj_ids)
    activ_reader = CiftiReader(activ_file)
    out_dict = {}
    for hemi in hemis:
        for roi1_idx, roi1 in enumerate(rois[:-1]):
            for roi2 in rois[roi1_idx + 1:]:
                k = f"{hemi}_{roi1.split('-')[0]}-{roi2.split('-')[0]}"
                out_dict[k] = np.ones(n_subj, dtype=np.float64) * np.nan
    log_lines = []

    # calculation
    for hemi in hemis:
        roi_maps = nib.load(roi_file.format(hemi)).get_fdata().squeeze().T
        activ_maps = activ_reader.get_data(hemi2stru[hemi], True)
        assert roi_maps.shape == activ_maps.shape
        for subj_idx, subj_id in enumerate(subj_ids):
            time1 = time.time()
            roi_map = roi_maps[subj_idx]
            activ_map = activ_maps[subj_idx]
            g_file = geo_file.format(sid=subj_id, Hemi=hemi2Hemi[hemi])
            if not os.path.exists(g_file):
                log_lines.append(f'{g_file} does not exist.')
                continue
            geo = nib.load(g_file)
            coords = geo.get_arrays_from_intent('NIFTI_INTENT_POINTSET')[0]
            coords = coords.data.astype(np.float64)
            faces = geo.get_arrays_from_intent('NIFTI_INTENT_TRIANGLE')[0]
            faces = faces.data.astype(np.int32)
            for roi1_idx, roi1 in enumerate(rois[:-1]):
                roi1_idx_map = roi_map == roi2label[roi1]
                if np.any(roi1_idx_map):
                    for roi2 in rois[roi1_idx + 1:]:
                        roi2_idx_map = roi_map == roi2label[roi2]
                        if np.any(roi2_idx_map):
                            k = f"{hemi}_{roi1.split('-')[0]}-"\
                                f"{roi2.split('-')[0]}"
                            if method == 'peak':
                                roi1_max = np.max(activ_map[roi1_idx_map])
                                roi2_max = np.max(activ_map[roi2_idx_map])
                                roi1_idx_map =\
                                    np.logical_and(roi1_idx_map,
                                                   activ_map == roi1_max)
                                roi2_idx_map =\
                                    np.logical_and(roi2_idx_map,
                                                   activ_map == roi2_max)
                                roi1_vertices = np.where(roi1_idx_map)[0]
                                roi1_vertices = roi1_vertices.astype(np.int32)
                                n_vtx1 = len(roi1_vertices)
                                roi2_vertices = np.where(roi2_idx_map)[0]
                                roi2_vertices = roi2_vertices.astype(np.int32)
                                n_vtx2 = len(roi2_vertices)
                                if n_vtx1 > 1 or n_vtx2 > 1:
                                    msg = f'{subj_id}: {roi1} vs {roi2} '\
                                          f'has multiple peaks.'
                                    log_lines.append(msg)
                                    ds = []
                                    for src_vtx in roi1_vertices:
                                        src_vtx = np.array([src_vtx], np.int32)
                                        ds_tmp = \
                                            gdist.compute_gdist(coords, faces,
                                                                src_vtx,
                                                                roi2_vertices)
                                        ds.extend(ds_tmp)
                                    out_dict[k][subj_idx] = np.mean(ds)
                                elif n_vtx1 == 1 and n_vtx2 == 1:
                                    ds = gdist.compute_gdist(
                                        coords, faces, roi1_vertices,
                                        roi2_vertices)
                                    assert len(ds) == 1
                                    out_dict[k][subj_idx] = ds[0]
                                else:
                                    raise RuntimeError("Impossible!")
                            elif method == 'min':
                                roi1_vertices = np.where(roi1_idx_map)[0]
                                roi1_vertices = roi1_vertices.astype(np.int32)
                                roi2_vertices = np.where(roi2_idx_map)[0]
                                roi2_vertices = roi2_vertices.astype(np.int32)
                                ds = gdist.compute_gdist(
                                    coords, faces, roi1_vertices,
                                    roi2_vertices)
                                out_dict[k][subj_idx] = np.min(ds)
                            else:
                                raise ValueError(f'Not supported method: '
                                                 f'{method}')
            print(f'Finished: {subj_idx+1}/{n_subj}, '
                  f'cost {time.time()-time1} seconds.')

    # save out
    out_df = pd.DataFrame(out_dict)
    out_df.to_csv(out_file, index=False)
    out_log = '\n'.join(log_lines)
    open(log_file, 'w').write(out_log)
Beispiel #18
0
def calc_meas_retest(roi_type):
    """
    用45个被试在test或retest中定出的个体FFA去提取各自在retest的face selectivity。

    Args:
        roi_type (str): ROI-test or ROI-retest
    """
    import time
    import numpy as np
    import pandas as pd
    import nibabel as nib
    from magicbox.io.io import CiftiReader
    from cxy_hcp_ffa.lib.predefine import hemi2stru, roi2label

    # inputs
    hemis = ('lh', 'rh')
    rois = ('pFus-face', 'mFus-face')
    subj_file_45 = pjoin(proj_dir, 'data/HCP/wm/analysis_s2/'
                         'retest/subject_id')
    subj_file_1080 = pjoin(proj_dir, 'analysis/s2/subject_id')
    meas_file = '/nfs/m1/hcp/retest/{0}/MNINonLinear/Results/tfMRI_WM/'\
                'tfMRI_WM_hp200_s2_level2_MSMAll.feat/GrayordinatesStats/'\
                'cope20.feat/zstat1.dtseries.nii'
    roi_type2file = {
        'ROI-test':
        pjoin(
            proj_dir, 'analysis/s2/1080_fROI/refined_with_Kevin/'
            'rois_v3_{hemi}.nii.gz'),
        'ROI-retest':
        pjoin(
            proj_dir, 'analysis/s2/1080_fROI/refined_with_Kevin/'
            'retest/rois_{hemi}_v2.nii.gz')
    }
    roi_file = roi_type2file[roi_type]

    # outputs
    out_file = pjoin(work_dir, f'activ-retest_{roi_type}.csv')

    # prepare
    subj_ids_45 = open(subj_file_45).read().splitlines()
    subj_ids_1080 = open(subj_file_1080).read().splitlines()
    retest_idx_in_1080 = [subj_ids_1080.index(i) for i in subj_ids_45]
    n_subj = len(subj_ids_45)
    out_df = pd.DataFrame(index=range(n_subj))

    # prepare atlas
    hemi2atlas = {}
    for hemi in hemis:
        atlas = nib.load(roi_file.format(hemi=hemi)).get_fdata().squeeze().T
        if roi_type == 'ROI-test':
            hemi2atlas[hemi] = atlas[retest_idx_in_1080]
        else:
            hemi2atlas[hemi] = atlas

    # calculate
    for idx, subj_id in enumerate(subj_ids_45):
        time1 = time.time()
        meas_reader = CiftiReader(meas_file.format(subj_id))
        for hemi in hemis:
            meas_map = meas_reader.get_data(hemi2stru[hemi], True)[0]
            roi_map = hemi2atlas[hemi][idx]
            for roi in rois:
                col = f"{hemi}_{roi.split('-')[0]}"
                roi_idx_map = roi_map == roi2label[roi]
                if np.any(roi_idx_map):
                    out_df.loc[idx, col] = np.mean(meas_map[roi_idx_map])
        print(f'Finished {idx+1}/{n_subj}: cost {time.time()-time1} seconds')

    # save
    out_df.to_csv(out_file, index=False)
Beispiel #19
0
def prepare_series(sess=1, run='AP'):
    import numpy as np
    import nibabel as nib
    import pickle as pkl
    from cxy_hcp_ffa.lib.predefine import hemi2stru, roi2label
    from magicbox.io.io import CiftiReader

    # prepare seeds
    seeds = ('IOG-face', 'pFus-face', 'mFus-face')
    n_seed = len(seeds)
    seed_mask_lh_file = pjoin(
        proj_dir, 'analysis/s2/1080_fROI/'
        'refined_with_Kevin/MPM_v3_lh_0.25.nii.gz')
    seed_mask_rh_file = pjoin(
        proj_dir, 'analysis/s2/1080_fROI/'
        'refined_with_Kevin/MPM_v3_rh_0.25.nii.gz')
    hemi2seed_mask = {
        'lh': nib.load(seed_mask_lh_file).get_fdata().squeeze(),
        'rh': nib.load(seed_mask_rh_file).get_fdata().squeeze()
    }

    # prepare targets
    trg_file = '/nfs/p1/atlases/multimodal_glasser/surface/'\
        'MMP_mpmLR32k.dlabel.nii'
    trg_reader = CiftiReader(trg_file)
    hemi2trg_mask = {
        'lh': trg_reader.get_data(hemi2stru['lh'], True).squeeze(),
        'rh': trg_reader.get_data(hemi2stru['rh'], True).squeeze()
    }

    trg_labels = np.unique(np.r_[hemi2trg_mask['lh'], hemi2trg_mask['rh']])
    trg_labels = trg_labels[trg_labels != 0].astype(int).tolist()
    n_trg = len(trg_labels)

    # prepare series dictionary
    subj_id_file = pjoin(work_dir, 'rfMRI_REST_4run_id')
    subj_ids = open(subj_id_file).read().splitlines()
    n_subj = len(subj_ids)
    n_tp = 478  # the number of time points

    seed_lh_dict = {
        'shape': 'n_subject x n_seed x n_time_point',
        'subject': subj_ids,
        'seed': seeds,
        'rfMRI': np.ones((n_subj, n_seed, n_tp)) * np.nan
    }
    seed_rh_dict = {
        'shape': 'n_subject x n_seed x n_time_point',
        'subject': subj_ids,
        'seed': seeds,
        'rfMRI': np.ones((n_subj, n_seed, n_tp)) * np.nan
    }
    hemi2seed_dict = {'lh': seed_lh_dict, 'rh': seed_rh_dict}
    trg_dict = {
        'shape': 'n_subject x n_target x n_time_point',
        'subject': subj_ids,
        'trg_label': trg_labels,
        'rfMRI': np.ones((n_subj, n_trg, n_tp)) * np.nan
    }
    global_dict = {
        'shape': 'n_subject x n_global x n_time_point',
        'subject': subj_ids,
        'global': ['lr', 'lh', 'rh'],
        'rfMRI': np.ones((n_subj, 3, n_tp)) * np.nan
    }

    # prepare outputs
    out_seed_lh = pjoin(work_dir, f'rfMRI{sess}_{run}_MPM_lh.pkl')
    out_seed_rh = pjoin(work_dir, f'rfMRI{sess}_{run}_MPM_rh.pkl')
    out_trg = pjoin(work_dir, f'rfMRI{sess}_{run}_MMP.pkl')
    out_global = pjoin(work_dir, f'rfMRI{sess}_{run}_global.pkl')

    # start
    maps_files = '/nfs/e1/HCPD/fmriresults01/{0}/MNINonLinear/'\
        'Results/rfMRI_REST{1}_{2}/'\
        'rfMRI_REST{1}_{2}_Atlas_MSMAll_hp0_clean.dtseries.nii'
    for subj_idx, subj_id in enumerate(subj_ids):
        print('Progress: {}/{}'.format(subj_idx + 1, n_subj))

        # prepare maps
        maps_file = maps_files.format(f'{subj_id}_V1_MR', sess, run)
        maps_reader = CiftiReader(maps_file)
        hemi2maps = {
            'lh': maps_reader.get_data(hemi2stru['lh'], True),
            'rh': maps_reader.get_data(hemi2stru['rh'], True)
        }

        for hemi in ['lh', 'rh']:

            maps = hemi2maps[hemi]

            # seed dict
            seed_mask = hemi2seed_mask[hemi]
            for seed_idx, seed in enumerate(seeds):
                lbl = roi2label[seed]
                hemi2seed_dict[hemi]['rfMRI'][subj_idx, seed_idx] =\
                    np.mean(maps[:, seed_mask == lbl], 1)

            # target dict
            trg_mask = hemi2trg_mask[hemi]
            tmp_labels = np.unique(trg_mask)
            tmp_labels = tmp_labels[tmp_labels != 0].astype(int)
            for lbl in tmp_labels:
                trg_idx = trg_labels.index(lbl)
                trg_dict['rfMRI'][subj_idx, trg_idx] =\
                    np.mean(maps[:, trg_mask == lbl], 1)

            # global dict
            global_idx = global_dict['global'].index(hemi)
            global_dict['rfMRI'][subj_idx, global_idx] = np.mean(maps, 1)

        maps = np.c_[hemi2maps['lh'], hemi2maps['rh']]
        global_idx = global_dict['global'].index('lr')
        global_dict['rfMRI'][subj_idx, global_idx] = np.mean(maps, 1)
        del maps

    pkl.dump(hemi2seed_dict['lh'], open(out_seed_lh, 'wb'))
    pkl.dump(hemi2seed_dict['rh'], open(out_seed_rh, 'wb'))
    pkl.dump(trg_dict, open(out_trg, 'wb'))
    pkl.dump(global_dict, open(out_global, 'wb'))