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