CMS 3D CMS Logo

All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Modules Pages
looper.h
Go to the documentation of this file.
1 // .
2 // ..: P. Chang, philip@physics.ucsd.edu
3 
4 #ifndef looper_cc
5 #define looper_cc
6 
7 // C/C++
8 #include <unistd.h>
9 #include <algorithm>
10 #include <fstream>
11 #include <iostream>
12 #include <map>
13 #include <string>
14 #include <unordered_map>
15 #include <vector>
16 #include <stdarg.h>
17 #include <functional>
18 #include <cmath>
19 
20 // ROOT
21 #include "TBenchmark.h"
22 #include "TBits.h"
23 #include "TChain.h"
24 #include "TFile.h"
25 #include "TTree.h"
26 #include "TBranch.h"
27 #include "TLeaf.h"
28 #include "TH1.h"
29 #include "TH1D.h"
30 #include "TH2D.h"
31 #include "TChainElement.h"
32 #include "TTreeCache.h"
33 #include "TTreePerfStats.h"
34 #include "TStopwatch.h"
35 #include "TSystem.h"
36 #include "TString.h"
37 #include "TLorentzVector.h"
38 #include "Math/LorentzVector.h"
39 
40 #include "printutil.h"
41 #include "eventindexmap.h"
42 
43 //#include "cpptqdm/tqdm.h"
44 
45 namespace RooUtil {
46 
48  // Looper class
50  // NOTE: This class assumes accessing TTree in the SNT style which uses the following,
51  // https://github.com/cmstas/Software/blob/master/makeCMS3ClassFiles/makeCMS3ClassFiles.C
52  // It is assumed that the "template" class passed to this class will have
53  // 1. "Init(TTree*)"
54  // 2. "GetEntry(uint)"
55  // 3. "progress(nevtProc'ed, total)"
56  template <class TREECLASS>
57  class Looper {
58  // Members
59  TChain* tchain;
60  TBenchmark* bmark;
61  TObjArray* listOfFiles;
62  TObjArrayIter* fileIter;
63  TFile* tfile;
64  TTree* ttree;
65  TTreePerfStats* ps;
66  unsigned int nEventsTotalInChain;
67  unsigned int nEventsTotalInTree;
69  unsigned int nEventsProcessed;
70  unsigned int indexOfEventInTTree;
71  bool fastmode;
72  TREECLASS* treeclass;
73  TStopwatch my_timer;
74  int bar_id;
76  bool doskim;
77  TString skimfilename;
78  TFile* skimfile;
79  TTree* skimtree;
80  unsigned int nEventsSkimmed;
81  std::vector<TString> skimbrfiltpttn;
82  bool silent;
83  bool isinit;
86  // bool use_tqdm_progress_bar;
87  unsigned int nskipped_batch;
88  unsigned int nskipped;
89  unsigned int nbatch_skip_threshold;
90  unsigned int nbatch_to_skip;
91  unsigned int nskipped_threshold;
92  unsigned int ncounter;
93  // tqdm bar;
95  TEventList* teventlist;
96 
97  public:
98  // Functions
99  Looper();
100  Looper(TChain* chain, TREECLASS* treeclass, int nEventsToProcess = -1);
101  ~Looper();
102  void init(TChain* chain, TREECLASS* treeclass, int nEventsToProcess);
103  void setTChain(TChain* c);
104  void setTreeClass(TREECLASS* t);
105  void printCurrentEventIndex();
106  void setSilent(bool s = true) { silent = s; }
110  bool nextEvent();
111  bool isNewFileInChain();
112  TTree* getTree() { return ttree; }
113  TChain* getTChain() { return tchain; }
114  unsigned int getNEventsProcessed() { return nEventsProcessed; }
115  void setSkim(TString ofilename);
116  void setSkimBranchFilterPattern(std::vector<TString> x) { skimbrfiltpttn = x; }
117  void fillSkim();
118  void saveSkim();
119  TTree* getSkimTree() { return skimtree; }
120  void setSkimMaxSize(Long64_t maxsize) { skimtree->SetMaxTreeSize(maxsize); }
121  TTreePerfStats* getTTreePerfStats() { return ps; }
122  unsigned int getCurrentEventIndex() { return indexOfEventInTTree - 1; }
123  TFile* getCurrentFile() { return tfile; }
124  TString getCurrentFileBaseName() { return gSystem->BaseName(tfile->GetName()); }
125  TString getCurrentFileName() { return TString(tfile->GetName()); }
126  TString getListOfFileNames();
127  TString getCurrentFileTitle() { return TString(tfile->GetTitle()); }
128  unsigned int getNEventsTotalInChain() { return nEventsTotalInChain; }
129  void setNbatchToSkip(unsigned int n) { nbatch_to_skip = n; }
130  void setNbadEventThreshold(unsigned int n) { nskipped_threshold = n; }
132  bool handleBadEvent();
133  void printStatus();
135  void setFastMode(bool f = true) { fastmode = f; }
136  void addCount() { ncounter++; }
137  void resetCounter() { ncounter = 0; }
138  bool doesBranchExist(TString bname);
139  TString getSkimFileName() { return skimfilename; }
140  TFile* getSkimFile() { return skimfile; }
141 
142  private:
143  void setFileList();
144  void setNEventsToProcess();
145  bool nextTree();
146  bool nextEventInTree();
147  void initProgressBar();
148  void printProgressBar(bool force = false);
149  void createSkimTree();
151  };
152 
153 } // namespace RooUtil
154 
156 //
157 //
158 // Event Looper (Looper) class template implementation
159 //
160 //
162 
163 // It's easier to put the implementation in the header file to avoid compilation issues.
164 
165 //_________________________________________________________________________________________________
166 template <class TREECLASS>
168  : tchain(0),
169  listOfFiles(0),
170  fileIter(0),
171  tfile(0),
172  ttree(0),
173  ps(0),
174  nEventsTotalInChain(0),
175  nEventsTotalInTree(0),
176  nEventsToProcess(-1),
177  nEventsProcessed(0),
178  indexOfEventInTTree(0),
179  fastmode(true),
180  treeclass(0),
181  bar_id(0),
182  print_rate(432),
183  doskim(false),
184  skimfilename(""),
185  skimfile(0),
186  skimtree(0),
187  nEventsSkimmed(0),
188  silent(false),
189  isinit(false),
190  use_treeclass_progress(false),
191  // use_tqdm_progress_bar( isatty(1) ),
192  nskipped_batch(0),
193  nskipped(0),
194  nbatch_skip_threshold(500),
195  nbatch_to_skip(5000),
196  nskipped_threshold(100000),
197  ncounter(0),
198  teventlist(0) {
199  bmark = new TBenchmark();
200  // bar.disable_colors();
201 }
202 
203 //_________________________________________________________________________________________________
204 template <class TREECLASS>
205 RooUtil::Looper<TREECLASS>::Looper(TChain* c, TREECLASS* t, int nevtToProc)
206  : tchain(0),
207  listOfFiles(0),
208  fileIter(0),
209  tfile(0),
210  ttree(0),
211  ps(0),
212  nEventsTotalInChain(0),
213  nEventsTotalInTree(0),
214  nEventsToProcess(nevtToProc),
215  nEventsProcessed(0),
216  indexOfEventInTTree(0),
217  fastmode(true),
218  treeclass(0),
219  bar_id(0),
220  print_rate(432),
221  doskim(false),
222  skimfilename(""),
223  skimfile(0),
224  skimtree(0),
225  nEventsSkimmed(0),
226  silent(false),
227  isinit(false),
228  use_treeclass_progress(false),
229  // use_tqdm_progress_bar( isatty(1) ),
230  nskipped_batch(0),
231  nskipped(0),
232  nbatch_skip_threshold(500),
233  nbatch_to_skip(5000),
234  nskipped_threshold(100000),
235  ncounter(0),
236  teventlist(0) {
237  bmark = new TBenchmark();
238  if (c && t)
239  init(c, t, nevtToProc);
240  // bar.disable_colors();
241 }
242 
243 //_________________________________________________________________________________________________
244 template <class TREECLASS>
245 void RooUtil::Looper<TREECLASS>::init(TChain* c, TREECLASS* t, int nevtToProc) {
246  listOfFiles = 0;
247  if (fileIter)
248  delete fileIter;
249  fileIter = 0;
250  tfile = 0;
251  ttree = 0;
252  ps = 0;
253  nEventsTotalInChain = 0;
254  nEventsTotalInTree = 0;
255  nEventsToProcess = nevtToProc;
256  nEventsProcessed = 0;
257  indexOfEventInTTree = 0;
258  fastmode = true;
259  treeclass = 0;
260  bar_id = 0;
261  print_rate = 432;
262  doskim = false;
263  skimfilename = "";
264  skimfile = 0;
265  skimtree = 0;
266  nEventsSkimmed = 0;
267  silent = false;
268  isinit = false;
269  use_treeclass_progress = false;
270  // use_tqdm_progress_bar( isatty(1) ),
271  nskipped_batch = 0;
272  nskipped = 0;
273  nbatch_skip_threshold = 500;
274  nbatch_to_skip = 5000;
275  nskipped_threshold = 100000;
276  ncounter = 0;
277  teventlist = 0;
278 
279  if (isinit)
280  error(
281  "The Looper is already initialized! Are you calling Looper::init(TChain* c, TREECLASS* t, int nevtToProcess) "
282  "for the second time?",
283  __FUNCTION__);
284 
285  initProgressBar();
286  print("Start EventLooping");
287  start();
288 
289  nEventsToProcess = nevtToProc;
290 
291  if (c)
292  setTChain(c);
293 
294  if (t)
295  setTreeClass(t);
296 
297  if (nEventsToProcess > 5000 || nEventsToProcess == -1)
298  fastmode = true;
299 
300  c->GetEntry(0);
301 
302  // Check tree exists
303  if (not c->GetTree()) {
304  throw std::ios_base::failure("Failed to get TTree from input ntuple");
305  }
306 
307  t->Init(c->GetTree());
308 
309  bmark->Start("benchmark");
310  isinit = true;
311 }
312 
313 //_________________________________________________________________________________________________
314 template <class TREECLASS>
316  if (isinit) {
317  end();
318 
319  // return
320  using namespace std;
321  bmark->Stop("benchmark");
322  cout << endl;
323  cout << "------------------------------" << endl;
324  cout << "CPU Time: " << Form("%.01f", bmark->GetCpuTime("benchmark")) << endl;
325  cout << "Real Time: " << Form("%.01f", bmark->GetRealTime("benchmark")) << endl;
326  cout << endl;
327  // delete bmark;
328 
329  // if ( fileIter )
330  // delete fileIter;
331  //
332  // if ( tfile )
333  // delete tfile;
334  }
335 }
336 
337 //_________________________________________________________________________________________________
338 template <class TREECLASS>
340  if (c) {
341  tchain = c;
342  setNEventsToProcess();
343  setFileList();
344  } else
345  error("You provided a null TChain pointer!", __FUNCTION__);
346 }
347 
348 //_________________________________________________________________________________________________
349 template <class TREECLASS>
351  if (t)
352  treeclass = t;
353  else
354  error("You provided a null TreeClass pointer!", __FUNCTION__);
355 }
356 
357 //_________________________________________________________________________________________________
358 template <class TREECLASS>
360  RooUtil::print(TString::Format("Current TFile = %s", tfile->GetName()));
361  RooUtil::print(TString::Format("Current TTree = %s", ttree->GetName()));
362  RooUtil::print(TString::Format("Current Entry # in TTree = %d", indexOfEventInTTree));
363 }
364 
365 //_________________________________________________________________________________________________
366 template <class TREECLASS>
368  if (!fileIter)
369  error("fileIter not set but you are trying to access the next file", __FUNCTION__);
370 
371  // Get the TChainElement from TObjArrayIter.
372  // If no more to run over, Next returns 0.
373  TChainElement* chainelement = (TChainElement*)fileIter->Next();
374 
375  if (chainelement) {
376  // If doskim is true and if this is the very first file being opened in the TChain,
377  // flag it to create a tfile and ttree where the skimmed events will go to.
378  bool createskimtree = false;
379 
380  if (!ttree && doskim)
381  createskimtree = true;
382 
383  // // If there is already a TFile opened from previous iteration, close it.
384  // if ( tfile )
385  // tfile->Close();
386 
387  // Open up a new file
388  tfile = TFile::Open(chainelement->GetTitle());
389  // Get the ttree
390  ttree = (TTree*)tfile->Get(tchain->GetName());
391 
392  // If an eventindexmap has a key for this file then set the TEventList for this TTree
393  // std::cout << " chainelement->GetTitle(): " << chainelement->GetTitle() << std::endl;
394  // std::cout << " eventindexmap.hasEventList(chainelement->GetTitle()): " << eventindexmap.hasEventList(chainelement->GetTitle()) << std::endl;
395  if (eventindexmap.hasEventList(chainelement->GetTitle())) {
396  // std::cout << chainelement->GetTitle() << std::endl;
397  teventlist = eventindexmap.getEventList(chainelement->GetTitle());
398  ttree->SetEventList(teventlist);
399  } else {
400  teventlist = 0;
401  }
402 
403  if (!ttree)
404  error("TTree is null!??", __FUNCTION__);
405 
406  // Set some fast mode stuff
407  if (fastmode) {
408  TTreeCache::SetLearnEntries(1000);
409  print("TTreeCache enabled");
410  }
411 
412  if (fastmode)
413  ttree->SetCacheSize(128 * 1024 * 1024);
414  else
415  ttree->SetCacheSize(-1);
416 
417  // Print some info to stdout
418  print("Looping " + TString(tfile->GetName()) + "/TTree:" + TString(ttree->GetName()));
419  // printProgressBar(true);
420  // Reset the nEventsTotalInTree in this tree
421  nEventsTotalInTree = ttree->GetEntries();
422  // Reset the event index as we got a new ttree
423  indexOfEventInTTree = 0;
424  // Set the ttree to the TREECLASS
425  treeclass->Init(ttree);
426 
427  // If skimming create the skim tree after the treeclass inits it.
428  // This is to make sure the branch addresses are correct.
429  if (createskimtree)
430  createSkimTree();
431  else if (doskim)
432  copyAddressesToSkimTree();
433 
434  // // TTreePerfStats
435  // if ( ps )
436  // ps->SaveAs( "perf.root" );
437  //
438  // ps = new TTreePerfStats( "ioperf", ttree );
439  // Return that I got a good one
440  return true;
441  } else {
442  // Announce that we are done with this chain
443  // print("");
444  // print("Done with all trees in this chain", __FUNCTION__);
445  return false;
446  }
447 }
448 
449 //_________________________________________________________________________________________________
450 template <class TREECLASS>
452  if (teventlist) {
453  if (indexOfEventInTTree >= (unsigned int)teventlist->GetN()) {
454  unsigned int curindex =
455  teventlist->GetEntry(indexOfEventInTTree - 1); // since I just increased by one a few lines before
456  unsigned int previndex = indexOfEventInTTree >= 2 ? teventlist->GetEntry(indexOfEventInTTree - 2) : 0;
457  nEventsToProcess += (curindex - previndex);
458  return true;
459  } else {
460  return false;
461  }
462  } else {
463  if (indexOfEventInTTree >= nEventsTotalInTree)
464  return true;
465  else
466  return false;
467  }
468 }
469 
470 //_________________________________________________________________________________________________
471 template <class TREECLASS>
473  if (nEventsProcessed >= (unsigned int)nEventsToProcess)
474  return true;
475  else
476  return false;
477 }
478 
479 //_________________________________________________________________________________________________
480 template <class TREECLASS>
482  // treeclass->progress(nEventsProcessed, nEventsToProcess);
483  // Sanity check before loading the next event.
484  if (!ttree)
485  error("current ttree not set!", __FUNCTION__);
486 
487  if (!tfile)
488  error("current tfile not set!", __FUNCTION__);
489 
490  if (!fileIter)
491  error("fileIter not set!", __FUNCTION__);
492 
493  // Check whether I processed everything
494  if (allEventsInTreeProcessed())
495  return false;
496 
497  if (allEventsInChainProcessed())
498  return false;
499 
500  // if fast mode do some extra
501  if (fastmode)
502  ttree->LoadTree(teventlist ? teventlist->GetEntry(indexOfEventInTTree) : indexOfEventInTTree);
503 
504  // Set the event index in TREECLASS
505  treeclass->GetEntry(teventlist ? teventlist->GetEntry(indexOfEventInTTree) : indexOfEventInTTree);
506  // Increment the counter for this ttree
507  ++indexOfEventInTTree;
508  // Increment the counter for the entire tchain
509  // If there is teventlist set then the skipping is a bit more complex...
510  if (teventlist) {
511  unsigned int curindex =
512  teventlist->GetEntry(indexOfEventInTTree - 1); // since I just increased by one a few lines before
513  unsigned int previndex = indexOfEventInTTree >= 2 ? teventlist->GetEntry(indexOfEventInTTree - 2) : 0;
514  nEventsToProcess += (curindex - previndex);
515  } else {
516  ++nEventsProcessed;
517  }
518  // Print progress
519  printProgressBar();
520  // If all fine return true
521  return true;
522 }
523 
524 //_________________________________________________________________________________________________
525 template <class TREECLASS>
527  if (!isinit)
528  error(
529  "The Looper is not initialized! please call properly Looper::init(TChain* c, TREECLASS* t, int nevtToProcess) "
530  "first!",
531  __FUNCTION__);
532 
533  // If no tree it means this is the beginning of the loop.
534  if (!ttree) {
535  // std::cout << " I think this is the first tree " << std::endl;
536  // Load the next tree if it returns true, then proceed to next event in tree.
537  while (nextTree()) {
538  // If the next event in tree was successfully loaded return true, that it's good.
539  if (nextEventInTree()) {
540  // std::cout << " I think this is the first event in first tree" << std::endl;
541  // Set the boolean that a new file opened for this event
542  isnewfileopened = true;
543  return true;
544  }
545  // If the first event in this tree was not good, continue to the next tree
546  else
547  continue;
548  }
549 
550  // If looping over all trees, we fail to find first event that's good,
551  // return false and call it quits.
552  // At this point it will exit the loop without processing any events.
553  // printProgressBar();
554  // Set the boolean that a new file has not opened for this event
555  isnewfileopened = false;
556  return false;
557  }
558  // If tree exists, it means that we're in the middle of a loop
559  else {
560  // If next event is successfully loaded proceed.
561  if (nextEventInTree()) {
562  // Set the boolean that a new file has not opened for this event
563  isnewfileopened = false;
564  return true;
565  }
566  // If next event is not loaded then check why.
567  else {
568  // If failed because it was the last event in the whole chain to process, exit the loop.
569  // You're done!
570  if (allEventsInChainProcessed()) {
571  // printProgressBar();
572  // Set the boolean that a new file has not opened for this event
573  isnewfileopened = false;
574  return false;
575  }
576  // If failed because it's last in the tree then load the next tree and the event
577  else if (allEventsInTreeProcessed()) {
578  // Load the next tree if it returns true, then proceed to next event in tree.
579  while (nextTree()) {
580  // If the next event in tree was successfully loaded return true, that it's good.
581  if (nextEventInTree()) {
582  // Set the boolean that a new file has opened for this event
583  isnewfileopened = true;
584  return true;
585  }
586  // If the first event in this tree was not good, continue to the next tree
587  else
588  continue;
589  }
590 
591  // If looping over all trees, we fail to find first event that's good,
592  // return false and call it quits.
593  // Again you're done!
594  // printProgressBar();
595  // Set the boolean that a new file has not opened for this event
596  isnewfileopened = false;
597  return false;
598  } else {
599  // Why are you even here?
600  // spit error and return false to avoid warnings
601  error("You should not be here! Please contact philip@physics.ucsd.edu", __FUNCTION__);
602  // Set the boolean that a new file has not opened for this event
603  isnewfileopened = false;
604  return false;
605  }
606  }
607  }
608 }
609 
610 //_________________________________________________________________________________________________
611 template <class TREECLASS>
613  return isnewfileopened;
614 }
615 
616 //_________________________________________________________________________________________________
617 template <class TREECLASS>
619  if (!fileIter) {
620  listOfFiles = tchain->GetListOfFiles();
621  fileIter = new TObjArrayIter(listOfFiles);
622  }
623 }
624 
625 //_________________________________________________________________________________________________
626 template <class TREECLASS>
628  if (tchain) {
629  nEventsTotalInChain = tchain->GetEntries();
630 
631  if (nEventsToProcess < 0)
632  nEventsToProcess = nEventsTotalInChain;
633 
634  if (nEventsToProcess > (int)nEventsTotalInChain) {
635  print(TString::Format("Asked to process %d events, but there aren't that many events", nEventsToProcess));
636  nEventsToProcess = nEventsTotalInChain;
637  }
638 
639  print(TString::Format("Total Events in this Chain to process = %d", nEventsToProcess));
640  }
641 }
642 
643 //_________________________________________________________________________________________________
644 template <class TREECLASS>
647  my_timer.Start();
648  bar_id = 0;
649 }
650 
651 //_________________________________________________________________________________________________
652 template <class TREECLASS>
654  if (silent)
655  return;
656 
658 
659  int entry = nEventsProcessed;
660  int totalN = nEventsToProcess;
661 
662  // if (use_tqdm_progress_bar)
663  // {
664  // if (force) return; // N.B. If i am not using my own scheme i shouldn't force it.
665  // bar.progress(nEventsProcessed-1, nEventsToProcess); // tqdm expects 0 to N-1 index not 1 to N
666  // return;
667  // }
668 
669  if (use_treeclass_progress) {
670  if (force)
671  return; // N.B. If i am not using my own scheme i shouldn't force it.
672  // treeclass->progress(nEventsProcessed, nEventsToProcess);
673  return;
674  }
675 
676  if (totalN < 20)
677  totalN = 20;
678 
679  // Progress bar
680  if (entry > totalN) {
681  // printf( "Why are you here?\n" );
682  } else if (entry == totalN) {
683  Double_t elapsed = my_timer.RealTime();
684  Double_t rate;
685 
686  if (elapsed != 0)
687  rate = entry / elapsed;
688  else
689  rate = -999;
690 
691  const int mins_in_hour = 60;
692  const int secs_to_min = 60;
693  Int_t input_seconds = elapsed;
694  Int_t seconds = input_seconds % secs_to_min;
695  Int_t minutes = input_seconds / secs_to_min % mins_in_hour;
696  Int_t hours = input_seconds / secs_to_min / mins_in_hour;
697 
698  printf("\rRooUtil::");
699  printf("+");
700  printf("|====================");
701 
702  //for ( int nb = 0; nb < 20; ++nb )
703  //{
704  // printf("=");
705  //}
706 
707  printf("| %.1f %% (%d/%d) with [avg. %d Hz] Total Time: %.2d:%.2d:%.2d \n",
708  100.0,
709  entry,
710  totalN,
711  (int)rate,
712  hours,
713  minutes,
714  seconds);
715  fflush(stdout);
716  }
717  //else if ( entry % ( ( ( int ) print_rate ) ) < (0.3) * print_rate || force )
718  else if (entry % (((int)print_rate)) == 0 || force) {
719  // sanity check
720  if (entry >=
721  totalN +
722  10) // +2 instead of +1 since, the loop might be a while loop where to check I got a bad event the index may go over 1.
723  {
724  TString msg = TString::Format("%d %d", entry, totalN);
725  RooUtil::print(msg, __FUNCTION__);
726  RooUtil::error("Total number of events processed went over max allowed! Check your loop boundary conditions!!",
727  __FUNCTION__);
728  }
729 
730  int nbars = entry / (totalN / 20);
731  Double_t elapsed = my_timer.RealTime();
732  Double_t rate;
733 
734  if (elapsed != 0)
735  rate = entry / elapsed;
736  else
737  rate = -999;
738 
739  Double_t percentage = entry / (totalN * 1.) * 100;
740  const int mins_in_hour = 60;
741  const int secs_to_min = 60;
742  Int_t input_seconds = (totalN - entry) / rate;
743  Int_t seconds = input_seconds % secs_to_min;
744  Int_t minutes = input_seconds / secs_to_min % mins_in_hour;
745  Int_t hours = input_seconds / secs_to_min / mins_in_hour;
746 
747  print_rate = (int)(rate / 5) + 1;
748 
749  printf("RooUtil:: ");
750 
751  if (bar_id % 4 == 3)
752  printf("-");
753 
754  if (bar_id % 4 == 2)
755  printf("/");
756 
757  if (bar_id % 4 == 1)
758  printf("|");
759 
760  if (bar_id % 4 == 0)
761  printf("\\");
762 
763  printf("|");
764  bar_id++;
765 
766  for (int nb = 0; nb < 20; ++nb) {
767  if (nb < nbars)
768  printf("=");
769  else
770  printf(".");
771  }
772 
773  printf("| %.1f %% (%d/%d) with [%d Hz] ETA %.2d:%.2d:%.2d \r",
774  percentage,
775  entry + 1,
776  totalN,
777  (int)rate,
778  hours,
779  minutes,
780  seconds);
781  fflush(stdout);
782  }
783 
784  my_timer.Start(kFALSE);
785 }
786 
787 //_________________________________________________________________________________________________
788 template <class TREECLASS>
789 void RooUtil::Looper<TREECLASS>::setSkim(TString ofilename) {
790  skimfilename = ofilename;
791  doskim = true;
792 }
793 
794 //_________________________________________________________________________________________________
795 template <class TREECLASS>
797  skimfile = new TFile(skimfilename, "recreate");
798  TObjArray* toa = ttree->GetListOfBranches();
799 
800  if (skimbrfiltpttn.size() > 0) {
801  ttree->SetBranchStatus("*", 0);
802 
803  for (auto& pttn : skimbrfiltpttn) {
804  for (const auto& brobj : *toa) {
805  TString brname = brobj->GetName();
806 
807  if (pttn.Contains("*")) {
808  TString modpttn = pttn;
809  modpttn.ReplaceAll("*", "");
810  if (brname.Contains(modpttn) && brname.BeginsWith(modpttn)) {
811  // std::cout << brname << std::endl;
812  ttree->SetBranchStatus(brname + "*", 1);
813  }
814  } else {
815  if (brname.EqualTo(pttn)) {
816  // std::cout << brname << std::endl;
817  ttree->SetBranchStatus(brname, 1);
818  }
819  }
820  }
821  }
822  }
823 
824  skimtree = ttree->CloneTree(0);
825 }
826 
827 //_________________________________________________________________________________________________
828 template <class TREECLASS>
830  ttree->CopyAddresses(skimtree);
831 }
832 
833 //_________________________________________________________________________________________________
834 template <class TREECLASS>
836  treeclass->LoadAllBranches();
837  skimtree->Fill();
838  nEventsSkimmed++;
839 }
840 
841 //_________________________________________________________________________________________________
842 template <class TREECLASS>
844  double frac_skimmed = (double)nEventsSkimmed / (double)nEventsProcessed * 100;
845  RooUtil::print(Form("Skimmed events %d out of %d. [%f%%]", nEventsSkimmed, nEventsProcessed, frac_skimmed));
846  skimtree->GetCurrentFile()->cd();
847  skimtree->Write();
848  // skimfile->Close();
849 }
850 
851 //_________________________________________________________________________________________________
852 template <class TREECLASS>
854  using namespace std;
855  cout << endl;
856  cout << "RooUtil::Looper [CheckCorrupt] Caught an I/O failure in the ROOT file." << endl;
857  cout << "RooUtil::Looper [CheckCorrupt] Possibly corrupted hadoop file." << endl;
858  cout << "RooUtil::Looper [CheckCorrupt] event index = " << getCurrentEventIndex() << " out of "
859  << tchain->GetEntries() << endl;
860  cout << endl;
861 
862  // If the total nskip reaches a threshold just fail the whole thing...
863  if (nskipped >= nskipped_threshold) {
864  nskipped += tchain->GetEntries() - getCurrentEventIndex() - 1;
865  return false;
866  }
867 
868  nskipped_batch++;
869 
870  // If the nskipped is quite large than skip the entire file
871  if (nskipped_batch > nbatch_skip_threshold) {
872  nskipped += nskipped_batch;
873  nskipped_batch = 0;
874  for (unsigned int i = 0; i < nbatch_to_skip; ++i) {
875  if (!nextEvent())
876  return false;
877  nskipped++;
878  }
879  }
880 
881  return true;
882 }
883 
884 //_________________________________________________________________________________________________
885 template <class TREECLASS>
887  getTree()->PrintCacheStats();
888  printSkippedBadEventStatus();
889 }
890 
891 //_________________________________________________________________________________________________
892 template <class TREECLASS>
894  TString rtnstring = "";
895  TObjArray* filepaths = tchain->GetListOfFiles();
896  TObjArrayIter* iter = new TObjArrayIter(listOfFiles);
897  for (Int_t ifile = 0; ifile < filepaths->GetEntries(); ++ifile) {
898  TChainElement* chainelement = (TChainElement*)iter->Next();
899  if (chainelement) {
900  TString filepath = chainelement->GetTitle();
901  if (rtnstring.IsNull())
902  rtnstring = filepath;
903  else
904  rtnstring += "," + filepath;
905  }
906  }
907  return rtnstring;
908 }
909 
910 //_________________________________________________________________________________________________
911 template <class TREECLASS>
913  using namespace std;
914  nskipped += nskipped_batch;
915 
916  if (nskipped) {
917  cout << "RooUtil:Looper [CheckCorrupt] Skipped " << nskipped << " events out of " << tchain->GetEntries() << " ["
918  << float(nskipped) / float(tchain->GetEntries()) * 100 << "% loss]"
919  << " POSSIBLE BADFILES = " << getListOfFileNames() << endl;
920  }
921 }
922 
923 //_________________________________________________________________________________________________
924 template <class TREECLASS>
926  if (ttree->GetBranch(bname))
927  return true;
928  if (ttree->GetBranch(ttree->GetAlias(bname)))
929  return true;
930  return false;
931 }
932 
933 #endif
unsigned int nEventsTotalInTree
Definition: looper.h:67
bool doskim
Definition: looper.h:76
bool doesBranchExist(TString bname)
Definition: looper.h:925
TFile * skimfile
Definition: looper.h:78
int nEventsToProcess
Definition: looper.h:68
bool isinit
Definition: looper.h:83
bool nextTree()
Definition: looper.h:367
TFile * tfile
Definition: looper.h:63
void saveSkim()
Definition: looper.h:843
TTreePerfStats * getTTreePerfStats()
Definition: looper.h:121
void setFileList()
Definition: looper.h:618
unsigned int indexOfEventInTTree
Definition: looper.h:70
TString skimfilename
Definition: looper.h:77
TTree * getTree()
Definition: looper.h:112
unsigned int nEventsSkimmed
Definition: looper.h:80
void print(TString msg="", const char *fname="", int flush_before=0, int flush_after=0)
Definition: printutil.cc:23
TTree * skimtree
Definition: looper.h:79
void printProgressBar(bool force=false)
Definition: looper.h:653
void setTChain(TChain *c)
Definition: looper.h:339
bool nextEventInTree()
Definition: looper.h:481
TEventList * teventlist
Definition: looper.h:95
bool allEventsInChainProcessed()
Definition: looper.h:472
int init
Definition: HydjetWrapper.h:66
void printCurrentEventIndex()
Definition: looper.h:359
void init(TChain *chain, TREECLASS *treeclass, int nEventsToProcess)
Definition: looper.h:245
unsigned int nskipped_threshold
Definition: looper.h:91
void setTreeClass(TREECLASS *t)
Definition: looper.h:350
void load(TString filename)
Definition: eventindexmap.cc:9
TObjArray * listOfFiles
Definition: looper.h:61
void error(TString msg, const char *fname="", int is_error=1)
Definition: printutil.cc:44
void setNbadEventThresholdToTriggerBatchSkip(unsigned int n)
Definition: looper.h:131
TTree * getSkimTree()
Definition: looper.h:119
TTree * ttree
Definition: looper.h:64
unsigned int nskipped_batch
Definition: looper.h:87
void resetCounter()
Definition: looper.h:137
unsigned int getNEventsProcessed()
Definition: looper.h:114
TString getCurrentFileBaseName()
Definition: looper.h:124
unsigned int nEventsProcessed
Definition: looper.h:69
std::vector< TString > skimbrfiltpttn
Definition: looper.h:81
void fillSkim()
Definition: looper.h:835
void printStatus()
Definition: looper.h:886
TChain * tchain
Definition: looper.h:59
bool allEventsInTreeProcessed()
Definition: looper.h:451
unsigned int ncounter
Definition: looper.h:92
Definition: tfile.py:1
void setEventIndexMap(TString file)
Definition: looper.h:107
TStopwatch my_timer
Definition: looper.h:73
void print(TMatrixD &m, const char *label=nullptr, bool mathematicaFormat=false)
Definition: Utilities.cc:47
void setNbatchToSkip(unsigned int n)
Definition: looper.h:129
double f[11][100]
unsigned int nskipped
Definition: looper.h:88
TBenchmark * bmark
Definition: looper.h:60
TString getListOfFileNames()
Definition: looper.h:893
bool fastmode
Definition: looper.h:71
void addCount()
Definition: looper.h:136
void setSkimBranchFilterPattern(std::vector< TString > x)
Definition: looper.h:116
EventIndexMap eventindexmap
Definition: looper.h:94
TTreePerfStats * ps
Definition: looper.h:65
TFile * getSkimFile()
Definition: looper.h:140
void setSkim(TString ofilename)
Definition: looper.h:789
bool silent
Definition: looper.h:82
TREECLASS * treeclass
Definition: looper.h:72
int print_rate
Definition: looper.h:75
void createSkimTree()
Definition: looper.h:796
tuple msg
Definition: mps_check.py:286
void copyAddressesToSkimTree()
Definition: looper.h:829
void setSkimMaxSize(Long64_t maxsize)
Definition: looper.h:120
double rate(double x)
Definition: Constants.cc:3
bool use_treeclass_progress
Definition: looper.h:84
bool isNewFileInChain()
Definition: looper.h:612
bool handleBadEvent()
Definition: looper.h:853
float x
void setSilent(bool s=true)
Definition: looper.h:106
unsigned int nbatch_skip_threshold
Definition: looper.h:89
void setFastMode(bool f=true)
Definition: looper.h:135
TString getSkimFileName()
Definition: looper.h:139
unsigned int getNEventsTotalInChain()
Definition: looper.h:128
bool isnewfileopened
Definition: looper.h:85
void printSkippedBadEventStatus()
Definition: looper.h:912
TString getCurrentFileTitle()
Definition: looper.h:127
TObjArrayIter * fileIter
Definition: looper.h:62
unsigned int nEventsTotalInChain
Definition: looper.h:66
void initProgressBar()
Definition: looper.h:645
void setNbadEventThreshold(unsigned int n)
Definition: looper.h:130
TString getCurrentFileName()
Definition: looper.h:125
bool nextEvent()
Definition: looper.h:526
TChain * getTChain()
Definition: looper.h:113
void setNEventsToProcess()
Definition: looper.h:627
unsigned int nbatch_to_skip
Definition: looper.h:90
TFile * getCurrentFile()
Definition: looper.h:123
unsigned int getCurrentEventIndex()
Definition: looper.h:122