]> git.uio.no Git - u/mrichter/AliRoot.git/blob - HLT/TPCLib/AliHLTTPCTrack.cxx
update
[u/mrichter/AliRoot.git] / HLT / TPCLib / AliHLTTPCTrack.cxx
1 // @(#) $Id$
2 // Original: AliHLTTrack.cxx,v 1.32 2005/06/14 10:55:21 cvetan 
3
4 /**************************************************************************
5  * This file is property of and copyright by the ALICE HLT Project        * 
6  * ALICE Experiment at CERN, All rights reserved.                         *
7  *                                                                        *
8  * Primary Authors: Anders Vestbo, Uli Frankenfeld, maintained by         *
9  *                  Matthias Richter <Matthias.Richter@ift.uib.no>        *
10  *                  for The ALICE HLT Project.                            *
11  *                                                                        *
12  * Permission to use, copy, modify and distribute this software and its   *
13  * documentation strictly for non-commercial purposes is hereby granted   *
14  * without fee, provided that the above copyright notice appears in all   *
15  * copies and that both the copyright notice and this permission notice   *
16  * appear in the supporting documentation. The authors make no claims     *
17  * about the suitability of this software for any purpose. It is          *
18  * provided "as is" without express or implied warranty.                  *
19  **************************************************************************/
20
21 /** @file   AliHLTTPCTrack.cxx
22     @author Anders Vestbo, Uli Frankenfeld, maintained by Matthias Richter
23     @date   
24     @brief  HLT TPC track implementation (conformal mapping) */
25
26
27 #include "AliHLTTPCLogging.h"
28 #include "AliHLTTPCTrack.h"
29 #include "AliHLTTPCTransform.h"
30 #include "AliHLTTPCVertex.h"
31 #include "AliHLTTPCSpacePointData.h"
32
33 #if __GNUC__ >= 3
34 using namespace std;
35 #endif
36
37 ClassImp(AliHLTTPCTrack)
38
39
40 AliHLTTPCTrack::AliHLTTPCTrack()
41   :
42   fNHits(0),
43   fMCid(-1),
44   fKappa(0),
45   fRadius(0),
46   fCenterX(0),
47   fCenterY(0),
48   fFromMainVertex(0),
49   fSector(0),
50   fQ(0),
51
52   fTanl(0),
53   fPsi(0),
54   fPt(0),
55   fLength(0),
56
57   fPterr(0),
58   fPsierr(0),
59   fZ0err(0),
60   fY0err(0),
61   fTanlerr(0),
62
63   fPhi0(0),
64   fR0(0),
65   fZ0(0),
66
67   //  fPoint({0,0,0}),
68   fPointPsi(0),
69
70   fIsPoint(0),
71   fIsLocal(true),
72   //  fRowRange({0,0}),
73
74   fPID(0)
75 {
76   //Constructor
77   fRowRange[0]=0;
78   fRowRange[1]=0;
79   fPoint[0]=0;
80   fPoint[1]=0;
81   fPoint[2]=0;
82
83   SetFirstPoint(0,0,0);
84   SetLastPoint(0,0,0);
85   memset(fHitNumbers,0,fgkHitArraySize*sizeof(UInt_t));
86 }
87
88 void AliHLTTPCTrack::Copy(AliHLTTPCTrack *tpt)
89 {
90   //setter
91   SetRowRange(tpt->GetFirstRow(),tpt->GetLastRow());
92   SetPhi0(tpt->GetPhi0());
93   SetKappa(tpt->GetKappa());
94   SetNHits(tpt->GetNHits());
95   SetFirstPoint(tpt->GetFirstPointX(),tpt->GetFirstPointY(),tpt->GetFirstPointZ());
96   SetLastPoint(tpt->GetLastPointX(),tpt->GetLastPointY(),tpt->GetLastPointZ());
97   SetPt(tpt->GetPt());
98   SetPsi(tpt->GetPsi());
99   SetTgl(tpt->GetTgl());
100   SetPterr(tpt->GetPterr());
101   SetPsierr(tpt->GetPsierr());
102   SetTglerr(tpt->GetTglerr());
103   SetZ0err(tpt->GetZ0err());
104   SetY0err(tpt->GetY0err());
105   SetCharge(tpt->GetCharge());
106   SetHits(tpt->GetNHits(),(UInt_t *)tpt->GetHitNumbers());
107   SetMCid(tpt->GetMCid());
108   SetPID(tpt->GetPID());
109   SetSector(tpt->GetSector());
110 }
111
112 Int_t AliHLTTPCTrack::Compare(const AliHLTTPCTrack *track) const
113 {
114   // compare tracks
115   if(track->GetNHits() < GetNHits()) return 1;
116   if(track->GetNHits() > GetNHits()) return -1;
117   return 0;
118 }
119
120 AliHLTTPCTrack::~AliHLTTPCTrack()
121 {
122   //Nothing to do
123 }
124
125 Double_t AliHLTTPCTrack::GetP() const
126 {
127   // Returns total momentum.  
128   return fabs(GetPt())*sqrt(1. + GetTgl()*GetTgl());
129 }
130
131 Double_t AliHLTTPCTrack::GetPseudoRapidity() const
132 { //get pseudo rap
133   return 0.5 * log((GetP() + GetPz()) / (GetP() - GetPz()));
134 }
135
136 Double_t AliHLTTPCTrack::GetRapidity() const
137
138   //get rap
139   const Double_t kmpi = 0.13957;
140   return 0.5 * log((kmpi + GetPz()) / (kmpi - GetPz()));
141 }
142
143 void AliHLTTPCTrack::Rotate(Int_t slice,Bool_t tolocal)
144 {
145   //Rotate track to global parameters
146   //If flag tolocal is set, the track is rotated
147   //to local coordinates.
148
149   Float_t psi[1] = {GetPsi()};
150   if(!tolocal)
151     AliHLTTPCTransform::Local2GlobalAngle(psi,slice);
152   else
153     AliHLTTPCTransform::Global2LocalAngle(psi,slice);
154   SetPsi(psi[0]);
155   Float_t first[3];
156   first[0] = GetFirstPointX();
157   first[1] = GetFirstPointY();
158   first[2] = GetFirstPointZ();
159   if(!tolocal)
160     AliHLTTPCTransform::Local2Global(first,slice);
161   else
162     AliHLTTPCTransform::Global2LocHLT(first,slice);
163   //AliHLTTPCTransform::Global2Local(first,slice,kTRUE);
164   
165   SetFirstPoint(first[0],first[1],first[2]);
166   Float_t last[3];
167   last[0] = GetLastPointX();
168   last[1] = GetLastPointY();
169   last[2] = GetLastPointZ();
170   if(!tolocal)
171     AliHLTTPCTransform::Local2Global(last,slice);
172   else
173     AliHLTTPCTransform::Global2LocHLT(last,slice);    
174   //AliHLTTPCTransform::Global2Local(last,slice,kTRUE);
175   SetLastPoint(last[0],last[1],last[2]);
176   
177   Float_t center[3] = {GetCenterX(),GetCenterY(),0};
178   if(!tolocal)
179     AliHLTTPCTransform::Local2Global(center,slice);
180   else
181     AliHLTTPCTransform::Global2LocHLT(center,slice);
182   //AliHLTTPCTransform::Global2Local(center,slice,kTRUE);
183   SetCenterX(center[0]);
184   SetCenterY(center[1]);
185   
186   SetPhi0(atan2(fFirstPoint[1],fFirstPoint[0]));
187   SetR0(sqrt(fFirstPoint[0]*fFirstPoint[0]+fFirstPoint[1]*fFirstPoint[1]));
188   
189   if(!tolocal)
190     fIsLocal=kFALSE;
191   else
192     fIsLocal=kTRUE;
193 }
194
195 void AliHLTTPCTrack::CalculateHelix()
196 {
197   // fit assigned clusters to helix
198   // for straight line fit
199   if (AliHLTTPCTransform::GetBFieldValue() == 0.0 ){
200     fRadius = 999999;  //just zero
201     
202     SetPhi0(atan2(fFirstPoint[1],fFirstPoint[0]));
203     SetR0(sqrt(fFirstPoint[0]*fFirstPoint[0]+fFirstPoint[1]*fFirstPoint[1]));
204   }
205   // for helix fit
206   else { 
207     //Calculate Radius, CenterX and CenterY from Psi, X0, Y0
208     fRadius = fPt / (AliHLTTPCTransform::GetBFieldValue());
209     if(fRadius) fKappa = -fQ*1./fRadius;
210     else fRadius = 999999;  //just zero
211     Double_t trackPhi0 = fPsi + fQ * AliHLTTPCTransform::PiHalf();
212     
213     fCenterX = fFirstPoint[0] - fRadius *  cos(trackPhi0);
214     fCenterY = fFirstPoint[1] - fRadius *  sin(trackPhi0);
215     
216     SetPhi0(atan2(fFirstPoint[1],fFirstPoint[0]));
217     SetR0(sqrt(fFirstPoint[0]*fFirstPoint[0]+fFirstPoint[1]*fFirstPoint[1]));
218   }
219 }
220
221 Double_t AliHLTTPCTrack::GetCrossingAngle(Int_t padrow,Int_t slice) 
222 {
223   //Calculate the crossing angle between track and given padrow.
224   //Take the dot product of the tangent vector of the track, and
225   //vector perpendicular to the padrow.
226   //In order to do this, we need the tangent vector to the track at the
227   //point. This is done by rotating the radius vector by 90 degrees;
228   //rotation matrix: (  0  1 )
229   //                 ( -1  0 )
230
231   Float_t angle=0;//Angle perpendicular to the padrow in local coordinates
232   if(slice>=0)//Global coordinates
233     {
234       AliHLTTPCTransform::Local2GlobalAngle(&angle,slice);
235       if(!CalculateReferencePoint(angle,AliHLTTPCTransform::Row2X(padrow)))
236         cerr<<"AliHLTTPCTrack::GetCrossingAngle : Track does not cross line in slice "<<slice<<" row "<<padrow<<endl;
237     }
238   else //should be in local coordinates
239     {
240       Float_t xyz[3];
241       GetCrossingPoint(padrow,xyz);
242       fPoint[0] = xyz[0];
243       fPoint[1] = xyz[1];
244       fPoint[2] = xyz[2];
245     }
246     
247   Double_t tangent[2];
248   
249   tangent[0] = (fPoint[1] - GetCenterY())/GetRadius();
250   tangent[1] = -1.*(fPoint[0] - GetCenterX())/GetRadius();
251
252   Double_t perppadrow[2] = {cos(angle),sin(angle)}; 
253   Double_t cosbeta = fabs(tangent[0]*perppadrow[0] + tangent[1]*perppadrow[1]);
254   if(cosbeta > 1) cosbeta=1;
255   return acos(cosbeta);
256 }
257
258 Bool_t AliHLTTPCTrack::GetCrossingPoint(Int_t padrow,Float_t *xyz)
259 {
260   //Assumes the track is given in local coordinates
261   if(!IsLocal())
262     {
263       cerr<<"GetCrossingPoint: Track is given on global coordinates"<<endl;
264       return false;
265     }
266   
267   Double_t xHit = AliHLTTPCTransform::Row2X(padrow);
268
269 //if (xHit < xyz[0]){
270 //    LOG(AliHLTTPCLog::kError,"AliHLTTPCTRACK::GetCrossingPoint","")<< "Track doesn't cross padrow " 
271 //                              << padrow <<"(x=" << xHit << "). Smallest x=" << xyz[0] << ENDLOG;
272 //      return false;
273 //}
274
275   // for straight line fit
276   if (AliHLTTPCTransform::GetBFieldValue() == 0.0 ){
277     
278     Double_t yHit = GetFirstPointY() + (Double_t) tan( GetPsi() ) * (xHit - GetFirstPointX());   
279     
280     Double_t s = (xHit - GetFirstPointX())*(xHit - GetFirstPointX()) + (yHit - GetFirstPointY())*(yHit - GetFirstPointY()); 
281     
282     Double_t zHit = GetFirstPointZ() + s * GetTgl();
283     
284     xyz[0] = xHit;
285     xyz[1] = yHit;
286     xyz[2] = zHit;
287   }
288   // for helix fit
289     else { 
290       xyz[0] = xHit;
291       Double_t aa = (xHit - GetCenterX())*(xHit - GetCenterX());
292       Double_t r2 = GetRadius()*GetRadius();
293       if(aa > r2)
294         return false;
295       
296       Double_t aa2 = sqrt(r2 - aa);
297       Double_t y1 = GetCenterY() + aa2;
298       Double_t y2 = GetCenterY() - aa2;
299       xyz[1] = y1;
300       if(fabs(y2) < fabs(y1)) xyz[1] = y2;
301       
302       Double_t yHit = xyz[1];
303       Double_t angle1 = atan2((yHit - GetCenterY()),(xHit - GetCenterX()));
304       if(angle1 < 0) angle1 += 2.*AliHLTTPCTransform::Pi();
305       Double_t angle2 = atan2((GetFirstPointY() - GetCenterY()),(GetFirstPointX() - GetCenterX()));
306       if(angle2 < 0) angle2 += AliHLTTPCTransform::TwoPi();
307       
308       Double_t diffangle = angle1 - angle2;
309       diffangle = fmod(diffangle,AliHLTTPCTransform::TwoPi());
310       if((GetCharge()*diffangle) > 0) diffangle = diffangle - GetCharge()*AliHLTTPCTransform::TwoPi();
311       
312       Double_t stot = fabs(diffangle)*GetRadius();
313       
314       Double_t zHit = GetFirstPointZ() + stot*GetTgl();
315       
316       xyz[2] = zHit;
317     }
318   
319   return true;
320 }
321
322 Bool_t AliHLTTPCTrack::CalculateReferencePoint(Double_t angle,Double_t radius)
323 {
324   // Global coordinate: crossing point with y = ax+ b; 
325   // a=tan(angle-AliHLTTPCTransform::PiHalf());
326   //
327   const Double_t krr=radius; //position of reference plane
328   const Double_t kxr = cos(angle) * krr;
329   const Double_t kyr = sin(angle) * krr;
330   
331   Double_t a = tan(angle-AliHLTTPCTransform::PiHalf());
332   Double_t b = kyr - a * kxr;
333
334   Double_t pp=(fCenterX+a*fCenterY-a*b)/(1+pow(a,2));
335   Double_t qq=(pow(fCenterX,2)+pow(fCenterY,2)-2*fCenterY*b+pow(b,2)-pow(fRadius,2))/(1+pow(a,2));
336
337   Double_t racine = pp*pp-qq;
338   if(racine<0) return IsPoint(kFALSE);      //no Point
339
340   Double_t rootRacine = sqrt(racine);
341   Double_t x0 = pp+rootRacine;
342   Double_t x1 = pp-rootRacine;
343   Double_t y0 = a*x0 + b;
344   Double_t y1 = a*x1 + b;
345
346   Double_t diff0 = sqrt(pow(x0-kxr,2)+pow(y0-kyr,2));
347   Double_t diff1 = sqrt(pow(x1-kxr,2)+pow(y1-kyr,2));
348  
349   if(diff0<diff1){
350     fPoint[0]=x0;
351     fPoint[1]=y0;
352   }
353   else{
354     fPoint[0]=x1;
355     fPoint[1]=y1;
356   }
357
358   Double_t pointPhi0  = atan2(fPoint[1]-fCenterY,fPoint[0]-fCenterX);
359   Double_t trackPhi0  = atan2(fFirstPoint[1]-fCenterY,fFirstPoint[0]-fCenterX);
360   if(fabs(trackPhi0-pointPhi0)>AliHLTTPCTransform::Pi()){
361     if(trackPhi0<pointPhi0) trackPhi0 += AliHLTTPCTransform::TwoPi();
362     else                    pointPhi0 += AliHLTTPCTransform::TwoPi();
363   }
364   Double_t stot = -fQ * (pointPhi0-trackPhi0) * fRadius ;
365   fPoint[2]   = fFirstPoint[2] + stot * fTanl;
366
367   fPointPsi = pointPhi0 - fQ * AliHLTTPCTransform::PiHalf();
368   if(fPointPsi<0.)  fPointPsi+= AliHLTTPCTransform::TwoPi();
369   fPointPsi = fmod(fPointPsi, AliHLTTPCTransform::TwoPi());
370
371   return IsPoint(kTRUE);
372 }
373
374 Bool_t AliHLTTPCTrack::CalculateEdgePoint(Double_t angle)
375 {
376   // Global coordinate: crossing point with y = ax; a=tan(angle);
377   //
378   Double_t rmin=AliHLTTPCTransform::Row2X(AliHLTTPCTransform::GetFirstRow(-1));  //min Radius of TPC
379   Double_t rmax=AliHLTTPCTransform::Row2X(AliHLTTPCTransform::GetLastRow(-1)); //max Radius of TPC
380
381   Double_t a = tan(angle);
382   Double_t pp=(fCenterX+a*fCenterY)/(1+pow(a,2));
383   Double_t qq=(pow(fCenterX,2)+pow(fCenterY,2)-pow(fRadius,2))/(1+pow(a,2));
384   Double_t racine = pp*pp-qq;
385   if(racine<0) return IsPoint(kFALSE);     //no Point
386   Double_t rootRacine = sqrt(racine);
387   Double_t x0 = pp+rootRacine;
388   Double_t x1 = pp-rootRacine;
389   Double_t y0 = a*x0;
390   Double_t y1 = a*x1;
391
392   Double_t r0 = sqrt(pow(x0,2)+pow(y0,2));
393   Double_t r1 = sqrt(pow(x1,2)+pow(y1,2)); 
394   //find the right crossing point:
395   //inside the TPC modules
396   Bool_t ok0 = kFALSE;
397   Bool_t ok1 = kFALSE;
398
399   if(r0>rmin&&r0<rmax){
400     Double_t da=atan2(y0,x0);
401     if(da<0) da+=AliHLTTPCTransform::TwoPi();
402     if(fabs(da-angle)<0.5)
403       ok0 = kTRUE;
404   }
405   if(r1>rmin&&r1<rmax){
406     Double_t da=atan2(y1,x1);
407     if(da<0) da+=AliHLTTPCTransform::TwoPi();
408     if(fabs(da-angle)<0.5)
409       ok1 = kTRUE;
410   }
411   if(!(ok0||ok1)) return IsPoint(kFALSE);   //no Point
412   
413   if(ok0&&ok1){
414     Double_t diff0 = sqrt(pow(fFirstPoint[0]-x0,2)+pow(fFirstPoint[1]-y0,2));
415     Double_t diff1 = sqrt(pow(fFirstPoint[0]-x1,2)+pow(fFirstPoint[1]-y1,2));
416     if(diff0<diff1) ok1 = kFALSE; //use ok0
417     else ok0 = kFALSE;            //use ok1
418   }
419   if(ok0){fPoint[0]=x0; fPoint[1]=y0;}
420   else   {fPoint[0]=x1; fPoint[1]=y1;}
421
422   Double_t pointPhi0  = atan2(fPoint[1]-fCenterY,fPoint[0]-fCenterX);
423   Double_t trackPhi0  = atan2(fFirstPoint[1]-fCenterY,fFirstPoint[0]-fCenterX);
424   if(fabs(trackPhi0-pointPhi0)>AliHLTTPCTransform::Pi()){
425     if(trackPhi0<pointPhi0) trackPhi0 += AliHLTTPCTransform::TwoPi();
426     else                    pointPhi0 += AliHLTTPCTransform::TwoPi();
427   }
428   Double_t stot = -fQ * (pointPhi0-trackPhi0) * fRadius ;
429   fPoint[2]   = fFirstPoint[2] + stot * fTanl;
430
431   fPointPsi = pointPhi0 - fQ * AliHLTTPCTransform::PiHalf();
432   if(fPointPsi<0.)  fPointPsi+= AliHLTTPCTransform::TwoPi();
433   fPointPsi = fmod(fPointPsi, AliHLTTPCTransform::TwoPi());
434
435   return IsPoint(kTRUE);
436 }
437
438 Bool_t AliHLTTPCTrack::CalculatePoint(Double_t xplane)
439 {
440   // Local coordinate: crossing point with x plane
441   //
442   Double_t racine = pow(fRadius,2)-pow(xplane-fCenterX,2);
443   if(racine<0) return IsPoint(kFALSE);
444   Double_t rootRacine = sqrt(racine);
445
446   Double_t y0 = fCenterY + rootRacine;
447   Double_t y1 = fCenterY - rootRacine;
448   //Double_t diff0 = sqrt(pow(fFirstPoint[0]-xplane)+pow(fFirstPoint[1]-y0));
449   //Double_t diff1 = sqrt(pow(fFirstPoint[0]-xplane)+pow(fFirstPoint[1]-y1));
450   Double_t diff0 = fabs(y0-fFirstPoint[1]);
451   Double_t diff1 = fabs(y1-fFirstPoint[1]);
452
453   fPoint[0]=xplane;
454   if(diff0<diff1) fPoint[1]=y0;
455   else            fPoint[1]=y1;
456
457   Double_t pointPhi0  = atan2(fPoint[1]-fCenterY,fPoint[0]-fCenterX);
458   Double_t trackPhi0  = atan2(fFirstPoint[1]-fCenterY,fFirstPoint[0]-fCenterX);
459   if(fabs(trackPhi0-pointPhi0)>AliHLTTPCTransform::Pi()){
460     if(trackPhi0<pointPhi0) trackPhi0 += AliHLTTPCTransform::TwoPi();
461     else                    pointPhi0 += AliHLTTPCTransform::TwoPi();
462   }
463   Double_t stot = -fQ * (pointPhi0-trackPhi0) * fRadius ;  
464   fPoint[2]   = fFirstPoint[2] + stot * fTanl;
465
466   fPointPsi = pointPhi0 - fQ * AliHLTTPCTransform::PiHalf();
467   if(fPointPsi<0.)  fPointPsi+= AliHLTTPCTransform::TwoPi();
468   fPointPsi = fmod(fPointPsi, AliHLTTPCTransform::TwoPi());
469
470   return IsPoint(kTRUE);
471 }
472
473 void AliHLTTPCTrack::UpdateToFirstPoint()
474 {
475   //Update track parameters to the innermost point on the track.
476   //This means that the parameters of the track will be given in the point
477   //of closest approach to the first innermost point, i.e. the point 
478   //lying on the track fit (and not the coordinates of the innermost point itself).
479   //This function assumes that fFirstPoint is already set to the coordinates of the innermost
480   //assigned cluster.
481   //
482   //During the helix-fit, the first point on the track is set to the coordinates
483   //of the innermost assigned cluster. This may be ok, if you just want a fast
484   //estimate of the "global" track parameters; such as the momentum etc.
485   //However, if you later on want to do more precise local calculations, such
486   //as impact parameter, residuals etc, you need to give the track parameters
487   //according to the actual fit.
488   // for straight line fit
489   if (AliHLTTPCTransform::GetBFieldValue() == 0.0 ){
490     Double_t xc = GetCenterX() - GetFirstPointX();
491     Double_t yc = GetCenterY() - GetFirstPointY();
492     
493     Double_t xn = (Double_t) sin( GetPsi() );
494     Double_t yn = -1. * (Double_t) cos( GetPsi() );
495     
496     Double_t d = xc*xn + yc*yn;
497     
498     Double_t distx = d * xn;
499     Double_t disty = d * yn;
500     
501     Double_t point[2];
502     
503     point[0] = distx + GetFirstPointX();
504     point[1] = disty + GetFirstPointY();
505     
506     //Update the track parameters
507     SetR0(sqrt(point[0]*point[0]+point[1]*point[1]));
508     SetPhi0(atan2(point[1],point[0]));
509     SetFirstPoint(point[0],point[1],GetZ0());
510   }
511   // for helix fit
512   else { 
513     Double_t xc = GetCenterX() - GetFirstPointX();
514     Double_t yc = GetCenterY() - GetFirstPointY();
515     
516     Double_t distx1 = xc*(1 + GetRadius()/sqrt(xc*xc + yc*yc));
517     Double_t disty1 = yc*(1 + GetRadius()/sqrt(xc*xc + yc*yc));
518     Double_t distance1 = sqrt(distx1*distx1 + disty1*disty1);
519     
520     Double_t distx2 = xc*(1 - GetRadius()/sqrt(xc*xc + yc*yc));
521     Double_t disty2 = yc*(1 - GetRadius()/sqrt(xc*xc + yc*yc));
522     Double_t distance2 = sqrt(distx2*distx2 + disty2*disty2);
523     
524     //Choose the closest:
525     Double_t point[2];
526     if(distance1 < distance2)
527       {
528         point[0] = distx1 + GetFirstPointX();
529         point[1] = disty1 + GetFirstPointY();
530       }
531     else
532       {
533         point[0] = distx2 + GetFirstPointX();
534         point[1] = disty2 + GetFirstPointY();
535       }
536     
537     Double_t pointpsi = atan2(point[1]-GetCenterY(),point[0]-GetCenterX());
538     pointpsi -= GetCharge()*AliHLTTPCTransform::PiHalf();
539     if(pointpsi < 0) pointpsi += AliHLTTPCTransform::TwoPi();
540     
541     //Update the track parameters
542     SetR0(sqrt(point[0]*point[0]+point[1]*point[1]));
543     SetPhi0(atan2(point[1],point[0]));
544     SetFirstPoint(point[0],point[1],GetZ0());
545     SetPsi(pointpsi);
546   }
547 }
548
549 void AliHLTTPCTrack::GetClosestPoint(AliHLTTPCVertex *vertex,Double_t &closestX,Double_t &closestY,Double_t &closestZ)
550 {
551   //Calculate the point of closest approach to the vertex
552   //This function calculates the minimum distance from the helix to the vertex, and choose 
553   //the corresponding point lying on the helix as the point of closest approach.
554   
555   Double_t xc = GetCenterX() - vertex->GetX();
556   Double_t yc = GetCenterY() - vertex->GetY();
557   
558   Double_t distx1 = xc*(1 + GetRadius()/sqrt(xc*xc + yc*yc));
559   Double_t disty1 = yc*(1 + GetRadius()/sqrt(xc*xc + yc*yc));
560   Double_t distance1 = sqrt(distx1*distx1 + disty1*disty1);
561   
562   Double_t distx2 = xc*(1 - GetRadius()/sqrt(xc*xc + yc*yc));
563   Double_t disty2 = yc*(1 - GetRadius()/sqrt(xc*xc + yc*yc));
564   Double_t distance2 = sqrt(distx2*distx2 + disty2*disty2);
565   
566   //Choose the closest:
567   if(distance1 < distance2)
568     {
569       closestX = distx1 + vertex->GetX();
570       closestY = disty1 + vertex->GetY();
571     }
572   else
573     {
574       closestX = distx2 + vertex->GetX();
575       closestY = disty2 + vertex->GetY();
576     }
577   
578   //Get the z coordinate:
579   Double_t angle1 = atan2((closestY-GetCenterY()),(closestX-GetCenterX()));
580   if(angle1 < 0) angle1 = angle1 + AliHLTTPCTransform::TwoPi();
581  
582   Double_t angle2 = atan2((GetFirstPointY()-GetCenterY()),(GetFirstPointX()-GetCenterX()));
583   if(angle2 < 0) angle2 = angle2 + AliHLTTPCTransform::TwoPi();
584   
585   Double_t diffAngle = angle1 - angle2;
586   diffAngle = fmod(diffAngle,AliHLTTPCTransform::TwoPi());
587   
588   if((GetCharge()*diffAngle) < 0) diffAngle = diffAngle + GetCharge()*AliHLTTPCTransform::TwoPi();
589   Double_t stot = fabs(diffAngle)*GetRadius();
590   closestZ = GetFirstPointZ() - stot*GetTgl();
591 }
592
593 void AliHLTTPCTrack::Print(Option_t* /*option*/) const
594
595 //print out parameters of track
596
597  LOG(AliHLTTPCLog::kInformational,"AliHLTTPCTrack::Print","Print values")
598     <<"NH="<<fNHits<<" "<<fMCid<<" K="<<fKappa<<" R="<<fRadius<<" Cx="<<fCenterX<<" Cy="<<fCenterY<<" MVT="
599     <<fFromMainVertex<<" Row0="<<fRowRange[0]<<" Row1="<<fRowRange[1]<<" Sector="<<fSector<<" Q="<<fQ<<" TgLam="
600     <<fTanl<<" psi="<<fPsi<<" pt="<<fPt<<" L="<<fLength<<" "<<fPterr<<" "<<fPsierr<<" "<<fZ0err<<" "
601     <<fTanlerr<<" phi0="<<fPhi0<<" R0="<<fR0<<" Z0="<<fZ0<<" X0="<<fFirstPoint[0]<<" Y0="<<fFirstPoint[1]<<" Z0="
602     <<fFirstPoint[2]<<" XL="<<fLastPoint[0]<<" YL="<<fLastPoint[1]<<" ZL="<<fLastPoint[2]<<" "
603     <<fPoint[0]<<" "<<fPoint[1]<<" "<<fPoint[2]<<" "<<fPointPsi<<" "<<fIsPoint<<" local="
604     <<fIsLocal<<" "<<fPID<<ENDLOG; 
605
606 }
607
608 int AliHLTTPCTrack::Convert2AliKalmanTrack()
609 {
610   // The method has been copied from AliHLTHoughKalmanTrack and adapted
611   // to the TPC conformal mapping track parametrization
612   int iResult=0;
613
614   // sector A00 starts at 3 o'clock, sectors are counted counterclockwise
615   // median of sector 00 is at 10 degrees, median of sector A04 at 90
616   //
617
618   Double_t charge=(double) GetCharge();
619   Double_t param[5];
620   param[1] = GetFirstPointZ();
621   param[3] = GetTgl();
622   param[4] = charge*(1.0/GetPt());
623
624   Double_t alpha, phi, xl, yl;
625
626   // rotate to local coordinates if necessary
627
628   if(GetSector() == -1){ // track in global coordinates
629
630     alpha = TMath::ATan2(GetFirstPointY(),GetFirstPointX());
631     double sinAlpha = TMath::Sin(alpha);
632     double cosAlpha = TMath::Cos(alpha);   
633
634     phi = GetPsi() - alpha;
635     xl =  GetFirstPointX()*cosAlpha + GetFirstPointY()*sinAlpha;    
636     yl = -GetFirstPointX()*sinAlpha + GetFirstPointY()*cosAlpha;
637
638   } else{ // track in local coordinates
639
640     alpha = (GetSector()+0.5)*(TMath::TwoPi()/18);
641     phi = GetPsi();    
642     xl = GetFirstPointX();
643     yl = GetFirstPointY();
644
645     // normalize alpha to [-Pi,+Pi]
646
647     alpha = alpha - TMath::TwoPi() * TMath::Floor( alpha /TMath::TwoPi()+.5);
648   }
649   
650   // extra rotation to keep phi in the range (-Pi/2,+Pi/2)
651   {  
652     const Double_t kMaxPhi = TMath::PiOver2() - 10./180.*TMath::Pi(); 
653     
654     // normalize phi to [-Pi,+Pi]
655     
656     phi = phi - TMath::TwoPi() * TMath::Floor( phi /TMath::TwoPi()+.5);
657     
658     if( phi >= kMaxPhi )
659       {      
660         alpha += TMath::PiOver2();
661         phi   -= TMath::PiOver2();
662         Double_t xtmp = xl;
663         xl =  yl;
664         yl = -xtmp;
665       } 
666     else if( phi <= -kMaxPhi )
667       {      
668         alpha += -TMath::PiOver2();
669         phi   -= -TMath::PiOver2();
670         Double_t xtmp = xl;
671         xl = -yl;
672         yl =  xtmp;
673       }
674   }
675
676   param[0] = yl;
677   param[2] = TMath::Sin(phi);
678   
679   //covariance matrix
680   Double_t cov[15]={
681     GetY0err(),                         //Error in Y (Y and X are the same)
682     0.,  GetZ0err(),                    //Error in Z
683     0.,  0.,  GetPsierr(),              //Error for Psi
684     0.,  0.,  0.,  GetTglerr(),         //Error for Tgl
685     0.,  0.,  0.,  0.,  GetPterr()      //Error for Pt
686   };
687
688   Int_t nCluster = GetNHits();
689   fdEdx=0;
690
691   // the Set function was not available in earlier versions, check done
692   // during configure; for the AliRoot build, by default ON
693 #ifdef EXTERNALTRACKPARAM_V1
694 #warning track conversion to ESD format needs AliRoot version > v4-05-04
695   //TODO (Feb 07): make this a real warning when logging system is adapted
696   //HLTWarning("track conversion to ESD format needs AliRoot version > v4-05-04");
697 #else
698   Set(xl,alpha,param,cov);
699   SetNumberOfClusters(nCluster);
700   SetChi2(0.);
701   SetFakeRatio(0.);
702   SetMass(0.13957);
703 #endif
704
705   return iResult;
706 }
707
708 void AliHLTTPCTrack::SetHits(Int_t nhits,UInt_t *hits)
709 {
710   // set hit array
711   if (!hits) return;
712   if (nhits>fgkHitArraySize) {
713     LOG(AliHLTTPCLog::kWarning,"AliHLTTPCTrack::SetHits","too many hits")
714       << "too many hits (" << nhits << ") for hit array of size " << fgkHitArraySize << ENDLOG; 
715     SetNHits(fgkHitArraySize);
716   } else {
717     SetNHits(nhits);
718   }
719   memcpy(fHitNumbers,hits,fNHits*sizeof(UInt_t));
720 }
721
722 Double_t AliHLTTPCTrack::GetLengthXY() const
723 {
724   //calculates the length of the arc in XY-plane. This is the length of the track in XY-plane.
725   //Using a^2 = b^2 + c^2 - 2bc * cosA for finding the angle between first and last point.
726   //Length of arc is arc = r*A. Where A is the angle between first and last point.
727
728   Double_t dx = GetLastPointX()-GetFirstPointX();
729   Double_t dy = GetLastPointY()-GetFirstPointY();
730   Double_t a = TMath::Sqrt((dx*dx)+(dy*dy)); 
731   Double_t r = GetRadius();
732   Double_t r2 = r*r;
733
734   Double_t A = TMath::ACos((r2+r2-(a*a))/(2*r2));
735
736   return r*A;
737 }
738
739 Double_t AliHLTTPCTrack::GetLengthTot() const
740 {
741   //Calculates the length of the track in 3D
742
743
744
745
746
747   return 100.0;
748
749 }
750
751 int AliHLTTPCTrack::CheckConsistency()
752 {
753   // Check consistency of all members
754   int iResult=0;
755   if (CheckDoubleMember(&fPterr,   0., "fPterr")<0) iResult=-EDOM;
756   if (CheckDoubleMember(&fPsierr,  0., "fPsierr")<0) iResult=-EDOM;
757   if (CheckDoubleMember(&fZ0err,   0., "fZ0err")<0) iResult=-EDOM;
758   if (CheckDoubleMember(&fY0err,   0., "fY0err")<0) iResult=-EDOM;  
759   if (CheckDoubleMember(&fTanlerr, 0., "fTanlerr")<0) iResult=-EDOM;
760   return iResult;
761 }
762
763 int AliHLTTPCTrack::CheckDoubleMember(double* pMember, double def, const char* name) const
764 {
765   // Check consistency of a Double member
766   if (!pMember) return -EINVAL;
767   if (TMath::Abs(*pMember)>kVeryBig) {
768     LOG(AliHLTTPCLog::kWarning,"AliHLTTPCTrack","member consistency")
769       << "invalid Double number %f" << *pMember << " in member " << name << ENDLOG; 
770     *pMember=def;
771     return -EDOM;
772   }
773   return 0;
774 }