OSCR

Hierarchical brain dynamics supporting visual perceptual transitions.

Code ↔ Paper

19 matches between paragraphs of the paper and lines of its authors' code, computed by the harvester (lexical-v1). Click a colored paragraph or line to see its counterpart.

The 19 matches · 7 of them tie a paragraph to a whole file, not to given lines: weak matches, whose lines are not tinted
  1. [1] § MATERIALS AND METHODS › Regions of interest ↔ brainstorm_analysis.zip/UI_prep_motorcortex.m, the whole file · a weak match · score 0.93 · precentral gyrus, 1–80 Hz, 30–50 ms, right hemisphere, band pass, 30 ms
  2. [2] § RESULTS › Task and behavior ↔ behavior.zip/analyze_group_data.m, the whole file · a weak match · score 0.84 · Wilcoxon signed rank, replay FTs, Replay trials, illusion trial, report filling, S1
  3. [3] § MATERIALS AND METHODS › Data acquisition ↔ paradigm.zip/UI_master.m, lines 2–129 · score 0.79 · eye tracker, eyeLink, eye tracking, fixation point, Post, restarts
  4. [4] § MATERIALS AND METHODS › MEG preprocessing ↔ brainstorm_analysis.zip/UI_preproc.m, lines 409–449 · score 0.79 · 0.05–200 Hz, notch filtered, band pass, attenuated, preprocessing, ECG
  5. [5] § MATERIALS AND METHODS › Whole-brain analysis of high-alpha activity ↔ brainstorm_analysis.zip/UI_source_timefreq.m, lines 455–507 · score 0.77 · 0.5–0.75 s, 10–15 Hz, Hilbert transformed, high alpha, brain, 0.5 s
  6. [6] § MATERIALS AND METHODS › Stimuli and behavioral tasks ↔ paradigm.zip/UI_master.m, lines 2–129 · score 0.72 · DKL azimuth, isoluminant, radius, calibrations, physical, RGB
  7. [7] § MATERIALS AND METHODS › Stimuli and behavioral tasks ↔ paradigm.zip/UI_openScreen.m, the whole file · a weak match · score 0.69 · ProPixx, visual angle, gamma, calibrations, smoothly, RGB
  8. [8] § MATERIALS AND METHODS › Data acquisition ↔ brainstorm_analysis.zip/UI_import_anat.m, the whole file · a weak match · score 0.66 · fiducial points, FreeSurfer, warp, MRI, Brainstorm, surfaces
  9. [9] § MATERIALS AND METHODS › Phase-locking of cortical time series with photodiode or template sinusoid signals ↔ brainstorm_edited_code.zip/bst_connectivity_MGL.m, lines 850–930 · score 0.64 · Hilbert transform, band pass, frequency band, fc, phase, cross
  10. [10] § MATERIALS AND METHODS › RIFT presentation ↔ paradigm.zip/UI_openScreen.m, the whole file · a weak match · score 0.62 · ProPixx, double, gamma, quadrants, RGB, frame
  11. [11] § MATERIALS AND METHODS › Statistical analysis ↔ brainstorm_analysis.zip/UI_source_timefreq.m, lines 455–507 · score 0.59 · spatial smoothing, mm, FWHM, template, brain, maps
  12. [12] § MATERIALS AND METHODS › Statistical analysis ↔ statistics.zip/timeseries_permutation_zero.m, lines 18–60 · score 0.59 · cluster defining threshold, zero, ROI, PLVt, permutation, epoch
  13. [13] § MATERIALS AND METHODS › Microsaccade detection ↔ eye_analysis.zip/UI_extractMicrosaccades.m, lines 173–243 · score 0.57 · eye movements, arc, velocity, min, angle, binocular
  14. [14] § RESULTS › Microsaccades restore both visual inhibition and motor high-alpha activity ↔ statistics.zip/timeseries_permutation_zero.m, lines 135–236 · score 0.56 · Aperiodic exponent, Aperiodic corrected, baseline corrected, uncorrected, permutation, offset
  15. [15] § MATERIALS AND METHODS › Regions of interest ↔ brainstorm_analysis.zip/UI_ret_analysis.m, lines 12–153 · score 0.55 · phase locking, FWHM, kernel, occipital, smoothed, PLV
  16. [16] § RESULTS › Excitation-inhibition balance in visual cortex before filling-in ↔ statistics.zip/timeseries_permutation_zero.m, lines 135–236 · score 0.55 · Aperiodic exponent, Aperiodic corrected, baseline period, permutation, offset, cluster
  17. [17] § RESULTS › Task and behavior ↔ behavior.zip/analyze_group_data.m, the whole file · a weak match · score 0.54 · Wilcoxon signed rank, Replay trials, FT, illusion, uniform, behavior
  18. [18] § MATERIALS AND METHODS › Phase-locking of cortical time series with photodiode or template sinusoid signals ↔ brainstorm_analysis.zip/UI_source_timefreq.m, lines 928–1032 · score 0.54 · Hilbert transform, sinusoids, intermodulation, magnitude, PLVt, phase
  19. [19] § MATERIALS AND METHODS › RIFT presentation ↔ paradigm.zip/generateAlphaSinusoids.m, the whole file · a weak match · score 0.54 · sinusoidal luminance, perceived, fp, fc, frame, modulations

Paper

Loaded from Europe PMC by your browser, not stored by OSCR: doi.org · Europe PMC

The paper is loaded when this pane is shown.

The authors' code

