KWStyle - itkDenseFiniteDifferenceImageFilter.txx
 
Matrix View
Description

1 /*=========================================================================
2
3   Program:   Insight Segmentation & Registration Toolkit
4   Module:    $RCSfile: itkDenseFiniteDifferenceImageFilter.txx.html,v $
5   Language:  C++
6   Date:      $Date: 2006/01/17 19:15:34 $
7   Version:   $Revision: 1.4 $
8
9   Copyright (c) Insight Software Consortium. All rights reserved.
10   See ITKCopyright.txt or http://www.itk.org/HTML/Copyright.htm for details.
11
12      This software is distributed WITHOUT ANY WARRANTY; without even 
13      the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR 
14      PURPOSE.  See the above copyright notices for more information.
15
16 =========================================================================*/
17 DEF #ifndef __itkDenseFiniteDifferenceImageFilter_txx_
18 DEF #define __itkDenseFiniteDifferenceImageFilter_txx_
19 #include "itkDenseFiniteDifferenceImageFilter.h"
20
21 #include <list>
22 #include "itkImageRegionConstIterator.h"
23 #include "itkImageRegionIterator.h"
24 #include "itkNumericTraits.h"
25 #include "itkNeighborhoodAlgorithm.h"
26
27 namespace itk {
28
29 template <class TInputImage, class TOutputImage>
30 void
31 DenseFiniteDifferenceImageFilter<TInputImage, TOutputImage>
32 ::CopyInputToOutput()
33 {
34   typename TInputImage::ConstPointer  input  = this->GetInput();
35   typename TOutputImage::Pointer      output = this->GetOutput();
36
37   if ( !input || !output )
38     {
39     itkExceptionMacro(<< "Either input and/or output is NULL.");
40     }
41
42   // Check if we are doing in-place filtering
43   if ( this->GetInPlace() && (typeid(TInputImage) == typeid(TOutputImage)) )
44     {
45     typename TInputImage::Pointer tempPtr = 
46 IND ******dynamic_cast<TInputImage *>( output.GetPointer() );
47     if ( tempPtr && tempPtr->GetPixelContainer() == input->GetPixelContainer() )
48       {
49       // the input and output container are the same - no need to copy
50       return;
51       }
52     }
53   
54 LEN   ImageRegionConstIterator<TInputImage>  in(input, output->GetRequestedRegion());
55   ImageRegionIterator<TOutputImage> out(output, output->GetRequestedRegion());
56
57   while( ! out.IsAtEnd() )
58     {
59 LEN     out.Value() =  static_cast<PixelType>(in.Get());  // Supports input image adaptors only
60     ++in;
61     ++out;
62     }
63 }
64
65 template <class TInputImage, class TOutputImage>
66 void
67 DenseFiniteDifferenceImageFilter<TInputImage, TOutputImage>
68 ::AllocateUpdateBuffer()
69 {
70   // The update buffer looks just like the output.
71   typename TOutputImage::Pointer output = this->GetOutput();
72
73   m_UpdateBuffer->SetLargestPossibleRegion(output->GetLargestPossibleRegion());
74   m_UpdateBuffer->SetRequestedRegion(output->GetRequestedRegion());
75   m_UpdateBuffer->SetBufferedRegion(output->GetBufferedRegion());
76   m_UpdateBuffer->Allocate();
77 }
78
79 template<class TInputImage, class TOutputImage>
80 void
81 DenseFiniteDifferenceImageFilter<TInputImage, TOutputImage>
82 ::ApplyUpdate(TimeStepType dt)
83 {
84   // Set up for multithreaded processing.
85   DenseFDThreadStruct str;
86   str.Filter = this;
87   str.TimeStep = dt;
88   this->GetMultiThreader()->SetNumberOfThreads(this->GetNumberOfThreads());
89   this->GetMultiThreader()->SetSingleMethod(this->ApplyUpdateThreaderCallback,
90                                             &str);
91   // Multithread the execution
92   this->GetMultiThreader()->SingleMethodExecute();
93 }
94
95 template<class TInputImage, class TOutputImage>
96 ITK_THREAD_RETURN_TYPE
97 DenseFiniteDifferenceImageFilter<TInputImage, TOutputImage>
98 ::ApplyUpdateThreaderCallback( void * arg )
99 {
100   DenseFDThreadStruct * str;
101   int total, threadId, threadCount;
102
103   threadId = ((MultiThreader::ThreadInfoStruct *)(arg))->ThreadID;
104   threadCount = ((MultiThreader::ThreadInfoStruct *)(arg))->NumberOfThreads;
105
106 LEN   str = (DenseFDThreadStruct *)(((MultiThreader::ThreadInfoStruct *)(arg))->UserData);
107
108   // Execute the actual method with appropriate output region
109   // first find out how many pieces extent can be split into.
110   // Using the SplitRequestedRegion method from itk::ImageSource.
111   ThreadRegionType splitRegion;
112   total = str->Filter->SplitRequestedRegion(threadId, threadCount,
113                                             splitRegion);
114   
115   if (threadId < total)
116     {
117     str->Filter->ThreadedApplyUpdate(str->TimeStep, splitRegion, threadId);
118     }
119
120   return ITK_THREAD_RETURN_VALUE;
121 }
122
123 template <class TInputImage, class TOutputImage>
124 typename
125 DenseFiniteDifferenceImageFilter<TInputImage, TOutputImage>::TimeStepType
126 DenseFiniteDifferenceImageFilter<TInputImage, TOutputImage>
127 ::CalculateChange()
128 {
129   int threadCount;
130   TimeStepType dt;
131
132   // Set up for multithreaded processing.
133   DenseFDThreadStruct str;
134   str.Filter = this;
135   str.TimeStep = NumericTraits<TimeStepType>::Zero;  // Not used during the
136   // calculate change step.
137   this->GetMultiThreader()->SetNumberOfThreads(this->GetNumberOfThreads());
138 LEN   this->GetMultiThreader()->SetSingleMethod(this->CalculateChangeThreaderCallback,
139                                             &str);
140
141   // Initialize the list of time step values that will be generated by the
142   // various threads.  There is one distinct slot for each possible thread,
143   // so this data structure is thread-safe.
144   threadCount = this->GetMultiThreader()->GetNumberOfThreads();  
145   str.TimeStepList = new TimeStepType[threadCount];                 
146   str.ValidTimeStepList = new bool[threadCount];
147   for (int i =0; i < threadCount; ++i)
148     {      str.ValidTimeStepList[i] = false;    } 
149
150   // Multithread the execution
151   this->GetMultiThreader()->SingleMethodExecute();
152
153   // Resolve the single value time step to return
154 LEN   dt = this->ResolveTimeStep(str.TimeStepList, str.ValidTimeStepList, threadCount);
155   delete [] str.TimeStepList;
156   delete [] str.ValidTimeStepList;
157
158   return  dt;
159 }
160
161 template <class TInputImage, class TOutputImage>
162 ITK_THREAD_RETURN_TYPE
163 DenseFiniteDifferenceImageFilter<TInputImage, TOutputImage>
164 ::CalculateChangeThreaderCallback( void * arg )
165 {
166   DenseFDThreadStruct * str;
167   int total, threadId, threadCount;
168
169   threadId = ((MultiThreader::ThreadInfoStruct *)(arg))->ThreadID;
170   threadCount = ((MultiThreader::ThreadInfoStruct *)(arg))->NumberOfThreads;
171
172 LEN   str = (DenseFDThreadStruct *)(((MultiThreader::ThreadInfoStruct *)(arg))->UserData);
173
174   // Execute the actual method with appropriate output region
175   // first find out how many pieces extent can be split into.
176   // Using the SplitRequestedRegion method from itk::ImageSource.
177   ThreadRegionType splitRegion;
178
179   total = str->Filter->SplitRequestedRegion(threadId, threadCount,
180                                             splitRegion);
181
182   if (threadId < total)
183     { 
184     str->TimeStepList[threadId]
185 IND ******= str->Filter->ThreadedCalculateChange(splitRegion, threadId);
186     str->ValidTimeStepList[threadId] = true;
187     }
188
189   return ITK_THREAD_RETURN_VALUE;  
190 }
191
192 template <class TInputImage, class TOutputImage>
193 void
194 DenseFiniteDifferenceImageFilter<TInputImage, TOutputImage>
195 ::ThreadedApplyUpdate(TimeStepType dt, const ThreadRegionType ®ionToProcess,
196                       int)
197 {
198   ImageRegionIterator<UpdateBufferType> u(m_UpdateBuffer,    regionToProcess);
199   ImageRegionIterator<OutputImageType>  o(this->GetOutput(), regionToProcess);
200
201   u = u.Begin();
202   o = o.Begin();
203
204   while ( !u.IsAtEnd() )
205     {
206 LEN     o.Value() += static_cast<PixelType>(u.Value() * dt);  // no adaptor support here
207     ++o;
208     ++u;
209     }
210 }
211
212 template <class TInputImage, class TOutputImage>
213 typename
214 DenseFiniteDifferenceImageFilter<TInputImage, TOutputImage>::TimeStepType
215 DenseFiniteDifferenceImageFilter<TInputImage, TOutputImage>
216 ::ThreadedCalculateChange(const ThreadRegionType ®ionToProcess, int)
217 {
218   typedef typename OutputImageType::RegionType RegionType;
219   typedef typename OutputImageType::SizeType   SizeType;
220 TDA   typedef typename OutputImageType::SizeValueType   SizeValueType;
221   typedef typename OutputImageType::IndexType  IndexType;
222 TDA   typedef typename OutputImageType::IndexValueType  IndexValueType;
223   typedef typename FiniteDifferenceFunctionType::NeighborhoodType
224 TDA,IND ****NeighborhoodIteratorType;
225 TDA   typedef ImageRegionIterator<UpdateBufferType> UpdateIteratorType;
226
227   typename OutputImageType::Pointer output = this->GetOutput();
228   TimeStepType timeStep;
229   void *globalData;
230
231   // Get the FiniteDifferenceFunction to use in calculations.
232   const typename FiniteDifferenceFunctionType::Pointer df
233 IND ****= this->GetDifferenceFunction();
234   const SizeType  radius = df->GetRadius();
235   
236   // Break the input into a series of regions.  The first region is free
237   // of boundary conditions, the rest with boundary conditions.  We operate
238   // on the output region because input has been copied to output.
239   typedef NeighborhoodAlgorithm::ImageBoundaryFacesCalculator<OutputImageType>
240 IND ****FaceCalculatorType;
241 TDA   typedef typename FaceCalculatorType::FaceListType FaceListType;
242
243   FaceCalculatorType faceCalculator;
244     
245   FaceListType faceList = faceCalculator(output, regionToProcess, radius);
246   typename FaceListType::iterator fIt = faceList.begin();
247
248   // Ask the function object for a pointer to a data structure it
249   // will use to manage any global values it needs.  We'll pass this
250   // back to the function object at each calculation and then
251   // again so that the function object can use it to determine a
252   // time step for this iteration.
253   globalData = df->GetGlobalDataPointer();
254
255   // Process the non-boundary region.
256   NeighborhoodIteratorType nD(radius, output, *fIt);
257   UpdateIteratorType       nU(m_UpdateBuffer,  *fIt);
258   nD.GoToBegin();
259   while( !nD.IsAtEnd() )
260     {
261     nU.Value() = df->ComputeUpdate(nD, globalData);
262     ++nD;
263     ++nU;
264     }
265
266   // Process each of the boundary faces.
267
268   NeighborhoodIteratorType bD;
269   UpdateIteratorType   bU;
270   for (++fIt; fIt != faceList.end(); ++fIt)
271     {
272     bD = NeighborhoodIteratorType(radius, output, *fIt);
273     bU = UpdateIteratorType  (m_UpdateBuffer, *fIt);
274      
275     bD.GoToBegin();
276     bU.GoToBegin();
277     while ( !bD.IsAtEnd() )
278       {
279       bU.Value() = df->ComputeUpdate(bD, globalData);
280       ++bD;
281       ++bU;
282       }
283     }
284
285   // Ask the finite difference function to compute the time step for
286   // this iteration.  We give it the global data pointer to use, then
287   // ask it to free the global data memory.
288   timeStep = df->ComputeGlobalTimeStep(globalData);
289   df->ReleaseGlobalDataPointer(globalData);
290
291   return timeStep;
292 }
293
294 template <class TInputImage, class TOutputImage>
295 void
296 DenseFiniteDifferenceImageFilter<TInputImage, TOutputImage>
297 ::PrintSelf(std::ostream& os, Indent indent) const
298 {
299   Superclass::PrintSelf(os, indent);
300
301   
302 }
303
304 }// end namespace itk
305
306 #endif
307

Generated by KWStyle 1.0b on Tuesday January,17 at 02:14:05PM
© Kitware Inc.