]> git.uio.no Git - u/mrichter/AliRoot.git/blob - PWGLF/FORWARD/analysis2/scripts/SummarydNdetaDrawer.C
Fixed up scripts to use same flags for Pause and Landscape.
[u/mrichter/AliRoot.git] / PWGLF / FORWARD / analysis2 / scripts / SummarydNdetaDrawer.C
1 #include "SummaryDrawer.C"
2 #include <TPaveText.h>
3 #include <TMultiGraph.h>
4
5 class SummarydNdetaDrawer : public SummaryDrawer
6 {
7 public:
8   enum { 
9     kForward   = 0x01,
10     kCentral   = 0x02, 
11     kSums      = 0x04, 
12     kResults   = 0x08, 
13     kMinBias   = 0x10, 
14     kMC        = 0x80,
15     kNormal    = 0x0F
16   };
17   SummarydNdetaDrawer() 
18     : SummaryDrawer()
19   {}
20   //____________________________________________________________________
21   void Run(const char* fname="forward_dndeta.root", UShort_t flags=kNormal)
22   {
23     // --- Open the file -----------------------------------------------
24     TString filename(fname);
25     TFile* file = TFile::Open(filename.Data(), "READ");
26     if (!file) { 
27       Error("Run", "Failed to open \"%s\"", filename.Data());
28       return;
29     }
30     // Options 
31     Bool_t forward = flags & kForward;
32     Bool_t central = flags & kCentral;
33     Bool_t sums    = flags & kSums;
34     Bool_t results = flags & kResults;
35     Bool_t onlyMB  = flags & kMinBias;
36     Bool_t mc      = flags & kMC;
37     fPause         = flags & kPause;
38     
39     // --- Force MB for pp ---------------------------------------------
40     UShort_t     sys = 0;
41     TCollection* c   = GetCollection(file, "ForwardSums");
42     GetParameter(c, "sys", sys); 
43     if (sys == 1) onlyMB = true;
44
45     // --- Test of MC --------------------------------------------------
46     TCollection* mcC = GetCollection(file, "MCTruthSums", false);
47     if (mcC) { 
48       TCollection* mcAll = GetCollection(mcC, "all");
49       if (mcAll && GetObject(mcAll, "MCTruth"))
50         mc = true;
51     }
52     // --- Make our canvas ---------------------------------------------
53     TString pdfName(filename);
54     pdfName.ReplaceAll(".root", ".pdf");
55     CreateCanvas(pdfName, flags & kLandscape);
56
57     // --- Make a Title page -------------------------------------------
58     DrawTitlePage(file, mc, onlyMB);
59
60     // --- Do each sub-algorithm ---------------------------------------
61     THStack* rF = 0;
62     if (forward && sums)    DrawSums(file, "Forward", onlyMB);
63     if (forward && results) rF = DrawRes(file, "Forward", onlyMB);
64     
65     THStack* rC = 0;
66     if (central && sums)    DrawSums(file, "Central", onlyMB);
67     if (central && results) rC = DrawRes(file, "Central", onlyMB);
68
69     THStack* rM = 0;
70     if (mc && sums)    DrawSums(file, "MCTruth", onlyMB);
71     if (mc && results) rM = DrawRes(file, "MCTruth", onlyMB);
72
73     if (rC && rF && results) DrawBoth(rC, rF, rM, file, onlyMB);
74   
75     CloseCanvas();
76   }
77
78 protected:
79   //____________________________________________________________________
80   TCollection* GetCentCollection(const TCollection* sums, 
81                                  const TString&     base, 
82                                  Int_t              cLow, 
83                                  Int_t              cHigh,
84                                  TString&           title)
85   {
86     TString folder; 
87     title = TString::Format("%s %s: ", base.Data(), title.Data());
88     if (cLow < 0 || cHigh < 0 || cLow >= cHigh) {
89       folder = "all";
90       title.Append("All selected events");
91       cHigh  *= -1;
92     }
93     else {
94       folder.Form("cent%03d_%03d", cLow, cHigh);
95       title.Append(Form("%3d%% - %3d%%", cLow, cHigh));
96     }
97     
98     return GetCollection(sums, folder);
99     
100   }
101   //____________________________________________________________________
102   void DrawTitlePage(TFile* file, Bool_t mc, Bool_t onlyMB)
103   {
104     TCollection* c   = GetCollection(file, "ForwardResults");
105
106     fBody->cd();
107     
108     Double_t y = .9;
109     TLatex* ltx = new TLatex(.5, y, 
110                              "#frac{1}{#it{N}}#kern[.1]"
111                              "{#frac{d#it{N_{ch}}}{d#it{#eta}}}");
112     ltx->SetTextSize(0.07);
113     ltx->SetTextFont(42);
114     ltx->SetTextAlign(22);
115     ltx->SetNDC();
116     ltx->Draw();
117     y -= .075;
118     
119     if (mc) {
120       ltx = new TLatex(.5, y, "Simulation input");
121       ltx->SetNDC();
122       ltx->SetTextAlign(23);
123       ltx->SetTextFont(42);
124       ltx->SetTextSize(.03);
125       ltx->Draw();
126       y -= .035;
127     }
128     if (onlyMB) {
129       ltx = new TLatex(.5, y, "No centrality");
130       ltx->SetNDC();
131       ltx->SetTextAlign(23);
132       ltx->SetTextFont(42);
133       ltx->SetTextSize(.03);
134       ltx->Draw();
135       y -= .035;
136     }
137     
138     DrawResTitle(c, y, onlyMB);
139
140     PrintCanvas("1/N dN/d#eta");
141   }
142   //____________________________________________________________________
143   void DrawBoth(THStack* rC, THStack* rF, THStack* rM, 
144                 TFile* file, Bool_t onlyMB)
145   {
146     fBody->cd();
147     Double_t y1 = fLandscape ? 0  : .3;
148     Double_t x2 = fLandscape ? .7 : 1;
149     Double_t x1 = fLandscape ? x2 : 0;
150     Double_t y2 = fLandscape ? 1  : y1;
151     TPad* p1 = new TPad("p1", "p1", 0,  y1, x2, 1,  0, 0);
152     TPad* p2 = new TPad("p2", "p2", x1, 0,  1,  y2, 0, 0);
153
154     fBody->cd();
155     p1->Draw();
156     p1->cd();
157
158     TH1*  h  = 0;
159     if (rM) { 
160       TIter nextM(rM->GetHists());
161       while ((h = static_cast<TH1*>(nextM()))) rC->Add(h);
162     }
163
164     TIter next(rF->GetHists());
165     while ((h = static_cast<TH1*>(next()))) rC->Add(h);
166
167
168     rC->Draw("nostack");
169
170     TCollection* fS = GetCollection(file, "ForwardSums");
171     Int_t sys, sNN, trigger;
172     GetParameter(fS, "sNN",     sNN); 
173     GetParameter(fS, "sys",     sys); 
174     GetParameter(fS, "trigger", trigger); 
175     TAxis* centAxis = 
176       static_cast<TAxis*>(GetObject(fS, "centAxis", false));
177     UShort_t cLow  = centAxis && !onlyMB ? centAxis->GetXmin() : 0;
178     UShort_t cHigh = centAxis && !onlyMB ? centAxis->GetXmax() : 100;
179
180     TString savPath(gROOT->GetMacroPath());
181     gROOT->SetMacroPath(Form("%s:$(ALICE_ROOT)/PWGLF/FORWARD/analysis2",
182                              gROOT->GetMacroPath()));
183     // Always recompile 
184     if (!gROOT->GetClass("RefData"))
185       gROOT->LoadMacro("OtherData.C++");
186     gROOT->SetMacroPath(savPath);
187
188     // If we have V0AND trigger, get NSD other data
189     Int_t   oT = (trigger == 0x2000) ? 0x4 : trigger;
190     TString oC = Form("RefData::GetData(%hu,%hu,%hu,%hu,%hu,0xF)", 
191                       sys, sNN, oT, cLow, cHigh);
192     TMultiGraph* other = 
193       reinterpret_cast<TMultiGraph*>(gROOT->ProcessLine(oC));
194     if (other) {
195       // p1->Clear();
196       // other->Draw("ap");
197       // Double_t oMax = other->GetHistogram()->GetMaximum();
198       // Double_t rMax = rC->GetMaximum("nostack");
199       // other->SetMaximum(1.2*TMath::Max(oMax, rMax));
200       // rC->Draw("same nostack");
201       TObject* g = 0;
202       TIter    nextG(other->GetListOfGraphs());
203       while ((g = nextG()))
204         g->DrawClone("same p");
205     }
206
207     fBody->cd();
208     p2->Draw();
209     p2->cd();
210
211
212     TLegend* l = new TLegend(0.01, 0.1, 0.99, 0.99, 
213                              onlyMB || !centAxis ? "" : "Centralities");
214     l->SetNColumns(fLandscape ? 1 : 2);
215     l->SetFillStyle(0);
216     l->SetBorderSize(0);
217     CleanStack(rC, l, onlyMB ? 0 : centAxis);
218     if (other) { 
219       TIter nextG(other->GetListOfGraphs());
220       TObject* g = 0;
221       while ((g = nextG())) 
222         l->AddEntry(g, g->GetTitle(), "p");
223     }
224     l->Draw();
225
226     PrintCanvas("Both");
227   }
228   //____________________________________________________________________
229   void DrawSums(TDirectory* top, const TString& base, bool onlyMB)
230   {
231     TCollection* c = GetCollection(top, Form("%sSums", base.Data()));
232     if (!c) return;
233     
234     TAxis* centAxis = static_cast<TAxis*>(GetObject(c, "centAxis", false));
235
236     Int_t   txtPad = 0;
237     Double_t save  = fParName->GetTextSize();
238     Double_t xSave = fParVal->GetX();
239     fParName->SetTextSize(0.03);
240     fParVal->SetTextSize(0.03);
241     fParVal->SetX(.45);
242     Double_t y = .8;
243     
244     if (!onlyMB && centAxis) {
245       fBody->Divide(1, 2);
246       txtPad = 1;
247     
248       fBody->cd(1);
249       for (Int_t i = 1; i <= centAxis->GetNbins(); i++) { 
250         DrawParameter(y, (i == 1 ? "Centrality classes" : ""),
251                       Form("%3d%% - %3d%%", 
252                            Int_t(centAxis->GetBinLowEdge(i)), 
253                            Int_t(centAxis->GetBinUpEdge(i))));
254       }
255     
256       TH1* cent = GetH1(c, "cent");
257       cent->SetFillColor(kRed+1);
258       cent->SetFillStyle(3001);
259       cent->SetXTitle("Centrality [%]");
260       cent->SetYTitle("Events");
261       
262       DrawInPad(fBody, 2, cent);
263     }
264     fBody->cd(txtPad);
265     
266     Int_t sys, sNN, scheme, trigger;
267     GetParameter(c, "sNN",     sNN); 
268     GetParameter(c, "sys",     sys); 
269     GetParameter(c, "scheme",  scheme); 
270     GetParameter(c, "trigger", trigger); 
271
272     TString schemeString;
273     if (scheme == 0)   schemeString = "1/N_{accepted}";
274     if (scheme & 0x1)  schemeString.Append("1/#epsilon_{V}1/#epsilon_{T}");
275     if (scheme & 0x2)  schemeString.Append("Shape ");
276     if (scheme & 0x4)  schemeString.Append("A+C-E ");
277     if (scheme & 0x8)  schemeString.Append("#epsilon_{T,MC} ");
278     if (scheme & 0x10) schemeString.Append("0-bin");
279
280     TString trigString;   TriggerString(trigger, trigString);
281     TString sysString;    SysString(sys, sysString);
282     TString sNNString;    SNNString(sNN, sNNString);
283     
284     DrawParameter(y, "Collision system",     sysString);
285     DrawParameter(y, "#sqrt{s_{NN}}",        sNNString);
286     DrawParameter(y, "Normalization scheme", schemeString);
287     DrawParameter(y, "Triggers",             trigString);
288     
289     fParName->SetTextSize(save);
290     fParVal->SetTextSize(save);
291     fParVal->SetX(xSave);
292
293     PrintCanvas(Form("%s sums", base.Data()));
294
295     Int_t cLow = centAxis  ?  centAxis->GetXmin() : 0;
296     Int_t cHigh = centAxis ? -centAxis->GetXmax() : -100;
297     DrawCentSum(c, base, cLow, cHigh);
298     if (onlyMB || !centAxis) return;
299
300     for (Int_t i = 1; i <= centAxis->GetNbins(); i++) 
301       DrawCentSum(c, base, centAxis->GetBinLowEdge(i), 
302                   centAxis->GetBinUpEdge(i));
303   }
304   //____________________________________________________________________
305   void DrawCentSum(const TCollection* sums, const TString& base, 
306                    Int_t cLow, Int_t cHigh)
307   {
308     TString title("sums");
309     TCollection* c = GetCentCollection(sums, base, cLow, cHigh, title);
310     if (!c) return;
311     
312     TH1* type = GetH1(c, Form("%sEvents",base.Data()));
313     TH2* bin0 = GetH2(c, Form("%s0", base.Data()));
314     TH1* trig = GetH1(c, "triggers");
315     TH2* bin  = GetH2(c, base.Data());
316     if (!bin0 || !bin || !trig || !type) return;
317
318     type->SetFillStyle(3001);
319     type->SetFillColor(kGreen+1);
320
321     fBody->Divide(2, 2);
322
323     DrawInPad(fBody, 1, trig, "HIST TEXT");
324     DrawInPad(fBody, 2, type, "HIST TEXT");
325     DrawInPad(fBody, 3, bin,  "colz");
326     DrawInPad(fBody, 4, bin0, "colz");
327     
328     if (bin0->GetEntries() <= 0) {
329       fBody->cd(4);
330       TLatex* l = new TLatex(0.5, 0.5, "No 0-bin events");
331       l->SetNDC();
332       l->SetTextAlign(22);
333       l->Draw();
334     }
335     PrintCanvas(title);
336   }
337   //____________________________________________________________________
338   void DrawResTitle(TCollection* c, Double_t& y, Bool_t onlyMB)
339   {
340     Double_t save  = fParName->GetTextSize();
341     Double_t xSave = fParVal->GetX();
342     fParName->SetTextSize(0.03);
343     fParVal->SetTextSize(0.03);
344     fParVal->SetX(.5);
345     // Double_t y = .9;
346     TAxis*   centAxis = static_cast<TAxis*>(GetObject(c, "centAxis", false));
347     if (!onlyMB && centAxis) {
348       for (Int_t i = 1; i <= centAxis->GetNbins(); i++) { 
349         DrawParameter(y, (i == 1 ? "Centrality classes" : ""),
350                       Form("%3d%% - %3d%%", 
351                            Int_t(centAxis->GetBinLowEdge(i)), 
352                            Int_t(centAxis->GetBinUpEdge(i))));
353       }
354     }
355     TObject* oSNN = GetObject(c, "sNN");
356     TString  tSNN; SNNString(oSNN->GetUniqueID(), tSNN);
357
358     DrawParameter(y, "Collision system", GetObject(c, "sys")->GetTitle());
359     DrawParameter(y, "#sqrt{s_{NN}}",tSNN);
360     DrawParameter(y, "Trigger",GetObject(c,"trigger")->GetTitle());
361     TObject* oscheme = GetObject(c,"scheme");
362     TString  scheme  = oscheme->GetTitle();
363     if (scheme.IsNull()) scheme = "1/N_{accepted}";
364     DrawParameter(y, "Normalization scheme", scheme);
365     
366     Double_t epsT, epsT0;
367     GetParameter(c, "triggerEff",  epsT);
368     GetParameter(c, "triggerEff0", epsT0);
369     DrawParameter(y, "#epsilon_{T}", Form("%5.3f", epsT));
370     DrawParameter(y, "#epsilon_{T,zero bin}", Form("%5.3f", epsT0));
371
372     TObject*    options = GetObject(c, "options");
373     TString     opts(options->GetTitle());
374     TObjArray*  tokens = opts.Tokenize(",");
375     TObjString* opt = 0;;
376     TIter       oNext(tokens);
377     Bool_t      first  = true;
378     while ((opt = static_cast<TObjString*>(oNext()))) { 
379       DrawParameter(y, (first ? "options" : ""), 
380                     opt->String().Strip(TString::kBoth));
381       first = false;
382     }
383     fParName->SetTextSize(save);
384     fParVal->SetTextSize(save);
385     fParVal->SetX(xSave);      
386   }
387
388   //____________________________________________________________________
389   THStack* DrawRes(TDirectory* top, const TString& base, Bool_t onlyMB)
390   {
391     TCollection* c = GetCollection(top, Form("%sResults", base.Data()));
392     if (!c) return 0;
393
394     fBody->cd();
395     Double_t y = .9;
396     DrawResTitle(c, y, onlyMB);
397     PrintCanvas(Form("%s results", base.Data()));
398
399     TAxis*   centAxis = static_cast<TAxis*>(GetObject(c, "centAxis", false));
400     TLegend* l = new TLegend(0.1, 0.1, 0.9, 0.9, 
401                              onlyMB || !centAxis? "" : "Centralities");
402     l->SetNColumns(2);
403     l->SetFillStyle(0);
404     l->SetBorderSize(0);
405
406     THStack* dndeta_  = GetStack(c, "dndeta");
407     THStack* dndeta5_ = GetStack(c, "dndeta_rebin05");
408     THStack* dndeta   = CleanStack(dndeta_, l, centAxis);
409     THStack* dndeta5  = CleanStack(dndeta5_, 0, 0);
410
411     if (!onlyMB) {
412       fBody->Divide(1, 3, 0, 0);
413       
414       DrawInPad(fBody, 1, l, "");
415       DrawInPad(fBody, 2, dndeta,  "nostack");
416       DrawInPad(fBody, 3, dndeta5, "nostack");
417       fBody->GetPad(2)->SetGridx();
418       fBody->GetPad(3)->SetGridx();
419       
420       PrintCanvas(Form("%s results - stacks", base.Data()));
421     }
422
423     Int_t cLow = centAxis  ?  centAxis->GetXmin() : 0;
424     Int_t cHigh = centAxis ? -centAxis->GetXmax() : -100;
425     DrawCentRes(c, base, cLow, cHigh);
426     if (onlyMB || !centAxis) {
427       Info("", "Returning dndeta for MB");
428       dndeta = MakeMBStack(c, base);
429       return dndeta;
430     }
431
432     for (Int_t i = 1; i <= centAxis->GetNbins(); i++) 
433       DrawCentRes(c, base, centAxis->GetBinLowEdge(i), 
434                   centAxis->GetBinUpEdge(i));
435     
436     return dndeta;
437   }
438   //____________________________________________________________________
439   THStack* MakeMBStack(const TCollection* sums, const TString& base)
440   {
441     TString title("results");
442     TCollection* c = GetCentCollection(sums, base, 0, -1, title);
443     if (!c) return 0;
444
445     TH1* dndeta      = GetH1(c, Form("dndeta%s",base.Data()));
446     if (!dndeta) return 0;
447
448     THStack* ret = new THStack("dndetaMB", title);
449     ret->Add(dndeta);
450
451     if (base.EqualTo("MCTruth")) {
452       dndeta      = GetH1(c, "dndetaTruth");
453       if (dndeta) ret->Add(dndeta);
454     }
455     return ret;
456   }
457       
458   //____________________________________________________________________
459   void DrawCentRes(const TCollection* sums, const TString& base, 
460                    Int_t cLow, Int_t cHigh)
461   {
462     TString title("results");
463     TCollection* c = GetCentCollection(sums, base, cLow, cHigh, title);
464     if (!c) return;
465
466
467     TH1* trig        = GetH1(c, "triggers");
468     TH1* norm        = GetH1(c, Form("norm%s",base.Data()));
469     TH1* dndeta      = GetH1(c, Form("dndeta%s",base.Data()));
470     TH2* d2ndetadphi = GetH2(c, Form("d2Ndetadphi%s", base.Data()));
471     if (!trig || !norm || !dndeta || !d2ndetadphi) return;
472
473     norm->SetFillColor(kGreen+1);
474     norm->SetFillStyle(3001);
475
476     fBody->Divide(2, 3, 0.05, 0);
477
478     Int_t        trP = 1;
479     TVirtualPad* p   = fBody->GetPad(trP);
480     p->SetBottomMargin(0.15);
481     p->SetLeftMargin(0.15);
482     if (trP > 2) p->SetTopMargin(0.05);
483     
484     DrawInPad(fBody, trP, trig, "HIST TEXT");
485     DrawInPad(fBody, 2,   norm);
486     DrawInPad(fBody, 4,   dndeta);
487     DrawInPad(fBody, 6,   GetH1(c, Form("dndeta%s_rebin05",base.Data())));
488     DrawInPad(fBody, 5,   d2ndetadphi, "colz");
489   
490     fBody->GetPad(2)->SetGridx(); fBody->GetPad(2)->SetLeftMargin(0.15);
491     fBody->GetPad(4)->SetGridx(); fBody->GetPad(4)->SetLeftMargin(0.15);
492     fBody->GetPad(6)->SetGridx(); fBody->GetPad(6)->SetLeftMargin(0.15);
493
494     TObject*   normCalc = GetObject(c, "normCalc");
495     TString    calc     = normCalc ? normCalc->GetTitle() : "?";
496
497     // Beautify the text
498     calc.ReplaceAll("beta", "#beta");
499     calc.ReplaceAll("eps", "#epsilon");
500     const char* sufs[] = { "all", "acc", "trg", "vtx", "B", "A", "C", "E", 
501                            "V", "T", 0 };
502     const char** suf = sufs;
503     while (*suf) { 
504       calc.ReplaceAll(Form("_%s", *suf), Form("_{%s}", *suf));
505       suf++;
506     }
507
508     fBody->cd(3);
509     TObjArray* lines    = calc.Tokenize("\n");
510     // TPaveText* disp     = new TPaveText(.1,.1,.9,.9, "NDC");
511     TIter       next(lines);
512     TObjString* sline     = 0;
513     Double_t y = .95;
514     Double_t xSave = fParName->GetX();
515     Int_t    aSave = fParName->GetTextAlign();
516     fParName->SetTextAlign(33);
517     fParName->SetX(fParVal->GetX()-.05);
518     while ((sline = static_cast<TObjString*>(next()))) {
519       // disp->AddText(line->GetName());
520       TString& line = sline->String();
521       Ssiz_t   eq   = line.Last('=');
522       if (eq == kNPOS) { 
523         DrawParameter(y, line, "");
524         continue;
525       }
526       TString name = line(0, eq);
527       TString val  = line(eq+1,line.Length()-eq-1);
528       DrawParameter(y, name.Strip(TString::kBoth), 
529                     val.Strip(TString::kBoth));
530       
531     }
532     fParName->SetTextAlign(aSave);
533     fParName->SetX(xSave);
534     // disp->SetBorderSize(0);
535     // disp->SetBorderSize(0);
536     // disp->SetFillStyle(0);
537     // DrawInPad(fBody, 3, disp);
538     // fBody->cd();
539
540     PrintCanvas(title);
541
542     DrawCentResDetails(c, title);
543   }  
544   //____________________________________________________________________
545   void DrawCentResDetails(const TCollection* sums, const TString& base)
546   {
547     TString title = TString::Format("%s - details: ", base.Data());
548
549     TCollection* c = GetCollection(sums, "partial");
550     if (!c) {
551       Warning("", "Collection partical not found in %s", sums->GetName());
552       sums->ls();
553       return;
554     }
555
556     fBody->Divide(3, 1, 0.05, 0);
557     
558     const char* typs[] = { "", "0", "All" };
559     const char* tits[] = { "Non-zero events", "Zero events", "Weighted sum" };
560     for (Int_t i = 1; i <= 3; i++) {
561       const char* suf = typs[i-1];
562       TVirtualPad* p   = fBody->cd(i);
563       p->SetTopMargin(0.10);
564
565       TLatex* ltx = new TLatex(0.5, .99, tits[i-1]);
566       ltx->SetNDC();
567       ltx->SetTextAlign(23);
568       ltx->SetTextSize(0.05);
569       ltx->Draw();
570
571       TH1* sum  = GetH2(c, Form("sum%s",     suf));
572       TH1* norm = GetH1(c, Form("norm%s", suf));
573       TH1* phi  = GetH1(c, Form("phi%s",  suf));
574     
575       norm->SetFillColor(kGreen+1);
576       norm->SetFillStyle(3002);
577       phi->SetFillColor(kBlue+1);
578       phi->SetFillStyle(3001);
579       
580       p->Divide(1, 3, 0, 0);
581       DrawInPad(p, 1, sum, sum->Integral()>0 ? "col" : "");
582       DrawInPad(p, 2, GetH1(c, Form("average%s", suf)), "");
583       DrawInPad(p, 3, norm);
584       DrawInPad(p, 3, phi, "same", kLegend);      
585     }
586     PrintCanvas(title);
587   }
588
589   //____________________________________________________________________
590   THStack* CleanStack(const THStack* stack, TLegend* l, const TAxis* axis)
591   {
592     THStack* ret   = new THStack(stack->GetName(), stack->GetTitle());
593     TList*   hists = stack->GetHists();
594     TIter    next(hists);
595     TH1*     h     = 0;
596     Int_t    j     = 0;
597     Bool_t   ok    = false;
598     while ((h = static_cast<TH1*>(next()))) {
599       TString name(h->GetTitle());
600       if (name.Contains("_mirror")) continue;
601       if (l && !ok) { 
602         j++;
603         if (axis) 
604           name.Form("%3d%% - %3d%%", 
605                     Int_t(axis->GetBinLowEdge(j)), 
606                     Int_t(axis->GetBinUpEdge(j)));
607         ok = axis && axis->GetBinUpEdge(j) > 100;
608         TLegendEntry* e = l->AddEntry("dummy", name, "f");
609         e->SetFillStyle(1001);
610         e->SetFillColor(h->GetMarkerColor());
611       }
612       ret->Add(h);
613     }
614     return ret;
615   }
616 };
617 //
618 // EOF
619 //