diff --git a/Modules/DiffusionImaging/DiffusionCore/mitkDiffusionFunctionCollection.cpp b/Modules/DiffusionImaging/DiffusionCore/mitkDiffusionFunctionCollection.cpp index 9e9ba9054f..04c092a739 100644 --- a/Modules/DiffusionImaging/DiffusionCore/mitkDiffusionFunctionCollection.cpp +++ b/Modules/DiffusionImaging/DiffusionCore/mitkDiffusionFunctionCollection.cpp @@ -1,93 +1,169 @@ /*=================================================================== The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See LICENSE.txt or http://www.mitk.org for details. ===================================================================*/ #include "mitkDiffusionFunctionCollection.h" #include #include "mitkVector.h" // for Windows #ifndef M_PI #define M_PI 3.14159265358979323846 #endif // Namespace ::SH #include #include #include -// Namespace ::vnl_function + +// Namespace ::Gradients +#include "itkVectorContainer.h" #include "vnl/vnl_vector.h" //------------------------- SH-function ------------------------------------ double mitk::sh::factorial(int number) { - if(number <= 1) return 1; - double result = 1.0; - for(int i=1; i<=number; i++) - result *= i; - return result; + if(number <= 1) return 1; + double result = 1.0; + for(int i=1; i<=number; i++) + result *= i; + return result; } void mitk::sh::Cart2Sph(double x, double y, double z, double *cart) { - double phi, th, rad; - rad = sqrt(x*x+y*y+z*z); - if( rad < mitk::eps ) - { - th = M_PI/2; - phi = M_PI/2; - } - else - { - th = acos(z/rad); - phi = atan2(y, x); - } - cart[0] = phi; - cart[1] = th; - cart[2] = rad; + double phi, th, rad; + rad = sqrt(x*x+y*y+z*z); + if( rad < mitk::eps ) + { + th = M_PI/2; + phi = M_PI/2; + } + else + { + th = acos(z/rad); + phi = atan2(y, x); + } + cart[0] = phi; + cart[1] = th; + cart[2] = rad; } double mitk::sh::legendre0(int l) { - if( l%2 != 0 ) - { - return 0; - } - else - { - double prod1 = 1.0; - for(int i=1;i mitk::gradients::GetAllUniqueDirections( std::map > & refBValueMap, GradientDirectionContainerType *refGradientsContainer ) +{ + + IndiciesVector directioncontainer; + BValueMap::iterator mapIterator = refBValueMap.begin(); + + if(refBValueMap.find(0) != refBValueMap.end() && refBValueMap.size() > 1) + mapIterator++; //skip bzero Values + + for( ; mapIterator != refBValueMap.end(); mapIterator++){ + + IndiciesVector currentShell = mapIterator->second; + + while(currentShell.size()>0) + { + unsigned int wntIndex = currentShell.back(); + currentShell.pop_back(); + + IndiciesVector::iterator containerIt = directioncontainer.begin(); + bool directionExist = false; + while(containerIt != directioncontainer.end()) + { + if (fabs(dot(refGradientsContainer->ElementAt(*containerIt), refGradientsContainer->ElementAt(wntIndex))) > 0.9998) + { + directionExist = true; + break; + } + containerIt++; + } + if(!directionExist) + { + directioncontainer.push_back(wntIndex); + } + } + } + + return directioncontainer; +} + + +bool mitk::gradients::CheckForDifferingShellDirections(std::map > & refBValueMap, GradientDirectionContainerType *refGradientsContainer) +{ + BValueMap::iterator mapIterator = refBValueMap.begin(); + + if(refBValueMap.find(0) != refBValueMap.end() && refBValueMap.size() > 1) + mapIterator++; //skip bzero Values + + for( ; mapIterator != refBValueMap.end(); mapIterator++){ + BValueMap::iterator mapIterator_2 = refBValueMap.begin(); + if(refBValueMap.find(0) != refBValueMap.end() && refBValueMap.size() > 1) + mapIterator_2++; //skip bzero Values + for( ; mapIterator_2 != refBValueMap.end(); mapIterator_2++){ + + if(mapIterator_2 == mapIterator) continue; + + IndiciesVector currentShell = mapIterator->second; + IndiciesVector testShell = mapIterator_2->second; + for (unsigned int i = 0; i< currentShell.size(); i++) + if (fabs(dot(refGradientsContainer->ElementAt(currentShell[i]), refGradientsContainer->ElementAt(testShell[i]))) <= 0.9998) { return true; } + + } + } + return false; +} + + +template +double mitk::gradients::dot (vnl_vector_fixed< type ,3> const& v1, vnl_vector_fixed< type ,3 > const& v2 ) +{ + double result = (v1[0] * v2[0] + v1[1] * v2[1] + v1[2] * v2[2]) / (v1.two_norm() * v2.two_norm()); + return result ; +} diff --git a/Modules/DiffusionImaging/DiffusionCore/mitkDiffusionFunctionCollection.h b/Modules/DiffusionImaging/DiffusionCore/mitkDiffusionFunctionCollection.h index 8267c5cc9b..84103a505e 100644 --- a/Modules/DiffusionImaging/DiffusionCore/mitkDiffusionFunctionCollection.h +++ b/Modules/DiffusionImaging/DiffusionCore/mitkDiffusionFunctionCollection.h @@ -1,39 +1,61 @@ /*=================================================================== The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See LICENSE.txt or http://www.mitk.org for details. ===================================================================*/ #ifndef __mitkDiffusionFunctionCollection_h_ #define __mitkDiffusionFunctionCollection_h_ #include "DiffusionCoreExports.h" - +#include "vector.h" +#include "map.h" +#include "vnl/vnl_vector.h" +#include "vnl/vnl_vector_fixed.h" +#include "itkVectorContainer.h" namespace mitk{ class DiffusionCore_EXPORT sh { public: static double factorial(int number); static void Cart2Sph(double x, double y, double z, double* cart); static double legendre0(int l); static double spherical_harmonic(int m,int l,double theta,double phi, bool complexPart); static double Yj(int m, int k, double theta, double phi); }; + +class DiffusionCore_EXPORT gradients +{ +private: + typedef std::vector IndiciesVector; + typedef std::map BValueMap; + typedef itk::VectorContainer< unsigned int, vnl_vector_fixed< double, 3 > > GradientDirectionContainerType; + +public: + static std::vector GetAllUniqueDirections( std::map > & refBValueMap, GradientDirectionContainerType *refGradientsContainer ); + + static bool CheckForDifferingShellDirections(std::map > & refBValueMap, GradientDirectionContainerType *refGradientsContainer); + + template + static double dot (vnl_vector_fixed< type ,3> const& v1, vnl_vector_fixed< type ,3 > const& v2 ); + +}; + } #endif //__mitkDiffusionFunctionCollection_h_