]> git.uio.no Git - u/mrichter/AliRoot.git/blob - PWGLF/FORWARD/analysis2/corrs/CorrDrawer.C
Fixes for energy loss generation
[u/mrichter/AliRoot.git] / PWGLF / FORWARD / analysis2 / corrs / CorrDrawer.C
1 #ifndef __CINT__
2 # include "SummaryDrawer.C"
3 # include "AliFMDCorrAcceptance.h"
4 # include "AliFMDCorrSecondaryMap.h"
5 # include "AliFMDCorrELossFit.h"
6 # include "AliForwardUtil.h"
7 # include "AliForwardCorrectionManager.h"
8 # include "AliLog.h"
9 # include <TString.h>
10 # include <TError.h>
11 #else
12 // class SummaryDrawer;
13 // class TAxis;
14 // class AliFMDCorrAcceptance;
15 // class AliFMDCorrSecondaryMap;
16 // class AliFMDCorrELossFit;
17 #endif
18
19 class CorrDrawer : public SummaryDrawer
20 {
21 public:
22   TString  fELossExtra;
23   UShort_t fMinQuality;
24   /** 
25    * Constructor 
26    * 
27    * @param out Output file name 
28    */
29   CorrDrawer() 
30   {
31     fELossExtra = "forward_eloss.root";
32     fMinQuality = 8;
33   }
34   /** 
35    * Destructor.  Closes the PDF 
36    */
37   ~CorrDrawer() 
38   {
39     CloseCanvas();
40   }
41   /** 
42    * Create output file name 
43    * 
44    * @param out    Output file name on return 
45    * @param prefix Prefix of the file name 
46    * @param runNo  Run Number
47    * @param sys    Collision system 
48    * @param sNN    Center of mass energy 
49    * @param field  L3 Field 
50    * @param mc     Simulations or not
51    * @param sat    Satellite interactions or not 
52    */
53   static void MakeFileName(TString&    out,
54                            const TString&  prefix,
55                            ULong_t         runNo, 
56                            UShort_t        sys, 
57                            UShort_t        sNN, 
58                            Short_t         field,
59                            Bool_t          mc=false, 
60                            Bool_t          sat=false)
61   {
62     out = TString::Format("%s_run%09lu_%s_%04dGeV_%c%dkG_%s_%s.pdf",
63                           prefix.Data(), runNo, 
64                           (sys == 1 ? "pp" : 
65                            sys == 2 ? "PbPb" : 
66                            sys == 3 ? "pPb" : "unknown"), sNN, 
67                           (field >= 0 ? 'p' : 'm'), TMath::Abs(field), 
68                           (mc ? "MC" : "real"),
69                           (sat ? "satellite" : "nominal"));
70   }
71   /** 
72    * Draw corrections using the correction manager to get them 
73    *  
74    * @param what    What to draw 
75    * @param out     Output file name on return 
76    * @param prefix  Prefix of the file name 
77    * @param runNo   Run Number
78    * @param sys     Collision system 
79    * @param sNN     Center of mass energy 
80    * @param field   L3 Field 
81    * @param mc      Simulations or not
82    * @param sat     Satellite interactions or not 
83    * @param options Options
84    * @param local   Local database file 
85    */
86   void Run(const Char_t* what, 
87            ULong_t       runNo, 
88            const Char_t* sys, 
89            UShort_t      sNN, 
90            UShort_t      field,
91            Bool_t        mc=false, 
92            Bool_t        sat=false,
93            Option_t*     options="",
94            const char*   local="")         
95   {
96     Run(AliForwardCorrectionManager::ParseFields(what), 
97         runNo, AliForwardUtil::ParseCollisionSystem(sys), 
98         sNN, field, mc, sat, options, local);
99   }
100   void AppendName(TString& what, UShort_t which)
101   {
102     if (!what.IsNull()) what.Append("_");
103     switch (which) {
104     case AliForwardCorrectionManager::kSecondaryMap:
105       what.Append("secondary"); break;
106     case AliForwardCorrectionManager::kAcceptance:
107       what.Append("acceptance"); break;
108     case AliForwardCorrectionManager::kELossFits:                 
109       what.Append("elossfits"); break;
110     default:
111       what.Append("unknown"); break;
112     }
113   }
114   /** 
115    * Draw corrections using the correction manager to get them 
116    *  
117    * @param what    What to draw 
118    * @param out     Output file name on return 
119    * @param prefix  Prefix of the file name 
120    * @param runNo   Run Number
121    * @param sys     Collision system 
122    * @param sNN     Center of mass energy 
123    * @param field   L3 Field 
124    * @param mc      Simulations or not
125    * @param sat     Satellite interactions or not 
126    * @param options Options
127    * @param local   Local database file 
128    */
129   void Run(UShort_t    what, 
130            ULong_t     runNo, 
131            UShort_t    sys, 
132            UShort_t    sNN, 
133            UShort_t    field,
134            Bool_t      mc=false, 
135            Bool_t      sat=false,
136            Option_t*   options="",
137            const char* local="")
138   {
139     AliForwardCorrectionManager& mgr = AliForwardCorrectionManager::Instance();
140     mgr.SetDebug(true);
141     UShort_t flags = 0;
142
143     TString name;
144     if (what & AliForwardCorrectionManager::kSecondaryMap) {
145       flags |= AliForwardCorrectionManager::kSecondaryMap;
146       if (local) mgr.SetSecondaryMapPath(local);
147       AppendName(name, AliForwardCorrectionManager::kSecondaryMap);
148     }
149     if (what & AliForwardCorrectionManager::kAcceptance) {
150       flags |= AliForwardCorrectionManager::kAcceptance;
151       if (local) mgr.SetAcceptancePath(local);
152       AppendName(name, AliForwardCorrectionManager::kAcceptance);
153     }
154     if (what & AliForwardCorrectionManager::kELossFits) {
155       flags |= AliForwardCorrectionManager::kELossFits;
156       if (local) mgr.SetELossFitsPath(local);
157       AppendName(name, AliForwardCorrectionManager::kELossFits);
158     }
159     if (what & AliForwardCorrectionManager::kVertexBias) 
160       Warning("CorrDrawer","Vertex bias not implemented yet");
161     if (what & AliForwardCorrectionManager::kDoubleHit) 
162       Warning("CorrDrawer","Double hit not implemented yet");    
163     if (what & AliForwardCorrectionManager::kMergingEfficiency) 
164       Warning("CorrDrawer","Merging efficiency not implemented yet");
165     
166     if (!mgr.Init(runNo, sys, sNN, field, mc, sat, flags, true)) {
167       Error("CorrDrawer", "Failed to initialize for flags=0x%02x"
168                 "run=%lu, sys=%hu, sNN=%hu, field=%hd, mc=%d, sat=%d",
169                 flags, runNo, sys, sNN, field, mc, sat);
170       return;
171     }
172
173     TString out;
174     MakeFileName(out, name, runNo, sys, sNN, field, mc, sat);
175     CreateCanvas(out);
176
177     fBody->cd();
178     Double_t y = .8;
179     DrawParameter(y, "Run #", Form("%lu", runNo));
180     DrawParameter(y, "System", AliForwardUtil::CollisionSystemString(sys));
181     DrawParameter(y, "#sqrt{s_{NN}}", 
182                   AliForwardUtil::CenterOfMassEnergyString(sys));
183     DrawParameter(y, "L3 field", AliForwardUtil::MagneticFieldString(field));
184     DrawParameter(y, "Simulation", Form("%s", mc ? "yes" : "no"));
185     DrawParameter(y, "Satellite", Form("%s", sat ? "yes" : "no"));
186     PrintCanvas("Title");
187       
188     if (what & AliForwardCorrectionManager::kSecondaryMap) {
189       const AliFMDCorrSecondaryMap* sec = mgr.GetSecondaryMap();
190       if (!sec) 
191         Warning("CorrDrawer","No secondary map available");
192       else 
193         DrawIt(sec, true);
194     }
195     if (what & AliForwardCorrectionManager::kAcceptance) {
196       const AliFMDCorrAcceptance* acc = mgr.GetAcceptance();
197       if (!acc) 
198         Warning("CorrDrawer","No acceptance available");
199       else 
200         DrawIt(acc, true);
201     }
202     if (what & AliForwardCorrectionManager::kELossFits) {
203       const AliFMDCorrELossFit* fit = mgr.GetELossFit();
204       if (!fit) 
205         Warning("CorrDrawer","No energy loss fits available");
206       else 
207         DrawIt(fit, true);
208     }
209     CloseCanvas();
210   }
211   /** 
212    * Fall-back method
213    * 
214    * @param o Object to draw
215    */
216   void Draw(const TObject* o) 
217   {
218     if (!o) return;
219     Warning("CorrDrawer", "Don't know how to draw a %s object", 
220             o->ClassName());
221   }
222   /** 
223    * Draw a single plot of the mean acceptance correction
224    * 
225    * @param acc Acceptance correction
226    */
227   void Draw(const AliFMDCorrAcceptance* acc) { Summarize(acc, false); }
228   /** 
229    * Draw a single plot of the mean secondary correction 
230    * 
231    * @param sec Secondary correction
232    */
233   void Draw(const AliFMDCorrSecondaryMap* sec) { Summarize(sec, false); }
234   /** 
235    * Draw a single plot summarizing the energy loss fits
236    * 
237    * @param sec Energy loss fits
238    */
239   void Draw(const AliFMDCorrELossFit* fits) { Summarize(fits, false); }
240   /** 
241    * A generalized entry to the summarization functions
242    * 
243    * @param what    What to show - only one field
244    * @param runNo   Run number
245    * @param sys     System 
246    * @param sNN     Center of mass energy in GeV
247    * @param field   L3 magnetic field
248    * @param mc      Simulation flag
249    * @param sat     Satellite interaction flag
250    * @param options Options 
251    * @param local   Local storage
252    */
253   void Summarize(const TString& what, 
254                  ULong_t        runNo, 
255                  const Char_t*  sys, 
256                  UShort_t       sNN, 
257                  Short_t        field,
258                  Bool_t         mc=false, 
259                  Bool_t         sat=false,
260                  Option_t*      options="",
261                  const char*    local="")
262   {
263     Summarize(AliForwardCorrectionManager::ParseFields(what), 
264               runNo, AliForwardUtil::ParseCollisionSystem(sys), 
265               sNN, field, mc, sat, options, local);
266   }
267   /** 
268    * A generalized entry to the summarization functions
269    * 
270    * @param what    What to show - only one field
271    * @param runNo   Run number
272    * @param sys     System 
273    * @param sNN     Center of mass energy in GeV
274    * @param field   L3 magnetic field
275    * @param mc      Simulation flag
276    * @param sat     Satellite interaction flag
277    * @param options Options 
278    * @param local   Local storage
279    */
280   void Summarize(UShort_t    what, 
281                  ULong_t     runNo, 
282                  UShort_t    sys, 
283                  UShort_t    sNN, 
284                  Short_t     field,
285                  Bool_t      mc=false, 
286                  Bool_t      sat=false,
287                  Option_t*   options="",
288                  const char* local="")
289   {
290     AliForwardCorrectionManager& mgr = AliForwardCorrectionManager::Instance();
291     mgr.SetDebug(true);
292     if (local) mgr.SetPrefix(gSystem->DirName(local));
293     UShort_t flag = 0;
294     
295     if (what & AliForwardCorrectionManager::kSecondaryMap) 
296       flag = AliForwardCorrectionManager::kSecondaryMap;
297     if (what & AliForwardCorrectionManager::kAcceptance) 
298       flag = AliForwardCorrectionManager::kAcceptance;
299     if (what & AliForwardCorrectionManager::kELossFits) 
300       flag = AliForwardCorrectionManager::kELossFits;
301     if (what & AliForwardCorrectionManager::kVertexBias) 
302       Warning("CorrDrawer","Vertex bias not implemented yet");
303     if (what & AliForwardCorrectionManager::kDoubleHit) 
304       Warning("CorrDrawer","Double hit not implemented yet");    
305     if (what & AliForwardCorrectionManager::kMergingEfficiency) 
306       Warning("CorrDrawer","Merging efficiency not implemented yet");
307     if (flag == 0) { 
308       Warning("CorrDrawer", "Nothing to draw");
309       return;
310     }
311     
312     if (!mgr.Init(runNo, sys, sNN, field, mc, sat, flag, true)) {
313       Error("CorrDrawer", "Failed to initialize for flags=0x%02x "
314             "run=%lu, sys=%hu, sNN=%hu, field=%hd, mc=%d, sat=%d",
315             flag, runNo, sys, sNN, field, mc, sat);
316       return;
317     }
318
319     TString prefix;
320     if      (flag == AliForwardCorrectionManager::kSecondaryMap) 
321       prefix = "secondarymap";
322     else if (flag == AliForwardCorrectionManager::kAcceptance)
323       prefix = "acceptance";
324     else if (flag == AliForwardCorrectionManager::kELossFits) 
325       prefix = "elossfits";
326     else 
327       prefix = "unknown";
328     TString out;
329     MakeFileName(out, prefix, runNo, sys, sNN, field, mc, sat);
330     CreateCanvas(out);
331
332     fBody->cd();
333     Double_t y = .8;
334     DrawParameter(y, "Run #", Form("%lu", runNo));
335     DrawParameter(y, "System", AliForwardUtil::CollisionSystemString(sys));
336     DrawParameter(y, "#sqrt{s_{NN}}", 
337                   AliForwardUtil::CenterOfMassEnergyString(sys));
338     DrawParameter(y, "L3 field", AliForwardUtil::MagneticFieldString(field));
339     DrawParameter(y, "Simulation", Form("%s", mc ? "yes" : "no"));
340     DrawParameter(y, "Satellite", Form("%s", sat ? "yes" : "no"));
341     PrintCanvas("Title");
342       
343     if (flag == AliForwardCorrectionManager::kSecondaryMap) {
344       const AliFMDCorrSecondaryMap* sec = mgr.GetSecondaryMap();
345       if (!sec) 
346         Warning("CorrDrawer","No secondary map available");
347       else 
348         DrawIt(sec, true);
349     }
350     else if (flag == AliForwardCorrectionManager::kAcceptance) {
351       const AliFMDCorrAcceptance* acc = mgr.GetAcceptance();
352       if (!acc) 
353         Warning("CorrDrawer","No acceptance available");
354       else 
355         DrawIt(acc, true);
356     }
357     if (flag == AliForwardCorrectionManager::kELossFits) {
358       const AliFMDCorrELossFit* fit = mgr.GetELossFit();
359       if (!fit) 
360         Warning("CorrDrawer","No energy loss fits available");
361       else 
362         DrawIt(fit, true);
363     }
364     CloseCanvas();
365   }
366   /** 
367    * Fall-back method
368    * 
369    * @param o Object to draw
370    * @param pdf Not used
371    */
372   void Summarize(const TObject* o, Bool_t pdf=true) 
373   {
374     if (!o) return;
375     Warning("CorrDrawer", "Don't know how to draw a %s object", 
376             o->ClassName());
377   }
378   /** 
379    * Draw a single summary plot or multiple plots of the acceptance
380    * correction. A new Canvas is created for this.
381    * 
382    * @param acc Acceptance correction
383    * @param pdf If true, do multiple plots. Otherwise a single summary plot
384    */
385   void Summarize(const AliFMDCorrAcceptance* acc, Bool_t pdf=true) 
386   { 
387     CreateCanvas("acceptance.pdf", false, pdf);
388     DrawIt(acc, pdf); 
389     if (pdf) CloseCanvas();
390   }
391   /** 
392    * Draw a single summary plot multiple plots of the secondary
393    * correction. A new canvas is created for this.
394    * 
395    * @param sec Secondary correction
396    * @param pdf If true, do multiple plots. Otherwise a single summary plot
397    */
398   void Summarize(const AliFMDCorrSecondaryMap* sec, Bool_t pdf=true) 
399   { 
400     CreateCanvas("scondarymap.pdf", false, pdf);
401     DrawIt(sec, pdf); 
402     if (pdf) CloseCanvas();
403   }
404   /** 
405    * Draw a single summary plot multiple plots of the energy loss
406    * fits.  A new canvas is created for this.
407    * 
408    * @param sec Energy loss fits
409    * @param pdf If true, do multiple plots. Otherwise a single summary plot
410    */
411   void Summarize(const AliFMDCorrELossFit* fits, Bool_t pdf=true) 
412   { 
413     CreateCanvas("elossfits.pdf", false, pdf);
414     DrawIt(fits, pdf); 
415     if (pdf) CloseCanvas();
416   }
417
418   static void Summarize(const TString& what   = "", 
419                         Bool_t         mc     = false,
420                         const TString& output = "forward_eloss.root", 
421                         const TString& local  = "fmd_corrections.root",
422                         Option_t*      options= "")
423   {
424     Summarize(AliForwardCorrectionManager::ParseFields(what), mc, 
425               output, local, options);
426   }
427   static void Summarize(UShort_t       what, 
428                         Bool_t         mc     = false,
429                         const TString& output = "forward_eloss.root", 
430                         const TString& local  = "fmd_corrections.root",
431                         Option_t*      options= "")
432   {
433     TFile* fout = TFile::Open(output, "READ");
434     if (!fout) { 
435       Warning("SummarizeELoss", "Energy loss task output %s not found",
436               output.Data());
437       return;
438     }
439     TCollection* forward = GetCollection(fout, "Forward");
440     if (!forward) return;
441     
442     TCollection* eventInsp = GetCollection(forward, "fmdEventInspector");
443     if (!eventInsp) return;
444
445     UShort_t sys   = 0, sNN = 0;
446     Int_t    field = 0;
447     Int_t    runNo; 
448     Bool_t satellite;
449     if (!GetParameter(eventInsp, "sys",       sys))       return;
450     if (!GetParameter(eventInsp, "sNN",       sNN))       return;
451     if (!GetParameter(eventInsp, "field",     field))     return;
452     if (!GetParameter(eventInsp, "satellite", satellite)) return;
453     if (!GetParameter(eventInsp, "runNo",     runNo))     return;
454     
455     CorrDrawer* drawer = new CorrDrawer;
456     drawer->Run(what, runNo, sys, sNN, field, mc, satellite,
457                 options, local);
458   }
459 protected:
460   /** 
461    * Fall-back method
462    * 
463    * @param o Object to summarize
464    */
465   void DrawIt(const TObject* o) 
466   {
467     if (!o) return;
468     Warning("CorrDrawer", "Don't know how to summarize a %s object", 
469             o->ClassName());
470   }
471   /** 
472    * Draw the acceptance correction 
473    * 
474    * @param corr    Correction
475    * @param details If true, make a multipage PDF, otherwise plot the mean. 
476    */
477   void DrawIt(const AliFMDCorrAcceptance* corr, Bool_t details=true)
478   {
479     if (!corr || !fCanvas) return;
480
481     // --- Get vertex axis ---------------------------------------------
482     const TAxis& vtxAxis = corr->GetVertexAxis();
483     Int_t        nVtx    = vtxAxis.GetNbins();
484
485     // --- Create stacks for summaries ---------------------------------
486     TObjArray* stacks  = CreateVtxStacks(vtxAxis);
487     TObjArray* stacks2 = (corr->HasOverflow() && details 
488                           ? CreateVtxStacks(vtxAxis) : 0);
489     
490     //__________________________________________________________________
491     // Create a title page 
492     if (details) {
493       fBody->cd();
494       TLatex* ll = new TLatex(.5,.8, fCanvas->GetTitle());
495       ll->SetTextAlign(22);
496       ll->SetTextSize(0.03);
497       ll->SetNDC();
498       ll->Draw();
499       
500       TLatex* l = new TLatex(.5,.8, "");
501       l->SetNDC();
502       l->SetTextSize(0.03);
503       l->SetTextFont(132);
504       l->SetTextAlign(12);
505       l->DrawLatex(0.2, 0.70, "Acceptance due to dead channels");
506       l->SetTextAlign(22);
507       l->DrawLatex(0.5, 0.55, "c_{v,r}(#eta,#phi) = #frac{"
508                    "#sum active strips #in (#eta,#phi)}{"
509                  "#sum strips #in (#eta,#phi)}");
510       
511       PrintCanvas("Acceptance");
512     }
513     
514     // --- Loop over vertex ------------------------------------------
515     for (UShort_t v=1; v <= nVtx; v++) { 
516       Double_t vzMin = vtxAxis.GetBinLowEdge(v);
517       Double_t vzMax = vtxAxis.GetBinUpEdge(v);
518
519       if (details) DivideForRings(true, true);
520
521       // --- Loop over detectors -------------------------------------
522       for (UShort_t d = 1; d <= 3; d++) {
523         UShort_t     nQ = (d == 1 ? 1 : 2);
524         for (UShort_t q = 0; q < nQ; q++) { 
525           Char_t r = (q == 0 ? 'I' : 'O');
526           
527           TH2* h2 = corr->GetCorrection(d, r, v);
528           if (!h2) { 
529             Warning("DrawCorrAcc", "No correction for FMD%d%c, v=%d", d, r, v);
530             corr->ls();
531             continue;
532           }
533           
534           if (details) DrawInRingPad(d, r, h2, "colz");
535
536           Int_t nY = h2->GetNbinsY();
537           TH1* hh = h2->ProjectionX(Form("FMD%d%c", d, r), 1, nY);
538           hh->Scale(1. / nY);
539           hh->SetDirectory(0);
540           hh->SetMarkerColor(AliForwardUtil::RingColor(d, r));
541           hh->SetLineColor(AliForwardUtil::RingColor(d, r));
542           hh->SetFillColor(AliForwardUtil::RingColor(d, r));
543           hh->SetFillStyle(3001);
544           
545           THStack* stack = static_cast<THStack*>(stacks->At(v-1));
546           if (!stack) { 
547             Error("", "No stack at v=%d", v-1);
548             continue;
549           }
550           stack->Add(hh);
551
552           if (!stacks2) {
553             Warning("", "No phi acceptance defined");
554             continue;
555           }
556           stack = static_cast<THStack*>(stacks2->At(v-1));
557           if (!stack) { 
558             Error("", "No stack at v=%d", v-1);
559             continue;
560           }
561           TH1* hp = corr->GetPhiAcceptance(d, r, v);
562           if (!hp) { 
563             Error("", "No phi acceptance at v=%d", v-1);
564             continue;
565           }
566           hp->SetDirectory(0);
567           hp->SetMarkerColor(AliForwardUtil::RingColor(d, r));
568           hp->SetLineColor(AliForwardUtil::RingColor(d, r));
569           hp->SetFillColor(AliForwardUtil::RingColor(d, r));
570           hp->SetFillStyle(3001);
571           // Info("", "Adding phi acceptance plot %d", Int_t(hp->GetEntries()));
572           stack->Add(hp);
573
574         }
575       }
576       if (details) 
577         PrintCanvas(Form("%+5.1fcm<IP_{z}<%+5.1fcm", vzMin, vzMax));
578     }
579     if (DrawVtxStacks(stacks2, 1.2)) {
580       PrintCanvas("#phi acceptance");
581     }
582     if (DrawVtxStacks(stacks, 1.2)) {
583       PrintCanvas("#LTacceptance#GT");
584     }
585   }
586   /** 
587    * Draw the secondary correction 
588    * 
589    * @param corr       Correction
590    * @param details If true, make a multipage PDF, otherwise plot the mean. 
591    */
592   void DrawIt(const AliFMDCorrSecondaryMap* corr, bool details=true) 
593   {
594     if (!corr || !fCanvas) return;
595     
596     const TAxis& vtxAxis = corr->GetVertexAxis();
597     Int_t        nVtx    = vtxAxis.GetNbins();
598     TObjArray*   stacks  = CreateVtxStacks(vtxAxis);
599     
600     //__________________________________________________________________
601     // Create a title page 
602     if (details) {
603       fBody->cd();
604       TLatex* ll = new TLatex(.5,.8, fCanvas->GetTitle());
605       ll->SetTextAlign(22);
606       ll->SetTextSize(0.03);
607       ll->SetNDC();
608       ll->Draw();
609       
610       TLatex* l = new TLatex(.5,.8, "");
611       l->SetNDC();
612       l->SetTextSize(0.03);
613       l->SetTextFont(132);
614       l->SetTextAlign(12);
615       l->DrawLatex(0.2, 0.70, "Secondary map");
616       l->SetTextAlign(22);
617       l->DrawLatex(0.5, 0.60, "c_{v,r}(#eta,#phi)=#frac{"
618                    "#sum N_{ch,primary,i}(#eta,#phi)}{"
619                    "#sum N_{ch,FMD,i}(#eta,#phi)}");
620       l->SetTextAlign(12);
621       l->DrawLatex(0.2, 0.50, "N: Number of events");
622       l->DrawLatex(0.2, 0.45, "N_{ch,primary,i}(#eta,#phi): Number of charged, "
623                    "primary particles in (#eta,#phi) bin");
624       l->DrawLatex(0.2, 0.40, "N_{ch,primary,i}(#eta,#phi): Number of charged, "
625                    "particles that hit the FMD in (#eta,#phi) bin");
626       l->DrawLatex(0.2, 0.35, "All quantities determined in MC");
627       
628       PrintCanvas("Secondary maps");
629     }
630     
631     // --- Loop over vertex ------------------------------------------
632     for (UShort_t v=1; v <= nVtx; v++) { 
633       Double_t vzMin = vtxAxis.GetBinLowEdge(v);
634       Double_t vzMax = vtxAxis.GetBinUpEdge(v);
635
636       if (details) DivideForRings(true, true);
637
638       // --- Loop over detectors -------------------------------------
639       for (UShort_t d = 1; d <= 3; d++) {
640         UShort_t     nQ = (d == 1 ? 1 : 2);
641         for (UShort_t q = 0; q < nQ; q++) { 
642           Char_t r = (q == 0 ? 'I' : 'O');
643           
644           TH2* h2 = corr->GetCorrection(d, r, v);
645           if (!h2) { 
646             Warning("DrawCorrSec", "No correction for FMD%d%c, v=%d", d, r, v);
647             continue;
648           }
649           
650           if (details) DrawInRingPad(d, r, h2, "colz");
651
652           Int_t nY = h2->GetNbinsY();
653           TH1* hh = h2->ProjectionX(Form("FMD%d%c", d, r), 1, nY);
654           hh->Scale(1. / nY);
655           hh->SetDirectory(0);
656           hh->SetMarkerColor(AliForwardUtil::RingColor(d, r));
657           hh->SetLineColor(AliForwardUtil::RingColor(d, r));
658           hh->SetFillColor(AliForwardUtil::RingColor(d, r));
659           hh->SetFillStyle(3001);
660           
661           THStack* stack = static_cast<THStack*>(stacks->At(v-1));
662           if (!stack) { 
663             Error("", "No stack at v=%d", v-1);
664             continue;
665           }
666           stack->Add(hh);
667         }
668       }
669       if (details) 
670         PrintCanvas(Form("%+5.1fcm<IP_{z}<%+5.1fcm", vzMin, vzMax));
671     }
672     if (DrawVtxStacks(stacks, 3.5)) {
673       PrintCanvas("#LTsecondary map#GT");
674     }
675   }
676   /** 
677    * Draw the energy loss fits correction 
678    * 
679    * @param corr       Correction
680    * @param details If true, make a multipage PDF, 
681    *                   otherwise plot the parameters. 
682    */
683   void DrawIt(const AliFMDCorrELossFit* corr, bool details=true) 
684   {
685     if (!corr || !fCanvas) return;
686
687     AliFMDCorrELossFit* fits = const_cast<AliFMDCorrELossFit*>(corr);
688     fits->CacheBins(8);
689     fits->Print("C");
690     TList* fitter = 0;
691     if (details) { 
692       TFile* hists = 0;
693       TDirectory* savDir = gDirectory;
694       if (!gSystem->AccessPathName(fELossExtra.Data())) {
695         hists = TFile::Open(fELossExtra, "READ");
696         // Info("", "Opened forward_eloss.root -> %p", hists);
697       }
698       if (hists) {
699         TList* fr = static_cast<TList*>(hists->Get("ForwardResults"));
700         // Info("", "Got forward results -> %p", fr);
701         if (fr) { 
702           fitter = static_cast<TList*>(fr->FindObject("fmdEnergyFitter"));
703           // Info("", "Got fitter -> %p", fitter);
704         }
705         hists->Close();
706         savDir->cd();
707       }
708       fBody->cd();
709       TLatex* ll = new TLatex(.5,.8, fCanvas->GetTitle());
710       ll->SetTextAlign(22);
711       ll->SetTextSize(0.05);
712       ll->SetNDC();
713       ll->Draw();
714       
715       TLatex* l = new TLatex(.5,.8, "");
716       l->SetNDC();
717       l->SetTextSize(0.03);
718       l->SetTextFont(132);
719       l->SetTextAlign(12);
720       l->DrawLatex(0.2, 0.70, "1^{st} page is a summary of fit parameters");
721       l->DrawLatex(0.2, 0.67, "2^{nd} page is a summary of relative errors");
722       l->DrawLatex(0.2, 0.64, "Subsequent pages shows the fitted functions");
723       l->DrawLatex(0.3, 0.60, "Black line is the full fitted function");
724       l->DrawLatex(0.3, 0.57, "Coloured lines are the individual N-mip comp.");
725       //l->DrawLatex(0.3, 0.54, "Full drawn lines correspond to used components");
726       //l->DrawLatex(0.3, 0.51, "Dashed lines correspond to ignored components");
727       l->DrawLatex(0.2, 0.54, "Each component has the form");
728       l->DrawLatex(0.3, 0.49, "f_{n}(x; #Delta, #xi, #sigma') = "
729                    "#int_{-#infty}^{+#infty}d#Delta' "
730                    "landau(x; #Delta', #xi)gaus(#Delta'; #Delta, #sigma')");
731       l->DrawLatex(0.2, 0.44, "The full function is given by");
732       l->DrawLatex(0.3, 0.41, "f_{N}(x; #Delta, #xi, #sigma', #bf{a}) = "
733                  "C #sum_{i=1}^{N} a_{i} "
734                    "f_{i}(x; #Delta_{i}, #xi_{i}, #sigma_{i}')");
735       l->DrawLatex(0.3, 0.35, "#Delta_{i} = i (#Delta_{1} + #xi_{1} log(i))");
736       l->DrawLatex(0.3, 0.32, "#xi_{i} = i #xi_{1}");
737       l->DrawLatex(0.3, 0.29, "#sigma_{i} = #sqrt{i} #sigma_{1}");
738       l->DrawLatex(0.3, 0.26, "#sigma_{n} #dot{=} 0");
739       l->DrawLatex(0.3, 0.23, "#sigma_{i}'^{2} = #sigma^{2}_{n} + #sigma_{i}^{2}");
740       l->DrawLatex(0.3, 0.20, "a_{1} #dot{=} 1");
741       l->DrawLatex(0.3, 0.15, Form("Least quality: %d", fMinQuality));
742       if (fitter) {
743         TObject* refit = fitter->FindObject("refitted");
744         if (refit) l->DrawLatex(0.3, .10, "Refitted distributions");
745       }
746       PrintCanvas("Energy loss fits");
747     }
748
749     fBody->cd();
750     fits->Draw("error");
751     PrintCanvas("Fit overview");
752     if (!details) return;
753
754     //__________________________________________________________________
755     // Draw relative parameter errors 
756     fBody->cd();
757     fits->Draw("relative");
758     PrintCanvas("Relative parameter errors");
759
760     //__________________________________________________________________
761     // Draw all fits individually
762     for (UShort_t d=1; d<=3; d++) { 
763       UShort_t nQ = (d == 1 ? 1 : 2);
764       for (UShort_t q = 0; q < nQ; q++) { 
765         Char_t r = (q == 0 ? 'I' : 'O');
766         TList* dists = 0;
767         if (fitter) { 
768           // Info("", "Fitter: %s", fitter->GetName());
769           TList* dl = 
770             static_cast<TList*>(fitter->FindObject(Form("FMD%d%c",d,r)));
771           // Info("", "Got detector list -> %p", dl);
772           if (dl) { 
773             // Info("", "Detector list: %s", dl->GetName());
774             dists = static_cast<TList*>(dl->FindObject("EDists"));
775             // Info("", "Got distributions -> %p", dists);
776           }
777         }
778         
779         printf("FMD%d%c ", d, r);
780         ClearCanvas();
781         TObjArray*  ra = fits->GetRingArray(d, r);
782         if (!ra) continue;
783         DrawELossFits(d, r, ra, dists);
784       }
785     }
786   }
787   /** 
788    * CINT does too much when optimizing on a loop, so we take this out
789    * to force CINT to not optimize the third nested loop.
790    * 
791    * @param d 
792    * @param r 
793    * @param ra 
794    */
795   void DrawELossFits(UShort_t d, Char_t r, TObjArray* ra, TList* dists)
796   {
797     Int_t nPad = 6;
798     AliFMDCorrELossFit::ELossFit* fit = 0;
799     TIter next(ra);
800     Int_t i = 0;
801     Int_t j = 0;
802     while ((fit = static_cast<AliFMDCorrELossFit::ELossFit*>(next()))) {
803       j           = i % nPad;
804       Bool_t last = j == nPad-1;
805       if (j == 0) DivideForRings(true, true);
806
807       Bool_t same = false;
808       if (dists) { 
809         // Info("", "Distributions: %s", dists->GetName());
810         TH1* dist = 
811           static_cast<TH1*>(dists->FindObject(Form("FMD%d%c_etabin%03d", 
812                                                    d,r,fit->GetBin())));
813         // Info("", "Got histogram -> %p", dist);
814         if (dist) { 
815           // Info("", "Histogram: %s", dist->GetName());
816           DrawInPad(fBody, j+1, dist, "HIST", 0x2);
817           same = true;    
818         }
819       }
820       // if (same)
821       DrawInPad(fBody, j+1, fit, 
822                 Form("comp good values legend %s", (same ? "same" : "")),
823                 0x2);
824       if (fit->GetQuality() < fMinQuality) { 
825         TLatex* ltx = new TLatex(.2, .2, "NOT USED");
826         ltx->SetNDC();
827         ltx->SetTextFont(62);
828         ltx->SetTextColor(kRed+1);
829         ltx->SetTextAngle(30);
830         ltx->SetTextSize(0.2);
831         DrawInPad(fBody, j+1, ltx, "", 0);
832         // ltx->Draw();
833       }
834
835       // else 
836       // DrawInPad(fBody, j+1, fit, "comp good values legend", 0x2);
837       printf(".");
838       
839       if (last) 
840         PrintCanvas(Form("FMD%d%c page %d", d, r, (i/nPad)+1));
841       i++;
842     }
843     j = i % nPad;
844     if (j != 0) 
845       PrintCanvas(Form("FMD%d%c page %d", d, r, (i/nPad)+1));
846     printf(" done\n");
847   }
848
849   /** 
850    * Create an array of per-vertex bin stacks 
851    * 
852    * @param vtxAxis Vertex axis 
853    * 
854    * @return Array of stacks 
855    */
856   TObjArray* CreateVtxStacks(const TAxis& vtxAxis)
857   {
858     // --- Create stacks for summaries ---------------------------------
859     Int_t      nVtx    = vtxAxis.GetNbins();
860     TObjArray* stacks  = new TObjArray(nVtx);
861     for (UShort_t v = 1; v <= nVtx; v++) { 
862       THStack* stack = new THStack(Form("vtx%02d", v),
863                                    Form("%+5.1f<v_{z}<%+5.1f",
864                                         vtxAxis.GetBinLowEdge(v),
865                                         vtxAxis.GetBinUpEdge(v)));
866       stacks->AddAt(stack, v-1);
867     }
868     return stacks;
869   }
870   /** 
871    * Draw the vertex stacks in the canvas 
872    * 
873    * @param stacks Stacks to draw
874    * @param max    Possible maximum of the stacks 
875    * 
876    * @return true on success 
877    */
878   Bool_t DrawVtxStacks(TObjArray* stacks, Double_t max=-1)
879   {
880     if (!stacks) return false;
881     // --- Make summary page -------------------------------------------
882     Int_t nVtx = 10; // stacks->GetEntries();
883
884     fBody->Divide(3, (nVtx+2)/3, 0, 0);
885     Int_t ipad = 0;
886     for (UShort_t v = 1; v <= nVtx; v++) {
887       ipad++;
888     
889       if (ipad == 1 || ipad == 12) ipad++;
890
891       THStack*     stack = static_cast<THStack*>(stacks->At(v-1));
892       if (!stack) { 
893         Error("", "No stack at v=%d", v-1);
894         continue;
895       }
896       TVirtualPad* pad   = fBody->cd(ipad);
897       if (!pad) { 
898         Error("", "No pad at %d", ipad);
899         continue;
900       }
901       pad->SetFillColor(kWhite);
902     
903       if (max > 0) stack->SetMaximum(max);
904       stack->Draw("nostack hist");
905     }
906     return true;
907   }
908
909 };
910
911
912   
913 //
914 // EOF
915 //