14 #include <unordered_map> 21 #include "TBenchmark.h" 31 #include "TChainElement.h" 32 #include "TTreeCache.h" 33 #include "TTreePerfStats.h" 34 #include "TStopwatch.h" 37 #include "TLorentzVector.h" 38 #include "Math/LorentzVector.h" 56 template <
class TREECLASS>
115 void setSkim(TString ofilename);
166 template <
class TREECLASS>
174 nEventsTotalInChain(0),
175 nEventsTotalInTree(0),
176 nEventsToProcess(-1),
178 indexOfEventInTTree(0),
190 use_treeclass_progress(
false),
194 nbatch_skip_threshold(500),
195 nbatch_to_skip(5000),
196 nskipped_threshold(100000),
199 bmark =
new TBenchmark();
204 template <
class TREECLASS>
212 nEventsTotalInChain(0),
213 nEventsTotalInTree(0),
214 nEventsToProcess(nevtToProc),
216 indexOfEventInTTree(0),
228 use_treeclass_progress(
false),
232 nbatch_skip_threshold(500),
233 nbatch_to_skip(5000),
234 nskipped_threshold(100000),
237 bmark =
new TBenchmark();
244 template <
class TREECLASS>
253 nEventsTotalInChain = 0;
254 nEventsTotalInTree = 0;
255 nEventsToProcess = nevtToProc;
256 nEventsProcessed = 0;
257 indexOfEventInTTree = 0;
269 use_treeclass_progress =
false;
273 nbatch_skip_threshold = 500;
274 nbatch_to_skip = 5000;
275 nskipped_threshold = 100000;
281 "The Looper is already initialized! Are you calling Looper::init(TChain* c, TREECLASS* t, int nevtToProcess) " 282 "for the second time?",
286 print(
"Start EventLooping");
289 nEventsToProcess = nevtToProc;
297 if (nEventsToProcess > 5000 || nEventsToProcess == -1)
303 if (not
c->GetTree()) {
304 throw std::ios_base::failure(
"Failed to get TTree from input ntuple");
307 t->Init(
c->GetTree());
309 bmark->Start(
"benchmark");
314 template <
class TREECLASS>
321 bmark->Stop(
"benchmark");
323 cout <<
"------------------------------" << endl;
324 cout <<
"CPU Time: " << Form(
"%.01f", bmark->GetCpuTime(
"benchmark")) << endl;
325 cout <<
"Real Time: " << Form(
"%.01f", bmark->GetRealTime(
"benchmark")) << endl;
338 template <
class TREECLASS>
342 setNEventsToProcess();
345 error(
"You provided a null TChain pointer!", __FUNCTION__);
349 template <
class TREECLASS>
354 error(
"You provided a null TreeClass pointer!", __FUNCTION__);
358 template <
class TREECLASS>
361 RooUtil::print(TString::Format(
"Current TTree = %s", ttree->GetName()));
362 RooUtil::print(TString::Format(
"Current Entry # in TTree = %d", indexOfEventInTTree));
366 template <
class TREECLASS>
369 error(
"fileIter not set but you are trying to access the next file", __FUNCTION__);
373 TChainElement* chainelement = (TChainElement*)fileIter->Next();
378 bool createskimtree =
false;
380 if (!ttree && doskim)
381 createskimtree =
true;
388 tfile = TFile::Open(chainelement->GetTitle());
390 ttree = (TTree*)
tfile->Get(tchain->GetName());
395 if (eventindexmap.hasEventList(chainelement->GetTitle())) {
397 teventlist = eventindexmap.getEventList(chainelement->GetTitle());
398 ttree->SetEventList(teventlist);
404 error(
"TTree is null!??", __FUNCTION__);
408 TTreeCache::SetLearnEntries(1000);
409 print(
"TTreeCache enabled");
413 ttree->SetCacheSize(128 * 1024 * 1024);
415 ttree->SetCacheSize(-1);
418 print(
"Looping " + TString(
tfile->GetName()) +
"/TTree:" + TString(ttree->GetName()));
421 nEventsTotalInTree = ttree->GetEntries();
423 indexOfEventInTTree = 0;
425 treeclass->Init(ttree);
432 copyAddressesToSkimTree();
450 template <
class TREECLASS>
453 if (indexOfEventInTTree >= (
unsigned int)teventlist->GetN()) {
454 unsigned int curindex =
455 teventlist->GetEntry(indexOfEventInTTree - 1);
456 unsigned int previndex = indexOfEventInTTree >= 2 ? teventlist->GetEntry(indexOfEventInTTree - 2) : 0;
457 nEventsToProcess += (curindex - previndex);
463 if (indexOfEventInTTree >= nEventsTotalInTree)
471 template <
class TREECLASS>
473 if (nEventsProcessed >= (
unsigned int)nEventsToProcess)
480 template <
class TREECLASS>
485 error(
"current ttree not set!", __FUNCTION__);
488 error(
"current tfile not set!", __FUNCTION__);
491 error(
"fileIter not set!", __FUNCTION__);
494 if (allEventsInTreeProcessed())
497 if (allEventsInChainProcessed())
502 ttree->LoadTree(teventlist ? teventlist->GetEntry(indexOfEventInTTree) : indexOfEventInTTree);
505 treeclass->GetEntry(teventlist ? teventlist->GetEntry(indexOfEventInTTree) : indexOfEventInTTree);
507 ++indexOfEventInTTree;
511 unsigned int curindex =
512 teventlist->GetEntry(indexOfEventInTTree - 1);
513 unsigned int previndex = indexOfEventInTTree >= 2 ? teventlist->GetEntry(indexOfEventInTTree - 2) : 0;
514 nEventsToProcess += (curindex - previndex);
525 template <
class TREECLASS>
529 "The Looper is not initialized! please call properly Looper::init(TChain* c, TREECLASS* t, int nevtToProcess) " 539 if (nextEventInTree()) {
542 isnewfileopened =
true;
555 isnewfileopened =
false;
561 if (nextEventInTree()) {
563 isnewfileopened =
false;
570 if (allEventsInChainProcessed()) {
573 isnewfileopened =
false;
577 else if (allEventsInTreeProcessed()) {
581 if (nextEventInTree()) {
583 isnewfileopened =
true;
596 isnewfileopened =
false;
601 error(
"You should not be here! Please contact philip@physics.ucsd.edu", __FUNCTION__);
603 isnewfileopened =
false;
611 template <
class TREECLASS>
613 return isnewfileopened;
617 template <
class TREECLASS>
626 template <
class TREECLASS>
629 nEventsTotalInChain = tchain->GetEntries();
631 if (nEventsToProcess < 0)
632 nEventsToProcess = nEventsTotalInChain;
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;
639 print(TString::Format(
"Total Events in this Chain to process = %d", nEventsToProcess));
644 template <
class TREECLASS>
652 template <
class TREECLASS>
659 int entry = nEventsProcessed;
660 int totalN = nEventsToProcess;
669 if (use_treeclass_progress) {
680 if (
entry > totalN) {
682 }
else if (
entry == totalN) {
683 Double_t elapsed = my_timer.RealTime();
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;
698 printf(
"\rRooUtil::");
700 printf(
"|====================");
707 printf(
"| %.1f %% (%d/%d) with [avg. %d Hz] Total Time: %.2d:%.2d:%.2d \n",
718 else if (
entry % (((
int)print_rate)) == 0 ||
force) {
724 TString
msg = TString::Format(
"%d %d",
entry, totalN);
726 RooUtil::error(
"Total number of events processed went over max allowed! Check your loop boundary conditions!!",
730 int nbars =
entry / (totalN / 20);
731 Double_t elapsed = my_timer.RealTime();
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;
747 print_rate = (
int)(
rate / 5) + 1;
749 printf(
"RooUtil:: ");
766 for (
int nb = 0; nb < 20; ++nb) {
773 printf(
"| %.1f %% (%d/%d) with [%d Hz] ETA %.2d:%.2d:%.2d \r",
784 my_timer.Start(kFALSE);
788 template <
class TREECLASS>
790 skimfilename = ofilename;
795 template <
class TREECLASS>
797 skimfile =
new TFile(skimfilename,
"recreate");
798 TObjArray* toa = ttree->GetListOfBranches();
800 if (skimbrfiltpttn.size() > 0) {
801 ttree->SetBranchStatus(
"*", 0);
803 for (
auto& pttn : skimbrfiltpttn) {
804 for (
const auto& brobj : *toa) {
805 TString brname = brobj->GetName();
807 if (pttn.Contains(
"*")) {
808 TString modpttn = pttn;
809 modpttn.ReplaceAll(
"*",
"");
810 if (brname.Contains(modpttn) && brname.BeginsWith(modpttn)) {
812 ttree->SetBranchStatus(brname +
"*", 1);
815 if (brname.EqualTo(pttn)) {
817 ttree->SetBranchStatus(brname, 1);
824 skimtree = ttree->CloneTree(0);
828 template <
class TREECLASS>
830 ttree->CopyAddresses(skimtree);
834 template <
class TREECLASS>
836 treeclass->LoadAllBranches();
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();
852 template <
class TREECLASS>
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;
863 if (nskipped >= nskipped_threshold) {
864 nskipped += tchain->GetEntries() - getCurrentEventIndex() - 1;
871 if (nskipped_batch > nbatch_skip_threshold) {
872 nskipped += nskipped_batch;
874 for (
unsigned int i = 0;
i < nbatch_to_skip; ++
i) {
885 template <
class TREECLASS>
887 getTree()->PrintCacheStats();
888 printSkippedBadEventStatus();
892 template <
class TREECLASS>
894 TString rtnstring =
"";
895 TObjArray* filepaths = tchain->GetListOfFiles();
896 TObjArrayIter* iter =
new TObjArrayIter(
listOfFiles);
898 TChainElement* chainelement = (TChainElement*)iter->Next();
900 TString
filepath = chainelement->GetTitle();
901 if (rtnstring.IsNull())
911 template <
class TREECLASS>
914 nskipped += nskipped_batch;
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;
924 template <
class TREECLASS>
926 if (ttree->GetBranch(
bname))
928 if (ttree->GetBranch(ttree->GetAlias(
bname)))
unsigned int nEventsTotalInTree
bool doesBranchExist(TString bname)
TTreePerfStats * getTTreePerfStats()
unsigned int indexOfEventInTTree
unsigned int nEventsSkimmed
void print(TString msg="", const char *fname="", int flush_before=0, int flush_after=0)
void printProgressBar(bool force=false)
void setTChain(TChain *c)
bool allEventsInChainProcessed()
void printCurrentEventIndex()
void init(TChain *chain, TREECLASS *treeclass, int nEventsToProcess)
unsigned int nskipped_threshold
void setTreeClass(TREECLASS *t)
void load(TString filename)
void error(TString msg, const char *fname="", int is_error=1)
void setNbadEventThresholdToTriggerBatchSkip(unsigned int n)
unsigned int nskipped_batch
unsigned int getNEventsProcessed()
TString getCurrentFileBaseName()
unsigned int nEventsProcessed
std::vector< TString > skimbrfiltpttn
bool allEventsInTreeProcessed()
void setEventIndexMap(TString file)
void print(TMatrixD &m, const char *label=nullptr, bool mathematicaFormat=false)
void setNbatchToSkip(unsigned int n)
TString getListOfFileNames()
void setSkimBranchFilterPattern(std::vector< TString > x)
EventIndexMap eventindexmap
void setSkim(TString ofilename)
void copyAddressesToSkimTree()
void setSkimMaxSize(Long64_t maxsize)
bool use_treeclass_progress
void setSilent(bool s=true)
unsigned int nbatch_skip_threshold
void setFastMode(bool f=true)
TString getSkimFileName()
unsigned int getNEventsTotalInChain()
void printSkippedBadEventStatus()
TString getCurrentFileTitle()
unsigned int nEventsTotalInChain
void setNbadEventThreshold(unsigned int n)
TString getCurrentFileName()
void setNEventsToProcess()
unsigned int nbatch_to_skip
unsigned int getCurrentEventIndex()