Example #1
0
def test_noresample_stimulus():
    
    # stimulus features
    viewing_distance = 38
    screen_width = 25
    thetas = np.arange(0,360,90)
    num_blank_steps = 0
    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
    Ns = 3
    voxel_index = (1,2,3)
    auto_fit = True
    verbose = 1
    
    # 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)
    
    # stimulus
    npt.assert_equal(stimulus.stim_arr.shape[0:2],stimulus.stim_arr0.shape[0:2])
    npt.assert_equal(stimulus.deg_x.shape,stimulus.deg_x0.shape)
    npt.assert_equal(stimulus.deg_y.shape,stimulus.deg_y0.shape)
Example #2
0
def generate_stimulus(bars):
    tr_length = 1.0
    scale_factor = 1.0
    dtype = c_int16
    stimulus = VisualStimulus(bars, VIEWING_DISTANCE, SCREEN_WIDTH, scale_factor, tr_length, dtype)

    return stimulus
Example #3
0
    def __init__(self, dm, viewing_distance, screen_width, tr_dm):

        self.stimulus = VisualStimulus(stim_arr=dm,
                                       viewing_distance=viewing_distance,
                                       screen_width=screen_width,
                                       scale_factor=1,
                                       tr_length=tr_dm,
                                       dtype=np.short)

        self.model_func = OGModel.GaussianModel(stimulus=self.stimulus,
                                                hrf_model=utils.spm_hrf)
        self.model_func.hrf_delay = 0
        self.predictions = None
Example #4
0
def test_resurrect_model():
    
    # 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 = 20
    num_bar_steps = 20
    ecc = 10
    tr_length = 1.5
    frames_per_tr = 1.0
    scale_factor = 0.50
    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, clip=0.01)
                                
    # create an instance of the Stimulus class
    stimulus = VisualStimulus(bar, viewing_distance, screen_width, scale_factor, tr_length, dtype)
    
    # set cache grids
    x_grid = utils.grid_slice(-10, 10, 5)
    y_grid = utils.grid_slice(-10, 10, 5)
    s_grid = utils.grid_slice(0.55,5.25, 5)
    grids = (x_grid, y_grid, s_grid,)
    
    # initialize the gaussian model
    model = og.GaussianModel(stimulus, utils.spm_hrf)
    model.hrf_delay = 0
    model.mask_size = 5
    
    # seed rng
    np.random.seed(4932)
    
    # cache the model
    cache = model.cache_model(grids, ncpus=3)
    
    # resurrect cached model
    cached_model_path = '/tmp/og_cached_model.pkl'
    model = og.GaussianModel(stimulus, utils.double_gamma_hrf, cached_model_path=cached_model_path)
    model.hrf_delay = 0
    model.mask_size = 5
    
    # make sure the same
    nt.assert_true(np.sum([c[0] for c in cache] -  model.cached_model_timeseries) == 0)
    nt.assert_true(np.sum([c[1] for c in cache] -  model.cached_model_parameters) == 0)
Example #5
0
def test_cache_model_Ns():

    # 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 = 20
    num_bar_steps = 20
    ecc = 10
    tr_length = 1.5
    frames_per_tr = 1.0
    scale_factor = 0.50
    pixels_across = 100
    pixels_down = 100
    dtype = ctypes.c_int16
    Ns = 5
    
    # 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, clip=0.01)
                                
    # 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
    
    # set cache grids
    x_grid = (-10, 10)
    y_grid = (-10, 10)
    s_grid = (0.55,5.25)
    grids = (x_grid, y_grid, s_grid,)
    
    # seed rng
    np.random.seed(4932)
    
    # cache the pRF model
    cache = model.cache_model(grids, Ns=Ns, ncpus=3)
    
    # save it out
    pickle.dump(cache, open('/tmp/og_cached_model.pkl','wb'))
    
    # make sure its the right size
    cached_model = pickle.load(open('/tmp/og_cached_model.pkl','rb'))
    
    nt.assert_equal(np.sum([c[0] for c in cache]),np.sum([c[0] for c in cached_model]))
Example #6
0
    def __init__(self,
                 data,
                 fit_model,
                 visual_design,
                 screen_distance,
                 screen_width,
                 scale_factor,
                 tr,
                 bound_grids,
                 grid_steps,
                 bound_fits,
                 n_jobs,
                 hrf,
                 sg_filter_window_length=210,
                 sg_filter_polyorder=3,
                 sg_filter_deriv=0,
                 nr_TRs=103):

        # immediately convert nans to nums
        self.data = np.nan_to_num(data)
        self.data_var = self.data.var(axis=-1)

        self.n_units = self.data.shape[0]
        self.n_timepoints = self.data.shape[1]

        self.hrf = hrf
        self.nr_TRs = nr_TRs

        self.stimulus = VisualStimulus(stim_arr=visual_design,
                                       viewing_distance=screen_distance,
                                       screen_width=screen_width,
                                       scale_factor=scale_factor,
                                       tr_length=tr,
                                       dtype=np.short)

        #assert self.n_timepoints == self.stimulus.run_length, \
        #    "Data and design matrix do not have the same nr of timepoints, %i vs %i!"%(self.n_timepoints, self.stimulus.run_length)

        if fit_model == 'gauss':
            self.model_func = GaussianModel(stimulus=self.stimulus,
                                            hrf=self.hrf,
                                            nr_TRs=self.nr_TRs)

        self.model_func.hrf_delay = 0
        self.predictions = None
        self.fit_model = fit_model
        self.bound_grids = bound_grids
        self.grid_steps = grid_steps
        self.bound_fits = bound_fits
        self.n_jobs = n_jobs
Example #7
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,)
Example #8
0
def test_resample_stimulus():
    
    # stimulus features
    viewing_distance = 38
    screen_width = 25
    thetas = np.arange(0,360,90)
    num_blank_steps = 0
    num_bar_steps = 30
    ecc = 12
    tr_length = 1.0
    frames_per_tr = 1.0
    scale_factor = 0.50
    pixels_across = 100
    pixels_down = 100
    dtype = ctypes.c_int16
    Ns = 3
    voxel_index = (1,2,3)
    auto_fit = True
    verbose = 1
    
    # 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)
    
    # grab the stimulus dimensions
    stim_dims = stimulus.stim_arr.shape
    stim_coarse_dims = stimulus.stim_arr0.shape
    
    # assert
    nt.assert_true(stim_coarse_dims[0]/stim_dims[0] == scale_factor)
    nt.assert_true(stim_coarse_dims[1]/stim_dims[1] == scale_factor)
    nt.assert_true(stim_coarse_dims[2] == stim_dims[2])
    
    npt.assert_array_equal(np.unique(stimulus.stim_arr0), [0, 1])
    
    # make sure the duty-cycle doesn't change with resampling
    npt.assert_almost_equal(np.sum(stimulus.stim_arr0==1)/np.sum(stimulus.stim_arr0>-1),np.sum(stimulus.stim_arr==1)/np.sum(stimulus.stim_arr>-1),3)
Example #9
0
def read_prf_stimuli(n_vols=(224, 224)):
    img = loadmat('/Fridge/users/margriet/stimuli/BAIR_pRF/bar_apertures.mat')
    images = img['bar_apertures']

    baseline = int(11.9 / 0.85)

    b_img = zeros((images.shape[0], images.shape[1], baseline))
    c = concatenate((b_img, images, b_img), 2)

    all_img = []
    for n_vol in n_vols:
        all_img.append(c[:, :, :n_vol].copy())

    st = concatenate(all_img, 2)

    st = resize(st, (100, 100), anti_aliasing=True)
    stimulus = VisualStimulus(st,
                              112,
                              32,
                              scale_factor=0.1,
                              tr_length=0.85,
                              dtype=c_short)

    return stimulus
