├── 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
--------------------------------------------------------------------------------