]> git.uio.no Git - u/mrichter/AliRoot.git/blob - EVE/Alieve/MUONModule.cxx
Added option to respond to missing galice.root or AliESD.root files in Open() with...
[u/mrichter/AliRoot.git] / EVE / Alieve / MUONModule.cxx
1 /* HEAD11Jul06 */
2 //////////////////////////////////////////////////////////////////////////
3 //                                                                      //
4 // The main AliEVE drawing module for the MUON detector                 //
5 //                                                                      //
6 //////////////////////////////////////////////////////////////////////////
7
8 #include "EventAlieve.h"
9 #include "Reve/PointSet.h"
10 #include "Reve/RGTopFrame.h"
11
12 #include "AliRun.h"
13 #include "AliRunLoader.h"
14
15 #include "AliMUON.h"
16 #include "AliMpDEIterator.h"
17 #include "AliMpSectorSegmentation.h"
18 #include "AliMpSector.h"
19 #include "AliMUONGeometryTransformer.h"
20 #include "AliMUONSegmentation.h"
21 #include "AliMUONSegFactory.h"
22 #include "AliMpStationType.h"
23 #include "AliMpDEManager.h"
24 #include "AliMUONConstants.h"
25 #include "AliMUONDigit.h"
26 #include "AliMUONRawCluster.h"
27 #include "AliMUONTrack.h"
28 #include "AliMUONTrackParam.h"
29
30 #include "MUONModule.h"
31
32 #include <TPolyLine3D.h>
33 #include <TMarker3DBox.h>
34 #include <TColor.h>
35
36 using namespace Reve;
37 using namespace Alieve;
38 using namespace std;
39
40 ClassImp(MUONModule)
41
42 /**************************************************************************/
43 MUONModule::MUONModule(const Text_t* n, const Text_t* t, Color_t col) :
44   Reve::RenderElement(col),
45   QuadSet(n, t),
46   fInfo(0),
47   fID(-1), 
48   fCath(0),
49   fShowDigits(0), fShowClusters(0), fShowTracks(0),
50   fFrameCol(col),
51   fDetElemId(-1)
52 {
53   //
54   // Default constructor
55   //
56
57 }
58
59 /**************************************************************************/
60 MUONModule::MUONModule(Int_t id, Int_t cath, MUONDigitsInfo* info, Bool_t dig, Bool_t clus, Color_t col ) :
61   Reve::RenderElement(col),
62   QuadSet(Form("M-DetElemId %d C%1d",id,cath)),
63   fInfo(info),
64   fID(-1), 
65   fCath(0),
66   fShowDigits(dig), fShowClusters(clus), fShowTracks(0),
67   fFrameCol(col),
68   fDetElemId(-1)
69 {
70   //
71   // Constructor
72   //
73
74   if (!fShowDigits && !fShowClusters) fShowTracks = 1;
75
76   if (fShowClusters) SetName(Form("M-DetElemId %d",id));
77
78   if (id/100 >= 11 && cath == 1) SetName(Form("M-DetElemId %d X",id));
79   if (id/100 >= 11 && cath == 2) SetName(Form("M-DetElemId %d Y",id));
80   if (id == -1 && cath == -1) SetName(Form("M-Chambers"));
81   if (id >  -1 && cath == -1) SetName(Form("M-Track %d",id));
82   if (cath == -2) SetName(Form("M-Chamber %2d",id));
83   if (cath == -3) SetName(Form("M-Pads %d X",id));
84   if (cath == -4) SetName(Form("M-Pads %d Y",id));
85
86   SetID(id,cath);
87
88 }
89
90 /**************************************************************************/
91 MUONModule::MUONModule(const MUONModule &mmod) :
92   Reve::RenderElement(),
93   QuadSet(Form("M-DetElemId %d C%1d",mmod.fID,mmod.fCath)),
94   fInfo(mmod.fInfo),
95   fID(mmod.fID),
96   fCath(mmod.fCath),
97   fShowDigits(mmod.fShowDigits),
98   fShowClusters(mmod.fShowClusters),
99   fShowTracks(mmod.fShowTracks),
100   fFrameCol(mmod.fFrameCol),
101   fDetElemId(mmod.fDetElemId)
102 {
103   //
104   // Copy constructor
105   //
106
107 }
108
109 /**************************************************************************/
110 MUONModule& MUONModule::operator=(const MUONModule &mmod)
111 {
112   //
113   // Assignment operator
114   //
115
116   if (this != &mmod) {
117
118     fInfo         = mmod.fInfo;
119     fID           = mmod.fID;
120     fCath         = mmod.fCath;
121     fShowDigits   = mmod.fShowDigits;
122     fShowClusters = mmod.fShowClusters;
123     fShowTracks   = mmod.fShowTracks;
124     fFrameCol     = mmod.fFrameCol;
125     fDetElemId    = mmod.fDetElemId;
126
127   }
128
129   return *this;
130
131 }
132
133 /**************************************************************************/
134 void MUONModule::SetID(Int_t id, Int_t cath)
135 {
136   //
137   // Select a single detector element id
138   //
139
140   static const Exc_t eH("MUOModule::SetID ");
141
142   if(fInfo == 0)
143     throw(eH + "MUONDigitsInfo not set.");
144
145   fID   = id;
146   fCath = cath;
147
148   InitModule();
149
150 }
151
152 /**************************************************************************/
153 void MUONModule::InitModule()
154 {
155   // 
156   // Initialize and draw selected items
157   //
158
159   fDetElemId = 0;
160
161   if (fShowDigits) LoadQuadsDigits();
162   if (fShowClusters) LoadQuadsClusters();
163   if (fShowTracks) {
164     if (fCath == -1){
165       LoadQuadsTracks(fID);
166     } else if (fCath == -2 || fCath == -3 || fCath == -4) {
167       if (fCath == -2) LoadQuadsChambers(fID,fID);
168       if (fCath == -3) LoadQuadsChambers(fID,fID,-1,1);
169       if (fCath == -4) LoadQuadsChambers(fID,fID,-1,2);
170     }
171   }
172   ComputeBBox();
173
174 }
175
176 /**************************************************************************/
177 void MUONModule::LoadQuadsChambers(Int_t chamber1, Int_t chamber2, Int_t id, Int_t cat)
178 {
179   //
180   // Draw chambers
181   //
182
183   //printf("Draw chambers: %d %d %d %d %d \n",chamber1,chamber2,id,cat,fCath);
184
185   Int_t fChamber;
186
187   AliRunLoader *runLoader = Alieve::Event::AssertRunLoader();
188   runLoader->LoadgAlice();
189
190   AliMUON *pMUON = (AliMUON*)gAlice->GetModule("MUON");
191
192   const AliMUONGeometryTransformer* kGeomTransformer = pMUON->GetGeometryTransformer();
193   AliMUONSegmentation* segmentation = pMUON->GetSegmentation();
194   AliMpSegFactory segFactory;
195
196   Float_t xg1, xg2, yg1, yg2, zg1, zg2;
197
198   for (fChamber = chamber1; fChamber <= chamber2; fChamber++) {
199
200   if(fChamber < 5) {
201
202     AliMpDEIterator it;
203     for ( it.First(fChamber-1); ! it.IsDone(); it.Next() ) {
204       
205     Int_t detElemId = it.CurrentDE();
206
207     if (id > 0 && id != detElemId) continue;
208       
209     //printf("Detector element ID for chamber %d (tracking): %d \n",fChamber,detElemId);
210     
211     AliMpSectorSegmentation * seg = (AliMpSectorSegmentation *) segmentation->GetMpSegmentation(detElemId, 0);
212     const AliMpSector * sector = seg->GetSector();
213     
214     // get sector measurements
215     TVector2 position  = sector->Position(); 
216     TVector2 dimension = sector->Dimensions(); // half length
217
218     //printf("Sector position: \n"); position.Print();
219     //printf("Sector dimensions: \n"); dimension.Print();
220     
221     Float_t xlocal1 =  position.Px(); // FIXME: not really needed as it's 0 ?
222     Float_t ylocal1 =  position.Py(); // FIXME: not really needed as it's 0 ?
223     Float_t xlocal2 =  dimension.Px() * 2.;
224     Float_t ylocal2 =  dimension.Px() * 2.;
225     
226     //printf("Local position and dimension: xp = %f , yp = %f xd = %f yd = %f \n",xlocal1,ylocal1,xlocal2,ylocal2);
227     
228     kGeomTransformer->Local2Global(detElemId, xlocal1, ylocal1, 0, xg1, yg1, zg1);
229     kGeomTransformer->Local2Global(detElemId, xlocal2, ylocal2, 0, xg2, yg2, zg2);
230     
231     //printf("Global position: xpg = %f , ypg = %f zpg = %f \n",xg1,yg1,zg1);
232     //printf("Global dimension: xdg = %f , ydg = %f zdg = %f \n",xg2,yg2,zg2);
233     
234     Float_t *p;
235     if (fCath != -3 && fCath != -4) {
236     fQuads.push_back(Reve::Quad(fFrameCol));
237     p = fQuads.back().vertices;
238     /*
239     p[0] = xg1;      p[1] =  yg1; p[2]  = zg1;
240     p[3] = xg1;      p[4] =  yg1; p[5]  = zg1;
241     p[6] = xg1+xg2;  p[7] =  yg1; p[8]  = zg1;
242     p[9] = xg1+xg2;  p[10] = yg1; p[11] = zg1;
243     */
244     // switch x <> z
245     p[0] = zg1;      p[1] =  yg1; p[2]  = xg1;
246     p[3] = zg1;      p[4] =  yg1; p[5]  = xg1;
247     p[6] = zg1;      p[7] =  yg1; p[8]  = xg1+xg2;
248     p[9] = zg1;      p[10] = yg1; p[11] = xg1+xg2;
249     
250     Float_t xprev = xg1+xg2;
251     Float_t yprev = yg1;
252     Int_t nstep = 100;
253     Float_t dstep = TMath::Pi()/2.0 / (Float_t)nstep;
254     Float_t d;
255     for (Int_t istep = 1; istep < (nstep+1); istep++) {
256
257       d = istep * dstep;
258       Float_t x = xg1 + xg2 * TMath::Cos(d);
259       Float_t y = yg1 + yg2 * TMath::Sin(d);
260
261       fQuads.push_back(Reve::Quad(fFrameCol));
262       p = fQuads.back().vertices;
263       /*
264       p[0] = xprev; p[1] =  yprev; p[2]  = zg1;
265       p[3] = xprev; p[4] =  yprev; p[5]  = zg1;
266       p[6] = x;     p[7] =  y;     p[8]  = zg1;
267       p[9] = x;     p[10] = y;     p[11] = zg1;
268       */
269       // switch x <> z
270       p[0] = zg1;   p[1] =  yprev; p[2]  = xprev;
271       p[3] = zg1;   p[4] =  yprev; p[5]  = xprev;
272       p[6] = zg1;   p[7] =  y;     p[8]  = x;
273       p[9] = zg1;   p[10] = y;     p[11] = x;
274
275       xprev = x;
276       yprev = y;
277
278     }
279
280     fQuads.push_back(Reve::Quad(fFrameCol));
281     p = fQuads.back().vertices;
282     /*
283     p[0] = xprev;      p[1] =  yprev; p[2]  = zg1;
284     p[3] = xprev;      p[4] =  yprev; p[5]  = zg1;
285     p[6] = xg1;        p[7] =  yg1;   p[8]  = zg1;
286     p[9] = xg1;        p[10] = yg1;   p[11] = zg1;
287     */
288     // switch x <> z
289     p[0] = zg1;        p[1] =  yprev; p[2]  = xprev;
290     p[3] = zg1;        p[4] =  yprev; p[5]  = xprev;
291     p[6] = zg1;        p[7] =  yg1;   p[8]  = xg1;
292     p[9] = zg1;        p[10] = yg1;   p[11] = xg1;
293     }  //  end fCath != -3 , -4
294     }  //  end detElemId
295
296   }
297
298   if (fChamber>4) {
299
300     AliMpDEIterator it;
301     for ( it.First(fChamber-1); ! it.IsDone(); it.Next() ) {
302       
303     Int_t detElemId = it.CurrentDE();
304           
305     if (id > 0 && id != detElemId) continue;
306       
307     //AliMpStationType stationType = AliMpDEManager::GetStationType(detElemId);
308     
309     //printf("Detector element ID for chamber %d (trigger, stationType %s): %d \n",fChamber,StationTypeName(stationType).Data(),detElemId);
310     
311     if (  segmentation->HasDE(detElemId) ) {
312       const AliMpVSegmentation* seg1 = segmentation->GetMpSegmentation(detElemId, 0);
313       if (!seg1) { 
314         // Create mapping segmentation if old trigger segmentation
315         // (not using mapping)
316         seg1 = segFactory.CreateMpSegmentation(detElemId, 0);
317       }   
318       if (seg1) {  
319         
320         Float_t deltax = seg1->Dimensions().X();
321         Float_t deltay = seg1->Dimensions().Y();
322         Float_t xlocal1 =  -deltax;
323         Float_t ylocal1 =  -deltay;
324         Float_t xlocal2 =  +deltax;
325         Float_t ylocal2 =  +deltay;
326         
327         //printf("Local corners: x1 = %f , y1 = %f x2 = %f y2 = %f \n",xlocal1,ylocal1,xlocal2,ylocal2);
328         
329         kGeomTransformer->Local2Global(detElemId, xlocal1, ylocal1, 0, xg1, yg1, zg1);
330         kGeomTransformer->Local2Global(detElemId, xlocal2, ylocal2, 0, xg2, yg2, zg2);
331         
332         //printf("Global corner 1: xg1 = %f , yg1 = %f zg1 = %f \n",xg1,yg1,zg1);
333         //printf("Global corner 2: xg2 = %f , yg2 = %f zg2 = %f \n",xg2,yg2,zg2);
334         
335         if (fCath != -3 && fCath != -4) {
336         fQuads.push_back(Reve::Quad(fFrameCol));
337         Float_t* p = fQuads.back().vertices;
338         // the tilting direction now known...
339         /*
340         p[0] = xg1;  p[1] =  yg1; p[2]  = zg1;
341         p[3] = xg1;  p[4] =  yg2; p[5]  = zg1;
342         p[6] = xg2;  p[7] =  yg2; p[8]  = zg2;
343         p[9] = xg2;  p[10] = yg1; p[11] = zg2;
344         */
345         // switch x <> z
346         p[0] = zg1;  p[1] =  yg1; p[2]  = xg1;
347         p[3] = zg1;  p[4] =  yg2; p[5]  = xg1;
348         p[6] = zg2;  p[7] =  yg2; p[8]  = xg2;
349         p[9] = zg2;  p[10] = yg1; p[11] = xg2;
350         }
351         if (fCath == -3 || fCath == -4) {
352         // draw all pads in the trigger chambers
353         if (fChamber > 10) {
354
355           for (Int_t ic = 1; ic <= 2; ic++) {
356
357           if (ic != cat) continue;
358
359           const AliMpVSegmentation* seg3 = segmentation->GetMpSegmentation(detElemId, ic-1);
360           Int_t maxX = seg3->MaxPadIndexX();
361           Int_t maxY = seg3->MaxPadIndexY();
362           //printf("detElemId %d ic %d maxX %d maxY %d \n",detElemId,ic,maxX,maxY);
363           for (Int_t ix = 0; ix <= maxX; ix++) {
364             for (Int_t iy = 0; iy <= maxY; iy++) {
365
366               AliMpPad pad = seg3->PadByIndices(AliMpIntPair(ix,iy),kFALSE);
367
368               if (!pad.IsValid()) continue;
369
370               // get the pad position and dimensions
371               xlocal1 = pad.Position().X();
372               ylocal1 = pad.Position().Y();
373               xlocal2 = pad.Dimensions().X();
374               ylocal2 = pad.Dimensions().Y();
375
376               kGeomTransformer->Local2Global(detElemId, xlocal1, ylocal1, 0, xg1, yg1, zg1);
377               // (no transformation for pad dimensions)
378               xg2 = xlocal2;
379               yg2 = ylocal2;
380               
381               Int_t pcolor = 0;
382               if (ic == 1) pcolor = 5;
383               if (ic == 2) pcolor = 5;
384
385               fQuads.push_back(Reve::Quad());
386               fQuads.back().ColorFromIdx(pcolor);
387               Float_t* p = fQuads.back().vertices;
388               // the tilting direction now known...
389               // switch x <> z
390               p[0] = zg1;         p[1] =  yg1-yg2; p[2]  = xg1-xg2;
391               p[3] = zg1;         p[4] =  yg1+yg2; p[5]  = xg1-xg2;
392               p[6] = zg1;         p[7] =  yg1+yg2; p[8]  = xg1+xg2;
393               p[9] = zg1;         p[10] = yg1-yg2; p[11] = xg1+xg2;
394               
395             }
396           }
397
398           }  // end "cathode" loop
399
400         }  // end draw pads
401         }  // end fCath == -3 , -4
402      }  
403
404     }
405     
406     }  // end detElemId
407   
408   }
409
410   }  // end chamber loop
411
412 }
413
414 /**************************************************************************/
415 void MUONModule::LoadQuadsDigits()
416 {
417   // 
418   // Draw digits
419   //
420
421   if (fDetElemId > 0 && fDetElemId != fID) return;
422
423   Int_t fChamber;
424
425   AliRunLoader *runLoader = Alieve::Event::AssertRunLoader();
426   runLoader->LoadgAlice();
427
428   AliMUON *pMUON = (AliMUON*)gAlice->GetModule("MUON");
429
430   const AliMUONGeometryTransformer* kGeomTransformer = pMUON->GetGeometryTransformer();
431
432   fChamber = fID/100;
433
434   /*           D I S P L A Y     D I G I T S                              */
435
436   // Display X-Y strips for the trigger chambers
437
438   Float_t adcmax = 1024; // default
439   if (fChamber<11) adcmax = 4096;
440
441   TClonesArray *digits;
442   Int_t ndigits;
443   digits  = fInfo->GetDigits(fChamber);
444   ndigits = digits->GetEntriesFast(); 
445
446   AliMUONDigit  *mdig;
447
448   Int_t fCathode = fCath;
449
450   for (Int_t id = 0; id < ndigits; id++) {
451     mdig  = (AliMUONDigit*)digits->UncheckedAt(id);
452     if (mdig->Cathode() != fCathode-1) continue;
453
454     // get all needed parameters
455     Int_t ix=mdig->PadX();
456     Int_t iy=mdig->PadY();
457     Int_t detElemId=mdig->DetElemId();      
458     Int_t charge = mdig->Signal();
459     Int_t index  = Int_t(TMath::Log(charge)/(TMath::Log(adcmax)/22));
460     Int_t color  = 261+index;
461     Int_t colorTrigger = 2;   
462     if (color > 282) color = 282;
463
464     if (detElemId != fID) continue;
465       
466     const AliMpVSegmentation* seg2 = pMUON->GetSegmentation()->GetMpSegmentation(detElemId,fCathode-1);
467
468     AliMpPad pad = seg2->PadByIndices(AliMpIntPair(ix,iy),kTRUE);
469
470     //printf("Dig ix %d iy %d \n",ix,iy);
471
472     // time delay information
473     if (fChamber > 10) { // trigger chamber
474       Int_t sumCharge = 0;
475       Int_t n = mdig->Ntracks();
476       for (Int_t icharge = 0; icharge < n; icharge++) {
477         sumCharge = sumCharge+mdig->TrackCharge(icharge);
478       }
479       assert(sumCharge==mdig->Signal());
480       Int_t testCharge = sumCharge-(Int_t(sumCharge/n))*n;
481       if(sumCharge <= n || testCharge > 0) {
482         colorTrigger = 4; 
483       } else {
484         colorTrigger = 5; 
485       }
486     }
487             
488     // get the pad position and dimensions
489     Float_t xlocal1 = pad.Position().X();
490     Float_t ylocal1 = pad.Position().Y();
491     Float_t xlocal2 = pad.Dimensions().X();
492     Float_t ylocal2 = pad.Dimensions().Y();
493
494     Float_t xg1, xg2, yg1, yg2, zg1;
495             
496     kGeomTransformer->Local2Global(detElemId, xlocal1, ylocal1, 0, xg1, yg1, zg1);
497     // (no transformation for pad dimensions)
498     xg2 = xlocal2;
499     yg2 = ylocal2;
500
501     if (fChamber > 10) {
502       color = colorTrigger;
503     }
504
505     fQuads.push_back(Reve::Quad());
506     fQuads.back().ColorFromIdx(color);
507     Float_t* p = fQuads.back().vertices;
508     // the tilting direction now known...
509     /*
510     p[0] = xg1-xg2;  p[1] =  yg1-yg2; p[2]  = zg1;
511     p[3] = xg1-xg2;  p[4] =  yg1+yg2; p[5]  = zg1;
512     p[6] = xg1+xg2;  p[7] =  yg1+yg2; p[8]  = zg1;
513     p[9] = xg1+xg2;  p[10] = yg1-yg2; p[11] = zg1;
514     */
515     // switch x <> z
516     p[0] = zg1;         p[1] =  yg1-yg2; p[2]  = xg1-xg2;
517     p[3] = zg1;         p[4] =  yg1+yg2; p[5]  = xg1-xg2;
518     p[6] = zg1;         p[7] =  yg1+yg2; p[8]  = xg1+xg2;
519     p[9] = zg1;         p[10] = yg1-yg2; p[11] = xg1+xg2;
520     /*
521     if (fChamber < 11) {
522     printf("coordinates.............................. \n");
523     for (Int_t j = 0; j < 12; j++) {
524       printf("%f ",p[j]);
525       if ((j+1)%3 == 0) printf("\n");
526     }
527     }
528     */
529
530   }  // end loop over digits
531
532   LoadQuadsChambers(fChamber,fChamber,fID,fCath);
533
534 }
535
536 /**************************************************************************/
537 void MUONModule::LoadQuadsClusters()
538 {
539   //
540   // Draw clusters
541   //
542
543   Int_t fChamber;
544
545   fChamber = fID/100;
546
547   LoadQuadsChambers(fChamber,fChamber,fID);
548
549   /*           D I S P L A Y     C L U S T E R S                           */
550
551   TClonesArray *clusters;
552   Int_t nclusters;
553   clusters  = fInfo->GetClusters(fChamber);
554   if (clusters == 0) return;
555   nclusters = clusters->GetEntriesFast(); 
556
557   //Float_t zpos = AliMUONConstants::DefaultChamberZ(fChamber-1);  
558
559   AliMUONRawCluster  *cls;
560   for (Int_t iCls = 0; iCls < nclusters; iCls++) {
561
562     cls = (AliMUONRawCluster*)clusters->UncheckedAt(iCls);
563
564     if (cls->GetDetElemId() != fID) continue;
565
566     Float_t x = cls->GetX(0);
567     Float_t y = cls->GetY(0);
568     Float_t z = cls->GetZ(0);
569
570     Float_t dx = 1.0/2.0;
571     Float_t dy = 1.0/2.0;
572     Float_t r = TMath::Sqrt(dx*dx+dy*dy);
573     /*
574     // just an empty  square
575     fQuads.push_back(Reve::Quad(5));
576     Float_t* p = fQuads.back().vertices;
577     
578     //p[0] = x-dx;  p[1] =  y-dy; p[2]  = z;
579     //p[3] = x-dx;  p[4] =  y+dy; p[5]  = z;
580     //p[6] = x+dx;  p[7] =  y+dy; p[8]  = z;
581     //p[9] = x+dx;  p[10] = y-dy; p[11] = z;
582     
583     // switch x <> z
584     p[0] = z;     p[1] =  y-dy; p[2]  = x-dx;
585     p[3] = z;     p[4] =  y+dy; p[5]  = x-dx;
586     p[6] = z;     p[7] =  y+dy; p[8]  = x+dx;
587     p[9] = z;     p[10] = y-dy; p[11] = x+dx;
588     */
589     Int_t nstep = 100;
590     Float_t dstep = 2.0*TMath::Pi() / (Float_t)nstep;
591     Float_t d;
592     for (Int_t istep = 1; istep < (nstep+1); istep++) {
593
594       d = istep * dstep;
595       Float_t xc = x + r * TMath::Cos(d);
596       Float_t yc = y + r * TMath::Sin(d);
597
598       fQuads.push_back(Reve::Quad(5));
599       Float_t* p = fQuads.back().vertices;
600
601       p[0] = z;     p[1] =  y;  p[2]  = x;
602       p[3] = z;     p[4] =  y;  p[5]  = x;
603       p[6] = z;     p[7] =  yc; p[8]  = xc;
604       p[9] = z;     p[10] = yc; p[11] = xc;
605
606    }
607
608   }
609
610 }
611
612 /**************************************************************************/
613 void MUONModule::LoadQuadsTracks(Int_t id)
614 {
615   //
616   // Draw tracks
617   //
618
619   /*           D I S P L A Y     T R A C K S                           */
620
621   TClonesArray * trackParamAtHit = 0;   
622   TClonesArray *tracks;
623   Int_t ntracks;
624   tracks  = fInfo->GetTracks();
625   if (tracks == 0) return;
626   ntracks = tracks->GetEntriesFast(); 
627
628   Float_t *p;
629
630   AliMUONTrack *recTrack = (AliMUONTrack*)tracks->At(id);
631
632   Float_t xRec, xRec0;
633   Float_t yRec, yRec0;
634   Float_t zRec, zRec0;
635   
636   AliMUONTrackParam *trackParam = recTrack->GetTrackParamAtVertex(); 
637   xRec0  = trackParam->GetNonBendingCoor();
638   yRec0  = trackParam->GetBendingCoor();
639   zRec0  = trackParam->GetZ();
640
641   Int_t nTrackHits = recTrack->GetNTrackHits();
642   for (Int_t iHit = 0; iHit < nTrackHits; iHit++){
643     trackParamAtHit = recTrack->GetTrackParamAtHit();
644     trackParam = (AliMUONTrackParam*) trackParamAtHit->At(iHit); 
645     xRec  = trackParam->GetNonBendingCoor();
646     yRec  = trackParam->GetBendingCoor();
647     zRec  = trackParam->GetZ();
648
649     fQuads.push_back(Reve::Quad());
650     fQuads.back().ColorFromIdx(4);
651     p = fQuads.back().vertices;
652     
653     p[0] = zRec0; p[1] =  yRec0; p[2]  = xRec0;
654     p[3] = zRec0; p[4] =  yRec0; p[5]  = xRec0;
655     p[6] = zRec;  p[7] =  yRec;  p[8]  = xRec;
656     p[9] = zRec;  p[10] = yRec;  p[11] = xRec;
657
658     xRec0 = xRec;
659     yRec0 = yRec;
660     zRec0 = zRec;
661
662   } // end loop rec. hits
663
664 }
665