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