[Eeglablist] artifact detection in continuous data

Jan R Wessel Jan.Wessel at nf.mpg.de
Fri Jun 10 01:33:47 PDT 2011


Dear James,

i've done something like that a couple of months back, but just in a 
very rudimentary way.
It was quite a pragmatic (in the bad way, i.e. dumb) way of doing 
automated rejection of cont. data, basically just adding evenly spaced 
artificial events, epoching based on them and then running jointprob() 
on those epochs, then removing the new events and retian the boundary 
events when reconcatenating.

Feel free to use any of the code or ideas. I'm really not much of a 
programmer, so you might wanna start from scratch.
There are heaps of ways in which you could improve the basic approach, 
I'm sure.
You could start by replacing the fixed epoch duration that you have to 
give as an argument by trying to evenly divide the epochs, so that you 
don't drop any remainder of data at the end, for instance.

Anyhow, here goes the code.

Cheers,
Jan

% auto clean-up for continuous data
%
% multi-step clean up of data
%   1. split up files in even epochs (non-event locked)
%   2. search for malicious epochs using jointprob
%   3. re-concatenate data, delete temporary events
%   4. set markers for missing data
% Input
%   EEG = standard eeglab EEG structure
%   prob = standard deviation (parameter for j)
%   windowlength = length of epochs (in seconds), the longer, the more 
data you will reject
%   typerej = pop_jointprob parameter, 0 = components, 1 = electrodes
%   rejboundary = if set to 1, all epochs already containing boundary 
events are being rejected. if set to 0, boundary events will be ignored.
%           (useful if running contreject for a second time, e.g. after 
an ICA)
%
% JRW 2010

function OUTEEG = contreject(EEG, prob, windowlength,typerej,rejboundary)
%% preprocess

% get windowlength in samples
window = windowlength * EEG.srate;

% store continuous data in OUTEEG
OUTEEG = EEG;

% insert temporary event markers
epochs = 1:floor(EEG.pnts / window);
markertimes = [1 epochs * window]; % start at second sample, to avoid 
out of boundary error

% insert events
events = length(EEG.event);
tempevents = length(markertimes);
EEG.event(events+1:events+tempevents) = EEG.event(events); % make dummy 
events
     % loop through tempevents
     for i = 1:tempevents
         EEG.event(events+i).latency = markertimes(i);
         EEG.event(events+i).code = num2str(i); % be able to identify
         EEG.event(events+i).type = 'S998';
         EEG.event(events+i).urevent = events+i;
     end
EEG = eeg_checkset(EEG);

% ignore boundaries if wanted
if nargin >4 && rejboundary == 0
     boundaries = strmatch('boundary', { EEG.event.type });
     for ii = 1:numel(boundaries); EEG.event(boundaries(ii)).type = 
'old_boundary'; end;
end

%% extract epochs, reject epochs
% extract
disp('Making temporary sub-epochs');
EEG = pop_epoch( EEG , {'S998'} , [0 windowlength] , 'epochinfo', 
'yes','verbose','off');

% mark epochs for later identification
for i = 1:EEG.trials; EEG.epoch(i).nr = i; end;
allepochs = i;
% reject
disp('Rejecting data and reconcatenate');
[EEG,~,~,rejected] = pop_jointprob(EEG,typerej,1:EEG.nbchan 
,prob,prob,1,1,'verbose','off');
% get retained epochs
for i = 1:EEG.trials; retain(i) = EEG.epoch(i).nr; end
% get deleted epochs
deleted = setxor(1:allepochs,retain);
if length(deleted) ~= rejected
     error('somehting went wrong')
end

%% reject data from OUTEEG
% get datapoints to delete
delbegin = (deleted-1) * window+1;
delend = (deleted-1) * window + window;
deleteranges = [delbegin' delend']; % set up for pop_select function;
OUTEEG = pop_select(OUTEEG,'nopoint',deleteranges);

%% done
disp(['Data cleaned up based on a probability of ' num2str(prob) ', ' 
num2str(rejected) ' boundary events added.']);


-- 
Jan R. Wessel, Ph.D.
Cognitive Neurology
Max Planck Institute for Neurological Research
Gleueler Strasse 50, 50931 Koeln
http://www.nf.mpg.de/cv/jan-wessel.html




More information about the eeglablist mailing list