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