Home | News | Documentation | Download

Using std::map operator in TTree::Draw() selection expression doesn't work

Hello,

I have a question, a bit related to this post: Filtering the events using a std::map in a TTree and create a histogram with the results

I have a TTree that contains a standard branch Double_t signal (data from my detector), and a std::map veto (containing data from my veto detectors, with the panel ID as keys).
Now I want to draw a histogram of signal, while using a selection based on the veto.

My problem: using the std::map::operator[], which should let me select a specific key (i.e. using only one veto panel), doesn’t work:

myTree->Draw("signal>>histo", "veto[key] > 100 && veto[key]<200" );

This results in an empty histogram, because the condition is apparently never fulfilled (even though when looking at the data, it is).

Another thing which doesn’t work as I want is when applying this cut on all keys:

myTree->Draw("signal>>histo", "veto.second > 100 && veto.second<200" );

because here the signals are drawn as duplicates for each veto that fulfills the condition.

To use a function like "Min$(veto.second)<100" as in the solution of the previously mentioned post (here) is not applicable, as I am looking for values within a range, and I didn’t find any suitable other function in the documentation.

Is it somehow possible to achieve what I want to do with TTree::Draw()?
So far I am using a work around, which is very inefficient (I have to reprocess the data when changing a cut condition…).

I would be happy for any suggestion!

TTree::Draw does not support that operator, you might want to try RDataFrame

For one veto panel you can use:

myTree->Draw("signal>>histo", "veto.first == some_key_value && veto.second > 100 && veto.second<200" );

To draw the signal where at least one veto is in the range:

myTree->Draw("signal>>histo", "Sum$(veto.second > 100 && veto.second<200) > 0" );
1 Like

As Philippe mentioned, RDataFrame supports arbitrary C++ and can be used similarly to TTree::Draw (although it does much more). As a one-liner:

auto histo = RDataFrame("tree", "files*.root")
  .Filter("veto[key] > 100 && veto[key] < 200")
  .Histo1D(histomodel, "signal");

or compiled completely ahead of time for best performance:

bool filterFunc(const std::string &key) { return veto[key]; }
auto histo = RDataFrame("tree", "files*.root")
  .Filter(filterFunc)
  .Histo1D<float>(histomodel, "signal")

Cheers,
Enrico

1 Like