526 Int_t TH1::fgBufferSize = 1000;
527 Bool_t TH1::fgAddDirectory = kTRUE;
528 Bool_t TH1::fgDefaultSumw2 = kFALSE;
529 Bool_t TH1::fgStatOverflows= kFALSE;
531 extern void H1InitGaus();
532 extern void H1InitExpo();
533 extern void H1InitPolynom();
534 extern void H1LeastSquareFit(Int_t n, Int_t m, Double_t *a);
535 extern void H1LeastSquareLinearFit(Int_t ndata, Double_t &a0, Double_t &a1, Int_t &ifail);
536 extern void H1LeastSquareSeqnd(Int_t n, Double_t *a, Int_t idim, Int_t &ifail, Int_t k, Double_t *b);
539 class DifferentDimension:
public std::exception {};
540 class DifferentNumberOfBins:
public std::exception {};
541 class DifferentAxisLimits:
public std::exception {};
542 class DifferentBinLimits:
public std::exception {};
543 class DifferentLabels:
public std::exception {};
550 TH1::TH1(): TNamed(), TAttLine(), TAttFill(), TAttMarker()
553 fFunctions =
new TList;
559 fTsumw = fTsumw2=fTsumwx=fTsumwx2=0;
564 fBinStatErrOpt = kNormal;
565 fStatOverflows = EStatOverflows::kNeutral;
566 fXaxis.SetName(
"xaxis");
567 fYaxis.SetName(
"yaxis");
568 fZaxis.SetName(
"zaxis");
569 fXaxis.SetParent(
this);
570 fYaxis.SetParent(
this);
571 fZaxis.SetParent(
this);
580 if (!TestBit(kNotDeleted)) {
588 R__WRITE_LOCKGUARD(ROOT::gCoreMutex);
590 fFunctions->SetBit(kInvalidObject);
599 while ((obj = fFunctions->First())) {
600 while(fFunctions->Remove(obj)) { }
601 if (!obj->TestBit(kNotDeleted)) {
611 fDirectory->Remove(
this);
639 TH1::TH1(
const char *name,
const char *title,Int_t nbins,Double_t xlow,Double_t xup)
640 :TNamed(name,title), TAttLine(), TAttFill(), TAttMarker()
643 if (nbins <= 0) {Warning(
"TH1",
"nbins is <=0 - set to nbins = 1"); nbins = 1; }
644 fXaxis.Set(nbins,xlow,xup);
645 fNcells = fXaxis.GetNbins()+2;
661 TH1::TH1(
const char *name,
const char *title,Int_t nbins,
const Float_t *xbins)
662 :TNamed(name,title), TAttLine(), TAttFill(), TAttMarker()
665 if (nbins <= 0) {Warning(
"TH1",
"nbins is <=0 - set to nbins = 1"); nbins = 1; }
666 if (xbins) fXaxis.Set(nbins,xbins);
667 else fXaxis.Set(nbins,0,1);
668 fNcells = fXaxis.GetNbins()+2;
683 TH1::TH1(
const char *name,
const char *title,Int_t nbins,
const Double_t *xbins)
684 :TNamed(name,title), TAttLine(), TAttFill(), TAttMarker()
687 if (nbins <= 0) {Warning(
"TH1",
"nbins is <=0 - set to nbins = 1"); nbins = 1; }
688 if (xbins) fXaxis.Set(nbins,xbins);
689 else fXaxis.Set(nbins,0,1);
690 fNcells = fXaxis.GetNbins()+2;
697 TH1::TH1(
const TH1 &h) : TNamed(), TAttLine(), TAttFill(), TAttMarker()
699 ((TH1&)h).Copy(*
this);
705 Bool_t TH1::AddDirectoryStatus()
707 return fgAddDirectory;
713 void TH1::Browse(TBrowser *b)
715 Draw(b ? b->GetDrawOption() :
"");
729 fTsumw = fTsumw2=fTsumwx=fTsumwx2=0;
734 fBinStatErrOpt = kNormal;
735 fStatOverflows = EStatOverflows::kNeutral;
736 fXaxis.SetName(
"xaxis");
737 fYaxis.SetName(
"yaxis");
738 fZaxis.SetName(
"zaxis");
741 fXaxis.SetParent(
this);
742 fYaxis.SetParent(
this);
743 fZaxis.SetParent(
this);
745 SetTitle(fTitle.Data());
747 fFunctions =
new TList;
751 if (TH1::AddDirectoryStatus()) {
752 fDirectory = gDirectory;
754 fFunctions->UseRWLock();
755 fDirectory->Append(
this,kTRUE);
777 Bool_t TH1::Add(TF1 *f1, Double_t c1, Option_t *option)
780 Error(
"Add",
"Attempt to add a non-existing function");
784 TString opt = option;
786 Bool_t integral = kFALSE;
787 if (opt.Contains(
"i") && fDimension == 1) integral = kTRUE;
789 Int_t ncellsx = GetNbinsX() + 2;
790 Int_t ncellsy = GetNbinsY() + 2;
791 Int_t ncellsz = GetNbinsZ() + 2;
792 if (fDimension < 2) ncellsy = 1;
793 if (fDimension < 3) ncellsz = 1;
796 if (fBuffer) BufferEmpty(1);
800 for (Int_t i = 0; i < 10; ++i) s1[i] = 0;
806 Int_t bin, binx, biny, binz;
809 Double_t *params = 0;
810 f1->InitArgs(xx,params);
811 for (binz = 0; binz < ncellsz; ++binz) {
812 xx[2] = fZaxis.GetBinCenter(binz);
813 for (biny = 0; biny < ncellsy; ++biny) {
814 xx[1] = fYaxis.GetBinCenter(biny);
815 for (binx = 0; binx < ncellsx; ++binx) {
816 xx[0] = fXaxis.GetBinCenter(binx);
817 if (!f1->IsInside(xx))
continue;
818 TF1::RejectPoint(kFALSE);
819 bin = binx + ncellsx * (biny + ncellsy * binz);
821 cu = c1*f1->Integral(fXaxis.GetBinLowEdge(binx), fXaxis.GetBinUpEdge(binx), 0.) / fXaxis.GetBinWidth(binx);
823 cu = c1*f1->EvalPar(xx);
825 if (TF1::RejectedPoint())
continue;
826 AddBinContent(bin,cu);
862 Bool_t TH1::Add(
const TH1 *h1, Double_t c1)
865 Error(
"Add",
"Attempt to add a non-existing histogram");
870 if (fBuffer) BufferEmpty(1);
872 bool useMerge = (c1 == 1. && !this->TestBit(kIsAverage) && !h1->TestBit(kIsAverage) );
874 CheckConsistency(
this,h1);
876 }
catch(DifferentNumberOfBins&) {
878 Info(
"Add",
"Attempt to add histograms with different number of bins - trying to use TH1::Merge");
880 Error(
"Add",
"Attempt to add histograms with different number of bins : nbins h1 = %d , nbins h2 = %d",GetNbinsX(), h1->GetNbinsX());
883 }
catch(DifferentAxisLimits&) {
885 Info(
"Add",
"Attempt to add histograms with different axis limits - trying to use TH1::Merge");
887 Warning(
"Add",
"Attempt to add histograms with different axis limits");
888 }
catch(DifferentBinLimits&) {
890 Info(
"Add",
"Attempt to add histograms with different bin limits - trying to use TH1::Merge");
892 Warning(
"Add",
"Attempt to add histograms with different bin limits");
893 }
catch(DifferentLabels&) {
896 Info(
"Add",
"Attempt to add histograms with different labels - trying to use TH1::Merge");
898 Info(
"Warning",
"Attempt to add histograms with different labels");
903 l.Add(const_cast<TH1*>(h1));
904 auto iret = Merge(&l);
909 if (fSumw2.fN == 0 && h1->GetSumw2N() != 0) Sumw2();
912 Double_t entries = TMath::Abs( GetEntries() + c1 * h1->GetEntries() );
916 Bool_t resetStats = (c1 < 0);
917 Double_t s1[kNstat] = {0};
918 Double_t s2[kNstat] = {0};
931 if (h1->GetNormFactor() != 0) factor = h1->GetNormFactor()/h1->GetSumOfWeights();;
932 Double_t c1sq = c1 * c1;
933 Double_t factsq = factor * factor;
935 for (Int_t bin = 0; bin < fNcells; ++bin) {
937 if (this->TestBit(kIsAverage) && h1->TestBit(kIsAverage)) {
938 Double_t y1 = h1->RetrieveBinContent(bin);
939 Double_t y2 = this->RetrieveBinContent(bin);
940 Double_t e1sq = h1->GetBinErrorSqUnchecked(bin);
941 Double_t e2sq = this->GetBinErrorSqUnchecked(bin);
942 Double_t w1 = 1., w2 = 1.;
946 if (e1sq) w1 = 1. / e1sq;
947 else if (h1->fSumw2.fN) {
951 double sf = (s2[0] != 0) ? s2[1]/s2[0] : 1;
955 if (e2sq) w2 = 1. / e2sq;
956 else if (fSumw2.fN) {
960 double sf = (s1[0] != 0) ? s1[1]/s1[0] : 1;
965 double y = (w1*y1 + w2*y2)/(w1 + w2);
966 UpdateBinContent(bin, y);
968 double err2 = 1./(w1 + w2);
969 if (err2 < 1.E-200) err2 = 0;
970 fSumw2.fArray[bin] = err2;
973 AddBinContent(bin, c1 * factor * h1->RetrieveBinContent(bin));
974 if (fSumw2.fN) fSumw2.fArray[bin] += c1sq * factsq * h1->GetBinErrorSqUnchecked(bin);
984 for (Int_t i=0;i<kNstat;i++) {
985 if (i == 1) s1[i] += c1*c1*s2[i];
986 else s1[i] += c1*s2[i];
1023 Bool_t TH1::Add(
const TH1 *h1,
const TH1 *h2, Double_t c1, Double_t c2)
1027 Error(
"Add",
"Attempt to add a non-existing histogram");
1032 if (fBuffer) BufferEmpty(1);
1034 Bool_t normWidth = kFALSE;
1035 if (h1 == h2 && c2 < 0) {c2 = 0; normWidth = kTRUE;}
1038 bool useMerge = (c1 == 1. && c2 == 1. && !this->TestBit(kIsAverage) && !h1->TestBit(kIsAverage) );
1041 CheckConsistency(h1,h2);
1042 CheckConsistency(
this,h1);
1044 }
catch(DifferentNumberOfBins&) {
1046 Info(
"Add",
"Attempt to add histograms with different number of bins - trying to use TH1::Merge");
1048 Error(
"Add",
"Attempt to add histograms with different number of bins : nbins h1 = %d , nbins h2 = %d",GetNbinsX(), h1->GetNbinsX());
1051 }
catch(DifferentAxisLimits&) {
1053 Info(
"Add",
"Attempt to add histograms with different axis limits - trying to use TH1::Merge");
1055 Warning(
"Add",
"Attempt to add histograms with different axis limits");
1056 }
catch(DifferentBinLimits&) {
1058 Info(
"Add",
"Attempt to add histograms with different bin limits - trying to use TH1::Merge");
1060 Warning(
"Add",
"Attempt to add histograms with different bin limits");
1061 }
catch(DifferentLabels&) {
1064 Info(
"Add",
"Attempt to add histograms with different labels - trying to use TH1::Merge");
1066 Info(
"Warning",
"Attempt to add histograms with different labels");
1072 l.Add(const_cast<TH1*>(h1));
1073 l.Add(const_cast<TH1*>(h2));
1075 auto iret = Merge(&l);
1081 if (fSumw2.fN == 0 && (h1->GetSumw2N() != 0 || h2->GetSumw2N() != 0)) Sumw2();
1084 Double_t nEntries = TMath::Abs( c1*h1->GetEntries() + c2*h2->GetEntries() );
1090 Double_t s1[kNstat] = {0};
1091 Double_t s2[kNstat] = {0};
1092 Double_t s3[kNstat];
1095 Bool_t resetStats = (c1*c2 < 0) || normWidth;
1101 for (Int_t i=0;i<kNstat;i++) {
1102 if (i == 1) s3[i] = c1*c1*s1[i] + c2*c2*s2[i];
1104 else s3[i] = c1*s1[i] + c2*s2[i];
1113 Int_t nbinsx = GetNbinsX() + 2;
1114 Int_t nbinsy = GetNbinsY() + 2;
1115 Int_t nbinsz = GetNbinsZ() + 2;
1117 if (fDimension < 2) nbinsy = 1;
1118 if (fDimension < 3) nbinsz = 1;
1120 Int_t bin, binx, biny, binz;
1121 for (binz = 0; binz < nbinsz; ++binz) {
1122 Double_t wz = h1->GetZaxis()->GetBinWidth(binz);
1123 for (biny = 0; biny < nbinsy; ++biny) {
1124 Double_t wy = h1->GetYaxis()->GetBinWidth(biny);
1125 for (binx = 0; binx < nbinsx; ++binx) {
1126 Double_t wx = h1->GetXaxis()->GetBinWidth(binx);
1127 bin = GetBin(binx, biny, binz);
1128 Double_t w = wx*wy*wz;
1129 UpdateBinContent(bin, c1 * h1->RetrieveBinContent(bin) / w);
1131 Double_t e1 = h1->GetBinError(bin)/w;
1132 fSumw2.fArray[bin] = c1*c1*e1*e1;
1137 }
else if (h1->TestBit(kIsAverage) && h2->TestBit(kIsAverage)) {
1138 for (Int_t i = 0; i < fNcells; ++i) {
1140 Double_t y1 = h1->RetrieveBinContent(i);
1141 Double_t y2 = h2->RetrieveBinContent(i);
1142 Double_t e1sq = h1->GetBinErrorSqUnchecked(i);
1143 Double_t e2sq = h2->GetBinErrorSqUnchecked(i);
1144 Double_t w1 = 1., w2 = 1.;
1148 if (e1sq) w1 = 1./ e1sq;
1149 else if (h1->fSumw2.fN) {
1152 double sf = (s1[0] != 0) ? s1[1]/s1[0] : 1;
1156 if (e2sq) w2 = 1./ e2sq;
1157 else if (h2->fSumw2.fN) {
1160 double sf = (s2[0] != 0) ? s2[1]/s2[0] : 1;
1165 double y = (w1*y1 + w2*y2)/(w1 + w2);
1166 UpdateBinContent(i, y);
1168 double err2 = 1./(w1 + w2);
1169 if (err2 < 1.E-200) err2 = 0;
1170 fSumw2.fArray[i] = err2;
1174 Double_t c1sq = c1 * c1;
1175 Double_t c2sq = c2 * c2;
1176 for (Int_t i = 0; i < fNcells; ++i) {
1177 UpdateBinContent(i, c1 * h1->RetrieveBinContent(i) + c2 * h2->RetrieveBinContent(i));
1179 fSumw2.fArray[i] = c1sq * h1->GetBinErrorSqUnchecked(i) + c2sq * h2->GetBinErrorSqUnchecked(i);
1191 SetEntries(nEntries);
1200 void TH1::AddBinContent(Int_t)
1202 AbstractMethod(
"AddBinContent");
1208 void TH1::AddBinContent(Int_t, Double_t)
1210 AbstractMethod(
"AddBinContent");
1225 void TH1::AddDirectory(Bool_t add)
1227 fgAddDirectory = add;
1239 inline Double_t TH1::AutoP2GetPower2(Double_t x, Bool_t next)
1242 Double_t f2 = std::frexp(x, &nn);
1243 return ((next && x > 0.) || (!next && x <= 0.)) ? std::ldexp(std::copysign(1., f2), nn)
1244 : std::ldexp(std::copysign(1., f2), --nn);
1252 inline Int_t TH1::AutoP2GetBins(Int_t n)
1255 Double_t f2 = std::frexp(n, &nn);
1256 if (TMath::Abs(f2 - .5) > 0.001)
1257 return (Int_t)std::ldexp(1., nn);
1275 Int_t TH1::AutoP2FindLimits(Double_t xmi, Double_t xma)
1281 THLimitsFinder::GetLimitsFinder()->FindGoodLimits(
this, xmi, xma);
1282 Double_t xhmi = fXaxis.GetXmin();
1283 Double_t xhma = fXaxis.GetXmax();
1286 if (TMath::Abs(xhma) > TMath::Abs(xhmi)) {
1288 xhma = TH1::AutoP2GetPower2(xhma);
1289 xhmi = xhma - TH1::AutoP2GetPower2(xhma - xhmi);
1292 xhmi = TH1::AutoP2GetPower2(xhmi, kFALSE);
1293 xhma = xhmi + TH1::AutoP2GetPower2(xhma - xhmi);
1298 Double_t rr = (xhma - xhmi) / (xma - xmi);
1299 Int_t nb = TH1::AutoP2GetBins((Int_t)(rr * GetNbinsX()));
1302 Double_t bw = (xhma - xhmi) / nb;
1304 Double_t autoside = gEnv->GetValue(
"Hist.Binning.Auto.Side", 0.05);
1305 Int_t nbside = (Int_t)(nb * autoside);
1308 Int_t nbup = (xhma - xma) / bw;
1311 if (nbup != nbside) {
1313 xhma -= bw * (nbup - nbside);
1314 nb -= (nbup - nbside);
1318 Int_t nblw = (xmi - xhmi) / bw;
1321 if (nblw != nbside) {
1323 xhmi += bw * (nblw - nbside);
1324 nb -= (nblw - nbside);
1328 SetBins(nb, xhmi, xhma);
1346 Int_t TH1::BufferEmpty(Int_t action)
1349 if (!fBuffer)
return 0;
1350 Int_t nbentries = (Int_t)fBuffer[0];
1354 if (nbentries == 0) {
1364 if (nbentries < 0 && action == 0)
return 0;
1366 Double_t *buffer = fBuffer;
1367 if (nbentries < 0) {
1368 nbentries = -nbentries;
1376 if (CanExtendAllAxes() || (fXaxis.GetXmax() <= fXaxis.GetXmin())) {
1378 Double_t xmin = fBuffer[2];
1379 Double_t xmax = xmin;
1380 for (Int_t i=1;i<nbentries;i++) {
1381 Double_t x = fBuffer[2*i+2];
1382 if (x < xmin) xmin = x;
1383 if (x > xmax) xmax = x;
1385 if (fXaxis.GetXmax() <= fXaxis.GetXmin()) {
1387 if (TestBit(TH1::kAutoBinPTwo)) {
1388 if ((rc = AutoP2FindLimits(xmin, xmax)) < 0)
1389 Warning(
"BufferEmpty",
1390 "incosistency found by power-of-2 autobin algorithm: fallback to standard method");
1393 THLimitsFinder::GetLimitsFinder()->FindGoodLimits(
this, xmin, xmax);
1396 Int_t keep = fBufferSize; fBufferSize = 0;
1397 if (xmin < fXaxis.GetXmin()) ExtendAxis(xmin, &fXaxis);
1398 if (xmax >= fXaxis.GetXmax()) ExtendAxis(xmax, &fXaxis);
1407 buffer = fBuffer; fBuffer = 0;
1408 DoFillN(nbentries,&buffer[2],&buffer[1],2);
1421 if (nbentries == (Int_t)fEntries)
1422 fBuffer[0] = -nbentries;
1436 Int_t TH1::BufferFill(Double_t x, Double_t w)
1438 if (!fBuffer)
return -2;
1439 Int_t nbentries = (Int_t)fBuffer[0];
1442 if (nbentries < 0) {
1445 nbentries = -nbentries;
1446 fBuffer[0] = nbentries;
1449 Double_t *buffer = fBuffer; fBuffer=0;
1454 if (2*nbentries+2 >= fBufferSize) {
1462 fBuffer[2*nbentries+1] = w;
1463 fBuffer[2*nbentries+2] = x;
1471 bool TH1::CheckBinLimits(
const TAxis* a1,
const TAxis * a2)
1473 const TArrayD * h1Array = a1->GetXbins();
1474 const TArrayD * h2Array = a2->GetXbins();
1475 Int_t fN = h1Array->fN;
1477 if ( h2Array->fN != fN ) {
1478 throw DifferentBinLimits();
1482 for (
int i = 0; i < fN; ++i ) {
1485 double binWidth = a1->GetBinWidth(i);
1486 if ( ! TMath::AreEqualAbs( h1Array->GetAt(i), h2Array->GetAt(i), binWidth*1E-10 ) ) {
1487 throw DifferentBinLimits();
1500 bool TH1::CheckBinLabels(
const TAxis* a1,
const TAxis * a2)
1502 THashList *l1 = a1->GetLabels();
1503 THashList *l2 = a2->GetLabels();
1508 throw DifferentLabels();
1512 if (l1->GetSize() != l2->GetSize() ) {
1513 throw DifferentLabels();
1516 for (
int i = 1; i <= a1->GetNbins(); ++i) {
1517 TString label1 = a1->GetBinLabel(i);
1518 TString label2 = a2->GetBinLabel(i);
1519 if (label1 != label2) {
1520 throw DifferentLabels();
1532 bool TH1::CheckAxisLimits(
const TAxis *a1,
const TAxis *a2 )
1534 double firstBin = a1->GetBinWidth(1);
1535 double lastBin = a1->GetBinWidth( a1->GetNbins() );
1536 if ( ! TMath::AreEqualAbs(a1->GetXmin(), a2->GetXmin(), firstBin* 1.E-10) ||
1537 ! TMath::AreEqualAbs(a1->GetXmax(), a2->GetXmax(), lastBin*1.E-10) ) {
1538 throw DifferentAxisLimits();
1547 bool TH1::CheckEqualAxes(
const TAxis *a1,
const TAxis *a2 )
1549 if (a1->GetNbins() != a2->GetNbins() ) {
1551 ::Info(
"CheckEqualAxes",
"Axes have different number of bins : nbin1 = %d nbin2 = %d",a1->GetNbins(),a2->GetNbins() );
1555 CheckAxisLimits(a1,a2);
1556 }
catch (DifferentAxisLimits&) {
1557 ::Info(
"CheckEqualAxes",
"Axes have different limits");
1561 CheckBinLimits(a1,a2);
1562 }
catch (DifferentBinLimits&) {
1563 ::Info(
"CheckEqualAxes",
"Axes have different bin limits");
1569 CheckBinLabels(a1,a2);
1570 }
catch (DifferentLabels&) {
1571 ::Info(
"CheckEqualAxes",
"Axes have different labels");
1583 bool TH1::CheckConsistentSubAxes(
const TAxis *a1, Int_t firstBin1, Int_t lastBin1,
const TAxis * a2, Int_t firstBin2, Int_t lastBin2 )
1586 Int_t nbins1 = lastBin1-firstBin1 + 1;
1587 Double_t xmin1 = a1->GetBinLowEdge(firstBin1);
1588 Double_t xmax1 = a1->GetBinUpEdge(lastBin1);
1590 Int_t nbins2 = a2->GetNbins();
1591 Double_t xmin2 = a2->GetXmin();
1592 Double_t xmax2 = a2->GetXmax();
1594 if (firstBin2 < lastBin2) {
1596 nbins2 = lastBin1-firstBin1 + 1;
1597 xmin2 = a1->GetBinLowEdge(firstBin1);
1598 xmax2 = a1->GetBinUpEdge(lastBin1);
1601 if (nbins1 != nbins2 ) {
1602 ::Info(
"CheckConsistentSubAxes",
"Axes have different number of bins");
1606 Double_t firstBin = a1->GetBinWidth(firstBin1);
1607 Double_t lastBin = a1->GetBinWidth(lastBin1);
1608 if ( ! TMath::AreEqualAbs(xmin1,xmin2,1.E-10 * firstBin) ||
1609 ! TMath::AreEqualAbs(xmax1,xmax2,1.E-10 * lastBin) ) {
1610 ::Info(
"CheckConsistentSubAxes",
"Axes have different limits");
1620 bool TH1::CheckConsistency(
const TH1* h1,
const TH1* h2)
1622 if (h1 == h2)
return true;
1624 if (h1->GetDimension() != h2->GetDimension() ) {
1625 throw DifferentDimension();
1628 Int_t dim = h1->GetDimension();
1631 Int_t nbinsx = h1->GetNbinsX();
1632 Int_t nbinsy = h1->GetNbinsY();
1633 Int_t nbinsz = h1->GetNbinsZ();
1636 if (nbinsx != h2->GetNbinsX() ||
1637 (dim > 1 && nbinsy != h2->GetNbinsY()) ||
1638 (dim > 2 && nbinsz != h2->GetNbinsZ()) ) {
1639 throw DifferentNumberOfBins();
1646 ret &= CheckAxisLimits(h1->GetXaxis(), h2->GetXaxis());
1647 if (dim > 1) ret &= CheckAxisLimits(h1->GetYaxis(), h2->GetYaxis());
1648 if (dim > 2) ret &= CheckAxisLimits(h1->GetZaxis(), h2->GetZaxis());
1651 ret &= CheckBinLimits(h1->GetXaxis(), h2->GetXaxis());
1652 if (dim > 1) ret &= CheckBinLimits(h1->GetYaxis(), h2->GetYaxis());
1653 if (dim > 2) ret &= CheckBinLimits(h1->GetZaxis(), h2->GetZaxis());
1656 if ( !h1->IsEmpty() && !h2->IsEmpty() ) {
1657 ret &= CheckBinLabels(h1->GetXaxis(), h2->GetXaxis());
1658 if (dim > 1) ret &= CheckBinLabels(h1->GetYaxis(), h2->GetYaxis());
1659 if (dim > 2) ret &= CheckBinLabels(h1->GetZaxis(), h2->GetZaxis());
1951 Double_t TH1::Chi2Test(
const TH1* h2, Option_t *option, Double_t *res)
const
1954 Int_t ndf = 0, igood = 0;
1956 TString opt = option;
1959 Double_t prob = Chi2TestX(h2,chi2,ndf,igood,option,res);
1961 if(opt.Contains(
"P")) {
1962 printf(
"Chi2 = %f, Prob = %g, NDF = %d, igood = %d\n", chi2,prob,ndf,igood);
1964 if(opt.Contains(
"CHI2/NDF")) {
1965 if (ndf == 0)
return 0;
1968 if(opt.Contains(
"CHI2")) {
2010 Double_t TH1::Chi2TestX(
const TH1* h2, Double_t &chi2, Int_t &ndf, Int_t &igood, Option_t *option, Double_t *res)
const
2013 Int_t i_start, i_end;
2014 Int_t j_start, j_end;
2015 Int_t k_start, k_end;
2017 Double_t sum1 = 0.0, sumw1 = 0.0;
2018 Double_t sum2 = 0.0, sumw2 = 0.0;
2023 TString opt = option;
2026 if (fBuffer)
const_cast<TH1*
>(
this)->BufferEmpty();
2028 const TAxis *xaxis1 = GetXaxis();
2029 const TAxis *xaxis2 = h2->GetXaxis();
2030 const TAxis *yaxis1 = GetYaxis();
2031 const TAxis *yaxis2 = h2->GetYaxis();
2032 const TAxis *zaxis1 = GetZaxis();
2033 const TAxis *zaxis2 = h2->GetZaxis();
2035 Int_t nbinx1 = xaxis1->GetNbins();
2036 Int_t nbinx2 = xaxis2->GetNbins();
2037 Int_t nbiny1 = yaxis1->GetNbins();
2038 Int_t nbiny2 = yaxis2->GetNbins();
2039 Int_t nbinz1 = zaxis1->GetNbins();
2040 Int_t nbinz2 = zaxis2->GetNbins();
2043 if (this->GetDimension() != h2->GetDimension() ){
2044 Error(
"Chi2TestX",
"Histograms have different dimensions.");
2049 if (nbinx1 != nbinx2) {
2050 Error(
"Chi2TestX",
"different number of x channels");
2052 if (nbiny1 != nbiny2) {
2053 Error(
"Chi2TestX",
"different number of y channels");
2055 if (nbinz1 != nbinz2) {
2056 Error(
"Chi2TestX",
"different number of z channels");
2060 i_start = j_start = k_start = 1;
2065 if (xaxis1->TestBit(TAxis::kAxisRange)) {
2066 i_start = xaxis1->GetFirst();
2067 i_end = xaxis1->GetLast();
2069 if (yaxis1->TestBit(TAxis::kAxisRange)) {
2070 j_start = yaxis1->GetFirst();
2071 j_end = yaxis1->GetLast();
2073 if (zaxis1->TestBit(TAxis::kAxisRange)) {
2074 k_start = zaxis1->GetFirst();
2075 k_end = zaxis1->GetLast();
2079 if (opt.Contains(
"OF")) {
2080 if (GetDimension() == 3) k_end = ++nbinz1;
2081 if (GetDimension() >= 2) j_end = ++nbiny1;
2082 if (GetDimension() >= 1) i_end = ++nbinx1;
2085 if (opt.Contains(
"UF")) {
2086 if (GetDimension() == 3) k_start = 0;
2087 if (GetDimension() >= 2) j_start = 0;
2088 if (GetDimension() >= 1) i_start = 0;
2091 ndf = (i_end - i_start + 1) * (j_end - j_start + 1) * (k_end - k_start + 1) - 1;
2093 Bool_t comparisonUU = opt.Contains(
"UU");
2094 Bool_t comparisonUW = opt.Contains(
"UW");
2095 Bool_t comparisonWW = opt.Contains(
"WW");
2096 Bool_t scaledHistogram = opt.Contains(
"NORM");
2098 if (scaledHistogram && !comparisonUU) {
2099 Info(
"Chi2TestX",
"NORM option should be used together with UU option. It is ignored");
2105 Double_t sumBinContent1 = s[0];
2106 Double_t effEntries1 = (s[1] ? s[0] * s[0] / s[1] : 0.0);
2109 Double_t sumBinContent2 = s[0];
2110 Double_t effEntries2 = (s[1] ? s[0] * s[0] / s[1] : 0.0);
2112 if (!comparisonUU && !comparisonUW && !comparisonWW ) {
2114 if (TMath::Abs(sumBinContent1 - effEntries1) < 1) {
2115 if ( TMath::Abs(sumBinContent2 - effEntries2) < 1) comparisonUU =
true;
2116 else comparisonUW =
true;
2118 else comparisonWW =
true;
2122 if (TMath::Abs(sumBinContent1 - effEntries1) >= 1) {
2123 Warning(
"Chi2TestX",
"First histogram is not unweighted and option UW has been requested");
2126 if ( (!scaledHistogram && comparisonUU) ) {
2127 if ( ( TMath::Abs(sumBinContent1 - effEntries1) >= 1) || (TMath::Abs(sumBinContent2 - effEntries2) >= 1) ) {
2128 Warning(
"Chi2TestX",
"Both histograms are not unweighted and option UU has been requested");
2134 if (comparisonUU && scaledHistogram) {
2135 for (Int_t i = i_start; i <= i_end; ++i) {
2136 for (Int_t j = j_start; j <= j_end; ++j) {
2137 for (Int_t k = k_start; k <= k_end; ++k) {
2139 Int_t bin = GetBin(i, j, k);
2141 Double_t cnt1 = RetrieveBinContent(bin);
2142 Double_t cnt2 = h2->RetrieveBinContent(bin);
2143 Double_t e1sq = GetBinErrorSqUnchecked(bin);
2144 Double_t e2sq = h2->GetBinErrorSqUnchecked(bin);
2146 if (e1sq > 0.0) cnt1 = TMath::Floor(cnt1 * cnt1 / e1sq + 0.5);
2149 if (e2sq > 0.0) cnt2 = TMath::Floor(cnt2 * cnt2 / e2sq + 0.5);
2160 if (sumw1 <= 0.0 || sumw2 <= 0.0) {
2161 Error(
"Chi2TestX",
"Cannot use option NORM when one histogram has all zero errors");
2166 for (Int_t i = i_start; i <= i_end; ++i) {
2167 for (Int_t j = j_start; j <= j_end; ++j) {
2168 for (Int_t k = k_start; k <= k_end; ++k) {
2170 Int_t bin = GetBin(i, j, k);
2172 sum1 += RetrieveBinContent(bin);
2173 sum2 += h2->RetrieveBinContent(bin);
2175 if ( comparisonWW ) sumw1 += GetBinErrorSqUnchecked(bin);
2176 if ( comparisonUW || comparisonWW ) sumw2 += h2->GetBinErrorSqUnchecked(bin);
2182 if (sum1 == 0.0 || sum2 == 0.0) {
2183 Error(
"Chi2TestX",
"one histogram is empty");
2187 if ( comparisonWW && ( sumw1 <= 0.0 && sumw2 <= 0.0 ) ){
2188 Error(
"Chi2TestX",
"Hist1 and Hist2 have both all zero errors\n");
2197 Double_t sum = sum1 + sum2;
2198 for (Int_t i = i_start; i <= i_end; ++i) {
2199 for (Int_t j = j_start; j <= j_end; ++j) {
2200 for (Int_t k = k_start; k <= k_end; ++k) {
2202 Int_t bin = GetBin(i, j, k);
2204 Double_t cnt1 = RetrieveBinContent(bin);
2205 Double_t cnt2 = h2->RetrieveBinContent(bin);
2207 if (scaledHistogram) {
2209 Double_t e1sq = GetBinErrorSqUnchecked(bin);
2210 Double_t e2sq = h2->GetBinErrorSqUnchecked(bin);
2212 if (e1sq > 0) cnt1 = TMath::Floor(cnt1 * cnt1 / e1sq + 0.5);
2215 if (e2sq > 0) cnt2 = TMath::Floor(cnt2 * cnt2 / e2sq + 0.5);
2219 if (Int_t(cnt1) == 0 && Int_t(cnt2) == 0) --ndf;
2222 Double_t cntsum = cnt1 + cnt2;
2223 Double_t nexp1 = cntsum * sum1 / sum;
2226 if (res) res[i - i_start] = (cnt1 - nexp1) / TMath::Sqrt(nexp1);
2232 Double_t correc = (1. - sum1 / sum) * (1. - cntsum / sum);
2233 if (res) res[i - i_start] /= TMath::Sqrt(correc);
2235 Double_t delta = sum2 * cnt1 - sum1 * cnt2;
2236 chi2 += delta * delta / cntsum;
2241 chi2 /= sum1 * sum2;
2246 Info(
"Chi2TestX",
"There is a bin in h1 with less than 1 event.\n");
2250 Info(
"Chi2TestX",
"There is a bin in h2 with less than 1 event.\n");
2253 Double_t prob = TMath::Prob(chi2,ndf);
2261 if ( comparisonUW ) {
2262 for (Int_t i = i_start; i <= i_end; ++i) {
2263 for (Int_t j = j_start; j <= j_end; ++j) {
2264 for (Int_t k = k_start; k <= k_end; ++k) {
2266 Int_t bin = GetBin(i, j, k);
2268 Double_t cnt1 = RetrieveBinContent(bin);
2269 Double_t cnt2 = h2->RetrieveBinContent(bin);
2270 Double_t e2sq = h2->GetBinErrorSqUnchecked(bin);
2273 if (cnt1 * cnt1 == 0 && cnt2 * cnt2 == 0) {
2279 if (cnt2 * cnt2 == 0 && e2sq == 0) {
2283 e2sq = sumw2 / sum2;
2288 Error(
"Chi2TestX",
"Hist2 has in bin (%d,%d,%d) zero content and zero errors\n", i, j, k);
2294 if (e2sq > 0 && cnt2 * cnt2 / e2sq < 10) n++;
2296 Double_t var1 = sum2 * cnt2 - sum1 * e2sq;
2297 Double_t var2 = var1 * var1 + 4. * sum2 * sum2 * cnt1 * e2sq;
2302 while (var1 * var1 + cnt1 == 0 || var1 + var2 == 0) {
2305 var1 = sum2 * cnt2 - sum1 * e2sq;
2306 var2 = var1 * var1 + 4. * sum2 * sum2 * cnt1 * e2sq;
2308 var2 = TMath::Sqrt(var2);
2310 while (var1 + var2 == 0) {
2313 var1 = sum2 * cnt2 - sum1 * e2sq;
2314 var2 = var1 * var1 + 4. * sum2 * sum2 * cnt1 * e2sq;
2315 while (var1 * var1 + cnt1 == 0 || var1 + var2 == 0) {
2318 var1 = sum2 * cnt2 - sum1 * e2sq;
2319 var2 = var1 * var1 + 4. * sum2 * sum2 * cnt1 * e2sq;
2321 var2 = TMath::Sqrt(var2);
2324 Double_t probb = (var1 + var2) / (2. * sum2 * sum2);
2326 Double_t nexp1 = probb * sum1;
2327 Double_t nexp2 = probb * sum2;
2329 Double_t delta1 = cnt1 - nexp1;
2330 Double_t delta2 = cnt2 - nexp2;
2332 chi2 += delta1 * delta1 / nexp1;
2335 chi2 += delta2 * delta2 / e2sq;
2340 Double_t temp1 = sum2 * e2sq / var2;
2341 Double_t temp2 = 1.0 + (sum1 * e2sq - sum2 * cnt2) / var2;
2342 temp2 = temp1 * temp1 * sum1 * probb * (1.0 - probb) + temp2 * temp2 * e2sq / 4.0;
2344 res[i - i_start] = - delta2 / TMath::Sqrt(temp2);
2347 res[i - i_start] = delta1 / TMath::Sqrt(nexp1);
2355 Info(
"Chi2TestX",
"There is a bin in h1 with less than 1 event.\n");
2359 Info(
"Chi2TestX",
"There is a bin in h2 with less than 10 effective events.\n");
2362 Double_t prob = TMath::Prob(chi2, ndf);
2369 for (Int_t i = i_start; i <= i_end; ++i) {
2370 for (Int_t j = j_start; j <= j_end; ++j) {
2371 for (Int_t k = k_start; k <= k_end; ++k) {
2373 Int_t bin = GetBin(i, j, k);
2374 Double_t cnt1 = RetrieveBinContent(bin);
2375 Double_t cnt2 = h2->RetrieveBinContent(bin);
2376 Double_t e1sq = GetBinErrorSqUnchecked(bin);
2377 Double_t e2sq = h2->GetBinErrorSqUnchecked(bin);
2381 if (cnt1 * cnt1 == 0 && cnt2 * cnt2 == 0) {
2386 if (e1sq == 0 && e2sq == 0) {
2388 Error(
"Chi2TestX",
"h1 and h2 both have bin %d,%d,%d with all zero errors\n", i,j,k);
2392 Double_t sigma = sum1 * sum1 * e2sq + sum2 * sum2 * e1sq;
2393 Double_t delta = sum2 * cnt1 - sum1 * cnt2;
2394 chi2 += delta * delta / sigma;
2397 Double_t temp = cnt1 * sum1 * e2sq + cnt2 * sum2 * e1sq;
2398 Double_t probb = temp / sigma;
2401 Double_t d1 = cnt1 - sum1 * probb;
2402 Double_t s1 = e1sq * ( 1. - e2sq * sum1 * sum1 / sigma );
2403 z = d1 / TMath::Sqrt(s1);
2406 Double_t d2 = cnt2 - sum2 * probb;
2407 Double_t s2 = e2sq * ( 1. - e1sq * sum2 * sum2 / sigma );
2408 z = -d2 / TMath::Sqrt(s2);
2410 res[i - i_start] = z;
2413 if (e1sq > 0 && cnt1 * cnt1 / e1sq < 10) m++;
2414 if (e2sq > 0 && cnt2 * cnt2 / e2sq < 10) n++;
2420 Info(
"Chi2TestX",
"There is a bin in h1 with less than 10 effective events.\n");
2424 Info(
"Chi2TestX",
"There is a bin in h2 with less than 10 effective events.\n");
2426 Double_t prob = TMath::Prob(chi2, ndf);
2438 Double_t TH1::Chisquare(TF1 * func, Option_t *option)
const
2441 Error(
"Chisquare",
"Function pointer is Null - return -1");
2445 TString opt(option); opt.ToUpper();
2446 bool useRange = opt.Contains(
"R");
2447 bool usePL = opt.Contains(
"L");
2449 return ROOT::Fit::Chisquare(*
this, *func, useRange, usePL);
2457 void TH1::ClearUnderflowAndOverflow()
2459 for (Int_t bin = 0; bin < fNcells; ++bin)
2460 if (IsBinUnderflow(bin) || IsBinOverflow(bin)) {
2461 UpdateBinContent(bin, 0.0);
2462 if (fSumw2.fN) fSumw2.fArray[bin] = 0.0;
2476 Double_t TH1::ComputeIntegral(Bool_t onlyPositive)
2478 if (fBuffer) BufferEmpty();
2481 if (fIntegral)
delete [] fIntegral;
2484 Int_t nbinsx = GetNbinsX();
2485 Int_t nbinsy = GetNbinsY();
2486 Int_t nbinsz = GetNbinsZ();
2487 Int_t nbins = nbinsx * nbinsy * nbinsz;
2489 fIntegral =
new Double_t[nbins + 2];
2490 Int_t ibin = 0; fIntegral[ibin] = 0;
2492 for (Int_t binz=1; binz <= nbinsz; ++binz) {
2493 for (Int_t biny=1; biny <= nbinsy; ++biny) {
2494 for (Int_t binx=1; binx <= nbinsx; ++binx) {
2496 Double_t y = RetrieveBinContent(GetBin(binx, biny, binz));
2497 if (onlyPositive && y < 0) {
2498 Error(
"ComputeIntegral",
"Bin content is negative - return a NaN value");
2499 fIntegral[nbins] = TMath::QuietNaN();
2502 fIntegral[ibin] = fIntegral[ibin - 1] + y;
2508 if (fIntegral[nbins] == 0 ) {
2509 Error(
"ComputeIntegral",
"Integral = zero");
return 0;
2511 for (Int_t bin=1; bin <= nbins; ++bin) fIntegral[bin] /= fIntegral[nbins];
2512 fIntegral[nbins+1] = fEntries;
2513 return fIntegral[nbins];
2524 Double_t *TH1::GetIntegral()
2526 if (!fIntegral) ComputeIntegral();
2546 TH1 *TH1::GetCumulative(Bool_t forward,
const char* suffix)
const
2548 const Int_t nbinsx = GetNbinsX();
2549 const Int_t nbinsy = GetNbinsY();
2550 const Int_t nbinsz = GetNbinsZ();
2551 TH1* hintegrated = (TH1*) Clone(fName + suffix);
2552 hintegrated->Reset();
2555 for (Int_t binz = 1; binz <= nbinsz; ++binz) {
2556 for (Int_t biny = 1; biny <= nbinsy; ++biny) {
2557 for (Int_t binx = 1; binx <= nbinsx; ++binx) {
2558 const Int_t bin = hintegrated->GetBin(binx, biny, binz);
2559 sum += GetBinContent(bin);
2560 hintegrated->SetBinContent(bin, sum);
2566 for (Int_t binz = nbinsz; binz >= 1; --binz) {
2567 for (Int_t biny = nbinsy; biny >= 1; --biny) {
2568 for (Int_t binx = nbinsx; binx >= 1; --binx) {
2569 const Int_t bin = hintegrated->GetBin(binx, biny, binz);
2570 sum += GetBinContent(bin);
2571 hintegrated->SetBinContent(bin, sum);
2589 void TH1::Copy(TObject &obj)
const
2591 if (((TH1&)obj).fDirectory) {
2595 ((TH1&)obj).fDirectory->Remove(&obj);
2596 ((TH1&)obj).fDirectory = 0;
2599 ((TH1&)obj).fDimension = fDimension;
2600 ((TH1&)obj).fNormFactor= fNormFactor;
2601 ((TH1&)obj).fNcells = fNcells;
2602 ((TH1&)obj).fBarOffset = fBarOffset;
2603 ((TH1&)obj).fBarWidth = fBarWidth;
2604 ((TH1&)obj).fOption = fOption;
2605 ((TH1&)obj).fBinStatErrOpt = fBinStatErrOpt;
2606 ((TH1&)obj).fBufferSize= fBufferSize;
2609 if (((TH1&)obj).fBuffer != 0) {
2610 delete [] ((TH1&)obj).fBuffer;
2611 ((TH1&)obj).fBuffer = 0;
2614 Double_t *buf =
new Double_t[fBufferSize];
2615 for (Int_t i=0;i<fBufferSize;i++) buf[i] = fBuffer[i];
2617 ((TH1&)obj).fBuffer = buf;
2621 TArray* a =
dynamic_cast<TArray*
>(&obj);
2622 if (a) a->Set(fNcells);
2623 for (Int_t i = 0; i < fNcells; i++) ((TH1&)obj).UpdateBinContent(i, RetrieveBinContent(i));
2625 ((TH1&)obj).fEntries = fEntries;
2630 ((TH1&)obj).fTsumw = fTsumw;
2631 ((TH1&)obj).fTsumw2 = fTsumw2;
2632 ((TH1&)obj).fTsumwx = fTsumwx;
2633 ((TH1&)obj).fTsumwx2 = fTsumwx2;
2634 ((TH1&)obj).fMaximum = fMaximum;
2635 ((TH1&)obj).fMinimum = fMinimum;
2637 TAttLine::Copy(((TH1&)obj));
2638 TAttFill::Copy(((TH1&)obj));
2639 TAttMarker::Copy(((TH1&)obj));
2640 fXaxis.Copy(((TH1&)obj).fXaxis);
2641 fYaxis.Copy(((TH1&)obj).fYaxis);
2642 fZaxis.Copy(((TH1&)obj).fZaxis);
2643 ((TH1&)obj).fXaxis.SetParent(&obj);
2644 ((TH1&)obj).fYaxis.SetParent(&obj);
2645 ((TH1&)obj).fZaxis.SetParent(&obj);
2646 fContour.Copy(((TH1&)obj).fContour);
2647 fSumw2.Copy(((TH1&)obj).fSumw2);
2653 if (fgAddDirectory && gDirectory) {
2654 gDirectory->Append(&obj);
2655 ((TH1&)obj).fFunctions->UseRWLock();
2656 ((TH1&)obj).fDirectory = gDirectory;
2658 ((TH1&)obj).fDirectory = 0;
2666 TObject* TH1::Clone(
const char* newname)
const
2668 TH1* obj = (TH1*)IsA()->GetNew()(0);
2678 auto newlist = (TList*)fFunctions->Clone();
2679 auto oldlist = obj->fFunctions;
2681 R__WRITE_LOCKGUARD(ROOT::gCoreMutex);
2682 obj->fFunctions = newlist;
2686 if(newname && strlen(newname) ) {
2687 obj->SetName(newname);
2699 void TH1::DirectoryAutoAdd(TDirectory *dir)
2701 Bool_t addStatus = TH1::AddDirectoryStatus();
2705 ResetBit(kCanDelete);
2721 Int_t TH1::DistancetoPrimitive(Int_t px, Int_t py)
2723 if (!fPainter)
return 9999;
2724 return fPainter->DistancetoPrimitive(px,py);
2738 Bool_t TH1::Divide(TF1 *f1, Double_t c1)
2741 Error(
"Divide",
"Attempt to divide by a non-existing function");
2746 if (fBuffer) BufferEmpty(1);
2748 Int_t nx = GetNbinsX() + 2;
2749 Int_t ny = GetNbinsY() + 2;
2750 Int_t nz = GetNbinsZ() + 2;
2751 if (fDimension < 2) ny = 1;
2752 if (fDimension < 3) nz = 1;
2759 Int_t bin, binx, biny, binz;
2762 Double_t *params = 0;
2763 f1->InitArgs(xx,params);
2764 for (binz = 0; binz < nz; ++binz) {
2765 xx[2] = fZaxis.GetBinCenter(binz);
2766 for (biny = 0; biny < ny; ++biny) {
2767 xx[1] = fYaxis.GetBinCenter(biny);
2768 for (binx = 0; binx < nx; ++binx) {
2769 xx[0] = fXaxis.GetBinCenter(binx);
2770 if (!f1->IsInside(xx))
continue;
2771 TF1::RejectPoint(kFALSE);
2772 bin = binx + nx * (biny + ny * binz);
2773 cu = c1 * f1->EvalPar(xx);
2774 if (TF1::RejectedPoint())
continue;
2775 if (cu) w = RetrieveBinContent(bin) / cu;
2777 UpdateBinContent(bin, w);
2779 if (cu != 0) fSumw2.fArray[bin] = GetBinErrorSqUnchecked(bin) / (cu * cu);
2780 else fSumw2.fArray[bin] = 0;
2806 Bool_t TH1::Divide(
const TH1 *h1)
2809 Error(
"Divide",
"Input histogram passed does not exist (NULL).");
2814 if (fBuffer) BufferEmpty(1);
2817 CheckConsistency(
this,h1);
2818 }
catch(DifferentNumberOfBins&) {
2819 Error(
"Divide",
"Cannot divide histograms with different number of bins");
2821 }
catch(DifferentAxisLimits&) {
2822 Warning(
"Divide",
"Dividing histograms with different axis limits");
2823 }
catch(DifferentBinLimits&) {
2824 Warning(
"Divide",
"Dividing histograms with different bin limits");
2825 }
catch(DifferentLabels&) {
2826 Warning(
"Divide",
"Dividing histograms with different labels");
2830 if (fSumw2.fN == 0 && h1->GetSumw2N() != 0) Sumw2();
2833 for (Int_t i = 0; i < fNcells; ++i) {
2834 Double_t c0 = RetrieveBinContent(i);
2835 Double_t c1 = h1->RetrieveBinContent(i);
2836 if (c1) UpdateBinContent(i, c0 / c1);
2837 else UpdateBinContent(i, 0);
2840 if (c1 == 0) { fSumw2.fArray[i] = 0;
continue; }
2841 Double_t c1sq = c1 * c1;
2842 fSumw2.fArray[i] = (GetBinErrorSqUnchecked(i) * c1sq + h1->GetBinErrorSqUnchecked(i) * c0 * c0) / (c1sq * c1sq);
2873 Bool_t TH1::Divide(
const TH1 *h1,
const TH1 *h2, Double_t c1, Double_t c2, Option_t *option)
2876 TString opt = option;
2878 Bool_t binomial = kFALSE;
2879 if (opt.Contains(
"b")) binomial = kTRUE;
2881 Error(
"Divide",
"At least one of the input histograms passed does not exist (NULL).");
2886 if (fBuffer) BufferEmpty(1);
2889 CheckConsistency(h1,h2);
2890 CheckConsistency(
this,h1);
2891 }
catch(DifferentNumberOfBins&) {
2892 Error(
"Divide",
"Cannot divide histograms with different number of bins");
2894 }
catch(DifferentAxisLimits&) {
2895 Warning(
"Divide",
"Dividing histograms with different axis limits");
2896 }
catch(DifferentBinLimits&) {
2897 Warning(
"Divide",
"Dividing histograms with different bin limits");
2898 }
catch(DifferentLabels&) {
2899 Warning(
"Divide",
"Dividing histograms with different labels");
2904 Error(
"Divide",
"Coefficient of dividing histogram cannot be zero");
2909 if (fSumw2.fN == 0 && (h1->GetSumw2N() != 0 || h2->GetSumw2N() != 0 || binomial)) Sumw2();
2915 for (Int_t i = 0; i < fNcells; ++i) {
2916 Double_t b1 = h1->RetrieveBinContent(i);
2917 Double_t b2 = h2->RetrieveBinContent(i);
2918 if (b2) UpdateBinContent(i, c1 * b1 / (c2 * b2));
2919 else UpdateBinContent(i, 0);
2922 if (b2 == 0) { fSumw2.fArray[i] = 0;
continue; }
2923 Double_t b1sq = b1 * b1; Double_t b2sq = b2 * b2;
2924 Double_t c1sq = c1 * c1; Double_t c2sq = c2 * c2;
2925 Double_t e1sq = h1->GetBinErrorSqUnchecked(i);
2926 Double_t e2sq = h2->GetBinErrorSqUnchecked(i);
2934 fSumw2.fArray[i] = TMath::Abs( ( (1. - 2.* b1 / b2) * e1sq + b1sq * e2sq / b2sq ) / b2sq );
2938 fSumw2.fArray[i] = 0;
2941 fSumw2.fArray[i] = c1sq * c2sq * (e1sq * b2sq + e2sq * b1sq) / (c2sq * c2sq * b2sq * b2sq);
2948 SetEntries ( h2->GetEntries() );
2983 void TH1::Draw(Option_t *option)
2985 TString opt1 = option; opt1.ToLower();
2986 TString opt2 = option;
2987 Int_t index = opt1.Index(
"same");
2991 Int_t indb = opt1.Index(
"[");
2993 Int_t indk = opt1.Index(
"]");
2994 if (index>indb && index<indk) index = -1;
3000 if (!gPad->IsEditable()) gROOT->MakeDefCanvas();
3002 if (gPad->GetX1() == 0 && gPad->GetX2() == 1 &&
3003 gPad->GetY1() == 0 && gPad->GetY2() == 1 &&
3004 gPad->GetListOfPrimitives()->GetSize()==0) opt2.Remove(index,4);
3008 if (TestBit(kCanDelete)) gPad->GetListOfPrimitives()->Remove(
this);
3011 gPad->IncrementPaletteColor(1, opt1);
3013 if (index>=0) opt2.Remove(index,4);
3016 AppendPad(opt2.Data());
3030 TH1 *TH1::DrawCopy(Option_t *option,
const char * name_postfix)
const
3032 TString opt = option;
3034 if (gPad && !opt.Contains(
"same")) gPad->Clear();
3035 TString newName = (name_postfix) ? TString::Format(
"%s%s",GetName(),name_postfix) :
"";
3036 TH1 *newth1 = (TH1 *)Clone(newName);
3037 newth1->SetDirectory(0);
3038 newth1->SetBit(kCanDelete);
3039 if (gPad) gPad->IncrementPaletteColor(1, opt);
3041 newth1->AppendPad(option);
3060 TH1 *TH1::DrawNormalized(Option_t *option, Double_t norm)
const
3062 Double_t sum = GetSumOfWeights();
3064 Error(
"DrawNormalized",
"Sum of weights is null. Cannot normalize histogram: %s",GetName());
3067 Bool_t addStatus = TH1::AddDirectoryStatus();
3068 TH1::AddDirectory(kFALSE);
3069 TH1 *h = (TH1*)Clone();
3070 h->SetBit(kCanDelete);
3072 TString opt(option); opt.ToUpper();
3073 if (fSumw2.fN == 0) {
3076 if (opt.IsNull() || opt ==
"SAME") opt +=
"HIST";
3079 if (TMath::Abs(fMaximum+1111) > 1e-3) h->SetMaximum(fMaximum*norm/sum);
3080 if (TMath::Abs(fMinimum+1111) > 1e-3) h->SetMinimum(fMinimum*norm/sum);
3082 TH1::AddDirectory(addStatus);
3091 void TH1::DrawPanel()
3093 if (!fPainter) {Draw();
if (gPad) gPad->Update();}
3094 if (fPainter) fPainter->DrawPanel();
3108 void TH1::Eval(TF1 *f1, Option_t *option)
3111 Int_t range, stat, add;
3114 TString opt = option;
3116 if (opt.Contains(
"a")) add = 1;
3118 if (opt.Contains(
"s")) stat = 1;
3120 if (opt.Contains(
"r")) range = 1;
3124 if (fBuffer) BufferEmpty(1);
3126 Int_t nbinsx = fXaxis.GetNbins();
3127 Int_t nbinsy = fYaxis.GetNbins();
3128 Int_t nbinsz = fZaxis.GetNbins();
3131 for (Int_t binz = 1; binz <= nbinsz; ++binz) {
3132 x[2] = fZaxis.GetBinCenter(binz);
3133 for (Int_t biny = 1; biny <= nbinsy; ++biny) {
3134 x[1] = fYaxis.GetBinCenter(biny);
3135 for (Int_t binx = 1; binx <= nbinsx; ++binx) {
3136 Int_t bin = GetBin(binx,biny,binz);
3137 x[0] = fXaxis.GetBinCenter(binx);
3138 if (range && !f1->IsInside(x))
continue;
3139 Double_t fu = f1->Eval(x[0], x[1], x[2]);
3140 if (stat) fu = gRandom->PoissonD(fu);
3141 AddBinContent(bin, fu);
3142 if (fSumw2.fN) fSumw2.fArray[bin] += TMath::Abs(fu);
3156 void TH1::ExecuteEvent(Int_t event, Int_t px, Int_t py)
3158 if (fPainter) fPainter->ExecuteEvent(event, px, py);
3200 TH1* TH1::FFT(TH1* h_output, Option_t *option)
3204 ndim[0] = this->GetNbinsX();
3205 ndim[1] = this->GetNbinsY();
3206 ndim[2] = this->GetNbinsZ();
3209 TString opt = option;
3211 if (!opt.Contains(
"2R")){
3212 if (!opt.Contains(
"2C") && !opt.Contains(
"2HC") && !opt.Contains(
"DHT")) {
3216 fft = TVirtualFFT::FFT(this->GetDimension(), ndim, opt.Data());
3220 Int_t ind = opt.Index(
"R2R", 3);
3221 Int_t *kind =
new Int_t[2];
3225 if (h_output->GetDimension()>1) {
3229 fft = TVirtualFFT::SineCosine(this->GetDimension(), ndim, kind, option);
3235 for (Int_t binx = 1; binx<=ndim[0]; binx++) {
3236 for (Int_t biny=1; biny<=ndim[1]; biny++) {
3237 for (Int_t binz=1; binz<=ndim[2]; binz++) {
3238 fft->SetPoint(in, this->GetBinContent(binx, biny, binz));
3244 h_output = TransformHisto(fft, h_output, option);
3260 Int_t TH1::Fill(Double_t x)
3262 if (fBuffer)
return BufferFill(x,1);
3266 bin =fXaxis.FindBin(x);
3267 if (bin <0)
return -1;
3269 if (fSumw2.fN) ++fSumw2.fArray[bin];
3270 if (bin == 0 || bin > fXaxis.GetNbins()) {
3271 if (!GetStatOverflowsBehaviour())
return -1;
3292 Int_t TH1::Fill(Double_t x, Double_t w)
3295 if (fBuffer)
return BufferFill(x,w);
3299 bin =fXaxis.FindBin(x);
3300 if (bin <0)
return -1;
3301 if (!fSumw2.fN && w != 1.0 && !TestBit(TH1::kIsNotW) ) Sumw2();
3302 if (fSumw2.fN) fSumw2.fArray[bin] += w*w;
3303 AddBinContent(bin, w);
3304 if (bin == 0 || bin > fXaxis.GetNbins()) {
3305 if (!GetStatOverflowsBehaviour())
return -1;
3328 Int_t TH1::Fill(
const char *namex, Double_t w)
3332 bin =fXaxis.FindBin(namex);
3333 if (bin <0)
return -1;
3334 if (!fSumw2.fN && w != 1.0 && !TestBit(TH1::kIsNotW)) Sumw2();
3335 if (fSumw2.fN) fSumw2.fArray[bin] += w*w;
3336 AddBinContent(bin, w);
3337 if (bin == 0 || bin > fXaxis.GetNbins())
return -1;
3342 if (!CanExtendAllAxes()) {
3343 Double_t x = fXaxis.GetBinCenter(bin);
3363 void TH1::FillN(Int_t ntimes,
const Double_t *x,
const Double_t *w, Int_t stride)
3369 for (i=0;i<ntimes;i+=stride) {
3370 if (!fBuffer)
break;
3371 if (w) BufferFill(x[i],w[i]);
3372 else BufferFill(x[i], 1.);
3375 if (i < ntimes && fBuffer==0) {
3376 auto weights = w ? &w[i] :
nullptr;
3377 DoFillN((ntimes-i)/stride,&x[i],weights,stride);
3382 DoFillN(ntimes, x, w, stride);
3389 void TH1::DoFillN(Int_t ntimes,
const Double_t *x,
const Double_t *w, Int_t stride)
3395 Int_t nbins = fXaxis.GetNbins();
3397 for (i=0;i<ntimes;i+=stride) {
3398 bin =fXaxis.FindBin(x[i]);
3399 if (bin <0)
continue;
3401 if (!fSumw2.fN && ww != 1.0 && !TestBit(TH1::kIsNotW)) Sumw2();
3402 if (fSumw2.fN) fSumw2.fArray[bin] += ww*ww;
3403 AddBinContent(bin, ww);
3404 if (bin == 0 || bin > nbins) {
3405 if (!GetStatOverflowsBehaviour())
continue;
3411 fTsumwx2 += z*x[i]*x[i];
3430 void TH1::FillRandom(
const char *fname, Int_t ntimes)
3432 Int_t bin, binx, ibin, loop;
3435 TF1 *f1 = (TF1*)gROOT->GetFunction(fname);
3436 if (!f1) { Error(
"FillRandom",
"Unknown function: %s",fname);
return; }
3440 TAxis * xAxis = &fXaxis;
3443 if (fXaxis.GetXmax() <= fXaxis.GetXmin()) {
3445 f1->GetRange(xmin,xmax);
3446 Info(
"FillRandom",
"Using function axis and range [%g,%g]",xmin, xmax);
3447 xAxis = f1->GetHistogram()->GetXaxis();
3450 Int_t first = xAxis->GetFirst();
3451 Int_t last = xAxis->GetLast();
3452 Int_t nbinsx = last-first+1;
3454 Double_t *integral =
new Double_t[nbinsx+1];
3456 for (binx=1;binx<=nbinsx;binx++) {
3457 Double_t fint = f1->Integral(xAxis->GetBinLowEdge(binx+first-1),xAxis->GetBinUpEdge(binx+first-1), 0.);
3458 integral[binx] = integral[binx-1] + fint;
3462 if (integral[nbinsx] == 0 ) {
3464 Error(
"FillRandom",
"Integral = zero");
return;
3466 for (bin=1;bin<=nbinsx;bin++) integral[bin] /= integral[nbinsx];
3469 for (loop=0;loop<ntimes;loop++) {
3470 r1 = gRandom->Rndm();
3471 ibin = TMath::BinarySearch(nbinsx,&integral[0],r1);
3474 x = xAxis->GetBinLowEdge(ibin+first)
3475 +xAxis->GetBinWidth(ibin+first)*(r1-integral[ibin])/(integral[ibin+1] - integral[ibin]);
3497 void TH1::FillRandom(TH1 *h, Int_t ntimes)
3499 if (!h) { Error(
"FillRandom",
"Null histogram");
return; }
3500 if (fDimension != h->GetDimension()) {
3501 Error(
"FillRandom",
"Histograms with different dimensions");
return;
3503 if (std::isnan(h->ComputeIntegral(
true))) {
3504 Error(
"FillRandom",
"Histograms contains negative bins, does not represent probabilities");
3510 Int_t first = fXaxis.GetFirst();
3511 Int_t last = fXaxis.GetLast();
3512 Int_t nbins = last-first+1;
3513 if (ntimes > 10*nbins) {
3515 CheckConsistency(
this,h);
3516 Double_t sumw = h->Integral(first,last);
3517 if (sumw == 0)
return;
3518 Double_t sumgen = 0;
3519 for (Int_t bin=first;bin<=last;bin++) {
3520 Double_t mean = h->RetrieveBinContent(bin)*ntimes/sumw;
3521 Double_t cont = (Double_t)gRandom->Poisson(mean);
3523 AddBinContent(bin,cont);
3524 if (fSumw2.fN) fSumw2.fArray[bin] += cont;
3531 if (sumgen < ntimes) {
3533 for (i = Int_t(sumgen+0.5); i < ntimes; ++i)
3535 Double_t x = h->GetRandom();
3539 else if (sumgen > ntimes) {
3541 i = Int_t(sumgen+0.5);
3542 while( i > ntimes) {
3543 Double_t x = h->GetRandom();
3544 Int_t ibin = fXaxis.FindBin(x);
3545 Double_t y = RetrieveBinContent(ibin);
3548 SetBinContent(ibin, y-1.);
3557 catch(std::exception&) {}
3561 if (h->ComputeIntegral() ==0)
return;
3564 for (loop=0;loop<ntimes;loop++) {
3581 Int_t TH1::FindBin(Double_t x, Double_t y, Double_t z)
3583 if (GetDimension() < 2) {
3584 return fXaxis.FindBin(x);
3586 if (GetDimension() < 3) {
3587 Int_t nx = fXaxis.GetNbins()+2;
3588 Int_t binx = fXaxis.FindBin(x);
3589 Int_t biny = fYaxis.FindBin(y);
3590 return binx + nx*biny;
3592 if (GetDimension() < 4) {
3593 Int_t nx = fXaxis.GetNbins()+2;
3594 Int_t ny = fYaxis.GetNbins()+2;
3595 Int_t binx = fXaxis.FindBin(x);
3596 Int_t biny = fYaxis.FindBin(y);
3597 Int_t binz = fZaxis.FindBin(z);
3598 return binx + nx*(biny +ny*binz);
3614 Int_t TH1::FindFixBin(Double_t x, Double_t y, Double_t z)
const
3616 if (GetDimension() < 2) {
3617 return fXaxis.FindFixBin(x);
3619 if (GetDimension() < 3) {
3620 Int_t nx = fXaxis.GetNbins()+2;
3621 Int_t binx = fXaxis.FindFixBin(x);
3622 Int_t biny = fYaxis.FindFixBin(y);
3623 return binx + nx*biny;
3625 if (GetDimension() < 4) {
3626 Int_t nx = fXaxis.GetNbins()+2;
3627 Int_t ny = fYaxis.GetNbins()+2;
3628 Int_t binx = fXaxis.FindFixBin(x);
3629 Int_t biny = fYaxis.FindFixBin(y);
3630 Int_t binz = fZaxis.FindFixBin(z);
3631 return binx + nx*(biny +ny*binz);
3643 Int_t TH1::FindFirstBinAbove(Double_t threshold, Int_t axis, Int_t firstBin, Int_t lastBin)
const
3645 if (fBuffer) ((TH1*)
this)->BufferEmpty();
3647 if (axis < 1 || (axis > 1 && GetDimension() == 1 ) ||
3648 ( axis > 2 && GetDimension() == 2 ) || ( axis > 3 && GetDimension() > 3 ) ) {
3649 Warning(
"FindFirstBinAbove",
"Invalid axis number : %d, axis x assumed\n",axis);
3655 Int_t nbinsx = fXaxis.GetNbins();
3656 Int_t nbinsy = (GetDimension() > 1 ) ? fYaxis.GetNbins() : 1;
3657 Int_t nbinsz = (GetDimension() > 2 ) ? fZaxis.GetNbins() : 1;
3660 if (lastBin < 0 || lastBin > fXaxis.GetNbins()) {
3661 lastBin = fXaxis.GetNbins();
3663 for (Int_t binx = firstBin; binx <= lastBin; binx++) {
3664 for (Int_t biny = 1; biny <= nbinsy; biny++) {
3665 for (Int_t binz = 1; binz <= nbinsz; binz++) {
3666 if (RetrieveBinContent(GetBin(binx,biny,binz)) > threshold)
return binx;
3671 else if (axis == 2) {
3672 if (lastBin < 0 || lastBin > fYaxis.GetNbins()) {
3673 lastBin = fYaxis.GetNbins();
3675 for (Int_t biny = firstBin; biny <= lastBin; biny++) {
3676 for (Int_t binx = 1; binx <= nbinsx; binx++) {
3677 for (Int_t binz = 1; binz <= nbinsz; binz++) {
3678 if (RetrieveBinContent(GetBin(binx,biny,binz)) > threshold)
return biny;
3683 else if (axis == 3) {
3684 if (lastBin < 0 || lastBin > fZaxis.GetNbins()) {
3685 lastBin = fZaxis.GetNbins();
3687 for (Int_t binz = firstBin; binz <= lastBin; binz++) {
3688 for (Int_t binx = 1; binx <= nbinsx; binx++) {
3689 for (Int_t biny = 1; biny <= nbinsy; biny++) {
3690 if (RetrieveBinContent(GetBin(binx,biny,binz)) > threshold)
return binz;
3706 Int_t TH1::FindLastBinAbove(Double_t threshold, Int_t axis, Int_t firstBin, Int_t lastBin)
const
3708 if (fBuffer) ((TH1*)
this)->BufferEmpty();
3711 if (axis < 1 || ( axis > 1 && GetDimension() == 1 ) ||
3712 ( axis > 2 && GetDimension() == 2 ) || ( axis > 3 && GetDimension() > 3) ) {
3713 Warning(
"FindFirstBinAbove",
"Invalid axis number : %d, axis x assumed\n",axis);
3719 Int_t nbinsx = fXaxis.GetNbins();
3720 Int_t nbinsy = (GetDimension() > 1 ) ? fYaxis.GetNbins() : 1;
3721 Int_t nbinsz = (GetDimension() > 2 ) ? fZaxis.GetNbins() : 1;
3724 if (lastBin < 0 || lastBin > fXaxis.GetNbins()) {
3725 lastBin = fXaxis.GetNbins();
3727 for (Int_t binx = lastBin; binx >= firstBin; binx--) {
3728 for (Int_t biny = 1; biny <= nbinsy; biny++) {
3729 for (Int_t binz = 1; binz <= nbinsz; binz++) {
3730 if (RetrieveBinContent(GetBin(binx, biny, binz)) > threshold)
return binx;
3735 else if (axis == 2) {
3736 if (lastBin < 0 || lastBin > fYaxis.GetNbins()) {
3737 lastBin = fYaxis.GetNbins();
3739 for (Int_t biny = lastBin; biny >= firstBin; biny--) {
3740 for (Int_t binx = 1; binx <= nbinsx; binx++) {
3741 for (Int_t binz = 1; binz <= nbinsz; binz++) {
3742 if (RetrieveBinContent(GetBin(binx, biny, binz)) > threshold)
return biny;
3747 else if (axis == 3) {
3748 if (lastBin < 0 || lastBin > fZaxis.GetNbins()) {
3749 lastBin = fZaxis.GetNbins();
3751 for (Int_t binz = lastBin; binz >= firstBin; binz--) {
3752 for (Int_t binx = 1; binx <= nbinsx; binx++) {
3753 for (Int_t biny = 1; biny <= nbinsy; biny++) {
3754 if (RetrieveBinContent(GetBin(binx, biny, binz)) > threshold)
return binz;
3766 TObject *TH1::FindObject(
const char *name)
const
3768 if (fFunctions)
return fFunctions->FindObject(name);
3775 TObject *TH1::FindObject(
const TObject *obj)
const
3777 if (fFunctions)
return fFunctions->FindObject(obj);
3793 TFitResultPtr TH1::Fit(
const char *fname ,Option_t *option ,Option_t *goption, Double_t xxmin, Double_t xxmax)
3796 linear= (
char*)strstr(fname,
"++");
3797 Int_t ndim=GetDimension();
3800 TF1 f1(fname, fname, xxmin, xxmax);
3801 return Fit(&f1,option,goption,xxmin,xxmax);
3804 TF2 f2(fname, fname);
3805 return Fit(&f2,option,goption,xxmin,xxmax);
3808 TF3 f3(fname, fname);
3809 return Fit(&f3,option,goption,xxmin,xxmax);
3813 TF1 * f1 = (TF1*)gROOT->GetFunction(fname);
3814 if (!f1) { Printf(
"Unknown function: %s",fname);
return -1; }
3815 return Fit(f1,option,goption,xxmin,xxmax);
4118 TFitResultPtr TH1::Fit(TF1 *f1 ,Option_t *option ,Option_t *goption, Double_t xxmin, Double_t xxmax)
4121 Foption_t fitOption;
4122 ROOT::Fit::FitOptionsMake(ROOT::Fit::kHistogram,option,fitOption);
4125 ROOT::Fit::DataRange range(xxmin,xxmax);
4126 ROOT::Math::MinimizerOptions minOption;
4130 if (fBuffer) BufferEmpty();
4132 return ROOT::Fit::FitObject(
this, f1 , fitOption , minOption, goption, range);
4140 void TH1::FitPanel()
4143 gROOT->MakeDefCanvas();
4146 Error(
"FitPanel",
"Unable to create a default canvas");
4152 TPluginHandler *handler = gROOT->GetPluginManager()->FindHandler(
"TFitEditor");
4153 if (handler && handler->LoadPlugin() != -1) {
4154 if (handler->ExecPlugin(2, gPad,
this) == 0)
4155 Error(
"FitPanel",
"Unable to create the FitPanel");
4158 Error(
"FitPanel",
"Unable to find the FitPanel plug-in");
4195 TH1 *TH1::GetAsymmetry(TH1* h2, Double_t c2, Double_t dc2)
4198 TString name = TString::Format(
"Asymmetry_%s-%s",h1->GetName(),h2->GetName() );
4199 TH1 *asym = (TH1*)Clone(name);
4202 TString title = TString::Format(
"(%s - %s)/(%s+%s)",h1->GetName(),h2->GetName(),h1->GetName(),h2->GetName() );
4203 asym->SetTitle(title);
4206 Bool_t addStatus = TH1::AddDirectoryStatus();
4207 TH1::AddDirectory(kFALSE);
4208 TH1 *top = (TH1*)asym->Clone();
4209 TH1 *bottom = (TH1*)asym->Clone();
4210 TH1::AddDirectory(addStatus);
4213 top->Add(h1,h2,1,-c2);
4214 bottom->Add(h1,h2,1,c2);
4215 asym->Divide(top,bottom);
4217 Int_t xmax = asym->GetNbinsX();
4218 Int_t ymax = asym->GetNbinsY();
4219 Int_t zmax = asym->GetNbinsZ();
4221 if (h1->fBuffer) h1->BufferEmpty(1);
4222 if (h2->fBuffer) h2->BufferEmpty(1);
4223 if (bottom->fBuffer) bottom->BufferEmpty(1);
4227 for(Int_t i=1; i<= xmax; i++){
4228 for(Int_t j=1; j<= ymax; j++){
4229 for(Int_t k=1; k<= zmax; k++){
4230 Int_t bin = GetBin(i, j, k);
4233 Double_t a = h1->RetrieveBinContent(bin);
4234 Double_t b = h2->RetrieveBinContent(bin);
4235 Double_t bot = bottom->RetrieveBinContent(bin);
4243 Double_t dasq = h1->GetBinErrorSqUnchecked(bin);
4244 Double_t dbsq = h2->GetBinErrorSqUnchecked(bin);
4245 Double_t error = 2*TMath::Sqrt(a*a*c2*c2*dbsq + c2*c2*b*b*dasq+a*a*b*b*dc2*dc2)/(bot*bot);
4246 asym->SetBinError(i,j,k,error);
4262 Int_t TH1::GetDefaultBufferSize()
4264 return fgBufferSize;
4271 Bool_t TH1::GetDefaultSumw2()
4273 return fgDefaultSumw2;
4279 Double_t TH1::GetEntries()
const
4282 Int_t nentries = (Int_t) fBuffer[0];
4283 if (nentries > 0)
return nentries;
4304 Double_t TH1::GetEffectiveEntries()
const
4308 return (s[1] ? s[0]*s[0]/s[1] : TMath::Abs(s[0]) );
4315 void TH1::SetHighlight(Bool_t set)
4317 if (IsHighlight() == set)
return;
4318 if (fDimension > 2) {
4319 Info(
"SetHighlight",
"Supported only 1-D or 2-D histograms");
4324 Info(
"SetHighlight",
"Need to draw histogram first");
4327 SetBit(kIsHighlight, set);
4328 fPainter->SetHighlight();
4336 char *TH1::GetObjectInfo(Int_t px, Int_t py)
const
4338 return ((TH1*)
this)->GetPainter()->GetObjectInfo(px,py);
4345 TVirtualHistPainter *TH1::GetPainter(Option_t *option)
4348 TString opt = option;
4350 if (opt.Contains(
"gl") || gStyle->GetCanvasPreferGL()) {
4352 TPluginHandler *handler = gROOT->GetPluginManager()->FindHandler(
"TGLHistPainter");
4354 if (handler && handler->LoadPlugin() != -1)
4355 fPainter = reinterpret_cast<TVirtualHistPainter *>(handler->ExecPlugin(1,
this));
4359 if (!fPainter) fPainter = TVirtualHistPainter::HistPainter(
this);
4436 Int_t TH1::GetQuantiles(Int_t nprobSum, Double_t *q,
const Double_t *probSum)
4438 if (GetDimension() > 1) {
4439 Error(
"GetQuantiles",
"Only available for 1-d histograms");
4443 const Int_t nbins = GetXaxis()->GetNbins();
4444 if (!fIntegral) ComputeIntegral();
4445 if (fIntegral[nbins+1] != fEntries) ComputeIntegral();
4448 Double_t *prob = (Double_t*)probSum;
4449 Int_t nq = nprobSum;
4452 prob =
new Double_t[nq];
4454 for (i=1;i<nq;i++) {
4455 prob[i] = fIntegral[i]/fIntegral[nbins];
4459 for (i = 0; i < nq; i++) {
4460 ibin = TMath::BinarySearch(nbins,fIntegral,prob[i]);
4461 while (ibin < nbins-1 && fIntegral[ibin+1] == prob[i]) {
4462 if (fIntegral[ibin+2] == prob[i]) ibin++;
4465 q[i] = GetBinLowEdge(ibin+1);
4466 const Double_t dint = fIntegral[ibin+1]-fIntegral[ibin];
4467 if (dint > 0) q[i] += GetBinWidth(ibin+1)*(prob[i]-fIntegral[ibin])/dint;
4470 if (!probSum)
delete [] prob;
4477 Int_t TH1::FitOptionsMake(Option_t *choptin, Foption_t &fitOption)
4479 ROOT::Fit::FitOptionsMake(ROOT::Fit::kHistogram, choptin,fitOption);
4488 Double_t allcha, sumx, sumx2, x, val, stddev, mean;
4490 const Double_t sqrtpi = 2.506628;
4493 TVirtualFitter *hFitter = TVirtualFitter::GetFitter();
4494 TH1 *curHist = (TH1*)hFitter->GetObjectFit();
4495 Int_t hxfirst = hFitter->GetXfirst();
4496 Int_t hxlast = hFitter->GetXlast();
4497 Double_t valmax = curHist->GetBinContent(hxfirst);
4498 Double_t binwidx = curHist->GetBinWidth(hxfirst);
4499 allcha = sumx = sumx2 = 0;
4500 for (bin=hxfirst;bin<=hxlast;bin++) {
4501 x = curHist->GetBinCenter(bin);
4502 val = TMath::Abs(curHist->GetBinContent(bin));
4503 if (val > valmax) valmax = val;
4508 if (allcha == 0)
return;
4510 stddev = sumx2/allcha - mean*mean;
4511 if (stddev > 0) stddev = TMath::Sqrt(stddev);
4513 if (stddev == 0) stddev = binwidx*(hxlast-hxfirst+1)/4;
4520 Double_t constant = 0.5*(valmax+binwidx*allcha/(sqrtpi*stddev));
4526 Double_t xmin = curHist->GetXaxis()->GetXmin();
4527 Double_t xmax = curHist->GetXaxis()->GetXmax();
4528 if ((mean < xmin || mean > xmax) && stddev > (xmax-xmin)) {
4529 mean = 0.5*(xmax+xmin);
4530 stddev = 0.5*(xmax-xmin);
4532 TF1 *f1 = (TF1*)hFitter->GetUserFunc();
4533 f1->SetParameter(0,constant);
4534 f1->SetParameter(1,mean);
4535 f1->SetParameter(2,stddev);
4536 f1->SetParLimits(2,0,10*stddev);
4544 Double_t constant, slope;
4546 TVirtualFitter *hFitter = TVirtualFitter::GetFitter();
4547 Int_t hxfirst = hFitter->GetXfirst();
4548 Int_t hxlast = hFitter->GetXlast();
4549 Int_t nchanx = hxlast - hxfirst + 1;
4551 H1LeastSquareLinearFit(-nchanx, constant, slope, ifail);
4553 TF1 *f1 = (TF1*)hFitter->GetUserFunc();
4554 f1->SetParameter(0,constant);
4555 f1->SetParameter(1,slope);
4562 void H1InitPolynom()
4564 Double_t fitpar[25];
4566 TVirtualFitter *hFitter = TVirtualFitter::GetFitter();
4567 TF1 *f1 = (TF1*)hFitter->GetUserFunc();
4568 Int_t hxfirst = hFitter->GetXfirst();
4569 Int_t hxlast = hFitter->GetXlast();
4570 Int_t nchanx = hxlast - hxfirst + 1;
4571 Int_t npar = f1->GetNpar();
4573 if (nchanx <=1 || npar == 1) {
4574 TH1 *curHist = (TH1*)hFitter->GetObjectFit();
4575 fitpar[0] = curHist->GetSumOfWeights()/Double_t(nchanx);
4577 H1LeastSquareFit( nchanx, npar, fitpar);
4579 for (Int_t i=0;i<npar;i++) f1->SetParameter(i, fitpar[i]);
4592 void H1LeastSquareFit(Int_t n, Int_t m, Double_t *a)
4594 const Double_t zero = 0.;
4595 const Double_t one = 1.;
4596 const Int_t idim = 20;
4599 Int_t i, k, l, ifail;
4601 Double_t da[20], xk, yk;
4604 H1LeastSquareLinearFit(n, a[0], a[1], ifail);
4607 if (m > idim || m > n)
return;
4610 for (l = 2; l <= m; ++l) {
4612 b[m + l*20 - 21] = zero;
4615 TVirtualFitter *hFitter = TVirtualFitter::GetFitter();
4616 TH1 *curHist = (TH1*)hFitter->GetObjectFit();
4617 Int_t hxfirst = hFitter->GetXfirst();
4618 Int_t hxlast = hFitter->GetXlast();
4619 for (k = hxfirst; k <= hxlast; ++k) {
4620 xk = curHist->GetBinCenter(k);
4621 yk = curHist->GetBinContent(k);
4624 for (l = 2; l <= m; ++l) {
4627 da[l-1] += power*yk;
4629 for (l = 2; l <= m; ++l) {
4631 b[m + l*20 - 21] += power;
4634 for (i = 3; i <= m; ++i) {
4635 for (k = i; k <= m; ++k) {
4636 b[k - 1 + (i-1)*20 - 21] = b[k + (i-2)*20 - 21];
4639 H1LeastSquareSeqnd(m, b, idim, ifail, 1, da);
4641 for (i=0; i<m; ++i) a[i] = da[i];
4651 void H1LeastSquareLinearFit(Int_t ndata, Double_t &a0, Double_t &a1, Int_t &ifail)
4653 Double_t xbar, ybar, x2bar;
4656 Double_t fn, xk, yk;
4659 n = TMath::Abs(ndata);
4661 xbar = ybar = x2bar = xybar = 0;
4662 TVirtualFitter *hFitter = TVirtualFitter::GetFitter();
4663 TH1 *curHist = (TH1*)hFitter->GetObjectFit();
4664 Int_t hxfirst = hFitter->GetXfirst();
4665 Int_t hxlast = hFitter->GetXlast();
4666 for (i = hxfirst; i <= hxlast; ++i) {
4667 xk = curHist->GetBinCenter(i);
4668 yk = curHist->GetBinContent(i);
4670 if (yk <= 0) yk = 1e-9;
4671 yk = TMath::Log(yk);
4679 det = fn*x2bar - xbar*xbar;
4687 a0 = (x2bar*ybar - xbar*xybar) / det;
4688 a1 = (fn*xybar - xbar*ybar) / det;
4697 void H1LeastSquareSeqnd(Int_t n, Double_t *a, Int_t idim, Int_t &ifail, Int_t k, Double_t *b)
4699 Int_t a_dim1, a_offset, b_dim1, b_offset;
4700 Int_t nmjp1, i, j, l;
4701 Int_t im1, jp1, nm1, nmi;
4702 Double_t s1, s21, s22;
4703 const Double_t one = 1.;
4707 b_offset = b_dim1 + 1;
4710 a_offset = a_dim1 + 1;
4713 if (idim < n)
return;
4716 for (j = 1; j <= n; ++j) {
4717 if (a[j + j*a_dim1] <= 0) { ifail = -1;
return; }
4718 a[j + j*a_dim1] = one / a[j + j*a_dim1];
4719 if (j == n)
continue;
4721 for (l = jp1; l <= n; ++l) {
4722 a[j + l*a_dim1] = a[j + j*a_dim1] * a[l + j*a_dim1];
4723 s1 = -a[l + (j+1)*a_dim1];
4724 for (i = 1; i <= j; ++i) { s1 = a[l + i*a_dim1] * a[i + (j+1)*a_dim1] + s1; }
4725 a[l + (j+1)*a_dim1] = -s1;
4730 for (l = 1; l <= k; ++l) {
4731 b[l*b_dim1 + 1] = a[a_dim1 + 1]*b[l*b_dim1 + 1];
4734 for (l = 1; l <= k; ++l) {
4735 for (i = 2; i <= n; ++i) {
4737 s21 = -b[i + l*b_dim1];
4738 for (j = 1; j <= im1; ++j) {
4739 s21 = a[i + j*a_dim1]*b[j + l*b_dim1] + s21;
4741 b[i + l*b_dim1] = -a[i + i*a_dim1]*s21;
4744 for (i = 1; i <= nm1; ++i) {
4746 s22 = -b[nmi + l*b_dim1];
4747 for (j = 1; j <= i; ++j) {
4749 s22 = a[nmi + nmjp1*a_dim1]*b[nmjp1 + l*b_dim1] + s22;
4751 b[nmi + l*b_dim1] = -s22;
4786 Int_t TH1::GetBin(Int_t binx, Int_t, Int_t)
const
4788 Int_t ofx = fXaxis.GetNbins() + 1;
4789 if (binx < 0) binx = 0;
4790 if (binx > ofx) binx = ofx;
4799 void TH1::GetBinXYZ(Int_t binglobal, Int_t &binx, Int_t &biny, Int_t &binz)
const
4801 Int_t nx = fXaxis.GetNbins()+2;
4802 Int_t ny = fYaxis.GetNbins()+2;
4804 if (GetDimension() == 1) {
4805 binx = binglobal%nx;
4810 if (GetDimension() == 2) {
4811 binx = binglobal%nx;
4812 biny = ((binglobal-binx)/nx)%ny;
4816 if (GetDimension() == 3) {
4817 binx = binglobal%nx;
4818 biny = ((binglobal-binx)/nx)%ny;
4819 binz = ((binglobal-binx)/nx -biny)/ny;
4833 Double_t TH1::GetRandom()
const
4835 if (fDimension > 1) {
4836 Error(
"GetRandom",
"Function only valid for 1-d histograms");
4839 Int_t nbinsx = GetNbinsX();
4840 Double_t integral = 0;
4843 if (fIntegral[nbinsx+1] != fEntries) integral = ((TH1*)
this)->ComputeIntegral(
true);
4844 else integral = fIntegral[nbinsx];
4846 integral = ((TH1*)
this)->ComputeIntegral(
true);
4848 if (integral == 0)
return 0;
4850 if (integral == TMath::QuietNaN() )
return TMath::QuietNaN();
4852 Double_t r1 = gRandom->Rndm();
4853 Int_t ibin = TMath::BinarySearch(nbinsx,fIntegral,r1);
4854 Double_t x = GetBinLowEdge(ibin+1);
4855 if (r1 > fIntegral[ibin]) x +=
4856 GetBinWidth(ibin+1)*(r1-fIntegral[ibin])/(fIntegral[ibin+1] - fIntegral[ibin]);
4884 Double_t TH1::GetBinContent(Int_t bin)
const
4886 if (fBuffer)
const_cast<TH1*
>(
this)->BufferEmpty();
4887 if (bin < 0) bin = 0;
4888 if (bin >= fNcells) bin = fNcells-1;
4890 return RetrieveBinContent(bin);
4909 Double_t TH1::GetBinWithContent(Double_t c, Int_t &binx, Int_t firstx, Int_t lastx,Double_t maxdiff)
const
4911 if (fDimension > 1) {
4913 Error(
"GetBinWithContent",
"function is only valid for 1-D histograms");
4917 if (fBuffer) ((TH1*)
this)->BufferEmpty();
4919 if (firstx <= 0) firstx = 1;
4920 if (lastx < firstx) lastx = fXaxis.GetNbins();
4922 Double_t diff, curmax = 1.e240;
4923 for (Int_t i=firstx;i<=lastx;i++) {
4924 diff = TMath::Abs(RetrieveBinContent(i)-c);
4925 if (diff <= 0) {binx = i;
return diff;}
4926 if (diff < curmax && diff <= maxdiff) {curmax = diff, binminx=i;}
4938 Double_t TH1::Interpolate(Double_t x)
const
4940 if (fBuffer) ((TH1*)
this)->BufferEmpty();
4942 Int_t xbin = fXaxis.FindFixBin(x);
4943 Double_t x0,x1,y0,y1;
4945 if(x<=GetBinCenter(1)) {
4946 return RetrieveBinContent(1);
4947 }
else if(x>=GetBinCenter(GetNbinsX())) {
4948 return RetrieveBinContent(GetNbinsX());
4950 if(x<=GetBinCenter(xbin)) {
4951 y0 = RetrieveBinContent(xbin-1);
4952 x0 = GetBinCenter(xbin-1);
4953 y1 = RetrieveBinContent(xbin);
4954 x1 = GetBinCenter(xbin);
4956 y0 = RetrieveBinContent(xbin);
4957 x0 = GetBinCenter(xbin);
4958 y1 = RetrieveBinContent(xbin+1);
4959 x1 = GetBinCenter(xbin+1);
4961 return y0 + (x-x0)*((y1-y0)/(x1-x0));
4968 Double_t TH1::Interpolate(Double_t, Double_t)
const
4970 Error(
"Interpolate",
"This function must be called with 1 argument for a TH1");
4977 Double_t TH1::Interpolate(Double_t, Double_t, Double_t)
const
4979 Error(
"Interpolate",
"This function must be called with 1 argument for a TH1");
4987 Bool_t TH1::IsEmpty()
const
4992 if (fTsumw != 0)
return kFALSE;
4993 if (GetEntries() != 0)
return kFALSE;
4998 for (
int i = 0; i< GetNcells(); ++i) sumw += RetrieveBinContent(i);
4999 return (sumw != 0) ? kFALSE : kTRUE;
5005 Bool_t TH1::IsBinOverflow(Int_t bin, Int_t iaxis)
const
5007 Int_t binx, biny, binz;
5008 GetBinXYZ(bin, binx, biny, binz);
5011 if ( fDimension == 1 )
5012 return binx >= GetNbinsX() + 1;
5013 if ( fDimension == 2 )
5014 return (binx >= GetNbinsX() + 1) ||
5015 (biny >= GetNbinsY() + 1);
5016 if ( fDimension == 3 )
5017 return (binx >= GetNbinsX() + 1) ||
5018 (biny >= GetNbinsY() + 1) ||
5019 (binz >= GetNbinsZ() + 1);
5023 return binx >= GetNbinsX() + 1;
5025 return biny >= GetNbinsY() + 1;
5027 return binz >= GetNbinsZ() + 1;
5029 Error(
"IsBinOverflow",
"Invalid axis value");
5037 Bool_t TH1::IsBinUnderflow(Int_t bin, Int_t iaxis)
const
5039 Int_t binx, biny, binz;
5040 GetBinXYZ(bin, binx, biny, binz);
5043 if ( fDimension == 1 )
5045 else if ( fDimension == 2 )
5046 return (binx <= 0 || biny <= 0);
5047 else if ( fDimension == 3 )
5048 return (binx <= 0 || biny <= 0 || binz <= 0);
5059 Error(
"IsBinUnderflow",
"Invalid axis value");
5068 void TH1::LabelsDeflate(Option_t *ax)
5070 Int_t iaxis = AxisChoice(ax);
5072 if (iaxis == 1) axis = GetXaxis();
5073 if (iaxis == 2) axis = GetYaxis();
5074 if (iaxis == 3) axis = GetZaxis();
5076 Error(
"LabelsDeflate",
"Invalid axis option %s",ax);
5079 if (!axis->GetLabels())
return;
5084 TIter next(axis->GetLabels());
5087 while ((obj = next())) {
5088 Int_t ibin = obj->GetUniqueID();
5089 if (ibin > nbins) nbins = ibin;
5091 if (nbins < 1) nbins = 1;
5094 if (nbins==axis->GetNbins())
return;
5096 TH1 *hold = (TH1*)IsA()->New();
5098 hold->SetDirectory(0);
5101 Bool_t timedisp = axis->GetTimeDisplay();
5102 Double_t xmin = axis->GetXmin();
5103 Double_t xmax = axis->GetBinUpEdge(nbins);
5104 if (xmax <= xmin) xmax = xmin +nbins;
5105 axis->SetRange(0,0);
5106 axis->Set(nbins,xmin,xmax);
5108 Int_t errors = fSumw2.fN;
5109 if (errors) fSumw2.Set(fNcells);
5110 axis->SetTimeDisplay(timedisp);
5118 Double_t oldEntries = fEntries;
5119 Int_t bin,binx,biny,binz;
5120 for (bin=0; bin < hold->fNcells; ++bin) {
5121 hold->GetBinXYZ(bin,binx,biny,binz);
5122 Int_t ibin = GetBin(binx,biny,binz);
5123 Double_t cu = hold->RetrieveBinContent(bin);
5124 AddBinContent(ibin,cu);
5126 fSumw2.fArray[ibin] += hold->fSumw2.fArray[bin];
5129 fEntries = oldEntries;
5138 void TH1::LabelsInflate(Option_t *ax)
5140 Int_t iaxis = AxisChoice(ax);
5142 if (iaxis == 1) axis = GetXaxis();
5143 if (iaxis == 2) axis = GetYaxis();
5144 if (iaxis == 3) axis = GetZaxis();
5147 TH1 *hold = (TH1*)IsA()->New();;
5148 hold->SetDirectory(0);
5151 Bool_t timedisp = axis->GetTimeDisplay();
5152 Int_t nbins = axis->GetNbins();
5153 Double_t xmin = axis->GetXmin();
5154 Double_t xmax = axis->GetXmax();
5155 xmax = xmin + 2*(xmax-xmin);
5156 axis->SetRange(0,0);
5158 axis->Set(2*nbins,xmin,xmax);
5160 Int_t errors = fSumw2.fN;
5161 if (errors) fSumw2.Set(fNcells);
5162 axis->SetTimeDisplay(timedisp);
5167 Double_t oldEntries = fEntries;
5168 Int_t bin,ibin,binx,biny,binz;
5169 for (ibin =0; ibin < hold->fNcells; ibin++) {
5171 hold->GetBinXYZ(ibin,binx,biny,binz);
5172 bin = GetBin(binx,biny,binz);
5175 if (hold->IsBinUnderflow(ibin,iaxis) || hold->IsBinOverflow(ibin,iaxis)) {
5179 AddBinContent(bin, hold->RetrieveBinContent(ibin));
5180 if (errors) fSumw2.fArray[bin] += hold->fSumw2.fArray[ibin];
5183 fEntries = oldEntries;
5199 void TH1::LabelsOption(Option_t *option, Option_t *ax)
5201 Int_t iaxis = AxisChoice(ax);
5203 if (iaxis == 1) axis = GetXaxis();
5204 if (iaxis == 2) axis = GetYaxis();
5205 if (iaxis == 3) axis = GetZaxis();
5207 THashList *labels = axis->GetLabels();
5209 Warning(
"LabelsOption",
"Cannot sort. No labels");
5212 TString opt = option;
5214 if (opt.Contains(
"h")) {
5215 axis->SetBit(TAxis::kLabelsHori);
5216 axis->ResetBit(TAxis::kLabelsVert);
5217 axis->ResetBit(TAxis::kLabelsDown);
5218 axis->ResetBit(TAxis::kLabelsUp);
5220 if (opt.Contains(
"v")) {
5221 axis->SetBit(TAxis::kLabelsVert);
5222 axis->ResetBit(TAxis::kLabelsHori);
5223 axis->ResetBit(TAxis::kLabelsDown);
5224 axis->ResetBit(TAxis::kLabelsUp);
5226 if (opt.Contains(
"u")) {
5227 axis->SetBit(TAxis::kLabelsUp);
5228 axis->ResetBit(TAxis::kLabelsVert);
5229 axis->ResetBit(TAxis::kLabelsDown);
5230 axis->ResetBit(TAxis::kLabelsHori);
5232 if (opt.Contains(
"d")) {
5233 axis->SetBit(TAxis::kLabelsDown);
5234 axis->ResetBit(TAxis::kLabelsVert);
5235 axis->ResetBit(TAxis::kLabelsHori);
5236 axis->ResetBit(TAxis::kLabelsUp);
5239 if (opt.Contains(
"a")) sort = 0;
5240 if (opt.Contains(
">")) sort = 1;
5241 if (opt.Contains(
"<")) sort = 2;
5242 if (sort < 0)
return;
5243 if (sort > 0 && GetDimension() > 2) {
5244 Error(
"LabelsOption",
"Sorting by value not implemented for 3-D histograms");
5248 Double_t entries = fEntries;
5249 Int_t n = TMath::Min(axis->GetNbins(), labels->GetSize());
5250 std::vector<Int_t> a(n+2);
5253 std::vector<Double_t> cont;
5254 std::vector<Double_t> errors;
5255 THashList *labold =
new THashList(labels->GetSize(),1);
5256 TIter nextold(labels);
5258 while ((obj=nextold())) {
5264 if (GetDimension() == 1) {
5266 if (fSumw2.fN) errors.resize(n);
5267 for (i=1;i<=n;i++) {
5268 cont[i-1] = GetBinContent(i);
5269 if (!errors.empty()) errors[i-1] = GetBinError(i);
5271 if (sort ==1) TMath::Sort(n,cont.data(),a.data(),kTRUE);
5272 else TMath::Sort(n,cont.data(),a.data(),kFALSE);
5273 for (i=1;i<=n;i++) {
5274 SetBinContent(i,cont[a[i-1]]);
5275 if (!errors.empty()) SetBinError(i,errors[a[i-1]]);
5277 for (i=1;i<=n;i++) {
5278 obj = labold->At(a[i-1]);
5280 obj->SetUniqueID(i);
5282 }
else if (GetDimension()== 2) {
5283 std::vector<Double_t> pcont(n+2);
5284 Int_t nx = fXaxis.GetNbins();
5285 Int_t ny = fYaxis.GetNbins();
5286 cont.resize( (nx+2)*(ny+2));
5287 if (fSumw2.fN) errors.resize( (nx+2)*(ny+2));
5288 for (i=1;i<=nx;i++) {
5289 for (j=1;j<=ny;j++) {
5290 cont[i+nx*j] = GetBinContent(i,j);
5291 if (!errors.empty()) errors[i+nx*j] = GetBinError(i,j);
5292 if (axis == GetXaxis()) k = i;
5294 pcont[k-1] += cont[i+nx*j];
5297 if (sort ==1) TMath::Sort(n,pcont.data(),a.data(),kTRUE);
5298 else TMath::Sort(n,pcont.data(),a.data(),kFALSE);
5300 obj = labold->At(a[i]);
5302 obj->SetUniqueID(i+1);
5304 if (axis == GetXaxis()) {
5305 for (i=1;i<=n;i++) {
5306 for (j=1;j<=ny;j++) {
5307 SetBinContent(i,j,cont[a[i-1]+1+nx*j]);
5308 if (!errors.empty()) SetBinError(i,j,errors[a[i-1]+1+nx*j]);
5314 for (i=1;i<=nx;i++) {
5315 for (j=1;j<=n;j++) {
5316 SetBinContent(i,j,cont[i+nx*(a[j-1]+1)]);
5317 if (!errors.empty()) SetBinError(i,j,errors[i+nx*(a[j-1]+1)]);
5326 const UInt_t kUsed = 1<<18;
5330 for (i=1;i<=n;i++) {
5331 const char *label =
"zzzzzzzzzzzz";
5332 for (j=1;j<=n;j++) {
5333 obj = labold->At(j-1);
5335 if (obj->TestBit(kUsed))
continue;
5337 if (strcmp(label,obj->GetName()) < 0)
continue;
5340 label = obj->GetName();
5343 objk->SetUniqueID(i);
5345 objk->SetBit(kUsed);
5348 for (i=1;i<=n;i++) {
5349 obj = labels->At(i-1);
5351 obj->ResetBit(kUsed);
5354 if (GetDimension() == 1) {
5356 if (fSumw2.fN) errors.resize(n+2);
5357 for (i=1;i<=n;i++) {
5358 cont[i] = GetBinContent(a[i]);
5359 if (!errors.empty()) errors[i] = GetBinError(a[i]);
5361 for (i=1;i<=n;i++) {
5362 SetBinContent(i,cont[i]);
5363 if (!errors.empty()) SetBinError(i,errors[i]);
5365 }
else if (GetDimension()== 2) {
5366 Int_t nx = fXaxis.GetNbins()+2;
5367 Int_t ny = fYaxis.GetNbins()+2;
5369 if (fSumw2.fN) errors.resize(nx*ny);
5370 for (i=0;i<nx;i++) {
5371 for (j=0;j<ny;j++) {
5372 cont[i+nx*j] = GetBinContent(i,j);
5373 if (!errors.empty()) errors[i+nx*j] = GetBinError(i,j);
5376 if (axis == GetXaxis()) {
5377 for (i=1;i<=n;i++) {
5378 for (j=0;j<ny;j++) {
5379 SetBinContent(i,j,cont[a[i]+nx*j]);
5380 if (!errors.empty()) SetBinError(i,j,errors[a[i]+nx*j]);
5384 for (i=0;i<nx;i++) {
5385 for (j=1;j<=n;j++) {
5386 SetBinContent(i,j,cont[i+nx*a[j]]);
5387 if (!errors.empty()) SetBinError(i,j,errors[i+nx*a[j]]);
5392 Int_t nx = fXaxis.GetNbins()+2;
5393 Int_t ny = fYaxis.GetNbins()+2;
5394 Int_t nz = fZaxis.GetNbins()+2;
5395 cont.resize(nx*ny*nz);
5396 if (fSumw2.fN) errors.resize(nx*ny*nz);
5397 for (i=0;i<nx;i++) {
5398 for (j=0;j<ny;j++) {
5399 for (k=0;k<nz;k++) {
5400 cont[i+nx*(j+ny*k)] = GetBinContent(i,j,k);
5401 if (!errors.empty()) errors[i+nx*(j+ny*k)] = GetBinError(i,j,k);
5405 if (axis == GetXaxis()) {
5407 for (i=1;i<=n;i++) {
5408 for (j=0;j<ny;j++) {
5409 for (k=0;k<nz;k++) {
5410 SetBinContent(i,j,k,cont[a[i]+nx*(j+ny*k)]);
5411 if (!errors.empty()) SetBinError(i,j,k,errors[a[i]+nx*(j+ny*k)]);
5416 else if (axis == GetYaxis()) {
5418 for (i=0;i<nx;i++) {
5419 for (j=1;j<=n;j++) {
5420 for (k=0;k<nz;k++) {
5421 SetBinContent(i,j,k,cont[i+nx*(a[j]+ny*k)]);
5422 if (!errors.empty()) SetBinError(i,j,k,errors[i+nx*(a[j]+ny*k)]);
5429 for (i=0;i<nx;i++) {
5430 for (j=0;j<ny;j++) {
5431 for (k=1;k<=n;k++) {
5432 SetBinContent(i,j,k,cont[i+nx*(j+ny*a[k])]);
5433 if (!errors.empty()) SetBinError(i,j,k,errors[i+nx*(j+ny*a[k])]);
5447 static inline Bool_t AlmostEqual(Double_t a, Double_t b, Double_t epsilon = 0.00000001)
5449 return TMath::Abs(a - b) < epsilon;
5455 static inline Bool_t AlmostInteger(Double_t a, Double_t epsilon = 0.00000001)
5457 return AlmostEqual(a - TMath::Floor(a), 0, epsilon) ||
5458 AlmostEqual(a - TMath::Floor(a), 1, epsilon);
5464 static inline bool IsEquidistantBinning(
const TAxis& axis)
5467 if (!axis.GetXbins()->fN)
return true;
5469 bool isEquidistant =
true;
5470 const Double_t firstBinWidth = axis.GetBinWidth(1);
5471 for (
int i = 1; i < axis.GetNbins(); ++i) {
5472 const Double_t binWidth = axis.GetBinWidth(i);
5473 const bool match = TMath::AreEqualRel(firstBinWidth, binWidth, 1.E-10);
5474 isEquidistant &= match;
5478 return isEquidistant;
5484 Bool_t TH1::SameLimitsAndNBins(
const TAxis &axis1,
const TAxis &axis2){
5485 return axis1.GetNbins() == axis2.GetNbins() &&
5486 TMath::AreEqualAbs(axis1.GetXmin(), axis2.GetXmin(), axis1.GetBinWidth(axis1.GetNbins()) * 1.E-10) &&
5487 TMath::AreEqualAbs(axis1.GetXmax(), axis2.GetXmax(), axis1.GetBinWidth(axis1.GetNbins()) * 1.E-10);
5494 Bool_t TH1::RecomputeAxisLimits(TAxis &destAxis,
const TAxis &anAxis)
5496 if (SameLimitsAndNBins(destAxis, anAxis))
5499 if (!IsEquidistantBinning(destAxis) || !IsEquidistantBinning(anAxis))
5502 Double_t width1 = destAxis.GetBinWidth(0);
5503 Double_t width2 = anAxis.GetBinWidth(0);
5504 if (width1 == 0 || width2 == 0)
5507 Double_t xmin = TMath::Min(destAxis.GetXmin(), anAxis.GetXmin());
5508 Double_t xmax = TMath::Max(destAxis.GetXmax(), anAxis.GetXmax());
5509 Double_t width = TMath::Max(width1, width2);
5512 if (!AlmostInteger(width/width1) || !AlmostInteger(width/width2))
5521 delta = (destAxis.GetXmin() - xmin)/width1;
5522 if (!AlmostInteger(delta))
5523 xmin -= (TMath::Ceil(delta) - delta)*width1;
5525 delta = (anAxis.GetXmin() - xmin)/width2;
5526 if (!AlmostInteger(delta))
5527 xmin -= (TMath::Ceil(delta) - delta)*width2;
5530 delta = (destAxis.GetXmin() - xmin)/width1;
5531 if (!AlmostInteger(delta))
5535 delta = (xmax - destAxis.GetXmax())/width1;
5536 if (!AlmostInteger(delta))
5537 xmax += (TMath::Ceil(delta) - delta)*width1;
5540 delta = (xmax - anAxis.GetXmax())/width2;
5541 if (!AlmostInteger(delta))
5542 xmax += (TMath::Ceil(delta) - delta)*width2;
5545 delta = (xmax - destAxis.GetXmax())/width1;
5546 if (!AlmostInteger(delta))
5549 if (!AlmostInteger((xmax - xmin) / width)) {
5550 printf(
"TH1::RecomputeAxisLimits - Impossible\n");
5556 destAxis.Set(TMath::Nint((xmax - xmin)/width), xmin, xmax);
5608 Long64_t TH1::Merge(TCollection *li,Option_t * opt)
5611 if (li->IsEmpty())
return (Long64_t) GetEntries();
5614 TH1Merger merger(*
this,*li,opt);
5615 Bool_t ret = merger();
5617 return (ret) ? GetEntries() : -1;
5635 Bool_t TH1::Multiply(TF1 *f1, Double_t c1)
5638 Error(
"Multiply",
"Attempt to multiply by a non-existing function");
5643 if (fBuffer) BufferEmpty(1);
5645 Int_t nx = GetNbinsX() + 2;
5646 Int_t ny = GetNbinsY() + 2;
5647 Int_t nz = GetNbinsZ() + 2;
5648 if (fDimension < 2) ny = 1;
5649 if (fDimension < 3) nz = 1;
5657 Double_t *params = 0;
5658 f1->InitArgs(xx,params);
5660 for (Int_t binz = 0; binz < nz; ++binz) {
5661 xx[2] = fZaxis.GetBinCenter(binz);
5662 for (Int_t biny = 0; biny < ny; ++biny) {
5663 xx[1] = fYaxis.GetBinCenter(biny);
5664 for (Int_t binx = 0; binx < nx; ++binx) {
5665 xx[0] = fXaxis.GetBinCenter(binx);
5666 if (!f1->IsInside(xx))
continue;
5667 TF1::RejectPoint(kFALSE);
5668 Int_t bin = binx + nx * (biny + ny *binz);
5669 Double_t cu = c1*f1->EvalPar(xx);
5670 if (TF1::RejectedPoint())
continue;
5671 UpdateBinContent(bin, RetrieveBinContent(bin) * cu);
5673 fSumw2.fArray[bin] = cu * cu * GetBinErrorSqUnchecked(bin);
5697 Bool_t TH1::Multiply(
const TH1 *h1)
5700 Error(
"Multiply",
"Attempt to multiply by a non-existing histogram");
5705 if (fBuffer) BufferEmpty(1);
5708 CheckConsistency(
this,h1);
5709 }
catch(DifferentNumberOfBins&) {
5710 Error(
"Multiply",
"Attempt to multiply histograms with different number of bins");
5712 }
catch(DifferentAxisLimits&) {
5713 Warning(
"Multiply",
"Attempt to multiply histograms with different axis limits");
5714 }
catch(DifferentBinLimits&) {
5715 Warning(
"Multiply",
"Attempt to multiply histograms with different bin limits");
5716 }
catch(DifferentLabels&) {
5717 Warning(
"Multiply",
"Attempt to multiply histograms with different labels");
5721 if (fSumw2.fN == 0 && h1->GetSumw2N() != 0) Sumw2();
5728 for (Int_t i = 0; i < fNcells; ++i) {
5729 Double_t c0 = RetrieveBinContent(i);
5730 Double_t c1 = h1->RetrieveBinContent(i);
5731 UpdateBinContent(i, c0 * c1);
5733 fSumw2.fArray[i] = GetBinErrorSqUnchecked(i) * c1 * c1 + h1->GetBinErrorSqUnchecked(i) * c0 * c0;
5755 Bool_t TH1::Multiply(
const TH1 *h1,
const TH1 *h2, Double_t c1, Double_t c2, Option_t *option)
5757 TString opt = option;
5762 Error(
"Multiply",
"Attempt to multiply by a non-existing histogram");
5767 if (fBuffer) BufferEmpty(1);
5770 CheckConsistency(h1,h2);
5771 CheckConsistency(
this,h1);
5772 }
catch(DifferentNumberOfBins&) {
5773 Error(
"Multiply",
"Attempt to multiply histograms with different number of bins");
5775 }
catch(DifferentAxisLimits&) {
5776 Warning(
"Multiply",
"Attempt to multiply histograms with different axis limits");
5777 }
catch(DifferentBinLimits&) {
5778 Warning(
"Multiply",
"Attempt to multiply histograms with different bin limits");
5779 }
catch(DifferentLabels&) {
5780 Warning(
"Multiply",
"Attempt to multiply histograms with different labels");
5784 if (fSumw2.fN == 0 && (h1->GetSumw2N() != 0 || h2->GetSumw2N() != 0)) Sumw2();
5791 Double_t c1sq = c1 * c1; Double_t c2sq = c2 * c2;
5792 for (Int_t i = 0; i < fNcells; ++i) {
5793 Double_t b1 = h1->RetrieveBinContent(i);
5794 Double_t b2 = h2->RetrieveBinContent(i);
5795 UpdateBinContent(i, c1 * b1 * c2 * b2);
5797 fSumw2.fArray[i] = c1sq * c2sq * (h1->GetBinErrorSqUnchecked(i) * b2 * b2 + h2->GetBinErrorSqUnchecked(i) * b1 * b1);
5810 void TH1::Paint(Option_t *option)
5815 if (strlen(option) > 0) fPainter->Paint(option);
5816 else fPainter->Paint(fOption.Data());
5877 TH1 *TH1::Rebin(Int_t ngroup,
const char*newname,
const Double_t *xbins)
5879 Int_t nbins = fXaxis.GetNbins();
5880 Double_t xmin = fXaxis.GetXmin();
5881 Double_t xmax = fXaxis.GetXmax();
5882 if ((ngroup <= 0) || (ngroup > nbins)) {
5883 Error(
"Rebin",
"Illegal value of ngroup=%d",ngroup);
5887 if (fDimension > 1 || InheritsFrom(TProfile::Class())) {
5888 Error(
"Rebin",
"Operation valid on 1-D histograms only");
5891 if (!newname && xbins) {
5892 Error(
"Rebin",
"if xbins is specified, newname must be given");
5896 Int_t newbins = nbins/ngroup;
5898 Int_t nbg = nbins/ngroup;
5899 if (nbg*ngroup != nbins) {
5900 Warning(
"Rebin",
"ngroup=%d is not an exact divider of nbins=%d.",ngroup,nbins);
5913 Double_t entries = fEntries;
5914 Double_t *oldBins =
new Double_t[nbins+2];
5916 for (bin=0;bin<nbins+2;bin++) oldBins[bin] = RetrieveBinContent(bin);
5917 Double_t *oldErrors = 0;
5918 if (fSumw2.fN != 0) {
5919 oldErrors =
new Double_t[nbins+2];
5920 for (bin=0;bin<nbins+2;bin++) oldErrors[bin] = GetBinError(bin);
5924 if (xbins[0] < fXaxis.GetXmin() && oldBins[0] != 0 )
5925 Warning(
"Rebin",
"underflow entries will not be used when rebinning");
5926 if (xbins[newbins] > fXaxis.GetXmax() && oldBins[nbins+1] != 0 )
5927 Warning(
"Rebin",
"overflow entries will not be used when rebinning");
5933 if ((newname && strlen(newname) > 0) || xbins) {
5934 hnew = (TH1*)Clone(newname);
5938 UInt_t oldExtendBitMask = hnew->SetCanExtend(kNoAxis);
5941 Double_t stat[kNstat];
5943 bool resetStat =
false;
5945 if(!xbins && (newbins*ngroup != nbins)) {
5946 xmax = fXaxis.GetBinUpEdge(newbins*ngroup);
5950 Int_t nDivisions = fXaxis.GetNdivisions();
5951 Color_t axisColor = fXaxis.GetAxisColor();
5952 Color_t labelColor = fXaxis.GetLabelColor();
5953 Style_t labelFont = fXaxis.GetLabelFont();
5954 Float_t labelOffset = fXaxis.GetLabelOffset();
5955 Float_t labelSize = fXaxis.GetLabelSize();
5956 Float_t tickLength = fXaxis.GetTickLength();
5957 Float_t titleOffset = fXaxis.GetTitleOffset();
5958 Float_t titleSize = fXaxis.GetTitleSize();
5959 Color_t titleColor = fXaxis.GetTitleColor();
5960 Style_t titleFont = fXaxis.GetTitleFont();
5962 if(!xbins && (fXaxis.GetXbins()->GetSize() > 0)){
5963 Double_t *bins =
new Double_t[newbins+1];
5964 for(i = 0; i <= newbins; ++i) bins[i] = fXaxis.GetBinLowEdge(1+i*ngroup);
5965 hnew->SetBins(newbins,bins);
5968 hnew->SetBins(newbins,xbins);
5970 hnew->SetBins(newbins,xmin,xmax);
5974 fXaxis.SetNdivisions(nDivisions);
5975 fXaxis.SetAxisColor(axisColor);
5976 fXaxis.SetLabelColor(labelColor);
5977 fXaxis.SetLabelFont(labelFont);
5978 fXaxis.SetLabelOffset(labelOffset);
5979 fXaxis.SetLabelSize(labelSize);
5980 fXaxis.SetTickLength(tickLength);
5981 fXaxis.SetTitleOffset(titleOffset);
5982 fXaxis.SetTitleSize(titleSize);
5983 fXaxis.SetTitleColor(titleColor);
5984 fXaxis.SetTitleFont(titleFont);
5989 const Double_t newxmin = hnew->GetXaxis()->GetBinLowEdge(1);
5990 while( fXaxis.GetBinCenter(startbin) < newxmin && startbin <= nbins ) {
5993 Int_t oldbin = startbin;
5994 Double_t binContent, binError;
5995 for (bin = 1;bin<=newbins;bin++) {
5998 Int_t imax = ngroup;
5999 Double_t xbinmax = hnew->GetXaxis()->GetBinUpEdge(bin);
6002 if (xbins && !TMath::AreEqualAbs(fXaxis.GetBinLowEdge(oldbin),
6003 hnew->GetXaxis()->GetBinLowEdge(bin),
6004 TMath::Max(1.E-8 * fXaxis.GetBinWidth(oldbin), 1.E-16 )) )
6006 Warning(
"Rebin",
"Bin edge %d of rebinned histogram does not match any bin edges of the old histogram. Result can be inconsistent",bin);
6008 for (i=0;i<ngroup;i++) {
6009 if( (oldbin+i > nbins) ||
6010 ( hnew !=
this && (fXaxis.GetBinCenter(oldbin+i) > xbinmax)) ) {
6014 binContent += oldBins[oldbin+i];
6015 if (oldErrors) binError += oldErrors[oldbin+i]*oldErrors[oldbin+i];
6017 hnew->SetBinContent(bin,binContent);
6018 if (oldErrors) hnew->SetBinError(bin,TMath::Sqrt(binError));
6025 for (i = 0; i < startbin; ++i) {
6026 binContent += oldBins[i];
6027 if (oldErrors) binError += oldErrors[i]*oldErrors[i];
6029 hnew->SetBinContent(0,binContent);
6030 if (oldErrors) hnew->SetBinError(0,TMath::Sqrt(binError));
6034 for (i = oldbin; i <= nbins+1; ++i) {
6035 binContent += oldBins[i];
6036 if (oldErrors) binError += oldErrors[i]*oldErrors[i];
6038 hnew->SetBinContent(newbins+1,binContent);
6039 if (oldErrors) hnew->SetBinError(newbins+1,TMath::Sqrt(binError));
6041 hnew->SetCanExtend(oldExtendBitMask);
6044 hnew->SetEntries(entries);
6045 if (!resetStat) hnew->PutStats(stat);
6047 if (oldErrors)
delete [] oldErrors;
6062 Bool_t TH1::FindNewAxisLimits(
const TAxis* axis,
const Double_t point, Double_t& newMin, Double_t &newMax)
6064 Double_t xmin = axis->GetXmin();
6065 Double_t xmax = axis->GetXmax();
6066 if (xmin >= xmax)
return kFALSE;
6067 Double_t range = xmax-xmin;
6068 Double_t binsize = range / axis->GetNbins();
6072 while (point < xmin) {
6075 xmin = xmin - range;
6084 while (point >= xmax) {
6087 xmax = xmax + range;
6119 void TH1::ExtendAxis(Double_t x, TAxis *axis)
6121 if (!axis->CanExtend())
return;
6122 if (TMath::IsNaN(x)) {
6123 SetCanExtend(kNoAxis);
6127 if (axis->GetXmin() >= axis->GetXmax())
return;
6128 if (axis->GetNbins() <= 0)
return;
6130 Double_t xmin, xmax;
6131 if (!FindNewAxisLimits(axis, x, xmin, xmax))
6135 TH1 *hold = (TH1*)IsA()->New();
6136 hold->SetDirectory(0);
6139 axis->SetLimits(xmin,xmax);
6143 Int_t errors = GetSumw2N();
6148 if (axis == &fXaxis) iaxis = 1;
6149 if (axis == &fYaxis) iaxis = 2;
6150 if (axis == &fZaxis) iaxis = 3;
6151 bool firstw = kTRUE;
6152 Int_t binx,biny, binz = 0;
6153 Int_t ix = 0,iy = 0,iz = 0;
6155 Int_t ncells = hold->GetNcells();
6156 for (Int_t bin = 0; bin < ncells; ++bin) {
6157 hold->GetBinXYZ(bin,binx,biny,binz);
6158 bx = hold->GetXaxis()->GetBinCenter(binx);
6159 ix = fXaxis.FindFixBin(bx);
6160 if (fDimension > 1) {
6161 by = hold->GetYaxis()->GetBinCenter(biny);
6162 iy = fYaxis.FindFixBin(by);
6163 if (fDimension > 2) {
6164 bz = hold->GetZaxis()->GetBinCenter(binz);
6165 iz = fZaxis.FindFixBin(bz);
6169 double content = hold->RetrieveBinContent(bin);
6170 if (content == 0)
continue;
6171 if (IsBinUnderflow(bin,iaxis) || IsBinOverflow(bin,iaxis) ) {
6173 Warning(
"ExtendAxis",
"Histogram %s has underflow or overflow in the axis that is extendable"
6174 " their content will be lost",GetName() );
6179 Int_t ibin= GetBin(ix,iy,iz);
6180 AddBinContent(ibin, content);
6182 fSumw2.fArray[ibin] += hold->GetBinErrorSqUnchecked(bin);
6191 void TH1::RecursiveRemove(TObject *obj)
6196 if (!fFunctions->TestBit(kInvalidObject)) fFunctions->RecursiveRemove(obj);
6219 void TH1::Scale(Double_t c1, Option_t *option)
6222 TString opt = option; opt.ToLower();
6224 if (!opt.Contains(
"nosw2") && GetSumw2N() == 0) Sumw2();
6225 if (opt.Contains(
"width")) Add(
this,
this, c1, -1);
6227 if (fBuffer) BufferEmpty(1);
6228 for(Int_t i = 0; i < fNcells; ++i) UpdateBinContent(i, c1 * RetrieveBinContent(i));
6229 if (fSumw2.fN)
for(Int_t i = 0; i < fNcells; ++i) fSumw2.fArray[i] *= (c1 * c1);
6231 Double_t s[kNstat] = {0};
6233 for (Int_t i=0 ; i < kNstat; i++) {
6234 if (i == 1) s[i] = c1*c1*s[i];
6235 else s[i] = c1*s[i];
6238 SetMinimum(); SetMaximum();
6242 Int_t ncontours = GetContour();
6243 if (ncontours == 0)
return;
6244 Double_t* levels = fContour.GetArray();
6245 for (Int_t i = 0; i < ncontours; ++i) levels[i] *= c1;
6251 Bool_t TH1::CanExtendAllAxes()
const
6253 Bool_t canExtend = fXaxis.CanExtend();
6254 if (GetDimension() > 1) canExtend &= fYaxis.CanExtend();
6255 if (GetDimension() > 2) canExtend &= fZaxis.CanExtend();
6264 UInt_t TH1::SetCanExtend(UInt_t extendBitMask)
6266 UInt_t oldExtendBitMask = kNoAxis;
6268 if (fXaxis.CanExtend()) oldExtendBitMask |= kXaxis;
6269 if (extendBitMask & kXaxis) fXaxis.SetCanExtend(kTRUE);
6270 else fXaxis.SetCanExtend(kFALSE);
6272 if (GetDimension() > 1) {
6273 if (fYaxis.CanExtend()) oldExtendBitMask |= kYaxis;
6274 if (extendBitMask & kYaxis) fYaxis.SetCanExtend(kTRUE);
6275 else fYaxis.SetCanExtend(kFALSE);
6278 if (GetDimension() > 2) {
6279 if (fZaxis.CanExtend()) oldExtendBitMask |= kZaxis;
6280 if (extendBitMask & kZaxis) fZaxis.SetCanExtend(kTRUE);
6281 else fZaxis.SetCanExtend(kFALSE);
6284 return oldExtendBitMask;
6293 void TH1::SetDefaultBufferSize(Int_t buffersize)
6295 fgBufferSize = buffersize > 0 ? buffersize : 0;
6303 void TH1::SetDefaultSumw2(Bool_t sumw2)
6305 fgDefaultSumw2 = sumw2;
6318 void TH1::SetTitle(
const char *title)
6321 fTitle.ReplaceAll(
"#;",2,
"#semicolon",10);
6324 TString str1 = fTitle, str2;
6325 Int_t isc = str1.Index(
";");
6326 Int_t lns = str1.Length();
6329 fTitle = str1(0,isc);
6330 str1 = str1(isc+1, lns);
6331 isc = str1.Index(
";");
6334 str2.ReplaceAll(
"#semicolon",10,
";",1);
6335 fXaxis.SetTitle(str2.Data());
6336 lns = str1.Length();
6337 str1 = str1(isc+1, lns);
6338 isc = str1.Index(
";");
6341 str2.ReplaceAll(
"#semicolon",10,
";",1);
6342 fYaxis.SetTitle(str2.Data());
6343 lns = str1.Length();
6344 str1 = str1(isc+1, lns);
6345 str1.ReplaceAll(
"#semicolon",10,
";",1);
6346 fZaxis.SetTitle(str1.Data());
6348 str1.ReplaceAll(
"#semicolon",10,
";",1);
6349 fYaxis.SetTitle(str1.Data());
6352 str1.ReplaceAll(
"#semicolon",10,
";",1);
6353 fXaxis.SetTitle(str1.Data());
6357 fTitle.ReplaceAll(
"#semicolon",10,
";",1);
6359 if (gPad && TestBit(kMustCleanup)) gPad->Modified();
6367 void TH1::SmoothArray(Int_t nn, Double_t *xx, Int_t ntimes)
6370 ::Error(
"SmoothArray",
"Need at least 3 points for smoothing: n = %d",nn);
6375 Double_t hh[6] = {0,0,0,0,0,0};
6377 std::vector<double> yy(nn);
6378 std::vector<double> zz(nn);
6379 std::vector<double> rr(nn);
6381 for (Int_t pass=0;pass<ntimes;pass++) {
6383 std::copy(xx, xx+nn, zz.begin() );
6385 for (
int noent = 0; noent < 2; ++noent) {
6388 for (
int kk = 0; kk < 3; kk++) {
6389 std::copy(zz.begin(), zz.end(), yy.begin());
6390 int medianType = (kk != 1) ? 3 : 5;
6391 int ifirst = (kk != 1 ) ? 1 : 2;
6392 int ilast = (kk != 1 ) ? nn-1 : nn -2;
6396 for ( ii = ifirst; ii < ilast; ii++) {
6397 assert(ii - ifirst >= 0);
6398 for (
int jj = 0; jj < medianType; jj++) {
6399 hh[jj] = yy[ii - ifirst + jj ];
6401 zz[ii] = TMath::Median(medianType, hh);
6408 hh[2] = 3*zz[1] - 2*zz[2];
6409 zz[0] = TMath::Median(3, hh);
6413 hh[2] = 3*zz[nn - 2] - 2*zz[nn - 3];
6414 zz[nn - 1] = TMath::Median(3, hh);
6418 for (ii = 0; ii < 3; ii++) {
6421 zz[1] = TMath::Median(3, hh);
6423 for (ii = 0; ii < 3; ii++) {
6424 hh[ii] = yy[nn - 3 + ii];
6426 zz[nn - 2] = TMath::Median(3, hh);
6431 std::copy ( zz.begin(), zz.end(), yy.begin() );
6434 for (ii = 2; ii < (nn - 2); ii++) {
6435 if (zz[ii - 1] != zz[ii])
continue;
6436 if (zz[ii] != zz[ii + 1])
continue;
6437 hh[0] = zz[ii - 2] - zz[ii];
6438 hh[1] = zz[ii + 2] - zz[ii];
6439 if (hh[0] * hh[1] <= 0)
continue;
6441 if ( TMath::Abs(hh[1]) > TMath::Abs(hh[0]) ) jk = -1;
6442 yy[ii] = -0.5*zz[ii - 2*jk] + zz[ii]/0.75 + zz[ii + 2*jk] /6.;
6443 yy[ii + jk] = 0.5*(zz[ii + 2*jk] - zz[ii - 2*jk]) + zz[ii];
6448 for (ii = 1; ii < nn - 1; ii++) {
6449 zz[ii] = 0.25*yy[ii - 1] + 0.5*yy[ii] + 0.25*yy[ii + 1];
6452 zz[nn - 1] = yy[nn - 1];
6457 std::copy(zz.begin(), zz.end(), rr.begin());
6460 for (ii = 0; ii < nn; ii++) {
6461 zz[ii] = xx[ii] - zz[ii];
6468 double xmin = TMath::MinElement(nn,xx);
6469 for (ii = 0; ii < nn; ii++) {
6470 if (xmin < 0) xx[ii] = rr[ii] + zz[ii];
6472 else xx[ii] = TMath::Max((rr[ii] + zz[ii]),0.0 );
6485 void TH1::Smooth(Int_t ntimes, Option_t *option)
6487 if (fDimension != 1) {
6488 Error(
"Smooth",
"Smooth only supported for 1-d histograms");
6491 Int_t nbins = fXaxis.GetNbins();
6493 Error(
"Smooth",
"Smooth only supported for histograms with >= 3 bins. Nbins = %d",nbins);
6498 if (fBuffer) BufferEmpty(1);
6500 Int_t firstbin = 1, lastbin = nbins;
6501 TString opt = option;
6503 if (opt.Contains(
"r")) {
6504 firstbin= fXaxis.GetFirst();
6505 lastbin = fXaxis.GetLast();
6507 nbins = lastbin - firstbin + 1;
6508 Double_t *xx =
new Double_t[nbins];
6509 Double_t nent = fEntries;
6511 for (i=0;i<nbins;i++) {
6512 xx[i] = RetrieveBinContent(i+firstbin);
6515 TH1::SmoothArray(nbins,xx,ntimes);
6517 for (i=0;i<nbins;i++) {
6518 UpdateBinContent(i+firstbin,xx[i]);
6523 if (gPad) gPad->Modified();
6531 void TH1::StatOverflows(Bool_t flag)
6533 fgStatOverflows = flag;
6539 void TH1::Streamer(TBuffer &b)
6541 if (b.IsReading()) {
6543 Version_t R__v = b.ReadVersion(&R__s, &R__c);
6544 if (fDirectory) fDirectory->Remove(
this);
6547 b.ReadClassBuffer(TH1::Class(),
this, R__v, R__s, R__c);
6549 ResetBit(kMustCleanup);
6550 fXaxis.SetParent(
this);
6551 fYaxis.SetParent(
this);
6552 fZaxis.SetParent(
this);
6553 TIter next(fFunctions);
6555 while ((obj=next())) {
6556 if (obj->InheritsFrom(TF1::Class())) ((TF1*)obj)->SetParent(
this);
6561 TNamed::Streamer(b);
6562 TAttLine::Streamer(b);
6563 TAttFill::Streamer(b);
6564 TAttMarker::Streamer(b);
6569 fXaxis.SetParent(
this);
6570 fYaxis.SetParent(
this);
6571 fZaxis.SetParent(
this);
6580 Float_t maximum, minimum, norm;
6582 b >> maximum; fMaximum = maximum;
6583 b >> minimum; fMinimum = minimum;
6584 b >> norm; fNormFactor = norm;
6585 Int_t n = b.ReadArray(contour);
6587 for (Int_t i=0;i<n;i++) fContour.fArray[i] = contour[i];
6593 fContour.Streamer(b);
6596 fOption.Streamer(b);
6597 fFunctions->Delete();
6598 fFunctions->Streamer(b);
6599 b.CheckByteCount(R__s, R__c, TH1::IsA());
6602 b.WriteClassBuffer(TH1::Class(),
this);
6615 void TH1::Print(Option_t *option)
const
6617 if (fBuffer)
const_cast<TH1*
>(
this)->BufferEmpty();
6618 printf(
"TH1.Print Name = %s, Entries= %d, Total sum= %g\n",GetName(),Int_t(fEntries),GetSumOfWeights());
6619 TString opt = option;
6622 if (opt.Contains(
"all")) all = 0;
6623 else if (opt.Contains(
"range")) all = 1;
6624 else if (opt.Contains(
"base")) all = 2;
6627 Int_t bin, binx, biny, binz;
6628 Int_t firstx=0,lastx=0,firsty=0,lasty=0,firstz=0,lastz=0;
6630 lastx = fXaxis.GetNbins()+1;
6631 if (fDimension > 1) lasty = fYaxis.GetNbins()+1;
6632 if (fDimension > 2) lastz = fZaxis.GetNbins()+1;
6634 firstx = fXaxis.GetFirst(); lastx = fXaxis.GetLast();
6635 if (fDimension > 1) {firsty = fYaxis.GetFirst(); lasty = fYaxis.GetLast();}
6636 if (fDimension > 2) {firstz = fZaxis.GetFirst(); lastz = fZaxis.GetLast();}
6640 printf(
" Title = %s\n", GetTitle());
6641 printf(
" NbinsX= %d, xmin= %g, xmax=%g", fXaxis.GetNbins(), fXaxis.GetXmin(), fXaxis.GetXmax());
6642 if( fDimension > 1) printf(
", NbinsY= %d, ymin= %g, ymax=%g", fYaxis.GetNbins(), fYaxis.GetXmin(), fYaxis.GetXmax());
6643 if( fDimension > 2) printf(
", NbinsZ= %d, zmin= %g, zmax=%g", fZaxis.GetNbins(), fZaxis.GetXmin(), fZaxis.GetXmax());
6650 if (fDimension == 1) {
6651 for (binx=firstx;binx<=lastx;binx++) {
6652 x = fXaxis.GetBinCenter(binx);
6653 w = RetrieveBinContent(binx);
6654 e = GetBinError(binx);
6655 if(fSumw2.fN) printf(
" fSumw[%d]=%g, x=%g, error=%g\n",binx,w,x,e);
6656 else printf(
" fSumw[%d]=%g, x=%g\n",binx,w,x);
6659 if (fDimension == 2) {
6660 for (biny=firsty;biny<=lasty;biny++) {
6661 y = fYaxis.GetBinCenter(biny);
6662 for (binx=firstx;binx<=lastx;binx++) {
6663 bin = GetBin(binx,biny);
6664 x = fXaxis.GetBinCenter(binx);
6665 w = RetrieveBinContent(bin);
6666 e = GetBinError(bin);
6667 if(fSumw2.fN) printf(
" fSumw[%d][%d]=%g, x=%g, y=%g, error=%g\n",binx,biny,w,x,y,e);
6668 else printf(
" fSumw[%d][%d]=%g, x=%g, y=%g\n",binx,biny,w,x,y);
6672 if (fDimension == 3) {
6673 for (binz=firstz;binz<=lastz;binz++) {
6674 z = fZaxis.GetBinCenter(binz);
6675 for (biny=firsty;biny<=lasty;biny++) {
6676 y = fYaxis.GetBinCenter(biny);
6677 for (binx=firstx;binx<=lastx;binx++) {
6678 bin = GetBin(binx,biny,binz);
6679 x = fXaxis.GetBinCenter(binx);
6680 w = RetrieveBinContent(bin);
6681 e = GetBinError(bin);
6682 if(fSumw2.fN) printf(
" fSumw[%d][%d][%d]=%g, x=%g, y=%g, z=%g, error=%g\n",binx,biny,binz,w,x,y,z,e);
6683 else printf(
" fSumw[%d][%d][%d]=%g, x=%g, y=%g, z=%g\n",binx,biny,binz,w,x,y,z);
6693 void TH1::Rebuild(Option_t *)
6697 fSumw2.Set(fNcells);
6709 void TH1::Reset(Option_t *option)
6714 TString opt = option;
6717 if (fIntegral) {
delete [] fIntegral; fIntegral = 0;}
6719 if (opt.Contains(
"M")) {
6724 if (opt.Contains(
"ICE") && !opt.Contains(
"S"))
return;
6731 if (fBuffer) {BufferEmpty(); fBuffer[0] = 0;}
6741 if (opt ==
"ICES")
return;
6744 TObject *stats = fFunctions->FindObject(
"stats");
6745 fFunctions->Remove(stats);
6751 while ((obj = fFunctions->First())) {
6752 while(fFunctions->Remove(obj)) { }
6755 if(stats) fFunctions->Add(stats);
6762 void TH1::SavePrimitive(std::ostream &out, Option_t *option )
6765 if (fBuffer) BufferEmpty();
6767 Bool_t nonEqiX = kFALSE;
6768 Bool_t nonEqiY = kFALSE;
6769 Bool_t nonEqiZ = kFALSE;
6771 static Int_t nxaxis = 0;
6772 static Int_t nyaxis = 0;
6773 static Int_t nzaxis = 0;
6774 TString sxaxis=
"xAxis",syaxis=
"yAxis",szaxis=
"zAxis";
6778 if (GetXaxis()->GetXbins()->fN && GetXaxis()->GetXbins()->fArray) {
6782 out <<
" Double_t "<<sxaxis<<
"[" << GetXaxis()->GetXbins()->fN
6784 for (i = 0; i < GetXaxis()->GetXbins()->fN; i++) {
6785 if (i != 0) out <<
", ";
6786 out << GetXaxis()->GetXbins()->fArray[i];
6788 out <<
"}; " << std::endl;
6793 if (fDimension > 1 && GetYaxis()->GetXbins()->fN &&
6794 GetYaxis()->GetXbins()->fArray) {
6798 out <<
" Double_t "<<syaxis<<
"[" << GetYaxis()->GetXbins()->fN
6800 for (i = 0; i < GetYaxis()->GetXbins()->fN; i++) {
6801 if (i != 0) out <<
", ";
6802 out << GetYaxis()->GetXbins()->fArray[i];
6804 out <<
"}; " << std::endl;
6809 if (fDimension > 2 && GetZaxis()->GetXbins()->fN &&
6810 GetZaxis()->GetXbins()->fArray) {
6814 out <<
" Double_t "<<szaxis<<
"[" << GetZaxis()->GetXbins()->fN
6816 for (i = 0; i < GetZaxis()->GetXbins()->fN; i++) {
6817 if (i != 0) out <<
", ";
6818 out << GetZaxis()->GetXbins()->fArray[i];
6820 out <<
"}; " << std::endl;
6824 out <<
" "<<std::endl;
6825 out <<
" "<< ClassName() <<
" *";
6832 TString opt = option;
6834 static Int_t hcounter = 0;
6835 TString histName = GetName();
6836 if ( !histName.Contains(
"Graph")
6837 && !histName.Contains(
"_stack_")
6838 && !opt.Contains(
"colz")) {
6841 histName += hcounter;
6843 histName = gInterpreter-> MapCppName(histName);
6844 const char *hname = histName.Data();
6845 if (!strlen(hname)) hname =
"unnamed";
6846 TString savedName = GetName();
6847 this->SetName(hname);
6848 TString t(GetTitle());
6849 t.ReplaceAll(
"\\",
"\\\\");
6850 t.ReplaceAll(
"\"",
"\\\"");
6851 out << hname <<
" = new " << ClassName() <<
"(" << quote
6852 << hname << quote <<
"," << quote<< t.Data() << quote
6853 <<
"," << GetXaxis()->GetNbins();
6855 out <<
", "<<sxaxis;
6857 out <<
"," << GetXaxis()->GetXmin()
6858 <<
"," << GetXaxis()->GetXmax();
6859 if (fDimension > 1) {
6860 out <<
"," << GetYaxis()->GetNbins();
6862 out <<
", "<<syaxis;
6864 out <<
"," << GetYaxis()->GetXmin()
6865 <<
"," << GetYaxis()->GetXmax();
6867 if (fDimension > 2) {
6868 out <<
"," << GetZaxis()->GetNbins();
6870 out <<
", "<<szaxis;
6872 out <<
"," << GetZaxis()->GetXmin()
6873 <<
"," << GetZaxis()->GetXmax();
6875 out <<
");" << std::endl;
6879 for (bin=0;bin<fNcells;bin++) {
6880 Double_t bc = RetrieveBinContent(bin);
6882 out<<
" "<<hname<<
"->SetBinContent("<<bin<<
","<<bc<<
");"<<std::endl;
6888 for (bin=0;bin<fNcells;bin++) {
6889 Double_t be = GetBinError(bin);
6891 out<<
" "<<hname<<
"->SetBinError("<<bin<<
","<<be<<
");"<<std::endl;
6896 TH1::SavePrimitiveHelp(out, hname, option);
6897 this->SetName(savedName.Data());
6904 void TH1::SavePrimitiveHelp(std::ostream &out,
const char *hname, Option_t *option )
6907 if (TMath::Abs(GetBarOffset()) > 1e-5) {
6908 out<<
" "<<hname<<
"->SetBarOffset("<<GetBarOffset()<<
");"<<std::endl;
6910 if (TMath::Abs(GetBarWidth()-1) > 1e-5) {
6911 out<<
" "<<hname<<
"->SetBarWidth("<<GetBarWidth()<<
");"<<std::endl;
6913 if (fMinimum != -1111) {
6914 out<<
" "<<hname<<
"->SetMinimum("<<fMinimum<<
");"<<std::endl;
6916 if (fMaximum != -1111) {
6917 out<<
" "<<hname<<
"->SetMaximum("<<fMaximum<<
");"<<std::endl;
6919 if (fNormFactor != 0) {
6920 out<<
" "<<hname<<
"->SetNormFactor("<<fNormFactor<<
");"<<std::endl;
6922 if (fEntries != 0) {
6923 out<<
" "<<hname<<
"->SetEntries("<<fEntries<<
");"<<std::endl;
6925 if (fDirectory == 0) {
6926 out<<
" "<<hname<<
"->SetDirectory(0);"<<std::endl;
6928 if (TestBit(kNoStats)) {
6929 out<<
" "<<hname<<
"->SetStats(0);"<<std::endl;
6931 if (fOption.Length() != 0) {
6932 out<<
" "<<hname<<
"->SetOption("<<quote<<fOption.Data()<<quote<<
");"<<std::endl;
6936 Int_t ncontours = GetContour();
6937 if (ncontours > 0) {
6938 out<<
" "<<hname<<
"->SetContour("<<ncontours<<
");"<<std::endl;
6940 for (Int_t bin=0;bin<ncontours;bin++) {
6941 if (gPad->GetLogz()) {
6942 zlevel = TMath::Power(10,GetContourLevel(bin));
6944 zlevel = GetContourLevel(bin);
6946 out<<
" "<<hname<<
"->SetContourLevel("<<bin<<
","<<zlevel<<
");"<<std::endl;
6951 TObjOptLink *lnk = (TObjOptLink*)fFunctions->FirstLink();
6953 static Int_t funcNumber = 0;
6955 obj = lnk->GetObject();
6956 obj->SavePrimitive(out,Form(
"nodraw #%d\n",++funcNumber));
6957 if (obj->InheritsFrom(TF1::Class())) {
6959 fname.Form(
"%s%d",obj->GetName(),funcNumber);
6960 out <<
" " << fname <<
"->SetParent(" << hname <<
");\n";
6961 out<<
" "<<hname<<
"->GetListOfFunctions()->Add("
6962 << fname <<
");"<<std::endl;
6963 }
else if (obj->InheritsFrom(
"TPaveStats")) {
6964 out<<
" "<<hname<<
"->GetListOfFunctions()->Add(ptstats);"<<std::endl;
6965 out<<
" ptstats->SetParent("<<hname<<
");"<<std::endl;
6966 }
else if (obj->InheritsFrom(
"TPolyMarker")) {
6967 out<<
" "<<hname<<
"->GetListOfFunctions()->Add("
6968 <<
"pmarker ,"<<quote<<lnk->GetOption()<<quote<<
");"<<std::endl;
6970 out<<
" "<<hname<<
"->GetListOfFunctions()->Add("
6972 <<
","<<quote<<lnk->GetOption()<<quote<<
");"<<std::endl;
6974 lnk = (TObjOptLink*)lnk->Next();
6978 SaveFillAttributes(out,hname,0,1001);
6979 SaveLineAttributes(out,hname,1,1,1);
6980 SaveMarkerAttributes(out,hname,1,1,1);
6981 fXaxis.SaveAttributes(out,hname,
"->GetXaxis()");
6982 fYaxis.SaveAttributes(out,hname,
"->GetYaxis()");
6983 fZaxis.SaveAttributes(out,hname,
"->GetZaxis()");
6984 TString opt = option;
6986 if (!opt.Contains(
"nodraw")) {
6987 out<<
" "<<hname<<
"->Draw("
6988 <<quote<<option<<quote<<
");"<<std::endl;
6995 void TH1::UseCurrentStyle()
6997 if (!gStyle)
return;
6998 if (gStyle->IsReading()) {
6999 fXaxis.ResetAttAxis(
"X");
7000 fYaxis.ResetAttAxis(
"Y");
7001 fZaxis.ResetAttAxis(
"Z");
7002 SetBarOffset(gStyle->GetBarOffset());
7003 SetBarWidth(gStyle->GetBarWidth());
7004 SetFillColor(gStyle->GetHistFillColor());
7005 SetFillStyle(gStyle->GetHistFillStyle());
7006 SetLineColor(gStyle->GetHistLineColor());
7007 SetLineStyle(gStyle->GetHistLineStyle());
7008 SetLineWidth(gStyle->GetHistLineWidth());
7009 SetMarkerColor(gStyle->GetMarkerColor());
7010 SetMarkerStyle(gStyle->GetMarkerStyle());
7011 SetMarkerSize(gStyle->GetMarkerSize());
7012 Int_t dostat = gStyle->GetOptStat();
7013 if (gStyle->GetOptFit() && !dostat) dostat = 1000000001;
7016 gStyle->SetBarOffset(fBarOffset);
7017 gStyle->SetBarWidth(fBarWidth);
7018 gStyle->SetHistFillColor(GetFillColor());
7019 gStyle->SetHistFillStyle(GetFillStyle());
7020 gStyle->SetHistLineColor(GetLineColor());
7021 gStyle->SetHistLineStyle(GetLineStyle());
7022 gStyle->SetHistLineWidth(GetLineWidth());
7023 gStyle->SetMarkerColor(GetMarkerColor());
7024 gStyle->SetMarkerStyle(GetMarkerStyle());
7025 gStyle->SetMarkerSize(GetMarkerSize());
7026 gStyle->SetOptStat(TestBit(kNoStats));
7028 TIter next(GetListOfFunctions());
7031 while ((obj = next())) {
7032 obj->UseCurrentStyle();
7059 Double_t TH1::GetMean(Int_t axis)
const
7061 if (axis<1 || (axis>3 && axis<11) || axis>13)
return 0;
7062 Double_t stats[kNstat];
7063 for (Int_t i=4;i<kNstat;i++) stats[i] = 0;
7065 if (stats[0] == 0)
return 0;
7067 Int_t ax[3] = {2,4,7};
7068 return stats[ax[axis-1]]/stats[0];
7071 Double_t stddev = GetStdDev(axis-10);
7072 Double_t neff = GetEffectiveEntries();
7073 return ( neff > 0 ? stddev/TMath::Sqrt(neff) : 0. );
7090 Double_t TH1::GetMeanError(Int_t axis)
const
7092 return GetMean(axis+10);
7113 Double_t TH1::GetStdDev(Int_t axis)
const
7115 if (axis<1 || (axis>3 && axis<11) || axis>13)
return 0;
7117 Double_t x, stddev2, stats[kNstat];
7118 for (Int_t i=4;i<kNstat;i++) stats[i] = 0;
7120 if (stats[0] == 0)
return 0;
7121 Int_t ax[3] = {2,4,7};
7122 Int_t axm = ax[axis%10 - 1];
7123 x = stats[axm]/stats[0];
7125 stddev2 = TMath::Max( stats[axm+1]/stats[0] -x*x, 0.0 );
7127 return TMath::Sqrt(stddev2);
7131 Double_t neff = GetEffectiveEntries();
7132 return ( neff > 0 ? TMath::Sqrt(stddev2/(2*neff) ) : 0. );
7152 Double_t TH1::GetStdDevError(Int_t axis)
const
7154 return GetStdDev(axis+10);
7165 Double_t TH1::GetSkewness(Int_t axis)
const
7168 if (axis > 0 && axis <= 3){
7170 Double_t mean = GetMean(axis);
7171 Double_t stddev = GetStdDev(axis);
7172 Double_t stddev3 = stddev*stddev*stddev;
7174 Int_t firstBinX = fXaxis.GetFirst();
7175 Int_t lastBinX = fXaxis.GetLast();
7176 Int_t firstBinY = fYaxis.GetFirst();
7177 Int_t lastBinY = fYaxis.GetLast();
7178 Int_t firstBinZ = fZaxis.GetFirst();
7179 Int_t lastBinZ = fZaxis.GetLast();
7181 if (GetStatOverflowsBehaviour()) {
7182 if ( !fXaxis.TestBit(TAxis::kAxisRange) ) {
7183 if (firstBinX == 1) firstBinX = 0;
7184 if (lastBinX == fXaxis.GetNbins() ) lastBinX += 1;
7186 if ( !fYaxis.TestBit(TAxis::kAxisRange) ) {
7187 if (firstBinY == 1) firstBinY = 0;
7188 if (lastBinY == fYaxis.GetNbins() ) lastBinY += 1;
7190 if ( !fZaxis.TestBit(TAxis::kAxisRange) ) {
7191 if (firstBinZ == 1) firstBinZ = 0;
7192 if (lastBinZ == fZaxis.GetNbins() ) lastBinZ += 1;
7199 for (Int_t binx = firstBinX; binx <= lastBinX; binx++) {
7200 for (Int_t biny = firstBinY; biny <= lastBinY; biny++) {
7201 for (Int_t binz = firstBinZ; binz <= lastBinZ; binz++) {
7202 if (axis==1 ) x = fXaxis.GetBinCenter(binx);
7203 else if (axis==2 ) x = fYaxis.GetBinCenter(biny);
7204 else if (axis==3 ) x = fZaxis.GetBinCenter(binz);
7205 Double_t w = GetBinContent(binx,biny,binz);
7207 sum+=w*(x-mean)*(x-mean)*(x-mean);
7214 else if (axis > 10 && axis <= 13) {
7217 Double_t neff = GetEffectiveEntries();
7218 return ( neff > 0 ? TMath::Sqrt(6./neff ) : 0. );
7221 Error(
"GetSkewness",
"illegal value of parameter");
7235 Double_t TH1::GetKurtosis(Int_t axis)
const
7237 if (axis > 0 && axis <= 3){
7239 Double_t mean = GetMean(axis);
7240 Double_t stddev = GetStdDev(axis);
7241 Double_t stddev4 = stddev*stddev*stddev*stddev;
7243 Int_t firstBinX = fXaxis.GetFirst();
7244 Int_t lastBinX = fXaxis.GetLast();
7245 Int_t firstBinY = fYaxis.GetFirst();
7246 Int_t lastBinY = fYaxis.GetLast();
7247 Int_t firstBinZ = fZaxis.GetFirst();
7248 Int_t lastBinZ = fZaxis.GetLast();
7250 if (GetStatOverflowsBehaviour()) {
7251 if ( !fXaxis.TestBit(TAxis::kAxisRange) ) {
7252 if (firstBinX == 1) firstBinX = 0;
7253 if (lastBinX == fXaxis.GetNbins() ) lastBinX += 1;
7255 if ( !fYaxis.TestBit(TAxis::kAxisRange) ) {
7256 if (firstBinY == 1) firstBinY = 0;
7257 if (lastBinY == fYaxis.GetNbins() ) lastBinY += 1;
7259 if ( !fZaxis.TestBit(TAxis::kAxisRange) ) {
7260 if (firstBinZ == 1) firstBinZ = 0;
7261 if (lastBinZ == fZaxis.GetNbins() ) lastBinZ += 1;
7268 for (Int_t binx = firstBinX; binx <= lastBinX; binx++) {
7269 for (Int_t biny = firstBinY; biny <= lastBinY; biny++) {
7270 for (Int_t binz = firstBinZ; binz <= lastBinZ; binz++) {
7271 if (axis==1 ) x = fXaxis.GetBinCenter(binx);
7272 else if (axis==2 ) x = fYaxis.GetBinCenter(biny);
7273 else if (axis==3 ) x = fZaxis.GetBinCenter(binz);
7274 Double_t w = GetBinContent(binx,biny,binz);
7276 sum+=w*(x-mean)*(x-mean)*(x-mean)*(x-mean);
7283 }
else if (axis > 10 && axis <= 13) {
7286 Double_t neff = GetEffectiveEntries();
7287 return ( neff > 0 ? TMath::Sqrt(24./neff ) : 0. );
7290 Error(
"GetKurtosis",
"illegal value of parameter");
7318 void TH1::GetStats(Double_t *stats)
const
7320 if (fBuffer) ((TH1*)
this)->BufferEmpty();
7328 Bool_t labelHist = ((
const_cast<TAxis&
>(fXaxis)).GetLabels() && CanExtendAllAxes() );
7330 if ((fTsumw == 0 && fEntries > 0) || ( fXaxis.TestBit(TAxis::kAxisRange) && !labelHist) ) {
7331 for (bin=0;bin<4;bin++) stats[bin] = 0;
7333 Int_t firstBinX = fXaxis.GetFirst();
7334 Int_t lastBinX = fXaxis.GetLast();
7336 if (GetStatOverflowsBehaviour() && !fXaxis.TestBit(TAxis::kAxisRange)) {
7337 if (firstBinX == 1) firstBinX = 0;
7338 if (lastBinX == fXaxis.GetNbins() ) lastBinX += 1;
7340 for (binx = firstBinX; binx <= lastBinX; binx++) {
7341 x = fXaxis.GetBinCenter(binx);
7344 w = RetrieveBinContent(binx);
7345 err = TMath::Abs(GetBinError(binx));
7347 stats[1] += err*err;
7362 stats[3] = fTsumwx2;
7369 void TH1::PutStats(Double_t *stats)
7374 fTsumwx2 = stats[3];
7384 void TH1::ResetStats()
7386 Double_t stats[kNstat] = {0};
7391 fEntries = TMath::Abs(fTsumw);
7393 if (fSumw2.fN > 0 && fTsumw > 0 && stats[1] > 0 ) fEntries = stats[0]*stats[0]/ stats[1];
7399 Double_t TH1::GetSumOfWeights()
const
7401 if (fBuffer)
const_cast<TH1*
>(
this)->BufferEmpty();
7403 Int_t bin,binx,biny,binz;
7405 for(binz=1; binz<=fZaxis.GetNbins(); binz++) {
7406 for(biny=1; biny<=fYaxis.GetNbins(); biny++) {
7407 for(binx=1; binx<=fXaxis.GetNbins(); binx++) {
7408 bin = GetBin(binx,biny,binz);
7409 sum += RetrieveBinContent(bin);
7423 Double_t TH1::Integral(Option_t *option)
const
7425 return Integral(fXaxis.GetFirst(),fXaxis.GetLast(),option);
7435 Double_t TH1::Integral(Int_t binx1, Int_t binx2, Option_t *option)
const
7438 return DoIntegral(binx1,binx2,0,-1,0,-1,err,option);
7450 Double_t TH1::IntegralAndError(Int_t binx1, Int_t binx2, Double_t & error, Option_t *option)
const
7452 return DoIntegral(binx1,binx2,0,-1,0,-1,error,option,kTRUE);
7459 Double_t TH1::DoIntegral(Int_t binx1, Int_t binx2, Int_t biny1, Int_t biny2, Int_t binz1, Int_t binz2, Double_t & error ,
7460 Option_t *option, Bool_t doError)
const
7462 if (fBuffer) ((TH1*)
this)->BufferEmpty();
7464 Int_t nx = GetNbinsX() + 2;
7465 if (binx1 < 0) binx1 = 0;
7466 if (binx2 >= nx || binx2 < binx1) binx2 = nx - 1;
7468 if (GetDimension() > 1) {
7469 Int_t ny = GetNbinsY() + 2;
7470 if (biny1 < 0) biny1 = 0;
7471 if (biny2 >= ny || biny2 < biny1) biny2 = ny - 1;
7473 biny1 = 0; biny2 = 0;
7476 if (GetDimension() > 2) {
7477 Int_t nz = GetNbinsZ() + 2;
7478 if (binz1 < 0) binz1 = 0;
7479 if (binz2 >= nz || binz2 < binz1) binz2 = nz - 1;
7481 binz1 = 0; binz2 = 0;
7485 TString opt = option;
7487 Bool_t width = kFALSE;
7488 if (opt.Contains(
"width")) width = kTRUE;
7491 Double_t dx = 1., dy = .1, dz =.1;
7492 Double_t integral = 0;
7493 Double_t igerr2 = 0;
7494 for (Int_t binx = binx1; binx <= binx2; ++binx) {
7495 if (width) dx = fXaxis.GetBinWidth(binx);
7496 for (Int_t biny = biny1; biny <= biny2; ++biny) {
7497 if (width) dy = fYaxis.GetBinWidth(biny);
7498 for (Int_t binz = binz1; binz <= binz2; ++binz) {
7499 Int_t bin = GetBin(binx, biny, binz);
7502 dz = fZaxis.GetBinWidth(binz);
7504 integral += RetrieveBinContent(bin) * dv;
7506 integral += RetrieveBinContent(bin);
7509 if (width) igerr2 += GetBinErrorSqUnchecked(bin) * dv * dv;
7510 else igerr2 += GetBinErrorSqUnchecked(bin);
7516 if (doError) error = TMath::Sqrt(igerr2);
7543 Double_t TH1::AndersonDarlingTest(
const TH1 *h2, Option_t *option)
const
7545 Double_t advalue = 0;
7546 Double_t pvalue = AndersonDarlingTest(h2, advalue);
7548 TString opt = option;
7550 if (opt.Contains(
"D") ) {
7551 printf(
" AndersonDarlingTest Prob = %g, AD TestStatistic = %g\n",pvalue,advalue);
7553 if (opt.Contains(
"T") )
return advalue;
7561 Double_t TH1::AndersonDarlingTest(
const TH1 *h2, Double_t & advalue)
const
7563 if (GetDimension() != 1 || h2->GetDimension() != 1) {
7564 Error(
"AndersonDarlingTest",
"Histograms must be 1-D");
7569 if (fBuffer) ((TH1*)
this)->BufferEmpty();
7572 ROOT::Fit::BinData data1;
7573 ROOT::Fit::BinData data2;
7575 ROOT::Fit::FillData(data1,
this, 0);
7576 ROOT::Fit::FillData(data2, h2, 0);
7579 ROOT::Math::GoFTest::AndersonDarling2SamplesTest(data1,data2, pvalue,advalue);
7657 Double_t TH1::KolmogorovTest(
const TH1 *h2, Option_t *option)
const
7659 TString opt = option;
7663 TH1 *h1 = (TH1*)
this;
7664 if (h2 == 0)
return 0;
7665 const TAxis *axis1 = h1->GetXaxis();
7666 const TAxis *axis2 = h2->GetXaxis();
7667 Int_t ncx1 = axis1->GetNbins();
7668 Int_t ncx2 = axis2->GetNbins();
7671 if (h1->GetDimension() != 1 || h2->GetDimension() != 1) {
7672 Error(
"KolmogorovTest",
"Histograms must be 1-D\n");
7678 Error(
"KolmogorovTest",
"Histograms have different number of bins, %d and %d\n",ncx1,ncx2);
7683 if (fBuffer) ((TH1*)
this)->BufferEmpty();
7686 for(Int_t i = 1; i <= axis1->GetNbins() + 1; ++i) {
7687 if(!TMath::AreEqualRel(axis1->GetBinLowEdge(i), axis2->GetBinLowEdge(i), 1.E-15)) {
7688 Error(
"KolmogorovTest",
"Histograms are not consistent: they have different bin edges");
7693 Bool_t afunc1 = kFALSE;
7694 Bool_t afunc2 = kFALSE;
7695 Double_t sum1 = 0, sum2 = 0;
7696 Double_t ew1, ew2, w1 = 0, w2 = 0;
7701 if (opt.Contains(
"U")) ifirst = 0;
7702 if (opt.Contains(
"O")) ilast = ncx1 +1;
7703 for (bin = ifirst; bin <= ilast; bin++) {
7704 sum1 += h1->RetrieveBinContent(bin);
7705 sum2 += h2->RetrieveBinContent(bin);
7706 ew1 = h1->GetBinError(bin);
7707 ew2 = h2->GetBinError(bin);
7712 Error(
"KolmogorovTest",
"Histogram1 %s integral is zero\n",h1->GetName());
7716 Error(
"KolmogorovTest",
"Histogram2 %s integral is zero\n",h2->GetName());
7723 Double_t esum1 = 0, esum2 = 0;
7725 esum1 = sum1 * sum1 / w1;
7730 esum2 = sum2 * sum2 / w2;
7734 if (afunc2 && afunc1) {
7735 Error(
"KolmogorovTest",
"Errors are zero for both histograms\n");
7740 Double_t s1 = 1/sum1;
7741 Double_t s2 = 1/sum2;
7744 Double_t dfmax =0, rsum1 = 0, rsum2 = 0;
7746 for (bin=ifirst;bin<=ilast;bin++) {
7747 rsum1 += s1*h1->RetrieveBinContent(bin);
7748 rsum2 += s2*h2->RetrieveBinContent(bin);
7749 dfmax = TMath::Max(dfmax,TMath::Abs(rsum1-rsum2));
7753 Double_t z, prb1=0, prb2=0, prb3=0;
7757 z = dfmax*TMath::Sqrt(esum2);
7760 z = dfmax*TMath::Sqrt(esum1);
7763 z = dfmax*TMath::Sqrt(esum1*esum2/(esum1+esum2));
7765 prob = TMath::KolmogorovProb(z);
7768 if (opt.Contains(
"N") && !(afunc1 || afunc2 ) ) {
7771 Double_t d12 = esum1-esum2;
7772 Double_t chi2 = d12*d12/(esum1+esum2);
7773 prb2 = TMath::Prob(chi2,1);
7775 if (prob > 0 && prb2 > 0) prob *= prb2*(1-TMath::Log(prob*prb2));
7779 const Int_t nEXPT = 1000;
7780 if (opt.Contains(
"X") && !(afunc1 || afunc2 ) ) {
7782 TH1 *h1_cpy = (TH1 *)(gDirectory ? gDirectory->CloneObject(
this, kFALSE) : gROOT->CloneObject(
this, kFALSE));
7783 TH1 *h1Expt = (TH1*)(gDirectory ? gDirectory->CloneObject(
this,kFALSE) : gROOT->CloneObject(
this,kFALSE));
7784 TH1 *h2Expt = (TH1*)(gDirectory ? gDirectory->CloneObject(
this,kFALSE) : gROOT->CloneObject(
this,kFALSE));
7786 if (GetMinimum() < 0.0) {
7789 Warning(
"KolmogorovTest",
"Detected bins with negative weights, these have been ignored and output might be "
7790 "skewed. Reduce number of bins for histogram?");
7791 while (h1_cpy->GetMinimum() < 0.0) {
7792 Int_t idx = h1_cpy->GetMinimumBin();
7793 h1_cpy->SetBinContent(idx, 0.0);
7799 for (Int_t i=0; i < nEXPT; i++) {
7802 h1Expt->FillRandom(h1_cpy, (Int_t)esum1);
7803 h2Expt->FillRandom(h1_cpy, (Int_t)esum2);
7804 dSEXPT = h1Expt->KolmogorovTest(h2Expt,
"M");
7805 if (dSEXPT>dfmax) prb3 += 1.0;
7807 prb3 /= (Double_t)nEXPT;
7814 if (opt.Contains(
"D")) {
7815 printf(
" Kolmo Prob h1 = %s, sum bin content =%g effective entries =%g\n",h1->GetName(),sum1,esum1);
7816 printf(
" Kolmo Prob h2 = %s, sum bin content =%g effective entries =%g\n",h2->GetName(),sum2,esum2);
7817 printf(
" Kolmo Prob = %g, Max Dist = %g\n",prob,dfmax);
7818 if (opt.Contains(
"N"))
7819 printf(
" Kolmo Prob = %f for shape alone, =%f for normalisation alone\n",prb1,prb2);
7820 if (opt.Contains(
"X"))
7821 printf(
" Kolmo Prob = %f with %d pseudo-experiments\n",prb3,nEXPT);
7824 if (TMath::Abs(rsum1-1) > 0.002) Warning(
"KolmogorovTest",
"Numerical problems with h1=%s\n",h1->GetName());
7825 if (TMath::Abs(rsum2-1) > 0.002) Warning(
"KolmogorovTest",
"Numerical problems with h2=%s\n",h2->GetName());
7827 if(opt.Contains(
"M"))
return dfmax;
7828 else if(opt.Contains(
"X"))
return prb3;
7835 void TH1::SetContent(
const Double_t *content)
7839 for (Int_t i = 0; i < fNcells; ++i) UpdateBinContent(i, content[i]);
7848 Int_t TH1::GetContour(Double_t *levels)
7850 Int_t nlevels = fContour.fN;
7854 SetContour(nlevels);
7856 if (TestBit(kUserContour) == 0) SetContour(nlevels);
7858 for (Int_t level=0; level<nlevels; level++) levels[level] = fContour.fArray[level];
7867 Double_t TH1::GetContourLevel(Int_t level)
const
7869 return (level >= 0 && level < fContour.fN) ? fContour.fArray[level] : 0.0;
7877 Double_t TH1::GetContourLevelPad(Int_t level)
const
7879 if (level <0 || level >= fContour.fN)
return 0;
7880 Double_t zlevel = fContour.fArray[level];
7885 if (gPad && gPad->GetLogz() && TestBit(kUserContour)) {
7886 if (zlevel <= 0)
return 0;
7887 zlevel = TMath::Log10(zlevel);
7895 void TH1::SetBuffer(Int_t buffersize, Option_t * )
7902 if (buffersize <= 0) {
7906 if (buffersize < 100) buffersize = 100;
7907 fBufferSize = 1 + buffersize*(fDimension+1);
7908 fBuffer =
new Double_t[fBufferSize];
7909 memset(fBuffer,0,
sizeof(Double_t)*fBufferSize);
7920 void TH1::SetContour(Int_t nlevels,
const Double_t *levels)
7923 ResetBit(kUserContour);
7928 fContour.Set(nlevels);
7932 SetBit(kUserContour);
7933 for (level=0; level<nlevels; level++) fContour.fArray[level] = levels[level];
7936 Double_t zmin = GetMinimum();
7937 Double_t zmax = GetMaximum();
7938 if ((zmin == zmax) && (zmin != 0)) {
7939 zmax += 0.01*TMath::Abs(zmax);
7940 zmin -= 0.01*TMath::Abs(zmin);
7942 Double_t dz = (zmax-zmin)/Double_t(nlevels);
7943 if (gPad && gPad->GetLogz()) {
7944 if (zmax <= 0)
return;
7945 if (zmin <= 0) zmin = 0.001*zmax;
7946 zmin = TMath::Log10(zmin);
7947 zmax = TMath::Log10(zmax);
7948 dz = (zmax-zmin)/Double_t(nlevels);
7950 for (level=0; level<nlevels; level++) {
7951 fContour.fArray[level] = zmin + dz*Double_t(level);
7959 void TH1::SetContourLevel(Int_t level, Double_t value)
7961 if (level < 0 || level >= fContour.fN)
return;
7962 SetBit(kUserContour);
7963 fContour.fArray[level] = value;
7979 Double_t TH1::GetMaximum(Double_t maxval)
const
7981 if (fMaximum != -1111)
return fMaximum;
7984 if (fBuffer) ((TH1*)
this)->BufferEmpty();
7986 Int_t bin, binx, biny, binz;
7987 Int_t xfirst = fXaxis.GetFirst();
7988 Int_t xlast = fXaxis.GetLast();
7989 Int_t yfirst = fYaxis.GetFirst();
7990 Int_t ylast = fYaxis.GetLast();
7991 Int_t zfirst = fZaxis.GetFirst();
7992 Int_t zlast = fZaxis.GetLast();
7993 Double_t maximum = -FLT_MAX, value;
7994 for (binz=zfirst;binz<=zlast;binz++) {
7995 for (biny=yfirst;biny<=ylast;biny++) {
7996 for (binx=xfirst;binx<=xlast;binx++) {
7997 bin = GetBin(binx,biny,binz);
7998 value = RetrieveBinContent(bin);
7999 if (value > maximum && value < maxval) maximum = value;
8009 Int_t TH1::GetMaximumBin()
const
8011 Int_t locmax, locmay, locmaz;
8012 return GetMaximumBin(locmax, locmay, locmaz);
8018 Int_t TH1::GetMaximumBin(Int_t &locmax, Int_t &locmay, Int_t &locmaz)
const
8021 if (fBuffer) ((TH1*)
this)->BufferEmpty();
8023 Int_t bin, binx, biny, binz;
8025 Int_t xfirst = fXaxis.GetFirst();
8026 Int_t xlast = fXaxis.GetLast();
8027 Int_t yfirst = fYaxis.GetFirst();
8028 Int_t ylast = fYaxis.GetLast();
8029 Int_t zfirst = fZaxis.GetFirst();
8030 Int_t zlast = fZaxis.GetLast();
8031 Double_t maximum = -FLT_MAX, value;
8032 locm = locmax = locmay = locmaz = 0;
8033 for (binz=zfirst;binz<=zlast;binz++) {
8034 for (biny=yfirst;biny<=ylast;biny++) {
8035 for (binx=xfirst;binx<=xlast;binx++) {
8036 bin = GetBin(binx,biny,binz);
8037 value = RetrieveBinContent(bin);
8038 if (value > maximum) {
8064 Double_t TH1::GetMinimum(Double_t minval)
const
8066 if (fMinimum != -1111)
return fMinimum;
8069 if (fBuffer) ((TH1*)
this)->BufferEmpty();
8071 Int_t bin, binx, biny, binz;
8072 Int_t xfirst = fXaxis.GetFirst();
8073 Int_t xlast = fXaxis.GetLast();
8074 Int_t yfirst = fYaxis.GetFirst();
8075 Int_t ylast = fYaxis.GetLast();
8076 Int_t zfirst = fZaxis.GetFirst();
8077 Int_t zlast = fZaxis.GetLast();
8078 Double_t minimum=FLT_MAX, value;
8079 for (binz=zfirst;binz<=zlast;binz++) {
8080 for (biny=yfirst;biny<=ylast;biny++) {
8081 for (binx=xfirst;binx<=xlast;binx++) {
8082 bin = GetBin(binx,biny,binz);
8083 value = RetrieveBinContent(bin);
8084 if (value < minimum && value > minval) minimum = value;
8094 Int_t TH1::GetMinimumBin()
const
8096 Int_t locmix, locmiy, locmiz;
8097 return GetMinimumBin(locmix, locmiy, locmiz);
8103 Int_t TH1::GetMinimumBin(Int_t &locmix, Int_t &locmiy, Int_t &locmiz)
const
8106 if (fBuffer) ((TH1*)
this)->BufferEmpty();
8108 Int_t bin, binx, biny, binz;
8110 Int_t xfirst = fXaxis.GetFirst();
8111 Int_t xlast = fXaxis.GetLast();
8112 Int_t yfirst = fYaxis.GetFirst();
8113 Int_t ylast = fYaxis.GetLast();
8114 Int_t zfirst = fZaxis.GetFirst();
8115 Int_t zlast = fZaxis.GetLast();
8116 Double_t minimum = FLT_MAX, value;
8117 locm = locmix = locmiy = locmiz = 0;
8118 for (binz=zfirst;binz<=zlast;binz++) {
8119 for (biny=yfirst;biny<=ylast;biny++) {
8120 for (binx=xfirst;binx<=xlast;binx++) {
8121 bin = GetBin(binx,biny,binz);
8122 value = RetrieveBinContent(bin);
8123 if (value < minimum) {
8160 void TH1::GetMinimumAndMaximum(Double_t& min, Double_t& max)
const
8163 if (fBuffer) ((TH1*)
this)->BufferEmpty();
8165 Int_t bin, binx, biny, binz;
8166 Int_t xfirst = fXaxis.GetFirst();
8167 Int_t xlast = fXaxis.GetLast();
8168 Int_t yfirst = fYaxis.GetFirst();
8169 Int_t ylast = fYaxis.GetLast();
8170 Int_t zfirst = fZaxis.GetFirst();
8171 Int_t zlast = fZaxis.GetLast();
8172 min=TMath::Infinity();
8173 max=-TMath::Infinity();
8175 for (binz=zfirst;binz<=zlast;binz++) {
8176 for (biny=yfirst;biny<=ylast;biny++) {
8177 for (binx=xfirst;binx<=xlast;binx++) {
8178 bin = GetBin(binx,biny,binz);
8179 value = RetrieveBinContent(bin);
8180 if (value < min) min = value;
8181 if (value > max) max = value;
8196 void TH1::SetBins(Int_t nx, Double_t xmin, Double_t xmax)
8198 if (GetDimension() != 1) {
8199 Error(
"SetBins",
"Operation only valid for 1-d histograms");
8202 fXaxis.SetRange(0,0);
8203 fXaxis.Set(nx,xmin,xmax);
8207 SetBinsLength(fNcells);
8209 fSumw2.Set(fNcells);
8223 void TH1::SetBins(Int_t nx,
const Double_t *xBins)
8225 if (GetDimension() != 1) {
8226 Error(
"SetBins",
"Operation only valid for 1-d histograms");
8229 fXaxis.SetRange(0,0);
8230 fXaxis.Set(nx,xBins);
8234 SetBinsLength(fNcells);
8236 fSumw2.Set(fNcells);
8249 void TH1::SetBins(Int_t nx, Double_t xmin, Double_t xmax, Int_t ny, Double_t ymin, Double_t ymax)
8251 if (GetDimension() != 2) {
8252 Error(
"SetBins",
"Operation only valid for 2-D histograms");
8255 fXaxis.SetRange(0,0);
8256 fYaxis.SetRange(0,0);
8257 fXaxis.Set(nx,xmin,xmax);
8258 fYaxis.Set(ny,ymin,ymax);
8260 fNcells = (nx+2)*(ny+2);
8261 SetBinsLength(fNcells);
8263 fSumw2.Set(fNcells);
8277 void TH1::SetBins(Int_t nx,
const Double_t *xBins, Int_t ny,
const Double_t *yBins)
8279 if (GetDimension() != 2) {
8280 Error(
"SetBins",
"Operation only valid for 2-D histograms");
8283 fXaxis.SetRange(0,0);
8284 fYaxis.SetRange(0,0);
8285 fXaxis.Set(nx,xBins);
8286 fYaxis.Set(ny,yBins);
8288 fNcells = (nx+2)*(ny+2);
8289 SetBinsLength(fNcells);
8291 fSumw2.Set(fNcells);
8304 void TH1::SetBins(Int_t nx, Double_t xmin, Double_t xmax, Int_t ny, Double_t ymin, Double_t ymax, Int_t nz, Double_t zmin, Double_t zmax)
8306 if (GetDimension() != 3) {
8307 Error(
"SetBins",
"Operation only valid for 3-D histograms");
8310 fXaxis.SetRange(0,0);
8311 fYaxis.SetRange(0,0);
8312 fZaxis.SetRange(0,0);
8313 fXaxis.Set(nx,xmin,xmax);
8314 fYaxis.Set(ny,ymin,ymax);
8315 fZaxis.Set(nz,zmin,zmax);
8316 fNcells = (nx+2)*(ny+2)*(nz+2);
8317 SetBinsLength(fNcells);
8319 fSumw2.Set(fNcells);
8334 void TH1::SetBins(Int_t nx,
const Double_t *xBins, Int_t ny,
const Double_t *yBins, Int_t nz,
const Double_t *zBins)
8336 if (GetDimension() != 3) {
8337 Error(
"SetBins",
"Operation only valid for 3-D histograms");
8340 fXaxis.SetRange(0,0);
8341 fYaxis.SetRange(0,0);
8342 fZaxis.SetRange(0,0);
8343 fXaxis.Set(nx,xBins);
8344 fYaxis.Set(ny,yBins);
8345 fZaxis.Set(nz,zBins);
8346 fNcells = (nx+2)*(ny+2)*(nz+2);
8347 SetBinsLength(fNcells);
8349 fSumw2.Set(fNcells);
8366 void TH1::SetDirectory(TDirectory *dir)
8368 if (fDirectory == dir)
return;
8369 if (fDirectory) fDirectory->Remove(
this);
8372 fFunctions->UseRWLock();
8373 fDirectory->Append(
this);
8380 void TH1::SetError(
const Double_t *error)
8382 for (Int_t i = 0; i < fNcells; ++i) SetBinError(i, error[i]);
8389 void TH1::SetName(
const char *name)
8394 R__LOCKGUARD(gROOTMutex);
8395 if (fDirectory) fDirectory->Remove(
this);
8397 if (fDirectory) fDirectory->Append(
this);
8403 void TH1::SetNameTitle(
const char *name,
const char *title)
8419 void TH1::SetStats(Bool_t stats)
8426 TObject *obj = fFunctions->FindObject(
"stats");
8428 fFunctions->Remove(obj);
8449 void TH1::Sumw2(Bool_t flag)
8453 if (fSumw2.fN > 0 ) fSumw2.Set(0);
8457 if (fSumw2.fN == fNcells) {
8458 if (!fgDefaultSumw2 )
8459 Warning(
"Sumw2",
"Sum of squares of weights structure already created");
8463 fSumw2.Set(fNcells);
8466 if (fBuffer) BufferEmpty();
8469 for (Int_t i = 0; i < fNcells; ++i)
8470 fSumw2.fArray[i] = TMath::Abs(RetrieveBinContent(i));
8480 TF1 *TH1::GetFunction(
const char *name)
const
8482 return (TF1*)fFunctions->FindObject(name);
8492 Double_t TH1::GetBinError(Int_t bin)
const
8494 if (bin < 0) bin = 0;
8495 if (bin >= fNcells) bin = fNcells-1;
8496 if (fBuffer) ((TH1*)
this)->BufferEmpty();
8497 if (fSumw2.fN)
return TMath::Sqrt(fSumw2.fArray[bin]);
8499 return TMath::Sqrt(TMath::Abs(RetrieveBinContent(bin)));
8508 Double_t TH1::GetBinErrorLow(Int_t bin)
const
8510 if (fBinStatErrOpt == kNormal)
return GetBinError(bin);
8512 if (fSumw2.fN && fTsumw != fTsumw2)
return GetBinError(bin);
8514 if (bin < 0) bin = 0;
8515 if (bin >= fNcells) bin = fNcells-1;
8516 if (fBuffer) ((TH1*)
this)->BufferEmpty();
8518 Double_t alpha = 1.- 0.682689492;
8519 if (fBinStatErrOpt == kPoisson2) alpha = 0.05;
8521 Double_t c = RetrieveBinContent(bin);
8524 Warning(
"GetBinErrorLow",
"Histogram has negative bin content-force usage to normal errors");
8525 ((TH1*)
this)->fBinStatErrOpt = kNormal;
8526 return GetBinError(bin);
8529 if (n == 0)
return 0;
8530 return c - ROOT::Math::gamma_quantile( alpha/2, n, 1.);
8539 Double_t TH1::GetBinErrorUp(Int_t bin)
const
8541 if (fBinStatErrOpt == kNormal)
return GetBinError(bin);
8543 if (fSumw2.fN && fTsumw != fTsumw2)
return GetBinError(bin);
8544 if (bin < 0) bin = 0;
8545 if (bin >= fNcells) bin = fNcells-1;
8546 if (fBuffer) ((TH1*)
this)->BufferEmpty();
8548 Double_t alpha = 1.- 0.682689492;
8549 if (fBinStatErrOpt == kPoisson2) alpha = 0.05;
8551 Double_t c = RetrieveBinContent(bin);
8554 Warning(
"GetBinErrorUp",
"Histogram has negative bin content-force usage to normal errors");
8555 ((TH1*)
this)->fBinStatErrOpt = kNormal;
8556 return GetBinError(bin);
8562 return ROOT::Math::gamma_quantile_c( alpha/2, n+1, 1) - c;
8570 Double_t TH1::GetBinCenter(Int_t bin)
const
8572 if (fDimension == 1)
return fXaxis.GetBinCenter(bin);
8573 Error(
"GetBinCenter",
"Invalid method for a %d-d histogram - return a NaN",fDimension);
8574 return TMath::QuietNaN();
8581 Double_t TH1::GetBinLowEdge(Int_t bin)
const
8583 if (fDimension == 1)
return fXaxis.GetBinLowEdge(bin);
8584 Error(
"GetBinLowEdge",
"Invalid method for a %d-d histogram - return a NaN",fDimension);
8585 return TMath::QuietNaN();
8592 Double_t TH1::GetBinWidth(Int_t bin)
const
8594 if (fDimension == 1)
return fXaxis.GetBinWidth(bin);
8595 Error(
"GetBinWidth",
"Invalid method for a %d-d histogram - return a NaN",fDimension);
8596 return TMath::QuietNaN();
8603 void TH1::GetCenter(Double_t *center)
const
8605 if (fDimension == 1) {
8606 fXaxis.GetCenter(center);
8609 Error(
"GetCenter",
"Invalid method for a %d-d histogram ",fDimension);
8616 void TH1::GetLowEdge(Double_t *edge)
const
8618 if (fDimension == 1) {
8619 fXaxis.GetLowEdge(edge);
8622 Error(
"GetLowEdge",
"Invalid method for a %d-d histogram ",fDimension);
8635 void TH1::SetBinError(Int_t bin, Double_t error)
8637 if (bin < 0 || bin>= fNcells)
return;
8638 if (!fSumw2.fN) Sumw2();
8639 fSumw2.fArray[bin] = error * error;
8641 SetBinErrorOption(kNormal);
8651 void TH1::SetBinContent(Int_t bin, Double_t content)
8655 if (bin < 0)
return;
8656 if (bin >= fNcells-1) {
8657 if (fXaxis.GetTimeDisplay() || CanExtendAllAxes() ) {
8658 while (bin >= fNcells-1) LabelsInflate();
8660 if (bin == fNcells-1) UpdateBinContent(bin, content);
8664 UpdateBinContent(bin, content);
8670 void TH1::SetBinError(Int_t binx, Int_t biny, Double_t error)
8672 if (binx < 0 || binx > fXaxis.GetNbins() + 1)
return;
8673 if (biny < 0 || biny > fYaxis.GetNbins() + 1)
return;
8674 SetBinError(GetBin(binx, biny), error);
8680 void TH1::SetBinError(Int_t binx, Int_t biny, Int_t binz, Double_t error)
8682 if (binx < 0 || binx > fXaxis.GetNbins() + 1)
return;
8683 if (biny < 0 || biny > fYaxis.GetNbins() + 1)
return;
8684 if (binz < 0 || binz > fZaxis.GetNbins() + 1)
return;
8685 SetBinError(GetBin(binx, biny, binz), error);
8716 TH1 *TH1::ShowBackground(Int_t niter, Option_t *option)
8719 return (TH1*)gROOT->ProcessLineFast(Form(
"TSpectrum::StaticBackground((TH1*)0x%lx,%d,\"%s\")",
8720 (ULong_t)
this, niter, option));
8731 Int_t TH1::ShowPeaks(Double_t sigma, Option_t *option, Double_t threshold)
8733 return (Int_t)gROOT->ProcessLineFast(Form(
"TSpectrum::StaticSearch((TH1*)0x%lx,%g,\"%s\",%g)",
8734 (ULong_t)
this, sigma, option, threshold));
8749 TH1* TH1::TransformHisto(TVirtualFFT *fft, TH1* h_output, Option_t *option)
8751 if (!fft || !fft->GetN() ) {
8752 ::Error(
"TransformHisto",
"Invalid FFT transform class");
8756 if (fft->GetNdim()>2){
8757 ::Error(
"TransformHisto",
"Only 1d and 2D transform are supported");
8761 TString opt = option;
8763 Int_t *n = fft->GetN();
8769 TString name = TString::Format(
"out_%s", opt.Data());
8770 if (fft->GetNdim()==1)
8771 hout =
new TH1D(name, name,n[0], 0, n[0]);
8772 else if (fft->GetNdim()==2)
8773 hout =
new TH2D(name, name, n[0], 0, n[0], n[1], 0, n[1]);
8775 R__ASSERT(hout != 0);
8776 TString type=fft->GetType();
8778 if (opt.Contains(
"RE")){
8779 if (type.Contains(
"2C") || type.Contains(
"2HC")) {
8781 for (binx = 1; binx<=hout->GetNbinsX(); binx++) {
8782 for (biny=1; biny<=hout->GetNbinsY(); biny++) {
8783 ind[0] = binx-1; ind[1] = biny-1;
8784 fft->GetPointComplex(ind, re, im);
8785 hout->SetBinContent(binx, biny, re);
8789 for (binx = 1; binx<=hout->GetNbinsX(); binx++) {
8790 for (biny=1; biny<=hout->GetNbinsY(); biny++) {
8791 ind[0] = binx-1; ind[1] = biny-1;
8792 hout->SetBinContent(binx, biny, fft->GetPointReal(ind));
8797 if (opt.Contains(
"IM")) {
8798 if (type.Contains(
"2C") || type.Contains(
"2HC")) {
8800 for (binx = 1; binx<=hout->GetNbinsX(); binx++) {
8801 for (biny=1; biny<=hout->GetNbinsY(); biny++) {
8802 ind[0] = binx-1; ind[1] = biny-1;
8803 fft->GetPointComplex(ind, re, im);
8804 hout->SetBinContent(binx, biny, im);
8808 ::Error(
"TransformHisto",
"No complex numbers in the output");
8812 if (opt.Contains(
"MA")) {
8813 if (type.Contains(
"2C") || type.Contains(
"2HC")) {
8815 for (binx = 1; binx<=hout->GetNbinsX(); binx++) {
8816 for (biny=1; biny<=hout->GetNbinsY(); biny++) {
8817 ind[0] = binx-1; ind[1] = biny-1;
8818 fft->GetPointComplex(ind, re, im);
8819 hout->SetBinContent(binx, biny, TMath::Sqrt(re*re + im*im));
8823 for (binx = 1; binx<=hout->GetNbinsX(); binx++) {
8824 for (biny=1; biny<=hout->GetNbinsY(); biny++) {
8825 ind[0] = binx-1; ind[1] = biny-1;
8826 hout->SetBinContent(binx, biny, TMath::Abs(fft->GetPointReal(ind)));
8831 if (opt.Contains(
"PH")) {
8832 if (type.Contains(
"2C") || type.Contains(
"2HC")){
8833 Double_t re, im, ph;
8834 for (binx = 1; binx<=hout->GetNbinsX(); binx++){
8835 for (biny=1; biny<=hout->GetNbinsY(); biny++){
8836 ind[0] = binx-1; ind[1] = biny-1;
8837 fft->GetPointComplex(ind, re, im);
8838 if (TMath::Abs(re) > 1e-13){
8839 ph = TMath::ATan(im/re);
8846 if (TMath::Abs(im) < 1e-13)
8849 ph = TMath::Pi()*0.5;
8851 ph = -TMath::Pi()*0.5;
8853 hout->SetBinContent(binx, biny, ph);
8857 printf(
"Pure real output, no phase");
8869 Double_t TH1::RetrieveBinContent(Int_t)
const
8871 AbstractMethod(
"RetrieveBinContent");
8879 void TH1::UpdateBinContent(Int_t, Double_t)
8881 AbstractMethod(
"UpdateBinContent");
8887 std::string cling::printValue(TH1 *val) {
8888 std::ostringstream strm;
8889 strm << cling::printValue((TObject*)val) <<
" NbinsX: " << val->GetNbinsX();
8903 TH1C::TH1C(): TH1(), TArrayC()
8907 if (fgDefaultSumw2) Sumw2();
8914 TH1C::TH1C(
const char *name,
const char *title,Int_t nbins,Double_t xlow,Double_t xup)
8915 : TH1(name,title,nbins,xlow,xup)
8918 TArrayC::Set(fNcells);
8920 if (xlow >= xup) SetBuffer(fgBufferSize);
8921 if (fgDefaultSumw2) Sumw2();
8928 TH1C::TH1C(
const char *name,
const char *title,Int_t nbins,
const Float_t *xbins)
8929 : TH1(name,title,nbins,xbins)
8932 TArrayC::Set(fNcells);
8933 if (fgDefaultSumw2) Sumw2();
8940 TH1C::TH1C(
const char *name,
const char *title,Int_t nbins,
const Double_t *xbins)
8941 : TH1(name,title,nbins,xbins)
8944 TArrayC::Set(fNcells);
8945 if (fgDefaultSumw2) Sumw2();
8958 TH1C::TH1C(
const TH1C &h1c) : TH1(), TArrayC()
8960 ((TH1C&)h1c).Copy(*
this);
8966 void TH1C::AddBinContent(Int_t bin)
8968 if (fArray[bin] < 127) fArray[bin]++;
8974 void TH1C::AddBinContent(Int_t bin, Double_t w)
8976 Int_t newval = fArray[bin] + Int_t(w);
8977 if (newval > -128 && newval < 128) {fArray[bin] = Char_t(newval);
return;}
8978 if (newval < -127) fArray[bin] = -127;
8979 if (newval > 127) fArray[bin] = 127;
8985 void TH1C::Copy(TObject &newth1)
const
8993 void TH1C::Reset(Option_t *option)
9003 void TH1C::SetBinsLength(Int_t n)
9005 if (n < 0) n = fXaxis.GetNbins() + 2;
9013 TH1C& TH1C::operator=(
const TH1C &h1)
9015 if (
this != &h1) ((TH1C&)h1).Copy(*
this);
9022 TH1C operator*(Double_t c1,
const TH1C &h1)
9026 hnew.SetDirectory(0);
9033 TH1C operator+(
const TH1C &h1,
const TH1C &h2)
9037 hnew.SetDirectory(0);
9044 TH1C operator-(
const TH1C &h1,
const TH1C &h2)
9048 hnew.SetDirectory(0);
9055 TH1C operator*(
const TH1C &h1,
const TH1C &h2)
9059 hnew.SetDirectory(0);
9066 TH1C operator/(
const TH1C &h1,
const TH1C &h2)
9070 hnew.SetDirectory(0);
9084 TH1S::TH1S(): TH1(), TArrayS()
9088 if (fgDefaultSumw2) Sumw2();
9095 TH1S::TH1S(
const char *name,
const char *title,Int_t nbins,Double_t xlow,Double_t xup)
9096 : TH1(name,title,nbins,xlow,xup)
9099 TArrayS::Set(fNcells);
9101 if (xlow >= xup) SetBuffer(fgBufferSize);
9102 if (fgDefaultSumw2) Sumw2();
9109 TH1S::TH1S(
const char *name,
const char *title,Int_t nbins,
const Float_t *xbins)
9110 : TH1(name,title,nbins,xbins)
9113 TArrayS::Set(fNcells);
9114 if (fgDefaultSumw2) Sumw2();
9121 TH1S::TH1S(
const char *name,
const char *title,Int_t nbins,
const Double_t *xbins)
9122 : TH1(name,title,nbins,xbins)
9125 TArrayS::Set(fNcells);
9126 if (fgDefaultSumw2) Sumw2();
9139 TH1S::TH1S(
const TH1S &h1s) : TH1(), TArrayS()
9141 ((TH1S&)h1s).Copy(*
this);
9147 void TH1S::AddBinContent(Int_t bin)
9149 if (fArray[bin] < 32767) fArray[bin]++;
9155 void TH1S::AddBinContent(Int_t bin, Double_t w)
9157 Int_t newval = fArray[bin] + Int_t(w);
9158 if (newval > -32768 && newval < 32768) {fArray[bin] = Short_t(newval);
return;}
9159 if (newval < -32767) fArray[bin] = -32767;
9160 if (newval > 32767) fArray[bin] = 32767;
9166 void TH1S::Copy(TObject &newth1)
const
9174 void TH1S::Reset(Option_t *option)
9184 void TH1S::SetBinsLength(Int_t n)
9186 if (n < 0) n = fXaxis.GetNbins() + 2;
9194 TH1S& TH1S::operator=(
const TH1S &h1)
9196 if (
this != &h1) ((TH1S&)h1).Copy(*
this);
9203 TH1S operator*(Double_t c1,
const TH1S &h1)
9207 hnew.SetDirectory(0);
9214 TH1S operator+(
const TH1S &h1,
const TH1S &h2)
9218 hnew.SetDirectory(0);
9225 TH1S operator-(
const TH1S &h1,
const TH1S &h2)
9229 hnew.SetDirectory(0);
9236 TH1S operator*(
const TH1S &h1,
const TH1S &h2)
9240 hnew.SetDirectory(0);
9247 TH1S operator/(
const TH1S &h1,
const TH1S &h2)
9251 hnew.SetDirectory(0);
9265 TH1I::TH1I(): TH1(), TArrayI()
9269 if (fgDefaultSumw2) Sumw2();
9276 TH1I::TH1I(
const char *name,
const char *title,Int_t nbins,Double_t xlow,Double_t xup)
9277 : TH1(name,title,nbins,xlow,xup)
9280 TArrayI::Set(fNcells);
9282 if (xlow >= xup) SetBuffer(fgBufferSize);
9283 if (fgDefaultSumw2) Sumw2();
9290 TH1I::TH1I(
const char *name,
const char *title,Int_t nbins,
const Float_t *xbins)
9291 : TH1(name,title,nbins,xbins)
9294 TArrayI::Set(fNcells);
9295 if (fgDefaultSumw2) Sumw2();
9302 TH1I::TH1I(
const char *name,
const char *title,Int_t nbins,
const Double_t *xbins)
9303 : TH1(name,title,nbins,xbins)
9306 TArrayI::Set(fNcells);
9307 if (fgDefaultSumw2) Sumw2();
9320 TH1I::TH1I(
const TH1I &h1i) : TH1(), TArrayI()
9322 ((TH1I&)h1i).Copy(*
this);
9328 void TH1I::AddBinContent(Int_t bin)
9330 if (fArray[bin] < 2147483647) fArray[bin]++;
9336 void TH1I::AddBinContent(Int_t bin, Double_t w)
9338 Long64_t newval = fArray[bin] + Long64_t(w);
9339 if (newval > -2147483647 && newval < 2147483647) {fArray[bin] = Int_t(newval);
return;}
9340 if (newval < -2147483647) fArray[bin] = -2147483647;
9341 if (newval > 2147483647) fArray[bin] = 2147483647;
9347 void TH1I::Copy(TObject &newth1)
const
9355 void TH1I::Reset(Option_t *option)
9365 void TH1I::SetBinsLength(Int_t n)
9367 if (n < 0) n = fXaxis.GetNbins() + 2;
9375 TH1I& TH1I::operator=(
const TH1I &h1)
9377 if (
this != &h1) ((TH1I&)h1).Copy(*
this);
9385 TH1I operator*(Double_t c1,
const TH1I &h1)
9389 hnew.SetDirectory(0);
9396 TH1I operator+(
const TH1I &h1,
const TH1I &h2)
9400 hnew.SetDirectory(0);
9407 TH1I operator-(
const TH1I &h1,
const TH1I &h2)
9411 hnew.SetDirectory(0);
9418 TH1I operator*(
const TH1I &h1,
const TH1I &h2)
9422 hnew.SetDirectory(0);
9429 TH1I operator/(
const TH1I &h1,
const TH1I &h2)
9433 hnew.SetDirectory(0);
9447 TH1F::TH1F(): TH1(), TArrayF()
9451 if (fgDefaultSumw2) Sumw2();
9458 TH1F::TH1F(
const char *name,
const char *title,Int_t nbins,Double_t xlow,Double_t xup)
9459 : TH1(name,title,nbins,xlow,xup)
9462 TArrayF::Set(fNcells);
9464 if (xlow >= xup) SetBuffer(fgBufferSize);
9465 if (fgDefaultSumw2) Sumw2();
9472 TH1F::TH1F(
const char *name,
const char *title,Int_t nbins,
const Float_t *xbins)
9473 : TH1(name,title,nbins,xbins)
9476 TArrayF::Set(fNcells);
9477 if (fgDefaultSumw2) Sumw2();
9484 TH1F::TH1F(
const char *name,
const char *title,Int_t nbins,
const Double_t *xbins)
9485 : TH1(name,title,nbins,xbins)
9488 TArrayF::Set(fNcells);
9489 if (fgDefaultSumw2) Sumw2();
9496 TH1F::TH1F(
const TVectorF &v)
9497 : TH1(
"TVectorF",
"",v.GetNrows(),0,v.GetNrows())
9499 TArrayF::Set(fNcells);
9501 Int_t ivlow = v.GetLwb();
9502 for (Int_t i=0;i<fNcells-2;i++) {
9503 SetBinContent(i+1,v(i+ivlow));
9505 TArrayF::Set(fNcells);
9506 if (fgDefaultSumw2) Sumw2();
9512 TH1F::TH1F(
const TH1F &h) : TH1(), TArrayF()
9514 ((TH1F&)h).Copy(*
this);
9527 void TH1F::Copy(TObject &newth1)
const
9535 void TH1F::Reset(Option_t *option)
9545 void TH1F::SetBinsLength(Int_t n)
9547 if (n < 0) n = fXaxis.GetNbins() + 2;
9555 TH1F& TH1F::operator=(
const TH1F &h1)
9557 if (
this != &h1) ((TH1F&)h1).Copy(*
this);
9564 TH1F operator*(Double_t c1,
const TH1F &h1)
9568 hnew.SetDirectory(0);
9575 TH1F operator+(
const TH1F &h1,
const TH1F &h2)
9579 hnew.SetDirectory(0);
9586 TH1F operator-(
const TH1F &h1,
const TH1F &h2)
9590 hnew.SetDirectory(0);
9597 TH1F operator*(
const TH1F &h1,
const TH1F &h2)
9601 hnew.SetDirectory(0);
9608 TH1F operator/(
const TH1F &h1,
const TH1F &h2)
9612 hnew.SetDirectory(0);
9626 TH1D::TH1D(): TH1(), TArrayD()
9630 if (fgDefaultSumw2) Sumw2();
9637 TH1D::TH1D(
const char *name,
const char *title,Int_t nbins,Double_t xlow,Double_t xup)
9638 : TH1(name,title,nbins,xlow,xup)
9641 TArrayD::Set(fNcells);
9643 if (xlow >= xup) SetBuffer(fgBufferSize);
9644 if (fgDefaultSumw2) Sumw2();
9651 TH1D::TH1D(
const char *name,
const char *title,Int_t nbins,
const Float_t *xbins)
9652 : TH1(name,title,nbins,xbins)
9655 TArrayD::Set(fNcells);
9656 if (fgDefaultSumw2) Sumw2();
9663 TH1D::TH1D(
const char *name,
const char *title,Int_t nbins,
const Double_t *xbins)
9664 : TH1(name,title,nbins,xbins)
9667 TArrayD::Set(fNcells);
9668 if (fgDefaultSumw2) Sumw2();
9675 TH1D::TH1D(
const TVectorD &v)
9676 : TH1(
"TVectorD",
"",v.GetNrows(),0,v.GetNrows())
9678 TArrayD::Set(fNcells);
9680 Int_t ivlow = v.GetLwb();
9681 for (Int_t i=0;i<fNcells-2;i++) {
9682 SetBinContent(i+1,v(i+ivlow));
9684 TArrayD::Set(fNcells);
9685 if (fgDefaultSumw2) Sumw2();
9698 TH1D::TH1D(
const TH1D &h1d) : TH1(), TArrayD()
9700 ((TH1D&)h1d).Copy(*
this);
9706 void TH1D::Copy(TObject &newth1)
const
9714 void TH1D::Reset(Option_t *option)
9724 void TH1D::SetBinsLength(Int_t n)
9726 if (n < 0) n = fXaxis.GetNbins() + 2;
9734 TH1D& TH1D::operator=(
const TH1D &h1)
9736 if (
this != &h1) ((TH1D&)h1).Copy(*
this);
9743 TH1D operator*(Double_t c1,
const TH1D &h1)
9747 hnew.SetDirectory(0);
9754 TH1D operator+(
const TH1D &h1,
const TH1D &h2)
9758 hnew.SetDirectory(0);
9765 TH1D operator-(
const TH1D &h1,
const TH1D &h2)
9769 hnew.SetDirectory(0);
9776 TH1D operator*(
const TH1D &h1,
const TH1D &h2)
9780 hnew.SetDirectory(0);
9787 TH1D operator/(
const TH1D &h1,
const TH1D &h2)
9791 hnew.SetDirectory(0);
9800 TH1 *R__H(Int_t hid)
9803 if(hid >= 0) hname.Form(
"h%d",hid);
9804 else hname.Form(
"h_%d",hid);
9805 return (TH1*)gDirectory->Get(hname);
9811 TH1 *R__H(
const char * hname)
9813 return (TH1*)gDirectory->Get(hname);