Connect only MUON branches when reading the event to speed up digitisation.
[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 // debug hit numbers
933 //      printf("  Chamber, cathode, digit, hit: %3d, %3d, %3d, %3d \n",
934 //             chamber,cathode,digit,mdig->Hit());
935
936         //
937         // First get all needed parameters
938         //
939         Int_t charge = mdig->Signal();
940         Int_t index  = Int_t(TMath::Log(charge)/(TMath::Log(adcmax)/22));
941         Int_t color  = 261+index;
942         Int_t colorTrigger = 2;   
943         if (color > 282) color = 282;
944
945         if (chamber > 10) { // trigger chamber 
946             Int_t sumCharge = 0;
947             for (Int_t icharge = 0; icharge < 10; icharge++) {
948                 sumCharge = sumCharge+mdig->TrackCharge(icharge);
949             }
950             Int_t testCharge = sumCharge-(Int_t(sumCharge/10))*10;
951             if(sumCharge <= 10 || testCharge > 0) {
952                 colorTrigger = color; 
953             } else {
954                 colorTrigger = 5; 
955             }
956         }
957
958         // get the center of the pad - add on x and y half of pad size
959         Float_t xpad, ypad, zpad;
960         segmentation->GetPadC(mdig->PadX(), mdig->PadY(), xpad, ypad, zpad);
961         
962         Int_t   isec = segmentation->Sector(mdig->PadX(), mdig->PadY());
963         Float_t  dpx = segmentation->Dpx(isec)/2;
964         Float_t  dpy = segmentation->Dpy(isec)/2;
965 //
966 //      segmentation->Dump();
967         
968         //
969         // Then set the objects
970         //
971         points = new AliMUONPoints(npoints);
972         fPoints->AddAt(points,digit);
973         if (chamber > 10) {
974             points->SetMarkerColor(colorTrigger);
975         } else {  
976             points->SetMarkerColor(color);
977         }
978         points->SetMarkerStyle(21);
979         points->SetMarkerSize(0.5);
980         points->SetParticle(-1);
981         points->SetHitIndex(-1);
982         points->SetTrackIndex(-1);
983         points->SetDigitIndex(digit);
984         points->SetPoint(0,xpad,ypad,zpos);     
985
986         Int_t lineColor = (zpad-zpos > 0) ? 2:3;
987         marker=new TMarker3DBox(xpad,ypad,zpos,dpx,dpy,0,0,0);
988
989             
990         marker->SetLineColor(lineColor);
991         marker->SetFillStyle(1001);
992         marker->SetFillColor(color);
993         marker->SetRefObject((TObject*)points);
994         points->Set3DMarker(0, marker);
995     }
996 }
997 //___________________________________________
998 void AliMUONDisplay::LoadCoG(Int_t chamber, Int_t cathode)
999 {
1000 // Read raw clusters info and store x,y,z info in arrays fRpoints
1001 // Loop on all detectors
1002
1003     if (chamber > 10) return;
1004     
1005     ResetRpoints();
1006     
1007     AliMUON *pMUON  = (AliMUON*)gAlice->GetModule("MUON");
1008     AliMUONChamber*  iChamber;
1009     
1010     TClonesArray *muonRawClusters  = pMUON->RawClustAddress(chamber-1);
1011     if (muonRawClusters == 0) return;
1012
1013 //     pMUON->ResetRawClusters();
1014
1015     Int_t nent = 0;
1016     if (gAlice->TreeR()) {
1017         nent=(Int_t)gAlice->TreeR()->GetEntries();
1018         gAlice->TreeR()->GetEvent(0);
1019     }
1020     
1021     Int_t nrawcl = muonRawClusters->GetEntriesFast();
1022     if (nrawcl == 0) return;
1023     if (fRpoints == 0) fRpoints = new TObjArray(nrawcl);
1024     
1025     iChamber = &(pMUON->Chamber(chamber-1));
1026     Float_t zpos=iChamber->Z();  
1027     AliMUONRawCluster  *mRaw;
1028     AliMUONPoints *points = 0;
1029     //
1030     //loop over all raw clusters and store their position
1031     points = new AliMUONPoints(nrawcl);
1032     for (Int_t iraw=0;iraw<nrawcl;iraw++) {
1033         mRaw   = (AliMUONRawCluster*)muonRawClusters->UncheckedAt(iraw);
1034         fRpoints->AddAt(points,iraw);
1035         points->SetMarkerColor(51);
1036         points->SetMarkerStyle(2);
1037         points->SetMarkerSize(1.);
1038         points->SetParticle(-1);
1039         points->SetHitIndex(-1);
1040         points->SetTrackIndex(-1);
1041         points->SetDigitIndex(-1);
1042         points->SetPoint(iraw,mRaw->fX[0],mRaw->fY[0],zpos);
1043     }
1044 }
1045 //___________________________________________
1046 void AliMUONDisplay::LoadHits(Int_t chamber)
1047 {
1048 // Read hits info and store x,y,z info in arrays fPhits
1049 // Loop on all detectors
1050
1051     if (chamber > 14) return;
1052     Int_t track;
1053
1054     fChamber=chamber;
1055  
1056     ResetPhits();
1057     
1058     AliMUON *pMUON  = (AliMUON*)gAlice->GetModule("MUON");
1059     AliMUONChamber*  iChamber;
1060
1061     iChamber = &(pMUON->Chamber(chamber-1));
1062     Float_t zpos=iChamber->Z();
1063
1064     Int_t ntracks = (Int_t)gAlice->TreeH()->GetEntries();
1065     Int_t nthits  = 0;
1066     for (track = 0; track < ntracks; track++) {
1067         gAlice->ResetHits();
1068         gAlice->TreeH()->GetEvent(track);
1069         TClonesArray *muonHits  = pMUON->Hits();
1070         if (muonHits == 0) return;
1071         nthits += muonHits->GetEntriesFast();
1072     } 
1073     if (fPhits == 0) fPhits = new TObjArray(nthits);
1074     Int_t nhold=0;
1075     for (track=0; track<ntracks;track++) {
1076         gAlice->ResetHits();
1077         gAlice->TreeH()->GetEvent(track);
1078         TClonesArray *muonHits  = pMUON->Hits();
1079         if (muonHits == 0) return;
1080         Int_t nhits = muonHits->GetEntriesFast();
1081         if (nhits == 0) continue;
1082         AliMUONHit *mHit;
1083         AliMUONPoints *points = 0;
1084         Int_t npoints=1;
1085         for (Int_t hit=0;hit<nhits;hit++) {
1086             mHit = (AliMUONHit*)muonHits->UncheckedAt(hit);
1087             Int_t nch  = mHit->Chamber();              // chamber number
1088             if (nch != chamber) continue;
1089             //
1090             // Retrieve info and set the objects
1091             //
1092             points = new AliMUONPoints(npoints);
1093             fPhits->AddAt(points,nhold+hit);
1094             points->SetMarkerColor(kRed);
1095             points->SetMarkerStyle(5);
1096             points->SetMarkerSize(2.); // JCH change
1097             points->SetParticle(mHit->Track());
1098             points->SetHitIndex(hit);
1099             points->SetTrackIndex(track);
1100             points->SetDigitIndex(-1);
1101             points->SetPoint(0,mHit->X(),mHit->Y(),zpos);
1102         }
1103         nhold+=nhits;
1104     }
1105 }
1106
1107 //_____________________________________________________________________________
1108 void AliMUONDisplay::Paint(Option_t *)
1109 {
1110 //    Paint miscellaneous items
1111 }
1112
1113 //_____________________________________________________________________________
1114 void AliMUONDisplay::SetPickMode()
1115 {
1116 // Set parameters for pick mode.
1117 // 
1118     fZoomMode = 0;
1119
1120     fArcButton->SetY1(fPickButton->GetYlowNDC()+0.5*fPickButton->GetHNDC());
1121     fTrigPad->Modified();
1122 }
1123
1124 //_____________________________________________________________________________
1125 void AliMUONDisplay::SetZoomMode()
1126 {
1127 //  Set parameters for zoom mode
1128     fZoomMode = 1;
1129     
1130     fArcButton->SetY1(fZoomButton->GetYlowNDC()+0.5*fZoomButton->GetHNDC());
1131     fTrigPad->Modified();
1132 }
1133
1134 //_____________________________________________________________________________
1135 void AliMUONDisplay::NextChamber(Int_t delta)
1136 {
1137   // to go from chamber to next chamber if delta = 1
1138   // or previous chamber otherwise
1139     if (delta == 1) {
1140         if (fChamber < AliMUONConstants::NCh()) fChamber++;
1141     } else {
1142         if (fChamber > 1) fChamber--;
1143     }
1144     if (!fPad) return;
1145     fPad->Clear();
1146     LoadDigits(fChamber, fCathode);
1147     Draw();
1148 }
1149
1150 //_____________________________________________________________________________
1151 void AliMUONDisplay::NextCathode()
1152 {
1153     // to switch to other cathode plane
1154     if (!fPad) return;
1155     fPad->Clear();
1156     if (fCathode == 1) {
1157         LoadDigits(fChamber, 2);        
1158     } else {
1159         LoadDigits(fChamber, 1);
1160     }
1161     fNextCathode = kTRUE; // to keep the same zoom
1162     Draw();
1163     fNextCathode = kFALSE;
1164     TPad *pad = (TPad*)gPad->GetPadSave();
1165     pad->Range(fZoomX0[fZooms], fZoomY0[fZooms],
1166                fZoomX1[fZooms], fZoomY1[fZooms]);
1167     pad->Modified();
1168     fPad->cd();
1169     DrawTitle();
1170 }
1171
1172 //_____________________________________________________________________________
1173 void AliMUONDisplay::Trigger()
1174 {
1175   // returns Trigger Decision for current event
1176   AliMUONTriggerDecision* decision= new AliMUONTriggerDecision(1);
1177   decision->Trigger(); 
1178 }
1179
1180
1181 //_____________________________________________________________________________
1182 void AliMUONDisplay::SetChamberAndCathode(Int_t chamber, Int_t cathode)
1183 {
1184 // Set chamber and cathode number
1185    fChamber = chamber;
1186    fCathode = cathode;
1187
1188    if (!fPad) return;
1189    fPad->Clear();
1190    LoadDigits(chamber,cathode);
1191    Draw();
1192 }
1193
1194 void AliMUONDisplay::SetEvent(Int_t newevent)
1195 {
1196 // Chose event 
1197     gAlice->GetEvent(newevent);
1198     fEvent=newevent;
1199     if (!gAlice->TreeD()) return; 
1200     if (!fPad) return;
1201     fPad->Clear();
1202     LoadDigits(fChamber,fCathode);
1203     Draw();
1204 }
1205
1206 //_____________________________________________________________________________
1207 void AliMUONDisplay::SetRange(Float_t rrange, Float_t zrange)
1208 {
1209 // Set view range along R and Z
1210     fRrange = rrange;
1211     fZrange = zrange;
1212
1213     if (!fPad) return;
1214     fPad->Clear();
1215     Draw();
1216 }
1217    
1218 //_____________________________________________________________________________
1219 void AliMUONDisplay::SetView(Float_t theta, Float_t phi, Float_t psi)
1220 {
1221 //  change viewing angles for current event
1222
1223     fPad->cd();
1224     fPhi   = phi;
1225     fTheta = theta;
1226     fPsi   = psi;
1227     Int_t iret = 0;
1228     
1229     TView *view = gPad->GetView();
1230     if (view) view->SetView(fPhi, fTheta, fPsi, iret);
1231     else      Draw();
1232     gPad->Modified();
1233 }
1234
1235 //_____________________________________________________________________________
1236 void AliMUONDisplay::ShowNextEvent(Int_t delta)
1237 {
1238 //  Display (current event_number + delta)
1239 //    delta =  1  shown next event
1240 //    delta = -1 show previous event
1241     if (delta) {
1242         gAlice->Clear();
1243         Int_t currentEvent = gAlice->GetHeader()->GetEvent();
1244         Int_t newEvent     = currentEvent + delta;
1245         gAlice->GetEvent(newEvent);
1246         fEvent=newEvent;
1247         if (!gAlice->TreeD()) return; 
1248     }
1249     
1250     LoadDigits(fChamber, fCathode);
1251     fPad->cd(); 
1252     Draw();
1253 }
1254
1255 //______________________________________________________________________________
1256 void AliMUONDisplay::UnZoom()
1257 {
1258 // Unzoom 
1259     if (fZooms <= 0) return;
1260     fZooms--;
1261     TPad *pad = (TPad*)gPad->GetPadSave();
1262     pad->Range(fZoomX0[fZooms],fZoomY0[fZooms], fZoomX1[fZooms],fZoomY1[fZooms]);
1263     pad->Modified();
1264 }
1265
1266 //_____________________________________________________________________________
1267 void AliMUONDisplay::ResetPoints()
1268 {
1269     //
1270     // Reset array of points
1271     //
1272     if (fPoints) {
1273         fPoints->Delete();
1274         delete fPoints;
1275         fPoints = 0;
1276     }
1277 }
1278 //_____________________________________________________________________________
1279 void AliMUONDisplay::ResetPhits()
1280 {
1281     //
1282     // Reset array of points
1283     //
1284     if (fPhits) {
1285         fPhits->Delete();
1286         delete fPhits;
1287         fPhits = 0;
1288     }
1289 }
1290 //_____________________________________________________________________________
1291 void AliMUONDisplay::ResetRpoints()
1292 {
1293   //
1294   // Reset array of points
1295   //
1296     if (fRpoints) {
1297         fRpoints->Delete();
1298         delete fRpoints;
1299         fRpoints = 0;
1300     }
1301 }
1302
1303 AliMUONDisplay & AliMUONDisplay::operator = (const AliMUONDisplay &)
1304 {
1305 // Dummy assignment operator
1306     return *this;
1307 }
1308
1309
1310
1311
1312
1313
1314
1315
1316