2 //////////////////////////////////////////////////////////////////////////
6 // Utility class to display ALICE outline, tracks, hits,.. //
8 //////////////////////////////////////////////////////////////////////////
17 #include <TPolyMarker3D.h>
18 #include <TPolyMarker.h>
19 #include <TPaveLabel.h>
20 #include <TPaveText.h>
27 #include <TSliderBox.h>
31 #include <X3DBuffer.h>
34 #include "AliDetector.h"
36 #include "AliMUONConst.h"
37 #include "AliMUONdisplay.h"
38 #include "AliMUONpoints.h"
39 #include "GParticle.h"
42 ClassImp(AliMUONdisplay)
45 //_____________________________________________________________________________
46 AliMUONdisplay::AliMUONdisplay()
53 //_____________________________________________________________________________
54 AliMUONdisplay::AliMUONdisplay(Int_t size)
56 // Create an event display object.
57 // A canvas named "edisplay" is created with a vertical size in pixels
59 // A QUICK Overview of the Event Display functions
60 // ===============================================
62 // The event display can ve invoked by executing the macro "display.C"
63 // A canvas like in the picture below will appear.
65 // On the left side of the canvas, the following buttons appear:
66 // *Next* to move to the next event
67 // *Previous* to move to the previous event
69 // *Pick* Select this option to be able to point on a track with the
70 // mouse. Once on the track, use the right button to select
71 // an action. For example, select SetMarkerAttributes to
72 // change the marker type/color/size for the track.
73 // *Zoom* Select this option (default) if you want to zoom.
74 // To zoom, simply select the selected area with the left button.
75 // *UnZoom* To revert to the previous picture size.
77 // slider R On the left side, the vertical slider can be used to
78 // set the default picture size.
80 // When you are in Zoom mode, you can click on the black part of the canvas
81 // to select special options with the right mouse button.
84 // When you are in pick mode, you can "Inspect" the object pointed by the mouse.
85 // When you are on a track, select the menu item "InspectParticle"
86 // to display the current particle attributes.
88 // You can activate the Root browser by selecting the Inspect menu
89 // in the canvas tool bar menu. Then select "Start Browser"
90 // This will open a new canvas with the browser. At this point, you may want
91 // to display some histograms (from the Trees). Go to the "File" menu
92 // of the browser and click on "New canvas".
93 // In the browser, click on item "ROOT files" in the left pane.
94 // Click on galice.root.
96 // Click on TPC for example
97 // Click on any variable (eg TPC.fX) to histogram the variable.
99 // If you are lost, you can click on HELP in any Root canvas or browser.
102 <img src="gif/aliMUONdisplay.gif">
109 gAlice->SetDisplay(this);
111 // Initialize display default parameters
114 // Set front view by default
121 fDrawClusters = kTRUE;
129 // Create display canvas
131 if (ysize < 100) ysize = 750;
132 Int_t xsize = Int_t(size*830./ysize);
133 fCanvas = new TCanvas("Canvas", "MUON Clusters Display",14,47,xsize,ysize);
134 fCanvas->SetEditable(kIsNotEditable);
135 fCanvas->ToggleEventStatus();
137 // Create main display pad
138 fPad = new TPad("viewpad", "MUON display",0.15,0,0.9,1);
141 fPad->SetFillColor(1);
142 fPad->SetBorderSize(2);
147 fColPad = new TPad("colpad", "Colors pad",0.9,0,1,1);
150 fColPad->SetFillColor(19);
151 fColPad->SetBorderSize(2);
157 // Create user interface control pad
161 // Create Range and mode pad
164 fTrigPad = new TPad("trigger", "range and mode pad",0,0,dxtr,dytr);
167 fTrigPad->SetFillColor(22);
168 fTrigPad->SetBorderSize(2);
169 fRangeSlider = new TSlider("range","range",0.7,0.42,0.9,0.98);
170 fRangeSlider->SetObject(this);
171 char pickmode[] = "gAlice->Display()->SetPickMode()";
173 fPickButton = new TButton("Pick",pickmode,0.05,0.32,0.65,0.32+db);
174 fPickButton->SetFillColor(38);
176 char zoommode[] = "gAlice->Display()->SetZoomMode()";
177 fZoomButton = new TButton("Zoom",zoommode,0.05,0.21,0.65,0.21+db);
178 fZoomButton->SetFillColor(38);
180 fArcButton = new TArc(.8,fZoomButton->GetYlowNDC()+0.5*db,0.33*db);
181 fArcButton->SetFillColor(kGreen);
183 char butUnzoom[] = "gAlice->Display()->UnZoom()";
184 TButton *button = new TButton("UnZoom",butUnzoom,0.05,0.05,0.95,0.15);
185 button->SetFillColor(38);
187 AppendPad(); // append display object as last object to force selection
194 //_____________________________________________________________________________
195 AliMUONdisplay::~AliMUONdisplay()
197 // Delete space point structure
198 if (fPoints) fPoints->Delete();
202 if (fPhits) fPhits->Delete();
207 //_____________________________________________________________________________
208 void AliMUONdisplay::Clear(Option_t *)
210 // Delete graphics temporary objects
213 //_____________________________________________________________________________
214 void AliMUONdisplay::DisplayButtons()
216 // Create the user interface buttons
219 fButtons = new TPad("buttons", "newpad",0,0.45,0.15,1);
221 fButtons->SetFillColor(38);
222 fButtons->SetBorderSize(2);
225 // Int_t butcolor = 33;
226 Float_t dbutton = 0.08;
233 char but1[] = "gAlice->Display()->ShowNextEvent(1)";
234 button = new TButton("Next",but1,x0,y-dbutton,x1,y);
235 button->SetFillColor(38);
239 char but2[] = "gAlice->Display()->ShowNextEvent(-1)";
240 button = new TButton("Previous",but2,x0,y-dbutton,x1,y);
241 button->SetFillColor(38);
245 char but3[] = "gAlice->Display()->SetChamberAndCathode(1,1)";
246 button = new TButton("Cham&Cath",but3,x0,y-dbutton,x1,y);
247 button->SetFillColor(butcolor);
251 TDiamond *diamond = new TDiamond(0.05,0.015,0.95,0.22);
252 diamond->SetFillColor(50);
253 diamond->SetTextAlign(22);
254 diamond->SetTextColor(5);
255 diamond->SetTextSize(0.11);
257 diamond->AddText(".. ");
258 diamond->AddText("ROOT");
259 diamond->AddText("MUON");
260 diamond->AddText("... ");
261 diamond->AddText(" ");
264 //_____________________________________________________________________________
265 void AliMUONdisplay::CreateColors()
267 // Create the colors palette used to display clusters
282 // printf("CreateColors - i, k, color %d %d %d \n",i,k,color);
283 new TColor(color,r,g,b);
285 // printf("I'm out of case %d \n",k);
294 // printf("CreateColors - i, k, color %d %d %d \n",i,k,color);
295 new TColor(color,r,g,b);
297 // printf("I'm out of case %d \n",k);
306 // printf("CreateColors - i, k, color %d %d %d \n",i,k,color);
307 new TColor(color,r,g,b);
309 // printf("I'm out of case %d \n",k);
318 // printf("CreateColors - i, k, color %d %d %d \n",i,k,color);
319 new TColor(color,r,g,b);
321 // printf("I'm out of case %d \n",k);
330 // printf("CreateColors - i, k, color %d %d %d \n",i,k,color);
331 new TColor(color,r,g,b);
333 // printf("I'm out of case %d \n",k);
341 //_____________________________________________________________________________
342 void AliMUONdisplay::DisplayColorScale()
347 Float_t xlow, ylow, xup, yup, hs;
348 Float_t x1, y1, x2, y2;
352 gPad->SetFillColor(0);
354 gPad->Range(x1,y1,x2,y2);
356 TText *text = new TText(0,0,"");
357 text->SetTextFont(61);
358 text->SetTextSize(0.03);
359 text->SetTextAlign(22);
363 //*-* draw colortable boxes
364 hs = (y2-y1)/Float_t(22);
368 ylow = y1 + hs*(Float_t(i));
369 yup = y1 + hs*(Float_t(i+1));
371 // Int_t scale=(i+1)*(Int_t)adc_satm/22;
372 // sprintf(label,"%d",scale);
373 Double_t logscale=Double_t(i+1)*(TMath::Log(adc_satm)/22);
374 Int_t scale=(Int_t)TMath::Exp(logscale);
375 sprintf(label,"%d",scale);
376 box = new TBox(xlow, ylow, xup, yup);
377 box->SetFillColor(color);
379 text->DrawText(xup+4, 0.5*(ylow+yup),label);
383 //______________________________________________________________________________
384 Int_t AliMUONdisplay::DistancetoPrimitive(Int_t px, Int_t)
386 // Compute distance from point px,py to objects in event
388 gPad->SetCursor(kCross);
390 if (gPad == fTrigPad) return 9999;
392 const Int_t big = 9999;
394 Float_t xmin = gPad->GetX1();
395 Float_t xmax = gPad->GetX2();
396 Float_t dx = 0.02*(xmax - xmin);
397 Float_t x = gPad->AbsPixeltoX(px);
398 if (x < xmin+dx || x > xmax-dx) return dist;
400 if (fZoomMode) return 0;
404 //_____________________________________________________________________________
405 void AliMUONdisplay::Draw(Option_t *)
407 // Display current event
411 DrawView(fTheta, fPhi, fPsi); // see how to draw PGON+inner frames
413 // Display the event number and title
419 //_____________________________________________________________________________
420 void AliMUONdisplay::DrawClusters()
422 // Draw clusterss for MUON chambers
424 Int_t ndigits, digit;
433 ndigits = points->GetEntriesFast();
434 printf("DrawClusters - ndigits %d \n",ndigits);
435 for (digit=0;digit<ndigits;digit++){
436 pm = (AliMUONpoints*)points->UncheckedAt(digit);
440 // printf("DrawClusters - pxyz[0],pxyz[1] %f %f \n",pxyz[0],pxyz[1]);
442 // Int_t n=pm->GetN();
443 // printf("DrawClusters - n %d \n",n);
444 fClustersCuts +=pm->GetN();
448 //_____________________________________________________________________________
449 void AliMUONdisplay::DrawHits()
451 // Draw hits for MUON chambers
455 Int_t ntracks, track;
462 ntracks = points->GetEntriesFast();
463 printf("DrawHits - ntracks %d \n",ntracks);
464 for (track=0;track<ntracks;track++) {
465 pm = (AliMUONpoints*)points->UncheckedAt(track);
468 fHitsCuts += pm->GetN();
473 //_____________________________________________________________________________
474 void AliMUONdisplay::DrawTitle(Option_t *option)
476 // Draw the event title
478 Float_t xmin = gPad->GetX1();
479 Float_t xmax = gPad->GetX2();
480 Float_t ymin = gPad->GetY1();
481 Float_t ymax = gPad->GetY2();
482 Float_t dx = xmax-xmin;
483 Float_t dy = ymax-ymin;
485 if (strlen(option) == 0) {
486 TPaveText *title = new TPaveText(xmin +0.01*dx, ymax-0.09*dy, xmin +0.5*dx, ymax-0.01*dy);
487 title->SetBit(kCanDelete);
488 title->SetFillColor(42);
491 sprintf(ptitle,"Alice event: %d, Run:%d",gAlice->GetHeader()->GetEvent(), gAlice->GetHeader()->GetRun());
492 title->AddText(ptitle);
493 Int_t nparticles = gAlice->Particles()->GetEntriesFast();
494 sprintf(ptitle,"Nparticles = %d Nhits = %d Npads fired = %d",nparticles, fHitsCuts,fClustersCuts);
495 title->AddText(ptitle);
497 TPaveLabel *label = new TPaveLabel(xmin +0.01*dx, ymax-0.07*dy, xmin +0.2*dx, ymax-0.01*dy,option);
498 label->SetBit(kCanDelete);
499 label->SetFillColor(42);
504 //_____________________________________________________________________________
505 void AliMUONdisplay::DrawView(Float_t theta, Float_t phi, Float_t psi)
507 // Draw a view of MUON clusters
509 gPad->SetCursor(kWatch);
510 gPad->SetFillColor(1);
514 TView *view = new TView(1);
515 Float_t range = fRrange*fRangeSlider->GetMaximum();
516 view->SetRange(-range,-range,-range,range, range, range);
523 // Display MUON Chamber Geometry
524 // gAlice->GetGeometry()->Draw("same");
526 //add clusters to the pad
530 // add itself to the list (must be last)
533 view->SetView(phi, theta, psi, iret);
537 //______________________________________________________________________________
538 void AliMUONdisplay::ExecuteEvent(Int_t event, Int_t px, Int_t py)
540 // Execute action corresponding to the mouse event
542 static Float_t x0, y0, x1, y1;
544 static Int_t pxold, pyold;
545 static Int_t px0, py0;
546 static Int_t linedrawn;
549 if (px == 0 && py == 0) { //when called by sliders
550 if (event == kButton1Up) {
555 if (!fZoomMode && gPad->GetView()) {
556 gPad->GetView()->ExecuteRotateView(event, px, py);
560 // something to zoom ?
561 gPad->SetCursor(kCross);
566 gGXW->SetLineColor(-1);
567 gPad->TAttLine::Modify(); //Change line attributes only if necessary
568 x0 = gPad->AbsPixeltoX(px);
569 y0 = gPad->AbsPixeltoY(py);
571 pxold = px; pyold = py;
576 if (linedrawn) gGXW->DrawBox(px0, py0, pxold, pyold, TGXW::kHollow);
580 gGXW->DrawBox(px0, py0, pxold, pyold, TGXW::kHollow);
584 gPad->GetCanvas()->FeedbackMode(kFALSE);
585 if (px == px0) return;
586 if (py == py0) return;
587 x1 = gPad->AbsPixeltoX(px);
588 y1 = gPad->AbsPixeltoY(py);
590 if (x1 < x0) {temp = x0; x0 = x1; x1 = temp;}
591 if (y1 < y0) {temp = y0; y0 = y1; y1 = temp;}
592 gPad->Range(x0,y0,x1,y1);
593 if (fZooms < kMAXZOOM-1) {
595 fZoomX0[fZooms] = x0;
596 fZoomY0[fZooms] = y0;
597 fZoomX1[fZooms] = x1;
598 fZoomY1[fZooms] = y1;
600 gPad->Modified(kTRUE);
606 //___________________________________________
607 void AliMUONdisplay::LoadDigits(Int_t chamber, Int_t cathode)
609 // Read digits info and store x,y,z info in arrays fPoints
610 // Loop on all detectors
617 AliMUON *MUON = (AliMUON*)gAlice->GetModule("MUON");
618 AliMUONchamber* iChamber;
619 AliMUONsegmentation* segmentation;
621 TClonesArray *MUONdigits = MUON->DigitsAddress(chamber-1);
622 if (MUONdigits == 0) return;
624 gAlice->ResetDigits();
625 gAlice->TreeD()->GetEvent(cathode);
626 Int_t ndigits = MUONdigits->GetEntriesFast();
627 if (ndigits == 0) return;
628 if (fPoints == 0) fPoints = new TObjArray(ndigits);
629 printf("Found %d digits for cathode %d in chamber %d \n",ndigits,cathode,chamber);
631 iChamber = &(MUON->Chamber(chamber-1));
632 printf("LoadPoints - iChamber %p \n",iChamber);
633 segmentation=iChamber->GetSegmentationModel(cathode);
634 printf("LoadPoints - segmentation %p \n",segmentation);
635 Float_t dpx = segmentation->Dpx();
636 Float_t dpy = segmentation->Dpy();
637 printf("LoadPoints - dpx, dpy %f %f \n",dpx,dpy);
638 Float_t zpos=iChamber->ZPosition();
639 printf("LoadPoint - zpos %f \n",zpos);
641 AliMUONpoints *points = 0;
643 //loop over all digits and store their position
644 // points = new AliMUONpoints(ndigits);
646 for (Int_t digit=0;digit<ndigits;digit++) {
647 mdig = (AliMUONdigit*)MUONdigits->UncheckedAt(digit);
648 points = new AliMUONpoints(npoints);
649 fPoints->AddAt(points,digit);
650 Int_t charge=mdig->fSignal;
651 // set the color according to the color scale
652 // Int_t scale=(Int_t)adc_satm/22;
653 // Int_t index=(Int_t)charge/scale;
654 Int_t index=Int_t(TMath::Log(charge)/(TMath::Log(adc_satm)/22));
655 Int_t color=51+index;
656 if (color>72) color=72;
657 points->SetMarkerColor(color);
658 points->SetMarkerStyle(21);
659 points->SetMarkerSize(0.5);
660 // get the center of the pad - add on x and y half of pad size
662 segmentation->GetPadCxy(mdig->fPadX, mdig->fPadY,xpad, ypad);
663 points->SetParticle(-1);
664 points->SetHitIndex(-1);
665 points->SetTrackIndex(-1);
666 points->SetDigitIndex(digit);
667 points->SetPoint(0,xpad,ypad,zpos);
669 // pxyz=points->GetP();
670 // printf("pxyz[0],pxyz[1],color %f %f %d \n",pxyz[0],pxyz[1],color);
671 // Int_t np=points->GetN();
672 // printf("np %d \n",np);
677 //___________________________________________
678 void AliMUONdisplay::LoadHits(Int_t chamber)
680 // Read hits info and store x,y,z info in arrays fPhits
681 // Loop on all detectors
687 AliMUON *MUON = (AliMUON*)gAlice->GetModule("MUON");
688 AliMUONchamber* iChamber;
690 iChamber = &(MUON->Chamber(chamber-1));
691 Float_t zpos=iChamber->ZPosition();
692 printf("LoadHits - zpos %f \n",zpos);
694 Int_t ntracks = (Int_t)gAlice->TreeH()->GetEntries();
695 printf("ntracks %d\n",ntracks);
696 Int_t ntrks = gAlice->GetNtrack();
697 printf("ntrks %d\n",ntrks);
699 if (fPhits == 0) fPhits = new TObjArray(ntracks);
700 // if (fPhits == 0) fPhits = new TObjArray(ntrks);
702 TVector *xp = new TVector(10);
703 TVector *yp = new TVector(10);
704 TVector *ptrk = new TVector(10);
705 TVector *phit = new TVector(10);
706 for (Int_t track=0; track<ntracks;track++) {
708 gAlice->TreeH()->GetEvent(track);
709 TClonesArray *MUONhits = MUON->Hits();
710 // printf("MUONhits %p\n",MUONhits);
711 if (MUONhits == 0) return;
712 Int_t nhits = MUONhits->GetEntriesFast();
713 if (nhits == 0) continue;
714 // printf("nhits %d \n",nhits);
716 AliMUONpoints *points = 0;
717 // Int_t trko=-99, trk;
718 // points = new AliPoints(nhits);
720 for (Int_t hit=0;hit<nhits;hit++) {
721 mHit = (AliMUONhit*)MUONhits->UncheckedAt(hit);
722 Int_t nch = mHit->fChamber; // chamber number
723 if (nch != chamber) continue;
724 (*xp)(npoints)=mHit->fX;
725 (*yp)(npoints)=mHit->fY;
726 (*ptrk)(npoints)=Float_t(mHit->GetTrack());
727 (*phit)(npoints)=Float_t(hit);
728 // printf("track, trk %d %d\n",track,mHit->GetTrack());
731 if (npoints == 0) continue;
732 // printf("npoints %d \n",npoints);
733 points = new AliMUONpoints(npoints);
734 for (Int_t p=0;p<npoints;p++) {
735 points->SetMarkerColor(kRed);
736 points->SetMarkerStyle(5);
737 points->SetMarkerSize(1.);
738 points->SetParticle(Int_t((*ptrk)(p)));
739 // Int_t index=points->GetIndex();
740 // printf("index %d \n",index);
741 points->SetHitIndex(Int_t((*phit)(p)));
742 points->SetTrackIndex(track);
743 points->SetDigitIndex(-1);
744 points->SetPoint(p,(*xp)(p),(*yp)(p),zpos);
750 fPhits->AddAt(points,track);
751 // Int_t np=points->GetN();
752 // printf("np %d \n",np);
757 //_____________________________________________________________________________
758 void AliMUONdisplay::Paint(Option_t *)
760 // Paint miscellaneous items
764 //_____________________________________________________________________________
765 void AliMUONdisplay::SetPickMode()
769 fArcButton->SetY1(fPickButton->GetYlowNDC()+0.5*fPickButton->GetHNDC());
770 fTrigPad->Modified();
773 //_____________________________________________________________________________
774 void AliMUONdisplay::SetZoomMode()
778 fArcButton->SetY1(fZoomButton->GetYlowNDC()+0.5*fZoomButton->GetHNDC());
779 fTrigPad->Modified();
782 //_____________________________________________________________________________
783 void AliMUONdisplay::SetChamberAndCathode(Int_t chamber, Int_t cathode)
785 // Set chamber and cathode number
790 // printf("SetChamberAndCathode - fPad %p \n",fPad);
791 printf("SetChamberAndCathode - fChamber fCathode %d %d\n",fChamber,fCathode);
794 LoadDigits(chamber,cathode);
798 //_____________________________________________________________________________
799 void AliMUONdisplay::SetRange(Float_t rrange, Float_t zrange)
801 // Set view range along R and Z
810 //_____________________________________________________________________________
811 void AliMUONdisplay::SetView(Float_t theta, Float_t phi, Float_t psi)
813 // change viewing angles for current event
821 TView *view = gPad->GetView();
822 if (view) view->SetView(fPhi, fTheta, fPsi, iret);
828 //_____________________________________________________________________________
829 void AliMUONdisplay::ShowNextEvent(Int_t delta)
831 // Display (current event_number+delta)
832 // delta = 1 shown next event
833 // delta = -1 show previous event
837 Int_t current_event = gAlice->GetHeader()->GetEvent();
838 Int_t new_event = current_event + delta;
839 gAlice->GetEvent(new_event);
840 if (!gAlice->TreeD()) return;
842 LoadDigits(fChamber,fCathode);
847 //______________________________________________________________________________
848 void AliMUONdisplay::UnZoom()
850 if (fZooms <= 0) return;
852 TPad *pad = (TPad*)gPad->GetPadSave();
853 pad->Range(fZoomX0[fZooms],fZoomY0[fZooms], fZoomX1[fZooms],fZoomY1[fZooms]);
857 //_____________________________________________________________________________
858 void AliMUONdisplay::ResetPoints()
861 // Reset array of points
869 //_____________________________________________________________________________
870 void AliMUONdisplay::ResetPhits()
873 // Reset array of points