Accessing TBranch Value

Hello,
I’ve spent the past few hours looking for a way to read a TBranch value online, and I couldn’t find anything too useful.
Here’s the situation,

I’ve saved a list of integers into a file_info tree as an individual branch
TTree* file_info = new TTree(“file_info”,“file_info”);
file_info->Branch( keywords[i].c_str() , &headerlist[i] ,“Value/F” );

In another code, the values I am trying to access are &headerlist[i] elements.

When I look at the TBrowser, I can see the values just fine, but I’ve been looking for ways to extract these numbers in root command lines/macros and codes, how can I refer to these?

It’s driving me crazy because I’ve been specifically asked to save the header information in the tbranch and I’m wasting too many hours trying to navigate around ntuple structure instead of simply using if/ofstream into a text file


ROOT Version: Not Provided
Platform: Not Provided
Compiler: Not Provided


Hi,
this answer should help you and/or point to more resources on the topic.

Cheers,
Enrico

Thank you, but I have read it, and this is not at all what I am looking for.
What I am not looking to read a list of entries, I am looking to read a specific value of a specific branch in a specific tree

If you don’t know how to deal with your tree, see how various flavours of automatically generated “analysis skeletons” deal with it.

Thank you, but I am asking for a specific example, I did read through the root_directory/tutorials/ and several other posts including yours.
However I am looking for a simple solution. Basically, in C++ I can do something simple as
ofstream output;
output.open(“this.txt”);
output<<element<<endl;

then later call it
ifstream input;
input.open(“this.txt”);
while (input >> element){

}

It seems that for ROOT, for something as simple and easy as this requires reading through 100s of pages even though this is easily accessible in TBrowser.

I appreciate your pointer to the reference, but I am not looking for a reference, I am looking for a solution.

Hi,
I understand ROOT interfaces can be daunting at first.
Also, I would not suggest to use a ROOT file and a TTree to store data that you can more easily manipulated as text. ROOT solves the problem of dealing efficiently with larger amounts of data than you can fit in a text file.

But anyway, let’s start with a snippet refactored from the answer I linked above.
The following code reads a value (the one corresponding to entry 42) of a branch called "my_branch" of a TTree called "my_tree" in a ROOT file called "my_file.root":

TFile f("my_file.root");
TTreeReader reader("my_tree", &f);
TTreeReaderValue<double> my_branch_value(reader, "my_branch");
reader.SetEntry(42);
std::cout << *my_branch_value << std::endl;

There are lower-level (read “more complicated, but with less assumptions about what you want to do”) ways to accomplish the same using TTree directly, and higher-level (read “simpler, but with more assumptions about what you want to do”) ways using RDataFrame.

That snippet is the simplest I can come up with that reads a single TBranch value.
The snippet that is the most similar to your ifstream example would read all branch values:

while (reader.Next())
   std::cout << *my_branch_value << std::endl;

Hope this helps!
Enrico