MATLAB · 1,417 lines · 99 KB · CC-BY-4.0 · 3 matches

  1. clear
  2. SubjectNames = string([301:321 323:330]); % all
  3. %SubjectNames = string([301:321 323 326 328 329]); % all that have mris
  4. %SubjectNames = string(301);
  5. %SubjectNames = string([328:330]);
  6. nSubjects = numel(SubjectNames);
  7. opts = UI_load_params(3);
  8. runwholebrainhighalpha = 1; % whole brain high alpha activity, taken from motor cortex result, avg'd in one time window
  9. runplvt = 1;
  10. runfiplvt = 1; % PLVt at intermodulation, 8 Hz and 16 Hz
  11. runsprintcustom = 1; sprint_winlength = 1; sprint_winstep = 0.1; sprint_maxFreq = 50; % SPRiNT but for each moving window, average PSD across trials before computing FOOOF. Then recombine to form the SPRiNT timeseries.
  12. runpsds = 1; % initial psds for visualization?
  13. combinecontrasts = 1; % usually 1, just means we run the normal analyses combined across both contrasts
  14. splitcontrasts = 0;
  15. powerscoutfunc = 1; % 1 = mean, 3 = PCA
  16. first_run = 1; % if 1, also run some initial things
  17. runret = 0; % analyze ret microsaccades
  18. bl_method = 'ersd'; % zscore, ersd, or bl - what baseline-correction method to use
  19. % rl_rowidx: each element contains the two scouts that are R L of the same
  20. all_atlases(1).name = 'motor'; all_atlases(1).rl_rownames = {'RL_motor'}; all_atlases(1).scouts2use = {'R_motor_cortex', 'L_motor_cortex'}; all_atlases(1).rl_rowidx = {'1, 2'}; all_atlases(1).label = 'motor';
  21. all_atlases(2).name = 'localizer'; all_atlases(2).rl_rownames = {'periphery', 'center'}; all_atlases(2).scouts2use = {'R_periphery', 'R_center', 'L_periphery', 'L_center'}; all_atlases(2).rl_rowidx = {'1, 3', '2, 4'}; all_atlases(2).label = 'flicker';
  22. for iAtlas = 1:numel(all_atlases)
  23. all_atlases(iAtlas).rl_label = ['RL_', all_atlases(iAtlas).label];
  24. end
  25. mergerl = [0 1]; % motor is not merged across hemispheres; localizer is.
  26. use_atlases = 1; % just motor
  27. %use_atlases = 2; % just flicker
  28. %use_atlases = [1 2]; % both
  29. % set processing options for each epoch type
  30. epoch_types = {'stimon', 'button', 'button_noms', 'ms_instim', 'ms_infix'};
  31. % Have to run retinotopy part first (UI_ret_analysis), then manually define scouts,
  32. % then run this script.
  33. for iSubj = 1:nSubjects
  34. sname = ['s', char(SubjectNames(iSubj))];
  35. % Start a new report
  36. bst_report('Start');
  37. % get 8 Hz file
  38. f8Files = bst_process('CallProcess', 'process_select_files_matrix', [], [], ...
  39. 'subjectname', sname, ...
  40. 'condition', 'sin_8Hz', ...
  41. 'tag', [], ...
  42. 'includebad', 0, ...
  43. 'includeintra', 0, ...
  44. 'includecommon', 0);
  45. % get 16 Hz file
  46. f16Files = bst_process('CallProcess', 'process_select_files_matrix', [], [], ...
  47. 'subjectname', sname, ...
  48. 'condition', 'sin_16Hz', ...
  49. 'tag', [], ...
  50. 'includebad', 0, ...
  51. 'includeintra', 0, ...
  52. 'includecommon', 0);
  53. f11Files = bst_process('CallProcess', 'process_select_files_matrix', [], [], ...
  54. 'subjectname', sname, ...
  55. 'condition', 'sin_11Hz', ...
  56. 'tag', [], ...
  57. 'includebad', 0, ...
  58. 'includeintra', 0, ...
  59. 'includecommon', 0);
  60. % get 60 Hz file
  61. f60Files = bst_process('CallProcess', 'process_select_files_matrix', [], [], ...
  62. 'subjectname', sname, ...
  63. 'condition', 'sin_60Hz', ...
  64. 'tag', [], ...
  65. 'includebad', 0, ...
  66. 'includeintra', 0, ...
  67. 'includecommon', 0);
  68. %% retinotopy microsaccades within scouts
  69. if runret
  70. % Process: Select data files in: SUBJ
  71. retFiles = bst_process('CallProcess', 'process_select_files_results', [], [], ...
  72. 'subjectname', sname, ...
  73. 'condition', ['ret_sss_notch_band'], ...
  74. 'tag', [], ...
  75. 'includebad', 0, ...
  76. 'includeintra', 0, ...
  77. 'includecommon', 0);
  78. % Process: Ignore file names with tag: Avg
  79. retFiles = bst_process('CallProcess', 'process_select_tag', retFiles, [], ...
  80. 'tag', 'average', ...
  81. 'search', 1, ... % Search the file paths
  82. 'select', 2); % Ignore the files with the tag
  83. for iEpoch_type = 1:numel(epoch_types)
  84. epochname = epoch_types{iEpoch_type};
  85. curr_opts = opts.epochs.(epochname);
  86. if strcmp(epochname, 'button_noms') && sum(strcmp(sname, {'s318', 's320', 's324'}))
  87. continue
  88. end
  89. epochFiles = bst_process('CallProcess', 'process_select_tag', retFiles, [], ...
  90. 'tag', curr_opts.tag, ...
  91. 'search', 3, ... % Search the parent file names
  92. 'select', 1); % Select the files with the tag
  93. % Process: Ignore file names with tag: Avg
  94. epochFiles = bst_process('CallProcess', 'process_select_tag', epochFiles, [], ...
  95. 'tag', 'Avg', ...
  96. 'search', 3, ... % Search the parent file name
  97. 'select', 2); % Ignore the files with the tag
  98. % don't take the left / right / out / in specific epochs (these are copies)
  99. ignoreTags = {'left', 'right', 'outward', 'inward', 'noms'};
  100. for iTag = 1:numel(ignoreTags)
  101. if ~contains(curr_opts.tag, ignoreTags{iTag})
  102. epochFiles = bst_process('CallProcess', 'process_select_tag', epochFiles, [], ...
  103. 'tag', ignoreTags{iTag}, ...
  104. 'search', 1, ... % Search the file paths
  105. 'select', 2); % Ignore the files with the tag
  106. epochFiles = bst_process('CallProcess', 'process_select_tag', epochFiles, [], ...
  107. 'tag', ignoreTags{iTag}, ...
  108. 'search', 3, ... % Search the parent file name
  109. 'select', 2); % Ignore the files with the tag
  110. end
  111. end
  112. if isempty(epochFiles) | numel(epochFiles) < 2
  113. continue
  114. end
  115. for iAtlas = use_atlases
  116. curr_atlas = all_atlases(iAtlas);
  117. %% scout plvt
  118. if runplvt
  119. conn_metric = 'PLVt';
  120. % PHASE LOCKING WITH PHOTODIODE
  121. % Process: Select data files
  122. sensorepochFiles = bst_process('CallProcess', 'process_select_files_data', [], [], ...
  123. 'subjectname', sname, ...
  124. 'condition', ['ret_sss_notch_band'], ...
  125. 'tag', curr_opts.tag, ...
  126. 'includebad', 0, ...
  127. 'includeintra', 0, ...
  128. 'includecommon', 0);
  129. % Process: Ignore file names with tag: bl.mat (don't use baseline-corrected)
  130. sensorepochFiles = bst_process('CallProcess', 'process_select_tag', sensorepochFiles, [], ...
  131. 'tag', 'bl.mat', ...
  132. 'search', 1, ... % Search the file paths
  133. 'select', 2); % Ignore the files with the tag
  134. % don't take the wrong epochs
  135. ignoreTags = {'noms'};
  136. for iTag = 1:numel(ignoreTags)
  137. if ~contains(curr_opts.tag, ignoreTags{iTag})
  138. sensorepochFiles = bst_process('CallProcess', 'process_select_tag', sensorepochFiles, [], ...
  139. 'tag', ignoreTags{iTag}, ...
  140. 'search', 1, ... % Search the file paths
  141. 'select', 2); % Ignore the files with the tag
  142. end
  143. end
  144. % Process: Ignore file names with tag: Avg
  145. sensorepochFiles = bst_process('CallProcess', 'process_select_tag', sensorepochFiles, [], ...
  146. 'tag', 'Avg', ...
  147. 'search', 2, ... % Search the file names
  148. 'select', 2); % Ignore the files with the tag
  149. for iDiode = 1:2
  150. diode = opts.diode_channels{iDiode};
  151. useband = opts.flicker_bands{iDiode};
  152. % PLV in localizer scouts
  153. % Process: PLV: Phase locking value
  154. connectivityScout(iDiode) = bst_process('CallProcess', 'process_plv2', sensorepochFiles, epochFiles, ...
  155. 'timewindow', curr_opts.fullwindow, ...
  156. 'src_channel', diode, ...
  157. 'dest_scouts', {curr_atlas.name, curr_atlas.scouts2use}, ...
  158. 'scoutfunc', 'mean', ... % Mean
  159. 'scouttime', 'after', ... % After
  160. 'scoutfuncaft', 'mean', ... % Mean
  161. 'tfedit', struct(...
  162. 'Comment', 'Complex', ...
  163. 'TimeBands', [], ...
  164. 'Freqs', {useband}, ...
  165. 'ClusterFuncTime', 'none', ...
  166. 'Measure', 'none', ...
  167. 'Output', 'all', ...
  168. 'SaveKernel', 0), ...
  169. 'plvmethod', 'plv', ... % PLV: Phase locking value
  170. 'tfmeasure', 'hilbert', ... % Hilbert transform
  171. 'timeres', 'full', ... % Full (requires epochs)
  172. 'plvmeasure', 2, ... % Magnitude
  173. 'outputmode', 'avg'); % Save average connectivity matrix (one file)
  174. % Process: Set name:
  175. connectivityScout(iDiode) = bst_process('CallProcess', 'process_set_comment', connectivityScout(iDiode), [], ...
  176. 'tag', ['Scouts_', curr_atlas.label, ',Avg: ', conn_metric, ': ', diode, ' ', curr_opts.label, extralabel], ...
  177. 'isindex', 0);
  178. end
  179. % Process: PLV: Phase locking value with 60 Hz sin (control)
  180. f60FilesMulti = repmat(f60Files, 1, numel(epochFiles));
  181. connectivity60Scout = bst_process('CallProcess', 'process_plv2', f60FilesMulti, epochFiles, ...
  182. 'timewindow', curr_opts.fullwindow, ...
  183. 'src_channel', '', ...
  184. 'dest_scouts', {curr_atlas.name, curr_atlas.scouts2use}, ...
  185. 'scoutfunc', 'mean', ... % Mean
  186. 'scouttime', 'after', ... % After
  187. 'scoutfuncaft', 'mean', ... % Mean
  188. 'tfedit', struct(...
  189. 'Comment', 'Complex', ...
  190. 'TimeBands', [], ...
  191. 'Freqs', {{'fcontrol', '59, 61', 'mean'}}, ...
  192. 'ClusterFuncTime', 'none', ...
  193. 'Measure', 'none', ...
  194. 'Output', 'all', ...
  195. 'SaveKernel', 0), ...
  196. 'plvmethod', 'plv', ... % PLV: Phase locking value
  197. 'tfmeasure', 'hilbert', ... % Hilbert transform
  198. 'timeres', 'full', ... % Full (requires epochs)
  199. 'plvmeasure', 2, ... % Magnitude
  200. 'outputmode', 'avg'); % Save average connectivity matrix (one file)
  201. % Process: Set name:
  202. connectivity60Scout = bst_process('CallProcess', 'process_set_comment', connectivity60Scout, [], ...
  203. 'tag', ['Scouts_', curr_atlas.label, ',Avg: ', conn_metric, ' 60 ', curr_opts.label, extralabel], ...
  204. 'isindex', 0);
  205. % combine into one file (not merging R/L yet)
  206. mat56 = in_bst_timefreq(connectivityScout(1).FileName);
  207. mat64 = in_bst_timefreq(connectivityScout(2).FileName);
  208. mat60 = in_bst_timefreq(connectivity60Scout.FileName);
  209. matall = mat56;
  210. matall.Freqs = {'fp', '55,57', 'mean'; 'fc', '63,65', 'mean'; 'fcontrol', '59, 61', 'mean'};
  211. matall.RefRowNames = {'MISC'};
  212. matall.TF(:, :, 2) = mat64.TF;
  213. matall.TF(:, :, 3) = mat60.TF;
  214. matall.Comment = ['Scouts_', curr_atlas.label, ',Avg: ', conn_metric, ' fpfc ', curr_opts.label, ' ret'];
  215. scout_allconnectivity = db_add(connectivityScout(1).iStudy, matall);
  216. % Process: Extract time
  217. scout_allconnectivityTime = bst_process('CallProcess', 'process_extract_time', scout_allconnectivity, [], ...
  218. 'timewindow', curr_opts.extracttime, ...
  219. 'overwrite', 1);
  220. % Process: Event-related perturbation (ERS/ERD)
  221. scout_allconnectivityERSD = bst_process('CallProcess', 'process_baseline_norm', scout_allconnectivityTime, [], ...
  222. 'baseline', curr_opts.baseline, ...
  223. 'method', bl_method, ... % Event-related perturbation (ERS/ERD): x_std = (x - &mu;) / &mu; * 100
  224. 'overwrite', 0);
  225. % Process: Delete selected files
  226. bst_process('CallProcess', 'process_delete', [connectivityScout, connectivity60Scout], [], ...
  227. 'target', 1); % Delete selected files
  228. % Process: combine RL hemispheres
  229. if mergerl(iAtlas)
  230. for iScout = 1:numel(curr_atlas.rl_rowidx)
  231. RL_scoutconnectivity(iScout) = bst_process('CallProcess', 'process_extract_values', scout_allconnectivityERSD, [], ...
  232. 'timewindow', [], ...
  233. 'freqrange', [0, 100], ...
  234. 'rows', curr_atlas.rl_rowidx{iScout}, ...
  235. 'isabs', 0, ...
  236. 'avgtime', 0, ...
  237. 'avgrow', 1, ...
  238. 'avgfreq', 0, ...
  239. 'matchrows', 0, ...
  240. 'dim', 2, ... % Concatenate time (dimension 2)
  241. 'Comment', ['RL_scout,Avg: ', conn_metric, ' ', curr_opts.label, ' ret']);
  242. end
  243. clear allmats
  244. allmats(1) = in_bst_timefreq(RL_scoutconnectivity(1).FileName);
  245. matall = allmats(1);
  246. matall.RowNames = curr_atlas.rl_rownames;
  247. matall.Comment = [curr_atlas.rl_label, ',Avg: ', conn_metric, ' fpfc ', curr_opts.label, ' ret'];
  248. for iScout = 2:numel(curr_atlas.rl_rowidx)
  249. allmats(iScout) = in_bst_timefreq(RL_scoutconnectivity(iScout).FileName);
  250. matall.TF(iScout, :, :) = allmats(iScout).TF;
  251. end
  252. RL_allconnectivity = db_add(RL_scoutconnectivity(1).iStudy, matall);
  253. % Process: Delete selected files
  254. bst_process('CallProcess', 'process_delete', [RL_scoutconnectivity], [], ...
  255. 'target', 1); % Delete selected files
  256. end
  257. end
  258. %% custom SPRiNT
  259. if runsprintcustom
  260. % fooofs each moving window after averaging SFFTs across
  261. % trials.
  262. % method: extract each time window, run FOOOF, then combine
  263. % outputs into a SPRiNT structure.
  264. % set windows. winlength = 1 second, but at intervals of
  265. % 100ms.
  266. % make sure we'll cover the full extracttime window, but
  267. % don't waste compute on extra windows
  268. fulltime = curr_opts.extracttime + [-sprint_winlength/2, sprint_winlength/2];
  269. winstarts = fulltime(1):sprint_winstep:fulltime(2)-sprint_winlength+.001;
  270. winends = fulltime(1)+sprint_winlength:sprint_winstep:fulltime(2);
  271. nWin = numel(winstarts);
  272. % extract time windows, FFT, average them, and FOOOF.
  273. clear winFiles
  274. for iAtlas = use_atlases
  275. curr_atlas = all_atlases(iAtlas);
  276. for iWin = 1:nWin
  277. % Process: Power spectrum density (Welch)
  278. fftWinFiles = bst_process('CallProcess', 'process_psd', epochFiles, [], ...
  279. 'timewindow', [winstarts(iWin), winends(iWin)], ...
  280. 'win_length', sprint_winlength, ...
  281. 'win_overlap', 0, ...
  282. 'units', 'physical', ... % Physical: U2/Hz
  283. 'clusters', {curr_atlas.name, curr_atlas.scouts2use}, ...
  284. 'scoutfunc', 1, ... % Mean
  285. 'win_std', 0, ...
  286. 'edit', struct(...
  287. 'Comment', 'Scout psd,Avg,Power', ...
  288. 'TimeBands', [], ...
  289. 'Freqs', [], ...
  290. 'ClusterFuncTime', 'after', ...
  291. 'Measure', 'power', ...
  292. 'Output', 'average', ...
  293. 'SaveKernel', 0));
  294. % Process: specparam: Fitting oscillations and 1/f
  295. fooofWinFiles(iWin) = bst_process('CallProcess', 'process_fooof', fftWinFiles, [], ...
  296. 'implementation', 'matlab', ... % Matlab
  297. 'freqrange', [1, sprint_maxFreq], ...
  298. 'powerline', '50', ... % 50 Hz
  299. 'peaktype', 'gaussian', ... % Gaussian
  300. 'peakwidth', [0.5, 12], ...
  301. 'maxpeaks', 3, ...
  302. 'minpeakheight', 1, ...
  303. 'proxthresh', 2, ...
  304. 'apermode', 'fixed', ... % Fixed
  305. 'guessweight', 'none', ... % None
  306. 'sorttype', 'param', ... % Peak parameters
  307. 'sortparam', 'frequency', ... % Frequency
  308. 'sortbands', {'delta', '2, 4'; 'theta', '5, 7'; 'alpha', '8, 12'; 'beta', '15, 29'; 'gamma1', '30, 59'; 'gamma2', '60, 90'});
  309. % import to MATLAB.
  310. fooofMats(iWin) = in_bst(fooofWinFiles(iWin).FileName);
  311. % delete extracted ffts
  312. bst_process('CallProcess', 'process_delete', fftWinFiles, [], ...
  313. 'target', 1); % Delete selected files
  314. clear fftWinFiles
  315. end
  316. % manually convert to a SPRiNT structure.
  317. sprintMat = fooofMats(1); % get template from first fooof file.
  318. sprintMat.Comment = ['Scouts_', curr_atlas.label, ',Avg: SPRiNT_custom ', curr_opts.label, ' ret'];
  319. sprintMat.Time = winstarts + sprint_winlength/2;
  320. sprintMat.Freqs = sprintMat.Freqs(1:sprint_maxFreq);
  321. sprintMat.Method = 'sprint';
  322. sprintMat.RowNames = sprintMat.RowNames';
  323. sprintMat.nAvg = numel(epochFiles); sprintMat.Leff = numel(epochFiles);
  324. sprintMat.TF = sprintMat.TF(:, :, 1:sprint_maxFreq); % init TF
  325. sprintMat.Options.Method = 'sprint';
  326. sprintopts = struct;
  327. sprintopts.freqs = sprintMat.Options.FOOOF.freqs;
  328. for iScout = 1:numel(sprintMat.RowNames)
  329. sprintopts.channel(iScout).name = sprintMat.RowNames{iScout};
  330. sprintopts.channel(iScout).peaks = struct('time', 'center_frequency', 'amplitude', 'st_dev');
  331. for iWin = 1:nWin
  332. sprintMat.TF(iScout, iWin, :) = fooofMats(iWin).TF(iScout, :, 1:sprint_maxFreq);
  333. fooofopts = fooofMats(iWin).Options.FOOOF;
  334. sprintopts.topography.exponent(iScout, iWin) = fooofopts.aperiodics(iScout).exponent;
  335. sprintopts.topography.offset(iScout, iWin) = fooofopts.aperiodics(iScout).offset;
  336. sprintopts.SPRiNT_models(iScout, iWin, :) = fooofopts.data(iScout).fooofed_spectrum;
  337. sprintopts.peak_models(iScout, iWin, :) = fooofopts.data(iScout).peak_fit;
  338. sprintopts.aperiodic_models(iScout, iWin, :) = fooofopts.data(iScout).ap_fit;
  339. sprintopts.channel(iScout).data(iWin).time = sprintMat.Time(iWin);
  340. sprintopts.channel(iScout).data(iWin).aperiodic_params = [sprintopts.topography.offset(iScout, iWin), sprintopts.topography.exponent(iScout, iWin)];
  341. sprintopts.channel(iScout).data(iWin).peak_params = fooofopts.data(iScout).peak_params;
  342. sprintopts.channel(iScout).data(iWin).peak_types = fooofopts.data(iScout).peak_types;
  343. sprintopts.channel(iScout).data(iWin).ap_fit = fooofopts.data(iScout).ap_fit;
  344. sprintopts.channel(iScout).data(iWin).peak_fit = fooofopts.data(iScout).peak_fit;
  345. sprintopts.channel(iScout).data(iWin).fooofed_spectrum = fooofopts.data(iScout).fooofed_spectrum;
  346. sprintopts.channel(iScout).data(iWin).power_spectrum = fooofMats(iWin).TF(iScout, :, 1:sprint_maxFreq);
  347. sprintopts.channel(iScout).data(iWin).error = fooofopts.data.error;
  348. sprintopts.channel(iScout).data(iWin).r_squared = fooofopts.data.r_squared;
  349. sprintopts.channel(iScout).aperiodics(iWin).time = sprintMat.Time(iWin);
  350. sprintopts.channel(iScout).aperiodics(iWin).offset = sprintopts.topography.offset(iScout, iWin);
  351. sprintopts.channel(iScout).aperiodics(iWin).exponent = sprintopts.topography.exponent(iScout, iWin);
  352. sprintopts.channel(iScout).stats(iWin).MSE = fooofopts.stats(iScout).MSE;
  353. sprintopts.channel(iScout).stats(iWin).r_squared = fooofopts.stats(iScout).r_squared;
  354. sprintopts.channel(iScout).stats(iWin).frequency_wise_error = fooofopts.stats(iScout).frequency_wise_error;
  355. nPeaks = 1:numel(fooofopts.peaks);
  356. for iPeak = 1:nPeaks
  357. if strcmp(fooofopts.peaks(iPeak).channel{1}, sprintMat.RowNames{iScout})
  358. sprintopts.channel(iScout).peaks(iPeak).time = sprintMat.Time(iWin);
  359. sprintopts.channel(iScout).peaks(iPeak).center_frequency = fooofopts.peaks(iPeak).center_frequency;
  360. sprintopts.channel(iScout).peaks(iPeak).amplitude = fooofopts.peaks(iPeak).amplitude;
  361. sprintopts.channel(iScout).peaks(iPeak).st_dev = fooofopts.peaks(iPeak).std_dev;
  362. end
  363. end
  364. end
  365. end
  366. sprintopts.options.winLen = sprint_winlength;
  367. sprintopts.options.Ovrlp = 0;
  368. sprintopts.options.nAverage = 1;
  369. sprintopts.options.hOT = 1; % not sure what this is
  370. sprintopts.options.rmoutliers = 'no';
  371. sprintopts.options.freq_range = fooofopts.options.freq_range;
  372. sprintopts.options.peak_width_limits = fooofopts.options.peak_width_limits;
  373. sprintopts.options.max_peaks = fooofopts.options.max_peaks;
  374. sprintopts.options.min_peak_height = fooofopts.options.min_peak_height;
  375. sprintopts.options.peak_threshold = fooofopts.options.peak_threshold;
  376. sprintopts.options.aperiodic_mode = fooofopts.options.aperiodic_mode;
  377. sprintopts.options.peak_type = fooofopts.options.peak_type;
  378. sprintopts.options.proximity_threshold = fooofopts.options.proximity_threshold;
  379. sprintopts.options.guess_weight = fooofopts.options.guess_weight;
  380. sprintMat.Options.SPRiNT = sprintopts;
  381. sprintMat.Options = rmfield(sprintMat.Options, 'FOOOF');
  382. % add to database
  383. sprintFiles = db_add(fooofWinFiles(1).iStudy, sprintMat);
  384. % delete the windowed FOOOFs
  385. bst_process('CallProcess', 'process_delete', fooofWinFiles, [], ...
  386. 'target', 1); % Delete selected files
  387. clear fooofWinFiles
  388. % Process: Extract time
  389. sprintFiles = bst_process('CallProcess', 'process_extract_time', sprintFiles, [], ...
  390. 'timewindow', curr_opts.extracttime, ...
  391. 'overwrite', 1);
  392. % don't average across R/L hemispheres, it's too
  393. % complicated here. Instead we'll baseline correct,
  394. % then average across subjects, and can average across
  395. % R/L at group level.
  396. end
  397. end
  398. %% whole brain analyses (combined contrast)
  399. if runwholebrainhighalpha
  400. % extract only average of high alpha (10-15 Hz) from morlet
  401. % wavelets or hilbert transform.
  402. % project to template and smooth.
  403. % set times of interest
  404. buffer_time = [-0.4, 0.4]; % 4 cycles of 10Hz for edge effects
  405. switch epochname
  406. case 'button'
  407. target_time = [-1.25, -0.75];
  408. case 'ms_instim'
  409. target_time = [0.5 0.75];
  410. otherwise
  411. continue
  412. end
  413. timebands2use = {'baseline', num2str(curr_opts.baseline), 'mean'; 'target', num2str(target_time), 'mean'};
  414. % use hilbert transform, much faster
  415. mergedFiles = bst_process('CallProcess', 'process_hilbert', epochFiles, [], ...
  416. 'clusters', [], ...
  417. 'scoutfunc', 1, ...
  418. 'edit', struct(...
  419. 'Comment', ['Wholebrain,Avg,Power, highalpha ', curr_opts.label, extralabel], ...
  420. 'TimeBands', {timebands2use}, ...
  421. 'Freqs', {{'highalpha', '10,15', 'mean'}}, ...
  422. 'ClusterFuncTime', 'none', ...
  423. 'Measure', 'power', ...
  424. 'Output', 'average', ...
  425. 'RemoveEvoked', 0, ...
  426. 'SaveKernel', 0), ...
  427. 'normalize2020', 0, ...
  428. 'normalize', 'none', ... % None: Save non-standardized time-frequency maps
  429. 'mirror', 0);
  430. % remove timebands from file
  431. inMerge = in_bst(mergedFiles.FileName);
  432. inMerge.Time = [mean(curr_opts.baseline), mean(target_time)];
  433. inMerge = rmfield(inMerge, 'TimeBands');
  434. bst_save(file_fullpath(mergedFiles.FileName), inMerge, 'v7.3');
  435. db_reload_studies(mergedFiles.iStudy);
  436. % project to template & smooth
  437. % Process: Project on default anatomy: surface
  438. templateFiles = bst_process('CallProcess', 'process_project_sources', mergedFiles, [], ...
  439. 'headmodeltype', 'surface'); % Cortex surface
  440. % Process: Spatial smoothing (3.00)
  441. templateFiles = bst_process('CallProcess', 'process_ssmooth', templateFiles, [], ...
  442. 'fwhm', 3, ...
  443. 'method', 'geodesic_dist', ... % Geodesic (mm)(recommended)
  444. 'overwrite', 1);
  445. end
  446. %% Init Main illusion task (blocks 1-7)
  447. if ~runret % don't run main task if we set above to run retinotopy
  448. % epoch microsaccade files if analyzing them
  449. ms_epochnames = {'ms_instim', 'ms_infix'};
  450. msEpochFiles = [];
  451. for iMSEpoch = 1:numel(ms_epochnames)
  452. if sum(strcmp(epoch_types, ms_epochnames{iMSEpoch}))
  453. epoch_out = UI_epoch({ms_epochnames{iMSEpoch}}, SubjectNames(iSubj));
  454. % save files here to delete at the end
  455. msEpochFiles = [msEpochFiles, epoch_out{1}, epoch_out{2}];
  456. end
  457. end
  458. % Input files
  459. % Process: Select data files in: SUBJ
  460. allFiles = bst_process('CallProcess', 'process_select_files_results', [], [], ...
  461. 'subjectname', sname, ...
  462. 'condition', [], ...
  463. 'tag', [], ...
  464. 'includebad', 0, ...
  465. 'includeintra', 0, ...
  466. 'includecommon', 0);
  467. % Process: Ignore file names with tag: ret
  468. allFiles = bst_process('CallProcess', 'process_select_tag', allFiles, [], ...
  469. 'tag', 'ret', ...
  470. 'search', 1, ... % Search the file paths
  471. 'select', 2); % Ignore the files with the tag
  472. %% run blocktypes
  473. for blocktype = [2, 1] % first do main task blocks 1-6, then block 7
  474. % Process: Ignore file names with tag: block7
  475. blockFiles = bst_process('CallProcess', 'process_select_tag', allFiles, [], ...
  476. 'tag', 'block7', ...
  477. 'search', 1, ... % Search the file paths
  478. 'select', blocktype); % Select/Ignore the files with the tag
  479. if subset
  480. if blocktype == 1
  481. continue % don't analyze block7 when we're just running the main task subset
  482. elseif blocktype == 2
  483. % get block7 files to start
  484. block7Files = bst_process('CallProcess', 'process_select_tag', allFiles, [], ...
  485. 'tag', 'block7', ...
  486. 'search', 1, ... % Search the file paths
  487. 'select', 1); % Select
  488. end
  489. end
  490. %% run epochs
  491. for iEpoch_type = 1:numel(epoch_types)
  492. epochname = epoch_types{iEpoch_type};
  493. curr_opts = opts.epochs.(epochname);
  494. if strcmp(epochname, 'button_noms') && sum(strcmp(sname, {'s318', 's320', 's324'}))
  495. continue
  496. end
  497. epochFiles = bst_process('CallProcess', 'process_select_tag', blockFiles, [], ...
  498. 'tag', curr_opts.tag, ...
  499. 'search', 3, ... % Search the parent file names
  500. 'select', 1); % Select the files with the tag
  501. % Process: Ignore file names with tag: Avg
  502. epochFiles = bst_process('CallProcess', 'process_select_tag', epochFiles, [], ...
  503. 'tag', 'Avg', ...
  504. 'search', 3, ... % Search the parent file name
  505. 'select', 2); % Ignore the files with the tag
  506. epochFiles_bl = bst_process('CallProcess', 'process_select_tag', epochFiles, [], ...
  507. 'tag', 'bl.mat', ...
  508. 'search', 1, ... % Search the file paths
  509. 'select', 1); % Select the files with the tag
  510. % Process: Ignore file names with tag: bl.mat (don't use baseline-corrected)
  511. epochFiles = bst_process('CallProcess', 'process_select_tag', epochFiles, [], ...
  512. 'tag', 'bl.mat', ...
  513. 'search', 1, ... % Search the file paths
  514. 'select', 2); % Ignore the files with the tag
  515. % don't take the wrong epochs
  516. ignoreTags = {'noms'};
  517. for iTag = 1:numel(ignoreTags)
  518. if ~contains(curr_opts.tag, ignoreTags{iTag})
  519. epochFiles = bst_process('CallProcess', 'process_select_tag', epochFiles, [], ...
  520. 'tag', ignoreTags{iTag}, ...
  521. 'search', 3, ... % Search the parent filenames
  522. 'select', 2); % Ignore the files with the tag
  523. epochFiles = bst_process('CallProcess', 'process_select_tag', epochFiles, [], ...
  524. 'tag', ignoreTags{iTag}, ...
  525. 'search', 1, ... % Search the file paths
  526. 'select', 2); % Ignore the files with the tag
  527. end
  528. end
  529. if isempty(epochFiles) | numel(epochFiles) < 2
  530. continue
  531. end
  532. if subset % collect block7 trials too, to get subset of main task trials with same trial count.
  533. epoch7Files = bst_process('CallProcess', 'process_select_tag', block7Files, [], ...
  534. 'tag', curr_opts.tag, ...
  535. 'search', 3, ... % Search the parent file names
  536. 'select', 1); % Select the files with the tag
  537. % Process: Ignore file names with tag: Avg
  538. epoch7Files = bst_process('CallProcess', 'process_select_tag', epoch7Files, [], ...
  539. 'tag', 'Avg', ...
  540. 'search', 3, ... % Search the parent file name
  541. 'select', 2); % Ignore the files with the tag
  542. % Process: Ignore file names with tag: bl.mat (don't use baseline-corrected)
  543. epoch7Files = bst_process('CallProcess', 'process_select_tag', epoch7Files, [], ...
  544. 'tag', 'bl.mat', ...
  545. 'search', 1, ... % Search the file paths
  546. 'select', 2); % Ignore the files with the tag
  547. % don't take the wrong epochs
  548. ignoreTags = {'noms'};
  549. for iTag = 1:numel(ignoreTags)
  550. if ~contains(curr_opts.tag, ignoreTags{iTag})
  551. epoch7Files = bst_process('CallProcess', 'process_select_tag', epoch7Files, [], ...
  552. 'tag', ignoreTags{iTag}, ...
  553. 'search', 3, ... % Search the parent filenames
  554. 'select', 2); % Ignore the files with the tag
  555. epoch7Files = bst_process('CallProcess', 'process_select_tag', epoch7Files, [], ...
  556. 'tag', ignoreTags{iTag}, ...
  557. 'search', 1, ... % Search the file paths
  558. 'select', 2); % Ignore the files with the tag
  559. end
  560. end
  561. if isempty(epoch7Files) | numel(epoch7Files) < 2
  562. continue
  563. end
  564. % Process: Select uniform number of files [uniform]
  565. % so the files are uniformly distributed along the list of trials, which is
  566. % ordered block1,block2, etc...
  567. % i.e. a pseudo-random but fully reproducible selection, not necessarily biased towards
  568. % any particular task block.
  569. [epochFiles, epoch7Files] = bst_process('CallProcess', 'process_select_uniform2', epochFiles, epoch7Files, ...
  570. 'nfiles', 0, ...
  571. 'method', 4); % Uniformly distributed
  572. end
  573. for iAtlas = use_atlases
  574. curr_atlas = all_atlases(iAtlas);
  575. %% psds
  576. if strcmp(epochname, 'stimon') && runpsds % get avg FFTs or PSDs for quality control.
  577. psdscout = bst_process('CallProcess', 'process_psd', epochFiles, [], ...
  578. 'timewindow', [3, 5], ...
  579. 'win_length', 1, ...
  580. 'win_overlap', 50, ...
  581. 'units', 'physical', ... % Physical: U2/Hz
  582. 'clusters', {curr_atlas.name, curr_atlas.scouts2use}, ...
  583. 'scoutfunc', 1, ... % Mean
  584. 'win_std', 0, ...
  585. 'edit', struct(...
  586. 'Comment', 'Scouts,Avg,Power', ...
  587. 'TimeBands', [], ...
  588. 'Freqs', [], ...
  589. 'ClusterFuncTime', 'after', ...
  590. 'Measure', 'power', ...
  591. 'Output', 'average', ...
  592. 'SaveKernel', 0));
  593. bst_process('CallProcess', 'process_set_comment', psdscout, [], ...
  594. 'tag', ['PSD ', curr_atlas.label, ' stimon'], ...
  595. 'isindex', 0);
  596. psdscout = bst_process('CallProcess', 'process_psd', epochFiles, [], ...
  597. 'timewindow', [-2, 0], ...
  598. 'win_length', 1, ...
  599. 'win_overlap', 50, ...
  600. 'units', 'physical', ... % Physical: U2/Hz
  601. 'clusters', {curr_atlas.name, curr_atlas.scouts2use}, ...
  602. 'scoutfunc', 1, ... % Mean
  603. 'win_std', 0, ...
  604. 'edit', struct(...
  605. 'Comment', 'Scouts,Avg,Power', ...
  606. 'TimeBands', [], ...
  607. 'Freqs', [], ...
  608. 'ClusterFuncTime', 'after', ...
  609. 'Measure', 'power', ...
  610. 'Output', 'average', ...
  611. 'SaveKernel', 0));
  612. bst_process('CallProcess', 'process_set_comment', psdscout, [], ...
  613. 'tag', ['PSD ', curr_atlas.label, ' fix'], ...
  614. 'isindex', 0);
  615. elseif strcmp(epochname, 'button') && runpsds % get PSDs for button epoch to compare 1/f slope/intercept
  616. % button_baseline: t -4 to -3 s
  617. % button_filling: t -1.5 to -0.5 s
  618. psdscout = bst_process('CallProcess', 'process_psd', epochFiles, [], ...
  619. 'timewindow', [-4 -3], ...
  620. 'win_length', 1, ...
  621. 'win_overlap', 50, ...
  622. 'units', 'physical', ... % Physical: U2/Hz
  623. 'clusters', {curr_atlas.name, curr_atlas.scouts2use}, ...
  624. 'scoutfunc', 1, ... % Mean
  625. 'win_std', 0, ...
  626. 'edit', struct(...
  627. 'Comment', 'Scouts,Avg,Power', ...
  628. 'TimeBands', [], ...
  629. 'Freqs', [], ...
  630. 'ClusterFuncTime', 'after', ...
  631. 'Measure', 'power', ...
  632. 'Output', 'average', ...
  633. 'SaveKernel', 0));
  634. bst_process('CallProcess', 'process_set_comment', psdscout, [], ...
  635. 'tag', ['PSD ', curr_atlas.label, ' button_baseline'], ...
  636. 'isindex', 0);
  637. psdscout = bst_process('CallProcess', 'process_psd', epochFiles, [], ...
  638. 'timewindow', [-1.5 -0.5], ...
  639. 'win_length', 1, ...
  640. 'win_overlap', 50, ...
  641. 'units', 'physical', ... % Physical: U2/Hz
  642. 'clusters', {curr_atlas.name, curr_atlas.scouts2use}, ...
  643. 'scoutfunc', 1, ... % Mean
  644. 'win_std', 0, ...
  645. 'edit', struct(...
  646. 'Comment', 'Scouts,Avg,Power', ...
  647. 'TimeBands', [], ...
  648. 'Freqs', [], ...
  649. 'ClusterFuncTime', 'after', ...
  650. 'Measure', 'power', ...
  651. 'Output', 'average', ...
  652. 'SaveKernel', 0));
  653. bst_process('CallProcess', 'process_set_comment', psdscout, [], ...
  654. 'tag', ['PSD ', curr_atlas.label, ' button_filling'], ...
  655. 'isindex', 0);
  656. end
  657. %% scout combine contrasts
  658. if combinecontrasts % run power analyses combined across both contrasts
  659. %% scout plvt
  660. if runplvt
  661. conn_metric = 'PLVt';
  662. % PHASE LOCKING WITH PHOTODIODE
  663. % Process: Select data files
  664. sensorepochFiles = bst_process('CallProcess', 'process_select_files_data', [], [], ...
  665. 'subjectname', sname, ...
  666. 'condition', [], ...
  667. 'tag', curr_opts.tag, ...
  668. 'includebad', 0, ...
  669. 'includeintra', 0, ...
  670. 'includecommon', 0);
  671. % Process: Ignore file names with tag: bl.mat (don't use baseline-corrected)
  672. sensorepochFiles = bst_process('CallProcess', 'process_select_tag', sensorepochFiles, [], ...
  673. 'tag', 'bl.mat', ...
  674. 'search', 1, ... % Search the file paths
  675. 'select', 2); % Ignore the files with the tag
  676. % don't take the wrong epochs
  677. ignoreTags = {'noms'};
  678. for iTag = 1:numel(ignoreTags)
  679. if ~contains(curr_opts.tag, ignoreTags{iTag})
  680. sensorepochFiles = bst_process('CallProcess', 'process_select_tag', sensorepochFiles, [], ...
  681. 'tag', ignoreTags{iTag}, ...
  682. 'search', 1, ... % Search the file paths
  683. 'select', 2); % Ignore the files with the tag
  684. end
  685. end
  686. % Process: Ignore file names with tag: Avg
  687. sensorepochFiles = bst_process('CallProcess', 'process_select_tag', sensorepochFiles, [], ...
  688. 'tag', 'Avg', ...
  689. 'search', 2, ... % Search the file names
  690. 'select', 2); % Ignore the files with the tag
  691. % Process: Ignore file names with tag: ret
  692. sensorepochFiles = bst_process('CallProcess', 'process_select_tag', sensorepochFiles, [], ...
  693. 'tag', 'ret', ...
  694. 'search', 1, ... % Search the file paths
  695. 'select', 2); % Ignore the files with the tag
  696. % Process: Select/ignore file names with tag: block7
  697. sensorepochFiles = bst_process('CallProcess', 'process_select_tag', sensorepochFiles, [], ...
  698. 'tag', 'block7', ...
  699. 'search', 1, ... % Search the file paths
  700. 'select', blocktype); % Select/ignore the files with the tag
  701. for iDiode = 1:2
  702. diode = opts.diode_channels{iDiode};
  703. useband = opts.flicker_bands{iDiode};
  704. % PLV in localizer scouts
  705. % Process: PLV: Phase locking value
  706. connectivityScout(iDiode) = bst_process('CallProcess', 'process_plv2', sensorepochFiles, epochFiles, ...
  707. 'timewindow', curr_opts.fullwindow, ...
  708. 'src_channel', diode, ...
  709. 'dest_scouts', {curr_atlas.name, curr_atlas.scouts2use}, ...
  710. 'scoutfunc', 'mean', ... % Mean
  711. 'scouttime', 'after', ... % After
  712. 'scoutfuncaft', 'mean', ... % Mean
  713. 'tfedit', struct(...
  714. 'Comment', 'Complex', ...
  715. 'TimeBands', [], ...
  716. 'Freqs', {useband}, ...
  717. 'ClusterFuncTime', 'none', ...
  718. 'Measure', 'none', ...
  719. 'Output', 'all', ...
  720. 'SaveKernel', 0), ...
  721. 'plvmethod', 'plv', ... % PLV: Phase locking value
  722. 'tfmeasure', 'hilbert', ... % Hilbert transform
  723. 'timeres', 'full', ... % Full (requires epochs)
  724. 'plvmeasure', 2, ... % Magnitude
  725. 'outputmode', 'avg'); % Save average connectivity matrix (one file)
  726. % Process: Set name:
  727. connectivityScout(iDiode) = bst_process('CallProcess', 'process_set_comment', connectivityScout(iDiode), [], ...
  728. 'tag', ['Scouts_', curr_atlas.label, ',Avg: ', conn_metric, ': ', diode, ' ', curr_opts.label, extralabel], ...
  729. 'isindex', 0);
  730. end
  731. % Process: PLV: Phase locking value with 60 Hz sin (control)
  732. f60FilesMulti = repmat(f60Files, 1, numel(epochFiles));
  733. connectivity60Scout = bst_process('CallProcess', 'process_plv2', f60FilesMulti, epochFiles, ...
  734. 'timewindow', curr_opts.fullwindow, ...
  735. 'src_channel', '', ...
  736. 'dest_scouts', {curr_atlas.name, curr_atlas.scouts2use}, ...
  737. 'scoutfunc', 'mean', ... % Mean
  738. 'scouttime', 'after', ... % After
  739. 'scoutfuncaft', 'mean', ... % Mean
  740. 'tfedit', struct(...
  741. 'Comment', 'Complex', ...
  742. 'TimeBands', [], ...
  743. 'Freqs', {{'fcontrol', '59, 61', 'mean'}}, ...
  744. 'ClusterFuncTime', 'none', ...
  745. 'Measure', 'none', ...
  746. 'Output', 'all', ...
  747. 'SaveKernel', 0), ...
  748. 'plvmethod', 'plv', ... % PLV: Phase locking value
  749. 'tfmeasure', 'hilbert', ... % Hilbert transform
  750. 'timeres', 'full', ... % Full (requires epochs)
  751. 'plvmeasure', 2, ... % Magnitude
  752. 'outputmode', 'avg'); % Save average connectivity matrix (one file)
  753. % Process: Set name:
  754. connectivity60Scout = bst_process('CallProcess', 'process_set_comment', connectivity60Scout, [], ...
  755. 'tag', ['Scouts_', curr_atlas.label, ',Avg: ', conn_metric, ' 60 ', curr_opts.label, extralabel], ...
  756. 'isindex', 0);
  757. % combine into one file (not merging R/L yet)
  758. mat56 = in_bst_timefreq(connectivityScout(1).FileName);
  759. mat64 = in_bst_timefreq(connectivityScout(2).FileName);
  760. mat60 = in_bst_timefreq(connectivity60Scout.FileName);
  761. matall = mat56;
  762. matall.Freqs = {'fp', '55,57', 'mean'; 'fc', '63,65', 'mean'; 'fcontrol', '59, 61', 'mean'};
  763. matall.RefRowNames = {'MISC'};
  764. matall.TF(:, :, 2) = mat64.TF;
  765. matall.TF(:, :, 3) = mat60.TF;
  766. matall.Comment = ['Scouts_', curr_atlas.label, ',Avg: ', conn_metric, ' fpfc ', curr_opts.label, extralabel];
  767. scout_allconnectivity = db_add(connectivityScout(1).iStudy, matall);
  768. % Process: Extract time
  769. scout_allconnectivityTime = bst_process('CallProcess', 'process_extract_time', scout_allconnectivity, [], ...
  770. 'timewindow', curr_opts.extracttime, ...
  771. 'overwrite', 1);
  772. % Process: Event-related perturbation (ERS/ERD)
  773. scout_allconnectivityERSD = bst_process('CallProcess', 'process_baseline_norm', scout_allconnectivityTime, [], ...
  774. 'baseline', curr_opts.baseline, ...
  775. 'method', bl_method, ... % Event-related perturbation (ERS/ERD): x_std = (x - &mu;) / &mu; * 100
  776. 'overwrite', 0);
  777. % Process: Delete selected files
  778. bst_process('CallProcess', 'process_delete', [connectivityScout, connectivity60Scout], [], ...
  779. 'target', 1); % Delete selected files
  780. % Process: combine RL hemispheres
  781. if mergerl(iAtlas)
  782. for iScout = 1:numel(curr_atlas.rl_rowidx)
  783. RL_scoutconnectivity(iScout) = bst_process('CallProcess', 'process_extract_values', scout_allconnectivityERSD, [], ...
  784. 'timewindow', [], ...
  785. 'freqrange', [0, 100], ...
  786. 'rows', curr_atlas.rl_rowidx{iScout}, ...
  787. 'isabs', 0, ...
  788. 'avgtime', 0, ...
  789. 'avgrow', 1, ...
  790. 'avgfreq', 0, ...
  791. 'matchrows', 0, ...
  792. 'dim', 2, ... % Concatenate time (dimension 2)
  793. 'Comment', ['RL_scout,Avg: ', conn_metric, ' ', curr_opts.label, extralabel]);
  794. end
  795. clear allmats
  796. allmats(1) = in_bst_timefreq(RL_scoutconnectivity(1).FileName);
  797. matall = allmats(1);
  798. matall.RowNames = curr_atlas.rl_rownames;
  799. matall.Comment = [curr_atlas.rl_label, ',Avg: ', conn_metric, ' fpfc ', curr_opts.label, extralabel];
  800. for iScout = 2:numel(curr_atlas.rl_rowidx)
  801. allmats(iScout) = in_bst_timefreq(RL_scoutconnectivity(iScout).FileName);
  802. matall.TF(iScout, :, :) = allmats(iScout).TF;
  803. end
  804. RL_allconnectivity = db_add(RL_scoutconnectivity(1).iStudy, matall);
  805. % Process: Delete selected files
  806. bst_process('CallProcess', 'process_delete', [RL_scoutconnectivity], [], ...
  807. 'target', 1); % Delete selected files
  808. end
  809. end
  810. %% scout plvt intermodulation
  811. if runfiplvt
  812. conn_metric = 'PLVt';
  813. % PHASE LOCKING WITH 8 Hz AND 16 Hz
  814. fi_freqs = [8 16 11];
  815. for iFreq = 1:numel(fi_freqs)
  816. curr_freq = fi_freqs(iFreq);
  817. if curr_freq == 8
  818. fiFiles = f8Files;
  819. elseif curr_freq == 16
  820. fiFiles = f16Files;
  821. elseif curr_freq == 11
  822. fiFiles = f11Files;
  823. end
  824. fiFilesMulti = repmat(fiFiles, 1, numel(epochFiles));
  825. useband = opts.fi_bands{iFreq};
  826. % Process: PLV: Phase locking value with sinusoid
  827. connectivityfiScout(iFreq) = bst_process('CallProcess', 'process_plv2', fiFilesMulti, epochFiles, ...
  828. 'timewindow', curr_opts.fullwindow, ...
  829. 'src_channel', '', ...
  830. 'dest_scouts', {curr_atlas.name, curr_atlas.scouts2use}, ...
  831. 'scoutfunc', 'mean', ... % Mean
  832. 'scouttime', 'after', ... % After
  833. 'scoutfuncaft', 'mean', ... % Mean
  834. 'tfedit', struct(...
  835. 'Comment', 'Complex', ...
  836. 'TimeBands', [], ...
  837. 'Freqs', {useband}, ...
  838. 'ClusterFuncTime', 'none', ...
  839. 'Measure', 'none', ...
  840. 'Output', 'all', ...
  841. 'SaveKernel', 0), ...
  842. 'plvmethod', 'plv', ... % PLV: Phase locking value
  843. 'tfmeasure', 'hilbert', ... % Hilbert transform
  844. 'timeres', 'full', ... % Full (requires epochs)
  845. 'plvmeasure', 2, ... % Magnitude
  846. 'outputmode', 'avg'); % Save average connectivity matrix (one file)
  847. % Process: Set name:
  848. connectivityfiScout(iFreq) = bst_process('CallProcess', 'process_set_comment', connectivityfiScout(iFreq), [], ...
  849. 'tag', ['Scouts_', curr_atlas.label, ',Avg: ', conn_metric, ' ' num2str(curr_freq), ' ', curr_opts.label, extralabel], ...
  850. 'isindex', 0);
  851. end
  852. % combine into one file (not merging R/L yet)
  853. mat8 = in_bst_timefreq(connectivityfiScout(1).FileName);
  854. mat16 = in_bst_timefreq(connectivityfiScout(2).FileName);
  855. mat11 = in_bst_timefreq(connectivityfiScout(3).FileName);
  856. matall = mat8;
  857. matall.Freqs = {'fi', '7,9', 'mean'; 'fi2', '15,17', 'mean'; 'ficontrol', '10,12', 'mean'};
  858. matall.RefRowNames = {'MISC'};
  859. matall.TF(:, :, 2) = mat16.TF;
  860. matall.TF(:, :, 3) = mat11.TF;
  861. matall.Comment = ['Scouts_', curr_atlas.label, ',Avg: ', conn_metric, ' fi ', curr_opts.label, extralabel];
  862. scout_allconnectivity = db_add(connectivityfiScout(1).iStudy, matall);
  863. % Process: Event-related perturbation (ERS/ERD)
  864. scout_allconnectivityERSD = bst_process('CallProcess', 'process_baseline_norm', scout_allconnectivity, [], ...
  865. 'baseline', curr_opts.baseline, ...
  866. 'method', bl_method, ... % Event-related perturbation (ERS/ERD): x_std = (x - &mu;) / &mu; * 100
  867. 'overwrite', 0);
  868. % Process: Extract time
  869. scout_allconnectivityERSD = bst_process('CallProcess', 'process_extract_time', scout_allconnectivityERSD, [], ...
  870. 'timewindow', curr_opts.extracttime, ...
  871. 'overwrite', 1);
  872. % Process: Delete selected files
  873. bst_process('CallProcess', 'process_delete', [connectivityfiScout], [], ...
  874. 'target', 1); % Delete selected files
  875. % Process: combine RL hemispheres
  876. if mergerl(iAtlas)
  877. for iScout = 1:numel(curr_atlas.rl_rowidx)
  878. RL_scoutconnectivity(iScout) = bst_process('CallProcess', 'process_extract_values', scout_allconnectivityERSD, [], ...
  879. 'timewindow', [], ...
  880. 'freqrange', [0, 100], ...
  881. 'rows', curr_atlas.rl_rowidx{iScout}, ...
  882. 'isabs', 0, ...
  883. 'avgtime', 0, ...
  884. 'avgrow', 1, ...
  885. 'avgfreq', 0, ...
  886. 'matchrows', 0, ...
  887. 'dim', 2, ... % Concatenate time (dimension 2)
  888. 'Comment', ['RL_scout,Avg: ', conn_metric, ' ', curr_opts.label, extralabel]);
  889. end
  890. clear allmats
  891. allmats(1) = in_bst_timefreq(RL_scoutconnectivity(1).FileName);
  892. matall = allmats(1);
  893. matall.RowNames = curr_atlas.rl_rownames;
  894. matall.Comment = [curr_atlas.rl_label, ',Avg: ', conn_metric, ' fi ', curr_opts.label, extralabel];
  895. for iScout = 2:numel(curr_atlas.rl_rowidx)
  896. allmats(iScout) = in_bst_timefreq(RL_scoutconnectivity(iScout).FileName);
  897. matall.TF(iScout, :, :) = allmats(iScout).TF;
  898. end
  899. RL_allconnectivity = db_add(RL_scoutconnectivity(1).iStudy, matall);
  900. % Process: Delete selected files
  901. bst_process('CallProcess', 'process_delete', [RL_scoutconnectivity], [], ...
  902. 'target', 1); % Delete selected files
  903. end
  904. end
  905. %% split contrasts
  906. if splitcontrasts
  907. % REDO ANALYSES SPLIT BY STIMULUS COLOR CONTRAST
  908. if blocktype == 2
  909. for iContrast = 1:2 % low, high
  910. blocks2use = find(opts.blockorders.(sname) == iContrast);
  911. contrastEpochFiles = [];
  912. for iBlock = blocks2use
  913. % Process: select filenames
  914. curr_blockFiles = bst_process('CallProcess', 'process_select_tag', epochFiles, [], ...
  915. 'tag', ['block', num2str(iBlock)], ...
  916. 'search', 1, ... % Search the file paths
  917. 'select', 1); % Select the files with the tag
  918. contrastEpochFiles = [contrastEpochFiles, curr_blockFiles];
  919. end
  920. if isempty(contrastEpochFiles)
  921. continue
  922. end
  923. %% scout plvt
  924. if runplvt
  925. conn_metric = 'PLVt';
  926. % PHASE LOCKING WITH PHOTODIODE
  927. % Process: Select data files
  928. sensorepochFiles = bst_process('CallProcess', 'process_select_files_data', [], [], ...
  929. 'subjectname', sname, ...
  930. 'condition', [], ...
  931. 'tag', curr_opts.tag, ...
  932. 'includebad', 0, ...
  933. 'includeintra', 0, ...
  934. 'includecommon', 0);
  935. % Process: Ignore file names with tag: bl.mat (don't use baseline-corrected)
  936. sensorepochFiles = bst_process('CallProcess', 'process_select_tag', sensorepochFiles, [], ...
  937. 'tag', 'bl.mat', ...
  938. 'search', 1, ... % Search the file paths
  939. 'select', 2); % Ignore the files with the tag
  940. % don't take the wrong epochs
  941. ignoreTags = {'noms'};
  942. for iTag = 1:numel(ignoreTags)
  943. if ~contains(curr_opts.tag, ignoreTags{iTag})
  944. sensorepochFiles = bst_process('CallProcess', 'process_select_tag', sensorepochFiles, [], ...
  945. 'tag', ignoreTags{iTag}, ...
  946. 'search', 1, ... % Search the file paths
  947. 'select', 2); % Ignore the files with the tag
  948. end
  949. end
  950. % Process: Ignore file names with tag: Avg
  951. sensorepochFiles = bst_process('CallProcess', 'process_select_tag', sensorepochFiles, [], ...
  952. 'tag', 'Avg', ...
  953. 'search', 2, ... % Search the file names
  954. 'select', 2); % Ignore the files with the tag
  955. % Process: Ignore file names with tag: ret
  956. sensorepochFiles = bst_process('CallProcess', 'process_select_tag', sensorepochFiles, [], ...
  957. 'tag', 'ret', ...
  958. 'search', 1, ... % Search the file paths
  959. 'select', 2); % Ignore the files with the tag
  960. % Process: Select/ignore file names with tag: block7
  961. sensorepochFiles = bst_process('CallProcess', 'process_select_tag', sensorepochFiles, [], ...
  962. 'tag', 'block7', ...
  963. 'search', 1, ... % Search the file paths
  964. 'select', blocktype); % Select/ignore the files with the tag
  965. contrastSensorepochFiles = [];
  966. for iBlock = blocks2use
  967. % Process: select filenames
  968. curr_blockFiles = bst_process('CallProcess', 'process_select_tag', sensorepochFiles, [], ...
  969. 'tag', ['block', num2str(iBlock)], ...
  970. 'search', 1, ... % Search the file paths
  971. 'select', 1); % Select the files with the tag
  972. contrastSensorepochFiles = [contrastSensorepochFiles, curr_blockFiles];
  973. end
  974. for iDiode = 1:2
  975. diode = opts.diode_channels{iDiode};
  976. useband = opts.flicker_bands{iDiode};
  977. % PLV in localizer scouts
  978. % Process: PLV: Phase locking value
  979. connectivityScout(iDiode) = bst_process('CallProcess', 'process_plv2', contrastSensorepochFiles, contrastEpochFiles, ...
  980. 'timewindow', curr_opts.fullwindow, ...
  981. 'src_channel', diode, ...
  982. 'dest_scouts', {curr_atlas.name, curr_atlas.scouts2use}, ...
  983. 'scoutfunc', 'mean', ... % Mean
  984. 'scouttime', 'after', ... % After
  985. 'scoutfuncaft', 'mean', ... % Mean
  986. 'tfedit', struct(...
  987. 'Comment', 'Complex', ...
  988. 'TimeBands', [], ...
  989. 'Freqs', {useband}, ...
  990. 'ClusterFuncTime', 'none', ...
  991. 'Measure', 'none', ...
  992. 'Output', 'all', ...
  993. 'SaveKernel', 0), ...
  994. 'plvmethod', 'plv', ... % PLV: Phase locking value
  995. 'tfmeasure', 'hilbert', ... % Hilbert transform
  996. 'timeres', 'full', ... % Full (requires epochs)
  997. 'plvmeasure', 2, ... % Magnitude
  998. 'outputmode', 'avg'); % Save average connectivity matrix (one file)
  999. % Process: Set name:
  1000. connectivityScout(iDiode) = bst_process('CallProcess', 'process_set_comment', connectivityScout(iDiode), [], ...
  1001. 'tag', ['Scouts_', curr_atlas.label, ',Avg: ', conn_metric, ': ', diode, ' ', curr_opts.label, ' contrast', num2str(iContrast)], ...
  1002. 'isindex', 0);
  1003. end
  1004. % Process: PLV: Phase locking value with 60 Hz sin (control)
  1005. f60FilesMulti = repmat(f60Files, 1, numel(contrastEpochFiles));
  1006. connectivity60Scout = bst_process('CallProcess', 'process_plv2', f60FilesMulti, contrastEpochFiles, ...
  1007. 'timewindow', curr_opts.fullwindow, ...
  1008. 'src_channel', '', ...
  1009. 'dest_scouts', {curr_atlas.name, curr_atlas.scouts2use}, ...
  1010. 'scoutfunc', 'mean', ... % Mean
  1011. 'scouttime', 'after', ... % After
  1012. 'scoutfuncaft', 'mean', ... % Mean
  1013. 'tfedit', struct(...
  1014. 'Comment', 'Complex', ...
  1015. 'TimeBands', [], ...
  1016. 'Freqs', {{'fcontrol', '59, 61', 'mean'}}, ...
  1017. 'ClusterFuncTime', 'none', ...
  1018. 'Measure', 'none', ...
  1019. 'Output', 'all', ...
  1020. 'SaveKernel', 0), ... 'plvmethod', 'plv', ... % PLV: Phase locking value
  1021. 'tfmeasure', 'hilbert', ... % Hilbert transform
  1022. 'timeres', 'full', ... % Full (requires epochs)
  1023. 'plvmeasure', 2, ... % Magnitude
  1024. 'outputmode', 'avg'); % Save average connectivity matrix (one file)
  1025. % Process: Set name:
  1026. connectivity60Scout = bst_process('CallProcess', 'process_set_comment', connectivity60Scout, [], ...
  1027. 'tag', ['Scouts_', curr_atlas.label, ',Avg: ', conn_metric, ' 60 ', curr_opts.label, ' contrast', num2str(iContrast)], ...
  1028. 'isindex', 0);
  1029. % combine into one file (not merging R/L yet)
  1030. mat56 = in_bst_timefreq(connectivityScout(1).FileName);
  1031. mat64 = in_bst_timefreq(connectivityScout(2).FileName);
  1032. mat60 = in_bst_timefreq(connectivity60Scout.FileName);
  1033. matall = mat56;
  1034. matall.Freqs = {'fp', '55,57', 'mean'; 'fc', '63,65', 'mean'; 'fcontrol', '59, 61', 'mean'};
  1035. matall.RefRowNames = {'MISC'};
  1036. matall.TF(:, :, 2) = mat64.TF;
  1037. matall.TF(:, :, 3) = mat60.TF;
  1038. matall.Comment = ['Scouts_', curr_atlas.label, ',Avg: ', conn_metric, ' fpfc ', curr_opts.label, ' contrast', num2str(iContrast)];
  1039. scout_allconnectivity = db_add(connectivityScout(1).iStudy, matall);
  1040. % Process: Event-related perturbation (ERS/ERD)
  1041. scout_allconnectivityERSD = bst_process('CallProcess', 'process_baseline_norm', scout_allconnectivity, [], ...
  1042. 'baseline', curr_opts.baseline, ...
  1043. 'method', bl_method, ... % Event-related perturbation (ERS/ERD): x_std = (x - &mu;) / &mu; * 100
  1044. 'overwrite', 0);
  1045. % Process: Extract time
  1046. scout_allconnectivityERSD = bst_process('CallProcess', 'process_extract_time', scout_allconnectivityERSD, [], ...
  1047. 'timewindow', curr_opts.extracttime, ...
  1048. 'overwrite', 1);
  1049. % Process: Delete selected files
  1050. bst_process('CallProcess', 'process_delete', [connectivityScout, connectivity60Scout], [], ...
  1051. 'target', 1); % Delete selected files
  1052. % Process: combine RL hemispheres
  1053. if mergerl(iAtlas)
  1054. for iScout = 1:numel(curr_atlas.rl_rowidx)
  1055. RL_scoutconnectivity(iScout) = bst_process('CallProcess', 'process_extract_values', scout_allconnectivityERSD, [], ...
  1056. 'timewindow', [], ...
  1057. 'freqrange', [0, 100], ...
  1058. 'rows', curr_atlas.rl_rowidx{iScout}, ...
  1059. 'isabs', 0, ...
  1060. 'avgtime', 0, ...
  1061. 'avgrow', 1, ...
  1062. 'avgfreq', 0, ...
  1063. 'matchrows', 0, ...
  1064. 'dim', 2, ... % Concatenate time (dimension 2)
  1065. 'Comment', ['RL_scout,Avg: ', conn_metric, ' ', curr_opts.label, ' contrast', num2str(iContrast)]);
  1066. end
  1067. clear allmats
  1068. allmats(1) = in_bst_timefreq(RL_scoutconnectivity(1).FileName);
  1069. matall = allmats(1);
  1070. matall.RowNames = curr_atlas.rl_rownames;
  1071. matall.Comment = [curr_atlas.rl_label, ',Avg: ', conn_metric, ' fpfc ', curr_opts.label, ' contrast', num2str(iContrast)];
  1072. for iScout = 2:numel(curr_atlas.rl_rowidx)
  1073. allmats(iScout) = in_bst_timefreq(RL_scoutconnectivity(iScout).FileName);
  1074. matall.TF(iScout, :, :) = allmats(iScout).TF;
  1075. end
  1076. RL_allconnectivity = db_add(RL_scoutconnectivity(1).iStudy, matall);
  1077. % Process: Delete selected files
  1078. bst_process('CallProcess', 'process_delete', [RL_scoutconnectivity], [], ...
  1079. 'target', 1); % Delete selected files
  1080. end
  1081. end
  1082. end
  1083. end
  1084. end
  1085. %% custom SPRiNT
  1086. if runsprintcustom
  1087. % fooofs each moving window after averaging SFFTs across
  1088. % trials.
  1089. % method: extract each time window, run FOOOF, then combine
  1090. % outputs into a SPRiNT structure.
  1091. % set windows. winlength = 1 second, but at intervals of
  1092. % 100ms.
  1093. % make sure we'll cover the full extracttime window, but
  1094. % don't waste compute on extra windows
  1095. fulltime = curr_opts.extracttime + [-sprint_winlength/2, sprint_winlength/2];
  1096. winstarts = fulltime(1):sprint_winstep:fulltime(2)-sprint_winlength+.001;
  1097. winends = fulltime(1)+sprint_winlength:sprint_winstep:fulltime(2);
  1098. nWin = numel(winstarts);
  1099. % extract time windows, FFT, average them, and FOOOF.
  1100. clear winFiles
  1101. for iAtlas = use_atlases
  1102. curr_atlas = all_atlases(iAtlas);
  1103. for iWin = 1:nWin
  1104. % Process: Power spectrum density (Welch)
  1105. fftWinFiles = bst_process('CallProcess', 'process_psd', epochFiles, [], ...
  1106. 'timewindow', [winstarts(iWin), winends(iWin)], ...
  1107. 'win_length', sprint_winlength, ...
  1108. 'win_overlap', 0, ...
  1109. 'units', 'physical', ... % Physical: U2/Hz
  1110. 'clusters', {curr_atlas.name, curr_atlas.scouts2use}, ...
  1111. 'scoutfunc', 1, ... % Mean
  1112. 'win_std', 0, ...
  1113. 'edit', struct(...
  1114. 'Comment', 'Scout psd,Avg,Power', ...
  1115. 'TimeBands', [], ...
  1116. 'Freqs', [], ...
  1117. 'ClusterFuncTime', 'after', ...
  1118. 'Measure', 'power', ...
  1119. 'Output', 'average', ...
  1120. 'SaveKernel', 0));
  1121. % Process: specparam: Fitting oscillations and 1/f
  1122. fooofWinFiles(iWin) = bst_process('CallProcess', 'process_fooof', fftWinFiles, [], ...
  1123. 'implementation', 'matlab', ... % Matlab
  1124. 'freqrange', [1, sprint_maxFreq], ...
  1125. 'powerline', '50', ... % 50 Hz
  1126. 'peaktype', 'gaussian', ... % Gaussian
  1127. 'peakwidth', [0.5, 12], ...
  1128. 'maxpeaks', 3, ...
  1129. 'minpeakheight', 1, ...
  1130. 'proxthresh', 2, ...
  1131. 'apermode', 'fixed', ... % Fixed
  1132. 'guessweight', 'none', ... % None
  1133. 'sorttype', 'param', ... % Peak parameters
  1134. 'sortparam', 'frequency', ... % Frequency
  1135. 'sortbands', {'delta', '2, 4'; 'theta', '5, 7'; 'alpha', '8, 12'; 'beta', '15, 29'; 'gamma1', '30, 59'; 'gamma2', '60, 90'});
  1136. % import to MATLAB.
  1137. fooofMats(iWin) = in_bst(fooofWinFiles(iWin).FileName);
  1138. % delete extracted ffts
  1139. bst_process('CallProcess', 'process_delete', fftWinFiles, [], ...
  1140. 'target', 1); % Delete selected files
  1141. clear fftWinFiles
  1142. end
  1143. % manually convert to a SPRiNT structure.
  1144. sprintMat = fooofMats(1); % get template from first fooof file.
  1145. sprintMat.Comment = ['Scouts_', curr_atlas.label, ',Avg: SPRiNT_custom ', curr_opts.label, extralabel];
  1146. sprintMat.Time = winstarts + sprint_winlength/2;
  1147. sprintMat.Freqs = sprintMat.Freqs(1:sprint_maxFreq);
  1148. sprintMat.Method = 'sprint';
  1149. sprintMat.RowNames = sprintMat.RowNames';
  1150. sprintMat.nAvg = numel(epochFiles); sprintMat.Leff = numel(epochFiles);
  1151. sprintMat.TF = sprintMat.TF(:, :, 1:sprint_maxFreq); % init TF
  1152. sprintMat.Options.Method = 'sprint';
  1153. sprintopts = struct;
  1154. sprintopts.freqs = sprintMat.Options.FOOOF.freqs;
  1155. for iScout = 1:numel(sprintMat.RowNames)
  1156. sprintopts.channel(iScout).name = sprintMat.RowNames{iScout};
  1157. sprintopts.channel(iScout).peaks = struct('time', 'center_frequency', 'amplitude', 'st_dev');
  1158. for iWin = 1:nWin
  1159. sprintMat.TF(iScout, iWin, :) = fooofMats(iWin).TF(iScout, :, 1:sprint_maxFreq);
  1160. fooofopts = fooofMats(iWin).Options.FOOOF;
  1161. sprintopts.topography.exponent(iScout, iWin) = fooofopts.aperiodics(iScout).exponent;
  1162. sprintopts.topography.offset(iScout, iWin) = fooofopts.aperiodics(iScout).offset;
  1163. sprintopts.SPRiNT_models(iScout, iWin, :) = fooofopts.data(iScout).fooofed_spectrum;
  1164. sprintopts.peak_models(iScout, iWin, :) = fooofopts.data(iScout).peak_fit;
  1165. sprintopts.aperiodic_models(iScout, iWin, :) = fooofopts.data(iScout).ap_fit;
  1166. sprintopts.channel(iScout).data(iWin).time = sprintMat.Time(iWin);
  1167. sprintopts.channel(iScout).data(iWin).aperiodic_params = [sprintopts.topography.offset(iScout, iWin), sprintopts.topography.exponent(iScout, iWin)];
  1168. sprintopts.channel(iScout).data(iWin).peak_params = fooofopts.data(iScout).peak_params;
  1169. sprintopts.channel(iScout).data(iWin).peak_types = fooofopts.data(iScout).peak_types;
  1170. sprintopts.channel(iScout).data(iWin).ap_fit = fooofopts.data(iScout).ap_fit;
  1171. sprintopts.channel(iScout).data(iWin).peak_fit = fooofopts.data(iScout).peak_fit;
  1172. sprintopts.channel(iScout).data(iWin).fooofed_spectrum = fooofopts.data(iScout).fooofed_spectrum;
  1173. sprintopts.channel(iScout).data(iWin).power_spectrum = fooofMats(iWin).TF(iScout, :, 1:sprint_maxFreq);
  1174. sprintopts.channel(iScout).data(iWin).error = fooofopts.data.error;
  1175. sprintopts.channel(iScout).data(iWin).r_squared = fooofopts.data.r_squared;
  1176. sprintopts.channel(iScout).aperiodics(iWin).time = sprintMat.Time(iWin);
  1177. sprintopts.channel(iScout).aperiodics(iWin).offset = sprintopts.topography.offset(iScout, iWin);
  1178. sprintopts.channel(iScout).aperiodics(iWin).exponent = sprintopts.topography.exponent(iScout, iWin);
  1179. sprintopts.channel(iScout).stats(iWin).MSE = fooofopts.stats(iScout).MSE;
  1180. sprintopts.channel(iScout).stats(iWin).r_squared = fooofopts.stats(iScout).r_squared;
  1181. sprintopts.channel(iScout).stats(iWin).frequency_wise_error = fooofopts.stats(iScout).frequency_wise_error;
  1182. nPeaks = 1:numel(fooofopts.peaks);
  1183. for iPeak = 1:nPeaks
  1184. if strcmp(fooofopts.peaks(iPeak).channel{1}, sprintMat.RowNames{iScout})
  1185. sprintopts.channel(iScout).peaks(iPeak).time = sprintMat.Time(iWin);
  1186. sprintopts.channel(iScout).peaks(iPeak).center_frequency = fooofopts.peaks(iPeak).center_frequency;
  1187. sprintopts.channel(iScout).peaks(iPeak).amplitude = fooofopts.peaks(iPeak).amplitude;
  1188. sprintopts.channel(iScout).peaks(iPeak).st_dev = fooofopts.peaks(iPeak).std_dev;
  1189. end
  1190. end
  1191. end
  1192. end
  1193. sprintopts.options.winLen = sprint_winlength;
  1194. sprintopts.options.Ovrlp = 0;
  1195. sprintopts.options.nAverage = 1;
  1196. sprintopts.options.hOT = 1; % not sure what this is
  1197. sprintopts.options.rmoutliers = 'no';
  1198. sprintopts.options.freq_range = fooofopts.options.freq_range;
  1199. sprintopts.options.peak_width_limits = fooofopts.options.peak_width_limits;
  1200. sprintopts.options.max_peaks = fooofopts.options.max_peaks;
  1201. sprintopts.options.min_peak_height = fooofopts.options.min_peak_height;
  1202. sprintopts.options.peak_threshold = fooofopts.options.peak_threshold;
  1203. sprintopts.options.aperiodic_mode = fooofopts.options.aperiodic_mode;
  1204. sprintopts.options.peak_type = fooofopts.options.peak_type;
  1205. sprintopts.options.proximity_threshold = fooofopts.options.proximity_threshold;
  1206. sprintopts.options.guess_weight = fooofopts.options.guess_weight;
  1207. sprintMat.Options.SPRiNT = sprintopts;
  1208. sprintMat.Options = rmfield(sprintMat.Options, 'FOOOF');
  1209. % add to database
  1210. sprintFiles = db_add(fooofWinFiles(1).iStudy, sprintMat);
  1211. % delete the windowed FOOOFs
  1212. bst_process('CallProcess', 'process_delete', fooofWinFiles, [], ...
  1213. 'target', 1); % Delete selected files
  1214. clear fooofWinFiles
  1215. % Process: Extract time
  1216. sprintFiles = bst_process('CallProcess', 'process_extract_time', sprintFiles, [], ...
  1217. 'timewindow', curr_opts.extracttime, ...
  1218. 'overwrite', 1);
  1219. % don't average across R/L hemispheres, it's too
  1220. % complicated here. Instead we'll baseline correct,
  1221. % then average across subjects, and can average across
  1222. % R/L at group level.
  1223. end
  1224. end
  1225. % if analyzed microsaccades, delete the imported epochs
  1226. if exist('msEpochFiles', 'var') && ~isempty(msEpochFiles)
  1227. % Process: Delete selected files
  1228. bst_process('CallProcess', 'process_delete', [msEpochFiles], [], ...
  1229. 'target', 1); % Delete selected files
  1230. end
  1231. clear allmats
  1232. end
  1233. %% finish
  1234. % Save and display report
  1235. ReportFile = bst_report('Save');
  1236. bst_report('Open', ReportFile);
  1237. end
  1238. end
  1239. end
  1240. end
  1241. end
  1242. end
  1243. end
  1244. end

UI_source_timefreq.m, under CC-BY-4.0 · at the source

Overview

  1. Montreal Neurological Institute, McGill University, Montreal, Quebec, Canada
  2. Neuroscience Institute, New York University Grossman School of Medicine, New York, NY, USA
  3. Centre for Human Brain Health, School of Psychology, University of Birmingham, Birmingham, UK
  4. Department of Neuroscience, Brown University, Providence, RI, USA
  5. Oxford Centre for Human Brain Activity, Oxford Centre for Integrative Neuroimaging, Department of Psychiatry, University of Oxford, Oxford, UK
  6. Department of Experimental Psychology, University of Oxford, Oxford, UK
  7. Centre de Recherche du Centre Hospitalier de l’Université de Montréal, Montréal, Quebec, Canada
  8. Department of Neuroscience, Université de Montréal, Montréal, Québec, Canada
Journal: Science advances, volume 12, issue 19, article eaea3919
Dates: received 7 July 2025; accepted 3 April 2026; published online 8 May 2026; in print May 2026
Type: Research article · Language: English
License: CC BY
Identifiers: DOI 10.1126/sciadv.aea3919 · PMID 42102217 · PMCID PMC13155359 · OpenAlex W7160710247
Open access: gold, a free copy (OpenAlex)
Status: code verified
Categories: MEG (modality), human (organism), cognitive (subfield)
Methods: Spectral & time-frequency, Preprocessing, Connectivity, Statistics, fMRI & imaging, Physiology & signal measures
MeSH: Brain*, Visual Cortex*, Visual Perception*, Brain Mapping, Consciousness, Humans, Illusions, Magnetoencephalography, Male, Photic Stimulation, Saccades (* major topic)
Topic: Multisensory perception and integration (Experimental and Cognitive Psychology, Psychology), according to OpenAlex
Funding: National Institute for Health Research (NIHR) (NIHR203316); Wellcome Trust Discovery Award (227420); Wellcome Trust (227420); National Institutes of Health (R01-EB026299); Canadian Institutes of Health Research Canada Research Chair Tier 1 (CRC-2017-00311); National Sciences and Engineering Research Council of Canada (RGPIN-2020-06889); Quebec Bio imaging Network (12.49)
Citations: not cited yet (Europe PMC); 111 references in the paper

Abstract

A longstanding debate in consciousness research concerns whether subjective perceptual experiences arise primarily from activity in sensory cortices or rely critically on inferences made in higher-order brain regions. We address this question using a compelling visual illusion (perceptual filling-in) that isolates neural processes underlying transitions from veridical to illusory conscious experience. Using whole-brain magnetoencephalographic imaging and rapid invisible frequency tagging, we tracked cortical dynamics during filling-in and assessed their modulation by microsaccadic eye movements, which are known to delay the illusion. We found that transitions in conscious perception involved two dissociable mechanisms: (i) boundary fading in visual cortex, reflected by increased excitability and reduced alpha-band activity, consistent with a shift in excitation-inhibition balance, and (ii) higher-order perceptual monitoring processes involving motor cortex, indexed by decreased high-alpha and beta-band activity. Microsaccades selectively reset both processes. These findings support a hierarchical framework in which visual and motor systems jointly shape transitions in conscious visual experience.

Reproduced under the paper's license (CC BY), from the paper cited above.

Repository

Its files are read in the Code ↔ Paper reader above, with 19 matches between paragraphs and lines of code.

Zenodo 18793257

License: CC-BY-4.0
State: the link answers, verified on 28 September 2026
Evidence: files inventoried
Languages: MATLAB (1)
Size: 11 files, 1 script
Software Heritage: not checked
Found in: “Data, code, and materials availability:”
Holds: README
Not found: license file, CITATION.cff, environment file, tests, continuous integration, documentation
Tools: Brainstorm (18 files), Statistics and Machine Learning Toolbox (11 files), Psychtoolbox (8 files), boundedline (3 files), Signal Processing Toolbox (2 files), Matplotlib (2 files), NumPy (2 files), fdr_bh (Benjamini-Hochberg FDR) (1 file), ggplot2 (1 file), MNE-Python (1 file), pandas (1 file), SciPy (1 file), seaborn (1 file)
Availability: 1 check, the latest on 28 September 2026: the link answers (HTTP 200)
  • 28 September 2026: the link answers (HTTP 200)
123 files

The paper's code and data availability statement is in the Data section.

Tracing map

Proposed by the machine: these links were found in the paper and verified at the source, without human review. The map will receive a Zenodo DOI once one of the paper's authors has validated it with their ORCID.

What the map holds:

  • 1 repository of the authors' code, each at its verified commit, with its license and how the link was found in the paper;
  • 120 scripts, each with its path and the digest of its content;
  • 19 matches between paragraphs of the paper and lines of the code (method lexical-v1);
  • neither the text of the paper nor the code itself.

Its JSON (tracing-map.json) is deposited on Zenodo with its DOI once the map is validated.

Data

Datasets cited

Data, code, and materials availability

All data and code needed to evaluate and reproduce the results in the paper are present in the paper and/or the Supplementary Materials. Deidentified raw data (MEG, MRI, eye-tracking, and behavior) have been deposited in a publicly available Zenodo repository located at https://doi.org/10.5281/zenodo.18825563. All analyses were conducted using open-source software toolboxes. Custom MATLAB, Python, and R scripts used for preprocessing, analysis, and figure generation are available at a second dedicated Zenodo repository located at https://doi.org/10.5281/zenodo.18793257. This study did not generate new materials.

Reproduced under the paper's license (CC BY), from the paper cited above.

Versions

The history of this record: each version stored by the harvester or made by a correction of its authors or of the maintainers of its code, and what changed in its facts. The texts of the paper (its abstract, its availability statements) are not part of it; versions that changed only those are not listed.

Version 1, 28 September 2026: the first record

Recorded: type, language, journal, volume, issue, pages, dates, 6 authors, 11 MeSH terms, 7 funders, 104 references.

Cite

This paper

Levinson, M., Waitt, A. E., Duecker, K., Wynn, S. C., Jensen, O., & Baillet, S. (2026). Hierarchical brain dynamics supporting visual perceptual transitions. Science advances, 12(19), eaea3919. https://doi.org/10.1126/sciadv.aea3919

BibTeX

@article{levinson2026hierarchical,
author = {Levinson, Max and Waitt, Alice E and Duecker, Katharina and Wynn, Syanah C and Jensen, Ole and Baillet, Sylvain},
title = {{Hierarchical brain dynamics supporting visual perceptual transitions}},
journal = {Science advances},
year = {2026},
month = may,
volume = {12},
number = {19},
pages = {eaea3919},
publisher = {American Association for the Advancement of Science},
issn = {2375-2548},
doi = {10.1126/sciadv.aea3919},
url = {https://doi.org/10.1126/sciadv.aea3919},
pmid = {42102217},
pmcid = {PMC13155359}
}

RIS

TY - JOUR
AU - Levinson, Max
AU - Waitt, Alice E
AU - Duecker, Katharina
AU - Wynn, Syanah C
AU - Jensen, Ole
AU - Baillet, Sylvain
TI - Hierarchical brain dynamics supporting visual perceptual transitions
T2 - Science advances
J2 - Sci Adv
PY - 2026
DA - 2026/05/08
VL - 12
IS - 19
SP - eaea3919
SN - 2375-2548
PB - American Association for the Advancement of Science
DO - 10.1126/sciadv.aea3919
UR - https://doi.org/10.1126/sciadv.aea3919
LA - en
ER -

CSL-JSON

{
"id": "10.1126/sciadv.aea3919",
"type": "article-journal",
"title": "Hierarchical brain dynamics supporting visual perceptual transitions",
"container-title": "Science advances",
"author": [
{
"family": "Levinson",
"given": "Max"
},
{
"family": "Waitt",
"given": "Alice E"
},
{
"family": "Duecker",
"given": "Katharina"
},
{
"family": "Wynn",
"given": "Syanah C"
},
{
"family": "Jensen",
"given": "Ole"
},
{
"family": "Baillet",
"given": "Sylvain"
}
],
"container-title-short": "Sci Adv",
"volume": "12",
"issue": "19",
"page": "eaea3919",
"DOI": "10.1126/sciadv.aea3919",
"PMID": "42102217",
"PMCID": "PMC13155359",
"ISSN": "2375-2548",
"publisher": "American Association for the Advancement of Science",
"URL": "https://doi.org/10.1126/sciadv.aea3919",
"language": "en",
"issued": {
"date-parts": [
[
2026,
5,
8
]
]
}
}

The tracing map gets a citation of its own once an author has validated it and it has a DOI.

Similar papers

The papers with a page that share the most with this one: the tools found in their code, their categories, datasets, cited references and authors, the rarest counting most.

[1] doi:10.1038/s41597-026-07350-9 [code]
An open multi-center MEG-EEG dataset for studying conscious visual perception.
Journal: Scientific data
In common: MNE-Python, Statistics and Machine Learning Toolbox, ggplot2, 5 other tools, MEG, 3 references, author Ole Jensen
[2] doi:10.1038/s41467-026-73916-1 [code]
Learned statistical regularity modulates anticipatory micro-saccades toward suppressed distractor locations.
Journal: Nature communications
In common: Signal Processing Toolbox, Statistics and Machine Learning Toolbox, cognitive, 4 references, author Ole Jensen
[3] doi:10.1126/sciadv.aee2305 [code]
Prediction of mild cognitive impairment progression using time-sensitive multimodal biomarkers.
Journal: Science advances
In common: ggplot2, pandas, Matplotlib, 1 other tool, MEG, 4 references, author Sylvain Baillet
[4] doi:10.1038/s41467-026-71151-2 [code]
Common and distinct neural correlates of social interaction processing and theory of mind in narratives.
Journal: Nature communications
In common: boundedline, fdr_bh (Benjamini-Hochberg FDR), Psychtoolbox, 7 other tools, cognitive
[5] doi:10.1162/imag.a.1229 [code]
40 Hz audiovisual stimulation improves sustained attention and related brain oscillations.
Journal: Imaging neuroscience (Cambridge, Mass.)
In common: fdr_bh (Benjamini-Hochberg FDR), Signal Processing Toolbox, Statistics and Machine Learning Toolbox, 5 other tools, 4 references
[6] doi:10.1038/s42003-026-09992-2 [code]
Dynamic competition between bottom-up saliency and top-down goals in early visual cortex.
Journal: Communications biology
In common: Statistics and Machine Learning Toolbox, 7 references
[7] doi:10.1093/cercor/bhag113 [code]
Long-term reliability and stability of parameterized resting state EEG: evidence from a five-year follow-up.
Journal: Cerebral cortex (New York, N.Y. : 1991)
In common: MNE-Python, ggplot2, seaborn, 4 other tools, 5 references
[8] doi:10.7554/elife.106050
Cross-modal interaction of human alpha activity does not reflect inhibition of early sensory processing in a frequency-tagging study using EEG and MEG.
Journal: eLife
In common: MEG, cognitive, 4 references, author Ole Jensen
[9] doi:10.7554/elife.100605 [code]
Age-related changes in ‘cortical’ 1/f dynamics are linked to cardiac activity
Journal: n/a
In common: MNE-Python, seaborn, pandas, 3 other tools, MEG, 5 references
[10] doi:10.1371/journal.pone.0351872 [code]
Decoding visual object recognition from EEG signals.
Journal: PloS one
In common: MNE-Python, pandas, SciPy, 2 other tools, 7 references

Contribute

The authors of this paper can claim it, correct its record and validate its tracing map, and the maintainers of its code (its owner, or a public member of its organization) correct what it says of their repository; anyone signed in can ask for its removal. Every request goes to OSCR's own machine, which answers it; your account page follows them.

Sign in with ORCID to claim this paper as one of its authors, correct its record or validate its tracing map: when the paper's metadata lists your ORCID iD, you are recognized at once. Maintainers of its code: sign in with GitHub, then claim the repository on your account page.

Request its removal

To ask OSCR to remove this record, the copies of its authors' scripts or its tracing map, use the removal request page: signed in, you say who you are, what to remove and why, then review and confirm the request. Published rules decide every request (how).

Discussion, reproductions, activity

Discussion: questions and error reports about this paper and its code, from signed-in readers and its authors. It opens with sign-in.

Reproductions: reports from readers who ran the authors' code: what they reproduced, with which environment, commit and data. It opens with sign-in.

Activity: what happens around this paper: new versions of its record, its map's validation, discussions and reproductions. It opens with sign-in.