ROOT Version: 6.24/00 Platform: 5.12.13-300.fc34.x86_64 Compiler: gcc version 11.1.1 20210531 (Red Hat 11.1.1-3) (GCC)
Hello,
I have a ROOT Tree which contains 105 Branches. I am trying to access the values of each branch and fill the corresponding histogram using the attached code. This code works, but dead slow. With this it will take ages to complete the data analysis.
Any help/guidance is highly appreciated.
I can provide a sample root file which I am using for the analysis, if required.
calling fChain->LoadTree at every event is expensive
calling fCHain->GetListOfBranches()->At(i) is expensive
calling fChain->GetLeaf at every event might be expensive
On Linux you can use e.g. perf to profile an execution of your code and see where time is spent.
Also, if you need speed you should compile the code with optimizations (i.e. with g++ -O2 ...) or execute it via ACLiC (root GetValue.C+, note the + at the end) which compiles with with optimizations under the hood.
Also check ROOT: ROOT::RDataFrame Class Reference for a higher-level data processing interface that takes care of these details for you.
If you want a histogram for each branch in the tree, with RDataFrame the code looks like this (have not tested this but it should give you an idea):
ROOT::RDataFrame df("RoseNIAS", "eu152_11july_afterGlitch.001");
std::vector<ROOT::RDF::RResultPtr<TH1D>> histos;
for (const std::string &col : df.GetColumnNames()) {
auto h = df.Histo1D<double>(col);
histos.push_back(h);
}
// Computation has been booked but it has not started yet.
// The first time you access one of the histograms,
// all of them will be filled in a single event loop
If you add ROOT::EnableImplicitMT() at the beginning of that snippet, reading data and filling histograms is done in parallel on multiple threads for better performance.
Cheers,
Enrico
P.S.
note that the 6 lines of code above are really all the code needed to substitute what you have in GetValue.C: RDataFrame is more concise.
About 2., what do you mean when you say you want the âvalue of each branchâ? Each branch has one value per entry. Do you want to put all those values e.g. in a vector?
The way you were doing it in GetValue.C is totally fine. RDataFrame can count entries but it does not offer a method to retrieve the number directly from TTree.
With RDF, you can use Take:
auto vectorPtr = df.Take<double>("columnName");
vectorPtr is a RResultPtr<std::vector<double>>, i.e. a pointer to your vector.
After I execute the code that you have shared, I should get the histograms, right? If I do
ââ[root 1]ââ .ls
I donât see any histograms! How to access those? Where are they?
As an aside (@eguiraud answer are more relevant):
In,
Long64_t ientry = fChain->LoadTree(k);
if (ientry < 0) break;
fChain->GetEntry(k);
The first 2 lines are redundant with the 3rd one per se. However, calling fChain->GetEntry(k); is often an overkill as it reads the whole entry whereas you only need a âfewâ branches. The more typical use is:
Long64_t ientry = fChain->LoadTree(k);
if (ientry < 0) break;
// Do the following for all the branch you need.
branch->GetEntry(ientry);
is not quite accurate it âjustâ move the cursor (if needed) to the requested tree in the TChain and return the corresponding entry in the local TTree. It is cheap (except when its time to open a new file)
Fatal: fConcreteAction != nullptr violated at line 43 of `/opt/root-6.24.00/tree/dataframe/src/RJittedAction.cxx'
aborting
#0 0x00007f2329b20aca in ?? () from /lib64/libc.so.6
#1 0x00007f2329a9e09b in ?? () from /lib64/libc.so.6
#2 0x00007f232a2de7dc in TUnixSystem::StackTrace() () from /opt/root/pro/lib/libCore.so
#3 0x00007f232a1b0e12 in DefaultErrorHandler(int, bool, char const*, char const*) () from /opt/root/pro/lib/libCore.so
#4 0x00007f232a2697f1 in ErrorHandler () from /opt/root/pro/lib/libCore.so
#5 0x00007f232a26a208 in Fatal(char const*, char const*, ...) () from /opt/root/pro/lib/libCore.so
#6 0x00007f23118648e6 in ROOT::Internal::RDF::RJittedAction::TriggerChildrenCount() () from /opt/root/pro/lib/libROOTDataFrame.so
#7 0x00007f231186c265 in ROOT::Detail::RDF::RLoopManager::EvalChildrenCounts() () from /opt/root/pro/lib/libROOTDataFrame.so
#8 0x00007f231186c2ac in ROOT::Detail::RDF::RLoopManager::InitNodes() () from /opt/root/pro/lib/libROOTDataFrame.so
#9 0x00007f2311873eb3 in ROOT::Detail::RDF::RLoopManager::Run() () from /opt/root/pro/lib/libROOTDataFrame.so
#10 0x00007f2322cdc0cf in ?? ()
#11 0x0000000000000000 in ?? ()
I am sharing one data file with you for further dignosis, is required.
I tried with ROOTâs master branch compiled from source today, with ROOT v6.24.02 installed via conda and ROOT v6.24.00 on LXPLUS (using LCG view LCG_100). They all work.
They histogram is not particularly pretty (long tails!) but the axes limits can be adjusted
root [0] ROOT::RDataFrame df("RoseNIAS", "eu152_11july_afterGlitch.002")
(ROOT::RDataFrame &) A data frame built on top of the RoseNIAS dataset.
root [1] auto h1 = df.Histo1D("CL_02_E01")
(ROOT::RDF::RResultPtr<TH1D> &) @0x7fe186264050
root [2] h1->Draw()
Info in <TCanvas::MakeDefCanvas>: created default TCanvas with name c1
So I canât reproduce the crash. Things should also be fine for you if you install ROOT via conda or you use an LCG view on lxplus, as weâd be using the exact same ROOT (instructions are at Installing ROOT - ROOT ).
If you can reproduce the crash on LXPLUS, with a conda package or in a Docker container I should be able to reproduce it and check whatâs going on.
This is very strange! I always build ROOT from source. It would be difficult to install ROOT via conda only for this purpose.
Is there a way to improve my original code without using RDataFrame? Would certainly love to use RDF, but right now my objective is to get the histograms and access branch value efficiently, with the present versions of ROOT [6.24/00 & 6.25/01] installed on my laptop.
As per your suggestion, I have installed ROOT via conda and could draw the above histogram.
However, when I try to run the attached macro, with different methods as shown below, it is throwing error. Am I doing something wrong in the macro?
root [0] .x GetValue.C
Error in <TFile::TFile>: file /home/ajay/Research/IUAC_Experiments_July2021/DATA/Source/Misc/eu152_11july_afterGlitch.002/RoseNIAS does not exist
Warning in <TTreeReader::SetEntryBase()>: There was an issue opening the last file associated to the TChain being processed.
Error in <TFile::TFile>: file /home/ajay/Research/IUAC_Experiments_July2021/DATA/Source/Misc/eu152_11july_afterGlitch.002/RoseNIAS does not exist
Warning in <TTreeReader::SetEntryBase()>: There was an issue opening the last file associated to the TChain being processed.
Error in <TTreeReader::SetEntriesRange()>: Error setting first entry 1185030: problem reading dictionary info from tree
Info in <TCanvas::MakeDefCanvas>: created default TCanvas with name c1
root [1] .q
(myROOT) ajay@ZBook Misc$ root
------------------------------------------------------------------
| Welcome to ROOT 6.24/02 https://root.cern |
| (c) 1995-2021, The ROOT Team; conception: R. Brun, F. Rademakers |
| Built for linuxx8664gcc on Jul 03 2021, 08:02:00 |
| From tag , 28 June 2021 |
| With |
| Try '.help', '.demo', '.license', '.credits', '.quit'/'.q' |
------------------------------------------------------------------
root [0] .x GetValue.C+
Info in <TUnixSystem::ACLiC>: creating shared library /home/ajay/Research/IUAC_Experiments_July2021/DATA/Source/Misc/./GetValue_C.so
Error in <TFile::TFile>: file /home/ajay/Research/IUAC_Experiments_July2021/DATA/Source/Misc/eu152_11july_afterGlitch.002/RoseNIAS does not exist
Warning in <TTreeReader::SetEntryBase()>: There was an issue opening the last file associated to the TChain being processed.
Error in <TFile::TFile>: file /home/ajay/Research/IUAC_Experiments_July2021/DATA/Source/Misc/eu152_11july_afterGlitch.002/RoseNIAS does not exist
Warning in <TTreeReader::SetEntryBase()>: There was an issue opening the last file associated to the TChain being processed.
Error in <TTreeReader::SetEntriesRange()>: Error setting first entry 1185030: problem reading dictionary info from tree
Info in <TCanvas::MakeDefCanvas>: created default TCanvas with name c1
root [1] .q
(myROOT) ajay@ZBook Misc$ root
------------------------------------------------------------------
| Welcome to ROOT 6.24/02 https://root.cern |
| (c) 1995-2021, The ROOT Team; conception: R. Brun, F. Rademakers |
| Built for linuxx8664gcc on Jul 03 2021, 08:02:00 |
| From tag , 28 June 2021 |
| With |
| Try '.help', '.demo', '.license', '.credits', '.quit'/'.q' |
------------------------------------------------------------------
root [0] .x GetValue.C++
Info in <TUnixSystem::ACLiC>: creating shared library /home/ajay/Research/IUAC_Experiments_July2021/DATA/Source/Misc/./GetValue_C.so
Error in <TFile::TFile>: file /home/ajay/Research/IUAC_Experiments_July2021/DATA/Source/Misc/eu152_11july_afterGlitch.002/RoseNIAS does not exist
Warning in <TTreeReader::SetEntryBase()>: There was an issue opening the last file associated to the TChain being processed.
Error in <TFile::TFile>: file /home/ajay/Research/IUAC_Experiments_July2021/DATA/Source/Misc/eu152_11july_afterGlitch.002/RoseNIAS does not exist
Warning in <TTreeReader::SetEntryBase()>: There was an issue opening the last file associated to the TChain being processed.
Error in <TTreeReader::SetEntriesRange()>: Error setting first entry 1185030: problem reading dictionary info from tree
Info in <TCanvas::MakeDefCanvas>: created default TCanvas with name c1
root [1]