Dear ROOT experts,
I googled a bit the usage of TFormula with TChain and I may have found a solution to that. I just wanted to share and ask if there are drawbacks in the approach i am following.
Here the body of the method I wrote to build the content of a struct ( namely IsoBinReport )
struct IsoBinReport{
double sumOfWeightsPas;
double sumOfEntriesPas;
std::vector< std::pair< double, double > > varFill_weightFill;
}
IsoBinReport GetIsoBinReport( TChain* _eventType , TString _VarName ,double min, double max, const TCut & _Cut , const TString & _Weight , double frac , bool debug ){
IsoBinReport Report;
Report.sumOfWeightsPas = 0;
Report.sumOfEntriesPas = 0;
Report.varFill_weightFill = {};
Long64_t _nEntries = _eventType->GetEntries() ;
if( frac > 1 && frac < _nEntries){ _nEntries = frac ; }
if( frac > 0 && frac < 1 ){ _nEntries = floor( _nEntries * frac); }
TString _CutExpression = _Cut ;
TString _WeightExpression = _Weight ;
//get vector<TString> given the Expression and TChain
auto branches = GetBranchesFromExpression( _CutExpression, _eventType ) +
GetBranchesFromExpression( _WeightExpression, _eventType ) + GetBranchesFromExpression(_VarName, _eventType );
_eventType->SetBranchStatus("*",0);
for( auto & b : branches){
_eventType->SetBranchStatus(b,1);
}
// HERE
_chain->LoadTree(0); // < load the TFile linking to entry 0
TTreeFormula *cutFormula = new TTreeFormula("CUT",_CutExpression,_eventType );
_eventType->SetNotify( cutFormula); //Is this always required ?
TTreeFormula *weightFormula = new TTreeFormula("WEIGHT",_WeightExpression,_eventType );
_eventType->SetNotify( weightFormula); //Is this always required ?
TTreeFormula *toPlot = new TTreeFormula("VAR", _VarName , _eventType );
_eventType->SetNotify( toPlot); //is this always required ?
boost::progress_display show_progress_evtloop( _nEntries );
Report.varFill_weightFill.reserve(_nEntries);
int underflow = 0;
int overflow = 0;
for( Long64_t entry = 0 ; entry < _nEntries; ++entry){
++show_progress_evtloop;
_eventType->LoadTree(entry); //Is this required ?
_eventType->GetEntry(entry);
cutFormula->UpdateFormulaLeaves(); //Is this required ?
toPlot->UpdateFormulaLeaves(); //Is this required ?
weightFormula->UpdateFormulaLeaves(); //Is this required ?
bool _cutISPas = (bool) cutFormula->EvalInstance(0);
double _val = toPlot->EvalInstance(0);
double _weight = weightFormula->EvalInstance(0);
Report.sumOfEntries ++;
if( _cutISPas == false ){ continue;}
if( _val < min){
underflow++;
}
if ( _val > max){
overflow++;
}
Report.sumOfEntriesPas ++;
Report.varFill_weightFill.push_back( make_pair(_val, _weight) ) ;
Report.sumOfWeightsPas += _weight;
}
//re-enable all branches
_eventType->SetBranchStatus("*",1);
_eventType->LoadTree(0); //I must do this to enable the re-usage of the TChain afterwards, otherwise i get a nasty segfault from TBuffer
delete cutFormula;
delete weightFormula;
delete toPlot;
return Report;
};
I can polish down the method a bit more, but the questions i have are all in-lined with the code.
Is there anyone which knows what is the correct functions to use to enable the behaviour i implemented?
I basically have a Cut-Expression, a Weight-Expression, a VariableExpression whcih is used to fill afterwards an Histogram.
I parse the 3 as a TFormula, and I eval their value at each entry of the TChain so i can fill that.
I know this is roughly the same of TDataFrame or TTreeReader or Draw or whatever, but I would like to keep this code as it is since i want to spawn over a vector of cuts, set of weights and list of variables and do a loop over the Tree only once. This is the 1-1-1 case which i managed to get working. My questions is : is there some drawbackws in the way i use the various methods around ?
///LoadTree, SetNotify, UpdateFormulaLeaves, and at the exit the LoadTree(0).
THe code i wrote is working, but this doesn’t imply i am doing things correctly or at least that I could have some drawbacks in doing this. So my question. Do you think this is the correct way of doing that ?
Thanks In advance
Renato
_ROOT Version: 6.14/02
Platform: MacOs
Compiler: Not Provided