DMRITool  v0.1.1-139-g860d86b4
Diffusion MRI Tool
itkSamplingSchemeQSpaceIMOCEstimationFilter.hxx
Go to the documentation of this file.
1 
17 #ifndef __itkSamplingSchemeQSpaceIMOCEstimationFilter_hxx
18 #define __itkSamplingSchemeQSpaceIMOCEstimationFilter_hxx
19 
20 
22 #include "utl.h"
23 
24 #include <numeric>
25 
26 namespace itk
27 {
28 
29 template< class TSamplingType >
32  : Superclass(),
33  m_FineOrientations(new MatrixType())
34 {
35 }
36 
37 template< class TSamplingType >
38 void
41 {
42  // SamplingType* input = const_cast< SamplingType * >( this->GetInput() );
43  if (this->m_FineOrientations->Size()==0)
44  {
45  this->m_FineOrientations = utl::ReadGrad<double>(this->m_TessellationOrder, DIRECTION_NODUPLICATE, CARTESIAN_TO_CARTESIAN); // catesian
46  }
47  m_FineScheme->SetOrientationsCartesian(m_FineOrientations);
48  // utl::PrintUtlMatrix(*m_FineOrientations, "m_FineOrientations");
49 
50  // assume that m_FineScheme is uniformly distributed in sphere
51  m_MinDistanceInFineScheme = m_FineScheme->CalculateMinDistance(0,true);
52  m_MinDistanceInFineScheme = std::sqrt(2-2*std::cos(m_MinDistanceInFineScheme));
53 
54  // build kd tree
55  m_Sample = SampleType::New();
56  m_Sample->SetMeasurementVectorSize( 3 );
57  unsigned int numberOfSamples = m_FineOrientations->Rows();
59  for (unsigned int i = 0; i < numberOfSamples; ++i )
60  {
61  mv = (*m_FineScheme)[i];
62  m_Sample->PushBack( mv );
63  for ( int j = 0; j < 3; ++j )
64  mv[j] = -mv[j];
65  m_Sample->PushBack( mv );
66  }
67 
68  m_TreeGenerator = TreeGeneratorType::New();
69  m_TreeGenerator->SetSample( m_Sample );
70  m_TreeGenerator->SetBucketSize( 16 );
71  m_TreeGenerator->Update();
72 
73  // m_TreeGenerator->Print(std::cout<<"treeGenerator");
74  m_KDTree = m_TreeGenerator->GetOutput();
75 }
76 
77 template< class TSamplingType >
78 bool
80 ::IsSatisfiedSeparationAngles(const std::vector<double>& angles)
81 {
82  std::vector<double> euclideanDistances(angles.size()), overlapBallsInnerProduct(angles.size());
83  for ( int i = 0; i < angles.size(); ++i )
84  {
85  overlapBallsInnerProduct[i] = std::fabs(std::cos(2*angles[i]));
86  euclideanDistances[i] = std::sqrt(2-2*std::cos(angles[i]));
87  }
88 
89  unsigned int numberOfShells = this->m_NumbersInShell.size();
90  unsigned int numberOfSamples = m_FineScheme->GetNumberOfSamples();
91  int totalNumberOfSamples = std::accumulate(this->m_NumbersInShell.begin(), this->m_NumbersInShell.end(), 0);
92  Index2DVectorType sumOverlapVec(angles.size(), IndexVectorType(numberOfSamples,-1));
93 
94  std::vector<int> coverageInShells(numberOfShells,0);
95  bool isSameAngle = true;
96  for ( int j = 1; j < numberOfShells; ++j )
97  {
98  if (std::fabs(angles[0]-angles[j])>1e-4)
99  {
100  isSameAngle = false;
101  break;
102  }
103  }
104  bool needCoverageInshells = m_ChooseMinimalCoverageShell && !isSameAngle;
105 
106  MeasurementVectorType queryPoint, queryCandidate;
107  typedef typename TreeType::InstanceIdentifierVectorType InstanceIdentifierVectorType;
108  InstanceIdentifierVectorType neighbors, neighbors_1, candidates, candidates_1, neighbors_jj;
109  InstanceIdentifierVectorType candidateNumbersInOverlap;
110 
111  Index2DVectorPointer indices = this->m_FineScheme->GetIndicesInShells();
112  indices->clear();
113 
114  Index2DVectorType chosenIndices(numberOfShells);
115 
116  typedef utl_unordered_map<int, InstanceIdentifierVectorType> NeighborMapType;
117  typedef typename NeighborMapType::const_iterator NeighborMapIterator;
118  NeighborMapType neighborMap;
119  int indexDistPair;
120 
121  if (numberOfShells==1)
122  {
123  IndexVectorType hasChosen(numberOfSamples,-1);
124  std::set<int> nextCandidateIndices;
125 
126  int currentIndex = -1;
127  if (chosenIndices[0].size()==0)
128  currentIndex = 0;
129 
130  while (chosenIndices[0].size()< this->m_NumbersInShell[0] )
131  {
132  // std::cout << "\n chosenIndices[0.size()=" << chosenIndices[0.size() << std::endl << std::flush;
133 
134  hasChosen[currentIndex]=0;
135  chosenIndices[0].push_back(currentIndex);
136  queryPoint = (*m_FineScheme)[currentIndex];
137  // std::cout << "queryPoint = " << queryPoint << std::endl << std::flush;
138 
139  indexDistPair=currentIndex;
140 
141  NeighborMapIterator mapIter = neighborMap.find(indexDistPair);
142  if (mapIter==neighborMap.end())
143  {
144  m_KDTree->Search( queryPoint, euclideanDistances[0], neighbors );
145  neighborMap[indexDistPair] = neighbors;
146  }
147  else
148  neighbors = mapIter->second;
149  for ( int i = 0; i < neighbors.size(); ++i )
150  hasChosen[neighbors[i]/2] = 0;
151 
152  m_KDTree->Search( queryPoint, euclideanDistances[0]+1*m_MinDistanceInFineScheme, candidates );
153  utlException(candidates.size()<=neighbors.size(), "the size of candidates should be larger than the size of neighbors.");
154  // utlPrintVar2(true, neighbors.size(), candidates.size());
155  for ( int i = 0; i < candidates.size(); ++i )
156  {
157  int jj = candidates[i]/2;
158  if (hasChosen[jj] == -1)
159  nextCandidateIndices.insert(jj);
160  }
161 
162  int indexMaxOverlap=-1;
163  int sumMaxOverlap=-1;
164  int numberOfCandidates=0, numberSearch=0;
165  // utl::Tic(std::cout<<"time");
166 // #pragma omp parallel shared(indexMaxOverlap, sumMaxOverlap) private(iter, neighbors_jj, queryCandidate) firstprivate(indexMaxOverlap_ii, sumMaxOverlap_ii)
167  for ( typename std::set<int>::iterator iter = nextCandidateIndices.begin(); iter!=nextCandidateIndices.end(); ++iter )
168  {
169  int jj = *iter;
170  if (hasChosen[jj]==-1)
171  {
172  queryCandidate = (*m_FineScheme)[jj];
173  bool overlapBall = true;
174  double innerProduct = 0;
175  for ( int kk = 0; kk < 3; ++kk )
176  innerProduct+= queryPoint[kk]*queryCandidate[kk];
177  if (std::fabs(innerProduct) < overlapBallsInnerProduct[0])
178  overlapBall = false;
179 
180  int sumOverlap = 0;
181  if (sumOverlapVec[0][jj]>=0 && !overlapBall)
182  sumOverlap = sumOverlapVec[0][jj];
183  else
184  {
185  // sumOverlapVec[0][jj]<0 || (sumOverlapVec[0][jj]>=0 && overlapBall)
186  // m_KDTree->Search( queryCandidate, euclideanDistances[0], neighbors_jj );
187  indexDistPair=jj;
188  NeighborMapIterator mapIter = neighborMap.find(indexDistPair);
189  if (mapIter==neighborMap.end())
190  {
191  m_KDTree->Search( queryCandidate, euclideanDistances[0], neighbors_jj );
192  neighborMap[indexDistPair] = neighbors_jj;
193  }
194  else
195  neighbors_jj = mapIter->second;
196  numberSearch++;
197  for ( int k = 0; k < neighbors_jj.size(); ++k )
198  {
199  if (hasChosen[neighbors_jj[k]/2]==0)
200  sumOverlap++;
201  }
202  sumOverlapVec[0][jj]=sumOverlap;
203  }
204 
205  if (sumMaxOverlap<sumOverlap)
206  {
207  indexMaxOverlap = jj;
208  sumMaxOverlap = sumOverlap;
209  }
210  numberOfCandidates++;
211  }
212  }
213  // utl::Toc();
214  // utlPrintVar2(true, numberOfCandidates, numberSearch);
215 
216  if (numberOfCandidates==0)
217  break;
218 
219  currentIndex = indexMaxOverlap;
220  }
221 
222  if (chosenIndices[0].size()==this->m_NumbersInShell[0])
223  {
224  *indices = chosenIndices;
225  return true;
226  }
227  else
228  return false;
229  }
230  else
231  {
232 
233  // utl::PrintVector(this->m_NumbersInShell, "this->m_NumbersInShell");
234  // utlPrintVar1(true, totalNumberOfSamples);
235  // utl::PrintVector(euclideanDistances, "euclideanDistances 11");
236  // utl::PrintVector(angles, "angles 11");
237  for ( int s = 0; s < numberOfShells; ++s )
238  {
239  // It is impossible that the seperation angle in the combined shell is larger than the seperation angle in individual shell.
240  if (euclideanDistances[s]<= euclideanDistances.back())
241  return false;
242  }
243 
244  Index2DVectorType hasChosen(numberOfSamples, IndexVectorType(angles.size(),-1));
245  std::vector<std::set<int> > nextCandidateIndices(numberOfShells+1);
246 
247  // the first sample in each shell
248  int currentIndex = 0;
249  for ( int s = 0; s < numberOfShells; ++s )
250  {
251  hasChosen[currentIndex][s]=0;
252  hasChosen[currentIndex][numberOfShells]=s;
253 
254  chosenIndices[s].push_back(currentIndex);
255  queryPoint = (*m_FineScheme)[currentIndex];
256 
257  // utlPrintVar1(true, currentIndex);
258  // std::cout << "queryPoint=" << queryPoint << std::endl << std::flush;
259 
260  indexDistPair=currentIndex + s*numberOfSamples;
261  NeighborMapIterator mapIter = neighborMap.find(indexDistPair);
262  if (mapIter==neighborMap.end())
263  {
264  m_KDTree->Search( queryPoint, euclideanDistances[s], neighbors );
265  neighborMap[indexDistPair] = neighbors;
266  }
267  else
268  neighbors = mapIter->second;
269  for ( int i = 0; i < neighbors.size(); ++i )
270  hasChosen[neighbors[i]/2][s] = 0;
271  // update coverages
272  if (needCoverageInshells)
273  coverageInShells[s] += neighbors.size();
274 
275  indexDistPair=currentIndex + numberOfShells*numberOfSamples;
276  mapIter = neighborMap.find(indexDistPair);
277  if (mapIter==neighborMap.end())
278  {
279  m_KDTree->Search( queryPoint, euclideanDistances.back(), neighbors_1 );
280  neighborMap[indexDistPair] = neighbors_1;
281  }
282  else
283  neighbors_1 = mapIter->second;
284  for ( int i = 0; i < neighbors_1.size(); ++i )
285  hasChosen[neighbors_1[i]/2][numberOfShells] = s;
286 
287  m_KDTree->Search( queryPoint, euclideanDistances[s]+1*m_MinDistanceInFineScheme, candidates );
288  utlException(candidates.size()<=neighbors.size(), "the size of candidates should be larger than the size of neighbors.");
289 
290  m_KDTree->Search( queryPoint, euclideanDistances.back()+1*m_MinDistanceInFineScheme, candidates_1 );
291  utlException(candidates_1.size()<=neighbors_1.size(), "the size of candidates should be larger than the size of neighbors.");
292 
293  for ( int i = 0; i < candidates.size(); ++i )
294  {
295  int jj = candidates[i]/2;
296  if ( hasChosen[jj][s]==-1 && hasChosen[jj][numberOfShells]==-1)
297  nextCandidateIndices[s].insert(jj);
298  }
299 
300  for ( int i = 0; i < candidates_1.size(); ++i )
301  {
302  int jj = candidates_1[i]/2;
303  if ( hasChosen[jj][numberOfShells]==-1)
304  {
305  for ( int sss = 0; sss < numberOfShells; ++sss )
306  {
307  if (sss!=s && hasChosen[jj][sss]==-1)
308  nextCandidateIndices[sss].insert(jj);
309  }
310  nextCandidateIndices[numberOfShells].insert(jj);
311  }
312  }
313 
314  int indexMaxOverlap=-1;
315  int sumMaxOverlap=-1;
316  int numberOfCandidates=0, numberSearch=0;
317 
318  for ( typename std::set<int>::iterator iter = nextCandidateIndices[numberOfShells].begin(); iter!=nextCandidateIndices[numberOfShells].end(); ++iter )
319  {
320  int jj = *iter;
321  if (hasChosen[jj][numberOfShells]==-1)
322  {
323  queryCandidate = (*m_FineScheme)[jj];
324  bool overlapBall = true;
325  double innerProduct = 0;
326  for ( int kk = 0; kk < 3; ++kk )
327  innerProduct+= queryPoint[kk]*queryCandidate[kk];
328  if (std::fabs(innerProduct) < overlapBallsInnerProduct[numberOfShells])
329  overlapBall = false;
330 
331  int sumOverlap = 0;
332  if (sumOverlapVec[numberOfShells][jj]>=0 && !overlapBall)
333  sumOverlap = sumOverlapVec[numberOfShells][jj];
334  else
335  {
336  // sumOverlapVec[numberOfShells][jj]<0 || (sumOverlapVec[numberOfShells][jj]>=0 && overlapBall)
337  // m_KDTree->Search( queryCandidate, euclideanDistances.back(), neighbors_jj );
338  indexDistPair = jj + numberOfShells*numberOfSamples;
339  mapIter = neighborMap.find(indexDistPair);
340  if (mapIter==neighborMap.end())
341  {
342  m_KDTree->Search( queryCandidate, euclideanDistances.back(), neighbors_jj );
343  neighborMap[indexDistPair] = neighbors_jj;
344  }
345  else
346  neighbors_jj = mapIter->second;
347  numberSearch++;
348  for ( int k = 0; k < neighbors_jj.size(); ++k )
349  {
350  if (hasChosen[neighbors_jj[k]/2][numberOfShells]>=0)
351  sumOverlap++;
352  }
353  sumOverlapVec[numberOfShells][jj]=sumOverlap;
354  }
355 
356  if (sumMaxOverlap<sumOverlap)
357  {
358  indexMaxOverlap = jj;
359  sumMaxOverlap = sumOverlap;
360  }
361  numberOfCandidates++;
362  }
363  }
364 
365  currentIndex = indexMaxOverlap;
366  }
367 
368  // for ( int i = 0; i < chosenIndices.size(); ++i )
369  // utl::PrintVector(chosenIndices[i], "chosenIndices[i]");
370 
371  // all other samples
372  MeasurementVectorType queryPointLast(queryPoint);
373  int indexShellMaxOverlap=-1, indexShellMaxOverlapLast=-1, shellIndexMinCoverage=-1;
374 
375  for ( unsigned int n = numberOfShells; n < totalNumberOfSamples; ++n )
376  {
377  // std::cout << "n = " << n << std::endl << std::flush;
378 
379  int indexMaxOverlap=-1;
380  int sumMaxOverlap=-1;
381  int numberOfCandidates=0, numberSearch=0;
382 
383  if (needCoverageInshells)
384  {
385  // set the coverage of the shell with requested number of samples as the largest value.
386  for ( int s = 0; s < numberOfShells; ++s )
387  {
388  if (chosenIndices[s].size() >= this->m_NumbersInShell[s])
389  coverageInShells[s] = numberOfSamples;
390  }
391  // find the shell with the minimal coverage and it has not been set requested number of samples.
392  shellIndexMinCoverage = utl::argmin(coverageInShells.begin(), coverageInShells.end());
393  }
394 
395  for ( int s = 0; s < numberOfShells; ++s )
396  {
397 
398  if (needCoverageInshells && shellIndexMinCoverage!=s)
399  {
400  // only set the current sample to the shell with minimal coverage.
401  continue;
402  }
403 
404  if (chosenIndices[s].size() < this->m_NumbersInShell[s])
405  {
406 
407  for ( typename std::set<int>::iterator iter = nextCandidateIndices[s].begin(); iter!=nextCandidateIndices[s].end(); ++iter )
408  {
409  int jj = *iter;
410  if (hasChosen[jj][s]==-1 && hasChosen[jj][numberOfShells]==-1)
411  {
412  queryCandidate = (*m_FineScheme)[jj];
413  bool overlapBall = true;
414  if (n>numberOfShells)
415  {
416  double innerProduct = 0;
417  for ( int kk = 0; kk < 3; ++kk )
418  innerProduct+= queryPointLast[kk]*queryCandidate[kk];
419  // if ( ( std::fabs(innerProduct) < overlapBallsInnerProduct[numberOfShells])
420  // || (indexShellMaxOverlapLast==s && std::fabs(innerProduct) < overlapBallsInnerProduct[s]) )
421  if ( std::fabs(innerProduct) < overlapBallsInnerProduct[s] )
422  overlapBall = false;
423  }
424 
425  int sumOverlap = 0;
426  if (sumOverlapVec[s][jj]>=0 && !overlapBall)
427  sumOverlap = sumOverlapVec[s][jj];
428  else
429  {
430  // sumOverlapVec[s][jj]<0 || (sumOverlapVec[s][jj]>=0 && overlapBall)
431  indexDistPair=jj + s*numberOfSamples;
432  NeighborMapIterator mapIter = neighborMap.find(indexDistPair);
433  if (mapIter==neighborMap.end())
434  {
435  m_KDTree->Search( queryCandidate, euclideanDistances[s], neighbors_jj );
436  neighborMap[indexDistPair] = neighbors_jj;
437  }
438  else
439  neighbors_jj = mapIter->second;
440  numberSearch++;
441  for ( int k = 0; k < neighbors_jj.size(); ++k )
442  {
443  if (hasChosen[neighbors_jj[k]/2][s]>=0 || hasChosen[neighbors_jj[k]/2][numberOfShells]>=0)
444  sumOverlap++;
445  }
446  sumOverlapVec[s][jj]=sumOverlap;
447  }
448 
449  // utlPrintVar3(true, s, jj, sumOverlap);
450  if (sumMaxOverlap<sumOverlap)
451  {
452  indexShellMaxOverlap = s;
453  indexMaxOverlap = jj;
454  sumMaxOverlap = sumOverlap;
455  }
456  numberOfCandidates++;
457  }
458  }
459 
460  }
461  }
462 
463  if (numberOfCandidates==0)
464  break;
465 
466  currentIndex = indexMaxOverlap;
467  indexShellMaxOverlapLast = indexMaxOverlap;
468 
469  hasChosen[currentIndex][indexShellMaxOverlap]=0;
470  hasChosen[currentIndex][numberOfShells]=indexShellMaxOverlap;
471  chosenIndices[indexShellMaxOverlap].push_back(currentIndex);
472  queryPoint = (*m_FineScheme)[currentIndex];
473  queryPointLast = queryPoint;
474 
475  indexDistPair=currentIndex+indexShellMaxOverlap*numberOfSamples;
476  NeighborMapIterator mapIter = neighborMap.find(indexDistPair);
477  if (mapIter==neighborMap.end())
478  {
479  m_KDTree->Search( queryPoint, euclideanDistances[indexShellMaxOverlap], neighbors );
480  neighborMap[indexDistPair] = neighbors;
481  }
482  else
483  neighbors = mapIter->second;
484  for ( int i = 0; i < neighbors.size(); ++i )
485  {
486  // update coverages
487  if (needCoverageInshells)
488  {
489  if (hasChosen[neighbors[i]/2][indexShellMaxOverlap]==-1)
490  coverageInShells[indexShellMaxOverlap]++;
491  }
492  hasChosen[neighbors[i]/2][indexShellMaxOverlap] = 0;
493  }
494 
495  indexDistPair=currentIndex+numberOfShells*numberOfSamples;
496  mapIter = neighborMap.find(indexDistPair);
497  if (mapIter==neighborMap.end())
498  {
499  m_KDTree->Search( queryPoint, euclideanDistances.back(), neighbors_1 );
500  neighborMap[indexDistPair] = neighbors_1;
501  }
502  else
503  neighbors_1 = mapIter->second;
504  for ( int i = 0; i < neighbors_1.size(); ++i )
505  hasChosen[neighbors_1[i]/2][numberOfShells] = indexShellMaxOverlap;
506 
507  m_KDTree->Search( queryPoint, euclideanDistances[indexShellMaxOverlap]+1*m_MinDistanceInFineScheme, candidates );
508  utlException(candidates.size()<=neighbors.size(), "the size of candidates should be larger than the size of neighbors.");
509 
510  m_KDTree->Search( queryPoint, euclideanDistances.back()+1*m_MinDistanceInFineScheme, candidates_1 );
511  utlException(candidates_1.size()<=neighbors_1.size(), "the size of candidates should be larger than the size of neighbors.");
512 
513  for ( int i = 0; i < candidates.size(); ++i )
514  {
515  int jj = candidates[i]/2;
516  if ( hasChosen[jj][indexShellMaxOverlap]==-1 && hasChosen[jj][numberOfShells]==-1)
517  nextCandidateIndices[indexShellMaxOverlap].insert(jj);
518  }
519 
520  for ( int i = 0; i < candidates_1.size(); ++i )
521  {
522  int jj = candidates_1[i]/2;
523  if ( hasChosen[jj][numberOfShells]==-1)
524  {
525  for ( int sss = 0; sss < numberOfShells; ++sss )
526  {
527  if (sss!=indexShellMaxOverlap && hasChosen[jj][sss]==-1)
528  nextCandidateIndices[sss].insert(jj);
529  }
530  nextCandidateIndices[numberOfShells].insert(jj);
531  }
532  }
533 
534  }
535 
536  // for ( int i = 0; i < chosenIndices.size(); ++i )
537  // utl::PrintVector(chosenIndices[i], "chosenIndices[i]");
538  for ( int i = 0; i < chosenIndices.size(); ++i )
539  {
540  if (chosenIndices[i].size()!=this->m_NumbersInShell[i])
541  return false;
542  }
543  *indices = chosenIndices;
544  return true;
545 
546  }
547 
548  return true;
549 }
550 
551 template< class TSamplingType >
552 void
555 {
556  utlGlobalException(this->m_CriteriaType!=Self::DISTANCE, "m_CriteriaType should be DISTANCE");
557 
558  Initialization();
559 
560  // m_KDTree->Print(std::cout<<"m_KDTree");
561 
562  int numberOfShells = this->m_NumbersInShell.size();
563  int totalNumberOfSamples = std::accumulate(this->m_NumbersInShell.begin(), this->m_NumbersInShell.end(), 0);
564  int angleSize = numberOfShells==1?1:(numberOfShells+1);
565  std::vector<double> angles(angleSize,-1.0), anglesUpperBound(angleSize,-1.0), anglesLowerBound(angleSize,0.0);
566  std::vector<std::vector<double> > anglesTest(angleSize);
567 
568  for ( int i = 0; i < numberOfShells; ++i )
569  anglesUpperBound[i] = SamplingType::CalculateMinDistanceUpperBound(2*this->m_NumbersInShell[i]);
570  if (numberOfShells>1)
571  anglesUpperBound[numberOfShells] = SamplingType::CalculateMinDistanceUpperBound(2*totalNumberOfSamples);
572 
573  if (numberOfShells==1)
574  {
575  double angle_0=0, angle_1=anglesUpperBound[0];
576  while (angle_0<angle_1)
577  {
578  angles[0]= (angle_0+angle_1)*0.5;
579  bool successAngles = IsSatisfiedSeparationAngles(angles);
580  // utlPrintVar2(true, angles[0], successAngles);
581 
582  if (successAngles)
583  {
584  angle_0 = angles[0];
585  anglesTest[0].push_back(angles[0]);
586  }
587  else
588  angle_1 = angles[0];
589  if (anglesTest[0].size()>=2 && std::fabs(anglesTest[0].back()-anglesTest[0][anglesTest[0].size()-2])/anglesTest[0][anglesTest[0].size()-2]<m_AngleMinChange )
590  {
591  this->m_OutputOrientations = m_FineScheme;
592  // this->m_OutputOrientations->Print(std::cout<<"output");
593  break;
594  }
595  }
596  }
597  else
598  {
599 
600  std::vector<double> angle_0(anglesLowerBound), angle_1(anglesUpperBound);
601  while (true)
602  {
603  for ( int i = 0; i < angleSize; ++i )
604  angles[i] = (angle_0[i]+angle_1[i])*0.5;
605  bool successAngles = IsSatisfiedSeparationAngles(angles);
606  // utl::PrintVector(angles, "angles");
607  // utlPrintVar1(true, successAngles);
608 
609  if (successAngles)
610  {
611  for ( int i = 0; i < angleSize; ++i )
612  {
613  angle_0[i] = angles[i];
614  anglesTest[i].push_back(angles[i]);
615  }
616  }
617  else
618  {
619  for ( int i = 0; i < angleSize; ++i )
620  angle_1[i] = angles[i];
621  }
622 
623  bool minAngleStop = true;
624  for ( int i = 0; i < angleSize; ++i )
625  {
626  if (anglesTest[i].size()<2 || std::fabs(anglesTest[i].back()-anglesTest[i][anglesTest[i].size()-2])/anglesTest[i][anglesTest[i].size()-2]>=m_AngleMinChange )
627  {
628  minAngleStop = false;
629  break;
630  }
631  }
632  if (minAngleStop)
633  {
634  this->m_OutputOrientations = m_FineScheme;
635  // this->m_OutputOrientations->Print(std::cout<<"output");
636  break;
637  }
638  }
639 
640  }
641 }
642 
643 }
644 
645 
646 #endif
647 
648 
unsigned int argmin(Iterator i1, Iterator i2)
Definition: utlCore.h:212
helper functions specifically used in dmritool
#define utlException(cond, expout)
Definition: utlCoreMacro.h:548
#define utlGlobalException(cond, expout)
Definition: utlCoreMacro.h:372