def make_model(stimulus):

    # these define min and max of the edge of the initial brute-force search.
    x_grid = (-8, 8)
    y_grid = (-8, 8)
    s_grid = (1 / stimulus.ppd + 0.25, 5.25)
    h_grid = (-1.0, 1.0)

    # these define the boundaries of the final gradient-descent search.
    x_bound = (-10.0, 10.0)
    y_bound = (-10.0, 10.0)
    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)

    GRIDS = (x_grid, y_grid, s_grid, h_grid)
    BOUNDS = (
        x_bound,
        y_bound,
        s_bound,
        h_bound,
        b_bound,
        u_bound,
    )
    model = og.GaussianModel(stimulus, utils.double_gamma_hrf)

    return model, GRIDS, BOUNDS
Exemple #2
0
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,)
Exemple #3
0
def solver(params):
    '''
    solver(params) accepts a parameter dictionary params and solves the pRF models implied by them.

    The return value of solver is a dictionary of pRF parameters or statistics; e.g., a dictionary
    might contain keys 'r2', 'sigma', 'x', and 'y'.
    '''
    tr = params['TR_length']
    # go ahead and make the stimulus:
    stimulus_array = params['stimulus']
    stimulus_array = np.round(stimulus_array /
                              np.max(stimulus_array)).astype('short')
    # if the params tell us to invert y, we should do that now:
    if params.get('invert_y', False):
        stimulus_array = np.flip(stimulus_array, axis=0)
    # figure out screen width from assumed distance of 50 and d2p:
    stimpx = np.min(stimulus_array.shape[:2])
    stimdeg = stimpx / params['pixels_per_degree']
    stimcm = 2 * 50 * np.tan(stimdeg / 2 * np.pi / 180)
    stimulus = popeye.visual_stimulus.VisualStimulus(stimulus_array, 50,
                                                     stimcm, 0.5, tr, 'short')
    # A few other optional parameters:
    grid_n = params.get('grid_n', 5)
    minmax_x = params.get('range_x', (-stimdeg, stimdeg))
    minmax_y = params.get('range_y', (-stimdeg, stimdeg))
    minmax_s = params.get('range_sigma', (0.05, stimdeg * 0.75))
    minmax_h = params.get('range_hrf', (-6, 6))
    grids = [minmax_x, minmax_y, minmax_s, minmax_h]
    # Get the data and mask ready...
    data = params['data']
    mask = params.get('mask', None)
    # okay, now go ahead and solve:
    # note that changes/edits to the HRF should go here:
    hrf = popeye.utilities.double_gamma_hrf
    model = og_hrf.GaussianModel(stimulus, hrf)
    model.hrf_delay = -0.25
    args = [(og_hrf.GaussianFit, model, data[i, j, k], grids, grids, (i, j, k),
             grid_n, True, False) for i in np.arange(data.shape[0])
            for j in np.arange(data.shape[1]) for k in np.arange(data.shape[2])
            if (mask is None or mask[i, j, k])]
    # model = og.GaussianModel(stimulus, hrf)
    # model.hrf_delay = -0.25
    # args = [(og.GaussianFit, model, data[i,j,k], grids, grids, (i,j,k), grid_n, True, False)
    #         for i in np.arange(data.shape[0])
    #         for j in np.arange(data.shape[1])
    #         for k in np.arange(data.shape[2])
    #         if (mask is None or mask[i,j,k])]
    pool = mp.Pool()
    fits = pool.map(_dofit, args)
    pool.close()
    pool.join()
    # okay, reconstruct these into results volumes
    # res = {k:np.full(data.shape[:-1], np.nan)
    res = {
        k: np.full(data.shape, np.nan)
        for k in
        ['x', 'y', 'sigma', 'baseline', 'gain', 'hrf_delay', 'modelpred']
    }
    for (arg, fit) in zip(args, fits):
        ijk = arg[5]
        for (k, v) in zip(
            ['x', 'y', 'sigma', 'baseline', 'gain', 'hrf_delay', 'modelpred'],
            [
                fit.x, fit.y, fit.sigma, fit.baseline, fit.beta, fit.hrf_delay,
                fit.prediction
            ]):
            res[k][ijk] = v
    return res
Exemple #4
0
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()))
Exemple #5
0
    )
fields = ('theta', 'rho', 'sigma', 'hrfdelay', 'beta', 'baseline')
res = {k: [] for k in fields}
res['pred'] = []
for (ii, vx, js) in zip(range(len(bold)), bold, stim_json):
    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)
    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)
Exemple #6
0
# Stimulus related (we passed it as a nifti, to avoid sending matlab specific things)
nii2 = ny.load('~/toolboxes/PRFmodel/data/examples/Exp-103_binary-true_size-20x20.nii.gz', to='image')
stim = np.squeeze(nii2.dataobj)
# stim = np.roll(stim, -5, axis=2)
stimulus = popeye.visual_stimulus.VisualStimulus(stim.astype('int16'), 30, 10.57962, 0.5, 2, 'int16')


# %% 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