I have a tree of which most branches are arrays (say cells in a calorimeter)
for each tree entry, I want to select subsets of each array (cells satisfying some conditions, e.g an energy threshold)
I would like to do this using TTreeFormula, as I can then define the cuts in configuration files, read them in and apply them with complete flexibility
Currently my ugly-looking solution is to generate as many TTF’s as there are cells:
TTreeFormula* TTF[50];
ttf[0] = new TTreeFormula("ttf0","cell_et[0]>5",tree);
ttf[1] = new TTreeFormula("ttf1","cell_et[1]>5",tree);
...
and in the event loop, do:
GetEntry(jentry);
int icut = 0;
for(int i=0; i<50; i++) {
if( ttf[i]->EvalInstance() )
cellcut_et[icut] = cell_et[i]
icut++;
}
There must be something more elegant and efficient? In fact I am just trying to repeat what would happen inside this:
tree->Draw("cell_et","cell_et>5","",1,jentry)
although in an event loop over which I have control.
Could you please point me to the implementation (which I don’t find), or any solution?
Thanks. I had a look at TSelector and will use that. However I still have the same question (see above): for a given entry, how can I most efficiently select the elements of an array branch that satisfy a given cut, expressed as a TTreeFormula?
In other words: what happens inside:
tree->Draw(“cell_et”,cell_et>5,"",1,entry) ?
This plots the cell_et for the cells passing et>5 (cell_et is an array, for each entry).
I would like to adapt this for my event loop, retrieving the cells passing this cut, for later usage.
I understand that “cell_et>5” is used to define a TTreeFormula, but how is the cell_et loop and the cell selection done concretely? Does one need to define a TTreeFormula for each array element, i.e “cell_et[0]>5”, “cell_et[1]>5”, etc, and “EvalInstance()” each time? I guess that Draw() uses a more clever solution?
Example can be found in TSelectorDraw::ProcessMultiple and TTreePlayer::Scan and goes something like:TTreeFormula* TTF = new TTreeFormula("ttf0","cell_et>5",tree);
...
GetEntry(jentry);
int icut = 0;
Int_t ndata = TTF->GetNdata();
for(int i=0; i<ndata; ++i) {
if( TTF->EvalInstance(i) )
cellcut_et[icut] = cell_et[i]
icut++;
}
...
}Note that this code would need to be updated to support TChain (i.e. every time the chain goes to the next file you must call TTF->UpdateFormulaLeaves() )