OOT_prompt_1:1:13: error: no matching constructor for initialization of 'TTreeReader' &#160;&#160;
TTreeReader reader("file_info" , &file)
&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;^ &#160;&#160;&#160;&#160;&#160;~~~~~~~~~~~~~~~~~~~
/home/SJLPHI/Physics_Soft/ROOT6/include/TTreeReader.h:157:4: note: candidate constructor
not viable: no known conversion from 'TFile **' to 'TDirectory *'
&#160;&#160;&#160;&#160;&#160;for 2nd argument; remove &
&#160;&#160;TTreeReader(const char* keyname, TDirectory* dir, TEntryList* entryList = nullptr);
&#160;&#160;^
/home/SJLPHI/Physics_Soft/ROOT6/include/TTreeReader.h:158:4: note: candidate constructor
not viable: no known conversion from 'TFile **' to 'TEntryList *'
&#160;&#160;&#160;&#160;&#160;for 2nd argument
&#160;&#160;TTreeReader(const char* keyname, TEntryList* entryList = nullptr):
&#160;&#160;^
/home/SJLPHI/Physics_Soft/ROOT6/include/TTreeReader.h:156:4: note: candidate constructor
not viable: no known conversion from 'const char [10]' to
&#160;&#160;&#160;&#160;&#160;'TTree *' for 1st argument
&#160;&#160;TTreeReader(TTree* tree, TEntryList* entryList = nullptr);
&#160;&#160;^
/home/SJLPHI/Physics_Soft/ROOT6/include/TTreeReader.h:44:7: note: candidate constructor
(the implicit copy constructor) not viable: requires 1 argument,
&#160;&#160;&#160;&#160;&#160;but 2 were provided
class TTreeReader: public TObject {
&#160;&#160;&#160;&#160;&#160;^
/home/SJLPHI/Physics_Soft/ROOT6/include/TTreeReader.h:154:4: note: candidate constructor
not viable: requires 0 arguments, but 2 were provided
&#160;&#160;TTreeReader();

Hi,
from the error message it looks like in your code f is a pointer to TFile, so you just need to pass f to the TTreeReader constructor rather than &f (in my example f is a TFile object, not a pointer to TFile).

It has to be a pointer for the memory management, but I actually took out the actualvalue(&) in the constructor and I will get back to you after testing a bit more.

TTreeReaderValue<double> my_branch_value(reader "RUNID");
ROOT_prompt_2:1:49: error: expected ')'
TTreeReaderValue<double> my_branch_value(reader "RUNID");
                                                ^
ROOT_prompt_2:1:41: note: to match this '('
TTreeReaderValue<double> my_branch_value(reader "RUNID");
                                        ^
ROOT_prompt_2:1:26: error: no matching constructor for initialization of 'TTreeReaderValue<double>'
TTreeReaderValue<double> my_branch_value(reader "RUNID");
                         ^               ~~~~~~
/home/SJLPHI/Physics_Soft/ROOT6/include/ROOT/RDF/NodesUtils.hxx:21:7: note: candidate constructor (the implicit copy constructor) not viable: no known conversion
      from 'TTreeReader' to 'const TTreeReaderValue<double>' for 1st argument
class TTreeReaderValue;
      ^
/home/SJLPHI/Physics_Soft/ROOT6/include/ROOT/RDF/NodesUtils.hxx:21:7: note: candidate constructor (the implicit move constructor) not viable: no known conversion
      from 'TTreeReader' to 'TTreeReaderValue<double>' for 1st argument
/home/SJLPHI/Physics_Soft/ROOT6/include/TTreeReaderValue.h:137:4: note: candidate constructor not viable: requires 0 arguments, but 1 was provided
   TTreeReaderValue() = delete;
   ^
/home/SJLPHI/Physics_Soft/ROOT6/include/TTreeReaderValue.h:138:4: note: candidate constructor not viable: requires 2 arguments, but 1 was provided
   TTreeReaderValue(TTreeReader& tr, const char* branchname):
   ^

Note that ROOT does not require that you use pointers to TFiles. I only point it out because it’s a common misunderstanding, there are certainly use-cases in which a pointer might be more appropriate.

Should be reader, "RUNID", I missed a comma when I typed things out.

EDIT: the compiler error message could be clearer, but you can see from the candidate signatures that the constructor takes two arguments

root [0] TFile file("image_4232_ext_1.root")
(TFile &) Name: image_4232_ext_1.root Title: 
root [1] TTreeReader reader("file_info" , &file)
(TTreeReader &) Name: TTreeReader Title: A simple interface to read trees
root [2] TTreeReaderValue<double> my_branch_value(reader ,"RUNID");
root [3] reader.SetEntry(42);
root [4] std::cout << *my_branch_value << std::endl;
Error in <TTreeReaderValue::Get()>: Value reader not properly initialized, did you remember to call TTreeReader.Set(Next)Entry()?

