OSCR

Effects of TMS on the Decoding and Electrophysiology of Priority in Working Memory.

Code ↔ Paper

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

The 9 matches
  1. [1] § Materials and Methods › Decoding ↔ MVPA/MVPAcode/MVPALight_HTC_DSRfullsplit.m, lines 95–166 · score 0.82 · MVPA Light, beta power, theta power, alpha power, FieldTrip, L2
  2. [2] § Materials and Methods › Decoding ↔ MVPA/MVPAcode/MVPALight_HTC_SRfullsplit.m, lines 96–168 · score 0.82 · MVPA Light, beta power, theta power, alpha power, FieldTrip, L2
  3. [3] § Materials and Methods › EEG dynamics › EEG analyses of phase ↔ Phase Analyses/TMSPLV_slidingcombined.m, lines 1–31 · score 0.76 · frequency adaptive, sliding window, circular statistics, PLV changes, phase shifts, spTMS
  4. [4] § Materials and Methods › EEG dynamics › EEG analyses of phase ↔ Phase Analyses/CuePLV_slidingcombined.m, lines 44–47 · score 0.75 · 20–30 Hz, 8–13 Hz, 13–20 Hz, 4–8 Hz, high beta, low beta
  5. [5] § Materials and Methods › EEG dynamics › EEG analyses of phase ↔ Phase Analyses/TMSPLV_slidingcombined.m, lines 33–36 · score 0.74 · 20–30 Hz, 8–13 Hz, 13–20 Hz, 4–8 Hz, high beta, low beta
  6. [6] § Materials and Methods › EEG dynamics › EEG analyses of phase ↔ Phase Analyses/TMSPLV_slidingcombined.m, lines 41–153 · score 0.70 · cycle length, window lengths, candidate, high beta, sliding, optimal
  7. [7] § Materials and Methods › EEG dynamics › EEG analyses of phase ↔ Phase Analyses/CuePLV_slidingcombined.m, lines 1–14 · score 0.67 · frequency adaptive, sliding window, PLV changes, phase shifts, cue, SR
  8. [8] § EEG dynamics › Phase dynamics › Prioritization cues ↔ Phase Analyses/CuePLV_slidingcombined.m, lines 450–474 · score 0.56 · circular boundary, phase angle shifts, PLV, low beta, FDR, cue
  9. [9] § Materials and Methods › EEG dynamics › EEG analyses of phase ↔ Phase Analyses/CuePLV_slidingcombined.m, lines 157–182 · score 0.52 · post cue, absolute, chosen, candidate, cycles, PLV

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 · 531 lines · 21 KB · no license · 4 matches

  1. % =================================================================
  2. % Cue-Related Sliding-Window, Frequency-Adaptive Phase Analysis
  3. % DSR vs SR comparisons for PLV change, mean phase shift,
  4. % and inter-subject PLV (pre/post windows matched in length)
  5. % =================================================================
  6. % Fulvio & Postle
  7. clear; close all; clc;
  8. % rng('shuffle'); % sets the seed based on current time
  9. % s = rng; % capture current state
  10. % fprintf('Random seed for this run: %d (RNG type: %s)\n', s.Seed, s.Type);
  11. %% -----------------------------
  12. %% Set random seed for reproducibility
  13. %% -----------------------------
  14. seed_used = 147377794;
  15. rng(seed_used, 'twister');
  16. fprintf('RNG seed set to %d\n', seed_used);
  17. % addpath to Circular Statistics Toolbox here
  18. fprintf('=== LOADING TRIAL DATA ===\n');
  19. %% Load preprocessed baselined DSR and SR trial data
  20. load 'TMSEEG_DSR_NoLures_August2025_100hz_CueERP_indivtrials.mat';
  21. DSR_trials = ERPall;
  22. load 'TMSEEG_SR_NoLures_August2025_100hz_CueERP_indivtrials.mat';
  23. SR_trials = ERPall;
  24. n_subjects = 12;
  25. fs = 100; % Hz
  26. full_time_vector = -2000:(1000/fs):2000; % full time axis
  27. n_timepoints_full = length(full_time_vector);
  28. subset_cols = 901:1301; % these are the indices of the cue-related timepoints in the EEG data
  29. % extracts -2000 to +2000 ms relative to cue onset
  30. % (cue onset is at column 1101 in the original data matrix)
  31. time_vector = full_time_vector;
  32. n_timepoints = length(time_vector);
  33. %% Frequency bands
  34. freq_bands = {[4 8], [8 13], [13 20], [20 30]};
  35. band_names = {'Theta','Alpha','Low Beta','High Beta'};
  36. n_bands = length(freq_bands);
  37. %% Candidate cycles per band
  38. candidate_cycles = {
  39. 2:4, % Theta
  40. 2:4, % Alpha
  41. 3:6, % Low Beta
  42. 3:6 % High Beta
  43. };
  44. pre_end_ms = -1; % pre window must end 1 ms before cue (we go to nearest sample)
  45. post_max = 500; % ms
  46. n_perm_between = 5000; % number of permutations to test
  47. n_boot = 1000; % bootstrap samples for SEM
  48. %% Prepare storage
  49. cue_results = struct();
  50. %% Extract trial data
  51. combined_phase_data = cell(n_subjects,1);
  52. dsr_phase_data = cell(n_subjects,1);
  53. sr_phase_data = cell(n_subjects,1);
  54. for subj = 1:n_subjects
  55. dsr_trials_subj = DSR_trials{subj}(:, subset_cols); % cue window subset
  56. sr_trials_subj = SR_trials{subj}(:, subset_cols);
  57. dsr_phase_data{subj} = dsr_trials_subj;
  58. sr_phase_data{subj} = sr_trials_subj;
  59. combined_phase_data{subj} = [dsr_trials_subj; sr_trials_subj];
  60. end
  61. %% Precompute some time/sample helpers
  62. dt = time_vector(2) - time_vector(1); % ms per sample (should be 1000/fs)
  63. cue_idx_in_subset = find(time_vector == 0, 1, 'first');
  64. if isempty(cue_idx_in_subset)
  65. error('Cue (time 0) not found in the cropped time vector.');
  66. end
  67. pre_end_idx = cue_idx_in_subset - 1; % last sample before cue (pre window MUST end here)
  68. if pre_end_idx < 1
  69. error('pre_end index would be < 1; check time_vector and subset_cols.');
  70. end
  71. %% -----------------------------
  72. %% Sliding-window adaptive analysis
  73. %% -----------------------------
  74. for band_idx = 1:n_bands
  75. band_name = band_names{band_idx};
  76. freq_band = freq_bands{band_idx};
  77. max_freq = max(freq_band);
  78. fprintf('\n--- %s ---\n', band_name);
  79. % Bandpass filter
  80. filter_order = min(4, floor(n_timepoints/6));
  81. [b,a] = butter(filter_order, freq_band/(fs/2), 'bandpass');
  82. % Hilbert phases for combined trials (trials x time)
  83. combined_phase_hilb = cell(n_subjects,1);
  84. for subj = 1:n_subjects
  85. filt_data = filtfilt(b,a,combined_phase_data{subj}')'; % keep trials x time
  86. combined_phase_hilb{subj} = angle(hilbert(filt_data')'); % trials x time
  87. end
  88. % Candidate post-window start times (ms)
  89. post_start_candidates_ms = 0:post_max; % will convert to sample indices below
  90. tstats = zeros(length(post_start_candidates_ms), length(candidate_cycles{band_idx}));
  91. subj_diffs_all = zeros(n_subjects, length(post_start_candidates_ms), length(candidate_cycles{band_idx}));
  92. %% Loop over candidate cycles
  93. for c = 1:length(candidate_cycles{band_idx})
  94. cycles = candidate_cycles{band_idx}(c);
  95. window_length_ms = cycles / mean(freq_band) * 1000; %max_freq * 1000;
  96. % convert to number of samples (round to nearest sample)
  97. window_samples = max(1, round(window_length_ms / dt));
  98. % Pre window: end exactly 1 sample before cue and have length = window_samples
  99. pre_idx = (pre_end_idx - window_samples + 1) : pre_end_idx;
  100. % if this would go before start, shorten to available samples
  101. if pre_idx(1) < 1
  102. pre_idx = 1:pre_end_idx;
  103. window_samples = length(pre_idx);
  104. end
  105. for w = 1:length(post_start_candidates_ms)
  106. post_start_ms = post_start_candidates_ms(w);
  107. % find the first sample in the cropped time vector >= post_start_ms
  108. post_start_idx = find(time_vector >= post_start_ms, 1, 'first');
  109. if isempty(post_start_idx)
  110. tstats(w,c) = NaN; continue
  111. end
  112. post_end_idx = post_start_idx + window_samples - 1;
  113. % ensure post_end within allowed post_max and within data bounds
  114. if post_end_idx > n_timepoints || time_vector(post_end_idx) > post_max
  115. tstats(w,c) = NaN; continue
  116. end
  117. post_idx = post_start_idx : post_end_idx;
  118. % compute subject-level pre/post PLVs (using combined trials)
  119. for subj = 1:n_subjects
  120. phases = combined_phase_hilb{subj}; % trials x time
  121. % average across trials then across timepoints → use all samples
  122. pre_plv = abs(mean(mean(exp(1i*phases(:,pre_idx)),1),2));
  123. post_plv = abs(mean(mean(exp(1i*phases(:,post_idx)),1),2));
  124. subj_diffs_all(subj,w,c) = post_plv - pre_plv;
  125. end
  126. % t-stat across subjects
  127. [~,~,~,st] = ttest(subj_diffs_all(:,w,c));
  128. tstats(w,c) = st.tstat;
  129. end
  130. end
  131. %% Select best window (by absolute t-stat)
  132. [~, idx] = max(abs(tstats(:)));
  133. [best_w, best_c] = ind2sub(size(tstats), idx);
  134. best_post_start_ms = post_start_candidates_ms(best_w);
  135. best_window_ms = candidate_cycles{band_idx}(best_c) / mean(freq_band) *1000; %max_freq * 1000;
  136. % recompute window_samples for the chosen window (to avoid rounding drift)
  137. window_samples = max(1, round(best_window_ms / dt));
  138. % final post indices (in cropped time vector)
  139. post_start_idx_final = find(time_vector >= best_post_start_ms, 1, 'first');
  140. post_end_idx_final = post_start_idx_final + window_samples - 1;
  141. if post_end_idx_final > n_timepoints || time_vector(post_end_idx_final) > post_max
  142. error('Selected post window exceeds bounds — check candidate ranges.');
  143. end
  144. post_idx_final = post_start_idx_final : post_end_idx_final;
  145. % final pre indices: end at pre_end_idx and match length (window_samples)
  146. pre_end_idx = cue_idx_in_subset - 1; % ensure correct
  147. pre_start_idx = pre_end_idx - window_samples + 1;
  148. if pre_start_idx < 1
  149. pre_start_idx = 1; % shorten if necessary
  150. end
  151. pre_idx_final = pre_start_idx : pre_end_idx;
  152. fprintf('Selected window: %.1f - %.1f ms post-cue (length %.1f ms, %d samples) %f %f\n', ...
  153. time_vector(post_idx_final(1)), time_vector(post_idx_final(end)), best_window_ms, window_samples, length(pre_idx_final), length(post_idx_final));
  154. %% -----------------------------
  155. %% Compute PLV change and phase shifts per subject (DSR and SR separately) within the selected window
  156. %% -----------------------------
  157. dsr_diffs = zeros(n_subjects,1);
  158. sr_diffs = zeros(n_subjects,1);
  159. dsr_phase_shift = zeros(n_subjects,1);
  160. sr_phase_shift = zeros(n_subjects,1);
  161. for subj = 1:n_subjects
  162. % DSR
  163. filt_dsr = filtfilt(b,a,dsr_phase_data{subj}')';
  164. phase_dsr = angle(hilbert(filt_dsr')'); % trials x time
  165. % mean across trials then across timepoints in window
  166. dsr_pre_plv = abs(mean(mean(exp(1i*phase_dsr(:,pre_idx_final)),1),2));
  167. dsr_post_plv = abs(mean(mean(exp(1i*phase_dsr(:,post_idx_final)),1),2));
  168. dsr_diffs(subj) = dsr_post_plv - dsr_pre_plv;
  169. % phase (mean over trials then over timepoints)
  170. pre_phase = angle(mean(mean(exp(1i*phase_dsr(:,pre_idx_final)),1),2));
  171. post_phase = angle(mean(mean(exp(1i*phase_dsr(:,post_idx_final)),1),2));
  172. dsr_phase_shift(subj) = circ_dist(post_phase, pre_phase);
  173. % SR
  174. filt_sr = filtfilt(b,a,sr_phase_data{subj}')';
  175. phase_sr = angle(hilbert(filt_sr')');
  176. sr_pre_plv = abs(mean(mean(exp(1i*phase_sr(:,pre_idx_final)),1),2));
  177. sr_post_plv = abs(mean(mean(exp(1i*phase_sr(:,post_idx_final)),1),2));
  178. sr_diffs(subj) = sr_post_plv - sr_pre_plv;
  179. pre_phase = angle(mean(mean(exp(1i*phase_sr(:,pre_idx_final)),1),2));
  180. post_phase = angle(mean(mean(exp(1i*phase_sr(:,post_idx_final)),1),2));
  181. sr_phase_shift(subj) = circ_dist(post_phase, pre_phase);
  182. end
  183. %% -----------------------------
  184. %% Permutation tests DSR vs SR (paired across subjects)
  185. %% -----------------------------
  186. observed_diff_plv = mean(dsr_diffs) - mean(sr_diffs);
  187. observed_diff_phase = circ_mean(dsr_phase_shift) - circ_mean(sr_phase_shift);
  188. perm_diffs_plv = zeros(n_perm_between,1);
  189. perm_diffs_phase = zeros(n_perm_between,1);
  190. for p = 1:n_perm_between
  191. flip_signs = randi([0 1], n_subjects, 1) * 2 - 1;
  192. perm_diffs_plv(p) = mean(flip_signs .* (dsr_diffs - sr_diffs));
  193. perm_diffs_phase(p) = mean(flip_signs .* (dsr_phase_shift - sr_phase_shift));
  194. end
  195. p_perm_plv = 2*min(mean(perm_diffs_plv >= observed_diff_plv), mean(perm_diffs_plv <= observed_diff_plv));
  196. p_perm_phase = 2*min(mean(perm_diffs_phase >= observed_diff_phase), mean(perm_diffs_phase <= observed_diff_phase));
  197. %% -----------------------------
  198. %% Inter-subject PLV for DSR and SR (consistency of subject-level shifts)
  199. %% -----------------------------
  200. plv_dsr = abs(mean(exp(1i*dsr_phase_shift)));
  201. plv_sr = abs(mean(exp(1i*sr_phase_shift)));
  202. % Bootstrap SEM for each condition
  203. boot_plv_dsr = zeros(n_boot,1);
  204. boot_plv_sr = zeros(n_boot,1);
  205. for bb = 1:n_boot
  206. idxs = randsample(n_subjects, n_subjects, true);
  207. boot_plv_dsr(bb) = abs(mean(exp(1i*dsr_phase_shift(idxs))));
  208. boot_plv_sr(bb) = abs(mean(exp(1i*sr_phase_shift(idxs))));
  209. end
  210. sem_dsr = std(boot_plv_dsr);
  211. sem_sr = std(boot_plv_sr);
  212. % Paired permutation test on inter-subject PLV (swap subject labels)
  213. observed_diff_inter_plv = plv_dsr - plv_sr;
  214. perm_inter_plv = zeros(n_perm_between,1);
  215. for p = 1:n_perm_between
  216. flip = randi([0 1], n_subjects, 1) * 2 - 1;
  217. dsr_perm = dsr_phase_shift;
  218. sr_perm = sr_phase_shift;
  219. idx_flip = flip == -1;
  220. dsr_perm(idx_flip) = sr_phase_shift(idx_flip);
  221. sr_perm(idx_flip) = dsr_phase_shift(idx_flip);
  222. perm_inter_plv(p) = abs(mean(exp(1i*dsr_perm))) - abs(mean(exp(1i*sr_perm)));
  223. end
  224. p_perm_inter_plv = 2 * min(mean(perm_inter_plv >= observed_diff_inter_plv), mean(perm_inter_plv <= observed_diff_inter_plv));
  225. %% -----------------------------
  226. %% Store results
  227. %% -----------------------------
  228. cue_results(band_idx).band_name = band_name;
  229. cue_results(band_idx).freq_band = freq_band;
  230. cue_results(band_idx).pre_idx = pre_idx_final;
  231. cue_results(band_idx).post_idx = post_idx_final;
  232. % PLV change
  233. cue_results(band_idx).dsr_diffs = dsr_diffs;
  234. cue_results(band_idx).sr_diffs = sr_diffs;
  235. cue_results(band_idx).observed_diff_plv = observed_diff_plv;
  236. cue_results(band_idx).p_perm_plv = p_perm_plv;
  237. % Mean phase shift
  238. cue_results(band_idx).dsr_phase_shift = dsr_phase_shift;
  239. cue_results(band_idx).sr_phase_shift = sr_phase_shift;
  240. cue_results(band_idx).observed_diff_phase = observed_diff_phase;
  241. cue_results(band_idx).p_perm_phase = p_perm_phase;
  242. % Inter-subject PLV
  243. cue_results(band_idx).plv_dsr = plv_dsr;
  244. cue_results(band_idx).plv_sr = plv_sr;
  245. cue_results(band_idx).sem_dsr = sem_dsr;
  246. cue_results(band_idx).sem_sr = sem_sr;
  247. cue_results(band_idx).observed_diff_inter_plv = observed_diff_inter_plv;
  248. cue_results(band_idx).p_perm_inter_plv = p_perm_inter_plv;
  249. end
  250. %% FDR correction step
  251. % Collect raw p-values
  252. p_raw = [];
  253. for b = 1:n_bands
  254. p_raw = [p_raw; ...
  255. cue_results(b).p_perm_plv; ...
  256. cue_results(b).p_perm_phase; ...
  257. cue_results(b).p_perm_inter_plv];
  258. end
  259. % Apply FDR
  260. p_fdr = fdr_bh(p_raw);
  261. % Assign back to structure
  262. idx = 1;
  263. for b = 1:n_bands
  264. cue_results(b).p_perm_plv_fdr = p_fdr(idx); idx = idx+1;
  265. cue_results(b).p_perm_phase_fdr = p_fdr(idx); idx = idx+1;
  266. cue_results(b).p_perm_inter_plv_fdr = p_fdr(idx); idx = idx+1;
  267. end
  268. %% -----------------------------
  269. %% Report statistics
  270. %% -----------------------------
  271. fprintf('\n=== Statistics: DSR vs SR (FDR-corrected) ===\n');
  272. for b = 1:n_bands
  273. fprintf('\n%s:\n', cue_results(b).band_name);
  274. fprintf(' PLV change: p=%.4f (FDR=%.4f), Mean diff=%.4f\n', ...
  275. cue_results(b).p_perm_plv, cue_results(b).p_perm_plv_fdr, cue_results(b).observed_diff_plv);
  276. fprintf(' Mean phase shift: p=%.4f (FDR=%.4f), Mean diff=%.2f deg\n', ...
  277. cue_results(b).p_perm_phase, cue_results(b).p_perm_phase_fdr, mean(cue_results(b).dsr_phase_shift - cue_results(b).sr_phase_shift)*180/pi);
  278. fprintf(' Inter-subject PLV: p=%.4f (FDR=%.4f) DSR=%.3f ± %.3f, SR=%.3f ± %.3f\n', ...
  279. cue_results(b).p_perm_inter_plv, cue_results(b).p_perm_inter_plv_fdr, cue_results(b).plv_dsr, cue_results(b).sem_dsr, ...
  280. cue_results(b).plv_sr, cue_results(b).sem_sr);
  281. end
  282. %% -----------------------------
  283. %% Plot bar graphs: 2 bars per frequency band
  284. %% -----------------------------
  285. % PLV change
  286. plv_means = [];
  287. plv_sems = [];
  288. for b = 1:n_bands
  289. plv_means = [plv_means, mean(cue_results(b).dsr_diffs), mean(cue_results(b).sr_diffs)];
  290. plv_sems = [plv_sems, std(cue_results(b).dsr_diffs)/sqrt(n_subjects), std(cue_results(b).sr_diffs)/sqrt(n_subjects)];
  291. end
  292. figure; hold on;
  293. b_plot = bar(reshape(plv_means,2,[])','grouped');
  294. b_plot(1).FaceColor = [75 0 130]/255; % DSR
  295. b_plot(2).FaceColor = [53 94 59]/255; % SR
  296. % Error bars
  297. for i = 1:2*n_bands
  298. x = b_plot(mod(i-1,2)+1).XEndPoints(ceil(i/2));
  299. errorbar(x, plv_means(i), plv_sems(i),'k','LineStyle','none','LineWidth',2);
  300. end
  301. xticks(1:n_bands)
  302. set(gca,'XTickLabel',band_names,'TickDir','out','LineWidth',1.5)
  303. ylabel('PLV Change (Post - Pre)')
  304. title('DSR vs SR: PLV Change')
  305. set(gcf,'Color','white')
  306. % Mean phase shift
  307. phase_means = [];
  308. phase_sems = [];
  309. for b = 1:n_bands
  310. phase_means = [phase_means, circ_mean(cue_results(b).dsr_phase_shift), circ_mean(cue_results(b).sr_phase_shift)];
  311. phase_sems = [phase_sems, circ_std(cue_results(b).dsr_phase_shift)/sqrt(n_subjects), circ_std(cue_results(b).sr_phase_shift)/sqrt(n_subjects)];
  312. end
  313. phase_means_deg = phase_means*180/pi;
  314. phase_sems_deg = phase_sems*180/pi;
  315. figure; hold on;
  316. b_plot = bar(reshape(phase_means_deg,2,[])','grouped');
  317. b_plot(1).FaceColor = [75 0 130]/255; % DSR
  318. b_plot(2).FaceColor = [53 94 59]/255; % SR
  319. for i = 1:2*n_bands
  320. x = b_plot(mod(i-1,2)+1).XEndPoints(ceil(i/2));
  321. errorbar(x, phase_means_deg(i), phase_sems_deg(i),'k','LineStyle','none','LineWidth',2);
  322. end
  323. xticks(1:n_bands)
  324. set(gca,'XTickLabel',band_names,'TickDir','out','LineWidth',1.5)
  325. ylabel('Mean Phase Shift (deg)')
  326. title('DSR vs SR: Mean Phase Shift')
  327. set(gcf,'Color','white')
  328. % Inter-subject PLV
  329. plv_vals = [];
  330. plv_sems = [];
  331. for b = 1:n_bands
  332. plv_vals = [plv_vals, cue_results(b).plv_dsr, cue_results(b).plv_sr];
  333. plv_sems = [plv_sems, cue_results(b).sem_dsr, cue_results(b).sem_sr];
  334. end
  335. figure; hold on;
  336. b_plot = bar(reshape(plv_vals,2,[])','grouped');
  337. b_plot(1).FaceColor = [75 0 130]/255; % DSR
  338. b_plot(2).FaceColor = [53 94 59]/255; % SR
  339. for i = 1:2*n_bands
  340. x = b_plot(mod(i-1,2)+1).XEndPoints(ceil(i/2));
  341. errorbar(x, plv_vals(i), plv_sems(i),'k','LineStyle','none','LineWidth',2);
  342. end
  343. xticks(1:n_bands)
  344. set(gca,'XTickLabel',band_names,'TickDir','out','LineWidth',1.5)
  345. ylabel('Inter-Subject PLV')
  346. title('DSR vs SR: Inter-Subject Phase Alignment')
  347. ylim([0 1])
  348. set(gcf,'Color','white')
  349. %% Single-subject direction counts for cue-related phase effects
  350. %% Run this after the cue phase analysis script (cue_results must be in workspace)
  351. %% For each frequency band showing a significant effect, reports N participants
  352. %% showing the DSR vs SR difference in the same direction as the group-level effect
  353. fprintf('\n=== SINGLE-SUBJECT DIRECTION COUNTS: CUE-RELATED EFFECTS ===\n');
  354. fprintf('(Run after cue phase analysis script)\n\n');
  355. fprintf('For each contrast, N = participants whose individual difference\n');
  356. fprintf('score shares the sign of the group-level mean difference.\n\n');
  357. fprintf('Note: sign-based counts are only interpretable when the group-level\n');
  358. fprintf('mean difference is well away from the circular boundary (+-180 deg).\n\n');
  359. band_names = {'Theta','Alpha','Low Beta','High Beta'};
  360. n_bands = length(band_names);
  361. n_subjects = 12;
  362. %% -----------------------------------------------------------------------
  363. %% 1. Within-participant PLV change: Low Beta (significant effect)
  364. %% DSR vs SR
  365. %% -----------------------------------------------------------------------
  366. fprintf('=== Within-participant PLV change: All bands ===\n');
  367. fprintf('(Reporting all bands for completeness; key significant effect in Low Beta)\n\n');
  368. for band_idx = 1:n_bands
  369. diff_vals = cue_results(band_idx).dsr_diffs - cue_results(band_idx).sr_diffs;
  370. group_mean = mean(diff_vals);
  371. n_same_dir = sum(sign(diff_vals) == sign(group_mean));
  372. sig_str = '';
  373. if cue_results(band_idx).p_perm_plv_fdr < 0.05
  374. sig_str = ' *';
  375. end
  376. fprintf(' %s: group mean diff = %.4f, %d/%d participants in same direction%s\n', ...
  377. band_names{band_idx}, group_mean, n_same_dir, n_subjects, sig_str);
  378. end
  379. fprintf('\n');
  380. %% -----------------------------------------------------------------------
  381. %% 2. Mean phase angle shift: Theta, Alpha, Low Beta (significant effects)
  382. %% DSR vs SR — using circ_dist for circular measure
  383. %% -----------------------------------------------------------------------
  384. fprintf('=== Mean phase angle shift: All bands ===\n');
  385. fprintf('(Reporting all bands for completeness; significant effects in Theta, Alpha, Low Beta)\n\n');
  386. for band_idx = 1:n_bands
  387. diff_vals = circ_dist(cue_results(band_idx).dsr_phase_shift, cue_results(band_idx).sr_phase_shift);
  388. group_mean = circ_mean(diff_vals);
  389. group_mean_deg = rad2deg(group_mean);
  390. n_same_dir = sum(sign(diff_vals) == sign(group_mean));
  391. sig_str = '';
  392. if cue_results(band_idx).p_perm_phase_fdr < 0.05
  393. sig_str = ' *';
  394. end
  395. % Flag if near circular boundary
  396. boundary_warning = '';
  397. if abs(group_mean_deg) > 150
  398. boundary_warning = ' [WARNING: near +/-180 deg boundary - count may not be interpretable]';
  399. end
  400. fprintf(' %s: group mean diff = %.2f deg, %d/%d participants in same direction%s%s\n', ...
  401. band_names{band_idx}, group_mean_deg, n_same_dir, n_subjects, sig_str, boundary_warning);
  402. end
  403. fprintf('\n');
  404. %% -----------------------------------------------------------------------
  405. %% 3. Inter-subject PLV: report for completeness
  406. %% -----------------------------------------------------------------------
  407. fprintf('=== Inter-subject PLV: All bands ===\n');
  408. fprintf('(No significant effects expected; reported for completeness)\n\n');
  409. for band_idx = 1:n_bands
  410. % Inter-subject PLV is a scalar (not per-subject difference),
  411. % so we report the individual subject phase shifts going in the
  412. % same direction as the group mean for each condition separately
  413. dsr_group_mean = circ_mean(cue_results(band_idx).dsr_phase_shift);
  414. sr_group_mean = circ_mean(cue_results(band_idx).sr_phase_shift);
  415. n_dsr_same = sum(sign(cue_results(band_idx).dsr_phase_shift) == sign(dsr_group_mean));
  416. n_sr_same = sum(sign(cue_results(band_idx).sr_phase_shift) == sign(sr_group_mean));
  417. sig_str = '';
  418. if cue_results(band_idx).p_perm_inter_plv_fdr < 0.05
  419. sig_str = ' *';
  420. end
  421. fprintf(' %s: DSR inter-subject PLV = %.3f (%d/%d in group direction), SR = %.3f (%d/%d in group direction)%s\n', ...
  422. band_names{band_idx}, ...
  423. cue_results(band_idx).plv_dsr, n_dsr_same, n_subjects, ...
  424. cue_results(band_idx).plv_sr, n_sr_same, n_subjects, sig_str);
  425. end
  426. fprintf('\n');
  427. fprintf('* = FDR-corrected p < 0.05\n');
  428. fprintf('circ_dist used for all phase shift contrasts to handle circular wrapping\n');
  429. fprintf('Group mean differences near +-180 deg are flagged as potentially uninterpretable\n');
  430. %% Helper function
  431. function p_fdr = fdr_bh(pvals)
  432. % Benjamini-Hochberg FDR correction
  433. p = pvals(:);
  434. [p_sorted, idx] = sort(p);
  435. m = length(p);
  436. q = zeros(m,1);
  437. % Compute BH threshold-adjusted values
  438. for i = 1:m
  439. q(i) = p_sorted(i) * m / i;
  440. end
  441. % Ensure monotonicity
  442. q = cummin(flipud(q));
  443. q = flipud(q);
  444. q(q>1) = 1;
  445. % Return p-values in original order
  446. p_fdr = zeros(m,1);
  447. p_fdr(idx) = q;
  448. end

CuePLV_slidingcombined.m, no license · at the source

Overview

Authors: Jacqueline M Fulvio1, Bradley R Postle1,2
  1. Departments of Psychology, University of Wisconsin–Madison, Madison, Wisconsin 53706-1611
  2. Psychiatry, University of Wisconsin–Madison, Madison, Wisconsin 53706-1611
Institutions: University of Wisconsin–Madison (United States)
Journal: eNeuro, volume 13, issue 4, pages ENEURO.0346-25.2026
Dates: received 15 September 2025; accepted 1 April 2026; published online 21 April 2026; in print April 2026
Type: Research article · Language: English
License: CC BY
Identifiers: DOI 10.1523/eneuro.0346-25.2026 · PMID 41956898 · PMCID PMC13120838 · OpenAlex W7152534516
Open access: gold, a free copy (OpenAlex)
Status: code verified
Categories: EEG (modality), other (modality), human (organism), cognitive (subfield)
Methods: Spectral & time-frequency, Preprocessing, Connectivity, Statistics, Smoothing, state filtering, decompositions, Machine learning, Physiology & signal measures
Keywords: EEG, low-beta, oscillations, prioritization, TMS, working memory
MeSH: Brain*, Memory, Short-Term*, Parietal Lobe*, Transcranial Magnetic Stimulation*, Adult, Electroencephalography, Female, Humans, Male, Young Adult (* major topic)
Topic: Neural and Behavioral Psychology Studies (Cognitive Neuroscience, Neuroscience), according to OpenAlex
Funding: HHS | National Institutes of Health (MH131678)
Citations: not cited yet (Europe PMC); 46 references in the paper

Abstract

The flexible control of working memory (WM) requires prioritizing immediately task-relevant information while maintaining information with potential future relevance in a deprioritized state. Using double-serial retrocuing (DSR) with simultaneous EEG recording, we investigated how single pulses of transcranial magnetic stimulation (spTMS) to right intraparietal sulcus impacts neural representations of unprioritized memory items (UMI), relative to irrelevant memory items (IMI) that are no longer needed for the trial. Twelve human participants (8 female) performed DSR plus a single-retrocue task, while spTMS was delivered during delay periods. Multivariate pattern analysis revealed that spTMS restored decodability of the UMI concurrent with stimulation and that of the IMI several timesteps later, after the evoked effects of spTMS were no longer present in the EEG signal. This effect was carried by the alpha (8–13 Hz) and low-beta (13–20 Hz) frequency bands. Analyses of the raw EEG signal showed two effects selective to the epoch containing the UMI: the retrocue and spTMS each produced phase shifts in the low-beta band. These findings demonstrate that deprioritization involves active neural mechanisms distinct from the processing of the IMI and that these are supported by low-beta oscillatory dynamics in parietal cortex. We hypothesize that the mechanism underlying spTMS-triggered involuntary retrieval of the UMI is the disruption of the encoding of priority status, which may depend on oscillatory dynamics in the low-beta band.

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 9 matches between paragraphs and lines of code.

OSF wnt6q

License: none: the authors keep all their rights
State: the link answers, verified on 30 September 2026
Evidence: files inventoried
Languages: MATLAB (12)
Size: 19 files, 12 scripts
Software Heritage: not checked
Found in: “Code accessibility”
Not found: README, license file, CITATION.cff, environment file, tests, continuous integration, documentation
Availability: 1 check, the latest on 30 September 2026: the link answers (HTTP 200)
  • 30 September 2026: the link answers (HTTP 200)
12 files
At the source: osf.io/wnt6q

Code accessibility

The code/software described in the paper is freely available online at https://osf.io/wnt6q.

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

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;
  • 12 scripts, each with its path and the digest of its content;
  • 9 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.

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, issue, pages, dates, 2 authors, 6 keywords, 10 MeSH terms, 1 funder, 46 references.

Cite

This paper

Fulvio, J. M., & Postle, B. R. (2026). Effects of TMS on the Decoding and Electrophysiology of Priority in Working Memory. eNeuro, 13(4), ENEURO.0346-25.2026. https://doi.org/10.1523/eneuro.0346-25.2026

BibTeX

@article{fulvio2026effects,
author = {Fulvio, Jacqueline M and Postle, Bradley R},
title = {{Effects of TMS on the Decoding and Electrophysiology of Priority in Working Memory}},
journal = {eNeuro},
year = {2026},
month = apr,
volume = {13},
number = {4},
pages = {ENEURO.0346--25.2026},
publisher = {Society for Neuroscience},
issn = {2373-2822},
doi = {10.1523/eneuro.0346-25.2026},
url = {https://doi.org/10.1523/eneuro.0346-25.2026},
pmid = {41956898},
pmcid = {PMC13120838}
}

RIS

TY - JOUR
AU - Fulvio, Jacqueline M
AU - Postle, Bradley R
TI - Effects of TMS on the Decoding and Electrophysiology of Priority in Working Memory
T2 - eNeuro
J2 - eNeuro
PY - 2026
DA - 2026/04/27
VL - 13
IS - 4
SP - ENEURO.0346
EP - 25.2026
SN - 2373-2822
PB - Society for Neuroscience
DO - 10.1523/eneuro.0346-25.2026
UR - https://doi.org/10.1523/eneuro.0346-25.2026
LA - en
ER -

CSL-JSON

{
"id": "10.1523/eneuro.0346-25.2026",
"type": "article-journal",
"title": "Effects of TMS on the Decoding and Electrophysiology of Priority in Working Memory",
"container-title": "eNeuro",
"author": [
{
"family": "Fulvio",
"given": "Jacqueline M"
},
{
"family": "Postle",
"given": "Bradley R"
}
],
"container-title-short": "eNeuro",
"volume": "13",
"issue": "4",
"page": "ENEURO.0346-25.2026",
"DOI": "10.1523/eneuro.0346-25.2026",
"PMID": "41956898",
"PMCID": "PMC13120838",
"ISSN": "2373-2822",
"publisher": "Society for Neuroscience",
"URL": "https://doi.org/10.1523/eneuro.0346-25.2026",
"language": "en",
"issued": {
"date-parts": [
[
2026,
4,
27
]
]
}
}

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.1162/imag.a.1199 [code]
Sustained alpha oscillations serve attentional prioritization in working memory, not maintenance.
Journal: Imaging neuroscience (Cambridge, Mass.)
In common: CircStat, FieldTrip, Signal Processing Toolbox, 1 other tool, EEG, cognitive, 8 references
[2] doi:10.1038/s41467-026-73553-8 [code]
Universal rhythmic architecture uncovers two modes of neural dynamics.
Journal: Nature communications
In common: FieldTrip, Signal Processing Toolbox, Statistics and Machine Learning Toolbox, EEG, 4 references
[3] doi:10.1371/journal.pbio.3003938 [code]
Theta oscillations tag episodic memories for sleep-dependent consolidation.
Journal: PLoS biology
In common: CircStat, FieldTrip, Signal Processing Toolbox, 1 other tool, EEG, cognitive, 2 references
[4] doi:10.1111/psyp.70271 [code]
Disentangling Respiratory Phase-Dependent and Phase-Independent Components of Anticipatory Cardiac Deceleration.
Journal: Psychophysiology
In common: CircStat, FieldTrip, Signal Processing Toolbox, 1 other tool, other, EEG, cognitive, 2 references
[5] doi:10.1186/s12915-026-02630-7 [code]
Phasic modulation of attentional rhythmic sampling according to task demands.
Journal: BMC biology
In common: CircStat, FieldTrip, Statistics and Machine Learning Toolbox, EEG, cognitive, 3 references
[6] doi:10.1038/s42003-026-10071-9 [code]
Alpha phase coding supports feature binding during working memory maintenance.
Journal: Communications biology
In common: cognitive, 5 references
[7] doi:10.1371/journal.pbio.3003740 [code]
Sleep strengthens successor representations of learned sequences in humans.
Journal: PLoS biology
In common: CircStat, FieldTrip, Statistics and Machine Learning Toolbox, EEG, cognitive, 2 references
[8] doi:10.1016/j.isci.2026.116601 [code]
Random auditory stimulation during sleep disturbs traveling slow waves and declarative memory.
Journal: iScience
In common: CircStat, FieldTrip, Signal Processing Toolbox, 1 other tool, cognitive, 2 references
[9] doi:10.1523/eneuro.0076-26.2026 [code]
Exogenously Driven Neural Reactivation of Spatially Matching Visual Working-Memory Contents.
Journal: eNeuro
In common: FieldTrip, Statistics and Machine Learning Toolbox, EEG, cognitive, 3 references
[10] doi:10.1523/jneurosci.0154-26.2026 [code]
Faster but less precise: expectation enhances response speed while reducing sensory fidelity.
Journal: The Journal of neuroscience : the official journal of the Society for Neuroscience
In common: CircStat, Signal Processing Toolbox, Statistics and Machine Learning Toolbox, EEG, cognitive, 2 references

Contribute

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

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

Request its removal

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

Discussion, reproductions, activity

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

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

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