-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathCreatePredictedDiffusionNifti.m
More file actions
222 lines (163 loc) · 7.93 KB
/
CreatePredictedDiffusionNifti.m
File metadata and controls
222 lines (163 loc) · 7.93 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
function CreatePredictedDiffusionNifti
%% Use Franco's example data
try lifeDemoDataPath
catch
error('Add life data to your path');
end
%% Build the file names for the diffusion data, the anatomical MRI.
% Here are the original dMRI data
dwiFile = fullfile(lifeDemoDataPath('diffusion'),'life_demo_scan1_subject1_b2000_150dirs_stanford.nii.gz');
dwiFileRepeat = fullfile(lifeDemoDataPath('diffusion'),'life_demo_scan2_subject1_b2000_150dirs_stanford.nii.gz');
t1File = fullfile(lifeDemoDataPath('anatomy'), 'life_demo_anatomy_t1w_stanford.nii.gz');
%% Create dwi structure
nifti = niftiRead(dwiFile);
bvecs = dlmread(fullfile(lifeDemoDataPath('diffusion'),'life_demo_scan1_subject1_b2000_150dirs_stanford.bvecs'));
bvals = dlmread(fullfile(lifeDemoDataPath('diffusion'),'life_demo_scan1_subject1_b2000_150dirs_stanford.bvals'));
dwi = dwiCreate('nifti',nifti,'bvecs',bvecs','bvals',bvals');
%% Take the first 10 fibers from the fiber group
% This is intended to run quickly
fgFileName = fullfile(lifeDemoDataPath('tractography'), ...
'life_demo_mrtrix_csd_lmax10_probabilistic.mat');
fg = fgRead(fgFileName);
small_fg = fgCreate('name', ['small_' fg.name], 'fibers', fg.fibers(1:10));
small_fg.pathwayInfo = fg.pathwayInfo(1:10);
% fgWrite(small_fg, fullfile(lifeDemoDataPath('diffusion'), 'small_fg.mat'));
clear fg
% transform coordinates in image space form acpc
small_fg_img = dtiXformFiberCoords(small_fg, inv(dwi.nifti.qto_xyz), 'img');
% img_coords = horzcat(small_fg_img.fibers{:});
% img_coords2 = horzcat(fe.fg.fibers{:}); These are identical
%% Build a model of the connectome.
%
% Running with the issue2 branch on LiFE
%
% If we don't need fiber weights, we can skip this
feFileName = 'life_build_model_demo_CSD_PROB_small';
fe = feConnectomeInit(dwiFile, small_fg, feFileName,fullfile(fileparts(fgFileName)),dwiFileRepeat,t1File);
%% Fit the model with global weights.
fe = feSet(fe,'fit',feFitModel(feGet(fe,'mfiber'),feGet(fe,'dsigdemeaned'),'bbnnls'));
%% the weights from the LiFE solution
wgts = feGet(fe,'fiber weights');
%% Make an empty nifti file the same size as the original
% pNifti = niftiCreate;
pData = zeros(size(nifti.data));
% duplicate original nifti structure
pNifti = nifti;
pNifti.data = pData;
% strip .extension
[p,f] = fileparts(pNifti.fname);
[~,f] = fileparts(f);
newFname = [p,f,'_Predicted.nii.gz'];
% give name to pNifti
pNifti.fname = newFname;
%% Compute the diffusion tensors for each node in each fiber
% The direction at the node is the average direction between this node and
% each of its neighbors% Isotropic portion of M matrix. Returns the matrix for the full model or
% The diagonal parameters are for a perfect stick, [1 0 0]
Q = feComputeCanonicalDiffusion(small_fg_img.fibers, [1 0 0]); % Q = feGet(fe,''fibers tensors');
% Q = feComputeCanonicalDiffusion_voxel(img_coords, [1 0 0]);
%% Add diffusion signal for each fiber coordinate
% We are not sure about which coordinate is the xyz
% We are not sure how to get the S0 value out of the b=0 (non-diffusion
% weighted) image
%% Please explain
fe_bvecs2 = bvecs'; %feGet(fe,'bvecs');
fe_bvals2 = bvals'./1000; %feGet(fe,'bvals');
%% Comupute prediction diffusion signals
for ii = 1:length(small_fg_img.fibers);
% These coordinates are within the first fiber, and thus the connectome
% This is an N x 3 matrix of integers, needed by feGet.
% This way of getting the fiber coordinates matches the coordinates in the
% ROI. But it is obviously ridiculous and if we have to have a difference
% in the coordinate frames, then there has to be a roi2fg() coordinate
% transform. We can't write code like this everywhere.
fCoords = ((uint32(ceil(small_fg_img.fibers{ii})))+1)';
% take S0 image
S0 = dwiGet(dwi,'b0 image',fCoords); % S0_All = fe.diffusion_S0_img;
% Compute predicted diffusion direction in each voxel
for jj = 1:length(fCoords)
% For each fiber coordinate create a predicted signal. Here is the
% fiber tensor at that coordinate
voxTensor = Q{ii}(jj,:);
% Add the new signal to the current signals at that coordinate
curSig = pData(fCoords(jj,1),fCoords(jj,2),fCoords(jj,3),1:length(fe_bvecs2));
newSig = wgts(ii)*feComputeSignal(S0(jj), fe_bvecs2, fe_bvals2, voxTensor);
% Store back in
pData(fCoords(jj,1),fCoords(jj,2),fCoords(jj,3),1:length(fe_bvecs2)) = ...
squeeze(curSig) + newSig;
% BW to make the visualization work ... also, look over dwiSet/Get/Create
%
% tmp = feComputeSignal(S0(jj), fe_bvecs2, fe_bvals2, voxTensor);
% dwi2 = dwiSet(dwi,'sig',tmp);
% mrvNewGraphWin; dwiPlot(dwi2,'adc',tmp(11:end),reshape(voxTensor,3,3))
% dwiPlot(dwi2,'dsig image xy',tmp)
% pData(fCoords(jj,1),fCoords(jj,2),fCoords(jj,3),1:length(fe_bvecs2)) =...
% wgts(ii)*feComputeSignal(S0(jj), fe_bvecs2, fe_bvals2, voxTensor);
% For the moment we are keeping everything, but we may not have to
% do this in the long run.
% OK, keep PSig based on fiber and voxel
% The empty slots have no fibers.
% The other slots of 106 diffusion signals predicted
PSig_voxel{ii,jj} = newSig;
end
clear S0
end
%% Franco did get the pSig like this
% Predicted measured signal from both fiber and iso
%
% pSig = feGet(fe,'pSig full')
% pSig = feGet(fe,'pSig full',coords)
% pSig = feGet(fe,'pSig full',voxelIndices)
val = [feGet(fe,'M fiber'), feGet(fe,'M iso')] * feGet(fe,'full weights');
Mfiber = full(feGet(fe,'M fiber')); Miso = full(feGet(fe,'M iso'));
combine = [ Mfiber, Miso];
%%
if ~isempty(varargin)
% voxelIndices = feGet(fe,'voxelsindices',varargin);
% voxelRowsToKeep = feGet(fe,'voxel rows',voxelIndices);
% val = val(voxelRowsToKeep,:);
val = val(feGet(fe,'voxel rows',feGet(fe,'voxelsindices',varargin)));
end
%% Put pSig in nifti structure
pNifti = niftiSet(pNifti,'data',pData);
% save the nifti file
if save_flag,
niftiWrite(pNifti, pNifti.fname)
end
% Let's figure out how to see what we created in the pNifti data set.
return
%% EXTRA REMOVE SOME DAY
%% 96 diffusion direction only
fe_bvecs = feGet(fe,'bvecs');
fe_bvals = bvals(dwi.bvals ~= 0)'./1000; %feGet(fe,'bvals');
for ii = 1:length(fe.fg.fibers);
% These coordinates are within the first fiber, and thus the connectome
% This is an N x 3 matrix of integers, needed by feGet.
% This way of getting the fiber coordinates matches the coordinates in the
% ROI. But it is obviously ridiculous and if we have to have a difference
% in the coordinate frames, then there has to be a roi2fg() coordinate
% transform. We can't write code like this everywhere.
fCoords = ((uint32(ceil(fe.fg.fibers{ii})))+1)';
% take S0 image
S0 = dwiGet(dwi,'b0 image',fCoords); % S0_All = fe.diffusion_S0_img;
% keep indices of the coords in img space.
indx = sub2ind(dwi.nifti.dim(1:3),fCoords(:,1),fCoords(:,2),fCoords(:,3));
for jj = 1:length(S0)
% Once we get the S0 values for this particular voxel, we can compute
voxTesorQ = Q{ii}(jj,:);
% voxTesorQ = feGet(fe,'voxel tensors',foundVoxels(jj));
% TensorVoxel = dwiGet(dwi,'tensor image', fCoords(jj,:)); ??
PSig_voxel{ii,jj} = feComputeSignal(S0(jj), fe_bvecs, fe_bvals, voxTesorQ);
end
clear S0, clear indx
end
%% ---------
% Fiber density statistics.
% Computes the fiber density (how many fibers in each voxel)
% We compute the following values:
% (1) The number of fibers in each voxel
% (2) The number of unique fibers with non-zero weights
% (3) The sum of the weights in each voxel
% (4) The mean of the weights in each voxel
% (5) The variance of the weigths in each voxel
FiberStats = feGet(fe,'fiberdensity');