 *** Break *** segmentation violation



===========================================================
There was a crash.
This is the entire stack trace of all threads:
===========================================================
#0  0x00007fe8a2398d9a in waitpid () from /lib64/libc.so.6
#1  0x00007fe8a231646f in do_system () from /lib64/libc.so.6
#2  0x00007fe8a34e219d in TUnixSystem::Exec (shellcmd=<optimized out>, this=0x17a07c0) at /home/SJLPHI/Physics_Soft/source_packages/root6source/core/unix/src/TUnixSystem.cxx:2119
#3  TUnixSystem::StackTrace (this=0x17a07c0) at /home/SJLPHI/Physics_Soft/source_packages/root6source/core/unix/src/TUnixSystem.cxx:2413
#4  0x00007fe8a34e49b4 in TUnixSystem::DispatchSignals (this=0x17a07c0, sig=kSigSegmentationViolation) at /home/SJLPHI/Physics_Soft/source_packages/root6source/core/unix/src/TUnixSystem.cxx:3644
#5  <signal handler called>
#6  0x00007fe8a3b4203e in ?? ()
#7  0x0000000001df8960 in ?? ()
#8  0x00007fe89e208978 in cling::MultiplexInterpreterCallbacks::EnteringUserCode() () from /home/SJLPHI/Physics_Soft/ROOT6/lib/libCling.so
#9  0x00007ffde8479550 in ?? ()
#10 0x00007fe8a3b42000 in ?? ()
#11 0x00007fe89e20d0df in cling::Interpreter::RunFunction(clang::FunctionDecl const*, cling::Value*) [clone .part.310] () from /home/SJLPHI/Physics_Soft/ROOT6/lib/libCling.so
#12 0x00007fe89e20d4ff in cling::Interpreter::EvaluateInternal(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, cling::CompilationOptions, cling::Value*, cling::Transaction**, unsigned long) () from /home/SJLPHI/Physics_Soft/ROOT6/lib/libCling.so
#13 0x00007fe89e20dc47 in cling::Interpreter::process(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, cling::Value*, cling::Transaction**, bool) () from /home/SJLPHI/Physics_Soft/ROOT6/lib/libCling.so
#14 0x00007fe89e2c59dd in cling::MetaProcessor::process(llvm::StringRef, cling::Interpreter::CompilationResult&, cling::Value*, bool) () from /home/SJLPHI/Physics_Soft/ROOT6/lib/libCling.so
#15 0x00007fe89e16486e in HandleInterpreterException (metaProcessor=0x1df79c0, input_line=<optimized out>, compRes=
0x7ffde8479424: cling::Interpreter::kSuccess, result=result
entry=0x7ffde8479550) at /home/SJLPHI/Physics_Soft/source_packages/root6source/core/metacling/src/TCling.cxx:2163
#16 0x00007fe89e1775ed in TCling::ProcessLine (this=0x1812cd0, line=<optimized out>, error=0x7ffde847991c) at /home/SJLPHI/Physics_Soft/source_packages/root6source/core/metacling/src/TCling.cxx:2321
#17 0x00007fe8a33964ad in TApplication::ProcessLine (this=0x17fdb20, line=<optimized out>, sync=<optimized out>, err=0x7ffde847991c) at /home/SJLPHI/Physics_Soft/source_packages/root6source/core/base/src/TApplication.cxx:1031
#18 0x00007fe8a383a7a2 in TRint::ProcessLineNr (this=this
entry=0x17fdb20, filestem=filestem
entry=0x7fe8a384c3c5 "ROOT_prompt_", line=0x3117720 "std::cout << *my_branch_value << std::endl;", error=0x7ffde847991c, error
entry=0x0) at /home/SJLPHI/Physics_Soft/source_packages/root6source/core/rint/src/TRint.cxx:746
#19 0x00007fe8a383aaf4 in TRint::HandleTermInput (this=0x17fdb20) at /home/SJLPHI/Physics_Soft/source_packages/root6source/core/rint/src/TRint.cxx:607
#20 0x00007fe8a34e3ea8 in TUnixSystem::CheckDescriptors (this=this
entry=0x17a07c0) at /home/SJLPHI/Physics_Soft/source_packages/root6source/core/unix/src/TUnixSystem.cxx:1322
#21 0x00007fe8a34e5678 in TUnixSystem::DispatchOneEvent (this=0x17a07c0, pendingOnly=<optimized out>) at /home/SJLPHI/Physics_Soft/source_packages/root6source/core/unix/src/TUnixSystem.cxx:1077
#22 0x00007fe8a33ff581 in TSystem::InnerLoop (this=0x17a07c0) at /home/SJLPHI/Physics_Soft/source_packages/root6source/core/base/src/TSystem.cxx:412
#23 TSystem::Run (this=0x17a07c0) at /home/SJLPHI/Physics_Soft/source_packages/root6source/core/base/src/TSystem.cxx:362
#24 0x00007fe8a339456f in TApplication::Run (this=this
entry=0x17fdb20, retrn=retrn
entry=false) at /home/SJLPHI/Physics_Soft/source_packages/root6source/core/base/src/TApplication.cxx:1183
#25 0x00007fe8a383c046 in TRint::Run (this=this
entry=0x17fdb20, retrn=retrn
entry=false) at /home/SJLPHI/Physics_Soft/source_packages/root6source/core/rint/src/TRint.cxx:460
#26 0x000000000040098a in main (argc=<optimized out>, argv=0x7ffde847bd48) at /home/SJLPHI/Physics_Soft/source_packages/root6source/main/src/rmain.cxx:30
===========================================================


