]> git.uio.no Git - u/mrichter/AliRoot.git/blob - PWGLF/FORWARD/analysis2/scripts/SummaryAODDrawer.C
Merge branch 'master' of https://git.cern.ch/reps/AliRoot
[u/mrichter/AliRoot.git] / PWGLF / FORWARD / analysis2 / scripts / SummaryAODDrawer.C
1 #include "SummaryDrawer.C"
2 #ifndef __CINT__
3 # include <TGraph.h>
4 # include <TGraphErrors.h>
5 # include <TF1.h>
6 # include <TArrow.h>
7 #else
8 class TGraph;
9 #endif
10
11 /**
12  * Class to draw a summary of the AOD production
13  *
14  * @par Input: 
15  * - The merged <tt>forward.root</tt> file.
16  *   If the file isn't merged, it should still work. 
17  *
18  * @par Output:
19  * - A PDF file named after the input, but with <tt>.root</tt>
20  *   replaced with <tt>pdf</tt>
21  * 
22  */
23 class SummaryAODDrawer : public SummaryDrawer
24 {
25 public:
26   enum EFlags { 
27     kEventInspector    = 0x001, 
28     kSharingFilter     = 0x002, 
29     kDensityCalculator = 0x004,
30     kCorrector         = 0x008,
31     kHistCollector     = 0x010,
32     kSteps             = 0x020, 
33     kResults           = 0x040, 
34     kCentral           = 0x080,
35     kNormal            = 0x0FF
36   };
37   SummaryAODDrawer() 
38     : SummaryDrawer(),
39       fSums(0),
40       fResults(0)
41   {}
42   
43   //__________________________________________________________________
44   /** 
45    * 
46    * 
47    * @param fname 
48    * @param what 
49    */
50   void Run(const char* fname, UShort_t what=kNormal)
51   {
52     // --- Open the file ---------------------------------------------
53     TString filename(fname);
54     TFile*  file = TFile::Open(filename, "READ");
55     if (!file) { 
56       Error("Run", "Failed to open \"%s\"", filename.Data());
57       return;
58     }
59    
60
61     // --- Get top-level collection ----------------------------------
62     fSums = GetCollection(file, "ForwardSums");
63     if (!fSums) {
64       Info("Run", "Trying old name Forward");
65       fSums = GetCollection(file, "Forward");
66       if (!fSums) return;
67     }
68
69     // --- Do the results ----------------------------------------------
70     fResults = GetCollection(file, "ForwardResults");
71     if (!fResults) fResults = fSums; // Old-style
72
73     // --- Make our canvas -------------------------------------------
74     TString pdfName(filename);
75     pdfName.ReplaceAll(".root", ".pdf");
76     CreateCanvas(pdfName, what & kLandscape);
77     DrawTitlePage(file);
78
79     // --- Possibly make a chapter here ------------------------------
80     TCollection* centralSums = GetCollection(file, "CentralSums", false);
81     if (!centralSums) {
82       Info("Run", "Trying old name \"Central\"");
83       centralSums = GetCollection(file, "Central", false);
84     }
85     if (what & kCentral && centralSums) 
86       MakeChapter("Forward");
87     
88     // --- Set pause flag --------------------------------------------
89     fPause = what & kPause;
90
91     // --- Do each sub-algorithm -------------------------------------
92     if (what & kEventInspector)    DrawEventInspector(fSums);
93     if (what & kSharingFilter)     DrawSharingFilter();
94     if (what & kDensityCalculator) DrawDensityCalculator();
95     if (what & kCorrector)         DrawCorrector();
96     if (what & kHistCollector)     DrawHistCollector();
97   
98     
99     if (what & kSteps) DrawSteps();
100     if (what & kResults) DrawResults();
101
102     // --- SPD clusters ----------------------------------------------
103     if (what & kCentral) { 
104       // --- Get top-level collection --------------------------------
105       fSums = GetCollection(file, "CentralSums");
106       if (!fSums) 
107         fSums = GetCollection(file, "Central");
108       if (fSums) {
109         MakeChapter("Central");
110         DrawCentral();
111         if (what & kEventInspector) DrawEventInspector(fSums);
112       }
113       fResults = GetCollection(file, "CentralResults");
114       if (fResults && (what & kResults)) {
115         DrawCentralResults();
116       }
117
118       if (what & kResults) DrawBoth(file);
119     }
120
121     
122     CloseCanvas();
123   }
124 protected:
125   //____________________________________________________________________
126   void DrawTitlePage(TFile* f)
127   {
128     fBody->cd();
129
130     TLatex* ltx = new TLatex(.5, .7, "ESD #rightarrow AOD filtering");
131     ltx->SetNDC();
132     ltx->SetTextSize(0.07);
133     ltx->SetTextAlign(22);
134     ltx->Draw();
135
136     TCollection* fwd = fSums; // GetCollection(f, "ForwardSums");
137     TCollection* cen = GetCollection(f, "CentralSums");
138     Double_t y = .6;
139     
140     Double_t save = fParName->GetTextSize();
141     fParName->SetTextSize(0.03);
142     fParVal->SetTextSize(0.03);
143
144     DrawParameter(y, "Tasks", (fwd ? "Forward" : ""));
145     DrawParameter(y, "",      (cen ? "Central" : ""));
146
147     if (fwd) { 
148       TCollection* ei = GetCollection(fwd, "fmdEventInspector");
149       if (ei) { 
150
151         UShort_t sys=0, sNN=0;
152         Int_t field=0;
153         ULong_t runNo=0;
154         Bool_t mc=false;
155         GetParameter(ei, "sys", sys);
156         GetParameter(ei, "sNN", sNN);
157         GetParameter(ei, "field", field);
158         GetParameter(ei, "runNo", runNo);
159         if (!GetParameter(ei, "mc", mc, false)) mc = false;
160         
161         TString sysString;    SysString(sys, sysString);
162         TString sNNString;    SNNString(sNN, sNNString);
163         
164         DrawParameter(y, "System", sysString);
165         DrawParameter(y, "#sqrt{s_{NN}}", sNNString);
166         DrawParameter(y, "L3 B field", Form("%+2dkG", field));
167         DrawParameter(y, "Run #", Form("%6lu", runNo));
168         DrawParameter(y, "Simulation", (mc ? "yes" : "no"));    
169       }
170     }
171     PrintCanvas("Title page");
172     fParName->SetTextSize(save);
173     fParVal->SetTextSize(save);
174   }
175   TGraph* CreateCutGraph(Int_t method, Int_t iy, TH2* cuts, TH1* eloss,
176                          Int_t color)
177   {
178     TGraph*  ret = new TGraph(4);
179     Double_t y0  = TMath::Max(eloss->GetMinimum(),1.);
180     Double_t y1  = eloss->GetMaximum();
181     Double_t min = 1000;
182     Double_t max = 0;
183     if (method == 0) { // Fixed value
184       max = cuts->GetBinContent(1, iy);
185       min = eloss->GetXaxis()->GetXmin();
186     }
187     else {
188       for (Int_t ix=1; ix <= cuts->GetNbinsX(); ix++) {
189         Double_t c = cuts->GetBinContent(ix, iy);
190         if (c <= 0.0001) continue;
191         min = TMath::Min(c, min);
192         max = TMath::Max(c, max);
193       }
194     }
195     // Printf("Cuts between %f,%f @%f, %f", min, max, y0,y1);
196     ret->SetPoint(0, min, y0); 
197     ret->SetPoint(1, min, y1); 
198     ret->SetPoint(2, max, y1);
199     ret->SetPoint(3, max, y0);
200     ret->SetFillColor(color);
201     ret->SetFillStyle(3002);
202     ret->SetLineColor(kBlack);
203     ret->SetLineStyle(2);
204     ret->SetName(Form("g%s", cuts->GetName()));
205     ret->SetTitle(cuts->GetTitle());
206     
207     return ret;
208   }
209   //____________________________________________________________________
210   const Char_t* CutMethodName(Int_t lm) const
211   {
212     switch (lm) {
213     case 0: return "c=X";
214     case 1: return "c=X#times#Delta_{p}";
215     case 2: return "c:Lower bound of fit range";
216     case 3: return "c=#Delta_{p}-X#times#xi";
217     case 4: return "c=#Delta_{p}-X#times(#xi+#sigma)";
218     case 5: return "c:P(#Delta<c)<X";
219     }
220     return "unknown";
221   }
222   //____________________________________________________________________
223   Int_t PrintCut(const TCollection* c, Double_t& y, const Char_t* name,
224                  Double_t size=0)
225   {
226     if (!c) return -1;
227
228     Int_t method = 0;
229     if (!GetParameter(c, "method", method)) return -1;
230     DrawParameter(y, name, CutMethodName(method), size);
231
232     TString params;
233     const char*  cuts[] = { "fmd1i", "fmd2i", "fmd2o", "fmd3i", "fmd3o", 0 };
234     const char** pcut   = cuts;
235     while (*pcut) { 
236       Double_t cut;
237       GetParameter(c, *pcut, cut);
238       if (pcut != cuts) params.Append(", ");
239       params.Append(Form("%5.2f", cut));
240       pcut++;
241     }
242     DrawParameter(y, "Parameters", params, size);
243     return method;
244   }
245   //____________________________________________________________________
246   void DrawCut(TVirtualPad* parent, Int_t sub, TH2* cuts)
247   {
248     if (!cuts) return;
249     THStack* stack = new THStack(cuts,"x");
250     stack->SetTitle(cuts->GetTitle());
251     for (Int_t i = 1; i <= cuts->GetNbinsY(); i++) {
252       TH1*     hist = static_cast<TH1*>(stack->GetHists()->At(i-1));
253       TString  name(cuts->GetYaxis()->GetBinLabel(i));
254       UShort_t det = UShort_t(name[3]-48);
255       Char_t   rng = name[4];
256       Color_t  col = RingColor(det, rng);
257       hist->SetTitle(name);
258       hist->SetMarkerStyle(20);
259       hist->SetMarkerColor(col);
260       hist->SetLineColor(col);
261       hist->SetFillColor(col);
262       hist->SetLineWidth(0);
263       hist->SetFillStyle(0);
264       hist->SetXTitle("#eta");
265       hist->SetYTitle(cuts->GetZaxis()->GetTitle());
266     }
267     DrawInPad(parent, sub, stack, "nostack p", kLegend|kCenter|kSouth);
268   }
269   //____________________________________________________________________
270   void DrawSharingFilter()
271   {
272     Info("DrawSharingFilter", "Drawing sharing filter");
273     TCollection* c = GetCollection(fSums, "fmdSharingFilter");
274     if (!c) return;
275     TCollection* rc = GetCollection(fResults, "fmdSharingFilter");
276     if (!rc) rc = c;
277
278     // --- Draw summary information ----------------------------------
279     fBody->Divide(1, 3, 0, 0);
280     fBody->cd(1);
281   
282     Double_t y = .95;
283     Bool_t   angle=false, lowSignal=false, disabled=false;
284
285     if (GetParameter(c, "angle", angle))
286       DrawParameter(y, "Angle correct", (angle ? "yes" : "no")); 
287     if (GetParameter(c, "lowSignal", lowSignal))
288       DrawParameter(y, "Lower signal",  (lowSignal ? "yes" : "no"));
289     TParameter<int>* nFiles = 
290       static_cast<TParameter<int>*>(GetObject(c, "nFiles"));
291     if (nFiles)
292       DrawParameter(y, "# files merged", Form("%d", nFiles->GetVal()));    
293     if (GetParameter(c, "disabled", disabled)) 
294       DrawParameter(y, "Merging disabled", (disabled ? "yes" : "no"));
295
296     Int_t lm    = 0;
297     Int_t hm    = 0;
298     TH2*  hLow  = 0;
299     TH2*  hHigh = 0;
300     if (!disabled) {
301       Bool_t simple=false, three=false;
302       if (GetParameter(c, "simple", simple))
303         DrawParameter(y, "Simple method", (simple ? "yes" : "no"));
304       if (GetParameter(c, "sumThree", three)) 
305         DrawParameter(y, "3-strip merging", (three ? "yes" : "no"));
306     
307       TCollection* lc = GetCollection(c, "lCuts");
308       TCollection* hc = GetCollection(c, "hCuts");
309       lm              = PrintCut(lc, y, "Low cut");
310       hm              = PrintCut(hc, y, "High cut");
311       hLow            = GetH2(c, "lowCuts");
312       hHigh           = GetH2(c, "highCuts");
313       // if (hLow  && nFiles) hLow->Scale(1. / nFiles->GetVal());
314       // if (hHigh && nFiles) hHigh->Scale(1. / nFiles->GetVal());
315       DrawCut(fBody, 2, hLow);
316       DrawCut(fBody, 3, hHigh);
317     }
318     PrintCanvas("Sharing filter");
319
320     if (!disabled) {
321       // --- Draw rings individually -----------------------------------
322       Double_t savX = fParVal->GetX();
323       Double_t savY = fParVal->GetY();
324       fParVal->SetX(0.6);
325       fParVal->SetY(0.6);
326       const char** ptr   = GetRingNames(false);
327       UShort_t     iq    = 1;
328       while (*ptr) { 
329         TCollection* sc = GetCollection(c, *ptr);
330         if (!sc) { ptr++; iq++; continue; }
331         
332         if (fLandscape) fBody->Divide(3, 2);
333         else            fBody->Divide(2,3);
334         
335         TH1*    esdELoss = GetH1(sc, "esdEloss");
336         TH1*    anaELoss = GetH1(sc, "anaEloss");
337         Double_t esdInt  = esdELoss->Integral(0,esdELoss->GetNbinsX()+1);
338         Double_t anaInt  = anaELoss->Integral(0,anaELoss->GetNbinsX()+1);
339         Double_t frac    = esdInt > 0 ? (esdInt-anaInt)/esdInt : 1;
340         esdELoss->GetXaxis()->SetRangeUser(-.1, 2);
341         TGraph* lowCut   = CreateCutGraph(lm, iq,  hLow,  esdELoss, kYellow+1);
342         TGraph* highCut  = CreateCutGraph(hm, iq,  hHigh, esdELoss, kCyan+1);
343         
344         DrawInPad(fBody, 1, esdELoss, "", kLogy,
345                   "#Delta/#Delta_{mip} reconstructed and merged");
346         DrawInPad(fBody, 1, anaELoss, "same");
347         DrawInPad(fBody, 1, lowCut,  "lf same"); 
348         DrawInPad(fBody, 1, highCut, "lf same", kLogy|kLegend|kNorth|kWest); 
349         TVirtualPad* p = fBody->GetPad(1);
350         p->cd();
351         TLatex* l = new TLatex(1-p->GetRightMargin(), 
352                                0.5, Form("Loss: %5.1f%%", frac*100));
353         l->SetNDC();
354         l->SetTextAlign(32);
355         l->Draw();
356
357         TH1*     singles  = GetH1(sc, "singleEloss");
358         TH1*     doubles  = GetH1(sc, "doubleEloss");
359         TH1*     tripples = GetH1(sc, "tripleEloss");
360         Double_t int1     = singles->Integral(0,singles->GetNbinsX()+1);
361         Double_t int2     = doubles->Integral(0,doubles->GetNbinsX()+1);
362         Double_t int3     = tripples->Integral(0,tripples->GetNbinsX()+1);
363         Double_t intT     = int1 + int2 + int3;
364         Double_t f1       = intT > 0 ? int1 / intT : 0;
365         Double_t f2       = intT > 0 ? int2 / intT : 0;
366         Double_t f3       = intT > 0 ? int3 / intT : 0;
367
368         singles->GetXaxis()->SetRangeUser(-.1, 2);
369         DrawInPad(fBody, 2, singles,    "",    kLogy,
370                   "#Delta/#Delta_{mip} for single, double, and tripple hits");
371         DrawInPad(fBody, 2, doubles,    "same",    kLogy);
372         DrawInPad(fBody, 2, tripples,   "same",    kLogy);
373         DrawInPad(fBody, 2, lowCut,     "lf same", kLogy); 
374         DrawInPad(fBody, 2, highCut,    "lf same", kLogy|kLegend|kNorth|kWest); 
375         
376         fBody->cd(2);
377         Double_t nameX = fParName->GetX();
378         Double_t valX  = fParVal->GetX();
379         Double_t intY  = 0.4;
380         fParName->SetX(0.5);
381         fParVal->SetX(0.7);
382         DrawParameter(intY, "Singles",  Form("%5.1f%%", 100*f1), 0.05);
383         DrawParameter(intY, "Doubles",  Form("%5.1f%%", 100*f2), 0.05);
384         DrawParameter(intY, "Tripples", Form("%5.1f%%", 100*f3), 0.05);
385         fParName->SetX(nameX);
386         fParVal->SetX(valX);
387
388         DrawInPad(fBody, 3, GetH2(sc, "singlePerStrip"), "colz",kLogz);
389         // DrawInPad(fBody, 4, GetH1(sc, "distanceBefore"), "",     0x2);
390         // DrawInPad(fBody, 4, GetH1(sc, "distanceAfter"),  "same", 0x12);
391         DrawInPad(fBody, 4, GetH2(sc, "summed"),         "colz",0x0);
392         
393         TH2* nB = GetH2(sc, "neighborsBefore");
394         if (nB) { 
395           nB->GetXaxis()->SetRangeUser(0,2); 
396           nB->GetYaxis()->SetRangeUser(0,2); 
397         }
398         DrawInPad(fBody, 5, nB, "colz", kLogz);
399         DrawInPad(fBody, 5, GetH2(sc, "neighborsAfter"), "col same", kLogz,
400                   "Correlation of neighbors before and after merging");
401         DrawInPad(fBody, 6, GetH2(sc, "beforeAfter"),    "colz",   kLogz);
402         
403         PrintCanvas(Form("Sharing filter - %s", *ptr));
404         ptr++;
405         iq++;
406       }
407       fParVal->SetX(savX);
408       fParVal->SetY(savY);
409     }
410
411     // --- MC --------------------------------------------------------
412     TCollection* cc = GetCollection(c, "esd_mc_comparion", false); // Spelling!
413     if (!cc) return; // Not MC 
414
415     DivideForRings(false, false);
416     const char** ptr = GetRingNames(false);
417     while (*ptr) { 
418       DrawInRingPad(GetH2(cc, Form("%s_corr", *ptr)), "colz", kLogz);
419       ptr++;
420     }
421
422     PrintCanvas("Sharing filter - MC vs Reco");
423
424     // --- MC --------------------------------------------------------
425     DrawTrackDensity(c);
426   }
427   //__________________________________________________________________
428   /** 
429    * Draw a slice fit on a 2D histogram
430    * 
431    * @param inY   Whether to slice in Y
432    * @param h     2D histogram
433    * @param nVar  Number of variances
434    * @param p     Master pad to draw in 
435    * @param sub   Sub pad number 
436    * @param flags Flags 
437    * @param cut   Cut value 
438    */
439   void ShowSliceFit(Bool_t inY, TH2* h, Double_t nVar, 
440                     TVirtualPad* p, Int_t sub, UShort_t flags=0,
441                     Double_t cut=-1)
442   {
443     if (!h) return;
444
445     TObjArray* fits = new TObjArray;
446     fits->SetOwner();
447     if (inY) h->FitSlicesY(0, 1, -1, 10, "QN", fits);
448     else     h->FitSlicesX(0, 1, -1, 10, "QN", fits);
449     if (!fits) { 
450       Warning("ShowSliceFit", "No fits returned");
451       return;
452     }
453     TH1* mean = static_cast<TH1*>(fits->At(1));
454     TH1* var  = static_cast<TH1*>(fits->At(2));
455     if (!mean || !var) {
456       Warning("ShowSliceFit", "Didn't get histograms");
457       fits->Delete();
458       return;
459     }
460     TF1* fmean = new TF1("mean", "pol1");
461     TF1* fvar  = new TF1("var",  "pol1");
462     mean->Fit(fmean, "Q0+");
463     var->Fit(fvar, "Q0+");
464     if (!fmean || !fvar) {
465       Warning("ShowSliceFit", "No functions returned");
466       fits->Delete();
467       return;
468     }
469
470     TGraphErrors* g = new TGraphErrors(h->GetNbinsX());
471     g->SetName(Form("g%s", h->GetName()));
472     TString xTit = h->GetXaxis()->GetTitle();
473     TString yTit = h->GetYaxis()->GetTitle();
474     g->SetTitle(Form("Correlation of %s and %s",
475                      inY  ? xTit.Data() : yTit.Data(), 
476                      !inY ? xTit.Data() : yTit.Data()));
477     g->SetFillColor(kBlue-10);
478     g->SetFillStyle(3001);
479     TGraph* up  = (cut > 0 ? new TGraph(h->GetNbinsX()) : 0);
480     TGraph* low = (cut > 0 ? new TGraph(h->GetNbinsX()) : 0);
481     if (up)  { 
482       up ->SetLineColor(kBlack); 
483       up ->SetLineWidth(2); 
484       up ->SetLineStyle(2); 
485     }
486     if (low) { 
487       low->SetLineColor(kBlack); 
488       low->SetLineWidth(2); 
489       low->SetLineStyle(2); 
490     }
491     for (Int_t i = 1; i <= h->GetNbinsX(); i++) { 
492       Double_t x  = h->GetXaxis()->GetBinCenter(i);
493       Double_t y  = fmean->Eval(x);
494       Double_t e  = fvar->Eval(x);
495       Double_t ee = nVar * e;
496       if (flags & 0x8000) ee *= e > 0 ? TMath::Log10(e) : 1;
497       g->SetPoint(i-1, x, y);
498       g->SetPointError(i-1, 0, ee);
499
500       if (up)  up ->SetPoint(i-1,x,x+cut*x);
501       if (low) low->SetPoint(i-1,x,x-cut*x);
502     }
503     DrawInPad(p, sub, g, "3", flags);
504     if (up)  DrawInPad(p, sub, up, "l", flags);
505     if (low) DrawInPad(p, sub, low, "l", flags);
506     fmean->SetRange(h->GetXaxis()->GetXmin(), h->GetXaxis()->GetXmax());
507     fmean->SetLineWidth(2);
508     DrawInPad(p, sub, fmean, "same", flags);
509
510     TVirtualPad* pp = p->GetPad(sub);
511     Double_t y = 1-pp->GetTopMargin()-.01;
512     TLatex* l = new TLatex(.15, y, 
513                            Form("#LT%s#GT(%s) = "
514                                 "%f + %f %s", 
515                                 yTit.Data(), xTit.Data(), 
516                                 fmean->GetParameter(0), 
517                                 fmean->GetParameter(1), xTit.Data()));
518     l->SetNDC();
519     l->SetTextAlign(13);
520     l->SetTextSize(0.04);
521     l->SetTextFont(42);
522     l->Draw();
523     l->DrawLatex(0.15, y-0.07, 
524                  Form("#sigma_{%s}(%s) = "
525                       "%f + %f %s", 
526                       yTit.Data(), xTit.Data(),
527                       fvar->GetParameter(0), 
528                       fvar->GetParameter(1),  xTit.Data()));
529     l->DrawLatex(0.15, y-0.14, Form("#delta = %3.1f %s #sigma",
530                                     nVar, 
531                                     flags & 0x8000 ? "log_{10}(#sigma)" : ""));
532     fits->Delete();
533   }
534
535   //____________________________________________________________________
536   void DrawDensityCalculator()
537   {
538     Info("DrawDensityCalculator", "Drawing density calculator");
539     TCollection* c = GetCollection(fSums, "fmdDensityCalculator");
540     if (!c) return;
541
542     fBody->Divide(2, 2);
543     fBody->cd(1);
544   
545     Double_t y = .9;
546     Int_t maxParticles=0, phiAcceptance=0, etaLumping=0, phiLumping=0;
547     Bool_t method=false, recalcEta=false, recalcPhi=false;
548     Double_t maxOutliers=0, outlierCut=0;
549     Double_t size = fLandscape ? 0.05 : 0.03;
550   
551     GetParameter(c, "maxParticle", maxParticles);
552
553     if (GetParameter(c, "phiAcceptance", phiAcceptance))
554       DrawParameter(y, "#phi acceptance method", 
555                     (phiAcceptance == 1 ? "N_{ch}" : 
556                      phiAcceptance == 2 ? "#DeltaE" : "none"),       size);
557     if (GetParameter(c, "etaLumping", etaLumping) &&
558         GetParameter(c, "phiLumping", phiLumping))
559       DrawParameter(y, "Region size (sector#timesstrip)", 
560                     Form("%2d #times %2d", phiLumping, etaLumping),  size);
561     if (GetParameter(c, "method", method))
562       DrawParameter(y, "Method", (method ? "Poisson" : "#DeltaE"),   size); 
563     if (GetParameter(c, "recalcEta", recalcEta))
564       DrawParameter(y, "Recalculate #eta",(recalcEta ? "yes" : "no"),size); 
565     if (GetParameter(c, "recalcPhi", recalcPhi))
566       DrawParameter(y, "Recalculate #phi",(recalcPhi ? "yes" : "no"),size); 
567     if (GetParameter(c, "maxOutliers", maxOutliers))
568       DrawParameter(y, "Max relative N_{outlier}",
569                     Form("%5.3f",maxOutliers),size);
570     if (GetParameter(c, "outlierCut", outlierCut))
571       DrawParameter(y, "Max relative deviation",Form("%5.3f",outlierCut),size);
572
573
574     TParameter<int>* nFiles = 
575       static_cast<TParameter<int>*>(GetObject(c, "nFiles"));
576     if (nFiles)
577       DrawParameter(y, "# files merged", Form("%d", nFiles->GetVal()), size);
578
579     TCollection* lc = GetCollection(c, "lCuts");
580     Int_t tm = PrintCut(lc, y, "Threshold", size);
581
582     TVirtualPad* p = fBody; // fBody->cd(2);
583     // p->Divide(3,1);
584
585     TH1* accI = GetH1(c, "accI");
586     TH1* accO = GetH1(c, "accO");
587     if (accI) { 
588       Double_t scale = 1./accI->GetMaximum();
589       accI->Scale(scale); 
590       accO->Scale(scale);
591       accI->SetMinimum(0); 
592       accI->SetMaximum(1.3);
593     }
594     TH2* lCuts = GetH2(c, "lowCuts");
595     TH2* maxW  = GetH2(c, "maxWeights");
596     if (lCuts)           lCuts->SetTitle("Thresholds");
597     if (nFiles && lCuts) lCuts->Scale(1. / nFiles->GetVal());
598     if (nFiles && maxW)  maxW->Scale(1. / nFiles->GetVal());
599     DrawInPad(p, 2, accI); 
600     DrawInPad(p, 2, accO,  "same", kLegend|kNorth|kCenter); 
601     DrawCut(p, 3, lCuts);
602     // DrawInPad(p, 3, lCuts, "colz");
603     DrawCut(p, 4, maxW);
604     // DrawInPad(p, 4, maxW,  "colz");
605   
606     PrintCanvas("Density calculator");
607
608     UShort_t iq = 1;
609     const char** ptr   = GetRingNames(false);
610     while (*ptr) { 
611       TCollection* sc = GetCollection(c, *ptr);
612       if (!sc) { ptr++; continue; }
613     
614       if (fLandscape) fBody->Divide(3,2);
615       else            fBody->Divide(2,3);
616     
617       TH2* corr      = GetH2(sc, "elossVsPoisson");
618       TH2* corrOut   = GetH2(sc, "elossVsPoissonOutlier");
619       TH1* diff      = GetH1(sc, "diffElossPoisson");
620       TH1* diffOut   = GetH1(sc, "diffElossPoissonOutlier");
621       TH1* eloss     = GetH1(sc, "eloss");
622       TH1* elossUsed = GetH1(sc, "elossUsed");
623       TH1* occ       = GetH1(sc, "occupancy");
624       if (eloss)     eloss    ->SetLineWidth(1);
625       if (elossUsed) elossUsed->SetLineWidth(1);
626       if (eloss)     eloss->GetXaxis()->SetRangeUser(0.05, 2);
627       
628       DrawInPad(fBody, 1, corr,    "colz",        kLogz);
629       DrawInPad(fBody, 1, corrOut, "same",        kLogz);
630       DrawInPad(fBody, 2, diff,    "HIST E",      kLogy);
631       DrawInPad(fBody, 2, diffOut, "HIST E SAME", kLogy|kLegend|kNorth|kWest);
632       DrawInPad(fBody, 3, occ,      "",           kLogy);
633       DrawInPad(fBody, 4, eloss,    "",           kLogy, 
634                 "#Delta/#Delta_{mip} before and after cuts");
635       DrawInPad(fBody, 4, elossUsed, "same",      kLogy);
636       TGraph* thres = CreateCutGraph(tm, iq,  lCuts,  eloss, kYellow+1);
637       DrawInPad(fBody, 4, thres, "lf same", kLogy|kLegend|kNorth|kWest); 
638
639       if (eloss && elossUsed) {
640         Int_t    lowBin    = eloss->GetXaxis()->FindBin(0.)+1;
641         Int_t    upBin     = eloss->GetNbinsX()+1;
642         Double_t beforeInt = eloss->Integral(lowBin,upBin);
643         Double_t afterInt  = elossUsed->Integral(lowBin,upBin);
644         Double_t frac      = beforeInt > 0 ? (beforeInt-afterInt)/beforeInt : 1;
645         TVirtualPad* pp = fBody->GetPad(4);
646         pp->cd();
647         TLatex* l = new TLatex(1-pp->GetRightMargin(), 
648                                0.5, Form("Loss: %5.1f%%", frac*100));
649         l->SetNDC();
650         l->SetTextAlign(32);
651         l->Draw();
652       }
653
654
655       TH1* phiB = GetH1(sc, "phiBefore");
656       TH1* phiA = GetH1(sc, "phiAfter");
657       TH1* outliers = GetH1(sc, "outliers");
658       if (outliers) 
659         DrawInPad(fBody, 5, outliers, "hist", kLogy);
660       else if (phiB && phiA) { 
661         phiA->Add(phiB, -1);
662         phiA->Divide(phiB);
663         phiA->SetTitle("#Delta#phi from Ip (x,y) correction");
664         phiA->SetYTitle("(#phi_{after}-#phi_{before})/#phi_{before}");
665         DrawInPad(fBody, 5, phiA);
666       }
667       else {
668         fBody->cd(5);
669         TLatex* ltx = new TLatex(0.5, 0.5, "No outliers or #phi corrections");
670         ltx->SetTextAlign(22);
671         ltx->SetTextSize(0.07);
672         ltx->SetNDC();
673         ltx->Draw();
674       }
675       DrawInPad(fBody, 6, GetH2(sc, "phiAcc"), "colz",   kLogz);
676     
677       ShowSliceFit(true, corr, 10, fBody, 1, kLogz, outlierCut);
678
679       if (diff && diffOut) { 
680         fBody->cd(2);
681         Double_t in  = diff->GetEntries();
682         Double_t out = diffOut->GetEntries();
683         if ((in+out) > 0) {
684           TLatex*  ltx = new TLatex(0.11, 0.89, 
685                                     Form("Fraction: %7.3f%%", 
686                                          100*out/(in+out)));
687           ltx->SetNDC();
688           ltx->SetTextAlign(13);
689           ltx->SetTextSize(0.06);
690           ltx->Draw();
691         }
692       }
693       PrintCanvas(Form("Density calculator - %s", *ptr));
694       ptr++;    
695       iq++;
696     }
697
698     TCollection* cc = GetCollection(c, "esd_mc_comparison", false); 
699     if (!cc) return; // Not MC 
700
701     fBody->Divide(2,5);
702     ptr   = GetRingNames(false);
703     Int_t cnt = 0;
704     while (*ptr) { 
705       DrawInPad(fBody, 2*cnt+1, GetH2(cc, Form("%s_corr_mc_esd", *ptr)),
706                 "colz", kLogz);
707       DrawInPad(fBody, 2*(cnt+1), GetH2(cc, Form("%s_diff_mc_esd", *ptr)),
708                 "", kLogz);
709       ptr++;
710       cnt++;
711     }
712
713     PrintCanvas("Density calculator - MC vs Reco");
714   }
715
716   //____________________________________________________________________
717   void DrawCorrector()
718   {
719     Info("DrawCorrector", "Drawing corrector"); 
720     TCollection* c = GetCollection(fSums, "fmdCorrector"); 
721     if (!c) return;
722   
723     fBody->cd();
724   
725     Double_t y = .8;  
726     Bool_t secondary=false, vertexBias=false, acceptance=false, merging=false;  
727     if (GetParameter(c, "secondary", secondary))
728       DrawParameter(y, "Secondary corr.", secondary ? "yes" : "no");
729     if (GetParameter(c, "acceptance", acceptance))
730       DrawParameter(y, "Acceptance corr.", acceptance ? "yes" : "no");
731     if (GetParameter(c, "vertexBias", vertexBias))
732       DrawParameter(y, "Vertex bias corr.", vertexBias ? "yes" : "no");
733     if (GetParameter(c, "merging", merging))  
734       DrawParameter(y, "Merging eff.", merging ? "yes" : "no");
735     
736     PrintCanvas("Corrector");
737
738     TCollection* cc = GetCollection(c, "esd_mc_comparison", false); 
739     if (!cc) return; // Not MC 
740     
741     DivideForRings(false, false);
742     const char** ptr = GetRingNames(false);
743     while (*ptr) { 
744       DrawInRingPad(GetH2(cc, Form("%s_esd_vs_mc", *ptr)), "colz", 0x0);
745       ptr++;
746     }
747
748     PrintCanvas("Corrector - MC vs Reco");
749   }
750
751   //____________________________________________________________________
752   void DrawHistCollector()
753   {
754     Info("DrawHistCollector", "Drawing histogram collector");  
755     TCollection* c = GetCollection(fSums, "fmdHistCollector");
756     if (!c) return;
757
758     fBody->Divide(2, 1);
759     TVirtualPad* p = fBody->cd(1);
760     p->Divide(1,2);
761     p->cd(1);
762
763     Double_t y = .8;
764     Int_t nCutBins=0, fiducial=0, merge=0, skipRings=0;
765     Double_t fiducialCut=0.;
766     Bool_t  bgAndHits=false;
767     Double_t size = fLandscape ? 0.06 : 0.04;
768     if (GetParameter(c, "nCutBins", nCutBins))
769       DrawParameter(y, "# of bins to cut", Form("%d", nCutBins),size);
770
771     if (GetParameter(c, "skipRings", skipRings)) {
772       TString skipped;
773       if (skipRings & 0x05) skipped.Append("FMD1i ");
774       if (skipRings & 0x09) skipped.Append("FMD2i ");
775       if (skipRings & 0x0a) skipped.Append("FMD2o ");
776       if (skipRings & 0x11) skipped.Append("FMD3i ");
777       if (skipRings & 0x12) skipped.Append("FMD3o ");
778       if (skipped.IsNull()) skipped = "none";
779       DrawParameter(y, "Skipped rings", skipped, size);
780     }
781     if (GetParameter(c, "bgAndHits", bgAndHits))
782       DrawParameter(y, "Bg & hit maps stored.", bgAndHits?"yes":"no",size);
783     if (GetParameter(c, "merge", merge))
784       DrawParameter(y, "Merge method", 
785                     (merge == 0 ? "straight mean" :
786                      merge == 1 ? "straight mean, no zeroes" : 
787                      merge == 2 ? "weighted mean" : 
788                      merge == 3 ? "least error" : 
789                      merge == 4 ? "sum" : "unknown"),size);
790     if (GetParameter(c, "fiducial", fiducial))
791       DrawParameter(y, "Fiducial method.", 
792                     fiducial == 0 ? "cut" : "distance", size);
793     if (GetParameter(c, "fiducialCut", fiducialCut))
794       DrawParameter(y, "Fiducial cut.", Form("%f", fiducialCut), size);
795
796     // p->cd(2);
797     // Printf("Drawing skipped");
798     TH1* skipped = GetH1(c, "skipped");
799     if (skipped) { 
800       skipped->SetFillColor(kRed+1);
801       skipped->SetFillStyle(3001);
802     }
803     DrawInPad(p, 2, skipped, "hist");
804                  
805     p = fBody->cd(2);
806     p->Divide(1,2,0,0);
807
808     // Printf("Drawing sumRings");
809     DrawInPad(p, 1, GetH2(c, "sumRings"), "colz"); 
810     // Printf("Drawing coverage");
811     DrawInPad(p, 2, GetH2(c, "coverage"), "colz");
812     // Printf("Done drawing for now");
813     PrintCanvas("Histogram collector");
814                 
815     
816     TIter next(c);
817     TObject* o = 0;
818     TRegexp regexp("[pm][0-9]+_[pm][0-9]+");
819     while ((o = next())) { 
820       TString name(o->GetName());
821       if (name.Index(regexp) == kNPOS) continue;
822       
823       TList* vl = static_cast<TList*>(o);
824       if (!vl) continue;
825
826       DivideForRings(false, false);
827       const char** ptr = GetRingNames(false);
828       while (*ptr) { 
829         DrawInRingPad(GetH2(vl, Form("secMap%s", *ptr)), "colz", 0x0);
830         DrawInRingPad(GetH2(vl, Form("hitMap%s", *ptr)), "box same", 0x0);
831         ptr++;
832       }
833       PrintCanvas(Form("Histogram Collector - Vertex bin %s", vl->GetName()));
834     }
835
836     o = c->FindObject("byCentrality");
837     if (!o) return;
838     TList* bc = static_cast<TList*>(o);
839
840     DrawInPad(fBody, GetH3(bc, "FMD1I"), "box", 0);
841     DrawInPad(fBody, GetH3(bc, "FMD2I"), "box same", 0);
842     DrawInPad(fBody, GetH3(bc, "FMD2O"), "box same", 0);
843     DrawInPad(fBody, GetH3(bc, "FMD3O"), "box same", 0);
844     DrawInPad(fBody, GetH3(bc, "FMD3I"), "box same", kLegend);
845   }
846
847   //____________________________________________________________________
848   void DrawCentral()
849   {
850     Info("DrawCentral", "Drawing central (SPD)");  
851     TCollection* c = fSums; 
852     if (!c) return;
853
854     fBody->Divide(2, 2);
855     fBody->cd(1);
856     Double_t y = .7;  
857     Bool_t secondary=false, acceptance=false;  
858     if (GetParameter(c, "secondary", secondary))
859       DrawParameter(y, "Secondary corr.", secondary ? "yes" : "no");
860     if (GetParameter(c, "acceptance", acceptance))
861       DrawParameter(y, "Acceptance corr.", acceptance ? "yes" : "no");
862
863                  
864     DrawInPad(fBody, 2, GetH2(c, "coverage"), "col", 0,
865               "#eta coverage per v_{z}");
866     TH2* cvst = GetH2(c, "nClusterVsnTracklet");
867     if (cvst) {
868       // cvst->Scale(1, "width");
869       cvst->GetXaxis()->SetTitle("N_{free cluster}");
870       cvst->GetYaxis()->SetTitle("N_{tracklet}");
871       cvst->GetXaxis()->SetRangeUser(1,10000);
872       cvst->GetYaxis()->SetRangeUser(1,10000);
873     }
874     DrawInPad(fBody, 3, cvst, "colz", kLogx|kLogy|kLogz,
875               "Correlation of # of tracklets and clusters"); 
876     DrawInPad(fBody, 4, GetH2(c, "clusterPerTracklet"), "colz", 0x0,
877               "# clusters per tracklet vs #eta"); 
878     ShowSliceFit(true, cvst, 3, fBody, 3, 0x8000|kLogz);
879
880     fBody->cd(1)->Modified();
881     fBody->cd(2)->Modified();
882     fBody->cd(3)->Modified();
883     fBody->cd(4)->Modified();
884     fBody->cd(1)->Update();
885     fBody->cd(2)->Update();
886     fBody->cd(3)->Update();
887     fBody->cd(4)->Update();
888     PrintCanvas("Central - overview");
889                 
890     
891     TIter next(c);
892     TObject* o = 0;
893     TRegexp regexp("[pm][0-9]+_[pm][0-9]+");
894     while ((o = next())) { 
895       TString name(o->GetName());
896       if (name.Index(regexp) == kNPOS) continue;
897       
898       TList* vl = static_cast<TList*>(o);
899
900       fBody->Divide(1, 3);
901     
902       DrawInPad(fBody, 1, GetH1(vl, "acceptance"), "", 0);
903
904       TH1* sec = GetH1(vl, "secondary");
905       sec->SetMarkerStyle(21);
906       sec->SetMarkerSize(1.2);
907       DrawInPad(fBody, 2, sec, "", 0);
908       DrawInPad(fBody, 2, GetH1(vl, "secondaryFiducial"),    "same", 0x0);
909       DrawInPad(fBody, 3, GetH2(vl, "secondaryMapFiducial"), "colz", 0);
910       DrawInPad(fBody, 3, GetH2(vl, "hitMap"),               "box same", 0x0);
911
912       fBody->cd(1)->Modified();
913       fBody->cd(2)->Modified();
914       fBody->cd(3)->Modified();
915       fBody->cd(1)->Update();
916       fBody->cd(2)->Update();
917       fBody->cd(3)->Update();
918       PrintCanvas(Form("Central - Vertex bin %s", vl->GetName()));
919     }
920   }
921
922   
923   //____________________________________________________________________
924   void AddToAll(THStack* all, const THStack* stack, Int_t curr, Int_t step)
925   {
926     if (!stack) return;
927
928     TIter   next(stack->GetHists());
929     TH1*    h = 0;
930     while ((h = static_cast<TH1*>(next()))) {
931       TH1* copy = static_cast<TH1*>(h->Clone(Form("%s_copy", h->GetName())));
932       copy->SetDirectory(0);
933       if (curr != step) {
934         copy->SetMarkerColor(kGray);
935         copy->SetLineColor(kGray);
936       }
937       all->Add(copy);
938     }
939   }
940   //____________________________________________________________________
941   void AddToAll(THStack* all, const THStack* stack)
942   {
943     if (!stack) return;
944
945     TIter   next(stack->GetHists());
946     TH1*    h = 0;
947     while ((h = static_cast<TH1*>(next()))) {
948       TH1* copy = static_cast<TH1*>(h->Clone(Form("%s_copy", h->GetName())));
949       copy->SetDirectory(0);
950       copy->SetMarkerColor(kGray);
951       copy->SetLineColor(kGray);
952       all->Add(copy);
953     }
954   }
955
956   //____________________________________________________________________
957   void DrawStep(Int_t        step,
958                 THStack*     all,
959                 TObject*     cur,
960                 TLegend*     leg,
961                 const char*  title,
962                 TVirtualPad* can,
963                 Int_t        sub,
964                 Int_t        nCol)
965   {
966     if (all->GetHists()->GetEntries() <= 0 || !cur) return;
967
968     // Info("", "Drawing step # %d", step);
969     Bool_t       left = sub % nCol == 1; 
970     Bool_t       right= sub % nCol == 0;
971     Bool_t       top  = (sub-1) / nCol == 0;
972     TVirtualPad* p    = can->cd(sub);
973     gStyle->SetOptTitle(0);
974     p->SetTitle(Form("Step # %d", step));
975     p->SetFillColor(kWhite);
976     p->SetRightMargin(right ? 0.02 : 0);
977     p->SetTopMargin(top ? 0.02 : 0); // 0.02);
978     // Info("", "Drawing step %d in sub-pad %d (%s)", 
979     //      step, sub, (left?"left":"right"));
980
981     p->cd();
982     all->Draw("nostack");
983     all->GetHistogram()->SetXTitle("#eta");
984     all->GetHistogram()->SetYTitle("signal");
985
986     TLegendEntry* e = 
987       static_cast<TLegendEntry*>(leg->GetListOfPrimitives()->At(step-1));
988     if (e) {
989       e->SetMarkerColor(kBlack);
990       e->SetLineColor(kBlack);
991       e->SetTextColor(kBlack);
992     }
993
994     // p->cd();
995     gROOT->SetSelectedPad(p);
996     cur->DrawClone("same nostack");
997     leg->DrawClone("");
998
999     TLatex* ltx = new TLatex(.97, .97, title);
1000     ltx->SetNDC();
1001     ltx->SetTextSize(.06);
1002     ltx->SetTextAlign(33);
1003     ltx->Draw();
1004
1005     ltx = new TLatex((left ? .12 : .02), .97, p->GetTitle());
1006     ltx->SetNDC();
1007     ltx->SetTextSize(.06);
1008     ltx->SetTextAlign(13);
1009     ltx->Draw();
1010
1011     if (step > 1) { 
1012       Double_t x1 = 0.5*(p->GetUxmax()+p->GetUxmin());
1013       Double_t x2 = x1;
1014       Double_t y1 = p->GetUymax();
1015       Double_t y2 = 0.92*y1;
1016       Double_t sz = 0.05;
1017       if (fLandscape) { 
1018         x1 = 0.99*p->GetUxmin();
1019         x2 = 0.80*x1;
1020         y1 = .5*(p->GetUymax()+p->GetUymin());
1021         y2 = y1;
1022         sz = 0.034;
1023       }
1024       // Info("", "Arrow at (x1,y1)=%f,%f (x2,y2)=%f,%f", x1, y1, x2, y2);
1025       TArrow* a = new TArrow(x1, y1, x2, y2, sz, "|>");
1026       // (fLandscape ? "<|" : "|>"));
1027       a->SetFillColor(kGray+1);
1028       a->SetLineColor(kGray+1);
1029       a->Draw();
1030     }
1031     p->Modified();
1032     p->Update();
1033     p->cd();
1034
1035     if (e) {
1036       e->SetMarkerColor(kGray);
1037       e->SetLineColor(kGray);
1038       e->SetTextColor(kGray);
1039     }
1040     gStyle->SetOptTitle(1);
1041   }
1042
1043   //____________________________________________________________________
1044   void FixStack(THStack* stack, const TString& title, 
1045                 const TString& extra, Int_t marker)
1046   {
1047     if (!stack) return;
1048     stack->SetTitle(title);
1049     TIter next(stack->GetHists());
1050     TH1*  h = 0;
1051     while ((h = static_cast<TH1*>(next())))  {
1052       h->SetMarkerStyle(marker);
1053       TString tit(h->GetTitle());
1054       tit.ReplaceAll("cache", "");
1055       tit.Append(extra);
1056       h->SetTitle(tit);
1057     }
1058   }
1059   void AddLegendEntry(TLegend* l, 
1060                       const TH1* h, 
1061                       const TString& title)
1062   {
1063     if (!h) return;
1064
1065     TLegendEntry* e = l->AddEntry("dummy", title.Data(), "pl");
1066     e->SetMarkerStyle(h->GetMarkerStyle());
1067     e->SetMarkerColor(kGray);
1068     e->SetLineColor(kGray);
1069     e->SetTextColor(kGray);
1070   }
1071                       
1072
1073   //____________________________________________________________________
1074   void DrawSteps()
1075   {
1076     // MakeChapter(can, "Steps");
1077
1078     THStack* esds    = GetStack(GetCollection(fResults, "fmdSharingFilter"), 
1079                                 "sumsESD", "summedESD");
1080     THStack* deltas  = GetStack(GetCollection(fResults, "fmdSharingFilter"), 
1081                                 "sums", "summed");
1082     THStack* nchs    = GetStack(GetCollection(fResults, 
1083                                               "fmdDensityCalculator"), 
1084                                 "sums", "inclDensity");
1085     THStack* prims   = GetStack(GetCollection(fResults, "fmdCorrector"), 
1086                                 "sums", "primaryDensity");
1087     THStack* rings   = GetStack(GetCollection(fResults, "ringResults"), "all");
1088     THStack* mcRings = GetStack(GetCollection(fResults, "mcRingResults", false),
1089                                 "all","dndeta_eta", false);
1090     TH1*     dndeta  = GetH1(fResults, "dNdeta");
1091     if (dndeta) dndeta->SetMarkerColor(kBlack);
1092
1093     FixStack(esds,   "#sum_{s} #Delta/#Delta_{mip}", "",     20);
1094     FixStack(deltas, "#sum_{c} #Delta/#Delta_{mip}", "",     21);
1095     FixStack(nchs,   "#sum_{b} N_{ch,incl}",         "",     22);
1096     FixStack(prims,  "#sum_{b} N_{ch,primary}",      "",     23);
1097     FixStack(rings,  "dN/d#eta per ring",            "",     33);
1098     FixStack(mcRings,"dN/d#eta per ring (MC)",       "(MC)", 34);
1099
1100     THStack* all = new THStack;
1101     AddToAll(all, mcRings);
1102     AddToAll(all, esds);
1103     AddToAll(all, deltas);
1104     AddToAll(all, nchs);
1105     AddToAll(all, prims);
1106     AddToAll(all, rings);
1107
1108     TH1* res = 0;
1109     if (dndeta) {
1110       res = static_cast<TH1*>(dndeta->Clone("dNdeta"));
1111       res->SetTitle("dN/d#eta");
1112       res->SetMarkerColor(kGray);
1113       res->SetLineColor(kGray);
1114       res->SetDirectory(0);
1115       all->Add(res);
1116     }
1117
1118     TLegend* l = new TLegend(.35, .2, .55, .9);
1119     l->SetFillColor(kWhite);
1120     l->SetFillStyle(0);
1121     l->SetBorderSize(0);
1122     TLegendEntry* e = 0;
1123
1124     TH1* h = 0;
1125     if (mcRings) {
1126       h = static_cast<TH1*>(mcRings->GetHists()->At(0));
1127       AddLegendEntry(l, h, mcRings->GetTitle());
1128     }
1129
1130     if (esds) {
1131       h = static_cast<TH1*>(esds->GetHists()->At(0));
1132       AddLegendEntry(l, h, esds->GetTitle());
1133     }
1134
1135     if (deltas) {
1136       h = static_cast<TH1*>(deltas->GetHists()->At(0));
1137       AddLegendEntry(l, h, deltas->GetTitle());    
1138     }
1139
1140     if (nchs) {
1141       h = static_cast<TH1*>(nchs->GetHists()->At(0));
1142       AddLegendEntry(l, h, nchs->GetTitle());    
1143     }
1144
1145     if (prims) {
1146       h = static_cast<TH1*>(prims->GetHists()->At(0));
1147       AddLegendEntry(l, h, prims->GetTitle());    
1148     }
1149
1150     if (rings) {
1151       h = static_cast<TH1*>(rings->GetHists()->At(0));
1152       AddLegendEntry(l, h, rings->GetTitle());    
1153     }
1154
1155     if (res) {
1156       h = res;
1157       AddLegendEntry(l, h, h->GetTitle());
1158     }
1159     
1160     TObject* objs[] = { mcRings, 
1161                         esds, 
1162                         deltas, 
1163                         nchs, 
1164                         prims, 
1165                         rings, 
1166                         dndeta };
1167     const char* titles[] = { /* 1 */ "MC",  
1168                              /* 2 */ "ESD input",
1169                              /* 3 */ "After merging", 
1170                              /* 4 */ "After particle counting", 
1171                              /* 5 */ "After corrections", 
1172                              /* 6 */ "After normalization", 
1173                              /* 7 */ "After combining" };
1174     Int_t nY = mcRings ? 4 : 3;
1175     Int_t nX = 2;
1176     if (fLandscape) {
1177       Int_t tmp = nX;
1178       nX        = nY;
1179       nY        = tmp;
1180     }
1181     fBody->Divide(nX, nY, 0, 0);
1182     
1183     Int_t step = 0;
1184     for (Int_t i = 0; i < 7; i++) { 
1185       TObject* obj = objs[i];
1186       if (!obj) continue;
1187
1188       step++;
1189       Int_t padNo = step;
1190       if (!fLandscape) {
1191         switch (step) { 
1192         case 1: padNo = 1; break; 
1193         case 2: padNo = 3; break; 
1194         case 3: padNo = 5; break; 
1195         case 4: padNo = (mcRings ? 7 : 2); break; 
1196         case 5: padNo = (mcRings ? 2 : 4); break; 
1197         case 6: padNo = (mcRings ? 4 : 6); break; 
1198         case 7: padNo = (mcRings ? 6 : 8); break; 
1199     }
1200       }
1201       //Printf("Drawing step %d in sub-pad %d (%s)",step,padNo,obj->GetTitle());
1202       DrawStep(step, all, obj, l, titles[i], fBody, padNo, nX);
1203     }
1204
1205     if (!esds && !mcRings && deltas) { 
1206       fBody->cd(6);
1207       TLegend* ll = new TLegend(0.01, 0.11, 0.99, 0.99);
1208       // ll->SetNDC();
1209       ll->SetFillColor(kWhite);
1210       ll->SetFillStyle(0);
1211       ll->SetBorderSize(0);
1212
1213       TIter next(deltas->GetHists());
1214       TH1*  hh = 0;
1215       while ((hh = static_cast<TH1*>(next()))) {
1216         e = ll->AddEntry("dummy", hh->GetTitle(), "pl");
1217         e->SetMarkerColor(hh->GetMarkerColor());
1218         e->SetMarkerStyle(hh->GetMarkerStyle());
1219         e->SetLineColor(kBlack);
1220       }
1221       ll->Draw();
1222     }
1223     // Printf("Done drawing steps");
1224     PrintCanvas("Steps");
1225   }
1226
1227
1228   //____________________________________________________________________
1229   void DrawResults()
1230   {
1231     // MakeChapter(can, "Results");
1232
1233     fBody->Divide(2,1);
1234
1235     TCollection* c = GetCollection(fResults, "ringResults");
1236     if (!c) return;
1237   
1238     THStack* mcRings = GetStack(GetCollection(fResults, "mcRingResults", false),
1239                                 "all", "dndeta_eta", false);
1240
1241     TH1* dndeta_phi = GetH1(fResults, "dNdeta");
1242     TH1* dndeta_eta = GetH1(fResults, "dNdeta_");
1243     dndeta_phi->SetTitle("1/N_{ev}dN_{ch}/d#eta (#varphi norm)");
1244     dndeta_eta->SetTitle("1/N_{ev}dN_{ch}/d#eta (#eta norm)");
1245     dndeta_eta->SetMarkerSize(0.7);
1246
1247     THStack* allPhi = new THStack("phiAcc", "#varphi Acceptance");
1248     THStack* allEta = new THStack("etaCov", "#eta Coverage");
1249     const char** pring   = GetRingNames(false);
1250     
1251     while ((*pring)) { 
1252       TCollection* cc     = GetCollection(c, *pring);
1253       TH1*         etaCov = GetH1(cc, "etaCov");
1254       TH1*         phiAcc = GetH1(cc, "phiAcc");
1255       TH1*         dndeta = GetH1(cc, "dndeta_phi");
1256       Int_t        color  = kBlack;
1257       if (dndeta)  color  = dndeta->GetMarkerColor();
1258       if (etaCov) { 
1259         etaCov->SetTitle(*pring);
1260         etaCov->SetFillColor(color);
1261         etaCov->SetLineColor(color);
1262         allEta->Add(etaCov);
1263       }
1264       if (phiAcc) { 
1265         phiAcc->SetFillColor(color);
1266         phiAcc->SetLineColor(color);
1267         allPhi->Add(phiAcc);
1268       }
1269       pring++;
1270     }
1271     Double_t savX = fParVal->GetX();
1272     Double_t savY = fParVal->GetY();
1273     fParVal->SetX(.3);
1274     fParVal->SetY(.2);
1275     TVirtualPad* p = fBody->cd(1);
1276     p->Divide(1,2,0,0);
1277     DrawInPad(p, 1, GetStack(c, "all"), "nostack", mcRings ? 0 : kLegend,
1278               "Individual ring results");
1279     DrawInPad(p, 1, mcRings, "nostack same", kLegend|kSilent);
1280     DrawInPad(p, 2, allEta, "nostack hist", kLegend,
1281               "#phi acceptance and #eta coverage per ring");
1282     DrawInPad(p, 2, allPhi, "nostack hist same", 0x0);
1283
1284     p = fBody->cd(2);
1285     p->Divide(1,2,0,0);
1286     DrawInPad(p, 1, dndeta_phi, "", 0x0, 
1287               "1/#it{N}_{ev} d#it{N}_{ch}/d#it{#eta}");
1288     DrawInPad(p, 1, dndeta_eta, "Same", kLegend);
1289     DrawInPad(p, 2, GetH1(fResults, "norm"), "", 0x0, 
1290               "Total #phi acceptance and #eta coverage");
1291     DrawInPad(p, 2, GetH1(fResults, "phi"), "same", kLegend);
1292     // DrawInPad(fBody, 4, GetH1(fSums,    "d2Ndetadphi"), "colz");
1293
1294     // fBody->cd(1);
1295     // TLatex* l = new TLatex(.5, .2, "Ring results");
1296     // l->SetNDC();
1297     // l->SetTextAlign(21);
1298     // l->Draw();
1299
1300     // fBody->cd(2);
1301     // l->DrawLatex(.5, .2, "1/N_{ev}dN_{ch}/d#eta");
1302
1303     // fBody->cd(3);
1304     // l->DrawLatex(.5, .2, "1/N_{ev}dN_{ch}/d#eta (#vta norm.)");
1305     
1306     fParVal->SetX(savX);
1307     fParVal->SetY(savY);
1308     PrintCanvas("Results");
1309   }
1310
1311   //____________________________________________________________________
1312   void DrawCentralResults()
1313   {
1314     // MakeChapter(can, "Results");
1315     Info("DrawCentralResults", "Drawing central results");
1316
1317     fBody->Divide(1,2,0,0);
1318
1319     TH1* dndeta_ = GetH1(fResults, "dNdeta_");
1320     TH1* dndeta  = GetH1(fResults, "dNdeta");
1321     THStack* stack = new THStack("dndetas", 
1322                                  "d#it{N}_{ch}/d#it{#eta} - central");
1323     stack->Add(dndeta_);
1324     stack->Add(dndeta);
1325     
1326     DrawInPad(fBody, 1, stack, "nostack");
1327     TH1* h = stack->GetHistogram();
1328     if (h) {
1329       h->SetXTitle("#it{#eta}");
1330       h->SetYTitle("#frac{d#it{N}_{ch}}{d#it{#eta}}");
1331     }
1332     fBody->cd(1);
1333     TLegend* l = new TLegend(.3, .05, .7, .4);
1334     l->SetFillColor(0);
1335     l->SetFillStyle(0);
1336     l->SetBorderSize(0);
1337     l->AddEntry(dndeta_, "Normalized to coverage",        "lp");
1338     l->AddEntry(dndeta,  "Normalized to #phi acceptance", "lp");
1339     l->Draw();
1340
1341     DrawInPad(fBody, 2, GetH1(fResults, "norm"));
1342     DrawInPad(fBody, 2, GetH1(fResults, "phi"), "same", kLegend);
1343
1344     PrintCanvas("Central Results");
1345
1346   }
1347   void DrawBoth(TFile* file)
1348   {
1349     Info("DrawBoth", "Drawing central & forward results");
1350     TCollection* central = GetCollection(file, "CentralResults");
1351     TCollection* forward = GetCollection(file, "ForwardResults");
1352     
1353     if (!central || !forward) {
1354       Warning("DrawBoth", "central %p or forward %p results not found", 
1355               central, forward);
1356       return;
1357     }
1358
1359     TH1* f1 = GetH1(forward, "dNdeta_");
1360     TH1* c1 = GetH1(central, "dNdeta_");
1361     TH1* f2 = GetH1(forward, "dNdeta");
1362     TH1* c2 = GetH1(central, "dNdeta");
1363     f1->SetLineColor(kBlack);
1364     f2->SetLineColor(kBlack);
1365     c1->SetLineColor(kBlack);
1366     c2->SetLineColor(kBlack);
1367     f1->SetMarkerColor(f2->GetMarkerColor());
1368     f1->SetMarkerStyle(24);
1369     c1->SetMarkerStyle(24);
1370     c2->SetMarkerStyle(20);
1371     c2->SetMarkerColor(c1->GetMarkerColor());
1372     THStack* s = new THStack("dndetas", "d#it{N}_{ch}/d#it{#eta}");
1373     s->Add(f1);
1374     s->Add(c1);
1375     s->Add(f2);
1376     s->Add(c2);
1377
1378     fBody->Divide(1, 2, 0, 0);
1379     DrawInPad(fBody, 1, s, "nostack");
1380     s->GetHistogram()->SetXTitle("#it{#eta}");
1381     s->GetHistogram()->SetYTitle("#frac{d#it{N}_{ch}}{d#it{#eta}}");
1382     
1383     fBody->cd(1);
1384     TLegend* l = new TLegend(.4, .05, .8, .4);
1385     l->SetFillColor(0);
1386     l->SetFillStyle(0);
1387     l->SetBorderSize(0);
1388     TLegendEntry* entry = l->AddEntry("dummy", "Forward", "f");
1389     entry->SetFillColor(f1->GetMarkerColor());
1390     entry->SetLineColor(f1->GetMarkerColor());
1391     entry->SetFillStyle(1001);
1392     entry->SetLineWidth(0);
1393     entry = l->AddEntry("dummy", "Central", "f");
1394     entry->SetFillColor(c1->GetMarkerColor());
1395     entry->SetLineColor(c1->GetMarkerColor());
1396     entry->SetLineWidth(0);
1397     entry->SetFillStyle(1001);
1398     entry = l->AddEntry("dummy", "Normalized to coverage", "lp");
1399     entry->SetMarkerStyle(f1->GetMarkerStyle());
1400     entry = l->AddEntry("dummy", "Normalized to #phi acceptance", "lp");
1401     entry->SetMarkerStyle(f2->GetMarkerStyle());
1402     l->Draw();
1403
1404     TH1* f3 = GetH1(forward, "norm");
1405     TH1* c3 = GetH1(central, "norm");
1406     TH1* f4 = GetH1(forward, "phi");
1407     TH1* c4 = GetH1(central, "phi");
1408     f3->SetFillColor(f1->GetMarkerColor());
1409     f4->SetFillColor(f1->GetMarkerColor());
1410     c3->SetFillColor(c1->GetMarkerColor());
1411     c4->SetFillColor(c1->GetMarkerColor());
1412     f3->SetLineColor(f1->GetMarkerColor());
1413     f4->SetLineColor(f1->GetMarkerColor());
1414     c3->SetLineColor(c1->GetMarkerColor());
1415     c4->SetLineColor(c1->GetMarkerColor());
1416     
1417     THStack* a = new THStack("norms", "Normalizations");
1418     a->Add(f3);
1419     a->Add(c3);
1420     a->Add(f4);
1421     a->Add(c4);
1422     
1423     a->SetMaximum(a->GetMaximum("nostack")*1.2);
1424     DrawInPad(fBody, 2, a, "nostack");
1425     a->GetHistogram()->SetXTitle("#it{#eta}");
1426     a->GetHistogram()->SetYTitle("Normalization (coverage or acceptance)");
1427     
1428     fBody->cd(2);
1429     l = new TLegend(.2, .94, .9, .99);
1430     l->SetFillColor(0);
1431     l->SetFillStyle(0);
1432     l->SetBorderSize(0);
1433     l->SetNColumns(2);
1434     // entry = l->AddEntry("dummy", "Forward", "f");
1435     // entry->SetFillColor(f1->GetMarkerColor());
1436     // entry->SetLineColor(f1->GetMarkerColor());
1437     // entry->SetFillStyle(1001);
1438     // entry->SetLineWidth(0);
1439     // entry = l->AddEntry("dummy", "Central", "f");
1440     // entry->SetFillColor(c1->GetMarkerColor());
1441     // entry->SetLineColor(c1->GetMarkerColor());
1442     // entry->SetLineWidth(0);
1443     // entry->SetFillStyle(1001);
1444     entry = l->AddEntry("dummy", "#eta Coverage", "f");
1445     entry->SetFillStyle(f3->GetFillStyle());
1446     entry->SetFillColor(kBlack);
1447     entry = l->AddEntry("dummy", "#phi Acceptance", "f");
1448     entry->SetFillStyle(f4->GetFillStyle());
1449     entry->SetFillColor(kBlack);
1450     l->Draw();
1451
1452     PrintCanvas("Both results");
1453   }
1454   TCollection* fSums;
1455   TCollection* fResults;
1456 };
1457
1458 // #endif