/trunk/examples/toolboxes/eeglab/functions/sigprocfunc/eegfilt.m
http://brainstream.googlecode.com/ · Objective C · 237 lines · 215 code · 22 blank · 0 comment · 34 complexity · d8b47ed76194b268301db1a4d7a98a6b MD5 · raw file
- % eegfilt() - (high|low|band)-iass filter data using two-way least-squares
- % FIR filtering. Multiple data channels and epochs supported.
- % Requires the MATLAB Signal Processing Toolbox.
- % Usage:
- % >> [smoothdata] = eegfilt(data,srate,locutoff,hicutoff);
- % >> [smoothdata,filtwts] = eegfilt(data,srate,locutoff,hicutoff, ...
- % epochframes,filtorder);
- % Inputs:
- % data = (channels,frames*epochs) data to filter
- % srate = data sampling rate (Hz)
- % locutoff = low-edge frequency in pass band (Hz) {0 -> lowpass}
- % hicutoff = high-edge frequency in pass band (Hz) {0 -> highpass}
- % epochframes = frames per epoch (filter each epoch separately {def/0: data is 1 epoch}
- % filtorder = length of the filter in points {default 3*fix(srate/locutoff)}
- % revfilt = [0|1] reverse filter (i.e. bandpass filter to notch filter). {0}
- %
- % Outputs:
- % smoothdata = smoothed data
- % filtwts = filter coefficients [smoothdata <- filtfilt(filtwts,1,data)]
- %
- % See also: firls(), filtfilt()
- %
- % Author: Scott Makeig, Arnaud Delorme, SCCN/INC/UCSD, La Jolla, 1997
- % Copyright (C) 4-22-97 from bandpass.m Scott Makeig, SCCN/INC/UCSD, scott@sccn.ucsd.edu
- %
- % This program is free software; you can redistribute it and/or modify
- % it under the terms of the GNU General Public License as published by
- % the Free Software Foundation; either version 2 of the License, or
- % (at your option) any later version.
- %
- % This program is distributed in the hope that it will be useful,
- % but WITHOUT ANY WARRANTY; without even the implied warranty of
- % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- % GNU General Public License for more details.
- %
- % You should have received a copy of the GNU General Public License
- % along with this program; if not, write to the Free Software
- % Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- % $Log: eegfilt.m,v $
- % Revision 1.19 2004/11/19 23:28:11 arno
- % same
- %
- % Revision 1.18 2004/11/19 23:27:27 arno
- % better error messsage
- %
- % Revision 1.17 2004/08/31 02:12:56 arno
- % typo
- %
- % Revision 1.16 2004/02/12 23:09:19 scott
- % same
- %
- % Revision 1.15 2004/02/12 23:08:02 scott
- % text output edit
- %
- % Revision 1.14 2004/02/12 22:51:30 scott
- % text output edits
- %
- % Revision 1.13 2003/07/28 17:38:53 arno
- % updating error messages
- %
- % Revision 1.12 2003/07/20 19:17:07 scott
- % added channels-processed info if epochs==1 (continuous data)
- %
- % Revision 1.11 2003/04/11 15:03:46 arno
- % nothing
- %
- % Revision 1.10 2003/03/16 01:00:48 scott
- % header and error msgs -sm
- %
- % Revision 1.9 2003/01/24 03:59:19 scott
- % header edit -sm
- %
- % Revision 1.8 2003/01/24 00:23:33 arno
- % print information about transition bands
- %
- % Revision 1.7 2003/01/23 23:53:25 arno
- % change text
- %
- % Revision 1.6 2003/01/23 23:47:26 arno
- % same
- %
- % Revision 1.5 2003/01/23 23:40:59 arno
- % implementing notch filter
- %
- % Revision 1.4 2002/08/09 14:55:36 arno
- % update transition band
- %
- % Revision 1.3 2002/08/09 02:06:27 arno
- % updating transition
- %
- % Revision 1.2 2002/08/09 02:04:34 arno
- % debugging
- %
- % Revision 1.1 2002/04/05 17:36:45 jorn
- % Initial revision
- %
- % 5-08-97 fixed frequency bound computation -sm
- % 10-22-97 added MINFREQ tests -sm
- % 12-05-00 added error() calls -sm
- % 01-25-02 reformated help & license, added links -ad
- function [smoothdata,filtwts] = eegfilt(data,srate,locutoff,hicutoff,epochframes,filtorder, revfilt)
- if nargin<4
- fprintf('');
- help eegfilt
- return
- end
- if ~exist('firls')
- error('*** eegfilt() requires the signal processing toolbox. ***');
- end
- [chans frames] = size(data);
- if chans > 1 & frames == 1,
- help eegfilt
- error('input data should be a row vector.');
- end
- nyq = srate*0.5; % Nyquist frequency
- %MINFREQ = 0.1/nyq;
- MINFREQ = 0;
- minfac = 3; % this many (lo)cutoff-freq cycles in filter
- min_filtorder = 15; % minimum filter length
- trans = 0.15; % fractional width of transition zones
- if locutoff>0 & hicutoff > 0 & locutoff > hicutoff,
- error('locutoff > hicutoff ???\n');
- end
- if locutoff < 0 | hicutoff < 0,
- error('locutoff | hicutoff < 0 ???\n');
- end
- if locutoff>nyq,
- error('Low cutoff frequency cannot be > srate/2');
- end
- if hicutoff>nyq
- error('High cutoff frequency cannot be > srate/2');
- end
- if nargin<6
- filtorder = 0;
- end
- if nargin<7
- revfilt = 0;
- end
- if isempty(filtorder) | filtorder==0,
- if locutoff>0,
- filtorder = minfac*fix(srate/locutoff);
- elseif hicutoff>0,
- filtorder = minfac*fix(srate/hicutoff);
- end
-
- if filtorder < min_filtorder
- filtorder = min_filtorder;
- end
- end
- if nargin<5
- epochframes = 0;
- end
- if epochframes ==0,
- epochframes = frames; % default
- end
- epochs = fix(frames/epochframes);
- if epochs*epochframes ~= frames,
- error('epochframes does not divide frames.\n');
- end
- if filtorder*3 > epochframes, % Matlab filtfilt() restriction
- fprintf('eegfilt(): filter order is %d. ',filtorder);
- error('epochframes must be at least 3 times the filtorder.');
- end
- if (1+trans)*hicutoff/nyq > 1
- error('high cutoff frequency too close to Nyquist frequency');
- end;
- if locutoff > 0 & hicutoff > 0, % bandpass filter
- if revfilt
- fprintf('eegfilt() - performing %d-point notch filtering.\n',filtorder);
- else
- fprintf('eegfilt() - performing %d-point bandpass filtering.\n',filtorder);
- end;
- fprintf(' If a message, ''Matrix is close to singular or badly scaled,'' appears,\n');
- fprintf(' then Matlab has failed to design a good filter. As a workaround, \n');
- fprintf(' for band-pass filtering, first highpass the data, then lowpass it.\n');
- f=[MINFREQ (1-trans)*locutoff/nyq locutoff/nyq hicutoff/nyq (1+trans)*hicutoff/nyq 1];
- fprintf('eegfilt() - low transition band width is %1.1g Hz; high trans. band width, %1.1g Hz.\n',(f(3)-f(2))*srate, (f(5)-f(4))*srate/2);
- m=[0 0 1 1 0 0];
- elseif locutoff > 0 % highpass filter
- if locutoff/nyq < MINFREQ
- error(sprintf('eegfilt() - highpass cutoff freq must be > %g Hz\n\n',MINFREQ*nyq));
- end
- fprintf('eegfilt() - performing %d-point highpass filtering.\n',filtorder);
- f=[MINFREQ locutoff*(1-trans)/nyq locutoff/nyq 1];
- fprintf('eegfilt() - highpass transition band width is %1.1g Hz.\n',(f(3)-f(2))*srate/2);
- m=[ 0 0 1 1];
- elseif hicutoff > 0 % lowpass filter
- if hicutoff/nyq < MINFREQ
- error(sprintf('eegfilt() - lowpass cutoff freq must be > %g Hz',MINFREQ*nyq));
- end
- fprintf('eegfilt() - performing %d-point lowpass filtering.\n',filtorder);
- f=[MINFREQ hicutoff/nyq hicutoff*(1+trans)/nyq 1];
- fprintf('eegfilt() - lowpass transition band width is %1.1g Hz.\n',(f(3)-f(2))*srate/2);
- m=[ 1 1 0 0];
- else
- error('You must provide a non-0 low or high cut-off frequency');
- end
- if revfilt
- m = ~m;
- end;
- filtwts = firls(filtorder,f,m); % get FIR filter coefficients
- smoothdata = zeros(chans,frames);
- for e = 1:epochs % filter each epoch, channel
- for c=1:chans
- smoothdata(c,(e-1)*epochframes+1:e*epochframes) ...
- = filtfilt(filtwts,1,data(c,(e-1)*epochframes+1:e*epochframes));
- if epochs == 1
- if rem(c,20) ~= 0
- fprintf('.');
- else
- fprintf('%d',c);
- end
- end
- end
- end
- fprintf('\n');