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