Orfeo Toolbox  4.0
otbObjectListToObjectListFilter.txx
Go to the documentation of this file.
1 /*=========================================================================
2 
3  Program: ORFEO Toolbox
4  Language: C++
5  Date: $Date$
6  Version: $Revision$
7 
8 
9  Copyright (c) Centre National d'Etudes Spatiales. All rights reserved.
10  See OTBCopyright.txt for details.
11 
12 
13  This software is distributed WITHOUT ANY WARRANTY; without even
14  the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
15  PURPOSE. See the above copyright notices for more information.
16 
17 =========================================================================*/
18 #ifndef __otbObjectListToObjectListFilter_txx
19 #define __otbObjectListToObjectListFilter_txx
20 
22 #include "itkProgressReporter.h"
23 
24 namespace otb
25 {
26 
30 template <class TInputList, class TOutputList>
33 {
34  this->SetNumberOfRequiredInputs(1);
35 }
36 
37 template <class TInputList, class TOutputList>
38 void
41 {
42 // Process object is not const-correct so the const_cast is required here
44  const_cast<InputListType *>(input));
45 }
46 
47 template <class TInputList, class TOutputList>
51 {
52  if (this->GetNumberOfInputs() < 1)
53  {
54  return 0;
55  }
56 
57  return static_cast<const TInputList *>
59 }
60 
61 template <class TInputList, class TOutputList>
62 int
65  int threadCount,
66  unsigned int requestedElements,
67  unsigned int& startIndex,
68  unsigned int& stopIndex)
69 {
70  startIndex = static_cast<unsigned int>(vcl_floor(
71  requestedElements * static_cast<double>(threadId) /
72  static_cast<double>(threadCount) + 0.5
73  ));
74  stopIndex = static_cast<unsigned int>(vcl_floor(
75  requestedElements *
76  static_cast<double>(threadId + 1) / static_cast<double>(threadCount) + 0.5
77  ));
78  if (stopIndex > requestedElements) stopIndex = requestedElements;
79 
80  //Note: check the itkImageSource.txx for the compuration done there.
81  // for now, there is no requested region for ObjectListFilter, so we don't
82  // compute anything here.
83  return threadCount;
84 }
85 
89 template <class TInputList, class TOutputList>
90 void
93 {
94  // Call a method that can be overridden by a subclass to perform
95  // some calculations prior to splitting the main computations into
96  // separate threads
97  this->BeforeThreadedGenerateData();
98 
99  // Set up the multithreaded processing
100  ThreadStruct str;
101  str.Filter = this;
102 
103  // Initializing object per thread
104  OutputListPointer defaultList;
105  this->m_ObjectListPerThread = OutputListForThreadType(this->GetNumberOfThreads(), defaultList);
106 
107  // Setting up multithreader
108  this->GetMultiThreader()->SetNumberOfThreads(this->GetNumberOfThreads());
109  this->GetMultiThreader()->SetSingleMethod(this->ThreaderCallback, &str);
110 
111  // multithread the execution
112  this->GetMultiThreader()->SingleMethodExecute();
113 
114  // Call a method that can be overridden by a subclass to perform
115  // some calculations after all the threads have completed
116  this->AfterThreadedGenerateData();
117 
118 }
119 
120 template <class TInputList, class TOutputList>
121 void
124 {
125  this->AllocateOutputs();
126 }
127 
128 template <class TInputList, class TOutputList>
129 void
131 ::ThreadedGenerateData(unsigned int /*startIndex*/, unsigned int /*stopIndex*/, itk::ThreadIdType /*threadId*/)
132 {
133  // The following code is equivalent to:
134  // itkExceptionMacro("subclass should override this method!!!");
135  // The ExceptionMacro is not used because gcc warns that a
136  // 'noreturn' function does return
137  std::ostringstream message;
138  message << "itk::ERROR: " << this->GetNameOfClass()
139  << "(" << this << "): " << "Subclass should override this method!!!";
140  itk::ExceptionObject e_(__FILE__, __LINE__, message.str().c_str(), ITK_LOCATION);
141  throw e_;
142 
143 }
144 
145 template <class TInputList, class TOutputList>
149 {
150  ThreadStruct *str;
151  itk::ThreadIdType threadId, threadCount;
152  unsigned int total, start, stop;
153  unsigned int requestedElements;
154 
155  threadId = ((itk::MultiThreader::ThreadInfoStruct *) (arg))->ThreadID;
156  threadCount = ((itk::MultiThreader::ThreadInfoStruct *) (arg))->NumberOfThreads;
157  str = (ThreadStruct *) (((itk::MultiThreader::ThreadInfoStruct *) (arg))->UserData);
158 
159  requestedElements = str->Filter->GetInput()->Size();
160  total = str->Filter->SplitRequestedRegion(threadId, threadCount, requestedElements, start, stop);
161 
162  if (threadId < static_cast<itk::ThreadIdType>(total))
163  {
164 
165  // For very small list it might occur that start = stop. In this
166  // case the vertex at that index will be processed in the next strip.
167  if (start != stop)
168  {
169  str->Filter->ThreadedGenerateData(start, stop, threadId);
170  }
171  }
172  // else
173  // {
174  // otherwise don't use this thread. Sometimes the threads dont
175  // break up very well and it is just as efficient to leave a
176  // few threads idle.
177  // }
178 
180 }
181 
185 template <class TInputList, class TOutputList>
186 void
188 ::PrintSelf(std::ostream& os, itk::Indent indent) const
189 {
190  Superclass::PrintSelf(os, indent);
191 }
192 
193 } // end namespace otb
194 
195 #endif

Generated at Sat Mar 8 2014 16:11:42 for Orfeo Toolbox with doxygen 1.8.3.1