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