]> git.uio.no Git - u/mrichter/AliRoot.git/blob - STEER/AliDisplay.cxx
Bug fixed (Christian)
[u/mrichter/AliRoot.git] / STEER / AliDisplay.cxx
1 /**************************************************************************
2  * Copyright(c) 1998-1999, 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
16 /* $Id$ */
17
18 //////////////////////////////////////////////////////////////////////////
19 //                                                                      //
20 // AliDisplay                                                           //
21 //                                                                      //
22 // Utility class to display ALICE outline, tracks, hits,..              //
23 //                                                                      //
24 //////////////////////////////////////////////////////////////////////////
25
26 #include <TArc.h>
27 #include <TButton.h>
28 #include <TCanvas.h>
29 #include <TDiamond.h>
30 #include <TGaxis.h>
31 #include <TMath.h>
32 #include <TPaveLabel.h>
33 #include <TPaveText.h>
34 #include <TSlider.h>
35 #include <TSliderBox.h>
36 //#include <TTree.h>
37 #include <TView.h>
38 #include <TVirtualX.h>
39
40 #include "AliLog.h"
41 #include "AliDetector.h"
42 #include "AliDisplay.h"
43 #include "AliHeader.h"
44 #include "AliPoints.h"
45 #include "AliRun.h"
46 #include "AliStack.h"
47 #include "TGeometry.h"
48 #include "TParticle.h"
49 #include "AliMC.h"
50
51 const Float_t AliDisplay::fgkPtCutMax  = 2;
52 const Float_t AliDisplay::fgkEtaCutMax = 1.5;
53 const Int_t   AliDisplay::fgkMaxZooms = 20;
54
55
56 ClassImp(AliDisplay)
57
58
59 //_______________________________________________________________________
60 AliDisplay::AliDisplay():
61   fZoomMode(0),
62   fDrawAllViews(0),
63   fDrawParticles(0),
64   fDrawHits(0),
65   fPTcut(0),
66   fTheta(0),
67   fPhi(0),
68   fPsi(0),
69   fRrange(0),
70   fZrange(0),
71   fZooms(0),
72   fHitsCuts(0),
73   fCanvas(0),
74   fTrigPad(0),
75   fCutPad(0),
76   fEtaPad(0),
77   fButtons(0),
78   fPad(0),
79   fCutSlider(0),
80   fEtaSlider(0),
81   fRangeSlider(0),
82   fPickButton(0),
83   fZoomButton(0),
84   fArcButton(0),
85   fFruits(0),
86   fTracksToDisplay(0),
87   fNTracksToDisplay(0)
88 {
89   //
90   // Default constructor
91   //
92 }
93
94 //_____________________________________________________________________________
95 AliDisplay::AliDisplay(Int_t size):
96   fZoomMode(1),
97   fDrawAllViews(kFALSE),
98   fDrawParticles(kTRUE),
99   fDrawHits(kTRUE),
100   fPTcut(0),
101   fTheta(0),
102   fPhi(-90),
103   fPsi(0),
104   fRrange(0),
105   fZrange(0),
106   fZooms(1),
107   fHitsCuts(0),
108   fCanvas(0),
109   fTrigPad(0),
110   fCutPad(0),
111   fEtaPad(0),
112   fButtons(0),
113   fPad(0),
114   fCutSlider(0),
115   fEtaSlider(0),
116   fRangeSlider(0),
117   fPickButton(0),
118   fZoomButton(0),
119   fArcButton(0),
120   fFruits(0),
121   fTracksToDisplay(0),
122   fNTracksToDisplay(0)
123 {
124 // Create an event display object.
125 // A canvas named "edisplay" is created with a vertical size in pixels
126 //
127 //    A QUICK Overview of the Event Display functions
128 //    ===============================================
129 //
130 //  The event display can ve invoked by executing the macro "display.C"
131 // A canvas like in the picture below will appear.
132 //
133 //  On the left side of the canvas, the following buttons appear:
134 //   *Next*       to move to the next event
135 //   *Previous*   to move to the previous event
136 //   *Top View*   to display a top view of the current event
137 //   *Side View*  to display a side view of the current event
138 //   *Front View* to display a front view of the current event
139 //   *All Views*  to display front/side/top/30-30 views of the current event
140 //   *OpenGL*     to use OpenGl to view the current event.
141 //                Note that OpenGL cannot be used across the network.
142 //                Before using OpenGL, load the GL libraries
143 //                by executing the macro GL.C (in $ROOTSYS/macros/GL.C.
144 //                Once in GL, click the HELP button of the GL canvas.
145 //   *X3D*        to use X3D to view the current event (Unix only).
146 //                Once in X3D, type M to see the list of all possible options.
147 //                for example type J to zoom, K to unzoom
148 //                use the mouse to rotate.
149 //   *Pick*       Select this option to be able to point on a track with the
150 //                mouse. Once on the track, use the right button to select
151 //                an action. For example, select SetMarkerAttributes to
152 //                change the marker type/color/size for the track.
153 //   *Zoom*       Select this option (default) if you want to zoom.
154 //                To zoom, simply select the selected area with the left button.
155 //   *UnZoom*     To revert to the previous picture size.
156 //
157 //   slider R     On the left side, the vertical slider can be used to
158 //                set the default picture size.
159 //   slider pcut  At the top of the canvas, a slider can be used to change
160 //                the momentum cut (or range) to display tracks.
161 //   slider eta   On the right side of the canvas, a vertical slider can be used
162 //                to specify a rapidity range for the tracks.
163 //
164 //    When you are in Zoom mode, you can click on the black part of the canvas
165 //  to select special options with the right mouse button.
166 //  This will display a pop-up menu with items like:
167 //     *Disable detector* 
168 //     *Enable detector*, etc.
169 //  For example select "Disable detector". You get a dialog box.
170 //  Diable detector TRD for example.
171 //
172 //  When you are in pick mode, you can "Inspect" the object pointed by the mouse.
173 //  When you are on a track, select the menu item "InspectParticle"
174 //  to display the current particle attributes.
175 //
176 //  You can activate the Root browser by selecting the Inspect menu
177 //  in the canvas tool bar menu. Then select "Start Browser"
178 //  This will open a new canvas with the browser. At this point, you may want
179 //  to display some histograms (from the Trees). Go to the "File" menu
180 //  of the browser and click on "New canvas".
181 //  In the browser, click on item "ROOT files" in the left pane.
182 //  Click on galice.root.
183 //  Click on TH
184 //  Click on TPC for example
185 //  Click on any variable (eg TPC.fX) to histogram the variable.
186 //
187 //   If you are lost, you can click on HELP in any Root canvas or browser.
188 //Begin_Html
189 /*
190 <img src="picts/alidisplay.gif">
191 */
192 //End_Html
193    
194   gAlice->SetDisplay(this);
195    
196   // Initialize display default parameters
197   SetRange();
198   SetPTcut();
199   
200   // Create display canvas
201   Int_t ysize = size;
202   if (ysize < 100) ysize = 750;
203   Int_t xsize = Int_t(size*830./ysize);
204   fCanvas = new TCanvas("Canvas", "ALICE Event Display",14,47,xsize,ysize);
205   fCanvas->ToggleEventStatus();
206
207   // Create main display pad
208   fPad = new TPad("viewpad", "Alice display",0.15,0,0.97,0.96);
209   fPad->Draw();
210   fPad->Modified();
211   fPad->SetFillColor(1);
212   fPad->SetBorderSize(2);
213
214   // Create user interface control pad
215   DisplayButtons();
216   fCanvas->cd();
217
218   // Create Range and mode pad
219   Float_t dxtr     = 0.15;
220   Float_t dytr     = 0.45;
221   fTrigPad = new TPad("trigger", "range and mode pad",0,0,dxtr,dytr);
222   fTrigPad->Draw();
223   fTrigPad->cd();
224   fTrigPad->SetFillColor(22);
225   fTrigPad->SetBorderSize(2);
226   fRangeSlider = new TSlider("range","range",0.7,0.42,0.9,0.98);
227   fRangeSlider->SetObject(this);
228   char pickmode[] = "gAlice->Display()->SetPickMode()";
229   Float_t db = 0.09;
230   fPickButton = new TButton("Pick",pickmode,0.05,0.32,0.65,0.32+db);
231   fPickButton->SetFillColor(38);
232   fPickButton->Draw();
233   char zoommode[] = "gAlice->Display()->SetZoomMode()";
234   fZoomButton = new TButton("Zoom",zoommode,0.05,0.21,0.65,0.21+db);
235   fZoomButton->SetFillColor(38);
236   fZoomButton->Draw();
237   fArcButton = new TArc(.8,fZoomButton->GetYlowNDC()+0.5*db,0.33*db);
238   fArcButton->SetFillColor(kGreen);
239   fArcButton->Draw();
240   char butUnzoom[] = "gAlice->Display()->UnZoom()";
241   TButton *button = new TButton("UnZoom",butUnzoom,0.05,0.05,0.95,0.15);
242   button->SetFillColor(38);
243   button->Draw();
244   AppendPad(); // append display object as last object to force selection
245   // Create momentum cut slider pad
246   fCanvas->cd();
247   fCutPad = new TPad("cutSlider", "pcut slider pad",dxtr,.96,1,1);
248   fCutPad->Draw();
249   fCutPad->cd();
250   fCutPad->SetFillColor(22);
251   fCutPad->SetBorderSize(2);
252   fCutSlider = new TSlider("pcut","Momentum cut",0,0,1,1);
253   fCutSlider->SetRange(fPTcut/fgkPtCutMax,1);
254   fCutSlider->SetObject(this);
255   fCutSlider->SetFillColor(45);
256   TSliderBox *sbox = dynamic_cast<TSliderBox*>(fCutSlider->GetListOfPrimitives()->First());
257   sbox->SetFillColor(46);
258   fCutSlider->cd();
259   TGaxis *cutaxis = new TGaxis(0.02,0.8,0.98,0.8,0,fgkPtCutMax,510,"");
260   cutaxis->SetLabelSize(0.5);
261   cutaxis->SetTitleSize(0.6);
262   cutaxis->SetTitleOffset(0.5);
263   cutaxis->SetTitle("pcut .  ");
264   fCutSlider->GetListOfPrimitives()->AddFirst(cutaxis);
265   // Create rapidity cut slider pad
266   fCanvas->cd();
267   fEtaPad = new TPad("EtaSlider", "Eta slider pad",0.97,0,1,0.96);
268   fEtaPad->Draw();
269   fEtaPad->cd();
270   fEtaPad->SetFillColor(22);
271   fEtaPad->SetBorderSize(2);
272   fEtaSlider = new TSlider("etacut","Rapidity cut",0,0,1,1);
273   fEtaSlider->SetObject(this);
274   fEtaSlider->SetFillColor(45);
275   TSliderBox *sbox2 = dynamic_cast<TSliderBox*>(fEtaSlider->GetListOfPrimitives()->First());
276   sbox2->SetFillColor(46);
277   fEtaSlider->cd();
278   TGaxis *etaaxis = new TGaxis(0.9,0.02,0.9,0.98,-fgkEtaCutMax,fgkEtaCutMax,510,"");
279   etaaxis->SetLabelSize(0.5);
280   etaaxis->SetTitleSize(0.6);
281   etaaxis->SetTitleOffset(0.2);
282   cutaxis->SetTitle("Etacut .  ");
283   fEtaSlider->GetListOfPrimitives()->AddFirst(etaaxis);
284   fCanvas->cd();
285
286   fTrigPad->SetEditable(kFALSE);
287   fButtons->SetEditable(kFALSE);
288   fTracksToDisplay =0;
289   fNTracksToDisplay =0;   
290
291   fCanvas->cd();
292   fCanvas->Update();
293 }
294
295
296 //_______________________________________________________________________
297 AliDisplay::AliDisplay(const AliDisplay &disp):
298   TObject(disp),
299   fZoomMode(0),
300   fDrawAllViews(0),
301   fDrawParticles(0),
302   fDrawHits(0),
303   fPTcut(0),
304   fTheta(0),
305   fPhi(0),
306   fPsi(0),
307   fRrange(0),
308   fZrange(0),
309   fZooms(0),
310   fHitsCuts(0),
311   fCanvas(0),
312   fTrigPad(0),
313   fCutPad(0),
314   fEtaPad(0),
315   fButtons(0),
316   fPad(0),
317   fCutSlider(0),
318   fEtaSlider(0),
319   fRangeSlider(0),
320   fPickButton(0),
321   fZoomButton(0),
322   fArcButton(0),
323   fFruits(0),
324   fTracksToDisplay(0),
325   fNTracksToDisplay(0)
326 {
327   //
328   // Copy constructor
329   //
330   disp.Copy(*this);
331 }
332
333 //_____________________________________________________________________________
334 AliDisplay::~AliDisplay()
335 {
336   //
337   // Destructor
338   //
339 }
340
341 //_____________________________________________________________________________
342 void AliDisplay::Clear(Option_t *)
343 {
344 //    Delete graphics temporary objects
345 }
346
347 //_____________________________________________________________________________
348 void AliDisplay::Copy(TObject &) const
349 {
350   //
351   // Copy *this onto disp -- not implemented
352   //
353   AliFatal("Not implemented");
354 }
355
356 //----------------------------------------------------------------------------
357 void AliDisplay::ShowTrack(Int_t idx) 
358 {
359   //
360   // Display track idx
361   //
362    AliDetector *mTPC=dynamic_cast<AliDetector*>(gAlice->GetModule("TPC"));
363    TObjArray *points=mTPC->Points();
364    int ntracks=points->GetEntriesFast();
365    for (int track=0;track<ntracks;track++) {
366       AliPoints *pm = dynamic_cast<AliPoints*>(points->UncheckedAt(track));
367       if (!pm) continue;
368       if (idx == pm->GetIndex()) {
369          pm->SetMarkerColor(2);
370          pm->SetMarkerStyle(22);
371          pm->Draw("same");
372 //       fPad->Update();
373 //       fPad->Modified();
374          //         TClonesArray *particles=gAlice->Particles();
375          //         TParticle *p = (TParticle*)particles->UncheckedAt(idx);
376          TParticle *p = gAlice->GetMCApp()->Particle(idx);
377          AliInfo(Form("Track index %d",idx));
378          AliInfo(Form("Particle ID %d",p->GetPdgCode()));
379          AliInfo(Form("Parent %d",p->GetFirstMother()));
380          AliInfo(Form("First child %d",p->GetFirstDaughter()));
381          AliInfo(Form("Px,Py,Pz %f %f %f",p->Px(),p->Py(),p->Pz()));
382          return;
383       }
384    }
385 }
386
387 //----------------------------------------------------------------------------
388 void AliDisplay::HideTrack(Int_t idx) const
389 {
390   //
391   // Hide track on display
392   //
393    AliDetector *mTPC=dynamic_cast<AliDetector*>(gAlice->GetModule("TPC"));
394    TObjArray *points=mTPC->Points();
395    int ntracks=points->GetEntriesFast();
396    for (int track=0;track<ntracks;track++) {
397       AliPoints *pm = dynamic_cast<AliPoints*>(points->UncheckedAt(track));
398       if (!pm) continue;
399       if (idx == pm->GetIndex()) {
400          pm->SetMarkerColor(5);
401          pm->SetMarkerStyle(1);
402          pm->Draw("same");
403 //       fPad->Update();
404 //       fPad->Modified();
405          return;
406       }
407    }
408 }
409
410 //_____________________________________________________________________________
411 void AliDisplay::DisableDetector(const char *name)
412 {
413 //    Disable detector name from graphics views
414    
415    AliModule *module = dynamic_cast<AliModule*>(gAlice->Modules()->FindObject(name));
416    if (!module) return;
417    module->Disable();
418    Draw();
419 }
420
421 //_____________________________________________________________________________
422 void AliDisplay::DisplayButtons()
423 {
424 //    Create the user interface buttons
425
426    fButtons = new TPad("buttons", "newpad",0,0.45,0.15,1);
427    fButtons->Draw();
428    fButtons->SetFillColor(38);
429    fButtons->SetBorderSize(2);
430    fButtons->cd();
431
432    Int_t butcolor = 33;
433    Float_t dbutton = 0.08;
434    Float_t y  = 0.96;
435    Float_t dy = 0.014;
436    Float_t x0 = 0.05;
437    Float_t x1 = 0.95;
438
439    TButton *button;
440    char but1[] = "gAlice->Display()->ShowNextEvent(1)";
441    button = new TButton("Next",but1,x0,y-dbutton,x1,y);
442    button->SetFillColor(38);
443    button->Draw();
444
445    y -= dbutton +dy;
446    char but2[] = "gAlice->Display()->ShowNextEvent(-1)";
447    button = new TButton("Previous",but2,x0,y-dbutton,x1,y);
448    button->SetFillColor(38);
449    button->Draw();
450
451    y -= dbutton +dy;
452    char but3[] = "gAlice->Display()->SetView(90,-90,90)";
453    button = new TButton("Top View",but3,x0,y-dbutton,x1,y);
454    button->SetFillColor(butcolor);
455    button->Draw();
456
457    y -= dbutton +dy;
458    char but4[] = "gAlice->Display()->SetView(90,0,-90)";
459    button = new TButton("Side View",but4,x0,y-dbutton,x1,y);
460    button->SetFillColor(butcolor);
461    button->Draw();
462
463    y -= dbutton +dy;
464    char but5[] = "gAlice->Display()->SetView(0,-90,0)";
465    button = new TButton("Front View",but5,x0,y-dbutton,x1,y);
466    button->SetFillColor(butcolor);
467    button->Draw();
468
469    y -= dbutton +dy;
470    char but6[] = "gAlice->Display()->DrawAllViews()";
471    button = new TButton("All Views",but6,x0,y-dbutton,x1,y);
472    button->SetFillColor(butcolor);
473    button->Draw();
474
475    y -= dbutton +dy;
476    char but7[] = "gAlice->Display()->DrawViewGL()";
477    button = new TButton("OpenGL",but7,x0,y-dbutton,x1,y);
478    button->SetFillColor(38);
479    button->Draw();
480
481    y -= dbutton +dy;
482    char but8[] = "gAlice->Display()->DrawViewX3D()";
483    button = new TButton("X3D",but8,x0,y-dbutton,x1,y);
484    button->SetFillColor(38);
485    button->Draw();
486
487    // display logo
488    TDiamond *diamond = new TDiamond(0.05,0.015,0.95,0.22);
489    diamond->SetFillColor(50);
490    diamond->SetTextAlign(22);
491    diamond->SetTextColor(5);
492    diamond->SetTextSize(0.11);
493    diamond->Draw();
494    diamond->AddText(".. ");
495    diamond->AddText("ROOT");
496    diamond->AddText("ALICE");
497    diamond->AddText("... ");
498    diamond->AddText(" ");
499 }
500
501 //______________________________________________________________________________
502 Int_t AliDisplay::DistancetoPrimitive(Int_t px, Int_t)
503 {
504 // Compute distance from point px,py to objects in event
505
506    gPad->SetCursor(kCross);
507    
508    if (gPad == fTrigPad) return 9999;
509    if (gPad == fCutPad)  return 9999;
510    if (gPad == fEtaPad)  return 9999;
511
512    const Int_t kbig = 9999;
513    Int_t dist   = kbig;
514    Float_t xmin = gPad->GetX1();
515    Float_t xmax = gPad->GetX2();
516    Float_t dx   = 0.02*(xmax - xmin);
517    Float_t x    = gPad->AbsPixeltoX(px);
518    if (x < xmin+dx || x > xmax-dx) return dist;
519
520    if (fZoomMode) return 0;
521    else           return 7;
522 }
523
524 //_____________________________________________________________________________
525 void AliDisplay::Draw(Option_t *)
526 {
527 //    Display current event
528
529    if (fDrawAllViews) {
530       DrawAllViews();
531       return;
532    }
533
534    fPad->cd();
535
536    DrawView(fTheta, fPhi, fPsi);
537
538    // Display the event number and title
539    fPad->cd();
540    DrawTitle();
541 }
542
543 //_____________________________________________________________________________
544 void AliDisplay::DrawAllViews()
545 {
546 //    Draw front,top,side and 30 deg views
547
548    fDrawAllViews = kTRUE;
549    fPad->cd();
550    fPad->SetFillColor(15);
551    fPad->Clear();
552    fPad->Divide(2,2);
553
554    // draw 30 deg view
555    fPad->cd(1);
556    DrawView(30, 30, 0);
557    DrawTitle();
558
559    // draw front view
560    fPad->cd(2);
561    DrawView(0, -90,0);
562    DrawTitle("Front");
563
564    // draw top view
565    fPad->cd(3);
566    DrawView(90, -90, 90);
567    DrawTitle("Top");
568
569    // draw side view
570    fPad->cd(4);
571    DrawView(90, 0, -90);
572    DrawTitle("Side");
573
574    fPad->cd(2);
575 }
576
577 //_____________________________________________________________________________
578 void AliDisplay::DrawHits()
579 {
580 //    Draw hits for all ALICE detectors
581
582    Float_t cutmin, cutmax, etamin, etamax, pmom, smin, smax, eta, theta, r;
583    Float_t *pxyz;
584    Int_t ntracks,track;
585    TParticle *particle;
586    TObjArray *points;
587    AliPoints *pm;
588       
589    //Get cut slider
590    smax   = fCutSlider->GetMaximum();
591    smin   = fCutSlider->GetMinimum();
592    cutmin = fgkPtCutMax*smin;
593    if (smax < 0.98) cutmax = fgkPtCutMax*smax;
594    else             cutmax = 100000;
595    
596    //Get eta slider
597    smax   = fEtaSlider->GetMaximum();
598    smin   = fEtaSlider->GetMinimum();
599    etamin = fgkEtaCutMax*(2*smin-1);
600    etamax = fgkEtaCutMax*(2*smax-1);
601    if (smin < 0.02) etamin = -1000;
602    if (smax > 0.98) etamax =  1000;
603       
604    TIter next(gAlice->Modules());
605    AliModule *module;
606    fHitsCuts = 0;
607    while((module = dynamic_cast<AliModule*>(next()))) {
608       if (!module->IsActive()) continue;
609       points = module->Points();
610       if (!points) continue;
611       ntracks = points->GetEntriesFast();
612       for (track=0;track<ntracks;track++) {
613          pm = dynamic_cast<AliPoints*>(points->UncheckedAt(track));
614          if (!pm) continue;
615          particle = pm->GetParticle();
616          if (!particle) continue;
617          pmom = particle->P();
618          if (pmom < cutmin) continue;
619          if (pmom > cutmax) continue;
620          // as a first approximation, take eta of first point
621          pxyz  = pm->GetP();
622          r     = TMath::Sqrt(pxyz[0]*pxyz[0] + pxyz[1]*pxyz[1]);
623          theta = TMath::ATan2(r,TMath::Abs(pxyz[2]));
624          if(theta) eta = -TMath::Log(TMath::Abs(TMath::Tan(0.5*theta))); else eta = 1e10;
625          if (pxyz[2] < 0) eta = -eta;
626          if (eta < etamin || eta > etamax) continue;
627          pm->Draw();
628          fHitsCuts += pm->GetN();
629       }
630    }
631 }
632
633 //_____________________________________________________________________________
634 void AliDisplay::DrawTitle(Option_t *option)
635 {
636 //    Draw the event title
637
638    Float_t xmin = gPad->GetX1();
639    Float_t xmax = gPad->GetX2();
640    Float_t ymin = gPad->GetY1();
641    Float_t ymax = gPad->GetY2();
642    Float_t dx   = xmax-xmin;
643    Float_t dy   = ymax-ymin;
644
645    if (strlen(option) == 0) {
646       TPaveText *title = new TPaveText(xmin +0.01*dx, ymax-0.09*dy, xmin +0.5*dx, ymax-0.01*dy);
647       title->SetBit(kCanDelete);
648       title->SetFillColor(42);
649       title->Draw();
650       char ptitle[100];
651       sprintf(ptitle,"Alice event: %d, Run:%d",gAlice->GetHeader()->GetEvent(), gAlice->GetHeader()->GetRun());
652       title->AddText(ptitle);
653       Int_t nparticles = gAlice->GetMCApp()->Particles()->GetEntriesFast();
654       sprintf(ptitle,"Nparticles = %d  Nhits = %d",nparticles, fHitsCuts);
655       title->AddText(ptitle);
656    } else {
657       TPaveLabel *label = new TPaveLabel(xmin +0.01*dx, ymax-0.07*dy, xmin +0.2*dx, ymax-0.01*dy,option);
658       label->SetBit(kCanDelete);
659       label->SetFillColor(42);
660       label->Draw();
661    }
662 }
663
664 //_____________________________________________________________________________
665 void AliDisplay::DrawView(Float_t theta, Float_t phi, Float_t psi)
666 {
667 //    Draw a view of ALICE
668
669    gPad->SetCursor(kWatch);
670    gPad->SetFillColor(1);
671    gPad->Clear();
672
673    Int_t iret;
674    TView *view = new TView(1);
675    Float_t range = fRrange*fRangeSlider->GetMaximum();
676    view->SetRange(-range,-range,-range,range, range, range);
677    fZoomX0[0] = -1;
678    fZoomY0[0] = -1;
679    fZoomX1[0] =  1;
680    fZoomY1[0] =  1;
681    fZooms = 0;
682    
683    // Display Alice Geometry
684    gAlice->GetGeometry()->Draw("same");
685    
686    //Loop on all detectors to add their products to the pad
687    DrawHits();
688
689     // add itself to the list (must be last)
690    AppendPad();
691    
692    view->SetView(phi, theta, psi, iret);
693 }
694
695 //_____________________________________________________________________________
696 void AliDisplay::DrawViewGL()
697 {
698 //    Draw current view using OPENGL
699
700    TPad *pad = dynamic_cast<TPad*>(gPad->GetPadSave());
701    pad->cd();
702    TView *view = pad->GetView();
703    if (!view) return;
704    pad->x3d("OPENGL");
705 }
706
707 //_____________________________________________________________________________
708 void AliDisplay::DrawViewX3D()
709 {
710 //    Draw current view using X3D
711
712    TPad *pad = dynamic_cast<TPad*>(gPad->GetPadSave());
713    pad->cd();
714    TView *view = pad->GetView();
715    if (!view) return;
716    pad->x3d();
717 }
718
719 //_____________________________________________________________________________
720 void AliDisplay::EnableDetector(const char *name)
721 {
722 //    Enable detector name in graphics views
723    
724    AliModule *module = dynamic_cast<AliModule*>(gAlice->Modules()->FindObject(name));
725    if (!module) return;
726    module->Enable();
727    Draw();
728 }
729
730 //______________________________________________________________________________
731 void AliDisplay::ExecuteEvent(Int_t event, Int_t px, Int_t py)
732 {
733 //  Execute action corresponding to the mouse event
734
735    static Float_t x0, y0, x1, y1;
736
737    static Int_t pxold, pyold;
738    static Int_t px0, py0;
739    static Int_t linedrawn;
740    Float_t temp;
741
742    if (px == 0 && py == 0) { //when called by sliders
743       if (event == kButton1Up) {
744          Draw();
745       }
746       return;
747    }
748    if (!fZoomMode && gPad->GetView()) {
749       gPad->GetView()->ExecuteRotateView(event, px, py);
750       return;
751    }
752
753    // something to zoom ?
754 //   fPad->SetCursor(kCross);
755    gPad->SetCursor(kCross);
756    
757    switch (event) {
758
759    case kButton1Down:
760       gVirtualX->SetLineColor(-1);
761       gPad->TAttLine::Modify();  //Change line attributes only if necessary
762       x0 = gPad->AbsPixeltoX(px);
763       y0 = gPad->AbsPixeltoY(py);
764       px0   = px; py0   = py;
765       pxold = px; pyold = py;
766       linedrawn = 0;
767       return;
768
769    case kButton1Motion:
770       if (linedrawn) gVirtualX->DrawBox(px0, py0, pxold, pyold, TVirtualX::kHollow);
771       pxold = px;
772       pyold = py;
773       linedrawn = 1;
774       gVirtualX->DrawBox(px0, py0, pxold, pyold, TVirtualX::kHollow);
775       return;
776
777    case kButton1Up:
778       gPad->GetCanvas()->FeedbackMode(kFALSE);
779       if (px == px0) return;
780       if (py == py0) return;
781       x1 = gPad->AbsPixeltoX(px);
782       y1 = gPad->AbsPixeltoY(py);
783
784       if (x1 < x0) {temp = x0; x0 = x1; x1 = temp;}
785       if (y1 < y0) {temp = y0; y0 = y1; y1 = temp;}
786       gPad->Range(x0,y0,x1,y1);
787       if (fZooms < fgkMaxZooms-1) {
788          fZooms++;
789          fZoomX0[fZooms] = x0;
790          fZoomY0[fZooms] = y0;
791          fZoomX1[fZooms] = x1;
792          fZoomY1[fZooms] = y1;
793       }
794       gPad->Modified(kTRUE);
795       return;
796    }
797
798 }
799  
800
801 void AliDisplay::SetTracksToDisplay(Int_t *tracks, Int_t n){
802   //
803   // set tracks to display  - MI
804   fTracksToDisplay = tracks;
805   fNTracksToDisplay = n;
806 }
807 //___________________________________________
808 void AliDisplay::LoadPoints()
809 {
810 // Read hits info and store x,y,z info in arrays fPoints
811 // Loop on all detectors
812  
813    gAlice->ResetPoints();
814    TIter next(gAlice->Modules());
815    AliModule *module;
816    Int_t ntracks = gAlice->GetMCApp()->GetNtrack();
817
818    while((module = (AliModule*)next())) 
819     {
820      AliDetector* detector = dynamic_cast<AliDetector*>(module);
821      if(detector) detector->SetTreeAddress();
822     }
823    next.Reset();
824
825    // load only wanted tracks
826    if (fNTracksToDisplay>0)
827     {
828       Int_t nprim =  gAlice->Stack()->GetNprimary();
829       for (Int_t track=0; track<fNTracksToDisplay;track++) 
830        {
831         gAlice->ResetHits();
832         Int_t nev = nprim-1-gAlice->GetMCApp()->GetPrimary(fTracksToDisplay[track]);
833         while((module = (AliModule*)next())) 
834          {
835           AliDetector* detector = dynamic_cast<AliDetector*>(module);
836           if(detector)
837            {
838             detector->TreeH()->GetEvent(nev);
839             module->LoadPoints(nprim-1-gAlice->GetMCApp()->GetPrimary(fTracksToDisplay[track]));
840            }
841          }
842         next.Reset();
843      }
844    }
845    else
846     {
847       
848       for (Int_t track=0; track<ntracks;track++) {
849       gAlice->ResetHits();
850       while((module = (AliModule*)next())) {
851          AliDetector* detector = dynamic_cast<AliDetector*>(module);
852          if(detector)
853            {
854              if (detector->TreeH()->GetEvent(track))
855                detector->LoadPoints(track);
856            }
857       }
858       next.Reset();
859      }
860    }
861 }
862
863 //_____________________________________________________________________________
864 void AliDisplay::Paint(Option_t *)
865 {
866 //    Paint miscellaneous items
867
868 }
869
870 //_____________________________________________________________________________
871 void AliDisplay::SetPickMode()
872 {
873   //
874   // Set Pick Mode -- disable zoom
875   //
876    fZoomMode = 0;
877
878    fArcButton->SetY1(fPickButton->GetYlowNDC()+0.5*fPickButton->GetHNDC());
879    fTrigPad->Modified();
880 }
881
882 //_____________________________________________________________________________
883 void AliDisplay::SetZoomMode()
884 {
885   //
886   // Set Zoom Mode -- disable pick
887   //
888    fZoomMode = 1;
889
890    fArcButton->SetY1(fZoomButton->GetYlowNDC()+0.5*fZoomButton->GetHNDC());
891    fTrigPad->Modified();
892 }
893
894 //_____________________________________________________________________________
895 void AliDisplay::SetPTcut(Float_t ptcut)
896 {
897   //
898   // Set Pt Cut
899   //
900    fPTcut = ptcut;
901
902    if (!fPad) return;
903    fPad->Clear();
904    Draw();
905 }
906
907 //_____________________________________________________________________________
908 void AliDisplay::SetRange(Float_t rrange, Float_t zrange)
909 {
910 // Set view range along R and Z
911    fRrange = rrange;
912    fZrange = zrange;
913
914    if (!fPad) return;
915    fPad->Clear();
916    Draw();
917 }
918    
919 //_____________________________________________________________________________
920 void AliDisplay::SetView(Float_t theta, Float_t phi, Float_t psi)
921 {
922 //  change viewing angles for current event
923
924    fPad->cd();
925    fDrawAllViews = kFALSE;
926    fPhi   = phi;
927    fTheta = theta;
928    fPsi   = psi;
929    Int_t iret = 0;
930
931    TView *view = gPad->GetView();
932    if (view) view->SetView(fPhi, fTheta, fPsi, iret);
933    else      Draw();
934
935    gPad->Modified();
936 }
937
938 //_____________________________________________________________________________
939 void AliDisplay::ShowNextEvent(Int_t delta)
940 {
941 //  Display (current event_number+delta)
942 //    delta =  1  shown next event
943 //    delta = -1 show previous event
944
945   if (delta) {
946 //     gAlice->Clear();
947      //Int_t currentEvent = gAlice->GetHeader()->GetEvent();//event number is not filled correctly
948      Int_t currentEvent = gAlice->GetRunLoader()->GetEventNumber();
949      Int_t newEvent     = currentEvent + delta;
950      gAlice->GetEvent(newEvent);
951      AliInfo(Form("delta = %d  currentEvent = %d  newEvent = %d",
952                   delta, currentEvent, newEvent));
953    }
954   LoadPoints();
955   fPad->cd(); 
956   Draw();
957 }
958
959 //______________________________________________________________________________
960 void AliDisplay::UnZoom()
961 {
962   //
963   // Resets ZOOM 
964   //
965   if (fZooms <= 0) return;
966   fZooms--;
967   TPad *pad = dynamic_cast<TPad*>(gPad->GetPadSave());
968   pad->Range(fZoomX0[fZooms],fZoomY0[fZooms], fZoomX1[fZooms],fZoomY1[fZooms]);
969   pad->Modified();
970 }
971
972 //_____________________________________________________________________________
973 AliDisplay & AliDisplay::operator=(const AliDisplay &disp)
974 {
975   //
976   // Assignment operator
977   //
978   disp.Copy(*this);
979   return (*this);
980 }