ITK  4.4.0
Insight Segmentation and Registration Toolkit
itkParallelSparseFieldLevelSetImageFilter.h
Go to the documentation of this file.
1 /*=========================================================================
2  *
3  * Copyright Insight Software Consortium
4  *
5  * Licensed under the Apache License, Version 2.0 (the "License");
6  * you may not use this file except in compliance with the License.
7  * You may obtain a copy of the License at
8  *
9  * http://www.apache.org/licenses/LICENSE-2.0.txt
10  *
11  * Unless required by applicable law or agreed to in writing, software
12  * distributed under the License is distributed on an "AS IS" BASIS,
13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  * See the License for the specific language governing permissions and
15  * limitations under the License.
16  *
17  *=========================================================================*/
18 #ifndef __itkParallelSparseFieldLevelSetImageFilter_h
19 #define __itkParallelSparseFieldLevelSetImageFilter_h
20 
21 #include <vector>
23 #include "itkSparseFieldLayer.h"
24 #include "itkObjectStore.h"
26 #include "itkMultiThreader.h"
27 #include "itkBarrier.h"
28 
29 namespace itk
30 {
36 template< class TNodeIndexType >
38 {
39 public:
40  TNodeIndexType m_Index;
41  float m_Value;
44 };
45 
74 template< class TNeighborhoodType >
76 {
77 public:
78  typedef TNeighborhoodType NeighborhoodType;
81 
82  itkStaticConstMacro(Dimension, unsigned int, NeighborhoodType::Dimension);
83 
84  const RadiusType & GetRadius() const
85  {
86  return m_Radius;
87  }
88 
89  const unsigned int & GetArrayIndex(unsigned int i) const
90  {
91  return m_ArrayIndex[i];
92  }
93 
94  const OffsetType & GetNeighborhoodOffset(unsigned int i) const
95  {
96  return m_NeighborhoodOffset[i];
97  }
98 
99  const unsigned int & GetSize() const
100  {
101  return m_Size;
102  }
103 
104  unsigned int GetStride(unsigned int i)
105  {
106  return m_StrideTable[i];
107  }
108 
110 
112  {
113  m_ArrayIndex.clear();
114  m_NeighborhoodOffset.clear();
115  }
116 
117  void Print(std::ostream & os) const;
118 
119 private:
120  char m_Pad1[128];
121  unsigned int m_Size;
123  std::vector< unsigned int > m_ArrayIndex;
124  std::vector< OffsetType > m_NeighborhoodOffset;
125 
128  unsigned int m_StrideTable[Dimension];
129  char m_Pad2[128];
130 };
131 
248 template< class TInputImage, class TOutputImage >
250  public FiniteDifferenceImageFilter< TInputImage, TOutputImage >
251 {
252 public:
253 
259 
261  typedef typename Superclass::TimeStepType TimeStepType;
262  typedef typename Superclass::FiniteDifferenceFunctionType FiniteDifferenceFunctionType;
263  typedef typename Superclass::RadiusType RadiusType;
264  typedef typename Superclass::NeighborhoodScalesType NeighborhoodScalesType;
265 
267  itkNewMacro(Self);
268 
271 
273  typedef TInputImage InputImageType;
274  typedef TOutputImage OutputImageType;
275  typedef typename OutputImageType::IndexType IndexType;
276 
277  itkStaticConstMacro(ImageDimension, unsigned int, TOutputImage::ImageDimension);
278 
279  typedef typename OutputImageType::PixelType PixelType;
280 
281  typedef typename OutputImageType::RegionType ThreadRegionType;
282 
285  typedef typename OutputImageType::ValueType ValueType;
286 
289 
293 
295  typedef std::vector< LayerPointerType > LayerListType;
296 
298  typedef signed char StatusType;
299 
303 
307 
309 
313  itkSetMacro(NumberOfLayers, StatusType);
314  itkGetConstMacro(NumberOfLayers, StatusType);
316 
318  itkSetMacro(IsoSurfaceValue, ValueType);
319  itkGetConstMacro(IsoSurfaceValue, ValueType);
321 
322  LayerPointerType GetActiveListForIndex(const IndexType index)
323  {
324  // get the 'z' value for the index
325  const unsigned int indexZ = index[m_SplitAxis];
326  // get the thread in whose region the index lies
327  const unsigned int ThreadNum = this->GetThreadNumber (indexZ);
328 
329  // get the active list for that thread
330  return m_Data[ThreadNum].m_Layers[0];
331  }
332 
333 #ifdef ITK_USE_CONCEPT_CHECKING
334 
335  itkConceptMacro( OutputEqualityComparableCheck,
337  itkConceptMacro( DoubleConvertibleToOutputCheck,
339  itkConceptMacro( OutputOStreamWritableCheck,
341 
343 #endif
344 
345 protected:
348  virtual void PrintSelf(std::ostream & os, Indent indent) const;
349 
353 
357 
360 
363 
367 
371 
375 
379 
383 
388  typename OutputImageType::Pointer m_ShiftedImage;
389 
395 
401 
404  typename OutputImageType::Pointer m_OutputImage;
405 
409  typename OutputImageType::Pointer m_OutputImageTemp;
410 
413 
416 
420  // ValueType m_RMSChange;
421 
424  virtual void GenerateData();
425 
430  void CopyInputToOutput();
431 
434 
437  void Initialize();
438 
443  void ConstructActiveLayer();
444 
446  void InitializeActiveLayerValues();
447 
451  void ConstructLayer(const StatusType& from, const StatusType& to);
452 
454  void ProcessStatusList(LayerType *InputList, const StatusType& ChangeToStatus,
455  const StatusType& SearchForStatus, ThreadIdType ThreadId);
456 
461  void PropagateAllLayerValues();
462 
470  void PropagateLayerValues(const StatusType& from, const StatusType& to,
471  const StatusType& promote, unsigned int InOrOut);
472 
477  virtual void InitializeBackgroundPixels();
478 
482  void ThreadedAllocateData(ThreadIdType ThreadId);
483 
484  void ThreadedInitializeData(ThreadIdType ThreadId, const ThreadRegionType & ThreadRegion);
485 
495  void ComputeInitialThreadBoundaries();
496 
498  unsigned int GetThreadNumber(unsigned int splitAxisValue);
499 
501  void GetThreadRegionSplitByBoundary(ThreadIdType ThreadId, ThreadRegionType & ThreadRegion);
502 
505  void DeallocateData();
506 
510  std::vector< TimeStepType > TimeStepList;
511  std::vector< bool > ValidTimeStepList;
513  };
514 
519  void Iterate();
520 
521  static ITK_THREAD_RETURN_TYPE IterateThreaderCallback(void *arg);
522 
527  inline virtual ValueType ThreadedCalculateUpdateValue(const ThreadIdType itkNotUsed(ThreadId),
528  const IndexType itkNotUsed(index),
529  const TimeStepType & dt,
530  const ValueType & value,
531  const ValueType & change)
532  {
533  return ( value + static_cast< ValueType >( dt ) * change );
534  }
535 
536  // This method can be overridden in derived classes.
537  // The pixel at 'index' is entering the active layer for thread 'ThreadId'.
538  // The outputimage at 'index' will have the value as given by the
539  // 'value' parameter.
540  virtual void ThreadedProcessPixelEnteringActiveLayer( const IndexType& itkNotUsed(index),
541  const ValueType& itkNotUsed(value),
542  ThreadIdType itkNotUsed(ThreadId) );
543 
545  void ApplyUpdate(const TimeStepType&) {}
546 
549  virtual void ThreadedApplyUpdate(const TimeStepType& dt, ThreadIdType ThreadId);
550 
552  TimeStepType CalculateChange()
553  {
555  }
556 
559  virtual TimeStepType ThreadedCalculateChange(ThreadIdType ThreadId);
560 
567  void ThreadedUpdateActiveLayerValues( const TimeStepType& dt,
568  LayerType *StatusUpList,
569  LayerType *StatusDownList,
570  ThreadIdType ThreadId);
571 
574  void CopyInsertList( ThreadIdType ThreadId,
575  LayerPointerType FromListPtr,
576  LayerPointerType ToListPtr);
577 
579  void ClearList(ThreadIdType ThreadId, LayerPointerType ListPtr);
580 
583  void CopyInsertInterNeighborNodeTransferBufferLayers(
584  ThreadIdType ThreadId,
585  LayerPointerType InputList,
586  unsigned int InOrOut,
587  unsigned int BufferLayerNumber);
588 
591  void ClearInterNeighborNodeTransferBufferLayers(
592  ThreadIdType ThreadId, unsigned int InOrOut,
593  unsigned int BufferLayerNumber);
594 
602  void ThreadedProcessFirstLayerStatusLists(
603  unsigned int InputLayerNumber,
604  unsigned int OutputLayerNumber,
605  const StatusType& SearchForStatus,
606  unsigned int InOrOut,
607  unsigned int BufferLayerNumber,
608  ThreadIdType ThreadId);
609 
615  void ThreadedProcessStatusList(
616  unsigned int InputLayerNumber,
617  unsigned int OutputLayerNumber,
618  const StatusType& ChangeToStatus,
619  const StatusType& SearchForStatus,
620  unsigned int InOrOut,
621  unsigned int BufferLayerNumber,
622  ThreadIdType ThreadId);
623 
627  void ThreadedProcessOutsideList(
628  unsigned int InputLayerNumber,
629  const StatusType& ChangeToStatus,
630  unsigned int InOrOut,
631  unsigned int BufferLayerNumber,
632  ThreadIdType ThreadId);
633 
635  void ThreadedPropagateLayerValues(
636  const StatusType& from,
637  const StatusType& to,
638  const StatusType& promote,
639  unsigned int InorOut,
640  ThreadIdType ThreadId);
641 
644  void GetThreadRegionSplitUniformly(
645  ThreadIdType ThreadId, ThreadRegionType & ThreadRegion);
646 
652  void ThreadedPostProcessOutput(const ThreadRegionType & regionToProcess);
653 
664  virtual void CheckLoadBalance();
665 
668  virtual void ThreadedLoadBalance(ThreadIdType ThreadId);
669 
671  void WaitForAll();
672 
673  void SignalNeighborsAndWait(ThreadIdType ThreadId);
674 
675  void SignalNeighbor(unsigned int SemaphoreArrayNumber, ThreadIdType ThreadId);
676 
677  void WaitForNeighbor(unsigned int SemaphoreArrayNumber, ThreadIdType ThreadId);
678 
681  virtual void ThreadedInitializeIteration(ThreadIdType ThreadId);
682 
685  // void WriteActivePointsToFile ();
686 
689 
691  unsigned int m_SplitAxis;
692 
694  unsigned int m_ZSize;
695 
699 
701  unsigned int *m_Boundary;
702 
705 
708  unsigned int *m_MapZToThreadNumber;
709 
713 
716 
718  struct ThreadData {
719  char pad1[128];
720 
724  unsigned int m_Count;
725 
728 
731 
734 
735  LayerPointerType UpList[2];
736  LayerPointerType DownList[2];
737 
740  LayerPointerType **m_InterNeighborNodeTransferBufferLayers[2];
741 
744  void *globalData;
745 
748 
753  int m_Semaphore[2];
754 
755  SimpleMutexLock m_Lock[2];
757 
761 
762  char m_Pad2[128];
763  };
764 
768 
771  bool m_Stop;
772 
778 
779 private:
780 
781  ParallelSparseFieldLevelSetImageFilter(const Self &); // purposely not
782  // implemented
783  void operator=(const Self &); // purposely not
784 
785  // implemented
786 
790 };
791 } // end namespace itk
792 
793 #ifndef ITK_MANUAL_INSTANTIATION
794 #include "itkParallelSparseFieldLevelSetImageFilter.hxx"
795 #endif
796 
797 #endif
798