Divide histogram into sub-ranges with equal integral

HI,

I have a series of histograms, and I want to divide them into “n” sub-ranges in way that
integrals in that sub-ranges be as much as possible close to each other,
like integral(bin_1, bin_2) \approx integral(bin_3, bin_4) \approx … integral(bin_n, bin_n+1).

Is there a way in root, to get these bin_1, bin_2, … bin_n+1 automatically?

Rafayel

Hi,

We don’t have this algorithm working in ROOT for histogram. However, we have a class, called TKDTreeBinning (see root.cern.ch/root/html/TKDTreeBinning.html ) which can bin unbinned data in bins which have equal contents
By transforming your original histogram in a set of unbin data (e.g using n points placed at the bin center) you can then probably use the TKDTreeBinning class

Best Regards

Lorenzo

Thank you Lorenzo,

I tried to do a simple example using TKDTreeBinning,
but I didn’t succeed, probably I am doing something wrong there.
The method GetOneDimBinEdges(); looks like return somehow sorted
array, but not exactly what I need. Instead of starting from 0, it starts from 6.3
and starting from bin 28 it changes to 0.

Could you please have a look into the code.

#include <TF1.h>
#include <TH1D.h>
#include <TH2D.h>
#include <TMath.h>
#include <TCanvas.h>
#include <TRandom2.h>
#include "TKDTreeBinning.h"

void test_Binning1()
{
  const UInt_t DATASZ = 10000;
  const UInt_t DATADIM = 1;
  const UInt_t NBINS = 100;

  TCanvas *c1 = new TCanvas("c1", "", 1200, 750);

  TF1 *f_test = new TF1("f_test", "exp(-0.2*x)", 0., 50);
  f_test->SetNpx(1000.);

  Double_t smp[DATADIM*DATASZ];
  
  for( int i = 0; i < DATASZ; i++ )
    {
      smp[i] = f_test->GetRandom(0., 40.);
    }

  TKDTreeBinning* fBins = new TKDTreeBinning(DATASZ, DATADIM, smp, NBINS);
  
  const Double_t* binsMinEdges = fBins->GetOneDimBinEdges();

  TH1D *h_test_Varbins1 = new TH1D("h_test_Varbins1", "", NBINS, binsMinEdges);
  TH1D *h_simple_bin1 = new TH1D("h_simple_bin1", "", NBINS, 0., 41.);
  
  for( int i = 0; i < DATASZ; i++ )
    {
      h_test_Varbins1->Fill(smp[i]);
      h_simple_bin1->Fill(smp[i]);
    }

  for( int i = 0; i < NBINS; i++ )
    {
      cout<<"binsMinEdge["<<i<<"] = "<<binsMinEdges[i]<<endl;
    }
  
  c1->Divide(2, 1.);
  c1->cd(1);
  h_test_Varbins1->Draw();
  c1->cd(2);
  h_simple_bin1->Draw();
  c1->Print("binning.eps");
  c1->Print("binning.pdf");
  c1->Print("binning.gif");
}

Rafayel