ITK  4.13.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< typename TNodeIndexType >
37 class ITK_TEMPLATE_EXPORT ParallelSparseFieldLevelSetNode
38 {
39 public:
40  TNodeIndexType m_Index;
41  float m_Value;
44 };
45 
74 template< typename 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< typename TInputImage, typename TOutputImage >
249 class ITK_TEMPLATE_EXPORT ParallelSparseFieldLevelSetImageFilter:
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;
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 
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  // Begin concept checking
335  itkConceptMacro( OutputEqualityComparableCheck,
337  itkConceptMacro( DoubleConvertibleToOutputCheck,
339  itkConceptMacro( OutputOStreamWritableCheck,
341  // End concept checking
342 #endif
343 
344 protected:
347  virtual void PrintSelf(std::ostream & os, Indent indent) const ITK_OVERRIDE;
348 
352 
356 
359 
362 
366 
370 
374 
378 
382 
387  typename OutputImageType::Pointer m_ShiftedImage;
388 
394 
400 
403  typename OutputImageType::Pointer m_OutputImage;
404 
408  typename OutputImageType::Pointer m_OutputImageTemp;
409 
412 
415 
419  // ValueType m_RMSChange;
420 
423  virtual void GenerateData() ITK_OVERRIDE;
424 
429  void CopyInputToOutput() ITK_OVERRIDE;
430 
432  void AllocateUpdateBuffer() ITK_OVERRIDE {}
433 
436  void Initialize() ITK_OVERRIDE;
437 
442  void ConstructActiveLayer();
443 
445  void InitializeActiveLayerValues();
446 
450  void ConstructLayer(const StatusType& from, const StatusType& to);
451 
453  void ProcessStatusList(LayerType *InputList, const StatusType& ChangeToStatus,
454  const StatusType& SearchForStatus, ThreadIdType ThreadId);
455 
460  void PropagateAllLayerValues();
461 
469  void PropagateLayerValues(const StatusType& from, const StatusType& to,
470  const StatusType& promote, unsigned int InOrOut);
471 
476  virtual void InitializeBackgroundPixels();
477 
481  void ThreadedAllocateData(ThreadIdType ThreadId);
482 
483  void ThreadedInitializeData(ThreadIdType ThreadId, const ThreadRegionType & ThreadRegion);
484 
494  void ComputeInitialThreadBoundaries();
495 
497  unsigned int GetThreadNumber(unsigned int splitAxisValue);
498 
500  void GetThreadRegionSplitByBoundary(ThreadIdType ThreadId, ThreadRegionType & ThreadRegion);
501 
504  void DeallocateData();
505 
509  std::vector< TimeStepType > TimeStepList;
510  std::vector< bool > ValidTimeStepList;
512  };
513 
518  void Iterate();
519 
520  static ITK_THREAD_RETURN_TYPE IterateThreaderCallback(void *arg);
521 
526  inline virtual ValueType ThreadedCalculateUpdateValue(const ThreadIdType itkNotUsed(ThreadId),
527  const IndexType itkNotUsed(index),
528  const TimeStepType & dt,
529  const ValueType & value,
530  const ValueType & change)
531  {
532  return ( value + static_cast< ValueType >( dt ) * change );
533  }
534 
535  // This method can be overridden in derived classes.
536  // The pixel at 'index' is entering the active layer for thread 'ThreadId'.
537  // The outputimage at 'index' will have the value as given by the
538  // 'value' parameter.
539  virtual void ThreadedProcessPixelEnteringActiveLayer( const IndexType& itkNotUsed(index),
540  const ValueType& itkNotUsed(value),
541  ThreadIdType itkNotUsed(ThreadId) );
542 
544  void ApplyUpdate(const TimeStepType&) ITK_OVERRIDE {}
545 
548  virtual void ThreadedApplyUpdate(const TimeStepType& dt, ThreadIdType ThreadId);
549 
552  {
554  }
555 
558  virtual TimeStepType ThreadedCalculateChange(ThreadIdType ThreadId);
559 
566  void ThreadedUpdateActiveLayerValues( const TimeStepType& dt,
567  LayerType *StatusUpList,
568  LayerType *StatusDownList,
569  ThreadIdType ThreadId);
570 
573  void CopyInsertList( ThreadIdType ThreadId,
574  LayerPointerType FromListPtr,
575  LayerPointerType ToListPtr);
576 
578  void ClearList(ThreadIdType ThreadId, LayerPointerType ListPtr);
579 
582  void CopyInsertInterNeighborNodeTransferBufferLayers(
583  ThreadIdType ThreadId,
584  LayerPointerType InputList,
585  unsigned int InOrOut,
586  unsigned int BufferLayerNumber);
587 
590  void ClearInterNeighborNodeTransferBufferLayers(
591  ThreadIdType ThreadId, unsigned int InOrOut,
592  unsigned int BufferLayerNumber);
593 
601  void ThreadedProcessFirstLayerStatusLists(
602  unsigned int InputLayerNumber,
603  unsigned int OutputLayerNumber,
604  const StatusType& SearchForStatus,
605  unsigned int InOrOut,
606  unsigned int BufferLayerNumber,
607  ThreadIdType ThreadId);
608 
614  void ThreadedProcessStatusList(
615  unsigned int InputLayerNumber,
616  unsigned int OutputLayerNumber,
617  const StatusType& ChangeToStatus,
618  const StatusType& SearchForStatus,
619  unsigned int InOrOut,
620  unsigned int BufferLayerNumber,
621  ThreadIdType ThreadId);
622 
626  void ThreadedProcessOutsideList(
627  unsigned int InputLayerNumber,
628  const StatusType& ChangeToStatus,
629  unsigned int InOrOut,
630  unsigned int BufferLayerNumber,
631  ThreadIdType ThreadId);
632 
634  void ThreadedPropagateLayerValues(
635  const StatusType& from,
636  const StatusType& to,
637  const StatusType& promote,
638  unsigned int InorOut,
639  ThreadIdType ThreadId);
640 
643  void GetThreadRegionSplitUniformly(
644  ThreadIdType ThreadId, ThreadRegionType & ThreadRegion);
645 
651  void ThreadedPostProcessOutput(const ThreadRegionType & regionToProcess);
652 
663  virtual void CheckLoadBalance();
664 
667  virtual void ThreadedLoadBalance(ThreadIdType ThreadId);
668 
670  void WaitForAll();
671 
672  void SignalNeighborsAndWait(ThreadIdType ThreadId);
673 
674  void SignalNeighbor(unsigned int SemaphoreArrayNumber, ThreadIdType ThreadId);
675 
676  void WaitForNeighbor(unsigned int SemaphoreArrayNumber, ThreadIdType ThreadId);
677 
680  virtual void ThreadedInitializeIteration(ThreadIdType ThreadId);
681 
684  // void WriteActivePointsToFile ();
685 
688 
690  unsigned int m_SplitAxis;
691 
693  unsigned int m_ZSize;
694 
698 
700  unsigned int *m_Boundary;
701 
704 
707  unsigned int *m_MapZToThreadNumber;
708 
712 
715 
717  struct ThreadData {
718  char pad1[128];
719 
723  unsigned int m_Count;
724 
727 
730 
733 
734  LayerPointerType UpList[2];
735  LayerPointerType DownList[2];
736 
739  LayerPointerType **m_InterNeighborNodeTransferBufferLayers[2];
740 
743  void *globalData;
744 
747 
752  int m_Semaphore[2];
753 
754  SimpleMutexLock m_Lock[2];
756 
760 
761  char m_Pad2[128];
762  };
763 
767 
770  bool m_Stop;
771 
777 
778 private:
779 
780  ITK_DISALLOW_COPY_AND_ASSIGN(ParallelSparseFieldLevelSetImageFilter);
781 
785 };
786 } // end namespace itk
787 
788 #ifndef ITK_MANUAL_INSTANTIATION
789 #include "itkParallelSparseFieldLevelSetImageFilter.hxx"
790 #endif
791 
792 #endif
A convenience class for storing indices which reference neighbor pixels within a neighborhood.
Superclass::FiniteDifferenceFunctionType FiniteDifferenceFunctionType
ParallelSparseFieldLevelSetNode< IndexType > LayerNodeType
ParallelSparseFieldCityBlockNeighborList< NeighborhoodIterator< OutputImageType > > m_NeighborList
Base class for all process objects that output image data.
Offset< itkGetStaticConstMacro(ImageDimension) > OffsetType
#define ITK_THREAD_RETURN_TYPE
virtual ValueType ThreadedCalculateUpdateValue(const ThreadIdType, const IndexType, const TimeStepType &dt, const ValueType &value, const ValueType &change)
This class implements a finite difference partial differential equation solver for evolving surfaces ...
FiniteDifferenceImageFilter< TInputImage, TOutputImage > Superclass
Superclass::RadiusType RadiusType
unsigned int ThreadIdType
Definition: itkIntTypes.h:159
FiniteDifferenceFunctionType::TimeStepType TimeStepType
Control indentation during Print() invocation.
Definition: itkIndent.h:49
A very simple linked list that is used to manage nodes in a layer of a sparse field level-set solver...
#define itkConceptMacro(name, concept)
Image< StatusType, itkGetStaticConstMacro(ImageDimension) > StatusImageType
A specialized memory management object for allocating and destroying contiguous blocks of objects...
Templated n-dimensional image class.
Definition: itkImage.h:75
Simple mutual exclusion locking class.
Definition: itkMutexLock.h:48