Fixes for reading zero-suppressed data. These should be propagated to
[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 <AliLog.h>
54 #include "AliFMDDebug.h" // Better debug macros
55 class AliFMDDetector;
56
57 //____________________________________________________________________
58 ClassImp(AliFMDPattern)
59 #if 0
60   ; // This is here to keep Emacs for indenting the next line
61 #endif
62
63 //____________________________________________________________________
64 AliFMDPattern::AliFMDPatternDetector::AliFMDPatternDetector(UShort_t id) 
65   : fId(id),
66     fCounts(0), 
67     fGraphs(0), 
68     fFrame(0), 
69     fInners(id == 1 ? 10 : 0)
70 {
71   // CTOR 
72   // 
73   // Parameters: 
74   // 
75   //   ID       Identifier 
76 }
77
78 //____________________________________________________________________
79 AliFMDPattern::AliFMDPatternDetector::~AliFMDPatternDetector()
80 {
81   // DTOR 
82   // Destructor - 
83   // deletes mother frame 
84   if (fFrame) delete fFrame;
85 }
86
87 //____________________________________________________________________
88 void
89 AliFMDPattern::AliFMDPatternDetector::DrawShape(TObjArray& a) 
90 {
91   // Draw all shapes. 
92   // 
93   // Paramters 
94   // 
95   //    a       Array of shapes 
96   //
97   TIter next(&a);
98   TGraph* g = 0;
99   while ((g = static_cast<TGraph*>(next()))) {
100     g->DrawClone("f same");
101     g->DrawClone("l same");
102   }
103 }
104
105 //____________________________________________________________________
106 void
107 AliFMDPattern::AliFMDPatternDetector::CopyShapes(TObjArray& src, 
108                                                  TObjArray& dest, 
109                                                  Double_t ang, 
110                                                  Double_t fx, 
111                                                  Double_t fy)
112 {
113   TIter     next(&src);
114   TGraph*   g = 0;
115   while ((g = static_cast<TGraph*>(next()))) { 
116     TGraph* gg = new TGraph(*g);
117     Double_t* x  = gg->GetX();
118     Double_t* y  = gg->GetY();
119     for (Int_t i = 0; i < gg->GetN(); i++) { 
120       Float_t xx = x[i] * TMath::Cos(ang) - y[i] * TMath::Sin(ang);
121       Float_t yy = x[i] * TMath::Sin(ang) + y[i] * TMath::Cos(ang);
122       gg->SetPoint(i, fx * xx, fy * yy);
123     }
124     gg->SetFillStyle(g->GetFillStyle());
125     gg->SetFillColor(g->GetFillColor());
126     gg->SetLineStyle(g->GetLineStyle());
127     gg->SetLineColor(g->GetLineColor());
128     gg->SetLineWidth(g->GetLineWidth());
129     gg->SetMarkerStyle(g->GetMarkerStyle());
130     gg->SetMarkerColor(g->GetMarkerColor());
131     gg->SetMarkerSize(g->GetMarkerSize());
132     TString name(g->GetName());
133     name.ReplaceAll("X", Form("%d",fId));
134     gg->SetName(name.Data());
135     TString title(g->GetTitle());
136     title.ReplaceAll("X", Form("%d",fId));
137     gg->SetTitle(title.Data());
138     dest.Add(gg);
139   }
140   dest.SetOwner();
141 }
142
143 //____________________________________________________________________
144 void
145 AliFMDPattern::AliFMDPatternDetector::Begin(Int_t      nlevel, 
146                                             Double_t   r, 
147                                             TObjArray& inners, 
148                                             TObjArray& outers)
149 {
150   // Start of a run. 
151   // 
152   // Parameters 
153   // 
154   //    nlevel          Number of levels 
155   //    r               Radius 
156   //    inners          Array of inner shapes 
157   //    outers          Array of outer shapes 
158   //
159
160   // To make code-checker shut up
161   TStyle* style = gStyle;  
162   if (nlevel < 1) nlevel = style->GetNumberOfColors();
163   fCounts.Set(nlevel);
164   Double_t rr = 1.05 * r;
165   if (!fFrame) {
166     // The code-checker thinks this is not using the declaration of
167     // TH2F - what a morron!   
168     fFrame = new TH2F(Form("fmd%dFrame", fId), Form("FMD%d", fId), 
169                       100, -rr, rr, 100, -rr, rr);
170     fFrame->SetStats(kFALSE);
171     fFrame->Draw();
172   }
173   Double_t ang = (fId == 1 ? -TMath::Pi() / 2 : 0);
174   Double_t fx  = (fId == 3 ? -1               : 1); // Flip around Y
175   Double_t fy  = (fId == 1 ?  1               : 1); // Flip around X
176   
177   CopyShapes(inners, fInners, ang, fx, fy);
178   DrawShape(fInners);
179   if (fId != 1) { 
180     CopyShapes(outers, fOuters, ang, fx, fy);
181     DrawShape(fOuters);
182   }
183
184   for (Int_t i = 0; i < nlevel; i++) { 
185     TGraph* g = new TGraph;
186     Int_t idx = Int_t(Float_t(i) / nlevel * style->GetNumberOfColors());
187     Int_t col = style->GetColorPalette(idx);
188     g->SetName(Form("FMD%d_L%02d", fId, i));
189     g->SetMarkerColor(col);
190     g->SetLineColor(col);
191     g->SetFillColor(col);
192     g->SetMarkerSize(i * .2 + .2);
193     g->SetMarkerStyle(2);
194     g->SetEditable(kFALSE);
195     g->Draw("same p");
196     fGraphs.AddAtAndExpand(g, i);
197   }
198   // TIter   next(&fGraphs);
199 }
200
201 //____________________________________________________________________
202 void
203 AliFMDPattern::AliFMDPatternDetector::Clear() 
204 {
205   // Clear this display.  
206   // Simply reset counters to zero. 
207   // Avoid deleting memory. 
208   fCounts.Reset(0);
209 }
210
211 //____________________________________________________________________
212 void
213 AliFMDPattern::AliFMDPatternDetector::End()
214 {
215   // Called when displaying the data.  
216   // Simply resets number of points at each level to 
217   // the seen number of hits at that level. 
218   // Avoid deleting memory. 
219   TIter   next(&fGraphs);
220   TGraph* g = 0;
221   Int_t   i = 0;
222   while ((g = static_cast<TGraph*>(next()))) { 
223     Int_t cnt = fCounts[i++];
224     if (cnt > 0) { 
225       g->Set(cnt);
226       g->SetMarkerSize(i * .2 + .2);
227     }
228     else {
229       g->SetPoint(0,0,0);
230       g->SetMarkerSize(0);
231     }
232   }
233   
234 }
235 //____________________________________________________________________
236 void
237 AliFMDPattern::AliFMDPatternDetector::AddMarker(Double_t x, 
238                                                 Double_t y, 
239                                                 Float_t  s, 
240                                                 Float_t  max)
241 {
242   // Add a marker at (X,Y,Z).  The marker color and size is chosen
243   // relative to the MAX argument. 
244   // 
245   // Parameters 
246   // 
247   //    X,Y,Z           Coordiantes 
248   //    MAX             Maximum value. 
249   // 
250   /** Sigh, for some odd reason, the code-checker does not recognise
251       this a usage of the TMath namespace declaration! Idiot */
252   Int_t i = TMath::Min(Int_t(fCounts.fN * s / max),  
253                        Int_t(fGraphs.GetEntries()-1));
254   TGraph* g = static_cast<TGraph*>(fGraphs.At(i));
255   if (!g) return;
256   g->SetPoint(fCounts[i]++, x, y);
257 }
258
259
260 //____________________________________________________________________
261 AliFMDPattern::AliFMDPattern(const char* gAliceFile)
262   : AliFMDDisplay(kTRUE, gAliceFile),
263     fInners(0), 
264     fOuters(0),
265     fInnerMax(0), 
266     fOuterMax(0),
267     fFMD1Pad(0),
268     fFMD1(1),
269     fFMD2Pad(0),
270     fFMD2(2),
271     fFMD3Pad(0),
272     fFMD3(3),
273     fSummary(0),
274     fEvent(.1, .8, "Event #"),
275     fFMD1Sum(.2, .7, "# in FMD1: "),
276     fFMD2Sum(.2, .6, "# in FMD2: "),
277     fFMD3Sum(.2, .5, "# in FMD3: "),
278     fLine(.15, .47, .85, .47),
279     fTotal(.2, .35, "Total:   ")
280 {
281   // Constructor. 
282   // 
283   // Parameters 
284   // 
285   //   gAliceFile       The galice.root file to use - if any. 
286   // 
287
288   SetName("AliFMDPattern");
289   SetName("2D display of FMD data");
290   
291   // RemoveLoad(kGeometry);
292   fEvent.SetBit(TLatex::kTextNDC);
293   fFMD1Sum.SetBit(TLatex::kTextNDC);
294   fFMD2Sum.SetBit(TLatex::kTextNDC);
295   fFMD3Sum.SetBit(TLatex::kTextNDC);
296   fLine.SetBit(TLine::kLineNDC);
297   fTotal.SetBit(TLatex::kTextNDC);
298 }
299
300 //____________________________________________________________________
301 AliFMDPattern::~AliFMDPattern()
302 {
303   // DTOR 
304   // Free all allocated shapes. 
305   // note, that most members are real objects, so we do not need to
306   // deal with them here. 
307   fInners.Delete();
308   fOuters.Delete();
309 }
310
311     
312 //____________________________________________________________________
313 Bool_t 
314 AliFMDPattern::Init()
315 {
316   // Initialize.  Get transforms and such, 
317   if (!AliFMDInput::Init()) return kFALSE;
318   AliFMDGeometry* geom = AliFMDGeometry::Instance();
319   if (!geom) return kFALSE;
320   geom->Init();
321   geom->InitTransformations();
322   
323   Char_t rs[] = { 'I' , 'O', '\0' };
324   Char_t *r   = rs;
325   do {
326     AliFMDRing* ring = geom->GetRing(*r);
327     if (!ring) continue;
328     const TObjArray& vs = ring->GetVerticies();
329     TObjArray&       gs = (*r == 'I' ? fInners   : fOuters);
330     Float_t&         mr = (*r == 'I' ? fInnerMax : fOuterMax);
331     Int_t            nm = ring->GetNModules();
332     AliFMDDebug(1, ("Making %d modules for %c", nm, *r));
333     for (Int_t m = 0; m < nm; m++) {
334       Int_t          nv = vs.GetEntries();
335       Double_t       a  = TMath::Pi() / 180 * (m * 2 + 1) * ring->GetTheta();
336       TGraph*        g  = new TGraph(nv+1);
337       Double_t       x0 = 0, y0 = 0;
338       gs.AddAtAndExpand(g, m);
339       for (Int_t c = 0; c < nv; c++) {
340         TVector2* v = static_cast<TVector2*>(vs.At(c));
341         mr          = TMath::Max(mr, Float_t(v->Mod()));
342         TVector2  w(v->Rotate(a));
343         if (c == 0) { x0 = w.X(); y0 = w.Y(); }
344         g->SetPoint(c, w.X(), w.Y());
345       }
346       g->SetName(Form("FMDX%c_%02d%02d", *r, 2*m,2*m+1));
347       g->SetTitle(Form("FMDX%c, sectors %d and %d", *r, 2*m,2*m+1));
348       g->SetPoint(nv, x0, y0);
349       g->SetFillColor((*rs == 'I' ? 
350                        (m % 2 == 0 ? 18 : 17) :
351                        (m % 2 == 0 ? 20 : 23)));
352       g->SetFillStyle(3001);
353       g->SetLineColor(1);
354       g->SetLineWidth(1);
355       g->SetLineStyle(2);
356     }
357   } while (*(++r));
358     
359   return kTRUE;
360 }
361
362 //____________________________________________________________________
363 Bool_t 
364 AliFMDPattern::Begin(Int_t event) 
365 {
366   // Called at the begining of an event. 
367   // 
368   // Parameters 
369   //
370   //    EVENT           The event number 
371   // 
372   MakeAux();
373   if (!fCanvas) {
374     const char* which[] = { "Continue", "Start", "Pause", "Redisplay", 0 };
375     MakeCanvas(which);
376     
377     AliFMDGeometry* geom = AliFMDGeometry::Instance();
378     // AliFMDDetector* det;
379     if ((/* det = */ geom->GetDetector(1))) {
380       fPad->cd();
381       fFMD1Pad = new TPad("FMD1", "FMD1", 0.0, 0.50, 0.5, 1.0, 0, 0);
382       fFMD1Pad->Draw();
383       fFMD1Pad->cd();
384       fFMD1.Begin(-1, fInnerMax, fInners, fOuters);
385     }
386     if ((/* det = */ geom->GetDetector(2))) {
387       fPad->cd();
388       fFMD2Pad = new TPad("FMD2", "FMD2", 0.5, 0.50, 1.0, 1.0, 0, 0);
389       fFMD2Pad->Draw();
390       fFMD2Pad->cd();
391       fFMD2.Begin(-1, fOuterMax, fInners, fOuters);
392     }
393     if ((/* det = */ geom->GetDetector(3))) {
394       fPad->cd();
395       fFMD3Pad = new TPad("FMD3", "FMD3", 0.0, 0.0, .5, .5, 0, 0);
396       fFMD3Pad->Draw();
397       fFMD3Pad->cd();
398       fFMD3.Begin(-1, fOuterMax, fInners, fOuters);
399     }
400     fPad->cd();
401     fSummary = new TPad("display", "Display", 0.5, 0.0, 1.0, 0.5, 0, 0);
402     fSummary->Draw();
403     fSummary->cd();
404     fEvent.Draw();
405     fFMD1Sum.Draw();
406     fFMD2Sum.Draw();
407     fFMD3Sum.Draw();
408     fLine.Draw();
409     fTotal.Draw();
410   }
411   fEvent.SetTitle(Form("Event # %6d", event));
412
413   fCanvas->Modified();
414   fCanvas->Update();
415   fCanvas->cd();
416   fFMD1.Clear();
417   fFMD2.Clear();
418   fFMD3.Clear();
419   return AliFMDInput::Begin(event);
420 }
421
422 //____________________________________________________________________
423 void
424 AliFMDPattern::Redisplay()
425 {
426   // Redraw the displayu 
427   fFMD1.Clear();
428   fFMD2.Clear();
429   fFMD3.Clear();
430   AliFMDDisplay::Redisplay();
431 }
432
433 //____________________________________________________________________
434 void
435 AliFMDPattern::AtEnd()
436 {
437   // Called at the end of an event. 
438   DrawAux();
439   
440   Int_t total = 0;
441   
442   fFMD1.End();
443   fFMD1Pad->Modified();
444   fFMD1Sum.SetTitle(Form("# hits in FMD1: %5d", fFMD1.Total()));
445   total += fFMD1.Total();
446
447   fFMD2.End();
448   fFMD2Pad->Modified();
449   fFMD2Sum.SetTitle(Form("# hits in FMD2: %5d", fFMD2.Total()));
450   total += fFMD2.Total();
451
452   fFMD3.End();
453   fFMD3Pad->Modified();
454   fFMD3Sum.SetTitle(Form("# hits in FMD3: %5d", fFMD3.Total()));
455   total += fFMD3.Total();
456
457   fTotal.SetTitle(Form("Total:    %5d/51200 (%3d%%)", 
458                       total, Int_t(100. / 51200 * total)));
459   fSummary->Modified();
460   fCanvas->Modified();
461   fCanvas->Update();
462   fCanvas->cd();
463 }
464
465 //____________________________________________________________________
466 Bool_t 
467 AliFMDPattern::ProcessHit(AliFMDHit* hit, TParticle*) 
468 {
469   // Process a hit. 
470   // 
471   // Parameters 
472   // 
473   //    HIT             The hit to process. 
474   // 
475   // The TParticle argument is never used. 
476   static const Float_t rMin  = fgkEdepRange.fLow;
477   static const Float_t rMax  = fgkEdepRange.fHigh;
478
479   if (!hit) { AliError("No hit");   return kFALSE; }
480   // if (!p)   { AliError("No track"); return kFALSE; }
481   Float_t  edep  = hit->Edep();
482
483   if (fHits)                        fHits->Add(hit);
484   if (fSpec)                        fSpec->Fill(edep);
485   if (InsideCut(edep, rMin, rMax) && fSpecCut) fSpecCut->Fill(edep);
486
487   switch (hit->Detector()) {
488   case 1: fFMD1.AddMarker(hit->X(), hit->Y(), hit->Edep(), rMax); break;
489   case 2: fFMD2.AddMarker(hit->X(), hit->Y(), hit->Edep(), rMax); break;
490   case 3: fFMD3.AddMarker(hit->X(), hit->Y(), hit->Edep(), rMax); break;
491   }
492   return kTRUE;
493 }
494
495
496 //____________________________________________________________________
497 void
498 AliFMDPattern::AddMarker(UShort_t det, Char_t rng, 
499                          UShort_t sec, UShort_t str,
500                          TObject*, Float_t s, Float_t /*min*/, Float_t max)
501 {
502   // Add a marker to the display
503   //
504   //    det     Detector
505   //    rng     Ring
506   //    sec     Sector 
507   //    str     Strip
508   //    o       Object to refer to
509   //    s       Signal 
510   //    max     Maximum of signal 
511   //
512   AliFMDPatternDetector* d = 0;
513   switch (det) {
514   case 1: d = &fFMD1; break;
515   case 2: d = &fFMD2; break;
516   case 3: d = &fFMD3; break;
517   }
518   if (!d) return;
519   AliFMDGeometry*   geom = AliFMDGeometry::Instance();
520   Double_t x, y, z;
521   geom->Detector2XYZ(det, rng, sec, str, x, y, z);
522   // Make code-checker shut the f**k up 
523   TRandom* rand = gRandom;
524   if (false) {
525     AliFMDRing* r  = geom->GetRing(rng);
526     Double_t    t  = .9 * r->GetTheta() / 2;
527     Double_t    a  = rand->Uniform(-t,t) * TMath::Pi() / 180;
528     Double_t    x1 = x * TMath::Cos(a) - y * TMath::Sin(a);
529     Double_t    y1 = x * TMath::Sin(a) + y * TMath::Cos(a);
530     x = x1;
531     y = y1;
532   }
533   d->AddMarker(x, y, s, max);
534 }
535
536 //____________________________________________________________________
537 //
538 // EOF
539 //