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