init_unfold

Subjects are exploring a face stimulus. Using an eyetracker and the EEG-Eye toolbox we add markers of saccade onsets into our EEG-Data. The data were cleaned for eye-movement related artefacts using ICA.

In this tutorial we try to disentangle stimulus related ERPs and microsaccade related ERPs.

Find the data at: https://osf.io/wbz7x/

EEG = pop_loadset('C:\Users\behinger\Downloads\face_saccades_opendata_fig10.set')

EEG = eeg_checkset(EEG);

% A simple threshold function taken from ERPLAB

not_eyechan = cellfun(@(x)~strcmpi(x,'eye'),{EEG.chanlocs.type});

winrej = uf_continuousArtifactDetect(EEG,'amplitudeThreshold',250,'channels',not_eyechan);

% We remove very noisy data segments (>250mV) from the designmatrix

cfgDesign = [];

cfgDesign.eventtypes = {'saccade','stimonset'};

% We use intercept-only formulas because we are only interested in the overlap for now

cfgDesign.formula = {'y ~ 1','y~1'};

EEG = uf_designmat(EEG,cfgDesign);

In order to compensate for the inevitable linear overlap between ERPs, we want to use timeshifting / prepare the designmatrix for the deconvolution step. In this step we generate for each column of the designmatrix timeshifted (by t = 1, t=2, t=3 ...) and append them to the designmatrix.

cfgTimexpand = [];

cfgTimexpand.timelimits = [-.3,0.8];

cfgTimexpand.method = 'stick';

EEG1 = uf_timeexpandDesignmat(EEG,cfgTimexpand);

cfgTimexpand.method = 'fourier';

cfgTimexpand.timeexpandparam = 20; % use frequencies up to (dF = 1/T): 1/(1.1s) *20 ~ 18Hz

% effective parameters are here twice as high because each frequ. is defined by cos+sin

EEG2 = uf_timeexpandDesignmat(EEG,cfgTimexpand);

cfgTimexpand.method = 'splines';

cfgTimexpand.timeexpandparam = 40; % use 40 splines over the 1.1s epoch (equivalent number of effective parameters as fourier)

EEG3 = uf_timeexpandDesignmat(EEG,cfgTimexpand);

uf_plotDesignmat(EEG1,'timeexpand',1)

% % ylim([2232 2234.5])

uf_plotDesignmat(EEG2,'timeexpand',1)

ylim([2232 2234.5])

uf_plotDesignmat(EEG3,'timeexpand',1)

ylim([2232 2234.5])

EEG1 = uf_continuousArtifactExclude(EEG1,struct('winrej',winrej));

EEG2 = uf_continuousArtifactExclude(EEG2,struct('winrej',winrej));

EEG3 = uf_continuousArtifactExclude(EEG3,struct('winrej',winrej));

EEG1= uf_glmfit(EEG1,'channel',[32]);

EEG2= uf_glmfit(EEG2,'channel',[32]);

EEG3= uf_glmfit(EEG3,'channel',[32]);

We choose a single electrode and plot all effects.

ufresult1= uf_condense(EEG1);

ufresult2= uf_condense(EEG2);

ufresult3= uf_condense(EEG3);

% Our plotting function allows for arbitrary additional fields

% as long as they have the same size as unfold.beta

ufresult = ufresult1;

ufresult.fourier = ufresult2.beta;

ufresult.spline= ufresult3.beta;

display(ufresult)

uf_plotParam(ufresult,'channel',32);

The first model has 550 parameter per predictor, the second and third one only 40 per predictor. This can show up in memory performance for large models. But due to the great sparseness of the first model (the stick-functions), it is actually often the fastest one.

figure

plot(ufresult1.times,ufresult1.beta(32,:,2)), hold on

plot(ufresult2.times,ufresult2.beta(32,:,2)), hold on

plot(ufresult3.times,ufresult3.beta(32,:,2))

legend({"stick","fourier","spline"})