Пример #1
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())
Пример #2
0
def extract_net_parcel_info():
    """
    把每个网络的编号,名字以及所包含的MMP parcel的编号和名字列出来
    """
    from magicbox.io.io import CiftiReader

    # inputs
    net_file = pjoin(work_dir, 'networks.dlabel.nii')

    # outputs
    out_file = pjoin(work_dir, 'net_parcel_info.txt')

    # prepare
    reader = CiftiReader(net_file)
    net_names = reader.map_names()
    lbl_tables = reader.label_tables()

    # calculate & save
    wf = open(out_file, 'w')
    for net_idx, net_name in enumerate(net_names):
        wf.write(f'>>>{net_idx+1}-{net_name}\n')
        lbl_tab = lbl_tables[net_idx]
        for lbl_k, lbl_v in lbl_tab.items():
            if lbl_k == 0:
                continue
            wf.write(f'{lbl_k}-{lbl_v.label[:-4]}\n')
        wf.write('<<<\n')
    wf.close()
Пример #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'))
Пример #4
0
def make_age_maps(data_file, info_file, out_name):
    """
    对每个顶点,计算跨同一年龄被试的平均和sem,分别保存在
    out_name-mean.dscalar.nii, out_name-sem.dscalar.nii中

    Args:
        data_file (str): end with .dscalar.nii
            shape=(n_subj, LR_count_32k)
        info_file (str): subject info file
        out_name (str): filename to save
    """
    # prepare
    data_maps = nib.load(data_file).get_fdata()
    info_df = pd.read_csv(info_file)
    ages = np.array(info_df['age in years'])
    ages_uniq = np.unique(ages)
    n_age = len(ages_uniq)

    # calculate
    mean_maps = np.ones((n_age, LR_count_32k)) * np.nan
    sem_maps = np.ones((n_age, LR_count_32k)) * np.nan
    for age_idx, age in enumerate(ages_uniq):
        data = data_maps[ages == age]
        mean_maps[age_idx] = np.mean(data, 0)
        sem_maps[age_idx] = sem(data, 0)

    # save
    map_names = [str(i) for i in ages_uniq]
    reader = CiftiReader(mmp_map_file)
    save2cifti(f'{out_name}-mean.dscalar.nii', mean_maps,
               reader.brain_models(), map_names)
    save2cifti(f'{out_name}-sem.dscalar.nii', sem_maps, reader.brain_models(),
               map_names)
def merge_smoothed_data(dataset_name, meas_name, sigma):
    """
    合并我平滑过后的cifti文件

    Args:
        dataset_name (str): HCPD | HCPA
        meas_name (str): thickness | myelin
        sigma (float): the size of the gaussian surface smoothing kernel in mm
    """
    # outputs
    out_file = pjoin(work_dir,
                     f'{dataset_name}_{meas_name}_{sigma}mm.dscalar.nii')

    # prepare
    src_dir = pjoin(work_dir, f'{dataset_name}_{meas_name}_{sigma}mm')
    src_file = pjoin(src_dir, '{sid}.dscalar.nii')
    df = pd.read_csv(dataset_name2info[dataset_name])
    n_subj = df.shape[0]
    data = np.zeros((n_subj, LR_count_32k), np.float64)

    # calculate
    for subj_idx, subj_id in enumerate(df['subID']):
        time1 = time.time()
        meas_file = src_file.format(sid=subj_id)
        data[subj_idx] = nib.load(meas_file).get_fdata()[0]
        print(f'Finished: {subj_idx+1}/{n_subj},'
              f'cost: {time.time() - time1} seconds.')

    # save
    mmp_reader = CiftiReader(mmp_map_file)
    save2cifti(out_file, data, mmp_reader.brain_models(), df['subID'])
