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 //////////////////////////////////////////////////////////////////////////
22 // Utility class to display ALICE outline, tracks, hits,.. //
24 //////////////////////////////////////////////////////////////////////////
32 #include <TPaveLabel.h>
33 #include <TPaveText.h>
35 #include <TSliderBox.h>
38 #include <TVirtualX.h>
41 #include "AliDetector.h"
42 #include "AliDisplay.h"
43 #include "AliHeader.h"
44 #include "AliPoints.h"
47 #include "TGeometry.h"
48 #include "TParticle.h"
51 const Float_t AliDisplay::fgkPtCutMax = 2;
52 const Float_t AliDisplay::fgkEtaCutMax = 1.5;
53 const Int_t AliDisplay::fgkMaxZooms = 20;
59 //_______________________________________________________________________
60 AliDisplay::AliDisplay():
90 // Default constructor
94 //_____________________________________________________________________________
95 AliDisplay::AliDisplay(Int_t size):
97 fDrawAllViews(kFALSE),
98 fDrawParticles(kTRUE),
124 // Create an event display object.
125 // A canvas named "edisplay" is created with a vertical size in pixels
127 // A QUICK Overview of the Event Display functions
128 // ===============================================
130 // The event display can ve invoked by executing the macro "display.C"
131 // A canvas like in the picture below will appear.
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.
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.
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.
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.
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.
184 // Click on TPC for example
185 // Click on any variable (eg TPC.fX) to histogram the variable.
187 // If you are lost, you can click on HELP in any Root canvas or browser.
190 <img src="picts/alidisplay.gif">
194 gAlice->SetDisplay(this);
196 // Initialize display default parameters
200 // Create display canvas
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();
207 // Create main display pad
208 fPad = new TPad("viewpad", "Alice display",0.15,0,0.97,0.96);
211 fPad->SetFillColor(1);
212 fPad->SetBorderSize(2);
214 // Create user interface control pad
218 // Create Range and mode pad
221 fTrigPad = new TPad("trigger", "range and mode pad",0,0,dxtr,dytr);
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()";
230 fPickButton = new TButton("Pick",pickmode,0.05,0.32,0.65,0.32+db);
231 fPickButton->SetFillColor(38);
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);
237 fArcButton = new TArc(.8,fZoomButton->GetYlowNDC()+0.5*db,0.33*db);
238 fArcButton->SetFillColor(kGreen);
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);
244 AppendPad(); // append display object as last object to force selection
245 // Create momentum cut slider pad
247 fCutPad = new TPad("cutSlider", "pcut slider pad",dxtr,.96,1,1);
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);
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
267 fEtaPad = new TPad("EtaSlider", "Eta slider pad",0.97,0,1,0.96);
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);
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);
286 fTrigPad->SetEditable(kFALSE);
287 fButtons->SetEditable(kFALSE);
289 fNTracksToDisplay =0;
296 //_______________________________________________________________________
297 AliDisplay::AliDisplay(const AliDisplay &disp):
333 //_____________________________________________________________________________
334 AliDisplay::~AliDisplay()
341 //_____________________________________________________________________________
342 void AliDisplay::Clear(Option_t *)
344 // Delete graphics temporary objects
347 //_____________________________________________________________________________
348 void AliDisplay::Copy(TObject &) const
351 // Copy *this onto disp -- not implemented
353 AliFatal("Not implemented");
356 //----------------------------------------------------------------------------
357 void AliDisplay::ShowTrack(Int_t idx)
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));
368 if (idx == pm->GetIndex()) {
369 pm->SetMarkerColor(2);
370 pm->SetMarkerStyle(22);
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()));
387 //----------------------------------------------------------------------------
388 void AliDisplay::HideTrack(Int_t idx) const
391 // Hide track on display
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));
399 if (idx == pm->GetIndex()) {
400 pm->SetMarkerColor(5);
401 pm->SetMarkerStyle(1);
410 //_____________________________________________________________________________
411 void AliDisplay::DisableDetector(const char *name)
413 // Disable detector name from graphics views
415 AliModule *module = dynamic_cast<AliModule*>(gAlice->Modules()->FindObject(name));
421 //_____________________________________________________________________________
422 void AliDisplay::DisplayButtons()
424 // Create the user interface buttons
426 fButtons = new TPad("buttons", "newpad",0,0.45,0.15,1);
428 fButtons->SetFillColor(38);
429 fButtons->SetBorderSize(2);
433 Float_t dbutton = 0.08;
440 char but1[] = "gAlice->Display()->ShowNextEvent(1)";
441 button = new TButton("Next",but1,x0,y-dbutton,x1,y);
442 button->SetFillColor(38);
446 char but2[] = "gAlice->Display()->ShowNextEvent(-1)";
447 button = new TButton("Previous",but2,x0,y-dbutton,x1,y);
448 button->SetFillColor(38);
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);
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);
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);
470 char but6[] = "gAlice->Display()->DrawAllViews()";
471 button = new TButton("All Views",but6,x0,y-dbutton,x1,y);
472 button->SetFillColor(butcolor);
476 char but7[] = "gAlice->Display()->DrawViewGL()";
477 button = new TButton("OpenGL",but7,x0,y-dbutton,x1,y);
478 button->SetFillColor(38);
482 char but8[] = "gAlice->Display()->DrawViewX3D()";
483 button = new TButton("X3D",but8,x0,y-dbutton,x1,y);
484 button->SetFillColor(38);
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);
494 diamond->AddText(".. ");
495 diamond->AddText("ROOT");
496 diamond->AddText("ALICE");
497 diamond->AddText("... ");
498 diamond->AddText(" ");
501 //______________________________________________________________________________
502 Int_t AliDisplay::DistancetoPrimitive(Int_t px, Int_t)
504 // Compute distance from point px,py to objects in event
506 gPad->SetCursor(kCross);
508 if (gPad == fTrigPad) return 9999;
509 if (gPad == fCutPad) return 9999;
510 if (gPad == fEtaPad) return 9999;
512 const Int_t kbig = 9999;
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;
520 if (fZoomMode) return 0;
524 //_____________________________________________________________________________
525 void AliDisplay::Draw(Option_t *)
527 // Display current event
536 DrawView(fTheta, fPhi, fPsi);
538 // Display the event number and title
543 //_____________________________________________________________________________
544 void AliDisplay::DrawAllViews()
546 // Draw front,top,side and 30 deg views
548 fDrawAllViews = kTRUE;
550 fPad->SetFillColor(15);
566 DrawView(90, -90, 90);
571 DrawView(90, 0, -90);
577 //_____________________________________________________________________________
578 void AliDisplay::DrawHits()
580 // Draw hits for all ALICE detectors
582 Float_t cutmin, cutmax, etamin, etamax, pmom, smin, smax, eta, theta, r;
590 smax = fCutSlider->GetMaximum();
591 smin = fCutSlider->GetMinimum();
592 cutmin = fgkPtCutMax*smin;
593 if (smax < 0.98) cutmax = fgkPtCutMax*smax;
594 else cutmax = 100000;
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;
604 TIter next(gAlice->Modules());
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));
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
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;
628 fHitsCuts += pm->GetN();
633 //_____________________________________________________________________________
634 void AliDisplay::DrawTitle(Option_t *option)
636 // Draw the event title
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;
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);
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);
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);
664 //_____________________________________________________________________________
665 void AliDisplay::DrawView(Float_t theta, Float_t phi, Float_t psi)
667 // Draw a view of ALICE
669 gPad->SetCursor(kWatch);
670 gPad->SetFillColor(1);
674 TView *view = new TView(1);
675 Float_t range = fRrange*fRangeSlider->GetMaximum();
676 view->SetRange(-range,-range,-range,range, range, range);
683 // Display Alice Geometry
684 gAlice->GetGeometry()->Draw("same");
686 //Loop on all detectors to add their products to the pad
689 // add itself to the list (must be last)
692 view->SetView(phi, theta, psi, iret);
695 //_____________________________________________________________________________
696 void AliDisplay::DrawViewGL()
698 // Draw current view using OPENGL
700 TPad *pad = dynamic_cast<TPad*>(gPad->GetPadSave());
702 TView *view = pad->GetView();
707 //_____________________________________________________________________________
708 void AliDisplay::DrawViewX3D()
710 // Draw current view using X3D
712 TPad *pad = dynamic_cast<TPad*>(gPad->GetPadSave());
714 TView *view = pad->GetView();
719 //_____________________________________________________________________________
720 void AliDisplay::EnableDetector(const char *name)
722 // Enable detector name in graphics views
724 AliModule *module = dynamic_cast<AliModule*>(gAlice->Modules()->FindObject(name));
730 //______________________________________________________________________________
731 void AliDisplay::ExecuteEvent(Int_t event, Int_t px, Int_t py)
733 // Execute action corresponding to the mouse event
735 static Float_t x0, y0, x1, y1;
737 static Int_t pxold, pyold;
738 static Int_t px0, py0;
739 static Int_t linedrawn;
742 if (px == 0 && py == 0) { //when called by sliders
743 if (event == kButton1Up) {
748 if (!fZoomMode && gPad->GetView()) {
749 gPad->GetView()->ExecuteRotateView(event, px, py);
753 // something to zoom ?
754 // fPad->SetCursor(kCross);
755 gPad->SetCursor(kCross);
760 gVirtualX->SetLineColor(-1);
761 gPad->TAttLine::Modify(); //Change line attributes only if necessary
762 x0 = gPad->AbsPixeltoX(px);
763 y0 = gPad->AbsPixeltoY(py);
765 pxold = px; pyold = py;
770 if (linedrawn) gVirtualX->DrawBox(px0, py0, pxold, pyold, TVirtualX::kHollow);
774 gVirtualX->DrawBox(px0, py0, pxold, pyold, TVirtualX::kHollow);
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);
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) {
789 fZoomX0[fZooms] = x0;
790 fZoomY0[fZooms] = y0;
791 fZoomX1[fZooms] = x1;
792 fZoomY1[fZooms] = y1;
794 gPad->Modified(kTRUE);
801 void AliDisplay::SetTracksToDisplay(Int_t *tracks, Int_t n){
803 // set tracks to display - MI
804 fTracksToDisplay = tracks;
805 fNTracksToDisplay = n;
807 //___________________________________________
808 void AliDisplay::LoadPoints()
810 // Read hits info and store x,y,z info in arrays fPoints
811 // Loop on all detectors
813 gAlice->ResetPoints();
814 TIter next(gAlice->Modules());
816 Int_t ntracks = gAlice->GetMCApp()->GetNtrack();
818 while((module = (AliModule*)next()))
820 AliDetector* detector = dynamic_cast<AliDetector*>(module);
821 if(detector) detector->SetTreeAddress();
825 // load only wanted tracks
826 if (fNTracksToDisplay>0)
828 Int_t nprim = gAlice->Stack()->GetNprimary();
829 for (Int_t track=0; track<fNTracksToDisplay;track++)
832 Int_t nev = nprim-1-gAlice->GetMCApp()->GetPrimary(fTracksToDisplay[track]);
833 while((module = (AliModule*)next()))
835 AliDetector* detector = dynamic_cast<AliDetector*>(module);
838 detector->TreeH()->GetEvent(nev);
839 module->LoadPoints(nprim-1-gAlice->GetMCApp()->GetPrimary(fTracksToDisplay[track]));
848 for (Int_t track=0; track<ntracks;track++) {
850 while((module = (AliModule*)next())) {
851 AliDetector* detector = dynamic_cast<AliDetector*>(module);
854 if (detector->TreeH()->GetEvent(track))
855 detector->LoadPoints(track);
863 //_____________________________________________________________________________
864 void AliDisplay::Paint(Option_t *)
866 // Paint miscellaneous items
870 //_____________________________________________________________________________
871 void AliDisplay::SetPickMode()
874 // Set Pick Mode -- disable zoom
878 fArcButton->SetY1(fPickButton->GetYlowNDC()+0.5*fPickButton->GetHNDC());
879 fTrigPad->Modified();
882 //_____________________________________________________________________________
883 void AliDisplay::SetZoomMode()
886 // Set Zoom Mode -- disable pick
890 fArcButton->SetY1(fZoomButton->GetYlowNDC()+0.5*fZoomButton->GetHNDC());
891 fTrigPad->Modified();
894 //_____________________________________________________________________________
895 void AliDisplay::SetPTcut(Float_t ptcut)
907 //_____________________________________________________________________________
908 void AliDisplay::SetRange(Float_t rrange, Float_t zrange)
910 // Set view range along R and Z
919 //_____________________________________________________________________________
920 void AliDisplay::SetView(Float_t theta, Float_t phi, Float_t psi)
922 // change viewing angles for current event
925 fDrawAllViews = kFALSE;
931 TView *view = gPad->GetView();
932 if (view) view->SetView(fPhi, fTheta, fPsi, iret);
938 //_____________________________________________________________________________
939 void AliDisplay::ShowNextEvent(Int_t delta)
941 // Display (current event_number+delta)
942 // delta = 1 shown next event
943 // delta = -1 show previous event
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));
959 //______________________________________________________________________________
960 void AliDisplay::UnZoom()
965 if (fZooms <= 0) return;
967 TPad *pad = dynamic_cast<TPad*>(gPad->GetPadSave());
968 pad->Range(fZoomX0[fZooms],fZoomY0[fZooms], fZoomX1[fZooms],fZoomY1[fZooms]);
972 //_____________________________________________________________________________
973 AliDisplay & AliDisplay::operator=(const AliDisplay &disp)
976 // Assignment operator