Example #10
0
def setup_data_from_h5(data_file, 
                        n_pix, 
                        extent=[-5,5], 
                        screen_distance=225, 
                        screen_width=69.0, 
                        rsq_threshold=0.5,
                        TR=0.945,
                        cv_fold=1,
                        n_folds=6,
                        use_median=True,
                        mask_name = 'V1'):
        
    hdf5_file = get_figshare_data(data_file)

    ############################################################################################################################################
    #   getting the data
    ############################################################################################################################################

    # timecourses are single-run psc data, either original or leave-one-out. 
    timecourse_data_single_run = roi_data_from_hdf(['*psc'],mask_name, hdf5_file,'psc').astype(np.float64)
    timecourse_data_loo = roi_data_from_hdf(['*loo'],mask_name, hdf5_file,'loo').astype(np.float64)
    timecourse_data_all_psc = roi_data_from_hdf(['*av'],mask_name, hdf5_file,'all_psc').astype(np.float64)
    # prfs are per-run, as fit using the loo data
    all_prf_data = roi_data_from_hdf(['*all'],mask_name, hdf5_file,'all_prf').astype(np.float64)
    prf_data = roi_data_from_hdf(['*all'],mask_name, hdf5_file,'prf').astype(np.float64).reshape((all_prf_data.shape[0], -1, all_prf_data.shape[-1]))

    dm=create_visual_designmatrix_all(n_pixels=n_pix)
    if use_median:
        dm_crossv = dm
    else:
        dm_crossv = np.tile(dm,(1,1,n_folds-1))

    # apply pixel mask to design matrix, as we also do this to the prf profiles.    
    mask = dm.sum(axis = -1, dtype = bool)
    dm = dm[mask,:]
    
    # voxel mask for crossvalidation
    # only count those voxels here that have positive rsq
    rsq_crossv = np.mean(prf_data[:,:,-1], axis=1) * np.sign(np.mean(prf_data[:,:,4], axis=1))
    rsq_mask_crossv = rsq_crossv > rsq_threshold
    
    # determine amount of trs
    nr_TRs = int(timecourse_data_single_run.shape[-1] / n_folds)

    # now, mask the data and select for this fold
    test_data = timecourse_data_single_run[rsq_mask_crossv,nr_TRs*cv_fold:nr_TRs*(cv_fold+1)]
    if use_median:
        train_data = timecourse_data_loo[rsq_mask_crossv,nr_TRs*cv_fold:nr_TRs*(cv_fold+1)]
    else:
        train_data = np.delete(timecourse_data_single_run[rsq_mask_crossv,:], np.s_[nr_TRs*cv_fold:nr_TRs*(cv_fold+1)], axis=1)

    # set up the prf_data variable needed for decoding
    prf_cv_fold_data = prf_data[rsq_mask_crossv,cv_fold]

    # rescale the data
    #sign=np.sign(train_data)
    #train_data -= prf_cv_fold_data[:, 5, np.newaxis]
    #train_data /= prf_cv_fold_data[:, 4, np.newaxis]
    #train_data = sign * np.abs(train_data)**(1.0/prf_cv_fold_data[:, 3, np.newaxis])


    #test_data -= prf_cv_fold_data[:, 5, np.newaxis]
    #test_data /= prf_cv_fold_data[:, 4, np.newaxis]

    ############################################################################################################################################
    #   setting up prf timecourses - NOTE, this is for the 'all' situation, so should be really done on a run-by-run basis using a run's 
    #   loo data and prf parameters. A test set would then be taken from the single_run data as this hasn't been used for that run's fit.
    ############################################################################################################################################

    # set up model with hrf etc.
    def my_spmt(delay, tr):
        return spmt(np.arange(0, 33, tr))

    # we're going to use these popeye convenience functions 
    # because they are fast, and because they were used in the fitting procedure
    stimulus = VisualStimulus(dm_crossv, 
                            screen_distance, 
                            screen_width, 
                            1.0, 
                            TR, 
                            ctypes.c_int16)
    css_model = CompressiveSpatialSummationModelFiltered(stimulus, my_spmt)
    css_model.hrf_delay = 0

    ############################################################################################################################################
    #   setting up prf spatial profiles for subsequent covariances, now some per-run stuff was done
    ############################################################################################################################################
    
    # indices into prf output array:
    #	0:	X
    #	1:	Y
    #	2:	s (size, standard deviation of gauss)
    #	3:	n (nonlinearity power)
    #	4:	a (amplitude)
    #	5:	b (baseline, intercept value)
    #	6:	rsq per-run
    #	7:	rsq across all
    #
    deg_x, deg_y = np.meshgrid(np.linspace(extent[0], extent[1], n_pix, endpoint=True), np.linspace(
        extent[0], extent[1], n_pix, endpoint=True))

    rfs = generate_og_receptive_fields( prf_data[rsq_mask_crossv, cv_fold, 0], 
                                        prf_data[rsq_mask_crossv, cv_fold, 1], 
                                        prf_data[rsq_mask_crossv, cv_fold, 2], 
                                        np.ones((rsq_mask_crossv.sum())), 
                                        deg_x, 
                                        deg_y)
    
    #this step is used in the css model
    rfs_normal = rfs / ((2 * np.pi * prf_data[rsq_mask_crossv, cv_fold, 2]**2) * 1 /np.diff(css_model.stimulus.deg_x[0, 0:2])**2)
    #rfs **= prf_cv_fold_data[:, 3]
    
    #WARNING: CSS-like normalisation does not work well at all. simply divide by the sum for simplicity?
    #for i in range(rfs_normal.shape[2]):
    #    rfs_normal[:,:,i]/=np.sum(rfs_normal[:,:,i])
        
    #pl.imshow(rfs[:,:,3])
    #print(np.sum(rfs_normal[:,:,0]))
    #print(np.sum(rfs_normal[:,:,1]))
    #print(np.sum(rfs_normal[:,:,2]))
    #print(np.sum(rfs_normal[:,:,3]))
    #print(np.sum(rfs_normal[:,:,4]))
    #pl.colorbar()
   
    #(however in very original decoding, masking was done only at the end.i.e. W had all the pixels in the square.)
    #shouldnt have an impact but remember to check if it does. ask tomas.
    # convert to 1D array and mask with circular mask (tested, works)
    rfs_normal = rfs_normal.reshape((np.prod(mask.shape),-1))[mask.ravel(),:]
    rfs = rfs.reshape((np.prod(mask.shape),-1))[mask.ravel(),:]
    #rfs **= prf_cv_fold_data[:, 3, np.newaxis].T
    ############################################################################################################################################
    #   setting up prf spatial profiles for the decoding step, creating linear_predictor_ip
    ############################################################################################################################################

    # and then we try to use this:
    W=rfs_normal.T
    
    #linear_predictor_ip=np.zeros((W.shape[0], W.shape[1]+1))
    #linear_predictor_ip[:,1:]=np.copy(W)
    #do some rescalings. This affects decoding quite a lot!
    #linear_predictor_ip **= np.tile(prf_cv_fold_data[:, 3], (linear_predictor_ip.shape[1],1)).T
    # #at this point (after power raising but before multiplication/subtraction) the css model convolves with hrf.
    #linear_predictor_ip *= np.tile(prf_cv_fold_data[:, 4], (linear_predictor_ip.shape[1],1)).T
    #linear_predictor_ip += np.tile(prf_cv_fold_data[:, 5], (linear_predictor_ip.shape[1],1)).T


    

    ############################################################################################################################################
    #   no convolution simple prediction. use to test difference between CSS model (time dependent)
    #   and respective nonlinear, time-independent model that we use in decoding ("simple prediction")
    ############################################################################################################################################

    simple_prediction= np.dot(rfs_normal.T, dm_crossv.reshape((np.prod(mask.shape),-1))[mask.ravel(),:])
    simple_prediction **= prf_cv_fold_data[:, 3, np.newaxis]
    simple_prediction *= prf_cv_fold_data[:, 4, np.newaxis]
    simple_prediction += prf_cv_fold_data[:, 5, np.newaxis] 
    
    hrf = css_model.hrf_model(css_model.hrf_delay, css_model.stimulus.tr_length)
    
    #for i in range(simple_prediction.shape[0]):
       
        #a=np.max(simple_prediction[i,:])
        
        #simple_prediction[i,:] = fftconvolve(simple_prediction[i,:], hrf)[0:simple_prediction.shape[1]]
        #simple_prediction[i,:] -= savgol_filter(simple_prediction[i,:], window_length=css_model.sg_filter_window_length, polyorder=css_model.sg_filter_order, deriv=0, mode='nearest')
        
    
    
    
    css_prediction=np.zeros((rsq_mask_crossv.sum(),train_data.shape[1]))
    for g, vox_prf_pars in enumerate(prf_cv_fold_data):
        css_prediction[g] = css_model.generate_prediction(
            x=vox_prf_pars[0], y=vox_prf_pars[1], sigma=vox_prf_pars[2], n=vox_prf_pars[3], beta=vox_prf_pars[4], baseline=vox_prf_pars[5])
        #b=np.max(css_prediction[g,:])
        #simple_prediction[:,g] *= b/a
        
    all_residuals_css = train_data - css_prediction
    all_residuals_simple = train_data - simple_prediction
    print("Shapiro-Wilk normality test (if second value is large, residuals are normal):", sp.stats.shapiro(all_residuals_css))
    print("CSS resid: ",np.sum(all_residuals_css))
    print("simple model (no hrf) resid: ",np.sum(all_residuals_simple))

    
    
    #    print(np.max(simple_prediction[i,:])/a)
    
    
    # some quick visualization
    f = pl.figure(figsize=(17,5))
    s = f.add_subplot(211)
    pl.plot(css_prediction[np.argmax(rsq_crossv[rsq_mask_crossv])], label='CSS prediction')
    pl.plot(train_data[np.argmax(rsq_crossv[rsq_mask_crossv])], label='data')
    pl.plot(simple_prediction[np.argmax(rsq_crossv[rsq_mask_crossv])], label='Simple prediction')  
    #pl.plot(all_residuals_css[np.argmax(rsq_crossv[rsq_mask_crossv])], label='resid')   
    pl.legend()
    s.set_title('best voxel')
    
    s = f.add_subplot(212)
    pl.plot(css_prediction[np.argmin(rsq_crossv[rsq_mask_crossv])], label='CSS prediction')
    pl.plot(train_data[np.argmin(rsq_crossv[rsq_mask_crossv])], label='data')
    pl.plot(simple_prediction[np.argmin(rsq_crossv[rsq_mask_crossv])], label='Simple prediction')   
    #pl.plot(all_residuals_css[np.argmin(rsq_crossv[rsq_mask_crossv])], label='resid')
    pl.legend()
    s.set_title('worst voxel given this threshold')
    
    
    
    
    all_residual_covariance_css = np.cov(all_residuals_css) 

    return prf_cv_fold_data, W, all_residuals_css, all_residual_covariance_css, test_data, mask
