DMRITool  v0.1.1-139-g860d86b4
Diffusion MRI Tool
itkCommandProgressUpdate.h
Go to the documentation of this file.
1 /*=========================================================================
2 
3  Program: Command Progress Update
4 
5  Copyright (c) Pew-Thian Yap. All rights reserved.
6  See http://www.unc.edu/~ptyap/ for details.
7 
8  This software is distributed WITHOUT ANY WARRANTY; without even
9  the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
10  PURPOSE. See the above copyright notices for more information.
11 
12  =========================================================================*/
13 
14 #ifndef __itkCommandProgressUpdate_h
15 #define __itkCommandProgressUpdate_h
16 
17 #include "itkCommand.h"
18 #include "itkObject.h"
19 #include "itkProcessObject.h"
20 #include "itkTimeProbe.h"
21 #include "itkRealTimeClock.h"
22 #include <iostream>
23 #include <iomanip>
24 
25 namespace itk
26 {
27 
33 class CommandProgressUpdate : public Command
34 {
35 public:
37  typedef Command Superclass;
38  typedef SmartPointer<Self> Pointer;
39  itkNewMacro(Self);
40 
41  typedef RealTimeClock ClockType;
42  typedef ClockType::TimeStampType TimeStampType;
43 
44  itkSetMacro(UseColor, bool);
45  itkGetConstMacro(UseColor, bool);
46  itkBooleanMacro(UseColor);
47 
48  typedef enum {LIST=0, BAR} StyleType;
49  const static unsigned int NumberOfBarSegments = 20;
50 
51  itkSetMacro(Style, StyleType);
52  itkGetConstMacro(Style, StyleType);
53 
54 protected:
56  {
57  this->UseColorOn();
58  m_Style = BAR;
59  m_SuppressOutput = false; // avoid repeating output for 100%
60  m_Clock = ClockType::New();
61  m_StartTimeStamp = m_Clock->GetTimeInSeconds();
62  m_LastProgress = 0;
63  }
64 
65 private:
66  TimeProbe clock;
67  bool m_UseColor;
68  StyleType m_Style;
70  ClockType::Pointer m_Clock;
71  TimeStampType m_StartTimeStamp;
73 
74 public:
75  void Execute(Object *caller, const EventObject & event) ITK_OVERRIDE
76  {
77  Execute( (const Object *)caller, event );
78  }
79 
80  void Execute(const Object * object, const EventObject & event) ITK_OVERRIDE
81  {
82  const ProcessObject * filter =
83  dynamic_cast< const ProcessObject * >(object);
84  if (!ProgressEvent().CheckEvent( &event ))
85  {
86  return;
87  }
88  // In case filter needs to be executed multiple times
89  if (m_SuppressOutput)
90  {
91  m_SuppressOutput = false;
92  return;
93  }
94  float progress = filter->GetProgress();
95  unsigned int progressInRoundedPercent =
96  static_cast<unsigned int>( 100 * progress );
97 
98  std::string redPrefix = "";
99  std::string greenPrefix = "";
100  std::string yellowPrefix = "";
101  std::string bluePrefix = "";
102  std::string magentaPrefix = "";
103  std::string cyanPrefix = "";
104  std::string suffix = "";
105 
106  if ( m_UseColor )
107  {
108  redPrefix = "\033[1;31m";
109  greenPrefix = "\033[32m";
110  yellowPrefix = "\033[33m";
111  bluePrefix = "\033[1;34m";
112  magentaPrefix = "\033[35m";
113  cyanPrefix = "\033[36m";
114  suffix = "\033[0m";
115  }
116 
117  switch ( m_Style )
118  {
119  case LIST:
120 
121  std::cout << " >>>> "
122  // << std::setiosflags(std::ios::fixed)
123  // << std::setprecision(2)
124  << yellowPrefix
125  << std::setw(3)
126  << std::setiosflags(std::ios::right)
127  << progressInRoundedPercent << "%"
128  << suffix << " completed" << std::flush;
129 
130  if ( progress == 0 )
131  {
132  m_SuppressOutput = false;
133  std::cout << std::endl;
134  clock.Start();
135  }
136  else
137  {
138  clock.Stop();
139  std::cout
140  << ", "
141  << magentaPrefix
142  << std::setiosflags(std::ios::fixed)
143  << std::setprecision(3)
144  // << std::setw(5)
145  // << setiosflags(std::ios::right)
146  << clock.GetMean() << "s" << suffix << " elapsed" << std::endl;
147  std::cout.precision(6);
148  clock.Start();
149  }
150  if (progress == 1) m_SuppressOutput = true;
151  break;
152 
153  case BAR:
154  if ( progress == 0 )
155  {
156  m_LastProgress = progress;
157  m_SuppressOutput = false;
158  m_StartTimeStamp = m_Clock->GetTimeInSeconds();
159  clock.Start();
160  }
161 
162  clock.Stop();
163 
164  std::cout
165 // << "\e[?25l"
166  << "\r"
167  << yellowPrefix
168  << std::setw(3)
169  << std::setiosflags(std::ios::right)
170  << progressInRoundedPercent << "%" << suffix << std::flush;
171 
172  std::cout << " [" << std::flush;
173  for (unsigned int k=0; k<NumberOfBarSegments+1; k++)
174  {
175  if ( k == (unsigned int)(progress * NumberOfBarSegments) )
176  {
177  std::cout << greenPrefix << ">" << suffix << std::flush;
178  }
179  else if ( k < (unsigned int)(progress * NumberOfBarSegments) )
180  {
181  std::cout << greenPrefix << "=" << suffix << std::flush;
182  }
183  else
184  {
185  std::cout << " " << std::flush;
186  }
187  }
188 
189  if ( progress < 1 )
190  {
191  unsigned int secondsLeft = (unsigned int)
192  (clock.GetMean() * (1 - progress) * 100 + 0.5);
193  unsigned int hoursLeft = secondsLeft/3600;
194  secondsLeft = secondsLeft % 3600;
195  unsigned int minutesLeft = secondsLeft/60;
196  secondsLeft = secondsLeft % 60;
197 
198  unsigned int secondsElapsed = (unsigned int)
199  (m_Clock->GetTimeInSeconds() - m_StartTimeStamp + 0.5);
200  unsigned int hoursElapsed = secondsElapsed/3600;
201  secondsElapsed = secondsElapsed % 3600;
202  unsigned int minutesElapsed = secondsElapsed/60;
203  secondsElapsed = secondsElapsed % 60;
204 
205  float secondsPerPercent;
206 
207  if ( progress > 0.01 )
208  {
209  secondsPerPercent = clock.GetMean()/(progress - m_LastProgress)/100;
210  }
211  else
212  {
213  secondsPerPercent = 0;
214  }
215 
216  m_LastProgress = progress;
217 
218  std::cout << "] " << std::flush;
219  std::cout
220  << magentaPrefix
221  << std::setiosflags(std::ios::fixed)
222  << std::setprecision(3)
223  << secondsPerPercent << " s" << "/%"
224  << suffix
225  << cyanPrefix
226  << " ETA "
227  << std::setfill('0')
228  << std::setw(2)
229  << hoursLeft
230  << ":"
231  << std::setw(2)
232  << minutesLeft
233  << ":"
234  << std::setw(2)
235  << secondsLeft
236  << std::setfill(' ')
237  << suffix
238  << bluePrefix
239  << " ET "
240  << std::setfill('0')
241  << std::setw(2)
242  << hoursElapsed
243  << ":"
244  << std::setw(2)
245  << minutesElapsed
246  << ":"
247  << std::setw(2)
248  << secondsElapsed
249  << std::setfill(' ')
250  << suffix
251  << " " << std::flush;
252  std::cout.precision(6);
253  clock.Start();
254  }
255  else
256  {
257  std::cout << "]"
258 // << "\e[?25h"
259  << std::endl;
260  m_SuppressOutput = true;
261  }
262 
263  break;
264  }
265 
266  }
267 };
268 
269 } // end namespace itk
270 
271 
272 #endif
273 
274 
275 
#define ITK_OVERRIDE
Definition: utlITKMacro.h:46
void Execute(Object *caller, const EventObject &event) ITK_OVERRIDE
Observer for progress notification.
ClockType::TimeStampType TimeStampType
void Execute(const Object *object, const EventObject &event) ITK_OVERRIDE
static const unsigned int NumberOfBarSegments