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