Orfeo Toolbox  3.16
itkFiniteDifferenceSparseImageFilter.txx
Go to the documentation of this file.
1 /*=========================================================================
2 
3  Program: Insight Segmentation & Registration Toolkit
4  Module: $RCSfile: itkFiniteDifferenceSparseImageFilter.txx,v $
5  Language: C++
6  Date: $Date: 2008-10-16 23:25:41 $
7  Version: $Revision: 1.6 $
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 #ifndef __itkFiniteDifferenceSparseImageFilter_txx
18 #define __itkFiniteDifferenceSparseImageFilter_txx
19 
21 
22 namespace itk {
23 
24 template <class TInputImageType, class TSparseOutputImageType>
25 FiniteDifferenceSparseImageFilter <TInputImageType, TSparseOutputImageType>
27 {
28  m_SparseFunction = 0;
29  m_PrecomputeFlag = false;
30 }
31 
32 template <class TInputImageType, class TSparseOutputImageType>
33 void
35 ::PrintSelf(std::ostream& os, Indent indent) const
36 {
37  Superclass::PrintSelf(os, indent);
38  os << indent << "PrecomputeFlag: " << m_PrecomputeFlag << std::endl;
39 }
40 
41 template <class TInputImageType, class TSparseOutputImageType>
42 void
44 ::SetSparseFunction( SparseFunctionType *sf )
45 {
46  m_SparseFunction = sf;
47  Superclass::SetDifferenceFunction (sf);
48 }
49 
50 template <class TInputImageType, class TSparseOutputImageType>
51 void
53 ::Initialize()
54 {
55  m_RegionList=(this->GetOutput()->GetNodeList())
56  ->SplitRegions(this->GetNumberOfThreads());
57  // The active set of pixels in the sparse image is split into multi-threading
58  // regions once here for computationally efficiency.
59  // Later GetSplitRegions is used to access these partitions.
60  // This assumes that the active will not be changed until another
61  // call to Initialize(). Any reinitialization function also must call the
62  // SplitRegions function.
63 }
64 
65 template <class TInputImageType, class TSparseOutputImageType>
66 int
68 ::GetSplitRegion( int i, int num, ThreadRegionType &splitRegion )
69 {
70  splitRegion.first = m_RegionList[i].first;
71  splitRegion.last = m_RegionList[i].last;
72  return num;
73  // check this last line with the ITKdevelopers. not sure what this is doing
74  // copied it from FiniteDifferenceImageFilter class
75 }
76 
77 template<class TInputImageType, class TSparseOutputImageType>
78 void
81 {
82  // Set up for multithreaded processing.
83  FDThreadStruct str;
84  str.Filter = this;
85  str.TimeStep = dt;
86  this->GetMultiThreader()->SetNumberOfThreads(this->GetNumberOfThreads());
87  this->GetMultiThreader()->SetSingleMethod(this->ApplyUpdateThreaderCallback,
88  &str);
89  // Multithread the execution
90  this->GetMultiThreader()->SingleMethodExecute();
91 }
92 
93 template<class TInputImageType, class TSparseOutputImageType>
97 {
98  FDThreadStruct * str;
99  int total, threadId, threadCount;
100 
101  threadId = ((MultiThreader::ThreadInfoStruct *)(arg))->ThreadID;
102  threadCount = ((MultiThreader::ThreadInfoStruct *)(arg))->NumberOfThreads;
103  str = (FDThreadStruct *)
104  (((MultiThreader::ThreadInfoStruct *)(arg))->UserData);
105 
106  // Execute the actual method with appropriate output region
107  // first find out how many pieces extent can be split into.
108  // Use GetSplitRegion to access partition previously computed by
109  // the SplitRegions function in the SparseFieldLayer class.
110  ThreadRegionType splitRegion;
111  total = str->Filter->GetSplitRegion(threadId, threadCount, splitRegion);
112 
113  if (threadId < total)
114  {
115  str->Filter->ThreadedApplyUpdate(str->TimeStep, splitRegion, threadId);
116  }
117 
119 }
120 
121 template <class TInputImageType, class TSparseOutputImageType>
122 void
125  int)
126 {
127  typename NodeListType::Iterator it;
128 
129  for (it=regionToProcess.first; it != regionToProcess.last; ++it)
130  {
131  // all sparse image node types must have Data and Update members to be used
132  // with this filter
133  it->m_Data = this->DataConstraint (it->m_Data +
134  it->m_Update * dt);
135  }
136 }
137 
138 template <class TInputImageType, class TSparseOutputImageType>
139 void
142 {
143  // Set up for multithreaded processing.
144  FDThreadStruct str;
145  str.Filter = this;
146 
147  this->GetMultiThreader()->SetNumberOfThreads(this->GetNumberOfThreads());
148  this->GetMultiThreader()->SetSingleMethod
149  (this->PrecalculateChangeThreaderCallback,&str);
150 
151  // Multithread the execution
152  this->GetMultiThreader()->SingleMethodExecute();
153 }
154 
155 template <class TInputImageType, class TSparseOutputImageType>
156 typename FiniteDifferenceSparseImageFilter <TInputImageType,
157  TSparseOutputImageType>::TimeStepType
160 {
161  if (m_PrecomputeFlag == true)
162  {
163  this->PrecalculateChange();
164  }
165  int threadCount;
166  TimeStepType dt;
167 
168  // Set up for multithreaded processing.
169  FDThreadStruct str;
170  str.Filter = this;
171  str.TimeStep = NumericTraits<TimeStepType>::Zero;
172  // Not used during the calculate change step for normals.
173 
174  this->GetMultiThreader()->SetNumberOfThreads(this->GetNumberOfThreads());
175  this->GetMultiThreader()->SetSingleMethod
176  (this->CalculateChangeThreaderCallback,&str);
177 
178  // Initialize the list of time step values that will be generated by the
179  // various threads. There is one distinct slot for each possible thread,
180  // so this data structure is thread-safe. All of the time steps calculated
181  // in each thread will be combined in the ResolveTimeStepMethod.
182  threadCount = this->GetMultiThreader()->GetNumberOfThreads();
183  str.TimeStepList = new TimeStepType[threadCount];
184  str.ValidTimeStepList = new bool[threadCount];
185  for (int i =0; i < threadCount; ++i)
186  {
187  str.ValidTimeStepList[i] = false;
188  }
189 
190  // Multithread the execution
191  this->GetMultiThreader()->SingleMethodExecute();
192 
193  // Resolve the single value time step to return. The default implementation
194  // of ResolveTimeStep is to return the lowest value in the list that it is
195  // given.
196  dt = this->ResolveTimeStep(str.TimeStepList,
197  str.ValidTimeStepList, threadCount);
198 
199  delete [] str.TimeStepList;
200  delete [] str.ValidTimeStepList;
201 
202  return dt;
203 }
204 
205 template <class TInputImageType, class TSparseOutputImageType>
209 {
210  FDThreadStruct * str;
211  int total, threadId, threadCount;
212 
213  threadId = ((MultiThreader::ThreadInfoStruct *)(arg))->ThreadID;
214  threadCount = ((MultiThreader::ThreadInfoStruct *)(arg))->NumberOfThreads;
215 
216  str = (FDThreadStruct *)
217  (((MultiThreader::ThreadInfoStruct *)(arg))->UserData);
218 
219  // Execute the actual method with appropriate output region
220  // first find out how many pieces extent can be split into.
221  // Use GetSplitRegion to access partition previously computed by
222  // the Splitegions function in the SparseFieldLayer class.
223  ThreadRegionType splitRegion;
224  total = str->Filter->GetSplitRegion(threadId, threadCount, splitRegion);
225 
226  if( threadId < total )
227  {
228  str->TimeStepList[threadId]
229  = str->Filter->ThreadedCalculateChange(splitRegion, threadId);
230  str->ValidTimeStepList[threadId] = true;
231  }
232 
233  return ITK_THREAD_RETURN_VALUE;
234 }
235 
236 template <class TInputImageType, class TSparseOutputImageType>
240 {
241  FDThreadStruct * str;
242  int total, threadId, threadCount;
243 
244  threadId = ((MultiThreader::ThreadInfoStruct *)(arg))->ThreadID;
245  threadCount = ((MultiThreader::ThreadInfoStruct *)(arg))->NumberOfThreads;
246 
247  str = (FDThreadStruct *)
248  (((MultiThreader::ThreadInfoStruct *)(arg))->UserData);
249 
250  // Execute the actual method with appropriate output region
251  // first find out how many pieces extent can be split into.
252  // Use GetSplitRegion to access partition previously computed by
253  // the Splitegions function in the SparseFieldLayer class.
254  ThreadRegionType splitRegion;
255  total = str->Filter->GetSplitRegion(threadId, threadCount, splitRegion);
256 
257  if (threadId < total)
258  {
259  str->Filter->ThreadedPrecalculateChange(splitRegion, threadId);
260  }
261 
262  return ITK_THREAD_RETURN_VALUE;
263 }
264 
265 template <class TInputImageType, class TSparseOutputImageType>
266 typename FiniteDifferenceSparseImageFilter<TInputImageType,
267  TSparseOutputImageType>::TimeStepType
269 ::ThreadedCalculateChange( const ThreadRegionType &regionToProcess, int )
270 {
272  NeighborhoodIteratorType;
273 
274  typename SparseOutputImageType::Pointer output = this->GetOutput();
275 
276  TimeStepType timeStep;
277  void *globalData;
278 
279  const SizeType radius = m_SparseFunction->GetRadius();
280 
281  // Ask the function object for a pointer to a data structure it will use to
282  // manage any global values it needs. We'll pass this back to the function
283  // object at each calculation so that the function object can use it to
284  // determine a time step for this iteration.
285  globalData = m_SparseFunction->GetGlobalDataPointer();
286 
287  typename NodeListType::Iterator bandIt;
288  NeighborhoodIteratorType outputIt(radius, output,
289  output->GetRequestedRegion());
290 
291  // compute the update variables
292  for (bandIt = regionToProcess.first; bandIt != regionToProcess.last; ++bandIt)
293  {
294  outputIt.SetLocation (bandIt->m_Index);
295  outputIt.GetCenterPixel()->m_Update =
296  m_SparseFunction->ComputeSparseUpdate(outputIt, globalData);
297  }
298 
299  // Ask the finite difference function to compute the time step for
300  // this iteration. We give it the global data pointer to use, then
301  // ask it to free the global data memory.
302  timeStep = m_SparseFunction->ComputeGlobalTimeStep(globalData);
303  m_SparseFunction->ReleaseGlobalDataPointer(globalData);
304 
305  return timeStep;
306 }
307 
308 template <class TInputImageType, class TSparseOutputImageType>
309 void
311 ::ThreadedPrecalculateChange( const ThreadRegionType &regionToProcess, int )
312 {
314  NeighborhoodIteratorType;
315 
316  typename SparseOutputImageType::Pointer output = this->GetOutput();
317 
318  const SizeType radius = m_SparseFunction->GetRadius();
319 
320  typename NodeListType::Iterator bandIt;
321  NeighborhoodIteratorType outputIt(radius, output,
322  output->GetRequestedRegion());
323 
324  // the step for computing the flux variables
325  // these are used for computing the update in diffusion processes
326  // can disable these lines for non-diffusion processes
327  for (bandIt = regionToProcess.first; bandIt != regionToProcess.last; ++bandIt)
328  {
329  outputIt.SetLocation(bandIt->m_Index);
330  m_SparseFunction->PrecomputeSparseUpdate(outputIt);
331  }
332 
333 }
334 
335 } // end namespace itk
336 
337 #endif

Generated at Sat Feb 2 2013 23:38:07 for Orfeo Toolbox with doxygen 1.8.1.1