]> git.uio.no Git - u/mrichter/AliRoot.git/blob - STEER/AliKalmanTrack.cxx
preliminary PID in TPC needed by the ITS tracker
[u/mrichter/AliRoot.git] / STEER / AliKalmanTrack.cxx
1 /**************************************************************************
2  * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
3  *                                                                        *
4  * Author: The ALICE Off-line Project.                                    *
5  * Contributors are mentioned in the code where appropriate.              *
6  *                                                                        *
7  * Permission to use, copy, modify and distribute this software and its   *
8  * documentation strictly for non-commercial purposes is hereby granted   *
9  * without fee, provided that the above copyright notice appears in all   *
10  * copies and that both the copyright notice and this permission notice   *
11  * appear in the supporting documentation. The authors make no claims     *
12  * about the suitability of this software for any purpose. It is          *
13  * provided "as is" without express or implied warranty.                  *
14  **************************************************************************/
15
16 /* $Id$ */
17
18 //-------------------------------------------------------------------------
19 //                Implementation of the AliKalmanTrack class
20 //   that is the base for AliTPCtrack, AliITStrackV2 and AliTRDtrack
21 //        Origin: Iouri Belikov, CERN, Jouri.Belikov@cern.ch
22 //-------------------------------------------------------------------------
23
24 #include "AliKalmanTrack.h"
25 #include "AliLog.h"
26 #include "AliPDG.h"
27 #include "TPDGCode.h"
28 #include "TDatabasePDG.h"
29
30 ClassImp(AliKalmanTrack)
31
32 Double_t AliKalmanTrack::fgConvConst;
33
34 //_______________________________________________________________________
35 AliKalmanTrack::AliKalmanTrack():
36   fLab(-3141593),
37   fChi2(0),
38   fMass(0.13957),
39   fN(0)
40 {
41   //
42   // Default constructor
43   //
44     if (fgConvConst==0) {
45       AliFatal("The magnetic field has not been set!");
46     }
47     
48     fStartTimeIntegral = kFALSE;
49     fIntegratedLength = 0;
50     for(Int_t i=0; i<5; i++) fIntegratedTime[i] = 0;
51 }
52
53 //_______________________________________________________________________
54 AliKalmanTrack::AliKalmanTrack(const AliKalmanTrack &t):
55   TObject(t),
56   fLab(t.fLab),
57   fFakeRatio(t.fFakeRatio),
58   fChi2(t.fChi2),
59   fMass(t.fMass),
60   fN(t.fN)
61 {
62   //
63   // Copy constructor
64   //
65   if (fgConvConst==0) {
66     AliFatal("The magnetic field has not been set!");
67   }
68
69   fStartTimeIntegral = t.fStartTimeIntegral;
70   fIntegratedLength = t.fIntegratedLength;
71   
72   for (Int_t i=0; i<5; i++) 
73     fIntegratedTime[i] = t.fIntegratedTime[i];
74 }
75
76 //_______________________________________________________________________
77 void AliKalmanTrack::StartTimeIntegral() 
78 {
79   // Sylwester Radomski, GSI
80   // S.Radomski@gsi.de
81   //
82   // Start time integration
83   // To be called at Vertex by ITS tracker
84   //
85   
86   //if (fStartTimeIntegral) 
87   //  AliWarning("Reseting Recorded Time.");
88
89   fStartTimeIntegral = kTRUE;
90   for(Int_t i=0; i<fgkTypes; i++) fIntegratedTime[i] = 0;  
91   fIntegratedLength = 0;
92 }
93 //_______________________________________________________________________
94 void AliKalmanTrack:: AddTimeStep(Double_t length) 
95 {
96   // 
97   // Add step to integrated time
98   // this method should be called by a sublasses at the end
99   // of the PropagateTo function or by a tracker
100   // each time step is made.
101   //
102   // If integration not started function does nothing
103   //
104   // Formula
105   // dt = dl * sqrt(p^2 + m^2) / p
106   // p = pT * (1 + tg^2 (lambda) )
107   //
108   // pt = 1/external parameter [4]
109   // tg lambda = external parameter [3]
110   //
111   //
112   // Sylwester Radomski, GSI
113   // S.Radomski@gsi.de
114   // 
115   
116   static const Double_t kcc = 2.99792458e-2;
117
118   if (!fStartTimeIntegral) return;
119   
120   fIntegratedLength += length;
121
122   static Int_t pdgCode[fgkTypes]  = {kElectron, kMuonMinus, kPiPlus, kKPlus, kProton};
123   TDatabasePDG *db = TDatabasePDG::Instance();
124
125   Double_t xr, param[5];
126   Double_t pt, tgl;
127   
128   GetExternalParameters(xr, param);
129   pt =  1/param[4] ;
130   tgl = param[3];
131
132   Double_t p = TMath::Abs(pt * TMath::Sqrt(1+tgl*tgl));
133
134   if (length > 100) return;
135
136   for (Int_t i=0; i<fgkTypes; i++) {
137     
138     Double_t mass = db->GetParticle(pdgCode[i])->Mass();
139     Double_t correction = TMath::Sqrt( pt*pt * (1 + tgl*tgl) + mass * mass ) / p;
140     Double_t time = length * correction / kcc;
141
142     fIntegratedTime[i] += time;
143   }
144 }
145
146 //_______________________________________________________________________
147
148 Double_t AliKalmanTrack::GetIntegratedTime(Int_t pdg) const 
149 {
150   // Sylwester Radomski, GSI
151   // S.Radomski@gsi.de
152   //
153   // Return integrated time hypothesis for a given particle
154   // type assumption.
155   //
156   // Input parameter:
157   // pdg - Pdg code of a particle type
158   //
159
160
161   if (!fStartTimeIntegral) {
162     AliWarning("Time integration not started");
163     return 0.;
164   }
165
166   static Int_t pdgCode[fgkTypes] = {kElectron, kMuonMinus, kPiPlus, kKPlus, kProton};
167
168   for (Int_t i=0; i<fgkTypes; i++)
169     if (pdgCode[i] == TMath::Abs(pdg)) return fIntegratedTime[i];
170
171   AliWarning(Form("Particle type [%d] not found", pdg));
172   return 0;
173 }
174
175 void AliKalmanTrack::GetIntegratedTimes(Double_t *times) const {
176   for (Int_t i=0; i<fgkTypes; i++) times[i]=fIntegratedTime[i];
177 }
178
179 void AliKalmanTrack::SetIntegratedTimes(const Double_t *times) {
180   for (Int_t i=0; i<fgkTypes; i++) fIntegratedTime[i]=times[i];
181 }
182
183 //_______________________________________________________________________
184
185 void AliKalmanTrack::PrintTime() const
186 {
187   // Sylwester Radomski, GSI
188   // S.Radomski@gsi.de
189   //
190   // For testing
191   // Prints time for all hypothesis
192   //
193
194   static Int_t pdgCode[fgkTypes] = {kElectron, kMuonMinus, kPiPlus, kKPlus, kProton};
195
196   for (Int_t i=0; i<fgkTypes; i++)
197     printf("%d: %.2f  ", pdgCode[i], fIntegratedTime[i]);
198   printf("\n");  
199 }
200
201 static void External2Helix(const AliKalmanTrack *t, Double_t helix[6]) { 
202   //--------------------------------------------------------------------
203   // External track parameters -> helix parameters 
204   //--------------------------------------------------------------------
205   Double_t alpha,x,cs,sn;
206   t->GetExternalParameters(x,helix); alpha=t->GetAlpha();
207
208   cs=TMath::Cos(alpha); sn=TMath::Sin(alpha);
209   helix[5]=x*cs - helix[0]*sn;            // x0
210   helix[0]=x*sn + helix[0]*cs;            // y0
211 //helix[1]=                               // z0
212   helix[2]=TMath::ASin(helix[2]) + alpha; // phi0
213 //helix[3]=                               // tgl
214   helix[4]=helix[4]/t->GetConvConst();    // C
215 }
216
217 static void Evaluate(const Double_t *h, Double_t t,
218                      Double_t r[3],  //radius vector
219                      Double_t g[3],  //first defivatives
220                      Double_t gg[3]) //second derivatives
221 {
222   //--------------------------------------------------------------------
223   // Calculate position of a point on a track and some derivatives
224   //--------------------------------------------------------------------
225   Double_t phase=h[4]*t+h[2];
226   Double_t sn=TMath::Sin(phase), cs=TMath::Cos(phase);
227
228   r[0] = h[5] + (sn - h[6])/h[4];
229   r[1] = h[0] - (cs - h[7])/h[4];  
230   r[2] = h[1] + h[3]*t;
231
232   g[0] = cs; g[1]=sn; g[2]=h[3];
233   
234   gg[0]=-h[4]*sn; gg[1]=h[4]*cs; gg[2]=0.;
235 }
236
237 Double_t AliKalmanTrack::
238 GetDCA(const AliKalmanTrack *p, Double_t &xthis, Double_t &xp) const {
239   //------------------------------------------------------------
240   // Returns the (weighed !) distance of closest approach between 
241   // this track and the track passed as the argument.
242   // Other returned values:
243   //   xthis, xt - coordinates of tracks' reference planes at the DCA 
244   //-----------------------------------------------------------
245   Double_t dy2=GetSigmaY2() + p->GetSigmaY2();
246   Double_t dz2=GetSigmaZ2() + p->GetSigmaZ2();
247   Double_t dx2=dy2; 
248
249   //dx2=dy2=dz2=1.;
250
251   Double_t p1[8]; External2Helix(this,p1);
252   p1[6]=TMath::Sin(p1[2]); p1[7]=TMath::Cos(p1[2]);
253   Double_t p2[8]; External2Helix(p,p2);
254   p2[6]=TMath::Sin(p2[2]); p2[7]=TMath::Cos(p2[2]);
255
256
257   Double_t r1[3],g1[3],gg1[3]; Double_t t1=0.;
258   Evaluate(p1,t1,r1,g1,gg1);
259   Double_t r2[3],g2[3],gg2[3]; Double_t t2=0.;
260   Evaluate(p2,t2,r2,g2,gg2);
261
262   Double_t dx=r2[0]-r1[0], dy=r2[1]-r1[1], dz=r2[2]-r1[2];
263   Double_t dm=dx*dx/dx2 + dy*dy/dy2 + dz*dz/dz2;
264
265   Int_t max=27;
266   while (max--) {
267      Double_t gt1=-(dx*g1[0]/dx2 + dy*g1[1]/dy2 + dz*g1[2]/dz2);
268      Double_t gt2=+(dx*g2[0]/dx2 + dy*g2[1]/dy2 + dz*g2[2]/dz2);
269      Double_t h11=(g1[0]*g1[0] - dx*gg1[0])/dx2 + 
270                   (g1[1]*g1[1] - dy*gg1[1])/dy2 +
271                   (g1[2]*g1[2] - dz*gg1[2])/dz2;
272      Double_t h22=(g2[0]*g2[0] + dx*gg2[0])/dx2 + 
273                   (g2[1]*g2[1] + dy*gg2[1])/dy2 +
274                   (g2[2]*g2[2] + dz*gg2[2])/dz2;
275      Double_t h12=-(g1[0]*g2[0]/dx2 + g1[1]*g2[1]/dy2 + g1[2]*g2[2]/dz2);
276
277      Double_t det=h11*h22-h12*h12;
278
279      Double_t dt1,dt2;
280      if (TMath::Abs(det)<1.e-33) {
281         //(quasi)singular Hessian
282         dt1=-gt1; dt2=-gt2;
283      } else {
284         dt1=-(gt1*h22 - gt2*h12)/det; 
285         dt2=-(h11*gt2 - h12*gt1)/det;
286      }
287
288      if ((dt1*gt1+dt2*gt2)>0) {dt1=-dt1; dt2=-dt2;}
289
290      //check delta(phase1) ?
291      //check delta(phase2) ?
292
293      if (TMath::Abs(dt1)/(TMath::Abs(t1)+1.e-3) < 1.e-4)
294      if (TMath::Abs(dt2)/(TMath::Abs(t2)+1.e-3) < 1.e-4) {
295         if ((gt1*gt1+gt2*gt2) > 1.e-4/dy2/dy2) 
296           AliWarning(" stopped at not a stationary point !");
297         Double_t lmb=h11+h22; lmb=lmb-TMath::Sqrt(lmb*lmb-4*det);
298         if (lmb < 0.) 
299           AliWarning(" stopped at not a minimum !");
300         break;
301      }
302
303      Double_t dd=dm;
304      for (Int_t div=1 ; ; div*=2) {
305         Evaluate(p1,t1+dt1,r1,g1,gg1);
306         Evaluate(p2,t2+dt2,r2,g2,gg2);
307         dx=r2[0]-r1[0]; dy=r2[1]-r1[1]; dz=r2[2]-r1[2];
308         dd=dx*dx/dx2 + dy*dy/dy2 + dz*dz/dz2;
309         if (dd<dm) break;
310         dt1*=0.5; dt2*=0.5;
311         if (div>512) {
312            AliWarning(" overshoot !"); break;
313         }   
314      }
315      dm=dd;
316
317      t1+=dt1;
318      t2+=dt2;
319
320   }
321
322   if (max<=0) AliWarning(" too many iterations !");
323
324   Double_t cs=TMath::Cos(GetAlpha());
325   Double_t sn=TMath::Sin(GetAlpha());
326   xthis=r1[0]*cs + r1[1]*sn;
327
328   cs=TMath::Cos(p->GetAlpha());
329   sn=TMath::Sin(p->GetAlpha());
330   xp=r2[0]*cs + r2[1]*sn;
331
332   return TMath::Sqrt(dm*TMath::Sqrt(dy2*dz2));
333 }
334
335 Double_t AliKalmanTrack::
336 PropagateToDCA(AliKalmanTrack *p, Double_t d, Double_t x0) {
337   //--------------------------------------------------------------
338   // Propagates this track and the argument track to the position of the
339   // distance of closest approach. 
340   // Returns the (weighed !) distance of closest approach.
341   //--------------------------------------------------------------
342   Double_t xthis,xp;
343   Double_t dca=GetDCA(p,xthis,xp);
344
345   if (!PropagateTo(xthis,d,x0)) {
346     //AliWarning(" propagation failed !");
347     return 1e+33;
348   }  
349
350   if (!p->PropagateTo(xp,d,x0)) {
351     //AliWarning(" propagation failed !";
352     return 1e+33;
353   }  
354
355   return dca;
356 }