Progress.cxx
Go to the documentation of this file.
1 #include "CAFAna/Core/Progress.h"
2 
3 #include "sys/stat.h"
4 
5 #include "TString.h"
6 
7 #include <iostream>
8 
9 namespace{
10  const int kBarWidth = 60;
11 }
12 
13 namespace ana
14 {
15  bool Progress::fAnyLive = false;
16 
17  //----------------------------------------------------------------------
19  : fDone(false), fIFrac(-1), fStart(time(0)), fPrevCall(time(0)), fLive(false)
20  {
21  // If no else is drawing, we can
22  if(!fAnyLive){
23  fLive = true;
24  fAnyLive = true;
25  }
26 
27  if(!fLive) return;
28 
29  std::cout << title << "..." << std::endl;
30  SetProgress(0); // Draw the initial bar
31  }
32 
33  //----------------------------------------------------------------------
35  {
36  // Finish up in case the user forgot to call Done()
37  Done();
38  }
39 
40  //----------------------------------------------------------------------
42  {
43  if(!fLive || fDone) return;
44 
45  const time_t t_now = time(0);
46  const int ifrac = (kBarWidth-1)*frac;
47 
48  // Don't repaint unnecessarily
49  if(ifrac == fIFrac && t_now - fPrevCall < 2) return;
50 
51  fIFrac = ifrac;
52  fPrevCall = t_now;
53 
54  // Check if we're outputting to a file. If so don't bother showing off
55  // with the progress bar, it won't work.
56  struct stat buf;
57  fstat(fileno(stdout), &buf);
58  const bool isFile = (buf.st_mode & S_IFREG) || (buf.st_mode & S_IFIFO);
59  if(isFile) return;
60 
61  std::string str(kBarWidth, ' ');
62  for(int i = 0; i < ifrac; ++i) str[i] = '=';
63  str[ifrac] = '>';
64  str[0] = '[';
65  str[kBarWidth-1] = ']';
66 
67  if(frac > 0){
68  const int elapse = t_now - fStart;
69  if(elapse > 2){ // Don't show for very short steps
70  if(frac < 1)
71  str += " "+FormatTime(elapse*(1-frac)/frac);
72  else
73  str += " "+FormatTime(elapse);
74  str += " "; // Enough to cover up any previous version
75  }
76  }
77 
78  std::cout << "\r" << str << std::flush;
79 
80  if(frac == 1){
81  fDone = true;
83 
84  // If we were the ones drawing, we're not anymore
85  if(fLive) fLive = fAnyLive = false;
86  }
87  }
88 
89  //----------------------------------------------------------------------
91  {
92  if(!fLive) return;
93 
94  if(fDone) return; // Can easily be called multiple times
95 
96  SetProgress(1); // Make sure the bar shows 100%
97 
98  fDone = true;
99  }
100 
101  //----------------------------------------------------------------------
103  {
104  // Yes, I'm sure there's a standard way to do this, but this was easy, and
105  // lets me print exactly what I want.
107  if(sec >= 60*60-.5){
108  ret += TString::Format("%dh", (int(sec+.5)/(60*60))).Data();
109  }
110  if(sec >= 60-.5){
111  ret += TString::Format("%dm", (int(sec+.5)/60)%60).Data();
112  }
113  if(sec < 60*60){ // don't clutter if still measured in hours
114  ret += TString::Format("%ds", (int(sec+.5)%60)).Data();
115  }
116  return ret;
117  }
118 }
Cuts and Vars for the 2020 FD DiF Study.
Definition: vars.h:6
::xsd::cxx::tree::time< char, simple_type > time
Definition: Database.h:194
bool fDone
Has Done been called?
Definition: Progress.h:22
time_t fStart
Definition: Progress.h:25
static bool fAnyLive
Are any bars live?
Definition: Progress.h:30
Progress(const std::string &title)
Create and draw the progress bar.
Definition: Progress.cxx:18
double frac(double x)
Fractional part.
int fIFrac
What character are we on? Prevents unnecessary redraws.
Definition: Progress.h:23
time_t fPrevCall
Definition: Progress.h:26
OStream cout
Definition: OStream.cxx:6
void SetProgress(double frac)
Update the progress fraction between zero and one.
Definition: Progress.cxx:41
unsigned int fileno
Definition: runWimpSim.h:102
void Format(TGraph *gr, int lcol, int lsty, int lwid, int mcol, int msty, double msiz)
Definition: Style.cxx:154
bool fLive
Is this bar live (drawable?)
Definition: Progress.h:29
std::string FormatTime(double sec) const
Definition: Progress.cxx:102
void Done()
Call this when action is completed.
Definition: Progress.cxx:90
enum BeamMode string