Binning changes fitting values

Dear Rooters,

I‘m facing a fitting problem when binning. I have 2 histograms which display the same physical relation, but hist has far fewer counts than hist2: hist = factor * hist2. I need to obtain the factor. I do that by interpolating hist2 and fitting the interpolated function to hist. The following code breaks it down to an easy example:

TH1F* hist;
TH1F* hist2;

//user defined fit function
Double_t userfitf(Double_t *x, Double_t *par) {
	Double_t value = par[0]*hist2->Interpolate(x[0]);
	return value;
}

void QuestionRootForum(){

Int_t binningfactor = 1;

gRandom = new TRandom3();

//Create a variable bin size array
Int_t Nbins = 1000*binningfactor;
const Int_t size = Nbins+1;
Double_t xbins[size];
for (int i = 0; i< Nbins+1; i++) xbins[i] = i*1.02/(10*binningfactor);

//Create histos and fill with random gauss
hist   = new TH1F("hist","hist",Nbins,xbins);
hist2  = new TH1F("hist2","hist2s",Nbins,xbins);
for (int i = 0; i < 10000; i++) hist->Fill(gRandom->Gaus(50,5));
//histo2 will have 1000 time the counts
for (int i = 0; i < 10000*1000; i++) hist2->Fill(gRandom->Gaus(50,5));

//Fit with user defined fit function
ff = new TF1("ff",userfitf,20,80,1);
hist->Fit("ff","");
}

However the factor (from hist = factor*hist2) depends on the bin width, which I think shouldn‘t be the case. Try changing binningfactor to 10 or some value and compare. Somebody suggested to normalize the fitparameter with the bin width as follows:

Double_t userfunction(Double_t *x, Double_t *par) {
	Double_t normalize = hist->GetXaxis()->GetBinWidth(0);
	Double_t value     = par[0]/normalize*hist2->Interpolate(x[0]);
	return value;
}

Is that the correct approach?
It seems a good idea to me, because in the following I will have to multiply this factor to third histogram which needs to have a different bin size than hist & hist2.
However, GetBinWidth neither works with 0 nor x[0]. How do I get it to work?

Bin 0 is the underflow bin, its width is infinite.

https://root.cern.ch/doc/master/classTH1.html

Ok, now I know what the 0 means. Thank you for your reply ksmith.

In a loop over the bins I can pass the bin number to GetBinWidth(). But here GetBinWidth() is called in the fit function, which is only called by the Fit()-comand. How do I reference the (current) x-value in the fit function to pass it to GetBinWidth()?

hist->Fit("ff", "IL"); // "IL" ... or ... "IWL"

Do you want to get the bin width of the bin matching the current x-value?

hist->GetBinWidth(hist->GetXaxis()->FindBin(x[0]));

Thank you Wile_E_Coyote. That was what I needed. Simpler than thought.

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