TAxis::GetXbins does not always return bin edges

Hi,

I am attempting to build a 2D histogram with bins defined in 1D histograms, but it appears that the TAxis::GetXbins function does not always produce an array of bin edges. For the case where a user provides the number of bins and min and max, the edge array is not produced. In the case where an array of edges is passed GetXbins works as expected. This makes generalized code that can read from either type of histogram much more difficult. Below is an example where the wrong bin edges are produced as the array is not defined. It would be nice if TAxis::GetXaxis would produce an array on the fly when one is available.

Below is an example that demonstrates the issue:

void test() {
   auto h1 = new TH1F("h1", "H1", 10, -0.05, 10.05);
   double array[5] = {0, 1, 2, 3, 4};
   auto h2 = new TH1F("h2", "H2", 4, array);

   auto h2d = new TH2D("h2d", "H2D",
                       h1->GetNbinsX(), h1->GetXaxis()->GetXbins()->GetArray(),
                       h2->GetNbinsX(), h2->GetXaxis()->GetXbins()->GetArray());

   h2d->Draw();

   std::cout << "X-axis: ";
   for (int i=0; i < h1->GetNbinsX(); i++) {
      std::cout << h1->GetXaxis()->GetXbins()->At(i) << ",";
   }
   std::cout << "\n";

   std::cout << "Y-axis: ";
   for (int i=0; i < h2->GetNbinsX(); i++) {
      std::cout << h2->GetXaxis()->GetXbins()->At(i) << ",";
   }
   std::cout << "\n";
}
$ root test.C 
root [0] 
Processing test.C...
Info in <TCanvas::MakeDefCanvas>:  created default TCanvas with name c1
Error in <TArrayD::At>: index 0 out of bounds (size: 0, this: 0x7fabfb60ef68)
Error in <TArrayD::At>: index 1 out of bounds (size: 0, this: 0x7fabfb60ef68)
Error in <TArrayD::At>: index 2 out of bounds (size: 0, this: 0x7fabfb60ef68)
Error in <TArrayD::At>: index 3 out of bounds (size: 0, this: 0x7fabfb60ef68)
Error in <TArrayD::At>: index 4 out of bounds (size: 0, this: 0x7fabfb60ef68)
Error in <TArrayD::At>: index 5 out of bounds (size: 0, this: 0x7fabfb60ef68)
Error in <TArrayD::At>: index 6 out of bounds (size: 0, this: 0x7fabfb60ef68)
Error in <TArrayD::At>: index 7 out of bounds (size: 0, this: 0x7fabfb60ef68)
Error in <TArrayD::At>: index 8 out of bounds (size: 0, this: 0x7fabfb60ef68)
Error in <TArrayD::At>: index 9 out of bounds (size: 0, this: 0x7fabfb60ef68)
X-axis: 0,0,0,0,0,0,0,0,0,0,
Y-axis: 0,1,2,3,
root [1] 

This was also mentioned previously:


ROOT Version: 6.14.06
Platform: Not Provided
Compiler: Not Provided


For fix bin size histograms, histo->GetXaxis()->GetXbins()->GetArray() returns a “nullptr” (i.e. 0).

1 Like

I do not think this would be a good idea. From Taxis.cxx

 if (!fXbins.fN) { //*-* fix bins
       // do something
       } else {    //*-* variable bin sizes
       // do something
  }

fXbins is used as a basic test for fix/variable bin sizes. Moreover, for example TAxis::FindBin(Double_t x) with "forced fXbins" (for fix bins) will be less effective. I think TAxis FixedToVariable and VariableToFixed proposal is better choice.

I’m not proposing that the object store fXbins in the case of fixed bins, but rather that an array be generated on the fly for the user that matches the edges instead of simply providing a null array that indicates there are no edges.

Also, it seems like a mistake to use the bin edge container as a test to see how the edges were defined. A simple Boolean would be better and wouldn’t add much weight to this class.

I’m not a huge fan of a method to switch back and forth as the. The user still needs to know how the axis was declared initially. It seems to me that if I get an axis object all methods should work no matter how it was created.

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