Add two histograms with different ranges

Hello All,

I have several thousands of histograms (gaussians with different sigmas and centres). I want to shift the centres to zero and sum the histograms and produce one summed histogram. Any ideas on how to shift histograms along the x-axis.

Sample stand-alone code is attached.

Many thanks,
Karthik.

{
	gROOT->Reset();

	TH1F *h1      = new TH1F("h1","Hist 1",100,-1000,4000);
	TH1F *h2      = new TH1F("h2","Hist 2",100,-4000,1000);
	TH1F *SumHist = new TH1F("SumHist","Summed Histogram",100,1,-1);

	TF1 *fn1 = new TF1("fn1"," (1/([1]*2.5066)) * exp( -pow((x-[0]),2) / (2*[1]*[1]) )",-9000,9000);

	float sigma1=200; float centre1 =  1000;
	float sigma2=450; float centre2 = -2500;

	// Fill the histograms
	fn1->SetParameters(centre1,sigma1) ; h1->FillRandom("fn1",5000);
	fn1->SetParameters(centre2,sigma2) ; h2->FillRandom("fn1",5000);

	// Fit the histograms and shift them
	float centre,sigma; TF1 *fit; TAxis *histxaxis;
	h1->Fit("gaus","Q",""); fit = h1->GetFunction("gaus"); centre = fit->GetParameter(1);sigma=fit->GetParameter(2);
	//histxaxis=h1->GetXaxis();histxaxis->SetLimits(  centre-100 , centre+100);

	h2->Fit("gaus","Q",""); fit = h2->GetFunction("gaus"); centre = fit->GetParameter(1);sigma=fit->GetParameter(2);
	//histxaxis=h2->GetXaxis();histxaxis->SetLimits(  centre-100 , centre+100);
	
	SumHist->Add(h1,1);
	SumHist->Add(h2,1);

	TCanvas *c1 = new TCanvas("c1","c1",900,900);
	c1->Divide(1,3);
	c1->cd(1); h1->Draw();
	c1->cd(2); h2->Draw();
	c1->cd(3); SumHist->Draw();
}

offsethistograms0.C (1.17 KB)

Hi,

The histogram addition are done bins by bins and thus can only be done (via the Add function) when the bins can be aligned exactly. One things that can be done is to shift an histograms X axis:histxaxis=h1->GetXaxis();histxaxis->SetLimits( histxaxis->GetXmin() - centre , histxaxis->GetXmax() - centre);However this does not help in your case. Eventhough all the histogram will now have their picks are the X value 0, the number of bins on the left and right of the 0 will be different. In your example, after shifting, h1’s lowest bin correspond to the value -2000, while h2’s lowest bin correspond to the value -1500 and thus adding those 2 histogram is still invalid.

So in order to make the addition, you would need not only to shift the histogram on the x-axis but also either rebins or drop some of the bins so that they all have the exact same shapes. You probably can do that either by refilling the histogram using the calculated centers as appropriate or you would need to explicitly copy the data from the histogram into the summed histogram using GetBinContent and SetBinContent (assuming all the bins have the same/compatible width …).

Cheers,
Philippe.

you can use TH1::Merge to merge histograms with different limits, but with bin edges and width such that the overlapping bins have a common low and up edges.

Rene

Thanks. I tried TMerge but keep getting a “*** Break *** segmentation violation” error.

[code]root [0] .x summedhist_M0.C
root [1] .x summedhist_M2.C
root [2] TList *list = new TList;
root [3] list->Add(Module_0);
root [4] list->Add(Module_2);
root [5] TH1F h = (TH1F)Module_0->Clone(“h”);
root [6] h->Reset();
root [7] h->Merge(list);

*** Break *** segmentation violation[/code]

summedhist_M0.C and summedhist_M2.C attached.

[quote=“brun”]you can use TH1::Merge to merge histograms with different limits, but with bin edges and width such that the overlapping bins have a common low and up edges.

Rene[/quote]
summedhist_M2.C (67.9 KB)
summedhist_M0.C (66.2 KB)

Hi,

The crash is due to a problem in the code generated by SavePrimitive (SaveAs) and thus in your macro you should replace lines like: ptstats->SetParent(Module_2->GetListOfFunctions());with ptstats->SetParent(Module_2);

Cheers,
Philippe.