Contents
introduction
% s_SDnDTI_designBvec4AcquiredData.m % % A script for selecting diffusion encoding directions for SDnDTI from % acquired data with given diffusion encoding directions (e.g., 30 out of % 90 directions). % % Source code: % https://github.com/qiyuantian/SDnDTI/blob/main/s_SDnDTI_designBvec4AcquiredData.m % % HTML file can be automatically generaged using command: % publish('s_SDnDTI_designBvec4AcquiredData.m', 'html'); % % Reference: % [1] Tian Q, Li Z, Fan Q, Polimeni JR, Bilgic B, Salat DH, Huang SY. % SDnDTI: Self-supervised deep learning-based denoising for diffusion % tensor MRI. NeuroImage, 2022; 253: 119033. % % (c) Qiyuan Tian, Harvard, 2022
load bvecs from Human Connectome Project
clear, clc, close all bvals_all = dlmread('hcp_bval.txt'); % all bvals bvecs_all = dlmread('hcp_bvec.txt'); % all bvecs bvals_all = round(bvals_all / 100) * 100; disp(unique(bvals_all)); dirs = bvecs_all(bvals_all > 100 & bvals_all < 1500, :); % only use bvecs for b=1000 dirs_vis = dirs .* sign(dirs(:, 3)); % directions flipped to z > 0 for visualization figure; % display diffusion encoding directions, all flipped to z > 0 plot3(dirs_vis(:, 1), dirs_vis(:, 2), dirs_vis(:, 3), '.'); grid on, axis equal zlim([-1, 1]) title('90 diffusion encoding directions');
0 1000 2000 3000
select all sets of 6 encoding directions optimal for tensor fitting
% 6 optimized directions from the DSM scheme that minimizes the condition % number of the diffusion tensor transformation matrix % from S Skare et al., J Magn Reson. 2000;147(2):340-52 % 10, 20, 30 (dsm10.m, dsm20.m, dsm30.m) or more directions should be used for % very noisy data dsm6 = [0.91, 0.416, 0; ... 0, 0.91, 0.416; ... 0.416, 0, 0.91; ... 0.91, -0.416, 0; ... 0, 0.91, -0.416; ... -0.416, 0, 0.91]; dsm6_norm = dsm6 ./ sqrt(dsm6(:, 1) .^ 2 + dsm6(:, 2) .^ 2 + dsm6(:, 3) .^ 2); % normalize vectors % randomly rotate the DSM6 dirs, select their nearest 6 dirs from acquired % dirs, keep those with low condition number % selected dirs are not perfectly DSM6 dirs, so condition number might be % large, which is not optimal for tensor fitting and amplifies noise, which % is especially a problem for a small number of encoding directions (e.g., % lower than 60) rotang_all = []; condnum_all = []; ind_all = []; for ii = 1 : 100000 % number of iterations can be increased rotangs = rand(1, 3) * 2 * pi; % random angles to rotate around x, y, z axis R = rot3d(rotangs); % rotation matrix dsm6_rot = (R * dsm6_norm')'; % roated directions % find 6 nearest dirs in acquired dirs angerrors = acosd(abs(dsm6_rot * dirs')); % angles btw rotated DSM6 dirs and acquired dirs [minerrors, ind] = min(angerrors, [], 2); % 6 dirs with min angles compared to rotated DSM6 dirs condnum = cond(amatrix(dirs(ind, :))); % cond number of tensor tx matrix of selected dirs % only use dirs with low cond number if condnum < 1.6 % threshold should be determined based on given data, 1.6 is good in our experience if isempty(ind_all) || ~any(sum(ind_all == sort(ind'), 2) == 6) % make sure no repetition % record params for satisfied sets condnum_all = cat(1, condnum_all, condnum); ind_all = cat(1, ind_all, sort(ind')); rotang_all = cat(1, rotang_all, rotangs); end end end disp(size(ind_all, 1)) for ii = 1 : 2 figure; % display two selected sets of 6 optimal directions plot3(dirs_vis(:, 1), dirs_vis(:, 2), dirs_vis(:, 3), '.'); % all dirs hold on visdirs_use = dirs_vis(ind_all(ii, :), :); plot3(visdirs_use(:, 1), visdirs_use(:, 2), visdirs_use(:, 3), 'o'); % selected dirs R = rot3d(rotang_all(ii, :)); dsm6_rot = (R * dsm6_norm')'; dsm6_rot_vis = dsm6_rot .* sign(dsm6_rot(:, 3)); plot3(dsm6_rot_vis(:, 1), dsm6_rot_vis(:, 2), dsm6_rot_vis(:, 3), 'x'); % rotated DSM6 dirs grid on, axis equal xlim([-1, 1]) ylim([-1, 1]) zlim([-1, 1]) title(['cond num=' num2str(condnum_all(ii))]); end
21
select N sets out of all selected sets of 6 dirs
% directions from all sets are uniformly distributed on z>0 hemisphere % (since v and -v are identical for diffusion encoding) to maximize angular % coverage as well as on whole sphere N = 3; % select 3 sets as an example, so in total of 3x6=18 dirs bvecs_hemi = []; % designed diffusion encoding directions unif_min = 10^10; % init using a large number ind_min = []; for ii = 1 : 100000 % number of iterations can be increased for better results r = randperm(size(ind_all, 1), N); ind = ind_all(r, :); dirs_all = dirs(ind(:), :); % all 30 directions % [v; -v] is used for optimization such that v is uniformly distributed % on z>0 hemisphere dirs_tmp = [dirs_all; -dirs_all]; % uniformly distributed directions have lowest electrostatic potential energy % details see Jones Magn. Reson. Med., 51 (2004), pp. 807-815 unif = potentialenergy(dirs_tmp); % uniformity of all 30 directions if unif < unif_min % keep new directions if uniformity is better unif_min = unif; bvecs_hemi = dirs_all; ind_min = ind; disp(unif_min) end end n = size(bvecs_hemi, 1) / N; figure for ii = 1 : N idxs = (ii - 1) * n + 1; idxe = ii * n; bvecs_vis = bvecs_hemi(idxs:idxe, :); tmp = sign(bvecs_vis(:, 3)); tmp(tmp == 0) = 1; bvecs_vis = bvecs_vis .* tmp; % flip dirs with z<0 to z>0 plot3(bvecs_vis(:, 1), bvecs_vis(:, 2), bvecs_vis(:, 3), '.'); % each color represents a set hold on end grid on, axis equal xlim([-1, 1]) ylim([-1, 1]) zlim([-1, 1]) title('bvecs are uniform on both hemi and whole sphere'); figure for ii = 1 : N idxs = (ii - 1) * n + 1; idxe = ii * n; bvecs_vis = bvecs_hemi(idxs:idxe, :); tmp = sign(bvecs_vis(:, 3)); tmp(tmp == 0) = 1; bvecs_vis = bvecs_vis .* tmp; % flip dirs with z<0 to z>0 plot3(bvecs_vis(:, 1), bvecs_vis(:, 2), bvecs_vis(:, 3), 'o'); % each color represents a set hold on end plot3(dirs_vis(:, 1), dirs_vis(:, 2), dirs_vis(:, 3), 'k.'); grid on, axis equal xlim([-1, 1]) ylim([-1, 1]) zlim([-1, 1]) title('selected directions out of all directions');
1.0061e+03 996.6677 995.7374 995.0967 993.7528 989.3878
DeepDTI pipeline
% subsequent data preparation and CNN training and application follows DeepDTI % see codes here: https://github.com/qiyuantian/DeepDTI % diffusion weighted images (DWIs) from each set, which are optimal for % diffusion tensor fitting, serve as input for CNNs % DWIs from all sets serve as target of CNNs