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())
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()
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 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'])
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 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())
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)
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())
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
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)
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'))
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'))
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)
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 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])
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 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))
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)'])
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'))
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)
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'))
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'))
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'))
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)