1 /**************************************************************************
2 * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
4 * Author: The ALICE Off-line Project. *
5 * Contributors are mentioned in the code where appropriate. *
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 **************************************************************************/
18 Revision 1.6 1999/11/09 07:38:52 fca
19 Changes for compatibility with version 2.23 of ROOT
21 Revision 1.5 1999/09/29 09:24:29 fca
22 Introduction of the Copyright and cvs Log
27 //////////////////////////////////////////////////////////////////////////
31 // Utility class to display ALICE outline, tracks, hits,.. //
33 //////////////////////////////////////////////////////////////////////////
41 #include <TPolyMarker3D.h>
42 #include <TPaveLabel.h>
43 #include <TPaveText.h>
50 #include <TSliderBox.h>
52 #include <TVirtualX.h>
54 #include <X3DBuffer.h>
57 #include "AliDetector.h"
58 #include "AliDisplay.h"
59 #include "AliPoints.h"
60 #include "TParticle.h"
62 const Float_t ptcutmax = 2;
63 const Float_t etacutmax = 1.5;
68 //_____________________________________________________________________________
69 AliDisplay::AliDisplay()
74 //_____________________________________________________________________________
75 AliDisplay::AliDisplay(Int_t size)
77 // Create an event display object.
78 // A canvas named "edisplay" is created with a vertical size in pixels
80 // A QUICK Overview of the Event Display functions
81 // ===============================================
83 // The event display can ve invoked by executing the macro "display.C"
84 // A canvas like in the picture below will appear.
86 // On the left side of the canvas, the following buttons appear:
87 // *Next* to move to the next event
88 // *Previous* to move to the previous event
89 // *Top View* to display a top view of the current event
90 // *Side View* to display a side view of the current event
91 // *Front View* to display a front view of the current event
92 // *All Views* to display front/side/top/30-30 views of the current event
93 // *OpenGL* to use OpenGl to view the current event.
94 // Note that OpenGL cannot be used across the network.
95 // Before using OpenGL, load the GL libraries
96 // by executing the macro GL.C (in $ROOTSYS/macros/GL.C.
97 // Once in GL, click the HELP button of the GL canvas.
98 // *X3D* to use X3D to view the current event (Unix only).
99 // Once in X3D, type M to see the list of all possible options.
100 // for example type J to zoom, K to unzoom
101 // use the mouse to rotate.
102 // *Pick* Select this option to be able to point on a track with the
103 // mouse. Once on the track, use the right button to select
104 // an action. For example, select SetMarkerAttributes to
105 // change the marker type/color/size for the track.
106 // *Zoom* Select this option (default) if you want to zoom.
107 // To zoom, simply select the selected area with the left button.
108 // *UnZoom* To revert to the previous picture size.
110 // slider R On the left side, the vertical slider can be used to
111 // set the default picture size.
112 // slider pcut At the top of the canvas, a slider can be used to change
113 // the momentum cut (or range) to display tracks.
114 // slider eta On the right side of the canvas, a vertical slider can be used
115 // to specify a rapidity range for the tracks.
117 // When you are in Zoom mode, you can click on the black part of the canvas
118 // to select special options with the right mouse button.
119 // This will display a pop-up menu with items like:
120 // *Disable detector*
121 // *Enable detector*, etc.
122 // For example select "Disable detector". You get a dialog box.
123 // Diable detector TRD for example.
125 // When you are in pick mode, you can "Inspect" the object pointed by the mouse.
126 // When you are on a track, select the menu item "InspectParticle"
127 // to display the current particle attributes.
129 // You can activate the Root browser by selecting the Inspect menu
130 // in the canvas tool bar menu. Then select "Start Browser"
131 // This will open a new canvas with the browser. At this point, you may want
132 // to display some histograms (from the Trees). Go to the "File" menu
133 // of the browser and click on "New canvas".
134 // In the browser, click on item "ROOT files" in the left pane.
135 // Click on galice.root.
137 // Click on TPC for example
138 // Click on any variable (eg TPC.fX) to histogram the variable.
140 // If you are lost, you can click on HELP in any Root canvas or browser.
143 <img src="picts/alidisplay.gif">
148 gAlice->SetDisplay(this);
150 // Initialize display default parameters
154 // Set front view by default
158 fDrawAllViews = kFALSE;
160 fDrawParticles = kTRUE;
165 // Create display canvas
167 if (ysize < 100) ysize = 750;
168 Int_t xsize = Int_t(size*830./ysize);
169 fCanvas = new TCanvas("Canvas", "ALICE Event Display",14,47,xsize,ysize);
170 fCanvas->ToggleEventStatus();
172 // Create main display pad
173 fPad = new TPad("viewpad", "Alice display",0.15,0,0.97,0.96);
176 fPad->SetFillColor(1);
177 fPad->SetBorderSize(2);
179 // Create user interface control pad
183 // Create Range and mode pad
186 fTrigPad = new TPad("trigger", "range and mode pad",0,0,dxtr,dytr);
187 fTrigPad->SetEditable(kFALSE);
190 fTrigPad->SetFillColor(22);
191 fTrigPad->SetBorderSize(2);
192 fRangeSlider = new TSlider("range","range",0.7,0.42,0.9,0.98);
193 fRangeSlider->SetObject(this);
194 char pickmode[] = "gAlice->Display()->SetPickMode()";
196 fPickButton = new TButton("Pick",pickmode,0.05,0.32,0.65,0.32+db);
197 fPickButton->SetFillColor(38);
199 char zoommode[] = "gAlice->Display()->SetZoomMode()";
200 fZoomButton = new TButton("Zoom",zoommode,0.05,0.21,0.65,0.21+db);
201 fZoomButton->SetFillColor(38);
203 fArcButton = new TArc(.8,fZoomButton->GetYlowNDC()+0.5*db,0.33*db);
204 fArcButton->SetFillColor(kGreen);
206 char butUnzoom[] = "gAlice->Display()->UnZoom()";
207 TButton *button = new TButton("UnZoom",butUnzoom,0.05,0.05,0.95,0.15);
208 button->SetFillColor(38);
210 AppendPad(); // append display object as last object to force selection
212 // Create momentum cut slider pad
214 fCutPad = new TPad("cutSlider", "pcut slider pad",dxtr,.96,1,1);
217 fCutPad->SetFillColor(22);
218 fCutPad->SetBorderSize(2);
219 fCutSlider = new TSlider("pcut","Momentum cut",0,0,1,1);
220 fCutSlider->SetRange(fPTcut/ptcutmax,1);
221 fCutSlider->SetObject(this);
222 fCutSlider->SetFillColor(45);
223 TSliderBox *sbox = (TSliderBox*)fCutSlider->GetListOfPrimitives()->First();
224 sbox->SetFillColor(46);
226 TGaxis *cutaxis = new TGaxis(0.02,0.8,0.98,0.8,0,ptcutmax,510,"");
227 cutaxis->SetLabelSize(0.5);
228 cutaxis->SetTitleSize(0.6);
229 cutaxis->SetTitleOffset(0.5);
230 cutaxis->SetTitle("pcut . ");
231 fCutSlider->GetListOfPrimitives()->AddFirst(cutaxis);
233 // Create rapidity cut slider pad
235 fEtaPad = new TPad("EtaSlider", "Eta slider pad",0.97,0,1,0.96);
238 fEtaPad->SetFillColor(22);
239 fEtaPad->SetBorderSize(2);
240 fEtaSlider = new TSlider("etacut","Rapidity cut",0,0,1,1);
241 fEtaSlider->SetObject(this);
242 fEtaSlider->SetFillColor(45);
243 TSliderBox *sbox2 = (TSliderBox*)fEtaSlider->GetListOfPrimitives()->First();
244 sbox2->SetFillColor(46);
246 TGaxis *etaaxis = new TGaxis(0.9,0.02,0.9,0.98,-etacutmax,etacutmax,510,"");
247 etaaxis->SetLabelSize(0.5);
248 etaaxis->SetTitleSize(0.6);
249 etaaxis->SetTitleOffset(0.2);
250 cutaxis->SetTitle("Etacut . ");
251 fEtaSlider->GetListOfPrimitives()->AddFirst(etaaxis);
260 //_____________________________________________________________________________
261 AliDisplay::~AliDisplay()
265 //_____________________________________________________________________________
266 void AliDisplay::Clear(Option_t *)
268 // Delete graphics temporary objects
271 //----------------------------------------------------------------------------
272 void AliDisplay::ShowTrack(Int_t idx) {
273 AliDetector *TPC=(AliDetector*)gAlice->GetModule("TPC");
274 TObjArray *points=TPC->Points();
275 int ntracks=points->GetEntriesFast();
276 for (int track=0;track<ntracks;track++) {
277 AliPoints *pm = (AliPoints*)points->UncheckedAt(track);
279 if (idx == pm->GetIndex()) {
280 pm->SetMarkerColor(2);
281 pm->SetMarkerStyle(22);
285 TClonesArray *particles=gAlice->Particles();
286 TParticle *p = (TParticle*)particles->UncheckedAt(idx);
287 printf("\nTrack index %d\n",idx);
288 printf("Particle ID %d\n",p->GetPdgCode());
289 printf("Parent %d\n",p->GetFirstMother());
290 printf("First child %d\n",p->GetFirstDaughter());
291 printf("Px,Py,Pz %f %f %f\n",p->Px(),p->Py(),p->Pz());
297 //----------------------------------------------------------------------------
298 void AliDisplay::HideTrack(Int_t idx) {
299 AliDetector *TPC=(AliDetector*)gAlice->GetModule("TPC");
300 TObjArray *points=TPC->Points();
301 int ntracks=points->GetEntriesFast();
302 for (int track=0;track<ntracks;track++) {
303 AliPoints *pm = (AliPoints*)points->UncheckedAt(track);
305 if (idx == pm->GetIndex()) {
306 pm->SetMarkerColor(5);
307 pm->SetMarkerStyle(1);
316 //_____________________________________________________________________________
317 void AliDisplay::DisableDetector(const char *name)
319 // Disable detector name from graphics views
321 AliModule *module = (AliModule*)gAlice->Modules()->FindObject(name);
327 //_____________________________________________________________________________
328 void AliDisplay::DisplayButtons()
330 // Create the user interface buttons
332 fButtons = new TPad("buttons", "newpad",0,0.45,0.15,1);
333 fButtons->SetEditable(kFALSE);
335 fButtons->SetFillColor(38);
336 fButtons->SetBorderSize(2);
340 Float_t dbutton = 0.08;
347 char but1[] = "gAlice->Display()->ShowNextEvent(1)";
348 button = new TButton("Next",but1,x0,y-dbutton,x1,y);
349 button->SetFillColor(38);
353 char but2[] = "gAlice->Display()->ShowNextEvent(-1)";
354 button = new TButton("Previous",but2,x0,y-dbutton,x1,y);
355 button->SetFillColor(38);
359 char but3[] = "gAlice->Display()->SetView(90,-90,90)";
360 button = new TButton("Top View",but3,x0,y-dbutton,x1,y);
361 button->SetFillColor(butcolor);
365 char but4[] = "gAlice->Display()->SetView(90,0,-90)";
366 button = new TButton("Side View",but4,x0,y-dbutton,x1,y);
367 button->SetFillColor(butcolor);
371 char but5[] = "gAlice->Display()->SetView(0,-90,0)";
372 button = new TButton("Front View",but5,x0,y-dbutton,x1,y);
373 button->SetFillColor(butcolor);
377 char but6[] = "gAlice->Display()->DrawAllViews()";
378 button = new TButton("All Views",but6,x0,y-dbutton,x1,y);
379 button->SetFillColor(butcolor);
383 char but7[] = "gAlice->Display()->DrawViewGL()";
384 button = new TButton("OpenGL",but7,x0,y-dbutton,x1,y);
385 button->SetFillColor(38);
389 char but8[] = "gAlice->Display()->DrawViewX3D()";
390 button = new TButton("X3D",but8,x0,y-dbutton,x1,y);
391 button->SetFillColor(38);
395 TDiamond *diamond = new TDiamond(0.05,0.015,0.95,0.22);
396 diamond->SetFillColor(50);
397 diamond->SetTextAlign(22);
398 diamond->SetTextColor(5);
399 diamond->SetTextSize(0.11);
401 diamond->AddText(".. ");
402 diamond->AddText("ROOT");
403 diamond->AddText("ALICE");
404 diamond->AddText("... ");
405 diamond->AddText(" ");
408 //______________________________________________________________________________
409 Int_t AliDisplay::DistancetoPrimitive(Int_t px, Int_t)
411 // Compute distance from point px,py to objects in event
413 gPad->SetCursor(kCross);
415 if (gPad == fTrigPad) return 9999;
416 if (gPad == fCutPad) return 9999;
417 if (gPad == fEtaPad) return 9999;
419 const Int_t big = 9999;
421 Float_t xmin = gPad->GetX1();
422 Float_t xmax = gPad->GetX2();
423 Float_t dx = 0.02*(xmax - xmin);
424 Float_t x = gPad->AbsPixeltoX(px);
425 if (x < xmin+dx || x > xmax-dx) return dist;
427 if (fZoomMode) return 0;
431 //_____________________________________________________________________________
432 void AliDisplay::Draw(Option_t *)
434 // Display current event
443 DrawView(fTheta, fPhi, fPsi);
445 // Display the event number and title
450 //_____________________________________________________________________________
451 void AliDisplay::DrawAllViews()
453 // Draw front,top,side and 30 deg views
455 fDrawAllViews = kTRUE;
457 fPad->SetFillColor(15);
473 DrawView(90, -90, 90);
478 DrawView(90, 0, -90);
484 //_____________________________________________________________________________
485 void AliDisplay::DrawHits()
487 // Draw hits for all ALICE detectors
489 Float_t cutmin, cutmax, etamin, etamax, pmom, smin, smax, eta, theta, r;
497 smax = fCutSlider->GetMaximum();
498 smin = fCutSlider->GetMinimum();
499 cutmin = ptcutmax*smin;
500 if (smax < 0.98) cutmax = ptcutmax*smax;
501 else cutmax = 100000;
504 smax = fEtaSlider->GetMaximum();
505 smin = fEtaSlider->GetMinimum();
506 etamin = etacutmax*(2*smin-1);
507 etamax = etacutmax*(2*smax-1);
508 if (smin < 0.02) etamin = -1000;
509 if (smax > 0.98) etamax = 1000;
511 TIter next(gAlice->Modules());
514 while((module = (AliModule*)next())) {
515 if (!module->IsActive()) continue;
516 points = module->Points();
517 if (!points) continue;
518 ntracks = points->GetEntriesFast();
519 for (track=0;track<ntracks;track++) {
520 pm = (AliPoints*)points->UncheckedAt(track);
522 particle = pm->GetParticle();
523 if (!particle) continue;
524 pmom = particle->P();
525 if (pmom < cutmin) continue;
526 if (pmom > cutmax) continue;
527 // as a first approximation, take eta of first point
529 r = TMath::Sqrt(pxyz[0]*pxyz[0] + pxyz[1]*pxyz[1]);
530 theta = TMath::ATan2(r,TMath::Abs(pxyz[2]));
531 if(theta) eta = -TMath::Log(TMath::Tan(0.5*theta)); else eta = 1e10;
532 if (pxyz[2] < 0) eta = -eta;
533 if (eta < etamin || eta > etamax) continue;
535 fHitsCuts += pm->GetN();
540 //_____________________________________________________________________________
541 void AliDisplay::DrawTitle(Option_t *option)
543 // Draw the event title
545 Float_t xmin = gPad->GetX1();
546 Float_t xmax = gPad->GetX2();
547 Float_t ymin = gPad->GetY1();
548 Float_t ymax = gPad->GetY2();
549 Float_t dx = xmax-xmin;
550 Float_t dy = ymax-ymin;
552 if (strlen(option) == 0) {
553 TPaveText *title = new TPaveText(xmin +0.01*dx, ymax-0.09*dy, xmin +0.5*dx, ymax-0.01*dy);
554 title->SetBit(kCanDelete);
555 title->SetFillColor(42);
558 sprintf(ptitle,"Alice event: %d, Run:%d",gAlice->GetHeader()->GetEvent(), gAlice->GetHeader()->GetRun());
559 title->AddText(ptitle);
560 Int_t nparticles = gAlice->Particles()->GetEntriesFast();
561 sprintf(ptitle,"Nparticles = %d Nhits = %d",nparticles, fHitsCuts);
562 title->AddText(ptitle);
564 TPaveLabel *label = new TPaveLabel(xmin +0.01*dx, ymax-0.07*dy, xmin +0.2*dx, ymax-0.01*dy,option);
565 label->SetBit(kCanDelete);
566 label->SetFillColor(42);
571 //_____________________________________________________________________________
572 void AliDisplay::DrawView(Float_t theta, Float_t phi, Float_t psi)
574 // Draw a view of ALICE
576 gPad->SetCursor(kWatch);
577 gPad->SetFillColor(1);
581 TView *view = new TView(1);
582 Float_t range = fRrange*fRangeSlider->GetMaximum();
583 view->SetRange(-range,-range,-range,range, range, range);
590 // Display Alice Geometry
591 gAlice->GetGeometry()->Draw("same");
593 //Loop on all detectors to add their products to the pad
596 // add itself to the list (must be last)
599 view->SetView(phi, theta, psi, iret);
602 //_____________________________________________________________________________
603 void AliDisplay::DrawViewGL()
605 // Draw current view using OPENGL
607 TPad *pad = (TPad*)gPad->GetPadSave();
609 TView *view = pad->GetView();
614 //_____________________________________________________________________________
615 void AliDisplay::DrawViewX3D()
617 // Draw current view using X3D
619 TPad *pad = (TPad*)gPad->GetPadSave();
621 TView *view = pad->GetView();
626 //_____________________________________________________________________________
627 void AliDisplay::EnableDetector(const char *name)
629 // Enable detector name in graphics views
631 AliModule *module = (AliModule*)gAlice->Modules()->FindObject(name);
637 //______________________________________________________________________________
638 void AliDisplay::ExecuteEvent(Int_t event, Int_t px, Int_t py)
640 // Execute action corresponding to the mouse event
642 static Float_t x0, y0, x1, y1;
644 static Int_t pxold, pyold;
645 static Int_t px0, py0;
646 static Int_t linedrawn;
649 if (px == 0 && py == 0) { //when called by sliders
650 if (event == kButton1Up) {
655 if (!fZoomMode && gPad->GetView()) {
656 gPad->GetView()->ExecuteRotateView(event, px, py);
660 // something to zoom ?
661 // fPad->SetCursor(kCross);
662 gPad->SetCursor(kCross);
667 gVirtualX->SetLineColor(-1);
668 gPad->TAttLine::Modify(); //Change line attributes only if necessary
669 x0 = gPad->AbsPixeltoX(px);
670 y0 = gPad->AbsPixeltoY(py);
672 pxold = px; pyold = py;
677 if (linedrawn) gVirtualX->DrawBox(px0, py0, pxold, pyold, TVirtualX::kHollow);
681 gVirtualX->DrawBox(px0, py0, pxold, pyold, TVirtualX::kHollow);
685 gPad->GetCanvas()->FeedbackMode(kFALSE);
686 if (px == px0) return;
687 if (py == py0) return;
688 x1 = gPad->AbsPixeltoX(px);
689 y1 = gPad->AbsPixeltoY(py);
691 if (x1 < x0) {temp = x0; x0 = x1; x1 = temp;}
692 if (y1 < y0) {temp = y0; y0 = y1; y1 = temp;}
693 gPad->Range(x0,y0,x1,y1);
694 if (fZooms < kMAXZOOMS-1) {
696 fZoomX0[fZooms] = x0;
697 fZoomY0[fZooms] = y0;
698 fZoomX1[fZooms] = x1;
699 fZoomY1[fZooms] = y1;
701 gPad->Modified(kTRUE);
707 //___________________________________________
708 void AliDisplay::LoadPoints()
710 // Read hits info and store x,y,z info in arrays fPoints
711 // Loop on all detectors
713 gAlice->ResetPoints();
714 TIter next(gAlice->Modules());
716 Int_t ntracks = gAlice->GetNtrack();
717 for (Int_t track=0; track<ntracks;track++) {
719 gAlice->TreeH()->GetEvent(track);
720 while((module = (AliModule*)next())) {
721 module->LoadPoints(track);
727 //_____________________________________________________________________________
728 void AliDisplay::Paint(Option_t *)
730 // Paint miscellaneous items
734 //_____________________________________________________________________________
735 void AliDisplay::SetPickMode()
739 fArcButton->SetY1(fPickButton->GetYlowNDC()+0.5*fPickButton->GetHNDC());
740 fTrigPad->Modified();
743 //_____________________________________________________________________________
744 void AliDisplay::SetZoomMode()
748 fArcButton->SetY1(fZoomButton->GetYlowNDC()+0.5*fZoomButton->GetHNDC());
749 fTrigPad->Modified();
752 //_____________________________________________________________________________
753 void AliDisplay::SetPTcut(Float_t ptcut)
762 //_____________________________________________________________________________
763 void AliDisplay::SetRange(Float_t rrange, Float_t zrange)
765 // Set view range along R and Z
774 //_____________________________________________________________________________
775 void AliDisplay::SetView(Float_t theta, Float_t phi, Float_t psi)
777 // change viewing angles for current event
780 fDrawAllViews = kFALSE;
786 TView *view = gPad->GetView();
787 if (view) view->SetView(fPhi, fTheta, fPsi, iret);
793 //_____________________________________________________________________________
794 void AliDisplay::ShowNextEvent(Int_t delta)
796 // Display (current event_number+delta)
797 // delta = 1 shown next event
798 // delta = -1 show previous event
802 Int_t current_event = gAlice->GetHeader()->GetEvent();
803 Int_t new_event = current_event + delta;
804 gAlice->GetEvent(new_event);
805 if (!gAlice->TreeH()) return;
812 //______________________________________________________________________________
813 void AliDisplay::UnZoom()
815 if (fZooms <= 0) return;
817 TPad *pad = (TPad*)gPad->GetPadSave();
818 pad->Range(fZoomX0[fZooms],fZoomY0[fZooms], fZoomX1[fZooms],fZoomY1[fZooms]);