00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012 #include "TROOT.h"
00013 #include "TClassRef.h"
00014 #include "THStack.h"
00015 #include "TVirtualPad.h"
00016 #include "TVirtualHistPainter.h"
00017 #include "THashList.h"
00018 #include "TH2.h"
00019 #include "TH3.h"
00020 #include "TList.h"
00021 #include "TStyle.h"
00022 #include "Riostream.h"
00023 #include "TBrowser.h"
00024 #include "TMath.h"
00025 #include "TObjString.h"
00026
00027 ClassImp(THStack)
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062 THStack::THStack(): TNamed()
00063 {
00064
00065
00066 fHists = 0;
00067 fStack = 0;
00068 fHistogram = 0;
00069 fMaximum = -1111;
00070 fMinimum = -1111;
00071 }
00072
00073
00074 THStack::THStack(const char *name, const char *title)
00075 : TNamed(name,title)
00076 {
00077
00078 fHists = 0;
00079 fStack = 0;
00080 fHistogram = 0;
00081 fMaximum = -1111;
00082 fMinimum = -1111;
00083 gROOT->GetListOfCleanups()->Add(this);
00084 }
00085
00086
00087
00088 THStack::THStack(const TH1* hist, Option_t *axis ,
00089 const char *name , const char *title ,
00090 Int_t firstbin , Int_t lastbin ,
00091 Int_t firstbin2 , Int_t lastbin2 ,
00092 Option_t* proj_option , Option_t* draw_option ): TNamed(name, title) {
00093
00094
00095
00096
00097
00098
00099
00100
00101
00102
00103
00104
00105
00106
00107
00108
00109
00110
00111
00112
00113
00114
00115
00116
00117
00118
00119
00120 fHists = 0;
00121 fStack = 0;
00122 fHistogram = 0;
00123 fMaximum = -1111;
00124 fMinimum = -1111;
00125 gROOT->GetListOfCleanups()->Add(this);
00126
00127 if (!axis) {
00128 Warning("THStack", "Need an axis.");
00129 return;
00130 }
00131 if (!hist) {
00132 Warning("THStack", "Need a histogram.");
00133 return;
00134 }
00135 Bool_t isTH2=hist->IsA()->InheritsFrom(TH2::Class());
00136 Bool_t isTH3=hist->IsA()->InheritsFrom(TH3::Class());
00137 if (!isTH2 && !isTH3) {
00138 Warning("THStack", "Need a histogram deriving from TH2 or TH3.");
00139 return;
00140 }
00141
00142 if (!fName.Length())
00143 fName=Form("%s_stack%s", hist->GetName(), axis);
00144 if (!fTitle.Length()) {
00145 if (hist->GetTitle() && strlen(hist->GetTitle()))
00146 fTitle=Form("%s, stack of %s projections", hist->GetTitle(), axis);
00147 else
00148 fTitle=Form("stack of %s projections", axis);
00149 }
00150
00151 if (isTH2) {
00152 TH2* hist2=(TH2*) hist;
00153 Bool_t useX=(strchr(axis,'x')) || (strchr(axis,'X'));
00154 Bool_t useY=(strchr(axis,'y')) || (strchr(axis,'Y'));
00155 if ((!useX && !useY) || (useX && useY)) {
00156 Warning("THStack", "Need parameter axis=\"x\" or \"y\" for a TH2, not none or both.");
00157 return;
00158 }
00159 TAxis* haxis= useX ? hist->GetYaxis() : hist->GetXaxis();
00160 if (!haxis) {
00161 Warning("HStack","Histogram axis is NULL");
00162 return;
00163 }
00164 Int_t nbins = haxis->GetNbins();
00165 if (firstbin < 0) firstbin = 1;
00166 if (lastbin < 0) lastbin = nbins;
00167 if (lastbin > nbins+1) lastbin = nbins;
00168 for (Int_t iBin=firstbin; iBin<=lastbin; iBin++) {
00169 TH1* hProj=0;
00170 if (useX) hProj=hist2->ProjectionX(Form("%s_px%d",hist2->GetName(), iBin),
00171 iBin, iBin, proj_option);
00172 else hProj=hist2->ProjectionY(Form("%s_py%d",hist2->GetName(), iBin),
00173 iBin, iBin, proj_option);
00174 Add(hProj, draw_option);
00175 }
00176 } else {
00177
00178 TH3* hist3=(TH3*) hist;
00179 TString sAxis(axis);
00180 sAxis.ToLower();
00181 Int_t dim=3-sAxis.Length();
00182 if (dim<1 || dim>2) {
00183 Warning("THStack", "Invalid length for parameter axis.");
00184 return;
00185 }
00186
00187 if (dim==1) {
00188 TAxis* haxis = 0;
00189
00190 if (sAxis.First('x')==kNPOS)
00191 haxis=hist->GetXaxis();
00192 else if (sAxis.First('y')==kNPOS)
00193 haxis=hist->GetYaxis();
00194 else if (sAxis.First('z')==kNPOS)
00195 haxis=hist->GetZaxis();
00196 if (!haxis) {
00197 Warning("HStack","Histogram axis is NULL");
00198 return;
00199 }
00200
00201 Int_t nbins = haxis->GetNbins();
00202 if (firstbin < 0) firstbin = 1;
00203 if (lastbin < 0) lastbin = nbins;
00204 if (lastbin > nbins+1) lastbin = nbins;
00205 Int_t iFirstOld=haxis->GetFirst();
00206 Int_t iLastOld=haxis->GetLast();
00207 for (Int_t iBin=firstbin; iBin<=lastbin; iBin++) {
00208 haxis->SetRange(iBin, iBin);
00209
00210 TH1* hProj=hist3->Project3D(Form("%s_%s%s_%d", hist3->GetName(),
00211 axis, proj_option, iBin));
00212 Add(hProj, draw_option);
00213 }
00214 haxis->SetRange(iFirstOld, iLastOld);
00215 } else {
00216
00217 TAxis* haxis1 = 0;
00218 TAxis* haxis2 = 0;
00219
00220 if (sAxis.First('x')!=kNPOS) {
00221 haxis1=hist->GetYaxis();
00222 haxis2=hist->GetZaxis();
00223 } else if (sAxis.First('y')!=kNPOS) {
00224 haxis1=hist->GetXaxis();
00225 haxis2=hist->GetZaxis();
00226 } else if (sAxis.First('z')!=kNPOS) {
00227 haxis1=hist->GetXaxis();
00228 haxis2=hist->GetYaxis();
00229 }
00230 if (!haxis1 || !haxis2) {
00231 Warning("HStack","Histogram axis is NULL");
00232 return;
00233 }
00234
00235 Int_t nbins1 = haxis1->GetNbins();
00236 Int_t nbins2 = haxis2->GetNbins();
00237 if (firstbin < 0) firstbin = 1;
00238 if (lastbin < 0) lastbin = nbins1;
00239 if (lastbin > nbins1+1) lastbin = nbins1;
00240 if (firstbin2 < 0) firstbin2 = 1;
00241 if (lastbin2 < 0) lastbin2 = nbins2;
00242 if (lastbin2 > nbins2+1) lastbin2 = nbins2;
00243 Int_t iFirstOld1=haxis1->GetFirst();
00244 Int_t iLastOld1=haxis1->GetLast();
00245 Int_t iFirstOld2=haxis2->GetFirst();
00246 Int_t iLastOld2=haxis2->GetLast();
00247 for (Int_t iBin=firstbin; iBin<=lastbin; iBin++) {
00248 haxis1->SetRange(iBin, iBin);
00249 for (Int_t jBin=firstbin2; jBin<=lastbin2; jBin++) {
00250 haxis2->SetRange(jBin, jBin);
00251
00252 TH1* hProj=hist3->Project3D(Form("%s_%s%s_%d", hist3->GetName(),
00253 axis, proj_option, iBin));
00254 Add(hProj, draw_option);
00255 }
00256 }
00257 haxis1->SetRange(iFirstOld1, iLastOld1);
00258 haxis2->SetRange(iFirstOld2, iLastOld2);
00259 }
00260 }
00261 }
00262
00263
00264 THStack::~THStack()
00265 {
00266
00267
00268
00269 gROOT->GetListOfCleanups()->Remove(this);
00270 if (!fHists) return;
00271 fHists->Clear("nodelete");
00272 delete fHists;
00273 fHists = 0;
00274 if (fStack) {fStack->Delete(); delete fStack;}
00275 delete fHistogram;
00276 fHistogram = 0;
00277 }
00278
00279
00280 THStack::THStack(const THStack &hstack) :
00281 TNamed(hstack),
00282 fHists(0),
00283 fStack(0),
00284 fHistogram(0),
00285 fMaximum(hstack.fMaximum),
00286 fMinimum(hstack.fMinimum)
00287 {
00288
00289
00290 if (hstack.GetHists()) {
00291 TIter next(hstack.GetHists());
00292 TH1 *h;
00293 while ((h=(TH1*)next())) Add(h);
00294 }
00295 }
00296
00297
00298 void THStack::Add(TH1 *h1, Option_t *option)
00299 {
00300
00301
00302
00303
00304 if (!h1) return;
00305 if (h1->GetDimension() > 2) {
00306 Error("Add","THStack supports only 1-d and 2-d histograms");
00307 return;
00308 }
00309 if (!fHists) fHists = new TList();
00310 fHists->Add(h1,option);
00311 Modified();
00312 }
00313
00314
00315 void THStack::Browse(TBrowser *b)
00316 {
00317
00318
00319 Draw(b ? b->GetDrawOption() : "");
00320 gPad->Update();
00321 }
00322
00323
00324 void THStack::BuildStack()
00325 {
00326
00327
00328
00329 if (fStack) return;
00330 if (!fHists) return;
00331 Int_t nhists = fHists->GetSize();
00332 if (!nhists) return;
00333 fStack = new TObjArray(nhists);
00334 Bool_t add = TH1::AddDirectoryStatus();
00335 TH1::AddDirectory(kFALSE);
00336 TH1 *h = (TH1*)fHists->At(0)->Clone();
00337 fStack->Add(h);
00338 for (Int_t i=1;i<nhists;i++) {
00339 h = (TH1*)fHists->At(i)->Clone();
00340 h->Add((TH1*)fStack->At(i-1));
00341 fStack->AddAt(h,i);
00342 }
00343 TH1::AddDirectory(add);
00344 }
00345
00346
00347 Int_t THStack::DistancetoPrimitive(Int_t px, Int_t py)
00348 {
00349
00350
00351
00352
00353 const Int_t kMaxDiff = 10;
00354 Int_t distance = 9999;
00355 if (fHistogram) {
00356 distance = fHistogram->DistancetoPrimitive(px,py);
00357 if (distance <= 0) {return distance;}
00358 if (distance <= 1) {gPad->SetSelected(fHistogram);return distance;}
00359 }
00360
00361
00362
00363 if (!fHists) return distance;
00364 TH1 *h = 0;
00365 const char *doption = GetDrawOption();
00366 Int_t nhists = fHists->GetSize();
00367 for (Int_t i=0;i<nhists;i++) {
00368 h = (TH1*)fHists->At(i);
00369 if (fStack && !strstr(doption,"nostack")) h = (TH1*)fStack->At(i);
00370 Int_t dist = h->DistancetoPrimitive(px,py);
00371 if (dist <= 0) return 0;
00372 if (dist < kMaxDiff) {
00373 gPad->SetSelected(fHists->At(i));
00374 gPad->SetCursor(kPointer);
00375 return dist;
00376 }
00377 }
00378 return distance;
00379 }
00380
00381
00382 void THStack::Draw(Option_t *option)
00383 {
00384
00385
00386
00387
00388
00389
00390 TString opt = option;
00391 opt.ToLower();
00392 if (gPad) {
00393 if (!gPad->IsEditable()) gROOT->MakeDefCanvas();
00394 if (!opt.Contains("same")) {
00395
00396
00397 if (TestBit(kCanDelete)) gPad->GetListOfPrimitives()->Remove(this);
00398 gPad->Clear();
00399 }
00400 }
00401 AppendPad(opt.Data());
00402 }
00403
00404
00405 TH1 *THStack::GetHistogram() const
00406 {
00407
00408
00409
00410
00411
00412
00413
00414
00415
00416 if (fHistogram) return fHistogram;
00417 if (!gPad) return 0;
00418 gPad->Modified();
00419 gPad->Update();
00420 if (fHistogram) return fHistogram;
00421 TH1 *h1 = (TH1*)gPad->FindObject("hframe");
00422 return h1;
00423 }
00424
00425
00426 Double_t THStack::GetMaximum(Option_t *option)
00427 {
00428
00429
00430
00431 TString opt = option;
00432 opt.ToLower();
00433 Bool_t lerr = kFALSE;
00434 if (opt.Contains("e")) lerr = kTRUE;
00435 Double_t them=0, themax = -1e300, c1, e1;
00436 if (!fHists) return 0;
00437 Int_t nhists = fHists->GetSize();
00438 TH1 *h;
00439 Int_t first,last;
00440
00441 if (!opt.Contains("nostack")) {
00442 BuildStack();
00443 h = (TH1*)fStack->At(nhists-1);
00444 themax = h->GetMaximum();
00445 } else {
00446 for (Int_t i=0;i<nhists;i++) {
00447 h = (TH1*)fHists->At(i);
00448 them = h->GetMaximum();
00449 if (them > themax) themax = them;
00450 }
00451 }
00452
00453 if (lerr) {
00454 for (Int_t i=0;i<nhists;i++) {
00455 h = (TH1*)fHists->At(i);
00456 first = h->GetXaxis()->GetFirst();
00457 last = h->GetXaxis()->GetLast();
00458 for (Int_t j=first; j<=last;j++) {
00459 e1 = h->GetBinError(j);
00460 c1 = h->GetBinContent(j);
00461 themax = TMath::Max(themax,c1+e1);
00462 }
00463 }
00464 }
00465
00466 return themax;
00467 }
00468
00469
00470 Double_t THStack::GetMinimum(Option_t *option)
00471 {
00472
00473
00474
00475 TString opt = option;
00476 opt.ToLower();
00477 Bool_t lerr = kFALSE;
00478 if (opt.Contains("e")) lerr = kTRUE;
00479 Double_t them=0, themin = 1e300, c1, e1;
00480 if (!fHists) return 0;
00481 Int_t nhists = fHists->GetSize();
00482 Int_t first,last;
00483 TH1 *h;
00484
00485 if (!opt.Contains("nostack")) {
00486 BuildStack();
00487 h = (TH1*)fStack->At(nhists-1);
00488 themin = h->GetMinimum();
00489 } else {
00490 for (Int_t i=0;i<nhists;i++) {
00491 h = (TH1*)fHists->At(i);
00492 them = h->GetMinimum();
00493 if (them <= 0 && gPad && gPad->GetLogy()) them = h->GetMinimum(0);
00494 if (them < themin) themin = them;
00495 }
00496 }
00497
00498 if (lerr) {
00499 for (Int_t i=0;i<nhists;i++) {
00500 h = (TH1*)fHists->At(i);
00501 first = h->GetXaxis()->GetFirst();
00502 last = h->GetXaxis()->GetLast();
00503 for (Int_t j=first; j<=last;j++) {
00504 e1 = h->GetBinError(j);
00505 c1 = h->GetBinContent(j);
00506 themin = TMath::Min(themin,c1-e1);
00507 }
00508 }
00509 }
00510
00511 return themin;
00512 }
00513
00514
00515 TObjArray *THStack::GetStack()
00516 {
00517
00518
00519 BuildStack();
00520 return fStack;
00521 }
00522
00523
00524 TAxis *THStack::GetXaxis() const
00525 {
00526
00527
00528
00529
00530
00531
00532 if (!gPad) return 0;
00533 TH1 *h = GetHistogram();
00534 if (!h) return 0;
00535 return h->GetXaxis();
00536 }
00537
00538
00539 TAxis *THStack::GetYaxis() const
00540 {
00541
00542
00543
00544
00545
00546
00547 if (!gPad) return 0;
00548 TH1 *h = GetHistogram();
00549 if (!h) return 0;
00550 return h->GetYaxis();
00551 }
00552
00553
00554 void THStack::ls(Option_t *option) const
00555 {
00556
00557
00558 TROOT::IndentLevel();
00559 cout <<IsA()->GetName()
00560 <<" Name= "<<GetName()<<" Title= "<<GetTitle()<<" Option="<<option<<endl;
00561 TROOT::IncreaseDirLevel();
00562 if (fHists) fHists->ls(option);
00563 TROOT::DecreaseDirLevel();
00564 }
00565
00566
00567 void THStack::Modified()
00568 {
00569
00570
00571 if (!fStack) return;
00572 fStack->Delete();
00573 delete fStack;
00574 fStack = 0;
00575 delete fHistogram;
00576 fHistogram = 0;
00577 }
00578
00579
00580 void THStack::Paint(Option_t *option)
00581 {
00582
00583
00584
00585
00586
00587
00588
00589
00590
00591
00592
00593
00594
00595
00596 if (!fHists) return;
00597 if (!fHists->GetSize()) return;
00598
00599 TString opt = option;
00600 opt.ToLower();
00601 Bool_t lsame = kFALSE;
00602 if (opt.Contains("same")) {
00603 lsame = kTRUE;
00604 opt.ReplaceAll("same","");
00605 }
00606 if (opt.Contains("pads")) {
00607 Int_t npads = fHists->GetSize();
00608 TVirtualPad *padsav = gPad;
00609
00610 Int_t nps = 0;
00611 TObject *obj;
00612 TIter nextp(padsav->GetListOfPrimitives());
00613 while ((obj = nextp())) {
00614 if (obj->InheritsFrom(TVirtualPad::Class())) nps++;
00615 }
00616 if (nps < npads) {
00617 padsav->Clear();
00618 Int_t nx = (Int_t)TMath::Sqrt((Double_t)npads);
00619 if (nx*nx < npads) nx++;
00620 Int_t ny = nx;
00621 if (((nx*ny)-nx) >= npads) ny--;
00622 padsav->Divide(nx,ny);
00623 }
00624 TH1 *h;
00625 Int_t i = 0;
00626 TObjOptLink *lnk = (TObjOptLink*)fHists->FirstLink();
00627 while (lnk) {
00628 i++;
00629 padsav->cd(i);
00630 h = (TH1*)lnk->GetObject();
00631 h->Draw(lnk->GetOption());
00632 lnk = (TObjOptLink*)lnk->Next();
00633 }
00634 padsav->cd();
00635 return;
00636 }
00637
00638
00639 TH1 *h;
00640 TIter next(fHists);
00641 Double_t xmin = 1e100;
00642 Double_t xmax = -xmin;
00643 Double_t ymin = 1e100;
00644 Double_t ymax = -xmin;
00645 while ((h=(TH1*)next())) {
00646 if (h->GetXaxis()->GetXmin() < xmin) xmin = h->GetXaxis()->GetXmin();
00647 if (h->GetXaxis()->GetXmax() > xmax) xmax = h->GetXaxis()->GetXmax();
00648 if (h->GetYaxis()->GetXmin() < ymin) ymin = h->GetYaxis()->GetXmin();
00649 if (h->GetYaxis()->GetXmax() > ymax) ymax = h->GetYaxis()->GetXmax();
00650 }
00651
00652 char loption[32];
00653 snprintf(loption,31,"%s",opt.Data());
00654 char *nostack = strstr(loption,"nostack");
00655
00656
00657
00658
00659 if (!opt.Contains("nostack")) BuildStack();
00660
00661 Double_t themax,themin;
00662 if (fMaximum == -1111) themax = GetMaximum(option);
00663 else themax = fMaximum;
00664 if (fMinimum == -1111) {
00665 themin = GetMinimum(option);
00666 if (gPad->GetLogy()){
00667 if (themin>0) themin *= .9;
00668 else themin = themax*1.e-3;
00669 }
00670 else if (themin > 0)
00671 themin = 0;
00672 }
00673 else themin = fMinimum;
00674 if (!fHistogram) {
00675 Bool_t add = TH1::AddDirectoryStatus();
00676 TH1::AddDirectory(kFALSE);
00677 h = (TH1*)fHists->At(0);
00678 TAxis *xaxis = h->GetXaxis();
00679 TAxis *yaxis = h->GetYaxis();
00680 if (h->GetDimension() > 1) {
00681 if (strlen(option) == 0) strlcpy(loption,"lego1",32);
00682 const TArrayD *xbins = xaxis->GetXbins();
00683 const TArrayD *ybins = yaxis->GetXbins();
00684 if (xbins->fN != 0 && ybins->fN != 0) {
00685 fHistogram = new TH2F(GetName(),GetTitle(),
00686 xaxis->GetNbins(), xbins->GetArray(),
00687 yaxis->GetNbins(), ybins->GetArray());
00688 } else if (xbins->fN != 0 && ybins->fN == 0) {
00689 fHistogram = new TH2F(GetName(),GetTitle(),
00690 xaxis->GetNbins(), xbins->GetArray(),
00691 yaxis->GetNbins(), ymin, ymax);
00692 } else if (xbins->fN == 0 && ybins->fN != 0) {
00693 fHistogram = new TH2F(GetName(),GetTitle(),
00694 xaxis->GetNbins(), xmin, xmax,
00695 yaxis->GetNbins(), ybins->GetArray());
00696 } else {
00697 fHistogram = new TH2F(GetName(),GetTitle(),
00698 xaxis->GetNbins(), xmin, xmax,
00699 yaxis->GetNbins(), ymin, ymax);
00700 }
00701 } else {
00702 fHistogram = new TH1F(GetName(),GetTitle(),xaxis->GetNbins(),xmin, xmax);
00703 }
00704 fHistogram->SetStats(0);
00705 TH1::AddDirectory(add);
00706 } else {
00707 fHistogram->SetTitle(GetTitle());
00708 }
00709
00710 if (nostack) {*nostack = 0; strncat(nostack,nostack+7,7);}
00711
00712 else fHistogram->GetPainter()->SetStack(fHists);
00713
00714 if (!fHistogram->TestBit(TH1::kIsZoomed)) {
00715 if (nostack && fMaximum != -1111) fHistogram->SetMaximum(fMaximum);
00716 else {
00717 if (gPad->GetLogy()) fHistogram->SetMaximum(themax*(1+0.2*TMath::Log10(themax/themin)));
00718 else fHistogram->SetMaximum((1+gStyle->GetHistTopMargin())*themax);
00719 }
00720 if (nostack && fMinimum != -1111) fHistogram->SetMinimum(fMinimum);
00721 else {
00722 if (gPad->GetLogy()) fHistogram->SetMinimum(themin/(1+0.5*TMath::Log10(themax/themin)));
00723 else fHistogram->SetMinimum(themin);
00724 }
00725 }
00726
00727
00728 TH1 *hfirst;
00729 TObjOptLink *lnk = (TObjOptLink*)fHists->FirstLink();
00730 hfirst = (TH1*)lnk->GetObject();
00731 THashList* labels = hfirst->GetXaxis()->GetLabels();
00732 if (labels) {
00733 TIter iL(labels);
00734 TObjString* lb;
00735 Int_t ilab = 1;
00736 while ((lb=(TObjString*)iL())) {
00737 fHistogram->GetXaxis()->SetBinLabel(ilab,lb->String().Data());
00738 ilab++;
00739 }
00740 }
00741
00742 if (!lsame) fHistogram->Paint(loption);
00743
00744 if (fHistogram->GetDimension() > 1) SetDrawOption(loption);
00745 if (strstr(loption,"lego")) return;
00746
00747 char noption[32];
00748 strlcpy(noption,loption,32);
00749 Int_t nhists = fHists->GetSize();
00750 if (nostack) {
00751 lnk = (TObjOptLink*)fHists->FirstLink();
00752 for (Int_t i=0;i<nhists;i++) {
00753 if (strstr(lnk->GetOption(),"same")) {
00754 snprintf(loption,31,"%s%s",noption,lnk->GetOption());
00755 } else {
00756 snprintf(loption,31,"%ssame%s",noption,lnk->GetOption());
00757 }
00758 fHists->At(i)->Paint(loption);
00759 lnk = (TObjOptLink*)lnk->Next();
00760 }
00761 } else {
00762 lnk = (TObjOptLink*)fHists->LastLink();
00763 TH1 *h1;
00764 Int_t h1col, h1fill;
00765 for (Int_t i=0;i<nhists;i++) {
00766 if (strstr(lnk->GetOption(),"same")) {
00767 snprintf(loption,31,"%s%s",noption,lnk->GetOption());
00768 } else {
00769 snprintf(loption,31,"%ssame%s",noption,lnk->GetOption());
00770 }
00771 h1 = (TH1*)fStack->At(nhists-i-1);
00772 if (i>0) {
00773
00774 h1col = h1->GetFillColor();
00775 h1fill = h1->GetFillStyle();
00776 h1->SetFillColor(0);
00777 h1->SetFillStyle(1001);
00778 h1->Paint(loption);
00779 static TClassRef clTFrame = TClass::GetClass("TFrame",kFALSE);
00780 TAttFill *frameFill = (TAttFill*)clTFrame->DynamicCast(TAttFill::Class(),gPad->GetFrame());
00781 h1->SetFillColor(frameFill->GetFillColor());
00782 h1->SetFillStyle(frameFill->GetFillStyle());
00783 h1->Paint(loption);
00784 h1->SetFillColor(h1col);
00785 h1->SetFillStyle(h1fill);
00786 }
00787 h1->Paint(loption);
00788 lnk = (TObjOptLink*)lnk->Prev();
00789 }
00790 }
00791 if (!lsame) fHistogram->Paint("axissame");
00792 }
00793
00794
00795 void THStack::Print(Option_t *option) const
00796 {
00797
00798
00799 TH1 *h;
00800 if (fHists) {
00801 TIter next(fHists);
00802 while ((h = (TH1*) next())) {
00803 h->Print(option);
00804 }
00805 }
00806 }
00807
00808
00809 void THStack::RecursiveRemove(TObject *obj)
00810 {
00811
00812
00813 if (!fHists) return;
00814 fHists->RecursiveRemove(obj);
00815 while (fHists->IndexOf(obj) >= 0) fHists->Remove(obj);
00816 }
00817
00818
00819 void THStack::SavePrimitive(ostream &out, Option_t *option )
00820 {
00821
00822
00823 char quote = '"';
00824 out<<" "<<endl;
00825 if (gROOT->ClassSaved(THStack::Class())) {
00826 out<<" ";
00827 } else {
00828 out<<" THStack *";
00829 }
00830 out<<GetName()<<" = new THStack();"<<endl;
00831 out<<" "<<GetName()<<"->SetName("<<quote<<GetName()<<quote<<");"<<endl;
00832 out<<" "<<GetName()<<"->SetTitle("<<quote<<GetTitle()<<quote<<");"<<endl;
00833
00834 if (fMinimum != -1111) {
00835 out<<" "<<GetName()<<"->SetMinimum("<<fMinimum<<");"<<endl;
00836 }
00837 if (fMaximum != -1111) {
00838 out<<" "<<GetName()<<"->SetMaximum("<<fMaximum<<");"<<endl;
00839 }
00840
00841 static Int_t frameNumber = 0;
00842 if (fHistogram) {
00843 frameNumber++;
00844 TString hname = fHistogram->GetName();
00845 hname += frameNumber;
00846 fHistogram->SetName(hname.Data());
00847 fHistogram->SavePrimitive(out,"nodraw");
00848 out<<" "<<GetName()<<"->SetHistogram("<<fHistogram->GetName()<<");"<<endl;
00849 out<<" "<<endl;
00850 }
00851
00852 TH1 *h;
00853 if (fHists) {
00854 TObjOptLink *lnk = (TObjOptLink*)fHists->FirstLink();
00855 while (lnk) {
00856 h = (TH1*)lnk->GetObject();
00857 h->SavePrimitive(out,"nodraw");
00858 out<<" "<<GetName()<<"->Add("<<h->GetName()<<","<<quote<<lnk->GetOption()<<quote<<");"<<endl;
00859 lnk = (TObjOptLink*)lnk->Next();
00860 }
00861 }
00862 out<<" "<<GetName()<<"->Draw("
00863 <<quote<<option<<quote<<");"<<endl;
00864 }
00865
00866
00867 void THStack::SetMaximum(Double_t maximum)
00868 {
00869
00870
00871 fMaximum = maximum;
00872 if (fHistogram) fHistogram->SetMaximum(maximum);
00873 }
00874
00875
00876 void THStack::SetMinimum(Double_t minimum)
00877 {
00878
00879
00880 fMinimum = minimum;
00881 if (fHistogram) fHistogram->SetMinimum(minimum);
00882 }