Hello,
I have multiple efficiencies from various cuts (called eff_sel) as well as from my trigger (eff_trig) and want to get an absolute efficiency when applying all efficiencies. Naively, I’d just use eff_abs = eff_trig * eff_sel1 * eff_sel2 * …, but ROOT does not offer a way to multiply TEfficiency objects.
Now, I did look at the ROOT documentation and found the methods Add() and Combine(). It is unclear to me whether these functions do what I want in my case:
If any efficiency is defined as eff = N_pass/N_tot, then, for the selection efficiencies, N_tot is always the same, only N_pass changes.
The efficiencies are about eff_trig <= 0.7, eff_sel \approx 0.95.
I tried Add() on all efficiency objects, but the absolute efficiency at the end was bigger than eff_trig, so Add() is definitely the wrong function to call. That I understand, as it simply adds passed and total histograms and 7/10 “+” 9/10 = 16/20 = 8/10 > 7/10.
Then I tried Combine() – with default values, as I have no idea what different weights I’d use – but in this case also, the resulting efficiency was bigger than eff_trig. Plus, for some reason, Compare() returns a TGraphAsymmErrors* which cannot be constructed back into a TEfficiency object.
Did I misunderstand anything up to this point? I feel like my use case should be pretty normal and thus implemented in a library such as ROOT. That’s why I guess I did something horribly wrong.
Trying to multiply the efficiencies, as would’ve tried naively, is cumbersome and I see no possibility of retaining a TEfficiency object when doing so:
// init of all histograms hPassed* and hTot* with correct binning
TEfficiency effTrig(hPassedTrig, hTotTrig);
TEfficiency eff1(hPassed1, hTot1);
TEfficiency eff2(hPassed2, hTot2);
vector<TEfficiency> effVec = {effTrig, eff1, eff2};
TH1D* hEff = hPassed1->Clone("hEff");
int nBins = hEff->GetBinsX();
for (int iBin=0; iBin<nBins; iBin++) {
for (int iEff=0; iEff<effVec.size(); iEff++) {
if (iEff==0) hEff->SetBinContent(iBin+1, effVec[iEff].GetEfficiency(iBin+1);
else hEff->SetBinContent(iBin+1, hEff->GetBinContent(iBin+1)*effVec[iEff].GetEfficiency(iBin+1));
}
}
// Or I could do something like this
TH1D* hEff1 = hPassed1->Clone("hEff1");
hEff1->Multiply(hPassed2);
hEff1->Divide(hTot1);
hEff1->Divide(hTot2);
// and for all other efficiencies, but this
// doesn't look cleaner, either. Also, it
// leaves me with a TH1D, not with a
// TEfficiency.
Is there something obvious I’m missing?