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