54ec9c53352cfbb82cec8e7320513561f011ea38
[u/mrichter/AliRoot.git] / MUON / AliMUONDisplay.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 /*
17 $Log$
18 Revision 1.4  2000/06/27 09:46:57  morsch
19 kMAXZOOM global constant now in AliMUONConstants
20
21 Revision 1.3  2000/06/26 14:02:38  morsch
22 Add class AliMUONConstants with MUON specific constants using static memeber data and access methods.
23
24 Revision 1.2  2000/06/15 07:58:48  morsch
25 Code from MUON-dev joined
26
27 Revision 1.1.2.15  2000/06/14 14:37:53  morsch
28 method Trigger() modified
29
30 Revision 1.1.2.14  2000/06/09 21:57:09  morsch
31 Bug in color scale diplay corrected.
32 Most coding rule violations corrected.
33
34 Revision 1.1.2.13  2000/05/02 11:57:27  morsch
35 Coding rules RN3, RN13, RN17 violations corrected.
36
37 Revision 1.1.2.12  2000/04/26 12:27:33  morsch
38 Mods for trigger display (P. Crochet):
39 - color code versus time for pad hits in trigger chambers
40 - call to TriggerDecision corrected
41
42 Revision 1.1.2.11  2000/04/26 09:04:46  morsch
43 Obsolete cathode correlation related code removed.
44
45 Revision 1.1.2.10  2000/04/19 19:43:47  morsch
46 change NCH to kNCH as in AliMUON.h
47 no more TreeC related methods
48
49 Revision 1.1.2.9  2000/03/20 18:10:33  morsch
50 Trigger method for "online" trigger decission added
51
52 Revision 1.1.2.8  2000/02/23 10:12:01  morsch
53 Dont't try to draw reconstructed hit coordinates for Trigger Chambers.
54 General clean-up of commented code.
55
56 Revision 1.1.2.7  2000/02/17 14:36:55  morsch
57 Display of Trigger hits and clusters added.
58 Displacement between clusters and hits has to be investigated and corrected ! (A.M.)
59
60 Revision 1.1.2.6  2000/02/15 10:19:42  morsch
61 Previous log messages included
62
63 Revision 1.1.2.5  2000/02/15 10:09:09  morsch
64 Log Message added
65
66 Revision 1.1.2.4  2000/02/08 09:17:16  gosset    
67 One more improvement of MUON display:
68 same zoom for both cathode planes in a chamber
69
70 Revision 1.1.2.3  2000/02/07 15:37:21  gosset
71 A few improvements of the MUON display:
72 new buttons to change either chamber or cathode,
73 added to the more complicated way
74 (right mouse click and explicit filling of chamber and cathode)
75
76 Revision 1.1.2.2  2000/02/04 10:57:34  gosset
77 Z position of the chambers:
78 it was the Z position of the stations;
79 it is now really the Z position of the chambers.
80    !!!! WARNING: THE CALLS TO "AliMUONChamber::SetZPOS"
81    !!!!                   AND "AliMUONChamber::ZPosition"
82    !!!! HAVE TO BE CHANGED TO "AliMUONChamber::"SetZ"
83    !!!!                   AND "AliMUONChamber::Z"                                                           
84 */
85
86 //////////////////////////////////////////////////////////////////////////
87 //                                                                      //
88 // AliDisplay                                                           //
89 //                                                                      //
90 // Utility class to display ALICE outline, tracks, hits,..              //
91 //                                                                      //
92 //////////////////////////////////////////////////////////////////////////
93
94 #include <TROOT.h>
95 #include <TTree.h>
96 #include <TButton.h>
97 #include <TColor.h>
98 #include <TCanvas.h>
99 #include <TView.h>
100 #include <TText.h>
101 #include <TPolyMarker3D.h>
102 #include <TPaveLabel.h>
103 #include <TPaveText.h>
104 #include <TList.h>
105 #include <TDiamond.h>
106 #include <TNode.h>
107 #include <TArc.h>
108 #include <TTUBE.h>
109 #include <TSlider.h>
110 #include <TSliderBox.h>
111 #include <TGaxis.h>
112 #include <TVirtualX.h>
113 #include <TMath.h>
114 #include <TMatrix.h>
115 #include <X3DBuffer.h>
116 #include <TMarker3DBox.h>
117
118 #include "AliRun.h"
119 #include "AliDetector.h"
120 #include "AliMUON.h"
121 #include "AliMUONDisplay.h"
122 #include "AliMUONPoints.h"
123 #include "TParticle.h"
124 #include "AliMUONTriggerDecision.h"
125
126 #include "AliMUONHit.h"
127 #include "AliMUONPadHit.h"
128 #include "AliMUONDigit.h"
129 #include "AliMUONRawCluster.h"
130
131 #include "AliMUONSegmentation.h"
132 #include "AliMUONResponse.h"
133 #include "AliMUONChamber.h"
134 #include "AliMUONConstants.h"
135 // to manage the same zoom on both cathodes
136
137
138
139 ClassImp(AliMUONDisplay)
140
141
142 //_____________________________________________________________________________
143 AliMUONDisplay::AliMUONDisplay()
144 {
145 // Constructor
146     fPoints = 0;
147     fPhits = 0;
148     fRpoints = 0;
149     fR2points = 0;
150     fCpoints = 0;
151     fCanvas = 0;
152     fNextCathode = kFALSE; 
153 }
154
155 //_____________________________________________________________________________
156 AliMUONDisplay::AliMUONDisplay(Int_t size)
157 {
158 // Create an event display object.
159 // A canvas named "edisplay" is created with a vertical size in pixels
160 //
161 //    A QUICK Overview of the Event Display functions
162 //    ===============================================
163 //
164 //  The event display can ve invoked by executing the macro "display.C"
165 // A canvas like in the picture below will appear.
166 //
167 //  On the left side of the canvas, the following buttons appear:
168 //   *Next*       to move to the next event
169 //   *Previous*   to move to the previous event
170
171 //   *Pick*       Select this option to be able to point on a track with the
172 //                mouse. Once on the track, use the right button to select
173 //                an action. For example, select SetMarkerAttributes to
174 //                change the marker type/color/size for the track.
175 //   *Zoom*       Select this option (default) if you want to zoom.
176 //                To zoom, simply select the selected area with the left button.
177 //   *UnZoom*     To revert to the previous picture size.
178 //
179 //   slider R     On the left side, the vertical slider can be used to
180 //                set the default picture size.
181 //
182 //    When you are in Zoom mode, you can click on the black part of the canvas
183 //  to select special options with the right mouse button.
184
185 //
186 //  When you are in pick mode, you can "Inspect" the object pointed by the mouse.
187 //  When you are on a track, select the menu item "InspectParticle"
188 //  to display the current particle attributes.
189 //
190 //  You can activate the Root browser by selecting the Inspect menu
191 //  in the canvas tool bar menu. Then select "Start Browser"
192 //  This will open a new canvas with the browser. At this point, you may want
193 //  to display some histograms (from the Trees). Go to the "File" menu
194 //  of the browser and click on "New canvas".
195 //  In the browser, click on item "ROOT files" in the left pane.
196 //  Click on galice.root.
197 //  Click on TH
198 //  Click on TPC for example
199 //  Click on any variable (eg TPC.fX) to histogram the variable.
200 //
201 //   If you are lost, you can click on HELP in any Root canvas or browser.
202 //Begin_Html
203 /*
204 <img src="gif/AliMUONDisplay.gif">
205 */
206 //End_Html
207
208
209     fPad = 0;
210     
211     gAlice->SetDisplay(this);
212    
213    // Initialize display default parameters
214     SetRange(200,2000);
215    // Set front view by default
216     fTheta =   0;
217     fPhi   = -90;
218     fPsi   =   0;
219     fChamber = 1;
220     fCathode = 1;
221     //   fRzone   = 1.e10;
222     fDrawClusters  = kTRUE;
223     fDrawCoG       = kTRUE;
224     fDrawCoG  = kTRUE;
225     fZoomMode      = 1;
226     fZooms         = 0;
227     fClustersCuts  = 0;
228     fPoints        = 0;
229     fPhits         = 0;
230     fRpoints       = 0;
231     fR2points = 0;
232     fCpoints = 0;
233     // Create colors
234     CreateColors();
235     // Create display canvas
236     Int_t ysize = size;
237     if (ysize < 100) ysize = 750;
238     Int_t xsize = Int_t(size*830./ysize);
239     fCanvas = new TCanvas("Canvas", "MUON Clusters Display",14,47,xsize,ysize);
240     fCanvas->ToggleEventStatus();
241     
242    // Create main display pad
243     fPad = new TPad("viewpad", "MUON display",0.15,0,0.9,1);
244     fPad->Draw();
245     fPad->Modified();
246     fPad->SetFillColor(30);
247     fPad->SetBorderSize(2);
248
249     fCanvas->cd();
250
251    // Create colors pad
252     fColPad = new TPad("colpad", "Colors pad",0.9,0,1,1);
253     fColPad->Draw();
254     fColPad->SetFillColor(17);
255     fColPad->SetBorderSize(2);
256     fColPad->cd();
257     DisplayColorScale();
258
259     fCanvas->cd();
260    // Create user interface control pad
261     DisplayButtons();
262     fCanvas->cd();
263
264    // Create Range and mode pad
265     Float_t dxtr     = 0.15;
266     Float_t dytr     = 0.45;
267     fTrigPad = new TPad("trigger", "range and mode pad",0,0,dxtr,dytr);
268     fTrigPad->SetEditable(kFALSE);
269     fTrigPad->Draw();
270     fTrigPad->cd();
271     fTrigPad->SetFillColor(22);
272     fTrigPad->SetBorderSize(2);
273     fRangeSlider = new TSlider("range","range",0.7,0.42,0.9,0.98);
274     fRangeSlider->SetObject(this);
275     char pickmode[] = "gAlice->Display()->SetPickMode()";
276     Float_t db = 0.09;
277     fPickButton = new TButton("Pick",pickmode,0.05,0.32,0.65,0.32+db);
278     fPickButton->SetFillColor(38);
279     fPickButton->Draw();
280     char zoommode[] = "gAlice->Display()->SetZoomMode()";
281     fZoomButton = new TButton("Zoom",zoommode,0.05,0.21,0.65,0.21+db);
282     fZoomButton->SetFillColor(38);
283     fZoomButton->Draw();
284     fArcButton = new TArc(.8,fZoomButton->GetYlowNDC()+0.5*db,0.33*db);
285     fArcButton->SetFillColor(kGreen);
286     fArcButton->Draw();
287     char butUnzoom[] = "gAlice->Display()->UnZoom()";
288     TButton *button = new TButton("UnZoom",butUnzoom,0.05,0.05,0.95,0.15);
289     button->SetFillColor(38);
290     button->Draw();
291     AppendPad(); // append display object as last object to force selection
292     
293     fCanvas->cd();
294     fCanvas->Update();
295     fNextCathode = kFALSE; 
296 }
297
298 AliMUONDisplay::AliMUONDisplay(const AliMUONDisplay & display)
299 {
300 // Dummy copy constructor    
301     ;
302 }
303
304
305
306 //_____________________________________________________________________________
307 AliMUONDisplay::~AliMUONDisplay()
308 {
309   // Delete space point structure
310     if (fPoints) fPoints->Delete();
311     delete fPoints;
312     fPoints     = 0;
313     //
314     if (fPhits) fPhits->Delete();
315     delete fPhits;
316     fPhits     = 0;
317     //
318     if (fRpoints) fRpoints->Delete();
319     delete fRpoints;
320     fRpoints     = 0;
321 //
322     if (fR2points) fR2points->Delete();
323     delete fR2points;
324     fR2points     = 0;
325 //
326     if (fCpoints) fCpoints->Delete();
327     delete fCpoints;
328     fCpoints     = 0;
329 }
330
331 //_____________________________________________________________________________
332 void AliMUONDisplay::Clear(Option_t *)
333 {
334 //    Delete graphics temporary objects
335 }
336
337 //_____________________________________________________________________________
338 void AliMUONDisplay::DisplayButtons()
339 {
340 //    Create the user interface buttons
341
342
343     fButtons = new TPad("buttons", "newpad",0,0.45,0.15,1);
344     fButtons->SetEditable(kFALSE);
345     fButtons->Draw();
346     fButtons->SetFillColor(38);
347     fButtons->SetBorderSize(2);
348     fButtons->cd();
349     
350 //   Int_t butcolor = 33;
351     Float_t dbutton = 0.08;
352     Float_t y  = 0.96;
353     Float_t dy = 0.014;
354     Float_t x0 = 0.05;
355     Float_t x1 = 0.95;
356     
357     TButton *button;
358     char but1[] = "gAlice->Display()->ShowNextEvent(1)";
359     button = new TButton("Event +", but1, x0, y - dbutton, x1, y);
360     button->SetFillColor(38);
361     button->Draw();
362     
363     y -= dbutton + dy;
364     char but2[] = "gAlice->Display()->ShowNextEvent(-1)";
365     button = new TButton("Event -", but2, x0, y - dbutton, x1, y);
366     button->SetFillColor(38);
367     button->Draw();
368    
369     y -= dbutton + dy;
370     char but3[] = "((AliMUONDisplay*)(gAlice->Display()))->NextChamber(1)";
371     button = new TButton("Chamber +", but3, x0, y - dbutton, x1, y);
372     button->SetFillColor(38);
373     button->Draw();
374     
375     y -= dbutton + dy;
376     char but4[] = "((AliMUONDisplay*)(gAlice->Display()))->NextChamber(-1)";
377     button = new TButton("Chamber -", but4, x0, y - dbutton, x1, y);
378     button->SetFillColor(38);
379     button->Draw();
380     
381     y -= dbutton + dy;
382     char but5[] = "((AliMUONDisplay*)(gAlice->Display()))->SetChamberAndCathode(1,1)";
383     button = new TButton("Chamber 1", but5, x0, y - dbutton, x1, y);
384     button->SetFillColor(38);
385     button->Draw();
386    
387     y -= dbutton + dy;
388     char but6[] = "((AliMUONDisplay*)(gAlice->Display()))->NextCathode()";
389     button = new TButton("Cathode <>", but6, x0, y - dbutton, x1, y);
390     button->SetFillColor(38);
391     button->Draw();
392
393     y -= dbutton + dy;
394     char but7[] = "((AliMUONDisplay*)(gAlice->Display()))->Trigger()";
395     button = new TButton("Trigger", but7, x0, y - dbutton, x1, y);
396     button->SetFillColor(38);
397     button->Draw();
398     
399    // display logo
400     TDiamond *diamond = new TDiamond(0.05,0.015,0.95,0.22);
401     diamond->SetFillColor(50);
402     diamond->SetTextAlign(22);
403     diamond->SetTextColor(5);
404     diamond->SetTextSize(0.11);
405     diamond->Draw();
406     diamond->AddText(".. ");
407     diamond->AddText("ROOT");
408     diamond->AddText("MUON");
409     diamond->AddText("... ");
410     diamond->AddText(" ");
411 }
412
413 //_____________________________________________________________________________
414 void AliMUONDisplay::CreateColors()
415 {
416 //    Create the colors palette used to display clusters
417
418     Int_t k,i;
419     Int_t color;
420     Float_t r,g,b;
421     
422     for (k=1;k<=5;k++) {
423         switch(k) {
424         case 1:
425             for (i=1;i<=5;i++) {
426                 r=1.;
427                 g=i*0.2;  
428                 b=0.;
429                 color=i;
430                 color=260+23-color;
431                 new TColor(color,r,g,b);
432             } 
433             break;
434         case 2:
435             for (i=1;i<=4;i++) {
436                 r=1.1-i*0.2;
437                 g=1.;  
438                 b=0.;
439                 color=i+5;
440                 color=260+23-color;
441                 new TColor(color,r,g,b);
442             } 
443             break;
444         case 3:
445             for (i=1;i<=4;i++) {
446                 r=0.;
447                 g=1.;  
448                 b=i*0.2+0.2;
449                 color=i+9;
450                 color=260+23-color;
451                 new TColor(color,r,g,b);
452             } 
453             break;
454         case 4:
455             for (i=1;i<=4;i++) {
456                 r=0.;
457                 g=1.1-i*0.2;  
458                 b=1.;
459                 color=i+13;
460                 color=260+23-color;
461                 new TColor(color,r,g,b);
462             } 
463             break;
464         case 5:
465             for (i=1;i<=5;i++) {
466                 r=i*0.2;
467                 g=0.;  
468                 b=1.;
469                 color=i+17;
470                 color=260+23-color;
471                 new TColor(color,r,g,b);
472             } 
473             break;
474         }
475     }
476 }
477
478 //_____________________________________________________________________________
479 void AliMUONDisplay::DisplayColorScale()
480 {
481 // Display pulse height color scale
482     Int_t i;
483     Int_t color;
484     Float_t xlow, ylow, xup, yup, hs;
485     Float_t x1, y1, x2, y2;
486     x1 = y1 = 0;
487     x2 = y2 = 1.0;
488     
489     TText *text = new TText(0,0,"");
490     text->SetTextFont(61);
491     text->SetTextSize(0.2);
492     text->SetTextAlign(22);
493     
494     AliMUON *pMUON  = (AliMUON*)gAlice->GetModule("MUON");
495     AliMUONChamber *iChamber = &(pMUON->Chamber(fChamber-1));
496     AliMUONResponse * response=iChamber->ResponseModel();
497     Int_t adcmax=1024;
498     if (response) adcmax= (Int_t) response->MaxAdc();
499     
500
501     TBox *box;
502     char label[8];
503 //*-* draw colortable boxes
504     hs = (y2-y1)/Float_t(22);
505     xlow=x1+.05;
506     xup=x2-0.5;
507     for (i=0;i<22;i++) {
508         ylow = y1 + hs*(Float_t(i));
509         yup  = y1 + hs*(Float_t(i+1));
510         color = 261+i;
511         Double_t logscale=Double_t(i+1)*(TMath::Log(adcmax)/22);
512         Int_t scale=(Int_t)TMath::Exp(logscale);
513         sprintf(label,"%d",scale);
514         box = new TBox(xlow, ylow, xup, yup);
515         box->Draw();
516         box->SetFillColor(color);
517         text->DrawText(xlow+0.7, 0.5*(ylow+yup),label);
518     }
519 }
520
521 //______________________________________________________________________________
522 Int_t AliMUONDisplay::DistancetoPrimitive(Int_t px, Int_t)
523 {
524 // Compute distance from point px,py to objects in event
525
526     gPad->SetCursor(kCross);
527     
528     if (gPad == fTrigPad) return 9999;
529     
530     const Int_t kBig = 9999;
531     Int_t dist   = kBig;
532     Float_t xmin = gPad->GetX1();
533     Float_t xmax = gPad->GetX2();
534     Float_t dx   = 0.02*(xmax - xmin);
535     Float_t x    = gPad->AbsPixeltoX(px);
536     if (x < xmin+dx || x > xmax-dx) return dist;
537     
538     if (fZoomMode) return 0;
539     else           return 7;
540 }
541
542 //_____________________________________________________________________________
543 void AliMUONDisplay::Draw(Option_t *)
544 {
545 //    Display current event
546
547     fPad->cd();
548
549     DrawView(fTheta, fPhi, fPsi);   
550     // Display the event number and title
551     fPad->cd();
552     DrawTitle();
553 }
554
555 void AliMUONDisplay::DrawSegmentation()
556 {
557 // Draw graphical representation of segmenatation
558 // Attention: still experimental code
559     Int_t icat=1;
560     
561     AliMUON *pMUON  = (AliMUON*)gAlice->GetModule("MUON");
562     AliMUONChamber*  iChamber;
563     AliMUONSegmentation*  seg;
564     iChamber = &(pMUON->Chamber(fChamber));
565     seg=iChamber->SegmentationModel(icat);
566     Float_t zpos=iChamber->Z();
567     Float_t r=iChamber->ROuter();
568     
569     TMarker3DBox *marker;
570     if (icat == 1) {
571         for (Int_t j=0; j<seg->Npy(); j++) {
572             Float_t y0;
573             y0=j*seg->Dpy()-seg->Dpy()/2.;
574             for (seg->FirstPad(0.,y0,0,300,0.); 
575                  seg->MorePads();
576                  seg->NextPad())
577             {
578                 if (seg->ISector()==0) continue;
579                 Float_t x,y,z;
580                 seg->GetPadCxy(seg->Ix(), seg->Iy(), x, y, z);
581                 Float_t dpx=seg->Dpx(seg->ISector())/2;
582                 Float_t dpy=seg->Dpy(seg->ISector())/2;
583                 marker=new TMarker3DBox(x,y,zpos,dpx,dpy,0,0,0);
584                 marker->SetLineColor(seg->ISector()+1);
585                 marker->SetFillStyle(1001);
586                 marker->SetFillColor(0);
587                 marker->Draw();
588             }
589         }
590     } else {
591         for (Int_t j=0; j<250; j++) {
592             Float_t x0=j*seg->Dpx();
593             Float_t y0=TMath::Sqrt(r*r-x0*x0);
594             
595             for (seg->FirstPad(x0,0,0,0,y0); 
596                  seg->MorePads();
597                  seg->NextPad())
598             {
599                 if (seg->ISector()==0) continue;
600                 
601                 Float_t x,y,z;
602                 seg->GetPadCxy(seg->Ix(), seg->Iy(), x, y, z);
603                 Float_t dpx=seg->Dpx(seg->ISector())/2;
604                 Float_t dpy=seg->Dpy(seg->ISector())/2;
605                 marker=new TMarker3DBox(x,y,zpos,dpx,dpy,0,0,0);
606                 marker->SetLineColor(seg->ISector()+1);
607                 marker->SetFillStyle(1001);
608                 marker->SetFillColor(0);
609                 marker->Draw();
610             }
611         }
612     }
613 }
614
615 //_____________________________________________________________________________
616 void AliMUONDisplay::DrawClusters()
617 {
618 //    Draw clusters for MUON chambers
619
620     Int_t ndigits, digit;
621     TObjArray *points;
622     AliMUONPoints *pm;
623
624       
625     fClustersCuts = 0;
626     points = Points();
627     if (!points) return;
628     ndigits = points->GetEntriesFast();
629     for (digit=0;digit<ndigits;digit++){
630         pm = (AliMUONPoints*)points->UncheckedAt(digit);
631         if (!pm) continue;
632         Float_t *pxyz;
633         pxyz=pm->GetP();
634         for (Int_t im=0;im<3;im++) {
635             TMarker3DBox *marker=pm->GetMarker(im);
636             if (marker)
637                 marker->Draw();
638         }
639         pm->Draw();
640         fClustersCuts +=pm->GetN();
641     }
642 }
643
644 //_____________________________________________________________________________
645 void AliMUONDisplay::DrawHits()
646 {
647 //    Draw hits for MUON chambers
648
649     LoadHits(fChamber);
650
651     Int_t ntracks, track;
652     TObjArray *points;
653     AliMUONPoints *pm;
654     
655     fHitsCuts = 0;
656     points = Phits();
657     if (!points) return;
658     ntracks = points->GetEntriesFast();
659     for (track=0;track<ntracks;track++) {
660         pm = (AliMUONPoints*)points->UncheckedAt(track);
661         if (!pm) continue;
662         pm->Draw();
663         fHitsCuts += pm->GetN();
664     }
665 }
666
667
668 //_____________________________________________________________________________
669 void AliMUONDisplay::DrawCoG()
670 {
671 //    Draw hits for MUON chambers
672     if (!fDrawCoG) return;
673     if (fChamber > 10) return;
674     LoadCoG(fChamber,fCathode);
675     
676     Int_t ncog, icog;
677     TObjArray *points;
678     AliMUONPoints *pm;
679
680     points = Rpoints();
681     if (!points) return;
682     ncog = points->GetEntriesFast();
683     for (icog=0;icog<ncog;icog++) {
684         pm = (AliMUONPoints*)points->UncheckedAt(icog);
685         if (!pm) continue;
686         pm->Draw();
687     }
688 }
689 void AliMUONDisplay::DrawCoG2()
690 {
691 //    Draw hits for MUON chambers
692
693     if (!fDrawCoG) return;
694     if (fChamber > 10) return;  
695
696     if (fCathode==1) {
697         LoadCoG2(fChamber,2);
698     } else if (fCathode==2) {
699         LoadCoG2(fChamber,1);
700     }
701
702     Int_t ncog, icog;
703     TObjArray *points;
704     AliMUONPoints *pm;
705     
706     points = R2points();
707     if (!points) return;
708     ncog = points->GetEntriesFast();
709     for (icog=0;icog<ncog;icog++) {
710         pm = (AliMUONPoints*)points->UncheckedAt(icog);
711         if (!pm) continue;
712         pm->Draw();
713     }
714 }
715 //_____________________________________________________________________________
716
717 void AliMUONDisplay::DrawTitle(Option_t *option)
718 {
719 //    Draw the event title
720
721     Float_t xmin = gPad->GetX1();
722     Float_t xmax = gPad->GetX2();
723     Float_t ymin = gPad->GetY1();
724     Float_t ymax = gPad->GetY2();
725     Float_t dx   = xmax-xmin;
726     Float_t dy   = ymax-ymin;
727     
728     if (strlen(option) == 0) {
729         TPaveText *title = new TPaveText(xmin +0.01*dx, ymax-0.09*dy, xmin +0.5*dx, ymax-0.01*dy);
730 //      title->SetTextSize(0.023932);
731         title->SetTextSize(0.02);
732         title->SetBit(kCanDelete);
733         title->SetFillColor(42);
734         title->Draw();
735         char ptitle[100];
736         sprintf(ptitle, "Alice event:%d Run:%d Chamber:%d Cathode:%d",
737                 gAlice->GetHeader()->GetEvent(),
738                 gAlice->GetHeader()->GetRun(),
739                 fChamber,
740                 fCathode);
741         title->AddText(ptitle);
742         Int_t nparticles = gAlice->Particles()->GetEntriesFast();
743         sprintf(ptitle,"Nparticles = %d Nhits = %d Npads fired = %d",
744                 nparticles, fHitsCuts,fClustersCuts);
745         title->AddText(ptitle);
746     } else {
747         TPaveLabel *label = new TPaveLabel(xmin +0.01*dx, ymax-0.07*dy, xmin +0.2*dx, ymax-0.01*dy,option);
748         label->SetBit(kCanDelete);
749         label->SetFillColor(42);
750         label->Draw();
751     }
752 }
753
754 //_____________________________________________________________________________
755 void AliMUONDisplay::DrawView(Float_t theta, Float_t phi, Float_t psi)
756 {
757 //    Draw a view of MUON clusters
758     printf("\n Draw View");
759     
760     gPad->SetCursor(kWatch);
761     // gPad->SetFillColor(39);
762     gPad->SetFillColor(1);
763     gPad->Clear();
764     // gPad->SetFillColor(39);
765     gPad->SetFillColor(1);
766     
767
768     Int_t iret=0;
769     TView *view = new TView(1);
770     
771     Float_t range = fRrange*fRangeSlider->GetMaximum();
772     view->SetRange(-range,-range,-range,range, range, range);
773     // zoom back to full scale only if DrawView not called from NextCathode
774     if (!fNextCathode) {
775         fZoomX0[0] = -1;
776         fZoomY0[0] = -1;
777         fZoomX1[0] =  1;
778         fZoomY1[0] =  1;
779         fZooms = 0;
780     }
781
782 // Display MUON Chamber Geometry
783 // gAlice->GetGeometry()->Draw("same");
784     char nodeName[7];
785     sprintf(nodeName,"MUON%d",100+fChamber);
786     printf("\n Node name %s", nodeName);
787     
788     TNode *node1=gAlice->GetGeometry()->GetNode(nodeName);
789     if (node1) node1->Draw("same");  
790 //add clusters to the pad
791     DrawClusters();
792     printf("Node name %s", nodeName);   
793     DrawHits();
794     DrawCoG();
795     DrawCoG2();
796 //     DrawSegmentation();
797     // add itself to the list (must be last)
798     AppendPad();
799     view->SetView(phi, theta, psi, iret);
800 }
801
802
803 //______________________________________________________________________________
804 void AliMUONDisplay::ExecuteEvent(Int_t event, Int_t px, Int_t py)
805 {
806 //  Execute action corresponding to the mouse event
807
808     static Float_t x0, y0, x1, y1;
809     
810     static Int_t pxold, pyold;
811     static Int_t px0, py0;
812     static Int_t linedrawn;
813     Float_t temp;
814     
815     if (px == 0 && py == 0) { //when called by sliders
816         if (event == kButton1Up) {
817             Draw();
818         }
819         return;
820     }
821     if (!fZoomMode && gPad->GetView()) {
822         gPad->GetView()->ExecuteRotateView(event, px, py);
823         return;
824     }
825
826     // something to zoom ?
827     gPad->SetCursor(kCross);
828     
829     switch (event) {
830
831     case kButton1Down:
832         gVirtualX->SetLineColor(-1);
833         gPad->TAttLine::Modify();  //Change line attributes only if necessary
834         x0 = gPad->AbsPixeltoX(px);
835         y0 = gPad->AbsPixeltoY(py);
836         px0   = px; py0   = py;
837         pxold = px; pyold = py;
838         linedrawn = 0;
839         return;
840         
841     case kButton1Motion:
842         if (linedrawn) gVirtualX->DrawBox(px0, py0, pxold, pyold, TVirtualX::kHollow);
843         pxold = px;
844         pyold = py;
845         linedrawn = 1;
846         gVirtualX->DrawBox(px0, py0, pxold, pyold,  TVirtualX::kHollow);
847         return;
848         
849     case kButton1Up:
850         gPad->GetCanvas()->FeedbackMode(kFALSE);
851         if (px == px0) return;
852         if (py == py0) return;
853         x1 = gPad->AbsPixeltoX(px);
854         y1 = gPad->AbsPixeltoY(py);
855         
856         if (x1 < x0) {temp = x0; x0 = x1; x1 = temp;}
857         if (y1 < y0) {temp = y0; y0 = y1; y1 = temp;}
858         gPad->Range(x0,y0,x1,y1);
859         if (fZooms < AliMUONConstants::MaxZoom()-1) {
860             fZooms++;
861             fZoomX0[fZooms] = x0;
862             fZoomY0[fZooms] = y0;
863             fZoomX1[fZooms] = x1;
864             fZoomY1[fZooms] = y1;
865         }
866         gPad->Modified(kTRUE);
867         return;
868     }
869 }
870  
871 //___________________________________________
872 void AliMUONDisplay::LoadDigits(Int_t chamber, Int_t cathode)
873 {
874 // Read digits info and store x,y,z info in arrays fPoints
875 // Loop on all detectors
876
877     if (chamber > 14) return;
878     printf(" chamber %d \n",chamber);
879     fChamber=chamber;
880     fCathode=cathode;
881     
882     ResetPoints();
883     
884     AliMUON *pMUON  = (AliMUON*)gAlice->GetModule("MUON");
885     AliMUONChamber*       iChamber;
886     AliMUONSegmentation*  segmentation;
887     AliMUONResponse*      response;
888
889     TClonesArray *muonDigits  = pMUON->DigitsAddress(chamber-1);
890     if (muonDigits == 0) return;
891
892     gAlice->ResetDigits();
893
894     Int_t nent=(Int_t)gAlice->TreeD()->GetEntries();
895     gAlice->TreeD()->GetEvent(nent-2+cathode-1);
896     Int_t ndigits = muonDigits->GetEntriesFast();
897     if (ndigits == 0) return;
898     if (fPoints == 0) fPoints = new TObjArray(ndigits);
899     
900     iChamber = &(pMUON->Chamber(chamber-1));
901
902     segmentation = iChamber->SegmentationModel(cathode);
903     response     = iChamber->ResponseModel();
904     Float_t zpos=iChamber->Z();  
905     AliMUONDigit  *mdig;
906     AliMUONPoints *points = 0;
907     TMarker3DBox *marker=0;
908     //
909     //loop over all digits and store their position
910     
911     Int_t npoints=1;
912     Float_t adcmax=1024;
913     if (response) adcmax= response->MaxAdc();
914
915     for (Int_t digit=0;digit<ndigits;digit++) {
916         mdig    = (AliMUONDigit*)muonDigits->UncheckedAt(digit);
917         //
918         // First get all needed parameters
919         //
920         Int_t charge=mdig->fSignal;
921         Int_t index=Int_t(TMath::Log(charge)/(TMath::Log(adcmax)/22));
922         Int_t color=261+index;
923         Int_t colorTrigger=2;   
924         if (color>282) color=282;
925
926         if (chamber > 10) { // trigger chamber 
927             Int_t sumCharge=0;
928             for (Int_t icharge=0; icharge<10; icharge++) {
929                 sumCharge=sumCharge+mdig->fTcharges[icharge];
930             }
931             Int_t testCharge=sumCharge-(Int_t(sumCharge/10))*10;
932             if(sumCharge<=10||testCharge>0) {
933                 colorTrigger=color; 
934             } else {
935                 colorTrigger=5; 
936             }
937         }
938
939         // get the center of the pad - add on x and y half of pad size
940         Float_t xpad, ypad, zpad;
941         segmentation->GetPadCxy(mdig->fPadX, mdig->fPadY,xpad, ypad, zpad);
942         
943         Int_t isec=segmentation->Sector(mdig->fPadX, mdig->fPadY);
944         Float_t dpx=segmentation->Dpx(isec)/2;
945         Float_t dpy=segmentation->Dpy(isec)/2;
946         Int_t nPara, offset;
947         segmentation->GetNParallelAndOffset(mdig->fPadX,mdig->fPadY,
948                 &nPara,&offset);
949         //
950         // Then set the objects
951         //
952         points = new AliMUONPoints(npoints);
953         fPoints->AddAt(points,digit);
954         if (chamber > 10) {
955             points->SetMarkerColor(colorTrigger);
956         } else {  
957             points->SetMarkerColor(color);
958         }
959         points->SetMarkerStyle(21);
960         points->SetMarkerSize(0.5);
961         points->SetParticle(-1);
962         points->SetHitIndex(-1);
963         points->SetTrackIndex(-1);
964         points->SetDigitIndex(digit);
965         points->SetPoint(0,xpad,ypad,zpos);     
966         for (Int_t imark=0;imark<nPara; imark++)
967         {
968             segmentation->GetPadCxy(mdig->fPadX + imark*offset, mdig->fPadY,xpad, ypad, zpad);
969             marker=new TMarker3DBox(xpad,ypad,zpos,dpx,dpy,0,0,0);
970             marker->SetLineColor(2);
971             marker->SetFillStyle(1001);
972             marker->SetFillColor(color);
973             marker->SetRefObject((TObject*)points);
974             points->Set3DMarker(imark, marker);
975         }
976     }
977 }
978 //___________________________________________
979 void AliMUONDisplay::LoadCoG(Int_t chamber, Int_t cathode)
980 {
981 // Read raw clusters info and store x,y,z info in arrays fRpoints
982 // Loop on all detectors
983
984     if (chamber > 10) return;
985     
986     ResetRpoints();
987     
988     AliMUON *pMUON  = (AliMUON*)gAlice->GetModule("MUON");
989     AliMUONChamber*  iChamber;
990     
991     TClonesArray *muonRawClusters  = pMUON->RawClustAddress(chamber-1);
992     if (muonRawClusters == 0) return;
993
994     pMUON->ResetRawClusters();
995
996
997     Int_t nent=(Int_t)gAlice->TreeR()->GetEntries();
998     gAlice->TreeR()->GetEvent(nent-2+cathode-1);
999     Int_t nrawcl = muonRawClusters->GetEntriesFast();
1000     if (nrawcl == 0) return;
1001     if (fRpoints == 0) fRpoints = new TObjArray(nrawcl);
1002     
1003     iChamber = &(pMUON->Chamber(chamber-1));
1004     Float_t zpos=iChamber->Z();  
1005     AliMUONRawCluster  *mRaw;
1006     AliMUONPoints *points = 0;
1007     //
1008     //loop over all raw clusters and store their position
1009     points = new AliMUONPoints(nrawcl);
1010     for (Int_t iraw=0;iraw<nrawcl;iraw++) {
1011         mRaw   = (AliMUONRawCluster*)muonRawClusters->UncheckedAt(iraw);
1012         fRpoints->AddAt(points,iraw);
1013         points->SetMarkerColor(51);
1014         points->SetMarkerStyle(2);
1015         points->SetMarkerSize(1.);
1016         points->SetParticle(-1);
1017         points->SetHitIndex(-1);
1018         points->SetTrackIndex(-1);
1019         points->SetDigitIndex(-1);
1020         points->SetPoint(iraw,mRaw->fX[0],mRaw->fY[0],zpos);
1021     }
1022 }
1023 //___________________________________________
1024 void AliMUONDisplay::LoadCoG2(Int_t chamber, Int_t cathode)
1025 {
1026 // Read raw clusters info and store x,y,z info in arrays fRpoints
1027 // Loop on all detectors
1028
1029     if (chamber > 10) return;
1030
1031     ResetR2points();
1032
1033     AliMUON *pMUON  = (AliMUON*)gAlice->GetModule("MUON");
1034     AliMUONChamber*  iChamber;
1035     
1036     TClonesArray *muonRawClusters  = pMUON->RawClustAddress(chamber-1);
1037     if (muonRawClusters == 0) return;
1038     
1039     pMUON->ResetRawClusters();
1040
1041     Int_t nent=(Int_t)gAlice->TreeR()->GetEntries();
1042     gAlice->TreeR()->GetEvent(nent-2+cathode-1);
1043     Int_t nrawcl = muonRawClusters->GetEntriesFast();
1044     if (nrawcl == 0) return;
1045     if (fR2points == 0) fR2points = new TObjArray(nrawcl);
1046     
1047     iChamber = &(pMUON->Chamber(chamber-1));
1048     Float_t zpos=iChamber->Z();  
1049     AliMUONRawCluster  *mRaw;
1050     AliMUONPoints *points = 0;
1051     //
1052     //loop over all raw clusters and store their position
1053     points = new AliMUONPoints(nrawcl);
1054     for (Int_t iraw=0;iraw<nrawcl;iraw++) {
1055         mRaw   = (AliMUONRawCluster*)muonRawClusters->UncheckedAt(iraw);
1056         fR2points->AddAt(points,iraw);
1057         points->SetMarkerColor(51);
1058         points->SetMarkerStyle(4);
1059         points->SetMarkerSize(1.3);
1060         points->SetParticle(-1);
1061         points->SetHitIndex(-1);
1062         points->SetTrackIndex(-1);
1063         points->SetDigitIndex(-1);
1064         points->SetPoint(iraw,mRaw->fX[0],mRaw->fY[0],zpos);
1065    }
1066 }
1067 //___________________________________________
1068 void AliMUONDisplay::LoadHits(Int_t chamber)
1069 {
1070 // Read hits info and store x,y,z info in arrays fPhits
1071 // Loop on all detectors
1072
1073     if (chamber > 14) return;
1074     Int_t track;
1075
1076     fChamber=chamber;
1077  
1078     ResetPhits();
1079     
1080     AliMUON *pMUON  = (AliMUON*)gAlice->GetModule("MUON");
1081     AliMUONChamber*  iChamber;
1082
1083     iChamber = &(pMUON->Chamber(chamber-1));
1084     Float_t zpos=iChamber->Z();
1085
1086     Int_t ntracks = (Int_t)gAlice->TreeH()->GetEntries();
1087     Int_t nthits=0;
1088     for (track=0; track<ntracks;track++) {
1089         gAlice->ResetHits();
1090         gAlice->TreeH()->GetEvent(track);
1091         TClonesArray *muonHits  = pMUON->Hits();
1092         if (muonHits == 0) return;
1093         nthits += muonHits->GetEntriesFast();
1094     } 
1095     if (fPhits == 0) fPhits = new TObjArray(nthits);
1096     Int_t nhold=0;
1097     for (track=0; track<ntracks;track++) {
1098         gAlice->ResetHits();
1099         gAlice->TreeH()->GetEvent(track);
1100         TClonesArray *muonHits  = pMUON->Hits();
1101         if (muonHits == 0) return;
1102         Int_t nhits = muonHits->GetEntriesFast();
1103         if (nhits == 0) continue;
1104         AliMUONHit *mHit;
1105         AliMUONPoints *points = 0;
1106         Int_t npoints=1;
1107         for (Int_t hit=0;hit<nhits;hit++) {
1108             mHit = (AliMUONHit*)muonHits->UncheckedAt(hit);
1109             Int_t nch  = mHit->fChamber;              // chamber number
1110             if (nch != chamber) continue;
1111             //
1112             // Retrieve info and set the objects
1113             //
1114             points = new AliMUONPoints(npoints);
1115             fPhits->AddAt(points,nhold+hit);
1116             points->SetMarkerColor(kRed);
1117             points->SetMarkerStyle(5);
1118             points->SetMarkerSize(1.);
1119             points->SetParticle(mHit->fTrack);
1120             points->SetHitIndex(hit);
1121             points->SetTrackIndex(track);
1122             points->SetDigitIndex(-1);
1123             points->SetPoint(0,mHit->fX,mHit->fY,zpos);
1124         }
1125         nhold+=nhits;
1126     }
1127 }
1128
1129 //_____________________________________________________________________________
1130 void AliMUONDisplay::Paint(Option_t *)
1131 {
1132 //    Paint miscellaneous items
1133 }
1134
1135 //_____________________________________________________________________________
1136 void AliMUONDisplay::SetPickMode()
1137 {
1138 // Set parameters for pick mode.
1139 // 
1140     fZoomMode = 0;
1141
1142     fArcButton->SetY1(fPickButton->GetYlowNDC()+0.5*fPickButton->GetHNDC());
1143     fTrigPad->Modified();
1144 }
1145
1146 //_____________________________________________________________________________
1147 void AliMUONDisplay::SetZoomMode()
1148 {
1149 //  Set parameters for zoom mode
1150     fZoomMode = 1;
1151     
1152     fArcButton->SetY1(fZoomButton->GetYlowNDC()+0.5*fZoomButton->GetHNDC());
1153     fTrigPad->Modified();
1154 }
1155
1156 //_____________________________________________________________________________
1157 void AliMUONDisplay::NextChamber(Int_t delta)
1158 {
1159   // to go from chamber to next chamber if delta = 1
1160   // or previous chamber otherwise
1161     if (delta == 1) {
1162         if (fChamber < AliMUONConstants::NCh()) fChamber++;
1163     } else {
1164         if (fChamber > 1) fChamber--;
1165     }
1166     if (!fPad) return;
1167     fPad->Clear();
1168     LoadDigits(fChamber, fCathode);
1169     Draw();
1170 }
1171
1172 //_____________________________________________________________________________
1173 void AliMUONDisplay::NextCathode()
1174 {
1175     // to switch to other cathode plane
1176     if (!fPad) return;
1177     fPad->Clear();
1178     if (fCathode == 1) {
1179         LoadDigits(fChamber, 2);        
1180     } else {
1181         LoadDigits(fChamber, 1);
1182     }
1183     fNextCathode = kTRUE; // to keep the same zoom
1184     Draw();
1185     fNextCathode = kFALSE;
1186     TPad *pad = (TPad*)gPad->GetPadSave();
1187     pad->Range(fZoomX0[fZooms], fZoomY0[fZooms],
1188                fZoomX1[fZooms], fZoomY1[fZooms]);
1189     pad->Modified();
1190     fPad->cd();
1191     DrawTitle();
1192 }
1193
1194 //_____________________________________________________________________________
1195 void AliMUONDisplay::Trigger()
1196 {
1197   // returns Trigger Decision for current event
1198   AliMUONTriggerDecision* decision= new AliMUONTriggerDecision(1);
1199   decision->Trigger(); 
1200 }
1201
1202
1203 //_____________________________________________________________________________
1204 void AliMUONDisplay::SetChamberAndCathode(Int_t chamber, Int_t cathode)
1205 {
1206 // Set chamber and cathode number
1207    fChamber = chamber;
1208    fCathode = cathode;
1209
1210    if (!fPad) return;
1211    fPad->Clear();
1212    LoadDigits(chamber,cathode);
1213    Draw();
1214 }
1215
1216 void AliMUONDisplay::SetEvent(Int_t newevent)
1217 {
1218 // Chose event 
1219     gAlice->GetEvent(newevent);
1220     fEvent=newevent;
1221     if (!gAlice->TreeD()) return; 
1222     if (!fPad) return;
1223     fPad->Clear();
1224     LoadDigits(fChamber,fCathode);
1225     Draw();
1226 }
1227
1228 //_____________________________________________________________________________
1229 void AliMUONDisplay::SetRange(Float_t rrange, Float_t zrange)
1230 {
1231 // Set view range along R and Z
1232     fRrange = rrange;
1233     fZrange = zrange;
1234
1235     if (!fPad) return;
1236     fPad->Clear();
1237     Draw();
1238 }
1239    
1240 //_____________________________________________________________________________
1241 void AliMUONDisplay::SetView(Float_t theta, Float_t phi, Float_t psi)
1242 {
1243 //  change viewing angles for current event
1244
1245     fPad->cd();
1246     fPhi   = phi;
1247     fTheta = theta;
1248     fPsi   = psi;
1249     Int_t iret = 0;
1250     
1251     TView *view = gPad->GetView();
1252     if (view) view->SetView(fPhi, fTheta, fPsi, iret);
1253     else      Draw();
1254     gPad->Modified();
1255 }
1256
1257 //_____________________________________________________________________________
1258 void AliMUONDisplay::ShowNextEvent(Int_t delta)
1259 {
1260 //  Display (current event_number + delta)
1261 //    delta =  1  shown next event
1262 //    delta = -1 show previous event
1263     if (delta) {
1264         gAlice->Clear();
1265         Int_t currentEvent = gAlice->GetHeader()->GetEvent();
1266         Int_t newEvent     = currentEvent + delta;
1267         gAlice->GetEvent(newEvent);
1268         fEvent=newEvent;
1269         if (!gAlice->TreeD()) return; 
1270     }
1271     
1272     LoadDigits(fChamber, fCathode);
1273     fPad->cd(); 
1274     Draw();
1275 }
1276
1277 //______________________________________________________________________________
1278 void AliMUONDisplay::UnZoom()
1279 {
1280 // Unzoom 
1281     if (fZooms <= 0) return;
1282     fZooms--;
1283     TPad *pad = (TPad*)gPad->GetPadSave();
1284     pad->Range(fZoomX0[fZooms],fZoomY0[fZooms], fZoomX1[fZooms],fZoomY1[fZooms]);
1285     pad->Modified();
1286 }
1287
1288 //_____________________________________________________________________________
1289 void AliMUONDisplay::ResetPoints()
1290 {
1291     //
1292     // Reset array of points
1293     //
1294     if (fPoints) {
1295         fPoints->Delete();
1296         delete fPoints;
1297         fPoints = 0;
1298     }
1299 }
1300 //_____________________________________________________________________________
1301 void AliMUONDisplay::ResetPhits()
1302 {
1303     //
1304     // Reset array of points
1305     //
1306     if (fPhits) {
1307         fPhits->Delete();
1308         delete fPhits;
1309         fPhits = 0;
1310     }
1311 }
1312 //_____________________________________________________________________________
1313 void AliMUONDisplay::ResetRpoints()
1314 {
1315   //
1316   // Reset array of points
1317   //
1318     if (fRpoints) {
1319         fRpoints->Delete();
1320         delete fRpoints;
1321         fRpoints = 0;
1322     }
1323 }
1324 //_____________________________________________________________________________
1325 void AliMUONDisplay::ResetR2points()
1326 {
1327   //
1328   // Reset array of points
1329   //
1330     if (fR2points) {
1331         fR2points->Delete();
1332         delete fR2points;
1333         fR2points = 0;
1334     }
1335 }
1336 //_____________________________________________________________________________
1337 void AliMUONDisplay::ResetCpoints()
1338 {
1339     //
1340     // Reset array of points
1341     //
1342   if (fCpoints) {
1343       fCpoints->Delete();
1344       delete fCpoints;
1345       fCpoints = 0;
1346   }
1347 }
1348
1349
1350 AliMUONDisplay & AliMUONDisplay::operator = (const AliMUONDisplay &)
1351 {
1352 // Dummy assignment operator
1353     return *this;
1354 }
1355
1356
1357
1358
1359
1360
1361
1362
1363