H_STSW_automatic_artifact_correction_180123.m 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278
  1. function H_STSW_automatic_artifact_correction_180123(id)
  2. %% H_SS_automatic_artifact_correction_20170922
  3. %% initialize
  4. %restoredefaultpath;
  5. %clear all; close all; pack; clc;
  6. %% pathdef
  7. if ismac
  8. % pn.study = '/Volumes/LNDG/Projects/StateSwitch/';
  9. % pn.eeg_root = [pn.study, 'dynamic/data/eeg/task/A_preproc/SA_preproc_study_YA/'];
  10. pn.eeg_root = '/Users/kosciessa/Desktop/mountpoint_tardis_LNDG/LNDG/StateSwitch/WIP_eeg/SA_preproc_study_YA/';
  11. pn.dynamic_In = [pn.eeg_root, 'B_data/B_EEG_ET_ByRun/'];
  12. pn.triggerTiming= [pn.eeg_root, 'C_figures/D_TriggerTiming/'];
  13. pn.EEG = [pn.eeg_root, 'B_data/C_EEG_FT/']; mkdir(pn.EEG);
  14. pn.History = [pn.eeg_root, 'B_data/D_History/']; mkdir(pn.History);
  15. pn.logs = [pn.eeg_root, 'Y_logs/H_ArtCorr/'];
  16. % add ConMemEEG tools
  17. pn.MWBtools = [pn.eeg_root, 'T_tools/fnct_MWB/']; addpath(genpath(pn.MWBtools));
  18. pn.THGtools = [pn.eeg_root, 'T_tools/fnct_THG/']; addpath(genpath(pn.THGtools));
  19. pn.commontools = [pn.eeg_root, 'T_tools/fnct_common/']; addpath(genpath(pn.commontools));
  20. pn.fnct_JQK = [pn.eeg_root, 'T_tools/fnct_JQK/']; addpath(genpath(pn.fnct_JQK));
  21. pn.FT = [pn.eeg_root, 'T_tools/fieldtrip-20170904/']; addpath(pn.FT); ft_defaults;
  22. pn.helper = [pn.eeg_root, 'A_scripts/helper/']; addpath(pn.helper);
  23. else
  24. pn.root = '/home/mpib/LNDG/StateSwitch/WIP_eeg/SA_preproc_study_YA/';
  25. pn.EEG = [pn.root, 'B_data/C_EEG_FT/'];
  26. pn.History = [pn.root, 'B_data/D_History/'];
  27. pn.triggerTiming= [pn.root, 'C_figures/D_TriggerTiming/'];
  28. pn.logs = [pn.root, 'Y_logs/H_ArtCorr/'];
  29. end
  30. %% define Condition & IDs for preprocessing
  31. condEEG = 'dynamic';
  32. %% define IDs for segmentation
  33. % N = 47;
  34. IDs = {'1117';'1118';'1120';'1124';'1126';'1131';'1132';'1135';'1136';'1138';'1144';'1151';'1158';'1160';'1163';'1164';'1167';'1169';'1172';'1173';'1178';'1182';'1215';'1216';'1219';'1221';'1223';'1227';'1228';'1233';'1234';'1237';'1239';'1240';'1243';'1245';'1247';'1250';'1252';'1257';'1261';'1265';'1266';'1268';'1270';'1276';'1281'};
  35. id = str2num(id);
  36. %% loop IDs
  37. ID_unavailable = cell(length(IDs),1);
  38. %for id = 1:length(IDs)
  39. try
  40. display(['processing ID ' num2str(IDs{id})]);
  41. for iRun = 1:4
  42. % load data
  43. load([pn.EEG, IDs{id}, '_r',num2str(iRun), '_', condEEG, '_EEG_Rlm_Fhl_rdSeg'],'data_EEG');
  44. dataICA = load([pn.EEG, IDs{id}, '_', condEEG, '_EEG_Rlm_Fhl_Ica'],'data');
  45. data = data_EEG; clear data_EEG;
  46. data.elec = dataICA.data.elec;
  47. data.chanlocs = dataICA.data.chanlocs; clear dataICA;
  48. %% ------------------ ARTIFACT DETECTION - PREPARATION ----------------- %%
  49. % load config
  50. load([pn.History, IDs{id}, '_r',num2str(iRun), '_', condEEG, '_config'],'config')
  51. config.elec = data.elec;
  52. %% ICA (from weights)
  53. % ica config
  54. cfg.method = 'runica';
  55. cfg.channel = {'all','-ECG','-A2'};
  56. cfg.trials = 'all';
  57. cfg.numcomponent = 'all';
  58. cfg.demean = 'yes';
  59. cfg.runica.extended = 1;
  60. % ICA solution
  61. cfg.unmixing = config.ica1.unmixing;
  62. cfg.topolabel = config.ica1.topolabel;
  63. % components
  64. comp = ft_componentanalysis(cfg,data);
  65. % clear cfg
  66. clear cfg data
  67. %% remove components
  68. % get IC labels
  69. iclabels = config.ica1.iclabels.manual;
  70. % cfg for rejecting components (reject: blinks, eye movements,
  71. % ecg, ref); JQK: added artifacts and emg
  72. cfg.component = sortrows([iclabels.bli(:); iclabels.mov(:); iclabels.hrt(:); iclabels.ref(:); iclabels.art(:); iclabels.emg(:)])';
  73. cfg.demean = 'yes';
  74. % reject components
  75. data = ft_rejectcomponent(cfg,comp);
  76. % clear cfg
  77. clear cfg comp
  78. %% remove eye & reference channels
  79. cfg.channel = {'all','-IOR','-LHEOG','-RHEOG','-A1'};
  80. cfg.demean = 'yes';
  81. % remove channels
  82. tmpdat = ft_preprocessing(cfg,data);
  83. % clear cfg & data variable
  84. clear cfg data
  85. %% ------------------------- ARTIFACT DETECTION ------------------------ %%
  86. % open log file
  87. fid = fopen([pn.logs, 'log_' IDs{id}, '_r',num2str(iRun), '_' condEEG '_ArtCorr.txt'],'a');
  88. % write log
  89. % fprintf(fid,['********************* ' BLOCK ' *********************\n']); % Undefined function or variable 'BLOCK'. but see: %% H_prep_data_for_analysis_20141218
  90. fprintf(fid,['********************* BLOCK *********************\n']);
  91. fprintf(fid,['function: H_SS_automatic_artifact_correction_20170922.m \n\n']);
  92. fprintf(fid,['eeg file = ' config.data_file '\n\n']);
  93. n_trl = length(tmpdat.trial);
  94. %% get artifact contaminated channels by kurtosis, low & high frequency artifacts
  95. cfg.criterion = 3;
  96. cfg.recursive = 'no';
  97. [index0 parm0 zval0] = cm_MWB_channel_x_epoch_artifacts_20170922(cfg,tmpdat);
  98. % write log
  99. tmp_log = '';
  100. for j = 1:length(index0.c)
  101. tmp_log = [tmp_log num2str(index0.c(j)) ' '];
  102. end; clear j
  103. tmp_log = [tmp_log(1:end-1) '\n'];
  104. fprintf(fid,'(1) automatic bad channel detection:\n');
  105. fprintf(fid,['MWB: channel(s) ' tmp_log]);
  106. % clear cfg
  107. clear cfg tmp_log
  108. %% get artifact contaminated channels by FASTER
  109. cfg.criterion = 3;
  110. cfg.recursive = 'no';
  111. [index1 parm1 zval1] = THG_FASTER_1_channel_artifacts_20140302(cfg,tmpdat);
  112. % write log
  113. tmp_log = '';
  114. for j = 1:length(index1)
  115. tmp_log = [tmp_log num2str(index1(j)) ' '];
  116. end; clear j
  117. tmp_log = [tmp_log(1:end-1) '\n'];
  118. fprintf(fid,['FASTER: channel(s) ' tmp_log]);
  119. % clear cfg
  120. clear cfg tmp_log
  121. %% interpolate artifact contaminated channels
  122. % collect bad channels
  123. badchan = unique([index0.c; index1]);
  124. fprintf(fid,['--> ' num2str(length(badchan)) ' channels interpolated\n\n']);
  125. cfg.method = 'spline';
  126. cfg.badchannel = tmpdat.label(badchan);
  127. cfg.trials = 'all';
  128. cfg.lambda = 1e-5;
  129. cfg.order = 4;
  130. cfg.elec = config.elec;
  131. % interpolate
  132. tmpdat = ft_channelrepair(cfg,tmpdat);
  133. % clear cfg
  134. clear cfg
  135. %% equalize duration of trials to the trial with fewest samples
  136. for indTrial = 1:64
  137. TrialLength(indTrial) = size(tmpdat.trial{indTrial},2);
  138. end
  139. [val, idx] = min(TrialLength);
  140. for indTrial = 1:64
  141. tmpdat.trial{indTrial} = tmpdat.trial{indTrial}(:,1:val);
  142. tmpdat.time{indTrial} = tmpdat.time{idx};
  143. end
  144. %% get artifact contaminated epochs & exclude epochs
  145. % includes: - THG_MWB_channel_x_epoch_artifacts_20140311
  146. % - THG_FASTER_2_epoch_artifacts_20140302
  147. % recursive epoch exclusion!
  148. [tmpdat index] = THG_automatic_artifact_correction_trials_20170922(tmpdat);
  149. % write log
  150. fprintf(fid,'(2) automatic recursive bad epoch detection:\n');
  151. fprintf(fid,['MWB & FASTER: ' num2str(n_trl-length(index)) ' bad epoch(s) detected\n\n']);
  152. %% get channel x epoch artifacts
  153. % cfg
  154. cfg.criterion = 3;
  155. cfg.recursive = 'yes';
  156. [index3 parm3 zval3] = THG_FASTER_4_channel_x_epoch_artifacts_20140302(cfg,tmpdat);
  157. % write log
  158. fprintf(fid,'(3) automatic single epoch/channel detection:\n');
  159. fprintf(fid,['FASTER: ' num2str(sum(sum(index3))) ' channel(s) x trial(s) detected\n\n']);
  160. % clear cfg
  161. clear cfg
  162. %% collect and save detected artifacts & artifact correction infos
  163. % include ArtDect.parameters
  164. % bad channels
  165. ArtDect.channels = badchan;
  166. % bad trials
  167. tmp = zeros(n_trl,1); tmp(index,1) = 1;
  168. badtrl = find(tmp==0);
  169. ArtDect.trials = badtrl;
  170. clear tmp
  171. % bad single epoch(s)/channel(s) - after exclusion of bad epochs
  172. ArtDect.channels_x_trials = index3;
  173. % overview
  174. ind = [1:n_trl];
  175. ind(badtrl) = [];
  176. tmp = ones(length(tmpdat.label),n_trl);
  177. tmp(:,ind) = index3;
  178. tmp(badchan,:) = 1;
  179. ArtDect.channels_x_trials_all = tmp;
  180. clear tmp
  181. % save version
  182. ArtDect.version = 'JQK 20180123';
  183. % add to config
  184. config.ArtDect = ArtDect;
  185. % save config
  186. save([pn.History, IDs{id}, '_r',num2str(iRun), '_', condEEG, '_config'],'config')
  187. %% finalize log
  188. % log
  189. fprintf(fid,'Artifact detection completed.\n');
  190. fprintf(fid,['Information saved to: ' IDs{id} '_config.mat\n\n']);
  191. fclose(fid);
  192. end % run
  193. catch ME
  194. warning('Error occured. Please check.');
  195. rethrow(ME)
  196. fprintf('\n ID not availble! Skip! \n')
  197. ID_unavailable{id,1} = (IDs{id});
  198. end
  199. %end; clear id
  200. end