Home | News | Documentation | Download

Is there a bug in TH1::SetLimits when using a file?


#1

Hello,

is there somehow a bug with SetLimits when using a file ?

Here is a reproducible example.

I clone an histogram h1 into an histogram h2.
I shift in y by a Rescale, the second histogram (just in order to make appear the bug with the SetLimits)
I shift in x with SetLimits the second histogram.
In the default configuration, it works, but if h1 is read from a file, then the SetLimits on the h2 has no effect.
When ones uncomment the two commented lines, the shift in x no more works.

Is there a bug ?
Is there a solution ?

thank you

Here is the minimal example :
/afs/cern.ch/user/e/escalier/IsItBUG

void Test()
{

  //goal of the macro : to shift h1 by a tiny x value
  //the y is shifted by a factor 1.01 in order to make appear the user to understand that there is an apparent bug for the case for the histogram is read from the file : the shift in x no more appears

  TH1F *h2;

  TH1F *h1 = new TH1F("h1","h1",25,0,2.5);


  h1->FillRandom("gaus",1000);

  //switch off these two lines block, and the shift no more works !!
//   TFile *f_MC_13TeV_Zmumu_LowMu_Barrel=new TFile("ratioPlots_onlyBarrel.root");
//   h1=(TH1F *)f_MC_13TeV_Zmumu_LowMu_Barrel->Get("histMPV_from_fit_muS1_cell_E_total");

  h1->SetMarkerStyle(20);
  h1->SetMarkerColor(kBlue);


  h2 = (TH1F*)h1->Clone("h2");

  h2->Scale(1.01);
  Double_t shift = 0.5*h1->GetBinWidth(1);
  cout << "shift=" << shift << endl;
  cout << "h2->GetXaxis()->GetXmin()=" << h2->GetXaxis()->GetXmin() << endl;

  h2->GetXaxis()->SetLimits(0+shift,2.5+shift);

  h2->SetMarkerStyle(21);
  h2->SetMarkerColor(kRed);

  cout << "h2->GetXaxis()->GetXmin()=" << h2->GetXaxis()->GetXmin() << endl;

  h1->Draw("e1");
  h2->Draw("e1 same");
}

ROOT Version: 6.10/08
Platform: linux
Compiler: Not Provided



#2

Hi Marc,

Apologies that nobody replied :frowning:

Please see https://root-forum.cern.ch/t/how-to-set-ranges-on-axis - what you want is SetRangeUser() and SetAxisRange().

Cheers, Axel.


#3

Thank you Axel,

actually, your suggestion makes a change on the start of the histogram, but does not change the center of the histogram.

My goal is to a x-axis shift of two histograms (in order to vizualize easily the différences)

I was using SetLimits as a trick, given by:
https://root.cern.ch/root/roottalk/roottalk03/2765.html
but the point is that if the histograms are coming from files, the trick does not work any more.

–>I have provided a minimum reproducible example here :

/afs/cern.ch/user/e/escalier/IsItBUG

To see the bug, one should just switch off these two lines in my example :

//switch off these two lines block, and the shift no more works !!
// TFile *f_MC_13TeV_Zmumu_LowMu_Barrel=new TFile(“ratioPlots_onlyBarrel.root”);
// h1=(TH1F *)f_MC_13TeV_Zmumu_LowMu_Barrel->Get(“histMPV_from_fit_muS1_cell_E_total”);

Using the SetAxisRange would not allow to make a relative shift of one with respect to the other : the centers are still aligned.

thank you


#4

I tried with “${ROOTSYS}/tutorials/hsimple.root” and I see no problem (neither with ROOT 5.34 nor ROOT 6).
You can try my small test macro with your own ROOT file if you replace “#if 0” with “#if 1” inside:

{
  TFile *f;
  TH1 *h1, *h2;
#if 0 /* 0 or 1 */
  // try it with your own file
  f = TFile::Open("ratioPlots_onlyBarrel.root");
  if ((!f) || f->IsZombie()) { delete f; return; } // file is not usable
  f->GetObject("histMPV_from_fit_muS1_cell_E_total", h1);
  if (!h1) { delete f; return; } // no histogram found
#else /* 0 or 1 */
  // try it with the "${ROOTSYS}/tutorials/hsimple.root"
  f = TFile::Open("hsimple.root");
  if ((!f) || f->IsZombie()) { delete f; return; } // file is not usable
  f->GetObject("hpx", h1);
  if (!h1) { delete f; return; } // no histogram found
#endif /* 0 or 1 */
  // h1->Sumw2(1);
  h1->SetMarkerStyle(20);
  h1->SetMarkerColor(kBlue);
  h2 = ((TH1*)(h1->Clone("h2")));
  h2->Scale(1.01);
  h2->SetMarkerStyle(22);
  h2->SetMarkerColor(kRed);
  Double_t shift = 0.5 * h1->GetBinWidth(1);
  std::cout << "shift = " << shift << std::endl;
  TAxis *a = h2->GetXaxis();
  std::cout << "h2->GetXaxis()->GetXmin() = " << a->GetXmin() << std::endl;
  a->SetLimits(a->GetXmin() + shift, a->GetXmax() + shift);
  std::cout << "h2->GetXaxis()->GetXmin() = " << a->GetXmin() << std::endl;
  h1->Draw("e1");
  h2->Draw("e1 same");
}

#5

Dear Colleagues,
thank you for your kind help.
Unfortunately, I have found that actually, the problem was not from the TF1, but directly from TH1 :

–>in the special case where the histogram has not a constant bin width, the SetLimits is not working

–>proof :
it works with :

TH1F *h1 = new TH1F(“h1”,“h1”,25,0,2.5);
h1->FillRandom(“gaus”,1000);

but it does not work (no shift possible) with :

float bins[5]={0,0.1,0.3,0.8,2.5};
TH1F *h1=new TH1F(“h1”,“h1”,4,bins);
h1->FillRandom(“gaus”,1000);

–>Do you agree ?

thank you


#6

(sorry : I mean the problem is not from reading the TH1 from a TFile, but from the TH1 itself : the shift of histogram seems not to work in the special case where the histogram has a variable bin width)


#7

#8

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