Example #11
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()))
Example #12
0
    raise ValueError(
        'BOLD Image and Stimulus JSON do not have the same number of data points'
    )
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)
Example #13
0
def test_strf_fit():
    
    viewing_distance = 38
    screen_width = 25
    thetas = np.tile(np.arange(0,360,90),2)
    thetas = np.insert(thetas,0,-1)
    thetas = np.append(thetas,-1)
    num_blank_steps = 20
    num_bar_steps = 20
    ecc = 10
    tr_length = 1.0
    frames_per_tr = 1.0
    scale_factor = 0.50
    pixels_down = 200
    pixels_across = 200
    dtype = ctypes.c_int16
    Ns = 3
    voxel_index = (1,2,3)
    auto_fit = True
    verbose = 1
    projector_hz = 480
    tau = 0.00875
    mask_size = 5
    hrf = 0.25
    
    # create the sweeping bar stimulus in memory
    stim = 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(stim, viewing_distance, screen_width, scale_factor, tr_length, dtype)
    stimulus.fps = projector_hz
    flicker_vec = np.zeros_like(stim[0,0,:]).astype('uint8')
    flicker_vec[1*20:5*20] = 1
    flicker_vec[5*20:9*20] = 2
    stimulus.flicker_vec = flicker_vec
    stimulus.flicker_hz = [10,20]
    
    # initialize the gaussian model
    model = strf.SpatioTemporalModel(stimulus, utils.spm_hrf)
    model.tau = tau
    model.hrf_delay = hrf
    model.mask_size = mask_size
    
    # generate a random pRF estimate
    x = -2.24
    y = 1.58
    sigma = 1.23
    weight = 0.90
    beta = 1.0
    baseline = -0.25
    
    # create the "data"
    data =  model.generate_prediction(x, y, sigma, weight, beta, baseline)
    
    # set search grid
    x_grid = utils.grid_slice(-8.0,7.0,5)
    y_grid = utils.grid_slice(-8.0,7.0,5)
    s_grid = utils.grid_slice(0.75,3.0,5)
    w_grid = utils.grid_slice(0.05,0.95,5)
    
    # set search bounds
    x_bound = (-10,10)
    y_bound =  (-10,10)
    s_bound = (1/stimulus.ppd,10)
    w_bound = (1e-8,1.0)
    b_bound = (1e-8,1e5)
    u_bound = (None, None)
    
    # loop over each voxel and set up a GaussianFit object
    grids = (x_grid, y_grid, s_grid, w_grid,)
    bounds = (x_bound, y_bound, s_bound, w_bound, b_bound, u_bound)
    
    # fit the response
    fit = strf.SpatioTemporalFit(model, data, grids, bounds)
    
    # coarse fit
    ballpark = [-0.5,
                 3.25,
                 2.4375,
                 0.94999999999999996,
                 1.0292,
                 -0.24999999999999992]
                 
    npt.assert_almost_equal((fit.x0,fit.y0,fit.sigma0,fit.weight0,fit.beta0,fit.baseline0),ballpark,4)
    
    # fine fit
    npt.assert_almost_equal(fit.x, x, 2)
    npt.assert_almost_equal(fit.y, y, 2)
    npt.assert_almost_equal(fit.sigma, sigma, 2)
    npt.assert_almost_equal(fit.weight, weight, 2)
    npt.assert_almost_equal(fit.beta, beta, 2)
    npt.assert_almost_equal(fit.baseline, baseline, 2)
    
    # overloaded
    npt.assert_almost_equal(fit.overloaded_estimate, [ 2.5272803,  2.7411676,  1.23     ,  0.9      ,  1.       , -0.25     ], 2)
    
    m_rf = fit.model.m_rf(fit.model.tau)
    p_rf = fit.model.p_rf(fit.model.tau)
    npt.assert_almost_equal(simps(np.abs(m_rf)),simps(p_rf),2)
    
    # responses
    m_resp = fit.model.generate_m_resp(fit.model.tau)
    p_resp = fit.model.generate_p_resp(fit.model.tau)
    npt.assert_(np.max(m_resp,0)[0]<np.max(m_resp,0)[1])
    npt.assert_(np.max(p_resp,0)[0]>np.max(p_resp,0)[1])
    
    # amps
    npt.assert_(fit.model.m_amp[0]<fit.model.m_amp[1])
    npt.assert_(fit.model.p_amp[0]>fit.model.p_amp[1])
    
    # 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()))
Example #14
0
dms = []

for ix, row in df.iterrows():
    dm = create_visual_designmatrix_all(
        bar_width=0.125,
        iti_duration=0,
        thetas=[row.direction],
        n_pixels=n_pixels,
        nr_timepoints=row.bar_pass_duration
    )  # Note that we make a design matrix at level of seconds

    dms.append(dm)

dm = np.concatenate(dms, -1)

stimulus = VisualStimulus(dm, distance_screen, size_cm, 0.50, 1.0,
                          ctypes.c_int16)

hrf = utils.spm_hrf(0, 1.)
bold_dm = fftconvolve(stimulus.stim_arr, hrf[np.newaxis, np.newaxis, :],
                      'full')

bold_dm = np.moveaxis(bold_dm, -1, 0)[:total_duration]
bold_dm = resample(bold_dm, int(total_duration / TR), axis=0)

np.savetxt('/data/odc/derivatives/prf/dm.txt', dm.reshape(-1, n_pixels**2))
np.savetxt('/data/odc/derivatives/prf/bold_dm.txt',
           bold_dm.reshape(-1, n_pixels**2))

np.save('/data/odc/derivatives/prf/dm.npy', dm)
Example #15
0
# remove fixation point
dm[49, 88, :] = 0
dm[49, 89, :] = 0
dm[50, 88, :] = 0
dm[50, 89, :] = 0

#revert y axis
dm = dm[::-1, :, :]  # this is how popeye wants y dim (0 point is top of dm)

########################################################################################
# setup popeye filtered css model
########################################################################################

stimulus = VisualStimulus(stim_arr=dm,
                          viewing_distance=225,
                          screen_width=69.84,
                          scale_factor=1,
                          tr_length=TR,
                          dtype=np.short)

model_func = CompressiveSpatialSummationModelFiltered(
    stimulus=stimulus,
    hrf_model=utils.spm_hrf,
    sg_filter_window_length=120,
    sg_filter_order=3,
    tr=TR)

model_func.hrf_delay = hrf_delay

print 'loading data'

