def filter_recon(prf_dir, db_dir, subj_id, roi): """Reconstruct filter map of each voxel based on selected model.""" # load fmri response vxl_idx, train_fmri_ts, val_fmri_ts = dataio.load_vim1_fmri(db_dir, subj_id, roi=roi) del train_fmri_ts del val_fmri_ts print 'Voxel number: %s' % (len(vxl_idx)) # output config roi_dir = os.path.join(prf_dir, roi) # pRF estimate sel_models = np.load(os.path.join(roi_dir, 'reg_sel_model.npy')) sel_paras = np.load(os.path.join(roi_dir, 'reg_sel_paras.npy')) sel_model_corr = np.load(os.path.join(roi_dir, 'reg_sel_model_corr.npy')) filters = np.zeros((sel_models.shape[0], 500, 500)) fig_dir = os.path.join(roi_dir, 'filters') check_path(fig_dir) thr = 0.24 # gabor bank generation gwt = bob.ip.gabor.Transform(number_of_scales=9) gwt.generate_wavelets(500, 500) spatial_gabors = np.zeros((72, 500, 500)) for i in range(72): w = bob.ip.gabor.Wavelet(resolution=(500, 500), frequency=gwt.wavelet_frequencies[i]) sw = bob.sp.ifft(w.wavelet.astype(np.complex128)) spatial_gabors[i, ...] = np.roll(np.roll(np.real(sw), 250, 0), 250, 1) for i in range(sel_models.shape[0]): if sel_model_corr[i] < thr: continue print 'Voxel %s, Val Corr %s' % (i, sel_model_corr[i]) model_idx = int(sel_models[i]) # get gaussian pooling field parameters si = model_idx / 2500 xi = (model_idx % 2500) / 50 yi = (model_idx % 2500) % 50 x0 = np.arange(5, 500, 10)[xi] y0 = np.arange(5, 500, 10)[yi] sigma = [1] + [n * 5 for n in range(1, 13)] + [70, 80, 90, 100] s = sigma[si] print 'center: %s, %s, sigma: %s' % (y0, x0, s) kernel = make_2d_gaussian(500, s, center=(x0, y0)) kpos = np.nonzero(kernel > 0.00000001) paras = sel_paras[i] tmp_file = os.path.join(fig_dir, 'tmp_kernel.npy') tmp_filter = np.memmap(tmp_file, dtype='float64', mode='w+', shape=(72, 500, 500)) Parallel(n_jobs=25)(delayed(filter_pro)(tmp_filter, paras, kernel, kpos, spatial_gabors, gwt_idx) for gwt_idx in range(72)) tmp_filter = np.array(tmp_filter) filters[i] = tmp_filter.sum(axis=0) os.system('rm %s' % (tmp_file)) im_file = os.path.join(fig_dir, 'Voxel_%s_%s.png' % (i + 1, vxl_idx[i])) vutil.save_imshow(filters[i], im_file) np.save(os.path.join(roi_dir, 'filters.npy'), filters)
def prf_recon(prf_dir, db_dir, subj_id, roi): """Reconstruct pRF based on selected model.""" # load fmri response vxl_idx, train_fmri_ts, val_fmri_ts = dataio.load_vim1_fmri(db_dir, subj_id, roi=roi) del train_fmri_ts del val_fmri_ts print 'Voxel number: %s' % (len(vxl_idx)) # output directory config roi_dir = os.path.join(prf_dir, roi) # pRF estimate sel_models = np.load(os.path.join(roi_dir, 'reg_sel_model.npy')) sel_paras = np.load(os.path.join(roi_dir, 'reg_sel_paras.npy')) sel_model_corr = np.load(os.path.join(roi_dir, 'reg_sel_model_corr.npy')) prfs = np.zeros((sel_models.shape[0], 500, 500)) fig_dir = os.path.join(roi_dir, 'figs') check_path(fig_dir) for i in range(sel_models.shape[0]): # get pRF print 'Voxel %s, Val Corr %s' % (i, sel_model_corr[i]) model_idx = int(sel_models[i]) # get gaussian pooling field parameters si = model_idx / 2500 xi = (model_idx % 2500) / 50 yi = (model_idx % 2500) % 50 x0 = np.arange(5, 500, 10)[xi] y0 = np.arange(5, 500, 10)[yi] sigma = [1] + [n * 5 for n in range(1, 13)] + [70, 80, 90, 100] s = sigma[si] kernel = make_2d_gaussian(500, s, center=(x0, y0)) kpos = np.nonzero(kernel) paras = sel_paras[i] for f in range(9): fwt = np.sum(paras[(f * 8):(f * 8 + 8)]) fs = np.sqrt(2)**f * 4 for p in range(kpos[0].shape[0]): tmp = make_2d_gaussian(500, fs, center=(kpos[1][p], kpos[0][p])) prfs[i] += fwt * kernel[kpos[0][p], kpos[1][p]] * tmp if sel_model_corr[i] >= 0.24: prf_file = os.path.join(fig_dir, 'Voxel_%s_%s.png' % (i + 1, vxl_idx[i])) vutil.save_imshow(prfs[i], prf_file) np.save(os.path.join(roi_dir, 'prfs.npy'), prfs)
def filter_recon(prf_dir, db_dir, subj_id, roi): """Reconstruct filter map of each voxel based on selected model.""" # load fmri response vxl_idx, train_fmri_ts, val_fmri_ts = dataio.load_vim2_fmri(db_dir, subj_id, roi=roi) del train_fmri_ts del val_fmri_ts print 'Voxel number: %s' % (len(vxl_idx)) # output config roi_dir = os.path.join(prf_dir, roi) # pRF estimate sel_models = np.load(os.path.join(roi_dir, 'reg_sel_model.npy')) sel_paras = np.load(os.path.join(roi_dir, 'reg_sel_paras.npy')) sel_model_corr = np.load(os.path.join(roi_dir, 'reg_sel_model_corr.npy')) filters = np.zeros((sel_models.shape[0], 128, 128)) fig_dir = os.path.join(roi_dir, 'filters') check_path(fig_dir) thr = 0.17 # gabor bank generation gwt = bob.ip.gabor.Transform() gwt.generate_wavelets(128, 128) spatial_gabors = np.zeros((40, 128, 128)) for i in range(40): w = bob.ip.gabor.Wavelet(resolution=(128, 128), frequency=gwt.wavelet_frequencies[i]) sw = bob.sp.ifft(w.wavelet.astype(np.complex128)) spatial_gabors[i, ...] = np.roll(np.roll(np.real(sw), 64, 0), 64, 1) for i in range(sel_models.shape[0]): if sel_model_corr[i] < thr: continue print 'Voxel %s, Val Corr %s' % (i, sel_model_corr[i]) model_idx = int(sel_models[i]) # get gaussian pooling field parameters si = model_idx / 1024 xi = (model_idx % 1024) / 32 yi = (model_idx % 1024) % 32 x0 = np.arange(0, 128, 4)[xi] y0 = np.arange(0, 128, 4)[yi] s = np.linspace(1, 50, 15)[si] kernel = make_2d_gaussian(128, s, center=(x0, y0)) kpos = np.nonzero(kernel) paras = sel_paras[i] for gwt_idx in range(40): wt = paras[gwt_idx] arsw = spatial_gabors[gwt_idx] for p in range(kpos[0].shape[0]): tmp = img_offset(arsw, (kpos[0][p], kpos[1][p])) filters[i] += wt * kernel[kpos[0][p], kpos[1][p]] * tmp if sel_model_corr[i] >= thr: im_file = os.path.join(fig_dir, 'Voxel_%s_%s.png' % (i + 1, vxl_idx[i])) vutil.save_imshow(filters[i], im_file) np.save(os.path.join(roi_dir, 'filters.npy'), filters)
def get_vxl_coding_wts(feat_dir, prf_dir, roi): """Generate voxel-wise encoding model of specific roi.""" roi_dir = os.path.join(prf_dir, roi) # load model parameters sel_models = np.load(os.path.join(roi_dir, 'reg_sel_model.npy')) sel_paras = np.load(os.path.join(roi_dir, 'reg_sel_paras.npy')) sel_model_corr = np.load(os.path.join(roi_dir, 'reg_sel_model_corr.npy')) # load model norm paras norm_paras = np.load(os.path.join(feat_dir, 'model_norm_paras.npz')) # select voxels thr = 0.3 #sel_vxl_idx = np.array([4, 6, 40, 160]) sel_vxl_idx = np.nonzero(sel_model_corr>thr)[0] print 'Selecte %s voxels'%(sel_vxl_idx.shape[0]) parts = np.ceil(sel_vxl_idx.shape[0]*1.0/10) for p in range(int(parts)): if (p+1)*10 > sel_vxl_idx.shape[0]: tmp_idx = sel_vxl_idx[(p*10):] else: tmp_idx = sel_vxl_idx[(p*10):(p*10+10)] wt = np.zeros((500, 500, 72, tmp_idx.shape[0]), dtype=np.float32) bias = np.zeros(tmp_idx.shape[0]) for i in range(tmp_idx.shape[0]): print 'Voxel %s'%(tmp_idx[i]) model_idx = int(sel_models[tmp_idx[i]]) # get gaussian pooling field parameters si = model_idx / 2500 xi = (model_idx % 2500) / 50 yi = (model_idx % 2500) % 50 x0 = np.arange(5, 500, 10)[xi] y0 = np.arange(5, 500, 10)[yi] sigma = [1] + [n*5 for n in range(1, 13)] + [70, 80, 90, 100] s = sigma[si] print 'center: %s, %s, sigma: %s'%(y0, x0, s) kernel = make_2d_gaussian(500, s, center=(x0, y0)) kernel = np.expand_dims(kernel, 0) kernel = np.repeat(kernel, 72, 0) coding_wts = sel_paras[tmp_idx[i]] norm_mean = norm_paras['model_mean'][model_idx] norm_std = norm_paras['model_std'][model_idx] for c in range(72): kernel[c, ...] = kernel[c, ...] * coding_wts[c] / norm_std[c] kernel = np.swapaxes(kernel, 0, 1) kernel = np.swapaxes(kernel, 1, 2) wt[..., i] = kernel bias[i] = np.sum(coding_wts * norm_mean / norm_std) outdir = os.path.join(roi_dir, 'tfrecon') if not os.path.exists(outdir): os.makedirs(outdir, 0755) outfile = os.path.join(outdir, 'vxl_coding_wts_%s.npz'%(p+1)) np.savez(outfile, vxl_idx=tmp_idx, wt=wt, bias=bias)
def make_gaussian_prf(size): """Generate various pRFs based on 2d Gaussian kernel with different parameters. Return a pRF matrixs which shape is (size, size, size*size*fwhm#) """ fwhm_num = 10 fwhms = np.arange(1, fwhm_num+1) prfs = np.zeros((size, size, size*size*fwhm_num)) for k in range(fwhm_num): for i in range(size): for j in range(size): idx = k*size*size + i*size + j prfs[:, :, idx] = make_2d_gaussian(size, fwhm=fwhms[k], center=(j, i)) return prfs
def model_pro(feat, cand_model, xi, yi, si): """Sugar function for generating candidate model.""" mi = si * 50 * 50 + xi * 50 + yi center_x = np.arange(5, 500, 10) center_y = np.arange(5, 500, 10) sigma = [1] + [n * 5 for n in range(1, 13)] + [70, 80, 90, 100] x0 = center_x[xi] y0 = center_y[yi] s = sigma[si] print 'Model %s : center - (%s, %s), sigma %s' % (mi, y0, x0, s) kernel = make_2d_gaussian(500, s, center=(x0, y0)) kernel = kernel.flatten() idx_head = 0 parts = feat.shape[0] / 10 for i in range(parts): tmp = feat[(i * 10):(i * 10 + 10), ...] tmp = tmp.reshape(720, 250000) res = tmp.dot(kernel).astype(np.float16) cand_model[mi, idx_head:(idx_head + 10), ...] = res.reshape(10, 72) idx_head += 10
def model_pro(train_in, val_in, train_out, val_out, kernel, xi, yi, si): """Sugar function for generating candidate model""" mi = si * 32 * 32 + xi * 32 + yi center_x = np.arange(0, 128, 4) center_y = np.arange(0, 128, 4) sigma = np.linspace(1, 50, 15) x0 = center_x[xi] y0 = center_y[yi] s = sigma[si] print 'Model %s : center - (%s, %s), sigma %s' % (mi, x0, y0, s) if kernel == 'gaussian': kernel = make_2d_gaussian(128, s, center=(x0, y0)) else: kernel = 0.01 * make_cycle(128, s, center=(x0, y0)) kernel = kernel.flatten() tmp = np.zeros((331200, ), dtype=np.float16) for i in range(23): m = i * 14400 n = m + 14400 tmp[m:n] = kernel.dot(train_in[:, m:n]).astype(np.float16) train_out[mi] = tmp.reshape(46, 7200) val_out[mi] = kernel.dot(val_in).reshape(46, 540).astype(np.float16)
def get_vxl_coding_wts(feat_dir, prf_dir, rois): """Generate voxel-wise encoding model of specific roi.""" if not isinstance(rois, list): rois = [rois] # select voxels roi_vxl_idx = {} prf_center = np.zeros((500, 500)) for roi in rois: roi_vxl_idx[roi] = [] roi_dir = os.path.join(prf_dir, roi) # load model parameters sel_models = np.load(os.path.join(roi_dir, 'reg_sel_model.npy')) sel_model_corr = np.load( os.path.join(roi_dir, 'reg_sel_model_corr.npy')) # threshold for voxel selection thr = 0.3 rad = 200 for i in range(sel_model_corr.shape[0]): if sel_model_corr[i] > thr: model_idx = int(sel_models[i]) # get gaussian pooling field parameters si = model_idx / 2500 sigma = [1] + [n * 5 for n in range(1, 13)] + [70, 80, 90, 100] s = sigma[si] xi = (model_idx % 2500) / 50 yi = (model_idx % 2500) % 50 x0 = np.arange(5, 500, 10)[xi] y0 = np.arange(5, 500, 10)[yi] center_d = np.sqrt(np.square(x0 - 250) + np.square(y0 - 250)) if (center_d < rad): roi_vxl_idx[roi].append(i) prf_center[y0, x0] = prf_center[y0, x0] + 1 outdir = os.path.join(prf_dir, 'tfrecon', '_'.join(rois + [str(thr), str(rad)])) if not os.path.exists(outdir): os.makedirs(outdir, 0755) np.save(os.path.join(outdir, 'prf_center.npy'), prf_center) ## model test #for roi in rois: # roi_vxl_idx[roi] = roi_vxl_idx[roi][:3] vxl_num = [len(roi_vxl_idx[roi]) for roi in roi_vxl_idx] print 'Selecte %s voxels' % (sum(vxl_num)) # get voxel enoding wts masks = np.zeros((sum(vxl_num), 500, 500), dtype=np.float32) wts = np.zeros((sum(vxl_num), 72), dtype=np.float32) bias = np.zeros(sum(vxl_num)) sel_vxl_idx = np.zeros(sum(vxl_num)) # load model norm paras norm_paras = np.load(os.path.join(feat_dir, 'model_norm_paras.npz')) c = 0 for roi in rois: # load model paras roi_dir = os.path.join(prf_dir, roi) sel_models = np.load(os.path.join(roi_dir, 'reg_sel_model.npy')) sel_paras = np.load(os.path.join(roi_dir, 'reg_sel_paras.npy')) vxl_idx = np.load(os.path.join(roi_dir, 'vxl_idx.npy')) for i in range(len(roi_vxl_idx[roi])): print 'ROI %s, Voxel %s' % (roi, roi_vxl_idx[roi][i]) model_idx = int(sel_models[roi_vxl_idx[roi][i]]) # get gaussian pooling field parameters si = model_idx / 2500 xi = (model_idx % 2500) / 50 yi = (model_idx % 2500) % 50 x0 = np.arange(5, 500, 10)[xi] y0 = np.arange(5, 500, 10)[yi] sigma = [1] + [n * 5 for n in range(1, 13)] + [70, 80, 90, 100] s = sigma[si] print 'center: %s, %s, sigma: %s' % (y0, x0, s) masks[c] = make_2d_gaussian(500, s, center=(x0, y0)) vxl_wts = sel_paras[roi_vxl_idx[roi][i]] norm_mean = norm_paras['model_mean'][model_idx] norm_std = norm_paras['model_std'][model_idx] wts[c] = vxl_wts / norm_std bias[c] = np.sum(vxl_wts * norm_mean / norm_std) sel_vxl_idx[c] = vxl_idx[roi_vxl_idx[roi][i]] c = c + 1 outfile = os.path.join(outdir, 'vxl_coding_wts.npz') np.savez(outfile, vxl_idx=sel_vxl_idx, masks=masks, wts=wts, bias=bias)
def sugar_gaussian_f(size, x0, y0, sigma, offset, beta): """Sugar function for model fitting.""" g = make_2d_gaussian(size, sigma, center=(y0, x0)) g = offset + beta * g return g.ravel()