/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

  1. % eegfilt() - (high|low|band)-iass filter data using two-way least-squares
  2. % FIR filtering. Multiple data channels and epochs supported.
  3. % Requires the MATLAB Signal Processing Toolbox.
  4. % Usage:
  5. % >> [smoothdata] = eegfilt(data,srate,locutoff,hicutoff);
  6. % >> [smoothdata,filtwts] = eegfilt(data,srate,locutoff,hicutoff, ...
  7. % epochframes,filtorder);
  8. % Inputs:
  9. % data = (channels,frames*epochs) data to filter
  10. % srate = data sampling rate (Hz)
  11. % locutoff = low-edge frequency in pass band (Hz) {0 -> lowpass}
  12. % hicutoff = high-edge frequency in pass band (Hz) {0 -> highpass}
  13. % epochframes = frames per epoch (filter each epoch separately {def/0: data is 1 epoch}
  14. % filtorder = length of the filter in points {default 3*fix(srate/locutoff)}
  15. % revfilt = [0|1] reverse filter (i.e. bandpass filter to notch filter). {0}
  16. %
  17. % Outputs:
  18. % smoothdata = smoothed data
  19. % filtwts = filter coefficients [smoothdata <- filtfilt(filtwts,1,data)]
  20. %
  21. % See also: firls(), filtfilt()
  22. %
  23. % Author: Scott Makeig, Arnaud Delorme, SCCN/INC/UCSD, La Jolla, 1997
  24. % Copyright (C) 4-22-97 from bandpass.m Scott Makeig, SCCN/INC/UCSD, scott@sccn.ucsd.edu
  25. %
  26. % This program is free software; you can redistribute it and/or modify
  27. % it under the terms of the GNU General Public License as published by
  28. % the Free Software Foundation; either version 2 of the License, or
  29. % (at your option) any later version.
  30. %
  31. % This program is distributed in the hope that it will be useful,
  32. % but WITHOUT ANY WARRANTY; without even the implied warranty of
  33. % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  34. % GNU General Public License for more details.
  35. %
  36. % You should have received a copy of the GNU General Public License
  37. % along with this program; if not, write to the Free Software
  38. % Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
  39. % $Log: eegfilt.m,v $
  40. % Revision 1.19 2004/11/19 23:28:11 arno
  41. % same
  42. %
  43. % Revision 1.18 2004/11/19 23:27:27 arno
  44. % better error messsage
  45. %
  46. % Revision 1.17 2004/08/31 02:12:56 arno
  47. % typo
  48. %
  49. % Revision 1.16 2004/02/12 23:09:19 scott
  50. % same
  51. %
  52. % Revision 1.15 2004/02/12 23:08:02 scott
  53. % text output edit
  54. %
  55. % Revision 1.14 2004/02/12 22:51:30 scott
  56. % text output edits
  57. %
  58. % Revision 1.13 2003/07/28 17:38:53 arno
  59. % updating error messages
  60. %
  61. % Revision 1.12 2003/07/20 19:17:07 scott
  62. % added channels-processed info if epochs==1 (continuous data)
  63. %
  64. % Revision 1.11 2003/04/11 15:03:46 arno
  65. % nothing
  66. %
  67. % Revision 1.10 2003/03/16 01:00:48 scott
  68. % header and error msgs -sm
  69. %
  70. % Revision 1.9 2003/01/24 03:59:19 scott
  71. % header edit -sm
  72. %
  73. % Revision 1.8 2003/01/24 00:23:33 arno
  74. % print information about transition bands
  75. %
  76. % Revision 1.7 2003/01/23 23:53:25 arno
  77. % change text
  78. %
  79. % Revision 1.6 2003/01/23 23:47:26 arno
  80. % same
  81. %
  82. % Revision 1.5 2003/01/23 23:40:59 arno
  83. % implementing notch filter
  84. %
  85. % Revision 1.4 2002/08/09 14:55:36 arno
  86. % update transition band
  87. %
  88. % Revision 1.3 2002/08/09 02:06:27 arno
  89. % updating transition
  90. %
  91. % Revision 1.2 2002/08/09 02:04:34 arno
  92. % debugging
  93. %
  94. % Revision 1.1 2002/04/05 17:36:45 jorn
  95. % Initial revision
  96. %
  97. % 5-08-97 fixed frequency bound computation -sm
  98. % 10-22-97 added MINFREQ tests -sm
  99. % 12-05-00 added error() calls -sm
  100. % 01-25-02 reformated help & license, added links -ad
  101. function [smoothdata,filtwts] = eegfilt(data,srate,locutoff,hicutoff,epochframes,filtorder, revfilt)
  102. if nargin<4
  103. fprintf('');
  104. help eegfilt
  105. return
  106. end
  107. if ~exist('firls')
  108. error('*** eegfilt() requires the signal processing toolbox. ***');
  109. end
  110. [chans frames] = size(data);
  111. if chans > 1 & frames == 1,
  112. help eegfilt
  113. error('input data should be a row vector.');
  114. end
  115. nyq = srate*0.5; % Nyquist frequency
  116. %MINFREQ = 0.1/nyq;
  117. MINFREQ = 0;
  118. minfac = 3; % this many (lo)cutoff-freq cycles in filter
  119. min_filtorder = 15; % minimum filter length
  120. trans = 0.15; % fractional width of transition zones
  121. if locutoff>0 & hicutoff > 0 & locutoff > hicutoff,
  122. error('locutoff > hicutoff ???\n');
  123. end
  124. if locutoff < 0 | hicutoff < 0,
  125. error('locutoff | hicutoff < 0 ???\n');
  126. end
  127. if locutoff>nyq,
  128. error('Low cutoff frequency cannot be > srate/2');
  129. end
  130. if hicutoff>nyq
  131. error('High cutoff frequency cannot be > srate/2');
  132. end
  133. if nargin<6
  134. filtorder = 0;
  135. end
  136. if nargin<7
  137. revfilt = 0;
  138. end
  139. if isempty(filtorder) | filtorder==0,
  140. if locutoff>0,
  141. filtorder = minfac*fix(srate/locutoff);
  142. elseif hicutoff>0,
  143. filtorder = minfac*fix(srate/hicutoff);
  144. end
  145. if filtorder < min_filtorder
  146. filtorder = min_filtorder;
  147. end
  148. end
  149. if nargin<5
  150. epochframes = 0;
  151. end
  152. if epochframes ==0,
  153. epochframes = frames; % default
  154. end
  155. epochs = fix(frames/epochframes);
  156. if epochs*epochframes ~= frames,
  157. error('epochframes does not divide frames.\n');
  158. end
  159. if filtorder*3 > epochframes, % Matlab filtfilt() restriction
  160. fprintf('eegfilt(): filter order is %d. ',filtorder);
  161. error('epochframes must be at least 3 times the filtorder.');
  162. end
  163. if (1+trans)*hicutoff/nyq > 1
  164. error('high cutoff frequency too close to Nyquist frequency');
  165. end;
  166. if locutoff > 0 & hicutoff > 0, % bandpass filter
  167. if revfilt
  168. fprintf('eegfilt() - performing %d-point notch filtering.\n',filtorder);
  169. else
  170. fprintf('eegfilt() - performing %d-point bandpass filtering.\n',filtorder);
  171. end;
  172. fprintf(' If a message, ''Matrix is close to singular or badly scaled,'' appears,\n');
  173. fprintf(' then Matlab has failed to design a good filter. As a workaround, \n');
  174. fprintf(' for band-pass filtering, first highpass the data, then lowpass it.\n');
  175. f=[MINFREQ (1-trans)*locutoff/nyq locutoff/nyq hicutoff/nyq (1+trans)*hicutoff/nyq 1];
  176. 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);
  177. m=[0 0 1 1 0 0];
  178. elseif locutoff > 0 % highpass filter
  179. if locutoff/nyq < MINFREQ
  180. error(sprintf('eegfilt() - highpass cutoff freq must be > %g Hz\n\n',MINFREQ*nyq));
  181. end
  182. fprintf('eegfilt() - performing %d-point highpass filtering.\n',filtorder);
  183. f=[MINFREQ locutoff*(1-trans)/nyq locutoff/nyq 1];
  184. fprintf('eegfilt() - highpass transition band width is %1.1g Hz.\n',(f(3)-f(2))*srate/2);
  185. m=[ 0 0 1 1];
  186. elseif hicutoff > 0 % lowpass filter
  187. if hicutoff/nyq < MINFREQ
  188. error(sprintf('eegfilt() - lowpass cutoff freq must be > %g Hz',MINFREQ*nyq));
  189. end
  190. fprintf('eegfilt() - performing %d-point lowpass filtering.\n',filtorder);
  191. f=[MINFREQ hicutoff/nyq hicutoff*(1+trans)/nyq 1];
  192. fprintf('eegfilt() - lowpass transition band width is %1.1g Hz.\n',(f(3)-f(2))*srate/2);
  193. m=[ 1 1 0 0];
  194. else
  195. error('You must provide a non-0 low or high cut-off frequency');
  196. end
  197. if revfilt
  198. m = ~m;
  199. end;
  200. filtwts = firls(filtorder,f,m); % get FIR filter coefficients
  201. smoothdata = zeros(chans,frames);
  202. for e = 1:epochs % filter each epoch, channel
  203. for c=1:chans
  204. smoothdata(c,(e-1)*epochframes+1:e*epochframes) ...
  205. = filtfilt(filtwts,1,data(c,(e-1)*epochframes+1:e*epochframes));
  206. if epochs == 1
  207. if rem(c,20) ~= 0
  208. fprintf('.');
  209. else
  210. fprintf('%d',c);
  211. end
  212. end
  213. end
  214. end
  215. fprintf('\n');