00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012 #include "TROOT.h"
00013 #include "TClass.h"
00014 #include "THashList.h"
00015 #include "TH3.h"
00016 #include "TProfile2D.h"
00017 #include "TH2.h"
00018 #include "TF1.h"
00019 #include "TVirtualPad.h"
00020 #include "TVirtualHistPainter.h"
00021 #include "THLimitsFinder.h"
00022 #include "TRandom.h"
00023 #include "TError.h"
00024 #include "TMath.h"
00025 #include "TObjString.h"
00026
00027 ClassImp(TH3)
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048 TH3::TH3()
00049 {
00050
00051 fDimension = 3;
00052 fTsumwy = fTsumwy2 = fTsumwxy = 0;
00053 fTsumwz = fTsumwz2 = fTsumwxz = fTsumwyz = 0;
00054 }
00055
00056
00057 TH3::TH3(const char *name,const char *title,Int_t nbinsx,Double_t xlow,Double_t xup
00058 ,Int_t nbinsy,Double_t ylow,Double_t yup
00059 ,Int_t nbinsz,Double_t zlow,Double_t zup)
00060 :TH1(name,title,nbinsx,xlow,xup),
00061 TAtt3D()
00062 {
00063
00064
00065
00066 fDimension = 3;
00067 if (nbinsy <= 0) nbinsy = 1;
00068 if (nbinsz <= 0) nbinsz = 1;
00069 fYaxis.Set(nbinsy,ylow,yup);
00070 fZaxis.Set(nbinsz,zlow,zup);
00071 fNcells = (nbinsx+2)*(nbinsy+2)*(nbinsz+2);
00072 fTsumwy = fTsumwy2 = fTsumwxy = 0;
00073 fTsumwz = fTsumwz2 = fTsumwxz = fTsumwyz = 0;
00074 }
00075
00076
00077 TH3::TH3(const char *name,const char *title,Int_t nbinsx,const Float_t *xbins
00078 ,Int_t nbinsy,const Float_t *ybins
00079 ,Int_t nbinsz,const Float_t *zbins)
00080 :TH1(name,title,nbinsx,xbins),
00081 TAtt3D()
00082 {
00083
00084
00085 fDimension = 3;
00086 if (nbinsy <= 0) nbinsy = 1;
00087 if (nbinsz <= 0) nbinsz = 1;
00088 if (ybins) fYaxis.Set(nbinsy,ybins);
00089 else fYaxis.Set(nbinsy,0,1);
00090 if (zbins) fZaxis.Set(nbinsz,zbins);
00091 else fZaxis.Set(nbinsz,0,1);
00092 fNcells = (nbinsx+2)*(nbinsy+2)*(nbinsz+2);
00093 fTsumwy = fTsumwy2 = fTsumwxy = 0;
00094 fTsumwz = fTsumwz2 = fTsumwxz = fTsumwyz = 0;
00095 }
00096
00097
00098 TH3::TH3(const char *name,const char *title,Int_t nbinsx,const Double_t *xbins
00099 ,Int_t nbinsy,const Double_t *ybins
00100 ,Int_t nbinsz,const Double_t *zbins)
00101 :TH1(name,title,nbinsx,xbins),
00102 TAtt3D()
00103 {
00104
00105
00106 fDimension = 3;
00107 if (nbinsy <= 0) nbinsy = 1;
00108 if (nbinsz <= 0) nbinsz = 1;
00109 if (ybins) fYaxis.Set(nbinsy,ybins);
00110 else fYaxis.Set(nbinsy,0,1);
00111 if (zbins) fZaxis.Set(nbinsz,zbins);
00112 else fZaxis.Set(nbinsz,0,1);
00113 fNcells = (nbinsx+2)*(nbinsy+2)*(nbinsz+2);
00114 fTsumwy = fTsumwy2 = fTsumwxy = 0;
00115 fTsumwz = fTsumwz2 = fTsumwxz = fTsumwyz = 0;
00116 }
00117
00118
00119 TH3::TH3(const TH3 &h) : TH1(), TAtt3D()
00120 {
00121
00122
00123
00124 ((TH3&)h).Copy(*this);
00125 }
00126
00127
00128 TH3::~TH3()
00129 {
00130
00131 }
00132
00133
00134 void TH3::Copy(TObject &obj) const
00135 {
00136
00137
00138 TH1::Copy(obj);
00139 ((TH3&)obj).fTsumwy = fTsumwy;
00140 ((TH3&)obj).fTsumwy2 = fTsumwy2;
00141 ((TH3&)obj).fTsumwxy = fTsumwxy;
00142 ((TH3&)obj).fTsumwz = fTsumwz;
00143 ((TH3&)obj).fTsumwz2 = fTsumwz2;
00144 ((TH3&)obj).fTsumwxz = fTsumwxz;
00145 ((TH3&)obj).fTsumwyz = fTsumwyz;
00146 }
00147
00148
00149 Int_t TH3::BufferEmpty(Int_t action)
00150 {
00151
00152
00153
00154
00155
00156
00157
00158
00159 if (!fBuffer) return 0;
00160 Int_t nbentries = (Int_t)fBuffer[0];
00161 if (!nbentries) return 0;
00162 Double_t *buffer = fBuffer;
00163 if (nbentries < 0) {
00164 if (action == 0) return 0;
00165 nbentries = -nbentries;
00166 fBuffer=0;
00167 Reset();
00168 fBuffer = buffer;
00169 }
00170 if (TestBit(kCanRebin) || fXaxis.GetXmax() <= fXaxis.GetXmin() ||
00171 fYaxis.GetXmax() <= fYaxis.GetXmin() ||
00172 fZaxis.GetXmax() <= fZaxis.GetXmin()) {
00173
00174 Double_t xmin = fBuffer[2];
00175 Double_t xmax = xmin;
00176 Double_t ymin = fBuffer[3];
00177 Double_t ymax = ymin;
00178 Double_t zmin = fBuffer[4];
00179 Double_t zmax = zmin;
00180 for (Int_t i=1;i<nbentries;i++) {
00181 Double_t x = fBuffer[4*i+2];
00182 if (x < xmin) xmin = x;
00183 if (x > xmax) xmax = x;
00184 Double_t y = fBuffer[4*i+3];
00185 if (y < ymin) ymin = y;
00186 if (y > ymax) ymax = y;
00187 Double_t z = fBuffer[4*i+4];
00188 if (z < zmin) zmin = z;
00189 if (z > zmax) zmax = z;
00190 }
00191 if (fXaxis.GetXmax() <= fXaxis.GetXmin() || fYaxis.GetXmax() <= fYaxis.GetXmin() || fZaxis.GetXmax() <= fZaxis.GetXmin()) {
00192 THLimitsFinder::GetLimitsFinder()->FindGoodLimits(this,xmin,xmax,ymin,ymax,zmin,zmax);
00193 } else {
00194 fBuffer = 0;
00195 Int_t keep = fBufferSize; fBufferSize = 0;
00196 if (xmin < fXaxis.GetXmin()) RebinAxis(xmin,&fXaxis);
00197 if (xmax >= fXaxis.GetXmax()) RebinAxis(xmax,&fXaxis);
00198 if (ymin < fYaxis.GetXmin()) RebinAxis(ymin,&fYaxis);
00199 if (ymax >= fYaxis.GetXmax()) RebinAxis(ymax,&fYaxis);
00200 if (zmin < fZaxis.GetXmin()) RebinAxis(zmin,&fZaxis);
00201 if (zmax >= fZaxis.GetXmax()) RebinAxis(zmax,&fZaxis);
00202 fBuffer = buffer;
00203 fBufferSize = keep;
00204 }
00205 }
00206 fBuffer = 0;
00207
00208 for (Int_t i=0;i<nbentries;i++) {
00209 Fill(buffer[4*i+2],buffer[4*i+3],buffer[4*i+4],buffer[4*i+1]);
00210 }
00211 fBuffer = buffer;
00212
00213 if (action > 0) { delete [] fBuffer; fBuffer = 0; fBufferSize = 0;}
00214 else {
00215 if (nbentries == (Int_t)fEntries) fBuffer[0] = -nbentries;
00216 else fBuffer[0] = 0;
00217 }
00218 return nbentries;
00219 }
00220
00221
00222 Int_t TH3::BufferFill(Double_t x, Double_t y, Double_t z, Double_t w)
00223 {
00224
00225
00226
00227
00228
00229
00230
00231 if (!fBuffer) return -3;
00232 Int_t nbentries = (Int_t)fBuffer[0];
00233 if (nbentries < 0) {
00234 nbentries = -nbentries;
00235 fBuffer[0] = nbentries;
00236 if (fEntries > 0) {
00237 Double_t *buffer = fBuffer; fBuffer=0;
00238 Reset();
00239 fBuffer = buffer;
00240 }
00241 }
00242 if (4*nbentries+4 >= fBufferSize) {
00243 BufferEmpty(1);
00244 return Fill(x,y,z,w);
00245 }
00246 fBuffer[4*nbentries+1] = w;
00247 fBuffer[4*nbentries+2] = x;
00248 fBuffer[4*nbentries+3] = y;
00249 fBuffer[4*nbentries+4] = z;
00250 fBuffer[0] += 1;
00251 return -3;
00252 }
00253
00254
00255 Int_t TH3::Fill(Double_t x, Double_t y, Double_t z)
00256 {
00257
00258
00259
00260
00261
00262 if (fBuffer) return BufferFill(x,y,z,1);
00263
00264 Int_t binx, biny, binz, bin;
00265 fEntries++;
00266 binx = fXaxis.FindBin(x);
00267 biny = fYaxis.FindBin(y);
00268 binz = fZaxis.FindBin(z);
00269 if (binx <0 || biny <0 || binz<0) return -1;
00270 bin = binx + (fXaxis.GetNbins()+2)*(biny + (fYaxis.GetNbins()+2)*binz);
00271 AddBinContent(bin);
00272 if (fSumw2.fN) ++fSumw2.fArray[bin];
00273 if (binx == 0 || binx > fXaxis.GetNbins()) {
00274 if (!fgStatOverflows) return -1;
00275 }
00276
00277 if (biny == 0 || biny > fYaxis.GetNbins()) {
00278 if (!fgStatOverflows) return -1;
00279 }
00280 if (binz == 0 || binz > fZaxis.GetNbins()) {
00281 if (!fgStatOverflows) return -1;
00282 }
00283 ++fTsumw;
00284 ++fTsumw2;
00285 fTsumwx += x;
00286 fTsumwx2 += x*x;
00287 fTsumwy += y;
00288 fTsumwy2 += y*y;
00289 fTsumwxy += x*y;
00290 fTsumwz += z;
00291 fTsumwz2 += z*z;
00292 fTsumwxz += x*z;
00293 fTsumwyz += y*z;
00294 return bin;
00295 }
00296
00297
00298 Int_t TH3::Fill(Double_t x, Double_t y, Double_t z, Double_t w)
00299 {
00300
00301
00302
00303
00304
00305
00306
00307
00308
00309 if (fBuffer) return BufferFill(x,y,z,w);
00310
00311 Int_t binx, biny, binz, bin;
00312 fEntries++;
00313 binx = fXaxis.FindBin(x);
00314 biny = fYaxis.FindBin(y);
00315 binz = fZaxis.FindBin(z);
00316 if (binx <0 || biny <0 || binz<0) return -1;
00317 bin = binx + (fXaxis.GetNbins()+2)*(biny + (fYaxis.GetNbins()+2)*binz);
00318 AddBinContent(bin,w);
00319 if (fSumw2.fN) fSumw2.fArray[bin] += w*w;
00320 if (binx == 0 || binx > fXaxis.GetNbins()) {
00321 if (!fgStatOverflows) return -1;
00322 }
00323 if (biny == 0 || biny > fYaxis.GetNbins()) {
00324 if (!fgStatOverflows) return -1;
00325 }
00326 if (binz == 0 || binz > fZaxis.GetNbins()) {
00327 if (!fgStatOverflows) return -1;
00328 }
00329 fTsumw += w;
00330 fTsumw2 += w*w;
00331 fTsumwx += w*x;
00332 fTsumwx2 += w*x*x;
00333 fTsumwy += w*y;
00334 fTsumwy2 += w*y*y;
00335 fTsumwxy += w*x*y;
00336 fTsumwz += w*z;
00337 fTsumwz2 += w*z*z;
00338 fTsumwxz += w*x*z;
00339 fTsumwyz += w*y*z;
00340 return bin;
00341 }
00342
00343
00344 Int_t TH3::Fill(const char *namex, const char *namey, const char *namez, Double_t w)
00345 {
00346
00347
00348
00349
00350
00351
00352 Int_t binx, biny, binz, bin;
00353 fEntries++;
00354 binx = fXaxis.FindBin(namex);
00355 biny = fYaxis.FindBin(namey);
00356 binz = fZaxis.FindBin(namez);
00357 if (binx <0 || biny <0 || binz<0) return -1;
00358 bin = binx + (fXaxis.GetNbins()+2)*(biny + (fYaxis.GetNbins()+2)*binz);
00359 AddBinContent(bin,w);
00360 if (fSumw2.fN) fSumw2.fArray[bin] += w*w;
00361 if (binx == 0 || binx > fXaxis.GetNbins()) return -1;
00362 if (biny == 0 || biny > fYaxis.GetNbins()) return -1;
00363 if (binz == 0 || binz > fZaxis.GetNbins()) return -1;
00364 Double_t x = fXaxis.GetBinCenter(binx);
00365 Double_t y = fYaxis.GetBinCenter(biny);
00366 Double_t z = fZaxis.GetBinCenter(binz);
00367 Double_t v = (w > 0 ? w : -w);
00368 fTsumw += v;
00369 fTsumw2 += v*v;
00370 fTsumwx += v*x;
00371 fTsumwx2 += v*x*x;
00372 fTsumwy += v*y;
00373 fTsumwy2 += v*y*y;
00374 fTsumwxy += v*x*y;
00375 fTsumwz += v*z;
00376 fTsumwz2 += v*z*z;
00377 fTsumwxz += v*x*z;
00378 fTsumwyz += v*y*z;
00379 return bin;
00380 }
00381
00382
00383 Int_t TH3::Fill(const char *namex, Double_t y, const char *namez, Double_t w)
00384 {
00385
00386
00387
00388
00389
00390
00391 Int_t binx, biny, binz, bin;
00392 fEntries++;
00393 binx = fXaxis.FindBin(namex);
00394 biny = fYaxis.FindBin(y);
00395 binz = fZaxis.FindBin(namez);
00396 if (binx <0 || biny <0 || binz<0) return -1;
00397 bin = binx + (fXaxis.GetNbins()+2)*(biny + (fYaxis.GetNbins()+2)*binz);
00398 AddBinContent(bin,w);
00399 if (fSumw2.fN) fSumw2.fArray[bin] += w*w;
00400 if (binx == 0 || binx > fXaxis.GetNbins()) return -1;
00401 if (biny == 0 || biny > fYaxis.GetNbins()) {
00402 if (!fgStatOverflows) return -1;
00403 }
00404 if (binz == 0 || binz > fZaxis.GetNbins()) return -1;
00405 Double_t x = fXaxis.GetBinCenter(binx);
00406 Double_t z = fZaxis.GetBinCenter(binz);
00407 Double_t v = (w > 0 ? w : -w);
00408 fTsumw += v;
00409 fTsumw2 += v*v;
00410 fTsumwx += v*x;
00411 fTsumwx2 += v*x*x;
00412 fTsumwy += v*y;
00413 fTsumwy2 += v*y*y;
00414 fTsumwxy += v*x*y;
00415 fTsumwz += v*z;
00416 fTsumwz2 += v*z*z;
00417 fTsumwxz += v*x*z;
00418 fTsumwyz += v*y*z;
00419 return bin;
00420 }
00421
00422
00423 Int_t TH3::Fill(const char *namex, const char *namey, Double_t z, Double_t w)
00424 {
00425
00426
00427
00428
00429
00430
00431 Int_t binx, biny, binz, bin;
00432 fEntries++;
00433 binx = fXaxis.FindBin(namex);
00434 biny = fYaxis.FindBin(namey);
00435 binz = fZaxis.FindBin(z);
00436 if (binx <0 || biny <0 || binz<0) return -1;
00437 bin = binx + (fXaxis.GetNbins()+2)*(biny + (fYaxis.GetNbins()+2)*binz);
00438 AddBinContent(bin,w);
00439 if (fSumw2.fN) fSumw2.fArray[bin] += w*w;
00440 if (binx == 0 || binx > fXaxis.GetNbins()) return -1;
00441 if (biny == 0 || biny > fYaxis.GetNbins()) return -1;
00442 if (binz == 0 || binz > fZaxis.GetNbins()) {
00443 if (!fgStatOverflows) return -1;
00444 }
00445 Double_t x = fXaxis.GetBinCenter(binx);
00446 Double_t y = fYaxis.GetBinCenter(biny);
00447 Double_t v = (w > 0 ? w : -w);
00448 fTsumw += v;
00449 fTsumw2 += v*v;
00450 fTsumwx += v*x;
00451 fTsumwx2 += v*x*x;
00452 fTsumwy += v*y;
00453 fTsumwy2 += v*y*y;
00454 fTsumwxy += v*x*y;
00455 fTsumwz += v*z;
00456 fTsumwz2 += v*z*z;
00457 fTsumwxz += v*x*z;
00458 fTsumwyz += v*y*z;
00459 return bin;
00460 }
00461
00462
00463 Int_t TH3::Fill(Double_t x, const char *namey, const char *namez, Double_t w)
00464 {
00465
00466
00467
00468
00469
00470
00471 Int_t binx, biny, binz, bin;
00472 fEntries++;
00473 binx = fXaxis.FindBin(x);
00474 biny = fYaxis.FindBin(namey);
00475 binz = fZaxis.FindBin(namez);
00476 if (binx <0 || biny <0 || binz<0) return -1;
00477 bin = binx + (fXaxis.GetNbins()+2)*(biny + (fYaxis.GetNbins()+2)*binz);
00478 AddBinContent(bin,w);
00479 if (fSumw2.fN) fSumw2.fArray[bin] += w*w;
00480 if (binx == 0 || binx > fXaxis.GetNbins()) {
00481 if (!fgStatOverflows) return -1;
00482 }
00483 if (biny == 0 || biny > fYaxis.GetNbins()) return -1;
00484 if (binz == 0 || binz > fZaxis.GetNbins()) return -1;
00485 Double_t y = fYaxis.GetBinCenter(biny);
00486 Double_t z = fZaxis.GetBinCenter(binz);
00487 Double_t v = (w > 0 ? w : -w);
00488 fTsumw += v;
00489 fTsumw2 += v*v;
00490 fTsumwx += v*x;
00491 fTsumwx2 += v*x*x;
00492 fTsumwy += v*y;
00493 fTsumwy2 += v*y*y;
00494 fTsumwxy += v*x*y;
00495 fTsumwz += v*z;
00496 fTsumwz2 += v*z*z;
00497 fTsumwxz += v*x*z;
00498 fTsumwyz += v*y*z;
00499 return bin;
00500 }
00501
00502
00503 Int_t TH3::Fill(Double_t x, const char *namey, Double_t z, Double_t w)
00504 {
00505
00506
00507
00508
00509
00510
00511 Int_t binx, biny, binz, bin;
00512 fEntries++;
00513 binx = fXaxis.FindBin(x);
00514 biny = fYaxis.FindBin(namey);
00515 binz = fZaxis.FindBin(z);
00516 if (binx <0 || biny <0 || binz<0) return -1;
00517 bin = binx + (fXaxis.GetNbins()+2)*(biny + (fYaxis.GetNbins()+2)*binz);
00518 AddBinContent(bin,w);
00519 if (fSumw2.fN) fSumw2.fArray[bin] += w*w;
00520 if (binx == 0 || binx > fXaxis.GetNbins()) {
00521 if (!fgStatOverflows) return -1;
00522 }
00523 if (biny == 0 || biny > fYaxis.GetNbins()) return -1;
00524 if (binz == 0 || binz > fZaxis.GetNbins()) {
00525 if (!fgStatOverflows) return -1;
00526 }
00527 Double_t y = fYaxis.GetBinCenter(biny);
00528 Double_t v = (w > 0 ? w : -w);
00529 fTsumw += v;
00530 fTsumw2 += v*v;
00531 fTsumwx += v*x;
00532 fTsumwx2 += v*x*x;
00533 fTsumwy += v*y;
00534 fTsumwy2 += v*y*y;
00535 fTsumwxy += v*x*y;
00536 fTsumwz += v*z;
00537 fTsumwz2 += v*z*z;
00538 fTsumwxz += v*x*z;
00539 fTsumwyz += v*y*z;
00540 return bin;
00541 }
00542
00543
00544 Int_t TH3::Fill(Double_t x, Double_t y, const char *namez, Double_t w)
00545 {
00546
00547
00548
00549
00550
00551
00552 Int_t binx, biny, binz, bin;
00553 fEntries++;
00554 binx = fXaxis.FindBin(x);
00555 biny = fYaxis.FindBin(y);
00556 binz = fZaxis.FindBin(namez);
00557 if (binx <0 || biny <0 || binz<0) return -1;
00558 bin = binx + (fXaxis.GetNbins()+2)*(biny + (fYaxis.GetNbins()+2)*binz);
00559 AddBinContent(bin,w);
00560 if (fSumw2.fN) fSumw2.fArray[bin] += w*w;
00561 if (binx == 0 || binx > fXaxis.GetNbins()) {
00562 if (!fgStatOverflows) return -1;
00563 }
00564 if (biny == 0 || biny > fYaxis.GetNbins()) {
00565 if (!fgStatOverflows) return -1;
00566 }
00567 if (binz == 0 || binz > fZaxis.GetNbins()) return -1;
00568 Double_t z = fZaxis.GetBinCenter(binz);
00569 Double_t v = (w > 0 ? w : -w);
00570 fTsumw += v;
00571 fTsumw2 += v*v;
00572 fTsumwx += v*x;
00573 fTsumwx2 += v*x*x;
00574 fTsumwy += v*y;
00575 fTsumwy2 += v*y*y;
00576 fTsumwxy += v*x*y;
00577 fTsumwz += v*z;
00578 fTsumwz2 += v*z*z;
00579 fTsumwxz += v*x*z;
00580 fTsumwyz += v*y*z;
00581 return bin;
00582 }
00583
00584
00585 void TH3::FillRandom(const char *fname, Int_t ntimes)
00586 {
00587
00588
00589
00590
00591
00592
00593
00594
00595
00596
00597
00598
00599
00600
00601
00602
00603 Int_t bin, binx, biny, binz, ibin, loop;
00604 Double_t r1, x, y,z, xv[3];
00605
00606 TF1 *f1 = (TF1*)gROOT->GetFunction(fname);
00607 if (!f1) { Error("FillRandom", "Unknown function: %s",fname); return; }
00608
00609
00610 Int_t nbinsx = GetNbinsX();
00611 Int_t nbinsy = GetNbinsY();
00612 Int_t nbinsz = GetNbinsZ();
00613 Int_t nxy = nbinsx*nbinsy;
00614 Int_t nbins = nxy*nbinsz;
00615
00616 Double_t *integral = new Double_t[nbins+1];
00617 ibin = 0;
00618 integral[ibin] = 0;
00619 for (binz=1;binz<=nbinsz;binz++) {
00620 xv[2] = fZaxis.GetBinCenter(binz);
00621 for (biny=1;biny<=nbinsy;biny++) {
00622 xv[1] = fYaxis.GetBinCenter(biny);
00623 for (binx=1;binx<=nbinsx;binx++) {
00624 xv[0] = fXaxis.GetBinCenter(binx);
00625 ibin++;
00626 integral[ibin] = integral[ibin-1] + f1->Eval(xv[0],xv[1],xv[2]);
00627 }
00628 }
00629 }
00630
00631
00632 if (integral[nbins] == 0 ) {
00633 delete [] integral;
00634 Error("FillRandom", "Integral = zero"); return;
00635 }
00636 for (bin=1;bin<=nbins;bin++) integral[bin] /= integral[nbins];
00637
00638
00639 if (fDimension < 2) nbinsy = -1;
00640 if (fDimension < 3) nbinsz = -1;
00641 for (loop=0;loop<ntimes;loop++) {
00642 r1 = gRandom->Rndm(loop);
00643 ibin = TMath::BinarySearch(nbins,&integral[0],r1);
00644 binz = ibin/nxy;
00645 biny = (ibin - nxy*binz)/nbinsx;
00646 binx = 1 + ibin - nbinsx*(biny + nbinsy*binz);
00647 if (nbinsz) binz++;
00648 if (nbinsy) biny++;
00649 x = fXaxis.GetBinCenter(binx);
00650 y = fYaxis.GetBinCenter(biny);
00651 z = fZaxis.GetBinCenter(binz);
00652 Fill(x,y,z, 1.);
00653 }
00654 delete [] integral;
00655 }
00656
00657
00658 void TH3::FillRandom(TH1 *h, Int_t ntimes)
00659 {
00660
00661
00662
00663
00664
00665
00666
00667
00668
00669
00670
00671
00672
00673
00674 if (!h) { Error("FillRandom", "Null histogram"); return; }
00675 if (fDimension != h->GetDimension()) {
00676 Error("FillRandom", "Histograms with different dimensions"); return;
00677 }
00678
00679 if (h->ComputeIntegral() == 0) return;
00680
00681 TH3 *h3 = (TH3*)h;
00682 Int_t loop;
00683 Double_t x,y,z;
00684 for (loop=0;loop<ntimes;loop++) {
00685 h3->GetRandom3(x,y,z);
00686 Fill(x,y,z,1.);
00687 }
00688 }
00689
00690
00691
00692 Int_t TH3::FindFirstBinAbove(Double_t threshold, Int_t axis) const
00693 {
00694
00695
00696
00697 if (axis < 1 || axis > 3) {
00698 Warning("FindFirstBinAbove","Invalid axis number : %d, axis x assumed\n",axis);
00699 axis = 1;
00700 }
00701 Int_t nbinsx = fXaxis.GetNbins();
00702 Int_t nbinsy = fYaxis.GetNbins();
00703 Int_t nbinsz = fZaxis.GetNbins();
00704 Int_t binx, biny, binz;
00705 if (axis == 1) {
00706 for (binx=1;binx<=nbinsx;binx++) {
00707 for (biny=1;biny<=nbinsy;biny++) {
00708 for (binz=1;binz<=nbinsz;binz++) {
00709 if (GetBinContent(binx,biny,binz) > threshold) return binx;
00710 }
00711 }
00712 }
00713 } else if (axis == 2) {
00714 for (biny=1;biny<=nbinsy;biny++) {
00715 for (binx=1;binx<=nbinsx;binx++) {
00716 for (binz=1;binz<=nbinsz;binz++) {
00717 if (GetBinContent(binx,biny,binz) > threshold) return biny;
00718 }
00719 }
00720 }
00721 } else {
00722 for (binz=1;binz<=nbinsz;binz++) {
00723 for (binx=1;binx<=nbinsx;binx++) {
00724 for (biny=1;biny<=nbinsy;biny++) {
00725 if (GetBinContent(binx,biny,binz) > threshold) return binz;
00726 }
00727 }
00728 }
00729 }
00730 return -1;
00731 }
00732
00733
00734
00735 Int_t TH3::FindLastBinAbove(Double_t threshold, Int_t axis) const
00736 {
00737
00738
00739
00740 if (axis < 1 || axis > 3) {
00741 Warning("FindLastBinAbove","Invalid axis number : %d, axis x assumed\n",axis);
00742 axis = 1;
00743 }
00744 Int_t nbinsx = fXaxis.GetNbins();
00745 Int_t nbinsy = fYaxis.GetNbins();
00746 Int_t nbinsz = fZaxis.GetNbins();
00747 Int_t binx, biny, binz;
00748 if (axis == 1) {
00749 for (binx=nbinsx;binx>=1;binx--) {
00750 for (biny=1;biny<=nbinsy;biny++) {
00751 for (binz=1;binz<=nbinsz;binz++) {
00752 if (GetBinContent(binx,biny,binz) > threshold) return binx;
00753 }
00754 }
00755 }
00756 } else if (axis == 2) {
00757 for (biny=nbinsy;biny>=1;biny--) {
00758 for (binx=1;binx<=nbinsx;binx++) {
00759 for (binz=1;binz<=nbinsz;binz++) {
00760 if (GetBinContent(binx,biny,binz) > threshold) return biny;
00761 }
00762 }
00763 }
00764 } else {
00765 for (binz=nbinsz;binz>=1;binz--) {
00766 for (binx=1;binx<=nbinsx;binx++) {
00767 for (biny=1;biny<=nbinsy;biny++) {
00768 if (GetBinContent(binx,biny,binz) > threshold) return binz;
00769 }
00770 }
00771 }
00772 }
00773 return -1;
00774 }
00775
00776
00777
00778 void TH3::FitSlicesZ(TF1 *f1, Int_t binminx, Int_t binmaxx, Int_t binminy, Int_t binmaxy, Int_t cut, Option_t *option)
00779 {
00780
00781
00782
00783
00784
00785
00786
00787
00788
00789
00790
00791
00792
00793
00794
00795
00796
00797
00798
00799
00800
00801
00802
00803
00804
00805
00806
00807
00808
00809
00810
00811 Int_t nbinsx = fXaxis.GetNbins();
00812 Int_t nbinsy = fYaxis.GetNbins();
00813 Int_t nbinsz = fZaxis.GetNbins();
00814 if (binminx < 1) binminx = 1;
00815 if (binmaxx > nbinsx) binmaxx = nbinsx;
00816 if (binmaxx < binminx) {binminx = 1; binmaxx = nbinsx;}
00817 if (binminy < 1) binminy = 1;
00818 if (binmaxy > nbinsy) binmaxy = nbinsy;
00819 if (binmaxy < binminy) {binminy = 1; binmaxy = nbinsy;}
00820
00821
00822 if (f1 == 0) {
00823 f1 = (TF1*)gROOT->GetFunction("gaus");
00824 if (f1 == 0) f1 = new TF1("gaus","gaus",fZaxis.GetXmin(),fZaxis.GetXmax());
00825 else f1->SetRange(fZaxis.GetXmin(),fZaxis.GetXmax());
00826 }
00827 const char *fname = f1->GetName();
00828 Int_t npar = f1->GetNpar();
00829 Double_t *parsave = new Double_t[npar];
00830 f1->GetParameters(parsave);
00831
00832
00833 Int_t ipar;
00834 char name[80], title[80];
00835 TH2D *hlist[25];
00836 const TArrayD *xbins = fXaxis.GetXbins();
00837 const TArrayD *ybins = fYaxis.GetXbins();
00838 for (ipar=0;ipar<npar;ipar++) {
00839 snprintf(name,80,"%s_%d",GetName(),ipar);
00840 snprintf(title,80,"Fitted value of par[%d]=%s",ipar,f1->GetParName(ipar));
00841 if (xbins->fN == 0) {
00842 hlist[ipar] = new TH2D(name, title,
00843 nbinsx, fXaxis.GetXmin(), fXaxis.GetXmax(),
00844 nbinsy, fYaxis.GetXmin(), fYaxis.GetXmax());
00845 } else {
00846 hlist[ipar] = new TH2D(name, title,
00847 nbinsx, xbins->fArray,
00848 nbinsy, ybins->fArray);
00849 }
00850 hlist[ipar]->GetXaxis()->SetTitle(fXaxis.GetTitle());
00851 hlist[ipar]->GetYaxis()->SetTitle(fYaxis.GetTitle());
00852 }
00853 snprintf(name,80,"%s_chi2",GetName());
00854 TH2D *hchi2 = new TH2D(name,"chisquare", nbinsx, fXaxis.GetXmin(), fXaxis.GetXmax()
00855 , nbinsy, fYaxis.GetXmin(), fYaxis.GetXmax());
00856
00857
00858 TH1D *hpz = new TH1D("R_temp","_temp",nbinsz, fZaxis.GetXmin(), fZaxis.GetXmax());
00859 Int_t bin,binx,biny,binz;
00860 for (biny=binminy;biny<=binmaxy;biny++) {
00861 Float_t y = fYaxis.GetBinCenter(biny);
00862 for (binx=binminx;binx<=binmaxx;binx++) {
00863 Float_t x = fXaxis.GetBinCenter(binx);
00864 hpz->Reset();
00865 Int_t nfill = 0;
00866 for (binz=1;binz<=nbinsz;binz++) {
00867 bin = GetBin(binx,biny,binz);
00868 Float_t w = GetBinContent(bin);
00869 if (w == 0) continue;
00870 hpz->Fill(fZaxis.GetBinCenter(binz),w);
00871 hpz->SetBinError(binz,GetBinError(bin));
00872 nfill++;
00873 }
00874 if (nfill < cut) continue;
00875 f1->SetParameters(parsave);
00876 hpz->Fit(fname,option);
00877 Int_t npfits = f1->GetNumberFitPoints();
00878 if (npfits > npar && npfits >= cut) {
00879 for (ipar=0;ipar<npar;ipar++) {
00880 hlist[ipar]->Fill(x,y,f1->GetParameter(ipar));
00881 hlist[ipar]->SetCellError(binx,biny,f1->GetParError(ipar));
00882 }
00883 hchi2->Fill(x,y,f1->GetChisquare()/(npfits-npar));
00884 }
00885 }
00886 }
00887 delete [] parsave;
00888 delete hpz;
00889 }
00890
00891
00892 Double_t TH3::GetBinWithContent3(Double_t c, Int_t &binx, Int_t &biny, Int_t &binz, Int_t firstx, Int_t lastx, Int_t firsty, Int_t lasty, Int_t firstz, Int_t lastz, Double_t maxdiff) const
00893 {
00894
00895
00896
00897
00898
00899
00900
00901
00902
00903
00904
00905
00906
00907
00908
00909
00910
00911
00912
00913 if (fDimension != 3) {
00914 binx = 0;
00915 biny = 0;
00916 binz = 0;
00917 Error("GetBinWithContent3","function is only valid for 3-D histograms");
00918 return 0;
00919 }
00920 if (firstx <= 0) firstx = 1;
00921 if (lastx < firstx) lastx = fXaxis.GetNbins();
00922 if (firsty <= 0) firsty = 1;
00923 if (lasty < firsty) lasty = fYaxis.GetNbins();
00924 if (firstz <= 0) firstz = 1;
00925 if (lastz < firstz) lastz = fZaxis.GetNbins();
00926 Int_t binminx = 0, binminy=0, binminz=0;
00927 Double_t diff, curmax = 1.e240;
00928 for (Int_t k=firstz;k<=lastz;k++) {
00929 for (Int_t j=firsty;j<=lasty;j++) {
00930 for (Int_t i=firstx;i<=lastx;i++) {
00931 diff = TMath::Abs(GetBinContent(i,j,k)-c);
00932 if (diff <= 0) {binx = i; biny=j; binz=k; return diff;}
00933 if (diff < curmax && diff <= maxdiff) {curmax = diff, binminx=i; binminy=j;binminz=k;}
00934 }
00935 }
00936 }
00937 binx = binminx;
00938 biny = binminy;
00939 binz = binminz;
00940 return curmax;
00941 }
00942
00943
00944 Double_t TH3::GetCorrelationFactor(Int_t axis1, Int_t axis2) const
00945 {
00946
00947
00948 if (axis1 < 1 || axis2 < 1 || axis1 > 3 || axis2 > 3) {
00949 Error("GetCorrelationFactor","Wrong parameters");
00950 return 0;
00951 }
00952 if (axis1 == axis2) return 1;
00953 Double_t rms1 = GetRMS(axis1);
00954 if (rms1 == 0) return 0;
00955 Double_t rms2 = GetRMS(axis2);
00956 if (rms2 == 0) return 0;
00957 return GetCovariance(axis1,axis2)/rms1/rms2;
00958 }
00959
00960
00961 Double_t TH3::GetCovariance(Int_t axis1, Int_t axis2) const
00962 {
00963
00964
00965
00966 if (axis1 < 1 || axis2 < 1 || axis1 > 3 || axis2 > 3) {
00967 Error("GetCovariance","Wrong parameters");
00968 return 0;
00969 }
00970 Double_t stats[kNstat];
00971 GetStats(stats);
00972 Double_t sumw = stats[0];
00973 Double_t sumw2 = stats[1];
00974 Double_t sumwx = stats[2];
00975 Double_t sumwx2 = stats[3];
00976 Double_t sumwy = stats[4];
00977 Double_t sumwy2 = stats[5];
00978 Double_t sumwxy = stats[6];
00979 Double_t sumwz = stats[7];
00980 Double_t sumwz2 = stats[8];
00981 Double_t sumwxz = stats[9];
00982 Double_t sumwyz = stats[10];
00983
00984 if (sumw == 0) return 0;
00985 if (axis1 == 1 && axis2 == 1) {
00986 return TMath::Abs(sumwx2/sumw - sumwx*sumwx/sumw2);
00987 }
00988 if (axis1 == 2 && axis2 == 2) {
00989 return TMath::Abs(sumwy2/sumw - sumwy*sumwy/sumw2);
00990 }
00991 if (axis1 == 3 && axis2 == 3) {
00992 return TMath::Abs(sumwz2/sumw - sumwz*sumwz/sumw2);
00993 }
00994 if ((axis1 == 1 && axis2 == 2) || (axis1 == 2 && axis1 == 1)) {
00995 return sumwxy/sumw - sumwx/sumw*sumwy/sumw;
00996 }
00997 if ((axis1 == 1 && axis2 == 3) || (axis1 == 3 && axis2 == 1)) {
00998 return sumwxz/sumw - sumwx/sumw*sumwz/sumw;
00999 }
01000 if ((axis1 == 2 && axis2 == 3) || (axis1 == 3 && axis2 == 2)) {
01001 return sumwyz/sumw - sumwy/sumw*sumwz/sumw;
01002 }
01003 return 0;
01004 }
01005
01006
01007
01008 void TH3::GetRandom3(Double_t &x, Double_t &y, Double_t &z)
01009 {
01010
01011
01012
01013 Int_t nbinsx = GetNbinsX();
01014 Int_t nbinsy = GetNbinsY();
01015 Int_t nbinsz = GetNbinsZ();
01016 Int_t nxy = nbinsx*nbinsy;
01017 Int_t nbins = nxy*nbinsz;
01018 Double_t integral;
01019 if (fIntegral) {
01020 if (fIntegral[nbins+1] != fEntries) integral = ComputeIntegral();
01021 } else {
01022 integral = ComputeIntegral();
01023 if (integral == 0 || fIntegral == 0) return;
01024 }
01025 Double_t r1 = gRandom->Rndm();
01026 Int_t ibin = TMath::BinarySearch(nbins,fIntegral,(Double_t) r1);
01027 Int_t binz = ibin/nxy;
01028 Int_t biny = (ibin - nxy*binz)/nbinsx;
01029 Int_t binx = ibin - nbinsx*(biny + nbinsy*binz);
01030 x = fXaxis.GetBinLowEdge(binx+1);
01031 if (r1 > fIntegral[ibin]) x +=
01032 fXaxis.GetBinWidth(binx+1)*(r1-fIntegral[ibin])/(fIntegral[ibin+1] - fIntegral[ibin]);
01033 y = fYaxis.GetBinLowEdge(biny+1) + fYaxis.GetBinWidth(biny+1)*gRandom->Rndm();
01034 z = fZaxis.GetBinLowEdge(binz+1) + fZaxis.GetBinWidth(binz+1)*gRandom->Rndm();
01035 }
01036
01037
01038 void TH3::GetStats(Double_t *stats) const
01039 {
01040
01041
01042
01043
01044
01045
01046
01047
01048
01049
01050
01051
01052
01053
01054 if (fBuffer) ((TH3*)this)->BufferEmpty();
01055
01056 Int_t bin, binx, biny, binz;
01057 Double_t w,err;
01058 Double_t x,y,z;
01059 if ((fTsumw == 0 && fEntries > 0) || fXaxis.TestBit(TAxis::kAxisRange) || fYaxis.TestBit(TAxis::kAxisRange) || fZaxis.TestBit(TAxis::kAxisRange)) {
01060 for (bin=0;bin<9;bin++) stats[bin] = 0;
01061
01062 Int_t firstBinX = fXaxis.GetFirst();
01063 Int_t lastBinX = fXaxis.GetLast();
01064 Int_t firstBinY = fYaxis.GetFirst();
01065 Int_t lastBinY = fYaxis.GetLast();
01066 Int_t firstBinZ = fZaxis.GetFirst();
01067 Int_t lastBinZ = fZaxis.GetLast();
01068
01069 if (fgStatOverflows) {
01070 if ( !fXaxis.TestBit(TAxis::kAxisRange) ) {
01071 if (firstBinX == 1) firstBinX = 0;
01072 if (lastBinX == fXaxis.GetNbins() ) lastBinX += 1;
01073 }
01074 if ( !fYaxis.TestBit(TAxis::kAxisRange) ) {
01075 if (firstBinY == 1) firstBinY = 0;
01076 if (lastBinY == fYaxis.GetNbins() ) lastBinY += 1;
01077 }
01078 if ( !fZaxis.TestBit(TAxis::kAxisRange) ) {
01079 if (firstBinZ == 1) firstBinZ = 0;
01080 if (lastBinZ == fZaxis.GetNbins() ) lastBinZ += 1;
01081 }
01082 }
01083 for (binz = firstBinZ; binz <= lastBinZ; binz++) {
01084 z = fZaxis.GetBinCenter(binz);
01085 for (biny = firstBinY; biny <= lastBinY; biny++) {
01086 y = fYaxis.GetBinCenter(biny);
01087 for (binx = firstBinX; binx <= lastBinX; binx++) {
01088 bin = GetBin(binx,biny,binz);
01089 x = fXaxis.GetBinCenter(binx);
01090 w = TMath::Abs(GetBinContent(bin));
01091 err = TMath::Abs(GetBinError(bin));
01092 stats[0] += w;
01093 stats[1] += err*err;
01094 stats[2] += w*x;
01095 stats[3] += w*x*x;
01096 stats[4] += w*y;
01097 stats[5] += w*y*y;
01098 stats[6] += w*x*y;
01099 stats[7] += w*z;
01100 stats[8] += w*z*z;
01101 stats[9] += w*x*z;
01102 stats[10]+= w*y*z;
01103 }
01104 }
01105 }
01106 } else {
01107 stats[0] = fTsumw;
01108 stats[1] = fTsumw2;
01109 stats[2] = fTsumwx;
01110 stats[3] = fTsumwx2;
01111 stats[4] = fTsumwy;
01112 stats[5] = fTsumwy2;
01113 stats[6] = fTsumwxy;
01114 stats[7] = fTsumwz;
01115 stats[8] = fTsumwz2;
01116 stats[9] = fTsumwxz;
01117 stats[10]= fTsumwyz;
01118 }
01119 }
01120
01121
01122 Double_t TH3::Integral(Option_t *option) const
01123 {
01124
01125
01126
01127
01128
01129 return Integral(fXaxis.GetFirst(),fXaxis.GetLast(),
01130 fYaxis.GetFirst(),fYaxis.GetLast(),
01131 fZaxis.GetFirst(),fZaxis.GetLast(),option);
01132 }
01133
01134
01135 Double_t TH3::Integral(Int_t binx1, Int_t binx2, Int_t biny1, Int_t biny2, Int_t binz1, Int_t binz2, Option_t *option) const
01136 {
01137
01138
01139
01140
01141
01142
01143 Double_t err = 0;
01144 return DoIntegral(binx1,binx2,biny1,biny2,binz1,binz2,err,option);
01145 }
01146
01147 Double_t TH3::IntegralAndError(Int_t binx1, Int_t binx2, Int_t biny1, Int_t biny2, Int_t binz1, Int_t binz2, Double_t & error, Option_t *option) const
01148 {
01149
01150
01151
01152
01153
01154
01155 return DoIntegral(binx1,binx2,biny1,biny2,binz1,binz2,error,option,kTRUE);
01156 }
01157
01158
01159 Double_t TH3::Interpolate(Double_t)
01160 {
01161
01162
01163 Error("Interpolate","This function must be called with 3 arguments for a TH3");
01164 return 0;
01165 }
01166
01167
01168 Double_t TH3::Interpolate(Double_t, Double_t)
01169 {
01170
01171
01172 Error("Interpolate","This function must be called with 3 arguments for a TH3");
01173 return 0;
01174 }
01175
01176
01177 Double_t TH3::Interpolate(Double_t x, Double_t y, Double_t z)
01178 {
01179
01180
01181
01182
01183
01184
01185
01186
01187
01188 Int_t ubx = fXaxis.FindBin(x);
01189 if ( x < fXaxis.GetBinCenter(ubx) ) ubx -= 1;
01190 Int_t obx = ubx + 1;
01191
01192 Int_t uby = fYaxis.FindBin(y);
01193 if ( y < fYaxis.GetBinCenter(uby) ) uby -= 1;
01194 Int_t oby = uby + 1;
01195
01196 Int_t ubz = fZaxis.FindBin(z);
01197 if ( z < fZaxis.GetBinCenter(ubz) ) ubz -= 1;
01198 Int_t obz = ubz + 1;
01199
01200
01201
01202
01203 if (ubx <=0 || uby <=0 || ubz <= 0 ||
01204 obx > fXaxis.GetNbins() || oby > fYaxis.GetNbins() || obz > fZaxis.GetNbins() ) {
01205 Error("Interpolate","Cannot interpolate outside histogram domain.");
01206 return 0;
01207 }
01208
01209 Double_t xw = fXaxis.GetBinCenter(obx) - fXaxis.GetBinCenter(ubx);
01210 Double_t yw = fYaxis.GetBinCenter(oby) - fYaxis.GetBinCenter(uby);
01211 Double_t zw = fZaxis.GetBinCenter(obz) - fZaxis.GetBinCenter(ubz);
01212
01213 Double_t xd = (x - fXaxis.GetBinCenter(ubx)) / xw;
01214 Double_t yd = (y - fYaxis.GetBinCenter(uby)) / yw;
01215 Double_t zd = (z - fZaxis.GetBinCenter(ubz)) / zw;
01216
01217
01218 Double_t v[] = { GetBinContent( ubx, uby, ubz ), GetBinContent( ubx, uby, obz ),
01219 GetBinContent( ubx, oby, ubz ), GetBinContent( ubx, oby, obz ),
01220 GetBinContent( obx, uby, ubz ), GetBinContent( obx, uby, obz ),
01221 GetBinContent( obx, oby, ubz ), GetBinContent( obx, oby, obz ) };
01222
01223
01224 Double_t i1 = v[0] * (1 - zd) + v[1] * zd;
01225 Double_t i2 = v[2] * (1 - zd) + v[3] * zd;
01226 Double_t j1 = v[4] * (1 - zd) + v[5] * zd;
01227 Double_t j2 = v[6] * (1 - zd) + v[7] * zd;
01228
01229
01230 Double_t w1 = i1 * (1 - yd) + i2 * yd;
01231 Double_t w2 = j1 * (1 - yd) + j2 * yd;
01232
01233
01234 Double_t result = w1 * (1 - xd) + w2 * xd;
01235
01236 return result;
01237 }
01238
01239
01240 Double_t TH3::KolmogorovTest(const TH1 *h2, Option_t *option) const
01241 {
01242
01243
01244
01245
01246
01247
01248
01249
01250
01251
01252
01253
01254
01255
01256
01257
01258
01259
01260
01261 TString opt = option;
01262 opt.ToUpper();
01263
01264 Double_t prb = 0;
01265 TH1 *h1 = (TH1*)this;
01266 if (h2 == 0) return 0;
01267 TAxis *xaxis1 = h1->GetXaxis();
01268 TAxis *xaxis2 = h2->GetXaxis();
01269 TAxis *yaxis1 = h1->GetYaxis();
01270 TAxis *yaxis2 = h2->GetYaxis();
01271 TAxis *zaxis1 = h1->GetZaxis();
01272 TAxis *zaxis2 = h2->GetZaxis();
01273 Int_t ncx1 = xaxis1->GetNbins();
01274 Int_t ncx2 = xaxis2->GetNbins();
01275 Int_t ncy1 = yaxis1->GetNbins();
01276 Int_t ncy2 = yaxis2->GetNbins();
01277 Int_t ncz1 = zaxis1->GetNbins();
01278 Int_t ncz2 = zaxis2->GetNbins();
01279
01280
01281 if (h1->GetDimension() != 3 || h2->GetDimension() != 3) {
01282 Error("KolmogorovTest","Histograms must be 3-D\n");
01283 return 0;
01284 }
01285
01286
01287 if (ncx1 != ncx2) {
01288 Error("KolmogorovTest","Number of channels in X is different, %d and %d\n",ncx1,ncx2);
01289 return 0;
01290 }
01291 if (ncy1 != ncy2) {
01292 Error("KolmogorovTest","Number of channels in Y is different, %d and %d\n",ncy1,ncy2);
01293 return 0;
01294 }
01295 if (ncz1 != ncz2) {
01296 Error("KolmogorovTest","Number of channels in Z is different, %d and %d\n",ncz1,ncz2);
01297 return 0;
01298 }
01299
01300
01301 Bool_t afunc1 = kFALSE;
01302 Bool_t afunc2 = kFALSE;
01303 Double_t difprec = 1e-5;
01304 Double_t diff1 = TMath::Abs(xaxis1->GetXmin() - xaxis2->GetXmin());
01305 Double_t diff2 = TMath::Abs(xaxis1->GetXmax() - xaxis2->GetXmax());
01306 if (diff1 > difprec || diff2 > difprec) {
01307 Error("KolmogorovTest","histograms with different binning along X");
01308 return 0;
01309 }
01310 diff1 = TMath::Abs(yaxis1->GetXmin() - yaxis2->GetXmin());
01311 diff2 = TMath::Abs(yaxis1->GetXmax() - yaxis2->GetXmax());
01312 if (diff1 > difprec || diff2 > difprec) {
01313 Error("KolmogorovTest","histograms with different binning along Y");
01314 return 0;
01315 }
01316 diff1 = TMath::Abs(zaxis1->GetXmin() - zaxis2->GetXmin());
01317 diff2 = TMath::Abs(zaxis1->GetXmax() - zaxis2->GetXmax());
01318 if (diff1 > difprec || diff2 > difprec) {
01319 Error("KolmogorovTest","histograms with different binning along Z");
01320 return 0;
01321 }
01322
01323
01324 Int_t ibeg = 1, jbeg = 1, kbeg = 1;
01325 Int_t iend = ncx1, jend = ncy1, kend = ncz1;
01326 if (opt.Contains("U")) {ibeg = 0; jbeg = 0; kbeg = 0;}
01327 if (opt.Contains("O")) {iend = ncx1+1; jend = ncy1+1; kend = ncz1+1;}
01328
01329 Int_t i,j,k,bin;
01330 Double_t sum1 = 0;
01331 Double_t sum2 = 0;
01332 Double_t w1 = 0;
01333 Double_t w2 = 0;
01334 for (i = ibeg; i <= iend; i++) {
01335 for (j = jbeg; j <= jend; j++) {
01336 for (k = kbeg; k <= kend; k++) {
01337 bin = h1->GetBin(i,j,k);
01338 sum1 += h1->GetBinContent(bin);
01339 sum2 += h2->GetBinContent(bin);
01340 Double_t ew1 = h1->GetBinError(bin);
01341 Double_t ew2 = h2->GetBinError(bin);
01342 w1 += ew1*ew1;
01343 w2 += ew2*ew2;
01344 }
01345 }
01346 }
01347
01348
01349
01350 if (sum1 == 0) {
01351 Error("KolmogorovTest","Integral is zero for h1=%s\n",h1->GetName());
01352 return 0;
01353 }
01354 if (sum2 == 0) {
01355 Error("KolmogorovTest","Integral is zero for h2=%s\n",h2->GetName());
01356 return 0;
01357 }
01358
01359
01360
01361 Double_t esum1 = 0, esum2 = 0;
01362 if (w1 > 0)
01363 esum1 = sum1 * sum1 / w1;
01364 else
01365 afunc1 = kTRUE;
01366
01367 if (w2 > 0)
01368 esum2 = sum2 * sum2 / w2;
01369 else
01370 afunc2 = kTRUE;
01371
01372 if (afunc2 && afunc1) {
01373 Error("KolmogorovTest","Errors are zero for both histograms\n");
01374 return 0;
01375 }
01376
01377
01378
01379 int order[3] = {0,1,2};
01380 int binbeg[3];
01381 int binend[3];
01382 int ibin[3];
01383 binbeg[0] = ibeg; binbeg[1] = jbeg; binbeg[2] = kbeg;
01384 binend[0] = iend; binend[1] = jend; binend[2] = kend;
01385 Double_t vdfmax[6];
01386 int icomb = 0;
01387 Double_t s1 = 1./(6.*sum1);
01388 Double_t s2 = 1./(6.*sum2);
01389 Double_t rsum1=0, rsum2=0;
01390 do {
01391
01392 Double_t dmax = 0;
01393 for (i = binbeg[order[0] ]; i <= binend[order[0] ]; i++) {
01394 for ( j = binbeg[order[1] ]; j <= binend[order[1] ]; j++) {
01395 for ( k = binbeg[order[2] ]; k <= binend[order[2] ]; k++) {
01396 ibin[ order[0] ] = i;
01397 ibin[ order[1] ] = j;
01398 ibin[ order[2] ] = k;
01399 bin = h1->GetBin(ibin[0],ibin[1],ibin[2]);
01400 rsum1 += s1*h1->GetBinContent(bin);
01401 rsum2 += s2*h2->GetBinContent(bin);
01402 dmax = TMath::Max(dmax, TMath::Abs(rsum1-rsum2));
01403 }
01404 }
01405 }
01406 vdfmax[icomb] = dmax;
01407 icomb++;
01408 } while (TMath::Permute(3,order) );
01409
01410
01411
01412 Double_t dfmax = TMath::Mean(6,vdfmax);
01413
01414
01415 Double_t factnm;
01416 if (afunc1) factnm = TMath::Sqrt(sum2);
01417 else if (afunc2) factnm = TMath::Sqrt(sum1);
01418 else factnm = TMath::Sqrt(sum1*sum2/(sum1+sum2));
01419 Double_t z = dfmax*factnm;
01420
01421 prb = TMath::KolmogorovProb(z);
01422
01423 Double_t prb1 = 0, prb2 = 0;
01424
01425 if (opt.Contains("N") && !(afunc1 || afunc2 ) ) {
01426
01427 prb1 = prb;
01428 Double_t d12 = esum1-esum2;
01429 Double_t chi2 = d12*d12/(esum1+esum2);
01430 prb2 = TMath::Prob(chi2,1);
01431
01432 if (prb > 0 && prb2 > 0) prb = prb*prb2*(1-TMath::Log(prb*prb2));
01433 else prb = 0;
01434 }
01435
01436
01437 if (opt.Contains("D")) {
01438 printf(" Kolmo Prob h1 = %s, sum1=%g\n",h1->GetName(),sum1);
01439 printf(" Kolmo Prob h2 = %s, sum2=%g\n",h2->GetName(),sum2);
01440 printf(" Kolmo Probabil = %f, Max Dist = %g\n",prb,dfmax);
01441 if (opt.Contains("N"))
01442 printf(" Kolmo Probabil = %f for shape alone, =%f for normalisation alone\n",prb1,prb2);
01443 }
01444
01445 if (TMath::Abs(rsum1-1) > 0.002) Warning("KolmogorovTest","Numerical problems with h1=%s\n",h1->GetName());
01446 if (TMath::Abs(rsum2-1) > 0.002) Warning("KolmogorovTest","Numerical problems with h2=%s\n",h2->GetName());
01447
01448 if(opt.Contains("M")) return dfmax;
01449
01450 return prb;
01451 }
01452
01453
01454
01455 Long64_t TH3::Merge(TCollection *list)
01456 {
01457
01458
01459
01460
01461
01462
01463
01464
01465
01466
01467
01468
01469
01470 if (!list) return 0;
01471 if (list->IsEmpty()) return (Int_t) GetEntries();
01472
01473 TList inlist;
01474 TH1* hclone = (TH1*)Clone("FirstClone");
01475 R__ASSERT(hclone);
01476 BufferEmpty(1);
01477 Reset();
01478 SetEntries(0);
01479 inlist.Add(hclone);
01480 inlist.AddAll(list);
01481
01482 TAxis newXAxis;
01483 TAxis newYAxis;
01484 TAxis newZAxis;
01485 Bool_t initialLimitsFound = kFALSE;
01486 Bool_t same = kTRUE;
01487 Bool_t allHaveLimits = kTRUE;
01488
01489 TIter next(&inlist);
01490 while (TObject *o = next()) {
01491 TH3* h = dynamic_cast<TH3*> (o);
01492 if (!h) {
01493 Error("Add","Attempt to add object of class: %s to a %s",
01494 o->ClassName(),this->ClassName());
01495 return -1;
01496 }
01497 Bool_t hasLimits = h->GetXaxis()->GetXmin() < h->GetXaxis()->GetXmax();
01498 allHaveLimits = allHaveLimits && hasLimits;
01499
01500 if (hasLimits) {
01501 h->BufferEmpty();
01502 if (!initialLimitsFound) {
01503 initialLimitsFound = kTRUE;
01504 newXAxis.Set(h->GetXaxis()->GetNbins(), h->GetXaxis()->GetXmin(),
01505 h->GetXaxis()->GetXmax());
01506 newYAxis.Set(h->GetYaxis()->GetNbins(), h->GetYaxis()->GetXmin(),
01507 h->GetYaxis()->GetXmax());
01508 newZAxis.Set(h->GetZaxis()->GetNbins(), h->GetZaxis()->GetXmin(),
01509 h->GetZaxis()->GetXmax());
01510 }
01511 else {
01512 if (!RecomputeAxisLimits(newXAxis, *(h->GetXaxis()))) {
01513 Error("Merge", "Cannot merge histograms - limits are inconsistent:\n "
01514 "first: (%d, %f, %f), second: (%d, %f, %f)",
01515 newXAxis.GetNbins(), newXAxis.GetXmin(), newXAxis.GetXmax(),
01516 h->GetXaxis()->GetNbins(), h->GetXaxis()->GetXmin(),
01517 h->GetXaxis()->GetXmax());
01518 }
01519 if (!RecomputeAxisLimits(newYAxis, *(h->GetYaxis()))) {
01520 Error("Merge", "Cannot merge histograms - limits are inconsistent:\n "
01521 "first: (%d, %f, %f), second: (%d, %f, %f)",
01522 newYAxis.GetNbins(), newYAxis.GetXmin(), newYAxis.GetXmax(),
01523 h->GetYaxis()->GetNbins(), h->GetYaxis()->GetXmin(),
01524 h->GetYaxis()->GetXmax());
01525 }
01526 if (!RecomputeAxisLimits(newZAxis, *(h->GetZaxis()))) {
01527 Error("Merge", "Cannot merge histograms - limits are inconsistent:\n "
01528 "first: (%d, %f, %f), second: (%d, %f, %f)",
01529 newZAxis.GetNbins(), newZAxis.GetXmin(), newZAxis.GetXmax(),
01530 h->GetZaxis()->GetNbins(), h->GetZaxis()->GetXmin(),
01531 h->GetZaxis()->GetXmax());
01532 }
01533 }
01534 }
01535 }
01536 next.Reset();
01537
01538 same = same && SameLimitsAndNBins(newXAxis, *GetXaxis())
01539 && SameLimitsAndNBins(newYAxis, *GetYaxis());
01540 if (!same && initialLimitsFound)
01541 SetBins(newXAxis.GetNbins(), newXAxis.GetXmin(), newXAxis.GetXmax(),
01542 newYAxis.GetNbins(), newYAxis.GetXmin(), newYAxis.GetXmax(),
01543 newZAxis.GetNbins(), newZAxis.GetXmin(), newZAxis.GetXmax());
01544
01545 if (!allHaveLimits) {
01546
01547 while (TH3* h = dynamic_cast<TH3*> (next())) {
01548 if (h->GetXaxis()->GetXmin() >= h->GetXaxis()->GetXmax() && h->fBuffer) {
01549
01550 Int_t nbentries = (Int_t)h->fBuffer[0];
01551 for (Int_t i = 0; i < nbentries; i++)
01552 Fill(h->fBuffer[4*i + 2], h->fBuffer[4*i + 3],
01553 h->fBuffer[4*i + 4], h->fBuffer[4*i + 1]);
01554
01555
01556 }
01557 }
01558 if (!initialLimitsFound)
01559 return (Int_t) GetEntries();
01560 next.Reset();
01561 }
01562
01563
01564 Double_t stats[kNstat], totstats[kNstat];
01565 for (Int_t i=0;i<kNstat;i++) {totstats[i] = stats[i] = 0;}
01566 GetStats(totstats);
01567 Double_t nentries = GetEntries();
01568 Int_t binx, biny, binz, ix, iy, iz, nx, ny, nz, bin, ibin;
01569 Double_t cu;
01570 Int_t nbix = fXaxis.GetNbins();
01571 Int_t nbiy = fYaxis.GetNbins();
01572 Bool_t canRebin=TestBit(kCanRebin);
01573 ResetBit(kCanRebin);
01574
01575 while (TH1* h=(TH1*)next()) {
01576
01577 if (h->GetXaxis()->GetXmin() < h->GetXaxis()->GetXmax()) {
01578
01579 h->GetStats(stats);
01580 for (Int_t i = 0; i < kNstat; i++)
01581 totstats[i] += stats[i];
01582 nentries += h->GetEntries();
01583
01584 nx = h->GetXaxis()->GetNbins();
01585 ny = h->GetYaxis()->GetNbins();
01586 nz = h->GetZaxis()->GetNbins();
01587
01588 for (binz = 0; binz <= nz + 1; binz++) {
01589 iz = fZaxis.FindBin(h->GetZaxis()->GetBinCenter(binz));
01590 for (biny = 0; biny <= ny + 1; biny++) {
01591 iy = fYaxis.FindBin(h->GetYaxis()->GetBinCenter(biny));
01592 for (binx = 0; binx <= nx + 1; binx++) {
01593 ix = fXaxis.FindBin(h->GetXaxis()->GetBinCenter(binx));
01594 bin = binx +(nx+2)*(biny + (ny+2)*binz);
01595 ibin = ix +(nbix+2)*(iy + (nbiy+2)*iz);
01596 cu = h->GetBinContent(bin);
01597 if ((!same) && (binx == 0 || binx == nx + 1
01598 || biny == 0 || biny == ny + 1
01599 || binz == 0 || binz == nz + 1)) {
01600 if (cu != 0) {
01601 Error("Merge", "Cannot merge histograms - the histograms have"
01602 " different limits and undeflows/overflows are present."
01603 " The initial histogram is now broken!");
01604 return -1;
01605 }
01606 }
01607 if (ibin <0) continue;
01608 AddBinContent(ibin,cu);
01609 if (fSumw2.fN) {
01610 Double_t error1 = h->GetBinError(bin);
01611 fSumw2.fArray[ibin] += error1*error1;
01612 }
01613 }
01614 }
01615 }
01616 }
01617 }
01618 if (canRebin) SetBit(kCanRebin);
01619
01620
01621 PutStats(totstats);
01622 SetEntries(nentries);
01623 inlist.Remove(hclone);
01624 delete hclone;
01625 return (Long64_t)nentries;
01626 }
01627
01628
01629 TH1D *TH3::ProjectionX(const char *name, Int_t iymin, Int_t iymax, Int_t izmin, Int_t izmax, Option_t *option) const
01630 {
01631
01632
01633
01634
01635
01636
01637
01638
01639
01640
01641
01642
01643
01644
01645
01646
01647
01648
01649
01650
01651
01652 TString opt = option;
01653 opt.ToLower();
01654
01655 Int_t piymin = GetYaxis()->GetFirst();
01656 Int_t piymax = GetYaxis()->GetLast();
01657 Int_t pizmin = GetZaxis()->GetFirst();
01658 Int_t pizmax = GetZaxis()->GetLast();
01659
01660 GetYaxis()->SetRange(iymin,iymax);
01661 GetZaxis()->SetRange(izmin,izmax);
01662
01663
01664
01665 if (iymin == 1 && iymax == GetNbinsY() ) GetYaxis()->SetBit(TAxis::kAxisRange);
01666 if (izmin == 1 && izmax == GetNbinsZ() ) GetZaxis()->SetBit(TAxis::kAxisRange);
01667
01668
01669 Bool_t useUF = (iymin == 0 || izmin == 0);
01670 Bool_t useOF = ( (iymax < 0 ) || (iymax > GetNbinsY() ) || (izmax < 0) || (izmax > GetNbinsZ() ) );
01671
01672 Bool_t computeErrors = GetSumw2N();
01673 if (opt.Contains("e") ) {
01674 computeErrors = kTRUE;
01675 opt.Remove(opt.First("e"),1);
01676 }
01677 Bool_t originalRange = kFALSE;
01678 if (opt.Contains('o') ) {
01679 originalRange = kTRUE;
01680 opt.Remove(opt.First("o"),1);
01681 }
01682
01683 TH1D * h1 = DoProject1D(name, GetTitle(), this->GetXaxis(), computeErrors, originalRange, useUF, useOF);
01684
01685
01686 GetYaxis()->SetRange(piymin,piymax);
01687 GetZaxis()->SetRange(pizmin,pizmax);
01688
01689
01690 if (h1 && opt.Contains("d")) {
01691 opt.Remove(opt.First("d"),1);
01692 TVirtualPad *padsav = gPad;
01693 TVirtualPad *pad = gROOT->GetSelectedPad();
01694 if (pad) pad->cd();
01695 if (!gPad->FindObject(h1)) {
01696 h1->Draw(opt);
01697 } else {
01698 h1->Paint(opt);
01699 }
01700 if (padsav) padsav->cd();
01701 }
01702
01703 return h1;
01704 }
01705
01706
01707 TH1D *TH3::ProjectionY(const char *name, Int_t ixmin, Int_t ixmax, Int_t izmin, Int_t izmax, Option_t *option) const
01708 {
01709
01710
01711
01712
01713
01714
01715
01716
01717
01718
01719
01720
01721
01722
01723
01724
01725
01726
01727
01728
01729
01730 TString opt = option;
01731 opt.ToLower();
01732
01733 Int_t pixmin = GetXaxis()->GetFirst();
01734 Int_t pixmax = GetXaxis()->GetLast();
01735 Int_t pizmin = GetZaxis()->GetFirst();
01736 Int_t pizmax = GetZaxis()->GetLast();
01737
01738 GetXaxis()->SetRange(ixmin,ixmax);
01739 GetZaxis()->SetRange(izmin,izmax);
01740
01741
01742
01743 if (ixmin == 1 && ixmax == GetNbinsX() ) GetXaxis()->SetBit(TAxis::kAxisRange);
01744 if (izmin == 1 && izmax == GetNbinsZ() ) GetZaxis()->SetBit(TAxis::kAxisRange);
01745
01746
01747 Bool_t useUF = (ixmin == 0 || izmin == 0);
01748 Bool_t useOF = ( (ixmax < 0 ) || (ixmax > GetNbinsX() ) || (izmax < 0) || (izmax > GetNbinsZ() ) );
01749
01750 Bool_t computeErrors = GetSumw2N();
01751 if (opt.Contains("e") ) {
01752 computeErrors = kTRUE;
01753 opt.Remove(opt.First("e"),1);
01754 }
01755 Bool_t originalRange = kFALSE;
01756 if (opt.Contains('o') ) {
01757 originalRange = kTRUE;
01758 opt.Remove(opt.First("o"),1);
01759 }
01760
01761 TH1D * h1 = DoProject1D(name, GetTitle(), this->GetYaxis(), computeErrors, originalRange, useUF, useOF);
01762
01763
01764 GetXaxis()->SetRange(pixmin,pixmax);
01765 GetZaxis()->SetRange(pizmin,pizmax);
01766
01767
01768 if (h1 && opt.Contains("d")) {
01769 opt.Remove(opt.First("d"),1);
01770 TVirtualPad *padsav = gPad;
01771 TVirtualPad *pad = gROOT->GetSelectedPad();
01772 if (pad) pad->cd();
01773 if (!gPad->FindObject(h1)) {
01774 h1->Draw(opt);
01775 } else {
01776 h1->Paint(opt);
01777 }
01778 if (padsav) padsav->cd();
01779 }
01780
01781 return h1;
01782 }
01783
01784
01785 TH1D *TH3::ProjectionZ(const char *name, Int_t ixmin, Int_t ixmax, Int_t iymin, Int_t iymax, Option_t *option) const
01786 {
01787
01788
01789
01790
01791
01792
01793
01794
01795
01796
01797
01798
01799
01800
01801
01802
01803
01804
01805
01806
01807
01808
01809 TString opt = option;
01810 opt.ToLower();
01811
01812 Int_t pixmin = GetXaxis()->GetFirst();
01813 Int_t pixmax = GetXaxis()->GetLast();
01814 Int_t piymin = GetYaxis()->GetFirst();
01815 Int_t piymax = GetYaxis()->GetLast();
01816
01817 GetXaxis()->SetRange(ixmin,ixmax);
01818 GetYaxis()->SetRange(iymin,iymax);
01819
01820
01821
01822 if (ixmin == 1 && ixmax == GetNbinsX() ) GetXaxis()->SetBit(TAxis::kAxisRange);
01823 if (iymin == 1 && iymax == GetNbinsY() ) GetYaxis()->SetBit(TAxis::kAxisRange);
01824
01825
01826 Bool_t useUF = (ixmin == 0 || iymin == 0);
01827 Bool_t useOF = ( (ixmax < 0 ) || (ixmax > GetNbinsX() ) || (iymax < 0) || (iymax > GetNbinsY() ) );
01828
01829 Bool_t computeErrors = GetSumw2N();
01830 if (opt.Contains("e") ) {
01831 computeErrors = kTRUE;
01832 opt.Remove(opt.First("e"),1);
01833 }
01834 Bool_t originalRange = kFALSE;
01835 if (opt.Contains('o') ) {
01836 originalRange = kTRUE;
01837 opt.Remove(opt.First("o"),1);
01838 }
01839
01840 TH1D * h1 = DoProject1D(name, GetTitle(), this->GetZaxis(), computeErrors, originalRange, useUF, useOF);
01841
01842
01843 GetXaxis()->SetRange(pixmin,pixmax);
01844 GetYaxis()->SetRange(piymin,piymax);
01845
01846
01847 if (h1 && opt.Contains("d")) {
01848 opt.Remove(opt.First("d"),1);
01849 TVirtualPad *padsav = gPad;
01850 TVirtualPad *pad = gROOT->GetSelectedPad();
01851 if (pad) pad->cd();
01852 if (!gPad->FindObject(h1)) {
01853 h1->Draw(opt);
01854 } else {
01855 h1->Paint(opt);
01856 }
01857 if (padsav) padsav->cd();
01858 }
01859
01860 return h1;
01861 }
01862
01863
01864 TH1D *TH3::DoProject1D(const char* name, const char* title, TAxis* projX,
01865 bool computeErrors, bool originalRange,
01866 bool useUF, bool useOF) const
01867 {
01868
01869
01870
01871
01872 TH1D *h1 = 0;
01873
01874
01875 Int_t ixmin = projX->GetFirst();
01876 Int_t ixmax = projX->GetLast();
01877 if (ixmin == 0 && ixmax == 0) { ixmin = 1; ixmax = projX->GetNbins(); }
01878 Int_t nx = ixmax-ixmin+1;
01879
01880
01881
01882 TObject *h1obj = gROOT->FindObject(name);
01883 if (h1obj && h1obj->InheritsFrom(TH1::Class())) {
01884 if (h1obj->IsA() != TH1D::Class() ) {
01885 Error("DoProject1D","Histogram with name %s must be a TH1D and is a %s",name,h1obj->ClassName());
01886 return 0;
01887 }
01888 h1 = (TH1D*)h1obj;
01889
01890 if ( h1->GetNbinsX() == projX->GetNbins() &&
01891 h1->GetXaxis()->GetXmin() == projX->GetXmin() &&
01892 h1->GetXaxis()->GetXmax() == projX->GetXmax() ) {
01893
01894 originalRange = kTRUE;
01895 h1->Reset();
01896 }
01897 else if ( h1->GetNbinsX() == nx &&
01898 h1->GetXaxis()->GetXmin() == projX->GetBinLowEdge(ixmin) &&
01899 h1->GetXaxis()->GetXmax() == projX->GetBinUpEdge(ixmax) ) {
01900
01901 h1->Reset();
01902 }
01903 else {
01904 Error("DoProject1D","Histogram with name %s already exists and it is not compatible",name);
01905 return 0;
01906 }
01907 }
01908
01909 if (!h1) {
01910 const TArrayD *bins = projX->GetXbins();
01911 if ( originalRange )
01912 {
01913 if (bins->fN == 0) {
01914 h1 = new TH1D(name,title,projX->GetNbins(),projX->GetXmin(),projX->GetXmax());
01915 } else {
01916 h1 = new TH1D(name,title,projX->GetNbins(),bins->fArray);
01917 }
01918 } else {
01919 if (bins->fN == 0) {
01920 h1 = new TH1D(name,title,nx,projX->GetBinLowEdge(ixmin),projX->GetBinUpEdge(ixmax));
01921 } else {
01922 h1 = new TH1D(name,title,nx,&bins->fArray[ixmin-1]);
01923 }
01924 }
01925 }
01926
01927
01928 h1->GetXaxis()->ImportAttributes(projX);
01929 THashList* labels = projX->GetLabels();
01930 if (labels) {
01931 TIter iL(labels);
01932 TObjString* lb;
01933 Int_t i = 1;
01934 while ((lb=(TObjString*)iL())) {
01935 h1->GetXaxis()->SetBinLabel(i,lb->String().Data());
01936 i++;
01937 }
01938 }
01939 h1->SetLineColor(this->GetLineColor());
01940 h1->SetFillColor(this->GetFillColor());
01941 h1->SetMarkerColor(this->GetMarkerColor());
01942 h1->SetMarkerStyle(this->GetMarkerStyle());
01943
01944
01945 if ( computeErrors ) h1->Sumw2();
01946
01947
01948 TAxis* out1 = 0;
01949 TAxis* out2 = 0;
01950 if ( projX == GetXaxis() ) {
01951 out1 = GetYaxis();
01952 out2 = GetZaxis();
01953 } else if ( projX == GetYaxis() ) {
01954 out1 = GetZaxis();
01955 out2 = GetXaxis();
01956 } else {
01957 out1 = GetYaxis();
01958 out2 = GetXaxis();
01959 }
01960
01961 Int_t *refX = 0, *refY = 0, *refZ = 0;
01962 Int_t ixbin, out1bin, out2bin;
01963 if ( projX == GetXaxis() ) { refX = &ixbin; refY = &out1bin; refZ = &out2bin; }
01964 if ( projX == GetYaxis() ) { refX = &out2bin; refY = &ixbin; refZ = &out1bin; }
01965 if ( projX == GetZaxis() ) { refX = &out2bin; refY = &out1bin; refZ = &ixbin; }
01966 R__ASSERT (refX != 0 && refY != 0 && refZ != 0);
01967
01968
01969
01970 Double_t totcont = 0;
01971
01972 Int_t out1min = out1->GetFirst();
01973 Int_t out1max = out1->GetLast();
01974
01975 if (out1min == 0 && out1max == 0) { out1min = 1; out1max = out1->GetNbins(); }
01976
01977 if (useUF && !out1->TestBit(TAxis::kAxisRange) ) out1min -= 1;
01978 if (useOF && !out1->TestBit(TAxis::kAxisRange) ) out1max += 1;
01979 Int_t out2min = out2->GetFirst();
01980 Int_t out2max = out2->GetLast();
01981 if (out2min == 0 && out2max == 0) { out2min = 1; out2max = out2->GetNbins(); }
01982 if (useUF && !out2->TestBit(TAxis::kAxisRange) ) out2min -= 1;
01983 if (useOF && !out2->TestBit(TAxis::kAxisRange) ) out2max += 1;
01984
01985 for (ixbin=0;ixbin<=1+projX->GetNbins();ixbin++){
01986 if ( projX->TestBit(TAxis::kAxisRange) && ( ixbin < ixmin || ixbin > ixmax )) continue;
01987
01988 Double_t cont = 0;
01989 Double_t err2 = 0;
01990
01991
01992 for (out1bin = out1min; out1bin <= out1max; out1bin++){
01993 for (out2bin = out2min; out2bin <= out2max; out2bin++){
01994
01995 Int_t bin = GetBin(*refX, *refY, *refZ);
01996
01997
01998 cont += GetBinContent(bin);
01999 if (computeErrors) {
02000 Double_t exyz = GetBinError(bin);
02001 err2 += exyz*exyz;
02002 }
02003 }
02004 }
02005 Int_t ix = h1->FindBin( projX->GetBinCenter(ixbin) );
02006 h1->SetBinContent(ix ,cont);
02007 if (computeErrors) h1->SetBinError(ix, TMath::Sqrt(err2) );
02008
02009 totcont += cont;
02010
02011 }
02012
02013
02014
02015
02016
02017 bool resetStats = true;
02018 double eps = 1.E-12;
02019 if (IsA() == TH3F::Class() ) eps = 1.E-6;
02020 if (fTsumw != 0 && TMath::Abs( fTsumw - totcont) < TMath::Abs(fTsumw) * eps) resetStats = false;
02021
02022 bool resetEntries = resetStats;
02023
02024 resetEntries |= !useUF || !useOF;
02025
02026
02027 if (!resetStats) {
02028 Double_t stats[kNstat];
02029 GetStats(stats);
02030 if ( projX == GetYaxis() ) {
02031 stats[2] = stats[4];
02032 stats[3] = stats[5];
02033 }
02034 else if ( projX == GetZaxis() ) {
02035 stats[2] = stats[7];
02036 stats[3] = stats[8];
02037 }
02038 h1->PutStats(stats);
02039 }
02040 else {
02041
02042 h1->ResetStats();
02043 }
02044 if (resetEntries) {
02045
02046
02047
02048 Double_t entries = TMath::Floor( totcont + 0.5);
02049 if (computeErrors) entries = h1->GetEffectiveEntries();
02050 h1->SetEntries( entries );
02051 }
02052 else {
02053 h1->SetEntries( fEntries );
02054 }
02055
02056 return h1;
02057 }
02058
02059
02060 TH2D *TH3::DoProject2D(const char* name, const char * title, TAxis* projX, TAxis* projY,
02061 bool computeErrors, bool originalRange,
02062 bool useUF, bool useOF) const
02063 {
02064
02065
02066
02067 TH2D *h2 = 0;
02068
02069
02070 Int_t ixmin = projX->GetFirst();
02071 Int_t ixmax = projX->GetLast();
02072 Int_t iymin = projY->GetFirst();
02073 Int_t iymax = projY->GetLast();
02074 if (ixmin == 0 && ixmax == 0) { ixmin = 1; ixmax = projX->GetNbins(); }
02075 if (iymin == 0 && iymax == 0) { iymin = 1; iymax = projY->GetNbins(); }
02076 Int_t nx = ixmax-ixmin+1;
02077 Int_t ny = iymax-iymin+1;
02078
02079
02080
02081
02082 TObject *h2obj = gROOT->FindObject(name);
02083 if (h2obj && h2obj->InheritsFrom(TH1::Class())) {
02084 if ( h2obj->IsA() != TH2D::Class() ) {
02085 Error("DoProject2D","Histogram with name %s must be a TH2D and is a %s",name,h2obj->ClassName());
02086 return 0;
02087 }
02088 h2 = (TH2D*)h2obj;
02089
02090
02091 if ( ( h2->GetNbinsX() == projY->GetNbins() &&
02092 h2->GetXaxis()->GetXmin() == projY->GetXmin() &&
02093 h2->GetXaxis()->GetXmax() == projY->GetXmax() ) &&
02094 ( h2->GetNbinsY() == projX->GetNbins() &&
02095 h2->GetYaxis()->GetXmin() == projX->GetXmin() &&
02096 h2->GetYaxis()->GetXmax() == projX->GetXmax() ) ) {
02097
02098 originalRange = kTRUE;
02099 h2->Reset();
02100 }
02101 else if ( ( h2->GetNbinsX() == ny &&
02102 h2->GetXaxis()->GetXmin() == projY->GetBinLowEdge(iymin) &&
02103 h2->GetXaxis()->GetXmax() == projY->GetBinUpEdge(iymax) ) &&
02104 ( h2->GetNbinsY() == nx &&
02105 h2->GetYaxis()->GetXmin() == projX->GetBinLowEdge(ixmin) &&
02106 h2->GetYaxis()->GetXmax() == projX->GetBinUpEdge(ixmax) ) ) {
02107
02108 h2->Reset();
02109 }
02110 else {
02111 Error("DoProject2D","Histogram with name %s already exists and it is not compatible",name);
02112 return 0;
02113 }
02114 }
02115
02116
02117 if (!h2) {
02118 const TArrayD *xbins = projX->GetXbins();
02119 const TArrayD *ybins = projY->GetXbins();
02120 if ( originalRange )
02121 {
02122 if (xbins->fN == 0 && ybins->fN == 0) {
02123 h2 = new TH2D(name,title,projY->GetNbins(),projY->GetXmin(),projY->GetXmax()
02124 ,projX->GetNbins(),projX->GetXmin(),projX->GetXmax());
02125 } else if (ybins->fN == 0) {
02126 h2 = new TH2D(name,title,projY->GetNbins(),projY->GetXmin(),projY->GetXmax()
02127 ,projX->GetNbins(),&xbins->fArray[ixmin-1]);
02128 } else if (xbins->fN == 0) {
02129 h2 = new TH2D(name,title,projY->GetNbins(),&ybins->fArray[iymin-1]
02130 ,projX->GetNbins(),projX->GetXmin(),projX->GetXmax());
02131 } else {
02132 h2 = new TH2D(name,title,projY->GetNbins(),&ybins->fArray[iymin-1],projX->GetNbins(),&xbins->fArray[ixmin-1]);
02133 }
02134 } else {
02135 if (xbins->fN == 0 && ybins->fN == 0) {
02136 h2 = new TH2D(name,title,ny,projY->GetBinLowEdge(iymin),projY->GetBinUpEdge(iymax)
02137 ,nx,projX->GetBinLowEdge(ixmin),projX->GetBinUpEdge(ixmax));
02138 } else if (ybins->fN == 0) {
02139 h2 = new TH2D(name,title,ny,projY->GetBinLowEdge(iymin),projY->GetBinUpEdge(iymax)
02140 ,nx,&xbins->fArray[ixmin-1]);
02141 } else if (xbins->fN == 0) {
02142 h2 = new TH2D(name,title,ny,&ybins->fArray[iymin-1]
02143 ,nx,projX->GetBinLowEdge(ixmin),projX->GetBinUpEdge(ixmax));
02144 } else {
02145 h2 = new TH2D(name,title,ny,&ybins->fArray[iymin-1],nx,&xbins->fArray[ixmin-1]);
02146 }
02147 }
02148 }
02149
02150
02151 THashList* labels1 = 0;
02152 THashList* labels2 = 0;
02153
02154 h2->GetXaxis()->ImportAttributes(projY);
02155 h2->GetYaxis()->ImportAttributes(projX);
02156 labels1 = projY->GetLabels();
02157 labels2 = projX->GetLabels();
02158 if (labels1) {
02159 TIter iL(labels1);
02160 TObjString* lb;
02161 Int_t i = 1;
02162 while ((lb=(TObjString*)iL())) {
02163 h2->GetXaxis()->SetBinLabel(i,lb->String().Data());
02164 i++;
02165 }
02166 }
02167 if (labels2) {
02168 TIter iL(labels2);
02169 TObjString* lb;
02170 Int_t i = 1;
02171 while ((lb=(TObjString*)iL())) {
02172 h2->GetYaxis()->SetBinLabel(i,lb->String().Data());
02173 i++;
02174 }
02175 }
02176 h2->SetLineColor(this->GetLineColor());
02177 h2->SetFillColor(this->GetFillColor());
02178 h2->SetMarkerColor(this->GetMarkerColor());
02179 h2->SetMarkerStyle(this->GetMarkerStyle());
02180
02181
02182 if ( computeErrors) h2->Sumw2();
02183
02184
02185 TAxis* out = 0;
02186 if ( projX != GetXaxis() && projY != GetXaxis() ) {
02187 out = GetXaxis();
02188 } else if ( projX != GetYaxis() && projY != GetYaxis() ) {
02189 out = GetYaxis();
02190 } else {
02191 out = GetZaxis();
02192 }
02193
02194 Int_t *refX = 0, *refY = 0, *refZ = 0;
02195 Int_t ixbin, iybin, outbin;
02196 if ( projX == GetXaxis() && projY == GetYaxis() ) { refX = &ixbin; refY = &iybin; refZ = &outbin; }
02197 if ( projX == GetYaxis() && projY == GetXaxis() ) { refX = &iybin; refY = &ixbin; refZ = &outbin; }
02198 if ( projX == GetXaxis() && projY == GetZaxis() ) { refX = &ixbin; refY = &outbin; refZ = &iybin; }
02199 if ( projX == GetZaxis() && projY == GetXaxis() ) { refX = &iybin; refY = &outbin; refZ = &ixbin; }
02200 if ( projX == GetYaxis() && projY == GetZaxis() ) { refX = &outbin; refY = &ixbin; refZ = &iybin; }
02201 if ( projX == GetZaxis() && projY == GetYaxis() ) { refX = &outbin; refY = &iybin; refZ = &ixbin; }
02202 R__ASSERT (refX != 0 && refY != 0 && refZ != 0);
02203
02204
02205
02206 Double_t totcont = 0;
02207
02208 Int_t outmin = out->GetFirst();
02209 Int_t outmax = out->GetLast();
02210
02211 if (outmin == 0 && outmax == 0) { outmin = 1; outmax = out->GetNbins(); }
02212
02213 if (useUF && !out->TestBit(TAxis::kAxisRange) ) outmin -= 1;
02214 if (useOF && !out->TestBit(TAxis::kAxisRange) ) outmax += 1;
02215
02216 for (ixbin=0;ixbin<=1+projX->GetNbins();ixbin++){
02217 if ( projX->TestBit(TAxis::kAxisRange) && ( ixbin < ixmin || ixbin > ixmax )) continue;
02218 Int_t ix = h2->GetYaxis()->FindBin( projX->GetBinCenter(ixbin) );
02219
02220 for (iybin=0;iybin<=1+projY->GetNbins();iybin++){
02221 if ( projY->TestBit(TAxis::kAxisRange) && ( iybin < iymin || iybin > iymax )) continue;
02222 Int_t iy = h2->GetXaxis()->FindBin( projY->GetBinCenter(iybin) );
02223
02224 Double_t cont = 0;
02225 Double_t err2 = 0;
02226
02227
02228 for (outbin = outmin; outbin <= outmax; outbin++){
02229
02230 Int_t bin = GetBin(*refX,*refY,*refZ);
02231
02232
02233 cont += GetBinContent(bin);
02234 if (computeErrors) {
02235 Double_t exyz = GetBinError(bin);
02236 err2 += exyz*exyz;
02237 }
02238
02239 }
02240
02241
02242 h2->SetBinContent(iy , ix, cont);
02243 if (computeErrors) h2->SetBinError(iy, ix, TMath::Sqrt(err2) );
02244
02245 totcont += cont;
02246
02247 }
02248 }
02249
02250
02251
02252 bool resetStats = true;
02253 double eps = 1.E-12;
02254 if (IsA() == TH3F::Class() ) eps = 1.E-6;
02255 if (fTsumw != 0 && TMath::Abs( fTsumw - totcont) < TMath::Abs(fTsumw) * eps) resetStats = false;
02256
02257 bool resetEntries = resetStats;
02258
02259 resetEntries |= !useUF || !useOF;
02260
02261 if (!resetStats) {
02262 Double_t stats[kNstat];
02263 Double_t oldst[kNstat];
02264 for (Int_t i = 0; i < kNstat; ++i) { oldst[i] = 0; }
02265 GetStats(oldst);
02266 std::copy(oldst,oldst+kNstat,stats);
02267
02268
02269 if ( projY == GetXaxis() && projX == GetZaxis() ) {
02270 stats[4] = oldst[7];
02271 stats[5] = oldst[8];
02272 stats[6] = oldst[9];
02273 }
02274 if ( projY == GetYaxis() ) {
02275 stats[2] = oldst[4];
02276 stats[3] = oldst[5];
02277 if ( projX == GetXaxis() ) {
02278 stats[4] = oldst[2];
02279 stats[5] = oldst[3];
02280 }
02281 if ( projX == GetZaxis() ) {
02282 stats[4] = oldst[7];
02283 stats[5] = oldst[8];
02284 stats[6] = oldst[10];
02285 }
02286 }
02287 else if ( projY == GetZaxis() ) {
02288 stats[2] = oldst[7];
02289 stats[3] = oldst[8];
02290 if ( projX == GetXaxis() ) {
02291 stats[4] = oldst[2];
02292 stats[5] = oldst[3];
02293 stats[6] = oldst[9];
02294 }
02295 if ( projX == GetZaxis() ) {
02296 stats[4] = oldst[4];
02297 stats[5] = oldst[5];
02298 stats[6] = oldst[10];
02299 }
02300 }
02301
02302 h2->PutStats(stats);
02303 }
02304 else {
02305
02306 h2->ResetStats();
02307 }
02308
02309 if (resetEntries) {
02310
02311
02312 Double_t entries = h2->GetEffectiveEntries();
02313 if (!computeErrors) entries = TMath::Floor( entries + 0.5);
02314 h2->SetEntries( entries );
02315 }
02316 else {
02317 h2->SetEntries( fEntries );
02318 }
02319
02320
02321 return h2;
02322 }
02323
02324
02325
02326 TH1 *TH3::Project3D(Option_t *option) const
02327 {
02328
02329
02330
02331
02332
02333
02334
02335
02336
02337
02338
02339
02340
02341
02342
02343
02344
02345
02346
02347
02348
02349
02350
02351
02352
02353
02354
02355
02356
02357
02358
02359
02360
02361
02362
02363
02364
02365
02366
02367
02368
02369
02370
02371
02372
02373
02374
02375
02376
02377 TString opt = option; opt.ToLower();
02378 Int_t pcase = 0;
02379 TString ptype;
02380 if (opt.Contains("x")) { pcase = 1; ptype = "x"; }
02381 if (opt.Contains("y")) { pcase = 2; ptype = "y"; }
02382 if (opt.Contains("z")) { pcase = 3; ptype = "z"; }
02383 if (opt.Contains("xy")) { pcase = 4; ptype = "xy"; }
02384 if (opt.Contains("yx")) { pcase = 5; ptype = "yx"; }
02385 if (opt.Contains("xz")) { pcase = 6; ptype = "xz"; }
02386 if (opt.Contains("zx")) { pcase = 7; ptype = "zx"; }
02387 if (opt.Contains("yz")) { pcase = 8; ptype = "yz"; }
02388 if (opt.Contains("zy")) { pcase = 9; ptype = "zy"; }
02389
02390 if (pcase == 0) {
02391 Error("Project3D","No projection axis specified - return a NULL pointer");
02392 return 0;
02393 }
02394
02395
02396 Bool_t computeErrors = GetSumw2N();
02397 if (opt.Contains("e") ) {
02398 computeErrors = kTRUE;
02399 opt.Remove(opt.First("e"),1);
02400 }
02401
02402 Bool_t useUF = kTRUE;
02403 Bool_t useOF = kTRUE;
02404 if (opt.Contains("nuf") ) {
02405 useUF = kFALSE;
02406 opt.Remove(opt.Index("nuf"),3);
02407 }
02408 if (opt.Contains("nof") ) {
02409 useOF = kFALSE;
02410 opt.Remove(opt.Index("nof"),3);
02411 }
02412
02413 Bool_t originalRange = kFALSE;
02414 if (opt.Contains('o') ) {
02415 originalRange = kTRUE;
02416 opt.Remove(opt.First("o"),1);
02417 }
02418
02419
02420
02421 TH1 *h = 0;
02422
02423 TString name = GetName();
02424 TString title = GetTitle();
02425 name += "_"; name += opt;
02426 title += " "; title += ptype; title += " projection";
02427
02428 switch (pcase) {
02429 case 1:
02430
02431 h = DoProject1D(name, title, this->GetXaxis(),
02432 computeErrors, originalRange, useUF, useOF);
02433 break;
02434
02435 case 2:
02436
02437 h = DoProject1D(name, title, this->GetYaxis(),
02438 computeErrors, originalRange, useUF, useOF);
02439 break;
02440
02441 case 3:
02442
02443 h = DoProject1D(name, title, this->GetZaxis(),
02444 computeErrors, originalRange, useUF, useOF);
02445 break;
02446
02447 case 4:
02448
02449 h = DoProject2D(name, title, this->GetXaxis(),this->GetYaxis(),
02450 computeErrors, originalRange, useUF, useOF);
02451 break;
02452
02453 case 5:
02454
02455 h = DoProject2D(name, title, this->GetYaxis(),this->GetXaxis(),
02456 computeErrors, originalRange, useUF, useOF);
02457 break;
02458
02459 case 6:
02460
02461 h = DoProject2D(name, title, this->GetXaxis(),this->GetZaxis(),
02462 computeErrors, originalRange, useUF, useOF);
02463 break;
02464
02465 case 7:
02466
02467 h = DoProject2D(name, title, this->GetZaxis(),this->GetXaxis(),
02468 computeErrors, originalRange, useUF, useOF);
02469 break;
02470
02471 case 8:
02472
02473 h = DoProject2D(name, title, this->GetYaxis(),this->GetZaxis(),
02474 computeErrors, originalRange, useUF, useOF);
02475 break;
02476
02477 case 9:
02478
02479 h = DoProject2D(name, title, this->GetZaxis(),this->GetYaxis(),
02480 computeErrors, originalRange, useUF, useOF);
02481 break;
02482
02483 }
02484
02485
02486 if (h && opt.Contains("d")) {
02487 opt.Remove(opt.First("d"),1);
02488 TVirtualPad *padsav = gPad;
02489 TVirtualPad *pad = gROOT->GetSelectedPad();
02490 if (pad) pad->cd();
02491 if (!gPad->FindObject(h)) {
02492 h->Draw(opt);
02493 } else {
02494 h->Paint(opt);
02495 }
02496 if (padsav) padsav->cd();
02497 }
02498
02499 return h;
02500 }
02501
02502 void TH3::DoFillProfileProjection(TProfile2D * p2, const TAxis & a1, const TAxis & a2, const TAxis & a3, Int_t bin1, Int_t bin2, Int_t bin3, Int_t inBin, Bool_t useWeights ) const {
02503
02504
02505
02506 Double_t cont = GetBinContent(inBin);
02507 if (!cont) return;
02508 TArrayD & binSumw2 = *(p2->GetBinSumw2());
02509 if (useWeights && binSumw2.fN <= 0) useWeights = false;
02510
02511 Double_t u = a1.GetBinCenter(bin1);
02512 Double_t v = a2.GetBinCenter(bin2);
02513 Double_t w = a3.GetBinCenter(bin3);
02514 Int_t outBin = p2->FindBin(u, v);
02515 if (outBin <0) return;
02516 Double_t tmp = 0;
02517 if ( useWeights ) tmp = binSumw2.fArray[outBin];
02518 p2->Fill( u , v, w, cont);
02519
02520
02521
02522
02523
02524 if (useWeights ) binSumw2.fArray[outBin] = tmp + fSumw2.fArray[inBin];
02525 }
02526
02527
02528 TProfile2D *TH3::DoProjectProfile2D(const char* name, const char * title, TAxis* projX, TAxis* projY,
02529 bool originalRange, bool useUF, bool useOF) const
02530 {
02531
02532
02533
02534
02535 Int_t ixmin = projX->GetFirst();
02536 Int_t ixmax = projX->GetLast();
02537 Int_t iymin = projY->GetFirst();
02538 Int_t iymax = projY->GetLast();
02539 if (ixmin == 0 && ixmax == 0) { ixmin = 1; ixmax = projX->GetNbins(); }
02540 if (iymin == 0 && iymax == 0) { iymin = 1; iymax = projY->GetNbins(); }
02541 Int_t nx = ixmax-ixmin+1;
02542 Int_t ny = iymax-iymin+1;
02543
02544
02545 TProfile2D *p2 = 0;
02546
02547
02548
02549
02550 TObject *p2obj = gROOT->FindObject(name);
02551 if (p2obj && p2obj->InheritsFrom(TH1::Class())) {
02552 if (p2obj->IsA() != TProfile2D::Class() ) {
02553 Error("DoProjectProfile2D","Histogram with name %s must be a TProfile2D and is a %s",name,p2obj->ClassName());
02554 return 0;
02555 }
02556 p2 = (TProfile2D*)p2obj;
02557
02558
02559 if ( ( p2->GetNbinsX() == projY->GetNbins() &&
02560 p2->GetXaxis()->GetXmin() == projY->GetXmin() &&
02561 p2->GetXaxis()->GetXmax() == projY->GetXmax() ) &&
02562 ( p2->GetNbinsY() == projX->GetNbins() &&
02563 p2->GetYaxis()->GetXmin() == projX->GetXmin() &&
02564 p2->GetYaxis()->GetXmax() == projX->GetXmax() ) ) {
02565
02566 originalRange = kTRUE;
02567 p2->Reset();
02568 }
02569 else if ( ( p2->GetNbinsX() == ny &&
02570 p2->GetXaxis()->GetXmin() == projY->GetBinLowEdge(iymin) &&
02571 p2->GetXaxis()->GetXmax() == projY->GetBinUpEdge(iymax) ) &&
02572 ( p2->GetNbinsY() == nx &&
02573 p2->GetYaxis()->GetXmin() == projX->GetBinLowEdge(ixmin) &&
02574 p2->GetYaxis()->GetXmax() == projX->GetBinUpEdge(ixmax) ) ) {
02575
02576 p2->Reset();
02577 }
02578 else {
02579 p2->Dump();
02580 projY->Dump(); projX->Dump();
02581 std::cout << ny << " " << iymin << " , " << iymax << " nx " << nx << " " << ixmin << " , " << ixmax << std::endl;
02582 Error("DoProjectProfile2D","Profile2D with name %s already exists and it is not compatible",name);
02583 return 0;
02584 }
02585 }
02586
02587 if (!p2) {
02588 const TArrayD *xbins = projX->GetXbins();
02589 const TArrayD *ybins = projY->GetXbins();
02590 if ( originalRange ) {
02591 if (xbins->fN == 0 && ybins->fN == 0) {
02592 p2 = new TProfile2D(name,title,projY->GetNbins(),projY->GetXmin(),projY->GetXmax()
02593 ,projX->GetNbins(),projX->GetXmin(),projX->GetXmax());
02594 } else if (ybins->fN == 0) {
02595 p2 = new TProfile2D(name,title,projY->GetNbins(),projY->GetXmin(),projY->GetXmax()
02596 ,projX->GetNbins(),&xbins->fArray[ixmin-1]);
02597 } else if (xbins->fN == 0) {
02598 p2 = new TProfile2D(name,title,projY->GetNbins(),&ybins->fArray[iymin-1]
02599 ,projX->GetNbins(),projX->GetXmin(),projX->GetXmax());
02600 } else {
02601 p2 = new TProfile2D(name,title,projY->GetNbins(),&ybins->fArray[iymin-1],projX->GetNbins(),&xbins->fArray[ixmin-1]);
02602 }
02603 } else {
02604 if (xbins->fN == 0 && ybins->fN == 0) {
02605 p2 = new TProfile2D(name,title,ny,projY->GetBinLowEdge(iymin),projY->GetBinUpEdge(iymax)
02606 ,nx,projX->GetBinLowEdge(ixmin),projX->GetBinUpEdge(ixmax));
02607 } else if (ybins->fN == 0) {
02608 p2 = new TProfile2D(name,title,ny,projY->GetBinLowEdge(iymin),projY->GetBinUpEdge(iymax)
02609 ,nx,&xbins->fArray[ixmin-1]);
02610 } else if (xbins->fN == 0) {
02611 p2 = new TProfile2D(name,title,ny,&ybins->fArray[iymin-1]
02612 ,nx,projX->GetBinLowEdge(ixmin),projX->GetBinUpEdge(ixmax));
02613 } else {
02614 p2 = new TProfile2D(name,title,ny,&ybins->fArray[iymin-1],nx,&xbins->fArray[ixmin-1]);
02615 }
02616 }
02617 }
02618
02619
02620 TAxis* outAxis = 0;
02621 if ( projX != GetXaxis() && projY != GetXaxis() ) {
02622 outAxis = GetXaxis();
02623 } else if ( projX != GetYaxis() && projY != GetYaxis() ) {
02624 outAxis = GetYaxis();
02625 } else {
02626 outAxis = GetZaxis();
02627 }
02628
02629
02630 bool useWeights = (GetSumw2N() > 0);
02631 if (useWeights ) p2->Sumw2();
02632
02633
02634 Int_t *refX = 0, *refY = 0, *refZ = 0;
02635 Int_t ixbin, iybin, outbin;
02636 if ( projX == GetXaxis() && projY == GetYaxis() ) { refX = &ixbin; refY = &iybin; refZ = &outbin; }
02637 if ( projX == GetYaxis() && projY == GetXaxis() ) { refX = &iybin; refY = &ixbin; refZ = &outbin; }
02638 if ( projX == GetXaxis() && projY == GetZaxis() ) { refX = &ixbin; refY = &outbin; refZ = &iybin; }
02639 if ( projX == GetZaxis() && projY == GetXaxis() ) { refX = &iybin; refY = &outbin; refZ = &ixbin; }
02640 if ( projX == GetYaxis() && projY == GetZaxis() ) { refX = &outbin; refY = &ixbin; refZ = &iybin; }
02641 if ( projX == GetZaxis() && projY == GetYaxis() ) { refX = &outbin; refY = &iybin; refZ = &ixbin; }
02642 R__ASSERT (refX != 0 && refY != 0 && refZ != 0);
02643
02644 Int_t outmin = outAxis->GetFirst();
02645 Int_t outmax = outAxis->GetLast();
02646
02647 if (outmin == 0 && outmax == 0) { outmin = 1; outmax = outAxis->GetNbins(); }
02648
02649 if (useUF && !outAxis->TestBit(TAxis::kAxisRange) ) outmin -= 1;
02650 if (useOF && !outAxis->TestBit(TAxis::kAxisRange) ) outmax += 1;
02651
02652 TArrayD & binSumw2 = *(p2->GetBinSumw2());
02653 if (useWeights && binSumw2.fN <= 0) useWeights = false;
02654
02655
02656 for (ixbin=0;ixbin<=1+projX->GetNbins();ixbin++){
02657 if ( (ixbin < ixmin || ixbin > ixmax) && projX->TestBit(TAxis::kAxisRange)) continue;
02658 for ( iybin=0;iybin<=1+projY->GetNbins();iybin++){
02659 if ( (iybin < iymin || iybin > iymax) && projX->TestBit(TAxis::kAxisRange)) continue;
02660
02661
02662 Int_t poutBin = p2->FindBin(projY->GetBinCenter(iybin), projX->GetBinCenter(ixbin));
02663 if (poutBin <0) continue;
02664
02665 for (outbin = outmin; outbin <= outmax; outbin++){
02666
02667 Int_t bin = GetBin(*refX,*refY,*refZ);
02668
02669
02670
02671 Double_t cont = GetBinContent(bin);
02672 if (!cont) continue;
02673
02674 Double_t tmp = 0;
02675
02676 if ( useWeights ) tmp = binSumw2.fArray[poutBin];
02677 p2->Fill( projY->GetBinCenter(iybin) , projX->GetBinCenter(ixbin), outAxis->GetBinCenter(outbin), cont);
02678 if (useWeights ) binSumw2.fArray[poutBin] = tmp + fSumw2.fArray[bin];
02679
02680 }
02681 }
02682 }
02683
02684
02685
02686 bool resetStats = true;
02687 Double_t stats[kNstat];
02688
02689 if (resetStats)
02690 for (Int_t i=0;i<kNstat;i++) stats[i] = 0;
02691
02692 p2->PutStats(stats);
02693 Double_t entries = fEntries;
02694
02695 if (resetStats) {
02696 entries = p2->GetEffectiveEntries();
02697 if (!useWeights) entries = TMath::Floor( entries + 0.5);
02698 p2->SetEntries( entries );
02699 }
02700
02701 p2->SetEntries(entries);
02702
02703 return p2;
02704 }
02705
02706
02707 TProfile2D *TH3::Project3DProfile(Option_t *option) const
02708 {
02709
02710
02711
02712
02713
02714
02715
02716
02717
02718
02719
02720
02721
02722
02723
02724
02725
02726
02727
02728
02729
02730
02731
02732
02733
02734
02735
02736
02737
02738
02739
02740
02741
02742
02743
02744
02745
02746 TString opt = option; opt.ToLower();
02747 Int_t pcase = 0;
02748 TString ptype;
02749 if (opt.Contains("xy")) { pcase = 4; ptype = "xy"; }
02750 if (opt.Contains("yx")) { pcase = 5; ptype = "yx"; }
02751 if (opt.Contains("xz")) { pcase = 6; ptype = "xz"; }
02752 if (opt.Contains("zx")) { pcase = 7; ptype = "zx"; }
02753 if (opt.Contains("yz")) { pcase = 8; ptype = "yz"; }
02754 if (opt.Contains("zy")) { pcase = 9; ptype = "zy"; }
02755
02756 if (pcase == 0) {
02757 Error("Project3D","No projection axis specified - return a NULL pointer");
02758 return 0;
02759 }
02760
02761
02762 Bool_t useUF = kFALSE;
02763 if (opt.Contains("uf") ) {
02764 useUF = kTRUE;
02765 opt.Remove(opt.Index("uf"),2);
02766 }
02767 Bool_t useOF = kFALSE;
02768 if (opt.Contains("of") ) {
02769 useOF = kTRUE;
02770 opt.Remove(opt.Index("of"),2);
02771 }
02772
02773 Bool_t originalRange = kFALSE;
02774 if (opt.Contains('o') ) {
02775 originalRange = kTRUE;
02776 opt.Remove(opt.First("o"),1);
02777 }
02778
02779
02780 TProfile2D *p2 = 0;
02781 TString name = GetName();
02782 TString title = GetTitle();
02783 name += "_"; name += opt;
02784 title += " "; title += ptype; title += " projection";
02785
02786
02787 switch (pcase) {
02788 case 4:
02789
02790 p2 = DoProjectProfile2D(name, title, GetXaxis(), GetYaxis(), originalRange, useUF, useOF);
02791 break;
02792
02793 case 5:
02794
02795 p2 = DoProjectProfile2D(name, title, GetYaxis(), GetXaxis(), originalRange, useUF, useOF);
02796 break;
02797
02798 case 6:
02799
02800 p2 = DoProjectProfile2D(name, title, GetXaxis(), GetZaxis(), originalRange, useUF, useOF);
02801 break;
02802
02803 case 7:
02804
02805 p2 = DoProjectProfile2D(name, title, GetZaxis(), GetXaxis(), originalRange, useUF, useOF);
02806 break;
02807
02808 case 8:
02809
02810 p2 = DoProjectProfile2D(name, title, GetYaxis(), GetZaxis(), originalRange, useUF, useOF);
02811 break;
02812
02813 case 9:
02814
02815 p2 = DoProjectProfile2D(name, title, GetZaxis(), GetYaxis(), originalRange, useUF, useOF);
02816 break;
02817
02818 }
02819
02820 return p2;
02821 }
02822
02823
02824
02825 void TH3::PutStats(Double_t *stats)
02826 {
02827
02828
02829 TH1::PutStats(stats);
02830 fTsumwy = stats[4];
02831 fTsumwy2 = stats[5];
02832 fTsumwxy = stats[6];
02833 fTsumwz = stats[7];
02834 fTsumwz2 = stats[8];
02835 fTsumwxz = stats[9];
02836 fTsumwyz = stats[10];
02837 }
02838
02839
02840 void TH3::Reset(Option_t *option)
02841 {
02842
02843
02844
02845 TH1::Reset(option);
02846 TString opt = option;
02847 opt.ToUpper();
02848 if (opt.Contains("ICE")) return;
02849 fTsumwy = 0;
02850 fTsumwy2 = 0;
02851 fTsumwxy = 0;
02852 fTsumwz = 0;
02853 fTsumwz2 = 0;
02854 fTsumwxz = 0;
02855 fTsumwyz = 0;
02856 }
02857
02858
02859 void TH3::Streamer(TBuffer &R__b)
02860 {
02861
02862
02863 if (R__b.IsReading()) {
02864 UInt_t R__s, R__c;
02865 Version_t R__v = R__b.ReadVersion(&R__s, &R__c);
02866 if (R__v > 2) {
02867 R__b.ReadClassBuffer(TH3::Class(), this, R__v, R__s, R__c);
02868 return;
02869 }
02870
02871 TH1::Streamer(R__b);
02872 TAtt3D::Streamer(R__b);
02873 R__b.CheckByteCount(R__s, R__c, TH3::IsA());
02874
02875
02876 } else {
02877 R__b.WriteClassBuffer(TH3::Class(),this);
02878 }
02879 }
02880
02881
02882
02883
02884
02885
02886
02887
02888 ClassImp(TH3C)
02889
02890
02891 TH3C::TH3C(): TH3(), TArrayC()
02892 {
02893
02894 SetBinsLength(27);
02895 if (fgDefaultSumw2) Sumw2();
02896 }
02897
02898
02899 TH3C::~TH3C()
02900 {
02901
02902 }
02903
02904
02905 TH3C::TH3C(const char *name,const char *title,Int_t nbinsx,Double_t xlow,Double_t xup
02906 ,Int_t nbinsy,Double_t ylow,Double_t yup
02907 ,Int_t nbinsz,Double_t zlow,Double_t zup)
02908 :TH3(name,title,nbinsx,xlow,xup,nbinsy,ylow,yup,nbinsz,zlow,zup)
02909 {
02910
02911
02912
02913 TArrayC::Set(fNcells);
02914 if (fgDefaultSumw2) Sumw2();
02915
02916 if (xlow >= xup || ylow >= yup || zlow >= zup) SetBuffer(fgBufferSize);
02917 }
02918
02919
02920 TH3C::TH3C(const char *name,const char *title,Int_t nbinsx,const Float_t *xbins
02921 ,Int_t nbinsy,const Float_t *ybins
02922 ,Int_t nbinsz,const Float_t *zbins)
02923 :TH3(name,title,nbinsx,xbins,nbinsy,ybins,nbinsz,zbins)
02924 {
02925
02926
02927 TArrayC::Set(fNcells);
02928 if (fgDefaultSumw2) Sumw2();
02929 }
02930
02931
02932 TH3C::TH3C(const char *name,const char *title,Int_t nbinsx,const Double_t *xbins
02933 ,Int_t nbinsy,const Double_t *ybins
02934 ,Int_t nbinsz,const Double_t *zbins)
02935 :TH3(name,title,nbinsx,xbins,nbinsy,ybins,nbinsz,zbins)
02936 {
02937
02938
02939 TArrayC::Set(fNcells);
02940 if (fgDefaultSumw2) Sumw2();
02941 }
02942
02943
02944 TH3C::TH3C(const TH3C &h3c) : TH3(), TArrayC()
02945 {
02946
02947
02948 ((TH3C&)h3c).Copy(*this);
02949 }
02950
02951
02952 void TH3C::AddBinContent(Int_t bin)
02953 {
02954
02955
02956
02957 if (fArray[bin] < 127) fArray[bin]++;
02958 }
02959
02960
02961 void TH3C::AddBinContent(Int_t bin, Double_t w)
02962 {
02963
02964
02965
02966 Int_t newval = fArray[bin] + Int_t(w);
02967 if (newval > -128 && newval < 128) {fArray[bin] = Char_t(newval); return;}
02968 if (newval < -127) fArray[bin] = -127;
02969 if (newval > 127) fArray[bin] = 127;
02970 }
02971
02972
02973 void TH3C::Copy(TObject &newth3) const
02974 {
02975
02976
02977
02978 TH3::Copy((TH3C&)newth3);
02979 }
02980
02981
02982 TH1 *TH3C::DrawCopy(Option_t *option) const
02983 {
02984
02985
02986 TString opt = option;
02987 opt.ToLower();
02988 if (gPad && !opt.Contains("same")) gPad->Clear();
02989 TH3C *newth3 = (TH3C*)Clone();
02990 newth3->SetDirectory(0);
02991 newth3->SetBit(kCanDelete);
02992 newth3->AppendPad(option);
02993 return newth3;
02994 }
02995
02996
02997 Double_t TH3C::GetBinContent(Int_t bin) const
02998 {
02999
03000
03001 if (fBuffer) ((TH3C*)this)->BufferEmpty();
03002 if (bin < 0) bin = 0;
03003 if (bin >= fNcells) bin = fNcells-1;
03004 if (!fArray) return 0;
03005 return Double_t (fArray[bin]);
03006 }
03007
03008
03009 void TH3C::Reset(Option_t *option)
03010 {
03011
03012
03013
03014 TH3::Reset(option);
03015 TArrayC::Reset();
03016
03017 }
03018
03019
03020 void TH3C::SetBinsLength(Int_t n)
03021 {
03022
03023
03024
03025 if (n < 0) n = (fXaxis.GetNbins()+2)*(fYaxis.GetNbins()+2)*(fZaxis.GetNbins()+2);
03026 fNcells = n;
03027 TArrayC::Set(n);
03028 }
03029
03030
03031 void TH3C::SetBinContent(Int_t bin, Double_t content)
03032 {
03033
03034 fEntries++;
03035 fTsumw = 0;
03036 if (bin < 0) return;
03037 if (bin >= fNcells) return;
03038 fArray[bin] = Char_t (content);
03039 }
03040
03041
03042
03043 void TH3::SetShowProjection(const char *option,Int_t nbins)
03044 {
03045
03046
03047
03048
03049
03050
03051
03052
03053
03054
03055
03056
03057
03058
03059
03060
03061
03062
03063
03064
03065 GetPainter();
03066
03067 if (fPainter) fPainter->SetShowProjection(option,nbins);
03068 }
03069
03070
03071 void TH3C::Streamer(TBuffer &R__b)
03072 {
03073
03074
03075 if (R__b.IsReading()) {
03076 UInt_t R__s, R__c;
03077 if (R__b.GetParent() && R__b.GetVersionOwner() < 22300) return;
03078 Version_t R__v = R__b.ReadVersion(&R__s, &R__c);
03079 if (R__v > 2) {
03080 R__b.ReadClassBuffer(TH3C::Class(), this, R__v, R__s, R__c);
03081 return;
03082 }
03083
03084 if (R__v < 2) {
03085 R__b.ReadVersion();
03086 TH1::Streamer(R__b);
03087 TArrayC::Streamer(R__b);
03088 R__b.ReadVersion(&R__s, &R__c);
03089 TAtt3D::Streamer(R__b);
03090 } else {
03091 TH3::Streamer(R__b);
03092 TArrayC::Streamer(R__b);
03093 R__b.CheckByteCount(R__s, R__c, TH3C::IsA());
03094 }
03095
03096
03097 } else {
03098 R__b.WriteClassBuffer(TH3C::Class(),this);
03099 }
03100 }
03101
03102
03103 TH3C& TH3C::operator=(const TH3C &h1)
03104 {
03105
03106
03107 if (this != &h1) ((TH3C&)h1).Copy(*this);
03108 return *this;
03109 }
03110
03111
03112 TH3C operator*(Float_t c1, TH3C &h1)
03113 {
03114
03115
03116 TH3C hnew = h1;
03117 hnew.Scale(c1);
03118 hnew.SetDirectory(0);
03119 return hnew;
03120 }
03121
03122
03123 TH3C operator+(TH3C &h1, TH3C &h2)
03124 {
03125
03126
03127 TH3C hnew = h1;
03128 hnew.Add(&h2,1);
03129 hnew.SetDirectory(0);
03130 return hnew;
03131 }
03132
03133
03134 TH3C operator-(TH3C &h1, TH3C &h2)
03135 {
03136
03137
03138 TH3C hnew = h1;
03139 hnew.Add(&h2,-1);
03140 hnew.SetDirectory(0);
03141 return hnew;
03142 }
03143
03144
03145 TH3C operator*(TH3C &h1, TH3C &h2)
03146 {
03147
03148
03149 TH3C hnew = h1;
03150 hnew.Multiply(&h2);
03151 hnew.SetDirectory(0);
03152 return hnew;
03153 }
03154
03155
03156 TH3C operator/(TH3C &h1, TH3C &h2)
03157 {
03158
03159
03160 TH3C hnew = h1;
03161 hnew.Divide(&h2);
03162 hnew.SetDirectory(0);
03163 return hnew;
03164 }
03165
03166
03167
03168
03169
03170
03171
03172 ClassImp(TH3S)
03173
03174
03175 TH3S::TH3S(): TH3(), TArrayS()
03176 {
03177
03178 SetBinsLength(27);
03179 if (fgDefaultSumw2) Sumw2();
03180 }
03181
03182
03183 TH3S::~TH3S()
03184 {
03185
03186 }
03187
03188
03189 TH3S::TH3S(const char *name,const char *title,Int_t nbinsx,Double_t xlow,Double_t xup
03190 ,Int_t nbinsy,Double_t ylow,Double_t yup
03191 ,Int_t nbinsz,Double_t zlow,Double_t zup)
03192 :TH3(name,title,nbinsx,xlow,xup,nbinsy,ylow,yup,nbinsz,zlow,zup)
03193 {
03194
03195
03196 TH3S::Set(fNcells);
03197 if (fgDefaultSumw2) Sumw2();
03198
03199 if (xlow >= xup || ylow >= yup || zlow >= zup) SetBuffer(fgBufferSize);
03200 }
03201
03202
03203 TH3S::TH3S(const char *name,const char *title,Int_t nbinsx,const Float_t *xbins
03204 ,Int_t nbinsy,const Float_t *ybins
03205 ,Int_t nbinsz,const Float_t *zbins)
03206 :TH3(name,title,nbinsx,xbins,nbinsy,ybins,nbinsz,zbins)
03207 {
03208
03209
03210 TH3S::Set(fNcells);
03211 if (fgDefaultSumw2) Sumw2();
03212 }
03213
03214
03215 TH3S::TH3S(const char *name,const char *title,Int_t nbinsx,const Double_t *xbins
03216 ,Int_t nbinsy,const Double_t *ybins
03217 ,Int_t nbinsz,const Double_t *zbins)
03218 :TH3(name,title,nbinsx,xbins,nbinsy,ybins,nbinsz,zbins)
03219 {
03220
03221
03222 TH3S::Set(fNcells);
03223 if (fgDefaultSumw2) Sumw2();
03224 }
03225
03226
03227 TH3S::TH3S(const TH3S &h3s) : TH3(), TArrayS()
03228 {
03229
03230
03231 ((TH3S&)h3s).Copy(*this);
03232 }
03233
03234
03235 void TH3S::AddBinContent(Int_t bin)
03236 {
03237
03238
03239
03240 if (fArray[bin] < 32767) fArray[bin]++;
03241 }
03242
03243
03244 void TH3S::AddBinContent(Int_t bin, Double_t w)
03245 {
03246
03247
03248
03249 Int_t newval = fArray[bin] + Int_t(w);
03250 if (newval > -32768 && newval < 32768) {fArray[bin] = Short_t(newval); return;}
03251 if (newval < -32767) fArray[bin] = -32767;
03252 if (newval > 32767) fArray[bin] = 32767;
03253 }
03254
03255
03256 void TH3S::Copy(TObject &newth3) const
03257 {
03258
03259
03260
03261 TH3::Copy((TH3S&)newth3);
03262 }
03263
03264
03265 TH1 *TH3S::DrawCopy(Option_t *option) const
03266 {
03267
03268
03269 TString opt = option;
03270 opt.ToLower();
03271 if (gPad && !opt.Contains("same")) gPad->Clear();
03272 TH3S *newth3 = (TH3S*)Clone();
03273 newth3->SetDirectory(0);
03274 newth3->SetBit(kCanDelete);
03275 newth3->AppendPad(option);
03276 return newth3;
03277 }
03278
03279
03280 Double_t TH3S::GetBinContent(Int_t bin) const
03281 {
03282
03283
03284 if (fBuffer) ((TH3S*)this)->BufferEmpty();
03285 if (bin < 0) bin = 0;
03286 if (bin >= fNcells) bin = fNcells-1;
03287 if (!fArray) return 0;
03288 return Double_t (fArray[bin]);
03289 }
03290
03291
03292 void TH3S::Reset(Option_t *option)
03293 {
03294
03295
03296
03297 TH3::Reset(option);
03298 TArrayS::Reset();
03299
03300 }
03301
03302
03303 void TH3S::SetBinContent(Int_t bin, Double_t content)
03304 {
03305
03306 fEntries++;
03307 fTsumw = 0;
03308 if (bin < 0) return;
03309 if (bin >= fNcells) return;
03310 fArray[bin] = Short_t (content);
03311 }
03312
03313
03314 void TH3S::SetBinsLength(Int_t n)
03315 {
03316
03317
03318
03319 if (n < 0) n = (fXaxis.GetNbins()+2)*(fYaxis.GetNbins()+2)*(fZaxis.GetNbins()+2);
03320 fNcells = n;
03321 TArrayS::Set(n);
03322 }
03323
03324
03325 void TH3S::Streamer(TBuffer &R__b)
03326 {
03327
03328
03329 if (R__b.IsReading()) {
03330 UInt_t R__s, R__c;
03331 if (R__b.GetParent() && R__b.GetVersionOwner() < 22300) return;
03332 Version_t R__v = R__b.ReadVersion(&R__s, &R__c);
03333 if (R__v > 2) {
03334 R__b.ReadClassBuffer(TH3S::Class(), this, R__v, R__s, R__c);
03335 return;
03336 }
03337
03338 if (R__v < 2) {
03339 R__b.ReadVersion();
03340 TH1::Streamer(R__b);
03341 TArrayS::Streamer(R__b);
03342 R__b.ReadVersion(&R__s, &R__c);
03343 TAtt3D::Streamer(R__b);
03344 } else {
03345 TH3::Streamer(R__b);
03346 TArrayS::Streamer(R__b);
03347 R__b.CheckByteCount(R__s, R__c, TH3S::IsA());
03348 }
03349
03350
03351 } else {
03352 R__b.WriteClassBuffer(TH3S::Class(),this);
03353 }
03354 }
03355
03356
03357 TH3S& TH3S::operator=(const TH3S &h1)
03358 {
03359
03360
03361 if (this != &h1) ((TH3S&)h1).Copy(*this);
03362 return *this;
03363 }
03364
03365
03366 TH3S operator*(Float_t c1, TH3S &h1)
03367 {
03368
03369
03370 TH3S hnew = h1;
03371 hnew.Scale(c1);
03372 hnew.SetDirectory(0);
03373 return hnew;
03374 }
03375
03376
03377 TH3S operator+(TH3S &h1, TH3S &h2)
03378 {
03379
03380
03381 TH3S hnew = h1;
03382 hnew.Add(&h2,1);
03383 hnew.SetDirectory(0);
03384 return hnew;
03385 }
03386
03387
03388 TH3S operator-(TH3S &h1, TH3S &h2)
03389 {
03390
03391
03392 TH3S hnew = h1;
03393 hnew.Add(&h2,-1);
03394 hnew.SetDirectory(0);
03395 return hnew;
03396 }
03397
03398
03399 TH3S operator*(TH3S &h1, TH3S &h2)
03400 {
03401
03402
03403 TH3S hnew = h1;
03404 hnew.Multiply(&h2);
03405 hnew.SetDirectory(0);
03406 return hnew;
03407 }
03408
03409
03410 TH3S operator/(TH3S &h1, TH3S &h2)
03411 {
03412
03413
03414 TH3S hnew = h1;
03415 hnew.Divide(&h2);
03416 hnew.SetDirectory(0);
03417 return hnew;
03418 }
03419
03420
03421
03422
03423
03424
03425
03426 ClassImp(TH3I)
03427
03428
03429 TH3I::TH3I(): TH3(), TArrayI()
03430 {
03431
03432 SetBinsLength(27);
03433 if (fgDefaultSumw2) Sumw2();
03434 }
03435
03436
03437 TH3I::~TH3I()
03438 {
03439
03440 }
03441
03442
03443 TH3I::TH3I(const char *name,const char *title,Int_t nbinsx,Double_t xlow,Double_t xup
03444 ,Int_t nbinsy,Double_t ylow,Double_t yup
03445 ,Int_t nbinsz,Double_t zlow,Double_t zup)
03446 :TH3(name,title,nbinsx,xlow,xup,nbinsy,ylow,yup,nbinsz,zlow,zup)
03447 {
03448
03449
03450 TH3I::Set(fNcells);
03451 if (fgDefaultSumw2) Sumw2();
03452
03453 if (xlow >= xup || ylow >= yup || zlow >= zup) SetBuffer(fgBufferSize);
03454 }
03455
03456
03457 TH3I::TH3I(const char *name,const char *title,Int_t nbinsx,const Float_t *xbins
03458 ,Int_t nbinsy,const Float_t *ybins
03459 ,Int_t nbinsz,const Float_t *zbins)
03460 :TH3(name,title,nbinsx,xbins,nbinsy,ybins,nbinsz,zbins)
03461 {
03462
03463
03464 TArrayI::Set(fNcells);
03465 if (fgDefaultSumw2) Sumw2();
03466 }
03467
03468
03469 TH3I::TH3I(const char *name,const char *title,Int_t nbinsx,const Double_t *xbins
03470 ,Int_t nbinsy,const Double_t *ybins
03471 ,Int_t nbinsz,const Double_t *zbins)
03472 :TH3(name,title,nbinsx,xbins,nbinsy,ybins,nbinsz,zbins)
03473 {
03474
03475
03476 TArrayI::Set(fNcells);
03477 if (fgDefaultSumw2) Sumw2();
03478 }
03479
03480
03481 TH3I::TH3I(const TH3I &h3i) : TH3(), TArrayI()
03482 {
03483
03484
03485 ((TH3I&)h3i).Copy(*this);
03486 }
03487
03488
03489 void TH3I::AddBinContent(Int_t bin)
03490 {
03491
03492
03493
03494 if (fArray[bin] < 2147483647) fArray[bin]++;
03495 }
03496
03497
03498 void TH3I::AddBinContent(Int_t bin, Double_t w)
03499 {
03500
03501
03502
03503 Int_t newval = fArray[bin] + Int_t(w);
03504 if (newval > -2147483647 && newval < 2147483647) {fArray[bin] = Int_t(newval); return;}
03505 if (newval < -2147483647) fArray[bin] = -2147483647;
03506 if (newval > 2147483647) fArray[bin] = 2147483647;
03507 }
03508
03509
03510 void TH3I::Copy(TObject &newth3) const
03511 {
03512
03513
03514
03515 TH3::Copy((TH3I&)newth3);
03516 }
03517
03518
03519 TH1 *TH3I::DrawCopy(Option_t *option) const
03520 {
03521
03522
03523 TString opt = option;
03524 opt.ToLower();
03525 if (gPad && !opt.Contains("same")) gPad->Clear();
03526 TH3I *newth3 = (TH3I*)Clone();
03527 newth3->SetDirectory(0);
03528 newth3->SetBit(kCanDelete);
03529 newth3->AppendPad(option);
03530 return newth3;
03531 }
03532
03533
03534 Double_t TH3I::GetBinContent(Int_t bin) const
03535 {
03536
03537
03538 if (fBuffer) ((TH3I*)this)->BufferEmpty();
03539 if (bin < 0) bin = 0;
03540 if (bin >= fNcells) bin = fNcells-1;
03541 if (!fArray) return 0;
03542 return Double_t (fArray[bin]);
03543 }
03544
03545
03546 void TH3I::Reset(Option_t *option)
03547 {
03548
03549
03550
03551 TH3::Reset(option);
03552 TArrayI::Reset();
03553
03554 }
03555
03556
03557 void TH3I::SetBinContent(Int_t bin, Double_t content)
03558 {
03559
03560 fEntries++;
03561 fTsumw = 0;
03562 if (bin < 0) return;
03563 if (bin >= fNcells) return;
03564 fArray[bin] = Int_t (content);
03565 }
03566
03567
03568 void TH3I::SetBinsLength(Int_t n)
03569 {
03570
03571
03572
03573 if (n < 0) n = (fXaxis.GetNbins()+2)*(fYaxis.GetNbins()+2)*(fZaxis.GetNbins()+2);
03574 fNcells = n;
03575 TArrayI::Set(n);
03576 }
03577
03578
03579 TH3I& TH3I::operator=(const TH3I &h1)
03580 {
03581
03582
03583 if (this != &h1) ((TH3I&)h1).Copy(*this);
03584 return *this;
03585 }
03586
03587
03588 TH3I operator*(Float_t c1, TH3I &h1)
03589 {
03590
03591
03592 TH3I hnew = h1;
03593 hnew.Scale(c1);
03594 hnew.SetDirectory(0);
03595 return hnew;
03596 }
03597
03598
03599 TH3I operator+(TH3I &h1, TH3I &h2)
03600 {
03601
03602
03603 TH3I hnew = h1;
03604 hnew.Add(&h2,1);
03605 hnew.SetDirectory(0);
03606 return hnew;
03607 }
03608
03609
03610 TH3I operator-(TH3I &h1, TH3I &h2)
03611 {
03612
03613
03614 TH3I hnew = h1;
03615 hnew.Add(&h2,-1);
03616 hnew.SetDirectory(0);
03617 return hnew;
03618 }
03619
03620
03621 TH3I operator*(TH3I &h1, TH3I &h2)
03622 {
03623
03624
03625 TH3I hnew = h1;
03626 hnew.Multiply(&h2);
03627 hnew.SetDirectory(0);
03628 return hnew;
03629 }
03630
03631
03632 TH3I operator/(TH3I &h1, TH3I &h2)
03633 {
03634
03635
03636 TH3I hnew = h1;
03637 hnew.Divide(&h2);
03638 hnew.SetDirectory(0);
03639 return hnew;
03640 }
03641
03642
03643
03644
03645
03646
03647
03648 ClassImp(TH3F)
03649
03650
03651 TH3F::TH3F(): TH3(), TArrayF()
03652 {
03653
03654 SetBinsLength(27);
03655 if (fgDefaultSumw2) Sumw2();
03656 }
03657
03658
03659 TH3F::~TH3F()
03660 {
03661
03662 }
03663
03664
03665 TH3F::TH3F(const char *name,const char *title,Int_t nbinsx,Double_t xlow,Double_t xup
03666 ,Int_t nbinsy,Double_t ylow,Double_t yup
03667 ,Int_t nbinsz,Double_t zlow,Double_t zup)
03668 :TH3(name,title,nbinsx,xlow,xup,nbinsy,ylow,yup,nbinsz,zlow,zup)
03669 {
03670
03671
03672 TArrayF::Set(fNcells);
03673 if (fgDefaultSumw2) Sumw2();
03674
03675 if (xlow >= xup || ylow >= yup || zlow >= zup) SetBuffer(fgBufferSize);
03676 }
03677
03678
03679 TH3F::TH3F(const char *name,const char *title,Int_t nbinsx,const Float_t *xbins
03680 ,Int_t nbinsy,const Float_t *ybins
03681 ,Int_t nbinsz,const Float_t *zbins)
03682 :TH3(name,title,nbinsx,xbins,nbinsy,ybins,nbinsz,zbins)
03683 {
03684
03685
03686 TArrayF::Set(fNcells);
03687 if (fgDefaultSumw2) Sumw2();
03688 }
03689
03690
03691 TH3F::TH3F(const char *name,const char *title,Int_t nbinsx,const Double_t *xbins
03692 ,Int_t nbinsy,const Double_t *ybins
03693 ,Int_t nbinsz,const Double_t *zbins)
03694 :TH3(name,title,nbinsx,xbins,nbinsy,ybins,nbinsz,zbins)
03695 {
03696
03697
03698 TArrayF::Set(fNcells);
03699 if (fgDefaultSumw2) Sumw2();
03700 }
03701
03702
03703 TH3F::TH3F(const TH3F &h3f) : TH3(), TArrayF()
03704 {
03705
03706
03707 ((TH3F&)h3f).Copy(*this);
03708 }
03709
03710
03711 void TH3F::Copy(TObject &newth3) const
03712 {
03713
03714
03715
03716 TH3::Copy((TH3F&)newth3);
03717 }
03718
03719
03720 TH1 *TH3F::DrawCopy(Option_t *option) const
03721 {
03722
03723
03724 TString opt = option;
03725 opt.ToLower();
03726 if (gPad && !opt.Contains("same")) gPad->Clear();
03727 TH3F *newth3 = (TH3F*)Clone();
03728 newth3->SetDirectory(0);
03729 newth3->SetBit(kCanDelete);
03730 newth3->AppendPad(option);
03731 return newth3;
03732 }
03733
03734
03735 Double_t TH3F::GetBinContent(Int_t bin) const
03736 {
03737
03738
03739 if (fBuffer) ((TH3F*)this)->BufferEmpty();
03740 if (bin < 0) bin = 0;
03741 if (bin >= fNcells) bin = fNcells-1;
03742 if (!fArray) return 0;
03743 return Double_t (fArray[bin]);
03744 }
03745
03746
03747 void TH3F::Reset(Option_t *option)
03748 {
03749
03750
03751
03752 TH3::Reset(option);
03753 TArrayF::Reset();
03754
03755 }
03756
03757
03758 void TH3F::SetBinContent(Int_t bin, Double_t content)
03759 {
03760
03761 fEntries++;
03762 fTsumw = 0;
03763 if (bin < 0) return;
03764 if (bin >= fNcells) return;
03765 fArray[bin] = Float_t (content);
03766 }
03767
03768
03769 void TH3F::SetBinsLength(Int_t n)
03770 {
03771
03772
03773
03774 if (n < 0) n = (fXaxis.GetNbins()+2)*(fYaxis.GetNbins()+2)*(fZaxis.GetNbins()+2);
03775 fNcells = n;
03776 TArrayF::Set(n);
03777 }
03778
03779
03780 void TH3F::Streamer(TBuffer &R__b)
03781 {
03782
03783
03784 if (R__b.IsReading()) {
03785 UInt_t R__s, R__c;
03786 if (R__b.GetParent() && R__b.GetVersionOwner() < 22300) return;
03787 Version_t R__v = R__b.ReadVersion(&R__s, &R__c);
03788 if (R__v > 2) {
03789 R__b.ReadClassBuffer(TH3F::Class(), this, R__v, R__s, R__c);
03790 return;
03791 }
03792
03793 if (R__v < 2) {
03794 R__b.ReadVersion();
03795 TH1::Streamer(R__b);
03796 TArrayF::Streamer(R__b);
03797 R__b.ReadVersion(&R__s, &R__c);
03798 TAtt3D::Streamer(R__b);
03799 } else {
03800 TH3::Streamer(R__b);
03801 TArrayF::Streamer(R__b);
03802 R__b.CheckByteCount(R__s, R__c, TH3F::IsA());
03803 }
03804
03805
03806 } else {
03807 R__b.WriteClassBuffer(TH3F::Class(),this);
03808 }
03809 }
03810
03811
03812 TH3F& TH3F::operator=(const TH3F &h1)
03813 {
03814
03815
03816 if (this != &h1) ((TH3F&)h1).Copy(*this);
03817 return *this;
03818 }
03819
03820
03821 TH3F operator*(Float_t c1, TH3F &h1)
03822 {
03823
03824
03825 TH3F hnew = h1;
03826 hnew.Scale(c1);
03827 hnew.SetDirectory(0);
03828 return hnew;
03829 }
03830
03831
03832 TH3F operator+(TH3F &h1, TH3F &h2)
03833 {
03834
03835
03836 TH3F hnew = h1;
03837 hnew.Add(&h2,1);
03838 hnew.SetDirectory(0);
03839 return hnew;
03840 }
03841
03842
03843 TH3F operator-(TH3F &h1, TH3F &h2)
03844 {
03845
03846
03847 TH3F hnew = h1;
03848 hnew.Add(&h2,-1);
03849 hnew.SetDirectory(0);
03850 return hnew;
03851 }
03852
03853
03854 TH3F operator*(TH3F &h1, TH3F &h2)
03855 {
03856
03857
03858 TH3F hnew = h1;
03859 hnew.Multiply(&h2);
03860 hnew.SetDirectory(0);
03861 return hnew;
03862 }
03863
03864
03865 TH3F operator/(TH3F &h1, TH3F &h2)
03866 {
03867
03868
03869 TH3F hnew = h1;
03870 hnew.Divide(&h2);
03871 hnew.SetDirectory(0);
03872 return hnew;
03873 }
03874
03875
03876
03877
03878
03879
03880
03881 ClassImp(TH3D)
03882
03883
03884 TH3D::TH3D(): TH3(), TArrayD()
03885 {
03886
03887 SetBinsLength(27);
03888 if (fgDefaultSumw2) Sumw2();
03889 }
03890
03891
03892 TH3D::~TH3D()
03893 {
03894
03895 }
03896
03897
03898 TH3D::TH3D(const char *name,const char *title,Int_t nbinsx,Double_t xlow,Double_t xup
03899 ,Int_t nbinsy,Double_t ylow,Double_t yup
03900 ,Int_t nbinsz,Double_t zlow,Double_t zup)
03901 :TH3(name,title,nbinsx,xlow,xup,nbinsy,ylow,yup,nbinsz,zlow,zup)
03902 {
03903
03904
03905 TArrayD::Set(fNcells);
03906 if (fgDefaultSumw2) Sumw2();
03907
03908 if (xlow >= xup || ylow >= yup || zlow >= zup) SetBuffer(fgBufferSize);
03909 }
03910
03911
03912 TH3D::TH3D(const char *name,const char *title,Int_t nbinsx,const Float_t *xbins
03913 ,Int_t nbinsy,const Float_t *ybins
03914 ,Int_t nbinsz,const Float_t *zbins)
03915 :TH3(name,title,nbinsx,xbins,nbinsy,ybins,nbinsz,zbins)
03916 {
03917
03918
03919 TArrayD::Set(fNcells);
03920 if (fgDefaultSumw2) Sumw2();
03921 }
03922
03923
03924 TH3D::TH3D(const char *name,const char *title,Int_t nbinsx,const Double_t *xbins
03925 ,Int_t nbinsy,const Double_t *ybins
03926 ,Int_t nbinsz,const Double_t *zbins)
03927 :TH3(name,title,nbinsx,xbins,nbinsy,ybins,nbinsz,zbins)
03928 {
03929
03930
03931 TArrayD::Set(fNcells);
03932 if (fgDefaultSumw2) Sumw2();
03933 }
03934
03935
03936 TH3D::TH3D(const TH3D &h3d) : TH3(), TArrayD()
03937 {
03938
03939
03940 ((TH3D&)h3d).Copy(*this);
03941 }
03942
03943
03944 void TH3D::Copy(TObject &newth3) const
03945 {
03946
03947
03948
03949 TH3::Copy((TH3D&)newth3);
03950 }
03951
03952
03953 TH1 *TH3D::DrawCopy(Option_t *option) const
03954 {
03955
03956
03957 TString opt = option;
03958 opt.ToLower();
03959 if (gPad && !opt.Contains("same")) gPad->Clear();
03960 TH3D *newth3 = (TH3D*)Clone();
03961 newth3->SetDirectory(0);
03962 newth3->SetBit(kCanDelete);
03963 newth3->AppendPad(option);
03964 return newth3;
03965 }
03966
03967
03968 Double_t TH3D::GetBinContent(Int_t bin) const
03969 {
03970
03971
03972 if (fBuffer) ((TH3D*)this)->BufferEmpty();
03973 if (bin < 0) bin = 0;
03974 if (bin >= fNcells) bin = fNcells-1;
03975 if (!fArray) return 0;
03976 return Double_t (fArray[bin]);
03977 }
03978
03979
03980 void TH3D::Reset(Option_t *option)
03981 {
03982
03983
03984
03985 TH3::Reset(option);
03986 TArrayD::Reset();
03987
03988 }
03989
03990
03991 void TH3D::SetBinContent(Int_t bin, Double_t content)
03992 {
03993
03994 fEntries++;
03995 fTsumw = 0;
03996 if (bin < 0) return;
03997 if (bin >= fNcells) return;
03998 fArray[bin] = Double_t (content);
03999 }
04000
04001
04002
04003 void TH3D::SetBinsLength(Int_t n)
04004 {
04005
04006
04007
04008 if (n < 0) n = (fXaxis.GetNbins()+2)*(fYaxis.GetNbins()+2)*(fZaxis.GetNbins()+2);
04009 fNcells = n;
04010 TArrayD::Set(n);
04011 }
04012
04013
04014 void TH3D::Streamer(TBuffer &R__b)
04015 {
04016
04017
04018 if (R__b.IsReading()) {
04019 UInt_t R__s, R__c;
04020 if (R__b.GetParent() && R__b.GetVersionOwner() < 22300) return;
04021 Version_t R__v = R__b.ReadVersion(&R__s, &R__c);
04022 if (R__v > 2) {
04023 R__b.ReadClassBuffer(TH3D::Class(), this, R__v, R__s, R__c);
04024 return;
04025 }
04026
04027 if (R__v < 2) {
04028 R__b.ReadVersion();
04029 TH1::Streamer(R__b);
04030 TArrayD::Streamer(R__b);
04031 R__b.ReadVersion(&R__s, &R__c);
04032 TAtt3D::Streamer(R__b);
04033 } else {
04034 TH3::Streamer(R__b);
04035 TArrayD::Streamer(R__b);
04036 R__b.CheckByteCount(R__s, R__c, TH3D::IsA());
04037 }
04038
04039
04040 } else {
04041 R__b.WriteClassBuffer(TH3D::Class(),this);
04042 }
04043 }
04044
04045
04046 TH3D& TH3D::operator=(const TH3D &h1)
04047 {
04048
04049
04050 if (this != &h1) ((TH3D&)h1).Copy(*this);
04051 return *this;
04052 }
04053
04054
04055 TH3D operator*(Float_t c1, TH3D &h1)
04056 {
04057
04058
04059 TH3D hnew = h1;
04060 hnew.Scale(c1);
04061 hnew.SetDirectory(0);
04062 return hnew;
04063 }
04064
04065
04066 TH3D operator+(TH3D &h1, TH3D &h2)
04067 {
04068
04069
04070 TH3D hnew = h1;
04071 hnew.Add(&h2,1);
04072 hnew.SetDirectory(0);
04073 return hnew;
04074 }
04075
04076
04077 TH3D operator-(TH3D &h1, TH3D &h2)
04078 {
04079
04080
04081 TH3D hnew = h1;
04082 hnew.Add(&h2,-1);
04083 hnew.SetDirectory(0);
04084 return hnew;
04085 }
04086
04087
04088 TH3D operator*(TH3D &h1, TH3D &h2)
04089 {
04090
04091
04092 TH3D hnew = h1;
04093 hnew.Multiply(&h2);
04094 hnew.SetDirectory(0);
04095 return hnew;
04096 }
04097
04098
04099 TH3D operator/(TH3D &h1, TH3D &h2)
04100 {
04101
04102
04103 TH3D hnew = h1;
04104 hnew.Divide(&h2);
04105 hnew.SetDirectory(0);
04106 return hnew;
04107 }