The lines below might hint at the cause of the crash.
You may get help by asking at the ROOT forum http://root.cern.ch/forum
Only if you are really convinced it is a bug in ROOT then please submit a
report at http://root.cern.ch/bugs Please post the ENTIRE stack trace
from above as an attachment in addition to anything else
that might help us fixing this issue.
===========================================================
#6  0x00007fe8a3b4203e in ?? ()
#7  0x0000000001df8960 in ?? ()
#8  0x00007fe89e208978 in cling::MultiplexInterpreterCallbacks::EnteringUserCode() () from /home/SJLPHI/Physics_Soft/ROOT6/lib/libCling.so
#9  0x00007ffde8479550 in ?? ()
#10 0x00007fe8a3b42000 in ?? ()
#11 0x00007fe89e20d0df in cling::Interpreter::RunFunction(clang::FunctionDecl const*, cling::Value*) [clone .part.310] () from /home/SJLPHI/Physics_Soft/ROOT6/lib/libCling.so
#12 0x00007fe89e20d4ff in cling::Interpreter::EvaluateInternal(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, cling::CompilationOptions, cling::Value*, cling::Transaction**, unsigned long) () from /home/SJLPHI/Physics_Soft/ROOT6/lib/libCling.so
#13 0x00007fe89e20dc47 in cling::Interpreter::process(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, cling::Value*, cling::Transaction**, bool) () from /home/SJLPHI/Physics_Soft/ROOT6/lib/libCling.so
#14 0x00007fe89e2c59dd in cling::MetaProcessor::process(llvm::StringRef, cling::Interpreter::CompilationResult&, cling::Value*, bool) () from /home/SJLPHI/Physics_Soft/ROOT6/lib/libCling.so
#15 0x00007fe89e16486e in HandleInterpreterException (metaProcessor=0x1df79c0, input_line=<optimized out>, compRes=
0x7ffde8479424: cling::Interpreter::kSuccess, result=result
entry=0x7ffde8479550) at /home/SJLPHI/Physics_Soft/source_packages/root6source/core/metacling/src/TCling.cxx:2163
===========================================================


This is because I memory allocate the file size.

My best guess is that your TTree has less than 42 entries.

Yes, there are 17, and I tried setting entry to 42, same segment fault.

With 17 entries, reader.SetEntry(42) is bound to fail. Valid entry numbers are in the range 0 to 16 inclusive.
As per the doc, you can check wheter a SetEntry call succeded by inspecting its return value.

It did not fail at SetEntry, it failed at cout for the value.

You will get a segfault when accessing the value if SetEntry failed.
SetEntry signal failures through its return value.
Anyway, if your TTree has 17 entries, reader.SetEntry(42) will always return an error.

By the way, with RDataFrame your ifstream example becomes:

ROOT::RDataFrame("my_tree", "my_file.root").Foreach([](double x) { std::cout << x << std::endl; }, {"my_branch"});

or

ROOT::RDataFrame("my_tree", "my_file.root").Display("my_branch")->Print();