]> git.uio.no Git - u/mrichter/AliRoot.git/blob - STEER/AliAODTrack.cxx
restricting the consistency check for symbolic names to the subdetectors present...
[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 AliVParticle
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   AliVParticle(),
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   SetPID((Float_t*)NULL);
50 }
51
52 //______________________________________________________________________________
53 AliAODTrack::AliAODTrack(Short_t id,
54                          Int_t label, 
55                          Double_t p[3],
56                          Bool_t cartesian,
57                          Double_t x[3],
58                          Bool_t isDCA,
59                          Double_t covMatrix[21],
60                          Short_t charge,
61                          UChar_t itsClusMap,
62                          Double_t pid[10],
63                          AliAODVertex *prodVertex,
64                          Bool_t usedForVtxFit,
65                          Bool_t usedForPrimVtxFit,
66                          AODTrk_t ttype,
67                          UInt_t selectInfo) :
68   AliVParticle(),
69   fChi2perNDF(-999.),
70   fChi2MatchTrigger(0.),
71   fFlags(0),
72   fLabel(label),
73   fITSMuonClusterMap(itsClusMap),
74   fFilterMap(selectInfo),
75   fID(id),
76   fCharge(charge),
77   fType(ttype),
78   fCovMatrix(NULL),
79   fDetPid(NULL),
80   fProdVertex(prodVertex)
81 {
82   // constructor
83  
84   SetP(p, cartesian);
85   SetPosition(x, isDCA);
86   SetUsedForVtxFit(usedForVtxFit);
87   SetUsedForPrimVtxFit(usedForPrimVtxFit);
88   if(covMatrix) SetCovMatrix(covMatrix);
89   SetPID(pid);
90
91 }
92
93 //______________________________________________________________________________
94 AliAODTrack::AliAODTrack(Short_t id,
95                          Int_t label, 
96                          Float_t p[3],
97                          Bool_t cartesian,
98                          Float_t x[3],
99                          Bool_t isDCA,
100                          Float_t covMatrix[21],
101                          Short_t charge,
102                          UChar_t itsClusMap,
103                          Float_t pid[10],
104                          AliAODVertex *prodVertex,
105                          Bool_t usedForVtxFit,
106                          Bool_t usedForPrimVtxFit,
107                          AODTrk_t ttype,
108                          UInt_t selectInfo) :
109   AliVParticle(),
110   fChi2perNDF(-999.),
111   fChi2MatchTrigger(0.),
112   fFlags(0),
113   fLabel(label),
114   fITSMuonClusterMap(itsClusMap),
115   fFilterMap(selectInfo),
116   fID(id),
117   fCharge(charge),
118   fType(ttype),
119   fCovMatrix(NULL),
120   fDetPid(NULL),
121   fProdVertex(prodVertex)
122 {
123   // constructor
124  
125   SetP(p, cartesian);
126   SetPosition(x, isDCA);
127   SetUsedForVtxFit(usedForVtxFit);
128   SetUsedForPrimVtxFit(usedForPrimVtxFit);
129   if(covMatrix) SetCovMatrix(covMatrix);
130   SetPID(pid);
131 }
132
133 //______________________________________________________________________________
134 AliAODTrack::~AliAODTrack() 
135 {
136   // destructor
137   delete fCovMatrix;
138 }
139
140
141 //______________________________________________________________________________
142 AliAODTrack::AliAODTrack(const AliAODTrack& trk) :
143   AliVParticle(trk),
144   fChi2perNDF(trk.fChi2perNDF),
145   fChi2MatchTrigger(trk.fChi2MatchTrigger),
146   fFlags(trk.fFlags),
147   fLabel(trk.fLabel),
148   fITSMuonClusterMap(trk.fITSMuonClusterMap),
149   fFilterMap(trk.fFilterMap),
150   fID(trk.fID),
151   fCharge(trk.fCharge),
152   fType(trk.fType),
153   fCovMatrix(NULL),
154   fDetPid(NULL),
155   fProdVertex(trk.fProdVertex)
156 {
157   // Copy constructor
158
159   trk.GetP(fMomentum);
160   trk.GetPosition(fPosition);
161   SetUsedForVtxFit(trk.GetUsedForVtxFit());
162   SetUsedForPrimVtxFit(trk.GetUsedForPrimVtxFit());
163   if(trk.fCovMatrix) fCovMatrix=new AliAODRedCov<6>(*trk.fCovMatrix);
164   if(trk.fDetPid) fDetPid=new AliAODPid(*trk.fDetPid);
165   SetPID(trk.fPID);
166 }
167
168 //______________________________________________________________________________
169 AliAODTrack& AliAODTrack::operator=(const AliAODTrack& trk)
170 {
171   // Assignment operator
172   if(this!=&trk) {
173
174     AliVParticle::operator=(trk);
175
176     trk.GetP(fMomentum);
177     trk.GetPosition(fPosition);
178     trk.GetPID(fPID);
179
180     fChi2perNDF = trk.fChi2perNDF;
181     fChi2MatchTrigger = trk.fChi2MatchTrigger;
182
183     fFlags = trk.fFlags;
184     fLabel = trk.fLabel;    
185     
186     fITSMuonClusterMap = trk.fITSMuonClusterMap;
187     fFilterMap = trk.fFilterMap;
188
189     fID = trk.fID;
190
191     fCharge = trk.fCharge;
192     fType = trk.fType;
193
194     delete fCovMatrix;
195     if(trk.fCovMatrix) fCovMatrix=new AliAODRedCov<6>(*trk.fCovMatrix);
196     else fCovMatrix=NULL;
197     fProdVertex = trk.fProdVertex;
198
199     SetUsedForVtxFit(trk.GetUsedForVtxFit());
200     SetUsedForPrimVtxFit(trk.GetUsedForPrimVtxFit());
201
202     delete fDetPid;
203     if(trk.fDetPid) fDetPid=new AliAODPid(*trk.fDetPid);
204     else fDetPid=NULL;
205   }
206
207   return *this;
208 }
209
210 //______________________________________________________________________________
211 Double_t AliAODTrack::M(AODTrkPID_t pid) const
212 {
213   // Returns the mass.
214   // Masses for nuclei don't exist in the PDG tables, therefore they were put by hand.
215
216   switch (pid) {
217
218   case kElectron :
219     return 0.000510999; //TDatabasePDG::Instance()->GetParticle(11/*::kElectron*/)->Mass();
220     break;
221
222   case kMuon :
223     return 0.1056584; //TDatabasePDG::Instance()->GetParticle(13/*::kMuonMinus*/)->Mass();
224     break;
225
226   case kPion :
227     return 0.13957; //TDatabasePDG::Instance()->GetParticle(211/*::kPiPlus*/)->Mass();
228     break;
229
230   case kKaon :
231     return 0.4937; //TDatabasePDG::Instance()->GetParticle(321/*::kKPlus*/)->Mass();
232     break;
233
234   case kProton :
235     return 0.9382720; //TDatabasePDG::Instance()->GetParticle(2212/*::kProton*/)->Mass();
236     break;
237
238   case kDeuteron :
239     return 1.8756; //TDatabasePDG::Instance()->GetParticle(1000010020)->Mass();
240     break;
241
242   case kTriton :
243     return 2.8089; //TDatabasePDG::Instance()->GetParticle(1000010030)->Mass();
244     break;
245
246   case kHelium3 :
247     return 2.8084; //TDatabasePDG::Instance()->GetParticle(1000020030)->Mass();
248     break;
249
250   case kAlpha :
251     return 3.7274; //TDatabasePDG::Instance()->GetParticle(1000020040)->Mass();
252     break;
253
254   case kUnknown :
255     return -999.;
256     break;
257
258   default :
259     return -999.;
260   }
261 }
262
263 //______________________________________________________________________________
264 Double_t AliAODTrack::E(AODTrkPID_t pid) const
265 {
266   // Returns the energy of the particle of a given pid.
267   
268   if (pid != kUnknown) { // particle was identified
269     Double_t m = M(pid);
270     return TMath::Sqrt(P()*P() + m*m);
271   } else { // pid unknown
272     return -999.;
273   }
274 }
275
276 //______________________________________________________________________________
277 Double_t AliAODTrack::Y(AODTrkPID_t pid) const
278 {
279   // Returns the rapidity of a particle of a given pid.
280   
281   if (pid != kUnknown) { // particle was identified
282     Double_t e = E(pid);
283     Double_t pz = Pz();
284     if (e>=0 && e!=pz) { // energy was positive (e.g. not -999.) and not equal to pz
285       return 0.5*TMath::Log((e+pz)/(e-pz));
286     } else { // energy not known or equal to pz
287       return -999.;
288     }
289   } else { // pid unknown
290     return -999.;
291   }
292 }
293
294 //______________________________________________________________________________
295 Double_t AliAODTrack::Y(Double_t m) const
296 {
297   // Returns the rapidity of a particle of a given mass.
298   
299   if (m >= 0.) { // mass makes sense
300     Double_t e = E(m);
301     Double_t pz = Pz();
302     if (e>=0 && e!=pz) { // energy was positive (e.g. not -999.) and not equal to pz
303       return 0.5*TMath::Log((e+pz)/(e-pz));
304     } else { // energy not known or equal to pz
305       return -999.;
306     }
307   } else { // pid unknown
308     return -999.;
309   }
310 }
311
312 //______________________________________________________________________________
313 AliAODTrack::AODTrkPID_t AliAODTrack::GetMostProbablePID() const 
314 {
315   // Returns the most probable PID array element.
316   
317   Int_t nPID = 10;
318   if (fPID) {
319     AODTrkPID_t loc = kUnknown;
320     Double_t max = 0.;
321     Bool_t allTheSame = kTRUE;
322     
323     for (Int_t iPID = 0; iPID < nPID; iPID++) {
324       if (fPID[iPID] >= max) {
325         if (fPID[iPID] > max) {
326           allTheSame = kFALSE;
327           max = fPID[iPID];
328           loc = (AODTrkPID_t)iPID;
329         } else {
330           allTheSame = kTRUE;
331         }
332       }
333     }
334     
335     return allTheSame ? kUnknown : loc;
336   } else {
337     return kUnknown;
338   }
339 }
340
341 //______________________________________________________________________________
342 void AliAODTrack::ConvertAliPIDtoAODPID()
343 {
344   // Converts AliPID array.
345   // The numbering scheme is the same for electrons, muons, pions, kaons, and protons.
346   // Everything else has to be set to zero.
347
348   fPID[kDeuteron] = 0.;
349   fPID[kTriton]   = 0.;
350   fPID[kHelium3]  = 0.;
351   fPID[kAlpha]    = 0.;
352   fPID[kUnknown]  = 0.;
353   
354   return;
355 }
356
357
358 //______________________________________________________________________________
359 template <class T> void AliAODTrack::SetP(const T *p, const Bool_t cartesian) 
360 {
361   // Set the momentum
362
363   if (p) {
364     if (cartesian) {
365       Double_t pt2 = p[0]*p[0] + p[1]*p[1];
366       Double_t pp  = TMath::Sqrt(pt2 + p[2]*p[2]);
367       
368       fMomentum[0] = TMath::Sqrt(pt2); // pt
369       fMomentum[1] = (pt2 != 0.) ? TMath::Pi()+TMath::ATan2(-p[1], -p[0]) : -999; // phi
370       fMomentum[2] = (pp != 0.) ? TMath::ACos(p[2] / pp) : -999.; // theta
371     } else {
372       fMomentum[0] = p[0];  // pt
373       fMomentum[1] = p[1];  // phi
374       fMomentum[2] = p[2];  // theta
375     }
376   } else {
377     fMomentum[0] = -999.;
378     fMomentum[1] = -999.;
379     fMomentum[2] = -999.;
380   }
381 }
382
383 //______________________________________________________________________________
384 template <class T> void AliAODTrack::SetPosition(const T *x, const Bool_t dca) 
385 {
386   // set the position
387
388   if (x) {
389     if (!dca) {
390       ResetBit(kIsDCA);
391
392       fPosition[0] = x[0];
393       fPosition[1] = x[1];
394       fPosition[2] = x[2];
395     } else {
396       SetBit(kIsDCA);
397       // don't know any better yet
398       fPosition[0] = -999.;
399       fPosition[1] = -999.;
400       fPosition[2] = -999.;
401     }
402   } else {
403     ResetBit(kIsDCA);
404
405     fPosition[0] = -999.;
406     fPosition[1] = -999.;
407     fPosition[2] = -999.;
408   }
409 }
410
411 //______________________________________________________________________________
412 void AliAODTrack::SetDCA(Double_t d, Double_t z) 
413 {
414   // set the dca
415   fPosition[0] = d;
416   fPosition[1] = z;
417   fPosition[2] = 0.;
418   SetBit(kIsDCA);
419 }
420
421 //______________________________________________________________________________
422 void AliAODTrack::Print(Option_t* /* option */) const
423 {
424   // prints information about AliAODTrack
425
426   printf("Object name: %s   Track type: %s\n", GetName(), GetTitle()); 
427   printf("        px = %f\n", Px());
428   printf("        py = %f\n", Py());
429   printf("        pz = %f\n", Pz());
430   printf("        pt = %f\n", Pt());
431   printf("      1/pt = %f\n", OneOverPt());
432   printf("     theta = %f\n", Theta());
433   printf("       phi = %f\n", Phi());
434   printf("  chi2/NDF = %f\n", Chi2perNDF());
435   printf("    charge = %d\n", Charge());
436 }
437
438 void AliAODTrack::SetMatchTrigger(Int_t matchTrig){
439 //
440 // Set the MUON trigger information
441   switch(matchTrig){
442     case 0: // 0 track does not match trigger
443       fITSMuonClusterMap=fITSMuonClusterMap&0x3fffffff;
444       break;
445     case 1: // 1 track match but does not pass pt cut
446       fITSMuonClusterMap=(fITSMuonClusterMap&0x3fffffff)|0x40000000;
447       break;
448     case 2: // 2 track match Low pt cut
449       fITSMuonClusterMap=(fITSMuonClusterMap&0x3fffffff)|0x80000000;
450       break;
451     case 3: // 3 track match High pt cut
452       fITSMuonClusterMap=fITSMuonClusterMap|0xc0000000;
453       break;
454     default:
455       fITSMuonClusterMap=fITSMuonClusterMap&0x3fffffff;
456       AliWarning(Form("unknown case for matchTrig: %d\n",matchTrig));
457   }
458 }
459
460 void AliAODTrack::SetHitsPatternInTrigCh(UShort_t hitsPatternInTrigCh){
461 //
462 // Set the MUON hit pattern (1 bit per chamber) 
463   fITSMuonClusterMap=(fITSMuonClusterMap&0xffff00ff)|(hitsPatternInTrigCh<<8);
464 }
465
466 Int_t AliAODTrack::HitsMT(Int_t istation, Int_t iplane, Char_t *cathode){
467 //
468 // Retrieve hit information for MUON identified by  (station, plane, cathode)
469   if(cathode){
470     if(cathode[0]=='x'||cathode[0]=='X'){
471       if(istation==1){
472         if(iplane==1)
473           return (fITSMuonClusterMap&0x8000)?1:0;
474         else if(iplane==2)
475           return (fITSMuonClusterMap&0x4000)?1:0;
476         else
477           return 0;
478       }else if(istation==2){
479         if(iplane==1)
480           return (fITSMuonClusterMap&0x2000)?1:0;
481         else if(iplane==2)
482           return (fITSMuonClusterMap&0x1000)?1:0;
483         else
484           return 0;
485       }else{
486         return 0;
487       }
488     }else if(cathode[0]=='y'||cathode[0]=='Y'){
489       if(istation==1){
490         if(iplane==1)
491           return (fITSMuonClusterMap&0x0800)?1:0;
492         else if(iplane==2)
493           return (fITSMuonClusterMap&0x0400)?1:0;
494         else
495           return 0;
496       }else if(istation==2){
497         if(iplane==1)
498           return (fITSMuonClusterMap&0x0200)?1:0;
499         else if(iplane==2)
500           return (fITSMuonClusterMap&0x0100)?1:0;
501         else
502           return 0;
503       }else{
504         return 0;
505       }
506     }else{
507       return 0;
508     }
509   }else{
510     if(istation==1){
511       if(iplane==1)
512         return (HitsMT(1,1,"X")||HitsMT(1,1,"Y"))?1:0;
513       else if(iplane==2)
514         return (HitsMT(1,2,"X")||HitsMT(1,2,"Y"))?1:0;
515       else
516         return 0;
517     }else if(istation==2){
518       if(iplane==1)
519         return (HitsMT(2,1,"X")||HitsMT(2,1,"Y"))?1:0;
520       else if(iplane==2)
521         return (HitsMT(2,2,"X")||HitsMT(2,2,"Y"))?1:0;
522       else
523         return 0;
524     }else{
525       return 0;
526     }
527   }
528 }
529
530 Int_t AliAODTrack::HitsMuonChamber(Int_t MuonChamber){
531 // Retrieve hit information for MUON Chamber
532   switch(MuonChamber){
533     case 11:
534       return HitsMT(1,1);
535     case 12:
536       return HitsMT(1,2);
537     case 13:
538       return HitsMT(2,1);
539     case 14:
540       return HitsMT(2,2);
541     default:
542       printf("Unknown MUON chamber: %d\n",MuonChamber);
543       return 0;
544   }
545 }
546
547
548
549 Bool_t AliAODTrack::PropagateTo(Double_t xk, Double_t b) {
550   //----------------------------------------------------------------
551   // Propagate this track to the plane X=xk (cm) in the field "b" (kG)
552   // This is in local coordinates!!!
553   //----------------------------------------------------------------
554
555   Double_t alpha = 0.;
556   Double_t localP[3] = {Px(), Py(), Pz()}; // set global (sic!) p
557   Global2LocalMomentum(localP, Charge(), alpha); // convert global to local momentum
558
559   AliAODVertex *origin = (AliAODVertex*)fProdVertex.GetObject();
560   Double_t localX[3] = {origin->GetX(), origin->GetY(), origin->GetZ()}; // set global (sic!) location of first track point
561   Global2LocalPosition(localX, alpha); // convert global to local position
562
563   Double_t &fX = localX[0];
564
565   Double_t dx=xk-fX;
566   if (TMath::Abs(dx)<=kAlmost0)  return kTRUE;
567
568   Double_t crv=localP[0]*b*kB2C;
569   if (TMath::Abs(b) < kAlmost0Field) crv=0.;
570
571   Double_t f1=localP[1], f2=f1 + crv*dx;
572   if (TMath::Abs(f1) >= kAlmost1) return kFALSE;
573   if (TMath::Abs(f2) >= kAlmost1) return kFALSE;
574
575   Double_t &fP0=localX[1], &fP1=localX[2], &fP2=localP[0], &fP3=localP[1], &fP4=localP[2];
576   /* covariance matrix to be fixed! 
577   Double_t 
578   &fC00=fC[0],
579   &fC10=fC[1],   &fC11=fC[2],  
580   &fC20=fC[3],   &fC21=fC[4],   &fC22=fC[5],
581   &fC30=fC[6],   &fC31=fC[7],   &fC32=fC[8],   &fC33=fC[9],  
582   &fC40=fC[10],  &fC41=fC[11],  &fC42=fC[12],  &fC43=fC[13], &fC44=fC[14];
583   */
584   Double_t r1=TMath::Sqrt(1.- f1*f1), r2=TMath::Sqrt(1.- f2*f2);
585
586   fX=xk;
587   fP0 += dx*(f1+f2)/(r1+r2);
588   fP1 += dx*(r2 + f2*(f1+f2)/(r1+r2))*fP3;
589   fP2 += dx*crv;
590
591   //f = F - 1
592    
593   //Double_t f02=    dx/(r1*r1*r1);            
594   Double_t cc=crv/fP4;
595   Double_t f04=0.5*dx*dx/(r1*r1*r1);         f04*=cc;
596   //Double_t f12=    dx*fP3*f1/(r1*r1*r1);
597   Double_t f14=0.5*dx*dx*fP3*f1/(r1*r1*r1);  f14*=cc;
598   //Double_t f13=    dx/r1;
599   Double_t f24=    dx;                       f24*=cc;
600   
601   /* covariance matrix to be fixed!
602   //b = C*ft
603   Double_t b00=f02*fC20 + f04*fC40, b01=f12*fC20 + f14*fC40 + f13*fC30;
604   Double_t b02=f24*fC40;
605   Double_t b10=f02*fC21 + f04*fC41, b11=f12*fC21 + f14*fC41 + f13*fC31;
606   Double_t b12=f24*fC41;
607   Double_t b20=f02*fC22 + f04*fC42, b21=f12*fC22 + f14*fC42 + f13*fC32;
608   Double_t b22=f24*fC42;
609   Double_t b40=f02*fC42 + f04*fC44, b41=f12*fC42 + f14*fC44 + f13*fC43;
610   Double_t b42=f24*fC44;
611   Double_t b30=f02*fC32 + f04*fC43, b31=f12*fC32 + f14*fC43 + f13*fC33;
612   Double_t b32=f24*fC43;
613   
614   //a = f*b = f*C*ft
615   Double_t a00=f02*b20+f04*b40,a01=f02*b21+f04*b41,a02=f02*b22+f04*b42;
616   Double_t a11=f12*b21+f14*b41+f13*b31,a12=f12*b22+f14*b42+f13*b32;
617   Double_t a22=f24*b42;
618
619   //F*C*Ft = C + (b + bt + a)
620   fC00 += b00 + b00 + a00;
621   fC10 += b10 + b01 + a01; 
622   fC20 += b20 + b02 + a02;
623   fC30 += b30;
624   fC40 += b40;
625   fC11 += b11 + b11 + a11;
626   fC21 += b21 + b12 + a12;
627   fC31 += b31; 
628   fC41 += b41;
629   fC22 += b22 + b22 + a22;
630   fC32 += b32;
631   fC42 += b42;
632   */
633   
634   Local2GlobalMomentum(localP, alpha); // convert local to global momentum
635   SetP(localP);
636
637   return kTRUE;
638 }