# load data
Example #16
0
def test_dog():

    # stimulus features
    viewing_distance = 31
    screen_width = 41
    thetas = np.arange(0, 360, 90)
    # thetas = np.insert(thetas,0,-1)
    # thetas = np.append(thetas,-1)
    num_blank_steps = 0
    num_bar_steps = 30
    ecc = 10
    tr_length = 1.0
    frames_per_tr = 1.0
    scale_factor = 0.50
    pixels_down = 100
    pixels_across = 100
    dtype = ctypes.c_int16
    auto_fit = True
    verbose = 0

    # 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 = dog.DifferenceOfGaussiansModel(stimulus, utils.spm_hrf)
    model.hrf_delay = 0
    model.mask_size = 20

    # set the pRF params
    x = 2.2
    y = 2.5
    sigma = 0.90
    sigma_ratio = 1.5
    volume_ratio = 0.5
    beta = 0.25
    baseline = -0.10

    # create "data"
    data = model.generate_prediction(x, y, sigma, sigma_ratio, volume_ratio,
                                     beta, baseline)

    # set up the grids
    x_grid = utils.grid_slice(-5, 5, 4)
    y_grid = utils.grid_slice(-5, 5, 4)
    s_grid = utils.grid_slice(1 / stimulus.ppd0 * 1.10, 3.5, 4)
    sr_grid = utils.grid_slice(1.0, 2.0, 4)
    vr_grid = utils.grid_slice(0.10, 0.90, 4)
    grids = (
        x_grid,
        y_grid,
        s_grid,
        sr_grid,
        vr_grid,
    )

    # set up the bounds
    x_bound = (-ecc, ecc)
    y_bound = (-ecc, ecc)
    s_bound = (1 / stimulus.ppd, 5)
    sr_bound = (1.0, None)
    vr_bound = (1e-8, 1.0)
    bounds = (
        x_bound,
        y_bound,
        s_bound,
        sr_bound,
        vr_bound,
    )

    # fit it
    fit = dog.DifferenceOfGaussiansFit(model, data, grids, bounds)

    # coarse fit
    ballpark = [
        1.666666666666667, 1.666666666666667, 2.8243187483428391,
        1.9999999999999998, 0.10000000000000001
    ]

    npt.assert_almost_equal((fit.x0, fit.y0, fit.s0, fit.sr0, fit.vr0),
                            ballpark)
    # 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)

    # fine fit
    npt.assert_almost_equal(fit.x, x, 2)
    npt.assert_almost_equal(fit.y, y, 2)
    npt.assert_almost_equal(fit.sigma, sigma, 2)
    npt.assert_almost_equal(fit.sigma_ratio, sigma_ratio, 1)
    npt.assert_almost_equal(fit.volume_ratio, volume_ratio, 1)

    # test the RF
    rf = fit.model.receptive_field(*fit.estimate[0:-2])
    est = fit.estimate[0:-2].copy()
    rf_new = fit.model.receptive_field(*est)
    value_1 = np.sqrt(simps(simps(rf)))
    value_2 = np.sqrt(simps(simps(rf_new)))
    nt.assert_almost_equal(value_1, value_2)

    # polar coordinates
    npt.assert_almost_equal(
        [fit.theta, fit.rho],
        [np.arctan2(y, x), np.sqrt(x**2 + y**2)], 4)
Example #17
0
def test_strf_css_fit():
    
    viewing_distance = 38
    screen_width = 25
    thetas = np.tile(np.arange(0,360,90),2)
    num_blank_steps = 0
    num_bar_steps = 30
    ecc = 10
    tr_length = 1.0
    frames_per_tr = 1.0
    scale_factor = 0.50
    pixels_down = 100
    pixels_across = 100
    dtype = ctypes.c_int16
    Ns = 3
    voxel_index = (1,2,3)
    auto_fit = True
    verbose = 1
    projector_hz = 480
    tau = 0.00875
    mask_size = 5
    hrf = 0.25
    
    # create the sweeping bar stimulus in memory
    stim1 = simulate_bar_stimulus(pixels_across, pixels_down, viewing_distance, 
                                 screen_width, thetas, num_bar_steps, num_blank_steps, ecc, clip=0.33)
                                 
    # create the sweeping bar stimulus in memory
    stim2 = simulate_bar_stimulus(pixels_across, pixels_down, viewing_distance, 
                                  screen_width, thetas, num_bar_steps, num_blank_steps, ecc, clip=0.0001)
                                  
    
    stim = np.concatenate((stim1,stim2),-1)
    
    # create an instance of the Stimulus class
    stimulus = VisualStimulus(stim, viewing_distance, screen_width, scale_factor, tr_length, dtype)
    stimulus.fps = projector_hz
    flicker_vec = np.zeros_like(stim1[0,0,:]).astype('uint8')
    flicker_vec[1*20:5*20] = 1
    flicker_vec[5*20:9*20] = 2
    flicker_vec = np.tile(flicker_vec,2)
    stimulus.flicker_vec = flicker_vec
    stimulus.flicker_hz = [10,20,10,20]
    
    # initialize the gaussian model
    model = strf.SpatioTemporalModel(stimulus, utils.spm_hrf)
    model.tau = tau
    model.hrf_delay = hrf
    model.mask_size = mask_size
    
    # generate a random pRF estimate
    x = -2.24
    y = 1.58
    sigma = 1.23
    n = 0.90
    weight = 0.95
    beta = 0.88
    baseline = -0.25
    
    # create the "data"
    data =  model.generate_prediction(x, y, sigma, n, weight, beta, baseline)
    
    # set search grid
    x_grid = utils.grid_slice(-8.0,7.0,4)
    y_grid = utils.grid_slice(-8.0,7.0,4)
    s_grid = utils.grid_slice(0.75,3.0,4)
    n_grid = utils.grid_slice(0.25,0.95,4)
    w_grid = utils.grid_slice(0.25,0.95,4)
    
    # set search bounds
    x_bound = (-10,10)
    y_bound =  (-10,10)
    s_bound = (1/stimulus.ppd,10)
    n_bound = (1e-8,1.0-1e-8)
    w_bound = (1e-8,1.0-1e-8)
    b_bound = (1e-8,1e5)
    u_bound = (None, None)
    
    # loop over each voxel and set up a GaussianFit object
    grids = (x_grid, y_grid, s_grid, n_grid, w_grid,)
    bounds = (x_bound, y_bound, s_bound, n_bound, w_bound, b_bound, u_bound)
    
    # fit the response
    fit = strf.SpatioTemporalFit(model, data, grids, bounds)
    
    # coarse fit
    ballpark = [-3.0,
                 2.0,
                 1.5,
                 0.95,
                 0.95,
                 0.88574075,
                 -0.25]
     
    npt.assert_almost_equal((fit.x0,fit.y0,fit.sigma0, fit.n0, fit.weight0,fit.beta0,fit.baseline0),ballpark)
    
    # fine fit
    npt.assert_almost_equal(fit.x, x, 2)
    npt.assert_almost_equal(fit.y, y, 2)
    npt.assert_almost_equal(fit.sigma, sigma, 1)
    npt.assert_almost_equal(fit.n, n, 2)
    npt.assert_almost_equal(fit.weight, weight, 2)
    npt.assert_almost_equal(fit.beta, beta, 2)
    npt.assert_almost_equal(fit.baseline, baseline, 2)
    
    # overloaded
    npt.assert_almost_equal(fit.overloaded_estimate,[2.5266437,  2.7390143,  1.3014282,  0.9004958,  0.9499708, 0.8801774], 2)
    
    # rfs
    m_rf = fit.model.m_rf(fit.model.tau)
    p_rf = fit.model.p_rf(fit.model.tau)
    npt.assert_almost_equal(simps(np.abs(m_rf)),simps(p_rf),5)
    
    # responses
    m_resp = fit.model.generate_m_resp(fit.model.tau)
    p_resp = fit.model.generate_p_resp(fit.model.tau)
    npt.assert_(np.max(m_resp,0)[0]<np.max(m_resp,0)[1])
    npt.assert_(np.max(p_resp,0)[0]>np.max(p_resp,0)[1])

    # amps
    npt.assert_(fit.model.m_amp[0]<fit.model.m_amp[1])
    npt.assert_(fit.model.p_amp[0]>fit.model.p_amp[1])
    
    # receptive field
    npt.assert_almost_equal(4.0, fit.receptive_field.sum())
