Fancy on-line monitor
[u/mrichter/AliRoot.git] / FMD / AliFMDDisplay.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    AliFMDDisplay.cxx
17     @author  Christian Holm Christensen <cholm@nbi.dk>
18     @date    Mon Mar 27 12:39:09 2006
19     @brief   FMD 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 <TSystem.h>
33 #include <TApplication.h>
34 #include <TButton.h>
35 #include <TCanvas.h>
36 #include <TGeoManager.h>
37 #include <TH1D.h>
38 #include <TMarker3DBox.h>
39 #include <TMath.h>
40 #include <TSlider.h>
41 #include <TSliderBox.h>
42 #include <TStyle.h>
43 #include <TView.h>
44 #include <TVirtualX.h>
45 #include <TVirtualViewer3D.h>
46 #include <TList.h>
47 // #include <TArrayF.h>
48 // #include <TParticle.h>
49
50 #include "AliFMDDisplay.h"      // ALIFMDDISPLAY_H
51 #include "AliFMDHit.h"          // ALIFMDHIT_H
52 #include "AliFMDDigit.h"        // ALIFMDDIGIT_H
53 #include "AliFMDSDigit.h"       // ALIFMDSDIGIT_H
54 #include "AliFMDRecPoint.h"     // ALIFMDRECPOINT_H
55 #include "AliFMDGeometry.h"     // ALIFMDGEOMETRY_H
56 #include "AliFMDParameters.h"   // ALIFMDPARAMETERS_H
57 #include <AliESDFMD.h>          // ALIESDFMD_H
58 // #include <AliLog.h>
59 #include "AliFMDDebug.h" // Better debug macros
60
61 //____________________________________________________________________
62 ClassImp(AliFMDDisplay)
63 #if 0
64   ; // This is here to keep Emacs for indenting the next line
65 #endif
66
67 //____________________________________________________________________
68 AliFMDDisplay* AliFMDDisplay::fgInstance = 0;
69
70 //____________________________________________________________________
71 const AliFMDDisplay::Range_t AliFMDDisplay::fgkEdepRange = {  100, 0.,    2. };
72 const AliFMDDisplay::Range_t AliFMDDisplay::fgkAdcRange  = { 1024, 0., 1023. };
73 const AliFMDDisplay::Range_t AliFMDDisplay::fgkMultRange = {  500, 0.,   20. };
74
75   
76 //____________________________________________________________________
77 AliFMDDisplay* 
78 AliFMDDisplay::Instance()
79 {
80   // Return static instance 
81   // If the instance does not exist
82   // it is not created!
83   return fgInstance;
84 }
85
86 //____________________________________________________________________
87 AliFMDDisplay::~AliFMDDisplay()
88 {
89   // Destructor. 
90   // Cleans 
91   // up 
92   if (fMarkers) {
93     fMarkers->Delete();
94     delete fMarkers;
95   }
96   if (fHits) {
97     fHits->Clear();
98     delete fHits;
99   }
100   if (fPad)     delete fPad;
101   fButtons.Delete();
102   if (fSlider)  delete fSlider;
103   if (fCanvas)  delete fCanvas;
104 }
105   
106 //____________________________________________________________________
107 AliFMDDisplay::AliFMDDisplay(Bool_t onlyFMD, const char* gAliceFile)
108   : AliFMDInput(gAliceFile),
109     fWait(kFALSE),
110     fMarkers(0),
111     fHits(0),
112     fCanvas(0), 
113     fPad(0), 
114     fButtons(0),
115     fSlider(0),
116     fFactor(0),
117     fZoomMode(kFALSE),
118     fX0(0),
119     fY0(0),
120     fX1(0),
121     fY1(0),
122     fXPixel(0),
123     fYPixel(0),
124     fOldXPixel(0),
125     fOldYPixel(0),
126     fLineDrawn(0),
127     fOnlyFMD(onlyFMD),
128     fSpec(0), 
129     fSpecCut(0),
130     fAux(0), 
131     fReturn(kFALSE), 
132     fContinous(kFALSE),
133     fTimeout("gApplication->StopIdleing()", 10)
134 {
135   // Constructor of an FMD display object. 
136   // Must be called 
137   // before Instance 
138   SetName("AliFMDDisplay");
139   SetTitle("3D Display of various kinds of FMD data");
140   AddLoad(kGeometry);
141   if (fgInstance) delete fgInstance;
142   fgInstance = this;
143 }
144
145 //____________________________________________________________________
146 void           
147 AliFMDDisplay::MakeCanvas(const char** which)
148 {
149   // Make a canvas 
150   // Parameters: 
151   //   which   Which button to put up. 
152   gStyle->SetPalette(1);
153   // gStyle->SetCanvasPreferGL(kTRUE);
154   Double_t y1 = .10;
155   Int_t    w  = 700;
156   fCanvas = new TCanvas(Form("gl%s", GetName()), 
157                         Form("%s - Display", GetTitle()), 
158                         w, Int_t(w / (1-y1)));
159   fCanvas->SetFillColor(1);
160   fCanvas->ToggleEventStatus();
161   fCanvas->cd();
162   fPad = new TPad("glview", "3DView", 0.0, y1, 1.0, 1.0, 1, 0, 0);
163   fPad->Draw();
164   
165   const char** p = which;
166   const char*  m;
167   Int_t        n  = 0;
168   Int_t        j  = 0;
169   while (*(p++)) n++;
170   AliFMDDebug(1, ("Got %d buttons", n));
171   if (n <= 0) return;
172
173   Double_t yb = 0;
174   Double_t xb = 1;
175   fCanvas->cd();
176   if (TESTBIT(fTreeMask, kDigits) || 
177       TESTBIT(fTreeMask, kRaw)) { 
178     yb = .05;
179     xb = .66;
180     fFactor = new TSlider("pedFactor", "Pedestal Factor", xb+.01, 0, 1, yb);
181     fFactor->SetMethod("AliFMDDisplay::Instance()->ChangeFactor()");
182     fFactor->SetRange(3./10, 1);
183     fFactor->Draw();
184     TSliderBox *sbox = 
185       static_cast<TSliderBox*>(fFactor->GetListOfPrimitives()->
186                                FindObject("TSliderBox"));
187     if (sbox) { 
188       sbox->SetToolTipText("Adjust the noise suppression factor by moving "
189                            "lower limit");
190     }
191   }
192   if (TESTBIT(fTreeMask, kHits)    || 
193       TESTBIT(fTreeMask, kESD)     || 
194       TESTBIT(fTreeMask, kDigits)  || 
195       TESTBIT(fTreeMask, kSDigits) || 
196       TESTBIT(fTreeMask, kRaw)) {
197     yb = .05;
198     fSlider = new TSlider("genCut", "Multiplicity cut", 0, 0, xb, yb);
199     fSlider->SetMethod("AliFMDDisplay::Instance()->ChangeCut()");
200     fSlider->SetRange(0,1);
201     fSlider->Draw();
202     TSliderBox *sbox = 
203       static_cast<TSliderBox*>(fSlider->GetListOfPrimitives()->
204                                FindObject("TSliderBox"));
205     if (sbox) { 
206       sbox->SetToolTipText("Adjust lower and upper limit on data signal");
207     }
208   }
209   Float_t      x0 = 0;
210   Float_t      dx = 1. / n;
211   p               = which;
212   while ((m = *(p++))) {
213     fCanvas->cd();
214     AliFMDDebug(1, ("Adding button %s", m));
215     TButton* b = new TButton(m, Form("AliFMDDisplay::Instance()->%s()", m),
216                              x0, yb, TMath::Min(x0 + dx,.999F), y1);
217     b->Draw();
218     fButtons.Add(b);
219     x0 += dx;
220     j++;
221   }
222 }
223
224 //____________________________________________________________________
225 void           
226 AliFMDDisplay::ShowOnlyFMD()
227 {
228   // Show only the FMD 
229   // Do not show 
230   // other volumes 
231   if (!fGeoManager) return;
232   static bool once = false;
233   if (once) return;
234   once = true;
235   AliInfo("Will only show the FMD");
236   TGeoVolume* top = gGeoManager->GetTopVolume();
237   top->InvisibleAll(kTRUE);
238   TGeoIterator next(top);
239   TGeoNode* node;
240   TGeoVolume* v = 0;
241   Bool_t hasFMD1 = kFALSE;
242   Bool_t hasFMD2 = kFALSE;
243   Bool_t hasFMD3 = kFALSE;
244   AliFMDDebug(1, ("Getting material FMD_Si$"));
245   TGeoMaterial* si   = gGeoManager->GetMaterial("FMD_Si$");      // kRed 
246   AliFMDDebug(1, ("Getting material FMD_Carbon$"));
247   TGeoMaterial* c    = gGeoManager->GetMaterial("FMD_Carbon$");  // kGray
248   AliFMDDebug(1, ("Getting material FMD_Aluminum$"));
249   TGeoMaterial* al   = gGeoManager->GetMaterial("FMD_Aluminum$");// kGray-2
250   AliFMDDebug(1, ("Getting material FMD_Copper$"));
251   TGeoMaterial* cu   = gGeoManager->GetMaterial("FMD_Copper$"); // kGreen-2
252   AliFMDDebug(1, ("Getting material FMD_PCB$"));
253   TGeoMaterial* pcb  = gGeoManager->GetMaterial("FMD_PCB$");    // kGreen+2
254   AliFMDDebug(1, ("Getting material FMD_PCB$"));
255   TGeoMaterial* chip = gGeoManager->GetMaterial("FMD_Si Chip$");// kGreen+2
256   TObjArray     toshow;
257   while ((node = static_cast<TGeoNode*>(next()))) {
258     const char* name = node->GetName();
259     if (!name) continue;
260     if (!(v = node->GetVolume())) continue;
261
262     if (name[0] == 'F') {
263       TGeoMaterial* m   = (v->IsAssembly() ? 0 : v->GetMaterial());
264       Int_t         col = -1;
265       if      (m == si)   col = kRed;
266       else if (m == c)    col = kGray;
267       else if (m == al)   col = kYellow+4;  
268       else if (m == cu)   col = kRed+6;   
269       else if (m == pcb)  col = kGreen+2; 
270       else if (m == chip) col = kGreen+4; 
271       if (col >= 0) { 
272         v->SetLineColor(col);
273         v->SetFillColor(col);
274       }
275       if (name[2] == 'M' && (name[3] == 'T' || name[3] == 'B')) {
276         // Virtual Master half-ring volume - top-level
277         Int_t det = node->GetNumber();
278         switch (det) {
279         case 1: hasFMD1 = true; break;
280         case 2: hasFMD2 = true; break;
281         case 3: hasFMD3 = true; break;
282         default: continue;
283         }
284         toshow.Add(v);
285       }
286       else if (name[3] == 'V' && (name[2] == 'T' || name[2] == 'B')) 
287         toshow.Add(v); // Virtual Half-ring, bare detectors
288       else if (name[3] == 'H' && (name[2] == 'F' || name[2] == 'B')) 
289         toshow.Add(v); // Virtual Hybrid container 
290       else if (name[2] == 'S' && name[3] == 'U') 
291         toshow.Add(v); // Virtual support structre 
292       // else if (name[3] == 'H' && (name[2] == 'F' || name[2] == 'B')) 
293       //  toshow.Add(v); // Virtual Hybrid container 
294     }
295     v->SetVisibility(kFALSE);
296     v->SetVisDaughters(kFALSE);
297     v->InvisibleAll(kTRUE);
298   }
299   TIter i(&toshow);
300   while ((v = static_cast<TGeoVolume*>(i()))) {
301     if (!v->IsAssembly())
302       v->SetVisibility(kTRUE);
303     v->InvisibleAll(kFALSE);
304     v->SetVisDaughters(kTRUE);
305     
306   }  
307 }
308
309     
310 //____________________________________________________________________
311 void           
312 AliFMDDisplay::ExecuteEvent(Int_t event, Int_t px, Int_t py) 
313 {
314   // Execute an event on canvas 
315   // Parameters: 
316   //   event   What happened
317   //   px, py  Pixel coordinates 
318   if (px == 0 && py == 0) return;
319   if (!fZoomMode && fPad->GetView()) {
320     fPad->GetView()->ExecuteRotateView(event, px, py);
321     return;
322   }
323   fPad->SetCursor(kCross);
324   switch (event) {
325   case kButton1Down: 
326     fPad->TAttLine::Modify();
327     fX0        = fPad->AbsPixeltoX(px);
328     fY0        = fPad->AbsPixeltoY(py);
329     fXPixel    = fOldXPixel = px;
330     fYPixel    = fOldYPixel = py;
331     fLineDrawn = kFALSE;
332     return;
333   case kButton1Motion:
334     if (fLineDrawn) 
335       gVirtualX->DrawBox(fXPixel, fYPixel, fOldXPixel, fOldYPixel, 
336                          TVirtualX::kHollow);
337     fOldXPixel = px;
338     fOldYPixel = py;
339     fLineDrawn = kTRUE;
340     gVirtualX->DrawBox(fXPixel, fYPixel, fOldXPixel, fOldYPixel, 
341                        TVirtualX::kHollow);
342     return;
343   case kButton1Up:
344     fPad->GetCanvas()->FeedbackMode(kFALSE);
345     if (px == fXPixel || py == fYPixel) return;
346     fX1 = fPad->AbsPixeltoX(px);
347     fY1 = fPad->AbsPixeltoY(py);
348     if (fX1 < fX0) std::swap(fX0, fX1); 
349     if (fY1 < fY0) std::swap(fY0, fY1); 
350     fPad->Range(fX0, fY0, fX1, fY1);
351     fPad->Modified();
352     return;
353   }
354 }
355
356 //____________________________________________________________________
357 Int_t          
358 AliFMDDisplay::DistancetoPrimitive(Int_t px, Int_t) 
359 {
360   // Calculate the distance from point to 
361   // something in the canvas. 
362   // Depends on the zoom mode. 
363   fPad->SetCursor(kCross);
364   Float_t xmin = fPad->GetX1();
365   Float_t xmax = fPad->GetX2();
366   Float_t dx   = .02 * (xmax - xmin);
367   Float_t x    = fPad->AbsPixeltoX(px);
368   if (x < xmin + dx || x > xmax - dx) return 9999;
369   return (fZoomMode ? 0 : 7);
370 }
371 //____________________________________________________________________
372 Bool_t 
373 AliFMDDisplay::Init()
374 {
375   // Initialize.  GEt transforms and such,
376   // so that we can draw thins properly 
377   // Returns true on success 
378   if (!AliFMDInput::Init()) return kFALSE;
379   AliFMDGeometry* geom = AliFMDGeometry::Instance();
380   geom->Init();
381   geom->InitTransformations();
382   if (TESTBIT(fTreeMask, kDigits) || TESTBIT(fTreeMask, kRaw)) 
383     AliFMDParameters::Instance()->Init();
384
385   fMarkers = new TObjArray;
386   fHits    = new TObjArray;
387   fMarkers->SetOwner(kTRUE);
388   fHits->SetOwner(kFALSE);
389   return kTRUE;
390 }
391
392 //____________________________________________________________________
393 void
394 AliFMDDisplay::MakeAux()
395 {
396   // MAke the aux canvas 
397   // This is used to display spectra
398   // etc, 
399   const Range_t* range = 0;
400   if      (TESTBIT(fTreeMask, kESD))      range = &fgkMultRange;
401   else if (TESTBIT(fTreeMask, kDigits))   range = &fgkAdcRange;
402   else if (TESTBIT(fTreeMask, kSDigits))  range = &fgkAdcRange;
403   else if (TESTBIT(fTreeMask, kRaw))      range = &fgkAdcRange;
404   else if (TESTBIT(fTreeMask, kHits))     range = &fgkEdepRange;
405   if (!range) return;
406   
407   if (!fAux) {
408     fAux = new TCanvas("aux", "Aux");
409     fAux->SetLogy();
410     Float_t dBin = (range->fHigh - range->fLow) / range->fNbins;
411     fSpec = new TH1D("spec", "Spectra", range->fNbins, 
412                      range->fLow-dBin/2, range->fHigh-dBin/2);
413     fSpecCut = static_cast<TH1*>(fSpec->Clone("specCut"));
414     fSpec->SetFillColor(2);
415     fSpec->SetFillStyle(3001);
416     fSpecCut->SetFillColor(4);
417     fSpecCut->SetFillStyle(3001);
418   }
419   else {
420     fSpec->Reset();
421     fSpecCut->Reset();
422   }  
423 }
424
425 //____________________________________________________________________
426 void
427 AliFMDDisplay::DrawAux()
428 {
429   // Draw in the Aux the canvas 
430   // For example draw the spectra 
431   // or such stuff 
432   if (!fAux) return;
433   fAux->cd();
434   fAux->Clear();
435   fSpec->Draw();
436   fSpecCut->Draw("same");
437   fAux->Modified();
438   fAux->Update();
439   fAux->cd();
440 }
441
442 //____________________________________________________________________
443 Bool_t 
444 AliFMDDisplay::Begin(Int_t event) 
445 {
446   // Begin of event.  Make canvas is not already done 
447   // Parameters: 
448   //   event   The event number 
449   if (!fCanvas) {
450     const char* m[] = { "Continue", 
451                         "Break", 
452                         "Zoom", 
453                         "Pick", 
454                         "Redisplay", 
455                         "Render", 
456                         0 }; 
457     MakeCanvas(m);
458   }
459   MakeAux();
460   fReturn = kFALSE;
461   
462   // AliInfo("Clearing canvas");
463   // fCanvas->Clear();
464   if (!fGeoManager) {
465     Warning("End", "No geometry manager");
466     return kFALSE;
467   }
468   AliFMDDebug(1, ("Drawing geometry"));
469   fPad->cd();
470   fGeoManager->GetTopVolume()->Draw();
471   if (fOnlyFMD) ShowOnlyFMD();
472   AliFMDDebug(1, ("Adjusting view"));
473   Int_t irep;
474   if (fPad->GetView()) {
475     fPad->GetView()->SetView(-200, -40, 80, irep);
476     fPad->GetView()->Zoom();
477     fPad->Modified();
478     fPad->cd();
479   }
480   return AliFMDInput::Begin(event);
481 }
482
483 //____________________________________________________________________
484 void
485 AliFMDDisplay::AtEnd() 
486 {
487   // Called at of the event. 
488   // Draw stuff. 
489   // Draw spectrum. 
490   fPad->cd();
491   fMarkers->Draw();
492   fPad->cd();
493   AppendPad();
494   fPad->cd();
495   DrawAux();
496 }
497
498 //____________________________________________________________________
499 void
500 AliFMDDisplay::Idle() 
501 {
502   // Idle loop. 
503   // Sends the ROOT loop into the idle loop,
504   // so that we can go on. 
505   fWait = kTRUE;
506   if (fContinous) fTimeout.Start(10, kTRUE);
507   while (fWait) {
508     gApplication->StartIdleing();
509     gSystem->InnerLoop();
510     gApplication->StopIdleing();
511     if (fContinous) break;
512   }
513   AliFMDDebug(1, ("After idle loop"));
514   if (fMarkers) fMarkers->Delete();
515   if (fHits)    fHits->Clear();
516   AliFMDDebug(1, ("After clearing caches"));
517 }
518
519 //____________________________________________________________________
520 Bool_t 
521 AliFMDDisplay::End()
522 {
523   // End of event.  Draw everything 
524   AtEnd();
525   Idle();
526   if (fReturn) return kFALSE;
527   return AliFMDInput::End();
528 }
529
530 //____________________________________________________________________
531 Int_t
532 AliFMDDisplay::LookupColor(Float_t x, Float_t min, Float_t max) const
533 {
534   // Look-up color.  
535   // Get a colour from the  current palette depending 
536   // on the ratio x/max 
537   Float_t range  = (max-min);
538   Float_t l      = fSlider->GetMinimum();
539   Float_t h      = fSlider->GetMaximum();
540   if (l == h) { l = 0; h = 1; }
541   Float_t cmin   = range * l;
542   Float_t cmax   = range * h;
543   Float_t crange = (cmax-cmin);
544   Int_t   idx    = Int_t((x-cmin) / crange * gStyle->GetNumberOfColors());
545   return gStyle->GetColorPalette(idx);
546
547
548 //____________________________________________________________________
549 void
550 AliFMDDisplay::SetCut(Float_t l, Float_t h) 
551 {
552   // Change the cut on the slider. 
553   fSlider->SetMinimum(l);
554   fSlider->SetMaximum(h);
555   ChangeCut();
556 }
557
558 //____________________________________________________________________
559 void
560 AliFMDDisplay::ChangeCut() 
561 {
562   // Change the cut on the slider. 
563   // The factor depends on what is 
564   // drawn in the AUX canvas
565   AliInfo(Form("Range is now %7.5f - %7.5f", fSlider->GetMinimum(), 
566                fSlider->GetMaximum()));
567   if ((TESTBIT(fTreeMask, kESD) || 
568        TESTBIT(fTreeMask, kDigits) || 
569        TESTBIT(fTreeMask, kSDigits) || 
570        TESTBIT(fTreeMask, kRaw))) {
571     Float_t l = fSlider->GetMinimum();
572     Float_t h = fSlider->GetMaximum();
573     l         = 1024 * l + 0;
574     h         = 1024 * h + 0;
575     AliInfo(Form("ADC range is now %4d - %4d", int(l), int(h)));
576   }
577   Redisplay();
578 }
579 //____________________________________________________________________
580 void
581 AliFMDDisplay::ChangeFactor() 
582 {
583   // Change the cut on the slider. 
584   // The factor depends on what is 
585   // drawn in the AUX canvas
586   AliInfo(Form("Noise factor is now %4.1f, pedestal factor %3.1f", 
587                10*fFactor->GetMinimum(),fFactor->GetMaximum()));
588   Redisplay();
589 }
590
591 //____________________________________________________________________
592 void
593 AliFMDDisplay::Redisplay()
594 {
595   // Redisplay stuff. 
596   // Redraw markers, hits, 
597   // spectra 
598   if (fMarkers) fMarkers->Delete();
599   if (fHits)    fHits->Clear();
600   if (fSpec)    fSpec->Reset();
601   if (fSpecCut) fSpecCut->Reset();
602   Event();
603   AtEnd();
604 }
605 //____________________________________________________________________
606 void
607 AliFMDDisplay::Break()
608 {
609   // Redisplay stuff. 
610   // Redraw markers, hits, 
611   // spectra 
612   if (fMarkers) fMarkers->Delete();
613   if (fHits)    fHits->Clear();
614   if (fSpec)    fSpec->Reset();
615   if (fSpecCut) fSpecCut->Reset();
616   fReturn = kTRUE;
617   fWait   = kFALSE;
618 }
619 //____________________________________________________________________
620 void
621 AliFMDDisplay::Render()
622 {
623   fPad->cd();
624   TVirtualViewer3D* viewer = fPad->GetViewer3D("ogl");
625   if (!viewer) return;
626 }
627
628 //____________________________________________________________________
629 void
630 AliFMDDisplay::AddMarker(Float_t x, Float_t y, Float_t z,
631                          TObject* o, Float_t s, Float_t min, Float_t max)
632 {
633   // Add a marker to the display
634   //
635   //    det     Detector
636   //    rng     Ring
637   //    sec     Sector 
638   //    str     Strip
639   //    o       Object to refer to
640   //    s       Signal 
641   //    max     Maximum of signal 
642   //
643   Float_t  size  = .1;
644   Float_t  zsize = (s - min) / (max-min) * 10;
645   Float_t  r     = TMath::Sqrt(x * x + y * y);
646   Float_t  theta = TMath::ATan2(r, z);
647   Float_t  phi   = TMath::ATan2(y, x);
648   Float_t  rz    = z + (z < 0 ? 1 : -1) * zsize;
649   TMarker3DBox* marker = new  TMarker3DBox(x,y,rz,size,size,zsize,theta,phi);
650   if (o) marker->SetRefObject(o);
651   marker->SetLineColor(LookupColor(s, min, max));
652   fMarkers->Add(marker);
653 }
654 //____________________________________________________________________
655 void
656 AliFMDDisplay::AddMarker(UShort_t det, Char_t rng, UShort_t sec, UShort_t str,
657                          TObject* o, Float_t s, Float_t min, Float_t max)
658 {
659   // Add a marker to the display
660   //
661   //    det     Detector
662   //    rng     Ring
663   //    sec     Sector 
664   //    str     Strip
665   //    o       Object to refer to
666   //    s       Signal 
667   //    max     Maximum of signal 
668   //
669   AliFMDGeometry*   geom = AliFMDGeometry::Instance();
670   Double_t x, y, z;
671   geom->Detector2XYZ(det, rng, sec, str, x, y, z);
672   AddMarker(x,y,z,o,s,min,max);
673 }
674   
675 //____________________________________________________________________
676 Bool_t 
677 AliFMDDisplay::InsideCut(Float_t val, const Float_t& min, 
678                          const Float_t& max) const
679 {
680   Float_t r = max - min;
681   Float_t l = fSlider->GetMinimum();
682   Float_t h = fSlider->GetMaximum();
683   if (l == h) { l = 0; h = 1; }
684   if (val < r * l + min || val > r * h + min) return kFALSE;
685   return kTRUE;
686 }
687
688
689 //____________________________________________________________________
690 Bool_t 
691 AliFMDDisplay::ProcessHit(AliFMDHit* hit, TParticle* /* p */) 
692 {
693   // Process a hit. 
694   // Parameters: 
695   //   hit   Hit data
696   static const Float_t rMin  = fgkEdepRange.fLow;
697   static const Float_t rMax  = fgkEdepRange.fHigh;
698
699   if (!hit) { AliError("No hit");   return kFALSE; }
700   // if (!p)   { AliError("No track"); return kFALSE; }
701   Float_t  edep  = hit->Edep();
702
703   if (fHits)                        fHits->Add(hit);
704   if (fSpec)                        fSpec->Fill(edep);
705   if (!InsideCut(edep, rMin, rMax)) return kTRUE;
706   if (fSpecCut)                     fSpecCut->Fill(edep);
707   
708   AddMarker(hit->X(), hit->Y(), hit->Z(), hit, edep, rMin, rMax);
709   return kTRUE;
710 }
711
712 //____________________________________________________________________
713 Bool_t 
714 AliFMDDisplay::ProcessDigit(AliFMDDigit* digit)
715 {
716   // Process a digit 
717   // Parameters: 
718   //   digit Digit information 
719   static const Float_t rMin  = fgkAdcRange.fLow;
720   static const Float_t rMax  = fgkAdcRange.fHigh;
721
722   if (!digit) { AliError("No digit");   return kFALSE; }
723
724   AliFMDParameters* parm = AliFMDParameters::Instance();
725   UShort_t det           =  digit->Detector();
726   Char_t   ring          =  digit->Ring();
727   UShort_t sec           =  digit->Sector();
728   UShort_t str           =  digit->Strip();
729   Double_t ped           =  parm->GetPedestal(det,ring, sec, str);
730   Double_t pedW          =  parm->GetPedestalWidth(det,ring, sec, str);
731   Double_t threshold     =  (ped * fFactor->GetMaximum()
732                              + pedW * fFactor->GetMinimum());
733   if (threshold > fgkAdcRange.fHigh) threshold = fgkAdcRange.fHigh;
734   Float_t  counts        =  digit->Counts();
735
736   AliFMDDebug(10, ("FMD%d%c[%02d,%03d] counts %4d threshold %4d", 
737                    det, ring, sec, str, Int_t(counts), Int_t(threshold)));
738   if (fHits)                                    fHits->Add(digit);
739   if (fSpec)                                    fSpec->Fill(counts);
740   if (!InsideCut(counts-threshold, rMin, rMax)) return kTRUE;
741   if (fSpecCut)                                 fSpecCut->Fill(counts);
742   
743
744   AddMarker(det, ring, sec, str, digit, counts, rMin, rMax);
745   return kTRUE;
746 }
747
748 //____________________________________________________________________
749 Bool_t 
750 AliFMDDisplay::ProcessSDigit(AliFMDSDigit* sdigit)
751 {
752   // Process a sdigit 
753   // Parameters: 
754   //   sdigit Digit information 
755   static const Float_t rMin  = fgkAdcRange.fLow;
756   static const Float_t rMax  = fgkAdcRange.fHigh;
757
758   if (!sdigit) { AliError("No sdigit");   return kFALSE; }
759   
760   UShort_t det           =  sdigit->Detector();
761   Char_t   ring          =  sdigit->Ring();
762   UShort_t sec           =  sdigit->Sector();
763   UShort_t str           =  sdigit->Strip();
764   Float_t  counts        =  sdigit->Counts();
765
766   if (fHits)                          fHits->Add(sdigit);
767   if (fSpec)                          fSpec->Fill(counts);
768   if (!InsideCut(counts, rMin, rMax)) return kTRUE;
769   if (fSpecCut)                       fSpecCut->Fill(counts);
770   
771   AddMarker(det, ring, sec, str, sdigit, counts, rMin, rMax);
772   return kTRUE;
773 }
774
775 //____________________________________________________________________
776 Bool_t 
777 AliFMDDisplay::ProcessRawDigit(AliFMDDigit* digit)
778 {
779   // PRocess raw data 
780   // Parameters: 
781   //   digit Digit information 
782   AliFMDDebug(50, ("Forwarding call of ProcessRaw to ProcessDigit "
783                   "for FMD%d&c[%02d,%03d] %d", 
784                   digit->Detector(), digit->Ring(), digit->Sector(), 
785                   digit->Strip(), digit->Counts()));
786   return ProcessDigit(digit);
787 }
788
789 //____________________________________________________________________
790 Bool_t 
791 AliFMDDisplay::ProcessRecPoint(AliFMDRecPoint* recpoint)
792 {
793   // Process reconstructed point 
794   // Parameters: 
795   //  recpoint  Reconstructed multiplicity/energy
796   static const Float_t rMin  = fgkMultRange.fLow;
797   static const Float_t rMax  = fgkMultRange.fHigh;
798
799
800   if (!recpoint) { AliError("No recpoint");   return kFALSE; }
801
802   if (!InsideCut(recpoint->Particles(), rMin, rMax)) return kTRUE;
803
804   if (fHits) fHits->Add(recpoint);
805   AddMarker(recpoint->Detector(), recpoint->Ring(), recpoint->Sector(),  
806             recpoint->Strip(), recpoint, recpoint->Particles(), rMin, rMax);
807   return kTRUE;
808 }
809
810 //____________________________________________________________________
811 Bool_t 
812 AliFMDDisplay::ProcessESD(UShort_t det, Char_t rng, UShort_t sec, UShort_t str,
813                           Float_t, Float_t mult)
814 {
815   // Process data from ESD 
816   // Parameters 
817   //   det,rng,sec,str   Detector coordinates. 
818   //   mult              Multiplicity. 
819   static const Float_t rMin  = fgkMultRange.fLow;
820   static const Float_t rMax  = fgkMultRange.fHigh;
821   
822   Double_t cmult = mult;
823   if (fSpec) fSpec->Fill(cmult);
824   if (!InsideCut(cmult, rMin, rMax) || cmult == AliESDFMD::kInvalidMult) 
825     return kTRUE;
826
827   AddMarker(det,rng,sec,str, 0, cmult, rMin, rMax);
828
829   if (fSpecCut) fSpecCut->Fill(cmult);
830
831   return kTRUE;
832 }
833
834 //____________________________________________________________________
835 //
836 // EOF
837 //