]> git.uio.no Git - u/mrichter/AliRoot.git/blame - PWGLF/FORWARD/analysis2/scripts/SummaryDrawer.C
Added script to copy secondary correction
[u/mrichter/AliRoot.git] / PWGLF / FORWARD / analysis2 / scripts / SummaryDrawer.C
CommitLineData
2955f67c 1/**
2 * @file SummaryDrawer.C
3 * @author Christian Holm Christensen <cholm@master.hehi.nbi.dk>
4 * @date Sun Nov 25 11:36:41 2012
5 *
6 * @brief Base class for classes to draw summaries
7 *
8 *
9 */
10#ifndef SUMMARYDRAWER_C
11# define SUMMARYDRAWER_C
12# ifndef __CINT__
13# include <THStack.h>
14# include <TH1.h>
15# include <TH2.h>
8449e3e0 16# include <TH3.h>
2955f67c 17# include <TParameter.h>
18# include <TCanvas.h>
19# include <TList.h>
20# include <TFile.h>
21# include <TError.h>
22# include <TLatex.h>
23# include <TLegend.h>
24# include <TLegendEntry.h>
25# include <TMath.h>
26# include <TString.h>
27# include <TStyle.h>
28# include <TSystem.h>
29# include <TProfile.h>
30# include <TGaxis.h>
31# include <TPad.h>
8449e3e0 32# include <TRegexp.h>
77f97e3f 33# include <TGraph.h>
a19faec0 34# include <sstream>
35# include <iomanip>
bfab35d9 36# else
37# ifdef __ACLIC__
2955f67c 38class THStack;
39class TH1;
40class TH2;
8449e3e0 41class TH3;
2955f67c 42class TCollection;
43class TCanvas;
44class TVirtualPad;
45class TPad;
46class TLatex;
47class TAxis;
bfab35d9 48# endif
2955f67c 49# endif
50
8449e3e0 51/**
52 * Base class for summary drawers
53 *
54 */
2955f67c 55class SummaryDrawer
56{
57public:
bfab35d9 58 enum {
59 kLogx = 0x1,
60 kLogy = 0x2,
61 kLogz = 0x4,
62 kLegend = 0x10,
63 kGridx = 0x100,
64 kGridy = 0x200,
b767da2c 65 kGridz = 0x400,
70849dc0 66 kSilent = 0x800,
67 kNorth = 0x1000,
68 kMiddle = 0x2000,
69 kSouth = 0x3000,
70 kEast = 0x10000,
71 kCenter = 0x20000,
72 kWest = 0x30000
bfab35d9 73 };
fba5d22d 74 enum {
75 kLandscape = 0x100,
76 kPause = 0x200
77 };
2955f67c 78 SummaryDrawer()
79 : fCanvas(0),
80 fTop(0),
81 fBody(0),
82 fHeader(0),
83 fParName(0),
84 fParVal(0),
85 fPause(false),
86 fLandscape(false),
8449e3e0 87 fRingMap(0),
77f97e3f
CHC
88 fPDF(true),
89 fLastTitle("")
2955f67c 90 {
91 fRingMap = new TVirtualPad*[6];
92 fRingMap[0] = 0;
93 fRingMap[1] = 0;
94 fRingMap[2] = 0;
95 fRingMap[3] = 0;
96 fRingMap[4] = 0;
97 fRingMap[5] = 0;
98 }
bfab35d9 99 virtual ~SummaryDrawer() {}
2955f67c 100
101protected:
70849dc0 102 //____________________________________________________________________
7095962e
CHC
103 /**
104 * Get null terminated array of ring names
105 *
106 * @param lower If true, return in the form FMD[1-3][io], otherwise
107 * in the form FMD[1-3][IO]
108 *
109 * @return Null terminated array of ring names
110 */
111 static const Char_t** GetRingNames(Bool_t lower=false)
112 {
113 static const Char_t* lN[]={ "FMD1i", "FMD2i", "FMD2o", "FMD3o", "FMD3i", 0};
114 static const Char_t* uN[]={ "FMD1I", "FMD2I", "FMD2O", "FMD3O", "FMD3I", 0};
115 return (lower ? lN : uN);
116 }
70849dc0 117 //____________________________________________________________________
bfab35d9 118 /**
119 * Get the standard color for a ring
120 *
121 * @param d Detector
122 * @param r Ring
123 *
124 * @return
125 */
126 static Color_t RingColor(UShort_t d, Char_t r)
127 {
128 return ((d == 1 ? kRed : (d == 2 ? kGreen : kBlue))
129 + ((r == 'I' || r == 'i') ? 2 : -3));
130 }
70849dc0 131 //____________________________________________________________________
132 TLegend* DrawRingLegend(TVirtualPad* p, UInt_t flags)
133 {
134 TLegend* l = MakeLegend(p, flags, false);
135
136 for (UShort_t i = 0; i < 5; i++) {
137 UShort_t d = (i+1)/2+1;
a19faec0 138 Char_t r = (i/2 == 1) ? 'o' : 'i';
70849dc0 139 TLegendEntry* e = l->AddEntry("dummy", Form("FMD%d%c", d, r), "f");
140 e->SetFillColor(RingColor(d, r));
141 e->SetFillStyle(1001);
142 e->SetLineColor(kBlack);
143 }
144
145 l->Draw();
146 return l;
147 }
148 //____________________________________________________________________
fba5d22d 149 static void SysString(UShort_t sys, TString& str)
150 {
151 str = "?";
152 switch (sys) {
153 case 1: str = "pp"; break;
154 case 2: str = "PbPb"; break;
155 case 3: str = "pPb"; break;
156 }
157 }
70849dc0 158 //____________________________________________________________________
fba5d22d 159 static void SNNString(UShort_t sNN, TString& str)
160 {
161 str = "?";
162 if (sNN < 1000) str = Form("%dGeV", sNN);
163 else if (sNN < 3000) str = Form("%4.2fTeV", 0.001*sNN);
164 else str = Form("%dTeV", sNN/1000);
165 }
70849dc0 166 //____________________________________________________________________
2955f67c 167 /**
fba5d22d 168 * Append an & to a string and the next term.
2955f67c 169 *
fba5d22d 170 * @param trg Output string
171 * @param what Term
2955f67c 172 */
fba5d22d 173 static void AppendAnd(TString& trg, const TString& what)
2955f67c 174 {
fba5d22d 175 if (!trg.IsNull()) trg.Append(" & ");
176 trg.Append(what);
177 }
70849dc0 178 //____________________________________________________________________
fba5d22d 179 static void TriggerString(ULong_t trigger, TString& str)
180 {
181 str = "";
182 /**
183 * Bits of the trigger pattern
184 */
185 enum {
186 /** In-elastic collision */
187 kInel = 0x0001,
188 /** In-elastic collision with at least one SPD tracklet */
189 kInelGt0 = 0x0002,
190 /** Non-single diffractive collision */
191 kNSD = 0x0004,
192 /** Empty bunch crossing */
193 kEmpty = 0x0008,
194 /** A-side trigger */
195 kA = 0x0010,
196 /** B(arrel) trigger */
197 kB = 0x0020,
198 /** C-side trigger */
199 kC = 0x0080,
200 /** Empty trigger */
201 kE = 0x0100,
202 /** pileup from SPD */
203 kPileUp = 0x0200,
204 /** true NSD from MC */
205 kMCNSD = 0x0400,
206 /** Offline MB triggered */
207 kOffline = 0x0800,
208 /** At least one SPD cluster */
209 kNClusterGt0 = 0x1000,
210 /** V0-AND trigger */
211 kV0AND = 0x2000,
212 /** Satellite event */
213 kSatellite = 0x4000
214 };
215 if ((trigger & kInel) != 0x0) AppendAnd(str, "INEL");
216 if ((trigger & kInelGt0) != 0x0) AppendAnd(str, "INEL>0");
217 if ((trigger & kNSD) != 0x0) AppendAnd(str, "NSD");
218 if ((trigger & kV0AND) != 0x0) AppendAnd(str, "V0AND");
219 if ((trigger & kA) != 0x0) AppendAnd(str, "A");
220 if ((trigger & kB) != 0x0) AppendAnd(str, "B");
221 if ((trigger & kC) != 0x0) AppendAnd(str, "C");
222 if ((trigger & kE) != 0x0) AppendAnd(str, "E");
223 if ((trigger & kMCNSD) != 0x0) AppendAnd(str, "MCNSD");
224 if ((trigger & kNClusterGt0) != 0x0) AppendAnd(str, "NCluster>0");
225 if ((trigger & kSatellite) != 0x0) AppendAnd(str, "Satellite");
2955f67c 226 }
fba5d22d 227
2955f67c 228 //__________________________________________________________________
229 /**
fba5d22d 230 * Find an object in a collection
2955f67c 231 *
232 * @param parent Parent directory
233 * @param name Name of object
33438b4c 234 * @param verb Be verbose
2955f67c 235 *
236 * @return Pointer to object or null
237 */
fba5d22d 238 static TObject* GetObject(const TObject* parent,
2955f67c 239 const TString& name,
240 Bool_t verb=true)
241 {
242 if (!parent) {
fba5d22d 243 if (verb) Warning("GetObject", "No parent given");
2955f67c 244 return 0;
245 }
246 if (name.IsNull()) {
247 if (verb) Warning("GetObject", "No name specified");
248 return 0;
249 }
fba5d22d 250 TObject* o = 0;
251 if (parent->IsA()->InheritsFrom(TCollection::Class())) {
252 const TCollection* p = static_cast<const TCollection*>(parent);
253 o = p->FindObject(name);
254 }
255 else if (parent->IsA()->InheritsFrom(TDirectory::Class())) {
256 const TDirectory* d = static_cast<const TDirectory*>(parent);
257 o = const_cast<TDirectory*>(d)->Get(name);
258 }
259 else
260 Warning("GetObject", "Do not know how to find an object (%s) in "
261 "%s (of class %s)", name.Data(),
262 parent ? parent->GetName() : "?",
263 parent ? parent->ClassName() : "?");
2955f67c 264 if (!o) {
265 if (verb) Warning("GetObject", "Object \"%s\" not found in parent \"%s\"",
266 name.Data(), parent->GetName());
267 return 0;
268 }
fba5d22d 269 return o;
2955f67c 270 }
271 //____________________________________________________________________
272 /**
273 * Check the type of a found object
274 *
275 * @param o Object
276 * @param cl Class
277 * @param src Source of object
278 *
279 * @return true on success, false otherwise
280 */
281 static Bool_t CheckType(const TObject* o,
282 const TClass* cl,
283 const TString& src)
284 {
285 if (!o->IsA()->InheritsFrom(cl)) {
286 Warning("CheckType", "Object \"%s\" retrieved from \"%s\" is not a "
287 "%s but a %s", o->GetName(), src.Data(), cl->GetName(),
288 o->ClassName());
289 return false;
290 }
291 return true;
292 }
fba5d22d 293 //__________________________________________________________________
294 /**
295 * Check a possibly returned object.
296 *
297 * @param o Object found - if any
298 * @param p Parent of object
299 *
300 * @return A pointer to the object cast to the right type
301 */
302 template <typename T>
303 static T* DoGetObject(TObject* o, const TObject* p)
304 {
305 if (!o) return 0;
306 if (!CheckType(o, T::Class(), p->GetName())) return 0;
307 return static_cast<T*>(o);
308 }
309 //__________________________________________________________________
310 /**
311 * Check a returned parameter from a parent
312 *
313 * @param o Possibly found object
314 * @param p Parent object
315 * @param value Value
316 *
317 * @return true on success, false otherwise
318 */
4fdca35c 319 template <typename T>
320 static Bool_t DoGetParameter(TObject* o, const TObject* p, T& value)
321 {
fba5d22d 322 TParameter<T>* r = DoGetObject<TParameter<T> >(o, p);
323 if (!r) return false;
324 // if (r->TestBit(TParameter<T>::kFirst)) value = r->GetVal();
325 // else value = r->GetUniqueID();
326 value = r->GetVal();
327 if (!r->TestBit(BIT(19))) {
328 TObject* oc = GetObject(p, "count", false);
329 if (oc) {
330 TParameter<int>* pc = static_cast<TParameter<int>*>(oc);
331 int cnt = pc->GetVal();
332 value /= cnt;
333 }
334 else
335 value = r->GetUniqueID();
336 }
337 // value = r->GetUniqueID();
4fdca35c 338 return true;
339 }
340
a19faec0 341 //___________________________________________________________________
342 /**
343 * Get a Short_t parameter value
344 *
345 * @param c Parent collection
346 * @param name Name of parameter
347 * @param value On return the value
348 * @param verb If true, complain if not found
349 */
350 static Bool_t GetParameter(const TObject* c,
351 const TString& name,
352 Short_t& value,
353 Bool_t verb=true)
354 {
355 int v;
356 Bool_t r = DoGetParameter(GetObject(c, name, verb), c, v);
357 value = v;
358 return r;
359 }
2955f67c 360 //___________________________________________________________________
361 /**
362 * Get a UShort_t parameter value
363 *
364 * @param c Parent collection
365 * @param name Name of parameter
366 * @param value On return the value
367 * @param verb If true, complain if not found
368 */
fba5d22d 369 static Bool_t GetParameter(const TObject* c,
370 const TString& name,
371 UShort_t& value,
372 Bool_t verb=true)
2955f67c 373 {
4fdca35c 374 int v;
375 Bool_t r = DoGetParameter(GetObject(c, name, verb), c, v);
376 value = v;
377 return r;
378 }
fba5d22d 379 //___________________________________________________________________
380 /**
a19faec0 381 * Get a ULong_t parameter value
fba5d22d 382 *
383 * @param c Parent collection
384 * @param name Name of parameter
385 * @param value On return the value
386 * @param verb If true, complain if not found
387 */
388 static Bool_t GetParameter(const TObject* c,
389 const TString& name,
390 ULong_t& value,
391 Bool_t verb=true)
4fdca35c 392 {
fba5d22d 393 Long_t v;
394 Bool_t r = DoGetParameter(GetObject(c, name, verb), c, v);
4fdca35c 395 value = v;
396 return r;
2955f67c 397 }
398 //_____________________________________________________________________
399 /**
400 * Get a Int_t parameter value
401 *
402 * @param c Parent collection
403 * @param name Name of parameter
404 * @param value On return the value
405 * @param verb If true, complain if not found
406 */
fba5d22d 407 static Bool_t GetParameter(const TObject* c,
408 const TString& name,
409 Int_t& value,
410 Bool_t verb=true)
4fdca35c 411 {
412 return DoGetParameter(GetObject(c, name, verb), c, value);
2955f67c 413 }
414 //_____________________________________________________________________
415 /**
416 * Get a Double_t parameter value
417 *
418 * @param c Parent collection
419 * @param name Name of parameter
420 * @param value On return the value
421 * @param verb If true, complain if not found
422 */
fba5d22d 423 static Bool_t GetParameter(const TObject* c,
4fdca35c 424 const TString& name,
425 Double_t& value,
426 Bool_t verb=true);
2955f67c 427 //_____________________________________________________________________
428 /**
429 * Get a Bool_t parameter value
430 *
431 * @param c Parent collection
432 * @param name Name of parameter
433 * @param value On return the value
434 * @param verb If true, complain if not found
435 */
fba5d22d 436 static Bool_t GetParameter(const TObject* c,
4fdca35c 437 const TString& name,
438 Bool_t& value,
439 Bool_t verb=true)
440 {
441 return DoGetParameter(GetObject(c, name, verb), c, value);
2955f67c 442 }
443 //____________________________________________________________________
444 /**
445 * Find a collection in another collection
446 *
447 * @param parent Parent collection
448 * @param name Name of the collection
449 * @param verb If true and not found, complain
450 *
451 * @return pointer to collection on success, otherwise null
452 */
fba5d22d 453 static TCollection* GetCollection(const TObject* parent,
2955f67c 454 const TString& name,
455 Bool_t verb=true)
456 {
fba5d22d 457 return DoGetObject<TCollection>(GetObject(parent, name, verb), parent);
2955f67c 458 }
459 //____________________________________________________________________
460 /**
fba5d22d 461 * Check a 1D histogram object from a parent
2955f67c 462 *
c8b1a7db 463 * @param parent Parent collection
464 * @param name Name of histogram
465 * @param verb Possibly be verbose
2955f67c 466 *
467 * @return pointer or null
468 */
fba5d22d 469 static TH1* GetH1(const TObject* parent,
2955f67c 470 const TString& name,
471 Bool_t verb=true)
472 {
fba5d22d 473 return DoGetObject<TH1>(GetObject(parent, name, verb), parent);
2955f67c 474 }
475 //____________________________________________________________________
476 /**
477 * Get a 2D histogram from a collection
478 *
479 * @param parent Parent collection
480 * @param name Name of histogram
481 * @param verb If true and not found, complain
482 *
483 * @return pointer or null
484 */
fba5d22d 485 static TH2* GetH2(const TObject* parent,
4fdca35c 486 const TString& name,
487 Bool_t verb=true)
488 {
fba5d22d 489 return DoGetObject<TH2>(GetObject(parent, name, verb), parent);
2955f67c 490 }
8449e3e0 491 //____________________________________________________________________
492 /**
493 * Get a 2D histogram from a collection
494 *
495 * @param parent Parent collection
496 * @param name Name of histogram
497 * @param verb If true and not found, complain
498 *
499 * @return pointer or null
500 */
501 static TH3* GetH3(const TCollection* parent,
502 const TString& name,
503 Bool_t verb=true)
504 {
505 // Info("GetH2", "Getting 2D histogram of %s from %p", name.Data(), c);
506 // --- Find the object -------------------------------------------
fba5d22d 507 return DoGetObject<TH3>(GetObject(parent, name, verb), parent);
8449e3e0 508 }
2955f67c 509 //__________________________________________________________________
510 /**
511 * Get a histogram stack from a collection
512 *
513 * @param parent Parent collection
514 * @param name Name of histogram
fba5d22d 515 * @param sub If set, fill from sub-component
2955f67c 516 * @param verb If true and not found, complain
517 *
518 * @return pointer or null
519 */
fba5d22d 520 static THStack* GetStack(const TObject* parent,
521 const TString& name,
522 const char* sub=0,
523 Bool_t verb=true)
4fdca35c 524 {
fba5d22d 525 THStack* stack = DoGetObject<THStack>(GetObject(parent,name,verb),parent);
526 if (!stack) return 0;
2955f67c 527 if (sub == 0) return stack;
528
529 if (stack->GetHists()->GetEntries() <= 0 ||stack->GetMaximum() < 1) {
530 // Info("GetStack", "No entries in %s", name.Data());
531 stack->GetHists()->Delete();
7095962e 532 const char** ptr = GetRingNames(false);
2955f67c 533 while (*ptr) {
534 TCollection* sc = GetCollection(parent, *ptr, true);
535 if (!sc) { ptr++; continue; }
536
537 TObject* obj = GetObject(sc, sub);
538 if (!obj) {
539 continue;
540 ptr++;
541 }
542
543 if (obj->IsA()->InheritsFrom(TH2::Class())) {
544 TH2* h = static_cast<TH2*>(obj);
545 TH1* p = h->ProjectionX(*ptr, 1, h->GetNbinsY(), "e");
546 p->Scale(1., "width");
547 p->SetTitle(*ptr);
548 p->SetDirectory(0);
549 stack->Add(p);
550 }
551 else if (obj->IsA()->InheritsFrom(TH1::Class())) {
552 TH1* hh = static_cast<TH1*>(obj);
553 hh->SetTitle(*ptr);
554 stack->Add(hh);
555 }
556 ptr++;
557 }
558 }
559 // --- Return the collection -------------------------------------
560 return stack;
561 }
562 //____________________________________________________________________
563 /**
564 * Clear canvas
565 *
566 */
567 void ClearCanvas()
568 {
569 fTop->Clear();
570 fTop->SetNumber(1);
571 fTop->SetFillColor(kBlue-5);
572 fTop->SetBorderSize(0);
573 fTop->SetBorderMode(0);
574
575 fBody->Clear();
576 fBody->SetNumber(2);
577 fBody->SetFillColor(0);
578 fBody->SetFillStyle(0);
579 fBody->SetBorderSize(0);
580 fBody->SetBorderMode(0);
581 fBody->SetTopMargin(0.01);
582 fBody->SetLeftMargin(0.10);
583 fBody->SetRightMargin(0.01);
584 fBody->SetBottomMargin(0.10);
585
586 fRingMap[0] = 0;
587 fRingMap[1] = 0;
588 fRingMap[2] = 0;
589 fRingMap[3] = 0;
590 fRingMap[4] = 0;
591 fRingMap[5] = 0;
592
593 fCanvas->cd();
594 }
595 //____________________________________________________________________
596 /**
597 * Create a canvas
598 *
c8b1a7db 599 * @param pname Name of PDF file to make
600 * @param landscape If true, print in landscape
601 * @param pdf Make PDF
33438b4c 602 *
2955f67c 603 * @return Created canvas
604 */
8449e3e0 605 void CreateCanvas(const TString& pname,
606 Bool_t landscape=false,
607 Bool_t pdf=true)
2955f67c 608 {
609 // Info("CreateCanvas", "Creating canvas");
610 fLandscape = landscape;
8449e3e0 611 fPDF = pdf;
2955f67c 612 Int_t height = 1000;
613 Int_t width = height / TMath::Sqrt(2);
614 if (fLandscape) {
615 Int_t tmp = height;
616 height = width;
617 width = tmp;
618 }
619 fCanvas = new TCanvas("c", pname.Data(), width, height);
620 fCanvas->SetFillColor(0);
621 fCanvas->SetBorderSize(0);
622 fCanvas->SetBorderMode(0);
8449e3e0 623 if (fPDF)
624 fCanvas->Print(Form("%s[", pname.Data()),
625 Form("pdf %s", fLandscape ? "Landscape" : ""));
2955f67c 626 fCanvas->SetLeftMargin(.1);
627 fCanvas->SetRightMargin(.05);
628 fCanvas->SetBottomMargin(.1);
629 fCanvas->SetTopMargin(.05);
630
631 gStyle->SetOptStat(0);
632 gStyle->SetTitleColor(0);
633 gStyle->SetTitleStyle(0);
634 gStyle->SetTitleBorderSize(0);
635 gStyle->SetTitleX(.5);
636 gStyle->SetTitleY(1);
637 gStyle->SetTitleW(.8);
638 gStyle->SetTitleH(.09);
639 gStyle->SetFrameFillColor(kWhite);
640 gStyle->SetFrameBorderSize(1);
641 gStyle->SetFrameBorderMode(1);
642 gStyle->SetPalette(1);
643
644 Float_t dy = .05;
645 fTop = new TPad("top", "Top", 0, 1-dy, 1, 1, 0, 0);
646 fTop->SetNumber(1);
647 fTop->SetFillColor(kBlue-5);
648 fTop->SetBorderSize(0);
649 fTop->SetBorderMode(0);
650 fCanvas->cd();
651 fTop->Draw();
652
653 fBody = new TPad("body", "Body", 0, 0, 1, 1-dy, 0, 0);
654 fBody->SetNumber(2);
655 fBody->SetFillColor(0);
656 fBody->SetFillStyle(0);
657 fBody->SetBorderSize(0);
658 fBody->SetBorderMode(0);
659 fCanvas->cd();
660 fBody->Draw();
661
662 fHeader = new TLatex(.5, .5, "Title");
663 fHeader->SetNDC();
664 fHeader->SetTextAlign(22);
665 fHeader->SetTextSize(.7);
666 fHeader->SetTextColor(kWhite);
667 fHeader->SetTextFont(62);
668
669 Double_t x1 = .1;
670 Double_t x2 = .6;
671 Double_t y = .8;
672 Double_t s = fLandscape ? 0.08 : 0.05;
673 fParName = new TLatex(x1, y, "");
674 fParName->SetTextAlign(13);
675 fParName->SetNDC();
676 fParName->SetTextSize(s);
bfab35d9 677 fParName->SetTextFont(62);
2955f67c 678
679 fParVal = new TLatex(x2, y, "");
680 fParVal->SetTextAlign(13);
681 fParVal->SetNDC();
682 fParVal->SetTextSize(s);
bfab35d9 683 fParVal->SetTextFont(42);
2955f67c 684
685 fCanvas->cd();
686 }
687
688 //____________________________________________________________________
689 /**
690 * Close the PDF
691 *
2955f67c 692 */
693 void CloseCanvas()
694 {
695 // Info("CloseCanvas", "Closing canvas");
696 // ClearCanvas();
77f97e3f
CHC
697 if (fPDF && fCanvas) {
698 // Printf("Closing canvas with last title %s", fLastTitle.Data());
8449e3e0 699 fCanvas->Print(Form("%s]", fCanvas->GetTitle()),
77f97e3f
CHC
700 Form("pdf %s Title:%s",
701 fLandscape ? "Landscape" : "",
702 fLastTitle.Data()));
703 }
8449e3e0 704 if (fCanvas)
705 fCanvas->Close();
706 fCanvas = 0;
2955f67c 707 }
708
709 //__________________________________________________________________
710 /**
711 * Print the canvas
712 *
713 * @param title Title
714 * @param size Size of text
715 */
716 void PrintCanvas(const TString& title, Float_t size=.7)
717 {
2955f67c 718 fTop->cd();
719 fHeader->SetTextSize(size);
720 fHeader->DrawLatex(.5,.5,title);
721
722 fCanvas->Modified();
723 fCanvas->Update();
724 fCanvas->cd();
725
8449e3e0 726 if (fPDF) {
70849dc0 727 TString tit;
728 tit.Form("pdf %s Title:%s", fLandscape ? "Landscape" : "",
729 title.Data());
730
731#ifdef DEBUG
732 Info("PrintCanvas", "Printing to %s (%s)",
733 fCanvas->GetTitle(), tit.Data());
734#else
8449e3e0 735 gSystem->RedirectOutput("/dev/null");
70849dc0 736#endif
8449e3e0 737 fCanvas->Print(fCanvas->GetTitle(), tit);
70849dc0 738#ifndef DEBUG
8449e3e0 739 gSystem->RedirectOutput(0);
70849dc0 740#endif
77f97e3f 741 fLastTitle = title;
8449e3e0 742 Pause();
70849dc0 743
8449e3e0 744 ClearCanvas();
745 }
2955f67c 746 }
747 //__________________________________________________________________
748 /**
749 * Make a chapter page
750 *
751 * @param title Title
752 */
753 void MakeChapter(const TString& title)
754 {
755 fBody->cd();
756
757 TLatex* ltx = new TLatex(.5, .5, title);
758 ltx->SetNDC();
759 ltx->SetTextAlign(22);
760 ltx->Draw();
761
762 PrintCanvas(title);
763 }
764 //__________________________________________________________________
765 /**
766 * Draw an object in pad
767 *
768 * @param c PArent pad
769 * @param padNo Sub-pad number (0 is self)
770 * @param h Object to draw
771 * @param opts Options
772 * @param flags Flags
c8b1a7db 773 * @param title Title on plot
a19faec0 774 *
775 * @return Drawn object - if any
2955f67c 776 */
a19faec0 777 TObject* DrawInPad(TVirtualPad* c,
778 Int_t padNo,
779 TObject* h,
780 Option_t* opts="",
781 UInt_t flags=0x0,
782 const char* title="")
2955f67c 783 {
784 TVirtualPad* p = c->GetPad(padNo);
785 if (!p) {
786 Warning("DrawInPad", "Pad # %d not found in %s", padNo, c->GetName());
a19faec0 787 return 0;
2955f67c 788 }
a19faec0 789 return DrawInPad(p, h, opts, flags, title);
2955f67c 790 }
c8b1a7db 791 /**
792 * Draw a clone of an object
793 *
794 * @param o Object
795 * @param options Draw options
796 * @param title Title of object
a19faec0 797 *
798 * @return Drawn object - if any
c8b1a7db 799 */
a19faec0 800 virtual TObject* DrawObjClone(TObject* o, Option_t* options,
801 const char* title)
079fd669 802 {
803 if (o->IsA()->InheritsFrom(TH1::Class()))
a19faec0 804 return DrawObjClone(static_cast<TH1*>(o), options, title);
079fd669 805 else if (o->IsA()->InheritsFrom(THStack::Class()))
a19faec0 806 return DrawObjClone(static_cast<THStack*>(o), options, title);
77f97e3f 807 else if (o->IsA()->InheritsFrom(TGraph::Class()))
a19faec0 808 return o->DrawClone(options);
079fd669 809 else
810 o->Draw(options);
a19faec0 811 return o;
079fd669 812 }
c8b1a7db 813 /**
814 * Draw an object clone
815 *
816 * @param o Stack object
817 * @param options Draw options
818 * @param title Title on plot
a19faec0 819 *
820 * @return Drawn object - if any
c8b1a7db 821 */
a19faec0 822 virtual TObject* DrawObjClone(THStack* o, Option_t* options,
823 const char* title)
079fd669 824 {
825 // THStack* tmp = static_cast<THStack*>(o->Clone());
826 o->Draw(options);
827 if (title && title[0] != '\0') o->GetHistogram()->SetTitle(title);
b767da2c 828 TAxis* xAxis = o->GetXaxis();
77f97e3f
CHC
829 if (!xAxis) {
830 Warning("DrawObjClone", "No X-axis for drawn stack %s", o->GetName());
a19faec0 831 return o;
77f97e3f 832 }
b767da2c 833 TH1* h = 0;
834 Int_t nBins = xAxis->GetNbins();
835 Double_t xMin = xAxis->GetXmin();
836 Double_t xMax = xAxis->GetXmax();
837 TIter next(o->GetHists());
838 while ((h = static_cast<TH1*>(next()))) {
839 TAxis* a = h->GetXaxis();
840 nBins = TMath::Max(nBins, a->GetNbins());
841 xMin = TMath::Min(xMin, a->GetXmin());
842 xMax = TMath::Max(xMax, a->GetXmax());
843 }
844 if (nBins != xAxis->GetNbins() ||
845 xMin != xAxis->GetXmin() ||
846 xMax != xAxis->GetXmax()) {
847 xAxis->Set(nBins, xMin, xMax);
848 o->GetHistogram()->Rebuild();
849 }
a19faec0 850 return o;
079fd669 851 }
c8b1a7db 852 /**
853 * Draw an object clone
854 *
855 * @param o Histogram
856 * @param options Draw options
857 * @param title Title on plot
a19faec0 858 *
859 * @return Drawn object - if any
c8b1a7db 860 */
a19faec0 861 virtual TObject* DrawObjClone(TH1* o, Option_t* options, const char* title)
079fd669 862 {
863 TH1* tmp = o->DrawCopy(options);
864 if (title && title[0] != '\0') tmp->SetTitle(title);
a19faec0 865 return tmp;
079fd669 866 }
2955f67c 867 //__________________________________________________________________
70849dc0 868 static void GetLegendPosition(UInt_t flags, TVirtualPad* p,
869 Double_t& x1, Double_t& y1,
870 Double_t& x2, Double_t& y2)
871 {
872 UInt_t horiz = (flags & 0xF0000);
873 UInt_t verti = (flags & 0xF000);
874 Double_t eps = .01;
875 Double_t dY = .4;
876 Double_t dX = .4;
877 Double_t yB = p->GetBottomMargin()+eps;
878 Double_t yT = 1-p->GetTopMargin()-eps;
879 Double_t xL = p->GetLeftMargin()+eps;
880 Double_t xR = 1-p->GetRightMargin()-eps;
881 switch (verti) {
882 case kNorth: y1 = yT-dY; break;
883 case kSouth: y1 = yB; break;
884 case kMiddle: y1 = (yB+yT-dY)/2; break;
885 }
886 y2 = TMath::Min(y1 + dY, yT);
887
888 switch (horiz) {
889 case kEast: x1 = xL; break;
890 case kWest: x1 = xR-dX; break;
891 case kCenter: x1 = (xL+xR-dX)/2; break;
892 }
893 x2 = TMath::Min(x1 + dX, xR);
894 }
895 TLegend* MakeLegend(TVirtualPad* p, UInt_t flags, Bool_t autoFill)
896 {
897 Double_t x1 = fParVal->GetX();
898 Double_t y1 = fParVal->GetY();
899 Double_t x2 = 0;
900 Double_t y2 = 0;
901 GetLegendPosition(flags, p, x1, y1, x2, y2);
902
903 //Printf("Legend at (%f,%f)x(%f,%f)", x1, y1, x2, y2);
904 TLegend* l = 0;
905 if (autoFill) l = p->BuildLegend(x1, y1, x2, y2);
906 else l = new TLegend(x1, y1, x2, y2);
907 l->SetFillColor(0);
908 l->SetFillStyle(0);
909 l->SetBorderSize(0);
910
911 return l;
912 }
913 //__________________________________________________________________
2955f67c 914 /**
915 * Draw an object in pad
916 *
33438b4c 917 * @param p Pad
2955f67c 918 * @param h Object to draw
919 * @param opts Options
920 * @param flags Flags
c8b1a7db 921 * @param title Title on plot
a19faec0 922 *
923 * @return Drawn object - if any
2955f67c 924 */
a19faec0 925 TObject* DrawInPad(TVirtualPad* p,
926 TObject* h,
927 Option_t* opts="",
928 UInt_t flags=0x0,
929 const char* title="")
2955f67c 930 {
931 if (!p) {
932 Warning("DrawInPad", "No pad specified");
a19faec0 933 return 0;
2955f67c 934 }
935 p->cd();
936 // Info("DrawInPad", "Drawing in pad %p", p);
937 // fBody->ls();
bfab35d9 938 if (flags & kLogx) p->SetLogx();
939 if (flags & kLogy) p->SetLogy();
940 if (flags & kLogz) p->SetLogz();
941 if (flags & kGridx) p->SetGridx();
942 if (flags & kGridy) p->SetGridy();
943 // if (flags & kGridz) p->SetGridz();
2955f67c 944 p->SetFillColor(0);
945 TString o(opts);
946 if (o.Contains("colz", TString::kIgnoreCase))
947 p->SetRightMargin(0.15);
8449e3e0 948 if (!h) {
b767da2c 949 if (!(flags & kSilent))
950 Warning("DrawInPad", "Nothing to draw in pad # %s", p->GetName());
a19faec0 951 return 0;
8449e3e0 952 }
2955f67c 953 if (o.Contains("text", TString::kIgnoreCase)) {
954 TH1* hh = static_cast<TH1*>(h);
955 hh->SetMaximum(1.1*hh->GetMaximum());
956 hh->SetMarkerSize(2);
957 o.Append("30");
958 }
a19faec0 959 TObject* ret = DrawObjClone(h, o, title);
2955f67c 960
70849dc0 961 if (flags & kLegend) {
962 MakeLegend(p, flags, true);
2955f67c 963 }
964 p->Modified();
965 p->Update();
966 p->cd();
a19faec0 967
968 return ret;
2955f67c 969 }
970 //__________________________________________________________________
971 /**
972 * Draw two graphs in the same frame, but with separate y-axis
973 *
974 * @param c Mother pad
975 * @param padNo Sub-pad number (0 is self)
976 * @param h1 First histogram
977 * @param h2 Second histogram
978 * @param opts Options
979 * @param flags Flags
980 */
981 void DrawTwoInPad(TVirtualPad* c, Int_t padNo, TH1* h1, TH1* h2,
982 Option_t* opts="", UShort_t flags=0x0)
983 {
984 TVirtualPad* p = c->cd(padNo);
985 if (!p) {
986 Warning("DrawInPad", "Pad # %d not found in %s", padNo, c->GetName());
987 return;
988 }
bfab35d9 989 if (flags & kLogx) p->SetLogx();
990 if (flags & kLogy) p->SetLogy();
991 if (flags & kLogz) p->SetLogz();
992 if (flags & kGridx) p->SetGridx();
993 if (flags & kGridy) p->SetGridy();
994 // if (flags & kGridz) p->SetGridz();
2955f67c 995 p->SetFillColor(0);
996
997 TString o(opts);
998 o.ToLower();
999 TString fopts(o);
1000 Bool_t e3 = o.Contains("e3");
1001 if (e3) {
1002 fopts.ReplaceAll("e3", " same");
1003 }
1004
1005 h1->GetYaxis()->SetLabelSize(0);
1006 h1->GetYaxis()->SetTicks("");
1007 h1->GetYaxis()->SetNdivisions(0);
1008 h1->DrawCopy(o); // First draw with opts
1009 if (e3) h1->DrawCopy(fopts);
1010 p->Update();
1011
1012 Double_t m1 = 1.05 * h1->GetMaximum();
bfab35d9 1013 if (m1 > 0) {
1014 TGaxis* a1 = new TGaxis(p->GetUxmin(), p->GetUymin(),
1015 p->GetUxmin(), p->GetUymax(),
1016 0, m1, 510);
1017 a1->SetLineColor(h1->GetLineColor());
1018 a1->Draw();
1019 }
1020
2955f67c 1021 o.Append(" same");
1022 Double_t m2 = 1.1 * h2->GetMaximum();
bfab35d9 1023 Double_t scale = m2 > 0 ? m1 / m2 : 1;
2955f67c 1024 h2->Scale(scale);
1025 h2->DrawCopy(o);
1026 if (e3) h2->DrawCopy(fopts);
bfab35d9 1027
1028 if (m2 > 0) {
1029 TGaxis* a2 = new TGaxis(p->GetUxmax(), p->GetUymin(),
1030 p->GetUxmax(), p->GetUymax(),
1031 0, m2, 510, "+L");
1032 a2->SetLineColor(h2->GetLineColor());
1033 a2->Draw();
1034 }
1035 if (flags& kLegend) {
70849dc0 1036 MakeLegend(p, flags, true);
2955f67c 1037 }
1038 p->Modified();
1039 p->Update();
1040 p->cd();
1041 }
1042
1043 //____________________________________________________________________
1044 /**
1045 * Draw a parameter.
1046 *
1047 * @param y Current y position. On return new y position
1048 * @param name Parameter name
1049 * @param value Parameter value
1050 * @param size Optional text size
1051 */
1052 void DrawParameter(Double_t& y,
1053 const TString& name,
1054 const TString& value,
1055 Double_t size=0)
1056 {
1057 Double_t s = fParName->GetTextSize();
1058 Double_t t = fParVal->GetTextSize();
1059 if (name.IsNull() && value.IsNull()) return;
1060 if (size > 0) {
1061 fParName->SetTextSize(size);
1062 fParVal->SetTextSize(size);
1063 }
1064 if (!name.IsNull())
1065 fParName->DrawLatex(fParName->GetX(), y, Form("%s:", name.Data()));
1066 if (!value.IsNull())
1067 fParVal->DrawLatex(fParVal->GetX(), y, value.Data());
1068 if (!name.IsNull())
1069 y -= 1.2 * fParName->GetTextSize();
1070 else if (!value.IsNull())
1071 y -= 1.2 * fParVal->GetTextSize();
1072
1073 fParName->SetTextSize(s);
1074 fParVal->SetTextSize(t);
1075 }
a19faec0 1076 template <typename T>
1077 void DrawTParameter(Double_t& y,
1078 TList* list,
1079 const TString& name) {
1080 T value;
1081 if (!GetParameter(list, name, value))
1082 return;
1083 std::stringstream s;
1084 s << std::boolalpha << value;
1085 DrawParameter(y, name, s.str().c_str(), 0);
1086 }
1087
1088 //__________________________________________________________________
1089 /**
1090 * Structure to hold a dived pad
1091 */
1092 struct DividedPad {
1093 TVirtualPad* fParent;
1094 TVirtualPad** fSubs;
1095 Bool_t fLandscape;
1096 Int_t fNCol;
1097 Int_t fNRow;
1098
1099 DividedPad(TVirtualPad* p, Bool_t landscape, Int_t nCol, Int_t nRow)
1100 : fParent(p),
1101 fSubs(0),
1102 fLandscape(landscape),
1103 fNCol(landscape ? nRow : nCol),
1104 fNRow(landscape ? nCol : nRow)
1105 {
1106 Int_t nPad = fNCol * fNRow;
1107 fSubs = new TVirtualPad*[nPad];
1108 }
1109 void Divide(Bool_t commonX, Bool_t commonY) {
1110 if ((!commonX && !commonY) || (commonX && commonY)) {
1111 // In case we have no common axis or do have both to be common,
1112 // we directly use the TVirtualPad::Divide member function
1113 fParent->Divide(fNCol, fNRow, commonX ? 0 : 0.01, commonY ? 0 : 0.01);
1114 for (Int_t iPad = 1; iPad <= fNRow*fNCol; iPad++)
1115 fSubs[iPad-1] = fParent->GetPad(iPad);
1116 }
1117 else if (commonX && !commonY) {
1118 // We need to have common X axis, but not common Y axis. We first
1119 // divide the pad in fNCol columns, and then each in to fNRow rows
1120 fParent->Divide(fNCol, 1);
1121 for (Int_t iCol = 1; iCol <= fNCol; iCol++) {
1122 TVirtualPad* q = fParent->GetPad(iCol);
1123
1124 if (fNRow == 1) {
1125 fSubs[GetIdx(iCol,0)] = q;
1126 continue;
1127 }
1128
1129 q->Divide(1,fNRow,0,0);
1130 for (Int_t iRow = 1; iRow <= fNRow; iRow++)
1131 fSubs[GetIdx(iCol, iRow)] = q->GetPad(iRow);
1132 }
1133 }
1134 else if (!commonX && commonY) {
1135 // We need to have common Y axis, but not common X axis. We first
1136 // divide the pad in fNRow rows, and then each in to fNCol columns
1137 fParent->Divide(1, fNRow);
1138 for (Int_t iRow = 1; iRow <= fNRow; iRow++) {
1139 TVirtualPad* q = fParent->GetPad(iRow);
1140
1141 if (fNCol == 1) {
1142 fSubs[GetIdx(0,iRow)] = q;
1143 continue;
1144 }
1145
1146 q->Divide(fNCol,1,0,0);
1147 for (Int_t iCol = 1; iCol <= fNCol; iCol++)
1148 fSubs[GetIdx(iCol, iRow)] = q->GetPad(iCol);
1149 }
1150 }
1151 }
1152 virtual ~DividedPad() { if (fSubs) delete [] fSubs; }
1153 /**
1154 * Get a sub-pad
1155 *
1156 * @param idx Index (0 based)
1157 *
1158 * @return Pad or null
1159 */
1160 TVirtualPad* GetPad(Int_t idx) {
1161 if (!fSubs) {
1162 ::Warning("GetPad","No sub-pads");
1163 return 0;
1164 }
1165 if (idx < 0 || idx >= (fNRow*fNCol)) {
1166 ::Warning("GetPad", "Inded %d out of bounds [%d,%d]",
1167 idx, 0, fNRow*fNCol);
1168 return 0;
1169 }
1170 return fSubs[idx];
1171 }
1172 Int_t GetIdx(Int_t iCol, Int_t iRow) const
1173 {
1174 return (iRow-1) * fNCol + iCol;
1175 }
1176 /**
1177 * Get a sub-pad
1178 *
1179 * @param iRow Row number (1-based)
1180 * @param iCol Column number (1-based)
1181 *
1182 * @return Pad or null
1183 */
1184 TVirtualPad* GetPad(Int_t iCol, Int_t iRow) {
1185 if (iRow < 0 || iRow > fNRow) return 0;
1186 if (iCol < 0 || iRow > fNCol) return 0;
1187 return GetPad(GetIdx(iCol, iRow));
1188 }
1189 };
1190
2955f67c 1191 //__________________________________________________________________
1192 void DivideForRings(Bool_t commonX, Bool_t commonY)
1193 {
1194 //
1195 // Divide canvas for rings
1196 //
1197 if ((!commonX && !commonY) ||
1198 (commonX && commonY)) {
1199 // Portrait:
1200 // +----------+----------+
1201 // | 1: FMD1i | 2: Free |
1202 // +----------+----------+
1203 // | 3: FMD2i | 4: FMD2o |
1204 // +----------+----------+
1205 // | 5: FMD3i | 6: FMD3o |
1206 // +----------+----------+
1207 //
1208 // Landscape:
1209 // +----------+----------+----------+
1210 // | 1: FMD1i | 2: FMD2i | 3: FMD3i |
1211 // +----------+----------+----------+
1212 // | 4: Free | 5: FMD2o | 6: FMD3o |
1213 // +----------+----------+----------+
1214 //
1215 fBody->Divide(fLandscape ? 3 : 2, fLandscape ? 2 : 3,
1216 commonX ? 0 : 0.01, commonY ? 0 : 0.01);
1217 fRingMap[0] = fBody->GetPad(1); // FMD1i;
1218 fRingMap[1] = fBody->GetPad(fLandscape ? 2 : 3); // FMD2i;
1219 fRingMap[2] = fBody->GetPad(fLandscape ? 5 : 4); // FMD2o;
1220 fRingMap[3] = fBody->GetPad(fLandscape ? 3 : 5); // FMD3i;
1221 fRingMap[4] = fBody->GetPad(6); // FMD3o;
1222 fRingMap[5] = fBody->GetPad(fLandscape ? 4 : 2); // Free
1223 }
1224 else if (commonX && !commonY) {
1225 // Divide into two - left/right
1226 // Portrait:
1227 // +----------++----------+
1228 // | 1: FMD1i || 1: Free |
1229 // +----------++----------+
1230 // | 2: FMD2i || 2: FMD2o |
1231 // +----------++----------+
1232 // | 3: FMD3i || 3: FMD3o |
1233 // +----------++----------+
1234 //
1235 // Landscape:
1236 // +----------++----------++----------+
1237 // | 1: FMD1i || 1: FMD2i || 1: FMD3i |
1238 // +----------++----------++----------+
1239 // | 2: Free || 2: FMD2o || 2: FMD3o |
1240 // +----------++----------++----------+
1241 //
1242 fBody->Divide(fLandscape ? 3 : 2, 1);
1243 TVirtualPad* left = fBody->cd(1);
1244 left->Divide(fLandscape ? 2 : 3);
1245 TVirtualPad* middle = fBody->cd(2);
1246 middle->Divide(fLandscape ? 2 : 3);
1247
1248 Info("left","%p",left); left->ls();
1249 Info("middle","%p",middle); middle->ls();
1250
1251 fRingMap[0] = left->GetPad(1); // FMD1i;
1252 if (!fLandscape) {
1253 fRingMap[1] = left->GetPad(2); // FMD2i
1254 fRingMap[2] = middle->GetPad(2); // FMD2o
1255 fRingMap[3] = left->GetPad(3); // FMD3i
1256 fRingMap[4] = middle->GetPad(3); // FMD3o
1257 fRingMap[5] = middle->GetPad(1); // Free
1258 }
1259 else {
1260 TVirtualPad* right = fBody->cd(3);
1261 right->Divide(fLandscape ? 2 : 3);
1262 fRingMap[1] = middle->GetPad(1); // FMD2i
1263 fRingMap[2] = middle->GetPad(2); // FMD2o
1264 fRingMap[3] = right->GetPad(1); // FMD3i
1265 fRingMap[4] = right->GetPad(2); // FMD3o
1266 fRingMap[5] = left->GetPad(2); // Free
1267 }
1268 }
1269 else {
1270 // Divide into two - left/right
1271 // Portrait:
1272 // +----------+----------+
1273 // | 1: FMD1i | 2: Free |
1274 // +----------+----------+
1275 // +----------+----------+
1276 // | 1: FMD2i | 2: FMD2o |
1277 // +----------+----------+
1278 // +----------+----------+
1279 // | 1: FMD3i | 2: FMD3o |
1280 // +----------+----------+
1281 //
1282 // Landscape:
1283 // +----------+----------+----------+
1284 // | 1: FMD1i | 2: FMD2i | 3: FMD3i |
1285 // +----------+----------+----------+
1286 // +----------+----------+----------+
1287 // | 1: Free | 2: FMD2o | 3: FMD3o |
1288 // +----------+----------+----------+
1289 //
1290 fBody->Divide(1, fLandscape ? 2 : 3);
1291 TVirtualPad* top = fBody->cd(1);
1292 top->Divide(fLandscape ? 3 : 2);
1293 TVirtualPad* middle = fBody->cd(2);
1294 middle->Divide(fLandscape ? 3 : 2);
1295
1296 fRingMap[0] = top->GetPad(1); // FMD1i;
1297 if (!fLandscape) {
1298 TVirtualPad* bottom = fBody->cd(2);
1299 bottom->Divide(2);
1300
1301 fRingMap[1] = middle->GetPad(1); // FMD2i
1302 fRingMap[2] = middle->GetPad(2); // FMD2o
1303 fRingMap[3] = bottom->GetPad(1); // FMD3i
1304 fRingMap[4] = bottom->GetPad(2); // FMD3o
1305 fRingMap[5] = top->GetPad(2); // Free
1306 }
1307 else {
1308 fRingMap[1] = top->GetPad(2); // FMD2i
1309 fRingMap[2] = middle->GetPad(2); // FMD2o
1310 fRingMap[3] = top->GetPad(3); // FMD3i
1311 fRingMap[4] = middle->GetPad(3); // FMD3o
1312 fRingMap[5] = middle->GetPad(1); // Free
1313 }
1314 }
1315 if (fRingMap[0]) fRingMap[0]->SetTitle("FMD1i");
1316 if (fRingMap[1]) fRingMap[1]->SetTitle("FMD2i");
1317 if (fRingMap[2]) fRingMap[2]->SetTitle("FMD2o");
1318 if (fRingMap[3]) fRingMap[3]->SetTitle("FMD3i");
1319 if (fRingMap[4]) fRingMap[4]->SetTitle("FMD3o");
1320 if (fRingMap[5]) fRingMap[5]->SetTitle("Other");
1321 }
1322 //__________________________________________________________________
1323 TVirtualPad* RingPad(UShort_t d, Char_t r) const
1324 {
1325 Int_t idx = 0;
1326 switch (d) {
1327 case 0: idx = 5; break;
1328 case 1: idx = 0; break;
1329 case 2: idx = 1 + ((r == 'I' || r == 'i') ? 0 : 1); break;
1330 case 3: idx = 3 + ((r == 'I' || r == 'i') ? 0 : 1); break;
1331 default: return 0;
1332 }
1333 return fRingMap[idx];
1334 // return fBody->GetPad(no);
1335 }
1336 //__________________________________________________________________
7095962e
CHC
1337 TVirtualPad* RingPad(const char* name) const
1338 {
1339 TString n(name);
1340 Int_t idx = n.Index("FMD");
1341 if (n == kNPOS) return 0;
1342 n.Remove(0, idx+3);
1343 Int_t det = n.Atoi();
1344 n.Remove(0,1);
1345 Char_t rng = n[0];
1346 return RingPad(det, rng);
1347 }
1348 //__________________________________________________________________
2955f67c 1349 /**
1350 * Draw an object in pad
1351 *
33438b4c 1352 * @param d Detector
1353 * @param r Ring
2955f67c 1354 * @param h Object to draw
1355 * @param opts Options
1356 * @param flags Flags
c8b1a7db 1357 * @param title Title on plot
2955f67c 1358 */
079fd669 1359 void DrawInRingPad(UShort_t d,
1360 Char_t r,
1361 TObject* h,
1362 Option_t* opts="",
1363 UShort_t flags=0x0,
1364 const char* title="")
2955f67c 1365 {
1366 TVirtualPad* p = RingPad(d, r);
1367 if (!p) {
1368 Warning("DrawInRingPad", "No pad found for FMD%d%c", d, r);
1369 return;
1370 }
079fd669 1371 DrawInPad(p, h, opts, flags, title);
2955f67c 1372 }
7095962e
CHC
1373 /**
1374 * Draw object in a ring pad
1375 *
1376 * @param name Name of ring
1377 * @param h Object to draw
1378 * @param opts Options
1379 * @param flags Flags
1380 * @param title Possible new title
1381 */
1382 void DrawInRingPad(const char* name,
1383 TObject* h,
1384 Option_t* opts="",
1385 UShort_t flags=0x0,
1386 const char* title="")
1387 {
1388 TVirtualPad* p = RingPad(name);
1389 if (!p) {
1390 Warning("DrawInRingPad", "No pad found for \"%s\"", name);
1391 return;
1392 }
1393 DrawInPad(p, h, opts, flags, title);
1394 }
1395 /**
1396 * Draw object in a ring pad. Which pad to draw in depends on the
1397 * name or title of the drawn object (must contain the ring name as
1398 * a sub-string).
1399 *
1400 * @param h Object to draw
1401 * @param opts Options
1402 * @param flags Flags
1403 * @param title Possible new title
1404 */
1405 void DrawInRingPad(TObject* h,
1406 Option_t* opts="",
1407 UShort_t flags=0x0,
1408 const char* title="")
1409 {
1410 if (!h) return;
1411 TVirtualPad* p = RingPad(h->GetName());
1412 if (!p) {
1413 p = RingPad(h->GetTitle());
1414 if (!p) {
1415 Warning("DrawInRingPad", "No pad found for %s/%s",
1416 h->GetName(), h->GetTitle());
1417 return;
1418 }
1419 }
1420 DrawInPad(p, h, opts, flags, title);
1421 }
2955f67c 1422
1423
1424 //__________________________________________________________________
1425 /**
1426 * Pause after each plot
1427 *
1428 */
1429 void Pause()
1430 {
1431 if (!fPause) return;
1432 printf("Press enter to continue");
1433 std::cin.get();
1434 }
a19faec0 1435 static void CompileScript(const TString& name,
1436 const TString& sub,
1437 const TString& check,
1438 Bool_t force)
1439 {
1440 if (!check.IsNull() && gROOT->GetClass(check)) return;
2955f67c 1441
a19faec0 1442 TString fwd =gSystem->ExpandPathName("$ALICE_ROOT/PWGLF/FORWARD/analysis2");
1443 TString macPath(gROOT->GetMacroPath());
1444 TString incPath(gSystem->GetIncludePath());
1445 if (!macPath.Contains(fwd)) macPath.Append(Form(":%s", fwd.Data()));
1446 if (!incPath.Contains(fwd)) gSystem->AddIncludePath(Form("-I%s",
1447 fwd.Data()));
1448 if (!sub.IsNull()) {
1449 TObjArray* subs = sub.Tokenize(": ");
1450 TObject* pSub = 0;
1451 TIter iSub(subs);
1452 while ((pSub = iSub())) {
1453 TString subDir = gSystem->ConcatFileName(fwd, pSub->GetName());
1454 if (!macPath.Contains(subDir))
1455 macPath.Append(Form(":%s", subDir.Data()));
1456 if (!incPath.Contains(subDir))
1457 gSystem->AddIncludePath(Form("-I%s", subDir.Data()));
1458 }
1459 }
d6cea8ac 1460 gROOT->SetMacroPath(macPath);
a19faec0 1461 gROOT->LoadMacro(Form("%s%s", name.Data(), (force ? "++g" : "+")));
a19faec0 1462 }
bfab35d9 1463 //____________________________________________________________________
1464 virtual void DrawEventInspector(TCollection* parent)
1465 {
1466 Info("DrawEventInspector", "Drawing event inspector");
1467 TCollection* c = GetCollection(parent, "fmdEventInspector");
1468 if (!c) return;
1469
fba5d22d 1470 UShort_t sys=0, sNN=0;
1471 Int_t field=0;
1472 ULong_t runNo=0;
24338c03 1473 Int_t lowFlux=0, nPileUp=0, ipMethod=0;
1474 ULong_t aliRev=0, aliBra=0;
1475 Bool_t v0and=false;
bfab35d9 1476 Double_t dPileUp=0.;
1477 Double_t y = .8;
1478
1479 fBody->cd();
1480
1481 Double_t save = fParName->GetTextSize();
1482 fParName->SetTextSize(0.03);
1483 fParVal->SetTextSize(0.03);
fba5d22d 1484
1485 GetParameter(c, "sys", sys);
1486 GetParameter(c, "sNN", sNN);
1487 GetParameter(c, "field", field);
1488 GetParameter(c, "runNo", runNo);
1489 GetParameter(c, "lowFlux", lowFlux);
24338c03 1490 GetParameter(c, "ipMethod", ipMethod);
fba5d22d 1491 GetParameter(c, "v0and", v0and);
1492 GetParameter(c, "nPileUp", nPileUp);
1493 GetParameter(c, "dPileup", dPileUp);
1494 GetParameter(c, "alirootRev", aliRev);
1495 GetParameter(c, "alirootBranch", aliBra);
1496
1497 TString tS; SysString(sys, tS); DrawParameter(y, "System", tS);
1498 TString tE; SNNString(sNN, tE); DrawParameter(y, "#sqrt{s_{NN}}", tE);
1499 DrawParameter(y, "L3 B field", Form("%+2dkG", field));
1500 DrawParameter(y, "Run #", Form("%lu", runNo));
1501 DrawParameter(y, "Low flux cut", Form("%d", lowFlux));
24338c03 1502 TString sIpMeth("unknown");
1503 switch(ipMethod) {
1504 case 0: sIpMeth = "Normal"; break;
1505 case 1: sIpMeth = "pA in 2012"; break;
1506 case 2: sIpMeth = "pA in 2013"; break;
1507 case 3: sIpMeth = "PWG-UD"; break;
1508 case 4: sIpMeth = "Satellite"; break;
1509 }
1510 DrawParameter(y, "Use PWG-UD vertex", sIpMeth);
fba5d22d 1511 DrawParameter(y, "Use V0AND for NSD", (v0and ? "yes" : "no"));
1512 DrawParameter(y, "Least # of pile-up vertex", Form("%d", nPileUp));
1513 DrawParameter(y, "Least distance of pile-up vertex",
1514 Form("%fcm", dPileUp));
1515 DrawParameter(y, "AliROOT", Form("%lu/0x%08lx", ULong_t(aliRev),
1516 ULong_t(aliBra)));
bfab35d9 1517
1518 TH1* triggers = GetH1(c, "triggers");
1519 TH1* vertex = GetH1(c, "vertex", false);
1520 Bool_t mc = (vertex != 0);
1521 if (mc) {
1522 Int_t nInelMC = vertex->GetEntries();
1523 Int_t nInel = triggers->GetBinContent(1);
1524 Int_t nNSDMC = triggers->GetBinContent(11);
1525 Int_t nNSD = triggers->GetBinContent(4);
1526 DrawParameter(y,
1527 Form("#varepsilon_{INEL} = #bf{%d/%d}", nInel, nInelMC),
1528 Form("%5.3f", float(nInel)/nInelMC));
1529 DrawParameter(y,
1530 Form("#varepsilon_{NSD} = #bf{%d/%d}", nNSD, nNSDMC),
1531 Form("%5.3f", float(nNSD)/nNSDMC));
1532 }
1533
1534 PrintCanvas("Event Inspector");
1535 fParName->SetTextSize(save);
1536 fParVal->SetTextSize(save);
1537
77f97e3f
CHC
1538 if (fLandscape) fBody->Divide(4,2);
1539 else fBody->Divide(2,4);
bfab35d9 1540
1541 TH1* nEventsTr = GetH1(c, "nEventsTr");
1542 TH1* nEventsTrVtx = GetH1(c, "nEventsTrVtx");
1543 TH1* nEventsAcc = GetH1(c, "nEventsAccepted");
1544 if (nEventsTr) nEventsTr->Rebin(2);
1545 if (nEventsTrVtx) nEventsTrVtx->Rebin(2);
1546 if (vertex) {
1547 // vertex->Rebin(2);
1548 vertex->SetFillColor(kMagenta+2);
1549 }
fba5d22d 1550 DrawInPad(fBody, 1, nEventsTr, "", kLogy,
079fd669 1551 "Events w/trigger, trigger+vertex, accepted");
bfab35d9 1552 if (vertex) DrawInPad(fBody, 1, vertex, "same");
1553 DrawInPad(fBody, 1, nEventsTrVtx, "same");
fba5d22d 1554 DrawInPad(fBody, 1, nEventsAcc, "same", kLegend);
bfab35d9 1555
1556
fba5d22d 1557 DrawInPad(fBody, 2, GetH2(c, "nEventsAcceptedXY"), "colz", kLogz);
bfab35d9 1558 DrawInPad(fBody, 3, triggers, "hist text");
1559 if (GetH1(c, "trgStatus"))
1560 DrawInPad(fBody, 4, GetH1(c, "trgStatus"), "hist text");
1561 else // Old one
fba5d22d 1562 DrawInPad(fBody, 4, GetH2(c, "triggerCorr"), "colz", kLogz);
bfab35d9 1563 DrawInPad(fBody, 5, GetH1(c, "status"), "hist text");
1564 if (GetH1(c, "vtxStatus"))
1565 DrawInPad(fBody, 6, GetH1(c, "vtxStatus"), "hist text");
1566 else // old
1567 DrawInPad(fBody, 6, GetH1(c, "type"), "hist text");
1568
1569 TH1* cent = GetH1(c, "cent");
1570 TH2* centQual = GetH2(c, "centVsQuality");
1571 if (cent && centQual) {
1572 cent->Scale(1, "width");
1573 centQual->Scale(1, "width");
77f97e3f 1574 DrawInPad(fBody, 7, cent, "", kLogy);
fba5d22d 1575 DrawInPad(fBody, 8, centQual, "colz", kLogz);
bfab35d9 1576 }
1577
1578 PrintCanvas("EventInspector - Histograms");
1579
1580 if (!mc) return; // not MC
1581
1582 TH1* phiR = GetH1(c, "phiR");
1583 TH1* b = GetH1(c, "b");
1584 TH2* bVsNpart = GetH2(c, "bVsParticipants");
1585 TH2* bVsNbin = GetH2(c, "bVsBinary");
1586 TH2* bVsCent = GetH2(c, "bVsCentrality");
1587 TH2* vzComparison = GetH2(c, "vzComparison");
1588 TH2* centVsNpart = GetH2(c, "centralityVsParticipans");// Spelling!
1589 TH2* centVsNbin = GetH2(c, "centralityVsBinary");
1590
1591 fBody->Divide(2,3);
1592
1593 DrawInPad(fBody, 1, phiR);
fba5d22d 1594 DrawInPad(fBody, 2, vzComparison, "colz", kLogz);
bfab35d9 1595 DrawInPad(fBody, 3, b);
1596
1597 TProfile* nPartB = bVsNpart->ProfileX("nPartB",1,-1,"s");
1598 TProfile* nBinB = bVsNbin->ProfileX("nBinB",1,-1,"s");
1599 nPartB->SetMarkerColor(kBlue+2);
1600 nPartB->SetMarkerStyle(20);
1601 nPartB->SetLineColor(kBlue+2);
1602 nPartB->SetFillColor(kBlue-10);
1603 nPartB->SetFillStyle(1001);
1604 nPartB->SetMarkerSize(0.7);
1605 nBinB->SetMarkerColor(kRed+2);
1606 nBinB->SetMarkerStyle(21);
1607 nBinB->SetLineColor(kRed+2);
1608 nBinB->SetFillColor(kRed-10);
1609 nBinB->SetMarkerSize(0.7);
1610 nBinB->SetFillStyle(1001);
1611
fba5d22d 1612 DrawTwoInPad(fBody, 4, nPartB, nBinB, "e3 p", kLegend);
bfab35d9 1613
fba5d22d 1614 DrawInPad(fBody, 5, bVsCent, "colz", kLogz);
bfab35d9 1615
1616 TProfile* nPartC = centVsNpart->ProfileY("nPartC",1,-1,"s");
1617 TProfile* nBinC = centVsNbin->ProfileY("nBinC",1,-1,"s");
1618 nPartC->SetMarkerColor(kBlue+2);
1619 nPartC->SetMarkerStyle(20);
1620 nPartC->SetLineColor(kBlue+2);
1621 nPartC->SetFillColor(kBlue-10);
1622 nPartC->SetFillStyle(1001);
1623 nPartC->SetMarkerSize(0.7);
1624 nBinC->SetMarkerColor(kRed+2);
1625 nBinC->SetMarkerStyle(21);
1626 nBinC->SetLineColor(kRed+2);
1627 nBinC->SetFillColor(kRed-10);
1628 nBinC->SetMarkerSize(0.7);
1629 nBinC->SetFillStyle(1001);
1630
fba5d22d 1631 DrawTwoInPad(fBody, 6, nPartC, nBinC, "e3 p", kLegend);
bfab35d9 1632
1633 PrintCanvas("EventInspector - Monte-Carlo");
1634 }
1635 //____________________________________________________________________
24338c03 1636 virtual void DrawESDFixer(TCollection* parent)
1637 {
1638 Info("DrawESDFixer", "Drawing ESD fixer");
1639 TCollection* c = GetCollection(parent, "fmdESDFixer");
1640 if (!c) return;
1641
1642 Int_t recoFactor = 0;
1643 Bool_t recalcEta = false;
1644 Bool_t invalidIsEmpty = false;
1645
1646 fBody->cd();
1647
1648 Double_t save = fParName->GetTextSize();
1649 fParName->SetTextSize(0.05);
1650 fParVal->SetTextSize(0.05);
1651
1652 fBody->Divide(2,2);
1653 fBody->cd(1);
1654
1655 Double_t y = .8;
1656 if (GetParameter(c, "recoFactor", recoFactor))
1657 DrawParameter(y, "Noise factor used in reco",
1658 Form("%d (assumed)", recoFactor));
1659 if (GetParameter(c, "recalcEta", recalcEta))
1660 DrawParameter(y, "Recalculate #eta",
1661 Form("%s", (recalcEta ? "yes" : "no")));
1662 if (GetParameter(c, "invalidIsEmpty", invalidIsEmpty))
1663 DrawParameter(y, "Assume invalid strips are empty",
1664 Form("%s", (invalidIsEmpty ? "yes" : "no")));
1665
1666 TCollection* xd = GetCollection(c, "extraDead");
1667 if (xd)
1668 DrawParameter(y, "# extra dead strips",
1669 Form("%d", xd->GetEntries()));
1670
1671 DrawInPad(fBody, 2, GetH1(c, "noiseChange"), "", kLogy);
1672 DrawInPad(fBody, 3, GetH1(c, "etaChange"), "", kLogy);
1673 DrawInPad(fBody, 4, GetH1(c, "deadChange"), "", kLogy);
1674
1675 PrintCanvas("ESD Fixer");
1676 fParName->SetTextSize(save);
1677 fParVal->SetTextSize(save);
1678 }
1679 //____________________________________________________________________
bfab35d9 1680 void DrawTrackDensity(TCollection* parent)
1681 {
1682 Info("DrawTrackDensity", "Drawing track density");
1683
1684 // --- MC --------------------------------------------------------
1685 TCollection* mc = GetCollection(parent, "mcTrackDensity", false);
1686 if (!mc) return; // Not MC
1687
1688 fBody->Divide(2,3);
fba5d22d 1689 DrawInPad(fBody, 1, GetH2(mc, "binFlow"), "colz", kLogz);
1690 DrawInPad(fBody, 2, GetH2(mc, "binFlowEta"), "colz", kLogz);
1691 DrawInPad(fBody, 3, GetH2(mc, "binFlowPhi"), "colz", kLogz);
1692 DrawInPad(fBody, 4, GetH1(mc, "nRefs"), "", kLogy,
81775aba 1693 "# of references");
1694 DrawInPad(fBody, 4, GetH1(mc, "clusterRefs", false), "same");
1695 DrawInPad(fBody, 4, GetH1(mc, "clusterSize", false), "same");
fba5d22d 1696 DrawInPad(fBody, 4, GetH1(mc, "nClusters", false), "same", kLegend);
1697 DrawInPad(fBody, 5, GetH2(mc, "clusterVsRefs", false),"colz", kLogz);
bfab35d9 1698
1699 PrintCanvas("Track density");
1700 }
2955f67c 1701 //__________________________________________________________________
1702 TCanvas* fCanvas; // Our canvas
1703 TPad* fTop; // Top part
1704 TPad* fBody; // Body part
1705 TLatex* fHeader; // Header text
1706 TLatex* fParName; // Parameter name
1707 TLatex* fParVal; // Parameter value
1708 Bool_t fPause; // Whether to pause after drawing a canvas
1709 Bool_t fLandscape; // Landscape or Portrait orientation
1710 TVirtualPad** fRingMap;
8449e3e0 1711 Bool_t fPDF;
77f97e3f 1712 TString fLastTitle;
2955f67c 1713};
fba5d22d 1714#if 0
1715template <>
4fdca35c 1716inline Bool_t
fba5d22d 1717SummaryDrawer::DoGetParameter<Double_t>(TObject* o, const TObject* p,
1718 Double_t& value)
4fdca35c 1719{
fba5d22d 1720 TParameter<Double_t>* r = DoGetObject<TParameter<Double_t>(o, p);
1721 UInt_t i = o->GetUniqueID();
1722 Float_t v = *reinterpret_cast<Float_t*>(&i);
1723 value = v;
1724 return true;
4fdca35c 1725}
fba5d22d 1726#endif
4fdca35c 1727inline Bool_t
fba5d22d 1728SummaryDrawer::GetParameter(const TObject* c,
1729 const TString& name,
1730 Double_t& value,
1731 Bool_t verb)
4fdca35c 1732
1733{
1734 return DoGetParameter(GetObject(c, name, verb), c, value);
1735}
1736
2955f67c 1737#endif
fba5d22d 1738//
1739// EOF
1740//
2955f67c 1741