18 #ifndef __itkSamplingSchemeQSpaceIncrementalEstimationFilter_hxx 19 #define __itkSamplingSchemeQSpaceIncrementalEstimationFilter_hxx 27 template<
class TSamplingType >
33 m_TessellationOrder = 7;
36 template<
class TSamplingType >
42 if (this->m_FineOrientations->Size()==0)
47 if (this->m_InitialOrientations)
49 MatrixPointer initialMatrix = this->m_InitialOrientations->GetOrientationsCartesian();
53 output->SetOrientationsCartesian(this->m_FineOrientations);
54 output->SetIndicesInShells(this->m_InitialOrientations->GetIndicesInShells());
57 unsigned int numberInitialSamples = this->m_InitialOrientations->GetNumberOfSamples();
59 for (
unsigned int i = 0; i < indices->size(); i += 1 )
61 num += indices->operator[](i).size();
63 utlGlobalException(num!=numberInitialSamples,
"wrong intialization in m_InitialOrientations");
93 template<
class TSamplingType >
100 unsigned int numberOfShells = this->m_NumbersInShell.size();
101 unsigned int numberInitialSamples = 0;
102 if (this->m_InitialOrientations)
103 numberInitialSamples = this->m_InitialOrientations->GetNumberOfSamples();
106 output->SetOrientationsCartesian(this->m_FineOrientations);
109 unsigned int numberOfSamples = output->GetNumberOfSamples();
110 MatrixPointer outputMatrix = output->GetOrientationsCartesian();
126 utlGlobalException(this->m_NumbersInShell.size()==0,
"need to set this->m_NumbersInShell");
127 unsigned int totalNumbers=0;
128 for (
unsigned int i = 0; i < this->m_NumbersInShell.size(); i += 1 )
130 totalNumbers += this->m_NumbersInShell[i];
133 std::vector<int> chosenIndex;
134 std::vector<char> hasChosen(numberOfSamples, 0);
135 std::cout <<
"numberOfShells = " << numberOfShells << std::endl << std::flush;
136 std::cout <<
"numberOfSamples = " << numberOfSamples << std::endl << std::flush;
138 if (!this->m_InitialOrientations)
155 if (numberOfShells==1)
158 indexTmp.push_back(d0);
160 indices->push_back(indexTmp);
165 indexTmp.push_back(d0);
166 indices->push_back(indexTmp);
170 chosenIndex.push_back(d0);
176 for (
unsigned int i = 0; i < indices->size(); i += 1 )
177 for (
unsigned int j = 0; j < (*indices)[i].size(); j += 1 )
179 int ii = (*indices)[i][j];
180 chosenIndex.push_back(ii);
184 if (numberOfShells==1)
187 if (this->m_CriteriaType==Self::DISTANCE)
189 double x,y,z,x1,y1,z1;
190 std::vector<double> maxDots(numberOfSamples, -1);
192 for (
unsigned int i = (this->m_InitialOrientations?numberInitialSamples:1); i < totalNumbers; i += 1 )
196 for (
unsigned int j = 0; j < numberOfSamples; j += 1 )
201 x = output->operator[](j)[0];
202 y = output->operator[](j)[1];
203 z = output->operator[](j)[2];
206 for (
unsigned int k = 0; k < chosenIndex.size(); k += 1 )
208 unsigned int kk = chosenIndex[k];
210 x1 = output->operator[](kk)[0];
211 y1 = output->operator[](kk)[1];
212 z1 = output->operator[](kk)[2];
213 double value = x*x1 + y*y1 + z*z1;
216 if (value>maxValue_j)
219 maxDots[j] = maxValue_j;
223 unsigned int kk = chosenIndex.back();
225 x1 = output->operator[](kk)[0];
226 y1 = output->operator[](kk)[1];
227 z1 = output->operator[](kk)[2];
228 double value = x*x1 + y*y1 + z*z1;
231 if (value > maxDots[j] )
233 maxValue_j = maxDots[j];
236 if (maxValue_j < minValue )
238 minValue = maxValue_j;
244 chosenIndex.push_back(index);
245 hasChosen[index] = 1;
246 indices->operator[](0).push_back(index);
251 else if (this->m_CriteriaType==Self::ELECTROSTATIC)
253 double x,y,z,x1,y1,z1;
254 bool orderEqual2 =
std::abs(this->m_ElectrostaticOrder-2)<1e-8 ?
true :
false;
255 std::vector<double> energy(numberOfSamples,0.0);
257 for (
unsigned int i = (this->m_InitialOrientations?numberInitialSamples:1); i < totalNumbers; i += 1 )
261 for (
unsigned int j = 0; j < numberOfSamples; j += 1 )
265 x = output->operator[](j)[0];
266 y = output->operator[](j)[1];
267 z = output->operator[](j)[2];
270 for (
unsigned int k = 0; k < chosenIndex.size(); k += 1 )
272 unsigned int kk = chosenIndex[k];
274 x1 = output->operator[](kk)[0];
275 y1 = output->operator[](kk)[1];
276 z1 = output->operator[](kk)[2];
277 double dot = x*x1 + y*y1 + z*z1;
278 double result1 = 2+2*dot;
279 double result2 = 2-2*dot;
280 double value = (!orderEqual2) ? (1.0/std::pow(result1, this->m_ElectrostaticOrder*0.5) + 1.0/std::pow(result2, this->m_ElectrostaticOrder*0.5)) : (1.0/result1 + 1.0/result2);
286 unsigned int kk = chosenIndex.back();
288 x1 = output->operator[](kk)[0];
289 y1 = output->operator[](kk)[1];
290 z1 = output->operator[](kk)[2];
291 double dot = x*x1 + y*y1 + z*z1;
292 double result1 = 2+2*dot;
293 double result2 = 2-2*dot;
294 double value = (!orderEqual2) ? (1.0/std::pow(result1, this->m_ElectrostaticOrder*0.5) + 1.0/std::pow(result2, this->m_ElectrostaticOrder*0.5)) : (1.0/result1 + 1.0/result2);
297 if (energy[j] < minValue )
299 minValue = energy[j];
304 chosenIndex.push_back(index);
305 hasChosen[index] = 1;
306 indices->operator[](0).push_back(index);
318 if (this->m_CriteriaType==Self::DISTANCE)
321 double x,y,z,x1,y1,z1;
322 std::vector< std::vector<double> > maxDotsVec;
323 for (
int i = 0; i < numberOfShells+1; i += 1 )
325 std::vector<double> dotTemp(numberOfSamples,-1);
326 maxDotsVec.push_back(dotTemp);
331 unsigned startI = (this->m_InitialOrientations?numberInitialSamples:1);
332 for ( ; startI < numberOfShells; startI += 1 )
336 for (
unsigned int j = 0; j < numberOfSamples; j += 1 )
341 x = output->operator[](j)[0];
342 y = output->operator[](j)[1];
343 z = output->operator[](j)[2];
344 if (maxDotsVec[numberOfShells][j]< 0 )
346 for (
unsigned int k = 0; k < chosenIndex.size(); k += 1 )
348 unsigned int kk = chosenIndex[k];
350 x1 = output->operator[](kk)[0];
351 y1 = output->operator[](kk)[1];
352 z1 = output->operator[](kk)[2];
353 double value = x*x1 + y*y1 + z*z1;
356 if (value>maxValue_j)
359 maxDotsVec[numberOfShells][j] = maxValue_j;
363 unsigned int kk = chosenIndex.back();
365 x1 = output->operator[](kk)[0];
366 y1 = output->operator[](kk)[1];
367 z1 = output->operator[](kk)[2];
368 double value = x*x1 + y*y1 + z*z1;
371 if (value > maxDotsVec[numberOfShells][j] )
372 maxDotsVec[numberOfShells][j] = value;
373 maxValue_j = maxDotsVec[numberOfShells][j];
376 if (maxValue_j < minValue )
378 minValue = maxValue_j;
383 chosenIndex.push_back(index);
384 hasChosen[index] = 1;
386 tmp.push_back(index);
387 indices->push_back(tmp);
390 utlException(indices->size()!=numberOfShells,
"Logic ERROR!");
396 int chosedShellIndex_final = -1;
397 int chosedShellIndex_final_last = -1;
398 for (
unsigned int i = startI; i < totalNumbers; i += 1 )
402 int chosedShellIndex = -1;
404 for (
unsigned int j = 0; j < numberOfSamples; j += 1 )
411 x = output->operator[](j)[0];
412 y = output->operator[](j)[1];
413 z = output->operator[](j)[2];
416 if (chosedShellIndex_final_last>=0)
419 unsigned int kk = chosenIndex.back();
421 x1 = output->operator[](kk)[0];
422 y1 = output->operator[](kk)[1];
423 z1 = output->operator[](kk)[2];
424 double value = x*x1 + y*y1 + z*z1;
427 if (value > maxDotsVec[chosedShellIndex_final_last][j] )
428 maxDotsVec[chosedShellIndex_final_last][j] = value;
429 if (value > maxDotsVec[numberOfShells][j] )
430 maxDotsVec[numberOfShells][j] = value;
433 for (
unsigned int s = 0; s < numberOfShells; s += 1 )
435 int numbers = (*indices)[s].size();
436 if (numbers < this->m_NumbersInShell[s])
439 if (maxDotsVec[s][j]<0)
442 for (
unsigned int k = 0; k < numbers; k += 1 )
444 unsigned int kk = (*indices)[s][k];
446 x1 = output->operator[](kk)[0];
447 y1 = output->operator[](kk)[1];
448 z1 = output->operator[](kk)[2];
449 double value = x*x1 + y*y1 + z*z1;
452 if (value>maxValue_j[s])
453 maxValue_j[s] = value;
455 maxDotsVec[s][j] = maxValue_j[s];
456 if (maxValue_j[s]>maxDotsVec[numberOfShells][j])
457 maxDotsVec[numberOfShells][j] = maxValue_j[s];
461 maxValue_j[s] = maxDotsVec[s][j];
474 maxValue_j[numberOfShells] = maxDotsVec[numberOfShells][j];
478 chosedShellIndex = -1;
480 for (
unsigned int s = 0; s < numberOfShells; s += 1 )
482 if ( (*indices)[s].size()==this->m_NumbersInShell[s])
484 if (maxValue_j[s] < chosedShellDot)
486 chosedShellIndex = s;
487 chosedShellDot = maxValue_j[s];
494 double costDist = (1-this->m_WeightForSingleShell)*std::acos(maxValue_j[numberOfShells])
495 + this->m_WeightForSingleShell*std::acos(maxValue_j[chosedShellIndex]);
496 if (costDist > maxDist )
500 chosedShellIndex_final = chosedShellIndex;
506 chosenIndex.push_back(index);
507 hasChosen[index] = 1;
508 indices->operator[](chosedShellIndex_final).push_back(index);
509 chosedShellIndex_final_last = chosedShellIndex_final;
513 else if (this->m_CriteriaType==Self::ELECTROSTATIC)
void GenerateData() ITK_OVERRIDE
helper functions specifically used in dmritool
SamplingSchemeQSpaceIncrementalEstimationFilter()
NDArray< T, 2 > ConnectUtlMatrix(const NDArray< T, 2 > &m1, const NDArray< T, 2 > &m2, const bool isConnectRow)
#define utlException(cond, expout)
const T & max(const T &a, const T &b)
Return the maximum between a and b.
T abs(const T x)
template version of the fabs function
#define utlGlobalException(cond, expout)
SamplingType::Pointer SamplingPointer
LightProcessObject Superclass
SamplingType::MatrixPointer MatrixPointer
SamplingType::IndexVectorType IndexVectorType
void Initialization() ITK_OVERRIDE
SamplingType::Index2DVectorPointer Index2DVectorPointer
SamplingType::MatrixType MatrixType