Update to the current version in the Bergen CVS. Most important
[u/mrichter/AliRoot.git] / HLT / comp / AliL3ModelTrack.cxx
1 // @(#) $Id$
2
3 // Author: Anders Vestbo <mailto:vestbo$fi.uib.no>
4 //*-- Copyright &copy ALICE HLT Group
5
6 #include "AliL3StandardIncludes.h"
7
8 #include "AliL3Logging.h"
9 #include "AliL3ModelTrack.h"
10 #include "AliL3Transform.h"
11 #include "AliL3DataCompressor.h"
12 #include "AliL3Vertex.h"
13
14 #if GCCVERSION == 3
15 using namespace std;
16 #endif
17
18 //_____________________________________________________________
19 // AliL3ModelTrack
20 //
21 // 
22
23 ClassImp(AliL3ModelTrack)
24
25 AliL3ModelTrack::AliL3ModelTrack() 
26 {
27   fNClusters = 0;
28   fClusters = 0;
29   fOverlap = 0;
30   fPad=0;
31   fTime=0;
32   fNoverlaps=0;
33   fClusterCharge=0;
34   fTrackModel=0;
35   fCrossingAngle=0;
36   fParSigmaY2=0;
37   fParSigmaZ2=0;
38 }
39
40
41 AliL3ModelTrack::~AliL3ModelTrack()
42 {
43   if(fClusters)
44     delete [] fClusters;
45   if(fPad)
46     delete [] fPad;
47   if(fTime)
48     delete [] fTime;
49   if(fCrossingAngle)
50     delete [] fCrossingAngle;
51   if(fParSigmaY2)
52     delete [] fParSigmaY2;
53   if(fParSigmaZ2)
54     delete [] fParSigmaZ2;
55   if(fTrackModel)
56     delete fTrackModel;
57   if(fNoverlaps)
58     delete [] fNoverlaps;
59   if(fOverlap)
60     {
61       for(Int_t i=0; i<AliL3Transform::GetNRows(fPatch); i++)
62         delete [] fOverlap[i];
63       delete [] fOverlap;
64     }
65 }
66
67 void AliL3ModelTrack::Init(Int_t slice,Int_t patch)
68 {
69   fNClusters=AliL3Transform::GetNRows(patch);//is not incremented in setcluster anymore
70   //fSlice=slice;
71   fPatch=patch;
72   Int_t nrows = AliL3Transform::GetNRows(fPatch);
73   fClusters = new AliL3ClusterModel[nrows];
74   fPad = new Float_t[nrows];
75   fTime = new Float_t[nrows];
76   fCrossingAngle = new Float_t[nrows];
77   fParSigmaY2 = new Float_t[nrows];
78   fParSigmaZ2 = new Float_t[nrows];
79   fTrackModel = new AliL3TrackModel;
80   
81   fOverlap = new Int_t*[nrows];
82   fNoverlaps = new Int_t[nrows];
83   fMaxOverlaps = 5;
84   
85   memset(fNoverlaps,0,nrows*sizeof(Int_t));
86   memset(fClusters,0,nrows*sizeof(AliL3ClusterModel));
87   memset(fPad,0,nrows*sizeof(Float_t));
88   memset(fTime,0,nrows*sizeof(Float_t));
89   memset(fCrossingAngle,0,nrows*sizeof(Float_t));
90   memset(fParSigmaY2,0,nrows*sizeof(Float_t));
91   memset(fParSigmaZ2,0,nrows*sizeof(Float_t));
92   memset(fTrackModel,0,sizeof(AliL3TrackModel));
93   for(Int_t i=0; i<nrows; i++)
94     {
95       fOverlap[i] = new Int_t[fMaxOverlaps];
96       for(Int_t j=0; j<fMaxOverlaps; j++)
97         fOverlap[i][j]=-1;
98       fClusters[i].fSlice = -1;
99     }
100
101 }
102
103 void AliL3ModelTrack::CalculateClusterWidths(Int_t row,Bool_t parametrize)
104 {
105   //Cluster widths
106   
107   Float_t xyz[3];
108   Int_t sr,lr;
109   Int_t index = row - AliL3Transform::GetFirstRow(fPatch);
110   if(index < 0 || index > AliL3Transform::GetNRows(fPatch))
111     {
112       cerr<<"AliL3ModelTrack::CalculcateClusterWidths : Wrond index "<<index<<" row "<<row<<endl;
113       return;
114     }
115   Int_t patch = AliL3Transform::GetPatch(row);
116   AliL3Transform::Slice2Sector(0,row,sr,lr);
117   AliL3Transform::Raw2Local(xyz,sr,lr,GetPadHit(row),GetTimeHit(row));
118   fParSigmaY2[index] = AliL3Transform::GetParSigmaY2(row,xyz[2],GetCrossingAngleLUT(row));
119   fParSigmaZ2[index] = AliL3Transform::GetParSigmaZ2(row,xyz[2],GetTgl());
120   
121   if(parametrize)
122     {
123       fParSigmaY2[index] = (fParSigmaY2[index] + (1./12)*pow(AliL3Transform::GetPadPitchWidth(patch),2) );
124       fParSigmaY2[index] *= 0.108;
125       if(patch<2)
126         fParSigmaY2[index] *= 2.07;
127      
128       fParSigmaZ2[index] = (fParSigmaZ2[index] + (1./12)*pow(AliL3Transform::GetZWidth(),2) );
129       fParSigmaZ2[index] *= 0.169;
130       if(patch<2)
131         fParSigmaZ2[index] *= 1.77;
132     }
133   
134   //convert to raw coordinates:
135   fParSigmaY2[index] /= pow(AliL3Transform::GetPadPitchWidth(patch),2);
136   fParSigmaZ2[index] /= pow(AliL3Transform::GetZWidth(),2);
137 }
138
139 void AliL3ModelTrack::SetCluster(Int_t row,Float_t fpad,Float_t ftime,Float_t charge,
140                                  Float_t sigmaY2,Float_t sigmaZ2,Int_t npads)
141 {
142   AliL3ClusterModel *cl = GetClusterModel(row);
143   
144   //First bit: Cluster is present or not
145   //Second bit: Cluster was set, meaning an fit attempt was done (if true)
146   
147   cl->fPresent |= 0x2; //set second bit to true, because a fit attempt has been made
148   
149   if(!charge || npads == 1)
150     {
151       cl->fPresent &= ~0x1; //set first bit to false
152     }
153   else
154     {
155       cl->fPresent|=0x1;//set first bit to true
156       cl->fDPad = QuantizePad(row,fpad);
157       cl->fDTime = QuantizeTime(row,ftime);
158       cl->fDCharge = charge;
159       if(sigmaY2==0 && sigmaZ2==0)
160         {
161           cl->fDSigmaY2=0;//if width is zero, shape is not supposed to be written
162           cl->fDSigmaZ2=0;
163         }
164       else
165         {
166           cl->fDSigmaY2 = QuantizeSigmaY2(row,sigmaY2);
167           cl->fDSigmaZ2 = QuantizeSigmaZ2(row,sigmaZ2);
168         }
169       cl->fNPads = npads;
170     }
171 }
172
173
174 void AliL3ModelTrack::Set(AliL3Track *tpt)
175 {
176   AliL3ModelTrack *tr = (AliL3ModelTrack*)tpt;
177   SetRowRange(tr->GetFirstRow(),tr->GetLastRow());
178   SetPhi0(tr->GetPhi0());
179   SetKappa(tr->GetKappa());
180   SetFirstPoint(tr->GetFirstPointX(),tr->GetFirstPointY(),tr->GetFirstPointZ());
181   SetLastPoint(tr->GetLastPointX(),tr->GetLastPointY(),tr->GetLastPointZ());
182   SetPt(tr->GetPt());
183   SetPsi(tr->GetPsi());
184   SetTgl(tr->GetTgl());
185   SetCharge(tr->GetCharge());
186   
187   if(fClusters)
188     {
189       cerr<<"AliL3ModelTrack::Set : Init has already been called for this object!"<<endl;
190       return;
191     }
192
193   //Init(tr->fSlice,tr->fPatch);
194   Init(0,tr->fPatch);
195   memcpy(fClusters,tr->fClusters,AliL3Transform::GetNRows(fPatch)*sizeof(AliL3ClusterModel));
196   memcpy(fPad,tr->fPad,AliL3Transform::GetNRows(fPatch)*sizeof(Float_t));
197   memcpy(fTime,tr->fTime,AliL3Transform::GetNRows(fPatch)*sizeof(Float_t));
198   memcpy(fParSigmaY2,tr->fParSigmaY2,AliL3Transform::GetNRows(fPatch)*sizeof(Float_t));
199   memcpy(fParSigmaZ2,tr->fParSigmaZ2,AliL3Transform::GetNRows(fPatch)*sizeof(Float_t));
200   memcpy(fCrossingAngle,tr->fCrossingAngle,AliL3Transform::GetNRows(fPatch)*sizeof(Float_t));
201   memcpy(fTrackModel,tr->fTrackModel,sizeof(AliL3TrackModel));
202
203 }
204
205 Int_t AliL3ModelTrack::GetNPresentClusters()
206 {
207   //Return the number of assigned clusters to the track.
208   //Differs from fNClusters, which should be equal to the 
209   //number of padrows in the present patch.
210   
211   Int_t count=0;
212
213   for(Int_t i=AliL3Transform::GetFirstRow(fPatch); i<=AliL3Transform::GetLastRow(fPatch); i++)
214     if(IsPresent(i))
215       count++;
216
217   return count;
218 }
219
220 void AliL3ModelTrack::FillModel()
221 {
222   //Fill the track structure
223   
224   if(fNClusters != AliL3Transform::GetNRows(fPatch))
225     {
226       cout<<"AliL3ModelTrack::FillModel : fNClusters != nrows; beware, this could be caused by a bug!!!"<<endl;
227       fNClusters = AliL3Transform::GetNRows(fPatch);
228     }
229
230   if(!fTrackModel)
231     {
232       cerr<<"AliL3ModelTrack::FillModel() : No trackmodel "<<endl;
233       return;
234     }
235   Double_t impact[3];
236   AliL3Vertex vertex;
237   CalculateHelix();
238   GetClosestPoint(&vertex,impact[0],impact[1],impact[2]);
239   fTrackModel->fKappa = GetKappa();
240   fTrackModel->fPhi = atan2(impact[1],impact[0]);
241   fTrackModel->fD = sqrt(impact[0]*impact[0] + impact[1]*impact[1]);
242   fTrackModel->fZ0 = impact[2];
243   fTrackModel->fTgl = GetTgl();
244   
245   //We have to check on which of the vertex the track fit is lying
246   //This we need to encode the azimuthal angle coordinate of the center of curvature.
247   if(GetRadius() < sqrt(GetCenterX()*GetCenterX()+GetCenterY()*GetCenterY()))
248     fTrackModel->fD *=-1;
249   
250 }
251
252 void AliL3ModelTrack::FillTrack()
253 {
254   //Fill the track parameters from the structure.
255   
256   if(!fTrackModel)
257     {
258       cerr<<"AliL3ModelTrack::FillTrack() : No data!!"<<endl;
259       return;
260     }
261   SetKappa(fTrackModel->fKappa);
262   Double_t impact[3],psi;
263   Float_t trackPhi0 = fTrackModel->fPhi;
264   if(fTrackModel->fD < 0)
265     trackPhi0 += AliL3Transform::Pi();
266   Int_t charge = -1*(Int_t)copysign(1.,GetKappa());
267   impact[0] = fabs(fTrackModel->fD)*cos(fTrackModel->fPhi);
268   impact[1] = fabs(fTrackModel->fD)*sin(fTrackModel->fPhi);
269   impact[2] = fTrackModel->fZ0;
270
271   psi = trackPhi0 - charge*0.5*AliL3Transform::Pi();
272   if(psi < 0) 
273     psi += 2*AliL3Transform::Pi();
274
275   SetCharge(charge);
276   SetFirstPoint(impact[0],impact[1],impact[2]);
277   SetPsi(psi);
278   SetTgl(fTrackModel->fTgl);
279   SetPt((AliL3Transform::GetBFact()*AliL3Transform::GetBField())/fabs(GetKappa()));
280   fNClusters = AliL3Transform::GetNRows(fPatch);
281   CalculateHelix();
282   
283   for(Int_t i=AliL3Transform::GetFirstRow(fPatch); i<=AliL3Transform::GetLastRow(fPatch); i++)
284     {
285       AliL3ClusterModel *cl = GetClusterModel(i);
286       if(!cl) continue;
287
288       if(cl->fSlice == -1)
289         {
290           SetPadHit(i,-1);
291           SetTimeHit(i,-1);
292           continue;
293         }
294       if(cl->fSlice < 0 || cl->fSlice > 35)
295         {
296           cerr<<"AliL3ModelTrack::FillTrack : Slice out of range "<<cl->fSlice<<" on row "<<i<<endl;
297           exit(5);
298         }
299       
300       Float_t angle = 0;
301       
302       AliL3Transform::Local2GlobalAngle(&angle,cl->fSlice);
303       if(!CalculateReferencePoint(angle,AliL3Transform::Row2X(i)))
304         {
305           if(IsPresent(i))
306             {
307               cerr<<"AliL3ModelTrack::FillTrack : Track does not cross slice "<<cl->fSlice<<" row "<<i<<" Points "
308                   <<GetPointX()<<" "<<GetPointY()<<" "<<GetPointZ()<<endl;
309               Print();
310               exit(5);
311             }
312           SetPadHit(i,-1);
313           SetTimeHit(i,-1);
314           continue;
315         }
316       Float_t hit[3] = {GetPointX(),GetPointY(),GetPointZ()};
317       Int_t sector,row;
318       AliL3Transform::Slice2Sector(cl->fSlice,i,sector,row);
319       AliL3Transform::Global2Raw(hit,sector,row);
320
321       SetPadHit(i,hit[1]);
322       SetTimeHit(i,hit[2]);
323
324       Float_t crossingangle = GetCrossingAngle(i,cl->fSlice);
325       
326       SetCrossingAngleLUT(i,crossingangle);
327       CalculateClusterWidths(i,kTRUE);
328       
329     }
330 }
331
332 Float_t AliL3ModelTrack::QuantizePad(Int_t row,Float_t pad)
333 {
334   Float_t diff = pad - GetPadHit(row);
335   Float_t step = AliL3DataCompressor::GetPadResidualStep(row);
336   return diff/step;
337
338
339 Float_t AliL3ModelTrack::RetrievePad(Int_t row,Float_t dpad)
340 {
341   Float_t step = AliL3DataCompressor::GetPadResidualStep(row);
342   return dpad*step + GetPadHit(row);
343 }
344
345 Float_t AliL3ModelTrack::QuantizeTime(Int_t row,Float_t time)
346 {
347   Float_t diff = time - GetTimeHit(row);
348   Float_t step = AliL3DataCompressor::GetTimeResidualStep(row);
349   return diff/step;
350
351
352 Float_t AliL3ModelTrack::RetrieveTime(Int_t row,Float_t dtime)
353 {
354   Float_t step = AliL3DataCompressor::GetTimeResidualStep(row);
355   return dtime*step + GetTimeHit(row);
356 }
357
358 Float_t AliL3ModelTrack::QuantizeSigmaY2(Int_t row,Float_t sigmaY2)
359 {
360   Float_t diff = sigmaY2 - GetParSigmaY2(row);
361   Float_t step = AliL3DataCompressor::GetPadSigma2Step(AliL3Transform::GetPatch(row));
362   return diff/step;
363 }
364
365 Float_t AliL3ModelTrack::RetrieveSigmaY2(Int_t row,Float_t dsigmaY2)
366 {
367   Float_t step = AliL3DataCompressor::GetPadSigma2Step(AliL3Transform::GetPatch(row));
368   return dsigmaY2*step + GetParSigmaY2(row);
369 }
370
371 Float_t AliL3ModelTrack::QuantizeSigmaZ2(Int_t row,Float_t sigmaZ2)
372 {
373   Float_t diff = sigmaZ2 - GetParSigmaZ2(row);
374   Float_t step = AliL3DataCompressor::GetTimeSigma2Step();
375   return diff/step;
376 }
377
378 Float_t AliL3ModelTrack::RetrieveSigmaZ2(Int_t row,Float_t dsigmaZ2)
379 {
380   Float_t step = AliL3DataCompressor::GetTimeSigma2Step();
381   return dsigmaZ2*step + GetParSigmaZ2(row);
382 }
383
384 void AliL3ModelTrack::SetPadHit(Int_t row,Float_t pad)
385 {
386   Int_t index = row-AliL3Transform::GetFirstRow(fPatch);
387   if(index < 0 || index > AliL3Transform::GetNRows(fPatch))
388     {
389       cerr<<"AliL3ModelTrack::SetPadHit() : Wrong index: "<<index<<endl;
390       return;
391     }
392   fPad[index]=pad;
393 }
394
395 void AliL3ModelTrack::SetTimeHit(Int_t row,Float_t time)
396 {
397   Int_t index = row-AliL3Transform::GetFirstRow(fPatch);
398   if(index < 0 || index > AliL3Transform::GetNRows(fPatch))
399     {
400       cerr<<"AliL3ModelTrack::SetTimeHit() : Wrong index: "<<index<<endl;
401       return;
402     }
403   fTime[index]=time;
404 }
405
406 void AliL3ModelTrack::SetCrossingAngleLUT(Int_t row,Float_t angle)
407 {
408   Int_t index = row-AliL3Transform::GetFirstRow(fPatch);
409   if(index < 0 || index > AliL3Transform::GetNRows(fPatch))
410     {
411       cerr<<"AliL3ModelTrack::SetCrossingAngle() : Wrong index: "<<index<<endl;
412       return;
413     }
414   fCrossingAngle[index]=angle;
415 }
416
417 void AliL3ModelTrack::SetOverlap(Int_t row,Int_t id)
418 {
419
420   Int_t index = row-AliL3Transform::GetFirstRow(fPatch);
421   if(index < 0 || index > AliL3Transform::GetNRows(fPatch))
422     {
423       cerr<<"AliL3ModelTrack::SetOverlap() : Wrong index: "<<index<<endl;
424       return;
425     }
426   if(fNoverlaps[index] >= fMaxOverlaps) return;
427   fOverlap[index][fNoverlaps[index]++] = id;
428 }
429
430 Bool_t AliL3ModelTrack::IsPresent(Int_t row)
431 {
432   AliL3ClusterModel *cl = GetClusterModel(row);
433   return (Bool_t)(cl->fPresent & 0x1);
434 }
435
436 Bool_t AliL3ModelTrack::IsSet(Int_t row)
437 {
438   AliL3ClusterModel *cl = GetClusterModel(row);
439   return (Bool_t)(cl->fPresent & 0x2);
440 }
441
442 Int_t AliL3ModelTrack::GetNPads(Int_t row)
443 {
444   AliL3ClusterModel *cl = GetClusterModel(row);
445   return cl->fNPads;
446 }
447
448 Bool_t AliL3ModelTrack::GetPad(Int_t row,Float_t &pad)
449 {
450   AliL3ClusterModel *cl = GetClusterModel(row);
451   pad = RetrievePad(row,cl->fDPad);
452   return IsPresent(row);
453 }
454
455 Bool_t AliL3ModelTrack::GetTime(Int_t row,Float_t &time)
456 {
457   AliL3ClusterModel *cl = GetClusterModel(row);
458   time = RetrieveTime(row,cl->fDTime);
459   return IsPresent(row);
460 }
461
462 Bool_t AliL3ModelTrack::GetClusterCharge(Int_t row,Int_t &charge)
463 {
464   AliL3ClusterModel *cl = GetClusterModel(row);
465   charge = (Int_t)cl->fDCharge;// + AliL3DataCompressor::GetClusterCharge();
466   return IsPresent(row);
467 }
468
469 Bool_t AliL3ModelTrack::GetXYWidth(Int_t row,Float_t &width)
470 {
471   AliL3ClusterModel *cl = GetClusterModel(row);
472   width = RetrieveSigmaY2(row,cl->fDSigmaY2);
473   return IsPresent(row);
474 }
475
476 Bool_t AliL3ModelTrack::GetZWidth(Int_t row,Float_t &width)
477 {
478   AliL3ClusterModel *cl = GetClusterModel(row);
479   RetrieveSigmaZ2(row,cl->fDSigmaZ2);
480   return IsPresent(row);
481 }
482
483 Bool_t AliL3ModelTrack::GetPadResidual(Int_t row,Float_t &res)
484 {
485   AliL3ClusterModel *cl = GetClusterModel(row);
486   res = cl->fDPad;
487   return IsPresent(row);
488 }
489
490 Bool_t AliL3ModelTrack::GetTimeResidual(Int_t row,Float_t &res)
491 {
492   AliL3ClusterModel *cl = GetClusterModel(row);
493   res = cl->fDTime;
494   return IsPresent(row);
495 }
496
497 Bool_t AliL3ModelTrack::GetXYWidthResidual(Int_t row,Float_t &res)
498 {
499   AliL3ClusterModel *cl = GetClusterModel(row);
500   res = cl->fDSigmaY2;
501   return IsPresent(row);
502 }
503
504 Bool_t AliL3ModelTrack::GetZWidthResidual(Int_t row,Float_t &res)
505 {
506   AliL3ClusterModel *cl = GetClusterModel(row);
507   res = cl->fDSigmaZ2;
508   return IsPresent(row);
509 }
510
511 Int_t AliL3ModelTrack::GetSlice(Int_t row)
512 {
513   AliL3ClusterModel *cl = GetClusterModel(row);
514   return cl->fSlice;
515 }
516
517 Float_t AliL3ModelTrack::GetPadHit(Int_t row)
518 {
519   Int_t index = row-AliL3Transform::GetFirstRow(fPatch);
520   if(index < 0 || index > AliL3Transform::GetNRows(fPatch))
521     {
522       cerr<<"AliL3ModelTrack::GetPadHit() : Wrong index: "<<index<<" row "<<row<<endl;
523       return 0;
524     }
525   return fPad[index];
526 }
527
528 Float_t AliL3ModelTrack::GetTimeHit(Int_t row)
529 {
530   Int_t index = row-AliL3Transform::GetFirstRow(fPatch);
531   if(index < 0 || index > AliL3Transform::GetNRows(fPatch))
532     {
533       cerr<<"AliL3ModelTrack::GetTimeHit() : Wrong index: "<<index<<" row "<<row<<endl;
534       return 0;
535     }
536   return fTime[index];
537 }
538
539 Float_t AliL3ModelTrack::GetCrossingAngleLUT(Int_t row)
540 {
541   Int_t index = row-AliL3Transform::GetFirstRow(fPatch);
542   if(index < 0 || index > AliL3Transform::GetNRows(fPatch))
543     {
544       cerr<<"AliL3ModelTrack::GetCrossingAngleLUT() : Wrong index: "<<index<<" row "<<row<<endl;
545       return 0;
546     }
547   return fCrossingAngle[index];
548 }
549
550 Float_t AliL3ModelTrack::GetParSigmaY2(Int_t row)
551 {
552   Int_t index = row-AliL3Transform::GetFirstRow(fPatch);
553   if(index < 0 || index > AliL3Transform::GetNRows(fPatch))
554     {
555       cerr<<"AliL3ModelTrack::GetParSigmaY2() : Wrong index: "<<index<<" row "<<row<<endl;
556       return 0;
557     }
558   return fParSigmaY2[index];
559 }
560
561 Float_t AliL3ModelTrack::GetParSigmaZ2(Int_t row)
562 {
563   Int_t index = row-AliL3Transform::GetFirstRow(fPatch);
564   if(index < 0 || index > AliL3Transform::GetNRows(fPatch))
565     {
566       cerr<<"AliL3ModelTrack::GetParSigmaZ2() : Wrong index: "<<index<<" row "<<row<<endl;
567       return 0;
568     }
569   return fParSigmaZ2[index];
570 }
571
572 Int_t AliL3ModelTrack::GetNOverlaps(Int_t row)
573 {
574   Int_t index = row - AliL3Transform::GetFirstRow(fPatch);
575   if(index < 0 || index > AliL3Transform::GetNRows(fPatch))
576     {
577       cerr<<"AliL3ModelTrack::GetOverlap() : Wrong index: "<<index<<endl;
578       return 0;
579     }
580   return fNoverlaps[index];
581 }
582
583 Int_t *AliL3ModelTrack::GetOverlaps(Int_t row)
584 {
585   Int_t index = row - AliL3Transform::GetFirstRow(fPatch);
586   if(index < 0 || index > AliL3Transform::GetNRows(fPatch))
587     {
588       cerr<<"AliL3ModelTrack::GetOverlap() : Wrong index: "<<index<<endl;
589       return 0;
590     }
591   return fOverlap[index];
592 }
593
594 AliL3ClusterModel *AliL3ModelTrack::GetClusterModel(Int_t row)
595 {
596   if(!fClusters) return 0; 
597   Int_t index = row-AliL3Transform::GetFirstRow(fPatch);
598   if(index < 0 || index > AliL3Transform::GetNRows(fPatch))
599     {
600       cerr<<"AliL3ModelTrack::GetClusterModel() : Wrong index: "<<index<<endl;
601       return 0;
602     }
603   return &fClusters[index];
604 }
605
606 void AliL3ModelTrack::Print(Bool_t everything)
607 {
608   //Print info
609
610   cout<<"First point "<<GetFirstPointX()<<" "<<GetFirstPointY()<<" "<<GetFirstPointZ()<<endl;
611   cout<<"Last point "<<GetLastPointX()<<" "<<GetLastPointY()<<" "<<GetLastPointZ()<<endl;
612   cout<<"Pt "<<GetPt()<<" kappa "<<GetKappa()<<" tgl "<<GetTgl()<<" psi "<<GetPsi()<<" charge "<<GetCharge()<<endl;
613   cout<<"Center "<<GetCenterX()<<" "<<GetCenterY()<<endl<<endl;
614   if(!everything)
615     return;
616   cout<<"NHits "<<GetNClusters()<<endl;
617
618   cout<<"Clusters:"<<endl;
619   Int_t origslice=-1,counter=0;
620   Float_t fpad,ftime;
621   for(Int_t i=AliL3Transform::GetFirstRow(fPatch); i<=AliL3Transform::GetLastRow(fPatch); i++)
622     {
623       AliL3ClusterModel *cl = GetClusterModel(i);
624       
625       if(!IsPresent(i))
626         cout<<i<<" Empty"<<" Slice "<<cl->fSlice<<" Padcrossing "<<GetPadHit(i)<<" Timecrossing "<<GetTimeHit(i)<<" ";
627       else
628         {
629           GetPad(i,fpad);
630           GetTime(i,ftime);
631           if(counter==0)
632             origslice=cl->fSlice;
633           else if(cl->fSlice != origslice)
634             cout<<"Change in slice "<<cl->fSlice<<" "<<origslice<<endl;
635           cout<<i<<" Slice "<<cl->fSlice<<" Dpad "<<cl->fDPad<<" Dtime "<<cl->fDTime<<" Dcharge "<<cl->fDCharge;
636           cout<<" sigmaY2 "<<GetParSigmaY2(i)<<" sigmaZ2 "<<GetParSigmaZ2(i);
637           cout<<" Pad "<<fpad<<" padhit "<<GetPadHit(i)<<" Time "<<ftime<<" timehit "<<GetTimeHit(i)<<" ";
638           cout<<"Number of pads "<<GetNPads(i)<<" Overlaps "<<GetNOverlaps(i);
639           counter++;
640         }
641       cout<<endl;
642     }
643 }
644
645 void AliL3ModelTrack::SetClusterLabel(Int_t row,Int_t *trackID)
646 {
647 #ifdef do_mc
648   AliL3ClusterModel *cl = GetClusterModel(row);
649   cl->fTrackID[0] = trackID[0];
650   cl->fTrackID[1] = trackID[1];
651   cl->fTrackID[2] = trackID[2];
652 #endif
653   return;
654 }
655
656 void AliL3ModelTrack::GetClusterLabel(Int_t row,Int_t *trackID)
657 {
658 #ifdef do_mc
659   AliL3ClusterModel *cl = GetClusterModel(row);
660   trackID[0] = cl->fTrackID[0];
661   trackID[1] = cl->fTrackID[1];
662   trackID[2] = cl->fTrackID[2];
663 #endif
664   return;
665 }
666