How to have different bin widths for a histogram in a .root file?

So I have this code that helps extract two plots and divide them however how would I vary the histograms bin sizes I have extracted individually and the histogram that is created by dividing the other two ? I want to know how to have different bin sizes. I know how to create the number of bins and there width but they are all usually the same size bins and right now they are not ?

This is the code I use to extract and draw out the plots.

#include "TCanvas.h"
#include "TROOT.h"
#include "TGraphErrors.h"
#include "TF1.h"
#include "TLegend.h"
#include "TArrow.h"
#include "TLatex.h"

#include "TH1D.h"

#include "TH2D.h"

#include "TH2F.h"

void practice(){
TFile *f = TFile::Open("output_idAntiId_Mc16a.root");
 TFile *s = TFile::Open("output_IdId_Mc16a.root");

TH1F *Wg_IDIDeta;
 TH1F *Wg_IDAnti_IDeta;

Wg_IDIDeta= (TH1F*)s->Get("pass_wgidcr_all_eeSO_Nominal/plotEvent_Wy/wElEta");
Wg_IDAnti_IDeta =(TH1F*)f->Get("pass_wgantiidcr_all_e_Nominal/plotEvent_Wy/wElEta");
 TH1F *FFeta = (TH1F*)Wg_IDIDeta->Clone("FFeta");

 FFeta->GetXaxis() ->SetTitle("eta");

 FFeta->GetYaxis() ->SetTitle("Fake Factor");

 TCanvas *CFFeta = new TCanvas("CFFeta","CFFeta",0.,0.,700,600);

You need to contact the authors of your ROOT files. They need to create these histograms with your desired bin sizes.

So I cannot modify the bin size my self ?

You can “merge” bins: TH1::Rebin

merge ? I am seeing examples that I have to use if loops to create different width bins but none are using the rebin thing you sent ?

Hi @Abaraj48,

Can you post here any of those examples? Typically, you need the original data to rebuild the histograms (I am currently not sure whether that is serialized by the I/O layer when the histograms are written to a ROOT file).


@jalopezg You do not need “the original data”, if you only want to “merge” (some) bins of an existing histogram.

Sure! But I am still sure that’s what @Abaraj48 is looking for.

@Abaraj48 could you please elaborate a bit more?


Let me put a more simple example where I would want to have a varied width size and maybe through this example I can apply it to my main code

void getrandomh() {
  TH1F *source = new TH1F("source","source hist",100,-3,3);
  // Fill Random is a funciton or feature with in the TH1F class we access it through our pointer called source                                                                                                                               
  //FillRandom("the type of function that will I guess determine how the data distributed, so in this case we have a gaussian with the "gaus"                                                                                                 
  // the parameter 1000 indicates how many random numbers are generated and also how many are filled in the histogram called source                                                                                                           

  TH1F *final = new TH1F("final","final hist",100,-3,3);

  // continued...                                                                                                                                                                                                                             

  for (Int_t i=0;i<10000;i++) {
    // Int_t is a signed integer which can be both postive and negative                                                                                                                                                                       
    // i = 0, as long as i is less then 1000 the for look will continue                                                                                                                                                                       
    // i++ is basically increasing the variable i by one so i = i+1                                                                                                                                                                           
    // Aslong as the loop is going we we continue filling the final histogoram with values represented by i                                                                                                                                   
    // Here the get randmom operator is used to get random number distributed according tp the contents of a histogram which is the source histogram                                                                                          
    // Fill a histogram following the distribution of a existing histogram we can use as a second signature, we like intgerate and normalize the values i believe                                                                             

  Double_t xbins[3];
  TH1F *J = (TH1F*) final->Rebin(2,"hnew",xbins);

  // We are using  for loop for the final plot to fill in the values                                                                                                                                                                          
  TCanvas *c2 = new TCanvas ("c2","c2",800,100);

 TCanvas *c1 = new TCanvas("c1","c1",800,1000);
  // The lst two values are like width and length of the image will come out as                                                                                                                                                               
  // A canvas is an area mapped to a window directly under the control of the display manager                                                                                                                                                 
   //(main pad, divided by 2 so we have 2 pads now)                                                                                                                                                                                           
  // this command is what allows us to print the plots on the same canvaas but divided evenly one on top the other on bottom                                                                                                                  

  // the first pad is active now so now we use the source->draw() to visually show us the plot in pad one                                                                                                                                     
  // Now pad 2 is active so now we have to insert the plot into that pad                                                                                                                                                                      
  // basically draws plot two in pad two                                                                                                                                                                                                      


 // My attempt in trying to have different width size you can ignore                                                                                                                                                                         
  Float_t Lower[5];

  Lower[0] = -3;
  Lower[1] = -1;
  Lower[2] = 2;
  Lower[3] = 2.5;
  Lower[4] = 3;

  TH1F* hist =new  TH1F (*final,"hist", 4, Lower);

  hist->SetBinContent(1, 1);
  hist->SetBinContent(2, 2);
  hist->SetBinContent(3, 3);
  hist->SetBinContent(4, 4);



So here to reproduce the final or source signal in new bins how would we change the bins but also how to have different bin sizes.

@jalopezg I want to find a way to redo the bin width size of an already existing histogram and have these bin width sizes vary

I looked at this example ROOT: tutorials/hist/rebin.C File Reference

and also at this forum question Different bin size in 1D histogram

  TH1F *source = new TH1F("source", "source", 100, -3., 3.);
  source->FillRandom("gaus", 1000);
  Double_t Lower[5]; // [nbinsx + 1]
  // make sure new bin edges correspond to bin edges in the original histogram
  Lower[0] = source->GetBinLowEdge(1); // xlow
  Lower[1] = source->GetBinLowEdge(source->FindFixBin(-1.));
  Lower[2] = source->GetBinLowEdge(source->FindFixBin(2.));
  Lower[3] = source->GetBinLowEdge(source->FindFixBin(2.5));
  Lower[4] = source->GetBinLowEdge(source->GetNbinsX() + 1); // xup
  if (!source->GetSumw2N()) source->Sumw2(kTRUE); // needed for correct new errors
  TH1 *hist = (TH1*)source->Rebin((sizeof(Lower) / sizeof(Double_t) - 1),
                                  "hist", Lower);
  hist->SetTitle("hist is the rebinned source");
  TCanvas *c = new TCanvas("c", "c");
  c->Divide(1, 2);

I tried that with the main code and it printed out but it was not re-bined ?

@Abaraj48 did you get the values right for each element of the Lower[] array? Could you please provide an excerpt of the relevant fragments of the code that you have?


Yeah I think I am going to try to just download the out puts and the macro I did

Holy sh&% now it works I just did the same thing I did last week but now it works ? idk why but it works

@Wile_E_Coyote What is the purpose of the if statement here ?

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