Reading certain branches with TTreeReader class using TSelector

Hi Root experts!!

This is my dilemma: I have two different root files containing a tree, and they have the same structure and branches, but one of them has some extra branches. I would like to read both of them using the same TSelector.

Before, I had in the header, say ‘Selector.h’:

class Selector : public TSelector {
public : 
  TTree          *fChain;   //!pointer to the analyzed TTree or TChain
  Float_t         weight;
  TBranch        *b_weight;   //!
}
void Selector::Init(TTree *tree)
{
   fChain->SetBranchAddress("weight", &weight, &b_weight);
}

And then I was able to decide which branches I want to read inside the function Process of 'Selector.'C:

Bool_t Selector::Process(Long64_t entry)
{
  b_weight ->GetEntry(entry);
}

I would like to do the same with TTreeReader. I would like to use the GetOption() and depending on which file I am running on, read (or activate with SetBranchStatus?) a certain branch.

Is this possible to do at the Process level? For the time being, I just read everything as:

Bool_t Selector::Process(Long64_t entry)
{
  fReader.SetLocalEntry(entry); // For a TChain 
}

and I dont know how to just read some branches of my TTreeReaderValue

Gracias!

which root?
/cvmfs/sft.cern.ch/lcg/releases/LCG_94/ROOT/6.14.04/x86_64-slc6-gcc62-opt/bin/root
in lxplus

1 Like

@ganis could you perhaps give a hand with this TSelector related question?

In the meantime, perhaps this can help?

https://root.cern.ch/accessing-ttree-tselector

It is an example of using TTreeReader with TSelector, where a TTreeReaderValue is created and used in Process.

Thanks for the answer!

Indeed, my problem is not that my TSelector is not working. I am able to read ALL the branches defined with TTreeReaderValue and TTreeReaderArray with:

Bool_t Selector::Process(Long64_t entry)
{
  fReader.SetLocalEntry(entry); 
}

as it is done in the example code you shared with me. Enclosed you can find my TSelector code if you want to have a glance. UFO_jets.h (31.0 KB) UFO_jets.C (12.4 KB)

But I would like to read just some of the branches, not all of them inside Process. Something like:

Bool_t Selector::Process(Long64_t entry)
{
TString option = GetOption();
if (option.Index("Wprime")!=-1)
 {
   *Somehow read a particular branch of the tree which is present in the Wprime sample*
 }
else
 {
   fReader.SetLocalEntry(entry);  // READ ALL of them
 }
}

Is this possible? I am super sure there should be a simple way to do this and I am thinking in the complicated one :slight_smile:

1 Like

Hi,
All the branches for which you defined a TTreeReaderValue or TTreeReaderArray will be read. If you only define them for a subset of your branches, only that subset will be read.

If you were not using TTreeReader, what you could do is use this SetBranchStatus function from the TTree:

https://root.cern.ch/doc/master/classTTree.html#aeca53bcd4482de1d883d259df6663920

which allows to dynamically enable and disable the reading of branches. But I don’t know how that interplays with TTreeReader (what has precedence).

Thanks @etejedor for understanding my problem.

I still do not know how to able/disable a branch with TTreeReader :frowning:
I do not want to go back to the previous TSelector with branches definitions, maybe that is the solution.

Any suggestion? @ganis? Someone? :pleading_face:

Hi,
I understand it is not an option for you to not create TTreeReaderValues for the branches you do not want to read?

@pcanal do you know if it is possible to dynamically disable the reading of some branches when reading with TTreeReader (e.g. interplay with SetBranchStatus)?

Hi,
It does not look like TTreeReader has specific methods for that.
However, TTreeReader gives access to the underlying tree and TTreeReaderValue to the underlying branch. Therefore acting on the TTree to disable all the branches, and on the individual branches to enable which one is wanted should work.

G Ganis

The comment is misleading and might be the source of the confusion. SetLocalEntry does not read anything at all … all it does is set the ‘cursor’ of the TTreeReader to be at the requested entry. You should execute that line in all cases.

Bool_t Selector::Process(Long64_t entry)
{
  fReader.SetLocalEntry(entry);  // READ ALL of them
 TString option = GetOption();
if (option.Index("Wprime")!=-1)
 {
   *Somehow read a particular branch of the tree which is present in the Wprime sample*
 }
else
 {
   *Somehow read a particular branch of the tree which is present in the other sample*
 }
}

One of the main feature of the TTreeReader is that they read the data on demand. So there is never a need to disable any of the branches … the data will be read if and only if you access its corresponding field/data-member in the TSelector.

Cheers,
Philippe.

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