DAS  3.0
Das Analysis System
Looper.h
Go to the documentation of this file.
1 #pragma once
2 
3 #include <algorithm>
4 #include <memory>
5 #include <iostream>
6 #include <string>
7 
8 #include <chrono>
9 #include <ctime>
10 
11 #include <boost/exception/all.hpp>
12 
13 #include <TChain.h>
14 #include <TTree.h>
15 
16 #include "exceptions.h"
17 
18 namespace Darwin::Tools {
19 
20 typedef std::pair<unsigned, unsigned> Slice;
21 
24 inline std::ostream& operator<< (std::ostream& Stream, const Darwin::Tools::Slice& slice)
25 {
26  Stream << slice.second << '/' << slice.first;
27  return Stream;
28 }
29 
32 class Looper {
33  TTree * tree;
34  const Slice slice;
35 
36  const long long nEvTot,
37  start,
38  stop,
39  nEvSlice; // number of entries covered by the current process
40  long long iEvSlice; // current entry
41  long long percent; // percentage of progress for current entry
42 
43  const std::chrono::time_point<std::chrono::system_clock> start_t;
44 
45  Looper (TTree * t,
46  long long nEvents,
47  Slice s = {1,0}
48  ) : tree(t), slice(s),
49  nEvTot(nEvents),
50  start(nEvTot*((s.second+0.)/s.first)),
51  stop (nEvTot*((s.second+1.)/s.first)),
52  nEvSlice(stop - start), iEvSlice(0), percent(-1),
53  start_t(std::chrono::system_clock::now())
54  {
55  using namespace std;
56 
57  if (slice.first == 0 || slice.first <= slice.second)
58  BOOST_THROW_EXCEPTION(invalid_argument("The number of slices " + to_string(slice.first)
59  + " must be larger than the index of the current slice " + to_string(slice.second)));
60 
61  if (nEvSlice <= 0)
62  BOOST_THROW_EXCEPTION(invalid_argument("The number of events cannot be " + to_string(nEvSlice)));
63 
64  cout << slice << '\t' << start << '-' << stop << endl;
65  }
66 
67 public:
68 
69  static long long division;
70 
73  template<typename TTreePtr>
74  [[deprecated("Pass the slice to GetChain instead")]]
75  Looper (const TTreePtr& t,
76  Slice s
77  ) : Looper(&*t, t->GetEntries(), s)
78  {
79  using namespace std;
80  namespace DE = Darwin::Exceptions;
81  string root_log = DE::intercept_printf([this]() { printf("loading first entry"); tree->GetEntry(start); });
82  tree->GetEntry(start);
83  if (root_log.find("Error") != string::npos)
84  BOOST_THROW_EXCEPTION(runtime_error("Error while loading a TTree entry:\n" + root_log));
85  }
86 
89  template<typename TTreePtr>
90  Looper (const TTreePtr& t
91  ) : Looper(&*t, t->GetEntries(), {1, 0})
92  {
93  using namespace std;
94  namespace DE = Darwin::Exceptions;
95  string root_log = DE::intercept_printf([this]() { printf("loading first entry"); tree->GetEntry(start); });
96  tree->GetEntry(start);
97  if (root_log.find("Error") != string::npos)
98  BOOST_THROW_EXCEPTION(runtime_error("Error while loading a TTree entry:\n" + root_log));
99  }
100 
103  Looper (long long nEvents,
104  Slice s = {1,0}
105  ) : Looper(nullptr, nEvents, s)
106  {
107  }
108 
110  {
111  if (percent < 100ll)
112  std::cerr << red << "Warning: the event loop has stopped at entry "
113  << iEvSlice << def << '\n';
114  }
115 
118  void operator++ ()
119  {
120  ++iEvSlice;
121  if (tree) tree->GetEntry(start + iEvSlice);
122  }
123 
126  bool operator() ()
127  {
128  using namespace std;
129  long long test_percent = (100ll*iEvSlice)/nEvSlice;
130 
131  if (test_percent != percent && test_percent % division == 0) {
132  // display current slice
133  cout << slice.second << '/' << slice.first;
134 
135  // display total number of seconds
136  auto now_t = chrono::system_clock::now();
137  auto elapsed_time {now_t - start_t};
138  auto secs = chrono::duration_cast<chrono::seconds>(elapsed_time);
139  cout << '\t' << secs.count() << 's';
140 
141  // display current time in human readable format
142  time_t now = chrono::system_clock::to_time_t(now_t);
143  cout << '\t' << put_time(localtime(&now), "%Y-%m-%d %H:%M:%S %Z");
144 
145  // display progress
146  percent = test_percent;
147  cout << '\t' << percent << '%' << endl;
148  }
149 
150  return iEvSlice < nEvSlice;
151  }
152 
155  inline long long operator* () const
156  {
157  return start + iEvSlice;
158  }
159 };
160 
161 } // end of Darwin::Tools namespace
162 
163 using Darwin::Tools::operator<<;
Ntupliser_cfg.cerr
cerr
Definition: Ntupliser_cfg.py:93
exceptions.h
Darwin::Tools::Looper::iEvSlice
long long iEvSlice
Definition: Looper.h:40
Step::def
static const char * def
Definition: Step.h:36
Darwin::Tools::Looper::nEvSlice
const long long nEvSlice
Definition: Looper.h:39
Darwin::Tools::Looper
Facility to loop over a n-tuple, including parallelisation and printing.
Definition: Looper.h:32
Darwin::Tools::Looper::nEvTot
const long long nEvTot
{#processes, process index}
Definition: Looper.h:36
Darwin::Tools::Slice
std::pair< unsigned, unsigned > Slice
current slice (>=0) / total number of slices (>0)
Definition: Looper.h:20
Darwin::Exceptions
Handling of exceptions.
Definition: darwin.h:36
Step::red
static const char * red
Definition: Step.h:34
Darwin::Tools::Looper::operator++
void operator++()
Increments the counter and load entry (if applicable)
Definition: Looper.h:118
Darwin::Tools::operator<<
std::ostream & operator<<(std::ostream &Stream, const Darwin::Tools::Slice &slice)
Prints the current slice and the total number of slices.
Definition: Looper.h:24
Darwin::Tools::Looper::start_t
const std::chrono::time_point< std::chrono::system_clock > start_t
starting time
Definition: Looper.h:43
Darwin::Tools::Looper::operator*
long long operator*() const
Pointer-like operator to return the value of the entry.
Definition: Looper.h:155
Darwin::Tools::Looper::division
static long long division
steps at which progress is printed (100%/division)
Definition: Looper.h:69
Darwin::Tools::Looper::tree
TTree * tree
tree
Definition: Looper.h:33
Darwin::Tools
Classes and functions related to the framework.
Definition: Dict_rdict.cxx:990
Darwin::Tools::Looper::Looper
Looper(const TTreePtr &t)
Constructor for existing tree with raw pointer.
Definition: Looper.h:90
Darwin::Tools::Looper::slice
const Slice slice
Definition: Looper.h:34
Darwin::Tools::Looper::Looper
Looper(long long nEvents, Slice s={1, 0})
Constructor for simple counter.
Definition: Looper.h:103
Darwin::Exceptions::intercept_printf
std::string intercept_printf(std::function< void()> const lambda=[]() { printf(__func__);})
Definition: exceptions.h:33
Darwin::Tools::Looper::start
const long long start
first entry (included)
Definition: Looper.h:37
Darwin::Tools::Looper::operator()
bool operator()()
Check that the counter is still in the range and prints percentage.
Definition: Looper.h:126
Darwin::Tools::Looper::stop
const long long stop
last entry (excluded)
Definition: Looper.h:38
Darwin::Tools::Looper::Looper
Looper(TTree *t, long long nEvents, Slice s={1, 0})
Definition: Looper.h:45
Darwin::Tools::Looper::percent
long long percent
Definition: Looper.h:41
Darwin::Tools::Looper::~Looper
~Looper()
Definition: Looper.h:109
Darwin::Tools::Looper::Looper
Looper(const TTreePtr &t, Slice s)
Constructor for existing tree with raw pointer.
Definition: Looper.h:75