-
Notifications
You must be signed in to change notification settings - Fork 6
/
Copy pathpop_relica.m
287 lines (264 loc) · 14.2 KB
/
pop_relica.m
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
% pop_relica() - Call interactive windows of RELICA Toolbox
% The RELICA toolbox enables to estimate the reliability of
% independent components by performing the ICA algorithm several times,
% each time on different data, resampled with repetition and letting
% you see. The algorithm is already optimized for GPU/CUDA,
% if available on the workstation.
%
%
% Usage:
% >> EEG = pop_relica(EEG,M,algo,mode_relica, folder_relica); % Local computation call
% >> EEG = pop_relica(EEG,M,algo,mode_relica, folder_relica, 'nsg', 'runtime', 0.5); % NSG computation call
% >> EEG = pop_relica(EEG); % pop up interactive window
% >> EEG = pop_relica('relicansg_myjobID'); % Retreive/continue RELICA
% computation performed at NSG
%
% Inputs:
% EEG - Input dataset in the case of running RELICA on a local computational
% resource or when submitting a RELICA computaion to NSG.
% If retreiving a RELICA computation from NSG, this inpust
% should be the job ID assigned to the job.
% M - Number of boostraps, i.e. the number of times the ICA algorithm should run
% algo - ICA algorithm to run. Currently possible options are:
% 'beamica': (default)Infomax-based ICA algorithm already
% optimized for GPU computing (if available)
% mode_relica - select thd type of bootstrap to do. Possible options are:
% 'trial': each time the ICA algorithm is
% run trials are resampled with repetition. This
% option is only available on epoched datasets.
% If the dataset is no epoched, the RELICA
% algorithm will revert back to the
% point-by-point bootstrapping version
% 'point' Point-by-point: each time the ICA algorithm is
% run data samples are resampled with repetition.
% This is the default option
% folder_relica - select the output folder.
% compflag - {'local', 'nsg'} Flag to direct computation to NSG ('nsg') or
% or to local computer ('local'). Default: 'local'
%
% Optional inputs:
% These options must be provided as a pair: 'optname', optvalue
% 'icaopt' - Cell array with options for the ICA method used. The format
% of the inputs must be provided as pairs in a cell array as
% the following example. { 'optname1', optvalue1,'optname2', optvalue2 }
% 'parpools' - Number of workers to use in the parallelization.
% The default is the maximum number of MATLAB workers in your
% system (usually the number of cores). This option
% can not be used if the option below ('compflag') is
% set to 'nsg'.
% The options below require 'compflag' set to 'nsg'
% 'jobid' - String with the client job id. This was assigned to the
% job when created. Use with command line option option 'run'.
% Default: Prefix 'relicansg_' trailed by five digit random number. e.g 'relicansg_616402'
% 'runtime' - Time (in hours) to allocate for running the job in NSG.
% Maximun time allocation is 48 hrs. Use with command line
% option option 'run'. Default: 0.5
% GUI Inputs:
% 'ICA method' - Correspond to input 'algo'
% 'Relica mode' - Correspond to input 'mode_relica'
% 'trial-by-trial' -> 'trial'
% 'point-by-point' -> 'point'
% 'Bootstraps' - Correspond to input 'M'
% 'Output folder' - Correspond to input 'folder_relica'
% 'NSG options' - RELICA options non specific to NSG ('jobid', 'runtime')
% 'Compute on NSG' - Correspond to input 'compflag'
% 'NSG options' - Currently allows only options 'jobid' and 'runtime'.
% The number of options may increase in the feature.
%
% 'Outputs:
% EEG - Output dataset: RELICA data is in EEG.etc.RELICA, the same is
% saved in folder_relica folder
%
% See also: relica.m
%
% Author: Dr. Fiorenzo Artoni, 2019 %
%
% References:
% (1) Artoni, F., Menicucci, D., Delorme, A., Makeig, S., & Micera, S. (2014).
% RELICA: a method for estimating the reliability of independent components.
% NeuroImage, 103, 391-400.
%
% (2) Artoni, F., Delorme A., Makeig S. (2018)
% Applying dimension reduction to EEG data by Principal Component Analysis
% reduces the quality of its subsequent Independent Component
% decomposition, Neuroimage 175 176-187
%
% This project was in part supported by the European Union's Horizon 2020
% research and innovation programme under Marie Sklodowska-Curie Action
% agreement no. 750947 (BIREHAB)
%
% Acknowledgments go to Ramon Martinez-Cancino (SCCN/INC/UCSD 2019) for making the
% algorithm available and parallelized on the NSG server.
% Acknowledgments go also to Arnaud Delorme and Scott Makeig (SCCN/INC/UCSD 2019)
% for the precious inputs and ideas to perfect the project.
% Clustering and relative visualization within RELICA makes use of modified
% routines from J. Himberg's open source FastICA - ICASSO package
% Beamica is part of C. Kothe's open source BCILAB toolbox
%
% 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
function [EEGout, com] = pop_relica(EEG, M,algo,mode_relica, folder_relica,varargin)
if nargin < 1
help pop_relica;
return;
end
com = ''; EEGout = struct;
% Checking if NSGPORTAL Toolbox is set
nsginstalled_flag = 1;
try
nsg_info; % From here, get information on where to create the temporary file
catch
nsginstalled_flag = 0;
end
if isstruct(EEG)
icaalgorithm = {'beamica' 'runica' 'picard'}; % add new agorithm here
% Check if PICARD exist and adding it to menu
if exist('picard.m', 'file')
icaalgorithm{3} = 'picard';
end
moderelicaval = {'point' 'trial'};
jobiddef = ['relicansg_' num2str(floor(rand(1)*1000000))];
if license('test', 'Distrib_Computing_Toolbox')
clust = parcluster;
defpools = clust.NumWorkers;
end
if ~exist('M', 'var'), M = 50; end
if ~exist('algo', 'var'), algo = 'beamica'; end
if ~exist('mode_relica', 'var'), mode_relica = 'point'; end
if ~exist('folder_relica', 'var'), folder_relica = fullfile(pwd,'relicaoutput'); end
if ~exist('compflag', 'var'), compflag = 'local'; end
g = finputcheck(varargin, ...
{'icaopt' 'cell' '' {} ; ... % NSG specific
'jobid' 'string' '' jobiddef ; ... % NSG specific
'runtime' 'real' [0.1 48] 0.5}) ; % NSG specific
if ischar(g), error(g); end
if nargin < 5
% Closing open GUI and creating a new one
openfig = findobj('tag', 'pop_relicagui');
if ~isempty(openfig)
disp('pop_relica warning: there can be only one pop_relica window, closing old one...')
close(openfig);
end
guititle = 'Estimate reliability of independent components -- pop_relica()';
cfolder = '';
nsgcheck = ['if ' num2str(nsginstalled_flag) ',if get(findobj(''tag'',''chckbx_nsgt''),''value''),' ...
'set(findobj(''tag'',''nsgopt''),''enable'', ''on'');'...
'else, set(findobj(''tag'',''nsgopt''),''enable'', ''off'');end;'...
'else, set(findobj(''tag'',''nsgopt''),''enable'', ''off''); set(findobj(''tag'',''chckbx_nsgt''),''value'',0); end'];
cbfolder = 'pathname = uigetdir();if ~isequal(pathname, 0),[trash,filename] = fileparts(pathname); set(findobj(gcbf, ''tag'', ''relicafolder''), ''string'', pathname);end;';
moderelicagui = {'point-by-point' 'trial-by-trial'};
uilist = {{'style' 'text' 'string' 'ICA method'} {'style' 'popupmenu' 'string' icaalgorithm 'tag' 'icamethod' 'value' 1} ...
{'style' 'text' 'string' 'RELICA mode'} {'style' 'popupmenu' 'string' moderelicagui 'tag' 'relicamode' 'value' 1}...
{'style' 'text' 'string' 'Bootstraps'} {'style' 'edit' 'string' num2str(M) 'tag' 'nboots'}...
{'style' 'text' 'string' 'Output folder'} {'style' 'edit' 'string' folder_relica 'tag' 'relicafolder'} {'style' 'pushbutton' 'string' 'Browse...' 'tag' 'filebrowse' 'callback' cbfolder}...
{'style' 'text' 'string' 'RELICA options'} {'style' 'edit' 'string' ' ' 'tag' 'relicaopt'}...
{'style' 'text' 'string' 'Compute on NSG'} {'style' 'checkbox' 'tag' 'chckbx_nsgt' 'callback' nsgcheck 'value' fastif(strcmpi(compflag,'nsg'), 1, 0)}...
{'style' 'text' 'string' 'NSG options'} {'style' 'edit' 'string' ' ' 'tag' 'nsgopt' 'enable' fastif( strcmpi(compflag,'nsg'), 'on','off')}};
%%
ht = 6; wt = 4.5; c1 = 0; c2 = 1; c3 = 3; c4 = 4;
geom = { {wt ht [c1 0] [1 1]} {wt ht [c2 0] [3.5 1]} ...
{wt ht [c1 1] [1 1]} {wt ht [c2 1] [1.3 1]} {wt ht [2.3 1] [1 1]} {wt ht [3.1 1] [1 1]} ...
{wt ht [c1 2] [1 1]} {wt ht [c2 2] [2.6 1]} {wt ht [3.5 2] [1 1]}...
{wt ht [c1 3] [1 1]} {wt ht [c2 3] [3.5 1]}...
{wt ht [c1 4.5] [1 1]} {wt ht [c2 4.5] [1 1]} ...
{wt ht [c1 5.5] [1 1]} {wt ht [c2 5.5] [3.5 1]} ...
};
result = inputgui('title', guititle, 'geom', geom, 'uilist',uilist, 'eval', 'set(gcf,''tag'', ''pop_relicagui'')', 'helpcom','pophelp(''pop_relica'');');
if length(result) == 0 return; end
errorflag = 0;
algo = icaalgorithm{result{1}};
mode_relica = moderelicaval{result{2}};
if ~isempty(result{3}), M = str2num(result{3}); else, errorflag=1; end
if ~isempty(result{4}) && exist(result{4},'dir'), folder_relica = result{4}; else, errorflag=1; end
% NSG options
compflag = fastif(result{6}, 'nsg', 'local');
args = {};
if result{6}
tmpoptparams = eval(['{' result{7} '}']);
if ~isempty(tmpoptparams)
count = 1;
for i =1:length(tmpoptparams)/2
args = { args{:}, tmpoptparams{count}, tmpoptparams{count+1}};
count = count + 2;
end
end
end
% RELICA options
tmpoptparams = eval(['{' result{5} '}']);
if ~isempty(tmpoptparams)
count = 1;
for i =1:length(tmpoptparams)/2
if ~ismember( tmpoptparams{count},{'jobid' 'runtime' 'nnodes'})
args = { args{:}, tmpoptparams{count}, tmpoptparams{count+1}};
count = count + 2;
else
errordlg2(['Invalid NSG option provided.' char(10) 'Only RELICA options are accepted in ''RELICA options''']);
error(['Invalid NSG option provided.' char(10) 'Only RELICA options are accepted in ''RELICA otpions''']);
end
end
end
if size(EEG.data,3)>1; mode_relica = 'point';end
else % no interactive inputs
args = varargin;
end
EEGout = relica(EEG,M,algo,mode_relica,folder_relica, compflag, args{:});
else
if ~ nsginstalled_flag
error('Plugin nsgportal needs to be in the MATLAB path');
end
EEGout = relica(EEG);
end
% Command history output
if isstruct(EEG)
if ~isempty(args)
if ~iscell(args{2})
tmparg = ['''' args{1} ''',' num2str(args{2})];
else
argcell = ['{''' args{2}{1} ''''];
for i=2:length(args{2})
argcell = [argcell ',' num2str(args{2}{i}) ];
end
argcell=[argcell '}'];
tmparg = ['''' args{1} ''',' argcell];
end
count = 3;
for iarg = 1: length(args)/2-1
if ~iscell(args{count+1})
tmparg = [tmparg ',''' args{count} ''',' num2str(args{count+1})];
else
opttext = '{';
for i = 1:length(args{count+1})
if isstr(args{count+1}{i})
opttext = [opttext '''' args{count+1}{i} ''''];
elseif isnumeric(args{count+1}{i})
opttext = [opttext ' ' num2str(args{count+1}{i})];
elseif islogical(args{count+1}{i})
opttext = [opttext ' ' num2str(args{count+1}{i})];
end
end
opttext = [opttext '}'];
tmparg = [tmparg ',''' args{count} ''',' opttext];
end
count = count + 2;
end
com = ['EEG = pop_relica(EEG, ' num2str(M) ', ''' algo ''', ''' mode_relica ''', ''' folder_relica ''', ''' compflag ''',' tmparg ');' ];
else
com = ['EEG = pop_relica(EEG, ' num2str(M) ', ''' algo ''', ''' mode_relica ''', ''' folder_relica ''', ''' compflag ''');' ];
end
else
com = 'EEG = pop_relica(EEG)';
end
EEGout = eegh(com, EEGout);
disp('Done.')
end