812void GCube::FitSlicesZ(TF1* f1, Int_t binminx, Int_t binmaxx, Int_t binminy, Int_t binmaxy, Int_t cut, Option_t* option)
814 Int_t nbinsx = fXaxis.GetNbins();
815 Int_t nbinsy = fYaxis.GetNbins();
816 Int_t nbinsz = fZaxis.GetNbins();
820 if(binmaxx > nbinsx) {
823 if(binmaxx < binminx) {
830 if(binmaxy > nbinsy) {
833 if(binmaxy < binminy) {
840 f1 =
static_cast<TF1*
>(gROOT->GetFunction(
"gaus"));
842 f1 =
new TF1(
"gaus",
"gaus", fZaxis.GetXmin(), fZaxis.GetXmax());
844 f1->SetRange(fZaxis.GetXmin(), fZaxis.GetXmax());
847 const char* fname = f1->GetName();
848 Int_t npar = f1->GetNpar();
849 auto* parsave =
new Double_t[npar];
850 f1->GetParameters(parsave);
853 std::array<char, 80> name;
854 std::array<char, 80> title;
855 std::vector<TH2D*> hlist(npar);
856 const TArrayD* xbins = fXaxis.GetXbins();
857 const TArrayD* ybins = fYaxis.GetXbins();
858 for(Int_t ipar = 0; ipar < npar; ++ipar) {
859 snprintf(name.data(), name.size(),
"%s_%d", GetName(), ipar);
860 snprintf(title.data(), title.size(),
"Fitted value of par[%d]=%s", ipar, f1->GetParName(ipar));
862 hlist[ipar] =
new TH2D(name.data(), title.data(), nbinsx, fXaxis.GetXmin(), fXaxis.GetXmax(), nbinsy, fYaxis.GetXmin(), fYaxis.GetXmax());
864 hlist[ipar] =
new TH2D(name.data(), title.data(), nbinsx, xbins->fArray, nbinsy, ybins->fArray);
866 hlist[ipar]->GetXaxis()->SetTitle(fXaxis.GetTitle());
867 hlist[ipar]->GetYaxis()->SetTitle(fYaxis.GetTitle());
869 snprintf(name.data(), name.size(),
"%s_chi2", GetName());
870 auto* hchi2 =
new TH2D(name.data(),
"chisquare", nbinsx, fXaxis.GetXmin(), fXaxis.GetXmax(), nbinsy, fYaxis.GetXmin(), fYaxis.GetXmax());
873 auto* hpz =
new TH1D(
"R_temp",
"_temp", nbinsz, fZaxis.GetXmin(), fZaxis.GetXmax());
874 for(Int_t biny = binminy; biny <= binmaxy; biny++) {
875 Double_t y = fYaxis.GetBinCenter(biny);
876 for(Int_t binx = binminx; binx <= binmaxx; binx++) {
877 Double_t x = fXaxis.GetBinCenter(binx);
880 for(Int_t binz = 1; binz <= nbinsz; binz++) {
881 Int_t bin =
GetBin(binx, biny, binz);
882 Double_t w = RetrieveBinContent(bin);
886 hpz->Fill(fZaxis.GetBinCenter(binz), w);
887 hpz->SetBinError(binz, GetBinError(bin));
893 f1->SetParameters(parsave);
894 hpz->Fit(fname, option);
895 Int_t npfits = f1->GetNumberFitPoints();
896 if(npfits > npar && npfits >= cut) {
897 for(Int_t ipar = 0; ipar < npar; ipar++) {
898 hlist[ipar]->Fill(x, y, f1->GetParameter(ipar));
899 hlist[ipar]->SetBinError(binx, biny, f1->GetParError(ipar));
901 hchi2->SetBinContent(binx, biny, f1->GetChisquare() / (npfits - npar));
1320 Int_t ubx = fXaxis.FindBin(x);
1321 if(x < fXaxis.GetBinCenter(ubx)) {
1324 Int_t obx = ubx + 1;
1326 Int_t uby = fYaxis.FindBin(y);
1327 if(y < fYaxis.GetBinCenter(uby)) {
1330 Int_t oby = uby + 1;
1332 Int_t ubz = fZaxis.FindBin(z);
1333 if(z < fZaxis.GetBinCenter(ubz)) {
1336 Int_t obz = ubz + 1;
1338 if(ubx <= 0 || uby <= 0 || ubz <= 0 || obx > fXaxis.GetNbins() || oby > fYaxis.GetNbins() ||
1339 obz > fZaxis.GetNbins()) {
1340 Error(
"Interpolate",
"Cannot interpolate outside histogram domain.");
1344 Double_t xw = fXaxis.GetBinCenter(obx) - fXaxis.GetBinCenter(ubx);
1345 Double_t yw = fYaxis.GetBinCenter(oby) - fYaxis.GetBinCenter(uby);
1346 Double_t zw = fZaxis.GetBinCenter(obz) - fZaxis.GetBinCenter(ubz);
1348 Double_t xd = (x - fXaxis.GetBinCenter(ubx)) / xw;
1349 Double_t yd = (y - fYaxis.GetBinCenter(uby)) / yw;
1350 Double_t zd = (z - fZaxis.GetBinCenter(ubz)) / zw;
1352 std::array<Double_t, 8> v = {GetBinContent(ubx, uby, ubz), GetBinContent(ubx, uby, obz), GetBinContent(ubx, oby, ubz),
1353 GetBinContent(ubx, oby, obz), GetBinContent(obx, uby, ubz), GetBinContent(obx, uby, obz),
1354 GetBinContent(obx, oby, ubz), GetBinContent(obx, oby, obz)};
1356 Double_t i1 = v[0] * (1 - zd) + v[1] * zd;
1357 Double_t i2 = v[2] * (1 - zd) + v[3] * zd;
1358 Double_t j1 = v[4] * (1 - zd) + v[5] * zd;
1359 Double_t j2 = v[6] * (1 - zd) + v[7] * zd;
1361 Double_t w1 = i1 * (1 - yd) + i2 * yd;
1362 Double_t w2 = j1 * (1 - yd) + j2 * yd;
1364 Double_t result = w1 * (1 - xd) + w2 * xd;
1392 TString opt = option;
1396 auto* h1 =
const_cast<TH1*
>(
static_cast<const TH1*
>(
this));
1400 TAxis* xaxis1 = h1->GetXaxis();
1401 auto* xaxis2 =
const_cast<TAxis*
>(h2->GetXaxis());
1402 Int_t nc1 = xaxis1->GetNbins();
1403 Int_t nc2 = xaxis2->GetNbins();
1406 if(h1->GetDimension() != 3 || h2->GetDimension() != 3) {
1407 Error(
"KolmogorovTest",
"Histograms must be 3-D\n");
1412 if(nc1 != nc2 || nc1 < 1) {
1413 Error(
"KolmogorovTest",
"Number of channels is different, %d and %d\n", nc1, nc2);
1418 Bool_t afunc1 = kFALSE;
1419 Bool_t afunc2 = kFALSE;
1420 Double_t difprec = 1e-5;
1421 Double_t diff1 = TMath::Abs(xaxis1->GetXmin() - xaxis2->GetXmin());
1422 Double_t diff2 = TMath::Abs(xaxis1->GetXmax() - xaxis2->GetXmax());
1423 if(diff1 > difprec || diff2 > difprec) {
1424 Error(
"KolmogorovTest",
"histograms with different binning along X");
1431 if(opt.Contains(
"U")) {
1434 if(opt.Contains(
"O")) {
1442 for(Int_t i = ibeg; i <= iend; ++i) {
1443 for(Int_t j = ibeg; j <= iend; ++j) {
1444 for(Int_t k = ibeg; k <= iend; ++k) {
1445 sum1 += h1->GetBinContent(i, j, k);
1446 sum2 += h2->GetBinContent(i, j, k);
1447 Double_t ew1 = h1->GetBinError(i, j, k);
1448 Double_t ew2 = h2->GetBinError(i, j, k);
1457 Error(
"KolmogorovTest",
"Integral is zero for h1=%s\n", h1->GetName());
1461 Error(
"KolmogorovTest",
"Integral is zero for h2=%s\n", h2->GetName());
1467 Double_t esum1 = 0.;
1468 Double_t esum2 = 0.;
1470 esum1 = sum1 * sum1 / w1;
1476 esum2 = sum2 * sum2 / w2;
1481 if(afunc2 && afunc1) {
1482 Error(
"KolmogorovTest",
"Errors are zero for both histograms\n");
1488 std::array<int, 3> order = {0, 1, 2};
1489 std::array<int, 3> binbeg;
1490 std::array<int, 3> binend;
1491 std::array<int, 3> ibin;
1498 std::array<Double_t, 6> vdfmax;
1500 Double_t s1 = 1. / (6. * sum1);
1501 Double_t s2 = 1. / (6. * sum2);
1502 Double_t rsum1 = 0.;
1503 Double_t rsum2 = 0.;
1507 for(Int_t i = binbeg[order[0]]; i <= binend[order[0]]; i++) {
1508 for(Int_t j = binbeg[order[1]]; j <= binend[order[1]]; j++) {
1509 for(Int_t k = binbeg[order[2]]; k <= binend[order[2]]; k++) {
1513 int bin = h1->GetBin(ibin[0], ibin[1], ibin[2]);
1514 rsum1 += s1 * h1->GetBinContent(bin);
1515 rsum2 += s2 * h2->GetBinContent(bin);
1516 dmax = TMath::Max(dmax, TMath::Abs(rsum1 - rsum2));
1520 vdfmax[icomb] = dmax;
1522 }
while(TMath::Permute(3, order.data()));
1525 Double_t dfmax = TMath::Mean(vdfmax.size(), vdfmax.data());
1528 Double_t factnm = 0.;
1530 factnm = TMath::Sqrt(sum2);
1532 factnm = TMath::Sqrt(sum1);
1534 factnm = TMath::Sqrt(sum1 * sum2 / (sum1 + sum2));
1536 Double_t z = dfmax * factnm;
1538 prb = TMath::KolmogorovProb(z);
1543 if(opt.Contains(
"N") && !(afunc1 || afunc2)) {
1546 Double_t d12 = esum1 - esum2;
1547 Double_t chi2 = d12 * d12 / (esum1 + esum2);
1548 prb2 = TMath::Prob(chi2, 1);
1550 if(prb > 0 && prb2 > 0) {
1551 prb = prb * prb2 * (1 - TMath::Log(prb * prb2));
1558 if(opt.Contains(
"D")) {
1559 std::cout <<
" Kolmo Prob h1 = " << h1->GetName() <<
", sum1 = " << sum1 << std::endl;
1560 std::cout <<
" Kolmo Prob h2 = " << h2->GetName() <<
", sum2 = " << sum2 << std::endl;
1561 std::cout <<
" Kolmo Probabil = " << prb <<
", Max dist = " << dfmax << std::endl;
1562 if(opt.Contains(
"N")) {
1563 std::cout <<
" Kolmo Probabil = " << prb1 <<
" for shape alone, " << prb2 <<
" for normalisation alone" << std::endl;
1567 if(TMath::Abs(rsum1 - 1) > 0.002) {
1568 Warning(
"KolmogorovTest",
"Numerical problems with h1=%s\n", h1->GetName());
1570 if(TMath::Abs(rsum2 - 1) > 0.002) {
1571 Warning(
"KolmogorovTest",
"Numerical problems with h2=%s\n", h2->GetName());
1574 if(opt.Contains(
"M")) {
1596 if(list ==
nullptr) {
1599 if(list->IsEmpty()) {
1600 return static_cast<Long64_t
>(GetEntries());
1604 inlist.AddAll(list);
1609 Bool_t initialLimitsFound = kFALSE;
1610 Bool_t allSameLimits = kTRUE;
1611 Bool_t allHaveLimits = kTRUE;
1612 Bool_t firstNonEmptyHist = kTRUE;
1614 TIter next(&inlist);
1618 if(h->fTsumw == 0 && h->GetEntries() == 0) {
1622 Bool_t hasLimits = h->GetXaxis()->GetXmin() < h->GetXaxis()->GetXmax();
1623 allHaveLimits = allHaveLimits && hasLimits;
1630 if(firstNonEmptyHist) {
1633 if(!SameLimitsAndNBins(fXaxis, *(h->GetXaxis()))) {
1634 fXaxis.Set(h->GetXaxis()->GetNbins(), h->GetXaxis()->GetXmin(), h->GetXaxis()->GetXmax());
1636 if(!SameLimitsAndNBins(fYaxis, *(h->GetYaxis()))) {
1637 fYaxis.Set(h->GetYaxis()->GetNbins(), h->GetYaxis()->GetXmin(), h->GetYaxis()->GetXmax());
1639 if(!SameLimitsAndNBins(fZaxis, *(h->GetZaxis()))) {
1640 fZaxis.Set(h->GetZaxis()->GetNbins(), h->GetZaxis()->GetXmin(), h->GetZaxis()->GetXmax());
1643 firstNonEmptyHist = kFALSE;
1646 if(!initialLimitsFound) {
1649 initialLimitsFound = kTRUE;
1650 newXAxis.Set(h->GetXaxis()->GetNbins(), h->GetXaxis()->GetXmin(), h->GetXaxis()->GetXmax());
1651 newYAxis.Set(h->GetYaxis()->GetNbins(), h->GetYaxis()->GetXmin(), h->GetYaxis()->GetXmax());
1652 newZAxis.Set(h->GetZaxis()->GetNbins(), h->GetZaxis()->GetXmin(), h->GetYaxis()->GetXmax());
1655 if(!SameLimitsAndNBins(newXAxis, *(h->GetXaxis())) || !SameLimitsAndNBins(newYAxis, *(h->GetYaxis())) ||
1656 !SameLimitsAndNBins(newZAxis, *(h->GetZaxis()))) {
1657 allSameLimits = kFALSE;
1661 if(!RecomputeAxisLimits(newXAxis, *(h->GetXaxis()))) {
1662 Error(
"Merge",
"Cannot merge histograms - limits are inconsistent:\n "
1663 "first: (%d, %f, %f), second: (%d, %f, %f)",
1664 newXAxis.GetNbins(), newXAxis.GetXmin(), newXAxis.GetXmax(), h->GetXaxis()->GetNbins(),
1665 h->GetXaxis()->GetXmin(), h->GetXaxis()->GetXmax());
1668 if(!RecomputeAxisLimits(newYAxis, *(h->GetYaxis()))) {
1669 Error(
"Merge",
"Cannot merge histograms - limits are inconsistent:\n "
1670 "first: (%d, %f, %f), second: (%d, %f, %f)",
1671 newYAxis.GetNbins(), newYAxis.GetXmin(), newYAxis.GetXmax(), h->GetYaxis()->GetNbins(),
1672 h->GetYaxis()->GetXmin(), h->GetYaxis()->GetXmax());
1675 if(!RecomputeAxisLimits(newZAxis, *(h->GetZaxis()))) {
1676 Error(
"Merge",
"Cannot merge histograms - limits are inconsistent:\n "
1677 "first: (%d, %f, %f), second: (%d, %f, %f)",
1678 newZAxis.GetNbins(), newZAxis.GetXmin(), newZAxis.GetXmax(), h->GetZaxis()->GetNbins(),
1679 h->GetZaxis()->GetXmin(), h->GetZaxis()->GetXmax());
1685 }
while((h =
static_cast<GCube*
>(next())) !=
nullptr);
1686 if(h ==
nullptr && ((*next) !=
nullptr)) {
1687 Error(
"Merge",
"Attempt to merge object of class: %s to a %s", (*next)->ClassName(), ClassName());
1696 GCube* hclone =
nullptr;
1697 if(!allSameLimits) {
1700 Bool_t mustCleanup = TestBit(kMustCleanup);
1702 ResetBit(kMustCleanup);
1704 hclone =
static_cast<GCube*
>(IsA()->New());
1705 hclone->SetDirectory(
nullptr);
1708 SetBit(kMustCleanup);
1713 inlist.AddFirst(hclone);
1716 if(!allSameLimits && initialLimitsFound) {
1717 SetBins(newXAxis.GetNbins(), newXAxis.GetXmin(), newXAxis.GetXmax(), newYAxis.GetNbins(), newYAxis.GetXmin(),
1718 newYAxis.GetXmax(), newZAxis.GetNbins(), newZAxis.GetXmin(), newZAxis.GetXmax());
1721 if(!allHaveLimits) {
1723 while((h =
static_cast<GCube*
>(next())) !=
nullptr) {
1724 if(h->GetXaxis()->GetXmin() >= h->GetXaxis()->GetXmax() && (h->fBuffer !=
nullptr)) {
1726 auto nbentries =
static_cast<Int_t
>(h->fBuffer[0]);
1727 for(Int_t i = 0; i < nbentries; i++) {
1728 Fill(h->fBuffer[4 * i + 2], h->fBuffer[4 * i + 3], h->fBuffer[4 * i + 4], h->fBuffer[4 * i + 1]);
1734 if(!initialLimitsFound) {
1735 if(hclone !=
nullptr) {
1736 inlist.Remove(hclone);
1739 return static_cast<Long64_t
>(GetEntries());
1745 std::array<Double_t, kNstat> stats;
1746 std::array<Double_t, kNstat> totstats;
1747 for(Int_t i = 0; i < kNstat; ++i) {
1748 totstats[i] = stats[i] = 0;
1751 Double_t nentries = GetEntries();
1755 Bool_t canExtend = CanExtendAllAxes();
1756 SetCanExtend(TH1::kNoAxis);
1758 while((h =
static_cast<GCube*
>(next())) !=
nullptr) {
1760 if(h->GetXaxis()->GetXmin() < h->GetXaxis()->GetXmax()) {
1763 for(Int_t i = 0; i < kNstat; ++i) {
1764 totstats[i] += stats[i];
1766 nentries += h->GetEntries();
1768 Int_t nx = h->GetXaxis()->GetNbins();
1769 Int_t ny = h->GetYaxis()->GetNbins();
1770 Int_t nz = h->GetZaxis()->GetNbins();
1774 for(Int_t binz = 0; binz <= nz + 1; ++binz) {
1775 if(!allSameLimits) {
1776 iz = fZaxis.FindBin(h->GetZaxis()->GetBinCenter(binz));
1781 for(Int_t biny = 0; biny <= ny + 1; ++biny) {
1782 if(!allSameLimits) {
1783 iy = fYaxis.FindBin(h->GetYaxis()->GetBinCenter(biny));
1787 for(Int_t binx = 0; binx <= nx + 1; ++binx) {
1788 Int_t bin = binx + (nx + 2) * (biny + (ny + 2) * binz);
1789 Double_t cu = h->GetBinContent(bin);
1790 if(!allSameLimits) {
1792 if(cu != 0 && (h->IsBinUnderflow(bin) || h->IsBinOverflow(bin))) {
1793 Error(
"Merge",
"Cannot merge histograms - the histograms have"
1794 " different limits and undeflows/overflows are present."
1795 " The initial histogram is now broken!");
1798 ix = fXaxis.FindBin(h->GetXaxis()->GetBinCenter(binx));
1803 Int_t ibin =
GetBin(ix, iy, iz);
1808 AddBinContent(ibin, cu);
1809 if(fSumw2.fN != 0) {
1810 Double_t error1 = h->GetBinError(bin);
1811 fSumw2.fArray[ibin] += error1 * error1;
1819 SetCanExtend(
static_cast<UInt_t
>(canExtend));
1824 SetEntries(nentries);
1825 if(hclone !=
nullptr) {
1826 inlist.Remove(hclone);
1829 return static_cast<Long64_t
>(nentries);
1832TH1D*
GCube::Projection(
const char* name, Int_t firstBiny, Int_t lastBiny, Int_t firstBinz, Int_t lastBinz,
1833 Option_t* option)
const
1836 const char* expectedName =
"_pr";
1838 TString opt = option;
1840 Int_t i1 = opt.Index(
"[");
1842 Int_t i2 = opt.Index(
"]");
1843 cut = opt(i1, i2 - i1 + 1);
1846 bool originalRange = opt.Contains(
"o");
1848 Int_t firstXBin = fXaxis.GetFirst();
1849 Int_t lastXBin = fXaxis.GetLast();
1851 if(firstXBin == 0 && lastXBin == 0) {
1853 lastXBin = fXaxis.GetNbins();
1856 if(lastBiny < firstBiny && fYaxis.TestBit(TAxis::kAxisRange)) {
1857 firstBiny = fYaxis.GetFirst();
1858 lastBiny = fYaxis.GetLast();
1862 if(firstBiny == 0 && lastBiny == 0) {
1864 lastBiny = fYaxis.GetNbins();
1871 lastBiny = fYaxis.GetLast() + 1;
1873 if(lastBiny > fYaxis.GetLast() + 1) {
1874 lastBiny = fYaxis.GetLast() + 1;
1877 if(lastBinz < firstBinz && fZaxis.TestBit(TAxis::kAxisRange)) {
1878 firstBinz = fZaxis.GetFirst();
1879 lastBinz = fZaxis.GetLast();
1883 if(firstBinz == 0 && lastBinz == 0) {
1885 lastBinz = fZaxis.GetNbins();
1892 lastBinz = fZaxis.GetLast() + 1;
1894 if(lastBinz > fZaxis.GetLast() + 1) {
1895 lastBinz = fZaxis.GetLast() + 1;
1899 char* pname =
const_cast<char*
>(name);
1900 if(name !=
nullptr && strcmp(name, expectedName) == 0) {
1901 auto nch = strlen(GetName()) + 4;
1902 pname =
new char[nch];
1903 snprintf(pname, nch,
"%s%s", GetName(), name);
1909 TObject* h1obj = gROOT->FindObject(pname);
1910 if((h1obj !=
nullptr) && h1obj->InheritsFrom(TH1::Class())) {
1911 if(h1obj->IsA() != TH1D::Class()) {
1912 Error(
"DoProjection",
"Histogram with name %s must be a TH1D and is a %s", name, h1obj->ClassName());
1915 h1 =
static_cast<TH1D*
>(h1obj);
1920 const TArrayD* xbins = fXaxis.GetXbins();
1921 if(xbins->fN == 0) {
1923 h1->SetBins(fXaxis.GetNbins(), fXaxis.GetXmin(), fXaxis.GetXmax());
1925 h1->SetBins(lastXBin - firstXBin + 1, fXaxis.GetBinLowEdge(firstXBin), fXaxis.GetBinUpEdge(lastXBin));
1930 h1->SetBins(fXaxis.GetNbins(), xbins->fArray);
1932 h1->SetBins(lastXBin - firstXBin + 1, &(xbins->fArray[firstXBin - 1]));
1938 const TArrayD* bins = fXaxis.GetXbins();
1941 h1 =
new TH1D(pname, GetTitle(), fXaxis.GetNbins(), fXaxis.GetXmin(), fXaxis.GetXmax());
1943 h1 =
new TH1D(pname, GetTitle(), lastXBin - firstXBin + 1, fXaxis.GetBinLowEdge(firstXBin),
1944 fXaxis.GetBinUpEdge(lastXBin));
1949 h1 =
new TH1D(pname, GetTitle(), fXaxis.GetNbins(), bins->fArray);
1951 h1 =
new TH1D(pname, GetTitle(), lastXBin - firstXBin + 1, &(bins->fArray[firstXBin - 1]));
1954 if(opt.Contains(
"e") || (GetSumw2N() != 0)) {
1963 h1->GetXaxis()->ImportAttributes(&fXaxis);
1964 THashList* labels =
const_cast<TAxis*
>(&fXaxis)->GetLabels();
1965 if(labels !=
nullptr) {
1967 TObjString* lb =
nullptr;
1969 while((lb =
static_cast<TObjString*
>(iL())) !=
nullptr) {
1970 h1->GetXaxis()->SetBinLabel(i, lb->String().Data());
1975 h1->SetLineColor(GetLineColor());
1976 h1->SetFillColor(GetFillColor());
1977 h1->SetMarkerColor(GetMarkerColor());
1978 h1->SetMarkerStyle(GetMarkerStyle());
1981 Double_t totcont = 0.;
1982 Bool_t computeErrors = h1->GetSumw2N() != 0;
1987 for(Int_t xbin = 0; xbin <= fXaxis.GetNbins() + 1; ++xbin) {
1990 if(fXaxis.TestBit(TAxis::kAxisRange) && (xbin < firstXBin || xbin > lastXBin)) {
1994 for(Int_t ybin = firstBiny; ybin <= lastBiny; ++ybin) {
1995 for(Int_t zbin = firstBinz; zbin <= lastBinz; ++zbin) {
1997 cont += GetBinContent(xbin, ybin, zbin);
1999 Double_t exy = GetBinError(xbin, ybin, zbin);
2005 Int_t binOut = h1->GetXaxis()->FindBin(fXaxis.GetBinCenter(xbin));
2006 h1->SetBinContent(binOut, cont);
2008 h1->SetBinError(binOut, TMath::Sqrt(err2));
2015 bool reuseStats =
false;
2016 if(((!fgStatOverflows && firstBiny == 1 && lastBiny == fYaxis.GetLast()) ||
2017 (fgStatOverflows && firstBiny == 0 && lastBiny == fYaxis.GetLast() + 1)) &&
2018 ((!fgStatOverflows && firstBinz == 1 && lastBinz == fZaxis.GetLast()) ||
2019 (fgStatOverflows && firstBinz == 0 && lastBinz == fZaxis.GetLast() + 1))) {
2023 double eps = 1.E-12;
2024 if(IsA() == GCubeF::Class()) {
2027 if(fTsumw != 0 && TMath::Abs(fTsumw - totcont) < TMath::Abs(fTsumw) * eps) {
2032 bool reuseEntries = reuseStats;
2034 reuseEntries &=
static_cast<int>(firstBiny == 0 && lastBiny == fYaxis.GetLast() + 1 && firstBinz == 0 &&
2035 lastBinz == fYaxis.GetLast() + 1);
2037 std::array<Double_t, kNstat> stat;
2039 h1->PutStats(stat.data());
2044 h1->SetEntries(h1->GetEffectiveEntries());
2047 h1->SetEntries(fEntries);
2053 Double_t entries = TMath::Floor(totcont + 0.5);
2054 if(h1->GetSumw2N() != 0) {
2055 entries = h1->GetEffectiveEntries();
2057 h1->SetEntries(entries);
2060 if(opt.Contains(
"d")) {
2061 TVirtualPad* padsav = gPad;
2062 TVirtualPad* pad = gROOT->GetSelectedPad();
2063 if(pad !=
nullptr) {
2066 opt.Remove(opt.First(
"d"), 1);
2068 if(opt.Contains(
"e")) {
2069 opt.Remove(opt.First(
"e"), 1);
2071 if(!gPad || !gPad->FindObject(h1)) {
2076 if(padsav !=
nullptr) {
2122 Int_t nbins = fXaxis.GetNbins();
2123 Double_t min = fXaxis.GetXmin();
2124 Double_t max = fXaxis.GetXmax();
2125 if((ngroup <= 0) || (ngroup > nbins)) {
2126 Error(
"Rebin",
"Illegal value of ngroup=%d", ngroup);
2130 Int_t newbins = nbins / ngroup;
2133 Double_t entries = fEntries;
2134 auto* oldBins =
new Double_t[(nbins + 2) * (nbins + 3) * (nbins + 4) / 6];
2135 for(Int_t xbin = 0; xbin < nbins + 2; xbin++) {
2136 for(Int_t ybin = 0; ybin <= xbin; ybin++) {
2137 for(Int_t zbin = 0; zbin <= ybin; zbin++) {
2138 Int_t bin =
GetBin(xbin, ybin, zbin);
2139 oldBins[bin] = GetBinContent(bin);
2143 Double_t* oldErrors =
nullptr;
2144 if(fSumw2.fN != 0) {
2145 oldErrors =
new Double_t[(nbins + 2) * (nbins + 3) * (nbins + 4) / 6];
2146 for(Int_t xbin = 0; xbin < nbins + 2; xbin++) {
2147 for(Int_t ybin = 0; ybin <= xbin; ybin++) {
2148 for(Int_t zbin = 0; zbin <= ybin; zbin++) {
2149 Int_t bin =
GetBin(xbin, ybin, zbin);
2150 oldErrors[bin] = GetBinError(bin);
2158 if(newname !=
nullptr && (strlen(newname) != 0u)) {
2159 hnew =
static_cast<GCube*
>(Clone());
2160 hnew->SetName(newname);
2164 std::array<Double_t, kNstat> stat;
2167 bool resetStat =
false;
2170 if(newbins * ngroup != nbins) {
2171 max = fXaxis.GetBinUpEdge(newbins * ngroup);
2175 Int_t nXdivisions = fXaxis.GetNdivisions();
2176 Color_t xAxisColor = fXaxis.GetAxisColor();
2177 Color_t xLabelColor = fXaxis.GetLabelColor();
2178 Style_t xLabelFont = fXaxis.GetLabelFont();
2179 Float_t xLabelOffset = fXaxis.GetLabelOffset();
2180 Float_t xLabelSize = fXaxis.GetLabelSize();
2181 Float_t xTickLength = fXaxis.GetTickLength();
2182 Float_t xTitleOffset = fXaxis.GetTitleOffset();
2183 Float_t xTitleSize = fXaxis.GetTitleSize();
2184 Color_t xTitleColor = fXaxis.GetTitleColor();
2185 Style_t xTitleFont = fXaxis.GetTitleFont();
2187 Int_t nYdivisions = fYaxis.GetNdivisions();
2188 Color_t yAxisColor = fYaxis.GetAxisColor();
2189 Color_t yLabelColor = fYaxis.GetLabelColor();
2190 Style_t yLabelFont = fYaxis.GetLabelFont();
2191 Float_t yLabelOffset = fYaxis.GetLabelOffset();
2192 Float_t yLabelSize = fYaxis.GetLabelSize();
2193 Float_t yTickLength = fYaxis.GetTickLength();
2194 Float_t yTitleOffset = fYaxis.GetTitleOffset();
2195 Float_t yTitleSize = fYaxis.GetTitleSize();
2196 Color_t yTitleColor = fYaxis.GetTitleColor();
2197 Style_t yTitleFont = fYaxis.GetTitleFont();
2199 Int_t nZdivisions = fZaxis.GetNdivisions();
2200 Color_t zAxisColor = fZaxis.GetAxisColor();
2201 Color_t zLabelColor = fZaxis.GetLabelColor();
2202 Style_t zLabelFont = fZaxis.GetLabelFont();
2203 Float_t zLabelOffset = fZaxis.GetLabelOffset();
2204 Float_t zLabelSize = fZaxis.GetLabelSize();
2205 Float_t zTickLength = fZaxis.GetTickLength();
2206 Float_t zTitleOffset = fZaxis.GetTitleOffset();
2207 Float_t zTitleSize = fZaxis.GetTitleSize();
2208 Color_t zTitleColor = fZaxis.GetTitleColor();
2209 Style_t zTitleFont = fZaxis.GetTitleFont();
2213 if(fXaxis.GetXbins()->GetSize() > 0 || fYaxis.GetXbins()->GetSize() > 0 || fZaxis.GetXbins()->GetSize() > 0) {
2215 auto* bins =
new Double_t[newbins + 1];
2216 for(Int_t i = 0; i <= newbins; ++i) {
2217 bins[i] = fXaxis.GetBinLowEdge(1 + i * ngroup);
2219 hnew->SetBins(newbins, bins, newbins, bins);
2222 hnew->SetBins(newbins, min, max, newbins, min, max);
2228 for(Int_t xbin = 1; xbin <= newbins; ++xbin) {
2230 for(Int_t ybin = 1; ybin <= xbin; ++ybin) {
2231 Double_t binContent = 0;
2232 Double_t binError = 0;
2233 for(Int_t i = 0; i < ngroup; ++i) {
2234 if(oldxbin + i > nbins) {
2237 for(Int_t j = 0; j < ngroup; ++j) {
2238 if(oldybin + j > nbins) {
2242 if(oldybin + j <= oldxbin + i) {
2243 bin = oldxbin + i + (oldybin + j) * (2 * fXaxis.GetNbins() - (oldybin + j) + 3) / 2;
2245 bin = oldybin + j + (oldxbin + i) * (2 * fXaxis.GetNbins() - (oldxbin + i) + 3) / 2;
2247 binContent += oldBins[bin];
2248 if(oldErrors !=
nullptr) {
2249 binError += oldErrors[bin] * oldErrors[bin];
2253 hnew->SetBinContent(xbin, ybin, binContent);
2254 if(oldErrors !=
nullptr) {
2255 hnew->SetBinError(xbin, ybin, TMath::Sqrt(binError));
2265 hnew->SetBinContent(0, 0, oldBins[0]);
2266 if(oldErrors !=
nullptr) {
2267 hnew->SetBinError(0, 0, oldErrors[0]);
2271 Double_t binContent = 0.;
2272 Double_t binError = 0.;
2273 for(Int_t xbin = oldxbin; xbin <= nbins + 1; ++xbin) {
2274 for(Int_t ybin = oldybin; ybin <= xbin; ++ybin) {
2275 bin = xbin + ybin * (2 * nbins - ybin + 3) / 2;
2276 binContent += oldBins[bin];
2277 if(oldErrors !=
nullptr) {
2278 binError += oldErrors[bin] * oldErrors[bin];
2282 hnew->SetBinContent(newbins + 1, newbins + 1, binContent);
2283 if(oldErrors !=
nullptr) {
2284 hnew->SetBinError(newbins + 1, newbins + 1, TMath::Sqrt(binError));
2290 for(Int_t ybin = oldybin; ybin <= nbins + 1; ++ybin) {
2291 bin = ybin * (2 * nbins - ybin + 3) / 2;
2292 binContent += oldBins[bin];
2293 if(oldErrors !=
nullptr) {
2294 binError += oldErrors[bin] * oldErrors[bin];
2297 hnew->SetBinContent(0, newbins + 1, binContent);
2298 if(oldErrors !=
nullptr) {
2299 hnew->SetBinError(0, newbins + 1, TMath::Sqrt(binError));
2305 for(Int_t xbin = oldxbin; xbin <= nbins + 1; ++xbin) {
2307 binContent += oldBins[bin];
2308 if(oldErrors !=
nullptr) {
2309 binError += oldErrors[bin] * oldErrors[bin];
2312 hnew->SetBinContent(newbins + 1, 0, binContent);
2313 if(oldErrors !=
nullptr) {
2314 hnew->SetBinError(newbins + 1, 0, TMath::Sqrt(binError));
2319 for(Int_t xbin = 1; xbin <= newbins; ++xbin) {
2320 Double_t binContent0 = 0.;
2321 Double_t binContent2 = 0.;
2322 Double_t binError0 = 0.;
2323 Double_t binError2 = 0.;
2324 for(Int_t i = 0; i < ngroup; ++i) {
2325 if(oldxbin2 + i > nbins) {
2329 Int_t ufbin = oldxbin2 + i;
2330 binContent0 += oldBins[ufbin];
2331 if(oldErrors !=
nullptr) {
2332 binError0 += oldErrors[ufbin] * oldErrors[ufbin];
2334 for(Int_t ybin = oldybin; ybin <= nbins + 1; ++ybin) {
2336 Int_t ofbin = ufbin + ybin * (nbins + 2);
2337 binContent2 += oldBins[ofbin];
2338 if(oldErrors !=
nullptr) {
2339 binError2 += oldErrors[ofbin] * oldErrors[ofbin];
2343 hnew->SetBinContent(xbin, 0, binContent0);
2344 hnew->SetBinContent(xbin, newbins + 1, binContent2);
2345 if(oldErrors !=
nullptr) {
2346 hnew->SetBinError(xbin, 0, TMath::Sqrt(binError0));
2347 hnew->SetBinError(xbin, newbins + 1, TMath::Sqrt(binError2));
2354 for(Int_t ybin = 1; ybin <= newbins; ++ybin) {
2355 Double_t binContent0 = 0.;
2356 Double_t binContent2 = 0.;
2357 Double_t binError0 = 0.;
2358 Double_t binError2 = 0.;
2359 for(Int_t i = 0; i < ngroup; ++i) {
2360 if(oldybin2 + i > nbins) {
2364 Int_t ufbin = (oldybin2 + i) * (nbins + 2);
2365 binContent0 += oldBins[ufbin];
2366 if(oldErrors !=
nullptr) {
2367 binError0 += oldErrors[ufbin] * oldErrors[ufbin];
2369 for(Int_t xbin = oldxbin; xbin <= nbins + 1; ++xbin) {
2370 Int_t ofbin = ufbin + xbin;
2371 binContent2 += oldBins[ofbin];
2372 if(oldErrors !=
nullptr) {
2373 binError2 += oldErrors[ofbin] * oldErrors[ofbin];
2377 hnew->SetBinContent(0, ybin, binContent0);
2378 hnew->SetBinContent(newbins + 1, ybin, binContent2);
2379 if(oldErrors !=
nullptr) {
2380 hnew->SetBinError(0, ybin, TMath::Sqrt(binError0));
2381 hnew->SetBinError(newbins + 1, ybin, TMath::Sqrt(binError2));
2388 fXaxis.SetNdivisions(nXdivisions);
2389 fXaxis.SetAxisColor(xAxisColor);
2390 fXaxis.SetLabelColor(xLabelColor);
2391 fXaxis.SetLabelFont(xLabelFont);
2392 fXaxis.SetLabelOffset(xLabelOffset);
2393 fXaxis.SetLabelSize(xLabelSize);
2394 fXaxis.SetTickLength(xTickLength);
2395 fXaxis.SetTitleOffset(xTitleOffset);
2396 fXaxis.SetTitleSize(xTitleSize);
2397 fXaxis.SetTitleColor(xTitleColor);
2398 fXaxis.SetTitleFont(xTitleFont);
2400 fYaxis.SetNdivisions(nYdivisions);
2401 fYaxis.SetAxisColor(yAxisColor);
2402 fYaxis.SetLabelColor(yLabelColor);
2403 fYaxis.SetLabelFont(yLabelFont);
2404 fYaxis.SetLabelOffset(yLabelOffset);
2405 fYaxis.SetLabelSize(yLabelSize);
2406 fYaxis.SetTickLength(yTickLength);
2407 fYaxis.SetTitleOffset(yTitleOffset);
2408 fYaxis.SetTitleSize(yTitleSize);
2409 fYaxis.SetTitleColor(yTitleColor);
2410 fYaxis.SetTitleFont(yTitleFont);
2412 fZaxis.SetNdivisions(nZdivisions);
2413 fZaxis.SetAxisColor(zAxisColor);
2414 fZaxis.SetLabelColor(zLabelColor);
2415 fZaxis.SetLabelFont(zLabelFont);
2416 fZaxis.SetLabelOffset(zLabelOffset);
2417 fZaxis.SetLabelSize(zLabelSize);
2418 fZaxis.SetTickLength(zTickLength);
2419 fZaxis.SetTitleOffset(zTitleOffset);
2420 fZaxis.SetTitleSize(zTitleSize);
2421 fZaxis.SetTitleColor(zTitleColor);
2422 fZaxis.SetTitleFont(zTitleFont);
2425 hnew->SetEntries(entries);
2532 std::array<std::array<Double_t, 5>, 5> k5a = {{{0, 0, 1, 0, 0}, {0, 2, 2, 2, 0}, {1, 2, 5, 2, 1}, {0, 2, 2, 2, 0}, {0, 0, 1, 0, 0}}};
2533 std::array<std::array<Double_t, 5>, 5> k5b = {{{0, 1, 2, 1, 0}, {1, 2, 4, 2, 1}, {2, 4, 8, 4, 2}, {1, 2, 4, 2, 1}, {0, 1, 2, 1, 0}}};
2534 std::array<std::array<Double_t, 3>, 3> k3a = {{{0, 1, 0}, {1, 2, 1}, {0, 1, 0}}};
2537 Warning(
"Smooth",
"Currently only ntimes=1 is supported");
2539 TString opt = option;
2541 Int_t ksize_x = k5a.size();
2542 Int_t ksize_y = k5a.size();
2543 Double_t* kernel = k5a.data()->data();
2544 if(opt.Contains(
"k5b")) {
2545 kernel = k5b.data()->data();
2547 if(opt.Contains(
"k3a")) {
2548 kernel = k3a.data()->data();
2549 ksize_x = k3a.size();
2550 ksize_y = k3a.size();
2554 Int_t ifirst = fXaxis.GetFirst();
2555 Int_t ilast = fXaxis.GetLast();
2556 Int_t jfirst = fYaxis.GetFirst();
2557 Int_t jlast = fYaxis.GetLast();
2560 Double_t nentries = fEntries;
2561 Int_t nx = GetNbinsX();
2562 Int_t ny = GetNbinsY();
2563 Int_t bufSize = (nx + 2) * (ny + 2);
2564 auto* buf =
new Double_t[bufSize];
2565 Double_t* ebuf =
nullptr;
2566 if(fSumw2.fN != 0) {
2567 ebuf =
new Double_t[bufSize];
2571 for(Int_t i = ifirst; i <= ilast; ++i) {
2572 for(Int_t j = jfirst; j <= jlast; ++j) {
2573 Int_t bin =
GetBin(i, j);
2574 buf[bin] = GetBinContent(bin);
2575 if(ebuf !=
nullptr) {
2576 ebuf[bin] = GetBinError(bin);
2582 Int_t x_push = (ksize_x - 1) / 2;
2583 Int_t y_push = (ksize_y - 1) / 2;
2586 for(Int_t i = ifirst; i <= ilast; ++i) {
2587 for(Int_t j = jfirst; j <= jlast; ++j) {
2588 Double_t content = 0.0;
2589 Double_t error = 0.0;
2590 Double_t norm = 0.0;
2592 for(Int_t n = 0; n < ksize_x; ++n) {
2593 for(Int_t m = 0; m < ksize_y; ++m) {
2594 Int_t xb = i + (n - x_push);
2595 Int_t yb = j + (m - y_push);
2596 if((xb >= 1) && (xb <= nx) && (yb >= 1) && (yb <= ny)) {
2597 Int_t bin =
GetBin(xb, yb);
2598 Double_t k = kernel[n * ksize_y + m];
2601 content += k * buf[bin];
2602 if(ebuf !=
nullptr) {
2603 error += k * k * ebuf[bin] * ebuf[bin];
2611 SetBinContent(i, j, content / norm);
2612 if(ebuf !=
nullptr) {
2613 error /= (norm * norm);
2614 SetBinError(i, j, sqrt(error));
2619 fEntries = nentries;