24 Bool_t TProfile::fgApproximate = kFALSE;
82 TProfile::TProfile() : TH1D()
116 TProfile::TProfile(
const char *name,
const char *title,Int_t nbins,Double_t xlow,Double_t xup,Option_t *option)
117 : TH1D(name,title,nbins,xlow,xup)
119 BuildOptions(0,0,option);
128 TProfile::TProfile(
const char *name,
const char *title,Int_t nbins,
const Float_t *xbins,Option_t *option)
129 : TH1D(name,title,nbins,xbins)
131 BuildOptions(0,0,option);
140 TProfile::TProfile(
const char *name,
const char *title,Int_t nbins,
const Double_t *xbins,Option_t *option)
141 : TH1D(name,title,nbins,xbins)
143 BuildOptions(0,0,option);
152 TProfile::TProfile(
const char *name,
const char *title,Int_t nbins,
const Double_t *xbins,Double_t ylow,Double_t yup,Option_t *option)
153 : TH1D(name,title,nbins,xbins)
155 BuildOptions(ylow,yup,option);
170 TProfile::TProfile(
const char *name,
const char *title,Int_t nbins,Double_t xlow,Double_t xup,Double_t ylow,Double_t yup,Option_t *option)
171 : TH1D(name,title,nbins,xlow,xup)
173 BuildOptions(ylow,yup,option);
217 void TProfile::BuildOptions(Double_t ymin, Double_t ymax, Option_t *option)
219 SetErrorOption(option);
222 TProfileHelper::BuildArray(
this);
227 fTsumwy = fTsumwy2 = 0;
234 TProfile::TProfile(
const TProfile &profile) : TH1D()
236 ((TProfile&)profile).Copy(*
this);
239 TProfile &TProfile::operator=(
const TProfile &profile)
241 ((TProfile &)profile).Copy(*
this);
248 Bool_t TProfile::Add(TF1 *, Double_t, Option_t * )
250 Error(
"Add",
"Function not implemented for TProfile");
258 Bool_t TProfile::Add(
const TH1 *h1, Double_t c1)
261 Error(
"Add",
"Attempt to add a non-existing profile");
264 if (!h1->InheritsFrom(TProfile::Class())) {
265 Error(
"Add",
"Attempt to add a non-profile object");
269 return TProfileHelper::Add(
this,
this, h1, 1, c1);
280 Bool_t TProfile::Add(
const TH1 *h1,
const TH1 *h2, Double_t c1, Double_t c2)
283 Error(
"Add",
"Attempt to add a non-existing profile");
286 if (!h1->InheritsFrom(TProfile::Class())) {
287 Error(
"Add",
"Attempt to add a non-profile object");
290 if (!h2->InheritsFrom(TProfile::Class())) {
291 Error(
"Add",
"Attempt to add a non-profile object");
294 return TProfileHelper::Add(
this, h1, h2, c1, c2);
310 void TProfile::Approximate(Bool_t approx)
312 fgApproximate = approx;
324 Int_t TProfile::BufferEmpty(Int_t action)
327 if (!fBuffer)
return 0;
328 Int_t nbentries = (Int_t)fBuffer[0];
329 if (!nbentries)
return 0;
330 Double_t *buffer = fBuffer;
332 if (action == 0)
return 0;
333 nbentries = -nbentries;
338 if (CanExtendAllAxes() || fXaxis.GetXmax() <= fXaxis.GetXmin()) {
340 Double_t xmin = fBuffer[2];
341 Double_t xmax = xmin;
342 for (Int_t i=1;i<nbentries;i++) {
343 Double_t x = fBuffer[3*i+2];
344 if (x < xmin) xmin = x;
345 if (x > xmax) xmax = x;
347 if (fXaxis.GetXmax() <= fXaxis.GetXmin()) {
348 THLimitsFinder::GetLimitsFinder()->FindGoodLimits(
this,xmin,xmax);
351 Int_t keep = fBufferSize; fBufferSize = 0;
352 if (xmin < fXaxis.GetXmin()) ExtendAxis(xmin,&fXaxis);
353 if (xmax >= fXaxis.GetXmax()) ExtendAxis(xmax,&fXaxis);
361 for (Int_t i=0;i<nbentries;i++) {
362 Fill(buffer[3*i+2],buffer[3*i+3],buffer[3*i+1]);
366 if (action > 0) {
delete [] fBuffer; fBuffer = 0; fBufferSize = 0;}
368 if (nbentries == (Int_t)fEntries) fBuffer[0] = -nbentries;
382 Int_t TProfile::BufferFill(Double_t x, Double_t y, Double_t w)
384 if (!fBuffer)
return -2;
385 Int_t nbentries = (Int_t)fBuffer[0];
387 nbentries = -nbentries;
388 fBuffer[0] = nbentries;
390 Double_t *buffer = fBuffer; fBuffer=0;
395 if (3*nbentries+3 >= fBufferSize) {
399 fBuffer[3*nbentries+1] = w;
400 fBuffer[3*nbentries+2] = x;
401 fBuffer[3*nbentries+3] = y;
409 void TProfile::Copy(TObject &obj)
const
412 TProfile & pobj =
dynamic_cast<TProfile&
>(obj);
414 fBinEntries.Copy(pobj.fBinEntries);
415 fBinSumw2.Copy(pobj.fBinSumw2);
416 for (
int bin=0;bin<fNcells;bin++) {
417 pobj.fArray[bin] = fArray[bin];
418 pobj.fSumw2.fArray[bin] = fSumw2.fArray[bin];
423 pobj.fScaling = fScaling;
424 pobj.fErrorMode = fErrorMode;
425 pobj.fTsumwy = fTsumwy;
426 pobj.fTsumwy2 = fTsumwy2;
429 Fatal(
"Copy",
"Cannot copy a TProfile in a %s",obj.IsA()->GetName());
439 Bool_t TProfile::Divide(TF1 *, Double_t )
441 Error(
"Divide",
"Function not implemented for TProfile");
454 Bool_t TProfile::Divide(
const TH1 *h1)
457 Error(
"Divide",
"Attempt to divide a non-existing profile");
460 if (!h1->InheritsFrom(TH1::Class())) {
461 Error(
"Divide",
"Attempt to divide by a non-profile or non-histogram object");
464 TProfile *p1 = (TProfile*)h1;
467 if (fBuffer) BufferEmpty(1);
470 Int_t nbinsx = GetNbinsX();
472 if (nbinsx != p1->GetNbinsX()) {
473 Error(
"Divide",
"Attempt to divide profiles with different number of bins");
478 fEntries = fTsumw = fTsumw2 = fTsumwx = fTsumwx2 = fTsumwy = fTsumwy2 = 0;
482 Double_t *cu1=0, *er1=0, *en1=0;
484 if (h1->InheritsFrom(TProfile::Class())) {
489 Double_t c0,c1,w,z,x;
490 for (bin=0;bin<=nbinsx+1;bin++) {
492 if (cu1) c1 = cu1[bin];
493 else c1 = h1->GetBinContent(bin);
498 x = fXaxis.GetBinCenter(bin);
506 e0 = fSumw2.fArray[bin];
507 if (er1) e1 = er1[bin];
508 else {e1 = h1->GetBinError(bin); e1*=e1;}
510 if (!c1) fSumw2.fArray[bin] = 0;
511 else fSumw2.fArray[bin] = (e0*c1*c1 + e1*c0*c0)/(c12*c12);
513 if (!en1[bin]) fBinEntries.fArray[bin] = 0;
514 else fBinEntries.fArray[bin] /= en1[bin];
519 Warning(
"Divide",
"Cannot preserve during the division of profiles the sum of bin weight square");
520 fBinSumw2 = TArrayD();
533 Bool_t TProfile::Divide(
const TH1 *h1,
const TH1 *h2, Double_t c1, Double_t c2, Option_t *option)
535 TString opt = option;
537 Bool_t binomial = kFALSE;
538 if (opt.Contains(
"b")) binomial = kTRUE;
540 Error(
"Divide",
"Attempt to divide a non-existing profile");
543 if (!h1->InheritsFrom(TProfile::Class())) {
544 Error(
"Divide",
"Attempt to divide a non-profile object");
547 TProfile *p1 = (TProfile*)h1;
548 if (!h2->InheritsFrom(TProfile::Class())) {
549 Error(
"Divide",
"Attempt to divide by a non-profile object");
552 TProfile *p2 = (TProfile*)h2;
555 if (fBuffer) BufferEmpty(1);
557 Int_t nbinsx = GetNbinsX();
559 if (nbinsx != p1->GetNbinsX() || nbinsx != p2->GetNbinsX()) {
560 Error(
"Divide",
"Attempt to divide profiles with different number of bins");
564 Error(
"Divide",
"Coefficient of dividing profile cannot be zero");
569 printf(
"WARNING!!: The algorithm in TProfile::Divide computing the errors is not accurate\n");
570 printf(
" Instead of Divide(TProfile *h1, TProfile *h2, do:\n");
571 printf(
" TH1D *p1 = h1->ProjectionX();\n");
572 printf(
" TH1D *p2 = h2->ProjectionX();\n");
573 printf(
" p1->Divide(p2);\n");
576 fEntries = fTsumw = fTsumw2 = fTsumwx = fTsumwx2 = 0;
580 Double_t *cu1 = p1->GetW();
581 Double_t *cu2 = p2->GetW();
582 Double_t *er1 = p1->GetW2();
583 Double_t *er2 = p2->GetW2();
584 Double_t *en1 = p1->GetB();
585 Double_t *en2 = p2->GetB();
586 Double_t b1,b2,w,z,x,ac1,ac2;
589 ac1 = TMath::Abs(c1);
590 ac2 = TMath::Abs(c2);
591 for (bin=0;bin<=nbinsx+1;bin++) {
594 if (b2) w = c1*b1/(c2*b2);
598 x = fXaxis.GetBinCenter(bin);
606 Double_t e1 = er1[bin];
607 Double_t e2 = er2[bin];
609 Double_t b22= b2*b2*TMath::Abs(c2);
610 if (!b2) fSumw2.fArray[bin] = 0;
613 fSumw2.fArray[bin] = TMath::Abs(w*(1-w)/b2);
616 fSumw2.fArray[bin] = ac1*ac2*(e1*b2*b2 + e2*b1*b1)/(b22*b22);
619 if (en2[bin]) fBinEntries.fArray[bin] = en1[bin]/en2[bin];
620 else fBinEntries.fArray[bin] = 0;
626 Warning(
"Divide",
"Cannot preserve during the division of profiles the sum of bin weight square");
627 fBinSumw2 = TArrayD();
636 Int_t TProfile::Fill(Double_t x, Double_t y)
638 if (fBuffer)
return BufferFill(x,y,1);
641 if (fYmin != fYmax) {
642 if (y <fYmin || y> fYmax || TMath::IsNaN(y) )
return -1;
646 bin =fXaxis.FindBin(x);
647 AddBinContent(bin, y);
648 fSumw2.fArray[bin] += (Double_t)y*y;
649 fBinEntries.fArray[bin] += 1;
650 if (fBinSumw2.fN) fBinSumw2.fArray[bin] += 1;
651 if (bin == 0 || bin > fXaxis.GetNbins()) {
652 if (!GetStatOverflowsBehaviour())
return -1;
666 Int_t TProfile::Fill(
const char *namex, Double_t y)
669 if (fYmin != fYmax) {
670 if (y <fYmin || y> fYmax || TMath::IsNaN(y) )
return -1;
674 bin =fXaxis.FindBin(namex);
675 AddBinContent(bin, y);
676 fSumw2.fArray[bin] += (Double_t)y*y;
677 fBinEntries.fArray[bin] += 1;
678 if (fBinSumw2.fN) fBinSumw2.fArray[bin] += 1;
679 if (bin == 0 || bin > fXaxis.GetNbins()) {
680 if (!GetStatOverflowsBehaviour())
return -1;
682 Double_t x = fXaxis.GetBinCenter(bin);
695 Int_t TProfile::Fill(Double_t x, Double_t y, Double_t w)
697 if (fBuffer)
return BufferFill(x,y,w);
700 if (fYmin != fYmax) {
701 if (y <fYmin || y> fYmax || TMath::IsNaN(y) )
return -1;
706 bin =fXaxis.FindBin(x);
707 AddBinContent(bin, u*y);
708 fSumw2.fArray[bin] += u*y*y;
709 if (!fBinSumw2.fN && u != 1.0 && !TestBit(TH1::kIsNotW)) Sumw2();
710 if (fBinSumw2.fN) fBinSumw2.fArray[bin] += u*u;
711 fBinEntries.fArray[bin] += u;
712 if (bin == 0 || bin > fXaxis.GetNbins()) {
713 if (!GetStatOverflowsBehaviour())
return -1;
727 Int_t TProfile::Fill(
const char *namex, Double_t y, Double_t w)
731 if (fYmin != fYmax) {
732 if (y <fYmin || y> fYmax || TMath::IsNaN(y) )
return -1;
737 bin =fXaxis.FindBin(namex);
738 AddBinContent(bin, u*y);
739 fSumw2.fArray[bin] += u*y*y;
740 if (!fBinSumw2.fN && u != 1.0 && !TestBit(TH1::kIsNotW)) Sumw2();
741 if (fBinSumw2.fN) fBinSumw2.fArray[bin] += u*u;
742 fBinEntries.fArray[bin] += u;
743 if (bin == 0 || bin > fXaxis.GetNbins()) {
744 if (!GetStatOverflowsBehaviour())
return -1;
746 Double_t x = fXaxis.GetBinCenter(bin);
759 void TProfile::FillN(Int_t ntimes,
const Double_t *x,
const Double_t *y,
const Double_t *w, Int_t stride)
767 for (i=0;i<ntimes;i+=stride) {
769 if (w) BufferFill(x[i],y[i],w[i]);
770 else BufferFill(x[i], y[i], 1.);
773 if (i < ntimes && fBuffer==0)
779 for (i=ifirst;i<ntimes;i+=stride) {
780 if (fYmin != fYmax) {
781 if (y[i] <fYmin || y[i]> fYmax || TMath::IsNaN(y[i]))
continue;
784 Double_t u = (w) ? w[i] : 1;
786 bin =fXaxis.FindBin(x[i]);
787 AddBinContent(bin, u*y[i]);
788 fSumw2.fArray[bin] += u*y[i]*y[i];
789 if (!fBinSumw2.fN && u != 1.0 && !TestBit(TH1::kIsNotW)) Sumw2();
790 if (fBinSumw2.fN) fBinSumw2.fArray[bin] += u*u;
791 fBinEntries.fArray[bin] += u;
792 if (bin == 0 || bin > fXaxis.GetNbins()) {
793 if (!GetStatOverflowsBehaviour())
continue;
798 fTsumwx2 += u*x[i]*x[i];
800 fTsumwy2 += u*y[i]*y[i];
807 Double_t TProfile::GetBinContent(Int_t bin)
const
809 if (fBuffer) ((TProfile*)
this)->BufferEmpty();
811 if (bin < 0 || bin >= fNcells)
return 0;
812 if (fBinEntries.fArray[bin] == 0)
return 0;
813 if (!fArray)
return 0;
814 return fArray[bin]/fBinEntries.fArray[bin];
820 Double_t TProfile::GetBinEntries(Int_t bin)
const
822 if (fBuffer) ((TProfile*)
this)->BufferEmpty();
824 if (bin < 0 || bin >= fNcells)
return 0;
825 return fBinEntries.fArray[bin];
836 Double_t TProfile::GetBinEffectiveEntries(Int_t bin)
const
838 return TProfileHelper::GetBinEffectiveEntries((TProfile*)
this, bin);
871 Double_t TProfile::GetBinError(Int_t bin)
const
873 return TProfileHelper::GetBinError((TProfile*)
this, bin);
879 Option_t *TProfile::GetErrorOption()
const
881 if (fErrorMode == kERRORSPREAD)
return "s";
882 if (fErrorMode == kERRORSPREADI)
return "i";
883 if (fErrorMode == kERRORSPREADG)
return "g";
904 void TProfile::GetStats(Double_t *stats)
const
906 if (fBuffer) ((TProfile*)
this)->BufferEmpty();
910 if (fTsumw == 0 || fXaxis.TestBit(TAxis::kAxisRange)) {
911 for (bin=0;bin<6;bin++) stats[bin] = 0;
912 if (!fBinEntries.fArray)
return;
913 Int_t firstBinX = fXaxis.GetFirst();
914 Int_t lastBinX = fXaxis.GetLast();
916 if (GetStatOverflowsBehaviour() && !fXaxis.TestBit(TAxis::kAxisRange)) {
917 if (firstBinX == 1) firstBinX = 0;
918 if (lastBinX == fXaxis.GetNbins() ) lastBinX += 1;
920 for (binx = firstBinX; binx <= lastBinX; binx++) {
921 Double_t w = fBinEntries.fArray[binx];
922 Double_t w2 = (fBinSumw2.fN ? fBinSumw2.fArray[binx] : w);
923 Double_t x = fXaxis.GetBinCenter(binx);
928 stats[4] += fArray[binx];
929 stats[5] += fSumw2.fArray[binx];
932 if (fTsumwy == 0 && fTsumwy2 == 0) {
934 TProfile *p = (TProfile*)
this;
935 for (binx=fXaxis.GetFirst();binx<=fXaxis.GetLast();binx++) {
936 p->fTsumwy += fArray[binx];
937 p->fTsumwy2 += fSumw2.fArray[binx];
952 void TProfile::LabelsDeflate(Option_t *option)
954 TProfileHelper::LabelsDeflate(
this, option);
962 void TProfile::LabelsInflate(Option_t *options)
964 TProfileHelper::LabelsInflate(
this, options);
980 void TProfile::LabelsOption(Option_t *option, Option_t * )
982 THashList *labels = fXaxis.GetLabels();
984 Warning(
"LabelsOption",
"Cannot sort. No labels");
987 TString opt = option;
989 if (opt.Contains(
"h")) {
990 fXaxis.SetBit(TAxis::kLabelsHori);
991 fXaxis.ResetBit(TAxis::kLabelsVert);
992 fXaxis.ResetBit(TAxis::kLabelsDown);
993 fXaxis.ResetBit(TAxis::kLabelsUp);
995 if (opt.Contains(
"v")) {
996 fXaxis.SetBit(TAxis::kLabelsVert);
997 fXaxis.ResetBit(TAxis::kLabelsHori);
998 fXaxis.ResetBit(TAxis::kLabelsDown);
999 fXaxis.ResetBit(TAxis::kLabelsUp);
1001 if (opt.Contains(
"u")) {
1002 fXaxis.SetBit(TAxis::kLabelsUp);
1003 fXaxis.ResetBit(TAxis::kLabelsVert);
1004 fXaxis.ResetBit(TAxis::kLabelsDown);
1005 fXaxis.ResetBit(TAxis::kLabelsHori);
1007 if (opt.Contains(
"d")) {
1008 fXaxis.SetBit(TAxis::kLabelsDown);
1009 fXaxis.ResetBit(TAxis::kLabelsVert);
1010 fXaxis.ResetBit(TAxis::kLabelsHori);
1011 fXaxis.ResetBit(TAxis::kLabelsUp);
1014 if (opt.Contains(
"a")) sort = 0;
1015 if (opt.Contains(
">")) sort = 1;
1016 if (opt.Contains(
"<")) sort = 2;
1017 if (sort < 0)
return;
1019 Int_t n = TMath::Min(fXaxis.GetNbins(), labels->GetSize());
1020 Int_t *a =
new Int_t[n+2];
1022 Double_t *cont =
new Double_t[n+2];
1023 Double_t *sumw =
new Double_t[n+2];
1024 Double_t *errors =
new Double_t[n+2];
1025 Double_t *ent =
new Double_t[n+2];
1026 THashList *labold =
new THashList(labels->GetSize(),1);
1027 TIter nextold(labels);
1029 while ((obj=nextold())) {
1035 for (i=1;i<=n;i++) {
1036 sumw[i-1] = fArray[i];
1037 errors[i-1] = fSumw2.fArray[i];
1038 ent[i-1] = fBinEntries.fArray[i];
1039 if (fBinEntries.fArray[i] == 0) cont[i-1] = 0;
1040 else cont[i-1] = fArray[i]/fBinEntries.fArray[i];
1042 if (sort ==1) TMath::Sort(n,cont,a,kTRUE);
1043 else TMath::Sort(n,cont,a,kFALSE);
1044 for (i=1;i<=n;i++) {
1045 fArray[i] = sumw[a[i-1]];
1046 fSumw2.fArray[i] = errors[a[i-1]];
1047 fBinEntries.fArray[i] = ent[a[i-1]];
1049 for (i=1;i<=n;i++) {
1050 obj = labold->At(a[i-1]);
1052 obj->SetUniqueID(i);
1056 const UInt_t kUsed = 1<<18;
1060 for (i=1;i<=n;i++) {
1061 const char *label =
"zzzzzzzzzzzz";
1062 for (j=1;j<=n;j++) {
1063 obj = labold->At(j-1);
1065 if (obj->TestBit(kUsed))
continue;
1067 if (strcmp(label,obj->GetName()) < 0)
continue;
1070 label = obj->GetName();
1073 objk->SetUniqueID(i);
1075 objk->SetBit(kUsed);
1078 for (i=1;i<=n;i++) {
1079 obj = labels->At(i-1);
1081 obj->ResetBit(kUsed);
1084 for (i=1;i<=n;i++) {
1085 sumw[i] = fArray[a[i]];
1086 errors[i] = fSumw2.fArray[a[i]];
1087 ent[i] = fBinEntries.fArray[a[i]];
1089 for (i=1;i<=n;i++) {
1090 fArray[i] = sumw[i];
1091 fSumw2.fArray[i] = errors[i];
1092 fBinEntries.fArray[i] = ent[i];
1097 if (sumw)
delete [] sumw;
1098 if (cont)
delete [] cont;
1099 if (errors)
delete [] errors;
1100 if (ent)
delete [] ent;
1118 Long64_t TProfile::Merge(TCollection *li)
1120 return TProfileHelper::Merge(
this, li);
1128 Bool_t TProfile::Multiply(TF1 *f1, Double_t c1)
1132 Error(
"Multiply",
"Attempt to multiply by a null function");
1136 Int_t nbinsx = GetNbinsX();
1139 Double_t xx[1], cf1, ac1 = TMath::Abs(c1);
1142 for (i=0;i<10;i++) {s1[i] = 0;}
1150 for (bin=0;bin<=nbinsx+1;bin++) {
1151 xx[0] = fXaxis.GetBinCenter(bin);
1152 if (!f1->IsInside(xx))
continue;
1153 TF1::RejectPoint(kFALSE);
1154 cf1 = f1->EvalPar(xx);
1155 if (TF1::RejectedPoint())
continue;
1156 fArray[bin] *= c1*cf1;
1159 fSumw2.fArray[bin] *= ac1*cf1*cf1;
1170 Bool_t TProfile::Multiply(
const TH1 *)
1172 Error(
"Multiply",
"Multiplication of profile histograms not implemented");
1182 Bool_t TProfile::Multiply(
const TH1 *,
const TH1 *, Double_t, Double_t, Option_t *)
1184 Error(
"Multiply",
"Multiplication of profile histograms not implemented");
1209 TH1D *TProfile::ProjectionX(
const char *name, Option_t *option)
const
1212 TString opt = option;
1214 Int_t nx = fXaxis.GetNbins();
1217 TString pname = name;
1218 if (pname ==
"_px") {
1220 pname.Append(
"_px");
1223 const TArrayD *bins = fXaxis.GetXbins();
1224 if (bins->fN == 0) {
1225 h1 =
new TH1D(pname,GetTitle(),nx,fXaxis.GetXmin(),fXaxis.GetXmax());
1227 h1 =
new TH1D(pname,GetTitle(),nx,bins->fArray);
1229 Bool_t computeErrors = kFALSE;
1230 Bool_t cequalErrors = kFALSE;
1231 Bool_t binEntries = kFALSE;
1232 Bool_t binWeight = kFALSE;
1233 if (opt.Contains(
"b")) binEntries = kTRUE;
1234 if (opt.Contains(
"e")) computeErrors = kTRUE;
1235 if (opt.Contains(
"w")) binWeight = kTRUE;
1236 if (opt.Contains(
"c=e")) {cequalErrors = kTRUE; computeErrors=kFALSE;}
1237 if (computeErrors || binWeight || (binEntries && fBinSumw2.fN) ) h1->Sumw2();
1241 for (Int_t bin =0;bin<=nx+1;bin++) {
1243 if (binEntries) cont = GetBinEntries(bin);
1244 else if (cequalErrors) cont = GetBinError(bin);
1245 else if (binWeight) cont = fArray[bin];
1246 else cont = GetBinContent(bin);
1248 h1->SetBinContent(bin ,cont);
1251 if (computeErrors ) h1->SetBinError(bin , GetBinError(bin) );
1254 if (binWeight) h1->GetSumw2()->fArray[bin] = fSumw2.fArray[bin];
1256 if (binEntries && fBinSumw2.fN ) {
1257 R__ASSERT( h1->GetSumw2() );
1258 h1->GetSumw2()->fArray[bin] = fBinSumw2.fArray[bin];
1264 h1->GetXaxis()->ImportAttributes(this->GetXaxis());
1265 h1->GetYaxis()->ImportAttributes(this->GetYaxis());
1266 THashList* labels=this->GetXaxis()->GetLabels();
1271 while ((lb=(TObjString*)iL())) {
1272 h1->GetXaxis()->SetBinLabel(i,lb->String().Data());
1277 h1->SetEntries(fEntries);
1284 void TProfile::PutStats(Double_t *stats)
1289 fTsumwx2 = stats[3];
1291 fTsumwy2 = stats[5];
1336 TH1 *TProfile::Rebin(Int_t ngroup,
const char*newname,
const Double_t *xbins)
1338 Int_t nbins = fXaxis.GetNbins();
1339 Double_t xmin = fXaxis.GetXmin();
1340 Double_t xmax = fXaxis.GetXmax();
1341 if ((ngroup <= 0) || (ngroup > nbins)) {
1342 Error(
"Rebin",
"Illegal value of ngroup=%d",ngroup);
1345 if (!newname && xbins) {
1346 Error(
"Rebin",
"if xbins is specified, newname must be given");
1350 Int_t newbins = nbins/ngroup;
1352 Int_t nbg = nbins/ngroup;
1353 if (nbg*ngroup != nbins) {
1354 Warning(
"Rebin",
"ngroup=%d must be an exact divider of nbins=%d",ngroup,nbins);
1367 Double_t *oldBins =
new Double_t[nbins+2];
1368 Double_t *oldCount =
new Double_t[nbins+2];
1369 Double_t *oldErrors =
new Double_t[nbins+2];
1370 Double_t *oldBinw2 = (fBinSumw2.fN ?
new Double_t[nbins+2] : 0 );
1372 Double_t *cu1 = GetW();
1373 Double_t *er1 = GetW2();
1374 Double_t *en1 = GetB();
1375 Double_t *ew1 = GetB2();
1377 for (bin=0;bin<=nbins+1;bin++) {
1378 oldBins[bin] = cu1[bin];
1379 oldCount[bin] = en1[bin];
1380 oldErrors[bin] = er1[bin];
1381 if (ew1 && fBinSumw2.fN) oldBinw2[bin] = ew1[bin];
1385 TProfile *hnew =
this;
1386 if ((newname && strlen(newname) > 0) || xbins) {
1387 hnew = (TProfile*)Clone(newname);
1392 if(!xbins && (newbins*ngroup != nbins)) {
1393 xmax = fXaxis.GetBinUpEdge(newbins*ngroup);
1398 if(!xbins && (fXaxis.GetXbins()->GetSize() > 0)){
1400 Double_t *bins =
new Double_t[newbins+1];
1401 for(i = 0; i <= newbins; ++i) bins[i] = fXaxis.GetBinLowEdge(1+i*ngroup);
1402 hnew->SetBins(newbins,bins);
1406 hnew->SetBins(newbins,xbins);
1408 hnew->SetBins(newbins,xmin,xmax);
1412 if (fBinSumw2.fN) hnew->Sumw2();
1416 const Double_t newxmin = hnew->GetXaxis()->GetBinLowEdge(1);
1417 while( fXaxis.GetBinCenter(startbin) < newxmin && startbin <= nbins ) {
1421 Double_t *cu2 = hnew->GetW();
1422 Double_t *er2 = hnew->GetW2();
1423 Double_t *en2 = hnew->GetB();
1424 Double_t *ew2 = hnew->GetB2();
1425 Int_t oldbin = startbin;
1426 Double_t binContent, binCount, binError, binSumw2;
1427 for (bin = 1;bin<=newbins;bin++) {
1434 Int_t imax = ngroup;
1435 Double_t xbinmax = hnew->GetXaxis()->GetBinUpEdge(bin);
1436 for (i=0;i<ngroup;i++) {
1437 if((hnew ==
this && (oldbin+i > nbins)) ||
1438 (hnew !=
this && (fXaxis.GetBinCenter(oldbin+i) > xbinmax)))
1444 binContent += oldBins[oldbin+i];
1445 binCount += oldCount[oldbin+i];
1446 binError += oldErrors[oldbin+i];
1447 if (fBinSumw2.fN) binSumw2 += oldBinw2[oldbin+i];
1450 cu2[bin] = binContent;
1451 er2[bin] = binError;
1452 en2[bin] = binCount;
1453 if (fBinSumw2.fN) ew2[bin] = binSumw2;
1461 for(i=0;i<startbin;i++)
1463 binContent += oldBins[i];
1464 binCount += oldCount[i];
1465 binError += oldErrors[i];
1466 if (fBinSumw2.fN) binSumw2 += oldBinw2[i];
1468 hnew->fArray[0] = binContent;
1469 hnew->fBinEntries[0] = binCount;
1470 hnew->fSumw2[0] = binError;
1471 if ( fBinSumw2.fN ) hnew->fBinSumw2[0] = binSumw2;
1478 for(i=oldbin;i<=nbins+1;i++)
1480 binContent += oldBins[i];
1481 binCount += oldCount[i];
1482 binError += oldErrors[i];
1483 if (fBinSumw2.fN) binSumw2 += oldBinw2[i];
1485 hnew->fArray[newbins+1] = binContent;
1486 hnew->fBinEntries[newbins+1] = binCount;
1487 hnew->fSumw2[newbins+1] = binError;
1488 if ( fBinSumw2.fN ) hnew->fBinSumw2[newbins+1] = binSumw2;
1493 delete [] oldErrors;
1494 if (oldBinw2)
delete [] oldBinw2;
1509 void TProfile::ExtendAxis(Double_t x, TAxis *axis)
1511 TProfile* hold = TProfileHelper::ExtendAxis(
this, x, axis);
1513 fTsumwy = hold->fTsumwy;
1514 fTsumwy2 = hold->fTsumwy2;
1523 void TProfile::Reset(Option_t *option)
1525 TH1D::Reset(option);
1526 fBinEntries.Reset();
1528 TString opt = option;
1530 if (opt.Contains(
"ICE") && !opt.Contains(
"S"))
return;
1538 void TProfile::SavePrimitive(std::ostream &out, Option_t *option )
1544 Bool_t nonEqiX = kFALSE;
1548 if (GetXaxis()->GetXbins()->fN && GetXaxis()->GetXbins()->fArray) {
1550 out <<
" Double_t xAxis[" << GetXaxis()->GetXbins()->fN
1552 for (i = 0; i < GetXaxis()->GetXbins()->fN; i++) {
1553 if (i != 0) out <<
", ";
1554 out << GetXaxis()->GetXbins()->fArray[i];
1556 out <<
"}; " << std::endl;
1560 out<<
" "<<std::endl;
1561 out<<
" "<<ClassName()<<
" *";
1565 static Int_t hcounter = 0;
1566 TString histName = GetName();
1570 histName += hcounter;
1572 const char *hname = histName.Data();
1574 out<<hname<<
" = new "<<ClassName()<<
"("<<quote<<GetName()<<quote<<
","<<quote<<GetTitle()<<quote
1575 <<
","<<GetXaxis()->GetNbins();
1579 out <<
"," << GetXaxis()->GetXmin()
1580 <<
"," << GetXaxis()->GetXmax()
1581 <<
","<<quote<<GetErrorOption()<<quote<<
");"<<std::endl;
1585 for (bin=0;bin<fNcells;bin++) {
1586 Double_t bi = GetBinEntries(bin);
1588 out<<
" "<<hname<<
"->SetBinEntries("<<bin<<
","<<bi<<
");"<<std::endl;
1592 for (bin=0;bin<fNcells;bin++) {
1593 Double_t bc = fArray[bin];
1595 out<<
" "<<hname<<
"->SetBinContent("<<bin<<
","<<bc<<
");"<<std::endl;
1600 for (bin=0;bin<fNcells;bin++) {
1601 Double_t be = TMath::Sqrt(fSumw2.fArray[bin]);
1603 out<<
" "<<hname<<
"->SetBinError("<<bin<<
","<<be<<
");"<<std::endl;
1608 TH1::SavePrimitiveHelp(out, hname, option);
1618 void TProfile::Scale(Double_t c1, Option_t * option)
1620 TProfileHelper::Scale(
this, c1, option);
1626 void TProfile::SetBinEntries(Int_t bin, Double_t w)
1628 TProfileHelper::SetBinEntries(
this, bin, w);
1634 void TProfile::SetBins(Int_t nx, Double_t xmin, Double_t xmax)
1636 fXaxis.Set(nx,xmin,xmax);
1638 SetBinsLength(fNcells);
1644 void TProfile::SetBins(Int_t nx,
const Double_t *xbins)
1646 fXaxis.Set(nx,xbins);
1648 SetBinsLength(fNcells);
1655 void TProfile::SetBinsLength(Int_t n)
1657 TH1D::SetBinsLength(n);
1658 TProfileHelper::BuildArray(
this);
1664 void TProfile::SetBuffer(Int_t buffersize, Option_t *)
1671 if (buffersize <= 0) {
1675 if (buffersize < 100) buffersize = 100;
1676 fBufferSize = 1 + 3*buffersize;
1677 fBuffer =
new Double_t[fBufferSize];
1678 memset(fBuffer,0,
sizeof(Double_t)*fBufferSize);
1703 void TProfile::SetErrorOption(Option_t *option)
1705 TProfileHelper::SetErrorOption(
this, option);
1711 void TProfile::Streamer(TBuffer &R__b)
1713 if (R__b.IsReading()) {
1715 Version_t R__v = R__b.ReadVersion(&R__s, &R__c);
1717 R__b.ReadClassBuffer(TProfile::Class(),
this, R__v, R__s, R__c);
1721 TH1D::Streamer(R__b);
1722 fBinEntries.Streamer(R__b);
1725 fErrorMode = (EErrorType)errorMode;
1728 R__b >> ymin; fYmin = ymin;
1729 R__b >> ymax; fYmax = ymax;
1734 R__b.CheckByteCount(R__s, R__c, TProfile::IsA());
1738 R__b.WriteClassBuffer(TProfile::Class(),
this);
1751 void TProfile::Sumw2(Bool_t flag)
1753 TProfileHelper::Sumw2(
this, flag);