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