ICL_feature_extration_full.m 9.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291
  1. function [featuresmat, feature_label] = ICL_feature_extration_full(EEG, study_ID, dataset_ID)
  2. if ~exist('study_ID', 'var') || isempty(study_ID)
  3. study_ID = nan;
  4. end
  5. if ~exist('dataset_ID', 'var') || isempty(dataset_ID)
  6. dataset_ID = nan;
  7. end
  8. % =========================================================================
  9. % EEG stuff
  10. % =========================================================================
  11. % % for testing only
  12. % lower2 = 2;
  13. % EEG = pop_subcomp(EEG, setdiff(1:size(EEG.icaweights,1), ...
  14. % randperm(size(EEG.icaweights,1), min(lower2,size(EEG.icaweights,1)))),0);
  15. assert(~isempty(EEG.icawinv), ...
  16. 'No ica weights in the current EEG dataset! Compute ICA on your data first.')
  17. n_ic= size(EEG.icawinv,2); % ncps is number of components
  18. % =========================================================================
  19. % Convert to average reference
  20. % =========================================================================
  21. pop_reref(EEG,[],'exclude',setdiff(1:EEG.nbchan,EEG.icachansind));
  22. % calculate ica activations if missing
  23. if isempty(EEG.icaact)
  24. EEG.icaact = eeg_getdatact(EEG,'component',1:n_ic);
  25. end
  26. % =========================================================================
  27. % Computing dipole
  28. % =========================================================================
  29. % 1 dipole
  30. if isfield(EEG, 'dipfit') && ~isempty(EEG.dipfit) ...
  31. && isfield(EEG.dipfit, 'model') && ~isempty(EEG.dipfit.model) ...
  32. && length(EEG.dipfit.model) == n_ic
  33. % reuse existing dipoles
  34. ind2dp = cellfun(@(c) size(c, 1), {EEG.dipfit.model.posxyz}) == 2;
  35. % 2 dipole
  36. EEG.dipfit2 = getfield(pop_multifit( ...
  37. EEG, find(~ind2dp), 'threshold', 100, 'dipoles', 2), 'dipfit');
  38. % 1 dipole
  39. for it = find(ind2dp)
  40. EEG.dipfit.model(it).posxyz(2, :) = [];
  41. EEG.dipfit.model(it).momxyz(2, :) = [];
  42. end
  43. EEG = pop_multifit(EEG, find(ind2dp), 'threshold', 100, 'dipoles', 1);
  44. else
  45. % recompute all
  46. try
  47. EEG = pop_multifit(EEG,[],'threshold',100);
  48. catch
  49. EEG = pop_dipfit_settings(EEG);
  50. EEG = pop_multifit(EEG,[],'threshold',100);
  51. end
  52. % 2 dipole
  53. EEG.dipfit2 = getfield(pop_multifit( ...
  54. EEG,[],'threshold',100,'dipoles',2),'dipfit');
  55. end
  56. % =========================================================================
  57. % Creating structure for sasica
  58. % =========================================================================
  59. optvals = struct('FASTER_blinkchans', '',...
  60. 'chancorr_channames', '',...
  61. 'chancorr_corthresh', 0.6,...
  62. 'EOGcorr_Heogchannames', [] ,...
  63. 'EOGcorr_corthreshH', 'auto', ...
  64. 'EOGcorr_Veogchannames', '',...
  65. 'EOGcorr_corthreshV', 'auto',...
  66. 'resvar_thresh', 15,...
  67. 'SNR_snrcut', 1,...
  68. 'SNR_snrBL', [-Inf,0],...
  69. 'SNR_snrPOI', [0 Inf],...
  70. 'trialfoc_focaltrialout', 'auto',...
  71. 'focalcomp_focalICAout', 'auto',...
  72. 'autocorr_autocorrint', 20,...
  73. 'autocorr_dropautocorr', 'auto');
  74. % Enable/disable fields
  75. fenable = struct('MARA_enable', 0,...
  76. 'FASTER_enable', 1,...
  77. 'ADJUST_enable', 1,...
  78. 'chancorr_enable', 1,...
  79. 'EOGcorr_enable', 0,...
  80. 'resvar_enable', 0,... % !!! changed!
  81. 'SNR_enable', 1,...
  82. 'trialfoc_enable', 0,...
  83. 'focalcomp_enable', 1,...
  84. 'autocorr_enable', 1);
  85. fields = regexp(fieldnames(fenable),'[^_]*','match')';
  86. for i_f = 1:length(fields)
  87. instr.(fields{i_f}{1}).(fields{i_f}{2}) = ...
  88. fenable.([fields{i_f}{1} '_' fields{i_f}{2}]);
  89. end
  90. fields2 = regexp(fieldnames(optvals),'[^_]*','match')';
  91. for i_f = 1:numel(fields2)
  92. if ~isempty(strfind(fields2{i_f}{2},'channame'))
  93. if ischar(optvals.([fields2{i_f}{1} '_' fields2{i_f}{2}]))
  94. instr.(fields2{i_f}{1}).(fields2{i_f}{2}) = ...
  95. eval(['[chnb(''' optvals.([fields2{i_f}{1} '_' fields2{i_f}{2}]) ''')]']);
  96. else
  97. instr.(fields2{i_f}{1}).(fields2{i_f}{2}) = ...
  98. eval(['[chnb([' optvals.([fields2{i_f}{1} '_' fields2{i_f}{2}]) '])]']);
  99. end
  100. else
  101. try
  102. instr.(fields2{i_f}{1}).(fields2{i_f}{2}) = ...
  103. eval(['[' optvals.([fields2{i_f}{1} '_' fields2{i_f}{2}]) ']']);
  104. catch
  105. instr.(fields2{i_f}{1}).(fields2{i_f}{2}) = ...
  106. optvals.([fields2{i_f}{1} '_' fields2{i_f}{2}]) ;
  107. end
  108. end
  109. end
  110. instr.opts.noplot = 1;
  111. % =========================================================================
  112. % Running sasica
  113. % =========================================================================
  114. [EEG] = myeeg_SASICA(EEG,instr);
  115. disp 'leaving sasica'
  116. % =========================================================================
  117. % Generating topos
  118. % =========================================================================
  119. topo = zeros(n_ic,740);
  120. plotrad = zeros(n_ic,1);
  121. disp 'saving topomap'
  122. for i = 1:n_ic
  123. scalpmap_norm = EEG.icawinv(:,i)/sqrt(sum(EEG.icawinv(:,i).^2));
  124. [~,Zi,plotrad(i)] = topoplotFast( scalpmap_norm, EEG.chanlocs, 'chaninfo', EEG.chaninfo, ...
  125. 'shading', 'interp', 'numcontour', 3,'electrodes','on','noplot','on');
  126. topo(i,:) = Zi(~isnan(Zi));
  127. end
  128. disp 'finished saving topomap'
  129. EEG.reject.SASICA.topo = topo;
  130. EEG.reject.SASICA.plotrad = plotrad;
  131. % =========================================================================
  132. % Generating psds
  133. % =========================================================================
  134. [EEG.reject.SASICA.spec, EEG.reject.SASICA.specvar, ...
  135. EEG.reject.SASICA.speckrt] = eeg_rpsd(EEG, 100);
  136. % =========================================================================
  137. % Generating autocorrs
  138. % =========================================================================
  139. if EEG.trials == 1
  140. if EEG.pnts / EEG.srate > 5
  141. EEG.reject.SASICA.autocorr = eeg_autocorr_welch(EEG);
  142. else
  143. EEG.reject.SASICA.autocorr = eeg_autocorr(EEG);
  144. end
  145. else
  146. EEG.reject.SASICA.autocorr = eeg_autocorr_fftw(EEG);
  147. end
  148. % =========================================================================
  149. % Generate and save feature vectors
  150. % =========================================================================
  151. [~, feature_labels] = genfvect;
  152. featuresmat = nan(n_ic,length(feature_labels));
  153. disp 'saving features'
  154. for i = 1:n_ic
  155. [featuresmat(i,:), feature_label] = genfvect(EEG,study_ID,dataset_ID,i);
  156. end
  157. % =========================================================================
  158. % =========================================================================
  159. % =========================================================================
  160. function [nb,channame,strnames] = chnb(channame, varargin)
  161. % chnb() - return channel number corresponding to channel names in an EEG
  162. % structure
  163. %
  164. % Usage:
  165. % >> [nb] = chnb(channameornb);
  166. % >> [nb,names] = chnb(channameornb,...);
  167. % >> [nb,names,strnames] = chnb(channameornb,...);
  168. % >> [nb] = chnb(channameornb, labels);
  169. %
  170. % Input:
  171. % channameornb - If a string or cell array of strings, it is assumed to
  172. % be (part of) the name of channels to search. Either a
  173. % string with space separated channel names, or a cell
  174. % array of strings.
  175. % Note that regular expressions can be used to match
  176. % several channels. See regexp.
  177. % If only one channame pattern is given and the string
  178. % 'inv' is attached to it, the channels NOT matching the
  179. % pattern are returned.
  180. % labels - Channel names as found in {EEG.chanlocs.labels}.
  181. %
  182. % Output:
  183. % nb - Channel numbers in labels, or in the EEG structure
  184. % found in the caller workspace (i.e. where the function
  185. % is called from) or in the base workspace, if no EEG
  186. % structure exists in the caller workspace.
  187. % names - Channel names, cell array of strings.
  188. % strnames - Channel names, one line character array.
  189. narginchk(1, 2);
  190. if nargin == 2
  191. labels = varargin{1};
  192. else
  193. try
  194. EEG = evalin('caller','EEG');
  195. catch
  196. try
  197. EEG = evalin('base','EEG');
  198. catch
  199. error('Could not find EEG structure');
  200. end
  201. end
  202. if not(isfield(EEG,'chanlocs'))
  203. error('No channel list found');
  204. end
  205. EEG = EEG(1);
  206. labels = {EEG.chanlocs.labels};
  207. end
  208. if iscell(channame) || ischar(channame)
  209. if ischar(channame) || iscellstr(channame)
  210. if iscellstr(channame) && numel(channame) == 1 && isempty(channame{1})
  211. channame = '';
  212. end
  213. tmp = regexp(channame,'(\S*) ?','tokens');
  214. channame = {};
  215. for i = 1:numel(tmp)
  216. if iscellstr(tmp{i}{1})
  217. channame{i} = tmp{i}{1}{1};
  218. else
  219. channame{i} = tmp{i}{1};
  220. end
  221. end
  222. if isempty(channame)
  223. nb = [];
  224. return
  225. end
  226. end
  227. if numel(channame) == 1 && not(isempty(strmatch('inv',channame{1})))
  228. cmd = 'exactinv';
  229. channame{1} = strrep(channame{1},'inv','');
  230. else
  231. channame{1} = channame{1};
  232. cmd = 'exact';
  233. end
  234. nb = regexpcell(labels,channame,[cmd 'ignorecase']);
  235. elseif isnumeric(channame)
  236. nb = channame;
  237. if nb > numel(labels)
  238. nb = [];
  239. end
  240. end
  241. channame = labels(nb);
  242. strnames = sprintf('%s ',channame{:});
  243. if not(isempty(strnames))
  244. strnames(end) = [];
  245. end