diff --git a/hist/hist/src/TH2.cxx b/hist/hist/src/TH2.cxx index 8a109161cdd9d..ba9702c217253 100644 --- a/hist/hist/src/TH2.cxx +++ b/hist/hist/src/TH2.cxx @@ -2313,7 +2313,8 @@ TH1D *TH2::DoProjection(bool onX, const char *name, Int_t firstbin, Int_t lastbi if (fTsumw != 0 && TMath::Abs( fTsumw - totcont) < TMath::Abs(fTsumw) * eps) reuseStats = true; } - if (ncuts) reuseStats = false; + if (ncuts || useWidth) + reuseStats = false; // retrieve the statistics and set in projected histogram if we can re-use it bool reuseEntries = reuseStats; // can re-use entries if underflow/overflow are included diff --git a/hist/hist/src/TH3.cxx b/hist/hist/src/TH3.cxx index de7a3de5e0aa7..c56ebadccca31 100644 --- a/hist/hist/src/TH3.cxx +++ b/hist/hist/src/TH3.cxx @@ -2106,7 +2106,8 @@ TH1D *TH3::DoProject1D(const char* name, const char * title, const TAxis* projX, bool resetStats = true; double eps = 1.E-12; if (IsA() == TH3F::Class() ) eps = 1.E-6; - if (fTsumw != 0 && TMath::Abs( fTsumw - totcont) < TMath::Abs(fTsumw) * eps) resetStats = false; + if (!useWidth && fTsumw != 0 && TMath::Abs(fTsumw - totcont) < TMath::Abs(fTsumw) * eps) + resetStats = false; bool resetEntries = resetStats; // entries are calculated using underflow/overflow. If excluded entries must be reset @@ -2337,7 +2338,8 @@ TH2D *TH3::DoProject2D(const char* name, const char * title, const TAxis* projX, bool resetStats = true; double eps = 1.E-12; if (IsA() == TH3F::Class() ) eps = 1.E-6; - if (fTsumw != 0 && TMath::Abs( fTsumw - totcont) < TMath::Abs(fTsumw) * eps) resetStats = false; + if (!useWidth && fTsumw != 0 && TMath::Abs(fTsumw - totcont) < TMath::Abs(fTsumw) * eps) + resetStats = false; bool resetEntries = resetStats; // entries are calculated using underflow/overflow. If excluded entries must be reset diff --git a/hist/hist/test/test_projections.cxx b/hist/hist/test/test_projections.cxx index d57d4f325491d..ca96e3d0742f9 100644 --- a/hist/hist/test/test_projections.cxx +++ b/hist/hist/test/test_projections.cxx @@ -85,3 +85,38 @@ TEST(Projections, Issue_6658_Profile2D) EXPECT_EQ(xaxis_2d_nbins, xaxis_pxy_nbins); expect_list_eq_names(*labels_2d, *labels_pxy); } + +TEST(Projections, WidthWeightedTH2Statistics) +{ + double edges[] = {0., 1., 4.}; + TH2D x("width_x", "", 2, 0., 2., 2, edges); + x.Fill(0.5, 0.5); + x.Fill(1.5, 2.); + auto px = x.ProjectionX("width_px", 1, 2, "width"); + EXPECT_DOUBLE_EQ(px->GetBinContent(1), 1.); + EXPECT_DOUBLE_EQ(px->GetBinContent(2), 3.); + EXPECT_DOUBLE_EQ(px->GetMean(), 1.25); + TH2D y("width_y", "", 2, edges, 2, 0., 2.); + y.Fill(0.5, 0.5); + y.Fill(2., 1.5); + auto py = y.ProjectionY("width_py", 1, 2, "width"); + EXPECT_DOUBLE_EQ(py->GetMean(), 1.25); + delete px; + delete py; +} + +TEST(Projections, WidthWeightedTH3Statistics) +{ + double x[] = {0., 1., 2.}, y[] = {0., 0.5, 2.}, z[] = {0., 1.}; + TH3D h("width_h3", "", 2, x, 2, y, 1, z); + h.Fill(0.5, 0.25, 0.5); + h.Fill(1.5, 1., 0.5); + auto px = h.ProjectionX("width_px3", 1, 2, 1, 1, "width"); + auto p2 = static_cast(h.Project3D("zxwidth")); + EXPECT_DOUBLE_EQ(px->GetBinContent(1), 0.5); + EXPECT_DOUBLE_EQ(px->GetBinContent(2), 1.5); + EXPECT_DOUBLE_EQ(px->GetMean(), 1.25); + EXPECT_DOUBLE_EQ(p2->GetMean(1), 1.25); + delete px; + delete p2; +}