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