00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012 #include "TProfile3D.h"
00013 #include "THashList.h"
00014 #include "TMath.h"
00015 #include "THLimitsFinder.h"
00016 #include "Riostream.h"
00017 #include "TVirtualPad.h"
00018 #include "TError.h"
00019 #include "TClass.h"
00020
00021 #include "TProfileHelper.h"
00022
00023 Bool_t TProfile3D::fgApproximate = kFALSE;
00024
00025 ClassImp(TProfile3D)
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
00068
00069
00070
00071 TProfile3D::TProfile3D() : TH3D()
00072 {
00073
00074
00075 fTsumwt = fTsumwt2 = 0;
00076 fScaling = kFALSE;
00077 BuildOptions(0,0,"");
00078 }
00079
00080
00081 TProfile3D::~TProfile3D()
00082 {
00083
00084
00085
00086 }
00087
00088
00089 TProfile3D::TProfile3D(const char *name,const char *title,Int_t nx,Double_t xlow,Double_t xup,Int_t ny,Double_t ylow,Double_t yup,Int_t nz, Double_t zlow,Double_t zup,Option_t *option)
00090 : TH3D(name,title,nx,xlow,xup,ny,ylow,yup,nz,zlow,zup)
00091 {
00092
00093
00094
00095
00096
00097
00098
00099
00100
00101
00102
00103
00104
00105
00106
00107
00108
00109
00110
00111
00112
00113
00114
00115 BuildOptions(0,0,option);
00116 if (xlow >= xup || ylow >= yup || zlow >= zup) SetBuffer(fgBufferSize);
00117 }
00118
00119
00120 TProfile3D::TProfile3D(const char *name,const char *title,Int_t nx,const Double_t *xbins,Int_t ny,const Double_t *ybins,Int_t nz,const Double_t *zbins,Option_t *option)
00121 : TH3D(name,title,nx,xbins,ny,ybins,nz,zbins)
00122 {
00123
00124
00125 BuildOptions(0,0,option);
00126 }
00127
00128
00129 void TProfile3D::BuildOptions(Double_t tmin, Double_t tmax, Option_t *option)
00130 {
00131
00132
00133
00134
00135
00136
00137
00138
00139
00140
00141
00142
00143
00144
00145
00146
00147
00148
00149
00150
00151
00152
00153
00154
00155
00156
00157
00158
00159
00160
00161
00162
00163
00164
00165
00166
00167
00168
00169
00170
00171
00172
00173
00174
00175 SetErrorOption(option);
00176
00177 fBinEntries.Set(fNcells);
00178
00179 TH1::Sumw2();
00180 if (fgDefaultSumw2) Sumw2();
00181
00182 fTmin = tmin;
00183 fTmax = tmax;
00184 fScaling = kFALSE;
00185 fTsumwt = fTsumwt2 = 0;
00186 }
00187
00188
00189 TProfile3D::TProfile3D(const TProfile3D &profile) : TH3D()
00190 {
00191
00192 ((TProfile3D&)profile).Copy(*this);
00193 }
00194
00195
00196
00197 void TProfile3D::Add(TF1 *, Double_t , Option_t*)
00198 {
00199
00200
00201 Error("Add","Function not implemented for TProfile3D");
00202 return;
00203 }
00204
00205
00206
00207 void TProfile3D::Add(const TH1 *h1, Double_t c1)
00208 {
00209
00210
00211 if (!h1) {
00212 Error("Add","Attempt to add a non-existing profile");
00213 return;
00214 }
00215 if (!h1->InheritsFrom(TProfile3D::Class())) {
00216 Error("Add","Attempt to add a non-profile2D object");
00217 return;
00218 }
00219
00220 TProfileHelper::Add(this, this, h1, 1, c1);
00221 }
00222
00223
00224 void TProfile3D::Add(const TH1 *h1, const TH1 *h2, Double_t c1, Double_t c2)
00225 {
00226
00227
00228
00229
00230
00231
00232 if (!h1 || !h2) {
00233 Error("Add","Attempt to add a non-existing profile");
00234 return;
00235 }
00236 if (!h1->InheritsFrom(TProfile3D::Class())) {
00237 Error("Add","Attempt to add a non-profile3D object");
00238 return;
00239 }
00240 if (!h2->InheritsFrom(TProfile3D::Class())) {
00241 Error("Add","Attempt to add a non-profile3D object");
00242 return;
00243 }
00244
00245 TProfileHelper::Add(this, h1, h2, c1, c2);
00246 }
00247
00248
00249
00250 void TProfile3D::Approximate(Bool_t approx)
00251 {
00252
00253
00254
00255
00256
00257
00258
00259
00260
00261 fgApproximate = approx;
00262 }
00263
00264
00265
00266 Int_t TProfile3D::BufferEmpty(Int_t action)
00267 {
00268
00269
00270
00271
00272
00273
00274
00275
00276 if (!fBuffer) return 0;
00277 Int_t nbentries = (Int_t)fBuffer[0];
00278 if (!nbentries) return 0;
00279 Double_t *buffer = fBuffer;
00280 if (nbentries < 0) {
00281 if (action == 0) return 0;
00282 nbentries = -nbentries;
00283 fBuffer=0;
00284 Reset();
00285 fBuffer = buffer;
00286 }
00287 if (TestBit(kCanRebin) || fXaxis.GetXmax() <= fXaxis.GetXmin() || fYaxis.GetXmax() <= fYaxis.GetXmin()) {
00288
00289 Double_t xmin = fBuffer[2];
00290 Double_t xmax = xmin;
00291 Double_t ymin = fBuffer[3];
00292 Double_t ymax = ymin;
00293 Double_t zmin = fBuffer[4];
00294 Double_t zmax = zmin;
00295 for (Int_t i=1;i<nbentries;i++) {
00296 Double_t x = fBuffer[5*i+2];
00297 if (x < xmin) xmin = x;
00298 if (x > xmax) xmax = x;
00299 Double_t y = fBuffer[5*i+3];
00300 if (y < ymin) ymin = y;
00301 if (y > ymax) ymax = y;
00302 Double_t z = fBuffer[5*i+4];
00303 if (z < zmin) zmin = z;
00304 if (z > zmax) zmax = z;
00305 }
00306 if (fXaxis.GetXmax() <= fXaxis.GetXmin() || fYaxis.GetXmax() <= fYaxis.GetXmin() || fZaxis.GetXmax() <= fZaxis.GetXmin()) {
00307 THLimitsFinder::GetLimitsFinder()->FindGoodLimits(this,xmin,xmax,ymin,ymax,zmin,zmax);
00308 } else {
00309 fBuffer = 0;
00310 Int_t keep = fBufferSize; fBufferSize = 0;
00311 if (xmin < fXaxis.GetXmin()) RebinAxis(xmin,&fXaxis);
00312 if (xmax >= fXaxis.GetXmax()) RebinAxis(xmax,&fXaxis);
00313 if (ymin < fYaxis.GetXmin()) RebinAxis(ymin,&fYaxis);
00314 if (ymax >= fYaxis.GetXmax()) RebinAxis(ymax,&fYaxis);
00315 if (zmin < fZaxis.GetXmin()) RebinAxis(zmin,&fZaxis);
00316 if (zmax >= fZaxis.GetXmax()) RebinAxis(zmax,&fZaxis);
00317 fBuffer = buffer;
00318 fBufferSize = keep;
00319 }
00320 }
00321
00322 fBuffer = 0;
00323 for (Int_t i=0;i<nbentries;i++) {
00324 Fill(buffer[5*i+2],buffer[5*i+3],buffer[5*i+4],buffer[5*i+5],buffer[5*i+1]);
00325 }
00326 fBuffer = buffer;
00327
00328 if (action > 0) { delete [] fBuffer; fBuffer = 0; fBufferSize = 0;}
00329 else {
00330 if (nbentries == (Int_t)fEntries) fBuffer[0] = -nbentries;
00331 else fBuffer[0] = 0;
00332 }
00333 return nbentries;
00334 }
00335
00336
00337 Int_t TProfile3D::BufferFill(Double_t x, Double_t y, Double_t z, Double_t t, Double_t w)
00338 {
00339
00340
00341
00342
00343
00344
00345
00346
00347 if (!fBuffer) return -3;
00348 Int_t nbentries = (Int_t)fBuffer[0];
00349 if (nbentries < 0) {
00350 nbentries = -nbentries;
00351 fBuffer[0] = nbentries;
00352 if (fEntries > 0) {
00353 Double_t *buffer = fBuffer; fBuffer=0;
00354 Reset();
00355 fBuffer = buffer;
00356 }
00357 }
00358 if (5*nbentries+5 >= fBufferSize) {
00359 BufferEmpty(1);
00360 return Fill(x,y,z,t,w);
00361 }
00362 fBuffer[5*nbentries+1] = w;
00363 fBuffer[5*nbentries+2] = x;
00364 fBuffer[5*nbentries+3] = y;
00365 fBuffer[5*nbentries+4] = z;
00366 fBuffer[5*nbentries+5] = t;
00367 fBuffer[0] += 1;
00368 return -2;
00369 }
00370
00371
00372 void TProfile3D::Copy(TObject &obj) const
00373 {
00374
00375
00376
00377 TH3D::Copy(((TProfile3D&)obj));
00378 fBinEntries.Copy(((TProfile3D&)obj).fBinEntries);
00379 fBinSumw2.Copy(((TProfile3D&)obj).fBinSumw2);
00380 for (int bin=0;bin<fNcells;bin++) {
00381 ((TProfile3D&)obj).fArray[bin] = fArray[bin];
00382 ((TProfile3D&)obj).fSumw2.fArray[bin] = fSumw2.fArray[bin];
00383 }
00384 ((TProfile3D&)obj).fTmin = fTmin;
00385 ((TProfile3D&)obj).fTmax = fTmax;
00386 ((TProfile3D&)obj).fScaling = fScaling;
00387 ((TProfile3D&)obj).fErrorMode = fErrorMode;
00388 ((TProfile3D&)obj).fTsumwt = fTsumwt;
00389 ((TProfile3D&)obj).fTsumwt2 = fTsumwt2;
00390 }
00391
00392
00393
00394 void TProfile3D::Divide(TF1 *, Double_t )
00395 {
00396
00397
00398 Error("Divide","Function not implemented for TProfile3D");
00399 return;
00400 }
00401
00402
00403 void TProfile3D::Divide(const TH1 *h1)
00404 {
00405
00406
00407
00408
00409
00410
00411 if (!h1) {
00412 Error("Divide","Attempt to divide a non-existing profile2D");
00413 return;
00414 }
00415 if (!h1->InheritsFrom(TProfile3D::Class())) {
00416 Error("Divide","Attempt to divide a non-profile3D object");
00417 return;
00418 }
00419 TProfile3D *p1 = (TProfile3D*)h1;
00420
00421
00422 Int_t nx = GetNbinsX();
00423 if (nx != p1->GetNbinsX()) {
00424 Error("Divide","Attempt to divide profiles with different number of bins");
00425 return;
00426 }
00427 Int_t ny = GetNbinsY();
00428 if (ny != p1->GetNbinsY()) {
00429 Error("Divide","Attempt to divide profiles with different number of bins");
00430 return;
00431 }
00432 Int_t nz = GetNbinsZ();
00433 if (nz != p1->GetNbinsZ()) {
00434 Error("Divide","Attempt to divide profiles with different number of bins");
00435 return;
00436 }
00437
00438
00439 fEntries = fTsumw = fTsumw2 = fTsumwx = fTsumwx2 = 0;
00440
00441
00442 Int_t bin,binx,biny,binz;
00443 Double_t *cu1 = p1->GetW();
00444 Double_t *er1 = p1->GetW2();
00445 Double_t *en1 = p1->GetB();
00446 Double_t c0,c1,w,u,x,y,z;
00447 for (binx =0;binx<=nx+1;binx++) {
00448 for (biny =0;biny<=ny+1;biny++) {
00449 for (binz =0;binz<=nz+1;binz++) {
00450 bin = GetBin(binx,biny,binz);
00451 c0 = fArray[bin];
00452 c1 = cu1[bin];
00453 if (c1) w = c0/c1;
00454 else w = 0;
00455 fArray[bin] = w;
00456 u = TMath::Abs(w);
00457 x = fXaxis.GetBinCenter(binx);
00458 y = fYaxis.GetBinCenter(biny);
00459 z = fZaxis.GetBinCenter(binz);
00460 fEntries++;
00461 fTsumw += u;
00462 fTsumw2 += u*u;
00463 fTsumwx += u*x;
00464 fTsumwx2 += u*x*x;
00465 fTsumwy += u*y;
00466 fTsumwy2 += u*y*y;
00467 fTsumwxy += u*x*y;
00468 fTsumwz += u;
00469 fTsumwz2 += u*z;
00470 fTsumwxz += u*x*z;
00471 fTsumwyz += u*y*z;
00472 fTsumwt += u;
00473 fTsumwt2 += u*u;
00474 Double_t e0 = fSumw2.fArray[bin];
00475 Double_t e1 = er1[bin];
00476 Double_t c12= c1*c1;
00477 if (!c1) fSumw2.fArray[bin] = 0;
00478 else fSumw2.fArray[bin] = (e0*c1*c1 + e1*c0*c0)/(c12*c12);
00479 if (!en1[bin]) fBinEntries.fArray[bin] = 0;
00480 else fBinEntries.fArray[bin] /= en1[bin];
00481 }
00482 }
00483 }
00484
00485
00486 if (fBinSumw2.fN) {
00487 Warning("Divide","Cannot preserve during the division of profiles the sum of bin weight square");
00488 fBinSumw2 = TArrayD();
00489 }
00490 }
00491
00492
00493
00494 void TProfile3D::Divide(const TH1 *h1, const TH1 *h2, Double_t c1, Double_t c2, Option_t *option)
00495 {
00496
00497
00498
00499
00500
00501
00502 TString opt = option;
00503 opt.ToLower();
00504 Bool_t binomial = kFALSE;
00505 if (opt.Contains("b")) binomial = kTRUE;
00506 if (!h1 || !h2) {
00507 Error("Divide","Attempt to divide a non-existing profile2D");
00508 return;
00509 }
00510 if (!h1->InheritsFrom(TProfile3D::Class())) {
00511 Error("Divide","Attempt to divide a non-profile2D object");
00512 return;
00513 }
00514 TProfile3D *p1 = (TProfile3D*)h1;
00515 if (!h2->InheritsFrom(TProfile3D::Class())) {
00516 Error("Divide","Attempt to divide a non-profile2D object");
00517 return;
00518 }
00519 TProfile3D *p2 = (TProfile3D*)h2;
00520
00521
00522 Int_t nx = GetNbinsX();
00523 if (nx != p1->GetNbinsX() || nx != p2->GetNbinsX()) {
00524 Error("Divide","Attempt to divide profiles with different number of bins");
00525 return;
00526 }
00527 Int_t ny = GetNbinsY();
00528 if (ny != p1->GetNbinsY() || ny != p2->GetNbinsY()) {
00529 Error("Divide","Attempt to divide profiles with different number of bins");
00530 return;
00531 }
00532 Int_t nz = GetNbinsZ();
00533 if (nz != p1->GetNbinsZ() || nz != p2->GetNbinsZ()) {
00534 Error("Divide","Attempt to divide profiles with different number of bins");
00535 return;
00536 }
00537 if (!c2) {
00538 Error("Divide","Coefficient of dividing profile cannot be zero");
00539 return;
00540 }
00541
00542
00543 fEntries = fTsumw = fTsumw2 = fTsumwx = fTsumwx2 = 0;
00544
00545
00546 Int_t bin,binx,biny,binz;
00547 Double_t *cu1 = p1->GetW();
00548 Double_t *cu2 = p2->GetW();
00549 Double_t *er1 = p1->GetW2();
00550 Double_t *er2 = p2->GetW2();
00551 Double_t *en1 = p1->GetB();
00552 Double_t *en2 = p2->GetB();
00553 Double_t b1,b2,w,u,x,y,z,ac1,ac2;
00554 ac1 = TMath::Abs(c1);
00555 ac2 = TMath::Abs(c2);
00556 for (binx =0;binx<=nx+1;binx++) {
00557 for (biny =0;biny<=ny+1;biny++) {
00558 for (binz =0;binz<=nz+1;binz++) {
00559 bin = GetBin(binx,biny,binz);
00560 b1 = cu1[bin];
00561 b2 = cu2[bin];
00562 if (b2) w = c1*b1/(c2*b2);
00563 else w = 0;
00564 fArray[bin] = w;
00565 u = TMath::Abs(w);
00566 x = fXaxis.GetBinCenter(binx);
00567 y = fYaxis.GetBinCenter(biny);
00568 z = fZaxis.GetBinCenter(biny);
00569 fEntries++;
00570 fTsumw += u;
00571 fTsumw2 += u*u;
00572 fTsumwx += u*x;
00573 fTsumwx2 += u*x*x;
00574 fTsumwy += u*y;
00575 fTsumwy2 += u*y*y;
00576 fTsumwxy += u*x*y;
00577 fTsumwz += u*z;
00578 fTsumwz2 += u*z*z;
00579 fTsumwxz += u*x*z;
00580 fTsumwyz += u*y*z;
00581 fTsumwt += u;
00582 fTsumwt2 += u*u;
00583 Double_t e1 = er1[bin];
00584 Double_t e2 = er2[bin];
00585
00586 Double_t b22= b2*b2*TMath::Abs(c2);
00587 if (!b2) fSumw2.fArray[bin] = 0;
00588 else {
00589 if (binomial) {
00590 fSumw2.fArray[bin] = TMath::Abs(w*(1-w)/(c2*b2));
00591 } else {
00592 fSumw2.fArray[bin] = ac1*ac2*(e1*b2*b2 + e2*b1*b1)/(b22*b22);
00593 }
00594 }
00595 if (!en2[bin]) fBinEntries.fArray[bin] = 0;
00596 else fBinEntries.fArray[bin] = en1[bin]/en2[bin];
00597 }
00598 }
00599 }
00600 }
00601
00602
00603 TH1 *TProfile3D::DrawCopy(Option_t *option) const
00604 {
00605
00606
00607 TString opt = option;
00608 opt.ToLower();
00609 if (gPad && !opt.Contains("same")) gPad->Clear();
00610 TProfile3D *newpf = new TProfile3D();
00611 Copy(*newpf);
00612 newpf->SetDirectory(0);
00613 newpf->SetBit(kCanDelete);
00614 newpf->AppendPad(option);
00615 return newpf;
00616 }
00617
00618
00619 Int_t TProfile3D::Fill(Double_t x, Double_t y, Double_t z, Double_t t)
00620 {
00621
00622
00623
00624 if (fBuffer) return BufferFill(x,y,z,t,1);
00625
00626 Int_t bin,binx,biny,binz;
00627
00628 if (fTmin != fTmax) {
00629 if (t <fTmin || t> fTmax) return -1;
00630 }
00631
00632 fEntries++;
00633 binx =fXaxis.FindBin(x);
00634 biny =fYaxis.FindBin(y);
00635 binz =fZaxis.FindBin(z);
00636 if (binx <0 || biny <0 || binz<0) return -1;
00637 bin = GetBin(binx,biny,binz);
00638 AddBinContent(bin, t);
00639 fSumw2.fArray[bin] += (Double_t)t*t;
00640 fBinEntries.fArray[bin] += 1;
00641 if (fBinSumw2.fN) fBinSumw2.fArray[bin] += 1;
00642 if (binx == 0 || binx > fXaxis.GetNbins()) {
00643 if (!fgStatOverflows) return -1;
00644 }
00645 if (biny == 0 || biny > fYaxis.GetNbins()) {
00646 if (!fgStatOverflows) return -1;
00647 }
00648 if (binz == 0 || binz > fZaxis.GetNbins()) {
00649 if (!fgStatOverflows) return -1;
00650 }
00651
00652 ++fTsumw;
00653 ++fTsumw2;
00654 fTsumwx += x;
00655 fTsumwx2 += x*x;
00656 fTsumwy += y;
00657 fTsumwy2 += y*y;
00658 fTsumwxy += x*y;
00659 fTsumwz += z;
00660 fTsumwz2 += z*z;
00661 fTsumwxz += x*z;
00662 fTsumwyz += y*z;
00663 fTsumwt += t;
00664 fTsumwt2 += t*t;
00665 return bin;
00666 }
00667
00668
00669 Int_t TProfile3D::Fill(Double_t x, Double_t y, Double_t z, Double_t t, Double_t w)
00670 {
00671
00672
00673
00674 if (fBuffer) return BufferFill(x,y,z,t,w);
00675
00676 Int_t bin,binx,biny,binz;
00677
00678 if (fTmin != fTmax) {
00679 if (t <fTmin || z> fTmax) return -1;
00680 }
00681
00682 Double_t u= (w > 0 ? w : -w);
00683 fEntries++;
00684 binx =fXaxis.FindBin(x);
00685 biny =fYaxis.FindBin(y);
00686 binz =fZaxis.FindBin(z);
00687 if (binx <0 || biny <0 || binz<0) return -1;
00688 bin = GetBin(binx,biny,binz);
00689 AddBinContent(bin, u*t);
00690 fSumw2.fArray[bin] += u*t*t;
00691 fBinEntries.fArray[bin] += u;
00692 if (fBinSumw2.fN) fBinSumw2.fArray[bin] += u*u;
00693 if (binx == 0 || binx > fXaxis.GetNbins()) {
00694 if (!fgStatOverflows) return -1;
00695 }
00696 if (biny == 0 || biny > fYaxis.GetNbins()) {
00697 if (!fgStatOverflows) return -1;
00698 }
00699 if (binz == 0 || binz > fZaxis.GetNbins()) {
00700 if (!fgStatOverflows) return -1;
00701 }
00702 fTsumw += u;
00703 fTsumw2 += u*u;
00704 fTsumwx += u*x;
00705 fTsumwx2 += u*x*x;
00706 fTsumwy += u*y;
00707 fTsumwy2 += u*y*y;
00708 fTsumwxy += u*x*y;
00709 fTsumwz += u*z;
00710 fTsumwz2 += u*z*z;
00711 fTsumwxz += u*x*z;
00712 fTsumwyz += u*y*z;
00713 fTsumwt += u*t;
00714 fTsumwt2 += u*t*t;
00715 return bin;
00716 }
00717
00718
00719 Double_t TProfile3D::GetBinContent(Int_t bin) const
00720 {
00721
00722
00723
00724 if (fBuffer) ((TProfile3D*)this)->BufferEmpty();
00725
00726 if (bin < 0 || bin >= fNcells) return 0;
00727 if (fBinEntries.fArray[bin] == 0) return 0;
00728 if (!fArray) return 0;
00729 return fArray[bin]/fBinEntries.fArray[bin];
00730 }
00731
00732
00733 Double_t TProfile3D::GetBinEntries(Int_t bin) const
00734 {
00735
00736
00737
00738 if (fBuffer) ((TProfile3D*)this)->BufferEmpty();
00739
00740 if (bin < 0 || bin >= fNcells) return 0;
00741 return fBinEntries.fArray[bin];
00742 }
00743
00744
00745 Double_t TProfile3D::GetBinEffectiveEntries(Int_t bin)
00746 {
00747
00748
00749
00750
00751
00752
00753
00754
00755
00756 return TProfileHelper::GetBinEffectiveEntries((TProfile3D*)this, bin);
00757 }
00758
00759
00760 Double_t TProfile3D::GetBinError(Int_t bin) const
00761 {
00762
00763
00764
00765
00766
00767
00768
00769
00770
00771
00772
00773
00774
00775
00776
00777
00778
00779 return TProfileHelper::GetBinError((TProfile3D*)this, bin);
00780 }
00781
00782
00783 Option_t *TProfile3D::GetErrorOption() const
00784 {
00785
00786
00787
00788 if (fErrorMode == kERRORSPREAD) return "s";
00789 if (fErrorMode == kERRORSPREADI) return "i";
00790 if (fErrorMode == kERRORSPREADG) return "g";
00791 return "";
00792 }
00793
00794
00795 void TProfile3D::GetStats(Double_t *stats) const
00796 {
00797
00798
00799
00800
00801
00802
00803
00804
00805
00806
00807
00808
00809
00810
00811
00812
00813
00814
00815
00816
00817
00818 if (fBuffer) ((TProfile3D*)this)->BufferEmpty();
00819
00820
00821 if (fTsumw == 0 || fXaxis.TestBit(TAxis::kAxisRange) || fYaxis.TestBit(TAxis::kAxisRange)) {
00822 Int_t bin, binx, biny,binz;
00823 Double_t w, w2;
00824 Double_t x,y,z;
00825 for (bin=0;bin<kNstat;bin++) stats[bin] = 0;
00826 if (!fBinEntries.fArray) return;
00827 for (binz=fZaxis.GetFirst();binz<=fZaxis.GetLast();binz++) {
00828 z = fZaxis.GetBinCenter(binz);
00829 for (biny=fYaxis.GetFirst();biny<=fYaxis.GetLast();biny++) {
00830 y = fYaxis.GetBinCenter(biny);
00831 for (binx=fXaxis.GetFirst();binx<=fXaxis.GetLast();binx++) {
00832 bin = GetBin(binx,biny,binz);
00833 w = fBinEntries.fArray[bin];
00834 w2 = (fBinSumw2.fN ? fBinSumw2.fArray[bin] : w );
00835 x = fXaxis.GetBinCenter(binx);
00836 stats[0] += w;
00837 stats[1] += w2;
00838 stats[2] += w*x;
00839 stats[3] += w*x*x;
00840 stats[4] += w*y;
00841 stats[5] += w*y*y;
00842 stats[6] += w*x*y;
00843 stats[7] += w*z;
00844 stats[8] += w*z*z;
00845 stats[9] += w*x*z;
00846 stats[10] += w*y*z;
00847 stats[11] += fArray[bin];
00848 stats[12] += fSumw2.fArray[bin];
00849 }
00850 }
00851 }
00852 } else {
00853 stats[0] = fTsumw;
00854 stats[1] = fTsumw2;
00855 stats[2] = fTsumwx;
00856 stats[3] = fTsumwx2;
00857 stats[4] = fTsumwy;
00858 stats[5] = fTsumwy2;
00859 stats[6] = fTsumwxy;
00860 stats[7] = fTsumwz;
00861 stats[8] = fTsumwz2;
00862 stats[9] = fTsumwxz;
00863 stats[10] = fTsumwyz;
00864 stats[11] = fTsumwt;
00865 stats[12] = fTsumwt2;
00866 }
00867 }
00868
00869
00870 Long64_t TProfile3D::Merge(TCollection *li)
00871 {
00872
00873
00874
00875
00876
00877
00878
00879
00880
00881
00882
00883
00884
00885 return TProfileHelper::Merge(this, li);
00886
00887
00888
00889
00890
00891
00892
00893
00894
00895
00896
00897
00898
00899
00900
00901
00902
00903
00904
00905
00906
00907
00908
00909
00910
00911
00912
00913
00914
00915
00916
00917
00918
00919
00920
00921
00922
00923
00924
00925
00926
00927
00928
00929
00930
00931
00932
00933
00934
00935
00936
00937
00938
00939
00940
00941
00942
00943
00944
00945
00946
00947
00948
00949
00950
00951
00952
00953
00954
00955
00956
00957
00958
00959
00960
00961
00962
00963
00964
00965
00966
00967
00968
00969
00970
00971
00972
00973
00974
00975
00976
00977
00978
00979
00980
00981
00982
00983
00984
00985
00986
00987
00988
00989
00990
00991
00992
00993
00994
00995
00996
00997
00998
00999
01000
01001
01002
01003
01004
01005
01006
01007
01008
01009
01010
01011
01012
01013
01014
01015
01016
01017
01018
01019
01020
01021
01022
01023
01024
01025
01026
01027
01028
01029
01030
01031
01032
01033
01034
01035
01036
01037
01038
01039
01040
01041
01042
01043
01044
01045
01046
01047
01048
01049
01050
01051 }
01052
01053
01054 void TProfile3D::Multiply(TF1 *, Double_t )
01055 {
01056
01057
01058 Error("Multiply","Function not implemented for TProfile3D");
01059 return;
01060 }
01061
01062
01063 void TProfile3D::Multiply(const TH1 *)
01064 {
01065
01066
01067
01068
01069
01070 Error("Multiply","Multiplication of profile2D histograms not implemented");
01071 }
01072
01073
01074
01075 void TProfile3D::Multiply(const TH1 *, const TH1 *, Double_t, Double_t, Option_t *)
01076 {
01077
01078
01079
01080
01081
01082
01083 Error("Multiply","Multiplication of profile2D histograms not implemented");
01084 }
01085
01086
01087 TH3D *TProfile3D::ProjectionXYZ(const char *name, Option_t *option) const
01088 {
01089
01090
01091
01092
01093
01094
01095
01096
01097
01098
01099
01100
01101 TString opt = option;
01102 opt.ToLower();
01103 Int_t nx = fXaxis.GetNbins();
01104 Int_t ny = fYaxis.GetNbins();
01105 Int_t nz = fZaxis.GetNbins();
01106
01107
01108 TString pname = name;
01109 if (pname == "_px") {
01110 pname = GetName(); pname.Append("_px");
01111 }
01112 TH3D *h1 = new TH3D(pname,GetTitle(),nx,fXaxis.GetXmin(),fXaxis.GetXmax(),ny,fYaxis.GetXmin(),fYaxis.GetXmax(),nz,fZaxis.GetXmin(),fZaxis.GetXmax());
01113 Bool_t computeErrors = kFALSE;
01114 Bool_t cequalErrors = kFALSE;
01115 Bool_t binEntries = kFALSE;
01116 if (opt.Contains("b")) binEntries = kTRUE;
01117 if (opt.Contains("e")) computeErrors = kTRUE;
01118 if (opt.Contains("c=e")) {cequalErrors = kTRUE; computeErrors=kFALSE;}
01119 if (computeErrors) h1->Sumw2();
01120
01121
01122 Int_t bin,binx,biny,binz;
01123 Double_t cont,err;
01124 for (binx =0;binx<=nx+1;binx++) {
01125 for (biny =0;biny<=ny+1;biny++) {
01126 for (binz =0;binz<=nz+1;binz++) {
01127 bin = GetBin(binx,biny,binz);
01128 if (binEntries) cont = GetBinEntries(bin);
01129 else cont = GetBinContent(bin);
01130 err = GetBinError(bin);
01131 if (cequalErrors) h1->SetBinContent(binx,biny,binz, err);
01132 else h1->SetBinContent(binx,biny,binz,cont);
01133 if (computeErrors) h1->SetBinError(binx,biny,binz,err);
01134 }
01135 }
01136 }
01137 h1->SetEntries(fEntries);
01138 return h1;
01139 }
01140
01141
01142 void TProfile3D::PutStats(Double_t *stats)
01143 {
01144
01145
01146 TH3::PutStats(stats);
01147 fTsumwt = stats[11];
01148 fTsumwt2 = stats[12];
01149 }
01150
01151
01152 void TProfile3D::Reset(Option_t *option)
01153 {
01154
01155
01156 TH3D::Reset(option);
01157 fBinSumw2.Reset();
01158 fBinEntries.Reset();
01159 TString opt = option;
01160 opt.ToUpper();
01161 if (opt.Contains("ICE")) return;
01162 fTsumwt = fTsumwt2 = 0;
01163 }
01164
01165
01166 void TProfile3D::RebinAxis(Double_t x, TAxis *axis)
01167 {
01168
01169
01170
01171
01172
01173
01174
01175
01176
01177 TProfile3D* hold = TProfileHelper::RebinAxis(this, x, axis);
01178 if ( hold ) {
01179 fTsumwt = hold->fTsumwt;
01180 fTsumwt2 = hold->fTsumwt2;
01181 delete hold;
01182 }
01183 }
01184
01185
01186 void TProfile3D::SavePrimitive(ostream &out, Option_t *option )
01187 {
01188
01189
01190
01191
01192
01193
01194
01195 char quote = '"';
01196 out <<" "<<endl;
01197 out <<" "<<ClassName()<<" *";
01198
01199 out << GetName() << " = new " << ClassName() << "(" << quote
01200 << GetName() << quote << "," << quote<< GetTitle() << quote
01201 << "," << GetXaxis()->GetNbins();
01202 out << "," << GetXaxis()->GetXmin()
01203 << "," << GetXaxis()->GetXmax();
01204 out << "," << GetYaxis()->GetNbins();
01205 out << "," << GetYaxis()->GetXmin()
01206 << "," << GetYaxis()->GetXmax();
01207 out << "," << GetZaxis()->GetNbins();
01208 out << "," << GetZaxis()->GetXmin()
01209 << "," << GetZaxis()->GetXmax();
01210 out << "," << fTmin
01211 << "," << fTmax;
01212 out << ");" << endl;
01213
01214
01215
01216 Int_t bin;
01217 for (bin=0;bin<fNcells;bin++) {
01218 Double_t bi = GetBinEntries(bin);
01219 if (bi) {
01220 out<<" "<<GetName()<<"->SetBinEntries("<<bin<<","<<bi<<");"<<endl;
01221 }
01222 }
01223
01224 for (bin=0;bin<fNcells;bin++) {
01225 Double_t bc = fArray[bin];
01226 if (bc) {
01227 out<<" "<<GetName()<<"->SetBinContent("<<bin<<","<<bc<<");"<<endl;
01228 }
01229 }
01230
01231 if (fSumw2.fN) {
01232 for (bin=0;bin<fNcells;bin++) {
01233 Double_t be = TMath::Sqrt(fSumw2.fArray[bin]);
01234 if (be) {
01235 out<<" "<<GetName()<<"->SetBinError("<<bin<<","<<be<<");"<<endl;
01236 }
01237 }
01238 }
01239
01240 TH1::SavePrimitiveHelp(out, GetName(), option);
01241 }
01242
01243
01244 void TProfile3D::Scale(Double_t c1, Option_t *option)
01245 {
01246
01247
01248
01249
01250
01251
01252
01253
01254 TProfileHelper::Scale(this, c1, option);
01255 }
01256
01257
01258 void TProfile3D::SetBinEntries(Int_t bin, Double_t w)
01259 {
01260
01261
01262
01263 if (bin < 0 || bin >= fNcells) return;
01264 fBinEntries.fArray[bin] = w;
01265 }
01266
01267
01268 void TProfile3D::SetBins(Int_t nx, Double_t xmin, Double_t xmax, Int_t ny, Double_t ymin, Double_t ymax, Int_t nz, Double_t zmin, Double_t zmax)
01269 {
01270
01271
01272
01273 fXaxis.Set(nx,xmin,xmax);
01274 fYaxis.Set(ny,ymin,ymax);
01275 fZaxis.Set(ny,zmin,zmax);
01276 fNcells = (nx+2)*(ny+2)*(nz+2);
01277 fBinEntries.Set(fNcells);
01278 fSumw2.Set(fNcells);
01279 if (fBinSumw2.fN) fBinSumw2.Set(fNcells);
01280 }
01281
01282
01283
01284 void TProfile3D::SetBuffer(Int_t buffersize, Option_t *)
01285 {
01286
01287
01288 if (fBuffer) {
01289 BufferEmpty();
01290 delete [] fBuffer;
01291 fBuffer = 0;
01292 }
01293 if (buffersize <= 0) {
01294 fBufferSize = 0;
01295 return;
01296 }
01297 if (buffersize < 100) buffersize = 100;
01298 fBufferSize = 1 + 5*buffersize;
01299 fBuffer = new Double_t[fBufferSize];
01300 memset(fBuffer,0,8*fBufferSize);
01301 }
01302
01303
01304 void TProfile3D::SetErrorOption(Option_t *option)
01305 {
01306
01307
01308
01309
01310
01311
01312
01313
01314
01315
01316
01317
01318
01319
01320
01321
01322 TString opt = option;
01323 opt.ToLower();
01324 fErrorMode = kERRORMEAN;
01325 if (opt.Contains("s")) fErrorMode = kERRORSPREAD;
01326 if (opt.Contains("i")) fErrorMode = kERRORSPREADI;
01327 if (opt.Contains("g")) fErrorMode = kERRORSPREADG;
01328 }
01329
01330
01331 void TProfile3D::Sumw2()
01332 {
01333
01334
01335
01336
01337
01338
01339
01340
01341 TProfileHelper::Sumw2(this);
01342 }