-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathICL_feature_extractor_par.m
113 lines (98 loc) · 3.17 KB
/
ICL_feature_extractor_par.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
% extract features for the ICLabel Classifier
% if there are any issues, report them to [email protected]
function features = ICL_feature_extractor_par(EEG, flag_autocorr)
%% check inputs
if ~exist('flag_autocorr', 'var') || isempty(flag_autocorr)
flag_autocorr = false;
end
ncomp = size(EEG.icawinv, 2);
% check for ica
assert(isfield(EEG, 'icawinv'), 'You must have an ICA decomposition to use ICLabel')
% assuming chanlocs are correct
if ~strcmp(EEG.ref, 'averef')
[~, EEG] = evalc('pop_reref(EEG, [], ''exclude'', setdiff(1:EEG.nbchan, EEG.icachansind));');
end
% calculate ica activations if missing and cast to double
if isempty(EEG.icaact)
EEG.icaact = eeg_getica(EEG);
end
EEG.icaact = double(EEG.icaact);
% check ica is real
assert(isreal(EEG.icaact), 'Your ICA decomposition must be real to use ICLabel')
%% calc topo
topo = zeros(32, 32, 1, ncomp);
%haspar = [];
%haspar = ver('parallel');
%
% if ~isempty(haspar)
% parfor it = 1:ncomp
% if ~exist('OCTAVE_VERSION', 'builtin')
% [~, temp_topo, plotrad] = ...
% topoplotFast(EEG.icawinv(:, it), EEG.chanlocs(EEG.icachansind), ...
% 'noplot', 'on');
% else
% [~, temp_topo, plotrad] = ...
% topoplot(EEG.icawinv(:, it), EEG.chanlocs(EEG.icachansind), ...
% 'noplot', 'on', 'gridscale', 32);
% end
% temp_topo(isnan(temp_topo)) = 0;
% topo(:, :, 1, it) = temp_topo / max(abs(temp_topo(:)));
% end
% else
for it = 1:ncomp
if ~exist('OCTAVE_VERSION', 'builtin')
[~, temp_topo, plotrad] = ...
topoplotFast(EEG.icawinv(:, it), EEG.chanlocs(EEG.icachansind), ...
'noplot', 'on');
else
[~, temp_topo, plotrad] = ...
topoplot(EEG.icawinv(:, it), EEG.chanlocs(EEG.icachansind), ...
'noplot', 'on', 'gridscale', 32);
end
temp_topo(isnan(temp_topo)) = 0;
topo(:, :, 1, it) = temp_topo / max(abs(temp_topo(:)));
end
%end
% cast
topo = single(topo);
%% calc psd
psd = eeg_rpsd(EEG, 100);
% extrapolate or prune as needed
nfreq = size(psd, 2);
if nfreq < 100
psd = [psd, repmat(psd(:, end), 1, 100 - nfreq)];
end
% undo notch filter
for linenoise_ind = [50, 60]
linenoise_around = [linenoise_ind - 1, linenoise_ind + 1];
difference = bsxfun(@minus, psd(:, linenoise_around), ...
psd(:, linenoise_ind));
notch_ind = all(difference > 5, 2);
if any(notch_ind)
psd(notch_ind, linenoise_ind) = mean(psd(notch_ind, linenoise_around), 2);
end
end
% normalize
psd = bsxfun(@rdivide, psd, max(abs(psd), [], 2));
% reshape and cast
psd = single(permute(psd, [3 2 4 1]));
%% calc autocorrelation?
if flag_autocorr
if EEG.trials == 1
if EEG.pnts / EEG.srate > 5
autocorr = eeg_autocorr_welch(EEG);
else
autocorr = eeg_autocorr(EEG);
end
else
autocorr = eeg_autocorr_fftw(EEG);
end
% reshape and cast
autocorr = single(permute(autocorr, [3 2 4 1]));
end
%% format outputs
if flag_autocorr
features = {0.99 * topo, 0.99 * psd, 0.99 * autocorr};
else
features = {0.99 * topo, 0.99 * psd};
end