From e72e4b6eddb7823ef1d653f47995d8d84c1d4259 Mon Sep 17 00:00:00 2001 From: David Brown Date: Mon, 25 Apr 2022 16:13:37 -0700 Subject: [PATCH 1/3] Add a utility to make root command line parsing of splitlevel=99 TrkAna trees easier (cherry picked from commit e2c80add8dba5ab4689b29332bfaa85817fdea78) --- examples/TrkAnaUtils.C | 126 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 126 insertions(+) create mode 100644 examples/TrkAnaUtils.C diff --git a/examples/TrkAnaUtils.C b/examples/TrkAnaUtils.C new file mode 100644 index 0000000..e7d48d3 --- /dev/null +++ b/examples/TrkAnaUtils.C @@ -0,0 +1,126 @@ +// +// Utility macros for inspecting TrkAna files for use from the root prompt. As an example, running from +// a muse directory with TrkAna included: +// > root -l +// root> #include TrkAna/examples/TrkAnaUtils.C +// root> TrkAnaUtils tau("MyTrkAnaFile.cc"); +// root> tau.ListTrees(); // lists available TrkAna tree (TDirectories) +// root> tau.UseTree("TrkAnaNeg"); // use the tree based on downstream negative electron tracks +// root> tau.ListBranches(); // list the available branches +// root> tau.ListSubbranches("deent"); // list sub-branches for the downstream negative elecgtron branch +// root> tau.ListLeaves("hcnt."); // list leaves in the hitcount branch +// root> tau.Draw("deent.mom.Theta():deent.pos.Y()","hcnt.nbkg<400","colorz"); // Draw a plot +// +// Original author: Dave Brown (LBNL) +// +#include +#include +class TrkAnaUtils { + public: + TrkAnaUtils(const char* filename); + ~TrkAnaUtils() { delete myfile_; } + TFile const& File() const { return *myfile_; } + void ListTrees() const; + void UseTree(const char* treename="TrkAnaNeg"); + void fileName() { return myfile_->GetName(); } + void treeName() { if(mytree_)return mytree_->GetName(); else std::cout << "No current tree" << std::endl; } + TFile* file() { return myfile_;} + TTree* tree() { return mytree_;} + void ListBranches() const; + void ListSubbranches(const char* branch) const; + void ListLeaves(const char* branch) const; + void Draw(const char* lname,const char* cut="", const char* gopt="") const; + private: + TFile* myfile_; + TTree* mytree_; +}; + +TrkAnaUtils::TrkAnaUtils(const char* filename) : mytree_(0) { + myfile_ = new TFile(filename); +} + +void TrkAnaUtils::ListTrees() const { + TObjArray* keylist = (TObjArray*)myfile_->GetListOfKeys(); + int nkeys = keylist->GetEntries(); + for(int ikey=0;ikeyAt(ikey); + std::string kname(key->GetName()); + if(0 == kname.compare(0,6,std::string("TrkAna"))) + std::cout << kname << std::endl; + } +} + +void TrkAnaUtils::UseTree( const char* treename) { + TObjArray* keylist = (TObjArray*)myfile_->GetListOfKeys(); + int nkeys = keylist->GetEntries(); + for(int ikey=0;ikeyAt(ikey); + std::string kname(key->GetName()); + if(0 == kname.compare(std::string(treename))){ + auto td = (TDirectory*)myfile_->GetDirectory(treename); + if(td){ + mytree_ = (TTree*)td->Get("trkana"); + if(!mytree_) + std::cout <<"Error: can't find TrkAna tree in TDirectory " << treename << std::endl; + } else + std::cout <<"Error: can't find TDirectory " << treename << std::endl; + } + } +} + +void TrkAnaUtils::ListBranches() const { + if(mytree_){ + auto blist = mytree_->GetListOfBranches(); + int nbs = blist->GetEntries(); + for(int ib=0;ibAt(ib); + std::cout << b->GetName() << std::endl; + } + } else { + std::cout << "No current tree; call UseTree to set current tree" << std::endl; + } +} + +void TrkAnaUtils::ListSubbranches(const char* branch) const { + if(mytree_){ + auto bran = mytree_->GetBranch(branch); + if(bran){ + auto blist = bran->GetListOfBranches(); + int nbs = blist->GetEntries(); + for(int ib=0;ibAt(ib); + std::cout << b->GetName() << std::endl; + } + } else { + std::cout << "Current tree has no branch" << branch << std::endl; + } + } else { + std::cout << "No current tree; call UseTree to set current tree" << std::endl; + } +} + +void TrkAnaUtils::ListLeaves(const char* branch) const { + if(mytree_){ + auto bran = mytree_->GetBranch(branch); + if(bran){ + auto blist = bran->GetListOfLeaves(); + int nbs = blist->GetEntries(); + for(int ib=0;ibAt(ib); + std::cout << b->GetName() << std::endl; + } + } else { + std::cout << "Current tree has no branch" << branch << std::endl; + } + } else { + std::cout << "No current tree; call UseTree to set current tree" << std::endl; + } +} + +void TrkAnaUtils::Draw(const char* lname,const char* cut="", const char* gopt="") const { + if(mytree_){ + mytree_->Draw(lname,cut,gopt); + } else { + std::cout << "No current tree; call UseTree to set current tree" << std::endl; + } +} From 89433cbd940c738530f99c34ffd9306d1f7841a9 Mon Sep 17 00:00:00 2001 From: David Brown Date: Mon, 25 Apr 2022 16:25:59 -0700 Subject: [PATCH 2/3] Fix typos in comments (cherry picked from commit 3a4043e8fd7910f5a54504fbcaa45451882000e4) --- examples/TrkAnaUtils.C | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/examples/TrkAnaUtils.C b/examples/TrkAnaUtils.C index e7d48d3..2a64594 100644 --- a/examples/TrkAnaUtils.C +++ b/examples/TrkAnaUtils.C @@ -3,11 +3,11 @@ // a muse directory with TrkAna included: // > root -l // root> #include TrkAna/examples/TrkAnaUtils.C -// root> TrkAnaUtils tau("MyTrkAnaFile.cc"); -// root> tau.ListTrees(); // lists available TrkAna tree (TDirectories) +// root> TrkAnaUtils tau("MyTrkAnaFile.root"); +// root> tau.ListTrees(); // lists available TrkAna trees (TDirectories) // root> tau.UseTree("TrkAnaNeg"); // use the tree based on downstream negative electron tracks // root> tau.ListBranches(); // list the available branches -// root> tau.ListSubbranches("deent"); // list sub-branches for the downstream negative elecgtron branch +// root> tau.ListSubbranches("deent"); // list sub-branches for the downstream negative electron branch // root> tau.ListLeaves("hcnt."); // list leaves in the hitcount branch // root> tau.Draw("deent.mom.Theta():deent.pos.Y()","hcnt.nbkg<400","colorz"); // Draw a plot // From bd79d0971addb5cf12a0634013688c7a3022e225 Mon Sep 17 00:00:00 2001 From: brownd1978 Date: Mon, 2 May 2022 16:43:34 -0700 Subject: [PATCH 3/3] Improvements (cherry picked from commit 0dafe785c2de8e24ca959466804d096d4d16016e) --- examples/TrkAnaUtils.C | 59 +++++++++++++++++++++++++++--------------- 1 file changed, 38 insertions(+), 21 deletions(-) diff --git a/examples/TrkAnaUtils.C b/examples/TrkAnaUtils.C index 2a64594..3b20471 100644 --- a/examples/TrkAnaUtils.C +++ b/examples/TrkAnaUtils.C @@ -17,7 +17,8 @@ #include class TrkAnaUtils { public: - TrkAnaUtils(const char* filename); + TrkAnaUtils(TFile* myfile,const char* treename="TrkAnaNeg"); + TrkAnaUtils(const char* filename,const char* treename="TrkAnaNeg"); ~TrkAnaUtils() { delete myfile_; } TFile const& File() const { return *myfile_; } void ListTrees() const; @@ -26,17 +27,23 @@ class TrkAnaUtils { void treeName() { if(mytree_)return mytree_->GetName(); else std::cout << "No current tree" << std::endl; } TFile* file() { return myfile_;} TTree* tree() { return mytree_;} - void ListBranches() const; - void ListSubbranches(const char* branch) const; + void ListBranches(int maxdepth=0) const; + void ListBranch(const char* bname, int maxdepth=1) const; void ListLeaves(const char* branch) const; void Draw(const char* lname,const char* cut="", const char* gopt="") const; private: + void ListBranch(TBranch* branch, int idepth, int maxdepth) const; TFile* myfile_; TTree* mytree_; }; -TrkAnaUtils::TrkAnaUtils(const char* filename) : mytree_(0) { +TrkAnaUtils::TrkAnaUtils(TFile* myfile,const char* treename) : myfile_(myfile) { + UseTree(treename); +} + +TrkAnaUtils::TrkAnaUtils(const char* filename,const char* treename) : mytree_(0) { myfile_ = new TFile(filename); + UseTree(treename); } void TrkAnaUtils::ListTrees() const { @@ -60,45 +67,55 @@ void TrkAnaUtils::UseTree( const char* treename) { auto td = (TDirectory*)myfile_->GetDirectory(treename); if(td){ mytree_ = (TTree*)td->Get("trkana"); - if(!mytree_) - std::cout <<"Error: can't find TrkAna tree in TDirectory " << treename << std::endl; + if(!mytree_) + std::cout <<"Error: can't find TrkAna tree in TDirectory " << treename << std::endl; } else std::cout <<"Error: can't find TDirectory " << treename << std::endl; } } } -void TrkAnaUtils::ListBranches() const { +void TrkAnaUtils::ListBranches(int maxdepth) const { + int idepth(0); if(mytree_){ - auto blist = mytree_->GetListOfBranches(); - int nbs = blist->GetEntries(); + auto tlist = mytree_->GetListOfBranches(); + int nbs = tlist->GetEntries(); for(int ib=0;ibAt(ib); - std::cout << b->GetName() << std::endl; + auto branch = (TBranch*)tlist->At(ib); + ListBranch(branch,idepth,maxdepth); } } else { std::cout << "No current tree; call UseTree to set current tree" << std::endl; } } -void TrkAnaUtils::ListSubbranches(const char* branch) const { +void TrkAnaUtils::ListBranch(const char* bname, int maxdepth) const { if(mytree_){ - auto bran = mytree_->GetBranch(branch); - if(bran){ - auto blist = bran->GetListOfBranches(); - int nbs = blist->GetEntries(); - for(int ib=0;ibAt(ib); - std::cout << b->GetName() << std::endl; - } + auto branch = mytree_->GetBranch(bname); + if(branch){ + ListBranch(branch,0,maxdepth); } else { - std::cout << "Current tree has no branch" << branch << std::endl; + std::cout << "No branch " << bname << " in current tree" << std::endl; } } else { std::cout << "No current tree; call UseTree to set current tree" << std::endl; } } +void TrkAnaUtils::ListBranch(TBranch* branch, int idepth, int maxdepth) const { + std::cout << branch->GetName() << std::endl; + if(idepth < maxdepth){ + auto blist = branch->GetListOfBranches(); + int nbs = blist->GetEntries(); + for(int ib=0;ibAt(ib); + ListBranch(subbranch,idepth++,maxdepth); + } + } +} + + + void TrkAnaUtils::ListLeaves(const char* branch) const { if(mytree_){ auto bran = mytree_->GetBranch(branch);