File: itkTotalProgressReporter.h

package info (click to toggle)
insighttoolkit5 5.4.4-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 704,404 kB
  • sloc: cpp: 783,697; ansic: 628,724; xml: 44,704; fortran: 34,250; python: 22,874; sh: 4,078; pascal: 2,636; lisp: 2,158; makefile: 461; yacc: 328; asm: 205; perl: 203; lex: 146; tcl: 132; javascript: 98; csh: 81
file content (134 lines) | stat: -rw-r--r-- 4,628 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
/*=========================================================================
 *
 *  Copyright NumFOCUS
 *
 *  Licensed under the Apache License, Version 2.0 (the "License");
 *  you may not use this file except in compliance with the License.
 *  You may obtain a copy of the License at
 *
 *         https://www.apache.org/licenses/LICENSE-2.0.txt
 *
 *  Unless required by applicable law or agreed to in writing, software
 *  distributed under the License is distributed on an "AS IS" BASIS,
 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *  See the License for the specific language governing permissions and
 *  limitations under the License.
 *
 *=========================================================================*/
#ifndef itkTotalProgressReporter_h
#define itkTotalProgressReporter_h

#include "itkIntTypes.h"
#include "itkProcessObject.h"

namespace itk
{
/** \class TotalProgressReporter
 *  \brief A progress reporter for concurrent threads.
 *
 * Each thread should construct their own instance of the class. The ProcessObject::IncrementProgress method will be
 * called to update the progress from all threads. The ProcessObject's method will automatically create ProgressEvents
 * when the pipeline invoking thread updates the progress.
 *
 * All threads concurrently contribute parts of the progress to the *total* number of pixels for all threads. This
 * report will update the progress after a sufficient number of pixel to meet the numberOfUpdates requirement between
 * all threads. Also when the object is deconstructed, all remaining pixels will increment the progress.
 *
 *
 * \ingroup ITKCommon
 */
class ITKCommon_EXPORT TotalProgressReporter
{
public:
  ITK_DISALLOW_COPY_AND_MOVE(TotalProgressReporter);

  /** \brief Construct a TotalProgressReporter
   *
   * @param filter - the ProcessObject which whose progress will be updated. If nullptr then no updates will occur.
   * @param totalNumberOfPixels - the number of pixels between all threads and chunks that will be updated.
   * If zero, any completed chunk will result in a progress event.
   * @param numberOfUpdates - controls how often the ProcessObject's progress will be incremented
   * @param progressWeight - A percentage of the filters progress, this total number of pixels will contribute
   */
  TotalProgressReporter(ProcessObject * filter,
                        SizeValueType   totalNumberOfPixels,
                        SizeValueType   numberOfUpdates = 100,
                        float           progressWeight = 1.0f);

  /** Destructor sets progress to 1 because the filter has finished.  */
  ~TotalProgressReporter();

  /** Check if the filter has the ProcessObject::AbortGenerateData
   * flag set. If true, then a ProcessAborted exception will be thrown.
   */
  void
  CheckAbortGenerateData()
  {
    // all threads needs to check the abort flag
    if (m_Filter && m_Filter->GetAbortGenerateData())
    {
      std::string    msg;
      ProcessAborted e(__FILE__, __LINE__);
      msg += "Object " + std::string(m_Filter->GetNameOfClass()) + ": AbortGenerateDataOn";
      e.SetDescription(msg);
      throw e;
    }
  }

  /** Called by a filter once per pixel.  */
  void
  CompletedPixel()
  {
    // Inline implementation for efficiency.
    if (--m_PixelsBeforeUpdate == 0)
    {
      m_PixelsBeforeUpdate = m_PixelsPerUpdate;
      m_CurrentPixel += m_PixelsPerUpdate;

      if (m_Filter)
      {
        m_Filter->IncrementProgress(m_PixelsPerUpdate * m_InverseNumberOfPixels * m_ProgressWeight);

        this->CheckAbortGenerateData();
      }
    }
  }


  /** Called by a filter when a chunk, region, scan-line, etc. is completed. */
  void
  Completed(SizeValueType count)
  {

    if (count >= m_PixelsBeforeUpdate)
    {
      SizeValueType total = static_cast<SizeValueType>(m_PixelsPerUpdate - m_PixelsBeforeUpdate) + count;
      SizeValueType numberOfUpdates = total / m_PixelsPerUpdate;

      m_PixelsBeforeUpdate = m_PixelsPerUpdate - total % m_PixelsPerUpdate;
      m_CurrentPixel += numberOfUpdates * m_PixelsPerUpdate;

      if (m_Filter)
      {
        m_Filter->IncrementProgress(numberOfUpdates * m_PixelsPerUpdate * m_InverseNumberOfPixels * m_ProgressWeight);

        this->CheckAbortGenerateData();
      }
    }
    else
    {
      m_PixelsBeforeUpdate -= count;
    }
  }

protected:
  ProcessObject * m_Filter;
  float           m_InverseNumberOfPixels;
  SizeValueType   m_CurrentPixel;
  SizeValueType   m_PixelsPerUpdate;
  SizeValueType   m_PixelsBeforeUpdate;
  float           m_ProgressWeight;
};
} // end namespace itk

#endif