I have a histogram readable from a root file. This histogram has variable bin width over the x-range of 0-20 GeV. The bin width for the ranges 0-5 GeV, 5-10 GeV and 10-20 GeV are 0.5 GeV, 1GeV and 2 GeV respectively; viz. bin centered at 0.25, 0.75, 1.25…,3.75, 4.25, 4.75, 5.5, 6.5, 7.5, 8.5, 9.5, 11, 13, 15, 17 and 19 GeV consecutively.
I want to convert this histogram into a constant bin width of 0.05GeV over the whole range of 0-20 GeV and update the histogram back into the root file. This process will affect the BinContent too. How can I do that?
What you are trying to do doesn’t really make sense but here it is:
{
TH1D *h_wide = new TH1D("h_wide", "wide bins;X;Y", 40, 0., 20.);
h_wide->FillRandom("pol1", 10000);
TH1D *h_narrow = new TH1D("h_narrow", "narrow bins;X;Y", 400, 0., 20.);
//
#if 1 /* 0 or 1 */
// note: we assume that the X-axis range of both histograms is the
// same and all bin edges of "h_wide" correspond to some bin
// edges of "h_narrow" and we neglect bin errors of "h_wide"
h_narrow->AddBinContent(0, h_wide->GetBinContent(0)); // underflow bin
h_narrow->AddBinContent(h_narrow->GetNbinsX() + 1, // overflow bin
h_wide->GetBinContent(h_wide->GetNbinsX() + 1));
for (Int_t i = 1; i <= h_narrow->GetNbinsX(); i++) {
Int_t b = h_wide->FindFixBin(h_narrow->GetBinCenter(i));
Double_t w = h_narrow->GetBinWidth(i) / h_wide->GetBinWidth(b);
h_narrow->AddBinContent(i, w * h_wide->GetBinContent(b));
}
h_narrow->ResetStats(); // reset the statistics including the number of entries
#else /* 0 or 1 */
// note: the X-axis ranges and bin edges do not need to correspond
// but the contents of "h_narrow" will have some "random jitter"
Int_t n = 10000;
h_narrow->FillRandom(h_wide, n * h_wide->GetEntries());
h_narrow->Scale(1. / n);
h_narrow->Sumw2(kFALSE);
h_narrow->ResetStats(); // reset the statistics including the number of entries
#endif /* 0 or 1 */
//
TCanvas *c = new TCanvas("c", "c");
c->Divide(1, 2);
c->cd(1); h_wide->Draw();
c->cd(2); h_narrow->Draw();
c->cd(0);
}