c440da1da9483db8eb459776affa94d56b7b1afb
[u/mrichter/AliRoot.git] / STEER / AliAODTrack.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 /* $Id$ */
17
18 //-------------------------------------------------------------------------
19 //     AOD track implementation of AliVTrack
20 //     Author: Markus Oldenburg, CERN
21 //     Markus.Oldenburg@cern.ch
22 //-------------------------------------------------------------------------
23
24 #include "AliLog.h"
25 #include "AliAODTrack.h"
26
27 ClassImp(AliAODTrack)
28
29 //______________________________________________________________________________
30 AliAODTrack::AliAODTrack() : 
31   AliVTrack(),
32   fChi2perNDF(-999.),
33   fChi2MatchTrigger(0.),
34   fFlags(0),
35   fLabel(-999),
36   fITSMuonClusterMap(0),
37   fFilterMap(0),
38   fID(-999),
39   fCharge(-99),
40   fType(kUndef),
41   fCovMatrix(NULL),
42   fDetPid(NULL),
43   fProdVertex(NULL)
44 {
45   // default constructor
46
47   SetP();
48   SetPosition((Float_t*)NULL);
49   SetXYAtDCA(-999., -999.);
50   SetPxPyPzAtDCA(-999., -999., -999.);
51   SetPID((Float_t*)NULL);
52 }
53
54 //______________________________________________________________________________
55 AliAODTrack::AliAODTrack(Short_t id,
56                          Int_t label, 
57                          Double_t p[3],
58                          Bool_t cartesian,
59                          Double_t x[3],
60                          Bool_t isDCA,
61                          Double_t covMatrix[21],
62                          Short_t charge,
63                          UChar_t itsClusMap,
64                          Double_t pid[10],
65                          AliAODVertex *prodVertex,
66                          Bool_t usedForVtxFit,
67                          Bool_t usedForPrimVtxFit,
68                          AODTrk_t ttype,
69                          UInt_t selectInfo,
70                          Float_t chi2perNDF) :
71   AliVTrack(),
72   fChi2perNDF(chi2perNDF),
73   fChi2MatchTrigger(0.),
74   fFlags(0),
75   fLabel(label),
76   fITSMuonClusterMap(0),
77   fFilterMap(selectInfo),
78   fID(id),
79   fCharge(charge),
80   fType(ttype),
81   fCovMatrix(NULL),
82   fDetPid(NULL),
83   fProdVertex(prodVertex)
84 {
85   // constructor
86  
87   SetP(p, cartesian);
88   SetPosition(x, isDCA);
89   SetXYAtDCA(-999., -999.);
90   SetPxPyPzAtDCA(-999., -999., -999.);
91   SetUsedForVtxFit(usedForVtxFit);
92   SetUsedForPrimVtxFit(usedForPrimVtxFit);
93   if(covMatrix) SetCovMatrix(covMatrix);
94   SetPID(pid);
95   SetITSClusterMap(itsClusMap);
96 }
97
98 //______________________________________________________________________________
99 AliAODTrack::AliAODTrack(Short_t id,
100                          Int_t label, 
101                          Float_t p[3],
102                          Bool_t cartesian,
103                          Float_t x[3],
104                          Bool_t isDCA,
105                          Float_t covMatrix[21],
106                          Short_t charge,
107                          UChar_t itsClusMap,
108                          Float_t pid[10],
109                          AliAODVertex *prodVertex,
110                          Bool_t usedForVtxFit,
111                          Bool_t usedForPrimVtxFit,
112                          AODTrk_t ttype,
113                          UInt_t selectInfo,
114                          Float_t chi2perNDF) :
115   AliVTrack(),
116   fChi2perNDF(chi2perNDF),
117   fChi2MatchTrigger(0.),
118   fFlags(0),
119   fLabel(label),
120   fITSMuonClusterMap(0),
121   fFilterMap(selectInfo),
122   fID(id),
123   fCharge(charge),
124   fType(ttype),
125   fCovMatrix(NULL),
126   fDetPid(NULL),
127   fProdVertex(prodVertex)
128 {
129   // constructor
130  
131   SetP(p, cartesian);
132   SetPosition(x, isDCA);
133   SetXYAtDCA(-999., -999.);
134   SetPxPyPzAtDCA(-999., -999., -999.);
135   SetUsedForVtxFit(usedForVtxFit);
136   SetUsedForPrimVtxFit(usedForPrimVtxFit);
137   if(covMatrix) SetCovMatrix(covMatrix);
138   SetPID(pid);
139   SetITSClusterMap(itsClusMap);
140 }
141
142 //______________________________________________________________________________
143 AliAODTrack::~AliAODTrack() 
144 {
145   // destructor
146   delete fCovMatrix;
147   delete fDetPid;
148 }
149
150
151 //______________________________________________________________________________
152 AliAODTrack::AliAODTrack(const AliAODTrack& trk) :
153   AliVTrack(trk),
154   fChi2perNDF(trk.fChi2perNDF),
155   fChi2MatchTrigger(trk.fChi2MatchTrigger),
156   fFlags(trk.fFlags),
157   fLabel(trk.fLabel),
158   fITSMuonClusterMap(trk.fITSMuonClusterMap),
159   fFilterMap(trk.fFilterMap),
160   fID(trk.fID),
161   fCharge(trk.fCharge),
162   fType(trk.fType),
163   fCovMatrix(NULL),
164   fDetPid(NULL),
165   fProdVertex(trk.fProdVertex)
166 {
167   // Copy constructor
168
169   trk.GetP(fMomentum);
170   trk.GetPosition(fPosition);
171   SetXYAtDCA(trk.XAtDCA(), trk.YAtDCA());
172   SetPxPyPzAtDCA(trk.PxAtDCA(), trk.PyAtDCA(), trk.PzAtDCA());
173   SetUsedForVtxFit(trk.GetUsedForVtxFit());
174   SetUsedForPrimVtxFit(trk.GetUsedForPrimVtxFit());
175   if(trk.fCovMatrix) fCovMatrix=new AliAODRedCov<6>(*trk.fCovMatrix);
176   if(trk.fDetPid) fDetPid=new AliAODPid(*trk.fDetPid);
177   SetPID(trk.fPID);
178 }
179
180 //______________________________________________________________________________
181 AliAODTrack& AliAODTrack::operator=(const AliAODTrack& trk)
182 {
183   // Assignment operator
184   if(this!=&trk) {
185
186     AliVTrack::operator=(trk);
187
188     trk.GetP(fMomentum);
189     trk.GetPosition(fPosition);
190     trk.GetPID(fPID);
191
192     SetXYAtDCA(trk.XAtDCA(), trk.YAtDCA());
193     SetPxPyPzAtDCA(trk.PxAtDCA(), trk.PyAtDCA(), trk.PzAtDCA());
194     
195     fChi2perNDF = trk.fChi2perNDF;
196     fChi2MatchTrigger = trk.fChi2MatchTrigger;
197
198     fFlags = trk.fFlags;
199     fLabel = trk.fLabel;    
200     
201     fITSMuonClusterMap = trk.fITSMuonClusterMap;
202     fFilterMap = trk.fFilterMap;
203
204     fID = trk.fID;
205
206     fCharge = trk.fCharge;
207     fType = trk.fType;
208
209     delete fCovMatrix;
210     if(trk.fCovMatrix) fCovMatrix=new AliAODRedCov<6>(*trk.fCovMatrix);
211     else fCovMatrix=NULL;
212     fProdVertex = trk.fProdVertex;
213
214     SetUsedForVtxFit(trk.GetUsedForVtxFit());
215     SetUsedForPrimVtxFit(trk.GetUsedForPrimVtxFit());
216
217     delete fDetPid;
218     if(trk.fDetPid) fDetPid=new AliAODPid(*trk.fDetPid);
219     else fDetPid=NULL;
220   }
221
222   return *this;
223 }
224
225 //______________________________________________________________________________
226 Double_t AliAODTrack::M(AODTrkPID_t pid) const
227 {
228   // Returns the mass.
229   // Masses for nuclei don't exist in the PDG tables, therefore they were put by hand.
230
231   switch (pid) {
232
233   case kElectron :
234     return 0.000510999; //TDatabasePDG::Instance()->GetParticle(11/*::kElectron*/)->Mass();
235     break;
236
237   case kMuon :
238     return 0.1056584; //TDatabasePDG::Instance()->GetParticle(13/*::kMuonMinus*/)->Mass();
239     break;
240
241   case kPion :
242     return 0.13957; //TDatabasePDG::Instance()->GetParticle(211/*::kPiPlus*/)->Mass();
243     break;
244
245   case kKaon :
246     return 0.4937; //TDatabasePDG::Instance()->GetParticle(321/*::kKPlus*/)->Mass();
247     break;
248
249   case kProton :
250     return 0.9382720; //TDatabasePDG::Instance()->GetParticle(2212/*::kProton*/)->Mass();
251     break;
252
253   case kDeuteron :
254     return 1.8756; //TDatabasePDG::Instance()->GetParticle(1000010020)->Mass();
255     break;
256
257   case kTriton :
258     return 2.8089; //TDatabasePDG::Instance()->GetParticle(1000010030)->Mass();
259     break;
260
261   case kHelium3 :
262     return 2.8084; //TDatabasePDG::Instance()->GetParticle(1000020030)->Mass();
263     break;
264
265   case kAlpha :
266     return 3.7274; //TDatabasePDG::Instance()->GetParticle(1000020040)->Mass();
267     break;
268
269   case kUnknown :
270     return -999.;
271     break;
272
273   default :
274     return -999.;
275   }
276 }
277
278 //______________________________________________________________________________
279 Double_t AliAODTrack::E(AODTrkPID_t pid) const
280 {
281   // Returns the energy of the particle of a given pid.
282   
283   if (pid != kUnknown) { // particle was identified
284     Double_t m = M(pid);
285     return TMath::Sqrt(P()*P() + m*m);
286   } else { // pid unknown
287     return -999.;
288   }
289 }
290
291 //______________________________________________________________________________
292 Double_t AliAODTrack::Y(AODTrkPID_t pid) const
293 {
294   // Returns the rapidity of a particle of a given pid.
295   
296   if (pid != kUnknown) { // particle was identified
297     Double_t e = E(pid);
298     Double_t pz = Pz();
299     if (e>=0 && e!=pz) { // energy was positive (e.g. not -999.) and not equal to pz
300       return 0.5*TMath::Log((e+pz)/(e-pz));
301     } else { // energy not known or equal to pz
302       return -999.;
303     }
304   } else { // pid unknown
305     return -999.;
306   }
307 }
308
309 //______________________________________________________________________________
310 Double_t AliAODTrack::Y(Double_t m) const
311 {
312   // Returns the rapidity of a particle of a given mass.
313   
314   if (m >= 0.) { // mass makes sense
315     Double_t e = E(m);
316     Double_t pz = Pz();
317     if (e>=0 && e!=pz) { // energy was positive (e.g. not -999.) and not equal to pz
318       return 0.5*TMath::Log((e+pz)/(e-pz));
319     } else { // energy not known or equal to pz
320       return -999.;
321     }
322   } else { // pid unknown
323     return -999.;
324   }
325 }
326
327 //______________________________________________________________________________
328 AliAODTrack::AODTrkPID_t AliAODTrack::GetMostProbablePID() const 
329 {
330   // Returns the most probable PID array element.
331   
332   Int_t nPID = 10;
333   if (fPID) {
334     AODTrkPID_t loc = kUnknown;
335     Double_t max = 0.;
336     Bool_t allTheSame = kTRUE;
337     
338     for (Int_t iPID = 0; iPID < nPID; iPID++) {
339       if (fPID[iPID] >= max) {
340         if (fPID[iPID] > max) {
341           allTheSame = kFALSE;
342           max = fPID[iPID];
343           loc = (AODTrkPID_t)iPID;
344         } else {
345           allTheSame = kTRUE;
346         }
347       }
348     }
349     
350     return allTheSame ? kUnknown : loc;
351   } else {
352     return kUnknown;
353   }
354 }
355
356 //______________________________________________________________________________
357 void AliAODTrack::ConvertAliPIDtoAODPID()
358 {
359   // Converts AliPID array.
360   // The numbering scheme is the same for electrons, muons, pions, kaons, and protons.
361   // Everything else has to be set to zero.
362
363   fPID[kDeuteron] = 0.;
364   fPID[kTriton]   = 0.;
365   fPID[kHelium3]  = 0.;
366   fPID[kAlpha]    = 0.;
367   fPID[kUnknown]  = 0.;
368   
369   return;
370 }
371
372
373 //______________________________________________________________________________
374 template <class T> void AliAODTrack::SetP(const T *p, const Bool_t cartesian) 
375 {
376   // Set the momentum
377
378   if (p) {
379     if (cartesian) {
380       Double_t pt2 = p[0]*p[0] + p[1]*p[1];
381       Double_t pp  = TMath::Sqrt(pt2 + p[2]*p[2]);
382       
383       fMomentum[0] = TMath::Sqrt(pt2); // pt
384       fMomentum[1] = (pt2 != 0.) ? TMath::Pi()+TMath::ATan2(-p[1], -p[0]) : -999; // phi
385       fMomentum[2] = (pp != 0.) ? TMath::ACos(p[2] / pp) : -999.; // theta
386     } else {
387       fMomentum[0] = p[0];  // pt
388       fMomentum[1] = p[1];  // phi
389       fMomentum[2] = p[2];  // theta
390     }
391   } else {
392     fMomentum[0] = -999.;
393     fMomentum[1] = -999.;
394     fMomentum[2] = -999.;
395   }
396 }
397
398 //______________________________________________________________________________
399 template <class T> void AliAODTrack::SetPosition(const T *x, const Bool_t dca) 
400 {
401   // set the position
402
403   if (x) {
404     if (!dca) {
405       ResetBit(kIsDCA);
406
407       fPosition[0] = x[0];
408       fPosition[1] = x[1];
409       fPosition[2] = x[2];
410     } else {
411       SetBit(kIsDCA);
412       // don't know any better yet
413       fPosition[0] = -999.;
414       fPosition[1] = -999.;
415       fPosition[2] = -999.;
416     }
417   } else {
418     ResetBit(kIsDCA);
419
420     fPosition[0] = -999.;
421     fPosition[1] = -999.;
422     fPosition[2] = -999.;
423   }
424 }
425
426 //______________________________________________________________________________
427 void AliAODTrack::SetDCA(Double_t d, Double_t z) 
428 {
429   // set the dca
430   fPosition[0] = d;
431   fPosition[1] = z;
432   fPosition[2] = 0.;
433   SetBit(kIsDCA);
434 }
435
436 //______________________________________________________________________________
437 void AliAODTrack::Print(Option_t* /* option */) const
438 {
439   // prints information about AliAODTrack
440
441   printf("Object name: %s   Track type: %s\n", GetName(), GetTitle()); 
442   printf("        px = %f\n", Px());
443   printf("        py = %f\n", Py());
444   printf("        pz = %f\n", Pz());
445   printf("        pt = %f\n", Pt());
446   printf("      1/pt = %f\n", OneOverPt());
447   printf("     theta = %f\n", Theta());
448   printf("       phi = %f\n", Phi());
449   printf("  chi2/NDF = %f\n", Chi2perNDF());
450   printf("    charge = %d\n", Charge());
451 }
452
453 //______________________________________________________________________________
454 void AliAODTrack::SetMatchTrigger(Int_t matchTrig)
455 {
456   // Set the MUON trigger information
457   switch(matchTrig){
458     case 0: // 0 track does not match trigger
459       fITSMuonClusterMap=fITSMuonClusterMap&0x3fffffff;
460       break;
461     case 1: // 1 track match but does not pass pt cut
462       fITSMuonClusterMap=(fITSMuonClusterMap&0x3fffffff)|0x40000000;
463       break;
464     case 2: // 2 track match Low pt cut
465       fITSMuonClusterMap=(fITSMuonClusterMap&0x3fffffff)|0x80000000;
466       break;
467     case 3: // 3 track match High pt cut
468       fITSMuonClusterMap=fITSMuonClusterMap|0xc0000000;
469       break;
470     default:
471       fITSMuonClusterMap=fITSMuonClusterMap&0x3fffffff;
472       AliWarning(Form("unknown case for matchTrig: %d\n",matchTrig));
473   }
474 }
475
476 //______________________________________________________________________________
477 Bool_t AliAODTrack::HitsMuonChamber(Int_t MuonChamber, Int_t cathode) const
478 {
479   // return kTRUE if the track fires the given tracking or trigger chamber.
480   // If the chamber is a trigger one:
481   // - if cathode = 0 or 1, the track matches the corresponding cathode
482   // - if cathode = -1, the track matches both cathodes
483   
484   if (MuonChamber < 0) return kFALSE;
485   
486   if (MuonChamber < 10) return TESTBIT(GetMUONClusterMap(), MuonChamber);
487   
488   if (MuonChamber < 14) {
489     
490     if (cathode < 0) return TESTBIT(GetHitsPatternInTrigCh(), 13-MuonChamber) &&
491                             TESTBIT(GetHitsPatternInTrigCh(), 13-MuonChamber+4);
492     
493     if (cathode < 2) return TESTBIT(GetHitsPatternInTrigCh(), 13-MuonChamber+(1-cathode)*4);
494     
495   }
496   
497   return kFALSE;
498 }
499
500 //______________________________________________________________________________
501 Bool_t AliAODTrack::MatchTriggerDigits() const
502 {
503   // return kTRUE if the track matches a digit on both planes of at least 2 trigger chambers
504   
505   Int_t nMatchedChambers = 0;
506   for (Int_t ich=10; ich<14; ich++) if (HitsMuonChamber(ich)) nMatchedChambers++;
507   
508   return (nMatchedChambers >= 2);
509 }
510