Bringing CMakeLists under svn maintenance
[u/mrichter/AliRoot.git] / FMD / AliFMDPattern.cxx
1 /**************************************************************************
2  * Copyright(c) 2004, ALICE Experiment at CERN, All rights reserved. *
3  *                                                                        *
4  * Author: The ALICE Off-line Project.                                    *
5  * Contributors are mentioned in the code where appropriate.              *
6  *                                                                        *
7  * Permission to use, copy, modify and distribute this software and its   *
8  * documentation strictly for non-commercial purposes is hereby granted   *
9  * without fee, provided that the above copyright notice appears in all   *
10  * copies and that both the copyright notice and this permission notice   *
11  * appear in the supporting documentation. The authors make no claims     *
12  * about the suitability of this software for any purpose. It is          *
13  * provided "as is" without express or implied warranty.                  *
14  **************************************************************************/
15 /* $Id$ */
16 /** @file    AliFMDPattern.cxx
17     @author  Christian Holm Christensen <cholm@nbi.dk>
18     @date    Mon Mar 27 12:39:09 2006
19     @brief   FMD 2D Event display 
20 */
21 //___________________________________________________________________
22 //
23 // The classes defined here, are utility classes for reading in data
24 // for the FMD.  They are  put in a seperate library to not polute the
25 // normal libraries.  The classes are intended to be used as base
26 // classes for customized class that do some sort of analysis on the
27 // various types of data produced by the FMD. 
28 //
29 // Latest changes by Christian Holm Christensen
30 //
31
32 #include <iostream>
33
34 // #include <TApplication.h>
35 // #include <TButton.h>
36 #include <TCanvas.h>
37 #include <TH2F.h>
38 #include <TMath.h>
39 #include <TPad.h>
40 #include <TRandom.h>
41 // #include <TSlider.h>
42 #include <TStyle.h>
43 // #include <TSystem.h>
44 #include <TVector2.h>
45 // #include <TView.h>
46 #include <TGraph.h>
47 #include "AliFMDPattern.h"      // ALIFMDDISPLAY_H
48 #include "AliFMDGeometry.h"     // ALIFMDGEOMETRY_H
49 //#include "AliFMDParameters.h" // ALIFMDPARAMETERS_H
50 #include "AliFMDRing.h"
51 // #include "AliFMDDetector.h"
52 #include "AliFMDHit.h"
53 #include "AliMultiplicity.h"
54 #include "AliESDEvent.h"
55 #include "AliESDVertex.h"
56 // #include <AliLog.h>
57 #include "AliFMDDebug.h" // Better debug macros
58 // #include "AliPhysicsSelection.h"
59 class AliFMDDetector;
60
61 //____________________________________________________________________
62 ClassImp(AliFMDPattern)
63 #if 0
64   ; // This is here to keep Emacs for indenting the next line
65 #endif
66
67 //____________________________________________________________________
68 AliFMDPattern::AliFMDPatternDetector::AliFMDPatternDetector(UShort_t id) 
69   : fId(id),
70     fCounts(0), 
71     fGraphs(0), 
72     fFrame(0), 
73     fInners(10), 
74     fOuters(id == 1 ? 0 : 20)
75 {
76   // CTOR 
77   // 
78   // Parameters: 
79   // 
80   //   ID       Identifier 
81 }
82
83 //____________________________________________________________________
84 AliFMDPattern::AliFMDPatternDetector::~AliFMDPatternDetector()
85 {
86   // DTOR 
87   // Destructor - 
88   // deletes mother frame 
89   if (fFrame) delete fFrame;
90 }
91
92 //____________________________________________________________________
93 void
94 AliFMDPattern::AliFMDPatternDetector::DrawShape(const TObjArray& a) 
95 {
96   // Draw all shapes. 
97   // 
98   // Paramters 
99   // 
100   //    a       Array of shapes 
101   //
102   TIter next(&a);
103   TGraph* g = 0;
104   while ((g = static_cast<TGraph*>(next()))) {
105     g->DrawClone("f same");
106     g->DrawClone("l same");
107   }
108 }
109
110 //____________________________________________________________________
111 void
112 AliFMDPattern::AliFMDPatternDetector::CopyShapes(const TObjArray& src, 
113                                                  TObjArray& dest, 
114                                                  Double_t ang, 
115                                                  Double_t fx, 
116                                                  Double_t fy)
117 {
118   // 
119   // Copy shapes
120   // 
121   // Parameters:
122   //    input  Source
123   //    own    Ours
124   //    ang    Angle 
125   //    fx     Factor x
126   //    fy     Factor y
127   //
128   TIter     next(&src);
129   TGraph*   g = 0;
130   while ((g = static_cast<TGraph*>(next()))) { 
131     TGraph* gg = new TGraph(*g);
132     Double_t* x  = gg->GetX();
133     Double_t* y  = gg->GetY();
134     for (Int_t i = 0; i < gg->GetN(); i++) { 
135       Float_t xx = x[i] * TMath::Cos(ang) - y[i] * TMath::Sin(ang);
136       Float_t yy = x[i] * TMath::Sin(ang) + y[i] * TMath::Cos(ang);
137       gg->SetPoint(i, fx * xx, fy * yy);
138     }
139     gg->SetFillStyle(g->GetFillStyle());
140     gg->SetFillColor(g->GetFillColor());
141     gg->SetLineStyle(g->GetLineStyle());
142     gg->SetLineColor(g->GetLineColor());
143     gg->SetLineWidth(g->GetLineWidth());
144     gg->SetMarkerStyle(g->GetMarkerStyle());
145     gg->SetMarkerColor(g->GetMarkerColor());
146     gg->SetMarkerSize(g->GetMarkerSize());
147     TString name(g->GetName());
148     name.ReplaceAll("X", Form("%d",fId));
149     gg->SetName(name.Data());
150     TString title(g->GetTitle());
151     title.ReplaceAll("X", Form("%d",fId));
152     gg->SetTitle(title.Data());
153     dest.Add(gg);
154   }
155   dest.SetOwner();
156 }
157
158 //____________________________________________________________________
159 void
160 AliFMDPattern::AliFMDPatternDetector::Begin(Int_t      nlevel, 
161                                             Double_t   r, 
162                                             TObjArray& inners, 
163                                             TObjArray& outers)
164 {
165   // Start of a run. 
166   // 
167   // Parameters 
168   // 
169   //    nlevel          Number of levels 
170   //    r               Radius 
171   //    inners          Array of inner shapes 
172   //    outers          Array of outer shapes 
173   //
174
175   // To make code-checker shut up
176   TStyle* style = gStyle;  
177   if (nlevel < 1) nlevel = style->GetNumberOfColors();
178   fCounts.Set(nlevel);
179   Double_t rr = 1.05 * r;
180   if (!fFrame) {
181     // The code-checker thinks this is not using the declaration of
182     // TH2F - what a morron!   
183     fFrame = new TH2F(Form("fmd%dFrame", fId), Form("FMD%d", fId), 
184                       100, -rr, rr, 100, -rr, rr);
185     fFrame->SetStats(kFALSE);
186     fFrame->Draw();
187   }
188   Double_t ang = (fId == 1 ? -TMath::Pi() / 2 : 0);
189   Double_t fx  = (fId == 3 ? -1               : 1); // Flip around Y
190   Double_t fy  = (fId == 1 ?  1               : 1); // Flip around X
191   
192   CopyShapes(inners, fInners, ang, fx, fy);
193   DrawShape(fInners);
194   if (fId != 1) { 
195     CopyShapes(outers, fOuters, ang, fx, fy);
196     DrawShape(fOuters);
197   }
198
199   for (Int_t i = 0; i < nlevel; i++) { 
200     TGraph* g = new TGraph;
201     Int_t idx = Int_t(Float_t(i) / nlevel * style->GetNumberOfColors());
202     Int_t col = style->GetColorPalette(idx);
203     g->SetName(Form("FMD%d_L%02d", fId, i));
204     g->SetMarkerColor(col);
205     g->SetLineColor(col);
206     g->SetFillColor(col);
207     g->SetMarkerSize(i * .2 + .2);
208     g->SetMarkerStyle(2);
209     g->SetEditable(kFALSE);
210     g->Draw("same p");
211     fGraphs.AddAtAndExpand(g, i);
212   }
213   // TIter   next(&fGraphs);
214 }
215
216 //____________________________________________________________________
217 void
218 AliFMDPattern::AliFMDPatternDetector::Clear() 
219 {
220   // Clear this display.  
221   // Simply reset counters to zero. 
222   // Avoid deleting memory. 
223   fCounts.Reset(0);
224 }
225
226 //____________________________________________________________________
227 void
228 AliFMDPattern::AliFMDPatternDetector::End()
229 {
230   // Called when displaying the data.  
231   // Simply resets number of points at each level to 
232   // the seen number of hits at that level. 
233   // Avoid deleting memory. 
234   
235  
236   TIter   next(&fGraphs);
237   TGraph* g = 0;
238   Int_t   i = 0;
239   while ((g = static_cast<TGraph*>(next()))) { 
240     Int_t cnt = fCounts[i++];
241     if (cnt > 0) { 
242       g->Set(cnt);
243       g->SetMarkerSize(i * .2 + .2);
244     }
245     else {
246       g->SetPoint(0,0,0);
247       g->SetMarkerSize(0);
248     }
249   }
250   
251 }
252 //____________________________________________________________________
253 void
254 AliFMDPattern::AliFMDPatternDetector::AddMarker(Double_t x, 
255                                                 Double_t y, 
256                                                 Float_t  s, 
257                                                 Float_t  max)
258 {
259   // Add a marker at (X,Y,Z).  The marker color and size is chosen
260   // relative to the MAX argument. 
261   // 
262   // Parameters 
263   // 
264   //    X,Y,Z           Coordiantes 
265   //    MAX             Maximum value. 
266   // 
267   // Sigh, for some odd reason, the code-checker does not recognise
268   // this a usage of the TMath namespace declaration! Idiot 
269   // 
270   Int_t i = TMath::Min(Int_t(fCounts.fN * s / max),  
271                        Int_t(fGraphs.GetEntries()-1));
272   if (i < 0 || i >= fCounts.fN) { 
273     std::cerr << "Graph index " << i << " out of bounds [0," 
274               << fCounts.fN << ") - " 
275               << fCounts.fN << " * " << s << " / " << max << std::endl;
276     return;
277   }
278   TGraph* g = static_cast<TGraph*>(fGraphs.At(i));
279   if (!g) return;
280   g->SetPoint(fCounts[i]++, x, y);
281 }
282
283
284 //____________________________________________________________________
285 AliFMDPattern::AliFMDPattern(const char* gAliceFile)
286   : AliFMDDisplay(kTRUE, gAliceFile),
287     fInners(0), 
288     fOuters(0),
289     fInnerMax(0), 
290     fOuterMax(0),
291     fFMD1Pad(0),
292     fFMD1(1),
293     fFMD2Pad(0),
294     fFMD2(2),
295     fFMD3Pad(0),
296     fFMD3(3),
297     fSummary(0),
298     fEvent(.1, .8, "Event #"),
299     fFMD1Sum(.2, .7, "# in FMD1: "),
300     fFMD2Sum(.2, .6, "# in FMD2: "),
301     fFMD3Sum(.2, .5, "# in FMD3: "),
302     fLine(.15, .47, .85, .47),
303     fTotal(.2, .35, "Total:   "), 
304     fFMD1Area(0),
305     fFMD2Area(0),
306     fFMD3Area(0)// ,fPhysicsSelection(0)
307 {
308   // Constructor. 
309   // 
310   // Parameters 
311   // 
312   //   gAliceFile       The galice.root file to use - if any. 
313   // 
314
315   SetName("AliFMDPattern");
316   SetName("2D display of FMD data");
317   // fPhysicsSelection = new AliPhysicsSelection();
318   // RemoveLoad(kGeometry);
319   fEvent.SetBit(TLatex::kTextNDC);
320   fFMD1Sum.SetBit(TLatex::kTextNDC);
321   fFMD2Sum.SetBit(TLatex::kTextNDC);
322   fFMD3Sum.SetBit(TLatex::kTextNDC);
323   fLine.SetBit(TLine::kLineNDC);
324   fTotal.SetBit(TLatex::kTextNDC);
325 }
326
327 //____________________________________________________________________
328 AliFMDPattern::~AliFMDPattern()
329 {
330   // DTOR 
331   // Free all allocated shapes. 
332   // note, that most members are real objects, so we do not need to
333   // deal with them here. 
334   fInners.Delete();
335   fOuters.Delete();
336 }
337
338     
339 //____________________________________________________________________
340 Bool_t 
341 AliFMDPattern::Init()
342 {
343   // Initialize.  Get transforms and such, 
344   if (!AliFMDInput::Init()) return kFALSE;
345   AliFMDGeometry* geom = AliFMDGeometry::Instance();
346   if (!geom) return kFALSE;
347   geom->Init();
348   geom->InitTransformations();
349   
350   fFMD1Area = 0;
351   fFMD2Area = 0;
352   fFMD3Area = 0;
353
354   Double_t innerArea = 0;
355   Double_t outerArea = 0;
356
357   Char_t rs[] = { 'I' , 'O', '\0' };
358   Char_t *r   = rs;
359   do {
360     AliFMDRing* ring = geom->GetRing(*r);
361     if (!ring) continue;
362
363     Double_t rl   = ring->GetMinR();
364     Double_t rh   = ring->GetMaxR();
365     Double_t area = rh * rh * TMath::Pi() - rl * rl * TMath::Pi();
366     if (*r == 'I') innerArea = area;
367     else           outerArea = area;
368       
369
370     const TObjArray& vs = ring->GetVerticies();
371     TObjArray&       gs = (*r == 'I' ? fInners   : fOuters);
372     Float_t&         mr = (*r == 'I' ? fInnerMax : fOuterMax);
373     Int_t            nm = ring->GetNModules();
374     AliFMDDebug(1, ("Making %d modules for %c", nm, *r));
375     for (Int_t m = 0; m < nm; m++) {
376       Int_t          nv = 6; // vs.GetEntries();
377       Double_t       a  = TMath::Pi() / 180 * (m * 2 + 1) * ring->GetTheta();
378       TGraph*        g  = new TGraph(nv+1);
379       Double_t       x0 = 0, y0 = 0;
380       gs.AddAtAndExpand(g, m);
381       for (Int_t c = 1; c < 4; c++) {
382         TVector2* v = static_cast<TVector2*>(vs.At(c));
383         mr          = TMath::Max(mr, Float_t(v->Mod()));
384         TVector2  w(v->Rotate(a));
385         if (c == 1) { x0 = w.X(); y0 = w.Y(); }
386         g->SetPoint(c-1, w.X(), w.Y());
387       }
388       for (Int_t c = 3; c > 0; c--) {
389         TVector2* v = static_cast<TVector2*>(vs.At(c));
390         TVector2  u(-v->X(), v->Y());
391         mr          = TMath::Max(mr, Float_t(u.Mod()));
392         TVector2  w(u.Rotate(a));
393         g->SetPoint(3+(3-c), w.X(), w.Y());
394       }
395       g->SetName(Form("FMDX%c_%02d%02d", *r, 2*m,2*m+1));
396       g->SetTitle(Form("FMDX%c, sectors %d and %d", *r, 2*m,2*m+1));
397       g->SetPoint(nv, x0, y0);
398       g->SetFillColor((*rs == 'I' ? 
399                        (m % 2 == 0 ? 18 : 17) :
400                        (m % 2 == 0 ? 20 : 23)));
401       g->SetFillStyle(3001);
402       g->SetLineColor(1);
403       g->SetLineWidth(1);
404       g->SetLineStyle(2);
405     }
406   } while (*(++r));
407
408   fFMD1Area = innerArea;
409   fFMD2Area = innerArea + outerArea;
410   fFMD3Area = innerArea + outerArea;
411   
412   return kTRUE;
413 }
414
415 //____________________________________________________________________
416 Bool_t 
417 AliFMDPattern::Begin(Int_t event) 
418 {
419   // Called at the begining of an event. 
420   // 
421   // Parameters 
422   //
423   //    EVENT           The event number 
424   // 
425   MakeAux();
426   if (!fCanvas) {
427     const char* which[] = { "Continue", "Start", "Pause", "Redisplay", 0 };
428     MakeCanvas(which);
429     
430     AliFMDGeometry* geom = AliFMDGeometry::Instance();
431     // AliFMDDetector* det;
432     if ((/* det = */ geom->GetDetector(1))) {
433       fPad->cd();
434       fFMD1Pad = new TPad("FMD1", "FMD1", 0.0, 0.50, 0.5, 1.0, 0, 0);
435       fFMD1Pad->Draw();
436       fFMD1Pad->cd();
437       fFMD1.Begin(-1, fInnerMax, fInners, fOuters);
438     }
439     if ((/* det = */ geom->GetDetector(2))) {
440       fPad->cd();
441       fFMD2Pad = new TPad("FMD2", "FMD2", 0.5, 0.50, 1.0, 1.0, 0, 0);
442       fFMD2Pad->Draw();
443       fFMD2Pad->cd();
444       fFMD2.Begin(-1, fOuterMax, fInners, fOuters);
445     }
446     if ((/* det = */ geom->GetDetector(3))) {
447       fPad->cd();
448       fFMD3Pad = new TPad("FMD3", "FMD3", 0.0, 0.0, .5, .5, 0, 0);
449       fFMD3Pad->Draw();
450       fFMD3Pad->cd();
451       fFMD3.Begin(-1, fOuterMax, fInners, fOuters);
452     }
453     fPad->cd();
454     fSummary = new TPad("display", "Display", 0.5, 0.0, 1.0, 0.5, 0, 0);
455     fSummary->Draw();
456     fSummary->cd();
457     fEvent.Draw();
458     fFMD1Sum.Draw();
459     fFMD2Sum.Draw();
460     fFMD3Sum.Draw();
461     fLine.Draw();
462     fTotal.Draw();
463   }
464   fEvent.SetTitle(Form("Event # %6d", event));
465
466   fCanvas->Modified();
467   fCanvas->Update();
468   fCanvas->cd();
469   fFMD1.Clear();
470   fFMD2.Clear();
471   fFMD3.Clear();
472   
473 #if 0
474   TString triggers = fESDEvent->GetFiredTriggerClasses();
475   const AliESDVertex* vertex = fESDEvent->GetPrimaryVertexSPD();
476   Double_t vertexXYZ[3];
477   vertex->GetXYZ(vertexXYZ);
478   const AliMultiplicity* mult = fESDEvent->GetMultiplicity();
479   Int_t nTrackLets = mult->GetNumberOfTracklets();
480   std::cout<<triggers.Data()<<"  "<<fPhysicsSelection->IsCollisionCandidate(fESDEvent)<<"    "<<nTrackLets<<"   "<<vertexXYZ[0]<<"   "<<vertexXYZ[1]<<"   "<<vertexXYZ[2]<<std::endl;
481 #endif   
482   
483   return AliFMDInput::Begin(event);
484 }
485
486 //____________________________________________________________________
487 void
488 AliFMDPattern::Redisplay()
489 {
490   // Redraw the displayu 
491   fFMD1.Clear();
492   fFMD2.Clear();
493   fFMD3.Clear();
494   AliFMDDisplay::Redisplay();
495 }
496
497 //____________________________________________________________________
498 void
499 AliFMDPattern::AtEnd()
500 {
501   // Called at the end of an event. 
502   DrawAux();
503   
504   Int_t total = 0;
505   
506   fFMD1.End();
507   fFMD1Pad->Modified();
508   fFMD1Sum.SetTitle(Form("# hits in FMD1: %5d   (%4.2f /cm^{2})", 
509                          fFMD1.Total(), fFMD1.Total()/fFMD1Area));
510   total += fFMD1.Total();
511
512   fFMD2.End();
513   fFMD2Pad->Modified();
514   fFMD2Sum.SetTitle(Form("# hits in FMD2: %5d   (%4.2f /cm^{2})", 
515                          fFMD2.Total(), fFMD2.Total()/fFMD2Area));
516   total += fFMD2.Total();
517
518   fFMD3.End();
519   fFMD3Pad->Modified();
520   fFMD3Sum.SetTitle(Form("# hits in FMD3: %5d   (%4.2f /cm^{2})", 
521                          fFMD3.Total(), fFMD3.Total()/fFMD3Area));
522   total += fFMD3.Total();
523
524   fTotal.SetTitle(Form("Total:    %5d/51200 (%3d%%)", 
525                       total, Int_t(100. / 51200 * total)));
526   fSummary->Modified();
527   fCanvas->Modified();
528   fCanvas->Update();
529   fCanvas->cd();
530 }
531
532 //____________________________________________________________________
533 Bool_t 
534 AliFMDPattern::ProcessHit(AliFMDHit* hit, TParticle*) 
535 {
536   // Process a hit. 
537   // 
538   // Parameters 
539   // 
540   //    HIT             The hit to process. 
541   // 
542   // The TParticle argument is never used. 
543   static const Float_t rMin  = fgkEdepRange.fLow;
544   static const Float_t rMax  = fgkEdepRange.fHigh;
545
546   if (!hit) { AliError("No hit");   return kFALSE; }
547   // if (!p)   { AliError("No track"); return kFALSE; }
548   Float_t  edep  = hit->Edep();
549
550   if (fHits)                        fHits->Add(hit);
551   if (fSpec)                        fSpec->Fill(edep);
552   if (InsideCut(edep, rMin, rMax) && fSpecCut) fSpecCut->Fill(edep);
553
554   switch (hit->Detector()) {
555   case 1: fFMD1.AddMarker(hit->X(), hit->Y(), hit->Edep(), rMax); break;
556   case 2: fFMD2.AddMarker(hit->X(), hit->Y(), hit->Edep(), rMax); break;
557   case 3: fFMD3.AddMarker(hit->X(), hit->Y(), hit->Edep(), rMax); break;
558   }
559   return kTRUE;
560 }
561
562
563 //____________________________________________________________________
564 void
565 AliFMDPattern::AddMarker(UShort_t det, Char_t rng, 
566                          UShort_t sec, UShort_t str,
567                          TObject*, Float_t s, Float_t /*min*/, Float_t max)
568 {
569   // Add a marker to the display
570   //
571   //    det     Detector
572   //    rng     Ring
573   //    sec     Sector 
574   //    str     Strip
575   //    o       Object to refer to
576   //    s       Signal 
577   //    max     Maximum of signal 
578   //
579   AliFMDPatternDetector* d = 0;
580   switch (det) {
581   case 1: d = &fFMD1; break;
582   case 2: d = &fFMD2; break;
583   case 3: d = &fFMD3; break;
584   }
585   if (!d) return;
586   AliFMDGeometry*   geom = AliFMDGeometry::Instance();
587   Double_t x, y, z;
588   geom->Detector2XYZ(det, rng, sec, str, x, y, z);
589   // Make code-checker shut the f**k up 
590   TRandom* rand = gRandom;
591   if (false) {
592     AliFMDRing* r  = geom->GetRing(rng);
593     Double_t    t  = .9 * r->GetTheta() / 2;
594     Double_t    a  = rand->Uniform(-t,t) * TMath::Pi() / 180;
595     Double_t    x1 = x * TMath::Cos(a) - y * TMath::Sin(a);
596     Double_t    y1 = x * TMath::Sin(a) + y * TMath::Cos(a);
597     x = x1;
598     y = y1;
599   }
600   d->AddMarker(x, y, s, max);
601 }
602
603 //____________________________________________________________________
604 //
605 // EOF
606 //