11 #include <itkSymmetricEigenAnalysis.h> 13 #include <vtkPointData.h> 14 #include <vtkDoubleArray.h> 22 m_ThresholdForProlateTensor = 0.25;
35 double &log_proposal, std::mt19937 &random_generator,
36 unsigned int threadId)
40 double concentrationParameter;
44 if (LC > m_ThresholdForProlateTensor)
50 sampling_direction *= -1;
58 sampling_direction = oldDirection;
71 resVec[InputModelImageType::ImageDimension - 1] = 0;
75 if (LC > m_ThresholdForProlateTensor)
95 bool is2d = (this->
GetInputModelImage()->GetLargestPossibleRegion().GetSize()[2] == 1);
97 itk::SymmetricEigenAnalysis <Matrix3DType,Vector3DType,Matrix3DType> EigenAnalysis(InputModelImageType::ImageDimension);
98 EigenAnalysis.SetOrderEigenValues(
true);
103 unsigned int pos = 0;
104 for (
unsigned int i = 0;i < 3;++i)
105 for (
unsigned int j = 0;j <= i;++j)
107 dtiTensor(i,j) = modelValue[pos];
109 dtiTensor(j,i) = dtiTensor(i,j);
113 EigenAnalysis.ComputeEigenValuesAndVectors(dtiTensor,eigVals,eigVecs);
120 for (
unsigned int i = 0;i < 3;++i)
122 for (
unsigned int j = 0;j < 3;++j)
123 tmpVec[j] = eigVecs(i,j);
145 for (
unsigned int i = 0;i < 3;++i)
146 resVec[i] = eigVecs(2,i);
166 if (estimatedB0Value < 50.0)
169 bool isTensorNull =
true;
172 if (modelValue[j] != 0)
174 isTensorNull =
false;
183 if (fractionalAnisotropy < m_FAThreshold)
190 double &log_proposal,
unsigned int threadId)
195 double logLikelihood = 0;
198 double concentrationParameter = 50.0;
200 concentrationParameter = b0Value / std::sqrt(noiseValue);
202 if (LC > m_ThresholdForProlateTensor)
217 double resVal = log_prior + logLikelihood - log_proposal;
223 m_KappaPolynomialCoefficients.resize(coefs.size());
224 for (
unsigned int i = 0;i < coefs.size();++i)
225 m_KappaPolynomialCoefficients[i] = coefs[i];
231 for (
unsigned int i = 0;i < m_KappaPolynomialCoefficients.size();++i)
232 resVal += m_KappaPolynomialCoefficients[i] * std::pow(FA, (
double)i);
239 itk::SymmetricEigenAnalysis <Matrix3DType,Vector3DType,Matrix3DType> EigenAnalysis(InputModelImageType::ImageDimension);
240 EigenAnalysis.SetOrderEigenValues(
true);
245 unsigned int pos = 0;
246 for (
unsigned int i = 0;i < 3;++i)
247 for (
unsigned int j = 0;j <= i;++j)
249 dtiTensor(i,j) = modelValue[pos];
251 dtiTensor(j,i) = dtiTensor(i,j);
255 EigenAnalysis.ComputeEigenValuesAndVectors(dtiTensor,eigVals,eigVecs);
257 for (
unsigned int i = 0;i < 3;++i)
258 resVec[i] = eigVecs(2,i);
269 itk::SymmetricEigenAnalysis <Matrix3DType,Vector3DType,Matrix3DType> EigenAnalysis(InputModelImageType::ImageDimension);
270 EigenAnalysis.SetOrderEigenValues(
true);
275 unsigned int pos = 0;
276 for (
unsigned int i = 0;i < 3;++i)
277 for (
unsigned int j = 0;j <= i;++j)
279 dtiTensor(i,j) = modelValue[pos];
281 dtiTensor(j,i) = dtiTensor(i,j);
285 EigenAnalysis.ComputeEigenValuesAndVectors(dtiTensor,eigVals,eigVecs);
287 for (
unsigned int i = 0;i < 3;++i)
288 resVec[i] = eigVecs(0,i);
295 modelValue.Fill(0.0);
297 if (modelInterpolator->IsInsideBuffer(index))
298 modelValue = modelInterpolator->EvaluateAtContinuousIndex(index);
301 using LECalculatorPointer = LECalculatorType::Pointer;
303 LECalculatorPointer leCalculator = LECalculatorType::New();
305 vnl_matrix <double> tmpTensor(3,3);
307 leCalculator->GetTensorExponential(tmpTensor,tmpTensor);
313 itk::SymmetricEigenAnalysis <Matrix3DType,Vector3DType,Matrix3DType> EigenAnalysis(InputModelImageType::ImageDimension);
314 EigenAnalysis.SetOrderEigenValues(
true);
319 unsigned int pos = 0;
320 for (
unsigned int i = 0;i < 3;++i)
321 for (
unsigned int j = 0;j <= i;++j)
323 dtiTensor(i,j) = modelValue[pos];
325 dtiTensor(j,i) = dtiTensor(i,j);
329 EigenAnalysis.ComputeEigenValues(dtiTensor,eigVals);
332 for (
unsigned int i = 0;i < 3;++i)
333 denom += eigVals[i] * eigVals[i];
335 return (eigVals[2] - eigVals[1]) / sqrt(denom);
340 itk::SymmetricEigenAnalysis <Matrix3DType,Vector3DType,Matrix3DType> EigenAnalysis(InputModelImageType::ImageDimension);
341 EigenAnalysis.SetOrderEigenValues(
true);
346 unsigned int pos = 0;
347 for (
unsigned int i = 0;i < 3;++i)
348 for (
unsigned int j = 0;j <= i;++j)
350 dtiTensor(i,j) = modelValue[pos];
352 dtiTensor(j,i) = dtiTensor(i,j);
356 EigenAnalysis.ComputeEigenValues(dtiTensor,eigVals);
358 double meanLambda = 0;
359 for (
unsigned int i = 0;i < 3;++i)
360 meanLambda += eigVals[i];
366 for (
unsigned int i = 0;i < 3;++i)
368 num += (eigVals[i] - meanLambda) * (eigVals[i] - meanLambda);
369 denom += eigVals[i] * eigVals[i];
373 return std::sqrt(3.0 * num / (2.0 * denom));
378 itk::SymmetricEigenAnalysis <Matrix3DType,Vector3DType,Matrix3DType> EigenAnalysis(InputModelImageType::ImageDimension);
379 EigenAnalysis.SetOrderEigenValues(
true);
384 unsigned int pos = 0;
385 for (
unsigned int i = 0;i < 3;++i)
386 for (
unsigned int j = 0;j <= i;++j)
388 dtiTensor(i,j) = modelValue[pos];
390 dtiTensor(j,i) = dtiTensor(i,j);
394 EigenAnalysis.ComputeEigenValues(dtiTensor,eigVals);
398 for (
unsigned int i = 0;i < 3;++i)
400 meanLambda += eigVals[i];
402 perpLambda = meanLambda / 2.0;
410 vtkSmartPointer <vtkPolyData> outputPtr = this->
GetOutput();
414 unsigned int numPoints = outputPtr->GetPoints()->GetNumberOfPoints();
415 vtkPoints *myPoints = outputPtr->GetPoints();
417 vtkSmartPointer <vtkDoubleArray> faArray = vtkDoubleArray::New();
418 faArray->SetNumberOfComponents(1);
419 faArray->SetName(
"FA");
421 vtkSmartPointer <vtkDoubleArray> adcArray = vtkDoubleArray::New();
422 adcArray->SetNumberOfComponents(1);
423 adcArray->SetName(
"ADC");
428 typedef vnl_matrix <double> MatrixType;
429 MatrixType tmpMat(3,3);
430 vnl_diag_matrix <double> eVals(3);
431 itk::SymmetricEigenAnalysis <MatrixType,vnl_diag_matrix <double>,MatrixType> EigenAnalysis(3);
434 for (
unsigned int i = 0;i < numPoints;++i)
436 for (
unsigned int j = 0;j < 3;++j)
437 tmpPoint[j] = myPoints->GetPoint(i)[j];
439 this->
GetInputModelImage()->TransformPhysicalPointToContinuousIndex(tmpPoint,tmpIndex);
440 tensorValue.Fill(0.0);
441 if (modelInterpolator->IsInsideBuffer(tmpIndex))
447 for (
unsigned int j = 0;j < 3;++j)
448 adcValue += tmpMat(j,j);
450 adcArray->InsertNextValue(adcValue / 3.0);
453 double faValueDenom = 0;
454 EigenAnalysis.ComputeEigenValues(tmpMat,eVals);
455 for (
unsigned int j = 0;j < 3;++j)
457 faValueDenom += eVals[j] * eVals[j];
458 for (
unsigned int k = j + 1;k < 3;++k)
459 faValue += (eVals[j] - eVals[k]) * (eVals[j] - eVals[k]);
462 faValue = std::sqrt(faValue / (2.0 * faValueDenom));
463 faArray->InsertNextValue(faValue);
466 outputPtr->GetPointData()->AddArray(faArray);
467 outputPtr->GetPointData()->AddArray(adcArray);
itk::Matrix< ScalarType, 3, 3 > Matrix3DType
virtual Vector3DType ProposeNewDirection(Vector3DType &oldDirection, VectorType &modelValue, Vector3DType &sampling_direction, double &log_prior, double &log_proposal, std::mt19937 &random_generator, unsigned int threadId) ITK_OVERRIDE
MaskImageType::PointType PointType
void GetEigenValueCombinations(VectorType &modelValue, double &meanLambda, double &perpLambda)
virtual Vector3DType InitializeFirstIterationFromModel(Vector3DType &colinearDir, VectorType &modelValue, unsigned int threadId) ITK_OVERRIDE
InputModelImageType * GetInputModelImage()
void GetDTIPrincipalDirection(const VectorType &modelValue, Vector3DType &resVec, bool is2d)
virtual double GetKappaOfPriorDistribution()
double EvaluateWatsonPDF(const VectorType &v, const VectorType &meanAxis, const ScalarType &kappa)
virtual InitialDirectionModeType GetInitialDirectionMode()
void SetKappaPolynomialCoefficients(std::vector< double > &coefs)
void GetVectorRepresentation(const vnl_matrix< T1 > &tensor, itk::VariableLengthVector< T2 > &vector, unsigned int vecDim=0, bool scale=false)
DTIProbabilisticTractographyImageFilter()
virtual unsigned int GetModelDimension()
itk::Vector< ScalarType, 3 > Vector3DType
void ComputeAdditionalScalarMaps() ITK_OVERRIDE
Computes additional scalar maps that are model dependent to add to the output.
void GetTensorFromVectorRepresentation(const itk::VariableLengthVector< T1 > &vector, vnl_matrix< T2 > &tensor, unsigned int tensDim=0, bool scale=false)
virtual ~DTIProbabilisticTractographyImageFilter()
void GetDTIMinorDirection(VectorType &modelValue, Vector3DType &resVec)
vtkPolyData * GetOutput()
double GetFractionalAnisotropy(VectorType &modelValue)
double GetKappaFromFA(double FA)
virtual bool CheckModelProperties(double estimatedB0Value, double estimatedNoiseValue, VectorType &modelValue, unsigned int threadId) ITK_OVERRIDE
double ComputeScalarProduct(const VectorType &v1, const VectorType &v2, const unsigned int NDimension)
double safe_log(const ScalarType x)
virtual void SetModelDimension(unsigned int _arg)
virtual double ComputeLogWeightUpdate(double b0Value, double noiseValue, Vector3DType &newDirection, VectorType &modelValue, double &log_prior, double &log_proposal, unsigned int threadId) ITK_OVERRIDE
double GetLinearCoefficient(VectorType &modelValue)
itk::VariableLengthVector< ScalarType > VectorType
InterpolatorType::ContinuousIndexType ContinuousIndexType
InterpolatorType::Pointer InterpolatorPointer
void SampleFromWatsonDistribution(const ScalarType &kappa, const VectorType &meanDirection, VectorType &resVec, unsigned int DataDimension, std::mt19937 &generator)
virtual void ComputeModelValue(InterpolatorPointer &modelInterpolator, ContinuousIndexType &index, VectorType &modelValue) ITK_OVERRIDE
virtual InterpolatorType * GetModelInterpolator()