diff --git a/hist/hist/src/THnBase.cxx b/hist/hist/src/THnBase.cxx index 556808364863b..ebed694679f14 100644 --- a/hist/hist/src/THnBase.cxx +++ b/hist/hist/src/THnBase.cxx @@ -836,10 +836,14 @@ void THnBase::AddInternal(const THnBase* h, Double_t c, Bool_t rebinned) Long64_t i = 0; std::unique_ptr iter{h->CreateIter(false)}; // Add to this whatever is found inside the other histogram + const bool sparse = InheritsFrom(THnSparse::Class()); while ((i = iter->Next(coord)) >= 0) { // Get the content of the bin from the second histogram Double_t v = h->GetBinContent(i); - + Double_t err2 = haveErrors ? h->GetBinError2(i) * c * c : 0; + if (sparse && v == 0 && err2 == 0) { + continue; + } Long64_t mybinidx = -1; if (rebinned) { // Get the bin center given a coord @@ -852,7 +856,6 @@ void THnBase::AddInternal(const THnBase* h, Double_t c, Bool_t rebinned) } if (haveErrors) { - Double_t err2 = h->GetBinError2(i) * c * c; AddBinError2(mybinidx, err2); } // only _after_ error calculation, or sqrt(v) is taken into account! diff --git a/hist/hist/test/THn.cxx b/hist/hist/test/THn.cxx index e7dd8aae022c2..c9a682acb1123 100644 --- a/hist/hist/test/THn.cxx +++ b/hist/hist/test/THn.cxx @@ -1,6 +1,7 @@ #include "gtest/gtest.h" #include "THn.h" +#include "THnSparse.h" #include "TH1.h" #include "TH2.h" @@ -174,3 +175,16 @@ TEST(THn, ErrorsOfProjection) EXPECT_FLOAT_EQ(proj->GetBinContent(projectedBin2), 18.); EXPECT_FLOAT_EQ(proj->GetBinError(projectedBin2), 6.); } + +// https://github.com/root-project/root/issues/19366 +TEST(THn, CreateSparse) +{ + Int_t bins[1] = {5}; + Double_t xmin[1] = {0.}; + Double_t xmax[1] = {1.}; + THnD hn("hn", "hn", 1, bins, xmin, xmax); + hn.Fill(0.5); + auto hn_sparse = THnSparseD::CreateSparse("", "", &hn); + EXPECT_EQ(hn_sparse->GetNbins(), 1); + EXPECT_FLOAT_EQ(hn_sparse->GetSparseFractionBins(), 1. / 7); // 5 + under/overflows +}