|
40 | 40 | vox = MRS_struct.p.vox(1); |
41 | 41 | kk = 1; |
42 | 42 | setup_spm = 1; |
| 43 | +prob_threshold = 0.9; % threshold to reduce partial volume effect and |
| 44 | + % improve accuracy of tissue probability maps |
43 | 45 |
|
44 | 46 | for ii = 1:length(MRS_struct.metabfile) |
45 | 47 |
|
|
50 | 52 |
|
51 | 53 | % Check to see if segmentation has already been done (and all |
52 | 54 | % probability tissue maps are present) |
53 | | - tmp = {[T1dir filesep 'c1' T1name T1ext] |
54 | | - [T1dir filesep 'c2' T1name T1ext] |
55 | | - [T1dir filesep 'c3' T1name T1ext] |
56 | | - [T1dir filesep 'c6' T1name T1ext]}; |
57 | | - filesExist = zeros(1,length(tmp)); |
58 | | - for jj = 1:length(tmp) |
59 | | - filesExist(jj) = exist(tmp{jj}, 'file'); |
| 55 | + tissue_maps = {[T1dir filesep 'c1' T1name T1ext] |
| 56 | + [T1dir filesep 'c2' T1name T1ext] |
| 57 | + [T1dir filesep 'c3' T1name T1ext] |
| 58 | + [T1dir filesep 'c6' T1name T1ext]}; |
| 59 | + filesExist = zeros(1,length(tissue_maps)); |
| 60 | + for jj = 1:length(tissue_maps) |
| 61 | + filesExist(jj) = exist(tissue_maps{jj}, 'file'); |
60 | 62 | end |
61 | 63 | if ~all(filesExist) |
62 | 64 | if setup_spm |
|
88 | 90 | GM = [T1dir filesep 'c1' T1name T1ext]; |
89 | 91 | WM = [T1dir filesep 'c2' T1name T1ext]; |
90 | 92 | CSF = [T1dir filesep 'c3' T1name T1ext]; |
91 | | - air = [T1dir filesep 'c6' T1name T1ext]; |
| 93 | + BG = [T1dir filesep 'c6' T1name T1ext]; |
92 | 94 |
|
93 | | - GMvol = spm_vol(GM); |
94 | | - WMvol = spm_vol(WM); |
95 | | - CSFvol = spm_vol(CSF); |
96 | | - airvol = spm_vol(air); |
97 | | - |
98 | | - % Segmentation quality metrics (Chua et al. JMRI, 2009; Ganzetti et |
99 | | - % al. Front. Neuroinform., 2016; Esteban et al. PLOS One, 2017) |
| 95 | + GM_vol = spm_vol(GM); |
| 96 | + WM_vol = spm_vol(WM); |
| 97 | + CSF_vol = spm_vol(CSF); |
| 98 | + BG_vol = spm_vol(BG); |
| 99 | + |
| 100 | + % MRIQC image quality metrics (Esteban et al., 2017,doi:10.1371/journal.pone.0184661; |
| 101 | + % also see: Chua et al., 2009, doi:10.1002/jmri.21768; Ganzetti et al., 2016, |
| 102 | + % doi:10.3389/fninf.2016.00010) |
100 | 103 | T1 = spm_vol(struc); |
101 | 104 | T1_tmp = T1.private.dat(:,:,:); |
102 | | - |
103 | | - WMvol_tmp = WMvol.private.dat(:,:,:); |
104 | | - WMvol_tmp(WMvol_tmp < 0.9) = NaN; |
105 | | - WMvol_thresh = WMvol_tmp .* T1_tmp; |
106 | | - WMvol_thresh = WMvol_thresh(:); |
107 | | - |
108 | | - GMvol_tmp = GMvol.private.dat(:,:,:); |
109 | | - GMvol_tmp(GMvol_tmp < 0.9) = NaN; |
110 | | - GMvol_thresh = GMvol_tmp .* T1_tmp; |
111 | | - GMvol_thresh = GMvol_thresh(:); |
112 | | - |
113 | | - airvol_tmp = airvol.private.dat(:,:,:); |
114 | | - airvol_tmp(airvol_tmp < 0.9) = NaN; |
115 | | - airvol_thresh = airvol_tmp .* T1_tmp; |
116 | | - airvol_thresh = airvol_thresh(:); |
117 | | - |
118 | | - MRS_struct.out.QA.CV_WM(ii) = std(WMvol_thresh, 'omitnan') / mean(WMvol_thresh, 'omitnan'); |
119 | | - MRS_struct.out.QA.CV_GM(ii) = std(GMvol_thresh, 'omitnan') / mean(GMvol_thresh, 'omitnan'); |
120 | | - MRS_struct.out.QA.CJV(ii) = (std(WMvol_thresh, 'omitnan') + std(GMvol_thresh, 'omitnan')) ... |
121 | | - / abs(mean(WMvol_thresh, 'omitnan') - mean(GMvol_thresh, 'omitnan')); |
122 | | - MRS_struct.out.QA.CNR(ii) = abs(mean(WMvol_thresh, 'omitnan') - mean(GMvol_thresh, 'omitnan')) / ... |
123 | | - sqrt(var(airvol_thresh, 'omitnan') + var(WMvol_thresh, 'omitnan') + var(GMvol_thresh, 'omitnan')); |
124 | | - |
| 105 | + |
| 106 | + WM_vol_tmp = WM_vol.private.dat(:,:,:); |
| 107 | + WM_vol_tmp(WM_vol_tmp < prob_threshold) = 0; |
| 108 | + T1_WM = WM_vol_tmp .* T1_tmp; |
| 109 | + T1_WM = T1_WM(:); |
| 110 | + T1_WM = T1_WM(T1_WM > 0); % include only nonzero voxels |
| 111 | + |
| 112 | + GM_vol_tmp = GM_vol.private.dat(:,:,:); |
| 113 | + GM_vol_tmp(GM_vol_tmp < prob_threshold) = 0; |
| 114 | + T1_GM = GM_vol_tmp .* T1_tmp; |
| 115 | + T1_GM = T1_GM(:); |
| 116 | + T1_GM = T1_GM(T1_GM > 0); |
| 117 | + |
| 118 | + CSF_vol_tmp = CSF_vol.private.dat(:,:,:); |
| 119 | + CSF_vol_tmp(CSF_vol_tmp < prob_threshold) = 0; |
| 120 | + T1_CSF = CSF_vol_tmp .* T1_tmp; |
| 121 | + T1_CSF = T1_CSF(:); |
| 122 | + T1_CSF = T1_CSF(T1_CSF > 0); |
| 123 | + |
| 124 | + BG_vol_tmp = BG_vol.private.dat(:,:,:); |
| 125 | + BG_vol_tmp(BG_vol_tmp < prob_threshold) = 0; |
| 126 | + T1_BG = BG_vol_tmp .* T1_tmp; |
| 127 | + T1_BG = T1_BG(:); |
| 128 | + T1_BG = T1_BG(T1_BG > 0); |
| 129 | + |
| 130 | + head_vol_tmp = 1 - BG_vol.private.dat(:,:,:); |
| 131 | + head_vol_tmp(head_vol_tmp < prob_threshold) = 0; |
| 132 | + T1_head = head_vol_tmp .* T1_tmp; |
| 133 | + T1_head = T1_head(:); |
| 134 | + T1_head = T1_head(T1_head > 0); |
| 135 | + |
| 136 | + MRS_struct.out.QA.CV.WM(ii) = mad(T1_WM,1) / median(T1_WM); |
| 137 | + MRS_struct.out.QA.CV.GM(ii) = mad(T1_GM,1) / median(T1_GM); |
| 138 | + MRS_struct.out.QA.CV.CSF(ii) = mad(T1_CSF,1) / median(T1_CSF); |
| 139 | + MRS_struct.out.QA.CJV(ii) = (mad(T1_WM,1) + mad(T1_GM,1)) / abs(median(T1_WM) - median(T1_GM)); |
| 140 | + MRS_struct.out.QA.CNR(ii) = abs(median(T1_WM) - median(T1_GM)) / sqrt(std(T1_WM).^2 + std(T1_GM).^2 + std(T1_BG).^2); |
| 141 | + |
125 | 142 | T1_tmp = T1_tmp(:); |
126 | 143 | n_vox = numel(T1_tmp); |
127 | 144 | efc_max = n_vox * (1/sqrt(n_vox)) * log(1/sqrt(n_vox)); |
128 | 145 | b_max = sqrt(sum(T1_tmp.^2)); |
129 | | - MRS_struct.out.QA.EFC(ii) = (1/efc_max) .* sum((T1_tmp ./ b_max) .* log((T1_tmp + eps) ./ b_max)); |
130 | | - |
| 146 | + MRS_struct.out.QA.EFC(ii) = (1/efc_max) .* sum((T1_tmp / b_max) .* log((T1_tmp + eps) / b_max)); |
| 147 | + |
| 148 | + MRS_struct.out.QA.FBER(ii) = median(abs(T1_head).^2) / median(abs(T1_BG).^2); |
| 149 | + MRS_struct.out.QA.WM2MAX(ii) = median(T1_WM) / prctile(T1_tmp, 99.95); |
| 150 | + |
| 151 | + MRS_struct.out.QA.SNR.WM(ii) = median(T1_WM) / (std(T1_WM) * sqrt(numel(T1_WM) / (numel(T1_WM) - 1))); |
| 152 | + MRS_struct.out.QA.SNR.GM(ii) = median(T1_GM) / (std(T1_GM) * sqrt(numel(T1_GM) / (numel(T1_GM) - 1))); |
| 153 | + MRS_struct.out.QA.SNR.CSF(ii) = median(T1_CSF) / (std(T1_CSF) * sqrt(numel(T1_CSF) / (numel(T1_CSF) - 1))); |
| 154 | + MRS_struct.out.QA.SNR.total(ii) = mean([MRS_struct.out.QA.SNR.WM(ii) MRS_struct.out.QA.SNR.GM(ii) MRS_struct.out.QA.SNR.CSF(ii)]); |
| 155 | + |
| 156 | + MRS_struct.out.QA.SNR_D.WM(ii) = median(T1_WM) / (sqrt(2 / (4 - pi)) * mad(T1_BG,1)); |
| 157 | + MRS_struct.out.QA.SNR_D.GM(ii) = median(T1_GM) / (sqrt(2 / (4 - pi)) * mad(T1_BG,1)); |
| 158 | + MRS_struct.out.QA.SNR_D.CSF(ii) = median(T1_CSF) / (sqrt(2 / (4 - pi)) * mad(T1_BG,1)); |
| 159 | + MRS_struct.out.QA.SNR_D.total(ii) = mean([MRS_struct.out.QA.SNR_D.WM(ii) MRS_struct.out.QA.SNR_D.GM(ii) MRS_struct.out.QA.SNR_D.CSF(ii)]); |
| 160 | + |
131 | 161 | % Loop over voxels if PRIAM |
132 | 162 | for kk = 1:length(vox) |
133 | | - |
134 | | - voxmaskvol = spm_vol(cell2mat(MRS_struct.mask.(vox{kk}).fname(ii))); |
135 | | - [a,b,c] = fileparts(voxmaskvol.fname); |
136 | | - |
| 163 | + |
| 164 | + vox_mask_vol = spm_vol(cell2mat(MRS_struct.mask.(vox{kk}).fname(ii))); |
| 165 | + [a,b,c] = fileparts(vox_mask_vol.fname); |
| 166 | + |
137 | 167 | % GM |
138 | | - O_GMvox.fname = fullfile(a, [b '_GM' c]); |
139 | | - O_GMvox.descrip = 'MRS_voxel_mask_GM'; |
140 | | - O_GMvox.dim = voxmaskvol.dim; |
141 | | - O_GMvox.dt = voxmaskvol.dt; |
142 | | - O_GMvox.mat = voxmaskvol.mat; |
143 | | - GM_voxmask_vol = GMvol.private.dat(:,:,:) .* voxmaskvol.private.dat(:,:,:); |
144 | | - O_GMvox = spm_write_vol(O_GMvox, GM_voxmask_vol); |
| 168 | + GM_vox.fname = fullfile(a, [b '_GM' c]); |
| 169 | + GM_vox.descrip = 'MRS_voxel_mask_GM'; |
| 170 | + GM_vox.dim = vox_mask_vol.dim; |
| 171 | + GM_vox.dt = vox_mask_vol.dt; |
| 172 | + GM_vox.mat = vox_mask_vol.mat; |
| 173 | + GM_vox_mask_vol = GM_vol.private.dat(:,:,:) .* vox_mask_vol.private.dat(:,:,:); |
| 174 | + GM_vox = spm_write_vol(GM_vox, GM_vox_mask_vol); |
145 | 175 |
|
146 | 176 | % WM |
147 | | - O_WMvox.fname = fullfile(a, [b '_WM' c]); |
148 | | - O_WMvox.descrip = 'MRS_voxel_mask_WM'; |
149 | | - O_WMvox.dim = voxmaskvol.dim; |
150 | | - O_WMvox.dt = voxmaskvol.dt; |
151 | | - O_WMvox.mat = voxmaskvol.mat; |
152 | | - WM_voxmask_vol = WMvol.private.dat(:,:,:) .* voxmaskvol.private.dat(:,:,:); |
153 | | - O_WMvox = spm_write_vol(O_WMvox, WM_voxmask_vol); |
| 177 | + WM_vox.fname = fullfile(a, [b '_WM' c]); |
| 178 | + WM_vox.descrip = 'MRS_voxel_mask_WM'; |
| 179 | + WM_vox.dim = vox_mask_vol.dim; |
| 180 | + WM_vox.dt = vox_mask_vol.dt; |
| 181 | + WM_vox.mat = vox_mask_vol.mat; |
| 182 | + WM_vox_mask_vol = WM_vol.private.dat(:,:,:) .* vox_mask_vol.private.dat(:,:,:); |
| 183 | + WM_vox = spm_write_vol(WM_vox, WM_vox_mask_vol); |
154 | 184 |
|
155 | 185 | % CSF |
156 | | - O_CSFvox.fname = fullfile(a, [b '_CSF' c]); |
157 | | - O_CSFvox.descrip = 'MRS_voxel_mask_CSF'; |
158 | | - O_CSFvox.dim = voxmaskvol.dim; |
159 | | - O_CSFvox.dt = voxmaskvol.dt; |
160 | | - O_CSFvox.mat = voxmaskvol.mat; |
161 | | - CSF_voxmask_vol = CSFvol.private.dat(:,:,:) .* voxmaskvol.private.dat(:,:,:); |
162 | | - O_CSFvox = spm_write_vol(O_CSFvox, CSF_voxmask_vol); |
| 186 | + CSF_vox.fname = fullfile(a, [b '_CSF' c]); |
| 187 | + CSF_vox.descrip = 'MRS_voxel_mask_CSF'; |
| 188 | + CSF_vox.dim = vox_mask_vol.dim; |
| 189 | + CSF_vox.dt = vox_mask_vol.dt; |
| 190 | + CSF_vox.mat = vox_mask_vol.mat; |
| 191 | + CSF_vox_mask_vol = CSF_vol.private.dat(:,:,:) .* vox_mask_vol.private.dat(:,:,:); |
| 192 | + CSF_vox = spm_write_vol(CSF_vox, CSF_vox_mask_vol); |
163 | 193 |
|
164 | 194 | % 3. Calculate a CSF-corrected i.u. value and output it to the structure |
165 | 195 |
|
166 | | - GMsum = sum(sum(sum(O_GMvox.private.dat(:,:,:)))); |
167 | | - WMsum = sum(sum(sum(O_WMvox.private.dat(:,:,:)))); |
168 | | - CSFsum = sum(sum(sum(O_CSFvox.private.dat(:,:,:)))); |
169 | | - |
170 | | - fGM = GMsum / (GMsum + WMsum + CSFsum); |
171 | | - fWM = WMsum / (GMsum + WMsum + CSFsum); |
172 | | - fCSF = CSFsum / (GMsum + WMsum + CSFsum); |
173 | | - |
| 196 | + GM_vox_n = GM_vox.private.dat(:,:,:); |
| 197 | + GM_sum = sum(GM_vox_n(GM_vox_n > prob_threshold)); |
| 198 | + WM_vox_n = WM_vox.private.dat(:,:,:); |
| 199 | + WM_sum = sum(WM_vox_n(WM_vox_n > prob_threshold)); |
| 200 | + CSF_vox_n = CSF_vox.private.dat(:,:,:); |
| 201 | + CSF_sum = sum(CSF_vox_n(CSF_vox_n > prob_threshold)); |
| 202 | + |
| 203 | + fGM = GM_sum / (GM_sum + WM_sum + CSF_sum); |
| 204 | + fWM = WM_sum / (GM_sum + WM_sum + CSF_sum); |
| 205 | + fCSF = CSF_sum / (GM_sum + WM_sum + CSF_sum); |
| 206 | + |
174 | 207 | MRS_struct.out.(vox{kk}).tissue.fGM(ii) = fGM; |
175 | 208 | MRS_struct.out.(vox{kk}).tissue.fWM(ii) = fWM; |
176 | 209 | MRS_struct.out.(vox{kk}).tissue.fCSF(ii) = fCSF; |
|
247 | 280 | end |
248 | 281 |
|
249 | 282 | % Plot segmented voxel as a montage |
250 | | - MRS_struct.mask.(vox{kk}).img_montage{ii} = PlotSegmentedVoxels(struc, voxoff, voxmaskvol, O_GMvox, O_WMvox, O_CSFvox); |
| 283 | + MRS_struct.mask.(vox{kk}).img_montage{ii} = PlotSegmentedVoxels(struc, voxoff, vox_mask_vol, GM_vox, WM_vox, CSF_vox); |
251 | 284 |
|
252 | 285 | if strcmp(MRS_struct.p.vendor,'Siemens_rda') |
253 | 286 | [~,tmp,tmp2] = fileparts(MRS_struct.metabfile{ii*2-1}); |
|
348 | 381 | end |
349 | 382 |
|
350 | 383 |
|
351 | | -function img_montage = PlotSegmentedVoxels(struc, voxoff, voxmaskvol, O_GMvox, O_WMvox, O_CSFvox) |
| 384 | +function img_montage = PlotSegmentedVoxels(struc, voxoff, vox_mask_vol, GM_vox, WM_vox, CSF_vox) |
352 | 385 |
|
353 | 386 | img_t = flipud(voxel2world_space(spm_vol(struc), voxoff)); |
354 | | -mask_t = flipud(voxel2world_space(voxmaskvol, voxoff)); |
355 | | -mask_t_GM = flipud(voxel2world_space(O_GMvox, voxoff)); |
356 | | -mask_t_WM = flipud(voxel2world_space(O_WMvox, voxoff)); |
357 | | -mask_t_CSF = flipud(voxel2world_space(O_CSFvox, voxoff)); |
| 387 | +mask_t = flipud(voxel2world_space(vox_mask_vol, voxoff)); |
| 388 | +mask_t_GM = flipud(voxel2world_space(GM_vox, voxoff)); |
| 389 | +mask_t_WM = flipud(voxel2world_space(WM_vox, voxoff)); |
| 390 | +mask_t_CSF = flipud(voxel2world_space(CSF_vox, voxoff)); |
358 | 391 |
|
359 | 392 | w_t = zeros(size(img_t)); |
360 | 393 |
|
|
0 commit comments