TH1::GetQuantiles() gives wrong value for 100 percentile?


Please read tips for efficient and successful posting and posting code

ROOT Version: v6.2.6
Platform:
Compiler:


I am trying to calculate the percentile of the histogram (TH1F) stored in a tree branch (or many branches). I obtained some incorrect values.
When I am calculating the 100 percentile of the histogram, it gives the upper bin limit of the histogram, which is not the exact value.
also I reffered TH1 class,
https://root.cern.ch/doc/master/classTH1.html
Below I am attaching the code I used,
I have 100 root files now.

void pprd()
{
        int nfile=100;
        TList*list=new TList;
        for(int i=1;i<=nfile;++i){
                string name="pp"+to_string(i)+".root";
                TFile*f=TFile::Open(name.c_str());
                TTree*T=(TTree*)f->Get("T");
                T->Draw("multiplicity>>h","","goff");
                TH1F*h=(TH1F*)gDirectory->Get("h");
                list->Add(h);

        }
        TH1F*hist=new TH1F("hist","Ths",50,0,100);
        hist->Reset();
        hist->Merge(list);
        const int nq=100;
       double qn[nq]; //position where to compute the quantiles
        double qnv[nq]; //array to contain the quantiles
         for(int j=0;j<nq;++j){
                qnv[j]=float (j+1)/nq;
                hist->GetQuantiles(nq,qn,qnv);
               cout<<j+1<<"    "<<qn[j]<<endl;
        }

I don’t know what changes can give the correct answer. I am hoping that you got my point
thank you …

That is the 100 percentile of the histogram (if there are entries in that bin), being binned data. If you want the max of the “original” data, you have to look at the original data, not a histogram.

1 Like
{
  TCanvas *c = new TCanvas("c", "c"); c->Divide(1, 2);
  TH1F *hist = new TH1F("hist", "hist", 10, 0., 100.);
  hist->FillRandom("pol0", 10000); c->cd(1); hist->Draw(); c->cd(0);
  const int nq = 100;
  double qnv[nq]; // position where to compute the quantiles
  for(int j = 0; j < nq; j++) qnv[j] = double(j + 1) / double(nq);
  double qn[nq]; // array to contain the quantiles
  hist->GetQuantiles(nq, qn, qnv);
  for(int j = 0; j < nq; j++) std::cout << j + 1 << " : " << qn[j] << "\n";
  TGraph *g = new TGraph(nq, qnv, qn); g->SetTitle("quantiles nonlinearity");
  double xl = hist->GetXaxis()->GetXmin(), xr = hist->GetXaxis()->GetXmax();
  for(int j = 0; j < nq; j++) g->GetY()[j] -= g->GetX()[j] * (xr - xl) + xl;
  g->GetHistogram()->GetXaxis()->Set(100, 0., 1.);
  c->cd(2); g->Draw("A*"); gPad->SetGridx(); c->cd(0);
}
1 Like

Thank you,
There are no entries in that bin. The last bin which has an entry is 5 points below the upper limit.

Thank you,
It also gives the same result. I need that percentile value for further calculations. The problem I am facing is finding the last bin that has an entry, which is near the upper limit.

@moneta I can confirm this bug.
It seems to me that, for the “100 %” case, ROOT should return the upper edge of the last bin with non-zero content, not the low edge of the very last bin.
A similar problem exists for the “0 %” case. ROOT should return the low edge of the first bin with non-zero content, not the low edge of the preceding bin (with zero content).

{
  TH1F *h = new TH1F("h", "h", 30, -100., 200.); h->Draw();
  for(int j = 11; j <= 20; j++) h->SetBinContent(j, 1.);
  const int nq = 100;
  double xq[(nq + 1)]; // positions where to compute the quantiles in [0., 1.]
  for(int j = 0; j <= nq; j++) xq[j] = double(j) / double(nq);
  double yq[(nq + 1)]; // array to contain the quantiles
  h->GetQuantiles(nq + 1, yq, xq);
  // note: "0 %" should return 0 and "100 %" should return 100
  for(int j = 0; j <= nq; j++) std::cout << j << " % : " << yq[j] << "\n";
}
1 Like

Thank you.

Is there any other option for this ?

@_Ab_Ad For now, you must fix the “0%” and “100%” values yourself.

1 Like

ok, Thank you.

Thank you for reporting this bug.
I have pen a new issue for tracking this bug: Problems with `TH1::GetQuantile` · Issue #12251 · root-project/root · GitHub

1 Like

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