Example #18
0
def test_css_fit():

    viewing_distance = 38
    screen_width = 25
    thetas = np.arange(0, 360, 90)
    num_blank_steps = 0
    num_bar_steps = 30
    ecc = 10
    tr_length = 1.0
    frames_per_tr = 1.0
    scale_factor = 0.50
    pixels_down = 50
    pixels_across = 50
    dtype = ctypes.c_int16
    Ns = 3
    voxel_index = (1, 2, 3)
    auto_fit = True
    verbose = 1

    # 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 = css.CompressiveSpatialSummationModel(stimulus, utils.spm_hrf)
    model.hrf_delay = 0.2

    # generate a random pRF estimate
    x = -2.24
    y = 1.58
    sigma = 1.23
    n = 0.90
    beta = 1.0
    baseline = -0.25

    # create the "data"
    data = model.generate_prediction(x, y, sigma, n, beta, baseline)

    # set search grid
    x_grid = (-3, 2)
    y_grid = (-3, 2)
    s_grid = (1 / stimulus.ppd, 2.75)
    n_grid = (0.1, 0.90)

    # set search bounds
    x_bound = (-10, 10)
    y_bound = (-10, 10)
    s_bound = (1 / stimulus.ppd, 10)
    n_bound = (1e-8, 1.0)
    b_bound = (1e-8, 1e5)
    h_bound = (-3.0, 3.0)

    # loop over each voxel and set up a GaussianFit object
    grids = (
        x_grid,
        y_grid,
        s_grid,
        n_grid,
    )
    bounds = (
        x_bound,
        y_bound,
        s_bound,
        n_bound,
        b_bound,
    )

    # fit the response
    fit = css.CompressiveSpatialSummationFit(model, data, grids, bounds, Ns=Ns)

    # coarse fit
    observed = [fit.x0, fit.y0, fit.s0, fit.n0, fit.beta0, fit.baseline0]
    expected = [-3., 2., 0.72833938, 0.5, 0.9358213, -0.24999999999999997]
    npt.assert_almost_equal(observed, expected)

    # fine fit
    npt.assert_almost_equal(fit.x, x)
    npt.assert_almost_equal(fit.y, y)
    npt.assert_almost_equal(fit.sigma, sigma)
    npt.assert_almost_equal(fit.n, n)
    npt.assert_almost_equal(fit.beta, beta)
    npt.assert_almost_equal(fit.beta, beta)

    # overloaded
    npt.assert_almost_equal(fit.overloaded_estimate, [
        2.5272803327893043, 2.7411676344215277, 1.2965338406691291,
        0.90000000000036384, 0.99999999999999067, -0.25000000000200889
    ])
Example #19
0
def test_bounded_amplitude_failure():

    # 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.double_gamma_hrf,
                             utils.percent_change)
    model.hrf_delay = 0
    model.mask_size = 6

    # generate a random pRF estimate
    x = -5.24
    y = 2.58
    sigma = 1.24
    beta = -0.25
    baseline = 0.25

    # create the "data"
    data = model.generate_prediction(x, y, sigma, beta, baseline)

    # set search grid
    x_grid = utils.grid_slice(-10, 10, 5)
    y_grid = utils.grid_slice(-10, 10, 5)
    s_grid = utils.grid_slice(0.25, 5.25, 5)

    # set search bounds
    x_bound = (-12.0, 12.0)
    y_bound = (-12.0, 12.0)
    s_bound = (0.001, 12.0)
    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,
    )
    bounds = (x_bound, y_bound, s_bound, b_bound, m_bound)

    # fit the response
    fit = og.GaussianFit(model, data, grids, bounds)

    nt.assert_true(fit.model.bounded_amplitude)
    nt.assert_true(fit.slope > 0)
    nt.assert_true(fit.beta0 > 0)
    nt.assert_true(fit.beta > 0)
    nt.assert_true(fit.beta != beta)
Example #20
0
def test_recast_estimation_results():

    # stimulus features
    viewing_distance = 38
    screen_width = 25
    thetas = np.arange(0, 360, 45)
    num_blank_steps = 0
    num_bar_steps = 30
    ecc = 10
    tr_length = 1.0
    frames_per_tr = 1.0
    scale_factor = 0.10
    pixels_down = 100
    pixels_across = 100
    dtype = ctypes.c_int16
    voxel_index = (1, 2, 3)
    auto_fit = True
    verbose = 1

    # 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

    # generate a random pRF estimate
    x = -5.24
    y = 2.58
    sigma = 1.24
    beta = 2.5
    baseline = -0.25

    # create the "data"
    data = model.generate_prediction(x, y, sigma, beta, baseline)

    # set search grid
    x_grid = utils.grid_slice(-5, 4, 5)
    y_grid = utils.grid_slice(-5, 7, 5)
    s_grid = utils.grid_slice(1 / stimulus.ppd, 5.25, 5)
    b_grid = utils.grid_slice(0.1, 4.0, 5)

    # set search bounds
    x_bound = (-12.0, 12.0)
    y_bound = (-12.0, 12.0)
    s_bound = (1 / stimulus.ppd, 12.0)
    b_bound = (1e-8, 1e2)
    m_bound = (None, None)

    # loop over each voxel and set up a GaussianFit object
    grids = (
        x_grid,
        y_grid,
        s_grid,
    )
    bounds = (x_bound, y_bound, s_bound, b_bound, m_bound)

    # create 3 voxels of data
    all_data = np.array([data, data, data])
    indices = [(0, 0, 0), (0, 0, 1), (0, 0, 2)]

    # bundle the voxels
    bundle = utils.multiprocess_bundle(og.GaussianFit, model, all_data, grids,
                                       bounds, indices)

    # run analysis
    with sharedmem.Pool(np=3) as pool:
        output = pool.map(utils.parallel_fit, bundle)

    # create grid parent
    arr = np.zeros((1, 1, 3))
    grid_parent = nibabel.Nifti1Image(arr, np.eye(4, 4))

    # recast the estimation results
    nif = utils.recast_estimation_results(output, grid_parent)
    dat = nif.get_data()

    # assert equivalence
    npt.assert_almost_equal(np.mean(dat[..., 0]), x)
    npt.assert_almost_equal(np.mean(dat[..., 1]), y)
    npt.assert_almost_equal(np.mean(dat[..., 2]), sigma)
    npt.assert_almost_equal(np.mean(dat[..., 3]), beta)
    npt.assert_almost_equal(np.mean(dat[..., 4]), baseline)

    # recast the estimation results - OVERLOADED
    nif = utils.recast_estimation_results(output, grid_parent, True)
    dat = nif.get_data()

    # assert equivalence
    npt.assert_almost_equal(np.mean(dat[..., 0]), np.arctan2(y, x), 2)
    npt.assert_almost_equal(np.mean(dat[..., 1]), np.sqrt(x**2 + y**2), 2)
    npt.assert_almost_equal(np.mean(dat[..., 2]), sigma)
    npt.assert_almost_equal(np.mean(dat[..., 3]), beta)
    npt.assert_almost_equal(np.mean(dat[..., 4]), baseline)
Example #21
0
rsq_mask_crossv = np.mean(prf_data[:, :, -1], axis=1) > rsq_threshold

############################################################################################################################################
#   setting up prf timecourses - NOTE, this is for the 'all' situation, so should be really done on a run-by-run basis using a run's
#	loo data and prf parameters. A test set would then be taken from the single_run data as this hasn't been used for that run's fit.
############################################################################################################################################


# set up model with hrf etc.
def my_spmt(delay, tr):
    return spmt(np.arange(0, 33, tr))


# we're going to use these popeye convenience functions
# because they are fast, and because they were used in the fitting procedure
stimulus = VisualStimulus(dm_crossv, screen_distance, screen_width, 1.0 / 3.0,
                          TR, ctypes.c_int16)
css_model = CompressiveSpatialSummationModelFiltered(stimulus, my_spmt)
css_model.hrf_delay = 0

############################################################################################################################################
#   setting up prf spatial profiles for subsequent covariances, now some per-run stuff was done
############################################################################################################################################
#use this number to choose which section to use in crossvalidate setup
crossv = 0

deg_x, deg_y = np.meshgrid(
    np.linspace(extent[0], extent[1], n_pix, endpoint=True),
    np.linspace(extent[0], extent[1], n_pix, endpoint=True))

