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