File: elxProgressCommand.h

package info (click to toggle)
elastix 5.2.0-2
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 42,480 kB
  • sloc: cpp: 68,403; lisp: 4,118; python: 1,013; xml: 182; sh: 177; makefile: 33
file content (178 lines) | stat: -rw-r--r-- 5,717 bytes parent folder | download
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
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
/*=========================================================================
 *
 *  Copyright UMC Utrecht and contributors
 *
 *  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
 *
 *        http://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 elxProgressCommand_h
#define elxProgressCommand_h

#include "itkProcessObject.h"
#include "itkCommand.h"

namespace elastix
{

/**
 * \class ProgressCommand
 * \brief A specialized Command object for updating the progress of a
 *  filter.
 *
 * There are 3 ways to use this class.
 *
 * \li Whenever a filter, such as the itk::ResampleImageFilter, supports
 * a ProgressReporter, this class can be employed. This class makes
 * sure that the progress of a filter is printed to screen. It works
 * as follows:
 *
 * \code
 *   auto command = ProgressCommand::New();
 *   command->ConnectObserver( filterpointer );
 *   command->SetStartString( "  Progress: " );
 *   command->SetEndString( "%" );
 *   filterpointer->Update(); // run the filter, progress messages are printed now
 *   command->DisconnectObserver( filterPointer );
 * \endcode
 *
 * So, first an instantiation of this class is created, then it is
 * connected to a filter, and some options are set. Whenever the filter
 * throws a ProgressEvent(), this class asks for the progress and prints
 * the percentage of progress.
 *
 * \li In manually written loops, a call to UpdateAndPrintProgress() can be included.
 * Before the loop, the user should set the total number of loops, and the frequency
 * that the progress message should be printed with. For example
 *
 * \code
 *   auto command = ProgressCommand::New();
 *   command->SetUpdateFrequency( maxnrofvoxels, 100 );
 *   command->SetStartString( "  Progress: " );
 *   command->SetEndString( "%" );
 *   log::info(std::ostringstream{}  << "Looping over voxels... ");
 *   for ( unsigned int i =0; i < maxnrofvoxels; ++i )
 *   {
 *     command->UpdateAndPrintProgress( i );
 *   }
 *   command->PrintProgress(1.0); // make sure the 100% is reached
 * \endcode
 *
 * \li The last possibility is to directly use the PrintProgress function:
 *
 * \code
 *   auto command = ProgressCommand::New();
 *   command->SetStartString( "  Progress: " );
 *   command->SetEndString( "%" );
 *   // Reading, casting, writing...
 *   command->PrintProgress( 0.0 );
 *   reader->Update();
 *   command->PrintProgress( 0.33 );
 *   caster->Update();
 *   command->PrintProgress( 0.67 );
 *   writer->Update();
 *   command->PrintProgress( 1.0 );
 *   // example assumes reader, caster and writer have been configured before
 * \endcode
 *
 */

class ProgressCommand : public itk::Command
{
public:
  /** Smart pointer declaration methods. */
  using Self = ProgressCommand;
  using Superclass = itk::Command;
  using Pointer = itk::SmartPointer<Self>;
  using ConstPointer = itk::SmartPointer<const Self>;

  /** Standard ITK stuff. */
  itkTypeMacro(ProgressCommand, Command);
  itkNewMacro(Self);

  /** Typedef's. */
  using ProcessObjectType = itk::ProcessObject;
  using ProcessObjectPointer = ProcessObjectType::Pointer;

  /** Define when to print the progress. */
  virtual void
  SetUpdateFrequency(const unsigned long numberOfVoxels, const unsigned long numberOfUpdates);

  /** Connect an observer to a process object. */
  virtual void
  ConnectObserver(itk::ProcessObject * filter);

  /** Disconnect an observer to a process object. */
  void
  DisconnectObserver(itk::ProcessObject * filter);

  /** Standard Command virtual methods. */
  void
  Execute(itk::Object * caller, const itk::EventObject & event) override;

  void
  Execute(const itk::Object * caller, const itk::EventObject & event) override;

  /** Print the progress to screen. A float value between 0.0 and 1.0
   * is expected as input.
   */
  void
  PrintProgress(const float progress) const;

  /** Update and possibly print the progress to screen.
   * The progress information on screen is refreshed according to the
   * UpdateFrequency, which is assumed being specified beforehand using the
   * SetUpdateFrequency function.
   */
  void
  UpdateAndPrintProgress(const unsigned long currentVoxelNumber) const;

  /** Set and get the string starting each progress report. */
  itkSetStringMacro(StartString);
  itkGetStringMacro(StartString);

  /** Set and get the string ending each progress report. */
  itkSetStringMacro(EndString);
  itkGetStringMacro(EndString);

  static Pointer
  CreateAndSetUpdateFrequency(unsigned long numberOfVoxels);

  static Pointer
  CreateAndConnect(itk::ProcessObject &);

protected:
  /** The constructor. */
  ProgressCommand();

  /** The destructor. */
  ~ProgressCommand() override;

private:
  /** Member variables to define a start and end string for printing. */
  std::string m_StartString;
  std::string m_EndString;

  /** Member variables to keep track of what is set. */
  unsigned long        m_Tag;
  bool                 m_TagIsSet;
  ProcessObjectPointer m_ObservedProcessObject;

  /** Member variables that define the update frequency. */
  unsigned long m_NumberOfVoxels;
  unsigned long m_NumberOfUpdates;
};

} // end namespace elastix

#endif // end #ifndef elxProgressCommand_h