PyROOT & RDataFrame: Filter with arrays

Dear experts,

I am trying to use RDataFrame in PyROOT.
I have the following questions on this example.

Not considering the first two selections (df_2mu and df_os), how should I proceed to add selections on Muon_pt and Muon_eta (which are both arrays)? For example, how can I keep only the muons having Muon_pt > 0.5 GeV and Muon_eta >2.4?
It should be something like:

pt_and_eta_cuts = df.Filter("Keep only the muons with Muon_pt > 0.5").Filter("Keep only the muons with Muon_eta > 2.4")

In general, how should I use the Filter function with arrays in PyRoot?

Moreover, is the above code equivalent to looping (in C++) on nEvents (given by tree->GetEntries()) and nMuon?

for( int i = 0 ; i < nEvents; i++){
    int muonN = tree->nMuon[i];
    for( int j = 0; j < muonN; j++){
         if( Muon_pt[j] < 0.5 && Muon_eta[j] < 2.4 ) continue;
         ....
    }
}

ROOT Version: 6.18.02

Hi Nathanael,
and welcome to the ROOT forum!
There are several threads on the forum that should answer your question, the most recent being RDF filter the content of branches

If checking that out/searching the forum does not clarify things, please let us know.
Cheers,
Enrico

Hi Enrico,

thank you for the prompt reply.

Following the example you pointed me to, I should first of all determine the indices of the good muons, i.e. the indices of the muons with Muon_pt>0.5 and Muon_eta>2.4.

Is there a faster way to filter?

I was having a look at another topic.

Following one of the answers, it seems that something like (in C++?)

df.Filter("! Muon_pt[Muon_pt > 0.5].empty()").Filter("! Muon_eta[Muon_eta > 2.4].empty()")

should do the same job, right?

Hi,
it really depends what are the quantities you need to e.g. fill histograms at the end of the day.
Sometimes it’s easier to store the “good indeces”, other times you can directly defines the quantities you need.

For example, if you just need the pt of muons that satisfy your criteria, you’d do something like

df.Filter("nMuons > 0") # discard events with no muons
  .Define("good_muon_pts", "Muon_pt[Muon_pt > 0.5 && Muon_eta > 2.4]")
  .Histo1D("good_muon_pts")

Your last snippet filters out events (Filter always discards or accept whole events) for which no muon satisfies your requirements.

Cheers,
Enrico

Thank you for your clarification Enrico

1 Like

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