DMRITool  v0.1.1-139-g860d86b4
Diffusion MRI Tool
itkSamplingSchemeQSpace1OptEstimationFilter.hxx
Go to the documentation of this file.
1 
13 #ifndef __itkSamplingSchemeQSpace1OptEstimationFilter_hxx
14 #define __itkSamplingSchemeQSpace1OptEstimationFilter_hxx
15 
17 #include "utl.h"
18 
19 namespace itk
20 {
21 
22 template< class TSamplingType >
25  : Superclass(),
26  m_FineOrientations(new MatrixType())
27 {
28  m_TessellationOrder = 7;
29  m_FineScheme = SamplingType::New();
30 }
31 
32 template< class TSamplingType >
33 void
36 {
37  if (this->m_FineScheme->GetNumberOfSamples()==0)
38  {
39  if (this->m_FineOrientations->Size()==0)
40  this->m_FineOrientations = utl::ReadGrad<double>(this->m_TessellationOrder, DIRECTION_NODUPLICATE, CARTESIAN_TO_CARTESIAN); // catesian
41  m_FineScheme->SetOrientationsCartesian(m_FineOrientations);
42  }
43 
44  utlGlobalException(!this->IsSetInitialization(), "Need to set m_InitialOrientations for initialization!");
45 
46  this->m_OutputOrientations = this->m_InitialOrientations->Clone();
47 
48  Index2DVectorPointer indices = this->m_OutputOrientations->GetIndicesInShells();
49  this->m_NumbersInShell.resize(indices->size());
50  for ( int i = 0; i < indices->size(); ++i )
51  {
52  this->m_NumbersInShell[i] = ((*indices)[i].size());
53  }
54 
55 }
56 
57 
58 template< class TSamplingType >
59 void
62 {
63  Initialization();
64 
65  SamplingPointer output = this->GetOutputOrientations();
66  Index2DVectorPointer indices = output->GetIndicesInShells();
67  unsigned int numberOfSamples = output->GetNumberOfSamples();
68  unsigned int N = m_FineScheme->GetNumberOfSamples();
69  MatrixPointer outputMatrix = output->GetOrientationsCartesian();
70  unsigned int numberOfShells = this->m_NumbersInShell.size();
71 
72  std::vector<char> hasChosen(N, 0);
73  std::vector<int> chosenIndex;
74 
75 
76  if (numberOfShells==1)
77  {
78 
79  MatrixType dotMat;
80  Index2DVectorType indexNear2(N);
81  STDVectorType dotVec(numberOfSamples);
82 
83  for ( int k = 0; k < numberOfSamples; ++k )
84  {
85  dotVec[k] = output->CalculateMaxDot(k, true);
86  }
87 
88  dotMat = (*output->GetOrientationsCartesian()) * m_FineScheme->GetOrientationsCartesian()->GetTranspose();
89  dotMat = utl::Abs(dotMat);
90 
91  bool has1Opt=true;
92  double dotMax_k=0, dotMax_k2=0;
93 
94  do
95  {
96  double minDot = 100;
97  int index_j=-1, index_k=-1;
98 
99  IndexVectorType index2(2,-1);
100  for ( int i = 0; i < N; ++i )
101  {
102  if (hasChosen[i]>0)
103  continue;
104  utl::Vector<double> vec = dotMat.GetColumn(i);
105  utl::argmax2(vec, vec.Size(), index2[0], index2[1]);
106  indexNear2[i] = index2;
107  }
108  // for ( int i= 0; i < N; ++i )
109  // {
110  // utl::PrintVector(indexNear2[i], "", " ", std::cout<<"indexNear2[" <<i<<"]");
111  // utlPrintVar(true, std::acos(dotMat(indexNear2[i][0],i)), std::acos(dotMat(indexNear2[i][1],i)));
112  // }
113 
114  for ( unsigned int k = 0; k < numberOfSamples; k += 1 )
115  {
116  double dot_k=dotVec[k];
117 
118  for ( unsigned int j = 0; j < N; j += 1 )
119  {
120  if (hasChosen[j]>0)
121  continue;
122  // utlPrintVar(true, j, k);
123  // PointType p = (*this->m_FineScheme)[j];
124  double dot_k2=-1;
125 
126  int index2_0 = indexNear2[j][0];
127  int index2_1 = indexNear2[j][1];
128  if (index2_0!=k)
129  dot_k2 = dotMat(index2_0,j);
130  else
131  dot_k2 = dotMat(index2_1,j);
132 
133  if (dot_k2<dot_k)
134  {
135  if (minDot>dot_k2)
136  {
137  minDot=dot_k2;
138  index_j = j;
139  index_k = k;
140  dotMax_k = dot_k;
141  dotMax_k2 = dot_k2;
142  }
143  }
144  // (*output)[k] = p1;
145  }
146  }
147 
148  if (index_j>=0 && index_k>=0)
149  {
150  utlPrintVar(utl::IsLogDebug(), index_j, index_k, std::acos(dotMax_k), std::acos(dotMax_k2));
151  hasChosen[index_j] = 1;
152  (*output)[index_k] = (*this->m_FineScheme)[index_j];
153  // dotVec[index_k] = dotMax_k2;
154  for ( int k = 0; k < numberOfSamples; ++k )
155  {
156  dotVec[k] = output->CalculateMaxDot(k, true);
157  }
158 
159 
160  PointType p1 = (*output)[index_k];
161  for ( int i = 0; i < N; ++i )
162  {
163  if (hasChosen[i]>0)
164  continue;
165  PointType p2 = (*this->m_FineScheme)[i];
166  double dotTmp = p1[0]*p2[0] + p1[1]*p2[1] + p1[2]*p2[2];
167  if (dotTmp<0)
168  dotTmp = -dotTmp;
169  dotMat(index_k, i) = dotTmp;
170  }
171 
172  // dotMat = (*output->GetOrientationsCartesian(true)) * m_FineScheme->GetOrientationsCartesian()->GetTranspose();
173  // dotMat = utl::Abs(dotMat);
174  // dotMat = utl::Acos(utl::Abs(dotMat));
175 
176  }
177  else
178  has1Opt=false;
179 
180  } while ( has1Opt );
181 
182  }
183  else
184  {
185  std::vector<MatrixType> dotMat(numberOfShells+1);
186  std::vector<Index2DVectorType> indexNear2(numberOfShells+1, Index2DVectorType(N));
187 
188  for ( int s = 0; s < numberOfShells; ++s )
189  {
190  utl::ProductUtlMMt(*output->GetOrientationsCartesianInShell(s), *m_FineScheme->GetOrientationsCartesian(), dotMat[s]);
191  dotMat[s] = utl::Abs(dotMat[s]);
192  }
193  utl::ProductUtlMMt(*output->GetOrientationsCartesian(), *m_FineScheme->GetOrientationsCartesian(), dotMat[numberOfShells]);
194  dotMat.back() = utl::Abs(dotMat.back());
195 
196  bool has1Opt=true;
197  STDVectorType dot_k(numberOfShells+1, -1);
198  STDVectorType dot_k2(numberOfShells+1, -1);
199  STDVectorType dotMax_k(numberOfShells+1, -1);
200  STDVectorType dotMax_k2(numberOfShells+1, -1);
201  double w0 = 1.0-this->m_WeightForSingleShell;
202  double ws = this->m_WeightForSingleShell/numberOfShells;
203 
204  do
205  {
206  STDVectorType minDot(numberOfShells+1, 100);
207  int index_s=-1, index_j=-1, index_k=-1;
208 
209  Index2DVectorPointer indices = output->GetIndicesInShells();
210 
211  IndexVectorType index2(2,-1);
212  for ( int s = 0; s < numberOfShells+1; ++s )
213  {
214  for ( int i = 0; i < N; ++i )
215  {
216  if (hasChosen[i]>0)
217  continue;
218  utl::Vector<double> vec = dotMat[s].GetColumn(i);
219  utl::argmax2(vec, vec.Size(), index2[0], index2[1]);
220  indexNear2[s][i] = index2;
221  }
222  }
223 
224  for ( int s = 0; s < numberOfShells; ++s )
225  {
226  for ( unsigned int k = 0; k < this->m_NumbersInShell[s]; k += 1 )
227  {
228  int ind = (*indices)[s][k];
229  dot_k[s] = output->CalculateMaxDotInShell(ind, s, true);
230  dot_k.back()= output->CalculateMaxDot(ind, true);
231 
232  for ( unsigned int j = 0; j < N; j += 1 )
233  {
234  if (hasChosen[j]>0)
235  continue;
236  // utlPrintVar(true, j, k);
237  // PointType p = (*this->m_FineScheme)[j];
238  // double dot_k2_s=-1, dot_k2=-1;
239 
240  int index2_0 = indexNear2[s][j][0];
241  int index2_1 = indexNear2[s][j][1];
242  if (index2_0!=k)
243  dot_k2[s] = dotMat[s](index2_0,j);
244  else
245  dot_k2[s] = dotMat[s](index2_1,j);
246 
247  index2_0 = indexNear2[numberOfShells][j][0];
248  index2_1 = indexNear2[numberOfShells][j][1];
249  if (index2_0!=ind)
250  dot_k2.back() = dotMat[numberOfShells](index2_0,j);
251  else
252  dot_k2.back() = dotMat[numberOfShells](index2_1,j);
253 
254  // utlPrintVar(utl::IsLogDebug(), j, s, k, dot_k[s], dot_k2[s], dot_k.back(), dot_k2.back());
255  // if ( w0*std::acos(dot_k2.back()) + ws*std::acos(dot_k2[s]) > w0*std::acos(dot_k.back()) + ws*std::acos(dot_k[s]))
256  if ( (dot_k2.back() <= dot_k.back() && dot_k2[s] < dot_k[s]) || (dot_k2.back() < dot_k.back() && dot_k2[s] <= dot_k[s]))
257  {
258  if ((minDot.back()>=dot_k2.back() && minDot[s]>dot_k2[s]) || (minDot.back()>dot_k2.back() && minDot[s]>=dot_k2[s]))
259  {
260  minDot.back()=dot_k2.back();
261  minDot[s]=dot_k2[s];
262  index_s = s;
263  index_j = j;
264  index_k = k;
265  if (utl::IsLogDebug())
266  {
267  dotMax_k = dot_k;
268  dotMax_k2 = dot_k2;
269  }
270  }
271  }
272  // (*output)[k] = p1;
273  }
274  }
275  }
276 
277  if (index_j>=0 && index_k>=0 && index_s>=0)
278  {
279  utlPrintVar(utl::IsLogDebug(), index_j, index_s, index_k, std::acos(dotMax_k[index_s]), std::acos(dotMax_k2[index_s]), std::acos(dotMax_k.back()), std::acos(dotMax_k2.back()));
280  hasChosen[index_j] = 1;
281  int ind = (*indices)[index_s][index_k];
282  (*output)[ind] = (*this->m_FineScheme)[index_j];
283  // dotVec[index_k] = dotMax_k2;
284 
285  // for ( int k = 0; k < numberOfSamples; ++k )
286  // {
287  // dotVec[k] = output->CalculateMaxDot(k, true);
288  // }
289 
290 
291  PointType p1 = (*output)[ind];
292  for ( int i = 0; i < N; ++i )
293  {
294  if (hasChosen[i]>0)
295  continue;
296  PointType p2 = (*this->m_FineScheme)[i];
297 
298  double dotTmp = p1[0]*p2[0] + p1[1]*p2[1] + p1[2]*p2[2];
299  if (dotTmp<0)
300  dotTmp = -dotTmp;
301  dotMat[numberOfShells](ind, i) = dotTmp;
302  dotMat[index_s](index_k, i) = dotTmp;
303  }
304 
305 
306  }
307  else
308  has1Opt=false;
309 
310  } while ( has1Opt );
311 
312  }
313 
314 }
315 
316 }
317 
318 
319 #endif
320 
321 
NDArray<T,1> is a vector class which uses blas mkl.
Definition: utlVector.h:36
void argmax2(const VectorType &vec, int size, int &index0, int &index1)
Definition: utlCore.h:234
helper functions specifically used in dmritool
bool IsLogDebug(const int level=utl::LogLevel)
Definition: utlCoreMacro.h:213
#define utlGlobalException(cond, expout)
Definition: utlCoreMacro.h:372
#define utlPrintVar(cond,...)
Definition: utlCoreMacro.h:309
base class for the filters to estimate the sampling scheme in Q-space
auto Abs(const ExprT &expr) -> decltype(utl::F< utl::Functor::Abs< typename ExprT::ValueType > >(expr))
Definition: utlFunctors.h:356
void ProductUtlMMt(const utl::NDArray< T, 2 > &A, const utl::NDArray< T, 2 > &B, utl::NDArray< T, 2 > &C, const double alpha=1.0, const double beta=0.0)
SizeType Size() const
Definition: utlNDArray.h:321