def prf2visual_angle(prf_mtx, img_size, out_dir, base_name): """Generate retinotopic mapping based on voxels' pRF parameters. `prf_mtx` is a #voxel x pRF-features matrix, pRF features can be 2 columns (row, col) of image or 3 columns which adding a third pRF size parameters. """ feature_size = prf_mtx.shape[1] pos_mtx = prf_mtx[:, :2] # eccentricity ecc = retinotopy.coord2ecc(pos_mtx, img_size, 20) vol = ecc.reshape(18, 64, 64) vutil.save2nifti(vol, os.path.join(out_dir, base_name+'_ecc.nii.gz')) # angle angle = retinotopy.coord2angle(pos_mtx, img_size) vol = angle.reshape(18, 64, 64) vutil.save2nifti(vol, os.path.join(out_dir, base_name+'_angle.nii.gz')) # pRF size if feature_size > 2: size_angle = retinotopy.get_prf_size(prf_mtx, 55, 20) vol = size_angle.reshape(18, 64, 64) vutil.save2nifti(vol, os.path.join(out_dir, base_name+'_size.nii.gz'))
def retinotopic_mapping(prf_dir, roi): """Get eccentricity and angle based on pRF center for each voxel.""" roi_dir = os.path.join(prf_dir, roi) # load selected model index sel_models = np.load(os.path.join(roi_dir, 'reg_sel_model.npy')) # output variables ecc = np.zeros_like(sel_models) angle = np.zeros_like(sel_models) coords = np.zeros((sel_models.shape[0], 2)) for i in range(sel_models.shape[0]): print 'Voxel %s' % (i + 1) model_idx = int(sel_models[i]) xi = (model_idx % 2500) / 50 yi = (model_idx % 2500) % 50 # col x0 = np.arange(5, 500, 10)[xi] # row y0 = np.arange(5, 500, 10)[yi] coords[i] = [y0, x0] # get ecc and angle ecc = retinotopy.coord2ecc(coords, 500, 20) angle = retinotopy.coord2angle(coords, 500) np.save(os.path.join(roi_dir, 'ecc.npy'), ecc) np.save(os.path.join(roi_dir, 'angle.npy'), angle)
def retinotopic_mapping(corr_file, data_dir, vxl_idx=None, figout=False): """Make the retinotopic mapping using activation map from CNN.""" if figout: fig_dir = os.path.join(data_dir, 'fig') check_path(fig_dir) # load the cross-correlation matrix from file corr_mtx = np.load(corr_file, mmap_mode='r') # set voxel index if not isinstance(vxl_idx, np.ndarray): vxl_idx = np.arange(corr_mtx.shape[0]) elif len(vxl_idx) != corr_mtx.shape[0]: print 'mismatch on voxel number!' return else: print 'voxel index loaded.' pos_mtx = np.zeros((73728, 2)) pos_mtx[:] = np.nan for i in range(len(vxl_idx)): print 'Iter %s of %s' % (i + 1, len(vxl_idx)), tmp = corr_mtx[i, :] tmp = np.nan_to_num(np.array(tmp)) # significant threshold for one-tail test tmp[tmp <= 0.019257] = 0 if np.sum(tmp): tmp = tmp.reshape(96, 27, 27) mmtx = np.max(tmp, axis=0) print mmtx.min(), mmtx.max() # get indices of n maximum values max_n = 20 row_idx, col_idx = np.unravel_index( np.argsort(mmtx.ravel())[-1 * max_n:], mmtx.shape) nmtx = np.zeros(mmtx.shape) nmtx[row_idx, col_idx] = mmtx[row_idx, col_idx] if figout: fig_file = os.path.join(fig_dir, 'v' + str(vxl_idx[i]) + '.png') imsave(fig_file, nmtx) # center of mass x, y = ndimage.measurements.center_of_mass(nmtx) pos_mtx[vxl_idx[i], :] = [x, y] else: print ' ' #receptive_field_file = os.path.join(data_dir, 'receptive_field_pos.npy') #np.save(receptive_field_file, pos_mtx) #pos_mtx = np.load(receptive_field_file) # eccentricity dist = retinotopy.coord2ecc(pos_mtx, (27, 27)) # convert distance into degree # 0-4 degree -> d < 5.5 # 4-8 degree -> d < 11 # 8-12 degree -> d < 16.5 # 12-16 degree -> d < 22 # else > 16 degree ecc = np.zeros(dist.shape) for i in range(len(dist)): if np.isnan(dist[i]): ecc[i] = np.nan elif dist[i] < 2.7: ecc[i] = 1 elif dist[i] < 5.4: ecc[i] = 2 elif dist[i] < 8.1: ecc[i] = 3 elif dist[i] < 10.8: ecc[i] = 4 else: ecc[i] = 5 #dist_vec = np.nan_to_num(ecc) #vol = dist_vec.reshape(18, 64, 64) vol = ecc.reshape(18, 64, 64) vutil.save2nifti( vol, os.path.join(data_dir, 'train_max' + str(max_n) + '_ecc.nii.gz')) # angle angle_vec = retinotopy.coord2angle(pos_mtx, (27, 27)) #angle_vec = np.nan_to_num(angle_vec) vol = angle_vec.reshape(18, 64, 64) vutil.save2nifti( vol, os.path.join(data_dir, 'train_max' + str(max_n) + '_angle.nii.gz'))
def ridge_retinotopic_mapping(corr_file, vxl_idx=None, top_n=None): """Make the retinotopic mapping using activation map from CNN.""" data_dir = os.path.dirname(corr_file) # load the cross-correlation matrix from file corr_mtx = np.load(corr_file, mmap_mode='r') # corr_mtx.shape = (3025, vxl_num) if not isinstance(vxl_idx, np.ndarray): vxl_idx = np.arange(corr_mtx.shape[1]) if not top_n: top_n = 20 pos_mtx = np.zeros((73728, 2)) pos_mtx[:] = np.nan for i in range(len(vxl_idx)): print 'Iter %s of %s' % (i, len(vxl_idx)), tmp = corr_mtx[:, i] tmp = np.nan_to_num(np.array(tmp)) # significant threshold # one-tail test #tmp[tmp <= 0.17419] = 0 if np.sum(tmp): tmp = tmp.reshape(55, 55) print tmp.min(), tmp.max() # get indices of n maximum values row, col = np.unravel_index( np.argsort(tmp.ravel())[-1 * top_n:], tmp.shape) mtx = np.zeros(tmp.shape) mtx[row, col] = tmp[row, col] # center of mass x, y = ndimage.measurements.center_of_mass(mtx) pos_mtx[vxl_idx[i], :] = [x, y] else: print ' ' #receptive_field_file = os.path.join(data_dir, 'receptive_field_pos.npy') #np.save(receptive_field_file, pos_mtx) #pos_mtx = np.load(receptive_field_file) # eccentricity dist = retinotopy.coord2ecc(pos_mtx, (55, 55)) # convert distance into degree # 0-4 degree -> d < 5.5 # 4-8 degree -> d < 11 # 8-12 degree -> d < 16.5 # 12-16 degree -> d < 22 # else > 16 degree ecc = np.zeros(dist.shape) for i in range(len(dist)): if np.isnan(dist[i]): ecc[i] = np.nan elif dist[i] < 5.445: ecc[i] = 1 elif dist[i] < 10.91: ecc[i] = 2 elif dist[i] < 16.39: ecc[i] = 3 elif dist[i] < 21.92: ecc[i] = 4 else: ecc[i] = 5 vol = ecc.reshape(18, 64, 64) vutil.save2nifti(vol, os.path.join(data_dir, 'ecc_max%s.nii.gz' % (top_n))) # angle angle_vec = retinotopy.coord2angle(pos_mtx, (55, 55)) vol = angle_vec.reshape(18, 64, 64) vutil.save2nifti(vol, os.path.join(data_dir, 'angle_max%s.nii.gz' % (top_n)))