Main Page   Groups   Namespace List   Class Hierarchy   Alphabetical List   Compound List   File List   Namespace Members   Compound Members   File Members   Concepts

itkParallelSparseFieldLevelSetImageFilter.h

Go to the documentation of this file.
00001 /*=========================================================================
00002   
00003 Program:   Insight Segmentation & Registration Toolkit
00004 Module:    $RCSfile: itkParallelSparseFieldLevelSetImageFilter.h,v $
00005 Language:  C++
00006 Date:      $Date: 2006/03/30 15:36:25 $
00007 Version:   $Revision: 1.15 $
00008 
00009 Copyright (c) Insight Software Consortium. All rights reserved.
00010 See ITKCopyright.txt or http://www.itk.org/HTML/Copyright.htm for details.
00011 
00012 This software is distributed WITHOUT ANY WARRANTY; without even 
00013 the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR 
00014 PURPOSE.  See the above copyright notices for more information.
00015 
00016 =========================================================================*/
00017 #ifndef __itkParallelSparseFieldLevelSetImageFilter_h_
00018 #define __itkParallelSparseFieldLevelSetImageFilter_h_
00019 
00020 #include <vector>
00021 #include "itkFiniteDifferenceImageFilter.h"
00022 #include "itkSparseFieldLayer.h"
00023 #include "itkObjectStore.h"
00024 #include "itkNeighborhoodIterator.h"
00025 #include "itkConstNeighborhoodIterator.h"
00026 #include "itkMultiThreader.h"
00027 #include "itkBarrier.h"
00028 #include "itkSemaphore.h"
00029 
00030 namespace itk
00031 {
00032 
00037 template <class TNodeIndexType>
00038 class ParallelSparseFieldLevelSetNode
00039 {
00040 public:
00041   TNodeIndexType m_Index;
00042   float          m_Value;
00043   ParallelSparseFieldLevelSetNode *Next;
00044   ParallelSparseFieldLevelSetNode *Previous;
00045 };
00046 
00073 template <class TNeighborhoodType>
00074 class ParallelSparseFieldCityBlockNeighborList
00075 {
00076 public:
00077   typedef TNeighborhoodType NeighborhoodType;
00078   typedef typename NeighborhoodType::OffsetType OffsetType;
00079   typedef typename NeighborhoodType::RadiusType RadiusType;
00080 
00081   itkStaticConstMacro(Dimension, unsigned int, NeighborhoodType::Dimension);
00082   
00083   const RadiusType &GetRadius() const
00084   {
00085     return m_Radius;
00086   }
00087   
00088   const unsigned int &GetArrayIndex(unsigned int i) const
00089   {
00090     return m_ArrayIndex[i];
00091   }
00092 
00093   const OffsetType &GetNeighborhoodOffset(unsigned int i) const
00094   {
00095     return m_NeighborhoodOffset[i];
00096   }
00097   
00098   const unsigned int &GetSize() const
00099   {
00100     return m_Size;
00101   }
00102   
00103   unsigned int GetStride(unsigned int i)
00104   {
00105     return m_StrideTable[i];
00106   }
00107   
00108   ParallelSparseFieldCityBlockNeighborList();
00109   
00110   ~ParallelSparseFieldCityBlockNeighborList()
00111   {
00112     m_ArrayIndex.clear();
00113     m_NeighborhoodOffset.clear();
00114   }
00115   
00116   void Print(std::ostream &os) const;
00117   
00118 private:
00119   char pad1[128];
00120   unsigned int m_Size;
00121   RadiusType m_Radius;
00122   std::vector<unsigned int> m_ArrayIndex;
00123   std::vector<OffsetType>   m_NeighborhoodOffset;
00124   
00127   unsigned int m_StrideTable[Dimension];
00128   char pad2[128];
00129 };
00130 
00246 template <class TInputImage, class TOutputImage>
00247 class ITK_EXPORT ParallelSparseFieldLevelSetImageFilter :
00248   public FiniteDifferenceImageFilter<TInputImage, TOutputImage>
00249 {
00250 public:
00251 
00253   typedef ParallelSparseFieldLevelSetImageFilter  Self;
00254   typedef FiniteDifferenceImageFilter<TInputImage, TOutputImage> Superclass;
00255   typedef SmartPointer<Self>  Pointer;
00256   typedef SmartPointer<const Self>  ConstPointer;
00257 
00259   typedef typename Superclass::TimeStepType TimeStepType;
00260   typedef typename Superclass::FiniteDifferenceFunctionType FiniteDifferenceFunctionType;
00261 
00263   itkNewMacro(Self);
00264 
00266   itkTypeMacro(ParallelSparseFieldLevelSetImageFilter, FiniteDifferenceImageFilter);
00267 
00269   typedef TInputImage  InputImageType;
00270   typedef TOutputImage OutputImageType;
00271   typedef typename OutputImageType::IndexType IndexType;
00272 
00273   itkStaticConstMacro(ImageDimension, unsigned int, TOutputImage::ImageDimension);
00274 
00275   typedef typename OutputImageType::PixelType PixelType;
00276   
00277   typedef typename OutputImageType::RegionType ThreadRegionType;
00278   
00281   typedef typename OutputImageType::ValueType ValueType;
00282 
00284   typedef ParallelSparseFieldLevelSetNode<IndexType> LayerNodeType;
00285 
00287   typedef SparseFieldLayer<LayerNodeType> LayerType;
00288   typedef typename LayerType::Pointer LayerPointerType;
00289 
00291   typedef std::vector<LayerPointerType> LayerListType;
00292 
00294   typedef signed char StatusType;
00295 
00298   typedef Image<StatusType, itkGetStaticConstMacro(ImageDimension)> StatusImageType;
00299 
00302   typedef ObjectStore<LayerNodeType> LayerNodeStorageType;
00303 
00304   typedef Offset<itkGetStaticConstMacro(ImageDimension)> OffsetType;
00305   
00309   itkSetMacro(NumberOfLayers, StatusType);
00310   itkGetMacro(NumberOfLayers, StatusType);
00312 
00314   itkSetMacro(IsoSurfaceValue, ValueType);
00315   itkGetMacro(IsoSurfaceValue, ValueType);
00317 
00318   LayerPointerType GetActiveListForIndex (const IndexType index)
00319   {
00320   // get the 'z' value for the index
00321   const unsigned int indexZ= index[m_SplitAxis];
00322   // get the thread in whose region the index lies
00323   const unsigned int ThreadNum= this->GetThreadNumber (indexZ);
00324   // get the active list for that thread
00325   return m_Data[ThreadNum].m_Layers[0];
00326   }
00327 
00328 #ifdef ITK_USE_CONCEPT_CHECKING
00329 
00330   itkConceptMacro(OutputEqualityComparableCheck,
00331                   (Concept::EqualityComparable<PixelType>));
00332   itkConceptMacro(DoubleConvertibleToOutputCheck,
00333                   (Concept::Convertible<double, PixelType>));
00334   itkConceptMacro(OutputOStreamWritableCheck,
00335                   (Concept::OStreamWritable<PixelType>));
00336 
00338 #endif
00339 
00340 protected:
00341   ParallelSparseFieldLevelSetImageFilter();
00342   ~ParallelSparseFieldLevelSetImageFilter() {}
00343   virtual void PrintSelf(std::ostream& os, Indent indent) const;
00344 
00346   ParallelSparseFieldCityBlockNeighborList < NeighborhoodIterator<OutputImageType> >
00347     m_NeighborList;
00348 
00351   static double m_ConstantGradientValue;
00352 
00354   static ValueType m_ValueOne;
00355 
00357   static ValueType m_ValueZero;
00358 
00361   static StatusType m_StatusActiveChangingUp;
00362 
00365   static StatusType m_StatusActiveChangingDown;
00366 
00369   static StatusType m_StatusNull;
00370 
00373   static StatusType m_StatusChanging;
00374 
00377   static StatusType m_StatusBoundaryPixel;
00378 
00383   typename OutputImageType::Pointer m_ShiftedImage;
00384 
00389   LayerListType m_Layers;
00390 
00394   StatusType m_NumberOfLayers;
00395 
00397   typename StatusImageType::Pointer m_StatusImage;
00398   typename OutputImageType::Pointer m_OutputImage;
00399 
00401   typename StatusImageType::Pointer m_StatusImageTemp;
00402   typename OutputImageType::Pointer m_OutputImageTemp;
00403 
00405   typename LayerNodeStorageType::Pointer m_LayerNodeStore;
00406 
00408   ValueType m_IsoSurfaceValue;
00409 
00413   //  ValueType m_RMSChange;
00414 
00417   virtual void GenerateData();
00418 
00423   void CopyInputToOutput(); 
00424 
00426   void AllocateUpdateBuffer() {}
00427 
00430   void Initialize();
00431 
00436   void ConstructActiveLayer();
00437 
00439   void InitializeActiveLayerValues();
00440 
00444   void ConstructLayer(StatusType from, StatusType to);
00445 
00447   void ProcessStatusList(LayerType *InputList, StatusType ChangeToStatus,
00448                          StatusType SearchForStatus, unsigned int ThreadId);
00449 
00454   void PropagateAllLayerValues();
00455 
00463   void PropagateLayerValues(StatusType from, StatusType to, StatusType promote,
00464                             unsigned int InOrOut);
00465 
00470   virtual void InitializeBackgroundPixels();
00471 
00475   void ThreadedAllocateData(unsigned int ThreadId);
00476   void ThreadedInitializeData(unsigned int ThreadId, const ThreadRegionType & ThreadRegion);
00478 
00488   void ComputeInitialThreadBoundaries();
00489 
00491   unsigned int GetThreadNumber(unsigned int splitAxisValue);
00492 
00494   void GetThreadRegionSplitByBoundary(unsigned int ThreadId, ThreadRegionType& ThreadRegion);
00495 
00498   void DeallocateData();
00499 
00501   struct ParallelSparseFieldLevelSetThreadStruct
00502   {
00503     ParallelSparseFieldLevelSetImageFilter* Filter;
00504     TimeStepType* TimeStepList;
00505     bool* ValidTimeStepList;
00506     TimeStepType TimeStep;
00507   };
00508 
00513   void Iterate();
00514   static ITK_THREAD_RETURN_TYPE IterateThreaderCallback(void * arg);
00516 
00521   inline virtual ValueType ThreadedCalculateUpdateValue(const unsigned int itkNotUsed(ThreadId),
00522                                                         const IndexType itkNotUsed(index),
00523                                                         const TimeStepType &dt,
00524                                                         const ValueType &value,
00525                                                         const ValueType &change)
00526   {
00527     return (value + dt * change);
00528   }
00529 
00530   // This method can be overridden in derived classes.
00531   // The pixel at 'index' is entering the active layer for thread 'ThreadId'.
00532   // The outputimage at 'index' will have the value as given by the 'value' parameter.
00533   virtual void ThreadedProcessPixelEnteringActiveLayer (const IndexType itkNotUsed(index),
00534                                                         const ValueType itkNotUsed(value),
00535                                                         const unsigned int itkNotUsed(ThreadId));
00536   
00538   void ApplyUpdate(TimeStepType) {}
00539 
00542   virtual void ThreadedApplyUpdate(TimeStepType dt, unsigned int ThreadId);
00543 
00545   TimeStepType CalculateChange()
00546   {
00547     return NumericTraits<TimeStepType>::Zero;
00548   }
00549 
00552   virtual TimeStepType ThreadedCalculateChange(unsigned int ThreadId);
00553 
00560   void ThreadedUpdateActiveLayerValues(TimeStepType dt, LayerType *StatusUpList,
00561                                        LayerType *StatusDownList, unsigned int ThreadId);
00562 
00564   void CopyInsertList(unsigned int ThreadId, LayerPointerType FromListPtr,
00565                       LayerPointerType ToListPtr);
00566 
00568   void ClearList(unsigned int ThreadId, LayerPointerType ListPtr);
00569 
00572   void CopyInsertInterNeighborNodeTransferBufferLayers(unsigned int ThreadId,
00573                                                        LayerPointerType InputList,
00574                                                        unsigned int InOrOut,
00575                                                        unsigned int BufferLayerNumber);
00576 
00579   void ClearInterNeighborNodeTransferBufferLayers(unsigned int ThreadId, unsigned int InOrOut,
00580                                                   unsigned int BufferLayerNumber);
00581 
00589   void ThreadedProcessFirstLayerStatusLists(unsigned int InputLayerNumber,
00590                                             unsigned int OutputLayerNumber,
00591                                             StatusType SearchForStatus,
00592                                             unsigned int InOrOut,
00593                                             unsigned int BufferLayerNumber, unsigned int ThreadId);
00594 
00600   void ThreadedProcessStatusList(unsigned int InputLayerNumber, unsigned int OutputLayerNumber,
00601                                  StatusType ChangeToStatus, StatusType SearchForStatus,
00602                                  unsigned int InOrOut,
00603                                  unsigned int BufferLayerNumber, unsigned int ThreadId);
00604 
00608   void ThreadedProcessOutsideList(unsigned int InputLayerNumber, StatusType ChangeToStatus,
00609                                   unsigned int InOrOut, unsigned int BufferLayerNumber, unsigned int ThreadId);
00610 
00612   void ThreadedPropagateLayerValues(StatusType from, StatusType to, StatusType promote,
00613                                     unsigned int InorOut, unsigned int ThreadId);
00614 
00617   void GetThreadRegionSplitUniformly(unsigned int ThreadId, ThreadRegionType& ThreadRegion);
00618 
00624   void ThreadedPostProcessOutput(const ThreadRegionType & regionToProcess);
00625 
00636   virtual void CheckLoadBalance();
00637 
00640   virtual void ThreadedLoadBalance(unsigned int ThreadId);
00641 
00643   void WaitForAll();
00644   void SignalNeighborsAndWait (unsigned int ThreadId);
00645   void SignalNeighbor  (unsigned int SemaphoreArrayNumber, unsigned int ThreadId);
00646   void WaitForNeighbor (unsigned int SemaphoreArrayNumber, unsigned int ThreadId);
00648 
00651   virtual void ThreadedInitializeIteration (unsigned int ThreadId);
00652 
00655   //  void WriteActivePointsToFile ();
00656 
00658   unsigned int m_NumOfThreads;
00659 
00661   unsigned int m_SplitAxis;
00662 
00664   unsigned int m_ZSize;
00665 
00668   bool m_BoundaryChanged;
00669 
00671   unsigned int * m_Boundary;
00672 
00674   int * m_GlobalZHistogram;
00675 
00677   unsigned int * m_MapZToThreadNumber;
00678 
00681   int * m_ZCumulativeFrequency;
00682 
00684   typename Barrier::Pointer m_Barrier;
00685 
00687   struct ThreadData
00688   {
00689     char pad1 [128];
00690 
00691     TimeStepType TimeStep;
00692     ThreadRegionType ThreadRegion;
00693     ValueType m_RMSChange;
00694     unsigned int m_Count;
00695     
00697     LayerListType m_Layers;
00698 
00700     LayerListType * m_LoadTransferBufferLayers;
00701 
00703     typename LayerNodeStorageType::Pointer m_LayerNodeStore;
00704 
00705     LayerPointerType UpList[2];
00706     LayerPointerType DownList[2];
00707     
00710     LayerPointerType** m_InterNeighborNodeTransferBufferLayers[2];
00711 
00714     void * globalData;
00715 
00717     int * m_ZHistogram;
00718 
00722     typename Semaphore::Pointer m_Semaphore[2];
00723 
00725     unsigned int m_SemaphoreArrayNumber;
00726 
00727     char pad2 [128];
00728   };
00729   
00731   ThreadData *m_Data;
00732 
00735   bool m_Stop;
00736 
00741   bool m_InterpolateSurfaceLocation;
00742 
00743 private:
00744   
00745   ParallelSparseFieldLevelSetImageFilter(const Self&); // purposely not implemented
00746   void operator=(const Self&);                         // purposely not implemented
00747   
00750   bool m_BoundsCheckingActive;
00751 };
00752 
00753 } // end namespace itk
00754 
00755 #ifndef ITK_MANUAL_INSTANTIATION
00756 #include "itkParallelSparseFieldLevelSetImageFilter.txx"
00757 #endif
00758 
00759 #endif
00760 

Generated at Sun Sep 23 13:48:33 2007 for ITK by doxygen 1.5.1 written by Dimitri van Heesch, © 1997-2000