Hierarchical brain dynamics supporting visual perceptual transitions.
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] § 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] § 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] § 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] § 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] § 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] § 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] § 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] § 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] § 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] § 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] § 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] § 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] § 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] § 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] § 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] § 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] § 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] § 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] § 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
- clear
- SubjectNames = string([301:321 323:330]); % all
- %SubjectNames = string([301:321 323 326 328 329]); % all that have mris
- %SubjectNames = string(301);
- %SubjectNames = string([328:330]);
- nSubjects = numel(SubjectNames);
- opts = UI_load_params(3);
- runwholebrainhighalpha = 1; % whole brain high alpha activity, taken from motor cortex result, avg'd in one time window
- runplvt = 1;
- runfiplvt = 1; % PLVt at intermodulation, 8 Hz and 16 Hz
- 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.
- runpsds = 1; % initial psds for visualization?
- combinecontrasts = 1; % usually 1, just means we run the normal analyses combined across both contrasts
- splitcontrasts = 0;
- powerscoutfunc = 1; % 1 = mean, 3 = PCA
- first_run = 1; % if 1, also run some initial things
- runret = 0; % analyze ret microsaccades
- bl_method = 'ersd'; % zscore, ersd, or bl - what baseline-correction method to use
- % rl_rowidx: each element contains the two scouts that are R L of the same
- 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';
- 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';
- for iAtlas = 1:numel(all_atlases)
- all_atlases(iAtlas).rl_label = ['RL_', all_atlases(iAtlas).label];
- end
- mergerl = [0 1]; % motor is not merged across hemispheres; localizer is.
- use_atlases = 1; % just motor
- %use_atlases = 2; % just flicker
- %use_atlases = [1 2]; % both
- % set processing options for each epoch type
- epoch_types = {'stimon', 'button', 'button_noms', 'ms_instim', 'ms_infix'};
- % Have to run retinotopy part first (UI_ret_analysis), then manually define scouts,
- % then run this script.
- for iSubj = 1:nSubjects
- sname = ['s', char(SubjectNames(iSubj))];
- % Start a new report
- bst_report('Start');
- % get 8 Hz file
- f8Files = bst_process('CallProcess', 'process_select_files_matrix', [], [], ...
- 'subjectname', sname, ...
- 'condition', 'sin_8Hz', ...
- 'tag', [], ...
- 'includebad', 0, ...
- 'includeintra', 0, ...
- 'includecommon', 0);
- % get 16 Hz file
- f16Files = bst_process('CallProcess', 'process_select_files_matrix', [], [], ...
- 'subjectname', sname, ...
- 'condition', 'sin_16Hz', ...
- 'tag', [], ...
- 'includebad', 0, ...
- 'includeintra', 0, ...
- 'includecommon', 0);
- f11Files = bst_process('CallProcess', 'process_select_files_matrix', [], [], ...
- 'subjectname', sname, ...
- 'condition', 'sin_11Hz', ...
- 'tag', [], ...
- 'includebad', 0, ...
- 'includeintra', 0, ...
- 'includecommon', 0);
- % get 60 Hz file
- f60Files = bst_process('CallProcess', 'process_select_files_matrix', [], [], ...
- 'subjectname', sname, ...
- 'condition', 'sin_60Hz', ...
- 'tag', [], ...
- 'includebad', 0, ...
- 'includeintra', 0, ...
- 'includecommon', 0);
- %% retinotopy microsaccades within scouts
- if runret
- % Process: Select data files in: SUBJ
- retFiles = bst_process('CallProcess', 'process_select_files_results', [], [], ...
- 'subjectname', sname, ...
- 'condition', ['ret_sss_notch_band'], ...
- 'tag', [], ...
- 'includebad', 0, ...
- 'includeintra', 0, ...
- 'includecommon', 0);
- % Process: Ignore file names with tag: Avg
- retFiles = bst_process('CallProcess', 'process_select_tag', retFiles, [], ...
- 'tag', 'average', ...
- 'search', 1, ... % Search the file paths
- 'select', 2); % Ignore the files with the tag
- for iEpoch_type = 1:numel(epoch_types)
- epochname = epoch_types{iEpoch_type};
- curr_opts = opts.epochs.(epochname);
- if strcmp(epochname, 'button_noms') && sum(strcmp(sname, {'s318', 's320', 's324'}))
- continue
- end
- epochFiles = bst_process('CallProcess', 'process_select_tag', retFiles, [], ...
- 'tag', curr_opts.tag, ...
- 'search', 3, ... % Search the parent file names
- 'select', 1); % Select the files with the tag
- % Process: Ignore file names with tag: Avg
- epochFiles = bst_process('CallProcess', 'process_select_tag', epochFiles, [], ...
- 'tag', 'Avg', ...
- 'search', 3, ... % Search the parent file name
- 'select', 2); % Ignore the files with the tag
- % don't take the left / right / out / in specific epochs (these are copies)
- ignoreTags = {'left', 'right', 'outward', 'inward', 'noms'};
- for iTag = 1:numel(ignoreTags)
- if ~contains(curr_opts.tag, ignoreTags{iTag})
- epochFiles = bst_process('CallProcess', 'process_select_tag', epochFiles, [], ...
- 'tag', ignoreTags{iTag}, ...
- 'search', 1, ... % Search the file paths
- 'select', 2); % Ignore the files with the tag
- epochFiles = bst_process('CallProcess', 'process_select_tag', epochFiles, [], ...
- 'tag', ignoreTags{iTag}, ...
- 'search', 3, ... % Search the parent file name
- 'select', 2); % Ignore the files with the tag
- end
- end
- if isempty(epochFiles) | numel(epochFiles) < 2
- continue
- end
- for iAtlas = use_atlases
- curr_atlas = all_atlases(iAtlas);
- %% scout plvt
- if runplvt
- conn_metric = 'PLVt';
- % PHASE LOCKING WITH PHOTODIODE
- % Process: Select data files
- sensorepochFiles = bst_process('CallProcess', 'process_select_files_data', [], [], ...
- 'subjectname', sname, ...
- 'condition', ['ret_sss_notch_band'], ...
- 'tag', curr_opts.tag, ...
- 'includebad', 0, ...
- 'includeintra', 0, ...
- 'includecommon', 0);
- % Process: Ignore file names with tag: bl.mat (don't use baseline-corrected)
- sensorepochFiles = bst_process('CallProcess', 'process_select_tag', sensorepochFiles, [], ...
- 'tag', 'bl.mat', ...
- 'search', 1, ... % Search the file paths
- 'select', 2); % Ignore the files with the tag
- % don't take the wrong epochs
- ignoreTags = {'noms'};
- for iTag = 1:numel(ignoreTags)
- if ~contains(curr_opts.tag, ignoreTags{iTag})
- sensorepochFiles = bst_process('CallProcess', 'process_select_tag', sensorepochFiles, [], ...
- 'tag', ignoreTags{iTag}, ...
- 'search', 1, ... % Search the file paths
- 'select', 2); % Ignore the files with the tag
- end
- end
- % Process: Ignore file names with tag: Avg
- sensorepochFiles = bst_process('CallProcess', 'process_select_tag', sensorepochFiles, [], ...
- 'tag', 'Avg', ...
- 'search', 2, ... % Search the file names
- 'select', 2); % Ignore the files with the tag
- for iDiode = 1:2
- diode = opts.diode_channels{iDiode};
- useband = opts.flicker_bands{iDiode};
- % PLV in localizer scouts
- % Process: PLV: Phase locking value
- connectivityScout(iDiode) = bst_process('CallProcess', 'process_plv2', sensorepochFiles, epochFiles, ...
- 'timewindow', curr_opts.fullwindow, ...
- 'src_channel', diode, ...
- 'dest_scouts', {curr_atlas.name, curr_atlas.scouts2use}, ...
- 'scoutfunc', 'mean', ... % Mean
- 'scouttime', 'after', ... % After
- 'scoutfuncaft', 'mean', ... % Mean
- 'tfedit', struct(...
- 'Comment', 'Complex', ...
- 'TimeBands', [], ...
- 'Freqs', {useband}, ...
- 'ClusterFuncTime', 'none', ...
- 'Measure', 'none', ...
- 'Output', 'all', ...
- 'SaveKernel', 0), ...
- 'plvmethod', 'plv', ... % PLV: Phase locking value
- 'tfmeasure', 'hilbert', ... % Hilbert transform
- 'timeres', 'full', ... % Full (requires epochs)
- 'plvmeasure', 2, ... % Magnitude
- 'outputmode', 'avg'); % Save average connectivity matrix (one file)
- % Process: Set name:
- connectivityScout(iDiode) = bst_process('CallProcess', 'process_set_comment', connectivityScout(iDiode), [], ...
- 'tag', ['Scouts_', curr_atlas.label, ',Avg: ', conn_metric, ': ', diode, ' ', curr_opts.label, extralabel], ...
- 'isindex', 0);
- end
- % Process: PLV: Phase locking value with 60 Hz sin (control)
- f60FilesMulti = repmat(f60Files, 1, numel(epochFiles));
- connectivity60Scout = bst_process('CallProcess', 'process_plv2', f60FilesMulti, epochFiles, ...
- 'timewindow', curr_opts.fullwindow, ...
- 'src_channel', '', ...
- 'dest_scouts', {curr_atlas.name, curr_atlas.scouts2use}, ...
- 'scoutfunc', 'mean', ... % Mean
- 'scouttime', 'after', ... % After
- 'scoutfuncaft', 'mean', ... % Mean
- 'tfedit', struct(...
- 'Comment', 'Complex', ...
- 'TimeBands', [], ...
- 'Freqs', {{'fcontrol', '59, 61', 'mean'}}, ...
- 'ClusterFuncTime', 'none', ...
- 'Measure', 'none', ...
- 'Output', 'all', ...
- 'SaveKernel', 0), ...
- 'plvmethod', 'plv', ... % PLV: Phase locking value
- 'tfmeasure', 'hilbert', ... % Hilbert transform
- 'timeres', 'full', ... % Full (requires epochs)
- 'plvmeasure', 2, ... % Magnitude
- 'outputmode', 'avg'); % Save average connectivity matrix (one file)
- % Process: Set name:
- connectivity60Scout = bst_process('CallProcess', 'process_set_comment', connectivity60Scout, [], ...
- 'tag', ['Scouts_', curr_atlas.label, ',Avg: ', conn_metric, ' 60 ', curr_opts.label, extralabel], ...
- 'isindex', 0);
- % combine into one file (not merging R/L yet)
- mat56 = in_bst_timefreq(connectivityScout(1).FileName);
- mat64 = in_bst_timefreq(connectivityScout(2).FileName);
- mat60 = in_bst_timefreq(connectivity60Scout.FileName);
- matall = mat56;
- matall.Freqs = {'fp', '55,57', 'mean'; 'fc', '63,65', 'mean'; 'fcontrol', '59, 61', 'mean'};
- matall.RefRowNames = {'MISC'};
- matall.TF(:, :, 2) = mat64.TF;
- matall.TF(:, :, 3) = mat60.TF;
- matall.Comment = ['Scouts_', curr_atlas.label, ',Avg: ', conn_metric, ' fpfc ', curr_opts.label, ' ret'];
- scout_allconnectivity = db_add(connectivityScout(1).iStudy, matall);
- % Process: Extract time
- scout_allconnectivityTime = bst_process('CallProcess', 'process_extract_time', scout_allconnectivity, [], ...
- 'timewindow', curr_opts.extracttime, ...
- 'overwrite', 1);
- % Process: Event-related perturbation (ERS/ERD)
- scout_allconnectivityERSD = bst_process('CallProcess', 'process_baseline_norm', scout_allconnectivityTime, [], ...
- 'baseline', curr_opts.baseline, ...
- 'method', bl_method, ... % Event-related perturbation (ERS/ERD): x_std = (x - μ) / μ * 100
- 'overwrite', 0);
- % Process: Delete selected files
- bst_process('CallProcess', 'process_delete', [connectivityScout, connectivity60Scout], [], ...
- 'target', 1); % Delete selected files
- % Process: combine RL hemispheres
- if mergerl(iAtlas)
- for iScout = 1:numel(curr_atlas.rl_rowidx)
- RL_scoutconnectivity(iScout) = bst_process('CallProcess', 'process_extract_values', scout_allconnectivityERSD, [], ...
- 'timewindow', [], ...
- 'freqrange', [0, 100], ...
- 'rows', curr_atlas.rl_rowidx{iScout}, ...
- 'isabs', 0, ...
- 'avgtime', 0, ...
- 'avgrow', 1, ...
- 'avgfreq', 0, ...
- 'matchrows', 0, ...
- 'dim', 2, ... % Concatenate time (dimension 2)
- 'Comment', ['RL_scout,Avg: ', conn_metric, ' ', curr_opts.label, ' ret']);
- end
- clear allmats
- allmats(1) = in_bst_timefreq(RL_scoutconnectivity(1).FileName);
- matall = allmats(1);
- matall.RowNames = curr_atlas.rl_rownames;
- matall.Comment = [curr_atlas.rl_label, ',Avg: ', conn_metric, ' fpfc ', curr_opts.label, ' ret'];
- for iScout = 2:numel(curr_atlas.rl_rowidx)
- allmats(iScout) = in_bst_timefreq(RL_scoutconnectivity(iScout).FileName);
- matall.TF(iScout, :, :) = allmats(iScout).TF;
- end
- RL_allconnectivity = db_add(RL_scoutconnectivity(1).iStudy, matall);
- % Process: Delete selected files
- bst_process('CallProcess', 'process_delete', [RL_scoutconnectivity], [], ...
- 'target', 1); % Delete selected files
- end
- end
- %% custom SPRiNT
- if runsprintcustom
- % fooofs each moving window after averaging SFFTs across
- % trials.
- % method: extract each time window, run FOOOF, then combine
- % outputs into a SPRiNT structure.
- % set windows. winlength = 1 second, but at intervals of
- % 100ms.
- % make sure we'll cover the full extracttime window, but
- % don't waste compute on extra windows
- fulltime = curr_opts.extracttime + [-sprint_winlength/2, sprint_winlength/2];
- winstarts = fulltime(1):sprint_winstep:fulltime(2)-sprint_winlength+.001;
- winends = fulltime(1)+sprint_winlength:sprint_winstep:fulltime(2);
- nWin = numel(winstarts);
- % extract time windows, FFT, average them, and FOOOF.
- clear winFiles
- for iAtlas = use_atlases
- curr_atlas = all_atlases(iAtlas);
- for iWin = 1:nWin
- % Process: Power spectrum density (Welch)
- fftWinFiles = bst_process('CallProcess', 'process_psd', epochFiles, [], ...
- 'timewindow', [winstarts(iWin), winends(iWin)], ...
- 'win_length', sprint_winlength, ...
- 'win_overlap', 0, ...
- 'units', 'physical', ... % Physical: U2/Hz
- 'clusters', {curr_atlas.name, curr_atlas.scouts2use}, ...
- 'scoutfunc', 1, ... % Mean
- 'win_std', 0, ...
- 'edit', struct(...
- 'Comment', 'Scout psd,Avg,Power', ...
- 'TimeBands', [], ...
- 'Freqs', [], ...
- 'ClusterFuncTime', 'after', ...
- 'Measure', 'power', ...
- 'Output', 'average', ...
- 'SaveKernel', 0));
- % Process: specparam: Fitting oscillations and 1/f
- fooofWinFiles(iWin) = bst_process('CallProcess', 'process_fooof', fftWinFiles, [], ...
- 'implementation', 'matlab', ... % Matlab
- 'freqrange', [1, sprint_maxFreq], ...
- 'powerline', '50', ... % 50 Hz
- 'peaktype', 'gaussian', ... % Gaussian
- 'peakwidth', [0.5, 12], ...
- 'maxpeaks', 3, ...
- 'minpeakheight', 1, ...
- 'proxthresh', 2, ...
- 'apermode', 'fixed', ... % Fixed
- 'guessweight', 'none', ... % None
- 'sorttype', 'param', ... % Peak parameters
- 'sortparam', 'frequency', ... % Frequency
- 'sortbands', {'delta', '2, 4'; 'theta', '5, 7'; 'alpha', '8, 12'; 'beta', '15, 29'; 'gamma1', '30, 59'; 'gamma2', '60, 90'});
- % import to MATLAB.
- fooofMats(iWin) = in_bst(fooofWinFiles(iWin).FileName);
- % delete extracted ffts
- bst_process('CallProcess', 'process_delete', fftWinFiles, [], ...
- 'target', 1); % Delete selected files
- clear fftWinFiles
- end
- % manually convert to a SPRiNT structure.
- sprintMat = fooofMats(1); % get template from first fooof file.
- sprintMat.Comment = ['Scouts_', curr_atlas.label, ',Avg: SPRiNT_custom ', curr_opts.label, ' ret'];
- sprintMat.Time = winstarts + sprint_winlength/2;
- sprintMat.Freqs = sprintMat.Freqs(1:sprint_maxFreq);
- sprintMat.Method = 'sprint';
- sprintMat.RowNames = sprintMat.RowNames';
- sprintMat.nAvg = numel(epochFiles); sprintMat.Leff = numel(epochFiles);
- sprintMat.TF = sprintMat.TF(:, :, 1:sprint_maxFreq); % init TF
- sprintMat.Options.Method = 'sprint';
- sprintopts = struct;
- sprintopts.freqs = sprintMat.Options.FOOOF.freqs;
- for iScout = 1:numel(sprintMat.RowNames)
- sprintopts.channel(iScout).name = sprintMat.RowNames{iScout};
- sprintopts.channel(iScout).peaks = struct('time', 'center_frequency', 'amplitude', 'st_dev');
- for iWin = 1:nWin
- sprintMat.TF(iScout, iWin, :) = fooofMats(iWin).TF(iScout, :, 1:sprint_maxFreq);
- fooofopts = fooofMats(iWin).Options.FOOOF;
- sprintopts.topography.exponent(iScout, iWin) = fooofopts.aperiodics(iScout).exponent;
- sprintopts.topography.offset(iScout, iWin) = fooofopts.aperiodics(iScout).offset;
- sprintopts.SPRiNT_models(iScout, iWin, :) = fooofopts.data(iScout).fooofed_spectrum;
- sprintopts.peak_models(iScout, iWin, :) = fooofopts.data(iScout).peak_fit;
- sprintopts.aperiodic_models(iScout, iWin, :) = fooofopts.data(iScout).ap_fit;
- sprintopts.channel(iScout).data(iWin).time = sprintMat.Time(iWin);
- sprintopts.channel(iScout).data(iWin).aperiodic_params = [sprintopts.topography.offset(iScout, iWin), sprintopts.topography.exponent(iScout, iWin)];
- sprintopts.channel(iScout).data(iWin).peak_params = fooofopts.data(iScout).peak_params;
- sprintopts.channel(iScout).data(iWin).peak_types = fooofopts.data(iScout).peak_types;
- sprintopts.channel(iScout).data(iWin).ap_fit = fooofopts.data(iScout).ap_fit;
- sprintopts.channel(iScout).data(iWin).peak_fit = fooofopts.data(iScout).peak_fit;
- sprintopts.channel(iScout).data(iWin).fooofed_spectrum = fooofopts.data(iScout).fooofed_spectrum;
- sprintopts.channel(iScout).data(iWin).power_spectrum = fooofMats(iWin).TF(iScout, :, 1:sprint_maxFreq);
- sprintopts.channel(iScout).data(iWin).error = fooofopts.data.error;
- sprintopts.channel(iScout).data(iWin).r_squared = fooofopts.data.r_squared;
- sprintopts.channel(iScout).aperiodics(iWin).time = sprintMat.Time(iWin);
- sprintopts.channel(iScout).aperiodics(iWin).offset = sprintopts.topography.offset(iScout, iWin);
- sprintopts.channel(iScout).aperiodics(iWin).exponent = sprintopts.topography.exponent(iScout, iWin);
- sprintopts.channel(iScout).stats(iWin).MSE = fooofopts.stats(iScout).MSE;
- sprintopts.channel(iScout).stats(iWin).r_squared = fooofopts.stats(iScout).r_squared;
- sprintopts.channel(iScout).stats(iWin).frequency_wise_error = fooofopts.stats(iScout).frequency_wise_error;
- nPeaks = 1:numel(fooofopts.peaks);
- for iPeak = 1:nPeaks
- if strcmp(fooofopts.peaks(iPeak).channel{1}, sprintMat.RowNames{iScout})
- sprintopts.channel(iScout).peaks(iPeak).time = sprintMat.Time(iWin);
- sprintopts.channel(iScout).peaks(iPeak).center_frequency = fooofopts.peaks(iPeak).center_frequency;
- sprintopts.channel(iScout).peaks(iPeak).amplitude = fooofopts.peaks(iPeak).amplitude;
- sprintopts.channel(iScout).peaks(iPeak).st_dev = fooofopts.peaks(iPeak).std_dev;
- end
- end
- end
- end
- sprintopts.options.winLen = sprint_winlength;
- sprintopts.options.Ovrlp = 0;
- sprintopts.options.nAverage = 1;
- sprintopts.options.hOT = 1; % not sure what this is
- sprintopts.options.rmoutliers = 'no';
- sprintopts.options.freq_range = fooofopts.options.freq_range;
- sprintopts.options.peak_width_limits = fooofopts.options.peak_width_limits;
- sprintopts.options.max_peaks = fooofopts.options.max_peaks;
- sprintopts.options.min_peak_height = fooofopts.options.min_peak_height;
- sprintopts.options.peak_threshold = fooofopts.options.peak_threshold;
- sprintopts.options.aperiodic_mode = fooofopts.options.aperiodic_mode;
- sprintopts.options.peak_type = fooofopts.options.peak_type;
- sprintopts.options.proximity_threshold = fooofopts.options.proximity_threshold;
- sprintopts.options.guess_weight = fooofopts.options.guess_weight;
- sprintMat.Options.SPRiNT = sprintopts;
- sprintMat.Options = rmfield(sprintMat.Options, 'FOOOF');
- % add to database
- sprintFiles = db_add(fooofWinFiles(1).iStudy, sprintMat);
- % delete the windowed FOOOFs
- bst_process('CallProcess', 'process_delete', fooofWinFiles, [], ...
- 'target', 1); % Delete selected files
- clear fooofWinFiles
- % Process: Extract time
- sprintFiles = bst_process('CallProcess', 'process_extract_time', sprintFiles, [], ...
- 'timewindow', curr_opts.extracttime, ...
- 'overwrite', 1);
- % don't average across R/L hemispheres, it's too
- % complicated here. Instead we'll baseline correct,
- % then average across subjects, and can average across
- % R/L at group level.
- end
- end
- %% whole brain analyses (combined contrast)
- if runwholebrainhighalpha
- % extract only average of high alpha (10-15 Hz) from morlet
- % wavelets or hilbert transform.
- % project to template and smooth.
- % set times of interest
- buffer_time = [-0.4, 0.4]; % 4 cycles of 10Hz for edge effects
- switch epochname
- case 'button'
- target_time = [-1.25, -0.75];
- case 'ms_instim'
- target_time = [0.5 0.75];
- otherwise
- continue
- end
- timebands2use = {'baseline', num2str(curr_opts.baseline), 'mean'; 'target', num2str(target_time), 'mean'};
- % use hilbert transform, much faster
- mergedFiles = bst_process('CallProcess', 'process_hilbert', epochFiles, [], ...
- 'clusters', [], ...
- 'scoutfunc', 1, ...
- 'edit', struct(...
- 'Comment', ['Wholebrain,Avg,Power, highalpha ', curr_opts.label, extralabel], ...
- 'TimeBands', {timebands2use}, ...
- 'Freqs', {{'highalpha', '10,15', 'mean'}}, ...
- 'ClusterFuncTime', 'none', ...
- 'Measure', 'power', ...
- 'Output', 'average', ...
- 'RemoveEvoked', 0, ...
- 'SaveKernel', 0), ...
- 'normalize2020', 0, ...
- 'normalize', 'none', ... % None: Save non-standardized time-frequency maps
- 'mirror', 0);
- % remove timebands from file
- inMerge = in_bst(mergedFiles.FileName);
- inMerge.Time = [mean(curr_opts.baseline), mean(target_time)];
- inMerge = rmfield(inMerge, 'TimeBands');
- bst_save(file_fullpath(mergedFiles.FileName), inMerge, 'v7.3');
- db_reload_studies(mergedFiles.iStudy);
- % project to template & smooth
- % Process: Project on default anatomy: surface
- templateFiles = bst_process('CallProcess', 'process_project_sources', mergedFiles, [], ...
- 'headmodeltype', 'surface'); % Cortex surface
- % Process: Spatial smoothing (3.00)
- templateFiles = bst_process('CallProcess', 'process_ssmooth', templateFiles, [], ...
- 'fwhm', 3, ...
- 'method', 'geodesic_dist', ... % Geodesic (mm)(recommended)
- 'overwrite', 1);
- end
- %% Init Main illusion task (blocks 1-7)
- if ~runret % don't run main task if we set above to run retinotopy
- % epoch microsaccade files if analyzing them
- ms_epochnames = {'ms_instim', 'ms_infix'};
- msEpochFiles = [];
- for iMSEpoch = 1:numel(ms_epochnames)
- if sum(strcmp(epoch_types, ms_epochnames{iMSEpoch}))
- epoch_out = UI_epoch({ms_epochnames{iMSEpoch}}, SubjectNames(iSubj));
- % save files here to delete at the end
- msEpochFiles = [msEpochFiles, epoch_out{1}, epoch_out{2}];
- end
- end
- % Input files
- % Process: Select data files in: SUBJ
- allFiles = bst_process('CallProcess', 'process_select_files_results', [], [], ...
- 'subjectname', sname, ...
- 'condition', [], ...
- 'tag', [], ...
- 'includebad', 0, ...
- 'includeintra', 0, ...
- 'includecommon', 0);
- % Process: Ignore file names with tag: ret
- allFiles = bst_process('CallProcess', 'process_select_tag', allFiles, [], ...
- 'tag', 'ret', ...
- 'search', 1, ... % Search the file paths
- 'select', 2); % Ignore the files with the tag
- %% run blocktypes
- for blocktype = [2, 1] % first do main task blocks 1-6, then block 7
- % Process: Ignore file names with tag: block7
- blockFiles = bst_process('CallProcess', 'process_select_tag', allFiles, [], ...
- 'tag', 'block7', ...
- 'search', 1, ... % Search the file paths
- 'select', blocktype); % Select/Ignore the files with the tag
- if subset
- if blocktype == 1
- continue % don't analyze block7 when we're just running the main task subset
- elseif blocktype == 2
- % get block7 files to start
- block7Files = bst_process('CallProcess', 'process_select_tag', allFiles, [], ...
- 'tag', 'block7', ...
- 'search', 1, ... % Search the file paths
- 'select', 1); % Select
- end
- end
- %% run epochs
- for iEpoch_type = 1:numel(epoch_types)
- epochname = epoch_types{iEpoch_type};
- curr_opts = opts.epochs.(epochname);
- if strcmp(epochname, 'button_noms') && sum(strcmp(sname, {'s318', 's320', 's324'}))
- continue
- end
- epochFiles = bst_process('CallProcess', 'process_select_tag', blockFiles, [], ...
- 'tag', curr_opts.tag, ...
- 'search', 3, ... % Search the parent file names
- 'select', 1); % Select the files with the tag
- % Process: Ignore file names with tag: Avg
- epochFiles = bst_process('CallProcess', 'process_select_tag', epochFiles, [], ...
- 'tag', 'Avg', ...
- 'search', 3, ... % Search the parent file name
- 'select', 2); % Ignore the files with the tag
- epochFiles_bl = bst_process('CallProcess', 'process_select_tag', epochFiles, [], ...
- 'tag', 'bl.mat', ...
- 'search', 1, ... % Search the file paths
- 'select', 1); % Select the files with the tag
- % Process: Ignore file names with tag: bl.mat (don't use baseline-corrected)
- epochFiles = bst_process('CallProcess', 'process_select_tag', epochFiles, [], ...
- 'tag', 'bl.mat', ...
- 'search', 1, ... % Search the file paths
- 'select', 2); % Ignore the files with the tag
- % don't take the wrong epochs
- ignoreTags = {'noms'};
- for iTag = 1:numel(ignoreTags)
- if ~contains(curr_opts.tag, ignoreTags{iTag})
- epochFiles = bst_process('CallProcess', 'process_select_tag', epochFiles, [], ...
- 'tag', ignoreTags{iTag}, ...
- 'search', 3, ... % Search the parent filenames
- 'select', 2); % Ignore the files with the tag
- epochFiles = bst_process('CallProcess', 'process_select_tag', epochFiles, [], ...
- 'tag', ignoreTags{iTag}, ...
- 'search', 1, ... % Search the file paths
- 'select', 2); % Ignore the files with the tag
- end
- end
- if isempty(epochFiles) | numel(epochFiles) < 2
- continue
- end
- if subset % collect block7 trials too, to get subset of main task trials with same trial count.
- epoch7Files = bst_process('CallProcess', 'process_select_tag', block7Files, [], ...
- 'tag', curr_opts.tag, ...
- 'search', 3, ... % Search the parent file names
- 'select', 1); % Select the files with the tag
- % Process: Ignore file names with tag: Avg
- epoch7Files = bst_process('CallProcess', 'process_select_tag', epoch7Files, [], ...
- 'tag', 'Avg', ...
- 'search', 3, ... % Search the parent file name
- 'select', 2); % Ignore the files with the tag
- % Process: Ignore file names with tag: bl.mat (don't use baseline-corrected)
- epoch7Files = bst_process('CallProcess', 'process_select_tag', epoch7Files, [], ...
- 'tag', 'bl.mat', ...
- 'search', 1, ... % Search the file paths
- 'select', 2); % Ignore the files with the tag
- % don't take the wrong epochs
- ignoreTags = {'noms'};
- for iTag = 1:numel(ignoreTags)
- if ~contains(curr_opts.tag, ignoreTags{iTag})
- epoch7Files = bst_process('CallProcess', 'process_select_tag', epoch7Files, [], ...
- 'tag', ignoreTags{iTag}, ...
- 'search', 3, ... % Search the parent filenames
- 'select', 2); % Ignore the files with the tag
- epoch7Files = bst_process('CallProcess', 'process_select_tag', epoch7Files, [], ...
- 'tag', ignoreTags{iTag}, ...
- 'search', 1, ... % Search the file paths
- 'select', 2); % Ignore the files with the tag
- end
- end
- if isempty(epoch7Files) | numel(epoch7Files) < 2
- continue
- end
- % Process: Select uniform number of files [uniform]
- % so the files are uniformly distributed along the list of trials, which is
- % ordered block1,block2, etc...
- % i.e. a pseudo-random but fully reproducible selection, not necessarily biased towards
- % any particular task block.
- [epochFiles, epoch7Files] = bst_process('CallProcess', 'process_select_uniform2', epochFiles, epoch7Files, ...
- 'nfiles', 0, ...
- 'method', 4); % Uniformly distributed
- end
- for iAtlas = use_atlases
- curr_atlas = all_atlases(iAtlas);
- %% psds
- if strcmp(epochname, 'stimon') && runpsds % get avg FFTs or PSDs for quality control.
- psdscout = bst_process('CallProcess', 'process_psd', epochFiles, [], ...
- 'timewindow', [3, 5], ...
- 'win_length', 1, ...
- 'win_overlap', 50, ...
- 'units', 'physical', ... % Physical: U2/Hz
- 'clusters', {curr_atlas.name, curr_atlas.scouts2use}, ...
- 'scoutfunc', 1, ... % Mean
- 'win_std', 0, ...
- 'edit', struct(...
- 'Comment', 'Scouts,Avg,Power', ...
- 'TimeBands', [], ...
- 'Freqs', [], ...
- 'ClusterFuncTime', 'after', ...
- 'Measure', 'power', ...
- 'Output', 'average', ...
- 'SaveKernel', 0));
- bst_process('CallProcess', 'process_set_comment', psdscout, [], ...
- 'tag', ['PSD ', curr_atlas.label, ' stimon'], ...
- 'isindex', 0);
- psdscout = bst_process('CallProcess', 'process_psd', epochFiles, [], ...
- 'timewindow', [-2, 0], ...
- 'win_length', 1, ...
- 'win_overlap', 50, ...
- 'units', 'physical', ... % Physical: U2/Hz
- 'clusters', {curr_atlas.name, curr_atlas.scouts2use}, ...
- 'scoutfunc', 1, ... % Mean
- 'win_std', 0, ...
- 'edit', struct(...
- 'Comment', 'Scouts,Avg,Power', ...
- 'TimeBands', [], ...
- 'Freqs', [], ...
- 'ClusterFuncTime', 'after', ...
- 'Measure', 'power', ...
- 'Output', 'average', ...
- 'SaveKernel', 0));
- bst_process('CallProcess', 'process_set_comment', psdscout, [], ...
- 'tag', ['PSD ', curr_atlas.label, ' fix'], ...
- 'isindex', 0);
- elseif strcmp(epochname, 'button') && runpsds % get PSDs for button epoch to compare 1/f slope/intercept
- % button_baseline: t -4 to -3 s
- % button_filling: t -1.5 to -0.5 s
- psdscout = bst_process('CallProcess', 'process_psd', epochFiles, [], ...
- 'timewindow', [-4 -3], ...
- 'win_length', 1, ...
- 'win_overlap', 50, ...
- 'units', 'physical', ... % Physical: U2/Hz
- 'clusters', {curr_atlas.name, curr_atlas.scouts2use}, ...
- 'scoutfunc', 1, ... % Mean
- 'win_std', 0, ...
- 'edit', struct(...
- 'Comment', 'Scouts,Avg,Power', ...
- 'TimeBands', [], ...
- 'Freqs', [], ...
- 'ClusterFuncTime', 'after', ...
- 'Measure', 'power', ...
- 'Output', 'average', ...
- 'SaveKernel', 0));
- bst_process('CallProcess', 'process_set_comment', psdscout, [], ...
- 'tag', ['PSD ', curr_atlas.label, ' button_baseline'], ...
- 'isindex', 0);
- psdscout = bst_process('CallProcess', 'process_psd', epochFiles, [], ...
- 'timewindow', [-1.5 -0.5], ...
- 'win_length', 1, ...
- 'win_overlap', 50, ...
- 'units', 'physical', ... % Physical: U2/Hz
- 'clusters', {curr_atlas.name, curr_atlas.scouts2use}, ...
- 'scoutfunc', 1, ... % Mean
- 'win_std', 0, ...
- 'edit', struct(...
- 'Comment', 'Scouts,Avg,Power', ...
- 'TimeBands', [], ...
- 'Freqs', [], ...
- 'ClusterFuncTime', 'after', ...
- 'Measure', 'power', ...
- 'Output', 'average', ...
- 'SaveKernel', 0));
- bst_process('CallProcess', 'process_set_comment', psdscout, [], ...
- 'tag', ['PSD ', curr_atlas.label, ' button_filling'], ...
- 'isindex', 0);
- end
- %% scout combine contrasts
- if combinecontrasts % run power analyses combined across both contrasts
- %% scout plvt
- if runplvt
- conn_metric = 'PLVt';
- % PHASE LOCKING WITH PHOTODIODE
- % Process: Select data files
- sensorepochFiles = bst_process('CallProcess', 'process_select_files_data', [], [], ...
- 'subjectname', sname, ...
- 'condition', [], ...
- 'tag', curr_opts.tag, ...
- 'includebad', 0, ...
- 'includeintra', 0, ...
- 'includecommon', 0);
- % Process: Ignore file names with tag: bl.mat (don't use baseline-corrected)
- sensorepochFiles = bst_process('CallProcess', 'process_select_tag', sensorepochFiles, [], ...
- 'tag', 'bl.mat', ...
- 'search', 1, ... % Search the file paths
- 'select', 2); % Ignore the files with the tag
- % don't take the wrong epochs
- ignoreTags = {'noms'};
- for iTag = 1:numel(ignoreTags)
- if ~contains(curr_opts.tag, ignoreTags{iTag})
- sensorepochFiles = bst_process('CallProcess', 'process_select_tag', sensorepochFiles, [], ...
- 'tag', ignoreTags{iTag}, ...
- 'search', 1, ... % Search the file paths
- 'select', 2); % Ignore the files with the tag
- end
- end
- % Process: Ignore file names with tag: Avg
- sensorepochFiles = bst_process('CallProcess', 'process_select_tag', sensorepochFiles, [], ...
- 'tag', 'Avg', ...
- 'search', 2, ... % Search the file names
- 'select', 2); % Ignore the files with the tag
- % Process: Ignore file names with tag: ret
- sensorepochFiles = bst_process('CallProcess', 'process_select_tag', sensorepochFiles, [], ...
- 'tag', 'ret', ...
- 'search', 1, ... % Search the file paths
- 'select', 2); % Ignore the files with the tag
- % Process: Select/ignore file names with tag: block7
- sensorepochFiles = bst_process('CallProcess', 'process_select_tag', sensorepochFiles, [], ...
- 'tag', 'block7', ...
- 'search', 1, ... % Search the file paths
- 'select', blocktype); % Select/ignore the files with the tag
- for iDiode = 1:2
- diode = opts.diode_channels{iDiode};
- useband = opts.flicker_bands{iDiode};
- % PLV in localizer scouts
- % Process: PLV: Phase locking value
- connectivityScout(iDiode) = bst_process('CallProcess', 'process_plv2', sensorepochFiles, epochFiles, ...
- 'timewindow', curr_opts.fullwindow, ...
- 'src_channel', diode, ...
- 'dest_scouts', {curr_atlas.name, curr_atlas.scouts2use}, ...
- 'scoutfunc', 'mean', ... % Mean
- 'scouttime', 'after', ... % After
- 'scoutfuncaft', 'mean', ... % Mean
- 'tfedit', struct(...
- 'Comment', 'Complex', ...
- 'TimeBands', [], ...
- 'Freqs', {useband}, ...
- 'ClusterFuncTime', 'none', ...
- 'Measure', 'none', ...
- 'Output', 'all', ...
- 'SaveKernel', 0), ...
- 'plvmethod', 'plv', ... % PLV: Phase locking value
- 'tfmeasure', 'hilbert', ... % Hilbert transform
- 'timeres', 'full', ... % Full (requires epochs)
- 'plvmeasure', 2, ... % Magnitude
- 'outputmode', 'avg'); % Save average connectivity matrix (one file)
- % Process: Set name:
- connectivityScout(iDiode) = bst_process('CallProcess', 'process_set_comment', connectivityScout(iDiode), [], ...
- 'tag', ['Scouts_', curr_atlas.label, ',Avg: ', conn_metric, ': ', diode, ' ', curr_opts.label, extralabel], ...
- 'isindex', 0);
- end
- % Process: PLV: Phase locking value with 60 Hz sin (control)
- f60FilesMulti = repmat(f60Files, 1, numel(epochFiles));
- connectivity60Scout = bst_process('CallProcess', 'process_plv2', f60FilesMulti, epochFiles, ...
- 'timewindow', curr_opts.fullwindow, ...
- 'src_channel', '', ...
- 'dest_scouts', {curr_atlas.name, curr_atlas.scouts2use}, ...
- 'scoutfunc', 'mean', ... % Mean
- 'scouttime', 'after', ... % After
- 'scoutfuncaft', 'mean', ... % Mean
- 'tfedit', struct(...
- 'Comment', 'Complex', ...
- 'TimeBands', [], ...
- 'Freqs', {{'fcontrol', '59, 61', 'mean'}}, ...
- 'ClusterFuncTime', 'none', ...
- 'Measure', 'none', ...
- 'Output', 'all', ...
- 'SaveKernel', 0), ...
- 'plvmethod', 'plv', ... % PLV: Phase locking value
- 'tfmeasure', 'hilbert', ... % Hilbert transform
- 'timeres', 'full', ... % Full (requires epochs)
- 'plvmeasure', 2, ... % Magnitude
- 'outputmode', 'avg'); % Save average connectivity matrix (one file)
- % Process: Set name:
- connectivity60Scout = bst_process('CallProcess', 'process_set_comment', connectivity60Scout, [], ...
- 'tag', ['Scouts_', curr_atlas.label, ',Avg: ', conn_metric, ' 60 ', curr_opts.label, extralabel], ...
- 'isindex', 0);
- % combine into one file (not merging R/L yet)
- mat56 = in_bst_timefreq(connectivityScout(1).FileName);
- mat64 = in_bst_timefreq(connectivityScout(2).FileName);
- mat60 = in_bst_timefreq(connectivity60Scout.FileName);
- matall = mat56;
- matall.Freqs = {'fp', '55,57', 'mean'; 'fc', '63,65', 'mean'; 'fcontrol', '59, 61', 'mean'};
- matall.RefRowNames = {'MISC'};
- matall.TF(:, :, 2) = mat64.TF;
- matall.TF(:, :, 3) = mat60.TF;
- matall.Comment = ['Scouts_', curr_atlas.label, ',Avg: ', conn_metric, ' fpfc ', curr_opts.label, extralabel];
- scout_allconnectivity = db_add(connectivityScout(1).iStudy, matall);
- % Process: Extract time
- scout_allconnectivityTime = bst_process('CallProcess', 'process_extract_time', scout_allconnectivity, [], ...
- 'timewindow', curr_opts.extracttime, ...
- 'overwrite', 1);
- % Process: Event-related perturbation (ERS/ERD)
- scout_allconnectivityERSD = bst_process('CallProcess', 'process_baseline_norm', scout_allconnectivityTime, [], ...
- 'baseline', curr_opts.baseline, ...
- 'method', bl_method, ... % Event-related perturbation (ERS/ERD): x_std = (x - μ) / μ * 100
- 'overwrite', 0);
- % Process: Delete selected files
- bst_process('CallProcess', 'process_delete', [connectivityScout, connectivity60Scout], [], ...
- 'target', 1); % Delete selected files
- % Process: combine RL hemispheres
- if mergerl(iAtlas)
- for iScout = 1:numel(curr_atlas.rl_rowidx)
- RL_scoutconnectivity(iScout) = bst_process('CallProcess', 'process_extract_values', scout_allconnectivityERSD, [], ...
- 'timewindow', [], ...
- 'freqrange', [0, 100], ...
- 'rows', curr_atlas.rl_rowidx{iScout}, ...
- 'isabs', 0, ...
- 'avgtime', 0, ...
- 'avgrow', 1, ...
- 'avgfreq', 0, ...
- 'matchrows', 0, ...
- 'dim', 2, ... % Concatenate time (dimension 2)
- 'Comment', ['RL_scout,Avg: ', conn_metric, ' ', curr_opts.label, extralabel]);
- end
- clear allmats
- allmats(1) = in_bst_timefreq(RL_scoutconnectivity(1).FileName);
- matall = allmats(1);
- matall.RowNames = curr_atlas.rl_rownames;
- matall.Comment = [curr_atlas.rl_label, ',Avg: ', conn_metric, ' fpfc ', curr_opts.label, extralabel];
- for iScout = 2:numel(curr_atlas.rl_rowidx)
- allmats(iScout) = in_bst_timefreq(RL_scoutconnectivity(iScout).FileName);
- matall.TF(iScout, :, :) = allmats(iScout).TF;
- end
- RL_allconnectivity = db_add(RL_scoutconnectivity(1).iStudy, matall);
- % Process: Delete selected files
- bst_process('CallProcess', 'process_delete', [RL_scoutconnectivity], [], ...
- 'target', 1); % Delete selected files
- end
- end
- %% scout plvt intermodulation
- if runfiplvt
- conn_metric = 'PLVt';
- % PHASE LOCKING WITH 8 Hz AND 16 Hz
- fi_freqs = [8 16 11];
- for iFreq = 1:numel(fi_freqs)
- curr_freq = fi_freqs(iFreq);
- if curr_freq == 8
- fiFiles = f8Files;
- elseif curr_freq == 16
- fiFiles = f16Files;
- elseif curr_freq == 11
- fiFiles = f11Files;
- end
- fiFilesMulti = repmat(fiFiles, 1, numel(epochFiles));
- useband = opts.fi_bands{iFreq};
- % Process: PLV: Phase locking value with sinusoid
- connectivityfiScout(iFreq) = bst_process('CallProcess', 'process_plv2', fiFilesMulti, epochFiles, ...
- 'timewindow', curr_opts.fullwindow, ...
- 'src_channel', '', ...
- 'dest_scouts', {curr_atlas.name, curr_atlas.scouts2use}, ...
- 'scoutfunc', 'mean', ... % Mean
- 'scouttime', 'after', ... % After
- 'scoutfuncaft', 'mean', ... % Mean
- 'tfedit', struct(...
- 'Comment', 'Complex', ...
- 'TimeBands', [], ...
- 'Freqs', {useband}, ...
- 'ClusterFuncTime', 'none', ...
- 'Measure', 'none', ...
- 'Output', 'all', ...
- 'SaveKernel', 0), ...
- 'plvmethod', 'plv', ... % PLV: Phase locking value
- 'tfmeasure', 'hilbert', ... % Hilbert transform
- 'timeres', 'full', ... % Full (requires epochs)
- 'plvmeasure', 2, ... % Magnitude
- 'outputmode', 'avg'); % Save average connectivity matrix (one file)
- % Process: Set name:
- connectivityfiScout(iFreq) = bst_process('CallProcess', 'process_set_comment', connectivityfiScout(iFreq), [], ...
- 'tag', ['Scouts_', curr_atlas.label, ',Avg: ', conn_metric, ' ' num2str(curr_freq), ' ', curr_opts.label, extralabel], ...
- 'isindex', 0);
- end
- % combine into one file (not merging R/L yet)
- mat8 = in_bst_timefreq(connectivityfiScout(1).FileName);
- mat16 = in_bst_timefreq(connectivityfiScout(2).FileName);
- mat11 = in_bst_timefreq(connectivityfiScout(3).FileName);
- matall = mat8;
- matall.Freqs = {'fi', '7,9', 'mean'; 'fi2', '15,17', 'mean'; 'ficontrol', '10,12', 'mean'};
- matall.RefRowNames = {'MISC'};
- matall.TF(:, :, 2) = mat16.TF;
- matall.TF(:, :, 3) = mat11.TF;
- matall.Comment = ['Scouts_', curr_atlas.label, ',Avg: ', conn_metric, ' fi ', curr_opts.label, extralabel];
- scout_allconnectivity = db_add(connectivityfiScout(1).iStudy, matall);
- % Process: Event-related perturbation (ERS/ERD)
- scout_allconnectivityERSD = bst_process('CallProcess', 'process_baseline_norm', scout_allconnectivity, [], ...
- 'baseline', curr_opts.baseline, ...
- 'method', bl_method, ... % Event-related perturbation (ERS/ERD): x_std = (x - μ) / μ * 100
- 'overwrite', 0);
- % Process: Extract time
- scout_allconnectivityERSD = bst_process('CallProcess', 'process_extract_time', scout_allconnectivityERSD, [], ...
- 'timewindow', curr_opts.extracttime, ...
- 'overwrite', 1);
- % Process: Delete selected files
- bst_process('CallProcess', 'process_delete', [connectivityfiScout], [], ...
- 'target', 1); % Delete selected files
- % Process: combine RL hemispheres
- if mergerl(iAtlas)
- for iScout = 1:numel(curr_atlas.rl_rowidx)
- RL_scoutconnectivity(iScout) = bst_process('CallProcess', 'process_extract_values', scout_allconnectivityERSD, [], ...
- 'timewindow', [], ...
- 'freqrange', [0, 100], ...
- 'rows', curr_atlas.rl_rowidx{iScout}, ...
- 'isabs', 0, ...
- 'avgtime', 0, ...
- 'avgrow', 1, ...
- 'avgfreq', 0, ...
- 'matchrows', 0, ...
- 'dim', 2, ... % Concatenate time (dimension 2)
- 'Comment', ['RL_scout,Avg: ', conn_metric, ' ', curr_opts.label, extralabel]);
- end
- clear allmats
- allmats(1) = in_bst_timefreq(RL_scoutconnectivity(1).FileName);
- matall = allmats(1);
- matall.RowNames = curr_atlas.rl_rownames;
- matall.Comment = [curr_atlas.rl_label, ',Avg: ', conn_metric, ' fi ', curr_opts.label, extralabel];
- for iScout = 2:numel(curr_atlas.rl_rowidx)
- allmats(iScout) = in_bst_timefreq(RL_scoutconnectivity(iScout).FileName);
- matall.TF(iScout, :, :) = allmats(iScout).TF;
- end
- RL_allconnectivity = db_add(RL_scoutconnectivity(1).iStudy, matall);
- % Process: Delete selected files
- bst_process('CallProcess', 'process_delete', [RL_scoutconnectivity], [], ...
- 'target', 1); % Delete selected files
- end
- end
- %% split contrasts
- if splitcontrasts
- % REDO ANALYSES SPLIT BY STIMULUS COLOR CONTRAST
- if blocktype == 2
- for iContrast = 1:2 % low, high
- blocks2use = find(opts.blockorders.(sname) == iContrast);
- contrastEpochFiles = [];
- for iBlock = blocks2use
- % Process: select filenames
- curr_blockFiles = bst_process('CallProcess', 'process_select_tag', epochFiles, [], ...
- 'tag', ['block', num2str(iBlock)], ...
- 'search', 1, ... % Search the file paths
- 'select', 1); % Select the files with the tag
- contrastEpochFiles = [contrastEpochFiles, curr_blockFiles];
- end
- if isempty(contrastEpochFiles)
- continue
- end
- %% scout plvt
- if runplvt
- conn_metric = 'PLVt';
- % PHASE LOCKING WITH PHOTODIODE
- % Process: Select data files
- sensorepochFiles = bst_process('CallProcess', 'process_select_files_data', [], [], ...
- 'subjectname', sname, ...
- 'condition', [], ...
- 'tag', curr_opts.tag, ...
- 'includebad', 0, ...
- 'includeintra', 0, ...
- 'includecommon', 0);
- % Process: Ignore file names with tag: bl.mat (don't use baseline-corrected)
- sensorepochFiles = bst_process('CallProcess', 'process_select_tag', sensorepochFiles, [], ...
- 'tag', 'bl.mat', ...
- 'search', 1, ... % Search the file paths
- 'select', 2); % Ignore the files with the tag
- % don't take the wrong epochs
- ignoreTags = {'noms'};
- for iTag = 1:numel(ignoreTags)
- if ~contains(curr_opts.tag, ignoreTags{iTag})
- sensorepochFiles = bst_process('CallProcess', 'process_select_tag', sensorepochFiles, [], ...
- 'tag', ignoreTags{iTag}, ...
- 'search', 1, ... % Search the file paths
- 'select', 2); % Ignore the files with the tag
- end
- end
- % Process: Ignore file names with tag: Avg
- sensorepochFiles = bst_process('CallProcess', 'process_select_tag', sensorepochFiles, [], ...
- 'tag', 'Avg', ...
- 'search', 2, ... % Search the file names
- 'select', 2); % Ignore the files with the tag
- % Process: Ignore file names with tag: ret
- sensorepochFiles = bst_process('CallProcess', 'process_select_tag', sensorepochFiles, [], ...
- 'tag', 'ret', ...
- 'search', 1, ... % Search the file paths
- 'select', 2); % Ignore the files with the tag
- % Process: Select/ignore file names with tag: block7
- sensorepochFiles = bst_process('CallProcess', 'process_select_tag', sensorepochFiles, [], ...
- 'tag', 'block7', ...
- 'search', 1, ... % Search the file paths
- 'select', blocktype); % Select/ignore the files with the tag
- contrastSensorepochFiles = [];
- for iBlock = blocks2use
- % Process: select filenames
- curr_blockFiles = bst_process('CallProcess', 'process_select_tag', sensorepochFiles, [], ...
- 'tag', ['block', num2str(iBlock)], ...
- 'search', 1, ... % Search the file paths
- 'select', 1); % Select the files with the tag
- contrastSensorepochFiles = [contrastSensorepochFiles, curr_blockFiles];
- end
- for iDiode = 1:2
- diode = opts.diode_channels{iDiode};
- useband = opts.flicker_bands{iDiode};
- % PLV in localizer scouts
- % Process: PLV: Phase locking value
- connectivityScout(iDiode) = bst_process('CallProcess', 'process_plv2', contrastSensorepochFiles, contrastEpochFiles, ...
- 'timewindow', curr_opts.fullwindow, ...
- 'src_channel', diode, ...
- 'dest_scouts', {curr_atlas.name, curr_atlas.scouts2use}, ...
- 'scoutfunc', 'mean', ... % Mean
- 'scouttime', 'after', ... % After
- 'scoutfuncaft', 'mean', ... % Mean
- 'tfedit', struct(...
- 'Comment', 'Complex', ...
- 'TimeBands', [], ...
- 'Freqs', {useband}, ...
- 'ClusterFuncTime', 'none', ...
- 'Measure', 'none', ...
- 'Output', 'all', ...
- 'SaveKernel', 0), ...
- 'plvmethod', 'plv', ... % PLV: Phase locking value
- 'tfmeasure', 'hilbert', ... % Hilbert transform
- 'timeres', 'full', ... % Full (requires epochs)
- 'plvmeasure', 2, ... % Magnitude
- 'outputmode', 'avg'); % Save average connectivity matrix (one file)
- % Process: Set name:
- connectivityScout(iDiode) = bst_process('CallProcess', 'process_set_comment', connectivityScout(iDiode), [], ...
- 'tag', ['Scouts_', curr_atlas.label, ',Avg: ', conn_metric, ': ', diode, ' ', curr_opts.label, ' contrast', num2str(iContrast)], ...
- 'isindex', 0);
- end
- % Process: PLV: Phase locking value with 60 Hz sin (control)
- f60FilesMulti = repmat(f60Files, 1, numel(contrastEpochFiles));
- connectivity60Scout = bst_process('CallProcess', 'process_plv2', f60FilesMulti, contrastEpochFiles, ...
- 'timewindow', curr_opts.fullwindow, ...
- 'src_channel', '', ...
- 'dest_scouts', {curr_atlas.name, curr_atlas.scouts2use}, ...
- 'scoutfunc', 'mean', ... % Mean
- 'scouttime', 'after', ... % After
- 'scoutfuncaft', 'mean', ... % Mean
- 'tfedit', struct(...
- 'Comment', 'Complex', ...
- 'TimeBands', [], ...
- 'Freqs', {{'fcontrol', '59, 61', 'mean'}}, ...
- 'ClusterFuncTime', 'none', ...
- 'Measure', 'none', ...
- 'Output', 'all', ...
- 'SaveKernel', 0), ... 'plvmethod', 'plv', ... % PLV: Phase locking value
- 'tfmeasure', 'hilbert', ... % Hilbert transform
- 'timeres', 'full', ... % Full (requires epochs)
- 'plvmeasure', 2, ... % Magnitude
- 'outputmode', 'avg'); % Save average connectivity matrix (one file)
- % Process: Set name:
- connectivity60Scout = bst_process('CallProcess', 'process_set_comment', connectivity60Scout, [], ...
- 'tag', ['Scouts_', curr_atlas.label, ',Avg: ', conn_metric, ' 60 ', curr_opts.label, ' contrast', num2str(iContrast)], ...
- 'isindex', 0);
- % combine into one file (not merging R/L yet)
- mat56 = in_bst_timefreq(connectivityScout(1).FileName);
- mat64 = in_bst_timefreq(connectivityScout(2).FileName);
- mat60 = in_bst_timefreq(connectivity60Scout.FileName);
- matall = mat56;
- matall.Freqs = {'fp', '55,57', 'mean'; 'fc', '63,65', 'mean'; 'fcontrol', '59, 61', 'mean'};
- matall.RefRowNames = {'MISC'};
- matall.TF(:, :, 2) = mat64.TF;
- matall.TF(:, :, 3) = mat60.TF;
- matall.Comment = ['Scouts_', curr_atlas.label, ',Avg: ', conn_metric, ' fpfc ', curr_opts.label, ' contrast', num2str(iContrast)];
- scout_allconnectivity = db_add(connectivityScout(1).iStudy, matall);
- % Process: Event-related perturbation (ERS/ERD)
- scout_allconnectivityERSD = bst_process('CallProcess', 'process_baseline_norm', scout_allconnectivity, [], ...
- 'baseline', curr_opts.baseline, ...
- 'method', bl_method, ... % Event-related perturbation (ERS/ERD): x_std = (x - μ) / μ * 100
- 'overwrite', 0);
- % Process: Extract time
- scout_allconnectivityERSD = bst_process('CallProcess', 'process_extract_time', scout_allconnectivityERSD, [], ...
- 'timewindow', curr_opts.extracttime, ...
- 'overwrite', 1);
- % Process: Delete selected files
- bst_process('CallProcess', 'process_delete', [connectivityScout, connectivity60Scout], [], ...
- 'target', 1); % Delete selected files
- % Process: combine RL hemispheres
- if mergerl(iAtlas)
- for iScout = 1:numel(curr_atlas.rl_rowidx)
- RL_scoutconnectivity(iScout) = bst_process('CallProcess', 'process_extract_values', scout_allconnectivityERSD, [], ...
- 'timewindow', [], ...
- 'freqrange', [0, 100], ...
- 'rows', curr_atlas.rl_rowidx{iScout}, ...
- 'isabs', 0, ...
- 'avgtime', 0, ...
- 'avgrow', 1, ...
- 'avgfreq', 0, ...
- 'matchrows', 0, ...
- 'dim', 2, ... % Concatenate time (dimension 2)
- 'Comment', ['RL_scout,Avg: ', conn_metric, ' ', curr_opts.label, ' contrast', num2str(iContrast)]);
- end
- clear allmats
- allmats(1) = in_bst_timefreq(RL_scoutconnectivity(1).FileName);
- matall = allmats(1);
- matall.RowNames = curr_atlas.rl_rownames;
- matall.Comment = [curr_atlas.rl_label, ',Avg: ', conn_metric, ' fpfc ', curr_opts.label, ' contrast', num2str(iContrast)];
- for iScout = 2:numel(curr_atlas.rl_rowidx)
- allmats(iScout) = in_bst_timefreq(RL_scoutconnectivity(iScout).FileName);
- matall.TF(iScout, :, :) = allmats(iScout).TF;
- end
- RL_allconnectivity = db_add(RL_scoutconnectivity(1).iStudy, matall);
- % Process: Delete selected files
- bst_process('CallProcess', 'process_delete', [RL_scoutconnectivity], [], ...
- 'target', 1); % Delete selected files
- end
- end
- end
- end
- end
- %% custom SPRiNT
- if runsprintcustom
- % fooofs each moving window after averaging SFFTs across
- % trials.
- % method: extract each time window, run FOOOF, then combine
- % outputs into a SPRiNT structure.
- % set windows. winlength = 1 second, but at intervals of
- % 100ms.
- % make sure we'll cover the full extracttime window, but
- % don't waste compute on extra windows
- fulltime = curr_opts.extracttime + [-sprint_winlength/2, sprint_winlength/2];
- winstarts = fulltime(1):sprint_winstep:fulltime(2)-sprint_winlength+.001;
- winends = fulltime(1)+sprint_winlength:sprint_winstep:fulltime(2);
- nWin = numel(winstarts);
- % extract time windows, FFT, average them, and FOOOF.
- clear winFiles
- for iAtlas = use_atlases
- curr_atlas = all_atlases(iAtlas);
- for iWin = 1:nWin
- % Process: Power spectrum density (Welch)
- fftWinFiles = bst_process('CallProcess', 'process_psd', epochFiles, [], ...
- 'timewindow', [winstarts(iWin), winends(iWin)], ...
- 'win_length', sprint_winlength, ...
- 'win_overlap', 0, ...
- 'units', 'physical', ... % Physical: U2/Hz
- 'clusters', {curr_atlas.name, curr_atlas.scouts2use}, ...
- 'scoutfunc', 1, ... % Mean
- 'win_std', 0, ...
- 'edit', struct(...
- 'Comment', 'Scout psd,Avg,Power', ...
- 'TimeBands', [], ...
- 'Freqs', [], ...
- 'ClusterFuncTime', 'after', ...
- 'Measure', 'power', ...
- 'Output', 'average', ...
- 'SaveKernel', 0));
- % Process: specparam: Fitting oscillations and 1/f
- fooofWinFiles(iWin) = bst_process('CallProcess', 'process_fooof', fftWinFiles, [], ...
- 'implementation', 'matlab', ... % Matlab
- 'freqrange', [1, sprint_maxFreq], ...
- 'powerline', '50', ... % 50 Hz
- 'peaktype', 'gaussian', ... % Gaussian
- 'peakwidth', [0.5, 12], ...
- 'maxpeaks', 3, ...
- 'minpeakheight', 1, ...
- 'proxthresh', 2, ...
- 'apermode', 'fixed', ... % Fixed
- 'guessweight', 'none', ... % None
- 'sorttype', 'param', ... % Peak parameters
- 'sortparam', 'frequency', ... % Frequency
- 'sortbands', {'delta', '2, 4'; 'theta', '5, 7'; 'alpha', '8, 12'; 'beta', '15, 29'; 'gamma1', '30, 59'; 'gamma2', '60, 90'});
- % import to MATLAB.
- fooofMats(iWin) = in_bst(fooofWinFiles(iWin).FileName);
- % delete extracted ffts
- bst_process('CallProcess', 'process_delete', fftWinFiles, [], ...
- 'target', 1); % Delete selected files
- clear fftWinFiles
- end
- % manually convert to a SPRiNT structure.
- sprintMat = fooofMats(1); % get template from first fooof file.
- sprintMat.Comment = ['Scouts_', curr_atlas.label, ',Avg: SPRiNT_custom ', curr_opts.label, extralabel];
- sprintMat.Time = winstarts + sprint_winlength/2;
- sprintMat.Freqs = sprintMat.Freqs(1:sprint_maxFreq);
- sprintMat.Method = 'sprint';
- sprintMat.RowNames = sprintMat.RowNames';
- sprintMat.nAvg = numel(epochFiles); sprintMat.Leff = numel(epochFiles);
- sprintMat.TF = sprintMat.TF(:, :, 1:sprint_maxFreq); % init TF
- sprintMat.Options.Method = 'sprint';
- sprintopts = struct;
- sprintopts.freqs = sprintMat.Options.FOOOF.freqs;
- for iScout = 1:numel(sprintMat.RowNames)
- sprintopts.channel(iScout).name = sprintMat.RowNames{iScout};
- sprintopts.channel(iScout).peaks = struct('time', 'center_frequency', 'amplitude', 'st_dev');
- for iWin = 1:nWin
- sprintMat.TF(iScout, iWin, :) = fooofMats(iWin).TF(iScout, :, 1:sprint_maxFreq);
- fooofopts = fooofMats(iWin).Options.FOOOF;
- sprintopts.topography.exponent(iScout, iWin) = fooofopts.aperiodics(iScout).exponent;
- sprintopts.topography.offset(iScout, iWin) = fooofopts.aperiodics(iScout).offset;
- sprintopts.SPRiNT_models(iScout, iWin, :) = fooofopts.data(iScout).fooofed_spectrum;
- sprintopts.peak_models(iScout, iWin, :) = fooofopts.data(iScout).peak_fit;
- sprintopts.aperiodic_models(iScout, iWin, :) = fooofopts.data(iScout).ap_fit;
- sprintopts.channel(iScout).data(iWin).time = sprintMat.Time(iWin);
- sprintopts.channel(iScout).data(iWin).aperiodic_params = [sprintopts.topography.offset(iScout, iWin), sprintopts.topography.exponent(iScout, iWin)];
- sprintopts.channel(iScout).data(iWin).peak_params = fooofopts.data(iScout).peak_params;
- sprintopts.channel(iScout).data(iWin).peak_types = fooofopts.data(iScout).peak_types;
- sprintopts.channel(iScout).data(iWin).ap_fit = fooofopts.data(iScout).ap_fit;
- sprintopts.channel(iScout).data(iWin).peak_fit = fooofopts.data(iScout).peak_fit;
- sprintopts.channel(iScout).data(iWin).fooofed_spectrum = fooofopts.data(iScout).fooofed_spectrum;
- sprintopts.channel(iScout).data(iWin).power_spectrum = fooofMats(iWin).TF(iScout, :, 1:sprint_maxFreq);
- sprintopts.channel(iScout).data(iWin).error = fooofopts.data.error;
- sprintopts.channel(iScout).data(iWin).r_squared = fooofopts.data.r_squared;
- sprintopts.channel(iScout).aperiodics(iWin).time = sprintMat.Time(iWin);
- sprintopts.channel(iScout).aperiodics(iWin).offset = sprintopts.topography.offset(iScout, iWin);
- sprintopts.channel(iScout).aperiodics(iWin).exponent = sprintopts.topography.exponent(iScout, iWin);
- sprintopts.channel(iScout).stats(iWin).MSE = fooofopts.stats(iScout).MSE;
- sprintopts.channel(iScout).stats(iWin).r_squared = fooofopts.stats(iScout).r_squared;
- sprintopts.channel(iScout).stats(iWin).frequency_wise_error = fooofopts.stats(iScout).frequency_wise_error;
- nPeaks = 1:numel(fooofopts.peaks);
- for iPeak = 1:nPeaks
- if strcmp(fooofopts.peaks(iPeak).channel{1}, sprintMat.RowNames{iScout})
- sprintopts.channel(iScout).peaks(iPeak).time = sprintMat.Time(iWin);
- sprintopts.channel(iScout).peaks(iPeak).center_frequency = fooofopts.peaks(iPeak).center_frequency;
- sprintopts.channel(iScout).peaks(iPeak).amplitude = fooofopts.peaks(iPeak).amplitude;
- sprintopts.channel(iScout).peaks(iPeak).st_dev = fooofopts.peaks(iPeak).std_dev;
- end
- end
- end
- end
- sprintopts.options.winLen = sprint_winlength;
- sprintopts.options.Ovrlp = 0;
- sprintopts.options.nAverage = 1;
- sprintopts.options.hOT = 1; % not sure what this is
- sprintopts.options.rmoutliers = 'no';
- sprintopts.options.freq_range = fooofopts.options.freq_range;
- sprintopts.options.peak_width_limits = fooofopts.options.peak_width_limits;
- sprintopts.options.max_peaks = fooofopts.options.max_peaks;
- sprintopts.options.min_peak_height = fooofopts.options.min_peak_height;
- sprintopts.options.peak_threshold = fooofopts.options.peak_threshold;
- sprintopts.options.aperiodic_mode = fooofopts.options.aperiodic_mode;
- sprintopts.options.peak_type = fooofopts.options.peak_type;
- sprintopts.options.proximity_threshold = fooofopts.options.proximity_threshold;
- sprintopts.options.guess_weight = fooofopts.options.guess_weight;
- sprintMat.Options.SPRiNT = sprintopts;
- sprintMat.Options = rmfield(sprintMat.Options, 'FOOOF');
- % add to database
- sprintFiles = db_add(fooofWinFiles(1).iStudy, sprintMat);
- % delete the windowed FOOOFs
- bst_process('CallProcess', 'process_delete', fooofWinFiles, [], ...
- 'target', 1); % Delete selected files
- clear fooofWinFiles
- % Process: Extract time
- sprintFiles = bst_process('CallProcess', 'process_extract_time', sprintFiles, [], ...
- 'timewindow', curr_opts.extracttime, ...
- 'overwrite', 1);
- % don't average across R/L hemispheres, it's too
- % complicated here. Instead we'll baseline correct,
- % then average across subjects, and can average across
- % R/L at group level.
- end
- end
- % if analyzed microsaccades, delete the imported epochs
- if exist('msEpochFiles', 'var') && ~isempty(msEpochFiles)
- % Process: Delete selected files
- bst_process('CallProcess', 'process_delete', [msEpochFiles], [], ...
- 'target', 1); % Delete selected files
- end
- clear allmats
- end
- %% finish
- % Save and display report
- ReportFile = bst_report('Save');
- bst_report('Open', ReportFile);
- end
- end
- end
- end
- end
- end
- end
- end
UI_source_timefreq.m, under CC-BY-4.0 · at the source
Overview
- Montreal Neurological Institute, McGill University, Montreal, Quebec, Canada
- Neuroscience Institute, New York University Grossman School of Medicine, New York, NY, USA
- Centre for Human Brain Health, School of Psychology, University of Birmingham, Birmingham, UK
- Department of Neuroscience, Brown University, Providence, RI, USA
- Oxford Centre for Human Brain Activity, Oxford Centre for Integrative Neuroimaging, Department of Psychiatry, University of Oxford, Oxford, UK
- Department of Experimental Psychology, University of Oxford, Oxford, UK
- Centre de Recherche du Centre Hospitalier de l’Université de Montréal, Montréal, Quebec, Canada
- Department of Neuroscience, Université de Montréal, Montréal, Québec, Canada
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
Availability: 1 check, the latest on 28 September 2026: the link answers (HTTP 200)
- 28 September 2026: the link answers (HTTP 200)
123 files
- behavior.zip/
analyze_group_data.m , MATLAB, 104 lines, 2 matches - behavior.zip/
analyze_indiv_data.m , MATLAB, 82 lines - behavior.zip/
combine_datafiles.m , MATLAB, 55 lines - behavior.zip/
ft_fig_supp.R , R, 17 lines - brainstorm_analysis.zip/
UI_compute_sources.m , MATLAB, 117 lines - brainstorm_analysis.zip/
UI_epoch.m , MATLAB, 820 lines - brainstorm_analysis.zip/
UI_group_avg.m , MATLAB, 57 lines - brainstorm_analysis.zip/
UI_import_anat.m , MATLAB, 47 lines, 1 match - brainstorm_analysis.zip/
UI_import_data.m , MATLAB, 146 lines - brainstorm_analysis.zip/
UI_load_params.m , MATLAB, 55 lines - brainstorm_analysis.zip/
UI_prep_motorcortex.m , MATLAB, 111 lines, 1 match - brainstorm_analysis.zip/
UI_preproc.m , MATLAB, 835 lines, 1 match - brainstorm_analysis.zip/
UI_ret_analysis.m , MATLAB, 164 lines, 1 match - brainstorm_analysis.zip/
UI_source_timefreq.m , MATLAB, 1,417 lines, 3 matches - brainstorm_analysis.zip/
colorcet.m , MATLAB, 5,710 lines - brainstorm_analysis.zip/
deactivate_ssp.m , MATLAB, 34 lines - brainstorm_analysis.zip/
get_occipital_vertices.m , MATLAB, 66 lines - brainstorm_analysis.zip/
get_scout_overlap_across , MATLAB, 72 lines_subjects.m - brainstorm_edited_code.z
ip/ , MATLAB, 1,529 lines, 1 matchbst_connectivity_MGL.m - brainstorm_edited_code.z
ip/ , MATLAB, 271 linesin_fopen_eyelink.m - brainstorm_edited_code.z
ip/ , MATLAB, 70 linesin_fread_eyelink.m - brainstorm_edited_code.z
ip/ , MATLAB, 247 linesprocess_evt_transfer_MGL .m - edfImport.zip/
EDFFile2.cpp , C++, 583 lines - edfImport.zip/
EDFFile2.h , C/C++, 130 lines - edfImport.zip/
edf.h , C/C++, 1,028 lines - edfImport.zip/
edfCheckFixationStabilit , MATLAB, 31 linesy.m - edfImport.zip/
edfCompile.m , MATLAB, 31 lines - edfImport.zip/
edfComputeVelocity.m , MATLAB, 60 lines - edfImport.zip/
edfExtractInterestingEve , MATLAB, 161 linesnts.m - edfImport.zip/
edfExtractKeyEventsTimin , MATLAB, 35 linesg.m - edfImport.zip/
edfExtractMicrosaccades. , MATLAB, 244 linesm - edfImport.zip/
edfExtractVariables.m , MATLAB, 61 lines - edfImport.zip/
edfFindTrialRecordingSta , MATLAB, 31 linesrt.m - edfImport.zip/
edfImport.m , MATLAB, 131 lines - edfImport.zip/
edfMexImport.cpp , C++, 94 lines - edfImport.zip/
edfSelectSampleFields.m , MATLAB, 33 lines - edfImport.zip/
edf_data.h , C/C++, 589 lines - edfImport.zip/
edftypes.h , C/C++, 45 lines - eye_analysis.zip/
UI_extractMicrosaccades. , MATLAB, 394 lines, 1 matchm - eye_analysis.zip/
analyze_eyelink_fulltria , MATLAB, 176 linesl.m - eye_analysis.zip/
analyze_eyelink_fulltria , MATLAB, 175 linesl_block7.m - eye_analysis.zip/
combine_eyelink_trials.m , MATLAB, 71 lines - eye_analysis.zip/
cross_trial_ms_rate.m , MATLAB, 91 lines - eye_analysis.zip/
full_eyelink_analysis.m , MATLAB, 131 lines - eye_analysis.zip/
get_event_indices.m , MATLAB, 34 lines - eye_analysis.zip/
plot_msRates.m , MATLAB, 167 lines - func.zip/
barwitherr.m , MATLAB, 162 lines - func.zip/
fdr_bh/ , MATLAB, 226 linesfdr_bh.m - func.zip/
kakearney-boundedline-pk , MATLAB, 42 linesg-8179f9a/ Inpaint_nans/ demo/ inpaint_nans_demo_old.m - func.zip/
kakearney-boundedline-pk , MATLAB, 187 linesg-8179f9a/ Inpaint_nans/ doc/ methods_of_inpaint_nans. m - func.zip/
kakearney-boundedline-pk , MATLAB, 1 lineg-8179f9a/ Inpaint_nans/ inpaint_nans.m - func.zip/
kakearney-boundedline-pk , MATLAB, 1 lineg-8179f9a/ Inpaint_nans/ inpaint_nans_bc.m - func.zip/
kakearney-boundedline-pk , MATLAB, 43 linesg-8179f9a/ Inpaint_nans/ inpaint_nans_demo.m - func.zip/
kakearney-boundedline-pk , MATLAB, 178 linesg-8179f9a/ Inpaint_nans/ test/ test_main.m - func.zip/
kakearney-boundedline-pk , MATLAB, 240 linesg-8179f9a/ README.m - func.zip/
kakearney-boundedline-pk , MATLAB, 485 linesg-8179f9a/ boundedline/ boundedline.m - func.zip/
kakearney-boundedline-pk , MATLAB, 43 linesg-8179f9a/ boundedline/ outlinebounds.m - func.zip/
kakearney-boundedline-pk , MATLAB, 57 linesg-8179f9a/ catuneven/ catuneven.m - func.zip/
kakearney-boundedline-pk , MATLAB, 65 linesg-8179f9a/ singlepatch/ singlepatch.m - func.zip/
suplabel.m , MATLAB, 103 lines - myPaths.m, MATLAB, 6 lines
- paradigm.zip/
UI_color_create.m , MATLAB, 35 lines - paradigm.zip/
UI_color_init.m , MATLAB, 35 lines - paradigm.zip/
UI_dkl2rgb.m , MATLAB, 25 lines - paradigm.zip/
UI_drawFixation.m , MATLAB, 73 lines - paradigm.zip/
UI_drawInstructions.m , MATLAB, 72 lines - paradigm.zip/
UI_generate_center_rects , MATLAB, 27 lines.m - paradigm.zip/
UI_master.m , MATLAB, 764 lines, 2 matches - paradigm.zip/
UI_openScreen.m , MATLAB, 159 lines, 2 matches - paradigm.zip/
UI_rest.m , MATLAB, 246 lines - paradigm.zip/
UI_retinotopy.m , MATLAB, 574 lines - paradigm.zip/
UI_runTrial.m , MATLAB, 448 lines - paradigm.zip/
UI_runTrial_uniform.m , MATLAB, 405 lines - paradigm.zip/
UI_shade_create.m , MATLAB, 15 lines - paradigm.zip/
UI_shade_init.m , MATLAB, 35 lines - paradigm.zip/
chbh_func/ , MATLAB, 34 linesRESET_VPIXX.m - paradigm.zip/
chbh_func/ , MATLAB, 63 linesintialiseParallelPort.m - paradigm.zip/
color_scripts/ , MATLAB, 135 linescomp_colour_science_tool box_v1.3/ camera_demo.m - paradigm.zip/
color_scripts/ , MATLAB, 63 linescomp_colour_science_tool box_v1.3/ camera_demo1.m - paradigm.zip/
color_scripts/ , MATLAB, 28 linescomp_colour_science_tool box_v1.3/ cband.m - paradigm.zip/
color_scripts/ , MATLAB, 91 linescomp_colour_science_tool box_v1.3/ cie00de.m - paradigm.zip/
color_scripts/ , MATLAB, 78 linescomp_colour_science_tool box_v1.3/ cie94de.m - paradigm.zip/
color_scripts/ , MATLAB, 116 linescomp_colour_science_tool box_v1.3/ ciecam02.m - paradigm.zip/
color_scripts/ , MATLAB, 80 linescomp_colour_science_tool box_v1.3/ cielabde.m - paradigm.zip/
color_scripts/ , MATLAB, 145 linescomp_colour_science_tool box_v1.3/ cielabplot.m - paradigm.zip/
color_scripts/ , MATLAB, 101 linescomp_colour_science_tool box_v1.3/ cieplot.m - paradigm.zip/
color_scripts/ , MATLAB, 62 linescomp_colour_science_tool box_v1.3/ cmccat00.m - paradigm.zip/
color_scripts/ , MATLAB, 62 linescomp_colour_science_tool box_v1.3/ cmccat00r.m - paradigm.zip/
color_scripts/ , MATLAB, 62 linescomp_colour_science_tool box_v1.3/ cmccat97.m - paradigm.zip/
color_scripts/ , MATLAB, 86 linescomp_colour_science_tool box_v1.3/ cmcde.m - paradigm.zip/
color_scripts/ , MATLAB, 164 linescomp_colour_science_tool box_v1.3/ crtdemo.m - paradigm.zip/
color_scripts/ , MATLAB, 56 linescomp_colour_science_tool box_v1.3/ dkl2lms.m - paradigm.zip/
color_scripts/ , MATLAB, 60 linescomp_colour_science_tool box_v1.3/ dkl_cart2sph.m - paradigm.zip/
color_scripts/ , MATLAB, 45 linescomp_colour_science_tool box_v1.3/ dkl_sph2cart.m - paradigm.zip/
color_scripts/ , MATLAB, 107 linescomp_colour_science_tool box_v1.3/ lab2xyz.m - paradigm.zip/
color_scripts/ , MATLAB, 56 linescomp_colour_science_tool box_v1.3/ lms2dkl.m - paradigm.zip/
color_scripts/ , MATLAB, 20 linescomp_colour_science_tool box_v1.3/ lms2rgb.m - paradigm.zip/
color_scripts/ , MATLAB, 33 linescomp_colour_science_tool box_v1.3/ lms2rgbMB.m - paradigm.zip/
color_scripts/ , MATLAB, 167 linescomp_colour_science_tool box_v1.3/ plotDKLspace.m - paradigm.zip/
color_scripts/ , MATLAB, 39 linescomp_colour_science_tool box_v1.3/ plotDeviceSPDs.m - paradigm.zip/
color_scripts/ , MATLAB, 33 linescomp_colour_science_tool box_v1.3/ plotFundamentals.m - paradigm.zip/
color_scripts/ , MATLAB, 47 linescomp_colour_science_tool box_v1.3/ plotMBdiagram.m - paradigm.zip/
color_scripts/ , MATLAB, 144 linescomp_colour_science_tool box_v1.3/ printer_demo.m - paradigm.zip/
color_scripts/ , MATLAB, 142 linescomp_colour_science_tool box_v1.3/ printer_demo1.m - paradigm.zip/
color_scripts/ , MATLAB, 105 linescomp_colour_science_tool box_v1.3/ r2xyz.m - paradigm.zip/
color_scripts/ , MATLAB, 19 linescomp_colour_science_tool box_v1.3/ rgb2lms.m - paradigm.zip/
color_scripts/ , MATLAB, 31 linescomp_colour_science_tool box_v1.3/ rgbMB2lms.m - paradigm.zip/
color_scripts/ , MATLAB, 60 linescomp_colour_science_tool box_v1.3/ sprague.m - paradigm.zip/
color_scripts/ , MATLAB, 27 linescomp_colour_science_tool box_v1.3/ srgb2xyz.m - paradigm.zip/
color_scripts/ , MATLAB, 69 linescomp_colour_science_tool box_v1.3/ svd_demo.m - paradigm.zip/
color_scripts/ , MATLAB, 93 linescomp_colour_science_tool box_v1.3/ xyz2lab.m - paradigm.zip/
color_scripts/ , MATLAB, 94 linescomp_colour_science_tool box_v1.3/ xyz2luv.m - paradigm.zip/
color_scripts/ , MATLAB, 29 linescomp_colour_science_tool box_v1.3/ xyz2srgb.m - paradigm.zip/
generateAlphaSinusoids.m , MATLAB, 15 lines, 1 match - python.zip/
figure1.py , Python, 131 lines - python.zip/
sss.py , Python, 109 lines - statistics.zip/
plot_zerolines.m , MATLAB, 26 lines - statistics.zip/
tf_permutation.m , MATLAB, 301 lines - statistics.zip/
timeseries_permutation_z , MATLAB, 665 lines, 3 matchesero.m - statistics.zip/
wholebrain_permutation_z , MATLAB, 130 linesero.m - README.md, Text, 28 lines
- edfImport.zip/
LICENSE , License, 21 lines - edfImport.zip/
README.md , Text, 222 lines
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
- zenodo:18825563, at Zenodo; found in “Data, code, and materials availability:”
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/
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://
BibTeX
@article{levinson2026hie
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/
url = {https://
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/
VL - 12
IS - 19
SP - eaea3919
SN - 2375-2548
PB - American Association for the Advancement of Science
DO - 10.1126/
UR - https://
LA - en
ER -
CSL-JSON
{
"id": "10.1126/
"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":
"volume": "12",
"issue": "19",
"page": "eaea3919",
"DOI": "10.1126/
"PMID": "42102217",
"PMCID": "PMC13155359",
"ISSN": "2375-2548",
"publisher": "American Association for the Advancement of Science",
"URL": "https://
"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 dataIn 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 communicationsIn 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 advancesIn 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 communicationsIn 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 biologyIn 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: eLifeIn 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/aIn 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 oneIn 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.
Claim this paper
Correct its record
Say what each link of this record is, remove the ones that are not the paper's, add the ones that are missing. The correction becomes a new version of the record, in its Versions section.
Validate its tracing map
You validate the map as this page shows it: 1 repository of the authors' code, each at its verified commit and with its license, 120 scripts, and 19 matches between paragraphs and code (see the Code and Map sections). It then receives a DOI on Zenodo, with you (your ORCID iD) and OSCR as its creators; the code itself is not deposited.
The map's fingerprint: sha256:7efbe85655bd30af…
Add the badge to its README
The badge links the code to this page. Copy one of these into the README of the paper's code: only you decide where it goes, and nothing is changed for you.
Markdown
[.
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.
