00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012 #include "TProfile2D.h"
00013 #include "TMath.h"
00014 #include "THLimitsFinder.h"
00015 #include "Riostream.h"
00016 #include "TVirtualPad.h"
00017 #include "TError.h"
00018 #include "TClass.h"
00019
00020 #include "TProfileHelper.h"
00021
00022 Bool_t TProfile2D::fgApproximate = kFALSE;
00023
00024 ClassImp(TProfile2D)
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067 TProfile2D::TProfile2D() : TH2D()
00068 {
00069
00070
00071 fTsumwz = fTsumwz2 = 0;
00072 fScaling = kFALSE;
00073 BuildOptions(0,0,"");
00074 }
00075
00076
00077 TProfile2D::~TProfile2D()
00078 {
00079
00080
00081
00082 }
00083
00084
00085 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)
00086 : TH2D(name,title,nx,xlow,xup,ny,ylow,yup)
00087 {
00088
00089
00090
00091
00092
00093
00094
00095
00096
00097
00098
00099
00100
00101
00102
00103
00104
00105
00106
00107
00108
00109
00110
00111 BuildOptions(0,0,option);
00112 if (xlow >= xup || ylow >= yup) SetBuffer(fgBufferSize);
00113 }
00114
00115
00116 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)
00117 : TH2D(name,title,nx,xbins,ny,ylow,yup)
00118 {
00119
00120
00121 BuildOptions(0,0,option);
00122 }
00123
00124
00125 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)
00126 : TH2D(name,title,nx,xlow,xup,ny,ybins)
00127 {
00128
00129
00130 BuildOptions(0,0,option);
00131 }
00132
00133
00134 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)
00135 : TH2D(name,title,nx,xbins,ny,ybins)
00136 {
00137
00138
00139 BuildOptions(0,0,option);
00140 }
00141
00142
00143
00144 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)
00145 : TH2D(name,title,nx,xlow,xup,ny,ylow,yup)
00146 {
00147
00148
00149
00150
00151
00152
00153
00154
00155
00156
00157 BuildOptions(zlow,zup,option);
00158 if (xlow >= xup || ylow >= yup) SetBuffer(fgBufferSize);
00159 }
00160
00161
00162
00163 void TProfile2D::BuildOptions(Double_t zmin, Double_t zmax, Option_t *option)
00164 {
00165
00166
00167
00168
00169
00170
00171
00172
00173
00174
00175
00176
00177
00178
00179
00180
00181
00182
00183
00184
00185
00186
00187
00188
00189
00190
00191
00192
00193
00194
00195
00196
00197
00198
00199
00200
00201
00202
00203
00204
00205
00206
00207
00208
00209 SetErrorOption(option);
00210
00211 fBinEntries.Set(fNcells);
00212
00213 TH1::Sumw2();
00214 if (fgDefaultSumw2) Sumw2();
00215
00216 fZmin = zmin;
00217 fZmax = zmax;
00218 fScaling = kFALSE;
00219 fTsumwz = fTsumwz2 = 0;
00220 }
00221
00222
00223 TProfile2D::TProfile2D(const TProfile2D &profile) : TH2D()
00224 {
00225
00226
00227 ((TProfile2D&)profile).Copy(*this);
00228 }
00229
00230
00231
00232 void TProfile2D::Add(TF1 *, Double_t , Option_t*)
00233 {
00234
00235
00236 Error("Add","Function not implemented for TProfile2D");
00237 return;
00238 }
00239
00240
00241
00242 void TProfile2D::Add(const TH1 *h1, Double_t c1)
00243 {
00244
00245
00246 if (!h1) {
00247 Error("Add","Attempt to add a non-existing profile");
00248 return;
00249 }
00250 if (!h1->InheritsFrom(TProfile2D::Class())) {
00251 Error("Add","Attempt to add a non-profile2D object");
00252 return;
00253 }
00254
00255 TProfileHelper::Add(this, this, h1, 1, c1);
00256 }
00257
00258
00259 void TProfile2D::Add(const TH1 *h1, const TH1 *h2, Double_t c1, Double_t c2)
00260 {
00261
00262
00263
00264
00265
00266
00267 if (!h1 || !h2) {
00268 Error("Add","Attempt to add a non-existing profile");
00269 return;
00270 }
00271 if (!h1->InheritsFrom(TProfile2D::Class())) {
00272 Error("Add","Attempt to add a non-profile2D object");
00273 return;
00274 }
00275 if (!h2->InheritsFrom(TProfile2D::Class())) {
00276 Error("Add","Attempt to add a non-profile2D object");
00277 return;
00278 }
00279 TProfileHelper::Add(this, h1, h2, c1, c2);
00280 }
00281
00282
00283
00284 void TProfile2D::Approximate(Bool_t approx)
00285 {
00286
00287
00288
00289
00290
00291
00292
00293
00294
00295 fgApproximate = approx;
00296 }
00297
00298
00299
00300 Int_t TProfile2D::BufferEmpty(Int_t action)
00301 {
00302
00303
00304
00305
00306
00307
00308
00309
00310 if (!fBuffer) return 0;
00311 Int_t nbentries = (Int_t)fBuffer[0];
00312 if (!nbentries) return 0;
00313 Double_t *buffer = fBuffer;
00314 if (nbentries < 0) {
00315 if (action == 0) return 0;
00316 nbentries = -nbentries;
00317 fBuffer=0;
00318 Reset();
00319 fBuffer = buffer;
00320 }
00321 if (TestBit(kCanRebin) || fXaxis.GetXmax() <= fXaxis.GetXmin() || fYaxis.GetXmax() <= fYaxis.GetXmin()) {
00322
00323 Double_t xmin = fBuffer[2];
00324 Double_t xmax = xmin;
00325 Double_t ymin = fBuffer[3];
00326 Double_t ymax = ymin;
00327 for (Int_t i=1;i<nbentries;i++) {
00328 Double_t x = fBuffer[4*i+2];
00329 if (x < xmin) xmin = x;
00330 if (x > xmax) xmax = x;
00331 Double_t y = fBuffer[4*i+3];
00332 if (y < ymin) ymin = y;
00333 if (y > ymax) ymax = y;
00334 }
00335 if (fXaxis.GetXmax() <= fXaxis.GetXmin() || fYaxis.GetXmax() <= fYaxis.GetXmin()) {
00336 THLimitsFinder::GetLimitsFinder()->FindGoodLimits(this,xmin,xmax,ymin,ymax);
00337 } else {
00338 fBuffer = 0;
00339 Int_t keep = fBufferSize; fBufferSize = 0;
00340 if (xmin < fXaxis.GetXmin()) RebinAxis(xmin,&fXaxis);
00341 if (xmax >= fXaxis.GetXmax()) RebinAxis(xmax,&fXaxis);
00342 if (ymin < fYaxis.GetXmin()) RebinAxis(ymin,&fYaxis);
00343 if (ymax >= fYaxis.GetXmax()) RebinAxis(ymax,&fYaxis);
00344 fBuffer = buffer;
00345 fBufferSize = keep;
00346 }
00347 }
00348
00349 fBuffer = 0;
00350 for (Int_t i=0;i<nbentries;i++) {
00351 Fill(buffer[4*i+2],buffer[4*i+3],buffer[4*i+4],buffer[4*i+1]);
00352 }
00353 fBuffer = buffer;
00354
00355 if (action > 0) { delete [] fBuffer; fBuffer = 0; fBufferSize = 0;}
00356 else {
00357 if (nbentries == (Int_t)fEntries) fBuffer[0] = -nbentries;
00358 else fBuffer[0] = 0;
00359 }
00360 return nbentries;
00361 }
00362
00363
00364 Int_t TProfile2D::BufferFill(Double_t x, Double_t y, Double_t z, Double_t w)
00365 {
00366
00367
00368
00369
00370
00371
00372
00373 if (!fBuffer) return -3;
00374 Int_t nbentries = (Int_t)fBuffer[0];
00375 if (nbentries < 0) {
00376 nbentries = -nbentries;
00377 fBuffer[0] = nbentries;
00378 if (fEntries > 0) {
00379 Double_t *buffer = fBuffer; fBuffer=0;
00380 Reset();
00381 fBuffer = buffer;
00382 }
00383 }
00384 if (4*nbentries+4 >= fBufferSize) {
00385 BufferEmpty(1);
00386 return Fill(x,y,z,w);
00387 }
00388 fBuffer[4*nbentries+1] = w;
00389 fBuffer[4*nbentries+2] = x;
00390 fBuffer[4*nbentries+3] = y;
00391 fBuffer[4*nbentries+4] = z;
00392 fBuffer[0] += 1;
00393 return -2;
00394 }
00395
00396
00397 void TProfile2D::Copy(TObject &obj) const
00398 {
00399
00400
00401
00402 TH2D::Copy(((TProfile2D&)obj));
00403 fBinEntries.Copy(((TProfile2D&)obj).fBinEntries);
00404 fBinSumw2.Copy(((TProfile2D&)obj).fBinSumw2);
00405 for (int bin=0;bin<fNcells;bin++) {
00406 ((TProfile2D&)obj).fArray[bin] = fArray[bin];
00407 ((TProfile2D&)obj).fSumw2.fArray[bin] = fSumw2.fArray[bin];
00408 }
00409 ((TProfile2D&)obj).fZmin = fZmin;
00410 ((TProfile2D&)obj).fZmax = fZmax;
00411 ((TProfile2D&)obj).fScaling = fScaling;
00412 ((TProfile2D&)obj).fErrorMode = fErrorMode;
00413 ((TProfile2D&)obj).fTsumwz = fTsumwz;
00414 ((TProfile2D&)obj).fTsumwz2 = fTsumwz2;
00415 }
00416
00417
00418
00419 void TProfile2D::Divide(TF1 *, Double_t )
00420 {
00421
00422
00423 Error("Divide","Function not implemented for TProfile2D");
00424 return;
00425 }
00426
00427
00428 void TProfile2D::Divide(const TH1 *h1)
00429 {
00430
00431
00432
00433
00434
00435
00436 if (!h1) {
00437 Error("Divide","Attempt to divide a non-existing profile2D");
00438 return;
00439 }
00440 if (!h1->InheritsFrom(TProfile2D::Class())) {
00441 Error("Divide","Attempt to divide a non-profile2D object");
00442 return;
00443 }
00444 TProfile2D *p1 = (TProfile2D*)h1;
00445
00446
00447 Int_t nx = GetNbinsX();
00448 if (nx != p1->GetNbinsX()) {
00449 Error("Divide","Attempt to divide profiles with different number of bins");
00450 return;
00451 }
00452 Int_t ny = GetNbinsY();
00453 if (ny != p1->GetNbinsY()) {
00454 Error("Divide","Attempt to divide profiles with different number of bins");
00455 return;
00456 }
00457
00458
00459 fEntries = fTsumw = fTsumw2 = fTsumwx = fTsumwx2 = 0;
00460
00461
00462 Int_t bin,binx,biny;
00463 Double_t *cu1 = p1->GetW();
00464 Double_t *er1 = p1->GetW2();
00465 Double_t *en1 = p1->GetB();
00466 Double_t c0,c1,w,z,x,y;
00467 for (binx =0;binx<=nx+1;binx++) {
00468 for (biny =0;biny<=ny+1;biny++) {
00469 bin = biny*(fXaxis.GetNbins()+2) + binx;
00470 c0 = fArray[bin];
00471 c1 = cu1[bin];
00472 if (c1) w = c0/c1;
00473 else w = 0;
00474 fArray[bin] = w;
00475 z = TMath::Abs(w);
00476 x = fXaxis.GetBinCenter(binx);
00477 y = fYaxis.GetBinCenter(biny);
00478 fEntries++;
00479 fTsumw += z;
00480 fTsumw2 += z*z;
00481 fTsumwx += z*x;
00482 fTsumwx2 += z*x*x;
00483 fTsumwy += z*y;
00484 fTsumwy2 += z*y*y;
00485 fTsumwxy += z*x*y;
00486 fTsumwz += z;
00487 fTsumwz2 += z*z;
00488 Double_t e0 = fSumw2.fArray[bin];
00489 Double_t e1 = er1[bin];
00490 Double_t c12= c1*c1;
00491 if (!c1) fSumw2.fArray[bin] = 0;
00492 else fSumw2.fArray[bin] = (e0*c1*c1 + e1*c0*c0)/(c12*c12);
00493 if (!en1[bin]) fBinEntries.fArray[bin] = 0;
00494 else fBinEntries.fArray[bin] /= en1[bin];
00495 }
00496 }
00497
00498
00499 if (fBinSumw2.fN) {
00500 Warning("Divide","Cannot preserve during the division of profiles the sum of bin weight square");
00501 fBinSumw2 = TArrayD();
00502 }
00503 }
00504
00505
00506
00507 void TProfile2D::Divide(const TH1 *h1, const TH1 *h2, Double_t c1, Double_t c2, Option_t *option)
00508 {
00509
00510
00511
00512
00513
00514
00515 TString opt = option;
00516 opt.ToLower();
00517 Bool_t binomial = kFALSE;
00518 if (opt.Contains("b")) binomial = kTRUE;
00519 if (!h1 || !h2) {
00520 Error("Divide","Attempt to divide a non-existing profile2D");
00521 return;
00522 }
00523 if (!h1->InheritsFrom(TProfile2D::Class())) {
00524 Error("Divide","Attempt to divide a non-profile2D object");
00525 return;
00526 }
00527 TProfile2D *p1 = (TProfile2D*)h1;
00528 if (!h2->InheritsFrom(TProfile2D::Class())) {
00529 Error("Divide","Attempt to divide a non-profile2D object");
00530 return;
00531 }
00532 TProfile2D *p2 = (TProfile2D*)h2;
00533
00534
00535 Int_t nx = GetNbinsX();
00536 if (nx != p1->GetNbinsX() || nx != p2->GetNbinsX()) {
00537 Error("Divide","Attempt to divide profiles with different number of bins");
00538 return;
00539 }
00540 Int_t ny = GetNbinsY();
00541 if (ny != p1->GetNbinsY() || ny != p2->GetNbinsY()) {
00542 Error("Divide","Attempt to divide profiles with different number of bins");
00543 return;
00544 }
00545 if (!c2) {
00546 Error("Divide","Coefficient of dividing profile cannot be zero");
00547 return;
00548 }
00549
00550
00551 fEntries = fTsumw = fTsumw2 = fTsumwx = fTsumwx2 = 0;
00552
00553
00554 Int_t bin,binx,biny;
00555 Double_t *cu1 = p1->GetW();
00556 Double_t *cu2 = p2->GetW();
00557 Double_t *er1 = p1->GetW2();
00558 Double_t *er2 = p2->GetW2();
00559 Double_t *en1 = p1->GetB();
00560 Double_t *en2 = p2->GetB();
00561 Double_t b1,b2,w,z,x,y,ac1,ac2;
00562 ac1 = TMath::Abs(c1);
00563 ac2 = TMath::Abs(c2);
00564 for (binx =0;binx<=nx+1;binx++) {
00565 for (biny =0;biny<=ny+1;biny++) {
00566 bin = biny*(fXaxis.GetNbins()+2) + binx;
00567 b1 = cu1[bin];
00568 b2 = cu2[bin];
00569 if (b2) w = c1*b1/(c2*b2);
00570 else w = 0;
00571 fArray[bin] = w;
00572 z = TMath::Abs(w);
00573 x = fXaxis.GetBinCenter(binx);
00574 y = fYaxis.GetBinCenter(biny);
00575 fEntries++;
00576 fTsumw += z;
00577 fTsumw2 += z*z;
00578 fTsumwx += z*x;
00579 fTsumwx2 += z*x*x;
00580 fTsumwy += z*y;
00581 fTsumwy2 += z*y*y;
00582 fTsumwxy += z*x*y;
00583 fTsumwz += z;
00584 fTsumwz2 += z*z;
00585 Double_t e1 = er1[bin];
00586 Double_t e2 = er2[bin];
00587
00588 Double_t b22= b2*b2*TMath::Abs(c2);
00589 if (!b2) fSumw2.fArray[bin] = 0;
00590 else {
00591 if (binomial) {
00592 fSumw2.fArray[bin] = TMath::Abs(w*(1-w)/(c2*b2));
00593 } else {
00594 fSumw2.fArray[bin] = ac1*ac2*(e1*b2*b2 + e2*b1*b1)/(b22*b22);
00595 }
00596 }
00597 if (!en2[bin]) fBinEntries.fArray[bin] = 0;
00598 else fBinEntries.fArray[bin] = en1[bin]/en2[bin];
00599 }
00600 }
00601 }
00602
00603
00604 TH1 *TProfile2D::DrawCopy(Option_t *option) const
00605 {
00606
00607
00608 TString opt = option;
00609 opt.ToLower();
00610 if (gPad && !opt.Contains("same")) gPad->Clear();
00611 TProfile2D *newpf = (TProfile2D*)Clone();
00612 newpf->SetDirectory(0);
00613 newpf->SetBit(kCanDelete);
00614 newpf->AppendPad(option);
00615 return newpf;
00616 }
00617
00618
00619 Int_t TProfile2D::Fill(Double_t x, Double_t y, Double_t z)
00620 {
00621
00622
00623
00624 if (fBuffer) return BufferFill(x,y,z,1);
00625
00626 Int_t bin,binx,biny;
00627
00628 if (fZmin != fZmax) {
00629 if (z <fZmin || z> fZmax) return -1;
00630 }
00631
00632 fEntries++;
00633 binx =fXaxis.FindBin(x);
00634 biny =fYaxis.FindBin(y);
00635 if (binx <0 || biny <0) return -1;
00636 bin = GetBin(binx, biny);
00637 fArray[bin] += z;
00638 fSumw2.fArray[bin] += z*z;
00639 fBinEntries.fArray[bin] += 1;
00640 if (fBinSumw2.fN) fBinSumw2.fArray[bin] += 1;
00641 if (binx == 0 || binx > fXaxis.GetNbins()) {
00642 if (!fgStatOverflows) return -1;
00643 }
00644 if (biny == 0 || biny > fYaxis.GetNbins()) {
00645 if (!fgStatOverflows) return -1;
00646 }
00647 ++fTsumw;
00648 ++fTsumw2;
00649 fTsumwx += x;
00650 fTsumwx2 += x*x;
00651 fTsumwy += y;
00652 fTsumwy2 += y*y;
00653 fTsumwxy += x*y;
00654 fTsumwz += z;
00655 fTsumwz2 += z*z;
00656 return bin;
00657 }
00658
00659
00660 Int_t TProfile2D::Fill(Double_t x, const char *namey, Double_t z)
00661 {
00662
00663
00664 Int_t bin,binx,biny;
00665
00666 if (fZmin != fZmax) {
00667 if (z <fZmin || z> fZmax) return -1;
00668 }
00669
00670 fEntries++;
00671 binx =fXaxis.FindBin(x);
00672 biny =fYaxis.FindBin(namey);
00673 if (binx <0 || biny <0) return -1;
00674 bin = biny*(fXaxis.GetNbins()+2) + binx;
00675 AddBinContent(bin, z);
00676 fSumw2.fArray[bin] += (Double_t)z*z;
00677 fBinEntries.fArray[bin] += 1;
00678 if (fBinSumw2.fN) fBinSumw2.fArray[bin] += 1;
00679 if (binx == 0 || binx > fXaxis.GetNbins()) {
00680 if (!fgStatOverflows) return -1;
00681 }
00682 if (biny == 0 || biny > fYaxis.GetNbins()) return -1;
00683 Double_t y = fYaxis.GetBinCenter(biny);
00684 ++fTsumw;
00685 ++fTsumw2;
00686 fTsumwx += x;
00687 fTsumwx2 += x*x;
00688 fTsumwy += y;
00689 fTsumwy2 += y*y;
00690 fTsumwxy += x*y;
00691 fTsumwz += z;
00692 fTsumwz2 += z*z;
00693 return bin;
00694 }
00695
00696
00697 Int_t TProfile2D::Fill(const char *namex, const char *namey, Double_t z)
00698 {
00699
00700
00701 Int_t bin,binx,biny;
00702
00703 if (fZmin != fZmax) {
00704 if (z <fZmin || z> fZmax) return -1;
00705 }
00706
00707 fEntries++;
00708 binx =fXaxis.FindBin(namex);
00709 biny =fYaxis.FindBin(namey);
00710 if (binx <0 || biny <0) return -1;
00711 bin = biny*(fXaxis.GetNbins()+2) + binx;
00712 AddBinContent(bin, z);
00713 fSumw2.fArray[bin] += (Double_t)z*z;
00714 fBinEntries.fArray[bin] += 1;
00715 if (fBinSumw2.fN) fBinSumw2.fArray[bin] += 1;
00716 if (binx == 0 || binx > fXaxis.GetNbins()) return -1;
00717 if (biny == 0 || biny > fYaxis.GetNbins()) return -1;
00718 Double_t x = fYaxis.GetBinCenter(binx);
00719 Double_t y = fYaxis.GetBinCenter(biny);
00720 ++fTsumw;
00721 ++fTsumw2;
00722 fTsumwx += x;
00723 fTsumwx2 += x*x;
00724 fTsumwy += y;
00725 fTsumwy2 += y*y;
00726 fTsumwxy += x*y;
00727 fTsumwz += z;
00728 fTsumwz2 += z*z;
00729 return bin;
00730 }
00731
00732
00733 Int_t TProfile2D::Fill(const char *namex, Double_t y, Double_t z)
00734 {
00735
00736
00737 Int_t bin,binx,biny;
00738
00739 if (fZmin != fZmax) {
00740 if (z <fZmin || z> fZmax) return -1;
00741 }
00742
00743 fEntries++;
00744 binx =fXaxis.FindBin(namex);
00745 biny =fYaxis.FindBin(y);
00746 if (binx <0 || biny <0) return -1;
00747 bin = biny*(fXaxis.GetNbins()+2) + binx;
00748 AddBinContent(bin, z);
00749 fSumw2.fArray[bin] += (Double_t)z*z;
00750 fBinEntries.fArray[bin] += 1;
00751 if (fBinSumw2.fN) fBinSumw2.fArray[bin] += 1;
00752 if (binx == 0 || binx > fXaxis.GetNbins()) return -1;
00753 if (biny == 0 || biny > fYaxis.GetNbins()) {
00754 if (!fgStatOverflows) return -1;
00755 }
00756 Double_t x = fYaxis.GetBinCenter(binx);
00757 ++fTsumw;
00758 ++fTsumw2;
00759 fTsumwx += x;
00760 fTsumwx2 += x*x;
00761 fTsumwy += y;
00762 fTsumwy2 += y*y;
00763 fTsumwxy += x*y;
00764 fTsumwz += z;
00765 fTsumwz2 += z*z;
00766 return bin;
00767 }
00768
00769
00770 Int_t TProfile2D::Fill(Double_t x, Double_t y, Double_t z, Double_t w)
00771 {
00772
00773
00774
00775 if (fBuffer) return BufferFill(x,y,z,w);
00776
00777 Int_t bin,binx,biny;
00778
00779 if (fZmin != fZmax) {
00780 if (z <fZmin || z> fZmax) return -1;
00781 }
00782
00783 Double_t u= (w > 0 ? w : -w);
00784 fEntries++;
00785 binx =fXaxis.FindBin(x);
00786 biny =fYaxis.FindBin(y);
00787 if (binx <0 || biny <0) return -1;
00788 bin = biny*(fXaxis.GetNbins()+2) + binx;
00789 AddBinContent(bin, u*z);
00790 fSumw2.fArray[bin] += u*z*z;
00791 fBinEntries.fArray[bin] += u;
00792 if (fBinSumw2.fN) fBinSumw2.fArray[bin] += u*u;
00793 if (binx == 0 || binx > fXaxis.GetNbins()) {
00794 if (!fgStatOverflows) return -1;
00795 }
00796 if (biny == 0 || biny > fYaxis.GetNbins()) {
00797 if (!fgStatOverflows) return -1;
00798 }
00799 fTsumw += u;
00800 fTsumw2 += u*u;
00801 fTsumwx += u*x;
00802 fTsumwx2 += u*x*x;
00803 fTsumwy += u*y;
00804 fTsumwy2 += u*y*y;
00805 fTsumwxy += u*x*y;
00806 fTsumwz += u*z;
00807 fTsumwz2 += u*z*z;
00808 return bin;
00809 }
00810
00811
00812 Double_t TProfile2D::GetBinContent(Int_t bin) const
00813 {
00814
00815
00816
00817 if (fBuffer) ((TProfile2D*)this)->BufferEmpty();
00818
00819 if (bin < 0 || bin >= fNcells) return 0;
00820 if (fBinEntries.fArray[bin] == 0) return 0;
00821 if (!fArray) return 0;
00822 return fArray[bin]/fBinEntries.fArray[bin];
00823 }
00824
00825
00826 Double_t TProfile2D::GetBinEntries(Int_t bin) const
00827 {
00828
00829
00830
00831 if (fBuffer) ((TProfile2D*)this)->BufferEmpty();
00832
00833 if (bin < 0 || bin >= fNcells) return 0;
00834 return fBinEntries.fArray[bin];
00835 }
00836
00837
00838 Double_t TProfile2D::GetBinEffectiveEntries(Int_t bin)
00839 {
00840
00841
00842
00843
00844
00845
00846
00847
00848
00849 return TProfileHelper::GetBinEffectiveEntries(this, bin);
00850 }
00851
00852
00853 Double_t TProfile2D::GetBinError(Int_t bin) const
00854 {
00855
00856
00857
00858
00859
00860
00861
00862
00863
00864
00865
00866
00867
00868
00869
00870
00871
00872 return TProfileHelper::GetBinError((TProfile2D*)this, bin);
00873 }
00874
00875
00876 Option_t *TProfile2D::GetErrorOption() const
00877 {
00878
00879
00880
00881 if (fErrorMode == kERRORSPREAD) return "s";
00882 if (fErrorMode == kERRORSPREADI) return "i";
00883 if (fErrorMode == kERRORSPREADG) return "g";
00884 return "";
00885 }
00886
00887
00888 void TProfile2D::GetStats(Double_t *stats) const
00889 {
00890
00891
00892
00893
00894
00895
00896
00897
00898
00899
00900
00901
00902
00903
00904
00905
00906
00907 if (fBuffer) ((TProfile2D*)this)->BufferEmpty();
00908
00909
00910 if (fTsumw == 0 || fXaxis.TestBit(TAxis::kAxisRange) || fYaxis.TestBit(TAxis::kAxisRange)) {
00911 Int_t bin, binx, biny;
00912 Double_t w, w2;
00913 Double_t x,y;
00914 for (bin=0;bin<9;bin++) stats[bin] = 0;
00915 if (!fBinEntries.fArray) return;
00916 Int_t firstBinX = fXaxis.GetFirst();
00917 Int_t lastBinX = fXaxis.GetLast();
00918 Int_t firstBinY = fYaxis.GetFirst();
00919 Int_t lastBinY = fYaxis.GetLast();
00920
00921 if (fgStatOverflows) {
00922 if ( !fXaxis.TestBit(TAxis::kAxisRange) ) {
00923 if (firstBinX == 1) firstBinX = 0;
00924 if (lastBinX == fXaxis.GetNbins() ) lastBinX += 1;
00925 }
00926 if ( !fYaxis.TestBit(TAxis::kAxisRange) ) {
00927 if (firstBinY == 1) firstBinY = 0;
00928 if (lastBinY == fYaxis.GetNbins() ) lastBinY += 1;
00929 }
00930 }
00931 for (biny = firstBinY; biny <= lastBinY; biny++) {
00932 y = fYaxis.GetBinCenter(biny);
00933 for (binx = firstBinX; binx <= lastBinX; binx++) {
00934 bin = GetBin(binx,biny);
00935 w = fBinEntries.fArray[bin];
00936 w2 = (fBinSumw2.fN ? fBinSumw2.fArray[bin] : w );
00937 x = fXaxis.GetBinCenter(binx);
00938 stats[0] += w;
00939 stats[1] += w2;
00940 stats[2] += w*x;
00941 stats[3] += w*x*x;
00942 stats[4] += w*y;
00943 stats[5] += w*y*y;
00944 stats[6] += w*x*y;
00945 stats[7] += fArray[bin];
00946 stats[8] += fSumw2.fArray[bin];
00947 }
00948 }
00949 } else {
00950 stats[0] = fTsumw;
00951 stats[1] = fTsumw2;
00952 stats[2] = fTsumwx;
00953 stats[3] = fTsumwx2;
00954 stats[4] = fTsumwy;
00955 stats[5] = fTsumwy2;
00956 stats[6] = fTsumwxy;
00957 stats[7] = fTsumwz;
00958 stats[8] = fTsumwz2;
00959 }
00960 }
00961
00962
00963 void TProfile2D::LabelsDeflate(Option_t *ax)
00964 {
00965
00966
00967 TProfileHelper::LabelsDeflate(this, ax);
00968 }
00969
00970
00971 void TProfile2D::LabelsInflate(Option_t *ax)
00972 {
00973
00974
00975
00976
00977 TProfileHelper::LabelsInflate(this, ax);
00978 }
00979
00980
00981 void TProfile2D::LabelsOption(Option_t *option, Option_t *ax)
00982 {
00983
00984
00985
00986
00987
00988
00989
00990
00991
00992
00993 TAxis *axis = GetXaxis();
00994 if (ax[0] == 'y' || ax[0] == 'Y') axis = GetYaxis();
00995 THashList *labels = axis->GetLabels();
00996 if (!labels) {
00997 Warning("LabelsOption","Cannot sort. No labels");
00998 return;
00999 }
01000 TString opt = option;
01001 opt.ToLower();
01002 if (opt.Contains("h")) {
01003 axis->SetBit(TAxis::kLabelsHori);
01004 axis->ResetBit(TAxis::kLabelsVert);
01005 axis->ResetBit(TAxis::kLabelsDown);
01006 axis->ResetBit(TAxis::kLabelsUp);
01007 }
01008 if (opt.Contains("v")) {
01009 axis->SetBit(TAxis::kLabelsVert);
01010 axis->ResetBit(TAxis::kLabelsHori);
01011 axis->ResetBit(TAxis::kLabelsDown);
01012 axis->ResetBit(TAxis::kLabelsUp);
01013 }
01014 if (opt.Contains("u")) {
01015 axis->SetBit(TAxis::kLabelsUp);
01016 axis->ResetBit(TAxis::kLabelsVert);
01017 axis->ResetBit(TAxis::kLabelsDown);
01018 axis->ResetBit(TAxis::kLabelsHori);
01019 }
01020 if (opt.Contains("d")) {
01021 axis->SetBit(TAxis::kLabelsDown);
01022 axis->ResetBit(TAxis::kLabelsVert);
01023 axis->ResetBit(TAxis::kLabelsHori);
01024 axis->ResetBit(TAxis::kLabelsUp);
01025 }
01026 Int_t sort = -1;
01027 if (opt.Contains("a")) sort = 0;
01028 if (opt.Contains(">")) sort = 1;
01029 if (opt.Contains("<")) sort = 2;
01030 if (sort < 0) return;
01031
01032 Int_t nx = fXaxis.GetNbins()+2;
01033 Int_t ny = fYaxis.GetNbins()+2;
01034 Int_t n = TMath::Min(axis->GetNbins(), labels->GetSize());
01035 Int_t *a = new Int_t[n+2];
01036 Int_t i,j,k,bin;
01037 Double_t *sumw = new Double_t[nx*ny];
01038 Double_t *errors = new Double_t[nx*ny];
01039 Double_t *ent = new Double_t[nx*ny];
01040 THashList *labold = new THashList(labels->GetSize(),1);
01041 TIter nextold(labels);
01042 TObject *obj;
01043 while ((obj=nextold())) {
01044 labold->Add(obj);
01045 }
01046 labels->Clear();
01047 if (sort > 0) {
01048
01049 Double_t *pcont = new Double_t[n+2];
01050 for (i=0;i<=n;i++) pcont[i] = 0;
01051 for (i=1;i<nx;i++) {
01052 for (j=1;j<ny;j++) {
01053 bin = i+nx*j;
01054 sumw[bin] = fArray[bin];
01055 errors[bin] = fSumw2.fArray[bin];
01056 ent[bin] = fBinEntries.fArray[bin];
01057 if (axis == GetXaxis()) k = i;
01058 else k = j;
01059 if (fBinEntries.fArray[bin] != 0) pcont[k-1] += fArray[bin]/fBinEntries.fArray[bin];
01060 }
01061 }
01062 if (sort ==1) TMath::Sort(n,pcont,a,kTRUE);
01063 else TMath::Sort(n,pcont,a,kFALSE);
01064 delete [] pcont;
01065 for (i=0;i<n;i++) {
01066 obj = labold->At(a[i]);
01067 labels->Add(obj);
01068 obj->SetUniqueID(i+1);
01069 }
01070 for (i=1;i<nx;i++) {
01071 for (j=1;j<ny;j++) {
01072 bin = i+nx*j;
01073 if (axis == GetXaxis()) {
01074 fArray[bin] = sumw[a[i-1]+1+nx*j];
01075 fSumw2.fArray[bin] = errors[a[i-1]+1+nx*j];
01076 fBinEntries.fArray[bin] = ent[a[i-1]+1+nx*j];
01077 } else {
01078 fArray[bin] = sumw[i+nx*(a[j-1]+1)];
01079 fSumw2.fArray[bin] = errors[i+nx*(a[j-1]+1)];
01080 fBinEntries.fArray[bin] = ent[i+nx*(a[j-1]+1)];
01081 }
01082 }
01083 }
01084 } else {
01085
01086 const UInt_t kUsed = 1<<18;
01087 TObject *objk=0;
01088 a[0] = 0;
01089 a[n+1] = n+1;
01090 for (i=1;i<=n;i++) {
01091 const char *label = "zzzzzzzzzzzz";
01092 for (j=1;j<=n;j++) {
01093 obj = labold->At(j-1);
01094 if (!obj) continue;
01095 if (obj->TestBit(kUsed)) continue;
01096
01097 if (strcmp(label,obj->GetName()) < 0) continue;
01098 objk = obj;
01099 a[i] = j;
01100 label = obj->GetName();
01101 }
01102 if (objk) {
01103 objk->SetUniqueID(i);
01104 labels->Add(objk);
01105 objk->SetBit(kUsed);
01106 }
01107 }
01108 for (i=1;i<=n;i++) {
01109 obj = labels->At(i-1);
01110 if (!obj) continue;
01111 obj->ResetBit(kUsed);
01112 }
01113 for (i=0;i<nx;i++) {
01114 for (j=0;j<ny;j++) {
01115 bin = i+nx*j;
01116 sumw[bin] = fArray[bin];
01117 errors[bin] = fSumw2.fArray[bin];
01118 ent[bin] = fBinEntries.fArray[bin];
01119 }
01120 }
01121 for (i=0;i<nx;i++) {
01122 for (j=0;j<ny;j++) {
01123 bin = i+nx*j;
01124 if (axis == GetXaxis()) {
01125 fArray[bin] = sumw[a[i]+nx*j];
01126 fSumw2.fArray[bin] = errors[a[i]+nx*j];
01127 fBinEntries.fArray[bin] = ent[a[i]+nx*j];
01128 } else {
01129 fArray[bin] = sumw[i+nx*a[j]];
01130 fSumw2.fArray[bin] = errors[i+nx*a[j]];
01131 fBinEntries.fArray[bin] = ent[i+nx*a[j]];
01132 }
01133 }
01134 }
01135 }
01136 delete labold;
01137 if (a) delete [] a;
01138 if (sumw) delete [] sumw;
01139 if (errors) delete [] errors;
01140 if (ent) delete [] ent;
01141 }
01142
01143
01144 Long64_t TProfile2D::Merge(TCollection *li)
01145 {
01146
01147
01148
01149
01150
01151
01152
01153
01154
01155
01156
01157
01158
01159 return TProfileHelper::Merge(this, li);
01160 }
01161
01162
01163 void TProfile2D::Multiply(TF1 *, Double_t )
01164 {
01165
01166
01167 Error("Multiply","Function not implemented for TProfile2D");
01168 return;
01169 }
01170
01171
01172 void TProfile2D::Multiply(const TH1 *)
01173 {
01174
01175
01176
01177
01178
01179 Error("Multiply","Multiplication of profile2D histograms not implemented");
01180 }
01181
01182
01183
01184 void TProfile2D::Multiply(const TH1 *, const TH1 *, Double_t, Double_t, Option_t *)
01185 {
01186
01187
01188
01189
01190
01191
01192 Error("Multiply","Multiplication of profile2D histograms not implemented");
01193 }
01194
01195
01196 TH2D *TProfile2D::ProjectionXY(const char *name, Option_t *option) const
01197 {
01198
01199
01200
01201
01202
01203
01204
01205
01206
01207
01208
01209
01210
01211
01212
01213
01214
01215
01216
01217
01218
01219
01220
01221 TString opt = option;
01222 opt.ToLower();
01223
01224
01225 Int_t nx = fXaxis.GetNbins();
01226 Int_t ny = fYaxis.GetNbins();
01227
01228
01229 char *pname = (char*)name;
01230 if (strcmp(name,"_px") == 0) {
01231 Int_t nch = strlen(GetName()) + 4;
01232 pname = new char[nch];
01233 snprintf(pname,nch,"%s%s",GetName(),name);
01234 }
01235 TH2D *h1 = new TH2D(pname,GetTitle(),nx,fXaxis.GetXmin(),fXaxis.GetXmax(),ny,fYaxis.GetXmin(),fYaxis.GetXmax());
01236 Bool_t computeErrors = kFALSE;
01237 Bool_t cequalErrors = kFALSE;
01238 Bool_t binEntries = kFALSE;
01239 Bool_t binWeight = kFALSE;
01240 if (opt.Contains("b")) binEntries = kTRUE;
01241 if (opt.Contains("e")) computeErrors = kTRUE;
01242 if (opt.Contains("w")) binWeight = kTRUE;
01243 if (opt.Contains("c=e")) {cequalErrors = kTRUE; computeErrors=kFALSE;}
01244 if (computeErrors || binWeight ) h1->Sumw2();
01245 if (pname != name) delete [] pname;
01246
01247
01248 Int_t bin,binx, biny;
01249 Double_t cont;
01250 for (binx =0;binx<=nx+1;binx++) {
01251 for (biny =0;biny<=ny+1;biny++) {
01252 bin = GetBin(binx,biny);
01253
01254 if (binEntries) cont = GetBinEntries(bin);
01255 else if (cequalErrors) cont = GetBinError(bin);
01256 else if (binWeight) cont = GetBinContent(bin) * GetBinEntries(bin);
01257 else cont = GetBinContent(bin);
01258
01259 h1->SetBinContent(bin ,cont);
01260
01261
01262 if (computeErrors ) h1->SetBinError(bin , GetBinError(bin) );
01263
01264
01265 if (binWeight) h1->SetBinError(bin , TMath::Sqrt(fSumw2.fArray[bin] ) );
01266
01267 if (binEntries && h1->GetSumw2() ) {
01268 Double_t err2;
01269 if (fBinSumw2.fN)
01270 err2 = fBinSumw2.fArray[bin];
01271 else
01272 err2 = cont;
01273 h1->SetBinError(bin, TMath::Sqrt(err2 ) );
01274 }
01275 }
01276 }
01277 h1->SetEntries(fEntries);
01278 return h1;
01279 }
01280
01281
01282 void TProfile2D::PutStats(Double_t *stats)
01283 {
01284
01285
01286 fTsumw = stats[0];
01287 fTsumw2 = stats[1];
01288 fTsumwx = stats[2];
01289 fTsumwx2 = stats[3];
01290 fTsumwy = stats[4];
01291 fTsumwy2 = stats[5];
01292 fTsumwxy = stats[6];
01293 fTsumwz = stats[7];
01294 fTsumwz2 = stats[8];
01295 }
01296
01297
01298 void TProfile2D::Reset(Option_t *option)
01299 {
01300
01301
01302 TH2D::Reset(option);
01303 fBinEntries.Reset();
01304 fBinSumw2.Reset();
01305 TString opt = option;
01306 opt.ToUpper();
01307 if (opt.Contains("ICE")) return;
01308 fTsumwz = fTsumwz2 = 0;
01309 }
01310
01311
01312
01313 void TProfile2D::RebinAxis(Double_t x, TAxis *axis)
01314 {
01315
01316
01317
01318
01319
01320
01321
01322
01323
01324 TProfile2D* hold = TProfileHelper::RebinAxis(this, x, axis);
01325 if ( hold ) {
01326 fTsumwz = hold->fTsumwz;
01327 fTsumwz2 = hold->fTsumwz2;
01328 delete hold;
01329 }
01330 }
01331
01332
01333 TProfile2D * TProfile2D::Rebin2D(Int_t nxgroup ,Int_t nygroup,const char * newname ) {
01334
01335
01336
01337
01338
01339
01340
01341
01342
01343
01344
01345
01346
01347
01348
01349
01350
01351
01352
01353
01354
01355
01356
01357
01358
01359
01360 if((nxgroup != 1) || (nygroup != 1)){
01361 Int_t nxbins = fXaxis.GetNbins();
01362 Int_t nybins = fYaxis.GetNbins();
01363 Double_t xmin = fXaxis.GetXmin();
01364 Double_t xmax = fXaxis.GetXmax();
01365 Double_t ymin = fYaxis.GetXmin();
01366 Double_t ymax = fYaxis.GetXmax();
01367 if ((nxgroup <= 0) || (nxgroup > nxbins)) {
01368 Error("Rebin", "Illegal value of nxgroup=%d",nxgroup);
01369 return 0;
01370 }
01371 if ((nygroup <= 0) || (nygroup > nybins)) {
01372 Error("Rebin", "Illegal value of nygroup=%d",nygroup);
01373 return 0;
01374 }
01375
01376 Int_t newxbins = nxbins/nxgroup;
01377 Int_t newybins = nybins/nygroup;
01378
01379
01380 if(newxbins*nxgroup != nxbins) {
01381 Warning("Rebin", "nxgroup=%d should be an exact divider of nxbins=%d",nxgroup,nxbins);
01382 }
01383 if(newybins*nygroup != nybins) {
01384 Warning("Rebin", "nygroup=%d should be an exact divider of nybins=%d",nygroup,nybins);
01385 }
01386
01387
01388 Double_t *oldBins = new Double_t[(nxbins+2)*(nybins+2)];
01389 Double_t *oldCount = new Double_t[(nxbins+2)*(nybins+2)];
01390 Double_t *oldErrors = new Double_t[(nxbins+2)*(nybins+2)];
01391 Double_t *oldBinw2 = (fBinSumw2.fN ? new Double_t[(nxbins+2)*(nybins+2)] : 0 );
01392 Double_t *cu1 = GetW();
01393 Double_t *er1 = GetW2();
01394 Double_t *en1 = GetB();
01395 Double_t *ew1 = GetB2();
01396 for(Int_t ibin=0; ibin < (nxbins+2)*(nybins+2); ibin++){
01397 oldBins[ibin] = cu1[ibin];
01398 oldCount[ibin] = en1[ibin];
01399 oldErrors[ibin] = er1[ibin];
01400 if (ew1 && fBinSumw2.fN) oldBinw2[ibin] = ew1[ibin];
01401 }
01402
01403
01404 TProfile2D *hnew = this;
01405 if(newname && strlen(newname) > 0) {
01406 hnew = (TProfile2D*)Clone(newname);
01407 }
01408
01409
01410
01411 if(newxbins*nxgroup != nxbins) {
01412 xmax = fXaxis.GetBinUpEdge(newxbins*nxgroup);
01413 hnew->fTsumw = 0;
01414 }
01415 if(newybins*nygroup != nybins) {
01416 ymax = fYaxis.GetBinUpEdge(newybins*nygroup);
01417 hnew->fTsumw = 0;
01418 }
01419
01420
01421 if((fXaxis.GetXbins()->GetSize() > 0) || (fYaxis.GetXbins()->GetSize() > 0)){
01422 Double_t* xbins = new Double_t[newxbins+1];
01423 Double_t* ybins = new Double_t[newybins+1];
01424 for(Int_t i=0; i < newxbins+1; i++)
01425 xbins[i] = fXaxis.GetBinLowEdge(1+i*nxgroup);
01426 for(Int_t j=0; j < newybins+1; j++)
01427 ybins[j] = fYaxis.GetBinLowEdge(1+j*nygroup);
01428 hnew->SetBins(newxbins,xbins,newybins,ybins);
01429 delete [] xbins;
01430 delete [] ybins;
01431 }
01432
01433 else{
01434 hnew->SetBins(newxbins,xmin,xmax,newybins,ymin,ymax);
01435 }
01436
01437
01438 Double_t *cu2 = hnew->GetW();
01439 Double_t *er2 = hnew->GetW2();
01440 Double_t *en2 = hnew->GetB();
01441 Double_t *ew2 = hnew->GetB2();
01442 Double_t binContent, binCount, binError, binSumw2;
01443
01444
01445 Int_t oldxbin = 1;
01446 Int_t oldybin = 1;
01447
01448 Int_t bin;
01449 for(Int_t xbin = 1; xbin <= newxbins; xbin++){
01450 oldybin = 1;
01451 for(Int_t ybin = 1; ybin <= newybins; ybin++){
01452 binContent = 0;
01453 binCount = 0;
01454 binError = 0;
01455 binSumw2 = 0;
01456 for(Int_t i=0; i < nxgroup; i++){
01457 if(oldxbin + i > nxbins) break;
01458 for(Int_t j=0; j < nygroup; j++){
01459 if(oldybin + j > nybins) break;
01460 bin = oldxbin + i + (nxbins+2)*(oldybin+j);
01461 binContent += oldBins[bin];
01462 binCount += oldCount[bin];
01463 binError += oldErrors[bin];
01464 if(fBinSumw2.fN) binSumw2 += oldBinw2[bin];
01465 }
01466 }
01467 bin = xbin + (newxbins + 2)*ybin;
01468 cu2[bin] = binContent;
01469 er2[bin] = binError;
01470 en2[bin] = binCount;
01471 if(fBinSumw2.fN) ew2[bin] = binSumw2;
01472 oldybin += nygroup;
01473 }
01474 oldxbin += nxgroup;
01475 }
01476
01477
01478 cu2[0] = oldBins[0];
01479 er2[0] = oldErrors[0];
01480 en2[0] = oldCount[0];
01481 if(fBinSumw2.fN) ew2[0] = oldBinw2[0];
01482
01483
01484 binContent = 0;
01485 binCount = 0;
01486 binError = 0;
01487 binSumw2 = 0;
01488 for(Int_t i=oldxbin; i <= nxbins+1; i++){
01489 for(Int_t j=oldybin; j <= nybins+1; j++){
01490
01491 bin = i + (nxbins+2)*j;
01492 binContent += oldBins[bin];
01493 binCount += oldCount[bin];
01494 binError += oldErrors[bin];
01495 if(fBinSumw2.fN) binSumw2 += oldBinw2[bin];
01496 }
01497 }
01498 bin = (newxbins+2)*(newybins+2)-1;
01499 cu2[bin] = binContent;
01500 er2[bin] = binError;
01501 en2[bin] = binCount;
01502 if(fBinSumw2.fN) ew2[bin] = binSumw2;
01503
01504 binContent = 0;
01505 binCount = 0;
01506 binError = 0;
01507 binSumw2 = 0;
01508 for(Int_t i=oldxbin; i <= nxbins+1; i++){
01509 bin = i;
01510 binContent += oldBins[bin];
01511 binCount += oldCount[bin];
01512 binError += oldErrors[bin];
01513 if(fBinSumw2.fN) binSumw2 += oldBinw2[bin];
01514 }
01515 bin = newxbins + 1;
01516 cu2[bin] = binContent;
01517 er2[bin] = binError;
01518 en2[bin] = binCount;
01519 if(fBinSumw2.fN) ew2[bin] = binSumw2;
01520
01521 binContent = 0;
01522 binCount = 0;
01523 binError = 0;
01524 binSumw2 = 0;
01525 for(Int_t i=oldybin; i <= nybins+1; i++){
01526 bin = i*(nxbins + 2);
01527 binContent += oldBins[bin];
01528 binCount += oldCount[bin];
01529 binError += oldErrors[bin];
01530 if(fBinSumw2.fN) binSumw2 += oldBinw2[bin];
01531 }
01532 bin = (newxbins + 2)*(newybins + 1);
01533 cu2[bin] = binContent;
01534 er2[bin] = binError;
01535 en2[bin] = binCount;
01536 if(fBinSumw2.fN) ew2[bin] = binSumw2;
01537
01538 Double_t binContentuf, binCountuf, binErroruf, binSumw2uf;
01539 Double_t binContentof, binCountof, binErrorof, binSumw2of;
01540 Int_t ufbin, ofbin;
01541 Int_t oldxbin2 = 1;
01542 for(Int_t xbin = 1; xbin <= newxbins; xbin++){
01543 binContentuf = 0;
01544 binCountuf = 0;
01545 binErroruf = 0;
01546 binSumw2uf = 0;
01547 binContentof = 0;
01548 binCountof = 0;
01549 binErrorof = 0;
01550 binSumw2of = 0;
01551 for(Int_t i = 0; i < nxgroup; i++){
01552
01553 ufbin = (oldxbin2 + i);
01554 binContentuf += oldBins[ufbin];
01555 binCountuf += oldCount[ufbin];
01556 binErroruf += oldErrors[ufbin];
01557 if(fBinSumw2.fN) binSumw2uf += oldBinw2[ufbin];
01558 for(Int_t j = oldybin; j <= nybins+1; j++)
01559 {
01560 ofbin = ufbin + j*(nxbins + 2);
01561 binContentof += oldBins[ofbin];
01562 binCountof += oldCount[ofbin];
01563 binErrorof += oldErrors[ofbin];
01564 if(fBinSumw2.fN) binSumw2of += oldBinw2[ofbin];
01565 }
01566 }
01567
01568 ufbin = xbin;
01569 ofbin = ufbin + (newybins + 1)*(newxbins + 2);
01570 cu2[ufbin] = binContentuf;
01571 er2[ufbin] = binErroruf;
01572 en2[ufbin] = binCountuf;
01573 if(fBinSumw2.fN) ew2[ufbin] = binSumw2uf;
01574 cu2[ofbin] = binContentof;
01575 er2[ofbin] = binErrorof;
01576 en2[ofbin] = binCountof;
01577 if(fBinSumw2.fN) ew2[ofbin] = binSumw2of;
01578
01579 oldxbin2 += nxgroup;
01580 }
01581
01582 Int_t oldybin2 = 1;
01583 for(Int_t ybin = 1; ybin <= newybins; ybin++){
01584 binContentuf = 0;
01585 binCountuf = 0;
01586 binErroruf = 0;
01587 binSumw2uf = 0;
01588 binContentof = 0;
01589 binCountof = 0;
01590 binErrorof = 0;
01591 binSumw2of = 0;
01592 for(Int_t i = 0; i < nygroup; i++){
01593
01594 ufbin = (oldybin2 + i)*(nxbins+2);
01595 binContentuf += oldBins[ufbin];
01596 binCountuf += oldCount[ufbin];
01597 binErroruf += oldErrors[ufbin];
01598 if(fBinSumw2.fN) binSumw2uf += oldBinw2[ufbin];
01599 for(Int_t j = oldxbin; j <= nxbins+1; j++)
01600 {
01601 ofbin = j + ufbin;
01602 binContentof += oldBins[ofbin];
01603 binCountof += oldCount[ofbin];
01604 binErrorof += oldErrors[ofbin];
01605 if(fBinSumw2.fN) binSumw2of += oldBinw2[ofbin];
01606 }
01607 }
01608
01609 ufbin = ybin * (newxbins + 2);
01610 ofbin = newxbins + 1 + ufbin;
01611 cu2[ufbin] = binContentuf;
01612 er2[ufbin] = binErroruf;
01613 en2[ufbin] = binCountuf;
01614 if(fBinSumw2.fN) ew2[ufbin] = binSumw2uf;
01615 cu2[ofbin] = binContentof;
01616 er2[ofbin] = binErrorof;
01617 en2[ofbin] = binCountof;
01618 if(fBinSumw2.fN) ew2[ofbin] = binSumw2of;
01619
01620 oldybin2 += nygroup;
01621 }
01622
01623 delete [] oldBins;
01624 delete [] oldCount;
01625 delete [] oldErrors;
01626 if (oldBinw2) delete [] oldBinw2;
01627
01628 return hnew;
01629 }
01630
01631 else{
01632 if((newname) && (strlen(newname) > 0))
01633 return (TProfile2D*)Clone(newname);
01634 else
01635 return this;
01636 }
01637 }
01638
01639
01640 TProfile2D * TProfile2D::RebinX(Int_t ngroup,const char * newname ) {
01641
01642
01643
01644 return Rebin2D(ngroup,1,newname);
01645 }
01646
01647
01648 TProfile2D * TProfile2D::RebinY(Int_t ngroup,const char * newname ) {
01649
01650
01651
01652 return Rebin2D(1,ngroup,newname);
01653 }
01654
01655
01656 void TProfile2D::SavePrimitive(ostream &out, Option_t *option )
01657 {
01658
01659
01660
01661
01662
01663
01664
01665 char quote = '"';
01666 out <<" "<<endl;
01667 out <<" "<<ClassName()<<" *";
01668
01669 out << GetName() << " = new " << ClassName() << "(" << quote
01670 << GetName() << quote << "," << quote<< GetTitle() << quote
01671 << "," << GetXaxis()->GetNbins();
01672 out << "," << GetXaxis()->GetXmin()
01673 << "," << GetXaxis()->GetXmax();
01674 out << "," << GetYaxis()->GetNbins();
01675 out << "," << GetYaxis()->GetXmin()
01676 << "," << GetYaxis()->GetXmax();
01677 out << "," << fZmin
01678 << "," << fZmax;
01679 out << ");" << endl;
01680
01681
01682
01683 Int_t bin;
01684 for (bin=0;bin<fNcells;bin++) {
01685 Double_t bi = GetBinEntries(bin);
01686 if (bi) {
01687 out<<" "<<GetName()<<"->SetBinEntries("<<bin<<","<<bi<<");"<<endl;
01688 }
01689 }
01690
01691 for (bin=0;bin<fNcells;bin++) {
01692 Double_t bc = fArray[bin];
01693 if (bc) {
01694 out<<" "<<GetName()<<"->SetBinContent("<<bin<<","<<bc<<");"<<endl;
01695 }
01696 }
01697
01698 if (fSumw2.fN) {
01699 for (bin=0;bin<fNcells;bin++) {
01700 Double_t be = TMath::Sqrt(fSumw2.fArray[bin]);
01701 if (be) {
01702 out<<" "<<GetName()<<"->SetBinError("<<bin<<","<<be<<");"<<endl;
01703 }
01704 }
01705 }
01706
01707 TH1::SavePrimitiveHelp(out, GetName(), option);
01708 }
01709
01710
01711 void TProfile2D::Scale(Double_t c1, Option_t * option)
01712 {
01713
01714
01715
01716
01717
01718
01719
01720
01721 TProfileHelper::Scale(this, c1, option);
01722 }
01723
01724
01725 void TProfile2D::SetBinEntries(Int_t bin, Double_t w)
01726 {
01727
01728
01729
01730 if (bin < 0 || bin >= fNcells) return;
01731 fBinEntries.fArray[bin] = w;
01732 }
01733
01734
01735 void TProfile2D::SetBins(Int_t nx, Double_t xmin, Double_t xmax, Int_t ny, Double_t ymin, Double_t ymax)
01736 {
01737
01738
01739
01740 fXaxis.Set(nx,xmin,xmax);
01741 fYaxis.Set(ny,ymin,ymax);
01742 fNcells = (nx+2)*(ny+2);
01743 SetBinsLength(fNcells);
01744 fBinEntries.Set(fNcells);
01745 fSumw2.Set(fNcells);
01746 if (fBinSumw2.fN) fBinSumw2.Set(fNcells);
01747 }
01748
01749
01750
01751 void TProfile2D::SetBuffer(Int_t buffersize, Option_t *)
01752 {
01753
01754
01755 if (fBuffer) {
01756 BufferEmpty();
01757 delete [] fBuffer;
01758 fBuffer = 0;
01759 }
01760 if (buffersize <= 0) {
01761 fBufferSize = 0;
01762 return;
01763 }
01764 if (buffersize < 100) buffersize = 100;
01765 fBufferSize = 1 + 4*buffersize;
01766 fBuffer = new Double_t[fBufferSize];
01767 memset(fBuffer,0,8*fBufferSize);
01768 }
01769
01770
01771 void TProfile2D::SetErrorOption(Option_t *option)
01772 {
01773
01774
01775
01776
01777
01778
01779
01780
01781
01782
01783
01784
01785
01786
01787
01788
01789 TString opt = option;
01790 opt.ToLower();
01791 fErrorMode = kERRORMEAN;
01792 if (opt.Contains("s")) fErrorMode = kERRORSPREAD;
01793 if (opt.Contains("i")) fErrorMode = kERRORSPREADI;
01794 if (opt.Contains("g")) fErrorMode = kERRORSPREADG;
01795 }
01796
01797
01798 void TProfile2D::Streamer(TBuffer &R__b)
01799 {
01800
01801
01802 if (R__b.IsReading()) {
01803 UInt_t R__s, R__c;
01804 Version_t R__v = R__b.ReadVersion(&R__s, &R__c);
01805 if (R__v > 2) {
01806 R__b.ReadClassBuffer(TProfile2D::Class(), this, R__v, R__s, R__c);
01807 return;
01808 }
01809
01810 TH2D::Streamer(R__b);
01811 fBinEntries.Streamer(R__b);
01812 Int_t errorMode;
01813 R__b >> errorMode;
01814 fErrorMode = (EErrorType)errorMode;
01815 if (R__v < 2) {
01816 Float_t zmin,zmax;
01817 R__b >> zmin; fZmin = zmin;
01818 R__b >> zmax; fZmax = zmax;
01819 } else {
01820 R__b >> fZmin;
01821 R__b >> fZmax;
01822 }
01823 R__b.CheckByteCount(R__s, R__c, TProfile2D::IsA());
01824
01825
01826 } else {
01827 R__b.WriteClassBuffer(TProfile2D::Class(),this);
01828 }
01829 }
01830
01831
01832 void TProfile2D::Sumw2()
01833 {
01834
01835
01836
01837
01838
01839
01840
01841
01842 TProfileHelper::Sumw2(this);
01843 }