]> git.uio.no Git - u/mrichter/AliRoot.git/blob - PWGLF/FORWARD/analysis2/scripts/AliceLogo.C
Merge branch 'feature-movesplit'
[u/mrichter/AliRoot.git] / PWGLF / FORWARD / analysis2 / scripts / AliceLogo.C
1 #ifndef ALICELOGO_C
2 #define ALICELOGO_C
3 #include <TGraph.h>
4 #include <TBox.h>
5 #include <TEllipse.h>
6 #include <TPad.h>
7 #include <TCanvas.h>
8 #include <TMath.h>
9 #include <TString.h>
10 #include <TImage.h>
11 #include <TH1.h>
12 #include <TLine.h>
13 #include <TColor.h>
14
15 /** 
16  * Structure to draw the ALICE logo on a pad (canvas).  The logo and
17  * text is drawn using ROOT primitives and the result is somewhat
18  * scalable.
19  *
20  * Note, you can save the logo as a PNG, PDF, or SVG to include it in
21  * some other document or the like.  
22  *
23  * How to use
24  * 
25  * @code 
26  * {
27  *   TH1* h = new TH1F("h", "h", 60, -3, 3);
28  *   h->SetFillColor(kRed+1);
29  *   h->SetFillStyle(3001);
30  *   h->FillRandom("gaus");
31  *   h->Draw();
32  *   
33  *   gROOT->LoadMacro("AliceLogo.C");
34  *   AliceLogo* al = new AliceLogo();
35  *   // al->Draw(0, .75, .4, .25, "preliminary");
36  *   // al->Draw(0, .75, .4, .25, "performance");
37  *   // al->Draw(0, .75, .4, .25, "","text l3 many particles");
38  *   al->Draw(0, .75, .4, .25, "preliminary", "text l3 many particles");
39  * }
40  * @endcode
41  *
42  * There are many options for colours and options for preliminary,
43  * performance and just the logo.
44  *
45  * The logo produced does not exactly match the logos found on the
46  * ALICE web-site 
47  *
48  *   https://aliceinfo.cern.ch/Figure/alice_logo
49  *
50  * In particular, the 'C' was hard to get right.  However, the logo
51  * does follow the charter as described in 
52  * 
53  *   http://aliweb.cern.ch/system/files/documents/charter/charte_A5_120628.pdf
54  *
55  * Use the static member function(s) AliceLogo::Check to see how well
56  * this code reproduces the logos.  Note, you need the official logos
57  * in PNG format for this.  Here's a list of places to get them:
58  *
59  * - https://aliceinfo.cern.ch/Figure/sites/aliceinfo.cern.ch.Figure/files/Figures/General/elopez/2012-Jul-04-Preliminary_Logo.png
60  * - https://aliceinfo.cern.ch/Figure/sites/aliceinfo.cern.ch.Figure/files/Figures/General/elopez/2012-Jul-04-Performance_Logo.png
61  * - https://aliceinfo.cern.ch/Figure/sites/aliceinfo.cern.ch.Figure/files/Figures/General/elopez/2012-Jul-04-4_Color_Logo_CB.png
62  *
63  * @author Christian Holm Christensen <cholm@nbi.dk>
64  */
65 struct AliceLogo 
66 {
67   /** 
68    * Tags
69    */
70   enum ETag {
71     kNone = 0, 
72     kPreliminary, 
73     kPerformance
74   };
75   /** 
76    * Colour options 
77    */
78   enum {
79     kBW          = 0,    // Black and white only 
80     kText        = 0x1,  // Text is coloured dark-blue
81     kL3          = 0x2,  // Colour L3 red
82     kParticles   = 0x4,  // Particles coloured red
83     kMany        = 0x8,  // Many particles in many colours
84     kPad         = 0x10, // BAckground from pad 
85     kReverse     = 0x20  // Text is white 
86   };
87   /**
88    * Constructor 
89    */
90   AliceLogo(Bool_t debug=false)
91     : fPad(0), 
92       fAspect(1),
93       fL3Thick(.05),
94       fL3Height(.63), 
95       fL3Width(0),
96       fDebug(debug)
97   {
98     fRed    = TColor::GetColor(226,   0, 26);
99     fYellow = TColor::GetColor(238, 125, 17);
100     fPink   = TColor::GetColor(202,  71, 67);
101     fBlue   = TColor::GetColor(40,   58, 68);
102   }
103   /** 
104    * Parse a string with colour options 
105    * 
106    * @param what 
107    * 
108    * @return Colour flags 
109    */
110   static UInt_t ParseColors(const TString& what)
111   {
112     UInt_t col = AliceLogo::kBW;
113     if (what.Contains("l3",    TString::kIgnoreCase)) col |= kL3;
114     if (what.Contains("text",  TString::kIgnoreCase)) col |= kText;
115     if (what.Contains("part",  TString::kIgnoreCase)) col |= kParticles;
116     if (what.Contains("many",  TString::kIgnoreCase)) col |= kMany;
117     if (what.Contains("pad",   TString::kIgnoreCase)) col |= kPad;
118     if (what.Contains("rever", TString::kIgnoreCase)) col |= kReverse;
119     return col;
120   }
121   /** 
122    * Parse a tag string 
123    * 
124    * @param what String to parse 
125    * 
126    * @return Tag 
127    */
128   static UShort_t ParseTag(const TString& what)
129   {
130     UShort_t tag = AliceLogo::kNone;
131     if      (what.BeginsWith("pre", TString::kIgnoreCase)) tag = kPreliminary;
132     else if (what.BeginsWith("per", TString::kIgnoreCase)) tag = kPerformance;
133     return tag;
134   }
135   /**
136    * Draw everything 
137    * 
138    * @param p      Pad to draw in
139    * @param x      Starting X position
140    * @param y      Starting Y position
141    * @param h      Relative height 
142    * @param tag    Tag 
143    * @param colors Color options
144    */
145   void Draw(TVirtualPad* p, Double_t x=.77, Double_t y=.35, Double_t h=.25, 
146             const TString& tag="", const TString& colors="")
147   {
148     Draw(p, x, y, h, ParseTag(tag), ParseColors(colors));
149   }
150   /** 
151    * Draw everything 
152    * 
153    * @param p      Pad to draw in 
154    * @param x      Starting X position
155    * @param y      Starting Y position
156    * @param h      Relative height 
157    * @param tag    Tag 
158    * @param color  Color options
159    */
160   void Draw(TVirtualPad* p, Double_t x, Double_t y, Double_t h,
161             UShort_t tag, UInt_t color)
162   {
163     if (!p) p = gPad;
164     if (!p) { 
165       Error("AliceLogo::Draw", "No pad to draw in");
166       return;
167     }
168     if (fDebug) 
169       Printf("Pad to draw logo in: %s", p->GetName());
170     // p->SetFixedAspectRatio(true);
171     Int_t    pH  = p->YtoPixel(0);
172     if (fDebug) {
173       Int_t    pW  = p->XtoPixel(1);
174       Double_t pA  = Double_t(pW) / pH;
175       Printf("pA=%d/%d=%lf", pW, pH, pA);
176     }
177
178
179     if (tag == 0) { 
180       fAspect   =  1437. / 1933. ;
181       fL3Height = .75;
182       fL3Thick  *= 1.1;
183     }
184     else { 
185       fAspect   = 1835. / 2272. ;
186       fL3Height = .63;
187     }
188     fL3Width   = fL3Height / fAspect;
189     Int_t    hP   = Int_t(h * pH+.5); // Height in pixels 
190     Int_t    wP   = Int_t(fAspect * hP + .5); // Width in pixels 
191     Int_t    xP   = p->XtoPixel(x); // X pos in pixels 
192     Int_t    rP   = xP + wP; // Right in pixels; 
193     Double_t topX = p->PixeltoX(rP);
194     Double_t topY = y + h; // p->PixeltoY(tP); // y + h;
195     if (fDebug){
196       Int_t    yP   = p->YtoPixel(y); // X pos in pixels 
197       Int_t    tP   = yP - hP; // Top in pixels
198       Printf("(x,y)=(%d,%d) hP=%d wP=%d xP=%d yP=%d rP=%d tP=%d", 
199              xP, yP, hP, wP, xP, yP, rP, tP);
200     }
201     if (topX > 1 || topY > 1) { 
202       Warning("AliceLogo::Draw", "with (x,y)=(%f,%f) and h=%f -> top=(%f,%f)",
203               x, y, h, topX, topY);
204       topX = TMath::Min(topX, 1.);
205       topY = TMath::Min(topY, 1.);
206     }
207
208     p->cd();
209     fPad = new TPad("logo", "logo", x, y, topX, topY);
210     fPad->SetFixedAspectRatio(true);
211     fPad->SetFillColor(fDebug ? kGreen-4 : 0);
212     fPad->SetFillStyle(fDebug ? 4030     : 0);
213     fPad->SetBorderSize(fDebug ? 1 : 0);
214     fPad->SetBorderMode(fDebug ? 1 : 0);
215     fPad->SetLineColor(fDebug ? kBlue+1 : 0);
216     fPad->SetLineWidth(fDebug ? 1 : 0);
217     fPad->SetTopMargin(0);
218     fPad->SetBottomMargin(0);
219     fPad->SetLeftMargin(0);
220     fPad->SetRightMargin(0);
221     fPad->Draw();
222     if (fDebug)
223       Printf("(x,y)=(%f,%f) (tx,ty)=(%f,%f) (x1,y1)=(%f,%f) (x2,y2)=(%f,%f)", 
224              x, y, topX, topY, GetX1(), GetY1(), GetX2(), GetY2());
225     
226     if (fDebug) {
227       Int_t    ppH  = fPad->YtoPixel(0);
228       Int_t    ppW  = fPad->XtoPixel(1);
229       Double_t ppA  = Double_t(ppW) / ppH;
230       Printf("ppA=%d/%d=%lf A=%lf",ppW, ppH, ppA, fAspect);      
231       // Printf("ppA/A=%lf/%lf=%lf", ppA, fAspect, ppA/fAspect);
232     }
233
234     Int_t bg = (color & kPad) ? p->GetFillColor() : Int_t(kWhite);
235
236     DrawL3(color, (color & kReverse && !(color & kL3) ? bg : kWhite));
237
238     Int_t txtFg = kBlack;
239     if (color & kText)
240       txtFg = (color & kReverse ? kWhite : fBlue);
241     DrawALICE(txtFg, bg);
242     if      (tag == kPreliminary) DrawLabel(txtFg, bg, true);
243     else if (tag == kPerformance) DrawLabel(txtFg, bg, false);
244    
245     p->cd();
246   }
247   /** 
248    * Draw the L3 outline.  Note, this is put in a sub-pad of it's own. 
249    * 
250    * @param color Colour flags
251    * @param bg    Background color 
252    */
253   void DrawL3(UInt_t color, Int_t bg)
254   {
255     printf("Drawing L3 image ");
256     fPad->cd();
257     Double_t       o = TMath::Max((1-fL3Width)/2,0.);
258     TVirtualPad* pad = new TPad("l3","L3",o, 1-fL3Height, 
259                                 TMath::Min(fL3Width+o,1.), 1);
260     pad->SetFixedAspectRatio(true);
261     pad->SetFillColor(fDebug ? kGreen-4 : 0);
262     pad->SetFillStyle(fDebug ? 4030     : 0);
263     pad->SetBorderSize(fDebug ? 1 : 0);
264     pad->SetBorderMode(fDebug ? 1 : 0);
265     pad->SetLineColor(fDebug ? kRed+1 : 0);
266     pad->SetLineWidth(fDebug ? 1 : 0);
267     pad->SetTopMargin(0);
268     pad->SetBottomMargin(0);
269     pad->SetLeftMargin(0);
270     pad->SetRightMargin(0);
271     pad->Draw();
272     
273     Int_t lcol = (color & kL3 ? fRed : kBlack);
274     if (color & kReverse && lcol == kBlack) lcol = kWhite;
275
276     Double_t dA = 2 * TMath::Pi() / 8;
277     Double_t ro = .5 + .5 * (1 -  TMath::Cos(dA/2));
278     Double_t ri = ro - 1. / fL3Height * fL3Thick;
279     Double_t x0 = .5;
280     Double_t y0 = .5;
281     TGraph*  gi = new TGraph(9);
282     TGraph*  go = new TGraph(9);
283     gi->SetName("L3_inner");
284     go->SetName("L3_outer");
285     SetAttr(gi, gi, bg);
286     SetAttr(go, go, lcol);
287     for (Int_t i = 0; i < 9; i++) { 
288       Double_t a = (i + .5) * dA;
289       go->SetPoint(i, x0 + ro * TMath::Cos(a), y0 + ro * TMath::Sin(a));
290       gi->SetPoint(i, x0 + ri * TMath::Cos(a), y0 + ri * TMath::Sin(a));
291     }
292     pad->cd();
293     printf(".");
294     go->Draw("lf same");
295     printf(".");
296     gi->Draw("lf same");
297
298     Double_t len = .26;
299     if (color & kMany) {
300       Double_t w = 0.02;
301       for (Int_t i = 0; i < 36; i++) {
302         Int_t col = fYellow;
303         switch (i) { 
304         case 1: case 5: case 10: case 20: case 24: case 27: case 33: case 34:
305           col = fBlue; break;
306         case 3: case 4: case 8: case 16: case 19: case 23: case 29: case 30: 
307         case 32: 
308           col = fPink; break;
309         case 9: case 12: case 14: case 18: case 25: case 28: case 35:
310           col = fRed; break;
311         default:
312           break;
313         }
314         double l = len;
315         switch (i) { 
316         case 1: case 9: case 8: case 10: case 19: case 21: case 33:
317           l += 0.005; break; 
318         case 2: case 7:  case 11: case 12: case 15: case 16: case 20: case 34:
319           l += 0.02;  break;
320         case 3:  case 6: case 13: case 17: case 25: case 29:
321           l += 0.01;  break;
322         case 23: case 27: case 28: 
323           l -= 0.005;
324         default:      break;
325         }
326
327         printf(".");
328         DrawSpoke(i * 360/36, w, l, col);
329       }
330     }
331     else {
332       Double_t w  = .015;
333       Int_t col = (color & kParticles ? fRed : kBlack);
334       if (bg != kWhite) col = kWhite;
335       for (Int_t i = 0; i < 18; i++) {
336         double l = len;
337         switch (i) { 
338         case 0: case 2:                     
339           break;
340         case 1:  case 6:  case 8:         
341         case 10: case 17:
342           l += .02; break;
343         case 3: case 4: case 5: case 7: case 12: 
344           l += .01; break;
345         case 15: 
346           l += .005; break;
347         case 16:
348           l -= .005; break;
349         default:
350           break;
351         }
352         printf(".");
353         DrawSpoke(i * 360/18, w, l, col);
354       }
355     }
356     fPad->cd();
357     printf("\n");
358   }
359   /** 
360    * Draw a spoke in the L3 outline. 
361    * 
362    * @param ang Rotation angle in degrees. 
363    * @param w   Width
364    * @param len Length of spoke 
365    * @param fg  Foreground colour 
366    */
367   void DrawSpoke(Int_t ang, Double_t w, Double_t len, Int_t fg)
368   {
369     Double_t r1 = .12;
370
371     Double_t xx = r1;
372     Double_t yy = w/2;
373     Double_t xl = r1+len;
374
375     Double_t rad = TMath::Pi() / 180 * ang;
376     Double_t xtl  = .5 + xx * TMath::Cos(rad) - yy * TMath::Sin(rad);
377     Double_t ytl  = .5 + xx * TMath::Sin(rad) + yy * TMath::Cos(rad);
378     Double_t xbl  = .5 + xx * TMath::Cos(rad) + yy * TMath::Sin(rad);
379     Double_t ybl  = .5 + xx * TMath::Sin(rad) - yy * TMath::Cos(rad);
380     Double_t xtr  = .5 + xl * TMath::Cos(rad) - yy * TMath::Sin(rad);
381     Double_t ytr  = .5 + xl * TMath::Sin(rad) + yy * TMath::Cos(rad);
382     Double_t xbr  = .5 + xl * TMath::Cos(rad) + yy * TMath::Sin(rad);
383     Double_t ybr  = .5 + xl * TMath::Sin(rad) - yy * TMath::Cos(rad);
384
385     TGraph* tri = new TGraph(4);
386     SetAttr(tri, tri, fg);
387     tri->SetName(Form("spoke_tr_%03d", ang));
388     tri->SetPoint(0, 0.5,0.5);
389     tri->SetPoint(3, 0.5,0.5);
390     tri->SetPoint(1, xtl, ytl);
391     tri->SetPoint(2, xbl, ybl);
392     tri->Draw("same lf");
393
394     TGraph* lne = new TGraph(4);
395     SetAttr(lne, lne, fg);
396     lne->SetName(Form("spoke_ln_%03d", ang));
397     lne->SetPoint(0, xtl, ytl);
398     lne->SetPoint(1, xbl, ybl);
399     lne->SetPoint(2, xbr, ybr);
400     lne->SetPoint(3, xtr, ytr);
401     lne->SetPoint(4, xtl, ytl);
402     lne->Draw("same lf");
403     
404   }
405   /** 
406    * Draw the text ALICE in a separate pad 
407    * 
408    */
409   void DrawALICE(Int_t fg, Int_t bg)
410   {
411     printf("Drawing ALICE title ");
412     fPad->cd();
413     Double_t o  = TMath::Max((1-fL3Width)/2,0.);
414     Double_t r  = fL3Width/2;
415     Double_t t  = r*TMath::Sin(TMath::Pi()/8-.05);
416     Double_t t2 = r*TMath::Sin(TMath::Pi()/8+.05);
417     // Middle-bottom-left point is 
418     Double_t mblX = o;
419     Double_t mblY = (1-fL3Height/2) - t;
420     // Bottom-left point is 
421     Double_t blY = (1-fL3Height);
422     Double_t blX = .5 - t2;
423     // Slope
424     Double_t a = (blY - mblY) / (blX - mblX);
425     // Y is then, using y  = y1 + a (x - x1)
426     Double_t b = mblY + a * (.5 - mblX);
427
428     Double_t top = 1-fL3Height-fL3Thick;
429     Double_t hh  = 2 * (top - b);
430     Double_t bot = TMath::Max(top - hh,0.);
431     TVirtualPad* pad = new TPad("alice", "alice", o, bot+.005, 
432                                 TMath::Min(o+fL3Width,1.), top+.005);
433     pad->SetFixedAspectRatio(true);
434     pad->SetFillColor(fDebug ? kGreen-4 : 0);
435     pad->SetFillStyle(fDebug ? 4030     : 0);
436     pad->SetBorderSize(fDebug ? 1 : 0);
437     pad->SetBorderMode(fDebug ? 1 : 0);
438     pad->SetLineColor(fDebug ? kMagenta+1 : 0);
439     pad->SetLineWidth(fDebug ? 1 : 0);
440     pad->SetTopMargin(0);
441     pad->SetBottomMargin(0);
442     pad->SetLeftMargin(0);
443     pad->SetRightMargin(0);
444     pad->Draw();
445     pad->cd();
446
447     Double_t wp = pad->XtoPixel(1);
448     Double_t hp = pad->YtoPixel(0);
449     a           = hp / wp;
450     
451     Double_t w = .15;
452     printf(".");
453     DrawA(0,            0.01, w, a, fg, bg);
454     printf(".");
455     DrawL(.5 - 5.8*a*w, 0.01, w, a, fg);
456     printf(".");
457     DrawI(.5 - 1.5*a*w, 0.01, w, a, fg);
458     printf(".");
459     DrawC(.5 + 2.6*a*w, 0.00, /*w,*/ a, fg, bg);
460     printf(".");
461     DrawE(1  - 3.5*a*w, 0.01, w, a, fg);
462     fPad->cd();
463
464     printf("\n");
465   }
466   /** 
467    * Draw the letter A 
468    * 
469    * @param x    Base X coordinate 
470    * @param y    Base Y coordinate 
471    * @param w    Line width 
472    * @param a    Aspect ratio of pad 
473    * @param fg   Foreground colour
474    * @param bg   Background colour
475    */
476   void DrawA(Double_t x, Double_t y, Double_t w, Double_t a,
477              Int_t fg, Int_t bg)
478   {
479     Double_t u = 4.5 * w;
480     Double_t r = u / 2;
481     TBox* b1 = new TBox(x, y, x + a * w, y + 1 - r);
482     SetAttr(b1, b1, fg);
483     b1->Draw();
484     b1->DrawBox(x + (u-w) * a, y,         x + u * a, y + 1 - r);
485     b1->DrawBox(x,             y+1-r-2*w, x + u * a,     y + 1 - r -w);
486     TEllipse* a1 = new TEllipse(x+u*a/2, y+1-r-.01, (r-.005)*a, r, 0, 180);
487     SetAttr(a1, a1, fg);
488     a1->Draw("only");
489     TEllipse* a2 = new TEllipse(x+u*a/2, y+1-r-.01, (r-w-.005)*a, r-w, 0, 180);
490     SetAttr(a2, a2, bg);
491     a2->Draw("only");
492
493 #if 0
494     // To draw as lines - note line width does not scale 
495     Int_t lw = w*gPad->YtoPixel(0);
496     Double_t x1 = x+a*w/2;
497     Double_t x2 = x+a*(u-w/2);
498     Double_t y1 = y + 1 - r - 1.5*w;
499     TLine*    l1 = new TLine(x1, y, x1, y+1-r);
500     l1->SetLineWidth(lw);
501     l1->SetLineColor(kBlue);
502     l1->Draw();
503     l1->DrawLine(x2, y,x2, y+1-r);
504     l1->DrawLine(x1, y1,x2, y1);
505     
506     TEllipse* a3 = new TEllipse(x+u*a/2, y+1-r-.01, 
507                                 (r-w/2-.005)*a, r-w/2, 0, 180);
508     a3->SetFillStyle(0);
509     a3->SetFillColor(0);
510     // Int_t lw = w*gPad->YtoPixel(0);
511     Printf("Setting line width to %d", lw);
512     a3->SetLineWidth(lw);
513     a3->SetLineColor(kBlue);
514     a3->Draw("only");
515 #endif
516   }
517   /** 
518    * Draw the letter L
519    * 
520    * @param x    Base X coordinate 
521    * @param y    Base Y coordinate 
522    * @param w    Line width 
523    * @param a    Aspect ratio of pad 
524    * @param fg   Foreground colour
525    */
526   void DrawL(Double_t x, Double_t y, Double_t w, Double_t a, Int_t fg)
527   {
528     TBox* b1 = new TBox(x, y, x+3.1 * a * w, y + w);
529     SetAttr(b1, b1, fg);
530     b1->Draw();
531     b1->DrawBox(x, y , x + a * w,y+.99);
532   }
533   /** 
534    * Draw the letter I
535    * 
536    * @param x    Base X coordinate 
537    * @param y    Base Y coordinate 
538    * @param w    Line width 
539    * @param a    Aspect ratio of pad 
540    * @param fg   Foreground colour
541    */
542   void DrawI(Double_t x, Double_t y, Double_t w, Double_t a, Int_t fg)
543   {    
544     TBox* b1 = new TBox(x, y, x+3 * a * w, y + w);
545     SetAttr(b1, b1, fg);
546     b1->Draw();
547     b1->DrawBox(x+a*w,y,x+2*a*w,y+.99);
548     b1->DrawBox(x,y+1-w,x+3*a*w,y+.99);
549   }
550   /** 
551    * Draw the letter C
552    * 
553    * @param x    Base X coordinate 
554    * @param y    Base Y coordinate 
555    * @param a    Aspect ratio of pad 
556    * @param fg   Foreground colour
557    * @param bg   Background colour
558    */
559   void DrawC(Double_t x, Double_t y, Double_t a, Int_t fg, Int_t bg)
560   {
561     Int_t    nO   = 13;
562     Double_t dx   = 0; 
563     Double_t pO[] = { 
564       /* 0 */  0.698245  +dx, 0.271355,
565       /* 1 */  0.590204  +dx, 0.0755058,
566       /* 2 */  0.424947  +dx, 0.00,
567       /* 3 */  0.220343  +dx, 0.015668+.005,
568       /* 4 */  0.0629551 +dx, 0.15668,
569       /* 5 */  0.00786939+dx, 0.329027,
570       /* 6 */  -0.005,        0.564046,
571       /* 7 */  0.00786939+dx, 1-0.329027,
572       /* 8 */  0.0629551 +dx, 1-0.15668,
573       /* 9 */  0.220343  +dx, 1-0.015668-.005,
574       /* 10 */ 0.424947  +dx, .99,
575       /* 11 */ 0.590204  +dx, 1-0.0755058,
576       /* 12 */ 0.6982450 +dx, 1-0.271355, 0 };
577     TGraph* gO = new TGraph(nO);
578     gO->SetName("c_ext");
579     gO->SetLineColor(fDebug ? kGreen+1 : fg);
580     gO->SetLineWidth(fDebug ? 1        : 0);
581     gO->SetFillColor(fDebug ? kGreen+1 : fg);
582     gO->SetFillStyle(fDebug ? 0 : 1001);
583     for (Int_t i = 0; i < nO; i++) 
584       gO->SetPoint(i, x+pO[2*i]*a,y+pO[2*i+1]);
585     gO->Draw("fc same");
586     Int_t    nI   = 11;
587     Double_t pI[] = { 
588       /* 0 */ 0.551869, 1-0.713617,
589       /* 1 */ 0.481045, 1-0.821127,
590       /* 2 */ 0.363004, 1-0.853799,
591       /* 3 */ 0.213486, 1-0.783625,
592       /* 4 */ 0.158508, 1-0.635277,
593       /* 4 */ 0.158,    0.5, // 1-0.635277,
594       /* 5 */ 0.158508, 0.635277,
595       /* 6 */ 0.213486, 0.773625,
596       /* 7 */ 0.363004, 0.853799,
597       /* 8 */ 0.481045, 0.821127,
598       /* 9 */ 0.551869, 0.713617, 0 };
599     TGraph* gI = new TGraph(nI);
600     gI->SetName("c_int");
601     gI->SetLineColor(fDebug ? kGreen+1 : bg);
602     gI->SetLineWidth(fDebug ? 1        : 0);
603     gI->SetFillColor(fDebug ? kGreen+1 : bg);
604     gI->SetFillStyle(fDebug ? 0 : 1001);
605     for (Int_t i = 0; i < nI; i++) 
606       gI->SetPoint(i, x+pI[2*i]*a,y+pI[2*i+1]);
607     gI->Draw("fc same");
608
609
610     TGraph* gC = new TGraph(5);
611     gC->SetName("c_cut");
612     SetAttr(gC, gC, bg);
613     gC->SetPoint(0, gO->GetX()[0],    gO->GetY()[0]);
614     gC->SetPoint(1, gI->GetX()[0],    gI->GetY()[0]);
615     gC->SetPoint(2, gI->GetX()[nI-1], gI->GetY()[nI-1]);
616     gC->SetPoint(3, gO->GetX()[nO-1], gO->GetY()[nO-1]);
617     gC->SetPoint(4, gO->GetX()[0],    gO->GetY()[0]);
618     gC->Draw("fl same");
619   }
620   /** 
621    * Draw the letter E 
622    * 
623    * @param x    Base X coordinate 
624    * @param y    Base Y coordinate 
625    * @param w    Line width 
626    * @param a    Aspect ratio of pad 
627    * @param fg   Foreground colour
628    */
629   void DrawE(Double_t x, Double_t y, Double_t w, Double_t a, Int_t fg)
630   {
631     Double_t u = 3.5;
632     TBox* b1 = new TBox(x, y, x + a * w, y + .99);
633     SetAttr(b1, b1, fg);
634     b1->Draw();
635     b1->DrawBox(x, y,            x + u*a*w,      y+w);
636     b1->DrawBox(x, y+.99-w,      x + u*a*w,      y+.99);
637     b1->DrawBox(x, y+.5-w/2+.02, x + (u-.1)*a*w, y+.5+w/2+.02);
638   }
639   /** 
640    * Draw the letter F 
641    * 
642    * @param x    Base X coordinate 
643    * @param y    Base Y coordinate 
644    * @param w    Line width 
645    * @param a    Aspect ratio of pad 
646    * @param fg   Foreground colour
647    */
648   void DrawF(Double_t x, Double_t y, Double_t w, Double_t a, Int_t fg)
649   {
650     Double_t u = 3.5;
651     TBox* b1 = new TBox(x, y, x + a * w, y + .99);
652     SetAttr(b1, b1, fg);
653     b1->Draw();
654     b1->DrawBox(x, y+.99-w,      x + u*a*w,      y+.99);
655     b1->DrawBox(x, y+.5-w/2+.02, x + (u-.1)*a*w, y+.5+w/2+.02);
656   }
657   /** 
658    * Draw the label text ("Preliminary" or "Performance") in it's own pad 
659    * 
660    * @param fg Foreground colour 
661    * @param bg Background colour 
662    * @param preliminary If true, draw preliminary, otherwise performance
663    */
664   void DrawLabel(Int_t fg, Int_t bg, bool preliminary=true)
665   {
666     printf("Drawing stamp ");
667     fPad->cd();
668
669     Double_t top = .08;
670     Double_t bot = 0;
671     TVirtualPad* pad = new TPad("label", "label", 0, bot, 1, top);
672     pad->SetFixedAspectRatio(true);
673     pad->SetFillColor(fDebug ? kGreen-4 : 0);
674     pad->SetFillStyle(fDebug ? 4030     : 0);
675     pad->SetBorderSize(fDebug ? 1 : 0);
676     pad->SetBorderMode(fDebug ? 1 : 0);
677     pad->SetLineColor(fDebug ? kCyan+2 : 0);
678     pad->SetLineWidth(fDebug ? 1 : 0);
679     pad->SetTopMargin(0);
680     pad->SetBottomMargin(0);
681     pad->SetLeftMargin(0);
682     pad->SetRightMargin(0);
683     pad->Draw();
684     pad->cd();
685
686     Double_t wp = pad->XtoPixel(1);
687     Double_t hp = pad->YtoPixel(0);
688     Double_t a  = hp / wp;
689     
690     Double_t w = .15;
691     if (preliminary) {
692       printf("."); DrawP(0,            0.01, w, a, fg, bg);
693       printf("."); DrawR(6.3  * w * a, 0.01, w, a, fg, bg);
694       printf("."); DrawE(13   * w * a, 0.01, w, a, fg);
695       printf("."); DrawL(18.7 * w * a, 0.01, w, a, fg);
696       printf("."); DrawI(23.3 * w * a, 0.01, w, a, fg);
697       printf("."); DrawM(29   * w * a, 0.01, w, a, fg);
698       printf("."); DrawI(37.2 * w * a, 0.01, w, a, fg);
699       printf("."); DrawN(42.5 * w * a, 0.01, w, a, fg);
700       printf("."); DrawA(49.4 * w * a, 0.01, w, a, fg, bg);
701       printf("."); DrawR(56.4 * w * a, 0.01, w, a, fg, bg);
702       printf("."); DrawY(62.3 * w * a, 0.01, w, a, fg);
703     }
704     else { 
705       printf("."); DrawP(0,            0.01, w, a, fg, bg);
706       printf("."); DrawE(6.3  * w * a, 0.01, w, a, fg);
707       printf("."); DrawR(12   * w * a, 0.01, w, a, fg, bg);
708       printf("."); DrawF(18.7 * w * a, 0.01, w, a, fg);
709       printf("."); DrawO(24   * w * a, 0.01, w, a, fg, bg);
710       printf("."); DrawR(30.7 * w * a, 0.01, w, a, fg, bg);
711       printf("."); DrawM(37.5 * w * a, 0.01, w, a, fg);
712       printf("."); DrawA(45.5 * w * a, 0.01, w, a, fg, bg);
713       printf("."); DrawN(52.4 * w * a, 0.01, w, a, fg);
714       printf("."); DrawC(58.7 * w * a, 0.01, /*w,*/ a, fg, bg);
715       printf("."); DrawE(64.8 * w * a, 0.01, w, a, fg);
716     }
717
718     fPad->cd();
719     printf("\n"); 
720   }    
721   /** 
722    * Draw the letter O
723    * 
724    * @param x    Base X coordinate 
725    * @param y    Base Y coordinate 
726    * @param w    Line width 
727    * @param a    Aspect ratio of pad 
728    * @param fg   Foreground colour
729    * @param bg   Background colour
730    */
731   void DrawO(Double_t x, Double_t y, Double_t w, Double_t a, Int_t fg, Int_t bg)
732   {
733     Double_t fw = 4.8;
734
735     TEllipse* a1 = new TEllipse(x+fw/2*a*w, y + .495, a*w*fw/2, .495, 0, 360);
736     SetAttr(a1, a1, fg);
737     a1->Draw("only");
738     TEllipse* a2 = new TEllipse(x+fw/2*a*w, y + .495, a*w*(fw/2-1), .495-w);
739     SetAttr(a2, a2, bg);
740     a2->Draw("only");
741   }
742   /** 
743    * Draw the letter P 
744    * 
745    * @param x    Base X coordinate 
746    * @param y    Base Y coordinate 
747    * @param w    Line width 
748    * @param a    Aspect ratio of pad 
749    * @param fg   Foreground colour
750    * @param bg   Background colour
751    */
752   void DrawP(Double_t x, Double_t y, Double_t w, Double_t a, Int_t fg, Int_t bg)
753   {
754     Double_t u  = 4.3 * w;
755     Double_t r  = 4.3 * w / 2;
756
757     TBox* b1 = new TBox(x, y, x + a * w, y + .99);
758     SetAttr(b1, b1, fg);
759     b1->Draw();
760     b1->DrawBox(x + a * w, y + .99 - w, x + 2.5 * a * w, y + .99);
761     b1->DrawBox(x + a * w, y + .99 - u, x + 2.5 * a * w, y + .99 - u + w);
762     TEllipse* a1 = new TEllipse(x+2.5*a*w, y + .99 - r, a*r, r-.01, -90, 90);
763     SetAttr(a1, a1, fg);
764     a1->Draw("only");
765     TEllipse* a2 = new TEllipse(x+2.5*a*w, y + .99 - r, a*(r-w), r-w-.01, 
766                                 -90, 90);
767     SetAttr(a2, a2, bg);
768     a2->Draw("only");
769   }
770   /** 
771    * Draw the letter R
772    * 
773    * @param x    Base X coordinate 
774    * @param y    Base Y coordinate 
775    * @param w    Line width 
776    * @param a    Aspect ratio of pad 
777    * @param fg   Foreground colour
778    * @param bg   Background colour
779    */
780   void DrawR(Double_t x, Double_t y, Double_t w, Double_t a, Int_t fg, Int_t bg)
781   {
782     DrawP(x, y, w, a, fg, bg);
783
784     Double_t u   = 4.3 * w;
785     Double_t fw  = 2.5 + 4.3 / 2;
786     Double_t ang = 60 * TMath::Pi() / 180;
787     Double_t o   = w / TMath::Sin(ang);
788
789     TGraph* g = new TGraph(5);
790     SetAttr(g, g, fg);
791     // Top right
792     g->SetPoint(0, x+a*(2*w+o), y+1-u+.01);
793     // Top left 
794     g->SetPoint(1, x+a*2*w,     y+1-u+.01);
795     // Bottom left 
796     g->SetPoint(2, x+a*(fw*w-o+.06), y);
797     // Bottom right
798     g->SetPoint(3, x+a*(fw*w+.06),     y);
799     g->SetPoint(4, g->GetX()[0], g->GetY()[0]);
800     g->Draw("same lf");
801   }
802   /** 
803    * Draw the letter M
804    * 
805    * @param x    Base X coordinate 
806    * @param y    Base Y coordinate 
807    * @param w    Line width 
808    * @param a    Aspect ratio of pad 
809    * @param fg   Foreground colour
810    */
811   void DrawM(Double_t x, Double_t y, Double_t w, Double_t a, Int_t fg) 
812   {
813     TBox* b1 = new TBox(x, y, x + a * w, y + 1);
814     SetAttr(b1, b1, fg);
815     b1->Draw();
816     b1->DrawBox(x+4.8*a*w, y, x+5.8*a*w, y+1);
817     
818     Double_t ang = 28 * TMath::Pi() / 180;
819     Double_t o = w / TMath::Sin(ang);
820
821     TGraph* gl = new TGraph(7);
822     SetAttr(gl, gl, fg);
823     gl->SetPoint(0, x+a*w, y+1);
824     gl->SetPoint(1, x+a*w, y+1-o);
825     gl->SetPoint(2, x+a*w*(1+3.8/2), y+w);
826     gl->SetPoint(3, x+a*w*4.8, y+1-o);
827     gl->SetPoint(4, x+a*w*4.8, y+1);
828     gl->SetPoint(5, x+a*w*(1+3.8/2), y+w+o);
829     gl->SetPoint(6, x+a*w, y+1);
830     gl->Draw("same lf");
831
832   }
833   /** 
834    * Draw the letter N 
835    * 
836    * @param x    Base X coordinate 
837    * @param y    Base Y coordinate 
838    * @param w    Line width 
839    * @param a    Aspect ratio of pad 
840    * @param fg   Foreground colour
841    */
842   void DrawN(Double_t x, Double_t y, Double_t w, Double_t a, Int_t fg) 
843   {
844     Double_t fw = 4.6;
845     TBox* b1 = new TBox(x, y, x + a * w, y + 1);
846     SetAttr(b1, b1, fg);
847     b1->Draw();
848     b1->DrawBox(x+a*w*(fw-1), y, x+a*w*(fw), y+1);
849     
850     Double_t ang = 28 * TMath::Pi() / 180;
851     Double_t o = w / TMath::Sin(ang);
852
853     TGraph* gl = new TGraph(5);
854     gl->SetLineColor(fDebug ? kGreen+1 : fg);
855     gl->SetLineWidth(fDebug ? 1        : 0);
856     gl->SetFillColor(fDebug ? kGreen+1 : fg);
857     gl->SetFillStyle(fDebug ? 0 : 1001);
858     gl->SetPoint(0, x+a*w, y+1);
859     gl->SetPoint(1, x+a*w, y+1-o);
860     gl->SetPoint(2, x+a*w*(fw-1), y);
861     gl->SetPoint(3, x+a*w*(fw-1), y+o);
862     gl->SetPoint(4, x+a*w, y+1);
863     gl->Draw("same lf");
864   }
865   /** 
866    * Draw the letter Y
867    * 
868    * @param x    Base X coordinate 
869    * @param y    Base Y coordinate 
870    * @param w    Line width 
871    * @param a    Aspect ratio of pad 
872    * @param fg   Foreground colour
873    */
874   void DrawY(Double_t x, Double_t y, Double_t w, Double_t a, Int_t fg)
875   {
876     Double_t u  = 4 * w;
877     Double_t fw = 5.5;
878
879     TBox* b1 = new TBox(x+a*w*(fw/2-.5), y, x + a * w *(fw/2+.5), y + 1 - u);
880     b1->SetLineColor(fDebug ? kGreen+1 : fg);
881     b1->SetFillColor(fDebug ? 0 : fg);
882     b1->SetFillStyle(fDebug ? 0 : 1001);
883     b1->Draw();
884
885     Double_t ang = 40 * TMath::Pi() / 180;
886     Double_t o  = w / TMath::Sin(ang);
887     Double_t o2 = w / TMath::Cos(ang);
888
889
890     TGraph* g = new TGraph(8);
891     SetAttr(g, g, fg);
892     g->SetPoint(0, x+a*w*(fw/2-.5), y + 1-u);
893     g->SetPoint(1, x,             y + 1);
894     g->SetPoint(2, x+a*o2,        y + 1);
895     g->SetPoint(3, x+a*w*fw/2,    y + 1 - u + o);
896     g->SetPoint(4, x+a*w*fw-a*o2, y+1);
897     g->SetPoint(5, x+a*w*fw,      y+1);
898     g->SetPoint(6, x+a*w*(fw/2+.5), y + 1-u);
899     g->SetPoint(7, x+a*w*(fw/2-.5), y + 1-u);
900
901     
902     g->Draw("same lf");
903   }
904   /** 
905    * Set Line and Fill attributes
906    * 
907    * @param lne Line attribute interface 
908    * @param fll Fill attribute interface 
909    * @param col Colour 
910    */
911   void SetAttr(TAttLine* lne, TAttFill* fll, Int_t col) 
912   {
913     if (lne) {
914       lne->SetLineColor(fDebug ? kGreen+1 : col);
915       lne->SetLineWidth(fDebug ? 1        : 0);
916     }
917     if (fll) { 
918       fll->SetFillColor(fDebug ? kGreen+1 : col);
919       fll->SetFillStyle(fDebug ? 0        : 1001);
920     }
921   }
922   Double_t GetX1() const { return fPad ? fPad->GetXlowNDC() : -1; }
923   Double_t GetX2() const { return fPad ? GetX1()+fPad->GetWNDC() : -1; }
924   Double_t GetY1() const { return fPad ? fPad->GetYlowNDC() : -1; }
925   Double_t GetY2() const { return fPad ? GetY1()+fPad->GetHNDC() : -1; }
926   Double_t GetCX() const { return fPad ? (GetX1()+GetX2())/2 : -1; }
927   Double_t GetCY() const { return fPad ? (GetY1()+GetY2())/2 : -1; }
928   /** 
929    * run a simple test
930    * 
931    * @param what 
932    */
933   static void Test(const TString& what)
934   {
935     Test(AliceLogo::ParseTag(what), AliceLogo::ParseColors(what), 
936          what.Contains("debug", TString::kIgnoreCase));
937   }
938   /** 
939    * Run a simple test
940    * 
941    * @param tag 
942    * @param col 
943    * @param debug 
944    */
945   static void Test(UShort_t tag, UInt_t col, Bool_t debug)
946   {
947     TCanvas* c = new TCanvas("test", "Test of AliceLogo");
948     c->SetFillColor(kYellow-10);
949     TH1* h = new TH1F("h", "h", 60, -3, 3);
950     h->SetFillColor(kRed+1);
951     h->SetFillStyle(3001);
952     h->FillRandom("gaus");
953     h->Draw();
954     
955     AliceLogo* dut = new AliceLogo(debug);
956     dut->Draw(c, .75, .4, .25, tag, col);
957
958     c->SaveAs("test.png");
959     c->SaveAs("test.pdf");
960     c->SaveAs("test.svg");
961   }
962   /** 
963    * Check compatiblity by overlaying this logo on 'official' images
964    * 
965    * @param what 
966    */
967   static void Check(const TString& what)
968   {
969     Check(AliceLogo::ParseTag(what), AliceLogo::ParseColors(what), 
970          what.Contains("debug", TString::kIgnoreCase));
971   }
972   /** 
973    * Check compatiblity by overlaying this logo on 'official' images
974    * 
975    * @param tag 
976    * @param col 
977    * @param debug 
978    */
979   static void Check(UShort_t tag, UInt_t col, Bool_t debug=true)
980   {
981     
982     TImage* img = TImage::Create();
983     TString imgName = "2012-Jul-04-Base_Logo.png";
984     // Int_t   logoW   = 0; // img->GetWidth();
985     // Int_t   logoH   = 0; // img->GetHeight();
986     switch (tag) { 
987     case AliceLogo::kPreliminary: 
988       // logoW   = 1849;
989       // logoH   = 2277;
990       imgName = "2012-Jul-04-Preliminary_Logo.png"; 
991       break;
992     case AliceLogo::kPerformance: 
993       imgName = "2012-Jul-04-Performance_Logo.png";
994       break;
995     default:
996       if (col & kMany) 
997         imgName = "2012-Jul-04-4_Color_Logo_CB.png";
998       else
999         imgName = "2012-Jul-04-Base_Logo.png";
1000     }
1001     Printf("Reading %s", imgName.Data());
1002     img->ReadImage(imgName);
1003     Int_t    logoW = img->GetWidth();
1004     Int_t    logoH = img->GetHeight();
1005     Double_t logoA = Float_t(logoH) / logoW; 
1006
1007     Printf("Logo dimensions (wxh): (%d x %d)", logoW, logoH);
1008     Int_t myHeight = 800;
1009     TCanvas* c = new TCanvas("check", "Check of AliceLogo", 
1010                              (myHeight-22)/logoA, myHeight);
1011     c->SetTopMargin(0);
1012     c->SetRightMargin(0);
1013     c->SetBottomMargin(0);
1014     c->SetLeftMargin(0);
1015     c->SetFillColor(debug ? kRed-4 : kWhite);
1016     c->SetBorderSize(0);
1017     c->SetBorderMode(0);
1018     if (col & AliceLogo::kReverse /*&& !(col & AliceLogo::kL3)*/ && !debug) 
1019       c->SetFillColor(kBlack);
1020     
1021     if (debug) img->Draw();
1022
1023     AliceLogo* dut = new AliceLogo(debug);
1024     dut->Draw(c, 0, 0, 1, tag, col);
1025
1026     c->SaveAs("check.svg");
1027   }
1028
1029   TVirtualPad* fPad;      // Our pad 
1030   Double_t     fAspect;   // Aspect ratio of our pad 
1031   Double_t     fL3Thick;  // Fraction of canvas height
1032   Double_t     fL3Height; // Fraction of canvas height 
1033   Double_t     fL3Width;  // Width of L3 sub-pad
1034   Bool_t       fDebug;    // Debug (make outline only)
1035   Int_t        fRed;      // The red color 
1036   Int_t        fYellow;   // The yellow-ish color
1037   Int_t        fPink;     // The dark-red pink-ish color 
1038   Int_t        fBlue;     // The blue gray-ish color 
1039 };
1040
1041 #endif
1042 //
1043 // EOF
1044 //