Fix Coverity 24835
[u/mrichter/AliRoot.git] / PWG / DevNanoAOD / AliNanoAODTrack.cxx
1 /**************************************************************************
2  * Copyright(c) 1998-2007, 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
17 //-------------------------------------------------------------------------
18 //     AOD special track implementation of AliVTrack
19 //     Author: Michele Floris, CERN
20 //     michele.floris@cern.ch
21 //-------------------------------------------------------------------------
22
23 #include <TVector3.h>
24 #include "AliLog.h"
25 #include "AliExternalTrackParam.h"
26 #include "AliVVertex.h"
27 #include "AliDetectorPID.h"
28 #include "AliAODEvent.h"
29 #include "AliAODHMPIDrings.h"
30
31 #include "AliNanoAODTrack.h"
32 #include "AliNanoAODTrackMapping.h"
33
34 ClassImp(AliNanoAODTrack)
35
36
37 //______________________________________________________________________________
38 AliNanoAODTrack::AliNanoAODTrack() : 
39   AliVTrack(),
40   AliNanoAODStorage(),
41   fLabel(0),
42   fProdVertex(0),
43   fCharge(0),
44   fAODEvent(NULL)
45 {
46   // default constructor
47   // The default constructor should not allocate memory! You risk an infinite loop here.
48   //  AllocateInternalStorage(AliNanoAODTrackMapping::GetInstance()->GetSize());
49
50   //  AllocateInternalStorage("pt,theta,phi");
51   // FIXME: TO BE REIMPLEMENTED
52   // SetPosition((Float_t*)NULL);
53   // SetXYAtDCA(-999., -999.);
54   // SetPxPyPzAtDCA(-999., -999., -999.);
55   // SetPID((Float_t*)NULL);
56   // for (Int_t i = 0; i < 3; i++) {fTOFLabel[i] = -1;}
57 }
58
59 //______________________________________________________________________________
60 AliNanoAODTrack::AliNanoAODTrack(AliAODTrack * aodTrack, const char * vars) :
61   AliVTrack(), 
62   AliNanoAODStorage(),
63   fLabel(0),
64   fProdVertex(0),
65   fCharge(0),
66   fAODEvent(NULL)
67 {
68   // constructor
69
70   Double_t position[3];
71   Bool_t isPosAvailable = aodTrack->GetPosition(position);
72   new AliNanoAODTrackMapping(vars);
73
74   // Create internal structure
75   AllocateInternalStorage(AliNanoAODTrackMapping::GetInstance()->GetSize());
76
77   for (Int_t index = 0; index<AliNanoAODTrackMapping::GetInstance()->GetSize(); index++) {
78     TString varString = AliNanoAODTrackMapping::GetInstance()->GetVarName(index);
79
80     if     (varString == "pt"                     ) SetVar(AliNanoAODTrackMapping::GetInstance()->GetPt()               , aodTrack->Pt()                      );
81     else if(varString == "phi"                    ) SetVar(AliNanoAODTrackMapping::GetInstance()->GetPhi()              , aodTrack->Phi()                     );
82     else if(varString == "theta"                  ) SetVar(AliNanoAODTrackMapping::GetInstance()->GetTheta()            , aodTrack->Theta()                   );
83     else if(varString == "chi2perNDF"             ) SetVar(AliNanoAODTrackMapping::GetInstance()->GetChi2PerNDF()       , aodTrack->Chi2perNDF()              );  
84     else if(varString == "posx" && isPosAvailable ) SetVar(AliNanoAODTrackMapping::GetInstance()->GetPosX()             , position[0]                         );
85     else if(varString == "posy" && isPosAvailable ) SetVar(AliNanoAODTrackMapping::GetInstance()->GetPosY()             , position[1]                         );
86     else if(varString == "posz" && isPosAvailable ) SetVar(AliNanoAODTrackMapping::GetInstance()->GetPosZ()             , position[2]                         );
87     else if(varString == "posDCAx"                ) SetVar(AliNanoAODTrackMapping::GetInstance()->GetPosDCAx()          , aodTrack->XAtDCA()                  );
88     else if(varString == "posDCAy"                ) SetVar(AliNanoAODTrackMapping::GetInstance()->GetPosDCAy()          , aodTrack->YAtDCA()                  );
89     else if(varString == "pDCAx"                  ) SetVar(AliNanoAODTrackMapping::GetInstance()->GetPDCAX()            , aodTrack->PxAtDCA()                 );
90     else if(varString == "pDCAy"                  ) SetVar(AliNanoAODTrackMapping::GetInstance()->GetPDCAY()            , aodTrack->PyAtDCA()                 );
91     else if(varString == "pDCAz"                  ) SetVar(AliNanoAODTrackMapping::GetInstance()->GetPDCAZ()            , aodTrack->PzAtDCA()                 );
92     else if(varString == "RAtAbsorberEnd"         ) SetVar(AliNanoAODTrackMapping::GetInstance()->GetRAtAbsorberEnd()   , aodTrack->GetRAtAbsorberEnd()       );
93     else if(varString == "TPCncls"                ) SetVar(AliNanoAODTrackMapping::GetInstance()->GetTPCncls()          , aodTrack->GetTPCNcls()              );
94     else if(varString == "id"                     ) SetVar(AliNanoAODTrackMapping::GetInstance()->Getid()               , aodTrack->GetID()                   );
95     else if(varString == "TPCnclsF"               ) SetVar(AliNanoAODTrackMapping::GetInstance()->GetTPCnclsF()         , aodTrack->GetTPCNclsF()             );
96     else if(varString == "TPCNCrossedRows"        ) SetVar(AliNanoAODTrackMapping::GetInstance()->GetTPCNCrossedRows()  , aodTrack->GetTPCNCrossedRows()      );
97     else if(varString == "TrackPhiOnEMCal"        ) SetVar(AliNanoAODTrackMapping::GetInstance()->GetTrackPhiOnEMCal()  , aodTrack->GetTrackPhiOnEMCal()      );
98     else if(varString == "TrackEtaOnEMCal"        ) SetVar(AliNanoAODTrackMapping::GetInstance()->GetTrackEtaOnEMCal()  , aodTrack->GetTrackEtaOnEMCal()      );
99     else if(varString == "TrackPtOnEMCal"         ) SetVar(AliNanoAODTrackMapping::GetInstance()->GetTrackPtOnEMCal()   , aodTrack->GetTrackPtOnEMCal()       );
100     else if(varString == "ITSsignal"              ) SetVar(AliNanoAODTrackMapping::GetInstance()->GetITSsignal()        , aodTrack->GetITSsignal()            );
101     else if(varString == "TPCsignal"              ) SetVar(AliNanoAODTrackMapping::GetInstance()->GetTPCsignal()        , aodTrack->GetTPCsignal()            );
102     else if(varString == "TPCsignalTuned"         ) SetVar(AliNanoAODTrackMapping::GetInstance()->GetTPCsignalTuned()   , aodTrack->GetTPCsignalTunedOnData() );
103     else if(varString == "TPCsignalN"             ) SetVar(AliNanoAODTrackMapping::GetInstance()->GetTPCsignalN()       , aodTrack->GetTPCsignalN()           );
104     else if(varString == "TPCmomentum"            ) SetVar(AliNanoAODTrackMapping::GetInstance()->GetTPCmomentum()      , aodTrack->GetTPCmomentum()          );
105     else if(varString == "TPCTgl"                 ) SetVar(AliNanoAODTrackMapping::GetInstance()->GetTPCTgl()           , aodTrack->GetTPCTgl()               );
106     else if(varString == "TOFsignal"              ) SetVar(AliNanoAODTrackMapping::GetInstance()->GetTOFsignal()        , aodTrack->GetTOFsignal()            );
107     else if(varString == "integratedLenght"       ) SetVar(AliNanoAODTrackMapping::GetInstance()->GetintegratedLenght() , aodTrack->GetIntegratedLength()     );
108     else if(varString == "TOFsignalTuned"         ) SetVar(AliNanoAODTrackMapping::GetInstance()->GetTOFsignalTuned()   , aodTrack->GetTOFsignalTunedOnData() );
109     else if(varString == "HMPIDsignal"            ) SetVar(AliNanoAODTrackMapping::GetInstance()->GetHMPIDsignal()      , aodTrack->GetHMPIDsignal()          );
110     else if(varString == "HMPIDoccupancy"         ) SetVar(AliNanoAODTrackMapping::GetInstance()->GetHMPIDoccupancy()   , aodTrack->GetHMPIDoccupancy()       );
111     else if(varString == "TRDsignal"              ) SetVar(AliNanoAODTrackMapping::GetInstance()->GetTRDsignal()        , aodTrack->GetTRDsignal()            );
112     else if(varString == "TRDChi2"                ) SetVar(AliNanoAODTrackMapping::GetInstance()->GetTRDChi2()          , aodTrack->GetTRDchi2()              );
113     else if(varString == "TRDnSlices"             ) SetVar(AliNanoAODTrackMapping::GetInstance()->GetTRDnSlices()       , aodTrack->GetNumberOfTRDslices()    );  
114     else if(varString == "covmat"                 ) AliFatal("cov matrix To be implemented"                            );
115   }
116
117
118   fLabel = aodTrack->GetLabel();
119   fCharge = aodTrack->Charge();
120   fProdVertex = aodTrack->GetProdVertex();
121   // SetUsedForVtxFit(usedForVtxFit);// FIXME: what is this
122   // SetUsedForPrimVtxFit(usedForPrimVtxFit);// FIXME: what is this
123   // //  if(covMatrix) SetCovMatrix(covMatrix);// FIXME: 
124   // for (Int_t i=0;i<3;i++) {fTOFLabel[i]=-1;}
125
126 }
127
128 //______________________________________________________________________________
129 AliNanoAODTrack::AliNanoAODTrack(AliESDTrack * /*esdTrack*/, const char * /*vars*/) : 
130   AliVTrack(), 
131   AliNanoAODStorage(),
132   fLabel(0),
133   fProdVertex(0),
134   fCharge(0),
135   fAODEvent(NULL)
136 {
137   // ctor: Creates a special track by copying the requested variables from an ESD track
138   AliFatal("To be Implemented");
139 }
140
141
142 AliNanoAODTrack::AliNanoAODTrack(const char * vars) :
143   AliVTrack(),
144   AliNanoAODStorage(),
145   fLabel(0),
146   fProdVertex(0),
147   fCharge(0),
148   fAODEvent(NULL)
149 {
150    // ctor: Creates a special track simply allocating the required variables
151   new AliNanoAODTrackMapping(vars);
152
153   // Create internal structure
154   AllocateInternalStorage(AliNanoAODTrackMapping::GetInstance()->GetSize());
155
156
157 }
158
159 //______________________________________________________________________________
160 AliNanoAODTrack::~AliNanoAODTrack() 
161 {
162   //  std::cout << "1 " << this << " "  << fKinVars << " " << fNKinVars << std::endl;
163   //  this->Print();
164   // destructor
165   // if(fKinVars)                {
166   //   std::cout << "2" << std::endl;
167   //   delete [] fKinVars;
168   //   std::cout << "3" << std::endl;
169   //   fKinVars = 0;
170   //   std::cout << "4" << std::endl;
171   // }
172
173   // if(fCovMatrix) {
174   //   delete fCovMatrix;
175   //   fCovMatrix = 0;
176   // }
177 }
178
179
180 //______________________________________________________________________________
181 AliNanoAODTrack::AliNanoAODTrack(const AliNanoAODTrack& trk) :
182   AliVTrack(),
183   AliNanoAODStorage(),
184   fLabel(trk.fLabel),
185   fProdVertex(trk.fProdVertex),
186   fCharge(trk.fCharge),
187   fAODEvent(trk.fAODEvent)
188 {
189   // Copy constructor
190   // std::cout << "Copy Ctor" << std::endl;
191   
192   AllocateInternalStorage(AliNanoAODTrackMapping::GetInstance()->GetSize());
193   for (Int_t isize = 0; isize<AliNanoAODTrackMapping::GetInstance()->GetSize(); isize++) {
194     SetVar(isize, trk.GetVar(isize));    
195   }
196
197
198 }
199
200 //______________________________________________________________________________
201 AliNanoAODTrack& AliNanoAODTrack::operator=(const AliNanoAODTrack& trk)
202 {
203   // Assignment operator
204   if(this!=&trk) {
205
206     AliVTrack::operator=(trk); // FIXME: I think I should overload this...
207     AliNanoAODStorage::operator=(trk);
208
209     fLabel      = trk.fLabel;
210     fProdVertex = trk.fProdVertex;
211     fCharge     = trk.fCharge;
212     fAODEvent   = trk.fAODEvent;
213     
214   }
215
216   return *this;
217 }
218
219
220
221 //______________________________________________________________________________
222 Double_t AliNanoAODTrack::M(AliAODTrack::AODTrkPID_t pid) const
223 {
224   // Returns the mass.
225   // Masses for nuclei don't exist in the PDG tables, therefore they were put by hand.
226
227   switch (pid) {
228
229   case AliAODTrack::kElectron :
230     return 0.000510999; //TDatabasePDG::Instance()->GetParticle(11/*::kElectron*/)->Mass();
231     break;
232
233   case AliAODTrack::kMuon :
234     return 0.1056584; //TDatabasePDG::Instance()->GetParticle(13/*::kMuonMinus*/)->Mass();
235     break;
236
237   case AliAODTrack::kPion :
238     return 0.13957; //TDatabasePDG::Instance()->GetParticle(211/*::kPiPlus*/)->Mass();
239     break;
240
241   case AliAODTrack::kKaon :
242     return 0.4937; //TDatabasePDG::Instance()->GetParticle(321/*::kKPlus*/)->Mass();
243     break;
244
245   case AliAODTrack::kProton :
246     return 0.9382720; //TDatabasePDG::Instance()->GetParticle(2212/*::kProton*/)->Mass();
247     break;
248
249   case AliAODTrack::kDeuteron :
250     return 1.8756; //TDatabasePDG::Instance()->GetParticle(1000010020)->Mass();
251     break;
252
253   case AliAODTrack::kTriton :
254     return 2.8089; //TDatabasePDG::Instance()->GetParticle(1000010030)->Mass();
255     break;
256
257   case AliAODTrack::kHelium3 :
258     return 2.8084; //TDatabasePDG::Instance()->GetParticle(1000020030)->Mass();
259     break;
260
261   case AliAODTrack::kAlpha :
262     return 3.7274; //TDatabasePDG::Instance()->GetParticle(1000020040)->Mass();
263     break;
264
265   case AliAODTrack::kUnknown :
266     return -999.;
267     break;
268
269   default :
270     return -999.;
271   }
272 }
273
274 //______________________________________________________________________________
275 Double_t AliNanoAODTrack::E(AliAODTrack::AODTrkPID_t pid) const
276 {
277   // Returns the energy of the particle of a given pid.
278   
279   if (pid != AliAODTrack::kUnknown) { // particle was identified
280     Double_t m = M(pid);
281     return TMath::Sqrt(P()*P() + m*m);
282   } else { // pid unknown
283     return -999.;
284   }
285 }
286
287 //______________________________________________________________________________
288 Double_t AliNanoAODTrack::Y(AliAODTrack::AODTrkPID_t pid) const
289 {
290   // Returns the rapidity of a particle of a given pid.
291   
292   if (pid != AliAODTrack::kUnknown) { // particle was identified
293     Double_t e = E(pid);
294     Double_t pz = Pz();
295     if (e>=0 && e!=pz) { // energy was positive (e.g. not -999.) and not equal to pz
296       return 0.5*TMath::Log((e+pz)/(e-pz));
297     } else { // energy not known or equal to pz
298       return -999.;
299     }
300   } else { // pid unknown
301     return -999.;
302   }
303 }
304
305 //______________________________________________________________________________
306 Double_t AliNanoAODTrack::Y(Double_t m) const
307 {
308   // Returns the rapidity of a particle of a given mass.
309   
310   if (m >= 0.) { // mass makes sense
311     Double_t e = E(m);
312     Double_t pz = Pz();
313     if (e>=0 && e!=pz) { // energy was positive (e.g. not -999.) and not equal to pz
314       return 0.5*TMath::Log((e+pz)/(e-pz));
315     } else { // energy not known or equal to pz
316       return -999.;
317     }
318   } else { // pid unknown
319     return -999.;
320   }
321 }
322
323
324
325 //______________________________________________________________________________
326 template <typename T> void AliNanoAODTrack::SetP(const T *p, const Bool_t cartesian) 
327 {
328   // Set the momentum
329
330   if (p) {
331     if (cartesian) {
332       // This is inherited from AliAODtrack... I don't think we want/need this in the special track
333       AliFatal("Not implemented");
334     } else {
335       SetVar(AliNanoAODTrackMapping::GetInstance()->GetPt()      , p[0]);  
336       SetVar(AliNanoAODTrackMapping::GetInstance()->GetPhi()     , p[1]);  
337       SetVar(AliNanoAODTrackMapping::GetInstance()->GetTheta()   , p[2]);  
338     }
339   } else {
340       SetVar(AliNanoAODTrackMapping::GetInstance()->GetPt()      , p[0]);  
341       SetVar(AliNanoAODTrackMapping::GetInstance()->GetPhi()     , p[1]);  
342       SetVar(AliNanoAODTrackMapping::GetInstance()->GetTheta()   , p[2]);  
343   }
344 }
345
346 /*
347 //______________________________________________________________________________
348 template <typename T> void AliNanoAODTrack::SetPosition(const T *x, const Bool_t dca) 
349 {
350   // set the position
351
352   if (x) {
353     if (!dca) {
354       ResetBit(kIsDCA);
355
356       fPosition[0] = x[0];
357       fPosition[1] = x[1];
358       fPosition[2] = x[2];
359     } else {
360       SetBit(kIsDCA);
361       // don't know any better yet
362       fPosition[0] = -999.;
363       fPosition[1] = -999.;
364       fPosition[2] = -999.;
365     }
366   } else {
367     ResetBit(kIsDCA);
368
369     fPosition[0] = -999.;
370     fPosition[1] = -999.;
371     fPosition[2] = -999.;
372   }
373 }
374 */
375 //______________________________________________________________________________
376 void AliNanoAODTrack::SetDCA(Double_t d, Double_t z) 
377 {
378   // set the dca 
379
380   // FIXME: this is a hack which was taken over from the AliAODtrack,
381   // where the same variable is used to store DCA or position,
382   // according to the value of the bit kIsDCA. We can probably get rid
383   // of this in the special track.
384   SetVar(AliNanoAODTrackMapping::GetInstance()->GetPosX(), d);
385   SetVar(AliNanoAODTrackMapping::GetInstance()->GetPosY(), z);
386   SetVar(AliNanoAODTrackMapping::GetInstance()->GetPosZ(), 0);
387   SetBit(AliAODTrack::kIsDCA);
388 }
389
390 //______________________________________________________________________________
391 void AliNanoAODTrack::Print(Option_t* /* option */) const
392 {
393   // prints information about AliNanoAODTrack
394   //  std::cout << "Size: " << AliNanoAODTrackMapping::GetInstance()->GetSize() << std::endl;
395   AliNanoAODTrackMapping::GetInstance()->Print();
396
397   for (Int_t index = 0; index<AliNanoAODTrackMapping::GetInstance()->GetSize(); index++) {
398     printf(" - [%2.2d] %-10s : %f\n", index, AliNanoAODTrackMapping::GetInstance()->GetVarName(index), GetVar(index));    
399   }
400   std::cout << "" << std::endl;  
401
402 }
403
404
405
406 //______________________________________________________________________________
407 Bool_t AliNanoAODTrack::PropagateToDCA(const AliVVertex *vtx, 
408     Double_t b, Double_t maxd, Double_t dz[2], Double_t covar[3])
409 {
410   // compute impact parameters to the vertex vtx and their covariance matrix
411   // b is the Bz, needed to propagate correctly the track to vertex 
412   // only the track parameters are update after the propagation (pos and mom),
413   // not the covariance matrix. This is OK for propagation over short distance
414   // inside the beam pipe.
415   // return kFALSE is something went wrong
416
417   // allowed only for tracks inside the beam pipe
418   Float_t xstart2 = GetVar(AliNanoAODTrackMapping::GetInstance()->GetPosX())*GetVar(AliNanoAODTrackMapping::GetInstance()->GetPosX())+GetVar(AliNanoAODTrackMapping::GetInstance()->GetPosY())*GetVar(AliNanoAODTrackMapping::GetInstance()->GetPosY());
419   
420   if(xstart2 > 3.*3.) { // outside beampipe radius
421     AliError("This method can be used only for propagation inside the beam pipe");
422     return kFALSE; 
423   }
424
425   // convert to AliExternalTrackParam
426   AliExternalTrackParam etp; etp.CopyFromVTrack(this);  
427
428   // propagate
429   if(!etp.PropagateToDCA(vtx,b,maxd,dz,covar)) return kFALSE;
430
431   // update track position and momentum
432   Double_t mom[3];
433   etp.GetPxPyPz(mom);
434   SetP(mom,kTRUE);
435   etp.GetXYZ(mom);
436   SetPosition(mom,kFALSE);
437
438
439   return kTRUE;
440 }
441
442 //______________________________________________________________________________
443 Bool_t AliNanoAODTrack::GetPxPyPz(Double_t p[3]) const 
444 {
445     //---------------------------------------------------------------------
446     // This function returns the global track momentum components
447     //---------------------------------------------------------------------
448   p[0]=Px(); p[1]=Py(); p[2]=Pz();
449   return kTRUE;
450 }
451
452
453
454 //_____________________________________________________________________________
455 //_____________________________________________________________________________
456
457 Bool_t AliNanoAODTrack::GetXYZAt(Double_t x, Double_t b, Double_t *r) const
458 {
459   //---------------------------------------------------------------------
460   // This function returns the global track position extrapolated to
461   // the radial position "x" (cm) in the magnetic field "b" (kG)
462   //---------------------------------------------------------------------
463
464   //conversion of track parameter representation is
465   //based on the implementation of AliExternalTrackParam::Set(...)
466   //maybe some of this code can be moved to AliVTrack to avoid code duplication
467   const double kSafe = 1e-5;
468   Double_t alpha=0.0;
469   Double_t radPos2 = GetVar(AliNanoAODTrackMapping::GetInstance()->GetPosX())*GetVar(AliNanoAODTrackMapping::GetInstance()->GetPosX())+GetVar(AliNanoAODTrackMapping::GetInstance()->GetPosY())*GetVar(AliNanoAODTrackMapping::GetInstance()->GetPosY());
470   Double_t radMax  = 45.; // approximately ITS outer radius
471   if (radPos2 < radMax*radMax) { // inside the ITS     
472     alpha = TMath::ATan2(Py(),Px());
473   } else { // outside the ITS
474     Float_t phiPos = TMath::Pi()+TMath::ATan2(-GetVar(AliNanoAODTrackMapping::GetInstance()->GetPosY()), -GetVar(AliNanoAODTrackMapping::GetInstance()->GetPosX()));
475      alpha = 
476      TMath::DegToRad()*(20*((((Int_t)(phiPos*TMath::RadToDeg()))/20))+10);
477   }
478   //
479   Double_t cs=TMath::Cos(alpha), sn=TMath::Sin(alpha);
480   // protection:  avoid alpha being too close to 0 or +-pi/2
481   if (TMath::Abs(sn)<kSafe) {
482     alpha = kSafe;
483     cs=TMath::Cos(alpha);
484     sn=TMath::Sin(alpha);
485   }
486   else if (cs<kSafe) {
487     alpha -= TMath::Sign(kSafe, alpha);
488     cs=TMath::Cos(alpha);
489     sn=TMath::Sin(alpha);    
490   }
491   
492   // Get the vertex of origin and the momentum
493   TVector3 ver(GetVar(AliNanoAODTrackMapping::GetInstance()->GetPosX()), GetVar(AliNanoAODTrackMapping::GetInstance()->GetPosY()), GetVar(AliNanoAODTrackMapping::GetInstance()->GetPosZ()));
494   TVector3 mom(Px(),Py(),Pz());
495   //
496   // avoid momenta along axis
497   if (TMath::Abs(mom[0])<kSafe) mom[0] = TMath::Sign(kSafe*TMath::Abs(mom[1]), mom[0]);
498   if (TMath::Abs(mom[1])<kSafe) mom[1] = TMath::Sign(kSafe*TMath::Abs(mom[0]), mom[1]);
499
500   // Rotate to the local coordinate system
501   ver.RotateZ(-alpha);
502   mom.RotateZ(-alpha);
503
504   Double_t param0 = ver.Y();
505   Double_t param1 = ver.Z();
506   Double_t param2 = TMath::Sin(mom.Phi());
507   Double_t param3 = mom.Pz()/mom.Pt();
508   Double_t param4 = TMath::Sign(1/mom.Pt(),(Double_t)fCharge);
509
510   //calculate the propagated coordinates
511   //this is based on AliExternalTrackParam::GetXYZAt(Double_t x, Double_t b, Double_t *r)
512   Double_t dx=x-ver.X();
513   if(TMath::Abs(dx)<=kAlmost0) return GetXYZ(r);
514
515   Double_t f1=param2;
516   Double_t f2=f1 + dx*param4*b*kB2C;
517
518   if (TMath::Abs(f1) >= kAlmost1) return kFALSE;
519   if (TMath::Abs(f2) >= kAlmost1) return kFALSE;
520   
521   Double_t r1=TMath::Sqrt((1.-f1)*(1.+f1)), r2=TMath::Sqrt((1.-f2)*(1.+f2));
522   r[0] = x;
523   r[1] = param0 + dx*(f1+f2)/(r1+r2);
524   r[2] = param1 + dx*(r2 + f2*(f1+f2)/(r1+r2))*param3;//Thanks to Andrea & Peter
525
526   return Local2GlobalPosition(r,alpha);
527 }
528
529
530 //_______________________________________________________
531
532 void  AliNanoAODTrack::Clear(Option_t * /*opt*/) {
533   // empty storage
534   fVars.clear();
535   fNVars = 0;
536 }