OSCR

Multimodal imaging-based targeting approach for network-level brain stimulation.

Code ↔ Paper

4 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 4 matches
  1. [1] § Materials and methods › Statistical analysis › Confound time series removal ↔ scripts/denoising_pipeline.m, lines 1–62 · score 0.73 · denoising pipeline, fMRIPrep, preprocessing, confound
  2. [2] § Materials and methods › Statistical analysis › Preprocessing ↔ scripts/denoising_pipeline.m, lines 1–62 · score 0.72 · MNI152NLin6Asym, fMRIPrep, pipeline, preprocessing, spaces
  3. [3] § Materials and methods › Statistical analysis › Spatial overlap analysis ↔ scripts/spatial_overlap_analysis.py, lines 1–23 · score 0.57 · Pearson correlation, connectivity maps, coefficient, Dice, activation, overlap
  4. [4] § Materials and methods › Statistical analysis › Task-based fMRI analysis ↔ scripts/denoising_pipeline.m, lines 354–408 · score 0.56 · design matrix, GLMs, regressors, models, motion, error

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 · 574 lines · 21 KB · MIT · 3 matches

  1. % DENOISING_PIPELINE.M
  2. % Main script for resting-state fMRI denoising using CONN toolbox.
  3. % Input: Path to pre-processed data with fMRIPrep
  4. % Output: Denoised volumes in CONN's results folder.
  5. % Reference: Wang et al. (2024)
  6. % Author: Your Name
  7. %Author Alireza Shahbabaie and Filip Niemann
  8. % prepare data.
  9. % data must be in BIDS format
  10. % use unziped version of GM, WM and CSF masks conducted by fmriprep during
  11. % fresh start( no variables and values)in MATLAB
  12. clear
  13. clc
  14. %setpaths of CONN and SPM
  15. addpath /usr/local/MATLAB/MATLAB_TOOLBOX/conn_la
  16. addpath /usr/local/MATLAB/MATLAB_TOOLBOX/spm12
  17. % 1. Project name (fixed)
  18. Project = 'MeMoSLAP';
  19. % 2. Define root paths (user must customize these)
  20. % - Replace with relative paths or variables that auto-detect location
  21. repo_root = fileparts(mfilename('fullpath')); % Auto-detects script location
  22. % Default BIDS/derivatives structure (relative to repo root)
  23. root_fmriprep = fullfile(repo_root, 'derivatives', 'fMRIPrep');
  24. root_conn = fullfile(repo_root, 'derivatives', 'Conn_script_based');
  25. % 3. Mask paths (store masks in repo's /masks/ folder)
  26. mask_dir = fullfile(repo_root, 'masks');
  27. lvifg_mask_path = fullfile(mask_dir, 'resampled_res-2_lvIFG_seed_6mm.nii');
  28. rotc_mask_path = fullfile(mask_dir, 'resampled_rOTC_res-02.nii');
  29. hippo_mask_path = fullfile(mask_dir, 'resampled_hippocampus_4mm_mask_res-02.nii');
  30. % 4. Filename filters (shared across users)
  31. struct_filter_name = '_acq-mprage_space-MNI152NLin6Asym*_desc-preproc_T1w.nii.gz';
  32. func_filter_name = '_task-resting_dir-AP_space-MNI152NLin6Asym*_desc-preproc_bold.nii.gz';
  33. timeseries_filter_name = '_task-resting_dir-AP_merg_desc-confounds_timeseries.tsv';
  34. GM_filter_name = '_acq-mprage_space-MNI152NLin6Asym*_label-GM_probseg.nii';
  35. WM_filter_name = '_acq-mprage_space-MNI152NLin6Asym*_label-WM_probseg.nii';
  36. CSF_filter_name = '_acq-mprage_space-MNI152NLin6Asym*_label-CSF_probseg.nii';
  37. % 5. Session naming (user may need to modify)
  38. ses_1 = 'ses-1'; % Change to 'ses-01' if needed
  39. ses_2 ='ses-2'; % Change to 'ses-01' if needed
  40. ses_1_str ='ses_1'; % Change to 'ses_01' if needed
  41. ses_2_str ='ses_2';% Change too 'ses-02' if needed
  42. % ==============================================
  43. batch.Setup.RT = 1;
  44. % (Rest of your pipeline code here)
  45. % Verify paths exist before proceeding
  46. if ~exist(root_fmriprep, 'dir')
  47. error('fmriprep directory not found: %s', root_fmriprep);
  48. end
  49. if ~exist(root_conn, 'dir')
  50. mkdir(root_conn); % Create CONN directory if needed
  51. end
  52. batch.filename = fullfile(root_conn,'conn_rsfmri_denoising.mat');
  53. %% Get files
  54. % get all subjects in fmriprep folder, subjects are saved in list_sub.name
  55. list_sub = dir(fullfile(root_fmriprep,'sub-*'));
  56. list_sub = list_sub([list_sub.isdir]); % Only folders
  57. %for debugging use only one subject
  58. %list_sub=list_sub(1:2); %uncomment for debugging
  59. % get anatomical
  60. list_anat = dir(fullfile(root_fmriprep,'**',['sub*',struct_filter_name]));
  61. anat_path = fullfile({list_anat.folder},{list_anat.name});
  62. anat_path = sort(anat_path);
  63. %anat_path = anat_path(1:2); %uncomment for debugging
  64. % get gm mask
  65. gm_mask = dir(fullfile(root_fmriprep,'**',['sub*',GM_filter_name]));
  66. gm_path = fullfile({gm_mask.folder},{gm_mask.name});
  67. gm_path = sort(gm_path);
  68. %gm_path = gm_path(1:2); %uncomment for debugging
  69. % get gm mask
  70. wm_mask = dir(fullfile(root_fmriprep,'**',['sub*',WM_filter_name]));
  71. wm_path = fullfile({wm_mask.folder},{wm_mask.name});
  72. wm_path = sort(wm_path);
  73. %wm_path = wm_path(1:2); %uncomment for debugging
  74. % get csf mask
  75. csf_mask = dir(fullfile(root_fmriprep,'**',['sub*',CSF_filter_name]));
  76. csf_path = fullfile({csf_mask.folder},{csf_mask.name});
  77. csf_path = sort(csf_path);
  78. %csf_path = csf_path(1:2); %uncomment for debugging
  79. % get functional
  80. list_func_1 = dir(fullfile(root_fmriprep,'**',['sub*',ses_1,'*',func_filter_name]));
  81. list_func_2 = dir(fullfile(root_fmriprep,'**',['sub*',ses_2,'*',func_filter_name]));
  82. list_func = [list_func_1; list_func_2];
  83. func_path = fullfile({list_func.folder},{list_func.name});
  84. func_path = sort(func_path);
  85. %func_path = func_path(1:4); %uncomment for debugging
  86. % get timeseries
  87. list_timeseries = dir(fullfile(root_fmriprep,'**',['sub*',timeseries_filter_name]));
  88. cov_path = fullfile({list_timeseries.folder},{list_timeseries.name});
  89. cov_path = sort(cov_path);
  90. %cov_path = cov_path(1:4); %uncomment for debugging
  91. %% set basic parameters for batch and check if data are complete
  92. % Basic parameters
  93. batch.Setup.isnew = 1;
  94. batch.Setup.nsubjects = numel(list_sub);
  95. batch.Setup.nsessions = 2;
  96. batch.Setup.overwrite =1;
  97. batch.Setup.analysis =1;
  98. % number anatomical image verification
  99. if ~isequal(numel(list_sub),numel(anat_path))
  100. disp('anatomical images does not match subject count')
  101. end
  102. % number gm image verification
  103. if ~isequal(numel(list_sub),numel(gm_path))
  104. disp('grey matter images does not match subject count')
  105. end
  106. % number wm image verification
  107. if ~isequal(numel(list_sub),numel(wm_path))
  108. disp('white matter images does not match subject count')
  109. end
  110. % number csf image verification
  111. if ~isequal(numel(list_sub),numel(csf_path))
  112. disp('csf images does not match subject count')
  113. end
  114. % number functional image verification
  115. if ~isequal(numel(anat_path)*batch.Setup.nsessions,numel(func_path))
  116. disp('functional images does not match anatomical image count')
  117. end
  118. % number covariate file verification
  119. if ~isequal(numel(cov_path),numel(func_path))
  120. disp('timeseries images does not match functional image count')
  121. end
  122. % session verification
  123. for sub_idx = 1:numel(list_sub)
  124. subject_id = list_sub(sub_idx).name;
  125. ses_count = sum(contains(func_path, subject_id));
  126. if ses_count ~= 2
  127. warning('Subject %s has %d sessions (expected 2)', subject_id, ses_count);
  128. end
  129. end
  130. %% Initialize batch struct
  131. batch.Setup.structurals = cell(1, numel(list_sub));
  132. batch.Setup.functionals = cell(1, numel(list_sub));
  133. % Initialize covariates
  134. covariate_names = {'Global', 'csf', 'Motion','white_matter'};
  135. % Initialize covariates files structure properly
  136. batch.Setup.covariates.files = cell(1, numel(covariate_names));
  137. for c = 1:numel(covariate_names)
  138. batch.Setup.covariates.files{c} = cell(1, numel(list_sub));
  139. end
  140. % get timeseries and create temporary csv files
  141. % Create temporary directory for filtered CSV files
  142. temp_dir = fullfile(root_conn, 'temp_covariates');
  143. if ~exist(temp_dir, 'dir')
  144. mkdir(temp_dir);
  145. end
  146. %% set basic parameters for batch and check if data are complete
  147. % Basic parameters
  148. batch.Setup.isnew = 1;
  149. batch.Setup.nsubjects = numel(list_sub);
  150. batch.Setup.nsessions = 2;
  151. batch.Setup.overwrite =1;
  152. % number anatomical image verification
  153. if ~isequal(numel(list_sub),numel(anat_path))
  154. disp('anatomical images does not match subject count')
  155. end
  156. % number gm image verification
  157. if ~isequal(numel(list_sub),numel(gm_path))
  158. disp('grey matter images does not match subject count')
  159. end
  160. % number wm image verification
  161. if ~isequal(numel(list_sub),numel(wm_path))
  162. disp('white matter images does not match subject count')
  163. end
  164. % number csf image verification
  165. if ~isequal(numel(list_sub),numel(csf_path))
  166. disp('csf images does not match subject count')
  167. end
  168. % number functional image verification
  169. if ~isequal(numel(anat_path)*batch.Setup.nsessions,numel(func_path))
  170. disp('functional images does not match anatomical image count')
  171. end
  172. % number covariate file verification
  173. if ~isequal(numel(cov_path),numel(func_path))
  174. disp('timeseries images does not match functional image count')
  175. end
  176. % session verification
  177. for sub_idx = 1:numel(list_sub)
  178. subject_id = list_sub(sub_idx).name;
  179. ses_count = sum(contains(func_path, subject_id));
  180. if ses_count ~= 2
  181. warning('Subject %s has %d sessions (expected 2)', subject_id, ses_count);
  182. end
  183. end
  184. %% Process each subject
  185. for sub_idx = 1:numel(list_sub)
  186. subject_id = list_sub(sub_idx).name;
  187. % filter path that contain subject
  188. % Anatomical path
  189. idx_anat = contains(anat_path,subject_id);
  190. anat_path_subj = anat_path(idx_anat);
  191. % GM path
  192. idx_gm = contains(gm_path,subject_id);
  193. gm_path_subj = gm_path(idx_gm);
  194. % WM path
  195. idx_wm = contains(wm_path,subject_id);
  196. wm_path_subj = wm_path(idx_wm);
  197. % CSF path
  198. idx_csf = contains(csf_path,subject_id);
  199. csf_path_subj = csf_path(idx_csf);
  200. % functional path
  201. idx_func_ses1 = contains(func_path,subject_id) & contains(func_path,ses_1);
  202. func_path_subj_ses_1 = func_path(idx_func_ses1);
  203. idx_func_ses2 = contains(func_path,subject_id) & contains(func_path,ses_2);
  204. func_path_subj_ses_2 = func_path(idx_func_ses2);
  205. % covariate path
  206. idx_cov = contains(cov_path,subject_id);
  207. cov_path_subj = cov_path(idx_cov);
  208. % Get indices from timeseries.tsv file and create filtered CSV files
  209. [motion_indices, motion_csv_files] = get_indices_and_write_csv(Project, cov_path_subj, subject_id, "motion", temp_dir);
  210. [csf_indices, csf_csv_files] = get_indices_and_write_csv(Project, cov_path_subj, subject_id, "csf", temp_dir);
  211. [global_indices, global_csv_files] = get_indices_and_write_csv(Project, cov_path_subj, subject_id, "global", temp_dir);
  212. [wm_indices, wm_csv_files] = get_indices_and_write_csv(Project, cov_path_subj, subject_id,'white_matter', temp_dir);
  213. %% batch.Setup
  214. % Structural file
  215. batch.Setup.structurals{sub_idx} = {anat_path_subj};
  216. % Functional files
  217. batch.Setup.functionals{sub_idx} = { ...
  218. func_path_subj_ses_1, ...
  219. func_path_subj_ses_2 ...
  220. };
  221. % Covariates setup - now using the filtered CSV files
  222. batch.Setup.covariates.names = {'Global', 'csf', 'Motion','white_matter'};
  223. %% Process each subject - corrected covariates part
  224. % Corrected covariates files assignment
  225. for nses = 1:numel(global_csv_files)
  226. batch.Setup.covariates.files{1}{sub_idx}{nses} = global_csv_files{nses}; % Global
  227. batch.Setup.covariates.files{2}{sub_idx}{nses} = csf_csv_files{nses}; % CSF
  228. batch.Setup.covariates.files{3}{sub_idx}{nses} = motion_csv_files{nses}; % Motion
  229. batch.Setup.covariates.files{4}{sub_idx}{nses} = wm_csv_files{nses}; % WM
  230. end
  231. % Indices - now simple since we have 1 column per CSV
  232. batch.Setup.covariates.indices = { ...
  233. {1}, ... % Global (only 1 column in CSV)
  234. {1}, ... % CSF (only 1 column in CSV)
  235. {1:numel(motion_indices.ses_1.indices)}, ... % Motion (multiple columns)
  236. {1} ... % white matter (onley 1 column in csv
  237. };
  238. % Dimensions
  239. batch.Setup.covariates.dimensions = { ...
  240. 1, ... % Global
  241. 1, ... % CSF
  242. numel(motion_indices.ses_1.indices), ... % Motion
  243. 1, ... % WM
  244. };
  245. % ROIs setup
  246. %% ROIs setup (updated)
  247. batch.Setup.rois.names = {'Grey Matter', 'White Matter', 'CSF', 'IFG', 'OTC','Hippocampus'};
  248. batch.Setup.rois.files{1}{sub_idx} = gm_path_subj; % GM
  249. batch.Setup.rois.files{2}{sub_idx} = wm_path_subj; % WM
  250. batch.Setup.rois.files{3}{sub_idx} = csf_path_subj; % CSF
  251. batch.Setup.rois.files{4}{sub_idx} = lvifg_mask_path; % IFG (same file for all subjects)
  252. batch.Setup.rois.files{5}{sub_idx} = rotc_mask_path; % OTC (same file for all subjects)
  253. batch.Setup.rois.files{6}{sub_idx} = hippo_mask_path; % Hippocampus (same file for all subjects)
  254. batch.Setup.rois.multiplelabels = 0;
  255. batch.Setup.rois.dimensions = {1, 1, 1, 1, 1, 1};
  256. % Condition
  257. %% Condition setup - corrected version
  258. batch.Setup.conditions.names = {'rest'};
  259. for nsub = 1:numel(list_sub)
  260. for nses = 1:batch.Setup.nsessions
  261. % Get duration from this subject's data
  262. if nses == 1
  263. ses_field = 'ses_1';
  264. else
  265. ses_field = 'ses_02';
  266. end
  267. % Initialize onsets and durations for all subjects/sessions
  268. if nsub == 1 && nses == 1
  269. batch.Setup.conditions.onsets{1} = cell(1, numel(list_sub));
  270. batch.Setup.conditions.durations{1} = cell(1, numel(list_sub));
  271. end
  272. % Set onset to 0 and calculate duration based on RT and number of volumes
  273. batch.Setup.conditions.onsets{1}{nsub}{nses} = 0;
  274. % Use motion indices to get number of volumes (more reliable than CSF)
  275. if exist('motion_indices', 'var') && isfield(motion_indices, ses_field)
  276. batch.Setup.conditions.durations{1}{nsub}{nses} = batch.Setup.RT * motion_indices.(ses_field).table_length;
  277. else
  278. % Fallback to a default value if motion indices not available
  279. batch.Setup.conditions.durations{1}{nsub}{nses} = Inf; % or use a known value
  280. end
  281. end
  282. end
  283. end
  284. %% batch.Denoising
  285. % Debug: Verify denoising settings
  286. %Denoising steps for Debugging
  287. %Step 1/7: Expanding conditions - Sets up experimental conditions
  288. %Step 2/7: Importing conditions/covariates - Loads your regressors
  289. %Step 3/7: Updating Denoising variables (where you're stuck) - Prepares denoising parameters
  290. %Step 4/7: Creating Denoising design matrices - Builds the GLM model
  291. %Step 5/7: Estimating Denoising parameters (conn_process_5) - Computes the actual denoising
  292. %Step 6/7: Applying Denoising - Removes noise from data
  293. %Step 7/7: Saving results - Stores cleaned data
  294. % if you have problesm in Step 5/7 open conn_process for debugging (line
  295. % 1096)
  296. % this means ROIs where not created
  297. % line 657 Creates ROI_Subject###_Session###.mat files (activation timecourses for each roi)
  298. %this means DATA_Subject was not created
  299. % open conn_process
  300. % Denoising
  301. batch.Denoising.done = 1;
  302. batch.Denoising.overwrite = 1;
  303. batch.Denoising.filter = [0.01 Inf];
  304. batch.Denoising.detrending = 1;
  305. batch.Denoising.confounds.names = batch.Setup.covariates.names;
  306. %batch.Denoising.confounds.dimensions = batch.Setup.covariates.dimensions;
  307. batch.Denoising.confounds.dimensions = {1, 1, numel(motion_indices.ses_1.indices),1};
  308. % change derivative and power if needed
  309. batch.Denoising.confounds.deriv = {0, 0, 1, 0};
  310. batch.Denoising.confounds.power = {0, 0, 2, 0};
  311. %check if motion dimension match
  312. motion_dims_setup = batch.Setup.covariates.dimensions{3};
  313. motion_dims_denoise = batch.Denoising.confounds.dimensions{3};
  314. if ~isequal(motion_dims_setup, motion_dims_denoise)
  315. error('Motion dimensions mismatch! Setup: %d vs Denoising: %d',...
  316. motion_dims_setup, motion_dims_denoise);
  317. end
  318. disp('--- Denoising Configuration ---');
  319. disp(batch.Denoising)
  320. disp('Confounds:');
  321. disp(batch.Denoising.confounds)
  322. % Check if denoising is actually enabled
  323. if ~batch.Denoising.done
  324. warning('Denoising is set to done=0! Changing to done=1');
  325. batch.Denoising.done = 1;
  326. end
  327. %Verify filter settings
  328. if isempty(batch.Denoising.filter) || ~all(isfinite(batch.Denoising.filter))
  329. warning('Invalid filter settings! Using default [0.01 Inf]');
  330. batch.Denoising.filter = [0.01 Inf];
  331. end
  332. %% because incorrect covariate specification is the most common error for silent failure add verification code
  333. % Debug: Verify covariates
  334. disp('--- Covariates Implementation ---');
  335. for c = 1:numel(batch.Denoising.confounds.names)
  336. fprintf('Covariate %d (%s):\n', c, batch.Denoising.confounds.names{c});
  337. fprintf('Dimensions: %s\n', mat2str(batch.Denoising.confounds.dimensions{c}));
  338. fprintf('Derivatives: %d\n', batch.Denoising.confounds.deriv{c});
  339. fprintf('Powers: %d\n', batch.Denoising.confounds.power{c});
  340. % Verify files exist
  341. for s = 1:min(3,numel(list_sub)) % Check first 3 subjects
  342. if numel(batch.Setup.covariates.files) >= c && ...
  343. numel(batch.Setup.covariates.files{c}) >= s
  344. fprintf('Subject %d files exist: %d\n', s, ...
  345. exist(batch.Setup.covariates.files{c}{s}{1}, 'file'));
  346. end
  347. end
  348. end
  349. %% batch.Analysis
  350. %% Analysis
  351. % Analysis setup to run ALL steps
  352. batch.Analysis.done = 1;
  353. batch.Analysis.overwrite = 1;
  354. batch.Analysis.measure = 1; % Correlation
  355. batch.Analysis.type = 'all'; % Changed from 3 to 'ROI-to-ROI' for clarity
  356. batch.Analysis.sources = {'IFG', 'OTC','Hippocampus'}; % Seed ROI % Empty for ROI-to-ROI analysis
  357. batch.Analysis.ROI_files = {'GM', 'WM', 'CSF'}; % All ROIs for ROI-to-ROI
  358. % ADD THESE TWO LINES RIGHT HERE:
  359. batch.Analysis.save = 1; % Saves individual subject results
  360. batch.Analysis.keep = 1; % Keeps temporary analysis files
  361. % Set up the GUI interaction option for ROI-to-ROI analysis
  362. batch.Analysis.gui = 1; % Enable GUI interaction
  363. batch.Analysis.gui_prompt = 1; % Ask user on each step
  364. batch.Analysis.name = 'SBC_MeMoSLAP_rest'; % Name for this analysis
  365. % Additional analysis parameters
  366. batch.Analysis.weight = 2; % Fisher-transformed correlation coefficients
  367. batch.Analysis.modulation = 0; % No modulation
  368. batch.Analysis.symmetric = 1; % Symmetric matrices
  369. batch.Analysis.scale = 1; % Scale to correlation units
  370. %% Save and run
  371. batch_file = fullfile(root_conn,'conn_rsfmri_denoising.mat');
  372. save(batch_file, 'batch');
  373. % Display for debugging:
  374. disp('--- Analysis Configuration ---');
  375. disp(['Analysis type: ', batch.Analysis.type]);
  376. disp(['GUI enabled: ', num2str(batch.Analysis.gui)]);
  377. disp(['GUI prompts: ', num2str(batch.Analysis.gui_prompt)]);
  378. disp(['ROIs included: ', strjoin(batch.Analysis.ROI_files, ', ')]);
  379. % First run setup steps (0-5)
  380. setup_batch = batch;
  381. setup_batch.Analysis.done = 0; % Don't run analysis yet
  382. conn_batch(setup_batch);
  383. % Then run the ROI-to-ROI analysis with GUI interaction
  384. analysis_batch = batch;
  385. analysis_batch.Setup.done = 1; % Mark setup as already done
  386. analysis_batch.Denoising.done = 1; % Mark denoising as already done
  387. conn_batch(analysis_batch);
  388. %% Clean up temporary files
  389. % Move cleanup to the very end and add verification
  390. try
  391. conn_batch(batch,'setup');
  392. % Verify processing completed successfully before cleanup
  393. % csv file path is saved in batch so don't delete
  394. %if exist(fullfile(root_conn,'conn_rsfmri.mat'), 'file')
  395. % rmdir(temp_dir, 's');
  396. %end
  397. catch ME
  398. warning('Keeping temp files for debugging due to error');
  399. end
  400. %% define functions
  401. function [indices, csv_files] = get_indices_and_write_csv(Project, cov_path, subject_id, covariate_column, temp_dir)
  402. if strcmp(Project,'VerFlu')
  403. sessions = {'ses-01', 'ses-02'};
  404. elseif strcmp(Project,'MeMoSLAP')
  405. sessions = {'ses-1', 'ses-2'};
  406. end
  407. indices = struct();
  408. csv_files = cell(1, numel(sessions));
  409. for i = 1:numel(sessions)
  410. ses = sessions{i};
  411. ses_field = strrep(ses, '-', '_');
  412. idx = contains(cov_path,ses);
  413. confound_file = cov_path(idx);
  414. if exist(confound_file{1}, 'file')
  415. T = readtable(confound_file{1}, 'FileType', 'text', 'Delimiter', '\t');
  416. colnames = T.Properties.VariableNames;
  417. % Determine which columns to select
  418. if strcmp(covariate_column, 'motion')
  419. is_cov = startsWith(colnames, 'trans') | startsWith(colnames, 'rot');
  420. contains_deriv = contains(colnames, 'derivative') | contains(colnames, 'power') | contains(colnames, 'wm');
  421. select_cols = is_cov & ~contains_deriv;
  422. else
  423. is_cov = startsWith(colnames, covariate_column);
  424. contains_deriv = contains(colnames, 'derivative') | contains(colnames, 'power') | contains(colnames, 'wm');
  425. select_cols = is_cov & ~contains_deriv;
  426. end
  427. idx = find(select_cols);
  428. % Create filtered table with only selected columns
  429. filtered_table = T(:, idx);
  430. % Create CSV filename
  431. csv_filename = fullfile(temp_dir, sprintf('%s_%s_%s.csv', subject_id, ses, covariate_column));
  432. % Write to CSV
  433. writetable(filtered_table, csv_filename);
  434. fprintf('Created filtered CSV: %s\n', csv_filename);
  435. % Store CSV path for CONN
  436. csv_files{i} = csv_filename;
  437. % Check for NaN/Inf
  438. nan_or_inf = false(1, numel(idx));
  439. for j = 1:numel(idx)
  440. col_data = table2array(T(:, idx(j)));
  441. nan_or_inf(j) = any(isnan(col_data)) || any(isinf(col_data));
  442. end
  443. if any(nan_or_inf)
  444. fprintf('Session %s: WARNING: NaN or Inf detected in columns: %s\n', ...
  445. ses, strjoin(colnames(idx(nan_or_inf)), ', '));
  446. end
  447. % Get table length from CSF column if available
  448. if ismember('csf', colnames)
  449. table_length = height(T);
  450. else
  451. table_length = NaN;
  452. end
  453. % Store indices
  454. indices.(ses_field).indices = idx;
  455. indices.(ses_field).names = colnames(idx);
  456. indices.(ses_field).nan_or_inf = nan_or_inf;
  457. indices.(ses_field).table_length = table_length;
  458. else
  459. warning('File not found: %s', confound_file);
  460. indices.(ses_field).indices = [];
  461. indices.(ses_field).names = {};
  462. indices.(ses_field).nan_or_inf = [];
  463. indices.(ses_field).table_length = NaN;
  464. csv_files{i} = '';
  465. end
  466. end
  467. end

denoising_pipeline.m at commit 71fdc65, under MIT · at the source

Overview

Authors: Alireza Shahbabaie1, Mohamed Abdelmotaleb1, Harun Kocataş1, Filip Niemann1, Daria Antonenko1, Agnes Flöel1,2, Marcus Meinzer1
  1. Department of Neurology, University Medicine Greifswald, Greifswald, Germany
  2. German Center for Neurodegenerative Diseases (DZNE Site Greifswald), Greifswald, Germany
Journal: Frontiers in neuroscience, volume 20, article 1803897
Dates: received 4 February 2026; accepted 8 May 2026; published online 29 May 2026
Type: Research article · Language: English
License: CC BY
Identifiers: DOI 10.3389/fnins.2026.1803897 · PMID 42292341 · PMCID PMC13260067 · OpenAlex W7162752289
Open access: gold, a free copy (OpenAlex)
Status: code verified
Categories: fMRI (modality), other (modality), human (organism), systems (subfield)
Methods: Statistics, Connectivity, Machine learning, fMRI & imaging
Keywords: concurrent tDCS-fMRI, focal tDCS, functional connectivity, memory and language learning, multimodal magnetic resonance imaging, network-level brain stimulation, non-invasive brain stimulation (NIBS)
Topic: Transcranial Magnetic Stimulation Studies (Neurology, Neuroscience), according to OpenAlex
Citations: not cited yet (Europe PMC); 77 references in the paper
Research resources: 771) and the CONN toolbox RRID:SCR_009550

Abstract

Introduction: Neural network effects of transcranial direct current stimulation (tDCS) are poorly understood. Here, we introduce a prospective, empirically informed, multimodal functional magnetic resonance imaging (fMRI) framework for guiding target selection and hypothesis-based analysis in future focal tDCS-fMRI studies.

Methods: We illustrate our approach by using data of 37 healthy individuals (19 females; mean age ± SD = 25.8 ± 5.9) recruited from two tDCS-fMRI studies that were acquired at the same scanner and with placebo-tDCS. Participants completed two resting-state (RS) sessions and two task-fMRI sessions (object-location memory, OLM, or associative picture-pseudoword learning, APPL, experiments). Seed-based RS analysis identified functional networks originating from target regions for focal tDCS (right occipito-temporal cortex, rOTC; left ventral IFG, lvIFG) and established their test-retest reliability (TRR), using intraclass correlation coefficients (ICC). Dice coefficients quantified overlap between seeded RS networks and task-evoked activity to identify task-active regions potentially affected by downstream network effects from the target regions.

Results: Seed-based analyses identified highly reliable ventral visual-limbic (rOTC) and language-related networks (lvIFG), with 72-77% of voxels showing good-to-excellent TRR (ICC ≥ 0.75). Only a subset of network voxels identified by the RS analyses overlapped with activity elicited by the experimental paradigms (ranging from 7.5-55%), with larger correspondence for the OLM (Dice: 0.249-0.349; APPL 0.065-0.106). Therefore, the degree of potential tDCS network effects varied substantially depending on the target region, the extent of its functional network and task-specific activity patterns. Degree of correspondence was further mediated by the selected contrasts-of-interest in the task-based analyses, with more conservative control conditions resulting in reduced overlap.

Conclusion: In sum, we established a principled multimodal fMRI framework bridging a critical gap in neuromodulation research. By integrating reliable intrinsic connectivity maps with task-evoked activity patterns, we provide a method to prospectively identify network-level targets for focal brain stimulation and generate hypotheses for tDCS-fMRI analyses. This approach shifts the rationale from stimulating isolated brain regions to strategically targeting key nodes within a predefined functional pathway.

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

Repositories

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

ShahAliR/memoslap-denoising-pipeline

License: MIT
State: the link answers, verified on 28 September 2026
Evidence: files inventoried
Commit: 71fdc65075ca839a95213c109532702584b9b2ff, 8 August 2025
Languages: MATLAB (1)
Size: 10 files, 1 script
Software Heritage: not archived
Found in: the text, “Confound time series removal”
Holds: README, license file
Not found: CITATION.cff, environment file, tests, continuous integration, documentation
Tools: CONN (1 file)
Availability: 1 check, the latest on 28 September 2026: the link answers
  • 28 September 2026: the link answers
3 files

ShahAliR/NetworkOverlap-Task-RS-fMRI

License: none: the authors keep all their rights
State: the link answers, verified on 28 September 2026
Evidence: files inventoried
Commit: 842bca5478281657c8daad79bc9df09e492ff8bb, 23 January 2026
Languages: Jupyter (1), Python (1)
Size: 7 files, 2 scripts
Software Heritage: not archived
Found in: “Data availability statement”
Holds: README, 1 notebook
Not found: license file, CITATION.cff, environment file, tests, continuous integration, documentation
Tools: Matplotlib (2 files), NiBabel (2 files), Nilearn (2 files), NumPy (2 files), SciPy (2 files)
Availability: 1 check, the latest on 28 September 2026: the link answers
  • 28 September 2026: the link answers
3 files

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

Tracing map

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

What the map holds:

  • 2 repositories of the authors' code, each at its verified commit, with its license and how the link was found in the paper;
  • 3 scripts, each with its path and the digest of its content;
  • 4 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 availability statement

The study was pre-registered with the Open Science Framework (OSF), and the protocol can be accessed through OSF Registries (https://osf.io/t37u2). To ensure full transparency and reproducibility, our analysis scripts are publicly available on GitHub (https://github.com/ShahAliR/NetworkOverlap-Task-RS-fMRI). Due to ethical and privacy concerns about the study’s participants, the row data are not publicly accessible. However, the corresponding author can provide the data supporting the study’s conclusions upon request.

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

Versions

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

Version 1, 28 September 2026: the first record

Recorded: type, language, journal, volume, pages, dates, 7 authors, 7 keywords, 75 references, 1 RRID.

Cite

This paper

Shahbabaie, A., Abdelmotaleb, M., Kocataş, H., Niemann, F., Antonenko, D., Flöel, A., & Meinzer, M. (2026). Multimodal imaging-based targeting approach for network-level brain stimulation. Frontiers in neuroscience, 20, 1803897. https://doi.org/10.3389/fnins.2026.1803897

BibTeX

@article{shahbabaie2026multimodal,
author = {Shahbabaie, Alireza and Abdelmotaleb, Mohamed and Kocataş, Harun and Niemann, Filip and Antonenko, Daria and Flöel, Agnes and Meinzer, Marcus},
title = {{Multimodal imaging-based targeting approach for network-level brain stimulation}},
journal = {Frontiers in neuroscience},
year = {2026},
month = may,
volume = {20},
pages = {1803897},
publisher = {Frontiers Media SA},
issn = {1662-4548},
doi = {10.3389/fnins.2026.1803897},
url = {https://doi.org/10.3389/fnins.2026.1803897},
pmid = {42292341},
pmcid = {PMC13260067}
}

RIS

TY - JOUR
AU - Shahbabaie, Alireza
AU - Abdelmotaleb, Mohamed
AU - Kocataş, Harun
AU - Niemann, Filip
AU - Antonenko, Daria
AU - Flöel, Agnes
AU - Meinzer, Marcus
TI - Multimodal imaging-based targeting approach for network-level brain stimulation
T2 - Frontiers in neuroscience
J2 - Front Neurosci
PY - 2026
DA - 2026/05/29
VL - 20
SP - 1803897
SN - 1662-4548
PB - Frontiers Media SA
DO - 10.3389/fnins.2026.1803897
UR - https://doi.org/10.3389/fnins.2026.1803897
LA - en
ER -

CSL-JSON

{
"id": "10.3389/fnins.2026.1803897",
"type": "article-journal",
"title": "Multimodal imaging-based targeting approach for network-level brain stimulation",
"container-title": "Frontiers in neuroscience",
"author": [
{
"family": "Shahbabaie",
"given": "Alireza"
},
{
"family": "Abdelmotaleb",
"given": "Mohamed"
},
{
"family": "Kocataş",
"given": "Harun"
},
{
"family": "Niemann",
"given": "Filip"
},
{
"family": "Antonenko",
"given": "Daria"
},
{
"family": "Flöel",
"given": "Agnes"
},
{
"family": "Meinzer",
"given": "Marcus"
}
],
"container-title-short": "Front Neurosci",
"volume": "20",
"page": "1803897",
"DOI": "10.3389/fnins.2026.1803897",
"PMID": "42292341",
"PMCID": "PMC13260067",
"ISSN": "1662-4548",
"publisher": "Frontiers Media SA",
"URL": "https://doi.org/10.3389/fnins.2026.1803897",
"language": "en",
"issued": {
"date-parts": [
[
2026,
5,
29
]
]
}
}

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.1222 [code]
Network-based near-scalp personalized brain stimulation targets.
Journal: Imaging neuroscience (Cambridge, Mass.)
In common: Nilearn, NiBabel, SciPy, 2 other tools, other, systems, 3 references
[2] doi:10.1162/imag.a.1283 [code]
The language network responds robustly to sentences across tasks.
Journal: Imaging neuroscience (Cambridge, Mass.)
In common: CONN, Nilearn, SciPy, 2 other tools, fMRI, 2 references
[3] doi:10.1016/j.neuron.2026.04.011 [code]
Precision fMRI reveals densely interdigitated network patches with conserved motifs in the lateral prefrontal cortex.
Journal: Neuron
In common: Nilearn, NiBabel, SciPy, 2 other tools, fMRI, systems, 3 references
[4] doi:10.1371/journal.pbio.3003684 [code]
The retrieval of previously learned motor memories is facilitated by the reinstatement of default mode network manifold structures.
Journal: PLoS biology
In common: Nilearn, NiBabel, SciPy, 2 other tools, fMRI, 4 references
[5] doi:10.1038/s41531-026-01354-3 [code]
Neuromodulation-induced normalization of cortical metastable dynamics signatures in Parkinson's disease.
Journal: NPJ Parkinson's disease
In common: Nilearn, NiBabel, SciPy, 2 other tools, 4 references
[6] doi:10.1186/s12916-026-04978-7 [code]
Mapping shared and specific cortical after-effects of repetitive TMS on brain function.
Journal: BMC medicine
In common: Nilearn, NiBabel, SciPy, 2 other tools, other, 2 references
[7] doi:10.1162/imag.a.1256 [code]
Gamer in the scanner: Event-related analysis of fMRI activity during retro videogame play guided by automated annotations of game content.
Journal: Imaging neuroscience (Cambridge, Mass.)
In common: Nilearn, NiBabel, SciPy, 2 other tools, fMRI, 3 references
[8] doi:10.1038/s41467-026-71428-6 [code]
Binding items to contexts through conjunctive neural representations with the method of loci.
Journal: Nature communications
In common: Nilearn, NiBabel, SciPy, 2 other tools, systems, 3 references
[9] doi:10.21203/rs.3.rs-9326213/v1 [code]
Multi-task fMRI outperforms resting-state fMRI for revealing task-invariant organization of the human brain
Journal: Research Square (preprint)
In common: Nilearn, NiBabel, SciPy, 2 other tools, fMRI, 2 references
[10] doi:10.64898/2026.03.09.710558 [code]
Multi-task fMRI outperforms resting-state fMRI for revealing task-invariant organization of the human brain
Journal: bioRxiv (preprint)
In common: Nilearn, NiBabel, SciPy, 2 other tools, fMRI, 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.