Home | News | Documentation | Download

How to select events in TChain and create a new TTree?

Hello ROOTers,

Is it possible to do TChain::Merge applying selections on the entries? In alternative, I can first do TChain::Merge and then apply selection: how do I select entries in a TTree (or create a new TTree selecting entries from a previous one)?

I am doing a loop on different selections and inside the loop just asking the number of entries of a TChain for the given selection (code posted below). However, it takes a lot because the entries are O(10^7), or at least I think this is the motivation.
I’d like to create offline a TTree with only the entries that already pass a baseline selection, and then just loop on this TTree varying the selections. I think this could speed up the whole loop.

This is the code I am using:


 TChain t("merged");
  t.Add("~/mydir/*_ntuple.root");

  Int_t R2cuts[5] = {50, 40, 30, 25, 20};
  Int_t TBTOcuts[5] = {92, 90, 87, 85, 80};
  Int_t dim = 25;
  Int_t counter = 0;
  Int_t globalIndex[dim];
  TString Scut;
  TString Bcut;
  Float_t S[dim];
  Float_t B[dim];

  for(Int_t iTBTO=0; iTBTO<5; iTBTO++){
    for(Int_t iR2=0; iR2<5; iR2++){
      globalIndex[counter] = R2cuts[iR2] + TBTOcuts[iTBTO]*100;

      Scut.Form("Mbc>5.27 && abs(deltaE)<0.06 && R2<%i/100 && cosTBTO<%i/100 && K_PID_bin_kaon>0.6 && pi0_InvM>0.1 && pi0_InvM<0.15 && abs(cosHelicityAngleMomentum)<0.98 && ((pi0_daughter0clusterReg==1 && pi0_daughter0E>0.0225) || (pi0_daughter0clusterReg==2 && pi0_daughter0E>0.020) || (pi0_daughter0clusterReg==3 && pi0_daughter0E>0.020)) && ((pi0_daughter1clusterReg==1 && pi0_daughter1E>0.0225) || (pi0_daughter1clusterReg==2 && pi0_daughter1E>0.020) || (pi0_daughter1clusterReg==3 && pi0_daughter1E>0.020)) && isSignal>0", R2cuts[iR2],TBTOcuts[iTBTO]);
      Bcut.Form("Mbc>5.27 && abs(deltaE)<0.06 && R2<%i/100 && cosTBTO<%i/100 && K_PID_bin_kaon>0.6 && pi0_InvM>0.1 && pi0_InvM<0.15 && abs(cosHelicityAngleMomentum)<0.98 && ((pi0_daughter0clusterReg==1 && pi0_daughter0E>0.0225) || (pi0_daughter0clusterReg==2 && pi0_daughter0E>0.020) || (pi0_daughter0clusterReg==3 && pi0_daughter0E>0.020)) && ((pi0_daughter1clusterReg==1 && pi0_daughter1E>0.0225) || (pi0_daughter1clusterReg==2 && pi0_daughter1E>0.020) || (pi0_daughter1clusterReg==3 && pi0_daughter1E>0.020)) && isSignal<1", R2cuts[iR2],TBTOcuts[iTBTO]);
     S[counter] = t.GetEntries(Scut);
     B[counter] = t.GetEntries(Bcut);
     counter++;
    }
  }

Thanks a lot for your help!
Cheers,
Riccardo

It seems to be a good candidate for RDataFrame usage.

This looks quite similar to what I was looking for, thanks a lot!

Hi,
I finally had time to try this solution, and it gives always strange errors.
I tried basic commands from terminal, the output were misterious, such as

root [13] auto entries = d.Filter("isSignal>0").Count();
ROOT_prompt_13:1:39: error: no member named 'Count' in 'ROOT::RDF::RInterface<ROOT::Detail::RDF::RJittedFilter, void>'
auto entries = d.Filter("isSignal>0").Count();
               ~~~~~~~~~~~~~~~~~~~~~~ ^

Do you have any suggestion on what is missing?

I assume you do not have a macro. What I understand is you are trying to calculate the number of events with “isSignal>0”. If they are stored in a tree then try this
<Tree_name>->GetEntries(“isSignal>0”).

Hi,
that should work as far as I can tell.
What ROOT version are you using? I think at least v6.16 is required.

Cheers,
Enrico