Пример #6
0
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)
Пример #7
0
def make_non_outlier_map(fpath,
                         thr,
                         roi_name,
                         out_file_mask=None,
                         out_file_prob=None):
    """
    将同时在thr%以上的被试中被认定为outlier的顶点判定为跨被试的outlier
    If out_file_mask is not None, save mask map. (.dlabel.nii or .npy)
    If out_file_prob is not None, save prob map. (.dscalar.nii)
    """
    # prepare
    data = np.load(fpath)
    n_subj, n_vtx = data.shape

    atlas1 = Atlas('Cole_visual_LR')
    atlas2 = Atlas('Cole_visual_ROI')
    assert atlas1.maps.shape == (1, LR_count_32k)
    assert atlas2.maps.shape == (1, LR_count_32k)
    roi_idx_map = atlas1.maps[0] == atlas1.roi2label[roi_name]

    if roi_name == 'R_cole_visual':
        prefix = 'R_'
    elif roi_name == 'L_cole_visual':
        prefix = 'L_'
    else:
        raise ValueError("error roi_name:", roi_name)
    mmp_reader = CiftiReader(mmp_map_file)
    mmp_lbl_tab = mmp_reader.label_tables()[0]

    # calculate
    if out_file_mask is not None:
        data_tmp = np.sum(data, axis=0)
        outlier_vec = data_tmp > thr / 100 * n_subj
        print(f'#outliers/total: {np.sum(outlier_vec)}/{n_vtx}')
        mask_npy = np.zeros(LR_count_32k, bool)
        mask_npy[roi_idx_map] = ~outlier_vec
        if out_file_mask.endswith('.npy'):
            np.save(out_file_mask, mask_npy)
        elif out_file_mask.endswith('.dlabel.nii'):
            mask_cii = atlas2.maps.copy()
            mask_cii[0, ~mask_npy] = np.nan
            lbl_tab = nib.cifti2.cifti2.Cifti2LabelTable()
            for roi, lbl in atlas2.roi2label.items():
                if roi.startswith(prefix):
                    lbl_tab[lbl] = mmp_lbl_tab[lbl]
            save2cifti(out_file_mask,
                       mask_cii,
                       mmp_reader.brain_models(),
                       label_tables=[lbl_tab])
        else:
            raise ValueError("Not supported file name:", out_file_mask)

    if out_file_prob is not None:
        data_tmp = np.mean(data, axis=0)
        prob_map = np.ones((1, LR_count_32k), dtype=np.float64) * np.nan
        prob_map[0, roi_idx_map] = data_tmp
        assert out_file_prob.endswith('.dscalar.nii')
        save2cifti(out_file_prob, prob_map, mmp_reader.brain_models())
Пример #8
0
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)
Пример #9
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'))
Пример #10
0
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())
Пример #12
0
def check_1096_sid():
    """
    检查HCPY_SubjInfo.csv文件中的1096个被试ID及其顺序和
    S1200 1096 myelin file, S1200 1096 thickness file
    是对的上的
    """
    df = pd.read_csv(dataset_name2info['HCPY'])
    subj_ids = df['subID'].to_list()

    fpaths = (s1200_1096_myelin, s1200_1096_thickness)
    for fpath in fpaths:
        reader = CiftiReader(fpath)
        tmp = [int(i.split('_')[0]) for i in reader.map_names()]
        assert tmp == subj_ids
Пример #13
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)
Пример #14
0
def pca(data_file, atlas_name, roi_name, n_component, axis, out_name):
    """
    对n_subj x n_vtx形状的矩阵进行PCA降维

    Args:
        data_file (str): end with .dscalar.nii
            shape=(n_subj, LR_count_32k)
        atlas_name (str): include ROIs' labels and mask map
        roi_name (str): 决定选用哪个区域内的顶点来参与PCA
        n_component (int): the number of components
        axis (str): vertex | subject
            vertex: 对顶点数量进行降维,得到几个主成分时间序列,
            观察某个主成分在各顶点上的权重,刻画其空间分布。
            subject: 对被试数量进行降维,得到几个主成分map,
            观察某个主成分在各被试上的权重,按年龄排序即可得到时间序列。
        out_name (str): output name
            If axis=vertex, output
            1. n_subj x n_component out_name.csv
            2. n_component x LR_count_32k out_name.dscalar.nii
            3. out_name.pkl with fitted PCA model
    """
    # prepare
    component_names = [f'C{i}' for i in range(1, n_component + 1)]

    meas_maps = nib.load(data_file).get_fdata()
    atlas = Atlas(atlas_name)
    assert atlas.maps.shape == (1, LR_count_32k)
    roi_idx_map = atlas.maps[0] == atlas.roi2label[roi_name]
    meas_maps = meas_maps[:, roi_idx_map]

    bms = CiftiReader(mmp_map_file).brain_models()

    # calculate
    pca = PCA(n_components=n_component)
    data = np.ones((n_component, LR_count_32k), np.float64) * np.nan
    if axis == 'vertex':
        X = meas_maps
        pca.fit(X)
        Y = pca.transform(X)
        df = pd.DataFrame(data=Y, columns=component_names)
        data[:, roi_idx_map] = pca.components_

    elif axis == 'subject':
        X = meas_maps.T
        pca.fit(X)
        Y = pca.transform(X)
        df = pd.DataFrame(data=pca.components_.T, columns=component_names)
        data[:, roi_idx_map] = Y.T

    else:
        raise ValueError('Invalid axis:', axis)

    # save
    df.to_csv(f'{out_name}.csv', index=False)
    save2cifti(f'{out_name}.dscalar.nii', data, bms, component_names)
    pkl.dump(pca, open(f'{out_name}.pkl', 'wb'))
