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