rfs = generate_og_receptive_fields(prf_data[rsq_mask_crossv, crossv, 0],
                                   prf_data[rsq_mask_crossv, crossv, 1],
def test_strf_hrf_fit():

    viewing_distance = 38
    screen_width = 25
    thetas = np.tile(np.arange(0, 360, 90), 2)
    thetas = np.insert(thetas, 0, -1)
    thetas = np.append(thetas, -1)
    num_blank_steps = 20
    num_bar_steps = 20
    ecc = 10
    tr_length = 1.0
    frames_per_tr = 1.0
    scale_factor = 0.50
    pixels_down = 200
    pixels_across = 200
    dtype = ctypes.c_int16
    Ns = 3
    voxel_index = (1, 2, 3)
    auto_fit = True
    verbose = 1
    projector_hz = 480
    tau = 0.00875
    mask_size = 5

    # create the sweeping bar stimulus in memory
    stim = 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(stim, viewing_distance, screen_width,
                              scale_factor, tr_length, dtype)
    stimulus.fps = projector_hz
    flicker_vec = np.zeros_like(stim[0, 0, :]).astype('uint8')
    flicker_vec[1 * 20:5 * 20] = 1
    flicker_vec[5 * 20:9 * 20] = 2
    stimulus.flicker_vec = flicker_vec
    stimulus.flicker_hz = [10, 20]

    # initialize the gaussian model
    model = strf.SpatioTemporalModel(stimulus, utils.double_gamma_hrf)
    model.tau = tau
    model.mask_size = mask_size

    # generate a random pRF estimate
    x = -2.24
    y = 1.58
    sigma = 1.23
    weight = 0.90
    hrf_delay = -0.13
    beta = 1.0
    baseline = -0.25

    # create the "data"
    data = model.generate_prediction(x, y, sigma, weight, hrf_delay, beta,
                                     baseline)

    # set search grid
    x_grid = utils.grid_slice(-8.0, 7.0, 3)
    y_grid = utils.grid_slice(-8.0, 7.0, 3)
    s_grid = utils.grid_slice(0.75, 3.0, 3)
    w_grid = utils.grid_slice(0.05, 0.95, 3)
    h_grid = utils.grid_slice(-0.25, 0.25, 3)

    # set search bounds
    x_bound = (-10, 10)
    y_bound = (-10, 10)
    s_bound = (1 / stimulus.ppd, 10)
    w_bound = (1e-8, 1.0)
    b_bound = (1e-8, 1e5)
    u_bound = (None, None)
    h_bound = (-2.0, 2.0)

    # loop over each voxel and set up a GaussianFit object
    grids = (
        x_grid,
        y_grid,
        s_grid,
        w_grid,
        h_grid,
    )
    bounds = (x_bound, y_bound, s_bound, w_bound, h_bound, b_bound, u_bound)

    # fit the response
    fit = strf.SpatioTemporalFit(model, data, grids, bounds)

    # coarse fit
    npt.assert_almost_equal((fit.x0, fit.y0, fit.sigma0, fit.weight0, fit.hrf0,
                             fit.beta0, fit.baseline0),
                            [-0.5, -0.5, 3., 0.95, -0.25, 1., 0.02], 2)

    # fine fit
    npt.assert_almost_equal(fit.x, x, 2)
    npt.assert_almost_equal(fit.y, y, 2)
    npt.assert_almost_equal(fit.sigma, sigma, 2)
    npt.assert_almost_equal(fit.weight, weight, 2)
    npt.assert_almost_equal(fit.beta, beta, 2)
    npt.assert_almost_equal(fit.baseline, baseline, 2)

    # overloaded
    npt.assert_almost_equal(fit.overloaded_estimate,
                            [2.53, 2.74, 1.23, 0.9, 5.87, 1., -0.25], 2)

    m_rf = fit.model.m_rf(fit.model.tau)
    p_rf = fit.model.p_rf(fit.model.tau)
    npt.assert_almost_equal(simps(np.abs(m_rf)), simps(p_rf), 5)

    # responses
    m_resp = fit.model.generate_m_resp(fit.model.tau)
    p_resp = fit.model.generate_p_resp(fit.model.tau)
    npt.assert_(np.max(m_resp, 0)[0] < np.max(m_resp, 0)[1])
    npt.assert_(np.max(p_resp, 0)[0] > np.max(p_resp, 0)[1])

    # amps
    npt.assert_(fit.model.m_amp[0] < fit.model.m_amp[1])
    npt.assert_(fit.model.p_amp[0] > fit.model.p_amp[1])

    # receptive field
    npt.assert_almost_equal(4.0, fit.receptive_field.sum())
Example #23
0
def test_strf_css_fit():
    
    viewing_distance = 38
    screen_width = 25
    thetas = np.tile(np.arange(0,360,90),2)
    thetas = np.insert(thetas,0,-1)
    thetas = np.append(thetas,-1)
    num_blank_steps = 20
    num_bar_steps = 20
    ecc = 10
    tr_length = 1.0
    frames_per_tr = 1.0
    scale_factor = 0.50
    pixels_down = 100
    pixels_across = 100
    dtype = ctypes.c_int16
    Ns = 3
    voxel_index = (1,2,3)
    auto_fit = True
    verbose = 1
    projector_hz = 480
    tau = 0.00875
    mask_size = 5
    hrf = 0.25
    
    # create the sweeping bar stimulus in memory
    stim1 = simulate_bar_stimulus(pixels_across, pixels_down, viewing_distance, 
                                 screen_width, thetas, num_bar_steps, num_blank_steps, ecc, clip=0.33)
                                 
    # create the sweeping bar stimulus in memory
    stim2 = simulate_bar_stimulus(pixels_across, pixels_down, viewing_distance, 
                                  screen_width, thetas, num_bar_steps, num_blank_steps, ecc, clip=0.0001)
                                  
    
    stim = np.concatenate((stim1,stim2),-1)
    
    # create an instance of the Stimulus class
    stimulus = VisualStimulus(stim, viewing_distance, screen_width, scale_factor, tr_length, dtype)
    stimulus.fps = projector_hz
    flicker_vec = np.zeros_like(stim1[0,0,:]).astype('uint8')
    flicker_vec[1*20:5*20] = 1
    flicker_vec[5*20:9*20] = 2
    flicker_vec = np.tile(flicker_vec,2)
    stimulus.flicker_vec = flicker_vec
    stimulus.flicker_hz = [10,20,10,20]
    
    # initialize the gaussian model
    model = strf.SpatioTemporalModel(stimulus, utils.double_gamma_hrf)
    model.tau = tau
    model.hrf_delay = hrf
    model.mask_size = mask_size
    
    # generate a random pRF estimate
    x = -2.24
    y = 1.58
    sigma = 1.23
    n = 0.90
    weight = 0.95
    beta = 1.0
    baseline = 0
    
    # create the "data"
    data =  model.generate_prediction(x, y, sigma, n, weight, beta, baseline)
    
    # set search grid
    x_grid = utils.grid_slice(-8.0,7.0,3)
    y_grid = utils.grid_slice(-8.0,7.0,3)
    s_grid = utils.grid_slice(0.75,3.0,3)
    n_grid = utils.grid_slice(0.25,0.95,3)
    w_grid = utils.grid_slice(0.25,0.95,3)
    
    # set search bounds
    x_bound = (-10,10)
    y_bound =  (-10,10)
    s_bound = (1/stimulus.ppd,10)
    n_bound = (1e-8,1.0-1e-8)
    w_bound = (1e-8,1.0-1e-8)
    b_bound = (1e-8,1e5)
    u_bound = (None, None)
    
    # loop over each voxel and set up a GaussianFit object
    grids = (x_grid, y_grid, s_grid, n_grid, w_grid,)
    bounds = (x_bound, y_bound, s_bound, n_bound, w_bound, b_bound, u_bound)
    
    # fit the response
    fit = strf.SpatioTemporalFit(model, data, grids, bounds)
    
    # coarse fit
    npt.assert_almost_equal((fit.x0,fit.y0,fit.sigma0, fit.n0, fit.weight0,fit.beta0,fit.baseline0),[-0.5  , -0.5  ,  1.875,  0.95 ,  0.95 ,  1.   ,  0.   ])
    
    # fine fit
    npt.assert_almost_equal(fit.x, x, 1)
    npt.assert_almost_equal(fit.y, y, 1)
    npt.assert_almost_equal(fit.sigma, sigma, 1)
    npt.assert_almost_equal(fit.n, n, 1)
    npt.assert_almost_equal(fit.weight, weight, 1)
    npt.assert_almost_equal(fit.beta, beta, 1)
    npt.assert_almost_equal(fit.baseline, baseline, 1)
    
    # overloaded
    npt.assert_almost_equal(fit.overloaded_estimate, [2.5259863707822303,
                                                      2.7330681871539069,
                                                      1.3062396482386418,
                                                      0.9011492100931614,
                                                      0.94990930073215352,
                                                      1.0005707740082497],4)
                                                     
    # rfs
    m_rf = fit.model.m_rf(fit.model.tau)
    p_rf = fit.model.p_rf(fit.model.tau)
    npt.assert_almost_equal(simps(np.abs(m_rf)),simps(p_rf),5)
    
    # responses
    m_resp = fit.model.generate_m_resp(fit.model.tau)
    p_resp = fit.model.generate_p_resp(fit.model.tau)
    npt.assert_(np.max(m_resp,0)[0]<np.max(m_resp,0)[1])
    npt.assert_(np.max(p_resp,0)[0]>np.max(p_resp,0)[1])

    # amps
    npt.assert_(fit.model.m_amp[0]<fit.model.m_amp[1])
    npt.assert_(fit.model.p_amp[0]>fit.model.p_amp[1])
    
    # receptive field
    npt.assert_almost_equal(4.0, fit.receptive_field.sum())
Example #24
0
def test_resurrect_model():
    
    # 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 = 20
    num_bar_steps = 20
    ecc = 10
    tr_length = 1.5
    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, clip=0.01)
                                
    # create an instance of the Stimulus class
    stimulus = VisualStimulus(bar, viewing_distance, screen_width, scale_factor, tr_length, dtype)
    
    # set cache grids
    x_grid = utils.grid_slice(-10, 10, 5)
    y_grid = utils.grid_slice(-10, 10, 5)
    s_grid = utils.grid_slice(0.55,5.25, 5)
    grids = (x_grid, y_grid, s_grid,)
    
    # set search bounds
    x_bound = (-12.0,12.0)
    y_bound = (-12.0,12.0)
    s_bound = (0.001,12.0)
    b_bound = (1e-8,None)
    m_bound = (None,None)
    bounds = (x_bound, y_bound, s_bound, b_bound, m_bound)
    
    # initialize the gaussian model
    model = og.GaussianModel(stimulus, utils.double_gamma_hrf)
    model.hrf_delay = 0
    model.mask_size = 5
    
    cache = model.cache_model(grids, ncpus=3)
    
    # seed rng
    np.random.seed(4932)
    
    # pluck an estimate and create timeseries
    x, y, sigma = cache[51][1]
    beta = 1.25
    baseline = 0.25
    
    # create "data"
    data = cache[51][0]
    
    # fit it
    fit = og.GaussianFit(model, data, grids, bounds, verbose=0)
    
    # assert
    npt.assert_equal(fit.estimate,fit.ballpark)
    
    # create "data"
    data = model.generate_prediction(x,y,sigma,beta,baseline)
    
    # fit it
    fit = og.GaussianFit(model, data, grids, bounds, verbose=0)
    
    # assert
    npt.assert_almost_equal(np.sum(fit.scaled_ballpark_prediction-fit.data)**2,0)
    
    
    