Пример #15
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'))
Пример #16
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)
def merge_data(dataset_name, meas_name):
    """
    把所有被试的数据合并到一个cifti文件里

    Args:
        dataset_name (str): HCPD | HCPA
        meas_name (str): thickness | myelin
    """
    # outputs
    out_file = pjoin(work_dir, f'{dataset_name}_{meas_name}.dscalar.nii')

    # prepare
    dataset_dir = dataset_name2dir[dataset_name]
    meas2file = {
        'myelin':
        pjoin(
            dataset_dir,
            'fmriresults01/{sid}_V1_MR/MNINonLinear/fsaverage_LR32k/'
            '{sid}_V1_MR.MyelinMap_BC_MSMAll.32k_fs_LR.dscalar.nii'),
        'thickness':
        pjoin(
            dataset_dir,
            'fmriresults01/{sid}_V1_MR/MNINonLinear/fsaverage_LR32k/'
            '{sid}_V1_MR.thickness_MSMAll.32k_fs_LR.dscalar.nii')
    }

    df = pd.read_csv(dataset_name2info[dataset_name])
    n_subj = df.shape[0]

    data = np.zeros((n_subj, LR_count_32k), np.float64)

    # calculate
    for subj_idx, subj_id in enumerate(df['subID']):
        time1 = time.time()
        meas_file = meas2file[meas_name].format(sid=subj_id)
        data[subj_idx] = nib.load(meas_file).get_fdata()[0]
        print(f'Finished: {subj_idx+1}/{n_subj},'
              f'cost: {time.time() - time1} seconds.')

    # save
    mmp_reader = CiftiReader(mmp_map_file)
    save2cifti(out_file, data, mmp_reader.brain_models(), df['subID'])
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)
Пример #19
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)
Пример #20
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])
Пример #21
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())
Пример #22
0
def get_valid_id(sess=1, run='AP'):
    import os
    import time
    import pandas as pd
    from magicbox.io.io import CiftiReader

    # inputs
    subj_info_file = pjoin(dev_dir, 'HCPD_SubjInfo.csv')

    # outputs
    log_file = pjoin(work_dir, f'get_valid_id_log_{sess}_{run}')
    out_file = pjoin(work_dir, f'rfMRI_REST{sess}_{run}_id')

    subj_info = pd.read_csv(subj_info_file)
    subj_ids = subj_info['subID'].to_list()
    n_subj = len(subj_ids)
    maps_files = '/nfs/e1/HCPD/fmriresults01/{0}/MNINonLinear/Results/rfMRI_REST{1}_{2}/rfMRI_REST{1}_{2}_Atlas_MSMAll_hp0_clean.dtseries.nii'
    valid_ids = []
    log_writer = open(log_file, 'w')
    for idx, subj_id in enumerate(subj_ids, 1):
        time1 = time.time()
        maps_file = maps_files.format(f'{subj_id}_V1_MR', sess, run)
        if not os.path.exists(maps_file):
            msg = f'{maps_file} is not exist.'
            print(msg)
            log_writer.write(f'{msg}\n')
            continue
        try:
            data = CiftiReader(maps_file).get_data()
        except OSError:
            msg = f'{maps_file} meets OSError.'
            print(msg)
            log_writer.write(f'{msg}\n')
            continue
        if data.shape[0] != 478:
            msg = f'The number of time points in {maps_file} is not 478.'
            print(msg)
            log_writer.write(f'{msg}\n')
            continue
        valid_ids.append(subj_id)
        print(
            f'Finished: {idx}/{n_subj}, cost: {time.time() - time1} seconds.')
    log_writer.close()

    # save out
    with open(out_file, 'w') as wf:
        wf.write('\n'.join(valid_ids))
