How to disable branches in TSelector using TTreeReader

Dear ROOT experts,

I’m trying to write a TSelector class to run on a number of different TTrees, some of which have branches which are not present in the other trees.

The problem is that, when using TTreeReader, TTreeReaderValues need to be specified for each of the branches in the header file:

TTreeReaderValue<Float_t> branch_name = {fReader, "branch_name"};

If I try to run on a different TTree, which does not contain “branch_name”, I get the error:

Error in <TTreeReaderValueBase::CreateProxy()>: The tree does not have a branch called branch_name. You could check with TTree::Print() for available branches.

Is there some way that I can choose which TTreeReaderValues should be initialised without needing to modify the header file of my TSelector class for every new TTree that I want to run over?

From what I can tell, there is no way to set the members of TTreeReader during runtime because it doesn’t have a default constructor – i.e. I canot just write:

TTreeReaderValue<Float_t> branch_name;

in my header file, and then set

branch_name = {fReader, "branch_name"};

in TSelector::Begin.

But I would like to add an option here to tell the TSelector which branches are present in the tree. Is there a way to do this, or do I need to write a new TSelector class for each of the different TTree structures that I want to read?


ROOT Version: 6.18
Platform: CentOS7
Compiler: Not Provided

Hi Alex,

I invite @pcanal or @eguiraud to have a look.

That depends. If you do not use this branch, you can simply comment out from the header file any mention of it (i.e. the data member and all related uses).

If you do use the branch, how do you handle the case where it is missing?

Hi @pcanal,

Thanks for the speedy reply!

I would like to not have to modify the code each time I run over a different tree, so commenting out lines in the header file is not an option. Is there no way to pass an optional parameter to the TSelector to tell the TTreeReader which branches are present in the tree?


Hi Alex,

Are you using the branch in some cases and not others?


Yes, I’m running over two different trees which contain truth and reco-level information respectively. The truth tree has all the same branches as the reco tree plus additional branches containing truth-level information that has no equivalent at reco-level.

I would like to turn the truth-only branches on or off depending on which type of tree I’m running on. This would be a lot more convenient than having a separate TSelector for the truth tree, since most of the operations I do on each o f the trees are the same, except for a handful that use the truth-only branches.


In which case you easiest solution (albeit a tad bit cumbersome) is to turn that data member into a pointer:

TTreeReaderValue<Float_t> *branch_name{nullptr};

and assign it with

branch_name = new TTreeReaderValue<Float_t>{fReader, "branch_name"};

only for the Tree that contains the branch.

That did the trick. Thanks!


Note that you (of course) need to remember to delete it later on, either by adding an explicit call to operate delete or by using a unique_ptr:

std::unique_ptr<TTreeReaderValue<Float_t>> branch_name;

branch_name.reset( new TTreeReaderValue<Float_t>{fReader, "branch_name"} ); // or std::make_unique

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.