TEfficiency with Log Scale?

Hello all,

Just wanted to check how the TEfficiency class are supposed to be drawn on a log Canvas. I am hoping I’ve done something stupid here. Here is a quick reproducer.

import ROOT
import numpy as np

xBins = np.logspace(0, 3, 10) 
yPass = np.random.normal(loc=500, scale=50, size=len(xBins)-1).astype(int)
yTotal = yPass + np.random.poisson(lam=20, size=len(xBins)-1)

hTotal = ROOT.TH1D("hTotal", "Total;Track Momentum (GeV/c);Entries", len(xBins)-1, xBins)
hPass = ROOT.TH1D("hPass", "Passed;Track Momentum (GeV/c);Entries", len(xBins)-1, xBins)

for i in range(len(xBins)-1):
    hTotal.SetBinContent(i+1, yTotal[i])
    hPass.SetBinContent(i+1, yPass[i])

c = ROOT.TCanvas()
c.SetLogx()

eff = ROOT.TEfficiency(hPass, hTotal)
eff.SetTitle("Tracking Efficiency;Track Momentum (GeV/c);Efficiency")
eff.SetMarkerStyle(20)
eff.SetLineColor(ROOT.kBlue)
eff.SetMarkerColor(ROOT.kBlue)
eff.Draw("AP")

c.Draw()

Without the logScale it works perfectly.
But the minute I turn it on it breaks.
How do I make the underlying graph aware that it is drawing on a log canvas?

A C++ version of your script works fine with ROOT master:

void trackingEfficiency() {
    TRandom3 rng;

    const int nBins = 9;
    std::vector<double> xBins(nBins + 1);

    double xmin = 1.0;
    double xmax = 1000.0;

    for (int i = 0; i <= nBins; ++i) {
        xBins[i] = xmin * TMath::Power(xmax / xmin, double(i) / nBins);
    }

    std::vector<int> yPass(nBins);
    std::vector<int> yTotal(nBins);

    for (int i = 0; i < nBins; ++i) {
        yPass[i]  = int(rng.Gaus(500, 50));
        yTotal[i] = yPass[i] + rng.Poisson(20);
    }

    auto hTotal = new TH1D("hTotal", "Total;Track Momentum (GeV/c);Entries", nBins, &xBins[0]);
    auto hPass = new TH1D("hPass", "Passed;Track Momentum (GeV/c);Entries", nBins, &xBins[0]);

    for (int i = 0; i < nBins; ++i) {
        hTotal->SetBinContent(i + 1, yTotal[i]);
        hPass->SetBinContent(i + 1, yPass[i]);
    }

    auto c = new TCanvas("c", "Tracking Efficiency", 800, 600);
    c->SetLogx();

    auto *eff = new TEfficiency(*hPass, *hTotal);
    eff->SetTitle("Tracking Efficiency;Track Momentum (GeV/c);Efficiency");
    eff->SetMarkerStyle(20);
    eff->SetLineColor(kBlue);
    eff->SetMarkerColor(kBlue);

    eff->Draw();
}

Try with a newer or the latest ROOT version; with the latest (6.36.08) I don’t see that issue (used your Python script).

Thank you @dastudillo @couet

I was already based off master which caught me by surprise since I could reproduce this in both my master build and a conda build (ROOT-6-36-06) which is why I didn’t mention my version in the above.

I did a little more digging turns out this only happen when I try to do the above plot in a notebook environment (for fine tuning) regardless of the root version.

The minute I run it as a python script the plot seems to work okay. Sorry about that should I checked this before I posted.

Thanks a lot. I just continue with as a python script instead.

P.S Here is an attachment of my notebook render if it helps.

1 Like

Try adding %jsroot off

I forgot to mention that I ran the script with standard graphics (option --web=off). When I run without this option I get the following wrong result:

So it is clearly a problem with Web Graphics. Let’s ping @linev about it.

1 Like

Yes, I can reproduce the problem.

TEfficiency is not handled correctly by TWebCanvas.

Here PR which fixes the problem: [webcanv] add TEfficiency to list of supported classes by linev · Pull Request #21249 · root-project/root · GitHub

I will provide also backport to ROOT 6.38 branch

1 Like