23 Bool_t TProfile2D::fgApproximate = kFALSE;
72 TProfile2D::TProfile2D() : TH2D()
74 fTsumwz = fTsumwz2 = 0;
82 TProfile2D::~TProfile2D()
109 TProfile2D::TProfile2D(
const char *name,
const char *title,Int_t nx,Double_t xlow,Double_t xup,Int_t ny,Double_t ylow,Double_t yup,Option_t *option)
110 : TH2D(name,title,nx,xlow,xup,ny,ylow,yup)
112 BuildOptions(0,0,option);
113 if (xlow >= xup || ylow >= yup) SetBuffer(fgBufferSize);
119 TProfile2D::TProfile2D(
const char *name,
const char *title,Int_t nx,
const Double_t *xbins,Int_t ny,Double_t ylow,Double_t yup,Option_t *option)
120 : TH2D(name,title,nx,xbins,ny,ylow,yup)
122 BuildOptions(0,0,option);
128 TProfile2D::TProfile2D(
const char *name,
const char *title,Int_t nx,Double_t xlow,Double_t xup,Int_t ny,
const Double_t *ybins,Option_t *option)
129 : TH2D(name,title,nx,xlow,xup,ny,ybins)
131 BuildOptions(0,0,option);
137 TProfile2D::TProfile2D(
const char *name,
const char *title,Int_t nx,
const Double_t *xbins,Int_t ny,
const Double_t *ybins,Option_t *option)
138 : TH2D(name,title,nx,xbins,ny,ybins)
140 BuildOptions(0,0,option);
153 TProfile2D::TProfile2D(
const char *name,
const char *title,Int_t nx,Double_t xlow,Double_t xup,Int_t ny, Double_t ylow,Double_t yup,Double_t zlow,Double_t zup,Option_t *option)
154 : TH2D(name,title,nx,xlow,xup,ny,ylow,yup)
156 BuildOptions(zlow,zup,option);
157 if (xlow >= xup || ylow >= yup) SetBuffer(fgBufferSize);
173 void TProfile2D::BuildOptions(Double_t zmin, Double_t zmax, Option_t *option)
176 SetErrorOption(option);
179 TProfileHelper::BuildArray(
this);
184 fTsumwz = fTsumwz2 = 0;
190 TProfile2D::TProfile2D(
const TProfile2D &profile) : TH2D()
192 ((TProfile2D&)profile).Copy(*
this);
195 TProfile2D &TProfile2D::operator=(
const TProfile2D &profile)
197 ((TProfile2D &)profile).Copy(*
this);
204 Bool_t TProfile2D::Add(TF1 *, Double_t , Option_t*)
206 Error(
"Add",
"Function not implemented for TProfile2D");
213 Bool_t TProfile2D::Add(
const TH1 *h1, Double_t c1)
216 Error(
"Add",
"Attempt to add a non-existing profile");
219 if (!h1->InheritsFrom(TProfile2D::Class())) {
220 Error(
"Add",
"Attempt to add a non-profile2D object");
224 return TProfileHelper::Add(
this,
this, h1, 1, c1);
232 Bool_t TProfile2D::Add(
const TH1 *h1,
const TH1 *h2, Double_t c1, Double_t c2)
235 Error(
"Add",
"Attempt to add a non-existing profile");
238 if (!h1->InheritsFrom(TProfile2D::Class())) {
239 Error(
"Add",
"Attempt to add a non-profile2D object");
242 if (!h2->InheritsFrom(TProfile2D::Class())) {
243 Error(
"Add",
"Attempt to add a non-profile2D object");
246 return TProfileHelper::Add(
this, h1, h2, c1, c2);
260 void TProfile2D::Approximate(Bool_t approx)
262 fgApproximate = approx;
274 Int_t TProfile2D::BufferEmpty(Int_t action)
277 if (!fBuffer)
return 0;
278 Int_t nbentries = (Int_t)fBuffer[0];
279 if (!nbentries)
return 0;
280 Double_t *buffer = fBuffer;
282 if (action == 0)
return 0;
283 nbentries = -nbentries;
288 if (CanExtendAllAxes() || fXaxis.GetXmax() <= fXaxis.GetXmin() || fYaxis.GetXmax() <= fYaxis.GetXmin()) {
290 Double_t xmin = fBuffer[2];
291 Double_t xmax = xmin;
292 Double_t ymin = fBuffer[3];
293 Double_t ymax = ymin;
294 for (Int_t i=1;i<nbentries;i++) {
295 Double_t x = fBuffer[4*i+2];
296 if (x < xmin) xmin = x;
297 if (x > xmax) xmax = x;
298 Double_t y = fBuffer[4*i+3];
299 if (y < ymin) ymin = y;
300 if (y > ymax) ymax = y;
302 if (fXaxis.GetXmax() <= fXaxis.GetXmin() || fYaxis.GetXmax() <= fYaxis.GetXmin()) {
303 THLimitsFinder::GetLimitsFinder()->FindGoodLimits(
this,xmin,xmax,ymin,ymax);
306 Int_t keep = fBufferSize; fBufferSize = 0;
307 if (xmin < fXaxis.GetXmin()) ExtendAxis(xmin,&fXaxis);
308 if (xmax >= fXaxis.GetXmax()) ExtendAxis(xmax,&fXaxis);
309 if (ymin < fYaxis.GetXmin()) ExtendAxis(ymin,&fYaxis);
310 if (ymax >= fYaxis.GetXmax()) ExtendAxis(ymax,&fYaxis);
317 for (Int_t i=0;i<nbentries;i++) {
318 Fill(buffer[4*i+2],buffer[4*i+3],buffer[4*i+4],buffer[4*i+1]);
322 if (action > 0) {
delete [] fBuffer; fBuffer = 0; fBufferSize = 0;}
324 if (nbentries == (Int_t)fEntries) fBuffer[0] = -nbentries;
341 Int_t TProfile2D::BufferFill(Double_t x, Double_t y, Double_t z, Double_t w)
343 if (!fBuffer)
return -3;
344 Int_t nbentries = (Int_t)fBuffer[0];
346 nbentries = -nbentries;
347 fBuffer[0] = nbentries;
349 Double_t *buffer = fBuffer; fBuffer=0;
354 if (4*nbentries+4 >= fBufferSize) {
356 return Fill(x,y,z,w);
358 fBuffer[4*nbentries+1] = w;
359 fBuffer[4*nbentries+2] = x;
360 fBuffer[4*nbentries+3] = y;
361 fBuffer[4*nbentries+4] = z;
369 void TProfile2D::Copy(TObject &obj)
const
372 TProfile2D & pobj =
dynamic_cast<TProfile2D&
>(obj);
375 fBinEntries.Copy(pobj.fBinEntries);
376 fBinSumw2.Copy(pobj.fBinSumw2);
377 for (
int bin=0;bin<fNcells;bin++) {
378 pobj.fArray[bin] = fArray[bin];
379 pobj.fSumw2.fArray[bin] = fSumw2.fArray[bin];
383 pobj.fScaling = fScaling;
384 pobj.fErrorMode = fErrorMode;
385 pobj.fTsumwz = fTsumwz;
386 pobj.fTsumwz2 = fTsumwz2;
389 Fatal(
"Copy",
"Cannot copy a TProfile2D in a %s",obj.IsA()->GetName());
398 Bool_t TProfile2D::Divide(TF1 *, Double_t )
400 Error(
"Divide",
"Function not implemented for TProfile2D");
411 Bool_t TProfile2D::Divide(
const TH1 *h1)
415 Error(
"Divide",
"Attempt to divide a non-existing profile2D");
418 if (!h1->InheritsFrom(TProfile2D::Class())) {
419 Error(
"Divide",
"Attempt to divide a non-profile2D object");
422 TProfile2D *p1 = (TProfile2D*)h1;
425 if (fBuffer) BufferEmpty(1);
428 Int_t nx = GetNbinsX();
429 if (nx != p1->GetNbinsX()) {
430 Error(
"Divide",
"Attempt to divide profiles with different number of bins");
433 Int_t ny = GetNbinsY();
434 if (ny != p1->GetNbinsY()) {
435 Error(
"Divide",
"Attempt to divide profiles with different number of bins");
440 fEntries = fTsumw = fTsumw2 = fTsumwx = fTsumwx2 = 0;
444 Double_t *cu1 = p1->GetW();
445 Double_t *er1 = p1->GetW2();
446 Double_t *en1 = p1->GetB();
447 Double_t c0,c1,w,z,x,y;
448 for (binx =0;binx<=nx+1;binx++) {
449 for (biny =0;biny<=ny+1;biny++) {
450 bin = biny*(fXaxis.GetNbins()+2) + binx;
457 x = fXaxis.GetBinCenter(binx);
458 y = fYaxis.GetBinCenter(biny);
469 Double_t e0 = fSumw2.fArray[bin];
470 Double_t e1 = er1[bin];
472 if (!c1) fSumw2.fArray[bin] = 0;
473 else fSumw2.fArray[bin] = (e0*c1*c1 + e1*c0*c0)/(c12*c12);
474 if (!en1[bin]) fBinEntries.fArray[bin] = 0;
475 else fBinEntries.fArray[bin] /= en1[bin];
481 Warning(
"Divide",
"Cannot preserve during the division of profiles the sum of bin weight square");
482 fBinSumw2 = TArrayD();
494 Bool_t TProfile2D::Divide(
const TH1 *h1,
const TH1 *h2, Double_t c1, Double_t c2, Option_t *option)
496 TString opt = option;
498 Bool_t binomial = kFALSE;
499 if (opt.Contains(
"b")) binomial = kTRUE;
501 Error(
"Divide",
"Attempt to divide a non-existing profile2D");
504 if (!h1->InheritsFrom(TProfile2D::Class())) {
505 Error(
"Divide",
"Attempt to divide a non-profile2D object");
508 TProfile2D *p1 = (TProfile2D*)h1;
509 if (!h2->InheritsFrom(TProfile2D::Class())) {
510 Error(
"Divide",
"Attempt to divide a non-profile2D object");
513 TProfile2D *p2 = (TProfile2D*)h2;
516 if (fBuffer) BufferEmpty(1);
519 Int_t nx = GetNbinsX();
520 if (nx != p1->GetNbinsX() || nx != p2->GetNbinsX()) {
521 Error(
"Divide",
"Attempt to divide profiles with different number of bins");
524 Int_t ny = GetNbinsY();
525 if (ny != p1->GetNbinsY() || ny != p2->GetNbinsY()) {
526 Error(
"Divide",
"Attempt to divide profiles with different number of bins");
530 Error(
"Divide",
"Coefficient of dividing profile cannot be zero");
535 fEntries = fTsumw = fTsumw2 = fTsumwx = fTsumwx2 = 0;
539 Double_t *cu1 = p1->GetW();
540 Double_t *cu2 = p2->GetW();
541 Double_t *er1 = p1->GetW2();
542 Double_t *er2 = p2->GetW2();
543 Double_t *en1 = p1->GetB();
544 Double_t *en2 = p2->GetB();
545 Double_t b1,b2,w,z,x,y,ac1,ac2;
546 ac1 = TMath::Abs(c1);
547 ac2 = TMath::Abs(c2);
548 for (binx =0;binx<=nx+1;binx++) {
549 for (biny =0;biny<=ny+1;biny++) {
550 bin = biny*(fXaxis.GetNbins()+2) + binx;
553 if (b2) w = c1*b1/(c2*b2);
557 x = fXaxis.GetBinCenter(binx);
558 y = fYaxis.GetBinCenter(biny);
569 Double_t e1 = er1[bin];
570 Double_t e2 = er2[bin];
572 Double_t b22= b2*b2*TMath::Abs(c2);
573 if (!b2) fSumw2.fArray[bin] = 0;
576 fSumw2.fArray[bin] = TMath::Abs(w*(1-w)/(c2*b2));
578 fSumw2.fArray[bin] = ac1*ac2*(e1*b2*b2 + e2*b1*b1)/(b22*b22);
581 if (!en2[bin]) fBinEntries.fArray[bin] = 0;
582 else fBinEntries.fArray[bin] = en1[bin]/en2[bin];
591 Int_t TProfile2D::Fill(Double_t x, Double_t y, Double_t z)
593 if (fBuffer)
return BufferFill(x,y,z,1);
597 if (fZmin != fZmax) {
598 if (z <fZmin || z> fZmax || TMath::IsNaN(z) )
return -1;
602 binx =fXaxis.FindBin(x);
603 biny =fYaxis.FindBin(y);
604 if (binx <0 || biny <0)
return -1;
605 bin = GetBin(binx, biny);
607 fSumw2.fArray[bin] += z*z;
608 fBinEntries.fArray[bin] += 1;
609 if (fBinSumw2.fN) fBinSumw2.fArray[bin] += 1;
610 if (binx == 0 || binx > fXaxis.GetNbins()) {
611 if (!GetStatOverflowsBehaviour())
return -1;
613 if (biny == 0 || biny > fYaxis.GetNbins()) {
614 if (!GetStatOverflowsBehaviour())
return -1;
631 Int_t TProfile2D::Fill(Double_t x,
const char *namey, Double_t z)
635 if (fZmin != fZmax) {
636 if (z <fZmin || z> fZmax || TMath::IsNaN(z))
return -1;
640 binx =fXaxis.FindBin(x);
641 biny =fYaxis.FindBin(namey);
642 if (binx <0 || biny <0)
return -1;
643 bin = biny*(fXaxis.GetNbins()+2) + binx;
644 AddBinContent(bin, z);
645 fSumw2.fArray[bin] += (Double_t)z*z;
646 fBinEntries.fArray[bin] += 1;
647 if (fBinSumw2.fN) fBinSumw2.fArray[bin] += 1;
648 if (binx == 0 || binx > fXaxis.GetNbins()) {
649 if (!GetStatOverflowsBehaviour())
return -1;
651 if (biny == 0 || biny > fYaxis.GetNbins())
return -1;
652 Double_t y = fYaxis.GetBinCenter(biny);
668 Int_t TProfile2D::Fill(
const char *namex,
const char *namey, Double_t z)
672 if (fZmin != fZmax) {
673 if (z <fZmin || z> fZmax || TMath::IsNaN(z) )
return -1;
677 binx =fXaxis.FindBin(namex);
678 biny =fYaxis.FindBin(namey);
679 if (binx <0 || biny <0)
return -1;
680 bin = biny*(fXaxis.GetNbins()+2) + binx;
681 AddBinContent(bin, z);
682 fSumw2.fArray[bin] += (Double_t)z*z;
683 fBinEntries.fArray[bin] += 1;
684 if (fBinSumw2.fN) fBinSumw2.fArray[bin] += 1;
685 if (binx == 0 || binx > fXaxis.GetNbins())
return -1;
686 if (biny == 0 || biny > fYaxis.GetNbins())
return -1;
687 Double_t x = fYaxis.GetBinCenter(binx);
688 Double_t y = fYaxis.GetBinCenter(biny);
704 Int_t TProfile2D::Fill(
const char *namex, Double_t y, Double_t z)
708 if (fZmin != fZmax) {
709 if (z <fZmin || z> fZmax || TMath::IsNaN(z))
return -1;
713 binx =fXaxis.FindBin(namex);
714 biny =fYaxis.FindBin(y);
715 if (binx <0 || biny <0)
return -1;
716 bin = biny*(fXaxis.GetNbins()+2) + binx;
717 AddBinContent(bin, z);
718 fSumw2.fArray[bin] += (Double_t)z*z;
719 fBinEntries.fArray[bin] += 1;
720 if (fBinSumw2.fN) fBinSumw2.fArray[bin] += 1;
721 if (binx == 0 || binx > fXaxis.GetNbins())
return -1;
722 if (biny == 0 || biny > fYaxis.GetNbins()) {
723 if (!GetStatOverflowsBehaviour())
return -1;
725 Double_t x = fYaxis.GetBinCenter(binx);
741 Int_t TProfile2D::Fill(Double_t x, Double_t y, Double_t z, Double_t w)
743 if (fBuffer)
return BufferFill(x,y,z,w);
747 if (fZmin != fZmax) {
748 if (z <fZmin || z> fZmax || TMath::IsNaN(z))
return -1;
753 binx =fXaxis.FindBin(x);
754 biny =fYaxis.FindBin(y);
755 if (binx <0 || biny <0)
return -1;
756 bin = biny*(fXaxis.GetNbins()+2) + binx;
757 AddBinContent(bin, u*z);
758 fSumw2.fArray[bin] += u*z*z;
759 if (!fBinSumw2.fN && u != 1.0 && !TestBit(TH1::kIsNotW)) Sumw2();
760 if (fBinSumw2.fN) fBinSumw2.fArray[bin] += u*u;
761 fBinEntries.fArray[bin] += u;
762 if (binx == 0 || binx > fXaxis.GetNbins()) {
763 if (!GetStatOverflowsBehaviour())
return -1;
765 if (biny == 0 || biny > fYaxis.GetNbins()) {
766 if (!GetStatOverflowsBehaviour())
return -1;
783 Double_t TProfile2D::GetBinContent(Int_t bin)
const
785 if (fBuffer) ((TProfile2D*)
this)->BufferEmpty();
787 if (bin < 0 || bin >= fNcells)
return 0;
788 if (fBinEntries.fArray[bin] == 0)
return 0;
789 if (!fArray)
return 0;
790 return fArray[bin]/fBinEntries.fArray[bin];
796 Double_t TProfile2D::GetBinEntries(Int_t bin)
const
798 if (fBuffer) ((TProfile2D*)
this)->BufferEmpty();
800 if (bin < 0 || bin >= fNcells)
return 0;
801 return fBinEntries.fArray[bin];
812 Double_t TProfile2D::GetBinEffectiveEntries(Int_t bin)
814 return TProfileHelper::GetBinEffectiveEntries(
this, bin);
835 Double_t TProfile2D::GetBinError(Int_t bin)
const
837 return TProfileHelper::GetBinError((TProfile2D*)
this, bin);
843 Option_t *TProfile2D::GetErrorOption()
const
845 if (fErrorMode == kERRORSPREAD)
return "s";
846 if (fErrorMode == kERRORSPREADI)
return "i";
847 if (fErrorMode == kERRORSPREADG)
return "g";
870 void TProfile2D::GetStats(Double_t *stats)
const
872 if (fBuffer) ((TProfile2D*)
this)->BufferEmpty();
875 if (fTsumw == 0 || fXaxis.TestBit(TAxis::kAxisRange) || fYaxis.TestBit(TAxis::kAxisRange)) {
876 Int_t bin, binx, biny;
879 for (bin=0;bin<9;bin++) stats[bin] = 0;
880 if (!fBinEntries.fArray)
return;
881 Int_t firstBinX = fXaxis.GetFirst();
882 Int_t lastBinX = fXaxis.GetLast();
883 Int_t firstBinY = fYaxis.GetFirst();
884 Int_t lastBinY = fYaxis.GetLast();
886 if (GetStatOverflowsBehaviour()) {
887 if ( !fXaxis.TestBit(TAxis::kAxisRange) ) {
888 if (firstBinX == 1) firstBinX = 0;
889 if (lastBinX == fXaxis.GetNbins() ) lastBinX += 1;
891 if ( !fYaxis.TestBit(TAxis::kAxisRange) ) {
892 if (firstBinY == 1) firstBinY = 0;
893 if (lastBinY == fYaxis.GetNbins() ) lastBinY += 1;
896 for (biny = firstBinY; biny <= lastBinY; biny++) {
897 y = fYaxis.GetBinCenter(biny);
898 for (binx = firstBinX; binx <= lastBinX; binx++) {
899 bin = GetBin(binx,biny);
900 w = fBinEntries.fArray[bin];
901 w2 = (fBinSumw2.fN ? fBinSumw2.fArray[bin] : w );
902 x = fXaxis.GetBinCenter(binx);
910 stats[7] += fArray[bin];
911 stats[8] += fSumw2.fArray[bin];
930 void TProfile2D::LabelsDeflate(Option_t *ax)
932 TProfileHelper::LabelsDeflate(
this, ax);
940 void TProfile2D::LabelsInflate(Option_t *ax)
942 TProfileHelper::LabelsInflate(
this, ax);
958 void TProfile2D::LabelsOption(Option_t *option, Option_t *ax)
961 TAxis *axis = GetXaxis();
962 if (ax[0] ==
'y' || ax[0] ==
'Y') axis = GetYaxis();
963 THashList *labels = axis->GetLabels();
965 Warning(
"LabelsOption",
"Cannot sort. No labels");
968 TString opt = option;
970 if (opt.Contains(
"h")) {
971 axis->SetBit(TAxis::kLabelsHori);
972 axis->ResetBit(TAxis::kLabelsVert);
973 axis->ResetBit(TAxis::kLabelsDown);
974 axis->ResetBit(TAxis::kLabelsUp);
976 if (opt.Contains(
"v")) {
977 axis->SetBit(TAxis::kLabelsVert);
978 axis->ResetBit(TAxis::kLabelsHori);
979 axis->ResetBit(TAxis::kLabelsDown);
980 axis->ResetBit(TAxis::kLabelsUp);
982 if (opt.Contains(
"u")) {
983 axis->SetBit(TAxis::kLabelsUp);
984 axis->ResetBit(TAxis::kLabelsVert);
985 axis->ResetBit(TAxis::kLabelsDown);
986 axis->ResetBit(TAxis::kLabelsHori);
988 if (opt.Contains(
"d")) {
989 axis->SetBit(TAxis::kLabelsDown);
990 axis->ResetBit(TAxis::kLabelsVert);
991 axis->ResetBit(TAxis::kLabelsHori);
992 axis->ResetBit(TAxis::kLabelsUp);
995 if (opt.Contains(
"a")) sort = 0;
996 if (opt.Contains(
">")) sort = 1;
997 if (opt.Contains(
"<")) sort = 2;
998 if (sort < 0)
return;
1000 Int_t nx = fXaxis.GetNbins()+2;
1001 Int_t ny = fYaxis.GetNbins()+2;
1002 Int_t n = TMath::Min(axis->GetNbins(), labels->GetSize());
1003 Int_t *a =
new Int_t[n+2];
1005 Double_t *sumw =
new Double_t[nx*ny];
1006 Double_t *errors =
new Double_t[nx*ny];
1007 Double_t *ent =
new Double_t[nx*ny];
1008 THashList *labold =
new THashList(labels->GetSize(),1);
1009 TIter nextold(labels);
1011 while ((obj=nextold())) {
1017 Double_t *pcont =
new Double_t[n+2];
1018 for (i=0;i<=n;i++) pcont[i] = 0;
1019 for (i=1;i<nx;i++) {
1020 for (j=1;j<ny;j++) {
1022 sumw[bin] = fArray[bin];
1023 errors[bin] = fSumw2.fArray[bin];
1024 ent[bin] = fBinEntries.fArray[bin];
1025 if (axis == GetXaxis()) k = i;
1027 if (fBinEntries.fArray[bin] != 0) pcont[k-1] += fArray[bin]/fBinEntries.fArray[bin];
1030 if (sort ==1) TMath::Sort(n,pcont,a,kTRUE);
1031 else TMath::Sort(n,pcont,a,kFALSE);
1034 obj = labold->At(a[i]);
1036 obj->SetUniqueID(i+1);
1038 for (i=1;i<nx;i++) {
1039 for (j=1;j<ny;j++) {
1041 if (axis == GetXaxis()) {
1042 fArray[bin] = sumw[a[i-1]+1+nx*j];
1043 fSumw2.fArray[bin] = errors[a[i-1]+1+nx*j];
1044 fBinEntries.fArray[bin] = ent[a[i-1]+1+nx*j];
1046 fArray[bin] = sumw[i+nx*(a[j-1]+1)];
1047 fSumw2.fArray[bin] = errors[i+nx*(a[j-1]+1)];
1048 fBinEntries.fArray[bin] = ent[i+nx*(a[j-1]+1)];
1054 const UInt_t kUsed = 1<<18;
1058 for (i=1;i<=n;i++) {
1059 const char *label =
"zzzzzzzzzzzz";
1060 for (j=1;j<=n;j++) {
1061 obj = labold->At(j-1);
1063 if (obj->TestBit(kUsed))
continue;
1065 if (strcmp(label,obj->GetName()) < 0)
continue;
1068 label = obj->GetName();
1071 objk->SetUniqueID(i);
1073 objk->SetBit(kUsed);
1076 for (i=1;i<=n;i++) {
1077 obj = labels->At(i-1);
1079 obj->ResetBit(kUsed);
1081 for (i=0;i<nx;i++) {
1082 for (j=0;j<ny;j++) {
1084 sumw[bin] = fArray[bin];
1085 errors[bin] = fSumw2.fArray[bin];
1086 ent[bin] = fBinEntries.fArray[bin];
1089 for (i=0;i<nx;i++) {
1090 for (j=0;j<ny;j++) {
1092 if (axis == GetXaxis()) {
1093 fArray[bin] = sumw[a[i]+nx*j];
1094 fSumw2.fArray[bin] = errors[a[i]+nx*j];
1095 fBinEntries.fArray[bin] = ent[a[i]+nx*j];
1097 fArray[bin] = sumw[i+nx*a[j]];
1098 fSumw2.fArray[bin] = errors[i+nx*a[j]];
1099 fBinEntries.fArray[bin] = ent[i+nx*a[j]];
1106 if (sumw)
delete [] sumw;
1107 if (errors)
delete [] errors;
1108 if (ent)
delete [] ent;
1125 Long64_t TProfile2D::Merge(TCollection *li)
1127 return TProfileHelper::Merge(
this, li);
1133 Bool_t TProfile2D::Multiply(TF1 *, Double_t )
1135 Error(
"Multiply",
"Function not implemented for TProfile2D");
1144 Bool_t TProfile2D::Multiply(
const TH1 *)
1146 Error(
"Multiply",
"Multiplication of profile2D histograms not implemented");
1155 Bool_t TProfile2D::Multiply(
const TH1 *,
const TH1 *, Double_t, Double_t, Option_t *)
1157 Error(
"Multiply",
"Multiplication of profile2D histograms not implemented");
1185 TH2D *TProfile2D::ProjectionXY(
const char *name, Option_t *option)
const
1188 TString opt = option;
1193 TString pname(name);
1194 if (pname.IsNull() || pname ==
"_pxy")
1195 pname = TString(GetName() ) + TString(
"_pxy");
1198 Int_t nx = fXaxis.GetNbins();
1199 Int_t ny = fYaxis.GetNbins();
1200 const TArrayD *xbins = fXaxis.GetXbins();
1201 const TArrayD *ybins = fYaxis.GetXbins();
1203 if (xbins->fN == 0 && ybins->fN == 0) {
1204 h1 =
new TH2D(pname,GetTitle(),nx,fXaxis.GetXmin(),fXaxis.GetXmax(),ny,fYaxis.GetXmin(),fYaxis.GetXmax());
1205 }
else if (xbins->fN == 0) {
1206 h1 =
new TH2D(pname,GetTitle(),nx,fXaxis.GetXmin(),fXaxis.GetXmax(),ny, ybins->GetArray() );
1207 }
else if (ybins->fN == 0) {
1208 h1 =
new TH2D(pname,GetTitle(),nx,xbins->GetArray(),ny,fYaxis.GetXmin(),fYaxis.GetXmax());
1210 h1 =
new TH2D(pname,GetTitle(),nx,xbins->GetArray(),ny,ybins->GetArray() );
1212 Bool_t computeErrors = kFALSE;
1213 Bool_t cequalErrors = kFALSE;
1214 Bool_t binEntries = kFALSE;
1215 Bool_t binWeight = kFALSE;
1216 if (opt.Contains(
"b")) binEntries = kTRUE;
1217 if (opt.Contains(
"e")) computeErrors = kTRUE;
1218 if (opt.Contains(
"w")) binWeight = kTRUE;
1219 if (opt.Contains(
"c=e")) {cequalErrors = kTRUE; computeErrors=kFALSE;}
1220 if (computeErrors || binWeight || (binEntries && fBinSumw2.fN) ) h1->Sumw2();
1223 Int_t bin,binx, biny;
1225 for (binx =0;binx<=nx+1;binx++) {
1226 for (biny =0;biny<=ny+1;biny++) {
1227 bin = GetBin(binx,biny);
1229 if (binEntries) cont = GetBinEntries(bin);
1230 else if (cequalErrors) cont = GetBinError(bin);
1231 else if (binWeight) cont = GetBinContent(bin) * GetBinEntries(bin);
1232 else cont = GetBinContent(bin);
1234 h1->SetBinContent(bin ,cont);
1237 if (computeErrors ) h1->SetBinError(bin , GetBinError(bin) );
1240 if (binWeight) h1->GetSumw2()->fArray[bin] = fSumw2.fArray[bin];
1242 if (binEntries && fBinSumw2.fN ) {
1243 R__ASSERT( h1->GetSumw2() );
1244 h1->GetSumw2()->fArray[bin] = fBinSumw2.fArray[bin];
1248 h1->SetEntries(fEntries);
1266 TProfile *TProfile2D::ProfileX(
const char *name, Int_t firstybin, Int_t lastybin, Option_t *option)
const
1268 return DoProfile(
true, name, firstybin, lastybin, option);
1285 TProfile *TProfile2D::ProfileY(
const char *name, Int_t firstxbin, Int_t lastxbin, Option_t *option)
const
1287 return DoProfile(
false, name, firstxbin, lastxbin, option);
1295 TProfile * TProfile2D::DoProfile(
bool onX,
const char *name, Int_t firstbin, Int_t lastbin, Option_t *option)
const {
1296 TString opt = option;
1298 bool originalRange = opt.Contains(
"o");
1300 TString expectedName = ( onX ?
"_pfx" :
"_pfy" );
1302 TString pname(name);
1303 if (pname.IsNull() || name == expectedName)
1304 pname = TString(GetName() ) + expectedName;
1306 const TAxis& outAxis = ( onX ? fXaxis : fYaxis );
1307 const TArrayD *bins = outAxis.GetXbins();
1308 Int_t firstOutBin = outAxis.GetFirst();
1309 Int_t lastOutBin = outAxis.GetLast();
1313 if (bins->fN == 0) {
1315 p1 =
new TProfile(pname,GetTitle(), outAxis.GetNbins(), outAxis.GetXmin(), outAxis.GetXmax(), opt );
1317 p1 =
new TProfile(pname,GetTitle(), lastOutBin-firstOutBin+1,
1318 outAxis.GetBinLowEdge(firstOutBin),outAxis.GetBinUpEdge(lastOutBin), opt);
1322 p1 =
new TProfile(pname,GetTitle(),outAxis.GetNbins(),bins->fArray,opt);
1324 p1 =
new TProfile(pname,GetTitle(),lastOutBin-firstOutBin+1,&bins->fArray[firstOutBin-1],opt);
1328 if (fBinSumw2.fN) p1->Sumw2();
1331 TH2D * h2dW = ProjectionXY(
"h2temp-W",
"W");
1332 TH2D * h2dN = ProjectionXY(
"h2temp-N",
"B");
1334 h2dW->SetDirectory(0); h2dN->SetDirectory(0);
1337 TString opt1 = (originalRange) ?
"o" :
"";
1338 TH1D * h1W = (onX) ? h2dW->ProjectionX(
"h1temp-W",firstbin,lastbin,opt1) : h2dW->ProjectionY(
"h1temp-W",firstbin,lastbin,opt1);
1339 TH1D * h1N = (onX) ? h2dN->ProjectionX(
"h1temp-N",firstbin,lastbin,opt1) : h2dN->ProjectionY(
"h1temp-N",firstbin,lastbin,opt1);
1340 h1W->SetDirectory(0); h1N->SetDirectory(0);
1344 R__ASSERT( h1W->fN == p1->fN );
1345 R__ASSERT( h1N->fN == p1->fN );
1346 R__ASSERT( h1W->GetSumw2()->fN != 0);
1347 for (
int i = 0; i < p1->fN ; ++i) {
1348 p1->fArray[i] = h1W->GetBinContent(i);
1349 p1->GetSumw2()->fArray[i] = h1W->GetSumw2()->fArray[i];
1350 p1->SetBinEntries(i, h1N->GetBinContent(i) );
1351 if (fBinSumw2.fN) p1->GetBinSumw2()->fArray[i] = h1N->GetSumw2()->fArray[i];
1361 p1->SetEntries( p1->GetEffectiveEntries() );
1370 void TProfile2D::PutStats(Double_t *stats)
1375 fTsumwx2 = stats[3];
1377 fTsumwy2 = stats[5];
1378 fTsumwxy = stats[6];
1380 fTsumwz2 = stats[8];
1386 void TProfile2D::Reset(Option_t *option)
1388 TH2D::Reset(option);
1389 fBinEntries.Reset();
1391 TString opt = option;
1393 if (opt.Contains(
"ICE") && !opt.Contains(
"S"))
return;
1394 fTsumwz = fTsumwz2 = 0;
1410 void TProfile2D::ExtendAxis(Double_t x, TAxis *axis)
1412 TProfile2D* hold = TProfileHelper::ExtendAxis(
this, x, axis);
1414 fTsumwz = hold->fTsumwz;
1415 fTsumwz2 = hold->fTsumwz2;
1448 TProfile2D * TProfile2D::Rebin2D(Int_t nxgroup ,Int_t nygroup,
const char * newname ) {
1450 if((nxgroup != 1) || (nygroup != 1)){
1451 Int_t nxbins = fXaxis.GetNbins();
1452 Int_t nybins = fYaxis.GetNbins();
1453 Double_t xmin = fXaxis.GetXmin();
1454 Double_t xmax = fXaxis.GetXmax();
1455 Double_t ymin = fYaxis.GetXmin();
1456 Double_t ymax = fYaxis.GetXmax();
1457 if ((nxgroup <= 0) || (nxgroup > nxbins)) {
1458 Error(
"Rebin",
"Illegal value of nxgroup=%d",nxgroup);
1461 if ((nygroup <= 0) || (nygroup > nybins)) {
1462 Error(
"Rebin",
"Illegal value of nygroup=%d",nygroup);
1466 Int_t newxbins = nxbins/nxgroup;
1467 Int_t newybins = nybins/nygroup;
1470 if(newxbins*nxgroup != nxbins) {
1471 Warning(
"Rebin",
"nxgroup=%d should be an exact divider of nxbins=%d",nxgroup,nxbins);
1473 if(newybins*nygroup != nybins) {
1474 Warning(
"Rebin",
"nygroup=%d should be an exact divider of nybins=%d",nygroup,nybins);
1478 Double_t *oldBins =
new Double_t[(nxbins+2)*(nybins+2)];
1479 Double_t *oldCount =
new Double_t[(nxbins+2)*(nybins+2)];
1480 Double_t *oldErrors =
new Double_t[(nxbins+2)*(nybins+2)];
1481 Double_t *oldBinw2 = (fBinSumw2.fN ?
new Double_t[(nxbins+2)*(nybins+2)] : 0 );
1482 Double_t *cu1 = GetW();
1483 Double_t *er1 = GetW2();
1484 Double_t *en1 = GetB();
1485 Double_t *ew1 = GetB2();
1486 for(Int_t ibin=0; ibin < (nxbins+2)*(nybins+2); ibin++){
1487 oldBins[ibin] = cu1[ibin];
1488 oldCount[ibin] = en1[ibin];
1489 oldErrors[ibin] = er1[ibin];
1490 if (ew1 && fBinSumw2.fN) oldBinw2[ibin] = ew1[ibin];
1494 TProfile2D *hnew =
this;
1495 if(newname && strlen(newname) > 0) {
1496 hnew = (TProfile2D*)Clone(newname);
1501 if(newxbins*nxgroup != nxbins) {
1502 xmax = fXaxis.GetBinUpEdge(newxbins*nxgroup);
1505 if(newybins*nygroup != nybins) {
1506 ymax = fYaxis.GetBinUpEdge(newybins*nygroup);
1511 if((fXaxis.GetXbins()->GetSize() > 0) || (fYaxis.GetXbins()->GetSize() > 0)){
1512 Double_t* xbins =
new Double_t[newxbins+1];
1513 Double_t* ybins =
new Double_t[newybins+1];
1514 for(Int_t i=0; i < newxbins+1; i++)
1515 xbins[i] = fXaxis.GetBinLowEdge(1+i*nxgroup);
1516 for(Int_t j=0; j < newybins+1; j++)
1517 ybins[j] = fYaxis.GetBinLowEdge(1+j*nygroup);
1518 hnew->SetBins(newxbins,xbins,newybins,ybins);
1524 hnew->SetBins(newxbins,xmin,xmax,newybins,ymin,ymax);
1528 Double_t *cu2 = hnew->GetW();
1529 Double_t *er2 = hnew->GetW2();
1530 Double_t *en2 = hnew->GetB();
1531 Double_t *ew2 = hnew->GetB2();
1532 Double_t binContent, binCount, binError, binSumw2;
1539 for(Int_t xbin = 1; xbin <= newxbins; xbin++){
1541 for(Int_t ybin = 1; ybin <= newybins; ybin++){
1546 for(Int_t i=0; i < nxgroup; i++){
1547 if(oldxbin + i > nxbins)
break;
1548 for(Int_t j=0; j < nygroup; j++){
1549 if(oldybin + j > nybins)
break;
1550 bin = oldxbin + i + (nxbins+2)*(oldybin+j);
1551 binContent += oldBins[bin];
1552 binCount += oldCount[bin];
1553 binError += oldErrors[bin];
1554 if(fBinSumw2.fN) binSumw2 += oldBinw2[bin];
1557 bin = xbin + (newxbins + 2)*ybin;
1558 cu2[bin] = binContent;
1559 er2[bin] = binError;
1560 en2[bin] = binCount;
1561 if(fBinSumw2.fN) ew2[bin] = binSumw2;
1568 cu2[0] = oldBins[0];
1569 er2[0] = oldErrors[0];
1570 en2[0] = oldCount[0];
1571 if(fBinSumw2.fN) ew2[0] = oldBinw2[0];
1578 for(Int_t i=oldxbin; i <= nxbins+1; i++){
1579 for(Int_t j=oldybin; j <= nybins+1; j++){
1581 bin = i + (nxbins+2)*j;
1582 binContent += oldBins[bin];
1583 binCount += oldCount[bin];
1584 binError += oldErrors[bin];
1585 if(fBinSumw2.fN) binSumw2 += oldBinw2[bin];
1588 bin = (newxbins+2)*(newybins+2)-1;
1589 cu2[bin] = binContent;
1590 er2[bin] = binError;
1591 en2[bin] = binCount;
1592 if(fBinSumw2.fN) ew2[bin] = binSumw2;
1598 for(Int_t i=oldxbin; i <= nxbins+1; i++){
1600 binContent += oldBins[bin];
1601 binCount += oldCount[bin];
1602 binError += oldErrors[bin];
1603 if(fBinSumw2.fN) binSumw2 += oldBinw2[bin];
1606 cu2[bin] = binContent;
1607 er2[bin] = binError;
1608 en2[bin] = binCount;
1609 if(fBinSumw2.fN) ew2[bin] = binSumw2;
1615 for(Int_t i=oldybin; i <= nybins+1; i++){
1616 bin = i*(nxbins + 2);
1617 binContent += oldBins[bin];
1618 binCount += oldCount[bin];
1619 binError += oldErrors[bin];
1620 if(fBinSumw2.fN) binSumw2 += oldBinw2[bin];
1622 bin = (newxbins + 2)*(newybins + 1);
1623 cu2[bin] = binContent;
1624 er2[bin] = binError;
1625 en2[bin] = binCount;
1626 if(fBinSumw2.fN) ew2[bin] = binSumw2;
1628 Double_t binContentuf, binCountuf, binErroruf, binSumw2uf;
1629 Double_t binContentof, binCountof, binErrorof, binSumw2of;
1632 for(Int_t xbin = 1; xbin <= newxbins; xbin++){
1641 for(Int_t i = 0; i < nxgroup; i++){
1643 ufbin = (oldxbin2 + i);
1644 binContentuf += oldBins[ufbin];
1645 binCountuf += oldCount[ufbin];
1646 binErroruf += oldErrors[ufbin];
1647 if(fBinSumw2.fN) binSumw2uf += oldBinw2[ufbin];
1648 for(Int_t j = oldybin; j <= nybins+1; j++)
1650 ofbin = ufbin + j*(nxbins + 2);
1651 binContentof += oldBins[ofbin];
1652 binCountof += oldCount[ofbin];
1653 binErrorof += oldErrors[ofbin];
1654 if(fBinSumw2.fN) binSumw2of += oldBinw2[ofbin];
1659 ofbin = ufbin + (newybins + 1)*(newxbins + 2);
1660 cu2[ufbin] = binContentuf;
1661 er2[ufbin] = binErroruf;
1662 en2[ufbin] = binCountuf;
1663 if(fBinSumw2.fN) ew2[ufbin] = binSumw2uf;
1664 cu2[ofbin] = binContentof;
1665 er2[ofbin] = binErrorof;
1666 en2[ofbin] = binCountof;
1667 if(fBinSumw2.fN) ew2[ofbin] = binSumw2of;
1669 oldxbin2 += nxgroup;
1673 for(Int_t ybin = 1; ybin <= newybins; ybin++){
1682 for(Int_t i = 0; i < nygroup; i++){
1684 ufbin = (oldybin2 + i)*(nxbins+2);
1685 binContentuf += oldBins[ufbin];
1686 binCountuf += oldCount[ufbin];
1687 binErroruf += oldErrors[ufbin];
1688 if(fBinSumw2.fN) binSumw2uf += oldBinw2[ufbin];
1689 for(Int_t j = oldxbin; j <= nxbins+1; j++)
1692 binContentof += oldBins[ofbin];
1693 binCountof += oldCount[ofbin];
1694 binErrorof += oldErrors[ofbin];
1695 if(fBinSumw2.fN) binSumw2of += oldBinw2[ofbin];
1699 ufbin = ybin * (newxbins + 2);
1700 ofbin = newxbins + 1 + ufbin;
1701 cu2[ufbin] = binContentuf;
1702 er2[ufbin] = binErroruf;
1703 en2[ufbin] = binCountuf;
1704 if(fBinSumw2.fN) ew2[ufbin] = binSumw2uf;
1705 cu2[ofbin] = binContentof;
1706 er2[ofbin] = binErrorof;
1707 en2[ofbin] = binCountof;
1708 if(fBinSumw2.fN) ew2[ofbin] = binSumw2of;
1710 oldybin2 += nygroup;
1715 delete [] oldErrors;
1716 if (oldBinw2)
delete [] oldBinw2;
1722 if((newname) && (strlen(newname) > 0))
1723 return (TProfile2D*)Clone(newname);
1733 TProfile2D * TProfile2D::RebinX(Int_t ngroup,
const char * newname ) {
1734 return Rebin2D(ngroup,1,newname);
1741 TProfile2D * TProfile2D::RebinY(Int_t ngroup,
const char * newname ) {
1742 return Rebin2D(1,ngroup,newname);
1752 void TProfile2D::SavePrimitive(std::ostream &out, Option_t *option )
1755 out <<
" "<<std::endl;
1756 out <<
" "<<ClassName()<<
" *";
1758 out << GetName() <<
" = new " << ClassName() <<
"(" << quote
1759 << GetName() << quote <<
"," << quote<< GetTitle() << quote
1760 <<
"," << GetXaxis()->GetNbins();
1761 out <<
"," << GetXaxis()->GetXmin()
1762 <<
"," << GetXaxis()->GetXmax();
1763 out <<
"," << GetYaxis()->GetNbins();
1764 out <<
"," << GetYaxis()->GetXmin()
1765 <<
"," << GetYaxis()->GetXmax();
1768 out <<
");" << std::endl;
1773 for (bin=0;bin<fNcells;bin++) {
1774 Double_t bi = GetBinEntries(bin);
1776 out<<
" "<<GetName()<<
"->SetBinEntries("<<bin<<
","<<bi<<
");"<<std::endl;
1780 for (bin=0;bin<fNcells;bin++) {
1781 Double_t bc = fArray[bin];
1783 out<<
" "<<GetName()<<
"->SetBinContent("<<bin<<
","<<bc<<
");"<<std::endl;
1788 for (bin=0;bin<fNcells;bin++) {
1789 Double_t be = TMath::Sqrt(fSumw2.fArray[bin]);
1791 out<<
" "<<GetName()<<
"->SetBinError("<<bin<<
","<<be<<
");"<<std::endl;
1796 TH1::SavePrimitiveHelp(out, GetName(), option);
1806 void TProfile2D::Scale(Double_t c1, Option_t * option)
1808 TProfileHelper::Scale(
this, c1, option);
1814 void TProfile2D::SetBinEntries(Int_t bin, Double_t w)
1816 TProfileHelper::SetBinEntries(
this, bin, w);
1822 void TProfile2D::SetBins(Int_t nx, Double_t xmin, Double_t xmax, Int_t ny, Double_t ymin, Double_t ymax)
1824 TH1::SetBins(nx,xmin, xmax,ny, ymin,ymax);
1825 fBinEntries.Set(fNcells);
1826 if (fBinSumw2.fN) fBinSumw2.Set(fNcells);
1832 void TProfile2D::SetBins(Int_t nx,
const Double_t *xbins, Int_t ny,
const Double_t *ybins)
1834 TH1::SetBins(nx,xbins,ny,ybins);
1835 fBinEntries.Set(fNcells);
1836 if (fBinSumw2.fN) fBinSumw2.Set(fNcells);
1843 void TProfile2D::SetBinsLength(Int_t n)
1845 TH2D::SetBinsLength(n);
1846 TProfileHelper::BuildArray(
this);
1852 void TProfile2D::SetBuffer(Int_t buffersize, Option_t *)
1859 if (buffersize <= 0) {
1863 if (buffersize < 100) buffersize = 100;
1864 fBufferSize = 1 + 4*buffersize;
1865 fBuffer =
new Double_t[fBufferSize];
1866 memset(fBuffer,0,
sizeof(Double_t)*fBufferSize);
1890 void TProfile2D::SetErrorOption(Option_t *option)
1892 TProfileHelper::SetErrorOption(
this, option);
1898 void TProfile2D::Streamer(TBuffer &R__b)
1900 if (R__b.IsReading()) {
1902 Version_t R__v = R__b.ReadVersion(&R__s, &R__c);
1904 R__b.ReadClassBuffer(TProfile2D::Class(),
this, R__v, R__s, R__c);
1908 TH2D::Streamer(R__b);
1909 fBinEntries.Streamer(R__b);
1912 fErrorMode = (EErrorType)errorMode;
1915 R__b >> zmin; fZmin = zmin;
1916 R__b >> zmax; fZmax = zmax;
1921 R__b.CheckByteCount(R__s, R__c, TProfile2D::IsA());
1925 R__b.WriteClassBuffer(TProfile2D::Class(),
this);
1939 void TProfile2D::Sumw2(Bool_t flag)
1941 TProfileHelper::Sumw2(
this, flag);