OTB  10.0.0
Orfeo Toolbox
otbObjectListToObjectListFilter.hxx
Go to the documentation of this file.
1 /*
2  * Copyright (C) 2005-2024 Centre National d'Etudes Spatiales (CNES)
3  *
4  * This file is part of Orfeo Toolbox
5  *
6  * https://www.orfeo-toolbox.org/
7  *
8  * Licensed under the Apache License, Version 2.0 (the "License");
9  * you may not use this file except in compliance with the License.
10  * You may obtain a copy of the License at
11  *
12  * http://www.apache.org/licenses/LICENSE-2.0
13  *
14  * Unless required by applicable law or agreed to in writing, software
15  * distributed under the License is distributed on an "AS IS" BASIS,
16  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17  * See the License for the specific language governing permissions and
18  * limitations under the License.
19  */
20 
21 #ifndef otbObjectListToObjectListFilter_hxx
22 #define otbObjectListToObjectListFilter_hxx
23 
25 #include "itkProgressReporter.h"
26 
27 namespace otb
28 {
29 
33 template <class TInputList, class TOutputList>
35 {
36  this->SetNumberOfRequiredInputs(1);
37 }
38 
39 template <class TInputList, class TOutputList>
41 {
42  // Process object is not const-correct so the const_cast is required here
43  this->itk::ProcessObject::SetNthInput(0, const_cast<InputListType*>(input));
44 }
45 
46 template <class TInputList, class TOutputList>
48 {
49  if (this->GetNumberOfInputs() < 1)
50  {
51  return nullptr;
52  }
53 
54  return static_cast<const TInputList*>(this->itk::ProcessObject::GetInput(0));
55 }
56 
57 template <class TInputList, class TOutputList>
58 int ObjectListToObjectListFilter<TInputList, TOutputList>::SplitRequestedRegion(itk::ThreadIdType threadId, int threadCount, unsigned int requestedElements,
59  unsigned int& startIndex, unsigned int& stopIndex)
60 {
61  startIndex = static_cast<unsigned int>(std::floor(requestedElements * static_cast<double>(threadId) / static_cast<double>(threadCount) + 0.5));
62  stopIndex = static_cast<unsigned int>(std::floor(requestedElements * static_cast<double>(threadId + 1) / static_cast<double>(threadCount) + 0.5));
63  if (stopIndex > requestedElements)
64  stopIndex = requestedElements;
65 
66  // Note: check the itkImageSource.hxx for the compuration done there.
67  // for now, there is no requested region for ObjectListFilter, so we don't
68  // compute anything here.
69  return threadCount;
70 }
71 
75 template <class TInputList, class TOutputList>
77 {
78  // Call a method that can be overridden by a subclass to perform
79  // some calculations prior to splitting the main computations into
80  // separate threads
81  this->BeforeThreadedGenerateData();
82 
83  // Set up the multithreaded processing
84  ThreadStruct str;
85  str.Filter = this;
86 
87  // Initializing object per thread
88  OutputListPointer defaultList;
89  this->m_ObjectListPerThread = OutputListForThreadType(this->GetNumberOfWorkUnits(), defaultList);
90 
91  // Setting up multithreader
92  this->GetMultiThreader()->SetNumberOfWorkUnits(this->GetNumberOfWorkUnits());
93  this->GetMultiThreader()->SetSingleMethod(this->ThreaderCallback, &str);
94 
95  // multithread the execution
96  this->GetMultiThreader()->SingleMethodExecute();
97 
98  // Call a method that can be overridden by a subclass to perform
99  // some calculations after all the threads have completed
100  this->AfterThreadedGenerateData();
101 }
102 
103 template <class TInputList, class TOutputList>
105 {
106  this->AllocateOutputs();
107 }
108 
109 template <class TInputList, class TOutputList>
110 void ObjectListToObjectListFilter<TInputList, TOutputList>::ThreadedGenerateData(unsigned int /*startIndex*/, unsigned int /*stopIndex*/,
111  itk::ThreadIdType /*threadId*/)
112 {
113  // The following code is equivalent to:
114  // itkExceptionMacro("subclass should override this method!!!");
115  // The ExceptionMacro is not used because gcc warns that a
116  // 'noreturn' function does return
117  std::ostringstream message;
118  message << "itk::ERROR: " << this->GetNameOfClass() << "(" << this << "): "
119  << "Subclass should override this method!!!";
120  itk::ExceptionObject e_(__FILE__, __LINE__, message.str(), ITK_LOCATION);
121  throw e_;
122 }
123 
124 template <class TInputList, class TOutputList>
125 itk::ITK_THREAD_RETURN_TYPE
128 {
129  ThreadStruct* str;
130  itk::ThreadIdType threadId, threadCount;
131  unsigned int total, start, stop;
132  unsigned int requestedElements;
133 
134  threadId = ((itk::MultiThreaderBase::WorkUnitInfo *) (arg))->WorkUnitID;
135  threadCount = ((itk::MultiThreaderBase::WorkUnitInfo *) (arg))->NumberOfWorkUnits;
136  str = (ThreadStruct *) (((itk::MultiThreaderBase::WorkUnitInfo *) (arg))->UserData);
137 
138  requestedElements = str->Filter->GetInput()->Size();
139  total = str->Filter->SplitRequestedRegion(threadId, threadCount, requestedElements, start, stop);
140 
141  if (threadId < static_cast<itk::ThreadIdType>(total))
142  {
143 
144  // For very small list it might occur that start = stop. In this
145  // case the vertex at that index will be processed in the next strip.
146  if (start != stop)
147  {
148  str->Filter->ThreadedGenerateData(start, stop, threadId);
149  }
150  }
151  // else
152  // {
153  // otherwise don't use this thread. Sometimes the threads don't
154  // break up very well and it is just as efficient to leave a
155  // few threads idle.
156  // }
157 
158  return itk::ITK_THREAD_RETURN_DEFAULT_VALUE;
159 }
160 
164 template <class TInputList, class TOutputList>
165 void ObjectListToObjectListFilter<TInputList, TOutputList>::PrintSelf(std::ostream& os, itk::Indent indent) const
166 {
167  Superclass::PrintSelf(os, indent);
168 }
169 
170 } // end namespace otb
171 
172 #endif
virtual void ThreadedGenerateData(unsigned int startIndex, unsigned int stopIndex, itk::ThreadIdType threadId)
void PrintSelf(std::ostream &os, itk::Indent indent) const override
virtual int SplitRequestedRegion(itk::ThreadIdType threadId, int threadCount, unsigned int requestedElements, unsigned int &startIndex, unsigned int &stopIndex)
virtual void SetInput(const InputListType *input)
static itk::ITK_THREAD_RETURN_TYPE ThreaderCallback(void *arg)
The "otb" namespace contains all Orfeo Toolbox (OTB) classes.