How to perform a Rebining?

Hi again rooters, I’d like to know if is there a method that perform rebining?

I’m working in a TH1 and I’d like to change its binwidth and at the same time perform a uniform redistribution of contents, it means that if I have a TH1 with just 1 bin, with binwidth of 1 and content 100, then when I set a new binwitdh of 0.3, the bin 1 has a content of 30, 2 of 30, 3 of 30 and 4 of 10.

I’ve written a code that makes this and it works well, but I can’t believe that this is not implemented in root whether as I did or using random numbers.


double GetXLow(TH1 * h){return h->GetBinLowEdge(1);};
double GetXUp(TH1 * h){return h->GetBinLowEdge(h->GetNbinsX()) + h->GetBinWidth(h->GetNbinsX()) ;};

TH1D * Procesador::ReBinear(TH1I * h,const char* name , double newbinwidth, double xlow, double xup)
{
  double binwidth = h->GetBinWidth(1);
  int nbin=h->GetNbinsX();
  double L = xup-xlow;
  TH1D * h2;
  int newnbin;
  double b=binwidth/newbinwidth;
  double n=newbinwidth/binwidth;
  
  if( (L/newbinwidth) - int(L/newbinwidth) == 0 )
    {
      newnbin= int(L/newbinwidth) ;
      h2= new TH1D (name, "" , newnbin , xlow , xup  ) ;
    }
  if( (L/newbinwidth) - int(L/newbinwidth) >0 )
    {
      newnbin= int(L/newbinwidth)+1 ;
      double newxup=xup+newbinwidth;
      h2= new TH1D (name, "" , newnbin , xlow , newxup ) ; 
    }

  int k=0;
  double l = GetXLow(h);
  int j= h2->FindBin(l);
  
  if (newbinwidth < binwidth )
    {
      for(int i =h2->FindBin(l) ; i <= h2->FindBin(GetXUp(h)) ; i++)
	{
	  if( i*newbinwidth <= k*binwidth+l )
	    h2->SetBinContent(i ,n*h->GetBinContent(k));
	  else
	    {
	      if(k==0)
		{
		  h2->SetBinContent(i , ( n*i -k-(l/binwidth) )*h->GetBinContent(k+1));
		  k=k+1;
		}
	      else
		{
		  h2->SetBinContent(i , ( k+(l/binwidth)- n*(i-1) )*h->GetBinContent(k) +  ( n*i -k-(l/binwidth) )*h->GetBinContent(k+1));
		  k=k+1;
		}
	    }	  
	}
    }
  else
    {
      for(int i =1 ; i <= h->GetNbinsX() ; i++)
	{
	  if( i*binwidth+l <= j*newbinwidth )
	    h2->AddBinContent( j , h->GetBinContent(i));
	  else
	    {
	      h2->AddBinContent(j , ( n*j - (i-1)-(l/binwidth) )*h->GetBinContent(i) );
	      h2->AddBinContent(j+1 , ( i+(l/binwidth)- n*j )*h->GetBinContent(i));
	      j=j+1;
	    }  
	}
      
    }
  return h2;
}

Best Regards.

Hi,
there is a TH1::Rebin, which merges adjacent bins into one, e.g.

h->Rebin(5) will merge each group of 5 adjacent bins into one new bin. Non-integers are not allowed though.

Yus thanks for you replie.
I’ve already tested this method, but this method is only a particular case of the general Rebining, this only works when the number of groups is a int.

For example if I do something like this

TH1D * h= new TH1D("","", 1,0.5, 10.5);
h->SetBinContent(1, 100);
h->Rebin(0.3);

it crashes.

the first parameter of Rebin is an int:
root.cern.ch/doc/master/classTH … 1800946790