Apply TTreeFormula on each Event Loaded in Memory

Dear ROOT community,

I am trying to propagate the effect of cuts / re-weight on a set of evens which are defined with a string we provide in a Tree::Draw call. Until now I was using the TTreeFormula to know if whether or not a given event is passing the cut. As it’s name indicates, a TTreeFormula is applied on a TTree (set at a given entry):

for(int jInstance = 0; jInstance < treeFormulae->GetNdata(); jInstance++) {
  if ( treeFormulae->EvalInstance(jInstance) != 0 ) {
    // the event is passing the cut
} // jInstance

However, I’d like to apply those cuts (aka eval the TFormula) on an event directly stored in RAM, in which I could change the value of a stored variable. For example: if I want change the energy scale due to a given systematic uncertainty, I would have to re-apply the energy cut to ensure the same event with a slightly shifted energy is still passing the selection.

Then my question is: how could I save one entry of a TTree in RAM for which I could edit the stored variables that could be recognized by a formula string?

Bests :slight_smile:

ROOT Version: 6.22/08
Platform: MacOS
Compiler: Apple clang version 12.0.5 (clang-1205.0.22.9)

Hi Adrien,

There are at least two possible answers :slight_smile:

  1. You could build a TTreeFormula that invokes the convolution, i.e. instead of a formula jetE > 120 you can do convJetE(jetE) > 120. If you #include the file containing the definition of convJet (which would vary the jet energy) then TTreeFormula can call it.

  2. Consider switching to RDataFrame. It has the tools you need for this - we’re even working on a dedicated systematics variation interface, expected this year. And it’s way faster than TTreeFormula, probably a factor O(100): it’s parallel / multi-threaded (factor O(10)) and it’s not an interpreted formula but (just-in-time-) compiled, which gives you another factor O(10). Here, you could just Define jetE_up as the varied value, or even Redefine to replace the original value.

Cheers, Axel.

Thanks a lot Axel!

I got few questions about the 2 solutions you proposed:

  1. It seems to be a rather straight forward solution to implement, but does it needs to be a static-like function? For example, is event.GetJetE() is gonna work? In fact these functions are intended to be called during a fit procedure, so I’d like to avoid relying on disk access as much as possible.

  2. It’s very interesting! Do you have a practical example I could use to get started? :slight_smile:



Yes it should.

Regarding RDataFrame, check out the excellent tutorials we offer, see ROOT: Data Frame tutorials

Cheers, Axel.

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