diff --git a/hist/hist/src/THLimitsFinder.cxx b/hist/hist/src/THLimitsFinder.cxx index 528b08303f651..fe0533b02db3e 100644 --- a/hist/hist/src/THLimitsFinder.cxx +++ b/hist/hist/src/THLimitsFinder.cxx @@ -12,6 +12,8 @@ #include "TMath.h" #include "THLimitsFinder.h" +#include + THLimitsFinder *THLimitsFinder::fgLimitsFinder = nullptr; ClassImp(THLimitsFinder); @@ -381,8 +383,8 @@ void THLimitsFinder::OptimizeLimits(Int_t nbins, Int_t &newbins, Double_t &xmin, xmin = -1; xmax = 1; } else { - xmin = binlow; - xmax = binhigh; + xmin = std::min(binlow, xmin); + xmax = std::max(binhigh, xmax + 0.01 * (xmax - xmin)); } if (isInteger) { Long64_t ixmin = Long64_t(xmin); diff --git a/hist/hist/test/test_TH1.cxx b/hist/hist/test/test_TH1.cxx index 6b625eb7ae528..381d04050f430 100644 --- a/hist/hist/test/test_TH1.cxx +++ b/hist/hist/test/test_TH1.cxx @@ -54,6 +54,19 @@ TEST(THLimitsFinder, Degenerate) EXPECT_GE(xmax, centralValue + 5.); } +// see https://root-forum.cern.ch/t/bug-or-feature-in-ttree-draw/62862 +// Due to a poor binning choice in THLimitsFinder, the histograms in +// TTree::Draw might not contain contain all values. +TEST(THLimitsFinder, TTreeDraw_AutoBinning) +{ + TH1F histo("limitsFinder", "", 100, 0, 0); + histo.Fill(-999); + histo.Fill(0); + histo.BufferEmpty(1); + + EXPECT_EQ(histo.GetEntries(), histo.GetEffectiveEntries()); +} + // Simple cross-check that TH1::SmoothArray() is not doing anything if input // array is already smooth. TEST(TH1, SmoothArrayCrossCheck) diff --git a/test/stressHistogram.cxx b/test/stressHistogram.cxx index 8e153d92209d9..09b3e64750c6a 100644 --- a/test/stressHistogram.cxx +++ b/test/stressHistogram.cxx @@ -6282,6 +6282,9 @@ bool testMerge1DWithBuffer(bool allNoLimits) TH1D* h4 = new TH1D("h4", "h4-Title", numberOfBins, x1,x2); h0->Sumw2(); h1->Sumw2();h2->Sumw2();h4->Sumw2(); + // The below histograms will be merged into h0, so they all need to fit into the buffer. + // Otherwise, the axis ranges will be computed already during the partial merge. + h0->SetBuffer(nEvents * 10); h1->SetBuffer(nEvents*10); h2->SetBuffer(nEvents*10); h3->SetBuffer(nEvents*10); diff --git a/tree/tree/test/TTreeRegressions.cxx b/tree/tree/test/TTreeRegressions.cxx index 06db04154e6d0..d73b9641f4fe1 100644 --- a/tree/tree/test/TTreeRegressions.cxx +++ b/tree/tree/test/TTreeRegressions.cxx @@ -289,3 +289,23 @@ TEST(TTreeRegressions, FindBranchBrackets) EXPECT_NE(t.FindBranch("branch[3]"), nullptr); EXPECT_EQ(t.FindBranch("branch[3]"), t.GetBranch("branch[3]")); } + +// see https://root-forum.cern.ch/t/bug-or-feature-in-ttree-draw/62862 +// Due to a poor binning choice in THLimitsFinder, the histogram didn't contain +// all values. +TEST(TTreeRegressions, DrawAutoBinning) +{ + TTree t; + Float_t x; + t.Branch("x", &x); + x = -999; + t.Fill(); + x = 0; + t.Fill(); + t.Draw("x"); + auto h = (TH1 *)gROOT->FindObject("htemp"); + ASSERT_NE(h, nullptr); + EXPECT_EQ(h->GetEntries(), h->GetEffectiveEntries()); + delete h; + delete gROOT->FindObject("c1"); +}