Tracing the neural trajectories of evidence accumulation and motor preparation processes during voluntary decisions.
The 16 matches · 1 of them tie a paragraph to a whole file without given lines: a weak match, whose lines are not tinted
- [1] § Method › EEG analyses ↔ EEG Processing/wavelet_convolution.m, lines 1 to 96 · score 0.89 · complex Morlet wavelet, wavelet cycles, baseline corrected, convolution, stimulus onset, dB · Report a mismatch
- [2] § Method › EEG data acquisition and processing ↔ EEG Processing/eegca_3_preprocessing_step2.m, lines 130 to 140 · score 0.88 · rank deficiency, high pass filtered, removed channel, bad channels, compensate, stationarity · Report a mismatch
- [3] § Method › EEG analyses › Characterising evidence accumulation and motor preparation signatures of voluntary decisions ↔ RT and EEG Analyses /RT and Fixed Window Analyses/eegca_ERP_LMM.Rmd, lines 352 to 395 · score 0.81 · random intercept models, likelihood ratio, random slope models, model comparisons, RT · Report a mismatch
- [4] § Method › EEG data acquisition and processing ↔ EEG Processing/eegca_4_preprocessing_step3.m, lines 139 to 150 · score 0.80 · spherical spline interpolation, scalp channel, bad channels, EEGLAB, noisy · Report a mismatch
- [5] § Method › EEG analyses › Characterising evidence accumulation and motor preparation signatures of voluntary decisions ↔ RT and EEG Analyses /Mass Univariate Analyses/eegca_massuni_ERP_stimlocked.m, lines 1274 to 1398 · score 0.59 · Bayes Factors, Bayesian, permutation, cluster · Report a mismatch
- [6] § Method › EEG analyses › Characterising evidence accumulation and motor preparation signatures of voluntary decisions ↔ RT and EEG Analyses /Mass Univariate Analyses/eegca_massuni_ERP_resplocked.m, lines 1317 to 1433 · score 0.59 · Bayes Factors, Bayesian, permutation, cluster · Report a mismatch
- [7] § Results › MB amplitudes exhibit accumulation-to-bound dynamics in voluntary decisions ↔ RT and EEG Analyses /RT and Fixed Window Analyses/eegca_derive_MB_measures.m, lines 11 to 21 · score 0.59 · slope window, amplitude window, fixed window, MB amplitudes, Mu, Beta · Report a mismatch
- [8] § Method › EEG analyses › Characterising evidence accumulation and motor preparation signatures of voluntary decisions ↔ RT and EEG Analyses /RT and Fixed Window Analyses/eegca_ERP_LMM.Rmd, lines 8 to 76 · score 0.58 · log transformed RTs, LMMs, scored, slope, amplitude, EEG · Report a mismatch
- [9] § Method › EEG analyses › Characterising evidence accumulation and motor preparation signatures of voluntary decisions ↔ RT and EEG Analyses /Mass Univariate Analyses/eegca_multcomp_cluster_permtest.m, lines 1 to 121 · score 0.57 · cluster mass, summed, uncorrected, zero, tailed, iterations · Report a mismatch
- [10] § Method › Procedure ↔ Experiment Code/Functions Library/eegca_experiment_parameters.m, the whole file · a weak match · score 0.57 · paced break, practice block, decision phase, EEG · Report a mismatch
- [11] § Results › MB amplitudes exhibit accumulation-to-bound dynamics in voluntary decisions ↔ RT and EEG Analyses /Mass Univariate Analyses/eegca_massuni_MB.m, lines 550 to 666 · score 0.57 · 8–30 Hz, slope window, MB amplitudes, response locked, sliding, Mu · Report a mismatch
- [12] § Method › Procedure ↔ Experiment Code/RUN_eegca_practice_session.m, lines 666 to 713 · score 0.54 · paced break, practice block, phase · Report a mismatch
- [13] § Results ↔ RT and EEG Analyses /Mass Univariate Analyses/eegca_massuni_MB.m, lines 812 to 935 · score 0.53 · 8–30 Hz, shaded standard error, waves, Mu, Beta, maps · Report a mismatch
- [14] § Results › The CPP exhibits accumulation-to-bound dynamics in voluntary decisions ↔ RT and EEG Analyses /RT and Fixed Window Analyses/eegca_derive_ERP_measures.m, lines 20 to 59 · score 0.52 · slope window, pre response amplitude, CPP amplitudes, electrode, ERP, RT · Report a mismatch
- [15] § Results › The CPP exhibits accumulation-to-bound dynamics in voluntary decisions ↔ RT and EEG Analyses /Mass Univariate Analyses/eegca_massuni_MB.m, lines 1009 to 1147 · score 0.50 · Bayes factors, standard errors, BF, smoothed, Gaussian, forced decisions · Report a mismatch
- [16] § Method › EEG analyses › Characterising evidence accumulation and motor preparation signatures of voluntary decisions ↔ RT and EEG Analyses /RT and Fixed Window Analyses/eegca_derive_ERP_measures.m, lines 361 to 431 · score 0.50 · linear regression, pre response amplitudes, model, epoch, slopes · Report a mismatch
Paper
Loaded from Europe PMC by your browser; OSCR does not store it: doi.org · Europe PMC
The paper is loaded when this pane is shown.
The authors' code
MATLAB · 1,148 lines · 48 KB · no license · 3 matches
- %% Housekeeping
- % Clear all variables in the workspace, and close all windows
- clear all;
- %close all;
- % Change working directory to that which contains this script
- mfile_name = mfilename('fullpath');
- [pathstring, nameOfFile, extensionString] = fileparts(mfile_name);
- cd(pathstring);
- %% Setting Parameters
- % IDs to process
- participantIDs = [1:29,31:50];
- % Choose experiment name
- experimentName = 'eegca_p';
- %% Analysis Options
- % Cluster-based permutation test options
- cluster_permtest_criticalAlpha = 0.05; % Critical cluster-level alpha
- cluster_permtest_clusteringAlpha = 0.01; % Cluster-forming alpha level
- cluster_permtest_iterations = 10000; % Number of permutation samples
- % Define sliding window parameters
- win_ms = 300; % your chosen window
- polyord = 2;
- MB_freq = 8:30;
- fs = 512;
- min_trials_for_reg = 20; % guardrail: need at least this many trials/condition for OLS
- min_obs_for_OLS = 10; % guardrail: at each timepoint, need >= this many finite values
- % Preallocate β matrices
- mb_slope_beta_RT.free = []; % slope β(t) in Free
- mb_slope_beta_RT.forced = []; % slope β(t) in Forced
- mb_amp_beta_RT.free = []; % amp β(t) in Free
- mb_amp_beta_RT.forced = []; % amp β(t) in Forced
- group_time_valid = []; % time axis (ms) for the "valid" interior samples
- %% Preallocate matrices to store trial by trial RT data across all participants
- % Group.DecPhaseRT = [];
- % Group.CoMPhaseRT = [];
- Group.DecFreeRT = [];
- % Group.DecFreeFast = [];
- % Group.DecFreeMedium = [];
- % Group.DecFreeSlow = [];
- Group.DecForcedRT = [];
- % Group.DecForcedFast = [];
- % Group.DecForcedMedium = [];
- % Group.DecForcedMedSlow = [];
- % Group.DecForcedSlow = [];
- %% EEG Data Processing
- for datasetNo = 1:length(participantIDs)
- % Announce the ID number we are processing
- fprintf(['-----------------------------------------------------', ...
- '\n\nProcessing participant ID ' int2str(participantIDs(datasetNo)), ' ****** Averaging ERPs\n\n', ...
- '-----------------------------------------------------\n\n']);
- %% -- Load EEG + Behavioural Data Files
- % Epoched EEG data file
- load(['EEG Data/Epoched Data/', experimentName, int2str(participantIDs(datasetNo)), '_MuBeta_CSD.mat']);
- % Behavioural data file
- %load(['Behavioural Data/Cleaned Behavioural Data/p' int2str(participantIDs(datasetNo)), '_cleaned.mat']);
- load(['Channel Locations/channel_information.mat'], 'chanlocs');
- %% -- Calculate Mean and SD
- % - Decision Phase RTs
- % Remove trials with RTs less than 200ms
- decBadTrials = [];
- for trialNo = 1:numel(TC_Resp_DecPhase.DecPhaseRT)
- if TC_Resp_DecPhase.DecPhaseRT(trialNo) < 0.2
- decBadTrials = [decBadTrials, trialNo];
- end
- end
- variables_TC_Resp_DecPhase = fieldnames(TC_Resp_DecPhase);
- for variable_index = 1:numel(variables_TC_Resp_DecPhase)
- TC_Resp_DecPhase.(variables_TC_Resp_DecPhase{variable_index})(:, decBadTrials) = [];
- end
- MuBeta_Resp{1,1}(:,:,decBadTrials) = [];
- % Calculate mean, median, and standard deviation
- mean_DecPhaseRTs = mean(TC_Resp_DecPhase.DecPhaseRT);
- median_DecPhaseRTs = median(TC_Resp_DecPhase.DecPhaseRT);
- std_DecPhaseRTs = std(TC_Resp_DecPhase.DecPhaseRT);
- DecPhaseMaxCutoff = 20;
- DecPhaseFreeRTs = TC_Resp_DecPhase.DecPhaseRT(TC_Resp_DecPhase.DecPhaseCondition == "free");
- DecPhaseFreeRTs = DecPhaseFreeRTs(DecPhaseFreeRTs <= DecPhaseMaxCutoff);
- DecPhaseForcedRTs = TC_Resp_DecPhase.DecPhaseRT(TC_Resp_DecPhase.DecPhaseCondition == "forced");
- DecPhaseForcedRTs = DecPhaseForcedRTs(DecPhaseForcedRTs < DecPhaseMaxCutoff);
- DecPhaseFreeRT_bins = prctile(DecPhaseFreeRTs, [33.33,66.67]);
- DecPhaseForcedRT_bins = prctile(DecPhaseForcedRTs, [33.33,66.67]);
- % Preallocate tertile matrices
- usableDecTrials = length(TC_Resp_DecPhase.DecPhaseRT);
- TC_Resp_DecPhase.FreeFast(1:usableDecTrials) = nan;
- TC_Resp_DecPhase.FreeMedium(1:usableDecTrials) = nan;
- TC_Resp_DecPhase.FreeSlow(1:usableDecTrials) = nan;
- TC_Resp_DecPhase.ForcedFast(1:usableDecTrials) = nan;
- TC_Resp_DecPhase.ForcedMedium(1:usableDecTrials) = nan;
- TC_Resp_DecPhase.ForcedSlow(1:usableDecTrials) = nan;
- clear trialNo
- for trialNo = 1:length(TC_Resp_DecPhase.DecPhaseRT)
- if TC_Resp_DecPhase.DecPhaseCondition{trialNo} == "free"
- TC_Resp_DecPhase.FreeRT(trialNo) = TC_Resp_DecPhase.DecPhaseRT(trialNo);
- % FREE FASTEST Quartile
- if TC_Resp_DecPhase.DecPhaseRT(trialNo) < DecPhaseFreeRT_bins(1)
- TC_Resp_DecPhase.FreeFast(trialNo) = TC_Resp_DecPhase.DecPhaseRT(trialNo);
- TC_Resp_DecPhase.FreeMedium(trialNo) = nan;
- TC_Resp_DecPhase.FreeSlow(trialNo) = nan;
- Tertile.DecIndex(datasetNo,trialNo) = 1;
- % FREE MEDIUM Quartile
- elseif TC_Resp_DecPhase.DecPhaseRT(trialNo) >= DecPhaseFreeRT_bins(1) && TC_Resp_DecPhase.DecPhaseRT(trialNo) < DecPhaseFreeRT_bins(2)
- TC_Resp_DecPhase.FreeMedium(trialNo) = TC_Resp_DecPhase.DecPhaseRT(trialNo);
- TC_Resp_DecPhase.FreeFast(trialNo) = nan;
- TC_Resp_DecPhase.FreeSlow(trialNo) = nan;
- Tertile.DecIndex(datasetNo,trialNo) = 2;
- % FREE SLOWEST Quartile
- else
- TC_Resp_DecPhase.FreeSlow(trialNo) = TC_Resp_DecPhase.DecPhaseRT(trialNo);
- TC_Resp_DecPhase.FreeFast(trialNo) = nan;
- TC_Resp_DecPhase.FreeMedium(trialNo) = nan;
- Tertile.DecIndex(datasetNo,trialNo) = 3;
- end
- elseif TC_Resp_DecPhase.DecPhaseCondition{trialNo} == "forced"
- TC_Resp_DecPhase.ForcedRT(trialNo) = TC_Resp_DecPhase.DecPhaseRT(trialNo);
- % FORCED FASTEST Quartile
- if TC_Resp_DecPhase.DecPhaseRT(trialNo) < DecPhaseForcedRT_bins(1)
- TC_Resp_DecPhase.ForcedFast(trialNo) = TC_Resp_DecPhase.DecPhaseRT(trialNo);
- TC_Resp_DecPhase.ForcedMedium(trialNo) = nan;
- TC_Resp_DecPhase.ForcedSlow(trialNo) = nan;
- Tertile.DecIndex(datasetNo, trialNo) = 4;
- % FORCED MEDIUM FAST Quartile
- elseif TC_Resp_DecPhase.DecPhaseRT(trialNo) >= DecPhaseForcedRT_bins(1) && TC_Resp_DecPhase.DecPhaseRT(trialNo) < DecPhaseForcedRT_bins(2)
- TC_Resp_DecPhase.ForcedMedium(trialNo) = TC_Resp_DecPhase.DecPhaseRT(trialNo);
- TC_Resp_DecPhase.ForcedFast(trialNo) = nan;
- TC_Resp_DecPhase.ForcedSlow(trialNo) = nan;
- Tertile.DecIndex(datasetNo, trialNo) = 5;
- % FORCED SLOWEST Quartile
- else
- TC_Resp_DecPhase.ForcedSlow(trialNo) = TC_Resp_DecPhase.DecPhaseRT(trialNo);
- TC_Resp_DecPhase.ForcedFast(trialNo) = nan;
- TC_Resp_DecPhase.ForcedMedium(trialNo) = nan;
- Tertile.DecIndex(datasetNo, trialNo) = 6;
- end
- end
- end
- % % - CoM Phase RTs
- % % Remove trials with RTs less than 200ms
- % comBadTrials = [];
- % for trialNo = 1:numel(TC_Resp_CoMPhase.CoMPhaseRT)
- % if TC_Resp_CoMPhase.CoMPhaseRT(trialNo) < 0.2
- % comBadTrials = [comBadTrials, trialNo];
- % end
- % end
- %
- % variables_TC_Resp_CoMPhase = fieldnames(TC_Resp_CoMPhase);
- %
- % for variable_index = 1:numel(variables_TC_Resp_CoMPhase)
- % TC_Resp_CoMPhase.(variables_TC_Resp_CoMPhase{variable_index})(:, comBadTrials) = [];
- % end
- %
- % EEG_Data_Resp_CoMPhase(:,:,comBadTrials) = [];
- %
- % % Calculate mean, median, and standard deviation
- % mean_CoMPhaseRTs = mean(TC_Resp_CoMPhase.CoMPhaseRT);
- % median_CoMPhaseRTs = median(TC_Resp_CoMPhase.CoMPhaseRT);
- % std_CoMPhaseRTs = std(TC_Resp_CoMPhase.CoMPhaseRT);
- % CoMPhaseRTMaxCutoff = 10;
- %
- % CoMPhaseFreeRTs = TC_Resp_CoMPhase.CoMPhaseRT(TC_Resp_CoMPhase.CoMPhaseCondition == "free");
- % CoMPhaseFreeRTs = CoMPhaseFreeRTs(CoMPhaseFreeRTs < CoMPhaseRTMaxCutoff);
- % CoMPhaseFreeSwitch = TC_Resp_CoMPhase.CoMPhaseRT(strcmp(TC_Resp_CoMPhase.CoMPhaseCondition, "free") & TC_Resp_CoMPhase.SwitchStay_Numeric == 1);
- % CoMPhaseFreeSwitch = CoMPhaseFreeSwitch(CoMPhaseFreeSwitch < CoMPhaseRTMaxCutoff);
- % CoMPhaseFreeStayed = TC_Resp_CoMPhase.CoMPhaseRT(strcmp(TC_Resp_CoMPhase.CoMPhaseCondition, 'free') & TC_Resp_CoMPhase.SwitchStay_Numeric == 2);
- % CoMPhaseFreeStayed = CoMPhaseFreeStayed(CoMPhaseFreeStayed < CoMPhaseRTMaxCutoff);
- %
- % CoMPhaseForcedRTs = TC_Resp_CoMPhase.CoMPhaseRT(TC_Resp_CoMPhase.CoMPhaseCondition == "forced");
- % CoMPhaseForcedRTs = CoMPhaseForcedRTs(CoMPhaseForcedRTs < CoMPhaseRTMaxCutoff);
- % CoMPhaseForcedSwitch = TC_Resp_CoMPhase.CoMPhaseRT(strcmp(TC_Resp_CoMPhase.CoMPhaseCondition, 'forced') & TC_Resp_CoMPhase.SwitchStay_Numeric == 1);
- % CoMPhaseForcedSwitch = CoMPhaseForcedSwitch(CoMPhaseForcedSwitch < CoMPhaseRTMaxCutoff);
- % CoMPhaseForcedStayed = TC_Resp_CoMPhase.CoMPhaseRT(strcmp(TC_Resp_CoMPhase.CoMPhaseCondition, 'forced') & TC_Resp_CoMPhase.SwitchStay_Numeric == 2);
- % CoMPhaseForcedStayed = CoMPhaseForcedStayed(CoMPhaseForcedStayed < CoMPhaseRTMaxCutoff);
- %
- % CoMPhaseFreeRT_bins = prctile(CoMPhaseFreeRTs, [33.33,66.67]);
- % CoMPhaseForcedRT_bins = prctile(CoMPhaseForcedRTs, [33.33,66.67]);
- %
- % % Preallocate tertile matrices
- % usableCoMTrials = length(TC_Resp_CoMPhase.CoMPhaseRT);
- % TC_Resp_CoMPhase.FreeFast(1:usableCoMTrials) = nan;
- % TC_Resp_CoMPhase.FreeMedium(1:usableCoMTrials) = nan;
- % TC_Resp_CoMPhase.FreeSlow(1:usableCoMTrials) = nan;
- % TC_Resp_CoMPhase.ForcedFast(1:usableCoMTrials) = nan;
- % TC_Resp_CoMPhase.ForcedMedium(1:usableCoMTrials) = nan;
- % TC_Resp_CoMPhase.ForcedSlow(1:usableCoMTrials) = nan;
- %
- % clear trialNo
- %
- % for trialNo = 1:length(TC_Resp_CoMPhase.CoMPhaseRT)
- % if TC_Resp_CoMPhase.CoMPhaseCondition{trialNo} == "free"
- %
- % TC_Resp_CoMPhase.FreeRT(trialNo) = TC_Resp_CoMPhase.CoMPhaseRT(trialNo);
- %
- % if TC_Resp_CoMPhase.SwitchStay_Numeric(trialNo) == 1
- %
- % TC_Resp_CoMPhase.FreeSwitch(trialNo) = TC_Resp_CoMPhase.CoMPhaseRT(trialNo);
- %
- % elseif TC_Resp_CoMPhase.SwitchStay_Numeric(trialNo) == 2
- %
- % TC_Resp_CoMPhase.FreeStay(trialNo) = TC_Resp_CoMPhase.CoMPhaseRT(trialNo);
- % end
- %
- %
- % % FREE FAST Tertile
- % if TC_Resp_CoMPhase.CoMPhaseRT(trialNo) < CoMPhaseFreeRT_bins(1)
- %
- % TC_Resp_CoMPhase.FreeFast(trialNo) = TC_Resp_CoMPhase.CoMPhaseRT(trialNo);
- % TC_Resp_CoMPhase.FreeMedium(trialNo) = nan;
- % TC_Resp_CoMPhase.FreeSlow(trialNo) = nan;
- % Tertile.CoMIndex(datasetNo,trialNo)= 1;
- %
- % % FREE SLOW Tertile
- % elseif TC_Resp_CoMPhase.CoMPhaseRT(trialNo) > CoMPhaseFreeRT_bins(2)
- %
- % TC_Resp_CoMPhase.FreeSlow(trialNo) = TC_Resp_CoMPhase.CoMPhaseRT(trialNo);
- % TC_Resp_CoMPhase.FreeMedium(trialNo) = nan;
- % TC_Resp_CoMPhase.FreeFast(trialNo) = nan;
- % Tertile.CoMIndex(datasetNo,trialNo)= 3;
- %
- % else
- % % FREE MEDIUM Tertile
- % TC_Resp_CoMPhase.FreeMedium(trialNo) = TC_Resp_CoMPhase.CoMPhaseRT(trialNo);
- % TC_Resp_CoMPhase.FreeFast(trialNo) = nan;
- % TC_Resp_CoMPhase.FreeSlow(trialNo) = nan;
- % Tertile.CoMIndex(datasetNo,trialNo)= 2;
- % end
- % elseif TC_Resp_CoMPhase.CoMPhaseCondition{trialNo} == "forced"
- %
- % TC_Resp_CoMPhase.ForcedRT(trialNo) = TC_Resp_CoMPhase.CoMPhaseRT(trialNo);
- %
- % if TC_Resp_CoMPhase.SwitchStay_Numeric(trialNo) == 1
- %
- % TC_Resp_CoMPhase.ForcedSwitch(trialNo) = TC_Resp_CoMPhase.CoMPhaseRT(trialNo);
- %
- % elseif TC_Resp_CoMPhase.SwitchStay_Numeric(trialNo) == 2
- %
- % TC_Resp_CoMPhase.ForcedStay(trialNo) = TC_Resp_CoMPhase.CoMPhaseRT(trialNo);
- % end
- %
- %
- % % FORCED FAST Tertile
- % if TC_Resp_CoMPhase.CoMPhaseRT(trialNo) < CoMPhaseForcedRT_bins(1)
- %
- % TC_Resp_CoMPhase.ForcedFast(trialNo) = TC_Resp_CoMPhase.CoMPhaseRT(trialNo);
- % TC_Resp_CoMPhase.ForcedMedium(trialNo) = nan;
- % TC_Resp_CoMPhase.ForcedSlow(trialNo) = nan;
- % Tertile.CoMIndex(datasetNo,trialNo)= 4;
- %
- % % FORCED SLOW Tertile
- % elseif TC_Resp_CoMPhase.CoMPhaseRT(trialNo) > CoMPhaseForcedRT_bins(2)
- %
- % TC_Resp_CoMPhase.ForcedSlow(trialNo) = TC_Resp_CoMPhase.CoMPhaseRT(trialNo);
- % TC_Resp_CoMPhase.ForcedMedium(trialNo) = nan;
- % TC_Resp_CoMPhase.ForcedFast(trialNo) = nan;
- % Tertile.CoMIndex(datasetNo,trialNo)= 6;
- %
- % else
- % % FORCED MEDIUM Tertile
- % TC_Resp_CoMPhase.ForcedMedium(trialNo) = TC_Resp_CoMPhase.CoMPhaseRT(trialNo);
- % TC_Resp_CoMPhase.ForcedFast(trialNo) = nan;
- % TC_Resp_CoMPhase.ForcedSlow(trialNo) = nan;
- % Tertile.CoMIndex(datasetNo,trialNo)= 5;
- % end
- %
- % end
- % end
- %
- % % - Choice Phase RTs
- % ChoicePhaseRTs = Res.Timing.choiceReportRTs(~isnan(Res.Timing.choiceReportRTs));
- % ChoicePhaseRTs = ChoicePhaseRTs(:); % Flatten matrix into single vector
- %
- % % Calculate mean, median, and standard deviation
- % mean_ChoicePhaseRTs = mean(ChoicePhaseRTs);
- % median_ChoicePhaseRTs = median(ChoicePhaseRTs);
- % std_ChoicePhaseRTs = std(ChoicePhaseRTs);
- % ChoicePhaseRTsCutoff = median_ChoicePhaseRTs + 3 * std_ChoicePhaseRTs;
- %
- % CoMReportRTs = Res.Timing.CoMSwitchReportRTs(~isnan(Res.Timing.CoMSwitchReportRTs));
- % CoMReportRTs = CoMReportRTs(:); % Flatten matrix into single vector
- %
- % % Calculate mean, median, and standard deviation
- % mean_CoMReportRTs = mean(CoMReportRTs);
- % median_CoMReportRTs = median(CoMReportRTs);
- % std_CoMReportRTs = std(CoMReportRTs);
- % CoMReportRTsCutoff = median_CoMReportRTs + 3 * std_CoMReportRTs;
- %% Remove zeros from TC RT structures to calculate means
- % Filter out zero elements
- TC_Resp_DecPhase.FreeRT = TC_Resp_DecPhase.FreeRT(TC_Resp_DecPhase.FreeRT ~= 0);
- TC_Resp_DecPhase.FreeFast = TC_Resp_DecPhase.FreeFast(TC_Resp_DecPhase.FreeFast ~= 0);
- TC_Resp_DecPhase.FreeMedium = TC_Resp_DecPhase.FreeMedium(TC_Resp_DecPhase.FreeMedium ~= 0);
- TC_Resp_DecPhase.FreeSlow = TC_Resp_DecPhase.FreeSlow(TC_Resp_DecPhase.FreeSlow ~= 0);
- TC_Resp_DecPhase.ForcedRT = TC_Resp_DecPhase.ForcedRT(TC_Resp_DecPhase.ForcedRT ~= 0);
- TC_Resp_DecPhase.ForcedFast = TC_Resp_DecPhase.ForcedFast(TC_Resp_DecPhase.ForcedFast ~= 0);
- TC_Resp_DecPhase.ForcedMedium = TC_Resp_DecPhase.ForcedMedium(TC_Resp_DecPhase.ForcedMedium ~= 0);
- TC_Resp_DecPhase.ForcedSlow = TC_Resp_DecPhase.ForcedSlow(TC_Resp_DecPhase.ForcedSlow ~= 0);
- % TC_Resp_CoMPhase.FreeRT = TC_Resp_CoMPhase.FreeRT(TC_Resp_CoMPhase.FreeRT ~= 0);
- % TC_Resp_CoMPhase.FreeSwitch = TC_Resp_CoMPhase.FreeSwitch(TC_Resp_CoMPhase.FreeSwitch~=0);
- % TC_Resp_CoMPhase.FreeStay = TC_Resp_CoMPhase.FreeStay(TC_Resp_CoMPhase.FreeStay ~= 0);
- % TC_Resp_CoMPhase.FreeFast = TC_Resp_CoMPhase.FreeFast(TC_Resp_CoMPhase.FreeFast ~= 0);
- % TC_Resp_CoMPhase.FreeMedium = TC_Resp_CoMPhase.FreeMedium(TC_Resp_CoMPhase.FreeMedium ~= 0);
- % TC_Resp_CoMPhase.FreeSlow = TC_Resp_CoMPhase.FreeSlow(TC_Resp_CoMPhase.FreeSlow ~= 0);
- % TC_Resp_CoMPhase.ForcedRT = TC_Resp_CoMPhase.ForcedRT(TC_Resp_CoMPhase.ForcedRT ~= 0);
- % TC_Resp_CoMPhase.ForcedSwitch = TC_Resp_CoMPhase.ForcedSwitch(TC_Resp_CoMPhase.ForcedSwitch ~= 0);
- % TC_Resp_CoMPhase.ForcedStay = TC_Resp_CoMPhase.ForcedStay(TC_Resp_CoMPhase.ForcedStay ~= 0);
- % TC_Resp_CoMPhase.ForcedFast = TC_Resp_CoMPhase.ForcedFast(TC_Resp_CoMPhase.ForcedFast ~= 0);
- % TC_Resp_CoMPhase.ForcedMedium = TC_Resp_CoMPhase.ForcedMedium(TC_Resp_CoMPhase.ForcedMedium ~= 0);
- % TC_Resp_CoMPhase.ForcedSlow = TC_Resp_CoMPhase.ForcedSlow(TC_Resp_CoMPhase.ForcedSlow ~= 0);
- %
- Group.DecFreeRT = [Group.DecFreeRT; TC_Resp_DecPhase.FreeRT'];
- Group.DecForcedRT = [Group.DecForcedRT; TC_Resp_DecPhase.ForcedRT'];
- %% Calculate Individual Level Tertile Means and Medians
- clear tertileNo
- for tertileNo = 1:length(participantIDs)
- Tertile.MeanDecFreeRT(datasetNo) = nanmean(TC_Resp_DecPhase.FreeRT);
- Tertile.MeanDecFreeFast(datasetNo) = nanmean(TC_Resp_DecPhase.FreeFast);
- Tertile.MeanDecFreeMedium(datasetNo) = nanmean(TC_Resp_DecPhase.FreeMedium);
- Tertile.MeanDecFreeSlow(datasetNo) = nanmean(TC_Resp_DecPhase.FreeSlow);
- Tertile.MeanDecForcedRT(datasetNo) = nanmean(TC_Resp_DecPhase.ForcedRT);
- Tertile.MeanDecForcedFast(datasetNo) = nanmean(TC_Resp_DecPhase.ForcedFast);
- Tertile.MeanDecForcedMedium(datasetNo) = nanmean(TC_Resp_DecPhase.ForcedMedium);
- Tertile.MeanDecForcedSlow(datasetNo) = nanmean(TC_Resp_DecPhase.ForcedSlow);
- % Tertile.MeanCoMFreeRT(datasetNo) = nanmean(TC_Resp_CoMPhase.FreeRT);
- % Tertile.MeanCoMFreeSwitch(datasetNo) = nanmean(TC_Resp_CoMPhase.FreeSwitch);
- % Tertile.MeanCoMFreeStay(datasetNo) = nanmean(TC_Resp_CoMPhase.FreeStay);
- % Tertile.MeanCoMFreeFast(datasetNo) = nanmean(TC_Resp_CoMPhase.FreeFast);
- % Tertile.MeanCoMFreeMedium(datasetNo) = nanmean(TC_Resp_CoMPhase.FreeMedium);
- % Tertile.MeanCoMFreeSlow(datasetNo) = nanmean(TC_Resp_CoMPhase.FreeSlow);
- % Tertile.MeanCoMForcedRT(datasetNo) = nanmean(TC_Resp_CoMPhase.ForcedRT);
- % Tertile.MeanCoMForcedSwitch(datasetNo) = nanmean(TC_Resp_CoMPhase.ForcedSwitch);
- % Tertile.MeanCoMForcedStay(datasetNo) = nanmean(TC_Resp_CoMPhase.ForcedStay);
- % Tertile.MeanCoMForcedFast(datasetNo) = nanmean(TC_Resp_CoMPhase.ForcedFast);
- % Tertile.MeanCoMForcedMedium(datasetNo) = nanmean(TC_Resp_CoMPhase.ForcedMedium);
- % Tertile.MeanCoMForcedSlow(datasetNo) = nanmean(TC_Resp_CoMPhase.ForcedSlow);
- end
- %% -- Average ERPs by Condition
- % Free Trials
- Epoch.FreeStandaloneAll(:, :, datasetNo) = ...
- nanmean(MuBeta_Resp{1,1}(:, :, ...
- strcmp(TC_Resp_DecPhase.DecPhaseCondition, 'free') & ...
- TC_Resp_DecPhase.ChoiceMade == 1 & ...
- TC_Resp_DecPhase.DecPhaseRT < DecPhaseMaxCutoff & ...
- TC_Resp_DecPhase.ChoicePhaseRT < 5), 3);
- Epoch.FreeStandaloneFast(:, :, datasetNo) = ...
- nanmean(MuBeta_Resp{1,1}(:, :, ...
- strcmp(TC_Resp_DecPhase.DecPhaseCondition, 'free') & ...
- TC_Resp_DecPhase.ChoiceMade == 1 & ...
- TC_Resp_DecPhase.DecPhaseRT < DecPhaseFreeRT_bins(1) & ...
- TC_Resp_DecPhase.ChoicePhaseRT < 5), 3);
- Epoch.FreeStandaloneMedium(:, :, datasetNo) = ...
- nanmean(MuBeta_Resp{1,1}(:, :, ...
- strcmp(TC_Resp_DecPhase.DecPhaseCondition, 'free') & ...
- TC_Resp_DecPhase.ChoiceMade == 1 & ...
- TC_Resp_DecPhase.DecPhaseRT >= DecPhaseFreeRT_bins(1) & ...
- TC_Resp_DecPhase.DecPhaseRT < DecPhaseFreeRT_bins(2) & ...
- TC_Resp_DecPhase.ChoicePhaseRT < 5), 3);
- Epoch.FreeStandaloneSlow(:, :, datasetNo) = ...
- nanmean(MuBeta_Resp{1,1}(:, :, ...
- strcmp(TC_Resp_DecPhase.DecPhaseCondition, 'free') & ...
- TC_Resp_DecPhase.ChoiceMade == 1 & ...
- TC_Resp_DecPhase.DecPhaseRT >= DecPhaseFreeRT_bins(2) & ...
- TC_Resp_DecPhase.DecPhaseRT < DecPhaseMaxCutoff & ...
- TC_Resp_DecPhase.ChoicePhaseRT < 5), 3);
- % Epoch.FreeSubsequentAll(:, :, datasetNo) = ...
- % mean(EEG_Data_Resp_CoMPhase(:, :, strcmp(TC_Resp_CoMPhase.CoMPhaseCondition, 'free') & ...
- % TC_Resp_CoMPhase.ChoiceMade == 1 & ...
- % TC_Resp_CoMPhase.CoMPhaseRT < CoMPhaseRTMaxCutoff & ...
- % TC_Resp_CoMPhase.ChoicePhaseRT < 5), 3);
- %
- % Epoch.FreeSubsequentFast(:, :, datasetNo) = ...
- % mean(EEG_Data_Resp_CoMPhase(:, :, strcmp(TC_Resp_CoMPhase.CoMPhaseCondition, 'free') & ...
- % TC_Resp_CoMPhase.ChoiceMade == 1 & ...
- % TC_Resp_CoMPhase.CoMPhaseRT <= CoMPhaseFreeRT_bins(1) & ...
- % TC_Resp_CoMPhase.CoMPhaseRT < CoMPhaseRTMaxCutoff & ...
- % TC_Resp_CoMPhase.ChoicePhaseRT < 5), 3);
- %
- % Epoch.FreeSubsequentMedium(:, :, datasetNo) = ...
- % mean(EEG_Data_Resp_CoMPhase(:, :, strcmp(TC_Resp_CoMPhase.CoMPhaseCondition, 'free') & ...
- % TC_Resp_CoMPhase.ChoiceMade == 1 & ...
- % TC_Resp_CoMPhase.CoMPhaseRT > CoMPhaseFreeRT_bins(1) & ...
- % TC_Resp_CoMPhase.CoMPhaseRT <= CoMPhaseFreeRT_bins(2) & ...
- % TC_Resp_CoMPhase.CoMPhaseRT < CoMPhaseRTMaxCutoff & ...
- % TC_Resp_CoMPhase.ChoicePhaseRT < 5), 3);
- %
- % Epoch.FreeSubsequentSlow(:, :, datasetNo) = ...
- % mean(EEG_Data_Resp_CoMPhase(:, :, strcmp(TC_Resp_CoMPhase.CoMPhaseCondition, 'free') & ...
- % TC_Resp_CoMPhase.ChoiceMade == 1 & ...
- % TC_Resp_CoMPhase.CoMPhaseRT > CoMPhaseFreeRT_bins(2) & ...
- % TC_Resp_CoMPhase.CoMPhaseRT < CoMPhaseRTMaxCutoff & ...
- % TC_Resp_CoMPhase.ChoicePhaseRT < 5), 3);
- %
- % Epoch.FreeStayed(:, :, datasetNo) = ...
- % mean(EEG_Data_Resp_CoMPhase(:, :, strcmp(TC_Resp_CoMPhase.CoMPhaseCondition, 'free') & ...
- % TC_Resp_CoMPhase.SwitchStay_Numeric == 2 & ...
- % TC_Resp_CoMPhase.ChoiceMade == 1 & ...
- % TC_Resp_CoMPhase.CoMPhaseRT < CoMPhaseRTMaxCutoff & ...
- % TC_Resp_CoMPhase.ChoicePhaseRT < 5), 3);
- %
- % Epoch.FreeSwitched(:, :, datasetNo) = ...
- % mean(EEG_Data_Resp_CoMPhase(:, :, strcmp(TC_Resp_CoMPhase.CoMPhaseCondition, 'free') & ...
- % TC_Resp_CoMPhase.SwitchStay_Numeric == 1 & ...
- % TC_Resp_CoMPhase.ChoiceMade == 1 & ...
- % TC_Resp_CoMPhase.CoMPhaseRT < CoMPhaseRTMaxCutoff & ...
- % TC_Resp_CoMPhase.ChoicePhaseRT < 5), 3);
- % Forced Trials
- Epoch.ForcedStandaloneAll(:, :, datasetNo) = ... % Forced Decision Phase
- nanmean(MuBeta_Resp{1,1}(:, :, strcmp(TC_Resp_DecPhase.DecPhaseCondition, 'forced') & ...
- TC_Resp_DecPhase.ChoiceMade == 1 & ...
- TC_Resp_DecPhase.DecPhaseRT > 0.2 & ...
- TC_Resp_DecPhase.DecPhaseRT < DecPhaseMaxCutoff & ...
- TC_Resp_DecPhase.ChoicePhaseRT < 5), 3);
- Epoch.ForcedStandaloneFast(:, :, datasetNo) = ...
- nanmean(MuBeta_Resp{1,1}(:, :, ...
- strcmp(TC_Resp_DecPhase.DecPhaseCondition, 'forced') & ...
- TC_Resp_DecPhase.ChoiceMade == 1 & ...
- TC_Resp_DecPhase.DecPhaseRT > 0.2 & ...
- TC_Resp_DecPhase.DecPhaseRT <= DecPhaseForcedRT_bins(1) & ...
- TC_Resp_DecPhase.ChoicePhaseRT < 5), 3);
- Epoch.ForcedStandaloneMedium(:, :, datasetNo) = ...
- nanmean(MuBeta_Resp{1,1}(:, :, ...
- strcmp(TC_Resp_DecPhase.DecPhaseCondition, 'forced') & ...
- TC_Resp_DecPhase.ChoiceMade == 1 & ...
- TC_Resp_DecPhase.DecPhaseRT > 0.2 & ...
- TC_Resp_DecPhase.DecPhaseRT >= DecPhaseForcedRT_bins(1) & ...
- TC_Resp_DecPhase.DecPhaseRT < DecPhaseForcedRT_bins(2) & ...
- TC_Resp_DecPhase.ChoicePhaseRT < 5), 3);
- Epoch.ForcedStandaloneSlow(:, :, datasetNo) = ...
- nanmean(MuBeta_Resp{1,1}(:, :, ...
- strcmp(TC_Resp_DecPhase.DecPhaseCondition, 'forced') & ...
- TC_Resp_DecPhase.ChoiceMade == 1 & ...
- TC_Resp_DecPhase.DecPhaseRT > 0.2 & ...
- TC_Resp_DecPhase.DecPhaseRT >= DecPhaseForcedRT_bins(2) & ...
- TC_Resp_DecPhase.ChoicePhaseRT < 5), 3);
- % Epoch.ForcedSubsequentAll(:, :, datasetNo) = ... % Forced CoM Phase
- % mean(EEG_Data_Resp_CoMPhase(:, :, strcmp(TC_Resp_CoMPhase.CoMPhaseCondition, 'forced') & ...
- % TC_Resp_CoMPhase.ChoiceMade == 1 & ...
- % TC_Resp_CoMPhase.CoMPhaseRT > 0.2 & ...
- % TC_Resp_CoMPhase.CoMPhaseRT < CoMPhaseRTMaxCutoff & ...
- % TC_Resp_CoMPhase.ChoicePhaseRT < 5), 3);
- %
- % Epoch.ForcedSubsequentFast(:, :, datasetNo) = ...
- % mean(EEG_Data_Resp_CoMPhase(:, :, ...
- % strcmp(TC_Resp_CoMPhase.CoMPhaseCondition, 'forced') & ...
- % TC_Resp_CoMPhase.ChoiceMade == 1 & ...
- % TC_Resp_CoMPhase.CoMPhaseRT > 0.2 & ...
- % TC_Resp_CoMPhase.CoMPhaseRT <= CoMPhaseForcedRT_bins(1) & ...
- % TC_Resp_CoMPhase.ChoicePhaseRT < 5), 3);
- %
- % Epoch.ForcedSubsequentMedium(:, :, datasetNo) = ...
- % mean(EEG_Data_Resp_CoMPhase(:, :, ...
- % strcmp(TC_Resp_CoMPhase.CoMPhaseCondition, 'forced') & ...
- % TC_Resp_CoMPhase.ChoiceMade == 1 & ...
- % TC_Resp_CoMPhase.CoMPhaseRT > 0.2 & ...
- % TC_Resp_CoMPhase.CoMPhaseRT > CoMPhaseForcedRT_bins(1) & ...
- % TC_Resp_CoMPhase.CoMPhaseRT <= CoMPhaseForcedRT_bins(2) & ...
- % TC_Resp_CoMPhase.ChoicePhaseRT < 5), 3);
- %
- % Epoch.ForcedSubsequentSlow(:, :, datasetNo) = ...
- % mean(EEG_Data_Resp_CoMPhase(:, :, ...
- % strcmp(TC_Resp_CoMPhase.CoMPhaseCondition, 'forced') & ...
- % TC_Resp_CoMPhase.ChoiceMade == 1 & ...
- % TC_Resp_CoMPhase.CoMPhaseRT > 0.2 & ...
- % TC_Resp_CoMPhase.CoMPhaseRT > CoMPhaseForcedRT_bins(2) & ...
- % TC_Resp_CoMPhase.ChoicePhaseRT < 5), 3);
- %
- % Epoch.ForcedStayed(:, :, datasetNo) = ... % Forced Stayed
- % mean(EEG_Data_Resp_CoMPhase(:, :, strcmp(TC_Resp_CoMPhase.CoMPhaseCondition, 'forced') & ...
- % TC_Resp_CoMPhase.SwitchStay_Numeric == 2 & ...
- % TC_Resp_CoMPhase.ChoiceMade == 1 & ...
- % TC_Resp_CoMPhase.CoMPhaseRT > 0.2 & ...
- % TC_Resp_CoMPhase.CoMPhaseRT < CoMPhaseRTMaxCutoff & ...
- % TC_Resp_CoMPhase.ChoicePhaseRT < 5), 3);
- %
- % Epoch.ForcedSwitched(:, :, datasetNo) = ... % Forced Switched
- % mean(EEG_Data_Resp_CoMPhase(:, :, strcmp(TC_Resp_CoMPhase.CoMPhaseCondition, 'forced') & ...
- % TC_Resp_CoMPhase.SwitchStay_Numeric == 1 & ...
- % TC_Resp_CoMPhase.ChoiceMade == 1 & ...
- % TC_Resp_CoMPhase.CoMPhaseRT > 0.2 & ...
- % TC_Resp_CoMPhase.CoMPhaseRT < CoMPhaseRTMaxCutoff & ...
- % TC_Resp_CoMPhase.ChoicePhaseRT < 5), 3);
- %% Derive sliding-window slope & amplitude & regress β(t) ~ zlogRT per condition
- % ---------------------------------------------------------------------
- % 1) Build trial × time waveform from Mu/Beta TF by averaging 8–30 Hz
- % Result: mb_trials is [nTrials × nTime], in dB or whatever your TF units are.
- % ---------------------------------------------------------------------
- mb_trials = squeeze(mean(MuBeta_Resp{1,1}(MB_freq, :, :), 1)).'; % [trials x time]
- [nTrials, nTime] = size(mb_trials);
- t_ms = timepts_struct.resp(:).'; % time axis (ms), response-locked
- % ---------------------------------------------------------------------
- % 2) Compute sliding-window slope & window-mean amplitude at each sample
- % Using the polyfit version (true OLS slope over each window).
- % Returns:
- % slope_ps: [nTrials x nTime], NaN at edges
- % amp_win : [nTrials x nTime], NaN at edges (mean within window)
- % valid_mask: 1 x nTime, logical, where full window is available
- % ---------------------------------------------------------------------
- [slope_ps, amp_win, valid_mask] = eegca_sliding_slope(mb_trials, fs, win_ms);
- t_valid = t_ms(valid_mask);
- % ---------------------------------------------------------------------
- % 3) Trial-level covariates: RT (z-scored log RT) and condition
- % We use log to reduce positive skew, then z-score within participant
- % so β reflects change per 1 SD of logRT (participant-normalised).
- % ---------------------------------------------------------------------
- RT_sec = TC_Resp_DecPhase.DecPhaseRT(:); % seconds
- cond_str = string(TC_Resp_DecPhase.DecPhaseCondition(:)); % "free"/"forced"
- logRT = log(RT_sec);
- % guard against zero/negative RTs (shouldn't happen after 0.2 s cut)
- logRT(~isfinite(logRT)) = NaN;
- zlogRT = (logRT - nanmean(logRT)) ./ nanstd(logRT);
- % ---------------------------------------------------------------------
- % 4) OLS per time sample: slope(t) ~ [1 zlogRT], amp(t) ~ [1 zlogRT]
- % Done separately for Free and Forced trials within participant.
- % We only keep β for zlogRT (2nd column).
- % ---------------------------------------------------------------------
- conds = ["free","forced"];
- beta_slope_free = nan(1,sum(valid_mask));
- beta_slope_forced = nan(1,sum(valid_mask));
- beta_amp_free = nan(1,sum(valid_mask));
- beta_amp_forced = nan(1,sum(valid_mask));
- for ci = 1:numel(conds)
- c = conds(ci);
- keep_tr = cond_str == c & isfinite(zlogRT);
- if nnz(keep_tr) < min_trials_for_reg
- fprintf(' [%s] too few trials (%d) → skipping β(t) this participant.\n', c, nnz(keep_tr));
- continue;
- end
- X = [ones(nnz(keep_tr),1), zlogRT(keep_tr)]; % design matrix
- Y_slope = slope_ps(keep_tr, valid_mask); % slopes, valid time only
- Y_amp = amp_win(keep_tr, valid_mask); % window-mean amplitude
- b_slope = nan(1,size(Y_slope,2));
- b_amp = nan(1,size(Y_amp,2));
- for tt = 1:size(Y_slope,2)
- ys = Y_slope(:,tt);
- ya = Y_amp(:,tt);
- oks = isfinite(ys);
- oka = isfinite(ya);
- if nnz(oks) >= min_obs_for_OLS
- betaS = X(oks,:) \ ys(oks); % OLS → β = (X'X)^-1 X'y
- b_slope(tt) = betaS(2); % β for zlogRT
- end
- if nnz(oka) >= min_obs_for_OLS
- betaA = X(oka,:) \ ya(oka);
- b_amp(tt) = betaA(2); % β for zlogRT
- end
- end
- if c == "free"
- beta_slope_free = b_slope;
- beta_amp_free = b_amp;
- else
- beta_slope_forced = b_slope;
- beta_amp_forced = b_amp;
- end
- end
- % ---------------------------------------------------------------------
- % 5) Stack β(t) rows for this participant (and align time if needed)
- % First participant sets the master time vector (t_valid).
- % Subsequent participants are truncated to the minimum overlapping
- % length to keep alignment perfect for group stats.
- % ---------------------------------------------------------------------
- if isempty(group_time_valid)
- group_time_valid = t_valid;
- end
- L = min(numel(group_time_valid), numel(t_valid));
- if L ~= numel(group_time_valid)
- group_time_valid = group_time_valid(1:L);
- end
- % Truncate participant vectors if their valid time differs
- beta_slope_free = beta_slope_free(1:L);
- beta_slope_forced = beta_slope_forced(1:L);
- beta_amp_free = beta_amp_free(1:L);
- beta_amp_forced = beta_amp_forced(1:L);
- % Append to group matrices
- mb_slope_beta_RT.free = [mb_slope_beta_RT.free; beta_slope_free];
- mb_slope_beta_RT.forced = [mb_slope_beta_RT.forced; beta_slope_forced];
- mb_amp_beta_RT.free = [mb_amp_beta_RT.free; beta_amp_free];
- mb_amp_beta_RT.forced = [mb_amp_beta_RT.forced; beta_amp_forced];
- end % of for datasetNo
- %% Calculate Group Means and Medians by Tertile
- Tertile.GroupMean.DecFreeRT = mean(Tertile.MeanDecFreeRT)*1000;
- Tertile.GroupMean.DecFreeFast = mean(Tertile.MeanDecFreeFast)*1000;
- Tertile.GroupMean.DecFreeMedium = mean(Tertile.MeanDecFreeMedium)*1000;
- Tertile.GroupMean.DecFreeSlow = mean(Tertile.MeanDecFreeSlow)*1000;
- Tertile.GroupMean.DecForcedRT = mean(Tertile.MeanDecForcedRT)*1000;
- Tertile.GroupMean.DecForcedFast = mean(Tertile.MeanDecForcedFast)*1000;
- Tertile.GroupMean.DecForcedMedium = mean(Tertile.MeanDecForcedMedium)*1000;
- Tertile.GroupMean.DecForcedSlow = mean(Tertile.MeanDecForcedSlow)*1000;
- % Tertile.GroupMean.CoMFreeRT = mean(Tertile.MeanCoMFreeRT)*1000;
- % Tertile.GroupMean.CoMFreeSwitch = mean(Tertile.MeanCoMFreeSwitch)*1000;
- % Tertile.GroupMean.CoMFreeStay = mean(Tertile.MeanCoMFreeStay)*1000;
- % Tertile.GroupMean.CoMFreeFast = mean(Tertile.MeanCoMFreeFast)*1000;
- % Tertile.GroupMean.CoMFreeMedium = mean(Tertile.MeanCoMFreeMedium)*1000;
- % Tertile.GroupMean.CoMFreeSlow = mean(Tertile.MeanCoMFreeSlow)*1000;
- % Tertile.GroupMean.CoMForcedRT = mean(Tertile.MeanCoMForcedRT)*1000;
- % Tertile.GroupMean.CoMForcedSwitch = mean(Tertile.MeanCoMForcedSwitch)*1000;
- % Tertile.GroupMean.CoMForcedStay = mean(Tertile.MeanCoMForcedStay)*1000;
- % Tertile.GroupMean.CoMForcedFast = mean(Tertile.MeanCoMForcedFast)*1000;
- % Tertile.GroupMean.CoMForcedMedium = mean(Tertile.MeanCoMForcedMedium)*1000;
- % Tertile.GroupMean.CoMForcedSlow = mean(Tertile.MeanCoMForcedSlow)*1000;
- %% Save Epochs
- %
- % save(['EEG Data/Epoched Data/eegca_GROUP_MB'], ...
- % 'Epoch', ...
- % 'TC_Resp_DecPhase', ...
- % 'Tertile', ...
- % 'Group', ...
- % 'timepts_struct');
- % %
- % %% Load Epochs
- %
- % load(['EEG Data/Epoched Data/eegca_GROUP', plottingData]);
- %% Create MB Plots
- % Define colours for different transparencies of blue
- t1_opacity = [0, 0.4470, 0.7410, 1]; % Dark blue with high opacity
- t2_opacity = [0.576, 0.439, 0.859, 1]; % Medium blue with medium opacity
- t3_opacity = [1, 0.773, 0, 1]; % Light blue with low opacity
- blue_t1_opacity = [0, 0.4470, 0.7410, 1]; % Dark blue with high opacity
- blue_t2_opacity = [0, 0.4470, 0.7410, 0.7]; % Medium blue with medium opacity
- blue_t3_opacity = [0, 0.4470, 0.7410, 0.3]; % Light blue with low opacity
- blue_q1_opacity = [0, 0.4470, 0.7410, 1]; % Dark blue with high opacity
- blue_q2_opacity = [0, 0.4470, 0.7410, 0.8]; % Medium blue with medium opacity
- blue_q3_opacity = [0, 0.4470, 0.7410, 0.6]; % Light blue with low opacity
- blue_q4_opacity = [0, 0.4470, 0.7410, 0.4]; % Light blue with low opacity
- red_t1_opacity = [1, 0.1, 0, 1]; % Dark blue with high opacity
- red_t2_opacity = [1, 0.1, 0, 0.7]; % Medium blue with medium opacity
- red_t3_opacity = [1, 0.1, 0, 0.3]; % Light blue with low opacity
- red_q1_opacity = [1, 0.1, 0, 1]; % Dark blue with high opacity
- red_q2_opacity = [1, 0.1, 0, 0.8]; % Medium blue with medium opacity
- red_q3_opacity = [1, 0.1, 0, 0.6]; % Light blue with low opacity
- red_q4_opacity = [1, 0.1, 0, 0.4]; % Light blue with low opacity
- ERP_smoothing_constant = 1;
- %% Run Bayesian and Frequentist T Tests on
- % Frequency bands to average over within ROI
- MuBeta_Freq_ttests = [8:30];
- % Alpha level for shading
- shadingAlpha = 0.2;
- % Default from other projects = 0.3
- % Run Bayesian t tests and get SD estimates for plotting
- % ---MB ---
- for timePoint = 1:size(Epoch.FreeStandaloneAll, 2)
- % Use Bayesian paired-samples t test from MATLAB bayesFactor
- % toolbox (https://klabhub.github.io/bayesFactor/#1)
- % Toolbox by Bart Krekelberg adapted from code by Rouder
- [MB.bf10(timePoint), MB.p(timePoint)] = ttest_bayes_df( ...
- mean(Epoch.FreeStandaloneAll(MuBeta_Freq_ttests, timePoint, :), 1), ...
- mean(Epoch.ForcedStandaloneAll(MuBeta_Freq_ttests, timePoint, :), 1));
- % Frequentist paired-samples t tests
- [~, ~, ~, temp_tstats] = ttest( ...
- mean(Epoch.FreeStandaloneAll(MuBeta_Freq_ttests, timePoint, :), 1), ...
- mean(Epoch.ForcedStandaloneAll(MuBeta_Freq_ttests, timePoint, :), 1));
- MB.diff_SD(timePoint) = temp_tstats.sd;
- end % of for timePoint
- % Copy Standalone Results into ERP_Results structure
- MB_Results.Standalone.bf10 = MB.bf10;
- MB_Results.Standalone.differenceWave_SD = MB.diff_SD;
- MB_Results.Standalone.channelsUsed = MuBeta_Freq_ttests;
- % Prepare data for cluster-based permutation test
- MB_freestandalone = squeeze(mean(Epoch.FreeStandaloneAll(MuBeta_Freq_ttests, :, :), 1));
- MB_freestandalone = MB_freestandalone'; % Transpose
- MB_forcedstandalone = squeeze(mean(Epoch.ForcedStandaloneAll(MuBeta_Freq_ttests, :, :), 1));
- MB_forcedstandalone = MB_forcedstandalone'; % Transpose
- % Run cluster-based permutation test for Standalone Decisions using function from DDTBOX
- [MB_Results.Standalone.cluster_permtest_outputs] =...
- eegca_multcomp_cluster_permtest(...
- MB_freestandalone, ...
- MB_forcedstandalone, ...
- 'alpha', cluster_permtest_criticalAlpha, ...
- 'iterations', cluster_permtest_iterations, ...
- 'clusteringalpha', cluster_permtest_clusteringAlpha, ...
- 'use_yuen', 0, ...
- 'tail', 'both');
- % Save Standalone Results from cluster-based permutation test
- MB_Results.Standalone.cluster_permtest_criticalAlpha = cluster_permtest_criticalAlpha;
- MB_Results.Standalone.cluster_permtest_clusteringAlpha = cluster_permtest_clusteringAlpha;
- MB_Results.Standalone.cluster_permtest_iterations = cluster_permtest_iterations;
- % Add timepoints information and info about EEG data
- MB_Results.Standalone.timepoints = timepts_struct.resp;
- MB_Results.Standalone.chanlocs = chanlocs;
- % Y Offset for statistical significance markers in plot
- sigMarkers_Y_Offset = 3; % Add extra one to account for 1/0 h test coding
- % E.g., A value of 2 means sig. timepoints will appear at Y value -1
- %% Plot MB and Diffs Below
- figure('Name', 'Free vs Forced Initial MB');
- subplot(6, 1, 1:3);
- plot(timepts_struct.resp, ...
- mean(mean(Epoch.FreeStandaloneAll(MuBeta_Freq_ttests, :, :), ...
- 1), ...
- 3), ...
- 'linewidth', 2);
- hold on;
- plot(timepts_struct.resp, ...
- mean(mean(Epoch.ForcedStandaloneAll(MuBeta_Freq_ttests, :, :), ...
- 1), ...
- 3), ...
- 'linewidth', 2);
- % Plot statistical significance markers from cluster-based permutation test
- tempSigMarkers = MB_Results.Standalone.cluster_permtest_outputs.corrected_h;
- tempSigMarkers(tempSigMarkers == 0) = nan;
- plot(timepts_struct.resp, ...
- tempSigMarkers - sigMarkers_Y_Offset, ...
- 'linewidth', 2);
- xlim([-1000, 100]);
- ylim([-2.5, -0.5]);
- x_patch = [-130, -70, -70, -130];
- y_patch = [-14, -14, 6, 6];
- fill(x_patch, y_patch, [0.8 0.8 0.8], 'EdgeColor', 'none', 'FaceAlpha', 0.4);
- xline(0, 'k', 'LineWidth', 1.5);
- line([timepts_struct.resp(1), timepts_struct.resp(end)], [0, 0], 'color', 'k');
- ylabel('dB');
- %legend({'Free', 'Forced'}, 'location', 'southwest');
- title('Motor Preparation Mu/Beta (8-30Hz)');
- % Mean Difference and SEMs
- subplot(6, 1, 4);
- plot(timepts_struct.resp, ...
- mean(mean(Epoch.FreeStandaloneAll(MuBeta_Freq_ttests, :, :) - Epoch.ForcedStandaloneAll(MuBeta_Freq_ttests, :, :), ...
- 1), ...
- 3), ...
- 'linewidth', 2);
- hold on;
- xlim([-1000, 100]);
- line([timepts_struct.resp(1), timepts_struct.resp(end)], [0, 0], 'color', 'k');
- % Make shaded standard error regions (using functions from DDTBOX v1.0.5)
- % First, calculate mean values and standard errors
- avg_y_vals = mean(mean(Epoch.FreeStandaloneAll(MuBeta_Freq_ttests, :, :) - Epoch.ForcedStandaloneAll(MuBeta_Freq_ttests, :, :), 1), 3);
- % Calculate standard errors of the mean
- standard_error_vals = ...
- std( ...
- squeeze( ...
- mean( ...
- Epoch.FreeStandaloneAll(MuBeta_Freq_ttests, :, :) - Epoch.ForcedStandaloneAll(MuBeta_Freq_ttests, :, :) ...
- , 1) ...
- )' ...
- ) ...
- ./ sqrt(size(Epoch.FreeStandaloneAll, 3));
- % Create shaded error regions
- [patch_x, patch_y] = dd_make_error_bar_object(timepts_struct.resp, ...
- avg_y_vals, ...
- standard_error_vals);
- SE_shading = patch('xdata', patch_x, 'ydata', patch_y);
- SE_shading.FaceAlpha = shadingAlpha; % Transparency
- % SE_shading.FaceColor = spectra_plots_colour_map(1, :);
- SE_shading.EdgeColor = 'none';
- xlim([-1000, 100]);
- ylim([-0.5, 0.5]);
- ylabel('Diff [µV]');
- % Effect Sizes (Cohen's d)
- subplot(6, 1, 5);
- plot(timepts_struct.resp, ...
- mean(mean(Epoch.FreeStandaloneAll(MuBeta_Freq_ttests, :, :) - Epoch.ForcedStandaloneAll(MuBeta_Freq_ttests, :, :), ...
- 1), ...
- 3) ...
- ./ MB_Results.Standalone.differenceWave_SD, ...
- 'linewidth', 2);
- ylabel('Cohen''s d');
- ylim([-1, 0.5]);
- xlim([-1000, 100]);
- line([timepts_struct.resp(1), timepts_struct.resp(end)], [0, 0], 'color', 'k');
- % Bayes Factors BF10
- subplot(6, 1, 6);
- semilogy(timepts_struct.resp, ...
- MB_Results.Standalone.bf10, ...
- 'linewidth', 2);
- ylim([0, 1500]);
- xlim([-1000, 100]);
- line([timepts_struct.resp(1), timepts_struct.resp(end)], [1, 1], 'color', 'k');
- ylabel('BF10');
- yticks([0, 1, 100, 1000]);
- % Save plot
- %saveas(gcf, 'ERP Plots/no RIDE Mass Uni MB Resp.png');
- % subplot(7, 1, 7);
- % plot(timepts_struct.resp, ...
- % ROI.p, ...
- % 'linewidth', 2);
- % ylim([0, 1]);
- %
- % line([timepts_struct.resp(1), timepts_struct.resp(end)], [0.05, 0.05], 'color', 'k');
- % ylabel('p');
- %% Cluster-based permutation tests for Slope and Amplitude Regressions
- % Assumptions:
- % - mb_slope_beta_RT.free / .forced: [nSubjects x nTimeValid]
- % - mb_amp_beta_RT.free / .forced: [nSubjects x nTimeValid] if you used the SAME window;
- % otherwise mask amplitude to the same valid region first.
- % - timepts_struct.resp: 1 x nTime (ms) for the full epoch
- % - time_valid: 1 x nTimeValid (ms) for the valid interior samples
- % - eegca_multcomp_cluster_permtest: your cluster test util; accepts (data, null, ...)
- % - ttest_bayes_df: your helper returning (bf10, p)
- measures = { ...
- struct('name','Slope','data', mb_slope_beta_RT,'time',group_time_valid), ...
- struct('name','Amp', 'data', mb_amp_beta_RT, 'time',group_time_valid) ...
- };
- conds_out = {'Free','Forced'};
- MB_RT_Results = struct();
- for m = 1:numel(measures)
- meas_name = measures{m}.name;
- meas_data = measures{m}.data;
- meas_time = measures{m}.time;
- for ci = 1:numel(conds_out)
- cname = lower(conds_out{ci});
- if ~isfield(meas_data, cname) || isempty(meas_data.(cname))
- warning('%s/%s: beta matrix missing or empty.', meas_name, cname);
- continue
- end
- betas = meas_data.(cname);
- keep_subj = any(isfinite(betas),2);
- betas = betas(keep_subj,:);
- keep_time = any(isfinite(betas),1);
- betas = betas(:,keep_time);
- time_use = meas_time(keep_time);
- if isempty(betas) || size(betas,1) < 5
- warning('%s/%s: not enough usable data after NaN filtering.', meas_name, cname);
- continue
- end
- MB_RT_Results.(meas_name).(conds_out{ci}).cluster_permtest_outputs = ...
- eegca_multcomp_cluster_permtest( ...
- betas, zeros(size(betas)), ...
- 'alpha', cluster_permtest_criticalAlpha, ...
- 'iterations', cluster_permtest_iterations, ...
- 'clusteringalpha', cluster_permtest_clusteringAlpha, ...
- 'use_yuen', 0, ...
- 'tail', 'both');
- MB_RT_Results.(meas_name).(conds_out{ci}).time = time_use;
- MB_RT_Results.(meas_name).(conds_out{ci}).nSubjects = size(betas,1);
- Tuse = size(betas,2);
- bf10 = nan(1,Tuse); pval = nan(1,Tuse); sd_b = nan(1,Tuse);
- for tt = 1:Tuse
- x = betas(:,tt); x = x(isfinite(x));
- if numel(x) < 5, continue, end
- [bf10(tt), pval(tt)] = ttest_bayes_df(x, 0);
- [~, ~, ~, stats] = ttest(x, 0);
- if isfield(stats,'sd'), sd_b(tt) = stats.sd; end
- end
- MB_RT_Results.(meas_name).(conds_out{ci}).bf10 = bf10;
- MB_RT_Results.(meas_name).(conds_out{ci}).p = pval;
- MB_RT_Results.(meas_name).(conds_out{ci}).diff_SD = sd_b;
- end
- end
- %% -------- TOP: FREE --------
- figure;
- subplot(6,1,1:2);
- hold on;
- % Define colours and labels for different tertiles
- colors = {t1_opacity, t2_opacity, t3_opacity};
- labels = {'Fast', 'Medium', 'Slow'};
- dataFieldsFree = {'FreeStandaloneFast', 'FreeStandaloneMedium', 'FreeStandaloneSlow'};
- for i = 1:3
- % Extract the current tertile data for Free condition
- data = Epoch.(dataFieldsFree{i})(MB_freq, :, :);
- % Calculate mean and SEM for the current tertile
- avg_y_vals = mean(mean(data, 1), 3);
- standard_error_vals = std(squeeze(mean(data, 1))') ./ sqrt(size(data, 3));
- % Plot mean line
- plot(timepts_struct.resp, smoothdata(avg_y_vals, 'gaussian', ERP_smoothing_constant), ...
- 'Color', colors{i}(1:4), 'LineWidth', 2, 'DisplayName', labels{i});
- % Shaded error
- [patch_x, patch_y] = dd_make_error_bar_object(timepts_struct.resp, avg_y_vals, standard_error_vals);
- SE_shading = patch('xdata', patch_x, 'ydata', patch_y);
- SE_shading.FaceAlpha = 0.2;
- SE_shading.FaceColor = colors{i}(1:3);
- SE_shading.EdgeColor = 'none';
- end
- % ----- Cluster permutation markers -----
- % Slope
- sigMaskSlopeFree = MB_RT_Results.Slope.Free.cluster_permtest_outputs.corrected_h;
- sigMaskSlopeFree(sigMaskSlopeFree==0) = NaN;
- y_mark_slope = -2.4;
- plot(MB_RT_Results.Slope.Free.time, sigMaskSlopeFree * y_mark_slope, 'k-', 'LineWidth', 2);
- % Amplitude
- sigMaskAmpFree = MB_RT_Results.Amp.Free.cluster_permtest_outputs.corrected_h;
- sigMaskAmpFree(sigMaskAmpFree==0) = NaN;
- y_mark_amp = -2.2; % offset so lines don't overlap
- plot(MB_RT_Results.Amp.Free.time, sigMaskAmpFree * y_mark_amp, 'r-', 'LineWidth', 2);
- xlim([-1000, 50]);
- ylim([-2.5, 0]);
- x_patch = [-130, -70, -70, -130];
- x2_patch = [-300, -70, -70, -300];
- y_patch = [-2.5, -2.5, 0, 0];
- fill(x_patch, y_patch, [0.8 0.8 0.8], 'EdgeColor', 'none', 'FaceAlpha', 0.4);
- fill(x2_patch, y_patch, [0.8 0.8 0.8], 'EdgeColor', 'none', 'FaceAlpha', 0.2);
- xline(0, 'k', 'LineWidth', 1.5);
- ylabel('µV/m^2');
- title('MB - Voluntary Decisions');
- % BF
- subplot(6,1,3);
- % Slope BF10
- semilogy(MB_RT_Results.Slope.Free.time, MB_RT_Results.Slope.Free.bf10, 'k-', 'LineWidth', 1.8, 'DisplayName', 'Free Slope BF_{10}');
- hold on;
- % Amplitude BF10
- semilogy(MB_RT_Results.Amp.Free.time, MB_RT_Results.Amp.Free.bf10, 'r-', 'LineWidth', 1.8, 'DisplayName', 'Free Amp BF_{10}');
- % Reference lines
- xline(0, 'k', 'LineWidth', 1.5);
- yline(1, 'k', 'LineWidth', 1); % BF=1 reference
- % yline(3, 'k--', 'LineWidth', 1); % optional: "moderate evidence" threshold
- xlim([-1000, 50]);
- ylim([0, 150])
- yticks([0,1, 100]);
- ylabel('BF_{10}');
- xlabel('Time (ms)');
- title('BF (Slope & Amplitude)');
- % -------- MIDDLE: FORCED --------
- subplot(6,1,4:5);
- hold on;
- dataFieldsForced = {'ForcedStandaloneFast', 'ForcedStandaloneMedium', 'ForcedStandaloneSlow'};
- for i = 1:3
- data = Epoch.(dataFieldsForced{i})(MB_freq, :, :);
- avg_y_vals = mean(mean(data, 1), 3);
- standard_error_vals = std(squeeze(mean(data, 1))') ./ sqrt(size(data, 3));
- plot(timepts_struct.resp, smoothdata(avg_y_vals, 'gaussian', ERP_smoothing_constant), ...
- 'Color', colors{i}(1:4), 'LineWidth', 2, 'DisplayName', labels{i});
- [patch_x, patch_y] = dd_make_error_bar_object(timepts_struct.resp, avg_y_vals, standard_error_vals);
- SE_shading = patch('xdata', patch_x, 'ydata', patch_y);
- SE_shading.FaceAlpha = 0.2;
- SE_shading.FaceColor = colors{i}(1:3);
- SE_shading.EdgeColor = 'none';
- end
- % Slope
- sigMaskSlopeForced = MB_RT_Results.Slope.Forced.cluster_permtest_outputs.corrected_h;
- sigMaskSlopeForced(sigMaskSlopeForced==0) = NaN;
- plot(MB_RT_Results.Slope.Forced.time, sigMaskSlopeForced * y_mark_slope, 'k-', 'LineWidth', 2);
- % Amplitude
- sigMaskAmpForced = MB_RT_Results.Amp.Forced.cluster_permtest_outputs.corrected_h;
- sigMaskAmpForced(sigMaskAmpForced==0) = NaN;
- plot(MB_RT_Results.Amp.Forced.time, sigMaskAmpForced * y_mark_amp, 'r-', 'LineWidth', 2);
- xlim([-1000, 50]);
- ylim([-2.5, 0]);
- x_patch = [-130, -70, -70, -130];
- x2_patch = [-300, -70, -70, -300];
- y_patch = [-3, -3, 0, 0];
- fill(x_patch, y_patch, [0.8 0.8 0.8], 'EdgeColor', 'none', 'FaceAlpha', 0.4);
- fill(x2_patch, y_patch, [0.8 0.8 0.8], 'EdgeColor', 'none', 'FaceAlpha', 0.2);
- xline(0, 'k', 'LineWidth', 1.5);
- ylabel('µV/m^2');
- title('MB - Forced Decisions');
- hold off;
- % -------- BOTTOM: BAYES FACTORS (correct .bf10 fields) --------
- subplot(6,1,6);
- % Slope BF10
- semilogy(MB_RT_Results.Slope.Forced.time, MB_RT_Results.Slope.Forced.bf10, 'k-', 'LineWidth', 1.8, 'DisplayName', 'Forced Slope BF_{10}');
- hold on;
- % Amplitude BF10
- semilogy(MB_RT_Results.Amp.Forced.time, MB_RT_Results.Amp.Forced.bf10, 'r-', 'LineWidth', 1.8, 'DisplayName', 'Forced Amp BF_{10}');
- % Reference lines
- xline(0, 'k', 'LineWidth', 1.5);
- yline(1, 'k', 'LineWidth', 1); % BF=1 reference
- xlim([-1000, 50]);
- ylim([0, 110000]);
- yticks([0,1, 150, 10^5]);
- ylabel('BF_{10}');
- xlabel('Time (ms)');
- title('BF (Slope & Amplitude)');
eegca_massuni_MB.m, no license · at the source
Overview
- Melbourne School of Psychological Sciences, The University of Melbourne, Melbourne, Australia
- Division of Science, New York University Abu Dhabi, Abu Dhabi, United Arab Emirates
Abstract
Voluntary decisions have previously been described by where they arise in the brain and how actions corresponding to one’s choice are prepared. However, the processes by which these internally guided decisions are formed and translated into action remain unclear. We tested whether neural signatures of evidence accumulation and motor preparation—established in perceptual decision-making—are also observed during voluntary decisions. Forty-nine adults made voluntary (free choice between two options) and forced (single specified choice) decisions while electroencephalography was recorded. To isolate decision formation from action selection, all responses were made with a right-handed keypress. After applying signal deconvolution and current source density transformations, we examined three signals: the centro-parietal positivity (CPP), Mu/
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 16 matches between paragraphs and lines of code.
OSF t7z4h
Availability: 1 check, the latest on 30 September 2026: the link answers (HTTP 200)
- 30 September 2026: the link answers (HTTP 200)
54 files
- EEG Processing/
eegca_1_clean_behavioura , MATLAB, 300 linesl_results.m - EEG Processing/
eegca_2_preprocessing_st , MATLAB, 211 linesep1.m - EEG Processing/
eegca_3_preprocessing_st , MATLAB, 164 lines, 1 matchep2.m - EEG Processing/
eegca_4_preprocessing_st , MATLAB, 173 lines, 1 matchep3.m - EEG Processing/
eegca_5_decresp_epoch.m , MATLAB, 398 lines - EEG Processing/
eegca_5_decstim_epoch.m , MATLAB, 340 lines - EEG Processing/
eegca_5_mubeta_C3_epoch. , MATLAB, 209 linesm - EEG Processing/
eegca_ICs_to_remove.m , MATLAB, 216 lines - EEG Processing/
eegca_add_behavioural_da , MATLAB, 88 linesta.m - EEG Processing/
eegca_bad_channels.m , MATLAB, 100 lines - EEG Processing/
eegca_bids_color.m , MATLAB, 1,070 lines - EEG Processing/
eegca_colour_rankorder.m , MATLAB, 425 lines - EEG Processing/
eegca_recode_events.m , MATLAB, 415 lines - EEG Processing/
eegca_reject_sections.m , MATLAB, 218 lines - EEG Processing/
eegca_remove_empty_event , MATLAB, 256 liness.m - EEG Processing/
eegca_transform_mubeta.m , MATLAB, 223 lines - EEG Processing/
wavelet_convolution.m , MATLAB, 593 lines, 1 match - Experiment Code/
Functions Library/ , MATLAB, 78 lineseegca_calculate_timing_p arameters.m - Experiment Code/
Functions Library/ , MATLAB, 22 lineseegca_close_eeg_ports.m - Experiment Code/
Functions Library/ , MATLAB, 68 lineseegca_comprehension_chec k.m - Experiment Code/
Functions Library/ , MATLAB, 343 lineseegca_display_task_instr uctions.m - Experiment Code/
Functions Library/ , MATLAB, 19 lineseegca_draw_CoMPhase_stim ulus.m - Experiment Code/
Functions Library/ , MATLAB, 30 lineseegca_draw_CoMSwitchRepo rtPhase.m - Experiment Code/
Functions Library/ , MATLAB, 72 lineseegca_draw_choicePhase_s timuli.m - Experiment Code/
Functions Library/ , MATLAB, 19 lineseegca_draw_decisionPhase _stimulus.m - Experiment Code/
Functions Library/ , MATLAB, 19 lineseegca_draw_delayPhase_st imulus.m - Experiment Code/
Functions Library/ , MATLAB, 21 lineseegca_draw_fix_stimulusG rey.m - Experiment Code/
Functions Library/ , MATLAB, 21 lineseegca_draw_fix_stimulusW hite.m - Experiment Code/
Functions Library/ , MATLAB, 31 lineseegca_end_of_block.m - Experiment Code/
Functions Library/ , MATLAB, 136 lines, 1 matcheegca_experiment_paramet ers.m - Experiment Code/
Functions Library/ , MATLAB, 47 lineseegca_load_balloon_image s.m - Experiment Code/
Functions Library/ , MATLAB, 34 lineseegca_participant_demogr aphics.m - Experiment Code/
Functions Library/ , MATLAB, 67 lineseegca_pre_questions.m - Experiment Code/
Functions Library/ , MATLAB, 88 lineseegca_preallocate_result s.m - Experiment Code/
Functions Library/ , MATLAB, 15 lineseegca_reinstate_system.m - Experiment Code/
Functions Library/ , MATLAB, 40 lineseegca_self_paced_break.m - Experiment Code/
Functions Library/ , MATLAB, 20 lineseegca_send_eeg_event_cod es.m - Experiment Code/
Functions Library/ , MATLAB, 21 lineseegca_send_event_trigger _mmb.m - Experiment Code/
Functions Library/ , MATLAB, 1,247 lineseegca_set_conditions_cur rent_trial.m - Experiment Code/
Functions Library/ , MATLAB, 22 lineseegca_set_up_eeg_port_mm b.m - Experiment Code/
Functions Library/ , MATLAB, 46 lineseegca_warnings.m - Experiment Code/
RUN_eegca_experimental_s , MATLAB, 1,762 linesession.m - Experiment Code/
RUN_eegca_practice_sessi , MATLAB, 714 lines, 1 matchon.m - RT and EEG Analyses /
Mass Univariate Analyses/ , MATLAB, 2,461 lines, 1 matcheegca_massuni_ERP_resplo cked.m - RT and EEG Analyses /
Mass Univariate Analyses/ , MATLAB, 1,689 lines, 1 matcheegca_massuni_ERP_stimlo cked.m - RT and EEG Analyses /
Mass Univariate Analyses/ , MATLAB, 1,148 lines, 3 matcheseegca_massuni_MB.m - RT and EEG Analyses /
Mass Univariate Analyses/ , MATLAB, 438 lines, 1 matcheegca_multcomp_cluster_p ermtest.m - RT and EEG Analyses /
Mass Univariate Analyses/ , MATLAB, 2,405 lineseegca_plot_heatmaps.m - RT and EEG Analyses /
Mass Univariate Analyses/ , MATLAB, 353 lineseegca_plot_heatmaps_MB.m - RT and EEG Analyses /
RT and Fixed Window Analyses/ , R, 397 lines, 2 matcheseegca_ERP_LMM.Rmd - RT and EEG Analyses /
RT and Fixed Window Analyses/ , MATLAB, 692 lines, 2 matcheseegca_derive_ERP_measure s.m - RT and EEG Analyses /
RT and Fixed Window Analyses/ , MATLAB, 173 lines, 1 matcheegca_derive_MB_measures .m - RT and EEG Analyses /
RT and Fixed Window Analyses/ , MATLAB, 76 lineseegca_pool_ERP_slopeamp. m - RT and EEG Analyses /
RT and Fixed Window Analyses/ , MATLAB, 60 lineseegca_pool_MB_slopeamp.m
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;
- 54 scripts, each with its path and the digest of its content;
- 16 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
No dataset and no data link were found in the paper.
Data and Code Availability
All code and data used for the experiment and analyses described in this manuscript are available at http://
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, 30 September 2026: the first record
Recorded: type, language, journal, volume, pages, dates, 6 authors, 6 keywords, 2 funders, 96 references.
Cite
This paper
Fong, L. C., Garrett, P. M., Smith, P. L., Hester, R., Bode, S., & Feuerriegel, D. (2026). Tracing the neural trajectories of evidence accumulation and motor preparation processes during voluntary decisions. Imaging neuroscience (Cambridge, Mass.), 4, IMAG.a.1184. https://
BibTeX
@article{fong2026tracing
author = {Fong, Lauren C. and Garrett, Paul M. and Smith, Philip L. and Hester, Robert and Bode, Stefan and Feuerriegel, Daniel},
title = {{Tracing the neural trajectories of evidence accumulation and motor preparation processes during voluntary decisions}},
journal = {Imaging neuroscience (Cambridge, Mass.)},
year = {2026},
month = mar,
volume = {4},
pages = {IMAG.a.1184},
publisher = {MIT Press},
issn = {2837-6056},
doi = {10.1162/
url = {https://
pmid = {41924032},
pmcid = {PMC13037662}
}
RIS
TY - JOUR
AU - Fong, Lauren C.
AU - Garrett, Paul M.
AU - Smith, Philip L.
AU - Hester, Robert
AU - Bode, Stefan
AU - Feuerriegel, Daniel
TI - Tracing the neural trajectories of evidence accumulation and motor preparation processes during voluntary decisions
T2 - Imaging neuroscience (Cambridge, Mass.)
J2 - Imaging Neurosci (Camb)
PY - 2026
DA - 2026/
VL - 4
SP - IMAG.a.1184
SN - 2837-6056
PB - MIT Press
DO - 10.1162/
UR - https://
LA - en
ER -
CSL-JSON
{
"id": "10.1162/
"type": "article-journal",
"title": "Tracing the neural trajectories of evidence accumulation and motor preparation processes during voluntary decisions",
"container-title": "Imaging neuroscience (Cambridge, Mass.)",
"author": [
{
"family": "Fong",
"given": "Lauren C."
},
{
"family": "Garrett",
"given": "Paul M."
},
{
"family": "Smith",
"given": "Philip L."
},
{
"family": "Hester",
"given": "Robert"
},
{
"family": "Bode",
"given": "Stefan"
},
{
"family": "Feuerriegel",
"given": "Daniel"
}
],
"container-title-short":
"volume": "4",
"page": "IMAG.a.1184",
"DOI": "10.1162/
"PMID": "41924032",
"PMCID": "PMC13037662",
"ISSN": "2837-6056",
"publisher": "MIT Press",
"URL": "https://
"language": "en",
"issued": {
"date-parts": [
[
2026,
3,
30
]
]
}
}
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.1523/eneuro.0316-25.2026 [code]
- Neural Mechanisms of Self-Generated Action Sequences.Journal: eNeuroIn common: EEGLAB, emmeans, lmerTest, 3 other tools, cognitive, 14 references
- [2] doi:10.7554/elife.83025 [code]
- Balancing true and false detection of intermittent sensory targets by adjusting the inputs to the evidence accumulation process.Journal: eLifeIn common: Psychtoolbox, EEGLAB, Statistics and Machine Learning Toolbox, cognitive, 14 references
- [3] doi:10.1016/j.isci.2026.115471 [code]
- Neural decision dynamics underlying reinforcement learning and working memory.Journal: iScienceIn common: cognitive, 16 references
- [4] doi:10.7554/elife.82823 [code]
- Quantifying decision-making in dynamic, continuously evolving environments.Journal: eLifeIn common: Psychtoolbox, EEGLAB, Statistics and Machine Learning Toolbox, cognitive, 13 references
- [5] doi:10.1038/s42003-025-07646-3 [code]
- Neural mechanisms of metacognitive improvement under speed pressure.Journal: Communications biologyIn common: afex, lme4, tidyverse, cognitive, 11 references
- [6] doi:10.1093/cercor/bhaf318 [code]
- Voluntary action as problem-solving: an functional magnetic resonance imaging study.Journal: Cerebral cortex (New York, N.Y. : 1991)In common: emmeans, lmerTest, lme4, 1 other tool, cognitive, 9 references
- [7] doi:10.1038/s41562-024-01971-z [code]
- Common neural choice signals can emerge artefactually amid multiple distinct value signals.Journal: Nature human behaviourIn common: EEGLAB, lmerTest, lme4, 2 other tools, cognitive, 10 references
- [8] doi:10.1111/psyp.70076 [code]
- Limited Evidence for Probabilistic Cueing Effects on Grating-Evoked Event-Related Potentials and Orientation Decoding Performance.Journal: PsychophysiologyIn common: EEGLAB, Statistics and Machine Learning Toolbox, 9 references, author Daniel Feuerriegel
- [9] doi:10.3758/s13423-022-02237-3 [code]
- "Reliable organisms from unreliable components" revisited: the linear drift, linear infinitesimal variance model of decision making.Journal: Psychonomic bulletin & reviewIn common: cognitive, 9 references, author Philip L. Smith
- [10] doi:10.3389/fpsyg.2024.1380196 [code]
- Modality-specific impacts of distractors on visual and auditory categorical decision-making: an evidence accumulation perspective.Journal: Frontiers in psychologyIn common: broom, EEGLAB, emmeans, 4 other tools, cognitive, 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, 54 scripts, and 16 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:640e448d9177346a…
Add the badge to the code's README
If you are an author or a maintainer of this paper's code, you can add this badge. It says what OSCR knows of the paper (its code, its validated tracing map) and links the code to this page. Paste one of these snippets under the README's title. Keep the two marks around it, so that the badge can be replaced in place and is never added twice. OSCR changes nothing in your repository.
Markdown
<!-- oscr-badge:start -->
[](https://openscicode.org/badge/doi/10.1162/imag.a.1184)
<!-- oscr-badge:end -->reStructuredText
.. oscr-badge:start
.. image:: https://openscicode.org/badge/doi/10.1162/imag.a.1184.svg
:target: https://openscicode.org/badge/doi/10.1162/imag.a.1184
:alt: OSCR
.. oscr-badge:endHTML
<!-- oscr-badge:start -->
<a href="https://openscicode.org/badge/doi/10.1162/imag.a.1184"><img src="https://openscicode.org/badge/doi/10.1162/imag.a.1184.svg" alt="OSCR"></a>
<!-- oscr-badge:end -->If you choose to, you can have the badge kept up to date for you, with oscr badge --write from the command line or with the GitHub Action in your repository's workflows. Every other form and option (a card, AsciiDoc, LaTeX, shields.io) is on the badge 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: code errors and mismatches between the code and the paper about this paper and its code, from readers and its authors, beside the paper and its tracing map.
Report a mismatch between the code and the paper · Report a code error (signed in)
Reproductions: reports from readers who ran the authors' code and did not get the paper's result, what they ran, with which environment, commit and data.
Report a reproduction failure (signed in)
Activity: what happens around this paper: new versions of its record, its map's validation, discussions and reproductions. It opens with sign-in.
