640void GHSym::FitSlices(TF1* f1, Int_t firstbin, Int_t lastbin, Int_t cut, Option_t* option, TObjArray* arr)
691 Int_t nbins = fYaxis.GetNbins();
695 if(lastbin < 0 || lastbin > nbins + 1) {
698 if(lastbin < firstbin) {
702 TString opt = option;
705 if(opt.Contains(
"g2")) {
707 opt.ReplaceAll(
"g2",
"");
709 if(opt.Contains(
"g3")) {
711 opt.ReplaceAll(
"g3",
"");
713 if(opt.Contains(
"g4")) {
715 opt.ReplaceAll(
"g4",
"");
717 if(opt.Contains(
"g5")) {
719 opt.ReplaceAll(
"g5",
"");
723 Int_t nstep = ngroup;
724 if(opt.Contains(
"s")) {
730 f1 =
static_cast<TF1*
>(gROOT->GetFunction(
"gaus"));
732 f1 =
new TF1(
"gaus",
"gaus", fXaxis.GetXmin(), fXaxis.GetXmax());
734 f1->SetRange(fXaxis.GetXmin(), fXaxis.GetXmax());
737 Int_t npar = f1->GetNpar();
741 auto* parsave =
new Double_t[npar];
742 f1->GetParameters(parsave);
746 arr->Expand(npar + 1);
750 auto** hlist =
new TH1D*[npar];
751 auto* name =
new char[2000];
752 auto* title =
new char[2000];
753 const TArrayD* bins = fYaxis.GetXbins();
754 for(Int_t ipar = 0; ipar < npar; ++ipar) {
755 snprintf(name, 2000,
"%s_%d", GetName(), ipar);
756 snprintf(title, 2000,
"Fitted value of par[%d]=%s", ipar, f1->GetParName(ipar));
757 delete gDirectory->FindObject(name);
759 hlist[ipar] =
new TH1D(name, title, nbins, fYaxis.GetXmin(), fYaxis.GetXmax());
761 hlist[ipar] =
new TH1D(name, title, nbins, bins->fArray);
763 hlist[ipar]->GetXaxis()->SetTitle(fYaxis.GetTitle());
765 (*arr)[ipar] = hlist[ipar];
768 snprintf(name, 2000,
"%s_chi2", GetName());
769 delete gDirectory->FindObject(name);
770 TH1D* hchi2 =
nullptr;
772 hchi2 =
new TH1D(name,
"chisquare", nbins, fYaxis.GetXmin(), fYaxis.GetXmax());
774 hchi2 =
new TH1D(name,
"chisquare", nbins, bins->fArray);
776 hchi2->GetXaxis()->SetTitle(fYaxis.GetTitle());
778 (*arr)[npar] = hchi2;
784 for(Int_t bin = firstbin; bin + ngroup - 1 <= lastbin; bin += nstep) {
785 TH1D* proj =
Projection(
"_temp", bin, bin + ngroup - 1,
"e");
786 if(proj ==
nullptr) {
789 auto nentries =
static_cast<Long64_t
>(proj->GetEntries());
790 if(nentries == 0 || nentries < cut) {
794 f1->SetParameters(parsave);
795 proj->Fit(f1, opt.Data());
796 Int_t npfits = f1->GetNumberFitPoints();
797 if(npfits > npar && npfits >= cut) {
798 Int_t binOn = bin + ngroup / 2;
799 for(Int_t ipar = 0; ipar < npar; ++ipar) {
800 hlist[ipar]->Fill(fYaxis.GetBinCenter(binOn), f1->GetParameter(ipar));
801 hlist[ipar]->SetBinError(binOn, f1->GetParError(ipar));
803 hchi2->Fill(fYaxis.GetBinCenter(binOn), f1->GetChisquare() / (npfits - npar));
1143 Int_t bin_x = fXaxis.FindBin(x);
1144 Int_t bin_y = fYaxis.FindBin(y);
1145 if(bin_x < 1 || bin_x > GetNbinsX() || bin_y < 1 || bin_y > GetNbinsY()) {
1146 Error(
"Interpolate",
"Cannot interpolate outside histogram domain.");
1151 dx = fXaxis.GetBinUpEdge(bin_x) - x;
1152 dy = fYaxis.GetBinUpEdge(bin_y) - y;
1153 if(dx <= fXaxis.GetBinWidth(bin_x) / 2 && dy <= fYaxis.GetBinWidth(bin_y) / 2) {
1156 if(dx > fXaxis.GetBinWidth(bin_x) / 2 && dy <= fYaxis.GetBinWidth(bin_y) / 2) {
1159 if(dx > fXaxis.GetBinWidth(bin_x) / 2 && dy > fYaxis.GetBinWidth(bin_y) / 2) {
1162 if(dx <= fXaxis.GetBinWidth(bin_x) / 2 && dy > fYaxis.GetBinWidth(bin_y) / 2) {
1167 x1 = fXaxis.GetBinCenter(bin_x);
1168 y1 = fYaxis.GetBinCenter(bin_y);
1169 x2 = fXaxis.GetBinCenter(bin_x + 1);
1170 y2 = fYaxis.GetBinCenter(bin_y + 1);
1173 x1 = fXaxis.GetBinCenter(bin_x - 1);
1174 y1 = fYaxis.GetBinCenter(bin_y);
1175 x2 = fXaxis.GetBinCenter(bin_x);
1176 y2 = fYaxis.GetBinCenter(bin_y + 1);
1179 x1 = fXaxis.GetBinCenter(bin_x - 1);
1180 y1 = fYaxis.GetBinCenter(bin_y - 1);
1181 x2 = fXaxis.GetBinCenter(bin_x);
1182 y2 = fYaxis.GetBinCenter(bin_y);
1185 x1 = fXaxis.GetBinCenter(bin_x);
1186 y1 = fYaxis.GetBinCenter(bin_y - 1);
1187 x2 = fXaxis.GetBinCenter(bin_x + 1);
1188 y2 = fYaxis.GetBinCenter(bin_y);
1191 Int_t bin_x1 = fXaxis.FindBin(x1);
1195 Int_t bin_x2 = fXaxis.FindBin(x2);
1196 if(bin_x2 > GetNbinsX()) {
1197 bin_x2 = GetNbinsX();
1199 Int_t bin_y1 = fYaxis.FindBin(y1);
1203 Int_t bin_y2 = fYaxis.FindBin(y2);
1204 if(bin_y2 > GetNbinsY()) {
1205 bin_y2 = GetNbinsY();
1207 Int_t bin_q22 = GetBin(bin_x2, bin_y2);
1208 Int_t bin_q12 = GetBin(bin_x1, bin_y2);
1209 Int_t bin_q11 = GetBin(bin_x1, bin_y1);
1210 Int_t bin_q21 = GetBin(bin_x2, bin_y1);
1211 Double_t q11 = GetBinContent(bin_q11);
1212 Double_t q12 = GetBinContent(bin_q12);
1213 Double_t q21 = GetBinContent(bin_q21);
1214 Double_t q22 = GetBinContent(bin_q22);
1215 Double_t d = 1.0 * (x2 - x1) * (y2 - y1);
1216 f = 1.0 * q11 / d * (x2 - x) * (y2 - y) + 1.0 * q21 / d * (x - x1) * (y2 - y) + 1.0 * q12 / d * (x2 - x) * (y - y1) +
1217 1.0 * q22 / d * (x - x1) * (y - y1);
1256 TString opt = option;
1260 TH1* h1 =
const_cast<TH1*
>(
static_cast<const TH1*
>(
this));
1264 TAxis* xaxis1 = h1->GetXaxis();
1265 auto* xaxis2 =
const_cast<TAxis*
>(h2->GetXaxis());
1266 TAxis* yaxis1 = h1->GetYaxis();
1267 auto* yaxis2 =
const_cast<TAxis*
>(h2->GetYaxis());
1268 Int_t ncx1 = xaxis1->GetNbins();
1269 Int_t ncx2 = xaxis2->GetNbins();
1270 Int_t ncy1 = yaxis1->GetNbins();
1271 Int_t ncy2 = yaxis2->GetNbins();
1274 if(h1->GetDimension() != 2 || h2->GetDimension() != 2) {
1275 Error(
"KolmogorovTest",
"Histograms must be 2-D\n");
1281 Error(
"KolmogorovTest",
"Number of channels in X is different, %d and %d\n", ncx1, ncx2);
1285 Error(
"KolmogorovTest",
"Number of channels in Y is different, %d and %d\n", ncy1, ncy2);
1290 Bool_t afunc1 = kFALSE;
1291 Bool_t afunc2 = kFALSE;
1292 Double_t difprec = 1e-5;
1293 Double_t diff1 = TMath::Abs(xaxis1->GetXmin() - xaxis2->GetXmin());
1294 Double_t diff2 = TMath::Abs(xaxis1->GetXmax() - xaxis2->GetXmax());
1295 if(diff1 > difprec || diff2 > difprec) {
1296 Error(
"KolmogorovTest",
"histograms with different binning along X");
1299 diff1 = TMath::Abs(yaxis1->GetXmin() - yaxis2->GetXmin());
1300 diff2 = TMath::Abs(yaxis1->GetXmax() - yaxis2->GetXmax());
1301 if(diff1 > difprec || diff2 > difprec) {
1302 Error(
"KolmogorovTest",
"histograms with different binning along Y");
1311 if(opt.Contains(
"U")) {
1315 if(opt.Contains(
"O")) {
1324 for(Int_t i = ibeg; i <= iend; ++i) {
1325 for(Int_t j = jbeg; j <= jend; ++j) {
1326 sum1 += h1->GetBinContent(i, j);
1327 sum2 += h2->GetBinContent(i, j);
1328 Double_t ew1 = h1->GetBinError(i, j);
1329 Double_t ew2 = h2->GetBinError(i, j);
1337 Error(
"KolmogorovTest",
"Integral is zero for h1=%s\n", h1->GetName());
1341 Error(
"KolmogorovTest",
"Integral is zero for h2=%s\n", h2->GetName());
1347 Double_t esum1 = 0.;
1348 Double_t esum2 = 0.;
1350 esum1 = sum1 * sum1 / w1;
1356 esum2 = sum2 * sum2 / w2;
1361 if(afunc2 && afunc1) {
1362 Error(
"KolmogorovTest",
"Errors are zero for both histograms\n");
1367 Double_t s1 = 1 / sum1;
1368 Double_t s2 = 1 / sum2;
1369 Double_t dfmax1 = 0;
1370 Double_t rsum1 = 0.;
1371 Double_t rsum2 = 0.;
1372 for(Int_t i = ibeg; i <= iend; ++i) {
1373 for(Int_t j = jbeg; j <= jend; ++j) {
1374 rsum1 += s1 * h1->GetCellContent(i, j);
1375 rsum2 += s2 * h2->GetCellContent(i, j);
1376 dfmax1 = TMath::Max(dfmax1, TMath::Abs(rsum1 - rsum2));
1381 Double_t dfmax2 = 0;
1384 for(Int_t j = jbeg; j <= jend; ++j) {
1385 for(Int_t i = ibeg; i <= iend; ++i) {
1386 rsum1 += s1 * h1->GetCellContent(i, j);
1387 rsum2 += s2 * h2->GetCellContent(i, j);
1388 dfmax2 = TMath::Max(dfmax2, TMath::Abs(rsum1 - rsum2));
1393 Double_t factnm = 0.;
1395 factnm = TMath::Sqrt(esum2);
1397 factnm = TMath::Sqrt(esum1);
1399 factnm = TMath::Sqrt(esum1 * sum2 / (esum1 + esum2));
1403 Double_t dfmax = 0.5 * (dfmax1 + dfmax2);
1404 Double_t z = dfmax * factnm;
1406 prb = TMath::KolmogorovProb(z);
1411 if(opt.Contains(
"N") && !(afunc1 || afunc2)) {
1414 Double_t d12 = esum1 - esum2;
1415 Double_t chi2 = d12 * d12 / (esum1 + esum2);
1416 prb2 = TMath::Prob(chi2, 1);
1418 if(prb > 0 && prb2 > 0) {
1419 prb = prb * prb2 * (1 - TMath::Log(prb * prb2));
1425 if(opt.Contains(
"D")) {
1426 std::cout <<
" Kolmo Prob h1 = " << h1->GetName() <<
", sum1 = " << sum1 << std::endl;
1427 std::cout <<
" Kolmo Prob h2 = " << h2->GetName() <<
", sum2 = " << sum2 << std::endl;
1428 std::cout <<
" Kolmo Probabil = " << prb <<
", Max dist = " << dfmax << std::endl;
1429 if(opt.Contains(
"N")) {
1430 std::cout <<
" Kolmo Probabil = " << prb1 <<
" for shape alone, " << prb2 <<
" for normalisation alone" << std::endl;
1434 if(TMath::Abs(rsum1 - 1) > 0.002) {
1435 Warning(
"KolmogorovTest",
"Numerical problems with h1=%s\n", h1->GetName());
1437 if(TMath::Abs(rsum2 - 1) > 0.002) {
1438 Warning(
"KolmogorovTest",
"Numerical problems with h2=%s\n", h2->GetName());
1441 if(opt.Contains(
"M")) {
1463 if(list ==
nullptr) {
1466 if(list->IsEmpty()) {
1467 return static_cast<Long64_t
>(GetEntries());
1471 inlist.AddAll(list);
1475 Bool_t initialLimitsFound = kFALSE;
1476 Bool_t allSameLimits = kTRUE;
1477 Bool_t sameLimitsX = kTRUE;
1478 Bool_t sameLimitsY = kTRUE;
1479 Bool_t allHaveLimits = kTRUE;
1480 Bool_t firstHistWithLimits = kTRUE;
1482 TIter next(&inlist);
1485 Bool_t hasLimits = h->GetXaxis()->GetXmin() < h->GetXaxis()->GetXmax();
1486 allHaveLimits = allHaveLimits && hasLimits;
1493 if(firstHistWithLimits) {
1496 if(!SameLimitsAndNBins(fXaxis, *(h->GetXaxis()))) {
1497 if(h->GetXaxis()->GetXbins()->GetSize() != 0) {
1498 fXaxis.Set(h->GetXaxis()->GetNbins(), h->GetXaxis()->GetXbins()->GetArray());
1500 fXaxis.Set(h->GetXaxis()->GetNbins(), h->GetXaxis()->GetXmin(), h->GetXaxis()->GetXmax());
1503 if(!SameLimitsAndNBins(fYaxis, *(h->GetYaxis()))) {
1504 if(h->GetYaxis()->GetXbins()->GetSize() != 0) {
1505 fYaxis.Set(h->GetYaxis()->GetNbins(), h->GetYaxis()->GetXbins()->GetArray());
1507 fYaxis.Set(h->GetYaxis()->GetNbins(), h->GetYaxis()->GetXmin(), h->GetYaxis()->GetXmax());
1511 firstHistWithLimits = kFALSE;
1514 if(!initialLimitsFound) {
1517 initialLimitsFound = kTRUE;
1518 if(h->GetXaxis()->GetXbins()->GetSize() != 0) {
1519 newXAxis.Set(h->GetXaxis()->GetNbins(), h->GetXaxis()->GetXbins()->GetArray());
1521 newXAxis.Set(h->GetXaxis()->GetNbins(), h->GetXaxis()->GetXmin(), h->GetXaxis()->GetXmax());
1523 if(h->GetYaxis()->GetXbins()->GetSize() != 0) {
1524 newYAxis.Set(h->GetYaxis()->GetNbins(), h->GetYaxis()->GetXbins()->GetArray());
1526 newYAxis.Set(h->GetYaxis()->GetNbins(), h->GetYaxis()->GetXmin(), h->GetYaxis()->GetXmax());
1530 if(!SameLimitsAndNBins(newXAxis, *(h->GetXaxis()))) {
1531 sameLimitsX = kFALSE;
1535 if(!RecomputeAxisLimits(newXAxis, *(h->GetXaxis()))) {
1536 Error(
"Merge",
"Cannot merge histograms - limits are inconsistent:\n "
1537 "first: (%d, %f, %f), second: (%d, %f, %f)",
1538 newXAxis.GetNbins(), newXAxis.GetXmin(), newXAxis.GetXmax(), h->GetXaxis()->GetNbins(),
1539 h->GetXaxis()->GetXmin(), h->GetXaxis()->GetXmax());
1545 if(!SameLimitsAndNBins(newYAxis, *(h->GetYaxis()))) {
1546 sameLimitsY = kFALSE;
1550 if(!RecomputeAxisLimits(newYAxis, *(h->GetYaxis()))) {
1551 Error(
"Merge",
"Cannot merge histograms - limits are inconsistent:\n "
1552 "first: (%d, %f, %f), second: (%d, %f, %f)",
1553 newYAxis.GetNbins(), newYAxis.GetXmin(), newYAxis.GetXmax(), h->GetYaxis()->GetNbins(),
1554 h->GetYaxis()->GetXmin(), h->GetYaxis()->GetXmax());
1558 allSameLimits = sameLimitsY && sameLimitsX;
1561 }
while((h =
static_cast<GHSym*
>(next())) !=
nullptr);
1562 if(h ==
nullptr && ((*next) !=
nullptr)) {
1563 Error(
"Merge",
"Attempt to merge object of class: %s to a %s", (*next)->ClassName(), ClassName());
1572 TH2* hclone =
nullptr;
1573 if(!allSameLimits) {
1576 Bool_t mustCleanup = TestBit(kMustCleanup);
1578 ResetBit(kMustCleanup);
1580 hclone =
static_cast<TH2*
>(IsA()->New());
1581 hclone->SetDirectory(
nullptr);
1584 SetBit(kMustCleanup);
1589 inlist.AddFirst(hclone);
1592 if(!allSameLimits && initialLimitsFound) {
1594 fXaxis.SetRange(0, 0);
1595 if(newXAxis.GetXbins()->GetSize() != 0) {
1596 fXaxis.Set(newXAxis.GetNbins(), newXAxis.GetXbins()->GetArray());
1598 fXaxis.Set(newXAxis.GetNbins(), newXAxis.GetXmin(), newXAxis.GetXmax());
1602 fYaxis.SetRange(0, 0);
1603 if(newYAxis.GetXbins()->GetSize() != 0) {
1604 fYaxis.Set(newYAxis.GetNbins(), newYAxis.GetXbins()->GetArray());
1606 fYaxis.Set(newYAxis.GetNbins(), newYAxis.GetXmin(), newYAxis.GetXmax());
1609 fZaxis.Set(1, 0, 1);
1610 fNcells = (fXaxis.GetNbins() + 2) * (fYaxis.GetNbins() + 2);
1611 SetBinsLength(fNcells);
1612 if(fSumw2.fN != 0) {
1613 fSumw2.Set(fNcells);
1617 if(!allHaveLimits) {
1619 while((h =
static_cast<GHSym*
>(next())) !=
nullptr) {
1620 if(h->GetXaxis()->GetXmin() >= h->GetXaxis()->GetXmax() && (h->fBuffer !=
nullptr)) {
1622 auto nbentries =
static_cast<Int_t
>(h->fBuffer[0]);
1623 for(Int_t i = 0; i < nbentries; i++) {
1624 Fill(h->fBuffer[3 * i + 2], h->fBuffer[3 * i + 3], h->fBuffer[3 * i + 1]);
1630 if(!initialLimitsFound) {
1631 if(hclone !=
nullptr) {
1632 inlist.Remove(hclone);
1635 return static_cast<Long64_t
>(GetEntries());
1641 std::array<Double_t, kNstat> stats;
1642 std::array<Double_t, kNstat> totstats;
1643 for(Int_t i = 0; i < kNstat; ++i) {
1644 totstats[i] = stats[i] = 0;
1647 Double_t nentries = GetEntries();
1651 Bool_t canExtend = CanExtendAllAxes();
1652 SetCanExtend(TH1::kNoAxis);
1654 while((h =
static_cast<GHSym*
>(next())) !=
nullptr) {
1656 Double_t histEntries = h->GetEntries();
1657 if(h->fTsumw == 0 && histEntries == 0) {
1662 if(h->GetXaxis()->GetXmin() < h->GetXaxis()->GetXmax()) {
1665 for(Int_t i = 0; i < kNstat; ++i) {
1666 totstats[i] += stats[i];
1668 nentries += histEntries;
1670 Int_t nx = h->GetXaxis()->GetNbins();
1671 Int_t ny = h->GetYaxis()->GetNbins();
1673 for(Int_t biny = 0; biny <= ny + 1; ++biny) {
1674 if(!allSameLimits) {
1675 iy = fYaxis.FindBin(h->GetYaxis()->GetBinCenter(biny));
1679 for(Int_t binx = 0; binx <= nx + 1; ++binx) {
1680 cu = h->GetBinContent(binx, biny);
1681 if(!allSameLimits) {
1682 if(cu != 0 && ((!sameLimitsX && (binx == 0 || binx == nx + 1)) ||
1683 (!sameLimitsY && (biny == 0 || biny == ny + 1)))) {
1684 Error(
"Merge",
"Cannot merge histograms - the histograms have"
1685 " different limits and undeflows/overflows are present."
1686 " The initial histogram is now broken!");
1689 ix = fXaxis.FindBin(h->GetXaxis()->GetBinCenter(binx));
1694 Int_t ibin =
GetBin(ix, iy);
1699 AddBinContent(ibin, cu);
1700 if(fSumw2.fN != 0) {
1701 Double_t error1 = h->GetBinError(
GetBin(binx, biny));
1702 fSumw2.fArray[ibin] += error1 * error1;
1708 SetCanExtend(
static_cast<UInt_t
>(canExtend));
1712 SetEntries(nentries);
1713 if(hclone !=
nullptr) {
1714 inlist.Remove(hclone);
1717 return static_cast<Long64_t
>(nentries);
1720TProfile*
GHSym::Profile(
const char* name, Int_t firstbin, Int_t lastbin, Option_t* option)
const
1760 TString opt = option;
1763 Int_t i1 = opt.Index(
"[");
1765 Int_t i2 = opt.Index(
"]");
1766 cut = opt(i1, i2 - i1 + 1);
1769 bool originalRange = opt.Contains(
"o");
1771 Int_t inN = fYaxis.GetNbins();
1772 const char* expectedName =
"_pf";
1774 Int_t firstOutBin = fXaxis.GetFirst();
1775 Int_t lastOutBin = fXaxis.GetLast();
1776 if(firstOutBin == 0 && lastOutBin == 0) {
1778 lastOutBin = fXaxis.GetNbins();
1781 if(lastbin < firstbin && fYaxis.TestBit(TAxis::kAxisRange)) {
1782 firstbin = fYaxis.GetFirst();
1783 lastbin = fYaxis.GetLast();
1787 if(firstbin == 0 && lastbin == 0) {
1789 lastbin = fYaxis.GetNbins();
1798 if(lastbin > inN + 1) {
1803 char* pname =
const_cast<char*
>(name);
1804 if((name !=
nullptr) && strcmp(name, expectedName) == 0) {
1805 auto nch = strlen(GetName()) + 5;
1806 pname =
new char[nch];
1807 snprintf(pname, nch,
"%s%s", GetName(), name);
1809 TProfile* h1 =
nullptr;
1812 TObject* h1obj = gROOT->FindObject(pname);
1813 if((h1obj !=
nullptr) && h1obj->InheritsFrom(TH1::Class())) {
1814 if(h1obj->IsA() != TProfile::Class()) {
1815 Error(
"DoProfile",
"Histogram with name %s must be a TProfile and is a %s", name, h1obj->ClassName());
1818 h1 =
static_cast<TProfile*
>(h1obj);
1823 const TArrayD* xbins = fXaxis.GetXbins();
1824 if(xbins->fN == 0) {
1826 h1->SetBins(fXaxis.GetNbins(), fXaxis.GetXmin(), fXaxis.GetXmax());
1828 h1->SetBins(lastOutBin - firstOutBin + 1, fXaxis.GetBinLowEdge(firstOutBin),
1829 fXaxis.GetBinUpEdge(lastOutBin));
1834 h1->SetBins(fXaxis.GetNbins(), xbins->fArray);
1836 h1->SetBins(lastOutBin - firstOutBin + 1, &xbins->fArray[firstOutBin - 1]);
1842 if(opt.Contains(
"[")) {
1843 const_cast<GHSym*
>(
this)->GetPainter();
1844 if(fPainter !=
nullptr) {
1845 ncuts = fPainter->MakeCuts(
const_cast<char*
>(cut.Data()));
1850 const TArrayD* bins = fXaxis.GetXbins();
1853 h1 =
new TProfile(pname, GetTitle(), fXaxis.GetNbins(), fXaxis.GetXmin(), fXaxis.GetXmax(), opt);
1855 h1 =
new TProfile(pname, GetTitle(), lastOutBin - firstOutBin + 1, fXaxis.GetBinLowEdge(firstOutBin),
1856 fXaxis.GetBinUpEdge(lastOutBin), opt);
1861 h1 =
new TProfile(pname, GetTitle(), fXaxis.GetNbins(), bins->fArray, opt);
1863 h1 =
new TProfile(pname, GetTitle(), lastOutBin - firstOutBin + 1, &bins->fArray[firstOutBin - 1], opt);
1872 h1->GetXaxis()->ImportAttributes(&fXaxis);
1873 h1->SetLineColor(GetLineColor());
1874 h1->SetFillColor(GetFillColor());
1875 h1->SetMarkerColor(GetMarkerColor());
1876 h1->SetMarkerStyle(GetMarkerStyle());
1880 bool useWeights = (GetSumw2N() > 0);
1887 TArrayD& binSumw2 = *(h1->GetBinSumw2());
1892 for(Int_t outbin = 0; outbin <= fXaxis.GetNbins() + 1; ++outbin) {
1893 if(fXaxis.TestBit(TAxis::kAxisRange) && (outbin < firstOutBin || outbin > lastOutBin)) {
1898 Double_t xOut = fXaxis.GetBinCenter(outbin);
1899 Int_t binOut = h1->GetXaxis()->FindBin(xOut);
1904 for(Int_t inbin = firstbin; inbin <= lastbin; ++inbin) {
1905 Int_t binx = outbin;
1909 if(!fPainter->IsInside(binx, biny)) {
1913 Int_t bin =
GetBin(binx, biny);
1914 Double_t cxy = GetBinContent(bin);
1920 tmp = binSumw2.fArray[binOut];
1922 h1->Fill(xOut, fYaxis.GetBinCenter(inbin), cxy);
1924 binSumw2.fArray[binOut] = tmp + fSumw2.fArray[bin];
1936 h1->SetEntries(h1->GetEffectiveEntries());
1938 if(opt.Contains(
"d")) {
1939 TVirtualPad* padsav = gPad;
1940 TVirtualPad* pad = gROOT->GetSelectedPad();
1941 if(pad !=
nullptr) {
1944 opt.Remove(opt.First(
"d"), 1);
1945 if(!gPad || !gPad->FindObject(h1)) {
1950 if(padsav !=
nullptr) {
1961 const char* expectedName =
"_pr";
1963 TString opt = option;
1965 Int_t i1 = opt.Index(
"[");
1967 Int_t i2 = opt.Index(
"]");
1968 cut = opt(i1, i2 - i1 + 1);
1971 bool originalRange = opt.Contains(
"o");
1973 Int_t firstXBin = fXaxis.GetFirst();
1974 Int_t lastXBin = fXaxis.GetLast();
1976 if(firstXBin == 0 && lastXBin == 0) {
1978 lastXBin = fXaxis.GetNbins();
1981 if(lastBin < firstBin && fYaxis.TestBit(TAxis::kAxisRange)) {
1982 firstBin = fYaxis.GetFirst();
1983 lastBin = fYaxis.GetLast();
1987 if(firstBin == 0 && lastBin == 0) {
1989 lastBin = fYaxis.GetNbins();
1996 lastBin = fYaxis.GetLast() + 1;
1998 if(lastBin > fYaxis.GetLast() + 1) {
1999 lastBin = fYaxis.GetLast() + 1;
2003 char* pname =
const_cast<char*
>(name);
2004 if(name !=
nullptr && strcmp(name, expectedName) == 0) {
2005 auto nch = strlen(GetName()) + 4;
2006 pname =
new char[nch];
2007 snprintf(pname, nch,
"%s%s", GetName(), name);
2013 TObject* h1obj = gROOT->FindObject(pname);
2014 if((h1obj !=
nullptr) && h1obj->InheritsFrom(TH1::Class())) {
2015 if(h1obj->IsA() != TH1D::Class()) {
2016 Error(
"DoProjection",
"Histogram with name %s must be a TH1D and is a %s", name, h1obj->ClassName());
2019 h1 =
static_cast<TH1D*
>(h1obj);
2024 const TArrayD* xbins = fXaxis.GetXbins();
2025 if(xbins->fN == 0) {
2027 h1->SetBins(fXaxis.GetNbins(), fXaxis.GetXmin(), fXaxis.GetXmax());
2029 h1->SetBins(lastXBin - firstXBin + 1, fXaxis.GetBinLowEdge(firstXBin), fXaxis.GetBinUpEdge(lastXBin));
2034 h1->SetBins(fXaxis.GetNbins(), xbins->fArray);
2036 h1->SetBins(lastXBin - firstXBin + 1, &(xbins->fArray[firstXBin - 1]));
2041 if(opt.Contains(
"[")) {
2042 const_cast<GHSym*
>(
this)->GetPainter();
2043 if(fPainter !=
nullptr) {
2044 ncuts = fPainter->MakeCuts(
const_cast<char*
>(cut.Data()));
2049 const TArrayD* bins = fXaxis.GetXbins();
2052 h1 =
new TH1D(pname, GetTitle(), fXaxis.GetNbins(), fXaxis.GetXmin(), fXaxis.GetXmax());
2054 h1 =
new TH1D(pname, GetTitle(), lastXBin - firstXBin + 1, fXaxis.GetBinLowEdge(firstXBin),
2055 fXaxis.GetBinUpEdge(lastXBin));
2060 h1 =
new TH1D(pname, GetTitle(), fXaxis.GetNbins(), bins->fArray);
2062 h1 =
new TH1D(pname, GetTitle(), lastXBin - firstXBin + 1, &(bins->fArray[firstXBin - 1]));
2065 if(opt.Contains(
"e") || (GetSumw2N() != 0)) {
2074 h1->GetXaxis()->ImportAttributes(&fXaxis);
2075 THashList* labels =
const_cast<TAxis*
>(&fXaxis)->GetLabels();
2076 if(labels !=
nullptr) {
2078 TObjString* lb =
nullptr;
2080 while((lb =
static_cast<TObjString*
>(iL())) !=
nullptr) {
2081 h1->GetXaxis()->SetBinLabel(i, lb->String().Data());
2086 h1->SetLineColor(GetLineColor());
2087 h1->SetFillColor(GetFillColor());
2088 h1->SetMarkerColor(GetMarkerColor());
2089 h1->SetMarkerStyle(GetMarkerStyle());
2092 Double_t totcont = 0;
2093 Bool_t computeErrors = h1->GetSumw2N() != 0;
2098 for(Int_t xbin = 0; xbin <= fXaxis.GetNbins() + 1; ++xbin) {
2101 if(fXaxis.TestBit(TAxis::kAxisRange) && (xbin < firstXBin || xbin > lastXBin)) {
2105 for(Int_t ybin = firstBin; ybin <= lastBin; ++ybin) {
2107 if(!fPainter->IsInside(xbin, ybin)) {
2119 Int_t binOut = h1->GetXaxis()->FindBin(fXaxis.GetBinCenter(xbin));
2120 h1->SetBinContent(binOut, cont);
2122 h1->SetBinError(binOut, TMath::Sqrt(err2));
2129 bool reuseStats =
false;
2130 if((!fgStatOverflows && firstBin == 1 && lastBin == fYaxis.GetLast()) ||
2131 (fgStatOverflows && firstBin == 0 && lastBin == fYaxis.GetLast() + 1)) {
2135 double eps = 1.E-12;
2136 if(IsA() == GHSymF::Class()) {
2139 if(fTsumw != 0 && TMath::Abs(fTsumw - totcont) < TMath::Abs(fTsumw) * eps) {
2147 bool reuseEntries = reuseStats;
2149 reuseEntries &=
static_cast<int>(firstBin == 0 && lastBin == fYaxis.GetLast() + 1);
2151 std::array<Double_t, kNstat> stats;
2153 h1->PutStats(stats.data());
2158 h1->SetEntries(h1->GetEffectiveEntries());
2161 h1->SetEntries(fEntries);
2167 Double_t entries = TMath::Floor(totcont + 0.5);
2168 if(h1->GetSumw2N() != 0) {
2169 entries = h1->GetEffectiveEntries();
2171 h1->SetEntries(entries);
2174 if(opt.Contains(
"d")) {
2175 TVirtualPad* padsav = gPad;
2176 TVirtualPad* pad = gROOT->GetSelectedPad();
2177 if(pad !=
nullptr) {
2180 opt.Remove(opt.First(
"d"), 1);
2182 if(opt.Contains(
"e")) {
2183 opt.Remove(opt.First(
"e"), 1);
2185 if(!gPad || !gPad->FindObject(h1)) {
2190 if(padsav !=
nullptr) {
2232 Int_t nbins = fXaxis.GetNbins();
2233 Double_t min = fXaxis.GetXmin();
2234 Double_t max = fXaxis.GetXmax();
2235 if((ngroup <= 0) || (ngroup > nbins)) {
2236 Error(
"Rebin",
"Illegal value of ngroup=%d", ngroup);
2240 Int_t newbins = nbins / ngroup;
2243 Double_t entries = fEntries;
2244 auto* oldBins =
new Double_t[(nbins + 2) * (nbins + 3) / 2];
2245 for(Int_t xbin = 0; xbin < nbins + 2; xbin++) {
2246 for(Int_t ybin = 0; ybin <= xbin; ybin++) {
2247 Int_t bin =
GetBin(xbin, ybin);
2248 oldBins[bin] = GetBinContent(bin);
2251 Double_t* oldErrors =
nullptr;
2252 if(fSumw2.fN != 0) {
2253 oldErrors =
new Double_t[(nbins + 2) * (nbins + 3) / 2];
2254 for(Int_t xbin = 0; xbin < nbins + 2; xbin++) {
2255 for(Int_t ybin = 0; ybin <= xbin; ybin++) {
2256 Int_t bin =
GetBin(xbin, ybin);
2257 oldErrors[bin] = GetBinError(bin);
2264 if((newname !=
nullptr) && (strlen(newname) != 0u)) {
2265 hnew =
static_cast<GHSym*
>(Clone());
2266 hnew->SetName(newname);
2270 std::array<Double_t, kNstat> stats;
2272 bool resetStat =
false;
2275 if(newbins * ngroup != nbins) {
2276 max = fXaxis.GetBinUpEdge(newbins * ngroup);
2280 Int_t nXdivisions = fXaxis.GetNdivisions();
2281 Color_t xAxisColor = fXaxis.GetAxisColor();
2282 Color_t xLabelColor = fXaxis.GetLabelColor();
2283 Style_t xLabelFont = fXaxis.GetLabelFont();
2284 Float_t xLabelOffset = fXaxis.GetLabelOffset();
2285 Float_t xLabelSize = fXaxis.GetLabelSize();
2286 Float_t xTickLength = fXaxis.GetTickLength();
2287 Float_t xTitleOffset = fXaxis.GetTitleOffset();
2288 Float_t xTitleSize = fXaxis.GetTitleSize();
2289 Color_t xTitleColor = fXaxis.GetTitleColor();
2290 Style_t xTitleFont = fXaxis.GetTitleFont();
2292 Int_t nYdivisions = fYaxis.GetNdivisions();
2293 Color_t yAxisColor = fYaxis.GetAxisColor();
2294 Color_t yLabelColor = fYaxis.GetLabelColor();
2295 Style_t yLabelFont = fYaxis.GetLabelFont();
2296 Float_t yLabelOffset = fYaxis.GetLabelOffset();
2297 Float_t yLabelSize = fYaxis.GetLabelSize();
2298 Float_t yTickLength = fYaxis.GetTickLength();
2299 Float_t yTitleOffset = fYaxis.GetTitleOffset();
2300 Float_t yTitleSize = fYaxis.GetTitleSize();
2301 Color_t yTitleColor = fYaxis.GetTitleColor();
2302 Style_t yTitleFont = fYaxis.GetTitleFont();
2306 if(fXaxis.GetXbins()->GetSize() > 0 || fYaxis.GetXbins()->GetSize() > 0) {
2308 auto* bins =
new Double_t[newbins + 1];
2309 for(Int_t i = 0; i <= newbins; ++i) {
2310 bins[i] = fXaxis.GetBinLowEdge(1 + i * ngroup);
2312 hnew->SetBins(newbins, bins, newbins, bins);
2315 hnew->SetBins(newbins, min, max, newbins, min, max);
2320 for(Int_t xbin = 1; xbin <= newbins; ++xbin) {
2322 for(Int_t ybin = 1; ybin <= xbin; ++ybin) {
2323 Double_t binContent = 0.;
2324 Double_t binError = 0.;
2325 for(Int_t i = 0; i < ngroup; ++i) {
2326 if(oldxbin + i > nbins) {
2329 for(Int_t j = 0; j < ngroup; ++j) {
2330 if(oldybin + j > nbins) {
2335 if(oldybin + j <= oldxbin + i) {
2336 bin = oldxbin + i + (oldybin + j) * (2 * fXaxis.GetNbins() - (oldybin + j) + 3) / 2;
2338 bin = oldybin + j + (oldxbin + i) * (2 * fXaxis.GetNbins() - (oldxbin + i) + 3) / 2;
2340 binContent += oldBins[bin];
2341 if(oldErrors !=
nullptr) {
2342 binError += oldErrors[bin] * oldErrors[bin];
2346 hnew->SetBinContent(xbin, ybin, binContent);
2347 if(oldErrors !=
nullptr) {
2348 hnew->SetBinError(xbin, ybin, TMath::Sqrt(binError));
2358 hnew->SetBinContent(0, 0, oldBins[0]);
2359 if(oldErrors !=
nullptr) {
2360 hnew->SetBinError(0, 0, oldErrors[0]);
2364 Double_t binContent = 0.;
2365 Double_t binError = 0.;
2366 for(Int_t xbin = oldxbin; xbin <= nbins + 1; ++xbin) {
2367 for(Int_t ybin = oldybin; ybin <= xbin; ++ybin) {
2368 Int_t bin = xbin + ybin * (2 * nbins - ybin + 3) / 2;
2369 binContent += oldBins[bin];
2370 if(oldErrors !=
nullptr) {
2371 binError += oldErrors[bin] * oldErrors[bin];
2375 hnew->SetBinContent(newbins + 1, newbins + 1, binContent);
2376 if(oldErrors !=
nullptr) {
2377 hnew->SetBinError(newbins + 1, newbins + 1, TMath::Sqrt(binError));
2383 for(Int_t ybin = oldybin; ybin <= nbins + 1; ++ybin) {
2384 Int_t bin = ybin * (2 * nbins - ybin + 3) / 2;
2385 binContent += oldBins[bin];
2386 if(oldErrors !=
nullptr) {
2387 binError += oldErrors[bin] * oldErrors[bin];
2390 hnew->SetBinContent(0, newbins + 1, binContent);
2391 if(oldErrors !=
nullptr) {
2392 hnew->SetBinError(0, newbins + 1, TMath::Sqrt(binError));
2398 for(Int_t xbin = oldxbin; xbin <= nbins + 1; ++xbin) {
2400 binContent += oldBins[bin];
2401 if(oldErrors !=
nullptr) {
2402 binError += oldErrors[bin] * oldErrors[bin];
2405 hnew->SetBinContent(newbins + 1, 0, binContent);
2406 if(oldErrors !=
nullptr) {
2407 hnew->SetBinError(newbins + 1, 0, TMath::Sqrt(binError));
2412 for(Int_t xbin = 1; xbin <= newbins; ++xbin) {
2413 Double_t binContent0 = 0.;
2414 Double_t binContent2 = 0.;
2415 Double_t binError0 = 0.;
2416 Double_t binError2 = 0.;
2417 for(Int_t i = 0; i < ngroup; ++i) {
2418 if(oldxbin2 + i > nbins) {
2422 Int_t ufbin = oldxbin2 + i;
2423 binContent0 += oldBins[ufbin];
2424 if(oldErrors !=
nullptr) {
2425 binError0 += oldErrors[ufbin] * oldErrors[ufbin];
2427 for(Int_t ybin = oldybin; ybin <= nbins + 1; ++ybin) {
2429 Int_t ofbin = ufbin + ybin * (nbins + 2);
2430 binContent2 += oldBins[ofbin];
2431 if(oldErrors !=
nullptr) {
2432 binError2 += oldErrors[ofbin] * oldErrors[ofbin];
2436 hnew->SetBinContent(xbin, 0, binContent0);
2437 hnew->SetBinContent(xbin, newbins + 1, binContent2);
2438 if(oldErrors !=
nullptr) {
2439 hnew->SetBinError(xbin, 0, TMath::Sqrt(binError0));
2440 hnew->SetBinError(xbin, newbins + 1, TMath::Sqrt(binError2));
2447 for(Int_t ybin = 1; ybin <= newbins; ++ybin) {
2448 Double_t binContent0 = 0.;
2449 Double_t binContent2 = 0.;
2450 Double_t binError0 = 0.;
2451 Double_t binError2 = 0.;
2452 for(Int_t i = 0; i < ngroup; ++i) {
2453 if(oldybin2 + i > nbins) {
2457 Int_t ufbin = (oldybin2 + i) * (nbins + 2);
2458 binContent0 += oldBins[ufbin];
2459 if(oldErrors !=
nullptr) {
2460 binError0 += oldErrors[ufbin] * oldErrors[ufbin];
2462 for(Int_t xbin = oldxbin; xbin <= nbins + 1; ++xbin) {
2463 Int_t ofbin = ufbin + xbin;
2464 binContent2 += oldBins[ofbin];
2465 if(oldErrors !=
nullptr) {
2466 binError2 += oldErrors[ofbin] * oldErrors[ofbin];
2470 hnew->SetBinContent(0, ybin, binContent0);
2471 hnew->SetBinContent(newbins + 1, ybin, binContent2);
2472 if(oldErrors !=
nullptr) {
2473 hnew->SetBinError(0, ybin, TMath::Sqrt(binError0));
2474 hnew->SetBinError(newbins + 1, ybin, TMath::Sqrt(binError2));
2481 fXaxis.SetNdivisions(nXdivisions);
2482 fXaxis.SetAxisColor(xAxisColor);
2483 fXaxis.SetLabelColor(xLabelColor);
2484 fXaxis.SetLabelFont(xLabelFont);
2485 fXaxis.SetLabelOffset(xLabelOffset);
2486 fXaxis.SetLabelSize(xLabelSize);
2487 fXaxis.SetTickLength(xTickLength);
2488 fXaxis.SetTitleOffset(xTitleOffset);
2489 fXaxis.SetTitleSize(xTitleSize);
2490 fXaxis.SetTitleColor(xTitleColor);
2491 fXaxis.SetTitleFont(xTitleFont);
2493 fYaxis.SetNdivisions(nYdivisions);
2494 fYaxis.SetAxisColor(yAxisColor);
2495 fYaxis.SetLabelColor(yLabelColor);
2496 fYaxis.SetLabelFont(yLabelFont);
2497 fYaxis.SetLabelOffset(yLabelOffset);
2498 fYaxis.SetLabelSize(yLabelSize);
2499 fYaxis.SetTickLength(yTickLength);
2500 fYaxis.SetTitleOffset(yTitleOffset);
2501 fYaxis.SetTitleSize(yTitleSize);
2502 fYaxis.SetTitleColor(yTitleColor);
2503 fYaxis.SetTitleFont(yTitleFont);
2506 hnew->SetEntries(entries);
2624 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}}};
2625 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}}};
2626 std::array<std::array<Double_t, 3>, 3> k3a = {{{0, 1, 0}, {1, 2, 1}, {0, 1, 0}}};
2629 Warning(
"Smooth",
"Currently only ntimes=1 is supported");
2631 TString opt = option;
2633 Int_t ksize_x = k5a.size();
2634 Int_t ksize_y = k5a.size();
2635 Double_t* kernel = k5a.data()->data();
2636 if(opt.Contains(
"k5b")) {
2637 kernel = k5b.data()->data();
2639 if(opt.Contains(
"k3a")) {
2640 kernel = k3a.data()->data();
2641 ksize_x = k3a.size();
2642 ksize_y = k3a.size();
2646 Int_t ifirst = fXaxis.GetFirst();
2647 Int_t ilast = fXaxis.GetLast();
2648 Int_t jfirst = fYaxis.GetFirst();
2649 Int_t jlast = fYaxis.GetLast();
2652 Double_t nentries = fEntries;
2653 Int_t nx = GetNbinsX();
2654 Int_t ny = GetNbinsY();
2655 Int_t bufSize = (nx + 2) * (ny + 2);
2656 auto* buf =
new Double_t[bufSize];
2657 Double_t* ebuf =
nullptr;
2658 if(fSumw2.fN != 0) {
2659 ebuf =
new Double_t[bufSize];
2663 for(Int_t i = ifirst; i <= ilast; ++i) {
2664 for(Int_t j = jfirst; j <= jlast; ++j) {
2665 Int_t bin =
GetBin(i, j);
2666 buf[bin] = GetBinContent(bin);
2667 if(ebuf !=
nullptr) {
2668 ebuf[bin] = GetBinError(bin);
2674 Int_t x_push = (ksize_x - 1) / 2;
2675 Int_t y_push = (ksize_y - 1) / 2;
2678 for(Int_t i = ifirst; i <= ilast; ++i) {
2679 for(Int_t j = jfirst; j <= jlast; ++j) {
2680 Double_t content = 0.0;
2681 Double_t error = 0.0;
2682 Double_t norm = 0.0;
2684 for(Int_t n = 0; n < ksize_x; ++n) {
2685 for(Int_t m = 0; m < ksize_y; ++m) {
2686 Int_t xb = i + (n - x_push);
2687 Int_t yb = j + (m - y_push);
2688 if((xb >= 1) && (xb <= nx) && (yb >= 1) && (yb <= ny)) {
2689 Int_t bin =
GetBin(xb, yb);
2690 Double_t k = kernel[n * ksize_y + m];
2693 content += k * buf[bin];
2694 if(ebuf !=
nullptr) {
2695 error += k * k * ebuf[bin] * ebuf[bin];
2703 SetBinContent(i, j, content / norm);
2704 if(ebuf !=
nullptr) {
2705 error /= (norm * norm);
2706 SetBinError(i, j, sqrt(error));
2711 fEntries = nentries;