thePlotSpmPreproc.m 9.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251
  1. function output = thePlotSpmPreproc(functional4D_fn, structural_fn, fwhm, spm_dir)
  2. % Function to complete preprocessing of structural and functional data from
  3. % a single subject for use in thePlotSpm.m
  4. %
  5. % Steps include coregistering structural image to first functional image,
  6. % segmenting the coregistered structural image into tissue types, and
  7. % reslicing the segments to the functional resolution image grid.
  8. %
  9. % Makes use of spm12 batch routines.
  10. % If spm12 batch parameters are not explicitly set, defaults are assumed.
  11. %
  12. % INPUT:
  13. % funcional4D_fn - filename of pre-real-time functional scan
  14. % structural_fn - filename of T1-weighted structural scan
  15. % fwhm - kernel size for smoothing operations
  16. %
  17. % OUTPUT:
  18. % output - structure with filenames and data
  19. %
  20. % EXAMPLE
  21. % fwhm = 6;
  22. % [spm_dir, ~, ~] = fileparts(which('spm'));
  23. % data_dir = 'D:';
  24. % subj = 'sub-01';
  25. % % structural image
  26. % structural_fn = spm_select('FPList', fullfile(data_dir , subj , 'anat'), ['^' subj '_T1w.*nii$']);
  27. % % 4D BOLD time series
  28. % functional4D_fn = spm_select('FPList', fullfile(data_dir , subj , 'func'), ['^' subj '_task-.*_bold*.nii$']);
  29. % _________________________________________________________________________
  30. % Copyright (C) Stephan Heunis
  31. %% Check that we have everything
  32. if nargin<4
  33. % trying to locate spm
  34. [spm_dir, ~, ~] = fileparts(which('spm'));
  35. if isempty(spm_dir)
  36. error('Tell me where SPM is, please.')
  37. end
  38. end
  39. if nargin<3
  40. fwhm = 6;
  41. end
  42. if nargin<2
  43. error('I need data to work with.')
  44. end
  45. % check number of volume in this 4D time series
  46. Nt = numel(spm_vol(functional4D_fn));
  47. % Declare output structure
  48. output = struct;
  49. %% STEP 1 -- Realign (estimate and reslice) all functionals to first functional
  50. % Only if this has not been done before
  51. [dir, file, ext] = fileparts(functional4D_fn);
  52. if ~exist(spm_select('FPList', dir, ['^r' file ext]), 'file')
  53. disp('Step 1...');
  54. realign_estimate_reslice = struct;
  55. % Data
  56. fnms={};
  57. for i = 1:Nt
  58. fnms{i} = [functional4D_fn ',' num2str(i) ];
  59. end
  60. realign_estimate_reslice.matlabbatch{1}.spm.spatial.realign.estwrite.data={fnms'};
  61. % Estimate options
  62. realign_estimate_reslice.matlabbatch{1}.spm.spatial.realign.estwrite.eoptions.quality = 0.9;
  63. realign_estimate_reslice.matlabbatch{1}.spm.spatial.realign.estwrite.eoptions.sep = 4;
  64. realign_estimate_reslice.matlabbatch{1}.spm.spatial.realign.estwrite.eoptions.fwhm = 5;
  65. realign_estimate_reslice.matlabbatch{1}.spm.spatial.realign.estwrite.eoptions.rtm = 1;
  66. realign_estimate_reslice.matlabbatch{1}.spm.spatial.realign.estwrite.eoptions.interp = 2;
  67. realign_estimate_reslice.matlabbatch{1}.spm.spatial.realign.estwrite.eoptions.wrap = [0 0 0];
  68. realign_estimate_reslice.matlabbatch{1}.spm.spatial.realign.estwrite.eoptions.weight = '';
  69. % Reslice options
  70. realign_estimate_reslice.matlabbatch{1}.spm.spatial.realign.estwrite.roptions.which = [2 1];
  71. realign_estimate_reslice.matlabbatch{1}.spm.spatial.realign.estwrite.roptions.interp = 4;
  72. realign_estimate_reslice.matlabbatch{1}.spm.spatial.realign.estwrite.roptions.wrap = [0 0 0];
  73. realign_estimate_reslice.matlabbatch{1}.spm.spatial.realign.estwrite.roptions.mask = 1;
  74. realign_estimate_reslice.matlabbatch{1}.spm.spatial.realign.estwrite.roptions.prefix = 'r';
  75. % Run
  76. cfg_util('run',realign_estimate_reslice.matlabbatch);
  77. end
  78. % identify the outputed realigned file
  79. output.rfunctional_fn = fullfile(dir , ['r' file ext]);
  80. % load the data from the realignement parameters
  81. output.mp_fn = fullfile(dir , ['rp_' file '.txt']);
  82. output.MP = load(output.mp_fn);
  83. disp('Step 1 - Done!');
  84. %% STEP 2 -- Coregister structural image to first dynamic image (estimate only)
  85. disp('Step 2...');
  86. spm('defaults','fmri');
  87. spm_jobman('initcfg');
  88. coreg_estimate = struct;
  89. % Ref
  90. coreg_estimate.matlabbatch{1}.spm.spatial.coreg.estimate.ref = {[functional4D_fn ',1']};
  91. % Source
  92. coreg_estimate.matlabbatch{1}.spm.spatial.coreg.estimate.source = {structural_fn};
  93. % Estimate options
  94. coreg_estimate.matlabbatch{1}.spm.spatial.coreg.estimate.eoptions.cost_fun = 'nmi';
  95. coreg_estimate.matlabbatch{1}.spm.spatial.coreg.estimate.eoptions.sep = [4 2];
  96. coreg_estimate.matlabbatch{1}.spm.spatial.coreg.estimate.eoptions.tol = [0.02 0.02 0.02 0.001 0.001 0.001 0.01 0.01 0.01 0.001 0.001 0.001];
  97. coreg_estimate.matlabbatch{1}.spm.spatial.coreg.estimate.eoptions.fwhm = [7 7];
  98. % Run
  99. spm_jobman('run',coreg_estimate.matlabbatch);
  100. disp('Step 2 - Done!');
  101. %% STEP 3 -- Segmentation of coregistered structural image into GM, WM, CSF, etc
  102. % (with implicit warping to MNI space, saving forward and inverse transformations)
  103. % Only if this has not been done before
  104. [dir, file, ext] = fileparts(structural_fn);
  105. if ~exist(spm_select('FPList', dir, ['^c1' file ext]), 'file')
  106. disp('Step 3...');
  107. segmentation = struct;
  108. % Channel
  109. segmentation.matlabbatch{1}.spm.spatial.preproc.channel.biasreg = 0.001;
  110. segmentation.matlabbatch{1}.spm.spatial.preproc.channel.biasfwhm = 60;
  111. segmentation.matlabbatch{1}.spm.spatial.preproc.channel.write = [0 1];
  112. segmentation.matlabbatch{1}.spm.spatial.preproc.channel.vols = {structural_fn};
  113. % Tissue
  114. for t = 1:6
  115. segmentation.matlabbatch{1}.spm.spatial.preproc.tissue(t).tpm = {fullfile(spm_dir , 'tpm' , ['TPM.nii,' num2str(t)])};
  116. segmentation.matlabbatch{1}.spm.spatial.preproc.tissue(t).ngaus = t-1;
  117. segmentation.matlabbatch{1}.spm.spatial.preproc.tissue(t).native = [1 0];
  118. segmentation.matlabbatch{1}.spm.spatial.preproc.tissue(t).warped = [0 0];
  119. end
  120. segmentation.matlabbatch{1}.spm.spatial.preproc.tissue(1).ngaus = 1;
  121. segmentation.matlabbatch{1}.spm.spatial.preproc.tissue(6).ngaus = 2;
  122. % Warp
  123. segmentation.matlabbatch{1}.spm.spatial.preproc.warp.mrf = 1;
  124. segmentation.matlabbatch{1}.spm.spatial.preproc.warp.cleanup = 1;
  125. segmentation.matlabbatch{1}.spm.spatial.preproc.warp.reg = [0 0.001 0.5 0.05 0.2];
  126. segmentation.matlabbatch{1}.spm.spatial.preproc.warp.affreg = 'mni';
  127. segmentation.matlabbatch{1}.spm.spatial.preproc.warp.fwhm = 0;
  128. segmentation.matlabbatch{1}.spm.spatial.preproc.warp.samp = 3;
  129. segmentation.matlabbatch{1}.spm.spatial.preproc.warp.write=[1 1];
  130. % Run
  131. cfg_util('run',segmentation.matlabbatch);
  132. end
  133. % Save filenames
  134. output.forward_transformation = fullfile(dir , ['y_' file ext]);
  135. output.inverse_transformation = fullfile(dir , ['iy_' file ext]);
  136. output.gm_fn = fullfile(dir , ['c1' file ext]);
  137. output.wm_fn = fullfile(dir , ['c2' file ext]);
  138. output.csf_fn = fullfile(dir , ['c3' file ext]);
  139. output.bone_fn = fullfile(dir , ['c4' file ext]);
  140. output.soft_fn = fullfile(dir , ['c5' file ext]);
  141. output.air_fn = fullfile(dir , ['c6' file ext]);
  142. disp('Step 3 - Done!');
  143. %% STEP 4 -- Reslice all to functional-resolution image grid
  144. % Only if this has not been done before
  145. [dir, file, ext] = fileparts(structural_fn);
  146. if ~exist(spm_select('FPList', dir, ['^rc1' file ext]), 'file')
  147. disp('Step 4...');
  148. reslice = struct;
  149. % Ref
  150. reslice.matlabbatch{1}.spm.spatial.coreg.write.ref = {[functional4D_fn ',1']};
  151. % Source: images to reslice
  152. source_fns = cellstr(spm_select('FPList', dir, ['^c' '.*nii$']))'; % all the tissue probability maps of that subject
  153. source_fns{end+1} = structural_fn;
  154. reslice.matlabbatch{1}.spm.spatial.coreg.write.source = source_fns';
  155. % Roptions
  156. reslice.matlabbatch{1}.spm.spatial.coreg.write.roptions.interp = 4;
  157. reslice.matlabbatch{1}.spm.spatial.coreg.write.roptions.wrap = [0 0 0];
  158. reslice.matlabbatch{1}.spm.spatial.coreg.write.roptions.mask = 0;
  159. reslice.matlabbatch{1}.spm.spatial.coreg.write.roptions.prefix = 'r';
  160. % Run
  161. cfg_util('run',reslice.matlabbatch);
  162. end
  163. % Save filenames
  164. [dir, file, ext] = fileparts(structural_fn);
  165. output.rstructural_fn = fullfile(dir , ['r' file ext]);
  166. output.rgm_fn = fullfile(dir , ['rc1' file ext]);
  167. output.rwm_fn = fullfile(dir , ['rc2' file ext]);
  168. output.rcsf_fn = fullfile(dir , ['rc3' file ext]);
  169. output.rbone_fn = fullfile(dir , ['rc4' file ext]);
  170. output.rsoft_fn = fullfile(dir , ['rc5' file ext]);
  171. output.rair_fn = fullfile(dir , ['rc6' file ext]);
  172. disp('Step 4 - Done!');
  173. %% STEP 5 -- Gaussian kernel smoothing of realigned data
  174. % Only if this has not been done before
  175. [dir, file, ext] = fileparts(functional4D_fn);
  176. if ~exist(spm_select('FPList', dir, ['^sr' file ext]), 'file')
  177. disp('Step 5...');
  178. smooth = struct;
  179. % Data
  180. fns={};
  181. for i = 1:Nt
  182. fns{i} = [output.rfunctional_fn ',' num2str(i) ];
  183. end
  184. smooth.matlabbatch{1}.spm.spatial.smooth.data = fns';
  185. % Other
  186. smooth.matlabbatch{1}.spm.spatial.smooth.fwhm = [fwhm fwhm fwhm];
  187. smooth.matlabbatch{1}.spm.spatial.smooth.dtype = 0;
  188. smooth.matlabbatch{1}.spm.spatial.smooth.im = 0;
  189. smooth.matlabbatch{1}.spm.spatial.smooth.prefix = 's';
  190. % Run
  191. cfg_util('run',smooth.matlabbatch);
  192. end
  193. % Save filenames
  194. [dir, file, ext] = fileparts(output.rfunctional_fn);
  195. output.srfunctional_fn = fullfile(dir , ['s' file ext]);
  196. disp('Step 5 - Done!');
  197. %% STEP 6 -- Gaussian kernel smoothing of unprocessed data
  198. % Only if this has not been done before
  199. [dir, file, ext] = fileparts(functional4D_fn);
  200. if ~exist(spm_select('FPList', dir, ['^s' file ext]), 'file')
  201. disp('Step 6...');
  202. smooth = struct;
  203. % Data
  204. fns={};
  205. for i = 1:Nt
  206. fns{i} = [functional4D_fn ',' num2str(i) ];
  207. end
  208. smooth.matlabbatch{1}.spm.spatial.smooth.data = fns';
  209. % Other
  210. smooth.matlabbatch{1}.spm.spatial.smooth.fwhm = [fwhm fwhm fwhm];
  211. smooth.matlabbatch{1}.spm.spatial.smooth.dtype = 0;
  212. smooth.matlabbatch{1}.spm.spatial.smooth.im = 0;
  213. smooth.matlabbatch{1}.spm.spatial.smooth.prefix = 's';
  214. % Run
  215. cfg_util('run',smooth.matlabbatch);
  216. end
  217. % Save filenames
  218. output.sfunctional_fn = fullfile(dir , ['s' file ext]);
  219. disp('Step 6 - Done!');