[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