PSY 696B, Analyzing Neural Time-series...
Transcript of PSY 696B, Analyzing Neural Time-series...
EEG artifacts: their detection, influence, and
removal
Jean-Paul Wiegand
Chapter 8
PSY 696B, Analyzing Neural Time-series Data
Necessary files• LFP2
What is an artifact?“Although EEG is designed to record cerebral activity, it also records electrical activities arising from sites other than the brain. The recorded activity that is not of cerebral origin is termed artifact and can be divided into physiologic and extraphysiologic artifacts. While physiologic artifacts are generated from the patient, they arise from sources other than the brain (ie, body). Extraphysiologic artifacts arise from outside the body (ie, equipment, environment).”
http://emedicine.medscape.com/article/1140247-overview
Artifact examples
• Blinks• Muscle movements• Brief amplifier saturations• Line noise• Cognitive artifacts
What do they look like?
http://eegatlas-online.com/myapplications/images/eeg0028/eeg0028on.png
Artifact InfluenceCan affect:
• Mean• Median• Distribution• Standard deviation• Signal to noise ratio
Adifferent definition?• Anything that obscures your ability to find the
electrophysiological signal that you’re looking for
What do artifacts tell you?• Long blinks – subject
may have been too tired
• Blink timing – may not have seen stimulus
• Saccades – may not have been focusing
• Noisy EMG – might have been restless
How to minimize artifacts• Proper test design• Good instructions• Response EMG or force
grips• Eye tracker• Electrode localization
equipment• Comfortable
environment• Good response device
Independent Components Analysis
• Assigning a set of varying weights to different electrodes
• “The Matlab toolbox eeglab is the toolbox that provides the most active development of independent components analysis”
EEGLAB
EEGLABTools > Run ICA2 default configurations:• Runica• Jader
http://sccn.ucsd.edu/wiki Chapter_09:_Decomposing_Data_Using_ICA
Independent Component Analysis
• Might require knowledge of where one’s signal is originating from
• May also require knowledge of where noise may come from
• May not need to remove trials with blinks
DetectionDepends upon the characteristics of your artifact, as well as your desired signal
• Is it longer or shorter than your signal?• Is it higher or lower in amplitude?• Does it oscillate? Is it faster or slower? • How does it compare to the mean?• Does it occur at particular times?• Is it phase- or time-locked to anything?
Detection: Matlab
• If it’s faster or slower…
• Bandpass filter
Detection: Matlab
• If it’s higher or lower in amplitude…
• Indexing
Detection: Matlab
• If it’s time- or phase-locked…
• Indexing
Detection: Matlab
• If it’s shorter or longer…
• Still indexing…but then it gets complicated…
Removal: Matlab
• Indexing• Enveloping• Squaring• Thresholding
Indexing is our friend
• An easy method to pick out wanted, or unwanted, time stamps and their corresponding data points
• For most artifacts, will likely be sufficient
But let’s say• You’re looking for sleep ripples…
• Ripples are an EEG signature commonly found during sleep and have been implicated in spatial memory recall and consolidation
• They are ~140-220Hz AND between 2.5-8 standard deviations above the mean AND last 50-200ms
So if signal=ripples, noise=?
• Spindles• Theta• Gamma• EMG• EKG• Waking activity
LFP2• Sample trace recorded from the hippocampus in
behaving rat during sleep
• Waking behavior already taken out via find_intervals
Bandpass filter% Filter for sleep ripplesnew_sFreq = 1000;lowlimit_fq = 100;highlimit_fq = 300;F_Ny = new_sFreq/2 %HzN = 4 %order of filterpassband = [lowlimit_fq/F_Ny highlimit_fq/F_Ny];ripple = .5[B,A] = cheby1(N,ripple,passband);LFPrip = filtfilt(B,A,LFP2(:,2));
Help cheby1>> help cheby1cheby1 Chebyshev Type I digital and analog filter design.
[B,A] = cheby1(N,R,Wp) designs an Nth order lowpass digital Chebyshev filter with R decibels of peak-to-peak ripple in the passband. cheby1 returns the filter coefficients in length N+1 vectors B (numerator) and A (denominator). The passband-edge frequency Wp must be 0.0 < Wp < 1.0, with 1.0 corresponding to half the sample rate. Use R=0.5 as a starting point, if you are unsure about choosing R.
Help filtfilt>> help filtfiltfiltfilt Zero-phase forward and reverse digital IIR filtering.
Y = filtfilt(B, A, X) filters the data in vector X with the filterdescribed by vectors A and B to create the filtered data
Y. The filter is described by the difference equation:
a(1)*y(n) = b(1)*x(n) + b(2)*x(n-1) + ... + b(nb+1)*x(n-nb)- a(2)*y(n-1) - ... - a(na+1)*y(n-na)
The length of the input X must be more than three timesthe filter order, defined as max(length(B)-1,length(A)-1).
Sanity check
• plot(LFP2(:,1),LFP2(:,2));• hold on• plot(LFP2(:,1),LFPrip(:,1),’r’);
LFPrip
• Now a sleep trace consisting of just desired frequency ranges
Find_intervals
• Cowen 2006
• Defines periods that fit within certain bounds
• Used to find periods of motionlessness, or “rest”• (Will be) Used to find hippocampal sleep ripples
Function descriptionfunction [above_times, below_times] = find_intervals(TX, thresh, lower_thresh, minimum_duration, minimum_inter_interval_period)% Finds intervals in a record TX (time and data) that are above% or below the specified threshold.%% INPUT: TX nx2 matrix where col1 is time, col 2 is data. OR TX is a vector% This should be a% smoothed energy trace of the data you wish to threshold.% thresh - threshold% low_thresh -% * if a value is specified: move out from the identified start end times until% you fall below the low_thresh. This allows you to set a higher% threshold for event detection, and still retain a good estimate% of the event onset time.% * if a nan, then move out in either direction until the first% derivative changes. Threshold free - which is nice.% * if empty, then don't do anything.% minimum_duration - the minimum duration of an event to be% considered above threshold.% minimum_inter_interval_period = if an interval between two% super-threshold periods is this small, merge them together.%% OUTPUT: start and end times for periods above or below the threshold.%% This is useful for code like theta or spindle detection.% % Cowen 2006
Find_intervals• function [above_times, below_times] = find_intervals(TX,
thresh, lower_thresh, minimum_duration, minimum_inter_interval_period)
• Above_times: start and end timestamps where TX is above thresh
• Below_times: start and end timestamps where TX is below thresh but above lower_thresh
• Minimum_duration: minimum time period of signal• Minimum_inter_interval_period: minimum time between
signals - if two signals are found within this time, then they are merged
Narginif size(TX,2) == 1
TX = [[1:length(TX)]' TX];end
if nargin <3lower_thresh = [];minimum_duration = [];
endif nargin < 4
minimum_duration = [];end if nargin < 5
minimum_inter_interval_period = [];endTX(1,2) = 0; % This allows it to register up times when the record STARTs above thresholdTX(end,2) = 0; % This allows it to register up times when the record ENDs above thresholdcross_points = diff(TX(:,2) > thresh); % Apply the threshold - append 0 to front and endabove_times = [TX(find(cross_points == 1),1) TX(find(cross_points == -1),1)];
Diff?• >> help diffdiff Difference and approximate derivative.
diff(X), for a vector X, is [X(2)-X(1) X(3)-X(2) ... X(n)-X(n-1)].
• TX(:,1) = 1:100;• TX(:,2) = rand(100,1);• cross_points = diff(TX(:,2) > .5);
if isnan(lower_thresh)% Move out or forward until the first derivative changes.new_above_times = above_times;all_start_ix = binsearch_vector(TX(:,1), above_times(:,1));all_end_ix = binsearch_vector(TX(:,1), above_times(:,2));for ii = 1:size(above_times,1)
% move the threshold out to the point where the 1st derivative% changes.ix = all_start_ix(ii);while (ix > 0 & TX(ix,2) < TX(ix+1,2) )
ix = ix - 1;endif ix > 0;
new_above_times(ii,1) = TX(ix,1);end
ix = all_end_ix(ii);while (ix < size(TX,1) & TX(ix,2) < TX(ix-1,2) )
ix = ix + 1;endnew_above_times(ii,2) = TX(ix,1);
end% Get rid of the overlapping intervals.% There is proably a 1 line command for this but I couldn't think of% it.
for ii = 1:(size(new_above_times,1)-1)if new_above_times(ii+1,1) <= new_above_times(ii,2)
new_above_times(ii+1,1) = nan;new_above_times(ii,2) = nan;
endendv = new_above_times(:); % Convert to a vector for easy
nan elimination.v = v(find(~isnan(v)));v = unique(v); % sorts and gets unique vals.new_above_times = [v(1:2:end) v(2:2:end)];above_times = new_above_times;
end
if ~isempty(minimum_inter_interval_period)new_above_times = above_times;d_times = above_times(2:end,1) - above_times(1:end-1,2);idx = find(d_times < minimum_inter_interval_period);new_above_times(idx,2) = nan;new_above_times(idx+1,1) = nan;v = new_above_times(:); % Convert to a vector for easy nan elimination.v = v(find(~isnan(v)));v = unique(v); % sorts and gets unique vals.new_above_times = [v(1:2:end) v(2:2:end)];above_times = new_above_times;
end
if ~isempty(minimum_duration)goodix = find((above_times(:,2) - above_times(:,1)) > minimum_duration);above_times = above_times(goodix,:);
end
if nargout > 1% Times when not above threshold.below_start_times = [TX(1,1); above_times(:,2)];below_end_times = [above_times(:,1); TX(end,1)];below_times = [below_start_times below_end_times];if Rows(below_times) > 1
if below_times(1,1) == below_times(2,1) below_times(1,:)= [];
endif below_times((end-1),2) == below_times(end,2)
below_times(end,:)= [];end
endend
• Index• Aaaand thenn…• v = v(find(~isnan(v))); %???!
• >> v(1:50,1) = nan;• >> v(51:100,1) = 50;• >> v = v(find(~isnan(v)));
Apply functionrip_ENV = LFPrip.^2;rip_ENV = sgolayfilt(rip_ENV,3,51);
rip_thresh = std(rip_ENV)*8;rip_lower_thresh = std(rip_ENV)*2.5;
rip_minimum_duration = 40;rip_minimum_inter_interval_period = 100;
[rip_above_times, rip_below_times] = find_intervals([LFP2(:,1) rip_ENV], rip_thresh, rip_lower_thresh, rip_minimum_duration, rip_minimum_inter_interval_period);
Results
Remaining questions?
THANK YOU!