Пример #23
0
def kendall2cifti(data_file, rois, atlas_name, out_file):
    """
    把指定ROI的Tau值和p值存成cifti格式 方便可视化在大脑上
    """
    # prepare
    df = pd.read_csv(data_file, index_col=0)
    atlas = Atlas(atlas_name)
    assert atlas.maps.shape == (1, LR_count_32k)
    out_data = np.ones((2, LR_count_32k)) * np.nan

    # calculate
    for roi in rois:
        mask = atlas.maps[0] == atlas.roi2label[roi]
        out_data[0, mask] = df.loc['tau', roi]
        out_data[1, mask] = -np.log10(df.loc['p', roi])

    # save
    save2cifti(out_file, out_data,
               CiftiReader(mmp_map_file).brain_models(), ['tau', '-lg(p)'])
Пример #24
0
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'))
Пример #25
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)
Пример #26
0
def test_retest_icc(hemi='lh'):
    import numpy as np
    import pickle as pkl
    import nibabel as nib
    from cxy_hcp_ffa.lib.predefine import roi2label, hemi2stru
    from cxy_hcp_ffa.lib.heritability import icc
    from magicbox.io.io import CiftiReader

    # inputs
    roi_names = ('pFus-face', 'mFus-face')
    test_file = pjoin(proj_dir, 'analysis/s2/activation.dscalar.nii')
    retest_file = pjoin(work_dir, 'activation.dscalar.nii')
    subj_test_file = pjoin(proj_dir, 'analysis/s2/subject_id')
    subj_retest_file = pjoin(work_dir, 'subject_id')
    mpm_file = pjoin(
        proj_dir, 'analysis/s2/1080_fROI/refined_with_Kevin/'
        f'MPM_v3_{hemi}_0.25_FFA.nii.gz')
    individual_file = pjoin(
        proj_dir, 'analysis/s2/1080_fROI/refined_with_Kevin/'
        f'rois_v3_{hemi}.nii.gz')

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

    # prepare
    subj_ids_test = open(subj_test_file).read().splitlines()
    subj_ids_retest = open(subj_retest_file).read().splitlines()
    retest_indices = [subj_ids_test.index(i) for i in subj_ids_retest]
    test_maps = CiftiReader(test_file).get_data(hemi2stru[hemi],
                                                True)[retest_indices]
    retest_maps = CiftiReader(retest_file).get_data(hemi2stru[hemi], True)
    mpm_mask = nib.load(mpm_file).get_fdata().squeeze()
    individual_mask = nib.load(
        individual_file).get_fdata().squeeze().T[retest_indices]

    # calculate
    n_roi = len(roi_names)
    mpm_iccs = np.ones((3, n_roi)) * np.nan
    individual_iccs = np.ones((3, n_roi)) * np.nan
    for i, roi_name in enumerate(roi_names):
        label = roi2label[roi_name]
        mpm_roi_idx_arr = mpm_mask == label
        individual_roi_idx_arr = individual_mask == label
        valid_subj_idx_vec = np.any(individual_roi_idx_arr, 1)
        individual_roi_idx_arr = individual_roi_idx_arr[valid_subj_idx_vec]
        test_maps_tmp = test_maps[valid_subj_idx_vec]
        retest_maps_tmp = retest_maps[valid_subj_idx_vec]
        n_subj_valid = np.sum(valid_subj_idx_vec)
        print(f'{hemi}_{roi_name}: {n_subj_valid} valid subjects')

        # calculate ICC for MPM
        test_series_mpm = np.mean(test_maps_tmp[:, mpm_roi_idx_arr], 1)
        retest_series_mpm = np.mean(retest_maps_tmp[:, mpm_roi_idx_arr], 1)
        mpm_iccs[:, i] = icc(test_series_mpm, retest_series_mpm, 10000, 95)

        # calculate ICC for individual
        test_series_ind = np.zeros((n_subj_valid, ))
        retest_series_ind = np.zeros((n_subj_valid, ))
        for j in range(n_subj_valid):
            individual_roi_idx_vec = individual_roi_idx_arr[j]
            test_series_ind[j] = np.mean(
                test_maps_tmp[j][individual_roi_idx_vec])
            retest_series_ind[j] = np.mean(
                retest_maps_tmp[j][individual_roi_idx_vec])
        individual_iccs[:, i] = icc(test_series_ind, retest_series_ind, 10000,
                                    95)

    # save
    out_data = {
        'roi_name': roi_names,
        'mpm': mpm_iccs,
        'individual': individual_iccs
    }
    pkl.dump(out_data, open(out_file, 'wb'))
Пример #27
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'))
Пример #28
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'))
Пример #29
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)