def fit_voxel(tup): (ii, vx, js) = tup stdat = js['Stimulus'] if pimms.is_list(stdat): stdat = stdat[0] height = stdat['fieldofviewVert'] width = stdat['fieldofviewHorz'] ### STIMULUS # First get a viewing distance and screen size dist = 100 # 100 cm is arbitrary stim_width = 2 * dist * np.tan(np.pi/180 * width/2) stimulus = VisualStimulus(stim, dist, stim_width, 1.0, float(js['TR']), ctypes.c_int16) if fixed_hrf is not False: model = og_nohrf.GaussianModel(stimulus, utils.double_gamma_hrf) model.hrf_delay = fixed_hrf else: model = og.GaussianModel(stimulus, utils.double_gamma_hrf) ### FIT ## define search grids # these define min and max of the edge of the initial brute-force search. x_grid = (-width/2,width/2) y_grid = (-height/2,height/2) s_grid = (1/stimulus.ppd + 0.25, 5.25) h_grid = (-1.0, 1.0) ## define search bounds # these define the boundaries of the final gradient-descent search. x_bound = (-width, width) y_bound = (-height, height) s_bound = (1/stimulus.ppd, 12.0) # smallest sigma is a pixel b_bound = (1e-8,None) u_bound = (None,None) h_bound = (-3.0,3.0) ## package the grids and bounds if fixed_hrf is not False: grids = (x_grid, y_grid, s_grid) bounds = (x_bound, y_bound, s_bound, b_bound, u_bound,) else: grids = (x_grid, y_grid, s_grid, h_grid) bounds = (x_bound, y_bound, s_bound, h_bound, b_bound, u_bound,) ## fit the response # auto_fit = True fits the model on assignment # verbose = 0 is silent # verbose = 1 is a single print # verbose = 2 is very verbose if fixed_hrf is not False: fit = og_nohrf.GaussianFit(model, vx, grids, bounds, Ns=Ns, voxel_index=(ii, 1, 1), auto_fit=True, verbose=2) else: fit = og.GaussianFit(model, vx, grids, bounds, Ns=Ns, voxel_index=(ii, 1, 1), auto_fit=True, verbose=2) return (ii, vx) + tuple(fit.overloaded_estimate) + (fit.prediction,)
def test_og_fit(): # stimulus features viewing_distance = 38 screen_width = 25 thetas = np.arange(0, 360, 90) thetas = np.insert(thetas, 0, -1) thetas = np.append(thetas, -1) num_blank_steps = 30 num_bar_steps = 30 ecc = 12 tr_length = 1.0 frames_per_tr = 1.0 scale_factor = 1.0 pixels_across = 100 pixels_down = 100 dtype = ctypes.c_int16 # create the sweeping bar stimulus in memory bar = simulate_bar_stimulus(pixels_across, pixels_down, viewing_distance, screen_width, thetas, num_bar_steps, num_blank_steps, ecc) # create an instance of the Stimulus class stimulus = VisualStimulus(bar, viewing_distance, screen_width, scale_factor, tr_length, dtype) # initialize the gaussian model model = og.GaussianModel(stimulus, utils.spm_hrf) model.hrf_delay = 0 model.mask_size = 5 # generate a random pRF estimate x = -5.24 y = 2.58 sigma = 1.24 hrf_delay = 0.66 beta = 2.5 baseline = -0.25 # create the "data" data = model.generate_prediction(x, y, sigma, hrf_delay, beta, baseline) # set search grid x_grid = (-10, 10) y_grid = (-10, 10) s_grid = (0.25, 5.25) h_grid = (-1.0, 1.0) # set search bounds x_bound = (-12.0, 12.0) y_bound = (-12.0, 12.0) s_bound = (0.001, 12.0) h_bound = (-1.5, 1.5) b_bound = (1e-8, None) m_bound = (None, None) # loop over each voxel and set up a GaussianFit object grids = ( x_grid, y_grid, s_grid, h_grid, ) bounds = (x_bound, y_bound, s_bound, h_bound, b_bound, m_bound) # fit the response fit = og.GaussianFit(model, data, grids, bounds, Ns=5) # coarse fit npt.assert_almost_equal(fit.x0, -5.0) npt.assert_almost_equal(fit.y0, 5.0) npt.assert_almost_equal(fit.s0, 2.75) npt.assert_almost_equal(fit.hrf0, 0.5) # the baseline/beta should be 0/1 when regressed data vs. estimate (m, b) = np.polyfit(fit.scaled_ballpark_prediction, data, 1) npt.assert_almost_equal(m, 1.0) npt.assert_almost_equal(b, 0.0) # assert equivalence npt.assert_almost_equal(fit.x, x) npt.assert_almost_equal(fit.y, y) npt.assert_almost_equal(fit.hrf_delay, hrf_delay) npt.assert_almost_equal(fit.sigma, sigma) npt.assert_almost_equal(fit.beta, beta) # test receptive field rf = generate_og_receptive_field(x, y, sigma, fit.model.stimulus.deg_x, fit.model.stimulus.deg_y) rf /= (2 * np.pi * sigma**2) * 1 / np.diff(model.stimulus.deg_x[0, 0:2])**2 npt.assert_almost_equal(np.round(rf.sum()), np.round(fit.receptive_field.sum())) # test model == fit RF npt.assert_almost_equal( np.round(fit.model.generate_receptive_field(x, y, sigma).sum()), np.round(fit.receptive_field.sum()))
x_bound, y_bound, s_bound, h_bound, b_bound, u_bound, ) ## fit the response # auto_fit = True fits the model on assignment # verbose = 0 is silent # verbose = 1 is a single print # verbose = 2 is very verbose fit = og.GaussianFit(model, vx, grids, bounds, Ns=Ns, voxel_index=(ii, 1, 1), auto_fit=True, verbose=2) for (k, v) in zip(fields, fit.overloaded_estimate): res[k].append(v) res['pred'].append(fit.prediction) # Update the results to match the x0/y0, sigma style used by prfanalyze rr = {} rr['x0'] = np.cos(res['theta']) * res['rho'] rr['y0'] = np.sin(res['theta']) * res['rho'] rr['sigmamajor'] = res['sigma'] rr['sigmaminor'] = res['sigma'] rr['beta'] = res['beta'] rr['baseline'] = res['baseline'] rr['hrfdelay'] = res['hrfdelay']
# %% markdown # #Fit the Models # ## Gaussian Model # % import popeye.og_hrf as og_hrf import popeye.og as og hrf = popeye.utilities.double_gamma_hrf model = og_hrf.GaussianModel(stimulus, hrf) # model.hrf_delay = -0.25 # RSQarray = [] # for ii in np.array([-0.5,-0.25, 1,0.25, 0.5]): model.hrf_delay = -0.25 fit = og_hrf.GaussianFit(model, input_data, ((-10, 10), (-10, 10), (0.25, 6.25), (-3.0, 3.0)), ((-10, 10), (-10, 10), (0.10, 12.0), (-6.0, 6.0)), auto_fit=True, Ns=5, verbose=1) # RSQarray.append((ii,fit.RSQ)) # % # find and show the parameters (x, y, sigma, n, beta, baseline) sol = fit.overloaded_estimate prediction = fit.prediction for (k,v) in zip(['theta', 'rho', 'sigma', 'hrf_delay', 'beta', 'baseline'], tuple(sol)): print('%-10s'%k,':\t',v) # % t = np.linspace(0, 300, 150) (m,b) = (1,0) (m,b) = sp.stats.linregress(prediction, input_data)[:2]
y_bound, s_bound, h_bound, b_bound, u_bound, ) ## fit the response # auto_fit = True fits the model on assignment # verbose = 0 is silent # verbose = 1 is a single print # verbose = 2 is very verbose fit = og.GaussianFit(model, data, grids, bounds, Ns=3, voxel_index=(1, 2, 3), auto_fit=True, verbose=2) ## plot the results import matplotlib.pyplot as plt plt.plot(fit.prediction, c='r', lw=3, label='model', zorder=1) plt.scatter(range(len(fit.data)), fit.data, s=30, c='k', label='data', zorder=2) plt.xticks(fontsize=16) plt.yticks(fontsize=16)