2 //////////////////////////////////////////////////////////////////////////
6 // Utility class to display ALICE outline, tracks, hits,.. //
8 //////////////////////////////////////////////////////////////////////////
16 #include <TPolyMarker3D.h>
17 #include <TPaveLabel.h>
18 #include <TPaveText.h>
25 #include <TSliderBox.h>
29 #include <X3DBuffer.h>
32 #include "AliDetector.h"
33 #include "AliDisplay.h"
34 #include "AliPoints.h"
35 #include "TParticle.h"
37 const Float_t ptcutmax = 2;
38 const Float_t etacutmax = 1.5;
43 //_____________________________________________________________________________
44 AliDisplay::AliDisplay()
49 //_____________________________________________________________________________
50 AliDisplay::AliDisplay(Int_t size)
52 // Create an event display object.
53 // A canvas named "edisplay" is created with a vertical size in pixels
55 // A QUICK Overview of the Event Display functions
56 // ===============================================
58 // The event display can ve invoked by executing the macro "display.C"
59 // A canvas like in the picture below will appear.
61 // On the left side of the canvas, the following buttons appear:
62 // *Next* to move to the next event
63 // *Previous* to move to the previous event
64 // *Top View* to display a top view of the current event
65 // *Side View* to display a side view of the current event
66 // *Front View* to display a front view of the current event
67 // *All Views* to display front/side/top/30-30 views of the current event
68 // *OpenGL* to use OpenGl to view the current event.
69 // Note that OpenGL cannot be used across the network.
70 // Before using OpenGL, load the GL libraries
71 // by executing the macro GL.C (in $ROOTSYS/macros/GL.C.
72 // Once in GL, click the HELP button of the GL canvas.
73 // *X3D* to use X3D to view the current event (Unix only).
74 // Once in X3D, type M to see the list of all possible options.
75 // for example type J to zoom, K to unzoom
76 // use the mouse to rotate.
77 // *Pick* Select this option to be able to point on a track with the
78 // mouse. Once on the track, use the right button to select
79 // an action. For example, select SetMarkerAttributes to
80 // change the marker type/color/size for the track.
81 // *Zoom* Select this option (default) if you want to zoom.
82 // To zoom, simply select the selected area with the left button.
83 // *UnZoom* To revert to the previous picture size.
85 // slider R On the left side, the vertical slider can be used to
86 // set the default picture size.
87 // slider pcut At the top of the canvas, a slider can be used to change
88 // the momentum cut (or range) to display tracks.
89 // slider eta On the right side of the canvas, a vertical slider can be used
90 // to specify a rapidity range for the tracks.
92 // When you are in Zoom mode, you can click on the black part of the canvas
93 // to select special options with the right mouse button.
94 // This will display a pop-up menu with items like:
96 // *Enable detector*, etc.
97 // For example select "Disable detector". You get a dialog box.
98 // Diable detector TRD for example.
100 // When you are in pick mode, you can "Inspect" the object pointed by the mouse.
101 // When you are on a track, select the menu item "InspectParticle"
102 // to display the current particle attributes.
104 // You can activate the Root browser by selecting the Inspect menu
105 // in the canvas tool bar menu. Then select "Start Browser"
106 // This will open a new canvas with the browser. At this point, you may want
107 // to display some histograms (from the Trees). Go to the "File" menu
108 // of the browser and click on "New canvas".
109 // In the browser, click on item "ROOT files" in the left pane.
110 // Click on galice.root.
112 // Click on TPC for example
113 // Click on any variable (eg TPC.fX) to histogram the variable.
115 // If you are lost, you can click on HELP in any Root canvas or browser.
118 <img src="picts/alidisplay.gif">
123 gAlice->SetDisplay(this);
125 // Initialize display default parameters
129 // Set front view by default
133 fDrawAllViews = kFALSE;
135 fDrawParticles = kTRUE;
140 // Create display canvas
142 if (ysize < 100) ysize = 750;
143 Int_t xsize = Int_t(size*830./ysize);
144 fCanvas = new TCanvas("Canvas", "ALICE Event Display",14,47,xsize,ysize);
145 fCanvas->SetEditable(kIsNotEditable);
146 fCanvas->ToggleEventStatus();
148 // Create main display pad
149 fPad = new TPad("viewpad", "Alice display",0.15,0,0.97,0.96);
152 fPad->SetFillColor(1);
153 fPad->SetBorderSize(2);
155 // Create user interface control pad
159 // Create Range and mode pad
162 fTrigPad = new TPad("trigger", "range and mode pad",0,0,dxtr,dytr);
165 fTrigPad->SetFillColor(22);
166 fTrigPad->SetBorderSize(2);
167 fRangeSlider = new TSlider("range","range",0.7,0.42,0.9,0.98);
168 fRangeSlider->SetObject(this);
169 char pickmode[] = "gAlice->Display()->SetPickMode()";
171 fPickButton = new TButton("Pick",pickmode,0.05,0.32,0.65,0.32+db);
172 fPickButton->SetFillColor(38);
174 char zoommode[] = "gAlice->Display()->SetZoomMode()";
175 fZoomButton = new TButton("Zoom",zoommode,0.05,0.21,0.65,0.21+db);
176 fZoomButton->SetFillColor(38);
178 fArcButton = new TArc(.8,fZoomButton->GetYlowNDC()+0.5*db,0.33*db);
179 fArcButton->SetFillColor(kGreen);
181 char butUnzoom[] = "gAlice->Display()->UnZoom()";
182 TButton *button = new TButton("UnZoom",butUnzoom,0.05,0.05,0.95,0.15);
183 button->SetFillColor(38);
185 AppendPad(); // append display object as last object to force selection
187 // Create momentum cut slider pad
189 fCutPad = new TPad("cutSlider", "pcut slider pad",dxtr,.96,1,1);
192 fCutPad->SetFillColor(22);
193 fCutPad->SetBorderSize(2);
194 fCutSlider = new TSlider("pcut","Momentum cut",0,0,1,1);
195 fCutSlider->SetRange(fPTcut/ptcutmax,1);
196 fCutSlider->SetObject(this);
197 fCutSlider->SetFillColor(45);
198 TSliderBox *sbox = (TSliderBox*)fCutSlider->GetListOfPrimitives()->First();
199 sbox->SetFillColor(46);
201 TGaxis *cutaxis = new TGaxis(0.02,0.8,0.98,0.8,0,ptcutmax,510,"");
202 cutaxis->SetLabelSize(0.5);
203 cutaxis->SetTitleSize(0.6);
204 cutaxis->SetTitleOffset(0.5);
205 cutaxis->SetTitle("pcut . ");
206 fCutSlider->GetListOfPrimitives()->AddFirst(cutaxis);
208 // Create rapidity cut slider pad
210 fEtaPad = new TPad("EtaSlider", "Eta slider pad",0.97,0,1,0.96);
213 fEtaPad->SetFillColor(22);
214 fEtaPad->SetBorderSize(2);
215 fEtaSlider = new TSlider("etacut","Rapidity cut",0,0,1,1);
216 fEtaSlider->SetObject(this);
217 fEtaSlider->SetFillColor(45);
218 TSliderBox *sbox2 = (TSliderBox*)fEtaSlider->GetListOfPrimitives()->First();
219 sbox2->SetFillColor(46);
221 TGaxis *etaaxis = new TGaxis(0.9,0.02,0.9,0.98,-etacutmax,etacutmax,510,"");
222 etaaxis->SetLabelSize(0.5);
223 etaaxis->SetTitleSize(0.6);
224 etaaxis->SetTitleOffset(0.2);
225 cutaxis->SetTitle("Etacut . ");
226 fEtaSlider->GetListOfPrimitives()->AddFirst(etaaxis);
235 //_____________________________________________________________________________
236 AliDisplay::~AliDisplay()
240 //_____________________________________________________________________________
241 void AliDisplay::Clear(Option_t *)
243 // Delete graphics temporary objects
246 //----------------------------------------------------------------------------
247 void AliDisplay::ShowTrack(Int_t idx) {
248 AliDetector *TPC=(AliDetector*)gAlice->GetModule("TPC");
249 TObjArray *points=TPC->Points();
250 int ntracks=points->GetEntriesFast();
251 for (int track=0;track<ntracks;track++) {
252 AliPoints *pm = (AliPoints*)points->UncheckedAt(track);
254 if (idx == pm->GetIndex()) {
255 pm->SetMarkerColor(2);
256 pm->SetMarkerStyle(22);
260 TClonesArray *particles=gAlice->Particles();
261 TParticle *p = (TParticle*)particles->UncheckedAt(idx);
262 printf("\nTrack index %d\n",idx);
263 printf("Particle ID %d\n",p->GetPdgCode());
264 printf("Parent %d\n",p->GetFirstMother());
265 printf("First child %d\n",p->GetFirstDaughter());
266 printf("Px,Py,Pz %f %f %f\n",p->Px(),p->Py(),p->Pz());
272 //----------------------------------------------------------------------------
273 void AliDisplay::HideTrack(Int_t idx) {
274 AliDetector *TPC=(AliDetector*)gAlice->GetModule("TPC");
275 TObjArray *points=TPC->Points();
276 int ntracks=points->GetEntriesFast();
277 for (int track=0;track<ntracks;track++) {
278 AliPoints *pm = (AliPoints*)points->UncheckedAt(track);
280 if (idx == pm->GetIndex()) {
281 pm->SetMarkerColor(5);
282 pm->SetMarkerStyle(1);
291 //_____________________________________________________________________________
292 void AliDisplay::DisableDetector(const char *name)
294 // Disable detector name from graphics views
296 AliModule *module = (AliModule*)gAlice->Modules()->FindObject(name);
302 //_____________________________________________________________________________
303 void AliDisplay::DisplayButtons()
305 // Create the user interface buttons
307 fButtons = new TPad("buttons", "newpad",0,0.45,0.15,1);
309 fButtons->SetFillColor(38);
310 fButtons->SetBorderSize(2);
314 Float_t dbutton = 0.08;
321 char but1[] = "gAlice->Display()->ShowNextEvent(1)";
322 button = new TButton("Next",but1,x0,y-dbutton,x1,y);
323 button->SetFillColor(38);
327 char but2[] = "gAlice->Display()->ShowNextEvent(-1)";
328 button = new TButton("Previous",but2,x0,y-dbutton,x1,y);
329 button->SetFillColor(38);
333 char but3[] = "gAlice->Display()->SetView(90,-90,90)";
334 button = new TButton("Top View",but3,x0,y-dbutton,x1,y);
335 button->SetFillColor(butcolor);
339 char but4[] = "gAlice->Display()->SetView(90,0,-90)";
340 button = new TButton("Side View",but4,x0,y-dbutton,x1,y);
341 button->SetFillColor(butcolor);
345 char but5[] = "gAlice->Display()->SetView(0,-90,0)";
346 button = new TButton("Front View",but5,x0,y-dbutton,x1,y);
347 button->SetFillColor(butcolor);
351 char but6[] = "gAlice->Display()->DrawAllViews()";
352 button = new TButton("All Views",but6,x0,y-dbutton,x1,y);
353 button->SetFillColor(butcolor);
357 char but7[] = "gAlice->Display()->DrawViewGL()";
358 button = new TButton("OpenGL",but7,x0,y-dbutton,x1,y);
359 button->SetFillColor(38);
363 char but8[] = "gAlice->Display()->DrawViewX3D()";
364 button = new TButton("X3D",but8,x0,y-dbutton,x1,y);
365 button->SetFillColor(38);
369 TDiamond *diamond = new TDiamond(0.05,0.015,0.95,0.22);
370 diamond->SetFillColor(50);
371 diamond->SetTextAlign(22);
372 diamond->SetTextColor(5);
373 diamond->SetTextSize(0.11);
375 diamond->AddText(".. ");
376 diamond->AddText("ROOT");
377 diamond->AddText("ALICE");
378 diamond->AddText("... ");
379 diamond->AddText(" ");
382 //______________________________________________________________________________
383 Int_t AliDisplay::DistancetoPrimitive(Int_t px, Int_t)
385 // Compute distance from point px,py to objects in event
387 gPad->SetCursor(kCross);
389 if (gPad == fTrigPad) return 9999;
390 if (gPad == fCutPad) return 9999;
391 if (gPad == fEtaPad) return 9999;
393 const Int_t big = 9999;
395 Float_t xmin = gPad->GetX1();
396 Float_t xmax = gPad->GetX2();
397 Float_t dx = 0.02*(xmax - xmin);
398 Float_t x = gPad->AbsPixeltoX(px);
399 if (x < xmin+dx || x > xmax-dx) return dist;
401 if (fZoomMode) return 0;
405 //_____________________________________________________________________________
406 void AliDisplay::Draw(Option_t *)
408 // Display current event
417 DrawView(fTheta, fPhi, fPsi);
419 // Display the event number and title
424 //_____________________________________________________________________________
425 void AliDisplay::DrawAllViews()
427 // Draw front,top,side and 30 deg views
429 fDrawAllViews = kTRUE;
431 fPad->SetFillColor(15);
447 DrawView(90, -90, 90);
452 DrawView(90, 0, -90);
458 //_____________________________________________________________________________
459 void AliDisplay::DrawHits()
461 // Draw hits for all ALICE detectors
463 Float_t cutmin, cutmax, etamin, etamax, pmom, smin, smax, eta, theta, r;
471 smax = fCutSlider->GetMaximum();
472 smin = fCutSlider->GetMinimum();
473 cutmin = ptcutmax*smin;
474 if (smax < 0.98) cutmax = ptcutmax*smax;
475 else cutmax = 100000;
478 smax = fEtaSlider->GetMaximum();
479 smin = fEtaSlider->GetMinimum();
480 etamin = etacutmax*(2*smin-1);
481 etamax = etacutmax*(2*smax-1);
482 if (smin < 0.02) etamin = -1000;
483 if (smax > 0.98) etamax = 1000;
485 TIter next(gAlice->Modules());
488 while((module = (AliModule*)next())) {
489 if (!module->IsActive()) continue;
490 points = module->Points();
491 if (!points) continue;
492 ntracks = points->GetEntriesFast();
493 for (track=0;track<ntracks;track++) {
494 pm = (AliPoints*)points->UncheckedAt(track);
496 particle = pm->GetParticle();
497 if (!particle) continue;
498 pmom = particle->P();
499 if (pmom < cutmin) continue;
500 if (pmom > cutmax) continue;
501 // as a first approximation, take eta of first point
503 r = TMath::Sqrt(pxyz[0]*pxyz[0] + pxyz[1]*pxyz[1]);
504 theta = TMath::ATan2(r,TMath::Abs(pxyz[2]));
505 if(theta) eta = -TMath::Log(TMath::Tan(0.5*theta)); else eta = 1e10;
506 if (pxyz[2] < 0) eta = -eta;
507 if (eta < etamin || eta > etamax) continue;
509 fHitsCuts += pm->GetN();
514 //_____________________________________________________________________________
515 void AliDisplay::DrawTitle(Option_t *option)
517 // Draw the event title
519 Float_t xmin = gPad->GetX1();
520 Float_t xmax = gPad->GetX2();
521 Float_t ymin = gPad->GetY1();
522 Float_t ymax = gPad->GetY2();
523 Float_t dx = xmax-xmin;
524 Float_t dy = ymax-ymin;
526 if (strlen(option) == 0) {
527 TPaveText *title = new TPaveText(xmin +0.01*dx, ymax-0.09*dy, xmin +0.5*dx, ymax-0.01*dy);
528 title->SetBit(kCanDelete);
529 title->SetFillColor(42);
532 sprintf(ptitle,"Alice event: %d, Run:%d",gAlice->GetHeader()->GetEvent(), gAlice->GetHeader()->GetRun());
533 title->AddText(ptitle);
534 Int_t nparticles = gAlice->Particles()->GetEntriesFast();
535 sprintf(ptitle,"Nparticles = %d Nhits = %d",nparticles, fHitsCuts);
536 title->AddText(ptitle);
538 TPaveLabel *label = new TPaveLabel(xmin +0.01*dx, ymax-0.07*dy, xmin +0.2*dx, ymax-0.01*dy,option);
539 label->SetBit(kCanDelete);
540 label->SetFillColor(42);
545 //_____________________________________________________________________________
546 void AliDisplay::DrawView(Float_t theta, Float_t phi, Float_t psi)
548 // Draw a view of ALICE
550 gPad->SetCursor(kWatch);
551 gPad->SetFillColor(1);
555 TView *view = new TView(1);
556 Float_t range = fRrange*fRangeSlider->GetMaximum();
557 view->SetRange(-range,-range,-range,range, range, range);
564 // Display Alice Geometry
565 gAlice->GetGeometry()->Draw("same");
567 //Loop on all detectors to add their products to the pad
570 // add itself to the list (must be last)
573 view->SetView(phi, theta, psi, iret);
576 //_____________________________________________________________________________
577 void AliDisplay::DrawViewGL()
579 // Draw current view using OPENGL
581 TPad *pad = (TPad*)gPad->GetPadSave();
583 TView *view = pad->GetView();
588 //_____________________________________________________________________________
589 void AliDisplay::DrawViewX3D()
591 // Draw current view using X3D
593 TPad *pad = (TPad*)gPad->GetPadSave();
595 TView *view = pad->GetView();
600 //_____________________________________________________________________________
601 void AliDisplay::EnableDetector(const char *name)
603 // Enable detector name in graphics views
605 AliModule *module = (AliModule*)gAlice->Modules()->FindObject(name);
611 //______________________________________________________________________________
612 void AliDisplay::ExecuteEvent(Int_t event, Int_t px, Int_t py)
614 // Execute action corresponding to the mouse event
616 static Float_t x0, y0, x1, y1;
618 static Int_t pxold, pyold;
619 static Int_t px0, py0;
620 static Int_t linedrawn;
623 if (px == 0 && py == 0) { //when called by sliders
624 if (event == kButton1Up) {
629 if (!fZoomMode && gPad->GetView()) {
630 gPad->GetView()->ExecuteRotateView(event, px, py);
634 // something to zoom ?
635 // fPad->SetCursor(kCross);
636 gPad->SetCursor(kCross);
641 gGXW->SetLineColor(-1);
642 gPad->TAttLine::Modify(); //Change line attributes only if necessary
643 x0 = gPad->AbsPixeltoX(px);
644 y0 = gPad->AbsPixeltoY(py);
646 pxold = px; pyold = py;
651 if (linedrawn) gGXW->DrawBox(px0, py0, pxold, pyold, TGXW::kHollow);
655 gGXW->DrawBox(px0, py0, pxold, pyold, TGXW::kHollow);
659 gPad->GetCanvas()->FeedbackMode(kFALSE);
660 if (px == px0) return;
661 if (py == py0) return;
662 x1 = gPad->AbsPixeltoX(px);
663 y1 = gPad->AbsPixeltoY(py);
665 if (x1 < x0) {temp = x0; x0 = x1; x1 = temp;}
666 if (y1 < y0) {temp = y0; y0 = y1; y1 = temp;}
667 gPad->Range(x0,y0,x1,y1);
668 if (fZooms < kMAXZOOMS-1) {
670 fZoomX0[fZooms] = x0;
671 fZoomY0[fZooms] = y0;
672 fZoomX1[fZooms] = x1;
673 fZoomY1[fZooms] = y1;
675 gPad->Modified(kTRUE);
681 //___________________________________________
682 void AliDisplay::LoadPoints()
684 // Read hits info and store x,y,z info in arrays fPoints
685 // Loop on all detectors
687 gAlice->ResetPoints();
688 TIter next(gAlice->Modules());
690 Int_t ntracks = gAlice->GetNtrack();
691 for (Int_t track=0; track<ntracks;track++) {
693 gAlice->TreeH()->GetEvent(track);
694 while((module = (AliModule*)next())) {
695 module->LoadPoints(track);
701 //_____________________________________________________________________________
702 void AliDisplay::Paint(Option_t *)
704 // Paint miscellaneous items
708 //_____________________________________________________________________________
709 void AliDisplay::SetPickMode()
713 fArcButton->SetY1(fPickButton->GetYlowNDC()+0.5*fPickButton->GetHNDC());
714 fTrigPad->Modified();
717 //_____________________________________________________________________________
718 void AliDisplay::SetZoomMode()
722 fArcButton->SetY1(fZoomButton->GetYlowNDC()+0.5*fZoomButton->GetHNDC());
723 fTrigPad->Modified();
726 //_____________________________________________________________________________
727 void AliDisplay::SetPTcut(Float_t ptcut)
736 //_____________________________________________________________________________
737 void AliDisplay::SetRange(Float_t rrange, Float_t zrange)
739 // Set view range along R and Z
748 //_____________________________________________________________________________
749 void AliDisplay::SetView(Float_t theta, Float_t phi, Float_t psi)
751 // change viewing angles for current event
754 fDrawAllViews = kFALSE;
760 TView *view = gPad->GetView();
761 if (view) view->SetView(fPhi, fTheta, fPsi, iret);
767 //_____________________________________________________________________________
768 void AliDisplay::ShowNextEvent(Int_t delta)
770 // Display (current event_number+delta)
771 // delta = 1 shown next event
772 // delta = -1 show previous event
776 Int_t current_event = gAlice->GetHeader()->GetEvent();
777 Int_t new_event = current_event + delta;
778 gAlice->GetEvent(new_event);
779 if (!gAlice->TreeH()) return;
786 //______________________________________________________________________________
787 void AliDisplay::UnZoom()
789 if (fZooms <= 0) return;
791 TPad *pad = (TPad*)gPad->GetPadSave();
792 pad->Range(fZoomX0[fZooms],fZoomY0[fZooms], fZoomX1[fZooms],fZoomY1[fZooms]);