/trunk/examples/toolboxes/eeglab/functions/popfunc/pop_runica.m

http://brainstream.googlecode.com/ · Objective C · 695 lines · 667 code · 28 blank · 0 comment · 93 complexity · 6d60fcf00fa0df975a7ce92707884e9d MD5 · raw file

  1. % pop_runica() - Run an ICA decomposition of an EEG dataset using runica(),
  2. % binica(), or another ICA or other linear decomposition.
  3. % Usage:
  4. % >> OUT_EEG = pop_runica( EEG ); % pops-up a data entry window
  5. % >> OUT_EEG = pop_runica( EEG, 'key', 'val' ); % no pop_up
  6. %
  7. % Graphic interface:
  8. % "ICA algorithm to use" - [edit box] The ICA algorithm to use for
  9. % ICA decomposition. Command line equivalent: 'icatype'
  10. % "Commandline options" - [edit box] Command line options to forward
  11. % to the ICA algorithm. Command line equivalent: 'options'
  12. % Inputs:
  13. % EEG - input EEG dataset or array of datasets
  14. %
  15. % Optional inputs:
  16. % 'icatype' - ['runica'|'binica'|'jader'|'fastica'] ICA algorithm
  17. % to use for the ICA decomposition. The nature of any
  18. % differences in the results of these algorithms have
  19. % not been well characterized. {default: binica(), if
  20. % found, else runica()}
  21. % 'dataset' - [integer array] dataset index or indices.
  22. % 'chanind' - [integer array] subset of channel indices for running
  23. % the ICA decomposition.
  24. % 'concatenate' - ['on'|'off'] 'on' concatenate all input datasets
  25. % (assuming there are several). 'off' run ICA independently
  26. % on each dataset. Default is 'on'.
  27. % 'key','val' - ICA algorithm options (see ICA routine help messages).
  28. %
  29. % Note:
  30. % 1) Infomax (runica, binica) is the ICA algorithm we use most. It is based
  31. % on Tony Bell's infomax algorithm as implemented for automated use by
  32. % Scott Makeig et al. using the natural gradient of Amari et al. It can
  33. % also extract sub-Gaussian sources using the (recommended) 'extended' option
  34. % of Lee and Girolami. Function runica() is the all-Matlab version; function
  35. % binica() calls the (1.5x faster) binary version (a separate download)
  36. % translated into C from runica() by Sigurd Enghoff.
  37. % 2) jader() calls the JADE algorithm of Jean-Francois Cardoso. This is
  38. % included in the EEGLAB toolbox by his permission. See >> help jader
  39. % 3) To run fastica(), download the fastICA toolbox from its website,
  40. % http://www.cis.hut.fi/projects/ica/fastica/, and make it available
  41. % in your Matlab path. According to its authors, default parameters
  42. % are not optimal: Try args 'approach', 'sym' to estimate components
  43. % in parallel.
  44. %
  45. % Outputs:
  46. % OUT_EEG = The input EEGLAB dataset with new fields icaweights, icasphere
  47. % and icachansind (channel indices).
  48. %
  49. % Author: Arnaud Delorme, CNL / Salk Institute, 2001
  50. %
  51. % See also: runica(), binica(), jader(), fastica()
  52. %123456789012345678901234567890123456789012345678901234567890123456789012
  53. % Copyright (C) 2001 Arnaud Delorme, Salk Institute, arno@salk.edu
  54. %
  55. % This program is free software; you can redistribute it and/or modify
  56. % it under the terms of the GNU General Public License as published by
  57. % the Free Software Foundation; either version 2 of the License, or
  58. % (at your option) any later version.
  59. %
  60. % This program is distributed in the hope that it will be useful,
  61. % but WITHOUT ANY WARRANTY; without even the implied warranty of
  62. % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  63. % GNU General Public License for more details.
  64. %
  65. % You should have received a copy of the GNU General Public License
  66. % along with this program; if not, write to the Free Software
  67. % Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
  68. % $Log: pop_runica.m,v $
  69. % Revision 1.81 2008/02/15 16:41:06 arno
  70. % fixing history problem for processing multiple datasets
  71. %
  72. % Revision 1.80 2007/11/26 18:55:59 arno
  73. % adding rank check
  74. %
  75. % Revision 1.79 2007/09/11 10:38:43 arno
  76. % && -> &
  77. %
  78. % Revision 1.78 2007/08/01 01:14:21 arno
  79. % same
  80. %
  81. % Revision 1.77 2007/08/01 01:13:43 arno
  82. % decoding optional imputs
  83. %
  84. % Revision 1.76 2007/05/03 02:46:10 toby
  85. % Only compute rank of double-precision data if data is double precision
  86. %
  87. % Revision 1.75 2007/03/22 18:59:12 arno
  88. % conversion to double
  89. %
  90. % Revision 1.74 2007/03/22 18:39:29 arno
  91. % convert to double for rank calculation
  92. %
  93. % Revision 1.73 2007/03/22 18:38:46 arno
  94. % do not convert data to double for runica and binica
  95. %
  96. % Revision 1.72 2007/03/21 23:11:26 arno
  97. % help message
  98. %
  99. % Revision 1.71 2007/03/21 23:08:33 arno
  100. % warning for computing ICA weights
  101. %
  102. % Revision 1.70 2007/02/20 14:17:08 arno
  103. % option to run several conditions of the same subject in a study
  104. %
  105. % Revision 1.69 2006/08/18 01:09:13 toby
  106. % bug fix, was collecting data from ALLEEG(1) instead of EEG in a particular situation
  107. %
  108. % Revision 1.68 2006/08/08 23:03:09 arno
  109. % fix bug for detecting PCA options
  110. %
  111. % Revision 1.67 2006/08/08 22:59:30 arno
  112. % remove debug message
  113. %
  114. % Revision 1.66 2006/05/17 18:32:10 arno
  115. % typo
  116. %
  117. % Revision 1.64 2006/04/17 16:20:05 scott
  118. % help msg and print text; fixed bug in saving icachansind to .etc
  119. %
  120. % Revision 1.63 2006/03/10 20:15:40 arno
  121. % extended 1 as default
  122. %
  123. % Revision 1.62 2005/11/22 00:25:38 arno
  124. % fixing channel browsing
  125. %
  126. % Revision 1.61 2005/11/10 23:44:45 arno
  127. % saving icachansind
  128. %
  129. % Revision 1.60 2005/11/10 23:39:56 arno
  130. % fixing concatenated datasets
  131. %
  132. % Revision 1.59 2005/11/10 22:38:51 arno
  133. % channel type, concatenation etc...
  134. %
  135. % Revision 1.58 2005/11/10 02:25:48 arno
  136. % channel type GUI
  137. %
  138. % Revision 1.57 2005/10/11 17:32:06 scott
  139. % help message - note: binica.sc 'stop' default changed to 1e-7 from 1e-6
  140. %
  141. % Revision 1.56 2005/09/27 22:07:28 arno
  142. % eeg_store instead of ALLEEG(g.dataset) = EEG;
  143. %
  144. % Revision 1.55 2005/07/28 18:18:19 arno
  145. % allowing to process mutliple datasets
  146. %
  147. % Revision 1.54 2005/07/26 23:55:17 arno
  148. % rewrote the function; allow to process several datasets
  149. %
  150. % Revision 1.53 2005/03/14 22:20:45 arno
  151. % fixing hilit correction
  152. %
  153. % Revision 1.52 2005/03/14 22:13:59 hilit
  154. % fixing a typo
  155. %
  156. % Revision 1.51 2005/03/14 19:43:28 arno
  157. % saving old weights
  158. %
  159. % Revision 1.50 2005/03/13 19:38:10 scott
  160. % saving EEG.oldwts and EEG.oldsph as cell arrays containing all former wts and sph
  161. %
  162. % Revision 1.49 2005/03/13 17:45:04 peter
  163. % saving wts and sph as EEG.oldwts (cell array) and EEG.oldsph
  164. % before clearing them
  165. % NOTE: 'binica' with 'maxsteps',5 doesnt work!!! (maxsteps not changed) ??
  166. %
  167. % Revision 1.48 2005/03/07 19:53:42 arno
  168. % fixing fastica call
  169. %
  170. % Revision 1.47 2005/02/02 01:29:28 arno
  171. % new method to compute weights, icawinv...
  172. %
  173. % Revision 1.46 2005/02/02 01:21:40 arno
  174. % remove old ICA information
  175. %
  176. % Revision 1.45 2005/02/01 23:09:42 arno
  177. % call to icaML and icaMS
  178. %
  179. % Revision 1.44 2004/09/09 00:13:31 arno
  180. % fixing rank problem
  181. %
  182. % Revision 1.43 2004/08/20 18:43:07 arno
  183. % remove MAC error for Osx
  184. %
  185. % Revision 1.42 2004/08/20 18:11:11 arno
  186. % no eval for binica
  187. %
  188. % Revision 1.41 2004/05/20 15:48:19 arno
  189. % debug fastica call
  190. %
  191. % Revision 1.40 2004/03/22 22:15:39 arno
  192. % pca option for binica
  193. %
  194. % Revision 1.39 2004/02/05 01:50:52 arno
  195. % call for acsobiro
  196. %
  197. % Revision 1.38 2004/02/05 01:37:51 arno
  198. % same
  199. %
  200. % Revision 1.37 2004/02/05 01:29:59 arno
  201. % debug sobi call
  202. %
  203. % Revision 1.36 2004/02/05 01:24:09 arno
  204. % updating sobi calls
  205. %
  206. % Revision 1.35 2003/12/19 02:49:43 arno
  207. % debug rank lowering
  208. %
  209. % Revision 1.34 2003/12/11 16:29:27 arno
  210. % debug history
  211. %
  212. % Revision 1.33 2003/12/11 16:28:01 arno
  213. % remove debug mesg
  214. %
  215. % Revision 1.32 2003/11/07 02:22:18 arno
  216. % fixing history problem
  217. %
  218. % Revision 1.31 2003/10/22 18:10:36 arno
  219. % typo in gui
  220. %
  221. % Revision 1.30 2003/10/15 00:36:33 arno
  222. % same
  223. %
  224. % Revision 1.29 2003/10/15 00:35:41 arno
  225. % debug fastica
  226. %
  227. % Revision 1.28 2003/09/02 21:40:59 lee
  228. % debug last
  229. %
  230. % Revision 1.27 2003/09/02 21:33:52 lee
  231. % changed data rank warning
  232. %
  233. % Revision 1.26 2003/07/26 00:53:32 arno
  234. % computing matrix rank and reducing number of comps accordingly
  235. %
  236. % Revision 1.25 2003/07/24 23:27:24 arno
  237. % debuging ng_ol
  238. %
  239. % Revision 1.24 2003/07/24 00:21:29 arno
  240. % buttons ...
  241. %
  242. % Revision 1.23 2003/07/23 18:36:54 arno
  243. % adding more algos
  244. %
  245. % Revision 1.22 2003/07/22 16:19:32 arno
  246. % tfbss
  247. %
  248. % Revision 1.21 2003/07/22 01:12:22 arno
  249. % adding algos
  250. %
  251. % Revision 1.20 2003/06/29 02:02:30 arno
  252. % last revision backup
  253. %
  254. % Revision 1.18 2003/02/23 08:38:32 scott
  255. % header edit -sm
  256. %
  257. % Revision 1.17 2003/02/19 19:22:40 arno
  258. % updating header for GUI
  259. %
  260. % Revision 1.16 2003/01/15 22:07:59 arno
  261. % typo
  262. %
  263. % Revision 1.15 2002/12/24 01:27:55 arno
  264. % debug for 'pca' option
  265. %
  266. % Revision 1.14 2002/12/05 03:12:06 arno
  267. % fixing fig problem
  268. %
  269. % Revision 1.13 2002/11/15 18:01:06 arno
  270. % adding more warning messages
  271. %
  272. % Revision 1.12 2002/11/13 23:05:53 arno
  273. % problem from command line call
  274. %
  275. % Revision 1.11 2002/11/13 17:08:26 scott
  276. % help msg
  277. % .,
  278. %
  279. % Revision 1.10 2002/10/25 23:55:09 arno
  280. % interupt only for runica
  281. %
  282. % Revision 1.9 2002/10/25 23:52:01 arno
  283. % debugging for Mac
  284. %
  285. % Revision 1.8 2002/10/23 18:09:58 arno
  286. % new interupt button
  287. %
  288. % Revision 1.7 2002/08/23 15:04:29 scott
  289. % help msg
  290. %
  291. % Revision 1.6 2002/08/19 21:53:40 arno
  292. % same
  293. %
  294. % Revision 1.5 2002/08/19 21:37:29 arno
  295. % debugging fastica for mac
  296. %
  297. % Revision 1.4 2002/08/12 02:28:24 arno
  298. % inputdlg2
  299. %
  300. % Revision 1.3 2002/05/02 21:39:42 arno
  301. % editing message
  302. %
  303. % Revision 1.2 2002/04/18 16:01:24 scott
  304. % editted msgs -sm
  305. %
  306. % Revision 1.1 2002/04/05 17:32:13 jorn
  307. % Initial revision
  308. %
  309. % 01-25-02 reformated help & license -ad
  310. % 03-07-02 add the eeglab options -ad
  311. % 03-18-02 add other decomposition options -ad
  312. % 03-19-02 text edition -sm
  313. function [ALLEEG, com] = pop_runica( ALLEEG, varargin )
  314. com = '';
  315. if nargin < 1
  316. help pop_runica;
  317. return;
  318. end;
  319. % find available algorithms
  320. % -------------------------
  321. allalgs = { 'runica' 'binica' 'jader' 'jadeop' 'jade_td_p' 'MatlabshibbsR' 'fastica' ...
  322. 'tica' 'erica' 'simbec' 'unica' 'amuse' 'fobi' 'evd' 'evd24' 'sons' 'sobi' 'ng_ol' ...
  323. 'acsobiro' 'acrsobibpf' 'pearson_ica' 'egld_ica' 'eeA' 'tfbss' 'icaML' 'icaMS' }; % do not use egld_ica => too slow
  324. selectalg = {};
  325. linenb = 1;
  326. count = 1;
  327. for index = length(allalgs):-1:1
  328. if exist(allalgs{index}) ~= 2 & exist(allalgs{index}) ~= 6
  329. allalgs(index) = [];
  330. end;
  331. end;
  332. % popup window parameters
  333. % -----------------------
  334. fig = [];
  335. if nargin < 2
  336. commandchans = [ 'tmpchans = get(gcbf, ''userdata'');' ...
  337. 'tmpchans = tmpchans{1};' ...
  338. 'set(findobj(gcbf, ''tag'', ''chantype''), ''string'', ' ...
  339. ' int2str(pop_chansel( tmpchans )));' ...
  340. 'clear tmpchans;' ];
  341. commandtype = ['tmptype = get(gcbf, ''userdata'');' ...
  342. 'tmptype = tmptype{2};' ...
  343. 'if ~isempty(tmptype),' ...
  344. ' [tmps,tmpv, tmpstr] = listdlg2(''PromptString'',''Select type(s)'', ''ListString'', tmptype);' ...
  345. ' if tmpv' ...
  346. ' set(findobj(''parent'', gcbf, ''tag'', ''chantype''), ''string'', tmpstr);' ...
  347. ' end;' ...
  348. 'else,' ...
  349. ' warndlg2(''No channel type'', ''No channel type'');' ...
  350. 'end;' ...
  351. 'clear tmps tmpv tmpstr tmptype tmpchans;' ];
  352. cb_ica = [ 'if get(gcbo, ''value'') < 3, ' ...
  353. ' set(findobj(gcbf, ''tag'', ''params''), ''string'', ''''''extended'''', 1'');' ...
  354. 'else set(findobj(gcbf, ''tag'', ''params''), ''string'', '''');' ...
  355. 'end;' ];
  356. promptstr = { { 'style' 'text' 'string' 'ICA algorithm to use (click to select)' } ...
  357. { 'style' 'listbox' 'string' strvcat(allalgs{:}) 'callback', cb_ica } ...
  358. { 'style' 'text' 'string' 'Commandline options (See help messages)' } ...
  359. { 'style' 'edit' 'string' '''extended'', 1' 'tag' 'params' } ...
  360. { 'style' 'text' 'string' 'Channel type(s) or channel indices' } ...
  361. { 'style' 'edit' 'string' '' 'tag' 'chantype' } ...
  362. { 'style' 'pushbutton' 'string' '... types' 'callback' commandtype } ...
  363. { 'style' 'pushbutton' 'string' '... channels' 'callback' commandchans } };
  364. geometry = { [2 1] [2 1] [2 1 1 1] };
  365. if length(ALLEEG) > 1
  366. cb1 = 'set(findobj(''parent'', gcbf, ''tag'', ''concat2''), ''value'', 0);';
  367. cb2 = 'set(findobj(''parent'', gcbf, ''tag'', ''concat1''), ''value'', 0);';
  368. promptstr = { promptstr{:} ...
  369. { 'style' 'text' 'string' 'Concatenate all datasets (check=yes; uncheck=run ICA on each dataset)?' } ...
  370. { 'style' 'checkbox' 'string' '' 'value' 0 'tag' 'concat1' 'callback' cb1 } ...
  371. { 'style' 'text' 'string' 'Concatenate datasets for the same subject and session (check=yes)?' } ...
  372. { 'style' 'checkbox' 'string' '' 'value' 1 'tag' 'concat2' 'callback' cb2 } };
  373. geometry = { geometry{:} [ 2 0.2 ] [ 2 0.2 ]};
  374. end;
  375. % channel types
  376. % -------------
  377. if isfield(ALLEEG(1).chanlocs, 'type'), alltypes = { ALLEEG(1).chanlocs.type };
  378. indempty = cellfun('isempty', alltypes);
  379. alltypes(indempty) = '';
  380. alltypes = unique(alltypes);
  381. else alltypes = '';
  382. end;
  383. % channel labels
  384. % --------------
  385. if ~isempty(ALLEEG(1).chanlocs)
  386. alllabels = { ALLEEG(1).chanlocs.labels };
  387. else
  388. for index = 1:ALLEEG(1).nbchan
  389. alllabels{index} = int2str(index);
  390. end;
  391. end;
  392. % gui
  393. % ---
  394. result = inputgui( 'geometry', geometry, 'uilist', promptstr, ...
  395. 'helpcom', 'pophelp(''pop_runica'')', ...
  396. 'title', 'Run ICA decomposition -- pop_runica()', 'userdata', { alllabels alltypes } );
  397. if length(result) == 0 return; end;
  398. options = { 'icatype' allalgs{result{1}} 'dataset' [1:length(ALLEEG)] 'options' eval( [ '{' result{2} '}' ]) };
  399. if ~isempty(result{3})
  400. if ~isempty(str2num(result{3})), options = { options{:} 'chanind' str2num(result{3}) };
  401. else options = { options{:} 'chanind' eeg_chantype(ALLEEG(1).chanlocs, parsetxt(result{3})) };
  402. end;
  403. end;
  404. if length(result) > 3
  405. options = { options{:} 'concatenate' fastif(result{4}, 'on', 'off') };
  406. options = { options{:} 'concatcond' fastif(result{5}, 'on', 'off') };
  407. end;
  408. else
  409. if mod(length(varargin),2) == 1
  410. options = { 'icatype' varargin{1:end} };
  411. else
  412. options = varargin;
  413. end;
  414. end;
  415. % decode input arguments
  416. % ----------------------
  417. [ g options ] = finputcheck( options, { 'icatype' 'string' allalgs 'runica'; ...
  418. 'dataset' 'integer' [] [1:length(ALLEEG)];
  419. 'options' 'cell' [] {};
  420. 'concatenate' 'string' { 'on' 'off' } 'off';
  421. 'concatcond' 'string' { 'on' 'off' } 'off';
  422. 'chanind' 'integer' [] [];}, ...
  423. 'pop_runica', 'ignore');
  424. if isstr(g), error(g); end;
  425. if isempty(g.options), g.options = options; end;
  426. % select datasets, create new big dataset if necessary
  427. % ----------------------------------------------------
  428. if length(g.dataset) == 1
  429. EEG = ALLEEG(g.dataset);
  430. elseif length(ALLEEG) > 1 & ~strcmpi(g.concatenate, 'on') & ~strcmpi(g.concatcond, 'on')
  431. [ ALLEEG com ] = eeg_eval( 'pop_runica', ALLEEG, 'warning', 'off', 'params', ...
  432. { 'icatype' g.icatype 'options' g.options 'chanind' g.chanind } );
  433. return;
  434. elseif length(ALLEEG) > 1 & strcmpi(g.concatcond, 'on')
  435. allsubjects = { ALLEEG.subject };
  436. allsessions = { ALLEEG.session };
  437. allgroups = { ALLEEG.group };
  438. alltags = zeros(1,length(allsubjects));
  439. if any(cellfun('isempty', allsubjects))
  440. disp('Abording, some datasets do not have subject names');
  441. return;
  442. end;
  443. dats = {};
  444. for index = 1:length(allsubjects)
  445. if ~alltags(index)
  446. allinds = strmatch(allsubjects{index}, allsubjects);
  447. rmind = [];
  448. for tmpi = 2:length(allinds)
  449. if ~isequal(allsessions(allinds(1)), allsessions(allinds(tmpi))), rmind = [rmind tmpi];
  450. elseif ~isequal(allgroups(allinds(1)), allgroups(allinds(tmpi))), rmind = [rmind tmpi];
  451. end;
  452. end;
  453. allinds(rmind) = [];
  454. fprintf('Found %d datasets for subject ''%s''\n', length(allinds), allsubjects{index});
  455. dats = { dats{:} allinds };
  456. alltags(allinds) = 1;
  457. end;
  458. end;
  459. fprintf('**************************\nNOW RUNNING ALL DECOMPOSITIONS\n****************************\n');
  460. for index = 1:length(dats)
  461. ALLEEG(dats{index}) = pop_runica(ALLEEG(dats{index}), 'icatype', g.icatype, ...
  462. 'options', g.options, 'chanind', g.chanind, 'concatenate', 'on');
  463. end;
  464. com = sprintf('%s = pop_runica(%s, %s);', inputname(1),inputname(1), ...
  465. vararg2str({ 'icatype' g.icatype 'concatcond' 'on' 'options' g.options }) );
  466. return;
  467. else
  468. disp('Concatenating datasets...');
  469. EEG = ALLEEG(g.dataset(1));
  470. % compute total data size
  471. % -----------------------
  472. totalpnts = 0;
  473. for i = g.dataset
  474. totalpnts = totalpnts+ALLEEG(g.dataset(i)).pnts*ALLEEG(g.dataset(i)).trials;
  475. end;
  476. EEG.data = zeros(EEG.nbchan, totalpnts);
  477. % copy data
  478. % ---------
  479. cpnts = 1;
  480. for i = g.dataset
  481. tmplen = ALLEEG(g.dataset(i)).pnts*ALLEEG(g.dataset(i)).trials;
  482. TMP = eeg_checkset(ALLEEG(g.dataset(i)), 'loaddata');
  483. EEG.data(:,cpnts:cpnts+tmplen-1) = reshape(TMP.data, size(TMP.data,1), size(TMP.data,2)*size(TMP.data,3));
  484. cpnts = cpnts+1;
  485. end;
  486. EEG.icaweights = [];
  487. EEG.trials = 1;
  488. EEG.pnts = size(EEG.data,2);
  489. end;
  490. % Store and then remove current EEG ICA weights and sphere
  491. % ---------------------------------------------------
  492. fprintf('\n');
  493. if ~isempty(EEG.icaweights)
  494. fprintf('Saving current ICA decomposition in "EEG.etc.oldicaweights" (etc.).\n');
  495. if ~isfield(EEG,'etc'), EEG.etc = []; end;
  496. if ~isfield(EEG.etc,'oldicaweights')
  497. EEG.etc.oldicaweights = {};
  498. EEG.etc.oldicasphere = {};
  499. EEG.etc.oldicachansind = {};
  500. end;
  501. EEG.etc.oldicaweights = { EEG.icaweights EEG.etc.oldicaweights{:} };
  502. EEG.etc.oldicasphere = { EEG.icasphere EEG.etc.oldicasphere{:} };
  503. EEG.etc.oldicachansind = { EEG.icachansind EEG.etc.oldicachansind{:} };
  504. fprintf(' Decomposition saved as entry %d.\n',length(EEG.etc.oldicaweights));
  505. end
  506. EEG.icaweights = [];
  507. EEG.icasphere = [];
  508. EEG.icawinv = [];
  509. EEG.icaact = [];
  510. % select sub_channels
  511. % -------------------
  512. if isempty(g.chanind)
  513. g.chanind = 1:EEG.nbchan;
  514. end;
  515. EEG.icachansind = g.chanind;
  516. % is pca already an option?
  517. % -------------------------
  518. pca_opt = 0;
  519. for i = 1:length(g.options)
  520. if isstr(g.options{i})
  521. if strcmpi(g.options{i}, 'pca')
  522. pca_opt = 1;
  523. end;
  524. end;
  525. end;
  526. %------------------------------
  527. % compute ICA on a definite set
  528. % -----------------------------
  529. tmpdata = reshape( EEG.data(g.chanind,:,:), length(g.chanind), EEG.pnts*EEG.trials);
  530. tmpdata = tmpdata - repmat(mean(tmpdata,2), [1 size(tmpdata,2)]); % zero mean
  531. if ~strcmpi(lower(g.icatype), 'binica')
  532. try,
  533. disp('Attempting to convert data matrix to double precision (more accurate ICA results)')
  534. tmpdata = double(tmpdata);
  535. tmpdata2 = tmpdata+1; % check for more memory
  536. clear tmpdata2;
  537. catch,
  538. disp('*************************************************************')
  539. disp('Not enougth memory to convert data Matrix to double precision')
  540. disp('All computation will be done in single precision. Matlab 7.x')
  541. disp('(under 64-bit Linux and others) is imprecise in this mode')
  542. disp('We advise that you use "binica" instead of "runica"')
  543. disp('*************************************************************')
  544. end;
  545. end;
  546. switch lower(g.icatype)
  547. case 'runica'
  548. if nargin < 2
  549. fig = figure('visible', 'off');
  550. supergui( fig, {1 1}, [], {'style' 'text' 'string' 'Press button to interrupt runica()' }, ...
  551. {'style' 'pushbutton' 'string' 'Interupt' 'callback' 'figure(gcbf); set(gcbf, ''tag'', ''stop'');' } );
  552. drawnow;
  553. end;
  554. tmprank = getrank(tmpdata(:,1:min(3000, size(tmpdata,2))));
  555. if tmprank == size(tmpdata,1) | pca_opt
  556. [EEG.icaweights,EEG.icasphere] = runica( tmpdata, 'lrate', 0.001, g.options{:} );
  557. else
  558. disp(['Data rank (' int2str(tmprank) ') less than the number of channels (' int2str(size(tmpdata,1)) ').']);
  559. [EEG.icaweights,EEG.icasphere] = runica( tmpdata, 'lrate', 0.001, 'pca', tmprank, g.options{:} );
  560. end;
  561. case 'binica'
  562. icadefs;
  563. fprintf(['Warning: If the binary ICA function does not work, check that you have added the\n' ...
  564. 'binary file location (in the EEGLAB directory) to your Unix /bin directory (.cshrc file)\n']);
  565. if exist(ICABINARY) ~= 2
  566. error('Pop_runica(): binary ICA executable not found. Edit icadefs.m file to specify the ICABINARY location');
  567. end;
  568. tmprank = getrank(tmpdata(:,1:min(3000, size(tmpdata,2))));
  569. if tmprank == size(tmpdata,1) | pca_opt
  570. [EEG.icaweights,EEG.icasphere] = binica( tmpdata, 'lrate', 0.001, g.options{:} );
  571. else
  572. disp(['Data rank (' int2str(tmprank) ') is less than the number of channels (' int2str(size(tmpdata,1)) ').']);
  573. [EEG.icaweights,EEG.icasphere] = binica( tmpdata, 'lrate', 0.001, 'pca', tmprank, g.options{:} );
  574. end;
  575. case 'pearson_ica'
  576. if isempty(g.options)
  577. disp('Warning: EEG default for pearson ICA changed to 1000 iterations and epsilon=0.0005');
  578. [tmp EEG.icaweights] = pearson_ica( tmpdata, 'maxNumIterations', 1000,'epsilon',0.0005);
  579. else
  580. [tmp EEG.icaweights] = pearson_ica( tmpdata, g.options{:});
  581. end;
  582. case 'egld_ica', disp('Warning: this algorithm is very slow!!!');
  583. [tmp EEG.icaweights] = egld_ica( tmpdata, g.options{:} );
  584. case 'tfbss'
  585. if isempty(g.options)
  586. [tmp EEG.icaweights] = tfbss( tmpdata, size(tmpdata,1), 8, 512 );
  587. else
  588. [tmp EEG.icaweights] = tfbss( tmpdata, g.options{:} );
  589. end;
  590. case 'jader', [EEG.icaweights] = jader( tmpdata, g.options{:} );
  591. case 'matlabshibbsr', [EEG.icaweights] = MatlabshibbsR( tmpdata, g.options{:} );
  592. case 'eea', [EEG.icaweights] = eeA( tmpdata, g.options{:} );
  593. case 'icaml', [tmp EEG.icawinv] = icaML( tmpdata, g.options{:} );
  594. case 'icams', [tmp EEG.icawinv] = icaMS( tmpdata, g.options{:} );
  595. case 'fastica', [ ICAcomp, EEG.icawinv, EEG.icaweights] = fastica( tmpdata, 'displayMode', 'off', g.options{:} );
  596. case { 'tica' 'erica' 'simbec' 'unica' 'amuse' 'fobi' 'evd' 'sons' ...
  597. 'jadeop' 'jade_td_p' 'evd24' 'sobi' 'ng_ol' 'acsobiro' 'acrsobibpf' }
  598. fig = figure('tag', 'alg_is_run', 'visible', 'off');
  599. if isempty(g.options), g.options = { size(tmpdata,1) }; end;
  600. switch lower(g.icatype)
  601. case 'tica', EEG.icaweights = tica( tmpdata, g.options{:} );
  602. case 'erica', EEG.icaweights = erica( tmpdata, g.options{:} );
  603. case 'simbec', EEG.icaweights = simbec( tmpdata, g.options{:} );
  604. case 'unica', EEG.icaweights = unica( tmpdata, g.options{:} );
  605. case 'amuse', EEG.icaweights = amuse( tmpdata );
  606. case 'fobi', [tmp EEG.icaweights] = fobi( tmpdata, g.options{:} );
  607. case 'evd', EEG.icaweights = evd( tmpdata, g.options{:} );
  608. case 'sons', EEG.icaweights = sons( tmpdata, g.options{:} );
  609. case 'jadeop', EEG.icaweights = jadeop( tmpdata, g.options{:} );
  610. case 'jade_td_p',EEG.icaweights = jade_td_p( tmpdata, g.options{:} );
  611. case 'evd24', EEG.icaweights = evd24( tmpdata, g.options{:} );
  612. case 'sobi', EEG.icawinv = sobi( EEG.data, g.options{:} );
  613. case 'ng_ol', [tmp EEG.icaweights] = ng_ol( tmpdata, g.options{:} );
  614. case 'acsobiro', EEG.icawinv = acsobiro( EEG.data, g.options{:} );
  615. case 'acrsobibpf', EEG.icawinv = acrsobibpf( tmpdata, g.options{:} );
  616. end;
  617. clear tmp;
  618. close(fig);
  619. otherwise, error('Pop_runica: unrecognized algorithm');
  620. end;
  621. % update weight and inverse matrices etc...
  622. % -----------------------------------------
  623. if ~isempty(fig), try, close(fig); catch, end; end;
  624. if isempty(EEG.icaweights)
  625. EEG.icaweights = pinv(EEG.icawinv);
  626. end;
  627. if isempty(EEG.icasphere)
  628. EEG.icasphere = eye(size(EEG.icaweights,2));
  629. end;
  630. if isempty(EEG.icawinv)
  631. EEG.icawinv = pinv(EEG.icaweights*EEG.icasphere); % a priori same result as inv
  632. end;
  633. % copy back data to datasets if necessary
  634. % ---------------------------------------
  635. if length(g.dataset) > 1
  636. for i = g.dataset
  637. ALLEEG(i).icaweights = EEG.icaweights;
  638. ALLEEG(i).icasphere = EEG.icasphere;
  639. ALLEEG(i).icawinv = EEG.icawinv;
  640. ALLEEG(i).icachansind = g.chanind;
  641. end;
  642. ALLEEG = eeg_checkset(ALLEEG);
  643. else
  644. EEG = eeg_checkset(EEG);
  645. ALLEEG = eeg_store(ALLEEG, EEG, g.dataset);
  646. end;
  647. if nargin < 2
  648. if length(ALLEEG) == 1
  649. com = sprintf('%s = pop_runica(%s, %s);', inputname(1),inputname(1), ...
  650. vararg2str({ 'icatype' g.icatype 'dataset' g.dataset 'options' g.options }) );
  651. else
  652. com = sprintf('%s = pop_runica(%s, %s);', inputname(1),inputname(1), vararg2str(options) );
  653. end;
  654. end;
  655. return;
  656. function tmprank2 = getrank(tmpdata);
  657. tmprank = rank(tmpdata);
  658. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  659. %Here: alternate computation of the rank by Sven Hoffman
  660. %tmprank = rank(tmpdata(:,1:min(3000, size(tmpdata,2)))); old code
  661. covarianceMatrix = cov(tmpdata', 1);
  662. [E, D] = eig (covarianceMatrix);
  663. rankTolerance = 1e-7;
  664. tmprank2=sum (diag (D) > rankTolerance);
  665. if tmprank ~= tmprank2
  666. fprintf('Warning: fixing rank computation inconsistency (%d vs %d) most likely because running under Linux 64-bit Matlab', tmprank, tmprank2);
  667. end;