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