]> git.uio.no Git - u/mrichter/AliRoot.git/blob - HLT/src/AliL3Track.cxx
Added Gautes changes from Bergen.
[u/mrichter/AliRoot.git] / HLT / src / AliL3Track.cxx
1 // @(#) $Id$
2
3 // Author: Anders Vestbo <mailto:vestbo$fi.uib.no>, Uli Frankenfeld <mailto:franken@fi.uib.no>
4 //*-- Copyright &copy ALICE HLT Group
5
6 #include "AliL3StandardIncludes.h"
7
8 #include "AliL3RootTypes.h"
9 #include "AliL3Logging.h"
10 #include "AliL3Track.h"
11 #include "AliL3Transform.h"
12 #include "AliL3Vertex.h"
13 #include "AliL3SpacePointData.h"
14
15 #if __GNUC__ == 3
16 using namespace std;
17 #endif
18
19 /** \class AliL3Track
20 //<pre>
21 //_____________________________________________________________
22 // AliL3Track
23 //
24 // Track base class
25 //Begin_Html
26 //<img src="track_coordinates.gif">
27 //End_Html
28 </pre>
29 */
30
31 ClassImp(AliL3Track)
32
33
34 AliL3Track::AliL3Track()
35 {
36   //Constructor
37
38   fNHits = 0;
39   fMCid = -1;
40   fKappa=0;
41   fRadius=0;
42   fCenterX=0;
43   fCenterY=0;
44   ComesFromMainVertex(false);
45   fQ = 0;
46   fPhi0=0;
47   fPsi=0;
48   fR0=0;
49   fTanl=0;
50   fZ0=0;
51   fPt=0;
52   fLength=0;
53   fIsLocal=true;
54   fRowRange[0]=0;
55   fRowRange[1]=0;
56   SetFirstPoint(0,0,0);
57   SetLastPoint(0,0,0);
58   memset(fHitNumbers,0,159*sizeof(UInt_t));
59   fPID = 0;
60 }
61
62 void AliL3Track::Set(AliL3Track *tpt)
63 {
64   //setter
65   SetRowRange(tpt->GetFirstRow(),tpt->GetLastRow());
66   SetPhi0(tpt->GetPhi0());
67   SetKappa(tpt->GetKappa());
68   SetNHits(tpt->GetNHits());
69   SetFirstPoint(tpt->GetFirstPointX(),tpt->GetFirstPointY(),tpt->GetFirstPointZ());
70   SetLastPoint(tpt->GetLastPointX(),tpt->GetLastPointY(),tpt->GetLastPointZ());
71   SetPt(tpt->GetPt());
72   SetPsi(tpt->GetPsi());
73   SetTgl(tpt->GetTgl());
74   SetCharge(tpt->GetCharge());
75   SetHits(tpt->GetNHits(),(UInt_t *)tpt->GetHitNumbers());
76 #ifdef do_mc
77   SetMCid(tpt->GetMCid());
78 #endif
79   SetPID(tpt->GetPID());
80   SetSector(tpt->GetSector());
81 }
82
83 Int_t AliL3Track::Compare(const AliL3Track *track) const
84 {
85   // compare tracks
86   if(track->GetNHits() < GetNHits()) return 1;
87   if(track->GetNHits() > GetNHits()) return -1;
88   return 0;
89 }
90
91 AliL3Track::~AliL3Track()
92 {
93   //Nothing to do
94 }
95
96 Double_t AliL3Track::GetP() const
97 {
98   // Returns total momentum.  
99   return fabs(GetPt())*sqrt(1. + GetTgl()*GetTgl());
100 }
101
102 Double_t AliL3Track::GetPseudoRapidity() const
103 { //get pseudo rap
104   return 0.5 * log((GetP() + GetPz()) / (GetP() - GetPz()));
105 }
106
107 /*
108 Double_t AliL3Track::GetEta() const
109 {
110   return GetPseudoRapidity();
111 }
112 */
113
114 Double_t AliL3Track::GetRapidity() const
115
116   //get rap
117   const Double_t m_pi = 0.13957;
118   return 0.5 * log((m_pi + GetPz()) / (m_pi - GetPz()));
119 }
120
121 void AliL3Track::Rotate(Int_t slice,Bool_t tolocal)
122 {
123   //Rotate track to global parameters
124   //If flag tolocal is set, the track is rotated
125   //to local coordinates.
126
127   Float_t psi[1] = {GetPsi()};
128   if(!tolocal)
129     AliL3Transform::Local2GlobalAngle(psi,slice);
130   else
131     AliL3Transform::Global2LocalAngle(psi,slice);
132   SetPsi(psi[0]);
133   Float_t first[3];
134   first[0] = GetFirstPointX();
135   first[1] = GetFirstPointY();
136   first[2] = GetFirstPointZ();
137   if(!tolocal)
138     AliL3Transform::Local2Global(first,slice);
139   else
140     AliL3Transform::Global2LocHLT(first,slice);
141   //AliL3Transform::Global2Local(first,slice,kTRUE);
142   
143   SetFirstPoint(first[0],first[1],first[2]);
144   Float_t last[3];
145   last[0] = GetLastPointX();
146   last[1] = GetLastPointY();
147   last[2] = GetLastPointZ();
148   if(!tolocal)
149     AliL3Transform::Local2Global(last,slice);
150   else
151     AliL3Transform::Global2LocHLT(last,slice);    
152   //AliL3Transform::Global2Local(last,slice,kTRUE);
153   SetLastPoint(last[0],last[1],last[2]);
154   
155   Float_t center[3] = {GetCenterX(),GetCenterY(),0};
156   if(!tolocal)
157     AliL3Transform::Local2Global(center,slice);
158   else
159     AliL3Transform::Global2LocHLT(center,slice);
160   //AliL3Transform::Global2Local(center,slice,kTRUE);
161   SetCenterX(center[0]);
162   SetCenterY(center[1]);
163   
164   SetPhi0(atan2(fFirstPoint[1],fFirstPoint[0]));
165   SetR0(sqrt(fFirstPoint[0]*fFirstPoint[0]+fFirstPoint[1]*fFirstPoint[1]));
166   
167   if(!tolocal)
168     fIsLocal=kFALSE;
169   else
170     fIsLocal=kTRUE;
171 }
172
173 void AliL3Track::CalculateHelix()
174 {
175   //Calculate Radius, CenterX and CenterY from Psi, X0, Y0
176   fRadius = fPt / (AliL3Transform::GetBFieldValue());
177   if(fRadius) fKappa = -fQ*1./fRadius;
178   else fRadius = 999999;  //just zero
179   Double_t trackPhi0 = fPsi + fQ * AliL3Transform::PiHalf();
180
181   fCenterX = fFirstPoint[0] - fRadius *  cos(trackPhi0);
182   fCenterY = fFirstPoint[1] - fRadius *  sin(trackPhi0);
183   
184   SetPhi0(atan2(fFirstPoint[1],fFirstPoint[0]));
185   SetR0(sqrt(fFirstPoint[0]*fFirstPoint[0]+fFirstPoint[1]*fFirstPoint[1]));
186 }
187
188 Double_t AliL3Track::GetCrossingAngle(Int_t padrow,Int_t slice) 
189 {
190   //Calculate the crossing angle between track and given padrow.
191   //Take the dot product of the tangent vector of the track, and
192   //vector perpendicular to the padrow.
193   //In order to do this, we need the tangent vector to the track at the
194   //point. This is done by rotating the radius vector by 90 degrees;
195   //rotation matrix: (  0  1 )
196   //                 ( -1  0 )
197
198   Float_t angle=0;//Angle perpendicular to the padrow in local coordinates
199   if(slice>=0)//Global coordinates
200     {
201       AliL3Transform::Local2GlobalAngle(&angle,slice);
202       if(!CalculateReferencePoint(angle,AliL3Transform::Row2X(padrow)))
203         cerr<<"AliL3Track::GetCrossingAngle : Track does not cross line in slice "<<slice<<" row "<<padrow<<endl;
204     }
205   else //should be in local coordinates
206     {
207       Float_t xyz[3];
208       GetCrossingPoint(padrow,xyz);
209       fPoint[0] = xyz[0];
210       fPoint[1] = xyz[1];
211       fPoint[2] = xyz[2];
212     }
213     
214   Double_t tangent[2];
215   
216   tangent[0] = (fPoint[1] - GetCenterY())/GetRadius();
217   tangent[1] = -1.*(fPoint[0] - GetCenterX())/GetRadius();
218
219   Double_t perp_padrow[2] = {cos(angle),sin(angle)}; 
220   
221   Double_t cos_beta = fabs(tangent[0]*perp_padrow[0] + tangent[1]*perp_padrow[1]);
222   if(cos_beta > 1) cos_beta=1;
223   return acos(cos_beta);
224 }
225
226 Bool_t AliL3Track::GetCrossingPoint(Int_t padrow,Float_t *xyz)
227 {
228   //Assumes the track is given in local coordinates
229   
230   if(!IsLocal())
231     {
232       cerr<<"GetCrossingPoint: Track is given on global coordinates"<<endl;
233       return false;
234     }
235   
236   Double_t xHit = AliL3Transform::Row2X(padrow);
237
238   xyz[0] = xHit;
239   Double_t aa = (xHit - GetCenterX())*(xHit - GetCenterX());
240   Double_t r2 = GetRadius()*GetRadius();
241   if(aa > r2)
242     return false;
243
244   Double_t aa2 = sqrt(r2 - aa);
245   Double_t y1 = GetCenterY() + aa2;
246   Double_t y2 = GetCenterY() - aa2;
247   xyz[1] = y1;
248   if(fabs(y2) < fabs(y1)) xyz[1] = y2;
249  
250   Double_t yHit = xyz[1];
251   Double_t angle1 = atan2((yHit - GetCenterY()),(xHit - GetCenterX()));
252   if(angle1 < 0) angle1 += 2.*AliL3Transform::Pi();
253   Double_t angle2 = atan2((GetFirstPointY() - GetCenterY()),(GetFirstPointX() - GetCenterX()));
254   if(angle2 < 0) angle2 += AliL3Transform::TwoPi();
255   Double_t diff_angle = angle1 - angle2;
256   diff_angle = fmod(diff_angle,AliL3Transform::TwoPi());
257   if((GetCharge()*diff_angle) > 0) diff_angle = diff_angle - GetCharge()*AliL3Transform::TwoPi();
258   Double_t s_tot = fabs(diff_angle)*GetRadius();
259   Double_t zHit = GetFirstPointZ() + s_tot*GetTgl();
260   xyz[2] = zHit;
261  
262   return true;
263
264 }
265
266 Bool_t AliL3Track::CalculateReferencePoint(Double_t angle,Double_t radius)
267 {
268   // Global coordinate: crossing point with y = ax+ b; 
269   // a=tan(angle-AliL3Transform::PiHalf());
270   //
271   const Double_t rr=radius; //position of reference plane
272   const Double_t xr = cos(angle) * rr;
273   const Double_t yr = sin(angle) * rr;
274   
275   Double_t a = tan(angle-AliL3Transform::PiHalf());
276   Double_t b = yr - a * xr;
277
278   Double_t pp=(fCenterX+a*fCenterY-a*b)/(1+pow(a,2));
279   Double_t qq=(pow(fCenterX,2)+pow(fCenterY,2)-2*fCenterY*b+pow(b,2)-pow(fRadius,2))/(1+pow(a,2));
280
281   Double_t racine = pp*pp-qq;
282   if(racine<0) return IsPoint(kFALSE);      //no Point
283
284   Double_t rootRacine = sqrt(racine);
285   Double_t x0 = pp+rootRacine;
286   Double_t x1 = pp-rootRacine;
287   Double_t y0 = a*x0 + b;
288   Double_t y1 = a*x1 + b;
289
290   Double_t diff0 = sqrt(pow(x0-xr,2)+pow(y0-yr,2));
291   Double_t diff1 = sqrt(pow(x1-xr,2)+pow(y1-yr,2));
292  
293   if(diff0<diff1){
294     fPoint[0]=x0;
295     fPoint[1]=y0;
296   }
297   else{
298     fPoint[0]=x1;
299     fPoint[1]=y1;
300   }
301
302   Double_t pointPhi0  = atan2(fPoint[1]-fCenterY,fPoint[0]-fCenterX);
303   Double_t trackPhi0  = atan2(fFirstPoint[1]-fCenterY,fFirstPoint[0]-fCenterX);
304   if(fabs(trackPhi0-pointPhi0)>AliL3Transform::Pi()){
305     if(trackPhi0<pointPhi0) trackPhi0 += AliL3Transform::TwoPi();
306     else                    pointPhi0 += AliL3Transform::TwoPi();
307   }
308   Double_t stot = -fQ * (pointPhi0-trackPhi0) * fRadius ;
309   fPoint[2]   = fFirstPoint[2] + stot * fTanl;
310
311   fPointPsi = pointPhi0 - fQ * AliL3Transform::PiHalf();
312   if(fPointPsi<0.)  fPointPsi+= AliL3Transform::TwoPi();
313   fPointPsi = fmod(fPointPsi, AliL3Transform::TwoPi());
314
315   return IsPoint(kTRUE);
316 }
317
318 Bool_t AliL3Track::CalculateEdgePoint(Double_t angle)
319 {
320   // Global coordinate: crossing point with y = ax; a=tan(angle);
321   //
322   Double_t rmin=AliL3Transform::Row2X(AliL3Transform::GetFirstRow(-1));  //min Radius of TPC
323   Double_t rmax=AliL3Transform::Row2X(AliL3Transform::GetLastRow(-1)); //max Radius of TPC
324
325   Double_t a = tan(angle);
326   Double_t pp=(fCenterX+a*fCenterY)/(1+pow(a,2));
327   Double_t qq=(pow(fCenterX,2)+pow(fCenterY,2)-pow(fRadius,2))/(1+pow(a,2));
328   Double_t racine = pp*pp-qq;
329   if(racine<0) return IsPoint(kFALSE);     //no Point
330   Double_t rootRacine = sqrt(racine);
331   Double_t x0 = pp+rootRacine;
332   Double_t x1 = pp-rootRacine;
333   Double_t y0 = a*x0;
334   Double_t y1 = a*x1;
335
336   Double_t r0 = sqrt(pow(x0,2)+pow(y0,2));
337   Double_t r1 = sqrt(pow(x1,2)+pow(y1,2)); 
338   //find the right crossing point:
339   //inside the TPC modules
340   Bool_t ok0 = kFALSE;
341   Bool_t ok1 = kFALSE;
342
343   if(r0>rmin&&r0<rmax){
344     Double_t da=atan2(y0,x0);
345     if(da<0) da+=AliL3Transform::TwoPi();
346     if(fabs(da-angle)<0.5)
347       ok0 = kTRUE;
348   }
349   if(r1>rmin&&r1<rmax){
350     Double_t da=atan2(y1,x1);
351     if(da<0) da+=AliL3Transform::TwoPi();
352     if(fabs(da-angle)<0.5)
353       ok1 = kTRUE;
354   }
355   if(!(ok0||ok1)) return IsPoint(kFALSE);   //no Point
356   
357   if(ok0&&ok1){
358     Double_t diff0 = sqrt(pow(fFirstPoint[0]-x0,2)+pow(fFirstPoint[1]-y0,2));
359     Double_t diff1 = sqrt(pow(fFirstPoint[0]-x1,2)+pow(fFirstPoint[1]-y1,2));
360     if(diff0<diff1) ok1 = kFALSE; //use ok0
361     else ok0 = kFALSE;            //use ok1
362   }
363   if(ok0){fPoint[0]=x0; fPoint[1]=y0;}
364   else   {fPoint[0]=x1; fPoint[1]=y1;}
365
366   Double_t pointPhi0  = atan2(fPoint[1]-fCenterY,fPoint[0]-fCenterX);
367   Double_t trackPhi0  = atan2(fFirstPoint[1]-fCenterY,fFirstPoint[0]-fCenterX);
368   if(fabs(trackPhi0-pointPhi0)>AliL3Transform::Pi()){
369     if(trackPhi0<pointPhi0) trackPhi0 += AliL3Transform::TwoPi();
370     else                    pointPhi0 += AliL3Transform::TwoPi();
371   }
372   Double_t stot = -fQ * (pointPhi0-trackPhi0) * fRadius ;
373   fPoint[2]   = fFirstPoint[2] + stot * fTanl;
374
375   fPointPsi = pointPhi0 - fQ * AliL3Transform::PiHalf();
376   if(fPointPsi<0.)  fPointPsi+= AliL3Transform::TwoPi();
377   fPointPsi = fmod(fPointPsi, AliL3Transform::TwoPi());
378
379   return IsPoint(kTRUE);
380 }
381
382 Bool_t AliL3Track::CalculatePoint(Double_t xplane)
383 {
384   // Local coordinate: crossing point with x plane
385   //
386   Double_t racine = pow(fRadius,2)-pow(xplane-fCenterX,2);
387   if(racine<0) return IsPoint(kFALSE);
388   Double_t rootRacine = sqrt(racine);
389
390   Double_t y0 = fCenterY + rootRacine;
391   Double_t y1 = fCenterY - rootRacine;
392   //Double_t diff0 = sqrt(pow(fFirstPoint[0]-xplane)+pow(fFirstPoint[1]-y0));
393   //Double_t diff1 = sqrt(pow(fFirstPoint[0]-xplane)+pow(fFirstPoint[1]-y1));
394   Double_t diff0 = fabs(y0-fFirstPoint[1]);
395   Double_t diff1 = fabs(y1-fFirstPoint[1]);
396
397   fPoint[0]=xplane;
398   if(diff0<diff1) fPoint[1]=y0;
399   else            fPoint[1]=y1;
400
401   Double_t pointPhi0  = atan2(fPoint[1]-fCenterY,fPoint[0]-fCenterX);
402   Double_t trackPhi0  = atan2(fFirstPoint[1]-fCenterY,fFirstPoint[0]-fCenterX);
403   if(fabs(trackPhi0-pointPhi0)>AliL3Transform::Pi()){
404     if(trackPhi0<pointPhi0) trackPhi0 += AliL3Transform::TwoPi();
405     else                    pointPhi0 += AliL3Transform::TwoPi();
406   }
407   Double_t stot = -fQ * (pointPhi0-trackPhi0) * fRadius ;  
408   fPoint[2]   = fFirstPoint[2] + stot * fTanl;
409
410   fPointPsi = pointPhi0 - fQ * AliL3Transform::PiHalf();
411   if(fPointPsi<0.)  fPointPsi+= AliL3Transform::TwoPi();
412   fPointPsi = fmod(fPointPsi, AliL3Transform::TwoPi());
413
414   return IsPoint(kTRUE);
415 }
416
417 void AliL3Track::UpdateToFirstPoint()
418 {
419   //Update track parameters to the innermost point on the track.
420   //This means that the parameters of the track will be given in the point
421   //of closest approach to the first innermost point, i.e. the point 
422   //lying on the track fit (and not the coordinates of the innermost point itself).
423   //This function assumes that fFirstPoint is already set to the coordinates of the innermost
424   //assigned cluster.
425   //
426   //During the helix-fit, the first point on the track is set to the coordinates
427   //of the innermost assigned cluster. This may be ok, if you just want a fast
428   //estimate of the "global" track parameters; such as the momentum etc.
429   //However, if you later on want to do more precise local calculations, such
430   //as impact parameter, residuals etc, you need to give the track parameters
431   //according to the actual fit.
432
433   Double_t xc = GetCenterX() - GetFirstPointX();
434   Double_t yc = GetCenterY() - GetFirstPointY();
435   
436   Double_t dist_x1 = xc*(1 + GetRadius()/sqrt(xc*xc + yc*yc));
437   Double_t dist_y1 = yc*(1 + GetRadius()/sqrt(xc*xc + yc*yc));
438   Double_t distance1 = sqrt(dist_x1*dist_x1 + dist_y1*dist_y1);
439   
440   Double_t dist_x2 = xc*(1 - GetRadius()/sqrt(xc*xc + yc*yc));
441   Double_t dist_y2 = yc*(1 - GetRadius()/sqrt(xc*xc + yc*yc));
442   Double_t distance2 = sqrt(dist_x2*dist_x2 + dist_y2*dist_y2);
443   
444   //Choose the closest:
445   Double_t point[2];
446   if(distance1 < distance2)
447     {
448       point[0] = dist_x1 + GetFirstPointX();
449       point[1] = dist_y1 + GetFirstPointY();
450     }
451   else
452     {
453       point[0] = dist_x2 + GetFirstPointX();
454       point[1] = dist_y2 + GetFirstPointY();
455     }
456
457   Double_t pointpsi = atan2(point[1]-GetCenterY(),point[0]-GetCenterX());
458   pointpsi -= GetCharge()*AliL3Transform::PiHalf();
459   if(pointpsi < 0) pointpsi += AliL3Transform::TwoPi();
460   
461   //Update the track parameters
462   SetR0(sqrt(point[0]*point[0]+point[1]*point[1]));
463   SetPhi0(atan2(point[1],point[0]));
464   SetFirstPoint(point[0],point[1],GetZ0());
465   SetPsi(pointpsi);
466   
467 }
468
469 void AliL3Track::GetClosestPoint(AliL3Vertex *vertex,Double_t &closest_x,Double_t &closest_y,Double_t &closest_z)
470 {
471   //Calculate the point of closest approach to the vertex
472   //This function calculates the minimum distance from the helix to the vertex, and choose 
473   //the corresponding point lying on the helix as the point of closest approach.
474   
475   Double_t xc = GetCenterX() - vertex->GetX();
476   Double_t yc = GetCenterY() - vertex->GetY();
477   
478   Double_t dist_x1 = xc*(1 + GetRadius()/sqrt(xc*xc + yc*yc));
479   Double_t dist_y1 = yc*(1 + GetRadius()/sqrt(xc*xc + yc*yc));
480   Double_t distance1 = sqrt(dist_x1*dist_x1 + dist_y1*dist_y1);
481   
482   Double_t dist_x2 = xc*(1 - GetRadius()/sqrt(xc*xc + yc*yc));
483   Double_t dist_y2 = yc*(1 - GetRadius()/sqrt(xc*xc + yc*yc));
484   Double_t distance2 = sqrt(dist_x2*dist_x2 + dist_y2*dist_y2);
485   
486   //Choose the closest:
487   if(distance1 < distance2)
488     {
489       closest_x = dist_x1 + vertex->GetX();
490       closest_y = dist_y1 + vertex->GetY();
491     }
492   else
493     {
494       closest_x = dist_x2 + vertex->GetX();
495       closest_y = dist_y2 + vertex->GetY();
496     }
497   
498   //Get the z coordinate:
499   Double_t angle1 = atan2((closest_y-GetCenterY()),(closest_x-GetCenterX()));
500   if(angle1 < 0) angle1 = angle1 + AliL3Transform::TwoPi();
501  
502   Double_t angle2 = atan2((GetFirstPointY()-GetCenterY()),(GetFirstPointX()-GetCenterX()));
503   if(angle2 < 0) angle2 = angle2 + AliL3Transform::TwoPi();
504   
505   Double_t diff_angle = angle1 - angle2;
506   diff_angle = fmod(diff_angle,AliL3Transform::TwoPi());
507   
508   if((GetCharge()*diff_angle) < 0) diff_angle = diff_angle + GetCharge()*AliL3Transform::TwoPi();
509   Double_t s_tot = fabs(diff_angle)*GetRadius();
510   
511   closest_z = GetFirstPointZ() - s_tot*GetTgl();
512 }