Example #25
0
def test_bootstrap():

    # stimulus features
    viewing_distance = 38
    screen_width = 25
    thetas = np.array([-1, 0, 90, 180, 270, -1])
    num_blank_steps = 30
    num_bar_steps = 30
    ecc = 10
    tr_length = 1.0
    frames_per_tr = 1.0
    scale_factor = 0.10
    pixels_down = 100
    pixels_across = 100
    dtype = ctypes.c_int16
    voxel_index = (1, 2, 3)
    auto_fit = True
    verbose = 1

    # rng
    np.random.seed(2764932)

    # 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

    # generate a random pRF estimate
    x = -5.24
    y = 2.58
    sigma = 1.24
    beta = 2.5
    baseline = -0.25

    # create the "data"
    data = model.generate_prediction(x, y, sigma, beta, baseline)

    # set search grid
    x_grid = utils.grid_slice(-10, 10, 5)
    y_grid = utils.grid_slice(-10, 10, 5)
    s_grid = utils.grid_slice(0.5, 3.25, 5)

    # set search bounds
    x_bound = (-12.0, 12.0)
    y_bound = (-12.0, 12.0)
    s_bound = (0.001, 12.0)
    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,
    )
    bounds = (x_bound, y_bound, s_bound, b_bound, m_bound)

    # pack multiple "runs"
    data = np.vstack((data, data, data))

    # make it a singular "voxel"
    data = np.reshape(data, (1, data.shape[0], data.shape[1]))

    # set bootstraps and resamples
    bootstraps = 2
    resamples = np.array((2, ))

    # make fodder
    bundle = utils.bootstrap_bundle(bootstraps, resamples, og.GaussianFit,
                                    model, data, grids, bounds,
                                    np.tile((1, 2, 3), (bootstraps, 1)))

    # test
    for b in bundle:
        fit = utils.parallel_bootstrap(b)
        npt.assert_almost_equal(fit.rss, 0)
        npt.assert_equal(fit.n_resamples, resamples[0])
        npt.assert_equal(np.sum(fit.resamples),
                         np.sum(np.arange(resamples[0])))
Example #26
0
def test_dog():

    # stimulus features
    viewing_distance = 38
    screen_width = 25
    thetas = np.arange(0, 360, 90)
    num_blank_steps = 0
    num_bar_steps = 30
    ecc = 10
    tr_length = 1.0
    frames_per_tr = 1.0
    scale_factor = 0.50
    pixels_down = 50
    pixels_across = 50
    dtype = ctypes.c_int16
    voxel_index = (1, 2, 3)
    auto_fit = True
    verbose = 1

    # 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 = dog.DifferenceOfGaussiansModel(stimulus, utils.spm_hrf)
    model.hrf_delay = 0.2

    # set the pRF params
    x = -1.4
    y = 1.5
    sigma = 1.0
    sigma_ratio = 2.0
    volume_ratio = 0.5
    hrf_delay = -0.2

    # create "data"
    data = model.generate_prediction(
        x,
        y,
        sigma,
        sigma_ratio,
        volume_ratio,
    )

    # set up the grids
    x_grid = slice(-10, 10, 3)
    y_grid = slice(-10, 10, 3)
    s_grid = slice(1 / stimulus.ppd, 5, 3)
    sr_grid = slice(1.0, 5.0, 3)
    vr_grid = slice(0.01, 0.99, 3)
    grids = (
        x_grid,
        y_grid,
        s_grid,
        sr_grid,
        vr_grid,
    )

    # set up the bounds
    x_bound = (-ecc, ecc)
    y_bound = (-ecc, ecc)
    s_bound = (1 / stimulus.ppd, 5)
    sr_bound = (1.0, None)
    vr_bound = (1e-8, 1.0)
    bounds = (
        x_bound,
        y_bound,
        s_bound,
        sr_bound,
        vr_bound,
    )

    # fit it
    fit = dog.DifferenceOfGaussiansFit(model, data, grids, bounds, voxel_index)

    # coarse fit
    nt.assert_almost_equal((fit.x0, fit.y0, fit.s0, fit.sr0, fit.vr0),
                           (-1.0, 2.0, 0.72833937882323319, 1.0, 0.01))

    # fine fit
    nt.assert_almost_equal(fit.x, x)
    nt.assert_almost_equal(fit.y, y)
    nt.assert_almost_equal(fit.sigma, sigma)
    nt.assert_almost_equal(fit.sigma_ratio, sigma_ratio)
    nt.assert_almost_equal(fit.volume_ratio, volume_ratio)

    # test the RF
    rf = fit.model.receptive_field(*fit.estimate)
    est = fit.estimate.copy()
    est[2] *= 2
    rf_new = fit.model.receptive_field(*est)
    value_1 = np.sqrt(simps(simps(rf)))
    value_2 = np.sqrt(simps(simps(rf_new)))
    nt.assert_almost_equal(value_2 / value_1, sigma_ratio, 1)

    # polar coordinates
    npt.assert_almost_equal(
        [fit.theta, fit.rho],
        [np.arctan2(y, x), np.sqrt(x**2 + y**2)])
