├── README.md ├── depreciated ├── run_dartel_1struct.m └── wrapper_dartel_1struct.m ├── run_spm12dartel.m └── wrapper_spm12dartel.m /README.md: -------------------------------------------------------------------------------- 1 | # spm12-dartel 2 | 3 | Code for preprocessing of functional and structural MRI data into standardized MNI space using SPM12 and DARTEL. 4 | 5 | * Can be used with only one structural scan (e.g. either T1 MPRAGE or T2 matched-bandwidth) 6 | * Can be used with two structural scans (e.g. T1 MPRAGE *and* T2 matched-bandwidth). Secondary scan (e.g. MBW) used as intermediary for coregistering functionals to primary structural (e.g. MPRAGE) 7 | 8 | Instructions: 9 | 10 | Call only the wrapper script as it will call the run function in a parfor loop. All user-editable parameters are in the epynomous section of the wrapper. Other sections of the wrapper script and run function shouldn't be edited unless you know what you're doing. 11 | 12 | A "runStatus" struct containg each subject's pre-dartel status will be saved in the folder specified in "batchDir". The matlab workspace after pre-dartel will also be saved in "batchDir", you can use this to re-run DARTEL without re-running pre-dartel. A text log of the matlab console output will be saved for predartel & dartel in the "batchDir" folder. All pre-dartel and DARTEL matlabbatches will be saved in "batchDir" 13 | 14 | Final image ouputs for further analyses: 15 | * rBOLD[run name].nii = resliced, native-space BOLD images (e.g. native-space single-subject analyeses) 16 | * wrBOLD[run name].nii = resliced, MNI-space & unsmoothed BOLD images (e.g. connectivity or MVPA analyses) 17 | * swrBOLD[run name].nii = resliced, MNI-space & smoothed BOLD images (e.g. normal group-level analyeses) 18 | * rp_BOLD[run name].nii = motion parameters to include in level1 model as nuisance regressors 19 | * wm[MPRAGE/structural name].nii = bias-corrected MNI-space structural image 20 | * wc1[MPRAGE/structural name].nii = MNI-space grey matter segmentation image (can be used as mask/ROI; signal from which typically used for functional connectivity analyses, etc) 21 | * wc2[MPRAGE/structural name].nii = MNI-space white matter segmentation image (can be used as mask/ROI; signal from which typically regressed out during functional connectivity analyses, etc) 22 | * wc3[MPRAGE/structural name].nii = MNI-space cerebrospinal fluid (also eyes/sinuses maybe) segmentation image (can be used as mask/ROI; signal from which typically regressed out during functional connectivity analyses, etc) 23 | 24 | Algorithm when using only one structural scan: 25 | 1) Realign & reslice functionals to mean functional (pre-dartel; parfor parallelization) 26 | 2) Co-register structural to mean functional (pre-dartel; parfor parallelization) 27 | 3) Segment & bias-correct structural, generate segment params for DARTEL (pre-dartel; implicit multithreading from here) 28 | 4) Create DARTEL templates & generate deformation fields for MNI normalization 29 | 5) Normalize & smooth functionals to MNI space via DARTEL (implicit parallelization from here) 30 | 6) Normalize bias-corrected structural to MNI space via DARTEL 31 | 7) Normalize grey matter (C1) segmentation to MNI space via DARTEL 32 | 8) Normalize white matter (C2) segmentation to MNI space via DARTEL 33 | 9) Normalize CSF (C3) segmentation to MNI space via DARTEL 34 | 35 | Algorithm when using MPRAGE & MBW: 36 | 1) Realign & reslice functionals to mean functional (pre-dartel; parfor parallelization) 37 | 2) Co-register MBW to mean functional (pre-dartel; parfor parallelization) 38 | 3) Co-register MPRAGE to MBW (pre-dartel; parfor parallelization) 39 | 4) Segment & bias-correct structural, generate segment params for DARTEL (pre-dartel; implicit multithreading from here) 40 | 5) Create DARTEL templates & generate deformation fields for MNI normalization 41 | 6) Normalize & smooth functionals to MNI space via DARTEL (implicit parallelization from here) 42 | 7) Normalize bias-corrected MPRAGE to MNI space via DARTEL 43 | 8) Normalize grey matter (C1) segmentation to MNI space via DARTEL 44 | 9) Normalize white matter (C2) segmentation to MNI space via DARTEL 45 | 10) Normalize CSF (C3) segmentation to MNI space via DARTEL 46 | -------------------------------------------------------------------------------- /depreciated/run_dartel_1struct.m: -------------------------------------------------------------------------------- 1 | function [status, errorMsg, allfuncs, allt1, allmt1, allrc1, allrc2, allu_rc1, allc1, allc2, allc3] =... 2 | run_dartel_1struct(subNam, owd, codeDir, batchDir, runID, funcID, mpragedirID,... 3 | fourDnii, execPreDartel) 4 | 5 | % Last revision: 2 Aug 2017 - Kevin Tan 6 | 7 | %% Organize files for matlabbatch 8 | spm('defaults','fmri'); spm_jobman('initcfg'); 9 | 10 | status = NaN; 11 | errorMsg = ''; 12 | allfuncs = []; 13 | allt1 = []; 14 | allmt1 = []; 15 | allrc1 = []; 16 | allrc2 = []; 17 | allu_rc1 = []; 18 | allc1 = []; 19 | allc2 = []; 20 | allc3 = []; 21 | 22 | try 23 | % Find run directories 24 | runDir = [owd '/' subNam '/raw/']; 25 | d = dir([owd '/' subNam '/raw/' runID]); 26 | nRuns = length(d); 27 | fprintf('Found %d runs\n', nRuns) 28 | tmpStr = sprintf('^%s.*\\.nii$', funcID); 29 | 30 | % Fund functional images per run 31 | volsFPr = {}; 32 | for r = 1:nRuns 33 | vols = {}; 34 | volsr = {}; 35 | [vols, ~] = spm_select('ExtList', [runDir '/' d(r).name], tmpStr, Inf); 36 | vols = cellstr(strcat(vols)); 37 | for v = 1:length(vols) 38 | chars = length(vols{v})-2; 39 | volsFP{r}{v,1} = [runDir '/' d(r).name '/' vols{v}]; 40 | volsr{v,1} = [runDir '/' d(r).name '/r' vols{v}(1:chars)]; 41 | end 42 | % Realigned images 43 | if fourDnii 44 | volsFPr = [volsFPr;volsr{1}]; 45 | else 46 | volsFPr = [volsFPr;volsr]; 47 | end 48 | end 49 | 50 | % find the mbw folder 51 | d = dir([owd '/' subNam '/raw/' mbwdirID]); 52 | mbwdir = [owd '/' subNam '/raw/' d(1).name]; 53 | 54 | % find the mprage folder 55 | d = dir([owd '/' subNam '/raw/' mpragedirID]); 56 | mprdir = [owd '/' subNam '/raw/' d(1).name]; 57 | 58 | % get the images 59 | d = dir([mbwdir '/' mbwdirID '.nii']); 60 | mbw_name = d.name; clear d 61 | d = dir([mprdir '/' mpragedirID '.nii']); 62 | mprage_name = d.name; clear d 63 | mbw = [mbwdir filesep mbw_name]; 64 | allt1 = [mprdir filesep mprage_name]; 65 | fprintf('MBW is: %s\n',mbw) 66 | fprintf('MPRAGE is: %s\n\n',allt1) 67 | 68 | % for DARTEL 69 | allfuncs = volsFPr; 70 | allmt1 = [mprdir filesep 'm' mprage_name]; 71 | allrc1 = [mprdir filesep 'rc1' mprage_name(1:end-4) '.nii']; 72 | allrc2 = [mprdir filesep 'rc2' mprage_name(1:end-4) '.nii']; 73 | allu_rc1 = [mprdir filesep 'u_rc1' mprage_name(1:end-4) '_Template.nii']; 74 | allc1 = [mprdir filesep 'c1' mprage_name]; 75 | allc2 = [mprdir filesep 'c2' mprage_name]; 76 | allc3 = [mprdir filesep 'c3' mprage_name]; 77 | catch 78 | status = 0; 79 | errorMsg = 'Error making matlabbatch'; 80 | disp([errorMsg ' for ' subNam]); 81 | cd(codeDir); 82 | return 83 | end 84 | 85 | 86 | %% Build matlabbatch 87 | try 88 | % Change working directory to 'notes' 89 | matlabbatch{1}.cfg_basicio.cfg_cd.dir = cellstr(strcat([owd '/' subNam],filesep,'notes')); 90 | 91 | % Realign and reslice functionals 92 | for i = 1:nRuns 93 | matlabbatch{2}.spm.spatial.realign.estwrite.data{i} = volsFP{i}; 94 | end 95 | matlabbatch{2}.spm.spatial.realign.estwrite.eoptions.quality = 0.9; % higher quality 96 | matlabbatch{2}.spm.spatial.realign.estwrite.eoptions.sep = 4; % default is 4 97 | matlabbatch{2}.spm.spatial.realign.estwrite.eoptions.fwhm = 5; % default 98 | matlabbatch{2}.spm.spatial.realign.estwrite.eoptions.rtm = 0; % 0=realign to first, to 1=realign to mean for 99 | matlabbatch{2}.spm.spatial.realign.estwrite.eoptions.interp = 4; % default 100 | matlabbatch{2}.spm.spatial.realign.estwrite.eoptions.wrap = [0 0 0]; % default 101 | matlabbatch{2}.spm.spatial.realign.estwrite.eoptions.weight = {}; % don't weight 102 | matlabbatch{2}.spm.spatial.realign.estwrite.roptions.which = [2 1]; % reslice all and mean 103 | matlabbatch{2}.spm.spatial.realign.estwrite.roptions.interp = 4; % default 104 | matlabbatch{2}.spm.spatial.realign.estwrite.roptions.wrap = [0 0 0]; % no wrap (default) 105 | matlabbatch{2}.spm.spatial.realign.estwrite.roptions.mask = 1; % enable masking (default) 106 | matlabbatch{2}.spm.spatial.realign.estwrite.roptions.prefix = 'r'; 107 | 108 | % Coregister struct to mean functional 109 | matlabbatch{3}.spm.spatial.coreg.estimate.ref(1) = cfg_dep('Realign: Estimate & Reslice: Mean Image', substruct('.','val', '{}',{2}, '.','val', '{}',{1}, '.','val', '{}',{1}, '.','val', '{}',{1}), substruct('.','rmean')); 110 | matlabbatch{3}.spm.spatial.coreg.estimate.source = cellstr(allt1); 111 | matlabbatch{3}.spm.spatial.coreg.estimate.other{1} = ''; 112 | matlabbatch{3}.spm.spatial.coreg.estimate.eoptions.cost_fun = 'nmi'; 113 | matlabbatch{3}.spm.spatial.coreg.estimate.eoptions.sep = [4 2]; 114 | matlabbatch{3}.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]; 115 | matlabbatch{3}.spm.spatial.coreg.estimate.eoptions.fwhm = [7 7]; 116 | catch 117 | status = 0; 118 | errorMsg = 'Error making matlabbatch'; 119 | disp([errorMsg ' for ' subNam]); 120 | cd(codeDir); 121 | return 122 | end 123 | 124 | %% Save matlabbatch 125 | try 126 | time_stamp = datestr(now, 'yyyymmdd_HHMM'); 127 | filename = [batchDir '/preDARTEL_1struct_' subNam '_' time_stamp]; 128 | save(filename, 'matlabbatch'); 129 | catch 130 | status = 0; 131 | errorMsg = 'Error saving matlabbatch'; 132 | disp([errorMsg ' for ' subNam]); 133 | cd(codeDir); 134 | return 135 | end 136 | %% Run Matlabbatch 137 | try 138 | if execPreDartel == 1 139 | spm_jobman('run',matlabbatch); 140 | end 141 | status = 1; 142 | cd(codeDir); 143 | catch 144 | status = 0; 145 | errorMsg = 'Error running matlabbatch'; 146 | disp([errorMsg ' for ' subNam]); 147 | cd(codeDir); 148 | return 149 | end 150 | end 151 | -------------------------------------------------------------------------------- /run_spm12dartel.m: -------------------------------------------------------------------------------- 1 | function [status, errorMsg, allfuncs, allt1, allmt1, allrc1, allrc2, allu_rc1, allc1, allc2, allc3] =... 2 | run_spm12dartel(subNam, owd, codeDir, batchDir, runID, funcID, structID,... 3 | twoStructs, fourDnii, execPreDartel) 4 | 5 | % Last revision: 23 Aug 2017 - Kevin Tan 6 | 7 | %% Find files for matlabbatch 8 | spm('defaults','fmri'); spm_jobman('initcfg'); 9 | 10 | status = NaN; 11 | errorMsg = ''; 12 | allfuncs = []; 13 | allt1 = []; 14 | allmt1 = []; 15 | allrc1 = []; 16 | allrc2 = []; 17 | allu_rc1 = []; 18 | allc1 = []; 19 | allc2 = []; 20 | allc3 = []; 21 | 22 | try 23 | % Find run directories 24 | runDir = [owd '/' subNam '/raw']; 25 | d = dir([owd '/' subNam '/raw/' runID]); 26 | nRuns = length(d); 27 | fprintf('Found %d runs\n', nRuns) 28 | tmpStr = sprintf('^%s.*\\.nii$', funcID); 29 | 30 | % Fund functional images per run 31 | volsFPr = {}; 32 | for r = 1:nRuns 33 | volsr = {}; 34 | [vols, ~] = spm_select('ExtList', [runDir '/' d(r).name], tmpStr, Inf); 35 | vols = cellstr(strcat(vols)); 36 | for v = 1:length(vols) 37 | chars = length(vols{v})-2; 38 | volsFP{r}{v,1} = [runDir '/' d(r).name '/' vols{v}]; 39 | volsr{v,1} = [runDir '/' d(r).name '/r' vols{v}(1:chars)]; 40 | end 41 | % Realigned images 42 | if fourDnii 43 | volsFPr = [volsFPr;volsr{1}]; 44 | else 45 | volsFPr = [volsFPr;volsr]; 46 | end 47 | end 48 | 49 | % Get primary struct image 50 | d = dir([runDir '/' structID{1}]); 51 | mprdir = [runDir '/' d(1).name]; 52 | d = dir([mprdir '/' structID{1} '.nii']); 53 | mprage_name = d(1).name; 54 | allt1 = [mprdir filesep mprage_name]; 55 | fprintf('Primary structural: %s\n\n',allt1) 56 | 57 | if twoStructs 58 | % Get secondary struct image 59 | d = dir([runDir '/' structID{2}]); 60 | mbwdir = [runDir '/' d(1).name]; 61 | d = dir([mbwdir '/' structID{2} '.nii']); 62 | mbw_name = d(1).name; 63 | mbw = [mbwdir filesep mbw_name]; 64 | fprintf('Secondary structural: %s\n',mbw) 65 | end 66 | 67 | % Get file paths for DARTEL 68 | allfuncs = volsFPr; 69 | allmt1 = [mprdir filesep 'm' mprage_name]; 70 | allrc1 = [mprdir filesep 'rc1' mprage_name(1:end-4) '.nii']; 71 | allrc2 = [mprdir filesep 'rc2' mprage_name(1:end-4) '.nii']; 72 | allu_rc1 = [mprdir filesep 'u_rc1' mprage_name(1:end-4) '_Template.nii']; 73 | allc1 = [mprdir filesep 'c1' mprage_name]; 74 | allc2 = [mprdir filesep 'c2' mprage_name]; 75 | allc3 = [mprdir filesep 'c3' mprage_name]; 76 | catch 77 | status = 0; 78 | errorMsg = 'Error finding files for matlabbatch'; 79 | disp([errorMsg ' for ' subNam]); 80 | cd(codeDir); 81 | return 82 | end 83 | 84 | %% Build matlabbatch 85 | try 86 | 87 | % Change working directory to 'notes' 88 | matlabbatch{1}.cfg_basicio.cfg_cd.dir = cellstr(strcat([owd '/' subNam],filesep,'notes')); 89 | 90 | % Realign and reslice functionals 91 | for i = 1:nRuns 92 | matlabbatch{2}.spm.spatial.realign.estwrite.data{i} = volsFP{i}; 93 | end 94 | matlabbatch{2}.spm.spatial.realign.estwrite.eoptions.quality = 0.9; % higher quality 95 | matlabbatch{2}.spm.spatial.realign.estwrite.eoptions.sep = 4; % default is 4 96 | matlabbatch{2}.spm.spatial.realign.estwrite.eoptions.fwhm = 5; % default 97 | matlabbatch{2}.spm.spatial.realign.estwrite.eoptions.rtm = 0; % 0=realign to first, to 1=realign to mean for 98 | matlabbatch{2}.spm.spatial.realign.estwrite.eoptions.interp = 4; % default 99 | matlabbatch{2}.spm.spatial.realign.estwrite.eoptions.wrap = [0 0 0]; % default 100 | matlabbatch{2}.spm.spatial.realign.estwrite.eoptions.weight = {}; % don't weight 101 | matlabbatch{2}.spm.spatial.realign.estwrite.roptions.which = [2 1]; % reslice all and mean 102 | matlabbatch{2}.spm.spatial.realign.estwrite.roptions.interp = 4; % default 103 | matlabbatch{2}.spm.spatial.realign.estwrite.roptions.wrap = [0 0 0]; % no wrap (default) 104 | matlabbatch{2}.spm.spatial.realign.estwrite.roptions.mask = 1; % enable masking (default) 105 | matlabbatch{2}.spm.spatial.realign.estwrite.roptions.prefix = 'r'; 106 | 107 | if twoStructs % 2 structural scans 108 | % Coregister MBW to mean functional (as intermediary) 109 | matlabbatch{3}.spm.spatial.coreg.estimate.ref(1) = cfg_dep('Realign: Estimate & Reslice: Mean Image', substruct('.','val', '{}',{2}, '.','val', '{}',{1}, '.','val', '{}',{1}, '.','val', '{}',{1}), substruct('.','rmean')); 110 | matlabbatch{3}.spm.spatial.coreg.estimate.source = cellstr(mbw); 111 | matlabbatch{3}.spm.spatial.coreg.estimate.other{1} = ''; 112 | matlabbatch{3}.spm.spatial.coreg.estimate.eoptions.cost_fun = 'nmi'; 113 | matlabbatch{3}.spm.spatial.coreg.estimate.eoptions.sep = [4 2]; 114 | matlabbatch{3}.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]; 115 | matlabbatch{3}.spm.spatial.coreg.estimate.eoptions.fwhm = [7 7]; 116 | 117 | % Coregister MPRAGE to MBW 118 | matlabbatch{4}.spm.spatial.coreg.estimate.ref = cellstr(mbw); 119 | matlabbatch{4}.spm.spatial.coreg.estimate.source = cellstr(allt1); 120 | matlabbatch{4}.spm.spatial.coreg.estimate.other{1} = ''; 121 | matlabbatch{4}.spm.spatial.coreg.estimate.eoptions.cost_fun = 'nmi'; 122 | matlabbatch{4}.spm.spatial.coreg.estimate.eoptions.sep = [4 2]; 123 | matlabbatch{4}.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]; 124 | matlabbatch{4}.spm.spatial.coreg.estimate.eoptions.fwhm = [7 7]; 125 | 126 | else % 1 structural scan 127 | % Coregister struct to mean functional 128 | matlabbatch{3}.spm.spatial.coreg.estimate.ref(1) = cfg_dep('Realign: Estimate & Reslice: Mean Image', substruct('.','val', '{}',{2}, '.','val', '{}',{1}, '.','val', '{}',{1}, '.','val', '{}',{1}), substruct('.','rmean')); 129 | matlabbatch{3}.spm.spatial.coreg.estimate.source = cellstr(allt1); 130 | matlabbatch{3}.spm.spatial.coreg.estimate.other{1} = ''; 131 | matlabbatch{3}.spm.spatial.coreg.estimate.eoptions.cost_fun = 'nmi'; 132 | matlabbatch{3}.spm.spatial.coreg.estimate.eoptions.sep = [4 2]; 133 | matlabbatch{3}.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]; 134 | matlabbatch{3}.spm.spatial.coreg.estimate.eoptions.fwhm = [7 7]; 135 | end 136 | 137 | catch 138 | status = 0; 139 | errorMsg = 'Error making matlabbatch'; 140 | disp([errorMsg ' for ' subNam]); 141 | cd(codeDir); 142 | return 143 | end 144 | 145 | %% Save matlabbatch 146 | try 147 | time_stamp = datestr(now, 'yyyymmdd_HHMM'); 148 | filename = [batchDir '/preDARTEL_' subNam '_' time_stamp]; 149 | save(filename, 'matlabbatch'); 150 | catch 151 | status = 0; 152 | errorMsg = 'Error saving matlabbatch'; 153 | disp([errorMsg ' for ' subNam]); 154 | cd(codeDir); 155 | return 156 | end 157 | %% Run Matlabbatch 158 | try 159 | if execPreDartel == 1 160 | spm_jobman('run',matlabbatch); 161 | end 162 | status = 1; 163 | cd(codeDir); 164 | catch 165 | status = 0; 166 | errorMsg = 'Error running matlabbatch'; 167 | disp([errorMsg ' for ' subNam]); 168 | cd(codeDir); 169 | return 170 | end 171 | end -------------------------------------------------------------------------------- /depreciated/wrapper_dartel_1struct.m: -------------------------------------------------------------------------------- 1 | %% SPM12 Dartel using one structural file (just MPRAGE or just MBW) 2 | % Created by Kevin Tan on Jun 29, 2017 (some code adopted from Bob Spunt) 3 | 4 | % Instructions, agorithmic description & edit history (please read!!): 5 | % https://github.com/scanUCLA/spm12-dartel 6 | 7 | % Last revision: 2 Aug 2017 - Kevin Tan 8 | %% User-editable Parameters 9 | 10 | % Path/directory/name information 11 | owd = '/data/gratitude_mprage/data'; % base study directory 12 | codeDir = '/data/gratitude_mprage/preproc'; % where code lives 13 | batchDir = '/data/gratitude_mprage/preproc/batches'; % dir in which to save batch scripts & predartel subject status + workspace 14 | subID = 'grat*'; % pattern for finding subject folders (use wildcards) 15 | runID = 'BOLD_*'; % pattern for finding functional run folders (use wildcards) 16 | funcID ='BOLD_'; % first character(s) in your functional images? (do NOT use wildcards) 17 | structID = 'MBW_*'; % pattern for finding structural folder (use wildcards) 18 | 19 | % Subjects to do/skip, example: {'sub001' 'sub002'} 20 | subNam = {}; % do which subjects? (leave empty to do all) 21 | skipSub = {}; % skip which subjects? (leave empty to do all) 22 | 23 | % 4d or 3d functional nifti files (e.g. BOLD runs all in one .nii or multiple .niis?) 24 | fourDnii = 1; % 1=4d, 0=3d 25 | 26 | % Path of TPM tissues in your SPM directory 27 | tpmPath = '/u/project/CCN/apps/spm12/tpm'; 28 | 29 | % Voxel size for resampling (use AFNI's dicom_hdr on the functional & structural DICOM files and use the "slice thickness") 30 | fVoxSize = [3 3 3]; % functionals (non-multiband usually [3 3 3], multiband usually [2 2 2]) 31 | sVoxSize = [1 1 1]; % MPRAGE usually [1 1 1] 32 | 33 | % smoothing kernel for functionals (mm isotropic) 34 | FWHM = 8; 35 | 36 | % Execute (1) or just make matlabbatches (0) 37 | execPreDartel = 1; 38 | execDartel = 1; 39 | 40 | % Number of workers (threads) matlab should use 41 | nWorkers = 15; %maxNumCompThreads 42 | 43 | %% Setup subjects 44 | 45 | % Make batch folder 46 | try 47 | mkdir(batchDir); 48 | catch 49 | end 50 | 51 | diary([batchDir '/preDARTEL_log_' datestr(now,'yyyymmdd_HHMM') '.txt']); 52 | 53 | % Find subject directories 54 | if isempty(subNam) 55 | d = dir([owd '/' subID]); 56 | for ii = 1:length(d) 57 | subNam{ii} = d(ii).name; 58 | fprintf('Adding %s\n', subNam{ii}) 59 | end 60 | end 61 | numSubs = length(subNam); 62 | cd(codeDir); 63 | 64 | % Prepare status struct 65 | runStatus = struct('subNam',[],'status',[],'error',[]); 66 | runStatus(numSubs).subNam = []; 67 | runStatus(numSubs).status = []; 68 | runStatus(numSubs).error = []; 69 | 70 | %% Run Pre-dartel (explicitly parallelized per subject) 71 | 72 | % Determine number of parallel workers 73 | parpool('local', nWorkers); 74 | 75 | % Parfor loop to run explicity parallelized pre-dartel across subs 76 | parfor i = 1:numSubs 77 | % Pre-allocate subject in runStatus struct 78 | runStatus(i).subNam = subNam{i}; 79 | 80 | % Cross-check subject with run/skip list 81 | if ismember(subNam{i}, skipSub) 82 | runStatus(i).status = 0; 83 | runStatus(i).error = 'Subject in exclusion list'; 84 | disp(['Skipping subject ' subNam{i} ', is in exclusion list']); 85 | continue 86 | else % Run subject 87 | disp(['Running subject ' subNam{i}]); 88 | [runStatus(i).status, runStatus(i).error, allfuncs{i}, allt1{i}, allmt1{i},... 89 | allrc1{i}, allrc2{i}, allu_rc1{i}, allc1{i}, allc2{i}, allc3{i}] =... 90 | run_dartel_1struct(subNam{i}, owd, codeDir, batchDir, runID, funcID,... 91 | structID, fourDnii, execPreDartel); 92 | if runStatus(i).status == 1 93 | disp(['subject ' subNam{i} ' successful']); 94 | else 95 | runStatus(i).status = 0; 96 | disp([runStatus(i).error ' for ' subNam{i}]); 97 | end 98 | end 99 | end 100 | delete(pool); 101 | 102 | % % Get rid of image frame specification for func images (SPM idiosyncrasy) 103 | % if fourDnii == 1 104 | % for ia = 1:length(a_allfuncs) 105 | % for ib = 1:length(a_allfuncs{ia}) 106 | % chars = length(a_allfuncs{ia}{ib}{1})-2; 107 | % allfuncs{ia}{ib,1} = a_allfuncs{ia}{ib}{1}(1:chars); 108 | % end 109 | % end 110 | % else 111 | % for ia = 1:length(a_allfuncs) 112 | % for ib = 1:length(a_allfuncs{ia}) 113 | % chars = length(a_allfuncs{ia}{ib})-2; 114 | % allfuncs{ia}{ib,1} = a_allfuncs{ia}{ib}(1:chars); 115 | % end 116 | % end 117 | % end 118 | 119 | % Save stuff 120 | date = datestr(now,'yyyymmdd_HHMM'); 121 | filename = [batchDir '/runStatus_' date '.mat']; 122 | save(filename,'runStatus'); 123 | filename = [batchDir '/forDartel_workspace_' date '.mat']; % Use this to re-do "run dartel" if it fails 124 | save(filename); 125 | diary off 126 | 127 | %% Create DARTEL matlabbatch 128 | 129 | diary([batchDir '/DARTEL_log_' datestr(now,'yyyymmdd_HHMM') '.txt']); 130 | 131 | % Set max threads for implicit multithreading 132 | %lastNumThreads = maxNumCompThreads(myCluster.NumWorkers); 133 | 134 | % Load SPM 135 | spm('defaults','fmri'); spm_jobman('initcfg'); 136 | 137 | % Subjects with no errors in pre-dartel 138 | inds = find([runStatus.status]); 139 | 140 | % Create Segmentation matlabbatch (implicitly parallelized in SPM) 141 | for s = 1:length(inds) 142 | matlabbatch{1}.spm.spatial.preproc.channel.vols{s,1} = allt1{inds(s)}; 143 | end 144 | matlabbatch{1}.spm.spatial.preproc.channel.biasreg = 0.0001; 145 | matlabbatch{1}.spm.spatial.preproc.channel.biasfwhm = 60; 146 | matlabbatch{1}.spm.spatial.preproc.channel.write = [0 1]; 147 | matlabbatch{1}.spm.spatial.preproc.tissue(1).tpm = cellstr([tpmPath '/TPM.nii,1']); 148 | matlabbatch{1}.spm.spatial.preproc.tissue(1).ngaus = 2; 149 | matlabbatch{1}.spm.spatial.preproc.tissue(1).native = [1 1]; 150 | matlabbatch{1}.spm.spatial.preproc.tissue(1).warped = [0 0]; 151 | matlabbatch{1}.spm.spatial.preproc.tissue(2).tpm = cellstr([tpmPath '/TPM.nii,2']); 152 | matlabbatch{1}.spm.spatial.preproc.tissue(2).ngaus = 2; 153 | matlabbatch{1}.spm.spatial.preproc.tissue(2).native = [1 1]; 154 | matlabbatch{1}.spm.spatial.preproc.tissue(2).warped = [0 0]; 155 | matlabbatch{1}.spm.spatial.preproc.tissue(3).tpm = cellstr([tpmPath '/TPM.nii,3']); 156 | matlabbatch{1}.spm.spatial.preproc.tissue(3).ngaus = 2; 157 | matlabbatch{1}.spm.spatial.preproc.tissue(3).native = [1 0]; 158 | matlabbatch{1}.spm.spatial.preproc.tissue(3).warped = [0 0]; 159 | matlabbatch{1}.spm.spatial.preproc.tissue(4).tpm = cellstr([tpmPath '/TPM.nii,4']); 160 | matlabbatch{1}.spm.spatial.preproc.tissue(4).ngaus = 3; 161 | matlabbatch{1}.spm.spatial.preproc.tissue(4).native = [0 0]; 162 | matlabbatch{1}.spm.spatial.preproc.tissue(4).warped = [0 0]; 163 | matlabbatch{1}.spm.spatial.preproc.tissue(5).tpm = cellstr([tpmPath '/TPM.nii,5']); 164 | matlabbatch{1}.spm.spatial.preproc.tissue(5).ngaus = 4; 165 | matlabbatch{1}.spm.spatial.preproc.tissue(5).native = [0 0]; 166 | matlabbatch{1}.spm.spatial.preproc.tissue(5).warped = [0 0]; 167 | matlabbatch{1}.spm.spatial.preproc.tissue(6).tpm = cellstr([tpmPath '/TPM.nii,6']); 168 | matlabbatch{1}.spm.spatial.preproc.tissue(6).ngaus = 2; 169 | matlabbatch{1}.spm.spatial.preproc.tissue(6).native = [0 0]; 170 | matlabbatch{1}.spm.spatial.preproc.tissue(6).warped = [0 0]; 171 | matlabbatch{1}.spm.spatial.preproc.warp.mrf = 1; 172 | matlabbatch{1}.spm.spatial.preproc.warp.cleanup = 1; 173 | matlabbatch{1}.spm.spatial.preproc.warp.reg = [0 0.001 0.5 0.05 0.2]; 174 | matlabbatch{1}.spm.spatial.preproc.warp.affreg = 'mni'; 175 | matlabbatch{1}.spm.spatial.preproc.warp.fwhm = 0; 176 | matlabbatch{1}.spm.spatial.preproc.warp.samp = 3; 177 | matlabbatch{1}.spm.spatial.preproc.warp.write = [0 1]; 178 | 179 | % DARTEL: create templates 180 | for s = 1:length(inds) 181 | matlabbatch{2}.spm.tools.dartel.warp.images{1,1}{s,1} = allrc1{inds(s)}; 182 | matlabbatch{2}.spm.tools.dartel.warp.images{1,2}{s,1} = allrc2{inds(s)}; 183 | end 184 | matlabbatch{2}.spm.tools.dartel.warp.settings.template = 'Template'; 185 | matlabbatch{2}.spm.tools.dartel.warp.settings.rform = 0; 186 | matlabbatch{2}.spm.tools.dartel.warp.settings.param(1).its = 3; 187 | matlabbatch{2}.spm.tools.dartel.warp.settings.param(1).rparam = [4 2 1e-06]; 188 | matlabbatch{2}.spm.tools.dartel.warp.settings.param(1).K = 0; 189 | matlabbatch{2}.spm.tools.dartel.warp.settings.param(1).slam = 16; 190 | matlabbatch{2}.spm.tools.dartel.warp.settings.param(2).its = 3; 191 | matlabbatch{2}.spm.tools.dartel.warp.settings.param(2).rparam = [2 1 1e-06]; 192 | matlabbatch{2}.spm.tools.dartel.warp.settings.param(2).K = 0; 193 | matlabbatch{2}.spm.tools.dartel.warp.settings.param(2).slam = 8; 194 | matlabbatch{2}.spm.tools.dartel.warp.settings.param(3).its = 3; 195 | matlabbatch{2}.spm.tools.dartel.warp.settings.param(3).rparam = [1 0.5 1e-06]; 196 | matlabbatch{2}.spm.tools.dartel.warp.settings.param(3).K = 1; 197 | matlabbatch{2}.spm.tools.dartel.warp.settings.param(3).slam = 4; 198 | matlabbatch{2}.spm.tools.dartel.warp.settings.param(4).its = 3; 199 | matlabbatch{2}.spm.tools.dartel.warp.settings.param(4).rparam = [0.5 0.25 1e-06]; 200 | matlabbatch{2}.spm.tools.dartel.warp.settings.param(4).K = 2; 201 | matlabbatch{2}.spm.tools.dartel.warp.settings.param(4).slam = 2; 202 | matlabbatch{2}.spm.tools.dartel.warp.settings.param(5).its = 3; 203 | matlabbatch{2}.spm.tools.dartel.warp.settings.param(5).rparam = [0.25 0.125 1e-06]; 204 | matlabbatch{2}.spm.tools.dartel.warp.settings.param(5).K = 4; 205 | matlabbatch{2}.spm.tools.dartel.warp.settings.param(5).slam = 1; 206 | matlabbatch{2}.spm.tools.dartel.warp.settings.param(6).its = 3; 207 | matlabbatch{2}.spm.tools.dartel.warp.settings.param(6).rparam = [0.25 0.125 1e-06]; 208 | matlabbatch{2}.spm.tools.dartel.warp.settings.param(6).K = 6; 209 | matlabbatch{2}.spm.tools.dartel.warp.settings.param(6).slam = 0.5; 210 | matlabbatch{2}.spm.tools.dartel.warp.settings.optim.lmreg = 0.01; 211 | matlabbatch{2}.spm.tools.dartel.warp.settings.optim.cyc = 3; 212 | matlabbatch{2}.spm.tools.dartel.warp.settings.optim.its = 3; 213 | 214 | % DARTEL: normalize functional images to MNI 215 | matlabbatch{3}.spm.tools.dartel.mni_norm.template(1) = cfg_dep('Run Dartel (create Templates): Template (Iteration 6)', substruct('.','val', '{}',{2}, '.','val', '{}',{1}, '.','val', '{}',{1}, '.','val', '{}',{1}), substruct('.','template', '()',{7})); 216 | for s = 1:length(inds) 217 | matlabbatch{3}.spm.tools.dartel.mni_norm.data.subj(s).flowfield{1} = allu_rc1{inds(s)}; 218 | matlabbatch{3}.spm.tools.dartel.mni_norm.data.subj(s).images = allfuncs{inds(s)}; 219 | end 220 | matlabbatch{3}.spm.tools.dartel.mni_norm.vox = fVoxSize; 221 | matlabbatch{3}.spm.tools.dartel.mni_norm.bb = [NaN NaN NaN; NaN NaN NaN]; 222 | matlabbatch{3}.spm.tools.dartel.mni_norm.preserve = 0; 223 | matlabbatch{3}.spm.tools.dartel.mni_norm.fwhm = [FWHM FWHM FWHM]; 224 | 225 | % DARTEL: normalize bias-corrected structural to MNI 226 | matlabbatch{4}.spm.tools.dartel.mni_norm.template(1) = cfg_dep('Run Dartel (create Templates): Template (Iteration 6)', substruct('.','val', '{}',{2}, '.','val', '{}',{1}, '.','val', '{}',{1}, '.','val', '{}',{1}), substruct('.','template', '()',{7})); 227 | for s = 1:length(inds) 228 | matlabbatch{4}.spm.tools.dartel.mni_norm.data.subj(s).flowfield{1} = allu_rc1{inds(s)}; 229 | matlabbatch{4}.spm.tools.dartel.mni_norm.data.subj(s).images{1} = allmt1{inds(s)}; 230 | end 231 | matlabbatch{4}.spm.tools.dartel.mni_norm.vox = sVoxSize; 232 | matlabbatch{4}.spm.tools.dartel.mni_norm.bb = [NaN NaN NaN; NaN NaN NaN]; 233 | matlabbatch{4}.spm.tools.dartel.mni_norm.preserve = 0; 234 | matlabbatch{4}.spm.tools.dartel.mni_norm.fwhm = [0 0 0]; 235 | 236 | % DARTEL: normalize grey matter segmentation to MNI (for Conn toolbox or other use of segmentations) 237 | matlabbatch{5}.spm.tools.dartel.mni_norm.template(1) = cfg_dep('Run Dartel (create Templates): Template (Iteration 6)', substruct('.','val', '{}',{2}, '.','val', '{}',{1}, '.','val', '{}',{1}, '.','val', '{}',{1}), substruct('.','template', '()',{7})); 238 | for s = 1:length(inds) 239 | matlabbatch{5}.spm.tools.dartel.mni_norm.data.subj(s).flowfield{1} = allu_rc1{inds(s)}; 240 | matlabbatch{5}.spm.tools.dartel.mni_norm.data.subj(s).images{1} = allc1{inds(s)}; 241 | end 242 | matlabbatch{5}.spm.tools.dartel.mni_norm.vox = sVoxSize; 243 | matlabbatch{5}.spm.tools.dartel.mni_norm.bb = [NaN NaN NaN; NaN NaN NaN]; 244 | matlabbatch{5}.spm.tools.dartel.mni_norm.preserve = 0; 245 | matlabbatch{5}.spm.tools.dartel.mni_norm.fwhm = [0 0 0]; 246 | 247 | % DARTEL: normalize white matter segmentation to MNI (for Conn toolbox or other use of segmentations) 248 | matlabbatch{6}.spm.tools.dartel.mni_norm.template(1) = cfg_dep('Run Dartel (create Templates): Template (Iteration 6)', substruct('.','val', '{}',{2}, '.','val', '{}',{1}, '.','val', '{}',{1}, '.','val', '{}',{1}), substruct('.','template', '()',{7})); 249 | for s = 1:length(inds) 250 | matlabbatch{6}.spm.tools.dartel.mni_norm.data.subj(s).flowfield{1} = allu_rc1{inds(s)}; 251 | matlabbatch{6}.spm.tools.dartel.mni_norm.data.subj(s).images{1} = allc2{inds(s)}; 252 | end 253 | matlabbatch{6}.spm.tools.dartel.mni_norm.vox = sVoxSize; 254 | matlabbatch{6}.spm.tools.dartel.mni_norm.bb = [NaN NaN NaN; NaN NaN NaN]; 255 | matlabbatch{6}.spm.tools.dartel.mni_norm.preserve = 0; 256 | matlabbatch{6}.spm.tools.dartel.mni_norm.fwhm = [0 0 0]; 257 | 258 | % DARTEL: normalize CSF segmentation to MNI (for Conn toolbox or other use of segmentations) 259 | matlabbatch{7}.spm.tools.dartel.mni_norm.template(1) = cfg_dep('Run Dartel (create Templates): Template (Iteration 6)', substruct('.','val', '{}',{2}, '.','val', '{}',{1}, '.','val', '{}',{1}, '.','val', '{}',{1}), substruct('.','template', '()',{7})); 260 | for s = 1:length(inds) 261 | matlabbatch{7}.spm.tools.dartel.mni_norm.data.subj(s).flowfield{1} = allu_rc1{inds(s)}; 262 | matlabbatch{7}.spm.tools.dartel.mni_norm.data.subj(s).images{1} = allc3{inds(s)}; 263 | end 264 | matlabbatch{7}.spm.tools.dartel.mni_norm.vox = sVoxSize; 265 | matlabbatch{7}.spm.tools.dartel.mni_norm.bb = [NaN NaN NaN; NaN NaN NaN]; 266 | matlabbatch{7}.spm.tools.dartel.mni_norm.preserve = 0; 267 | matlabbatch{7}.spm.tools.dartel.mni_norm.fwhm = [0 0 0]; 268 | 269 | %% Save & run DARTEL matlabbatch 270 | 271 | % save matlabbatch struct in output folder 272 | time_stamp = datestr(now,'yyyymmdd_HHMM'); 273 | filename = [batchDir '/DARTEL_' time_stamp]; 274 | save(filename,'matlabbatch'); 275 | 276 | % Execute matlabbatch 277 | if execDartel == 1 278 | spm_jobman('run',matlabbatch); 279 | disp(['DARTEL COMPLETED: ' datestr(now,'yyyymmdd_HHMM')]); 280 | end 281 | diary off 282 | -------------------------------------------------------------------------------- /wrapper_spm12dartel.m: -------------------------------------------------------------------------------- 1 | %% SPM12 Dartel using just MPRAGE or both MPRAGE & MBW 2 | % Created by Kevin Tan on Jun 29, 2017 (some code adopted from Bob Spunt) 3 | 4 | % Instructions, agorithmic description & edit history (please read!!): 5 | % https://github.com/scanUCLA/spm12-dartel 6 | 7 | % Last revision: 23 Aug 2017 - Kevin Tan 8 | %% User-editable Parameters 9 | 10 | % Path/directory/name information 11 | owd = '/u/project/sanscn/kevmtan/scripts/rawTestData/PTSD'; % base study directory 12 | codeDir = '/u/project/sanscn/kevmtan/scripts/SPM12_DARTEL'; % where code lives 13 | batchDir = '/u/project/sanscn/kevmtan/scripts/SPM12_DARTEL/PTSD_170802'; % dir in which to save batch scripts & predartel subject status + workspace 14 | 15 | % pattern for finding subject folders (use wildcards) 16 | subID = 'VET*'; 17 | 18 | % Subjects to do/skip, example: {'sub001' 'sub002'} 19 | subNam = {}; % do which subjects? (leave empty to do all) 20 | skipSub = {}; % skip which subjects? (leave empty to do all) 21 | 22 | % Funcitonal image info 23 | runID = 'BOLD_*'; % pattern for finding functional run folders (use wildcards) 24 | funcID ='BOLD_'; % first character(s) in your functional NIFTI files? (do NOT use wildcards) 25 | 26 | % Are you using 4D NIFTI functional files? 27 | fourDnii = true; % true=all run volumes in one NIFTI files, false=run volumes in separate NIFTI files 28 | 29 | % Structural image info (pattern for finding struct folders, assumes first characters of struct folder and struct filename are same) 30 | structID{1} = 'SAG_MPRAGE*'; % MPRAGE if you have it, MBW if no MPRAGE (use wildcards) 31 | structID{2} = 'Matched_Bandwidth_HiRes*'; % MBW if you have it in addition to MPRAGE (use wildcards) 32 | 33 | % Two structural scans or just one? 34 | twoStructs = true; % true = 2 structural scans, false = 1 strutural scan 35 | 36 | % Path of TPM tissues in your SPM directory 37 | tpmPath = '/u/project/CCN/apps/spm12/tpm'; 38 | 39 | % Voxel size for resampling (use AFNI's dicom_hdr on the functional & structural DICOM files and use the "slice thickness") 40 | fVoxSize = [3 3 3]; % functionals (non-multiband usually [3 3 3], multiband usually [2 2 2]) 41 | sVoxSize = [1 1 1]; % for structID{1} (MPRAGE usually [1 1 1], MBW usually [3 3 3]) 42 | 43 | % smoothing kernel for functionals (mm isotropic) 44 | FWHM = 8; 45 | 46 | % Number of workers (threads) matlab should use 47 | nWorkers = maxNumCompThreads; % specify integer if desired 48 | 49 | % EXECUTE (1) or just make matlabbatches (0) 50 | execPreDartel = 0; 51 | execDartel = 0; 52 | 53 | %% Setup subjects 54 | 55 | % Make batch folder 56 | try 57 | mkdir(batchDir); 58 | catch 59 | end 60 | 61 | diary([batchDir '/preDARTEL_log_' datestr(now,'yyyymmdd_HHMM') '.txt']); 62 | 63 | % Find subject directories 64 | if isempty(subNam) 65 | d = dir([owd '/' subID]); 66 | for ii = 1:length(d) 67 | subNam{ii} = d(ii).name; 68 | fprintf('Adding %s\n', subNam{ii}) 69 | end 70 | end 71 | numSubs = length(subNam); 72 | cd(codeDir); 73 | 74 | % Prepare status struct 75 | runStatus = struct('subNam',[],'status',[],'error',[]); 76 | runStatus(numSubs).subNam = []; 77 | runStatus(numSubs).status = []; 78 | runStatus(numSubs).error = []; 79 | 80 | %% Run Pre-dartel (explicitly parallelized per subject) 81 | 82 | % Determine number of parallel workers 83 | nWorkers = min(numSubs, nWorkers); 84 | parpool('local', nWorkers); 85 | 86 | % Parfor loop to run explicity parallelized pre-dartel across subs 87 | parfor i = 1:numSubs 88 | % Pre-allocate subject in runStatus struct 89 | runStatus(i).subNam = subNam{i}; 90 | 91 | % Cross-check subject with run/skip list 92 | if ismember(subNam{i}, skipSub) 93 | runStatus(i).status = 0; 94 | runStatus(i).error = 'Subject in exclusion list'; 95 | disp(['Skipping subject ' subNam{i} ', is in exclusion list']); 96 | continue 97 | else % Run subject 98 | disp(['Running subject ' subNam{i}]); 99 | [runStatus(i).status, runStatus(i).error, allfuncs{i}, allt1{i}, allmt1{i},... 100 | allrc1{i}, allrc2{i}, allu_rc1{i}, allc1{i}, allc2{i}, allc3{i}] =... 101 | run_spm12dartel(subNam{i}, owd, codeDir, batchDir, runID, funcID,... 102 | structID, twoStructs, fourDnii, execPreDartel); 103 | if runStatus(i).status == 1 104 | disp(['subject ' subNam{i} ' successful']); 105 | else 106 | runStatus(i).status = 0; 107 | disp([runStatus(i).error ' for ' subNam{i}]); 108 | end 109 | end 110 | end 111 | delete(gcp('nocreate')); 112 | 113 | % Save stuff 114 | date = datestr(now,'yyyymmdd_HHMM'); 115 | filename = [batchDir '/runStatus_' date '.mat']; 116 | save(filename,'runStatus'); 117 | filename = [batchDir '/forDartel_workspace_' date '.mat']; % Use this to re-do "run dartel" if it fails 118 | save(filename); 119 | diary off 120 | 121 | %% Create DARTEL matlabbatch 122 | 123 | diary([batchDir '/DARTEL_log_' datestr(now,'yyyymmdd_HHMM') '.txt']); 124 | 125 | % Load SPM 126 | spm('defaults','fmri'); spm_jobman('initcfg'); 127 | 128 | % Set max threads for implicit multithreading 129 | %lastNumThreads = maxNumCompThreads(nWorkers*2); 130 | 131 | % Subjects with no errors in pre-dartel 132 | inds = find([runStatus.status]); 133 | 134 | % Create Segmentation matlabbatch (implicitly parallelized in SPM) 135 | for s = 1:length(inds) 136 | matlabbatch{1}.spm.spatial.preproc.channel.vols{s,1} = allt1{inds(s)}; 137 | end 138 | matlabbatch{1}.spm.spatial.preproc.channel.biasreg = 0.001; 139 | matlabbatch{1}.spm.spatial.preproc.channel.biasfwhm = 60; 140 | matlabbatch{1}.spm.spatial.preproc.channel.write = [0 1]; 141 | matlabbatch{1}.spm.spatial.preproc.tissue(1).tpm = cellstr([tpmPath '/TPM.nii,1']); 142 | matlabbatch{1}.spm.spatial.preproc.tissue(1).ngaus = 2; 143 | matlabbatch{1}.spm.spatial.preproc.tissue(1).native = [1 1]; 144 | matlabbatch{1}.spm.spatial.preproc.tissue(1).warped = [0 0]; 145 | matlabbatch{1}.spm.spatial.preproc.tissue(2).tpm = cellstr([tpmPath '/TPM.nii,2']); 146 | matlabbatch{1}.spm.spatial.preproc.tissue(2).ngaus = 2; 147 | matlabbatch{1}.spm.spatial.preproc.tissue(2).native = [1 1]; 148 | matlabbatch{1}.spm.spatial.preproc.tissue(2).warped = [0 0]; 149 | matlabbatch{1}.spm.spatial.preproc.tissue(3).tpm = cellstr([tpmPath '/TPM.nii,3']); 150 | matlabbatch{1}.spm.spatial.preproc.tissue(3).ngaus = 2; 151 | matlabbatch{1}.spm.spatial.preproc.tissue(3).native = [1 0]; 152 | matlabbatch{1}.spm.spatial.preproc.tissue(3).warped = [0 0]; 153 | matlabbatch{1}.spm.spatial.preproc.tissue(4).tpm = cellstr([tpmPath '/TPM.nii,4']); 154 | matlabbatch{1}.spm.spatial.preproc.tissue(4).ngaus = 3; 155 | matlabbatch{1}.spm.spatial.preproc.tissue(4).native = [0 0]; 156 | matlabbatch{1}.spm.spatial.preproc.tissue(4).warped = [0 0]; 157 | matlabbatch{1}.spm.spatial.preproc.tissue(5).tpm = cellstr([tpmPath '/TPM.nii,5']); 158 | matlabbatch{1}.spm.spatial.preproc.tissue(5).ngaus = 4; 159 | matlabbatch{1}.spm.spatial.preproc.tissue(5).native = [0 0]; 160 | matlabbatch{1}.spm.spatial.preproc.tissue(5).warped = [0 0]; 161 | matlabbatch{1}.spm.spatial.preproc.tissue(6).tpm = cellstr([tpmPath '/TPM.nii,6']); 162 | matlabbatch{1}.spm.spatial.preproc.tissue(6).ngaus = 2; 163 | matlabbatch{1}.spm.spatial.preproc.tissue(6).native = [0 0]; 164 | matlabbatch{1}.spm.spatial.preproc.tissue(6).warped = [0 0]; 165 | matlabbatch{1}.spm.spatial.preproc.warp.mrf = 1; 166 | matlabbatch{1}.spm.spatial.preproc.warp.cleanup = 1; 167 | matlabbatch{1}.spm.spatial.preproc.warp.reg = [0 0.001 0.5 0.05 0.2]; 168 | matlabbatch{1}.spm.spatial.preproc.warp.affreg = 'mni'; 169 | matlabbatch{1}.spm.spatial.preproc.warp.fwhm = 0; 170 | matlabbatch{1}.spm.spatial.preproc.warp.samp = 3; 171 | matlabbatch{1}.spm.spatial.preproc.warp.write = [0 1]; 172 | 173 | % DARTEL: create templates 174 | for s = 1:length(inds) 175 | matlabbatch{2}.spm.tools.dartel.warp.images{1,1}{s,1} = allrc1{inds(s)}; 176 | matlabbatch{2}.spm.tools.dartel.warp.images{1,2}{s,1} = allrc2{inds(s)}; 177 | end 178 | matlabbatch{2}.spm.tools.dartel.warp.settings.template = 'Template'; 179 | matlabbatch{2}.spm.tools.dartel.warp.settings.rform = 0; 180 | matlabbatch{2}.spm.tools.dartel.warp.settings.param(1).its = 3; 181 | matlabbatch{2}.spm.tools.dartel.warp.settings.param(1).rparam = [4 2 1e-06]; 182 | matlabbatch{2}.spm.tools.dartel.warp.settings.param(1).K = 0; 183 | matlabbatch{2}.spm.tools.dartel.warp.settings.param(1).slam = 16; 184 | matlabbatch{2}.spm.tools.dartel.warp.settings.param(2).its = 3; 185 | matlabbatch{2}.spm.tools.dartel.warp.settings.param(2).rparam = [2 1 1e-06]; 186 | matlabbatch{2}.spm.tools.dartel.warp.settings.param(2).K = 0; 187 | matlabbatch{2}.spm.tools.dartel.warp.settings.param(2).slam = 8; 188 | matlabbatch{2}.spm.tools.dartel.warp.settings.param(3).its = 3; 189 | matlabbatch{2}.spm.tools.dartel.warp.settings.param(3).rparam = [1 0.5 1e-06]; 190 | matlabbatch{2}.spm.tools.dartel.warp.settings.param(3).K = 1; 191 | matlabbatch{2}.spm.tools.dartel.warp.settings.param(3).slam = 4; 192 | matlabbatch{2}.spm.tools.dartel.warp.settings.param(4).its = 3; 193 | matlabbatch{2}.spm.tools.dartel.warp.settings.param(4).rparam = [0.5 0.25 1e-06]; 194 | matlabbatch{2}.spm.tools.dartel.warp.settings.param(4).K = 2; 195 | matlabbatch{2}.spm.tools.dartel.warp.settings.param(4).slam = 2; 196 | matlabbatch{2}.spm.tools.dartel.warp.settings.param(5).its = 3; 197 | matlabbatch{2}.spm.tools.dartel.warp.settings.param(5).rparam = [0.25 0.125 1e-06]; 198 | matlabbatch{2}.spm.tools.dartel.warp.settings.param(5).K = 4; 199 | matlabbatch{2}.spm.tools.dartel.warp.settings.param(5).slam = 1; 200 | matlabbatch{2}.spm.tools.dartel.warp.settings.param(6).its = 3; 201 | matlabbatch{2}.spm.tools.dartel.warp.settings.param(6).rparam = [0.25 0.125 1e-06]; 202 | matlabbatch{2}.spm.tools.dartel.warp.settings.param(6).K = 6; 203 | matlabbatch{2}.spm.tools.dartel.warp.settings.param(6).slam = 0.5; 204 | matlabbatch{2}.spm.tools.dartel.warp.settings.optim.lmreg = 0.01; 205 | matlabbatch{2}.spm.tools.dartel.warp.settings.optim.cyc = 3; 206 | matlabbatch{2}.spm.tools.dartel.warp.settings.optim.its = 3; 207 | 208 | % DARTEL: normalize & smooth functional images to MNI 209 | matlabbatch{3}.spm.tools.dartel.mni_norm.template(1) = cfg_dep('Run Dartel (create Templates): Template (Iteration 6)', substruct('.','val', '{}',{2}, '.','val', '{}',{1}, '.','val', '{}',{1}, '.','val', '{}',{1}), substruct('.','template', '()',{7})); 210 | for s = 1:length(inds) 211 | matlabbatch{3}.spm.tools.dartel.mni_norm.data.subj(s).flowfield{1} = allu_rc1{inds(s)}; 212 | matlabbatch{3}.spm.tools.dartel.mni_norm.data.subj(s).images = allfuncs{inds(s)}; 213 | end 214 | matlabbatch{3}.spm.tools.dartel.mni_norm.vox = fVoxSize; 215 | matlabbatch{3}.spm.tools.dartel.mni_norm.bb = [NaN NaN NaN; NaN NaN NaN]; 216 | matlabbatch{3}.spm.tools.dartel.mni_norm.preserve = 0; 217 | matlabbatch{3}.spm.tools.dartel.mni_norm.fwhm = [FWHM FWHM FWHM]; 218 | 219 | % DARTEL: normalize bias-corrected MPRAGE to MNI 220 | matlabbatch{4}.spm.tools.dartel.mni_norm.template(1) = cfg_dep('Run Dartel (create Templates): Template (Iteration 6)', substruct('.','val', '{}',{2}, '.','val', '{}',{1}, '.','val', '{}',{1}, '.','val', '{}',{1}), substruct('.','template', '()',{7})); 221 | for s = 1:length(inds) 222 | matlabbatch{4}.spm.tools.dartel.mni_norm.data.subj(s).flowfield{1} = allu_rc1{inds(s)}; 223 | matlabbatch{4}.spm.tools.dartel.mni_norm.data.subj(s).images{1} = allmt1{inds(s)}; 224 | end 225 | matlabbatch{4}.spm.tools.dartel.mni_norm.vox = sVoxSize; 226 | matlabbatch{4}.spm.tools.dartel.mni_norm.bb = [NaN NaN NaN; NaN NaN NaN]; 227 | matlabbatch{4}.spm.tools.dartel.mni_norm.preserve = 0; 228 | matlabbatch{4}.spm.tools.dartel.mni_norm.fwhm = [0 0 0]; 229 | 230 | % DARTEL: normalize grey matter segmentation to MNI (for Conn toolbox or other use of segmentations) 231 | matlabbatch{5}.spm.tools.dartel.mni_norm.template(1) = cfg_dep('Run Dartel (create Templates): Template (Iteration 6)', substruct('.','val', '{}',{2}, '.','val', '{}',{1}, '.','val', '{}',{1}, '.','val', '{}',{1}), substruct('.','template', '()',{7})); 232 | for s = 1:length(inds) 233 | matlabbatch{5}.spm.tools.dartel.mni_norm.data.subj(s).flowfield{1} = allu_rc1{inds(s)}; 234 | matlabbatch{5}.spm.tools.dartel.mni_norm.data.subj(s).images{1} = allc1{inds(s)}; 235 | end 236 | matlabbatch{5}.spm.tools.dartel.mni_norm.vox = sVoxSize; 237 | matlabbatch{5}.spm.tools.dartel.mni_norm.bb = [NaN NaN NaN; NaN NaN NaN]; 238 | matlabbatch{5}.spm.tools.dartel.mni_norm.preserve = 0; 239 | matlabbatch{5}.spm.tools.dartel.mni_norm.fwhm = [0 0 0]; 240 | 241 | % DARTEL: normalize white matter segmentation to MNI (for Conn toolbox or other use of segmentations) 242 | matlabbatch{6}.spm.tools.dartel.mni_norm.template(1) = cfg_dep('Run Dartel (create Templates): Template (Iteration 6)', substruct('.','val', '{}',{2}, '.','val', '{}',{1}, '.','val', '{}',{1}, '.','val', '{}',{1}), substruct('.','template', '()',{7})); 243 | for s = 1:length(inds) 244 | matlabbatch{6}.spm.tools.dartel.mni_norm.data.subj(s).flowfield{1} = allu_rc1{inds(s)}; 245 | matlabbatch{6}.spm.tools.dartel.mni_norm.data.subj(s).images{1} = allc2{inds(s)}; 246 | end 247 | matlabbatch{6}.spm.tools.dartel.mni_norm.vox = sVoxSize; 248 | matlabbatch{6}.spm.tools.dartel.mni_norm.bb = [NaN NaN NaN; NaN NaN NaN]; 249 | matlabbatch{6}.spm.tools.dartel.mni_norm.preserve = 0; 250 | matlabbatch{6}.spm.tools.dartel.mni_norm.fwhm = [0 0 0]; 251 | 252 | % DARTEL: normalize CSF segmentation to MNI (for Conn toolbox or other use of segmentations) 253 | matlabbatch{7}.spm.tools.dartel.mni_norm.template(1) = cfg_dep('Run Dartel (create Templates): Template (Iteration 6)', substruct('.','val', '{}',{2}, '.','val', '{}',{1}, '.','val', '{}',{1}, '.','val', '{}',{1}), substruct('.','template', '()',{7})); 254 | for s = 1:length(inds) 255 | matlabbatch{7}.spm.tools.dartel.mni_norm.data.subj(s).flowfield{1} = allu_rc1{inds(s)}; 256 | matlabbatch{7}.spm.tools.dartel.mni_norm.data.subj(s).images{1} = allc3{inds(s)}; 257 | end 258 | matlabbatch{7}.spm.tools.dartel.mni_norm.vox = sVoxSize; 259 | matlabbatch{7}.spm.tools.dartel.mni_norm.bb = [NaN NaN NaN; NaN NaN NaN]; 260 | matlabbatch{7}.spm.tools.dartel.mni_norm.preserve = 0; 261 | matlabbatch{7}.spm.tools.dartel.mni_norm.fwhm = [0 0 0]; 262 | 263 | % DARTEL: normalize functional images to MNI no smoothing 264 | matlabbatch{8}.spm.tools.dartel.mni_norm.template(1) = cfg_dep('Run Dartel (create Templates): Template (Iteration 6)', substruct('.','val', '{}',{2}, '.','val', '{}',{1}, '.','val', '{}',{1}, '.','val', '{}',{1}), substruct('.','template', '()',{7})); 265 | for s = 1:length(inds) 266 | matlabbatch{8}.spm.tools.dartel.mni_norm.data.subj(s).flowfield{1} = allu_rc1{inds(s)}; 267 | matlabbatch{8}.spm.tools.dartel.mni_norm.data.subj(s).images = allfuncs{inds(s)}; 268 | end 269 | matlabbatch{8}.spm.tools.dartel.mni_norm.vox = fVoxSize; 270 | matlabbatch{8}.spm.tools.dartel.mni_norm.bb = [NaN NaN NaN; NaN NaN NaN]; 271 | matlabbatch{8}.spm.tools.dartel.mni_norm.preserve = 0; 272 | matlabbatch{8}.spm.tools.dartel.mni_norm.fwhm = [0 0 0]; 273 | 274 | %% Save & run DARTEL matlabbatch 275 | 276 | % save matlabbatch struct in output folder 277 | time_stamp = datestr(now,'yyyymmdd_HHMM'); 278 | filename = [batchDir '/DARTEL_' time_stamp]; 279 | save(filename,'matlabbatch'); 280 | 281 | % Execute matlabbatch 282 | if execDartel == 1 283 | spm_jobman('run',matlabbatch); 284 | disp(['DARTEL COMPLETED: ' datestr(now,'yyyymmdd_HHMM')]); 285 | end 286 | diary off --------------------------------------------------------------------------------