3 // Author: Anders Vestbo <mailto:vestbo$fi.uib.no>, Uli Frankenfeld <mailto:franken@fi.uib.no>
4 //*-- Copyright © ALICE HLT Group
6 #include "AliHLTTPCLogging.h"
7 #include "AliHLTTPCTrack.h"
8 #include "AliHLTTPCTransform.h"
9 #include "AliHLTTPCVertex.h"
10 #include "AliHLTTPCSpacePointData.h"
16 /** \class AliHLTTPCTrack
18 //_____________________________________________________________
23 //<img src="track_coordinates.gif">
28 ClassImp(AliHLTTPCTrack)
31 AliHLTTPCTrack::AliHLTTPCTrack()
40 ComesFromMainVertex(false);
54 memset(fHitNumbers,0,159*sizeof(UInt_t));
62 fPoint[0]=fPoint[1]=fPoint[2]=0;
66 void AliHLTTPCTrack::Set(AliHLTTPCTrack *tpt)
69 SetRowRange(tpt->GetFirstRow(),tpt->GetLastRow());
70 SetPhi0(tpt->GetPhi0());
71 SetKappa(tpt->GetKappa());
72 SetNHits(tpt->GetNHits());
73 SetFirstPoint(tpt->GetFirstPointX(),tpt->GetFirstPointY(),tpt->GetFirstPointZ());
74 SetLastPoint(tpt->GetLastPointX(),tpt->GetLastPointY(),tpt->GetLastPointZ());
76 SetPsi(tpt->GetPsi());
77 SetTgl(tpt->GetTgl());
78 SetPterr(tpt->GetPterr());
79 SetPsierr(tpt->GetPsierr());
80 SetTglerr(tpt->GetTglerr());
81 SetCharge(tpt->GetCharge());
82 SetHits(tpt->GetNHits(),(UInt_t *)tpt->GetHitNumbers());
84 SetMCid(tpt->GetMCid());
86 SetPID(tpt->GetPID());
87 SetSector(tpt->GetSector());
90 Int_t AliHLTTPCTrack::Compare(const AliHLTTPCTrack *track) const
93 if(track->GetNHits() < GetNHits()) return 1;
94 if(track->GetNHits() > GetNHits()) return -1;
98 AliHLTTPCTrack::~AliHLTTPCTrack()
103 Double_t AliHLTTPCTrack::GetP() const
105 // Returns total momentum.
106 return fabs(GetPt())*sqrt(1. + GetTgl()*GetTgl());
109 Double_t AliHLTTPCTrack::GetPseudoRapidity() const
111 return 0.5 * log((GetP() + GetPz()) / (GetP() - GetPz()));
115 Double_t AliHLTTPCTrack::GetEta() const
117 return GetPseudoRapidity();
121 Double_t AliHLTTPCTrack::GetRapidity() const
124 const Double_t kmpi = 0.13957;
125 return 0.5 * log((kmpi + GetPz()) / (kmpi - GetPz()));
128 void AliHLTTPCTrack::Rotate(Int_t slice,Bool_t tolocal)
130 //Rotate track to global parameters
131 //If flag tolocal is set, the track is rotated
132 //to local coordinates.
134 Float_t psi[1] = {GetPsi()};
136 AliHLTTPCTransform::Local2GlobalAngle(psi,slice);
138 AliHLTTPCTransform::Global2LocalAngle(psi,slice);
141 first[0] = GetFirstPointX();
142 first[1] = GetFirstPointY();
143 first[2] = GetFirstPointZ();
145 AliHLTTPCTransform::Local2Global(first,slice);
147 AliHLTTPCTransform::Global2LocHLT(first,slice);
148 //AliHLTTPCTransform::Global2Local(first,slice,kTRUE);
150 SetFirstPoint(first[0],first[1],first[2]);
152 last[0] = GetLastPointX();
153 last[1] = GetLastPointY();
154 last[2] = GetLastPointZ();
156 AliHLTTPCTransform::Local2Global(last,slice);
158 AliHLTTPCTransform::Global2LocHLT(last,slice);
159 //AliHLTTPCTransform::Global2Local(last,slice,kTRUE);
160 SetLastPoint(last[0],last[1],last[2]);
162 Float_t center[3] = {GetCenterX(),GetCenterY(),0};
164 AliHLTTPCTransform::Local2Global(center,slice);
166 AliHLTTPCTransform::Global2LocHLT(center,slice);
167 //AliHLTTPCTransform::Global2Local(center,slice,kTRUE);
168 SetCenterX(center[0]);
169 SetCenterY(center[1]);
171 SetPhi0(atan2(fFirstPoint[1],fFirstPoint[0]));
172 SetR0(sqrt(fFirstPoint[0]*fFirstPoint[0]+fFirstPoint[1]*fFirstPoint[1]));
180 void AliHLTTPCTrack::CalculateHelix()
182 //Calculate Radius, CenterX and CenterY from Psi, X0, Y0
183 fRadius = fPt / (AliHLTTPCTransform::GetBFieldValue());
184 if(fRadius) fKappa = -fQ*1./fRadius;
185 else fRadius = 999999; //just zero
186 Double_t trackPhi0 = fPsi + fQ * AliHLTTPCTransform::PiHalf();
188 fCenterX = fFirstPoint[0] - fRadius * cos(trackPhi0);
189 fCenterY = fFirstPoint[1] - fRadius * sin(trackPhi0);
191 SetPhi0(atan2(fFirstPoint[1],fFirstPoint[0]));
192 SetR0(sqrt(fFirstPoint[0]*fFirstPoint[0]+fFirstPoint[1]*fFirstPoint[1]));
195 Double_t AliHLTTPCTrack::GetCrossingAngle(Int_t padrow,Int_t slice)
197 //Calculate the crossing angle between track and given padrow.
198 //Take the dot product of the tangent vector of the track, and
199 //vector perpendicular to the padrow.
200 //In order to do this, we need the tangent vector to the track at the
201 //point. This is done by rotating the radius vector by 90 degrees;
202 //rotation matrix: ( 0 1 )
205 Float_t angle=0;//Angle perpendicular to the padrow in local coordinates
206 if(slice>=0)//Global coordinates
208 AliHLTTPCTransform::Local2GlobalAngle(&angle,slice);
209 if(!CalculateReferencePoint(angle,AliHLTTPCTransform::Row2X(padrow)))
210 cerr<<"AliHLTTPCTrack::GetCrossingAngle : Track does not cross line in slice "<<slice<<" row "<<padrow<<endl;
212 else //should be in local coordinates
215 GetCrossingPoint(padrow,xyz);
223 tangent[0] = (fPoint[1] - GetCenterY())/GetRadius();
224 tangent[1] = -1.*(fPoint[0] - GetCenterX())/GetRadius();
226 Double_t perppadrow[2] = {cos(angle),sin(angle)};
227 Double_t cosbeta = fabs(tangent[0]*perppadrow[0] + tangent[1]*perppadrow[1]);
228 if(cosbeta > 1) cosbeta=1;
229 return acos(cosbeta);
232 Bool_t AliHLTTPCTrack::GetCrossingPoint(Int_t padrow,Float_t *xyz)
234 //Assumes the track is given in local coordinates
237 cerr<<"GetCrossingPoint: Track is given on global coordinates"<<endl;
241 Double_t xHit = AliHLTTPCTransform::Row2X(padrow);
243 // BEGINN ############################################## MODIFIY JMT
245 LOG(AliHLTTPCLog::kError,"AliHLTTPCTRACK::GetCrossingPoint","")<< "Track doesn't cross padrow " << padrow <<"(x=" << xHit << "). Smallest x=" << xyz[0] << ENDLOG;
248 // END ################################################# MODIFIY JMT
251 Double_t aa = (xHit - GetCenterX())*(xHit - GetCenterX());
252 Double_t r2 = GetRadius()*GetRadius();
256 Double_t aa2 = sqrt(r2 - aa);
257 Double_t y1 = GetCenterY() + aa2;
258 Double_t y2 = GetCenterY() - aa2;
260 if(fabs(y2) < fabs(y1)) xyz[1] = y2;
262 Double_t yHit = xyz[1];
263 Double_t angle1 = atan2((yHit - GetCenterY()),(xHit - GetCenterX()));
264 if(angle1 < 0) angle1 += 2.*AliHLTTPCTransform::Pi();
265 Double_t angle2 = atan2((GetFirstPointY() - GetCenterY()),(GetFirstPointX() - GetCenterX()));
266 if(angle2 < 0) angle2 += AliHLTTPCTransform::TwoPi();
268 Double_t diffangle = angle1 - angle2;
269 diffangle = fmod(diffangle,AliHLTTPCTransform::TwoPi());
270 if((GetCharge()*diffangle) > 0) diffangle = diffangle - GetCharge()*AliHLTTPCTransform::TwoPi();
272 Double_t stot = fabs(diffangle)*GetRadius();
274 Double_t zHit = GetFirstPointZ() + stot*GetTgl();
282 Bool_t AliHLTTPCTrack::CalculateReferencePoint(Double_t angle,Double_t radius)
284 // Global coordinate: crossing point with y = ax+ b;
285 // a=tan(angle-AliHLTTPCTransform::PiHalf());
287 const Double_t krr=radius; //position of reference plane
288 const Double_t kxr = cos(angle) * krr;
289 const Double_t kyr = sin(angle) * krr;
291 Double_t a = tan(angle-AliHLTTPCTransform::PiHalf());
292 Double_t b = kyr - a * kxr;
294 Double_t pp=(fCenterX+a*fCenterY-a*b)/(1+pow(a,2));
295 Double_t qq=(pow(fCenterX,2)+pow(fCenterY,2)-2*fCenterY*b+pow(b,2)-pow(fRadius,2))/(1+pow(a,2));
297 Double_t racine = pp*pp-qq;
298 if(racine<0) return IsPoint(kFALSE); //no Point
300 Double_t rootRacine = sqrt(racine);
301 Double_t x0 = pp+rootRacine;
302 Double_t x1 = pp-rootRacine;
303 Double_t y0 = a*x0 + b;
304 Double_t y1 = a*x1 + b;
306 Double_t diff0 = sqrt(pow(x0-kxr,2)+pow(y0-kyr,2));
307 Double_t diff1 = sqrt(pow(x1-kxr,2)+pow(y1-kyr,2));
318 Double_t pointPhi0 = atan2(fPoint[1]-fCenterY,fPoint[0]-fCenterX);
319 Double_t trackPhi0 = atan2(fFirstPoint[1]-fCenterY,fFirstPoint[0]-fCenterX);
320 if(fabs(trackPhi0-pointPhi0)>AliHLTTPCTransform::Pi()){
321 if(trackPhi0<pointPhi0) trackPhi0 += AliHLTTPCTransform::TwoPi();
322 else pointPhi0 += AliHLTTPCTransform::TwoPi();
324 Double_t stot = -fQ * (pointPhi0-trackPhi0) * fRadius ;
325 fPoint[2] = fFirstPoint[2] + stot * fTanl;
327 fPointPsi = pointPhi0 - fQ * AliHLTTPCTransform::PiHalf();
328 if(fPointPsi<0.) fPointPsi+= AliHLTTPCTransform::TwoPi();
329 fPointPsi = fmod(fPointPsi, AliHLTTPCTransform::TwoPi());
331 return IsPoint(kTRUE);
334 Bool_t AliHLTTPCTrack::CalculateEdgePoint(Double_t angle)
336 // Global coordinate: crossing point with y = ax; a=tan(angle);
338 Double_t rmin=AliHLTTPCTransform::Row2X(AliHLTTPCTransform::GetFirstRow(-1)); //min Radius of TPC
339 Double_t rmax=AliHLTTPCTransform::Row2X(AliHLTTPCTransform::GetLastRow(-1)); //max Radius of TPC
341 Double_t a = tan(angle);
342 Double_t pp=(fCenterX+a*fCenterY)/(1+pow(a,2));
343 Double_t qq=(pow(fCenterX,2)+pow(fCenterY,2)-pow(fRadius,2))/(1+pow(a,2));
344 Double_t racine = pp*pp-qq;
345 if(racine<0) return IsPoint(kFALSE); //no Point
346 Double_t rootRacine = sqrt(racine);
347 Double_t x0 = pp+rootRacine;
348 Double_t x1 = pp-rootRacine;
352 Double_t r0 = sqrt(pow(x0,2)+pow(y0,2));
353 Double_t r1 = sqrt(pow(x1,2)+pow(y1,2));
354 //find the right crossing point:
355 //inside the TPC modules
359 if(r0>rmin&&r0<rmax){
360 Double_t da=atan2(y0,x0);
361 if(da<0) da+=AliHLTTPCTransform::TwoPi();
362 if(fabs(da-angle)<0.5)
365 if(r1>rmin&&r1<rmax){
366 Double_t da=atan2(y1,x1);
367 if(da<0) da+=AliHLTTPCTransform::TwoPi();
368 if(fabs(da-angle)<0.5)
371 if(!(ok0||ok1)) return IsPoint(kFALSE); //no Point
374 Double_t diff0 = sqrt(pow(fFirstPoint[0]-x0,2)+pow(fFirstPoint[1]-y0,2));
375 Double_t diff1 = sqrt(pow(fFirstPoint[0]-x1,2)+pow(fFirstPoint[1]-y1,2));
376 if(diff0<diff1) ok1 = kFALSE; //use ok0
377 else ok0 = kFALSE; //use ok1
379 if(ok0){fPoint[0]=x0; fPoint[1]=y0;}
380 else {fPoint[0]=x1; fPoint[1]=y1;}
382 Double_t pointPhi0 = atan2(fPoint[1]-fCenterY,fPoint[0]-fCenterX);
383 Double_t trackPhi0 = atan2(fFirstPoint[1]-fCenterY,fFirstPoint[0]-fCenterX);
384 if(fabs(trackPhi0-pointPhi0)>AliHLTTPCTransform::Pi()){
385 if(trackPhi0<pointPhi0) trackPhi0 += AliHLTTPCTransform::TwoPi();
386 else pointPhi0 += AliHLTTPCTransform::TwoPi();
388 Double_t stot = -fQ * (pointPhi0-trackPhi0) * fRadius ;
389 fPoint[2] = fFirstPoint[2] + stot * fTanl;
391 fPointPsi = pointPhi0 - fQ * AliHLTTPCTransform::PiHalf();
392 if(fPointPsi<0.) fPointPsi+= AliHLTTPCTransform::TwoPi();
393 fPointPsi = fmod(fPointPsi, AliHLTTPCTransform::TwoPi());
395 return IsPoint(kTRUE);
398 Bool_t AliHLTTPCTrack::CalculatePoint(Double_t xplane)
400 // Local coordinate: crossing point with x plane
402 Double_t racine = pow(fRadius,2)-pow(xplane-fCenterX,2);
403 if(racine<0) return IsPoint(kFALSE);
404 Double_t rootRacine = sqrt(racine);
406 Double_t y0 = fCenterY + rootRacine;
407 Double_t y1 = fCenterY - rootRacine;
408 //Double_t diff0 = sqrt(pow(fFirstPoint[0]-xplane)+pow(fFirstPoint[1]-y0));
409 //Double_t diff1 = sqrt(pow(fFirstPoint[0]-xplane)+pow(fFirstPoint[1]-y1));
410 Double_t diff0 = fabs(y0-fFirstPoint[1]);
411 Double_t diff1 = fabs(y1-fFirstPoint[1]);
414 if(diff0<diff1) fPoint[1]=y0;
417 Double_t pointPhi0 = atan2(fPoint[1]-fCenterY,fPoint[0]-fCenterX);
418 Double_t trackPhi0 = atan2(fFirstPoint[1]-fCenterY,fFirstPoint[0]-fCenterX);
419 if(fabs(trackPhi0-pointPhi0)>AliHLTTPCTransform::Pi()){
420 if(trackPhi0<pointPhi0) trackPhi0 += AliHLTTPCTransform::TwoPi();
421 else pointPhi0 += AliHLTTPCTransform::TwoPi();
423 Double_t stot = -fQ * (pointPhi0-trackPhi0) * fRadius ;
424 fPoint[2] = fFirstPoint[2] + stot * fTanl;
426 fPointPsi = pointPhi0 - fQ * AliHLTTPCTransform::PiHalf();
427 if(fPointPsi<0.) fPointPsi+= AliHLTTPCTransform::TwoPi();
428 fPointPsi = fmod(fPointPsi, AliHLTTPCTransform::TwoPi());
430 return IsPoint(kTRUE);
433 void AliHLTTPCTrack::UpdateToFirstPoint()
435 //Update track parameters to the innermost point on the track.
436 //This means that the parameters of the track will be given in the point
437 //of closest approach to the first innermost point, i.e. the point
438 //lying on the track fit (and not the coordinates of the innermost point itself).
439 //This function assumes that fFirstPoint is already set to the coordinates of the innermost
442 //During the helix-fit, the first point on the track is set to the coordinates
443 //of the innermost assigned cluster. This may be ok, if you just want a fast
444 //estimate of the "global" track parameters; such as the momentum etc.
445 //However, if you later on want to do more precise local calculations, such
446 //as impact parameter, residuals etc, you need to give the track parameters
447 //according to the actual fit.
448 // BEGINN ############################################## MODIFIY JMT
449 LOG(AliHLTTPCLog::kError,"AliHLTTPCTrack::UpdateToFirstPoint","ENTER") <<ENDLOG;
450 // END ################################################# MODIFIY JMT
451 Double_t xc = GetCenterX() - GetFirstPointX();
452 Double_t yc = GetCenterY() - GetFirstPointY();
454 Double_t distx1 = xc*(1 + GetRadius()/sqrt(xc*xc + yc*yc));
455 Double_t disty1 = yc*(1 + GetRadius()/sqrt(xc*xc + yc*yc));
456 Double_t distance1 = sqrt(distx1*distx1 + disty1*disty1);
458 Double_t distx2 = xc*(1 - GetRadius()/sqrt(xc*xc + yc*yc));
459 Double_t disty2 = yc*(1 - GetRadius()/sqrt(xc*xc + yc*yc));
460 Double_t distance2 = sqrt(distx2*distx2 + disty2*disty2);
462 //Choose the closest:
464 if(distance1 < distance2)
466 point[0] = distx1 + GetFirstPointX();
467 point[1] = disty1 + GetFirstPointY();
471 point[0] = distx2 + GetFirstPointX();
472 point[1] = disty2 + GetFirstPointY();
475 Double_t pointpsi = atan2(point[1]-GetCenterY(),point[0]-GetCenterX());
476 pointpsi -= GetCharge()*AliHLTTPCTransform::PiHalf();
477 if(pointpsi < 0) pointpsi += AliHLTTPCTransform::TwoPi();
479 //Update the track parameters
480 SetR0(sqrt(point[0]*point[0]+point[1]*point[1]));
481 SetPhi0(atan2(point[1],point[0]));
482 SetFirstPoint(point[0],point[1],GetZ0());
484 // BEGINN ############################################## MODIFIY JMT
485 LOG(AliHLTTPCLog::kError,"AliHLTTPCTrack::UpdateToFirstPoint","LEAVE") <<ENDLOG;
486 // END ################################################# MODIFIY JMT
489 void AliHLTTPCTrack::GetClosestPoint(AliHLTTPCVertex *vertex,Double_t &closestx,Double_t &closesty,Double_t &closestz)
491 //Calculate the point of closest approach to the vertex
492 //This function calculates the minimum distance from the helix to the vertex, and choose
493 //the corresponding point lying on the helix as the point of closest approach.
495 Double_t xc = GetCenterX() - vertex->GetX();
496 Double_t yc = GetCenterY() - vertex->GetY();
498 Double_t distx1 = xc*(1 + GetRadius()/sqrt(xc*xc + yc*yc));
499 Double_t disty1 = yc*(1 + GetRadius()/sqrt(xc*xc + yc*yc));
500 Double_t distance1 = sqrt(distx1*distx1 + disty1*disty1);
502 Double_t distx2 = xc*(1 - GetRadius()/sqrt(xc*xc + yc*yc));
503 Double_t disty2 = yc*(1 - GetRadius()/sqrt(xc*xc + yc*yc));
504 Double_t distance2 = sqrt(distx2*distx2 + disty2*disty2);
506 //Choose the closest:
507 if(distance1 < distance2)
509 closestx = distx1 + vertex->GetX();
510 closesty = disty1 + vertex->GetY();
514 closestx = distx2 + vertex->GetX();
515 closesty = disty2 + vertex->GetY();
518 //Get the z coordinate:
519 Double_t angle1 = atan2((closesty-GetCenterY()),(closestx-GetCenterX()));
520 if(angle1 < 0) angle1 = angle1 + AliHLTTPCTransform::TwoPi();
522 Double_t angle2 = atan2((GetFirstPointY()-GetCenterY()),(GetFirstPointX()-GetCenterX()));
523 if(angle2 < 0) angle2 = angle2 + AliHLTTPCTransform::TwoPi();
525 Double_t diff_angle = angle1 - angle2;
526 diff_angle = fmod(diff_angle,AliHLTTPCTransform::TwoPi());
528 if((GetCharge()*diff_angle) < 0) diff_angle = diff_angle + GetCharge()*AliHLTTPCTransform::TwoPi();
529 Double_t stot = fabs(diff_angle)*GetRadius();
530 closestz = GetFirstPointZ() - stot*GetTgl();
533 void AliHLTTPCTrack::Print() const
534 { //print out parameters of track
535 // BEGINN ############################################## MODIFIY JMT
538 LOG(AliHLTTPCLog::kInformational,"AliHLTTPCTrack::Print","Print values")
539 <<"NH="<<fNHits<<" "<<fMCid<<" K="<<fKappa<<" R="<<fRadius<<" Cx="<<fCenterX<<" Cy="<<fCenterY<<" MVT="
540 <<fFromMainVertex<<" Row0="<<fRowRange[0]<<" Row1="<<fRowRange[1]<<" Sector="<<fSector<<" Q="<<fQ<<" TgLam="
541 <<fTanl<<" psi="<<fPsi<<" pt="<<fPt<<" L="<<fLength<<" "<<fPterr<<" "<<fPsierr<<" "<<fZ0err<<" "
542 <<fTanlerr<<" phi0="<<fPhi0<<" R0="<<fR0<<" Z0"<<fZ0<<" X0"<<fFirstPoint[0]<<" Y0"<<fFirstPoint[1]<<" Z0"
543 <<fFirstPoint[2]<<" XL"<<fLastPoint[0]<<" YL"<<fLastPoint[1]<<" ZL"<<fLastPoint[2]<<" "
544 <<fPoint[0]<<" "<<fPoint[1]<<" "<<fPoint[2]<<" "<<fPointPsi<<" "<<fIsPoint<<" local="
545 <<fIsLocal<<" "<<fPID<<ENDLOG;
550 LOG(AliHLTTPCLog::kInformational,"AliHLTTPCTrack::Print","Print values")
551 <<fNHits<<" "<<fMCid<<" "<<fKappa<<" "<<fRadius<<" "<<fCenterX<<" "<<fCenterY<<" "
552 <<fFromMainVertex<<" "<<fRowRange[0]<<" "<<fRowRange[1]<<" "<<fSector<<" "<<fQ<<" "
553 <<fTanl<<" "<<fPsi<<" "<<fPt<<" "<<fLength<<" "<<fPterr<<" "<<fPsierr<<" "<<fZ0err<<" "
554 <<fTanlerr<<" "<<fPhi0<<" "<<fR0<<" "<<fZ0<<" "<<fFirstPoint[0]<<" "<<fFirstPoint[1]<<" "
555 <<fFirstPoint[2]<<" "<<fLastPoint[0]<<" "<<fLastPoint[1]<<" "<<fLastPoint[2]<<" "
556 <<fPoint[0]<<" "<<fPoint[1]<<" "<<fPoint[2]<<" "<<fPointPsi<<" "<<fIsPoint<<" "
557 <<fIsLocal<<" "<<fPID<<ENDLOG;
560 // END ################################################# MODIFIY JMT