Medical Imaging Interaction Toolkit  2016.11.0
Medical Imaging Interaction Toolkit
itkStochasticTractographyFilter.h
Go to the documentation of this file.
1 /*===================================================================
2 
3 The Medical Imaging Interaction Toolkit (MITK)
4 
5 Copyright (c) German Cancer Research Center,
6 Division of Medical and Biological Informatics.
7 All rights reserved.
8 
9 This software is distributed WITHOUT ANY WARRANTY; without
10 even the implied warranty of MERCHANTABILITY or FITNESS FOR
11 A PARTICULAR PURPOSE.
12 
13 See LICENSE.txt or http://www.mitk.org for details.
14 
15 ===================================================================*/
16 #ifndef __itkStochasticTractographyFilter_h__
17 #define __itkStochasticTractographyFilter_h__
18 
19 #include "itkImageToImageFilter.h"
20 #include "vnl/vnl_random.h"
21 #include "vnl/vnl_vector_fixed.h"
22 #include "vnl/vnl_matrix.h"
23 #include "itkArray.h"
24 #include "itkVectorContainer.h"
25 #include "vnl/algo/vnl_qr.h"
26 #include "itkVariableLengthVector.h"
28 #include "itkSimpleFastMutexLock.h"
29 #include "itkRealTimeClock.h"
30 #include "itkDiffusionTensor3D.h"
31 #include <vector>
32 
33 namespace itk{
34 
39 typedef Image< Array< double >, 3 > ProbabilityDistributionImageType;
40 
41 template< class TInputDWIImage, class TInputWhiteMatterProbabilityImage,
42  class TOutputConnectivityImage >
43 class ITK_EXPORT StochasticTractographyFilter :
44  public ImageToImageFilter< TInputDWIImage,
45  TOutputConnectivityImage >{
46 public:
48  typedef ImageToImageFilter< TInputDWIImage,
49  TOutputConnectivityImage > Superclass;
52 
53  itkFactorylessNewMacro(Self)
54  itkCloneMacro(Self)
55  itkTypeMacro( StochasticTractographyFilter,
56  ImageToImageFilter )
57 
59  typedef TInputDWIImage InputDWIImageType;
60 
62  typedef TOutputConnectivityImage OutputConnectivityImageType;
63 
65  typedef TInputWhiteMatterProbabilityImage InputWhiteMatterProbabilityImageType;
66 
69 
71  typedef VectorContainer< unsigned int, typename TractType::Pointer >
73 
75  typedef Image< DiffusionTensor3D< double >, 3 > OutputTensorImageType;
76 
78  typedef VectorContainer< unsigned int, vnl_vector_fixed< double, 3 > >
80 
82  typedef double bValueType;
83  typedef VectorContainer< unsigned int, bValueType > bValueContainerType;
84 
86  typedef vnl_matrix_fixed< double, 3, 3 > MeasurementFrameType;
87 
89  typedef VectorContainer< unsigned int, vnl_vector_fixed< double, 3 > >
91 
93  itkSetMacro( TotalTracts, unsigned int)
94  itkGetMacro( TotalTracts, unsigned int)
95 
97  itkSetMacro( MaxTractLength, unsigned int )
98  itkGetMacro( MaxTractLength, unsigned int )
99 
101  itkSetConstObjectMacro( bValues, bValueContainerType )
102  itkGetConstObjectMacro( bValues, bValueContainerType )
103 
105  itkSetConstObjectMacro( Gradients, GradientDirectionContainerType )
106  itkGetConstObjectMacro( Gradients, GradientDirectionContainerType )
107 
109  /* At each voxel specifies the probability of a mylinated fiber existing
110  at that location. This probability is interpreted to be the probability
111  that a fiber tract passes through that region.
112  */
113  itkSetInputMacro(WhiteMatterProbabilityImage, InputWhiteMatterProbabilityImageType)
114  itkGetInputMacro(WhiteMatterProbabilityImage, InputWhiteMatterProbabilityImageType)
115 
116  //overide the built in set input function
117  //we need to create a new cache everytime we change the input image
118  //but we need to preserve it when the input image is the same
119  void SetPrimaryInput(DataObject *input)
120  {
121  typename InputDWIImageType::Pointer dwiimagePtr;
122  try
123  {
124  dwiimagePtr = dynamic_cast<InputDWIImageType*>( input );
125  }
126  catch(itk::ExceptionObject &e)
127  {
128  MITK_INFO << "wrong image type: " << e.what();
129  throw;
130  }
131  Superclass::SetPrimaryInput( input );
132  //update the likelihood cache
133  this->m_LikelihoodCachePtr = ProbabilityDistributionImageType::New();
134  this->m_LikelihoodCachePtr->CopyInformation( this->GetInput() );
135  this->m_LikelihoodCachePtr->SetBufferedRegion( this->GetInput()->GetBufferedRegion() );
136  this->m_LikelihoodCachePtr->SetRequestedRegion( this->GetInput()->GetRequestedRegion() );
137  this->m_LikelihoodCachePtr->Allocate();
138  this->m_CurrentLikelihoodCacheElements = 0;
139  //update the likelihoodcache mutex image
140  this->m_LikelihoodCacheMutexImagePtr = LikelihoodCacheMutexImageType::New();
141  this->m_LikelihoodCacheMutexImagePtr->CopyInformation( this->GetInput() );
142  this->m_LikelihoodCacheMutexImagePtr->SetBufferedRegion( this->GetInput()->GetBufferedRegion() );
143  this->m_LikelihoodCacheMutexImagePtr->SetRequestedRegion( this->GetInput()->GetRequestedRegion() );
144  this->m_LikelihoodCacheMutexImagePtr->Allocate();
145  }
146 
148  itkSetMacro( SeedIndex, typename InputDWIImageType::IndexType )
149  itkGetMacro( SeedIndex, typename InputDWIImageType::IndexType )
150 
152  itkSetConstObjectMacro( SampleDirections, TractOrientationContainerType )
153  itkGetConstObjectMacro( SampleDirections, TractOrientationContainerType )
154 
156  itkSetMacro( MeasurementFrame, MeasurementFrameType )
157  itkGetMacro( MeasurementFrame, MeasurementFrameType )
158 
160  itkSetMacro( MaxLikelihoodCacheSize, unsigned int )
161  itkGetMacro( MaxLikelihoodCacheSize, unsigned int )
162 
164  itkGetObjectMacro( OutputTractContainer, TractContainerType )
165 
167  itkGetObjectMacro( OutputTensorImage, OutputTensorImageType )
168 
169  void GenerateData();
170  void GenerateTractContainerOutput( void );
171  void GenerateTensorImageOutput( void );
172 
173 protected:
177  typedef vnl_vector_fixed< double, 7 > TensorModelParamType;
178 
180  typedef vnl_vector_fixed< double, 6 > ConstrainedModelParamType;
181 
184 
186  typedef Image< Array< double >, 3 > ProbabilityDistributionImageType;
187 
189  typedef Image< SimpleFastMutexLock, 3 > LikelihoodCacheMutexImageType;
190 
192  virtual ~StochasticTractographyFilter();
193 
195  void LoadDefaultSampleDirections( void );
196 
198  void ProbabilisticallyInterpolate( vnl_random& randomgenerator,
199  const TractType::ContinuousIndexType& cindex,
200  typename InputDWIImageType::IndexType& index);
201 
203  void UpdateGradientDirections(void);
204  void UpdateTensorModelFittingMatrices( void );
205  void CalculateTensorModelParameters( const DWIVectorImageType::PixelType& dwivalues,
206  vnl_diag_matrix<double>& W,
207  TensorModelParamType& tensormodelparams);
208 
209  void CalculateConstrainedModelParameters( const TensorModelParamType& tensormodelparams,
210  ConstrainedModelParamType& constrainedmodelparams);
211 
212  void CalculateNoiseFreeDWIFromConstrainedModel( const ConstrainedModelParamType& constrainedmodelparams,
213  DWIVectorImageType::PixelType& noisefreedwi);
214 
215  void CalculateResidualVariance( const DWIVectorImageType::PixelType& noisydwi,
216  const DWIVectorImageType::PixelType& noisefreedwi,
217  const vnl_diag_matrix< double >& W,
218  const unsigned int numberofparameters,
219  double& residualvariance);
220 
221  void CalculateLikelihood( const DWIVectorImageType::PixelType &dwipixel,
222  TractOrientationContainerType::ConstPointer orientations,
223  ProbabilityDistributionImageType::PixelType& likelihood);
224 
225  void CalculatePrior( TractOrientationContainerType::Element v_prev,
226  TractOrientationContainerType::ConstPointer orientations,
227  ProbabilityDistributionImageType::PixelType& prior );
228 
229  void CalculatePosterior( const ProbabilityDistributionImageType::PixelType& likelihood,
230  const ProbabilityDistributionImageType::PixelType& prior,
231  ProbabilityDistributionImageType::PixelType& posterior);
232 
233  void SampleTractOrientation( vnl_random& randomgenerator,
234  const ProbabilityDistributionImageType::PixelType& posterior,
235  TractOrientationContainerType::ConstPointer orientations,
236  TractOrientationContainerType::Element& choosendirection );
237 
238  void StochasticTractGeneration( typename InputDWIImageType::ConstPointer dwiimagePtr,
239  typename InputWhiteMatterProbabilityImageType::ConstPointer maskimagePtr,
240  typename InputDWIImageType::IndexType seedindex,
241  unsigned long randomseed,
242  TractType::Pointer tract );
243 
247  static ITK_THREAD_RETURN_TYPE StochasticTractGenerationCallback( void *arg );
248 
250  Pointer Filter;
251  };
252 
255  AccessLikelihoodCache( typename InputDWIImageType::IndexType index );
257  bool DelegateTract(unsigned long& randomseed);
259  void TractContainerToConnectivityMap(TractContainerType::Pointer tractcontainer);
261  void StoreTract(TractType::Pointer tract);
263  bool FiberExistenceTest( vnl_random& randomgenerator,
265  typename InputWhiteMatterProbabilityImageType::IndexType index );
266 
267 
268 
270 
272  unsigned int m_TotalTracts;
273  unsigned int m_MaxTractLength;
275 
278 
279  typename InputDWIImageType::IndexType m_SeedIndex;
281 
282  //these will be the same for every pixel in the image so
283  //go ahead and do a QR decomposition to optimize the
284  //LS fitting process for estimating the weighing matrix W
285  //in this case we solve instead:
286  //R*Beta = Q'logPhi
287  vnl_matrix< double >* m_A;
288  vnl_qr< double >* m_Aqr;
290 
291  unsigned long m_MaxLikelihoodCacheSize; //in Megabytes
292  unsigned long m_MaxLikelihoodCacheElements; //in Elements (Voxels)
294  SimpleFastMutexLock m_LikelihoodCacheMutex;
295 
298  SimpleFastMutexLock m_TotalDelegatedTractsMutex;
299 
300  //unsigned long m_RandomSeed;
301  SimpleFastMutexLock m_OutputImageMutex;
303  SimpleFastMutexLock m_OutputTractContainerMutex;
304 
306  vnl_random m_RandomGenerator;
307 };
308 
309 }
310 
311 #ifndef ITK_MANUAL_INSTANTIATION
314 #endif
315 
316 #endif
vnl_vector_fixed< double, 6 > ConstrainedModelParamType
Represent a path of line segments through ND Space.
itk::SmartPointer< Self > Pointer
#define MITK_INFO
Definition: mitkLogMacros.h:22
TInputWhiteMatterProbabilityImage InputWhiteMatterProbabilityImageType
bValueContainerType::ConstPointer m_bValues
Image< Array< double >, 3 > ProbabilityDistributionImageType
Performs probabilistic streamline tracking on the input dwi.
VectorContainer< unsigned int, vnl_vector_fixed< double, 3 > > GradientDirectionContainerType
itk::SmartPointer< const Self > ConstPointer
vnl_matrix_fixed< double, 3, 3 > MeasurementFrameType
std::vector< TractType > TractContainerType
GradientDirectionContainerType::ConstPointer m_Gradients
VectorContainer< unsigned int, vnl_vector_fixed< double, 3 > > TractOrientationContainerType
class ITK_EXPORT Image
Image< VariableLengthVector< double >, 3 > DWIVectorImageType
GradientDirectionContainerType::Pointer m_TransformedGradients
ImageToImageFilter< TInputDWIImage, TOutputConnectivityImage > Superclass
Image< SimpleFastMutexLock, 3 > LikelihoodCacheMutexImageType
LikelihoodCacheMutexImageType::Pointer m_LikelihoodCacheMutexImagePtr
TractOrientationContainerType::ConstPointer m_SampleDirections
VectorContainer< unsigned int, bValueType > bValueContainerType
ProbabilityDistributionImageType::Pointer m_LikelihoodCachePtr
vnl_vector_fixed< double, 7 > TensorModelParamType
unsigned short PixelType
VectorContainer< unsigned int, typename TractType::Pointer > TractContainerType
Image< DiffusionTensor3D< double >, 3 > OutputTensorImageType
OutputTensorImageType::Pointer m_OutputTensorImage
static itkEventMacro(BoundingShapeInteractionEvent, itk::AnyEvent) class MITKBOUNDINGSHAPE_EXPORT BoundingShapeInteractor Pointer New()
Basic interaction methods for mitk::GeometryData.