Check-in to fix a few problems:
[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 <TApplication.h>
33 #include <TButton.h>
34 #include <TCanvas.h>
35 #include <TGeoManager.h>
36 #include <TH1D.h>
37 #include <TMarker3DBox.h>
38 #include <TMath.h>
39 #include <TSlider.h>
40 #include <TStyle.h>
41 #include <TView.h>
42 #include <TVirtualX.h>
43 // #include <TArrayF.h>
44 // #include <TParticle.h>
45
46 #include "AliFMDDisplay.h"      // ALIFMDDISPLAY_H
47 #include "AliFMDHit.h"          // ALIFMDHIT_H
48 #include "AliFMDDigit.h"        // ALIFMDDIGIT_H
49 #include "AliFMDRecPoint.h"     // ALIFMDRECPOINT_H
50 #include "AliFMDGeometry.h"     // ALIFMDGEOMETRY_H
51 #include "AliFMDParameters.h"   // ALIFMDPARAMETERS_H
52 #include <AliESDFMD.h>          // ALIESDFMD_H
53 // #include <AliLog.h>
54 #include "AliFMDDebug.h" // Better debug macros
55
56 //____________________________________________________________________
57 ClassImp(AliFMDDisplay)
58 #if 0
59   ; // This is here to keep Emacs for indenting the next line
60 #endif
61
62 //____________________________________________________________________
63 AliFMDDisplay* AliFMDDisplay::fgInstance = 0;
64
65 //____________________________________________________________________
66 AliFMDDisplay* 
67 AliFMDDisplay::Instance()
68 {
69   // Return static instance 
70   return fgInstance;
71 }
72
73 //____________________________________________________________________
74 AliFMDDisplay::~AliFMDDisplay()
75 {
76   if (fMarkers) {
77     fMarkers->Delete();
78     delete fMarkers;
79   }
80   if (fHits) {
81     fHits->Clear();
82     delete fHits;
83   }
84   if (fPad)     delete fPad;
85   fButtons.Delete();
86   if (fSlider)  delete fSlider;
87   if (fCanvas)  delete fCanvas;
88 }
89   
90 //____________________________________________________________________
91 AliFMDDisplay::AliFMDDisplay(Bool_t onlyFMD, const char* gAliceFile)
92   : AliFMDInput(gAliceFile),
93     fWait(kFALSE),
94     fMarkers(0),
95     fHits(0),
96     fCanvas(0), 
97     fPad(0), 
98     fSlider(0),
99     fZoomMode(kFALSE),
100     fX0(0),
101     fY0(0),
102     fX1(0),
103     fY1(0),
104     fMultCut(0),
105     fPedestalFactor(0),
106     fXPixel(0),
107     fYPixel(0),
108     fOldXPixel(0),
109     fOldYPixel(0),
110     fLineDrawn(0),
111     fOnlyFMD(onlyFMD)
112 {
113   // Constructor of an FMD display object. 
114   AddLoad(kGeometry);
115   if (fgInstance) delete fgInstance;
116   fgInstance = this;
117   SetMultiplicityCut();
118   SetPedestalFactor();
119 }
120
121 //____________________________________________________________________
122 void           
123 AliFMDDisplay::MakeCanvas(const char** which)
124 {
125   gStyle->SetPalette(1);
126   Double_t y1 = .10;
127   Int_t    w  = 700;
128   fCanvas = new TCanvas("display", "Display", w, Int_t(w / (1-y1)));
129   fCanvas->SetFillColor(1);
130   fCanvas->ToggleEventStatus();
131   fCanvas->cd();
132   fPad = new TPad("view", "3DView", 0.0, y1, 1.0, 1.0, 1, 0, 0);
133   fPad->Draw();
134
135   Double_t yb = 0;
136   fCanvas->cd();
137   if (TESTBIT(fTreeMask, kESD) || 
138       TESTBIT(fTreeMask, kDigits) || 
139       TESTBIT(fTreeMask, kRaw)) {
140     yb = .05;
141     fSlider = new TSlider("multCut", "Multiplicity cut", 0, 0, 1, yb);
142     fSlider->SetMethod("AliFMDDisplay::Instance()->ChangeCut()");
143     fSlider->Draw();
144     fSlider->SetMinimum(TESTBIT(fTreeMask, kESD) ? fMultCut * 10 :
145                         fPedestalFactor * 10);
146   }
147   const char** p = which;
148   const char*  m;
149   Int_t        n  = 0;
150   Int_t        j  = 0;
151   while (*(p++)) n++;
152   AliInfo(Form("Got %d buttons", n));
153   Float_t      x0 = 0;
154   Float_t      dx = 1. / n;
155   p               = which;
156   while ((m = *(p++))) {
157     fCanvas->cd();
158     AliInfo(Form("Adding button %s", m));
159     TButton* b = new TButton(m, Form("AliFMDDisplay::Instance()->%s()", m),
160                              x0, yb, x0 + dx, y1);
161     b->Draw();
162     fButtons.Add(b);
163     x0 += dx;
164     j++;
165   }
166 }
167
168 //____________________________________________________________________
169 void           
170 AliFMDDisplay::ShowOnlyFMD()
171 {
172   if (!fGeoManager) return;
173   static bool once = false;
174   if (once) return;
175   once = true;
176   AliInfo("Will only show the FMD");
177   TGeoVolume* top = gGeoManager->GetTopVolume();
178   top->InvisibleAll(kTRUE);
179   TGeoIterator next(top);
180   TGeoNode* node;
181   TGeoVolume* v = 0;
182   Bool_t hasFMD1 = kFALSE;
183   Bool_t hasFMD2 = kFALSE;
184   Bool_t hasFMD3 = kFALSE;
185   TObjArray toshow;
186   while ((node = static_cast<TGeoNode*>(next()))) {
187     const char* name = node->GetName();
188     if (!name) continue;
189     if (!(v = node->GetVolume())) continue;
190
191     if (name[0] == 'F') {
192       if (name[2] == 'M' && (name[3] == 'T' || name[3] == 'B')) {
193         // Virtual Master half-ring volume - top-level
194         Int_t det = node->GetNumber();
195         switch (det) {
196         case 1: hasFMD1 = true; break;
197         case 2: hasFMD2 = true; break;
198         case 3: hasFMD3 = true; break;
199         default: continue;
200         }
201         toshow.Add(v);
202       }
203       else if (name[3] == 'V' && (name[2] == 'T' || name[2] == 'B')) 
204         toshow.Add(v); // Virtual Half-ring, bare detectors
205       // else if (name[3] == 'H' && (name[2] == 'F' || name[2] == 'B')) 
206       //  toshow.Add(v); // Virtual Hybrid container 
207     }
208     v->SetVisibility(kFALSE);
209     v->SetVisDaughters(kFALSE);
210     v->InvisibleAll(kTRUE);
211   }
212   TIter i(&toshow);
213   while ((v = static_cast<TGeoVolume*>(i()))) {
214     v->SetVisibility(kTRUE);
215     v->SetVisDaughters(kTRUE);
216     v->InvisibleAll(kFALSE);
217   }  
218 }
219
220     
221 //____________________________________________________________________
222 void           
223 AliFMDDisplay::ExecuteEvent(Int_t event, Int_t px, Int_t py) 
224 {
225   // AliInfo(Form("Event %d, at (%d,%d)", px, py));
226   if (px == 0 && py == 0) return;
227   if (!fZoomMode && fPad->GetView()) {
228     fPad->GetView()->ExecuteRotateView(event, px, py);
229     return;
230   }
231   fPad->SetCursor(kCross);
232   switch (event) {
233   case kButton1Down: 
234     fPad->TAttLine::Modify();
235     fX0        = fPad->AbsPixeltoX(px);
236     fY0        = fPad->AbsPixeltoY(py);
237     fXPixel    = fOldXPixel = px;
238     fYPixel    = fOldYPixel = py;
239     fLineDrawn = kFALSE;
240     return;
241   case kButton1Motion:
242     if (fLineDrawn) 
243       gVirtualX->DrawBox(fXPixel, fYPixel, fOldXPixel, fOldYPixel, 
244                          TVirtualX::kHollow);
245     fOldXPixel = px;
246     fOldYPixel = py;
247     fLineDrawn = kTRUE;
248     gVirtualX->DrawBox(fXPixel, fYPixel, fOldXPixel, fOldYPixel, 
249                        TVirtualX::kHollow);
250     return;
251   case kButton1Up:
252     fPad->GetCanvas()->FeedbackMode(kFALSE);
253     if (px == fXPixel || py == fYPixel) return;
254     fX1 = fPad->AbsPixeltoX(px);
255     fY1 = fPad->AbsPixeltoY(py);
256     if (fX1 < fX0) std::swap(fX0, fX1); 
257     if (fY1 < fY0) std::swap(fY0, fY1); 
258     fPad->Range(fX0, fY0, fX1, fY1);
259     fPad->Modified();
260     return;
261   }
262 }
263
264 //____________________________________________________________________
265 Int_t          
266 AliFMDDisplay::DistancetoPrimitive(Int_t px, Int_t) 
267 {
268   // AliInfo(Form("@ (%d,%d)", px, py));
269   fPad->SetCursor(kCross);
270   Float_t xmin = fPad->GetX1();
271   Float_t xmax = fPad->GetX2();
272   Float_t dx   = .02 * (xmax - xmin);
273   Float_t x    = fPad->AbsPixeltoX(px);
274   if (x < xmin + dx || x > xmax - dx) return 9999;
275   return (fZoomMode ? 0 : 7);
276 }
277 //____________________________________________________________________
278 Bool_t 
279 AliFMDDisplay::Init()
280 {
281   // Initialize.  GEt transforms and such, 
282   if (!AliFMDInput::Init()) return kFALSE;
283   AliFMDGeometry* geom = AliFMDGeometry::Instance();
284   geom->Init();
285   geom->InitTransformations();
286   if (TESTBIT(fTreeMask, kDigits) || TESTBIT(fTreeMask, kRaw)) 
287     AliFMDParameters::Instance()->Init();
288
289   fMarkers = new TObjArray;
290   fHits    = new TObjArray;
291   fMarkers->SetOwner(kTRUE);
292   fHits->SetOwner(kFALSE);
293   return kTRUE;
294 }
295
296 //____________________________________________________________________
297 void
298 AliFMDDisplay::MakeAux()
299 {
300   if ((TESTBIT(fTreeMask, kESD) || 
301        TESTBIT(fTreeMask, kDigits) || 
302        TESTBIT(fTreeMask, kRaw))) {
303     if (!fAux) {
304       fAux = new TCanvas("aux", "Aux");
305       fAux->SetLogy();
306       if (TESTBIT(fTreeMask, kESD)) 
307         fSpec = new TH1D("spec", "Mult spectra", 500, 0, 10);
308       else 
309         fSpec = new TH1D("spec", "Adc spectra", 1024, -.5, 1023.5);
310       fSpecCut = static_cast<TH1*>(fSpec->Clone("specCut"));
311       fSpec->SetFillColor(2);
312       fSpec->SetFillStyle(3001);
313       fSpecCut->SetFillColor(4);
314       fSpecCut->SetFillStyle(3001);
315     }
316     else {
317       fSpec->Reset();
318       fSpecCut->Reset();
319     }
320   }
321 }
322
323 //____________________________________________________________________
324 void
325 AliFMDDisplay::DrawAux()
326 {
327   if (!fAux) return;
328   fAux->cd();
329   fAux->Clear();
330   fSpec->Draw();
331   fSpecCut->Draw("same");
332   fAux->Modified();
333   fAux->Update();
334   fAux->cd();
335 }
336
337 //____________________________________________________________________
338 Bool_t 
339 AliFMDDisplay::Begin(Int_t event) 
340 {
341   // Begin of event.  Make canvas is not already done 
342   if (!fCanvas) {
343     const char* m[] = { "Continue", "Zoom", "Pick", "Redisplay", 0 }; 
344     MakeCanvas(m);
345   }
346   MakeAux();
347
348   // AliInfo("Clearing canvas");
349   // fCanvas->Clear();
350   if (!fGeoManager) {
351     Warning("End", "No geometry manager");
352     return kFALSE;
353   }
354   AliInfo("Drawing geometry");
355   fPad->cd();
356   fGeoManager->GetTopVolume()->Draw();
357   if (fOnlyFMD) ShowOnlyFMD();
358   AliInfo("Adjusting view");
359   Int_t irep;
360   if (fPad->GetView()) {
361     fPad->GetView()->SetView(-200, -40, 80, irep);
362     fPad->GetView()->Zoom();
363     fPad->Modified();
364     fPad->cd();
365   }
366   return AliFMDInput::Begin(event);
367 }
368
369 //____________________________________________________________________
370 void
371 AliFMDDisplay::AtEnd() 
372 {
373   fPad->cd();
374   fMarkers->Draw();
375   fPad->cd();
376   AppendPad();
377   fPad->cd();
378   DrawAux();
379 }
380
381 //____________________________________________________________________
382 void
383 AliFMDDisplay::Idle() 
384 {
385   fWait = kTRUE;
386   while (fWait) {
387     gApplication->StartIdleing();
388     gSystem->InnerLoop();
389     gApplication->StopIdleing();
390   }
391   AliInfo("After idle loop");
392   if (fMarkers) fMarkers->Delete();
393   if (fHits)    fHits->Clear();
394   AliInfo("After clearing caches");
395 }
396
397 //____________________________________________________________________
398 Bool_t 
399 AliFMDDisplay::End()
400 {
401   // End of event.  Draw everything 
402   AtEnd();
403   Idle();
404   return AliFMDInput::End();
405 }
406
407 //____________________________________________________________________
408 Int_t
409 AliFMDDisplay::LookupColor(Float_t x, Float_t max) const
410 {
411   // Look-up color 
412   Int_t idx = Int_t(x / max * gStyle->GetNumberOfColors());
413   return gStyle->GetColorPalette(idx);
414 }
415
416 //____________________________________________________________________
417 void
418 AliFMDDisplay::ChangeCut() 
419 {
420   fMultCut        = fSlider->GetMinimum() * 10;
421   fPedestalFactor = fSlider->GetMinimum() * 10;
422   AliInfo(Form("Multiplicity cut: %7.5f, Pedestal factor: %7.4f (%6.5f)", 
423                fMultCut, fPedestalFactor, fSlider->GetMinimum()));
424   Redisplay();
425 }
426
427 //____________________________________________________________________
428 void
429 AliFMDDisplay::Redisplay()
430 {
431   if (fMarkers) fMarkers->Delete();
432   if (fHits)    fHits->Clear();
433   if (fSpec)    fSpec->Reset();
434   if (fSpecCut) fSpecCut->Reset();
435   Event();
436   AtEnd();
437 }
438
439 //____________________________________________________________________
440 void
441 AliFMDDisplay::AddMarker(UShort_t det, Char_t rng, UShort_t sec, UShort_t str,
442                          TObject* o, Float_t s, Float_t max)
443 {
444   // Add a marker to the display
445   //
446   //    det     Detector
447   //    rng     Ring
448   //    sec     Sector 
449   //    str     Strip
450   //    o       Object to refer to
451   //    s       Signal 
452   //    max     Maximum of signal 
453   //
454   AliFMDGeometry*   geom = AliFMDGeometry::Instance();
455   Double_t x, y, z;
456   geom->Detector2XYZ(det, rng, sec, str, x, y, z);
457   Float_t  size  = .1;
458   Float_t  zsize = s / max * 10;
459   Float_t  r     = TMath::Sqrt(x * x + y * y);
460   Float_t  theta = TMath::ATan2(r, z);
461   Float_t  phi   = TMath::ATan2(y, x);
462   Float_t  rz    = z + (z < 0 ? 1 : -1) * zsize;
463   TMarker3DBox* marker = new  TMarker3DBox(x,y,rz,size,size,zsize,theta,phi);
464   if (o) marker->SetRefObject(o);
465   marker->SetLineColor(LookupColor(s, max));
466   fMarkers->Add(marker);
467 }
468   
469
470 //____________________________________________________________________
471 Bool_t 
472 AliFMDDisplay::ProcessHit(AliFMDHit* hit, TParticle* /* p */) 
473 {
474   // Process a hit 
475   if (!hit) { AliError("No hit");   return kFALSE; }
476   // if (!p)   { AliError("No track"); return kFALSE; }
477
478   if (fHits) fHits->Add(hit);
479   Float_t  size  = .1;
480   Float_t  zsize = TMath::Sqrt(hit->Edep() * 20);
481   Float_t  z     = hit->Z() + (hit->Z() < 0 ? 1 : -1) * zsize; 
482   Float_t  pt    = TMath::Sqrt(hit->Py()*hit->Py()+hit->Px()*hit->Px());
483   Float_t  theta = TMath::ATan2(pt, hit->Pz());
484   Float_t  phi   = TMath::ATan2(hit->Py(), hit->Px());
485   TMarker3DBox* marker = new  TMarker3DBox(hit->X(), hit->Y(), z,
486                                            size, size, zsize, theta, phi);
487   marker->SetLineColor(LookupColor(hit->Edep(), 1));
488   marker->SetRefObject(hit);
489   fMarkers->Add(marker);
490   return kTRUE;
491 }
492
493 //____________________________________________________________________
494 Bool_t 
495 AliFMDDisplay::ProcessDigit(AliFMDDigit* digit)
496 {
497   // Process a digit 
498   if (!digit) { AliError("No digit");   return kFALSE; }
499
500   AliFMDParameters* parm = AliFMDParameters::Instance();
501   UShort_t det           =  digit->Detector();
502   Char_t   ring          =  digit->Ring();
503   UShort_t sec           =  digit->Sector();
504   UShort_t str           =  digit->Strip();
505   Double_t ped           =  parm->GetPedestal(det,ring, sec, str);
506   Double_t pedW          =  parm->GetPedestalWidth(det,ring, sec, str);
507   Double_t threshold     =  ped + fPedestalFactor * pedW;
508   Float_t  counts        =  digit->Counts();
509   AliFMDDebug(10, ("FMD%d%c[%2d,%3d] ADC: %d > %d (=%4.2f+%4.2f*%4.2f)", 
510                     digit->Detector(), digit->Ring(), digit->Sector(), 
511                     digit->Strip(), Int_t(counts), Int_t(threshold), 
512                     ped, fPedestalFactor, pedW));
513   if (fSpec) fSpec->Fill(counts);
514   if (counts < threshold) return kTRUE;
515   if (fHits) fHits->Add(digit);
516   if (fSpecCut) fSpecCut->Fill(counts);
517
518   AddMarker(det, ring, sec, str, digit, counts, 1024);
519   return kTRUE;
520 }
521
522 //____________________________________________________________________
523 Bool_t 
524 AliFMDDisplay::ProcessRaw(AliFMDDigit* digit)
525 {
526   // PRocess raw data 
527   return ProcessDigit(digit);
528 }
529
530 //____________________________________________________________________
531 Bool_t 
532 AliFMDDisplay::ProcessRecPoint(AliFMDRecPoint* recpoint)
533 {
534   // Process reconstructed point 
535   if (!recpoint) { AliError("No recpoint");   return kFALSE; }
536   if (recpoint->Particles() < fMultCut) return kTRUE;
537   if (fHits) fHits->Add(recpoint);
538   AddMarker(recpoint->Detector(), recpoint->Ring(), recpoint->Sector(),  
539             recpoint->Strip(), recpoint, recpoint->Particles(), 20);
540   return kTRUE;
541 }
542
543 //____________________________________________________________________
544 Bool_t 
545 AliFMDDisplay::ProcessESD(UShort_t det, Char_t rng, UShort_t sec, UShort_t str,
546                           Float_t, Float_t mult)
547 {
548   Double_t cmult = mult;
549   if (fSpec) fSpec->Fill(cmult);
550   if (cmult < fMultCut || cmult == AliESDFMD::kInvalidMult) return kTRUE;
551   AddMarker(det,rng,sec,str, 0, cmult, 20);
552   if (fSpecCut) fSpecCut->Fill(cmult);
553   return kTRUE;
554 }
555
556 //____________________________________________________________________
557 //
558 // EOF
559 //