Example #27
0
def test_parallel_fit_manual_grids():

    # stimulus features
    viewing_distance = 38
    screen_width = 25
    thetas = np.arange(0, 360, 45)
    num_blank_steps = 0
    num_bar_steps = 30
    ecc = 10
    tr_length = 1.0
    frames_per_tr = 1.0
    scale_factor = 0.10
    pixels_down = 100
    pixels_across = 100
    dtype = ctypes.c_int16
    voxel_index = (1, 2, 3)
    auto_fit = True
    verbose = 1

    # 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.double_gamma_hrf)
    model.hrf_delay = 0

    # generate a random pRF estimate
    x = -5.24
    y = 2.58
    sigma = 1.24
    beta = 2.5
    baseline = -0.25

    # create the "data"
    data = model.generate_prediction(x, y, sigma, beta, baseline)

    # set search grid
    x_grid = slice(-5, 4, 5)
    y_grid = slice(-5, 7, 5)
    s_grid = slice(1 / stimulus.ppd, 5.25, 5)
    b_grid = slice(0.1, 4.0, 5)

    # set search bounds
    x_bound = (-12.0, 12.0)
    y_bound = (-12.0, 12.0)
    s_bound = (1 / stimulus.ppd, 12.0)
    b_bound = (1e-8, 1e2)
    m_bound = (None, None)

    # loop over each voxel and set up a GaussianFit object
    grids = (
        x_grid,
        y_grid,
        s_grid,
    )
    bounds = (x_bound, y_bound, s_bound, b_bound, m_bound)

    # make 3 voxels
    all_data = np.array([data, data, data])
    num_voxels = data.shape[0]
    indices = [(1, 2, 3)] * 3

    # bundle the voxels
    bundle = utils.multiprocess_bundle(og.GaussianFit, model, all_data, grids,
                                       bounds, indices)

    # run analysis
    with sharedmem.Pool(np=3) as pool:
        output = pool.map(utils.parallel_fit, bundle)

    # assert equivalence
    for fit in output:
        npt.assert_almost_equal(fit.x, x, 2)
        npt.assert_almost_equal(fit.y, y, 2)
        npt.assert_almost_equal(fit.sigma, sigma, 2)
        npt.assert_almost_equal(fit.beta, beta, 2)
        npt.assert_almost_equal(fit.baseline, baseline, 2)
import numpy as np
import sharedmem
import popeye.og_hrf as og
import popeye.utilities as utils
from popeye.visual_stimulus import VisualStimulus, simulate_bar_stimulus

# seed random number generator so we get the same answers ...
np.random.seed(2764932)

### STIMULUS
## create sweeping bar stimulus
sweeps = np.array([-1, 0, 90, 180, 270, -1])  # in degrees, -1 is blank
bar = simulate_bar_stimulus(100, 100, 40, 20, sweeps, 30, 30, 10)

## create an instance of the Stimulus class
stimulus = VisualStimulus(bar, 50, 25, 0.50, 1.0, ctypes.c_int16)

### MODEL
## initialize the gaussian model
model = og.GaussianModel(stimulus, utils.double_gamma_hrf)

## generate a random pRF estimate
x = -5.24
y = 2.58
sigma = 1.24
hrf_delay = -0.25
beta = 0.55
baseline = -0.88

x = 6
y = 6
Example #29
0
def test_strf_2dcos_fit():

    viewing_distance = 38
    screen_width = 25
    thetas = np.tile(np.arange(0, 360, 90), 2)
    thetas = np.insert(thetas, 0, -1)
    thetas = np.append(thetas, -1)
    num_blank_steps = 0
    num_bar_steps = 30
    ecc = 10
    tr_length = 1
    frames_per_tr = 1
    scale_factor = 1.0
    pixels_down = 100
    pixels_across = 100
    dtype = ctypes.c_int16
    Ns = 5
    voxel_index = (1, 2, 3)
    auto_fit = True
    verbose = 1
    projector_hz = 480
    tau = 0.00875
    mask_size = 5
    hrf = 0.25

    # create the sweeping bar stimulus in memory
    stim = 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(stim, viewing_distance, screen_width,
                              scale_factor, tr_length, dtype)
    stimulus.fps = projector_hz
    flicker_vec = np.zeros_like(stim[0, 0, :]).astype('uint8')
    flicker_vec[1 * 20:5 * 20] = 1
    flicker_vec[5 * 20:9 * 20] = 2
    stimulus.flicker_vec = flicker_vec
    stimulus.flicker_hz = [10, 20]

    # initialize the gaussian model
    model = strf.SpatioTemporalModel(stimulus, utils.spm_hrf)
    model.tau = tau
    model.hrf_delay = hrf
    model.mask_size = mask_size
    model.power = 0.7

    # generate a random pRF estimate
    x = -2.24
    y = 1.58
    sigma = 1.23
    weight = 0.90
    beta = 1.0
    baseline = -0.25

    # create the "data"
    data = model.generate_prediction(x, y, sigma, weight, beta, baseline)

    # set search grid
    x_grid = utils.grid_slice(-8.0, 7.0, 5)
    y_grid = utils.grid_slice(-8.0, 7.0, 5)
    s_grid = utils.grid_slice(0.75, 3.0, 5)
    w_grid = utils.grid_slice(0.05, 0.95, 5)

    # set search bounds
    x_bound = (-10, 10)
    y_bound = (-10, 10)
    s_bound = (1 / stimulus.ppd, 10)
    w_bound = (1e-8, 1.0)
    b_bound = (1e-8, 1e5)
    u_bound = (None, None)

    # loop over each voxel and set up a GaussianFit object
    grids = (
        x_grid,
        y_grid,
        s_grid,
        w_grid,
    )
    bounds = (x_bound, y_bound, s_bound, w_bound, b_bound, u_bound)

    # fit the response
    fit = strf.SpatioTemporalFit(model, data, grids, bounds)

    # coarse fit
    ballpark = [
        -0.5, 3.25, 3.0, 0.72499999999999998, 0.858317, -0.25000000000000011
    ]

    npt.assert_almost_equal(
        (fit.x0, fit.y0, fit.sigma0, fit.weight0, fit.beta0, fit.baseline0),
        ballpark)

    # fine fit
    npt.assert_almost_equal(fit.x, x)
    npt.assert_almost_equal(fit.y, y)
    npt.assert_almost_equal(fit.sigma, sigma)
    npt.assert_almost_equal(fit.weight, weight)
    npt.assert_almost_equal(fit.beta, beta)
    npt.assert_almost_equal(fit.baseline, baseline)

    # overloaded
    npt.assert_almost_equal(fit.overloaded_estimate, [
        2.5272803327887128, 2.7411676344185993, 1.2300000000008835,
        0.89999999999333258, 1.0000000000005003, -0.25000000000063088
    ])
    m_rf = fit.model.m_rf(fit.model.tau)
    p_rf = fit.model.p_rf(fit.model.tau)
    npt.assert_almost_equal(simps(np.abs(m_rf)), simps(p_rf), 5)

    # responses
    m_resp = fit.model.generate_m_resp(fit.model.tau)
    p_resp = fit.model.generate_p_resp(fit.model.tau)
    npt.assert_(np.max(m_resp, 0)[0] < np.max(m_resp, 0)[1])
    npt.assert_(np.max(p_resp, 0)[0] > np.max(p_resp, 0)[1])

    # amps
    npt.assert_(fit.model.m_amp[0] < fit.model.m_amp[1])
    npt.assert_(fit.model.p_amp[0] > fit.model.p_amp[1])

    # receptive field
    rf = generate_2dcos_receptive_field(x, y, sigma, fit.model.power,
                                        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()))
Example #30
0
# visual_dm = np.vstack(visual_dm).transpose((1,2,0))

# the code above recreates Kendrick's design matrices, we'll now just load them.
visual_dm = []
# for i in [1,3,5]:
for i in [5]:
    file = tables.open_file(
        os.path.join(base_dir, 'retinotopysmall{i}.mat'.format(i=i)))
    visual_dm.append(file.get_node('/stim')[:])
    file.close()
visual_dm = np.vstack(visual_dm).transpose((1, 2, 0))

stimulus = VisualStimulus(stim_arr=visual_dm,
                          viewing_distance=analysis_info["screen_distance"],
                          screen_width=analysis_info["screen_width"],
                          scale_factor=0.05,
                          tr_length=analysis_info["TR"],
                          dtype=np.short)

############################################################################################################################################
#
#   load cii data, timepoints by grayordinates
#
############################################################################################################################################

# averaged_runs = ['CCW','EXP','RETBAR1']
averaged_runs = ['RETBAR1']
gii_files = [
    glob.glob(
        os.path.join(
            subject_folder,