]> git.uio.no Git - u/mrichter/AliRoot.git/blame - STEER/AOD/AliAODTrack.cxx
Fix for track vertices without constraint
[u/mrichter/AliRoot.git] / STEER / AOD / AliAODTrack.cxx
CommitLineData
df9db588 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//-------------------------------------------------------------------------
4f6e22bd 19// AOD track implementation of AliVTrack
df9db588 20// Author: Markus Oldenburg, CERN
0c5f89fb 21// Markus.Oldenburg@cern.ch
df9db588 22//-------------------------------------------------------------------------
23
086400fc 24#include <TVector3.h>
8ac4fa64 25#include "AliLog.h"
6dc40b1c 26#include "AliExternalTrackParam.h"
27#include "AliVVertex.h"
00a38d07 28#include "AliDetectorPID.h"
aab77ed0 29#include "AliAODEvent.h"
567624b5 30#include "AliAODHMPIDrings.h"
31
32#include "AliAODTrack.h"
df9db588 33
34ClassImp(AliAODTrack)
35
36//______________________________________________________________________________
37AliAODTrack::AliAODTrack() :
4f6e22bd 38 AliVTrack(),
f43586f0 39 fRAtAbsorberEnd(0.),
1912763f 40 fChi2perNDF(-999.),
9333290e 41 fChi2MatchTrigger(0.),
6efb741f 42 fFlags(0),
df9db588 43 fLabel(-999),
1912763f 44 fITSMuonClusterMap(0),
0a2dcc83 45 fMUONtrigHitsMapTrg(0),
46 fMUONtrigHitsMapTrk(0),
9333290e 47 fFilterMap(0),
bcabd0e4 48 fTPCFitMap(),
d999f2e6 49 fTPCClusterMap(),
50 fTPCSharedMap(),
3c01c166 51 fTPCnclsF(0),
820214a7 52 fTPCNCrossedRows(0),
02153d58 53 fID(-999),
9333290e 54 fCharge(-99),
e1c744ca 55 fType(kUndef),
a7d9ab9e 56 fCaloIndex(kEMCALNoMatch),
9333290e 57 fCovMatrix(NULL),
7be1db84 58 fDetPid(NULL),
00a38d07 59 fDetectorPID(NULL),
ed15417e 60 fProdVertex(NULL),
61 fTrackPhiOnEMCal(-999),
aab77ed0 62 fTrackEtaOnEMCal(-999),
539a5a59 63 fTPCsignalTuned(0),
aab77ed0 64 fAODEvent(NULL)
df9db588 65{
66 // default constructor
67
68 SetP();
69 SetPosition((Float_t*)NULL);
6c954176 70 SetXYAtDCA(-999., -999.);
71 SetPxPyPzAtDCA(-999., -999., -999.);
df9db588 72 SetPID((Float_t*)NULL);
73}
74
75//______________________________________________________________________________
02153d58 76AliAODTrack::AliAODTrack(Short_t id,
df9db588 77 Int_t label,
78 Double_t p[3],
79 Bool_t cartesian,
80 Double_t x[3],
81 Bool_t isDCA,
82 Double_t covMatrix[21],
83 Short_t charge,
84 UChar_t itsClusMap,
85 Double_t pid[10],
86 AliAODVertex *prodVertex,
1912763f 87 Bool_t usedForVtxFit,
dc825b15 88 Bool_t usedForPrimVtxFit,
ec40c484 89 AODTrk_t ttype,
862ce351 90 UInt_t selectInfo,
91 Float_t chi2perNDF) :
4f6e22bd 92 AliVTrack(),
f43586f0 93 fRAtAbsorberEnd(0.),
862ce351 94 fChi2perNDF(chi2perNDF),
9333290e 95 fChi2MatchTrigger(0.),
6efb741f 96 fFlags(0),
df9db588 97 fLabel(label),
6c954176 98 fITSMuonClusterMap(0),
0a2dcc83 99 fMUONtrigHitsMapTrg(0),
100 fMUONtrigHitsMapTrk(0),
9333290e 101 fFilterMap(selectInfo),
bcabd0e4 102 fTPCFitMap(),
d999f2e6 103 fTPCClusterMap(),
104 fTPCSharedMap(),
3c01c166 105 fTPCnclsF(0),
820214a7 106 fTPCNCrossedRows(0),
02153d58 107 fID(id),
9333290e 108 fCharge(charge),
e1c744ca 109 fType(ttype),
a7d9ab9e 110 fCaloIndex(kEMCALNoMatch),
9333290e 111 fCovMatrix(NULL),
7be1db84 112 fDetPid(NULL),
00a38d07 113 fDetectorPID(NULL),
ed15417e 114 fProdVertex(prodVertex),
115 fTrackPhiOnEMCal(-999),
aab77ed0 116 fTrackEtaOnEMCal(-999),
539a5a59 117 fTPCsignalTuned(0),
aab77ed0 118 fAODEvent(NULL)
df9db588 119{
120 // constructor
121
122 SetP(p, cartesian);
123 SetPosition(x, isDCA);
6c954176 124 SetXYAtDCA(-999., -999.);
125 SetPxPyPzAtDCA(-999., -999., -999.);
1912763f 126 SetUsedForVtxFit(usedForVtxFit);
dc825b15 127 SetUsedForPrimVtxFit(usedForPrimVtxFit);
df9db588 128 if(covMatrix) SetCovMatrix(covMatrix);
129 SetPID(pid);
6c954176 130 SetITSClusterMap(itsClusMap);
df9db588 131}
132
133//______________________________________________________________________________
02153d58 134AliAODTrack::AliAODTrack(Short_t id,
df9db588 135 Int_t label,
136 Float_t p[3],
137 Bool_t cartesian,
138 Float_t x[3],
139 Bool_t isDCA,
140 Float_t covMatrix[21],
141 Short_t charge,
142 UChar_t itsClusMap,
143 Float_t pid[10],
144 AliAODVertex *prodVertex,
1912763f 145 Bool_t usedForVtxFit,
dc825b15 146 Bool_t usedForPrimVtxFit,
ec40c484 147 AODTrk_t ttype,
862ce351 148 UInt_t selectInfo,
149 Float_t chi2perNDF) :
4f6e22bd 150 AliVTrack(),
f43586f0 151 fRAtAbsorberEnd(0.),
862ce351 152 fChi2perNDF(chi2perNDF),
9333290e 153 fChi2MatchTrigger(0.),
6efb741f 154 fFlags(0),
df9db588 155 fLabel(label),
6c954176 156 fITSMuonClusterMap(0),
0a2dcc83 157 fMUONtrigHitsMapTrg(0),
158 fMUONtrigHitsMapTrk(0),
9333290e 159 fFilterMap(selectInfo),
bcabd0e4 160 fTPCFitMap(),
d999f2e6 161 fTPCClusterMap(),
162 fTPCSharedMap(),
3c01c166 163 fTPCnclsF(0),
820214a7 164 fTPCNCrossedRows(0),
02153d58 165 fID(id),
9333290e 166 fCharge(charge),
e1c744ca 167 fType(ttype),
a7d9ab9e 168 fCaloIndex(kEMCALNoMatch),
9333290e 169 fCovMatrix(NULL),
7be1db84 170 fDetPid(NULL),
00a38d07 171 fDetectorPID(NULL),
ed15417e 172 fProdVertex(prodVertex),
173 fTrackPhiOnEMCal(-999),
aab77ed0 174 fTrackEtaOnEMCal(-999),
539a5a59 175 fTPCsignalTuned(0),
aab77ed0 176 fAODEvent(NULL)
df9db588 177{
178 // constructor
179
180 SetP(p, cartesian);
181 SetPosition(x, isDCA);
6c954176 182 SetXYAtDCA(-999., -999.);
183 SetPxPyPzAtDCA(-999., -999., -999.);
1912763f 184 SetUsedForVtxFit(usedForVtxFit);
dc825b15 185 SetUsedForPrimVtxFit(usedForPrimVtxFit);
df9db588 186 if(covMatrix) SetCovMatrix(covMatrix);
187 SetPID(pid);
6c954176 188 SetITSClusterMap(itsClusMap);
df9db588 189}
190
df9db588 191//______________________________________________________________________________
192AliAODTrack::~AliAODTrack()
193{
194 // destructor
195 delete fCovMatrix;
7450f8ab 196 delete fDetPid;
00a38d07 197 delete fDetectorPID;
df9db588 198}
199
200
201//______________________________________________________________________________
202AliAODTrack::AliAODTrack(const AliAODTrack& trk) :
4f6e22bd 203 AliVTrack(trk),
f43586f0 204 fRAtAbsorberEnd(trk.fRAtAbsorberEnd),
1912763f 205 fChi2perNDF(trk.fChi2perNDF),
9333290e 206 fChi2MatchTrigger(trk.fChi2MatchTrigger),
6efb741f 207 fFlags(trk.fFlags),
df9db588 208 fLabel(trk.fLabel),
1912763f 209 fITSMuonClusterMap(trk.fITSMuonClusterMap),
0a2dcc83 210 fMUONtrigHitsMapTrg(trk.fMUONtrigHitsMapTrg),
211 fMUONtrigHitsMapTrk(trk.fMUONtrigHitsMapTrk),
9333290e 212 fFilterMap(trk.fFilterMap),
bcabd0e4 213 fTPCFitMap(trk.fTPCFitMap),
d999f2e6 214 fTPCClusterMap(trk.fTPCClusterMap),
215 fTPCSharedMap(trk.fTPCSharedMap),
3c01c166 216 fTPCnclsF(trk.fTPCnclsF),
820214a7 217 fTPCNCrossedRows(trk.fTPCNCrossedRows),
02153d58 218 fID(trk.fID),
9333290e 219 fCharge(trk.fCharge),
e1c744ca 220 fType(trk.fType),
a7d9ab9e 221 fCaloIndex(trk.fCaloIndex),
9333290e 222 fCovMatrix(NULL),
7be1db84 223 fDetPid(NULL),
00a38d07 224 fDetectorPID(NULL),
ed15417e 225 fProdVertex(trk.fProdVertex),
226 fTrackPhiOnEMCal(trk.fTrackPhiOnEMCal),
aab77ed0 227 fTrackEtaOnEMCal(trk.fTrackEtaOnEMCal),
539a5a59 228 fTPCsignalTuned(trk.fTPCsignalTuned),
aab77ed0 229 fAODEvent(trk.fAODEvent)
df9db588 230{
231 // Copy constructor
232
233 trk.GetP(fMomentum);
234 trk.GetPosition(fPosition);
6c954176 235 SetXYAtDCA(trk.XAtDCA(), trk.YAtDCA());
236 SetPxPyPzAtDCA(trk.PxAtDCA(), trk.PyAtDCA(), trk.PzAtDCA());
1912763f 237 SetUsedForVtxFit(trk.GetUsedForVtxFit());
dc825b15 238 SetUsedForPrimVtxFit(trk.GetUsedForPrimVtxFit());
5d62ce04 239 if(trk.fCovMatrix) fCovMatrix=new AliAODRedCov<6>(*trk.fCovMatrix);
7be1db84 240 if(trk.fDetPid) fDetPid=new AliAODPid(*trk.fDetPid);
df9db588 241 SetPID(trk.fPID);
00a38d07 242 if (trk.fDetectorPID) fDetectorPID = new AliDetectorPID(*trk.fDetectorPID);
df9db588 243}
244
245//______________________________________________________________________________
246AliAODTrack& AliAODTrack::operator=(const AliAODTrack& trk)
247{
248 // Assignment operator
249 if(this!=&trk) {
250
4f6e22bd 251 AliVTrack::operator=(trk);
df9db588 252
253 trk.GetP(fMomentum);
254 trk.GetPosition(fPosition);
6c954176 255 SetXYAtDCA(trk.XAtDCA(), trk.YAtDCA());
256 SetPxPyPzAtDCA(trk.PxAtDCA(), trk.PyAtDCA(), trk.PzAtDCA());
05f9607e 257 fRAtAbsorberEnd = trk.fRAtAbsorberEnd;
258 fChi2perNDF = trk.fChi2perNDF;
259 fChi2MatchTrigger = trk.fChi2MatchTrigger;
260 trk.GetPID(fPID);
261 fFlags = trk.fFlags;
262 fLabel = trk.fLabel;
9333290e 263 fITSMuonClusterMap = trk.fITSMuonClusterMap;
0a2dcc83 264 fMUONtrigHitsMapTrg = trk.fMUONtrigHitsMapTrg;
265 fMUONtrigHitsMapTrk = trk.fMUONtrigHitsMapTrk;
05f9607e 266 fFilterMap = trk.fFilterMap;
bcabd0e4 267 fTPCFitMap = trk.fTPCFitMap;
05f9607e 268 fTPCClusterMap = trk.fTPCClusterMap;
269 fTPCSharedMap = trk.fTPCSharedMap;
270 fTPCnclsF = trk.fTPCnclsF;
820214a7 271 fTPCNCrossedRows = trk.fTPCNCrossedRows;
05f9607e 272 fID = trk.fID;
273 fCharge = trk.fCharge;
274 fType = trk.fType;
275 fCaloIndex = trk.fCaloIndex;
ed15417e 276 fTrackPhiOnEMCal = trk.fTrackPhiOnEMCal;
277 fTrackEtaOnEMCal = trk.fTrackEtaOnEMCal;
539a5a59 278 fTPCsignalTuned = trk.fTPCsignalTuned;
a7d9ab9e 279
df9db588 280 delete fCovMatrix;
5d62ce04 281 if(trk.fCovMatrix) fCovMatrix=new AliAODRedCov<6>(*trk.fCovMatrix);
df9db588 282 else fCovMatrix=NULL;
df9db588 283
05f9607e 284
285 fProdVertex = trk.fProdVertex;
1912763f 286 SetUsedForVtxFit(trk.GetUsedForVtxFit());
dc825b15 287 SetUsedForPrimVtxFit(trk.GetUsedForPrimVtxFit());
7be1db84 288
00a38d07 289 //detector raw signals
7be1db84 290 delete fDetPid;
291 if(trk.fDetPid) fDetPid=new AliAODPid(*trk.fDetPid);
292 else fDetPid=NULL;
05f9607e 293
00a38d07 294 //calibrated PID cache
295 delete fDetectorPID;
296 fDetectorPID=0x0;
297 if (trk.fDetectorPID) fDetectorPID = new AliDetectorPID(*trk.fDetectorPID);
df9db588 298 }
299
300 return *this;
301}
302
4697e4fb 303//______________________________________________________________________________
304Double_t AliAODTrack::M(AODTrkPID_t pid) const
305{
306 // Returns the mass.
9861edc0 307 // Masses for nuclei don't exist in the PDG tables, therefore they were put by hand.
4697e4fb 308
309 switch (pid) {
310
311 case kElectron :
9861edc0 312 return 0.000510999; //TDatabasePDG::Instance()->GetParticle(11/*::kElectron*/)->Mass();
4697e4fb 313 break;
314
315 case kMuon :
9861edc0 316 return 0.1056584; //TDatabasePDG::Instance()->GetParticle(13/*::kMuonMinus*/)->Mass();
4697e4fb 317 break;
318
319 case kPion :
9861edc0 320 return 0.13957; //TDatabasePDG::Instance()->GetParticle(211/*::kPiPlus*/)->Mass();
4697e4fb 321 break;
322
323 case kKaon :
9861edc0 324 return 0.4937; //TDatabasePDG::Instance()->GetParticle(321/*::kKPlus*/)->Mass();
4697e4fb 325 break;
326
327 case kProton :
9861edc0 328 return 0.9382720; //TDatabasePDG::Instance()->GetParticle(2212/*::kProton*/)->Mass();
4697e4fb 329 break;
330
331 case kDeuteron :
9861edc0 332 return 1.8756; //TDatabasePDG::Instance()->GetParticle(1000010020)->Mass();
4697e4fb 333 break;
334
335 case kTriton :
9861edc0 336 return 2.8089; //TDatabasePDG::Instance()->GetParticle(1000010030)->Mass();
4697e4fb 337 break;
338
339 case kHelium3 :
9861edc0 340 return 2.8084; //TDatabasePDG::Instance()->GetParticle(1000020030)->Mass();
4697e4fb 341 break;
342
343 case kAlpha :
9861edc0 344 return 3.7274; //TDatabasePDG::Instance()->GetParticle(1000020040)->Mass();
4697e4fb 345 break;
346
347 case kUnknown :
348 return -999.;
349 break;
350
351 default :
352 return -999.;
353 }
354}
355
356//______________________________________________________________________________
357Double_t AliAODTrack::E(AODTrkPID_t pid) const
358{
359 // Returns the energy of the particle of a given pid.
360
361 if (pid != kUnknown) { // particle was identified
362 Double_t m = M(pid);
363 return TMath::Sqrt(P()*P() + m*m);
364 } else { // pid unknown
365 return -999.;
366 }
367}
368
369//______________________________________________________________________________
370Double_t AliAODTrack::Y(AODTrkPID_t pid) const
371{
9861edc0 372 // Returns the rapidity of a particle of a given pid.
4697e4fb 373
374 if (pid != kUnknown) { // particle was identified
375 Double_t e = E(pid);
376 Double_t pz = Pz();
377 if (e>=0 && e!=pz) { // energy was positive (e.g. not -999.) and not equal to pz
378 return 0.5*TMath::Log((e+pz)/(e-pz));
379 } else { // energy not known or equal to pz
380 return -999.;
381 }
382 } else { // pid unknown
383 return -999.;
384 }
385}
386
387//______________________________________________________________________________
388Double_t AliAODTrack::Y(Double_t m) const
389{
9861edc0 390 // Returns the rapidity of a particle of a given mass.
4697e4fb 391
392 if (m >= 0.) { // mass makes sense
393 Double_t e = E(m);
394 Double_t pz = Pz();
395 if (e>=0 && e!=pz) { // energy was positive (e.g. not -999.) and not equal to pz
396 return 0.5*TMath::Log((e+pz)/(e-pz));
397 } else { // energy not known or equal to pz
398 return -999.;
399 }
400 } else { // pid unknown
401 return -999.;
402 }
403}
404
405//______________________________________________________________________________
406AliAODTrack::AODTrkPID_t AliAODTrack::GetMostProbablePID() const
407{
408 // Returns the most probable PID array element.
409
410 Int_t nPID = 10;
7ba6f91a 411 AODTrkPID_t loc = kUnknown;
412 Double_t max = 0.;
413 Bool_t allTheSame = kTRUE;
414
415 for (Int_t iPID = 0; iPID < nPID; iPID++) {
416 if (fPID[iPID] >= max) {
417 if (fPID[iPID] > max) {
418 allTheSame = kFALSE;
419 max = fPID[iPID];
420 loc = (AODTrkPID_t)iPID;
421 } else {
422 allTheSame = kTRUE;
4697e4fb 423 }
424 }
4697e4fb 425 }
7ba6f91a 426 return allTheSame ? kUnknown : loc;
4697e4fb 427}
428
429//______________________________________________________________________________
430void AliAODTrack::ConvertAliPIDtoAODPID()
431{
432 // Converts AliPID array.
433 // The numbering scheme is the same for electrons, muons, pions, kaons, and protons.
434 // Everything else has to be set to zero.
435
436 fPID[kDeuteron] = 0.;
8a1418dc 437 fPID[kTriton] = 0.;
438 fPID[kHelium3] = 0.;
439 fPID[kAlpha] = 0.;
440 fPID[kUnknown] = 0.;
4697e4fb 441
442 return;
443}
444
445
df9db588 446//______________________________________________________________________________
cdd730d0 447template <typename T> void AliAODTrack::SetP(const T *p, const Bool_t cartesian)
df9db588 448{
8a1418dc 449 // Set the momentum
df9db588 450
451 if (p) {
452 if (cartesian) {
16b65f2a 453 Double_t pt2 = p[0]*p[0] + p[1]*p[1];
0c5f89fb 454 Double_t pp = TMath::Sqrt(pt2 + p[2]*p[2]);
df9db588 455
16b65f2a 456 fMomentum[0] = TMath::Sqrt(pt2); // pt
b1a9edc8 457 fMomentum[1] = (pt2 != 0.) ? TMath::Pi()+TMath::ATan2(-p[1], -p[0]) : -999; // phi
0c5f89fb 458 fMomentum[2] = (pp != 0.) ? TMath::ACos(p[2] / pp) : -999.; // theta
df9db588 459 } else {
16b65f2a 460 fMomentum[0] = p[0]; // pt
df9db588 461 fMomentum[1] = p[1]; // phi
462 fMomentum[2] = p[2]; // theta
463 }
464 } else {
465 fMomentum[0] = -999.;
466 fMomentum[1] = -999.;
467 fMomentum[2] = -999.;
468 }
469}
470
6e78367a 471/*
df9db588 472//______________________________________________________________________________
cdd730d0 473template <typename T> void AliAODTrack::SetPosition(const T *x, const Bool_t dca)
df9db588 474{
475 // set the position
476
477 if (x) {
478 if (!dca) {
479 ResetBit(kIsDCA);
480
481 fPosition[0] = x[0];
482 fPosition[1] = x[1];
483 fPosition[2] = x[2];
484 } else {
485 SetBit(kIsDCA);
486 // don't know any better yet
487 fPosition[0] = -999.;
488 fPosition[1] = -999.;
489 fPosition[2] = -999.;
490 }
491 } else {
492 ResetBit(kIsDCA);
493
494 fPosition[0] = -999.;
495 fPosition[1] = -999.;
496 fPosition[2] = -999.;
497 }
498}
6e78367a 499*/
df9db588 500//______________________________________________________________________________
501void AliAODTrack::SetDCA(Double_t d, Double_t z)
502{
503 // set the dca
504 fPosition[0] = d;
505 fPosition[1] = z;
506 fPosition[2] = 0.;
507 SetBit(kIsDCA);
508}
509
510//______________________________________________________________________________
511void AliAODTrack::Print(Option_t* /* option */) const
512{
513 // prints information about AliAODTrack
514
515 printf("Object name: %s Track type: %s\n", GetName(), GetTitle());
516 printf(" px = %f\n", Px());
517 printf(" py = %f\n", Py());
518 printf(" pz = %f\n", Pz());
519 printf(" pt = %f\n", Pt());
520 printf(" 1/pt = %f\n", OneOverPt());
521 printf(" theta = %f\n", Theta());
522 printf(" phi = %f\n", Phi());
1912763f 523 printf(" chi2/NDF = %f\n", Chi2perNDF());
df9db588 524 printf(" charge = %d\n", Charge());
df9db588 525}
526
2200238e 527//______________________________________________________________________________
528void AliAODTrack::SetMatchTrigger(Int_t matchTrig)
529{
530 // Set the MUON trigger information
8ac4fa64 531 switch(matchTrig){
e1c744ca 532 case 0: // 0 track does not match trigger
533 fITSMuonClusterMap=fITSMuonClusterMap&0x3fffffff;
534 break;
535 case 1: // 1 track match but does not pass pt cut
536 fITSMuonClusterMap=(fITSMuonClusterMap&0x3fffffff)|0x40000000;
537 break;
538 case 2: // 2 track match Low pt cut
539 fITSMuonClusterMap=(fITSMuonClusterMap&0x3fffffff)|0x80000000;
540 break;
541 case 3: // 3 track match High pt cut
542 fITSMuonClusterMap=fITSMuonClusterMap|0xc0000000;
543 break;
544 default:
545 fITSMuonClusterMap=fITSMuonClusterMap&0x3fffffff;
8ac4fa64 546 AliWarning(Form("unknown case for matchTrig: %d\n",matchTrig));
e1c744ca 547 }
548}
549
2200238e 550//______________________________________________________________________________
551Bool_t AliAODTrack::HitsMuonChamber(Int_t MuonChamber, Int_t cathode) const
552{
553 // return kTRUE if the track fires the given tracking or trigger chamber.
554 // If the chamber is a trigger one:
555 // - if cathode = 0 or 1, the track matches the corresponding cathode
556 // - if cathode = -1, the track matches both cathodes
557
558 if (MuonChamber < 0) return kFALSE;
559
560 if (MuonChamber < 10) return TESTBIT(GetMUONClusterMap(), MuonChamber);
561
562 if (MuonChamber < 14) {
563
564 if (cathode < 0) return TESTBIT(GetHitsPatternInTrigCh(), 13-MuonChamber) &&
565 TESTBIT(GetHitsPatternInTrigCh(), 13-MuonChamber+4);
566
567 if (cathode < 2) return TESTBIT(GetHitsPatternInTrigCh(), 13-MuonChamber+(1-cathode)*4);
568
e1c744ca 569 }
2200238e 570
571 return kFALSE;
e1c744ca 572}
573
2200238e 574//______________________________________________________________________________
575Bool_t AliAODTrack::MatchTriggerDigits() const
576{
577 // return kTRUE if the track matches a digit on both planes of at least 2 trigger chambers
6c954176 578
2200238e 579 Int_t nMatchedChambers = 0;
580 for (Int_t ich=10; ich<14; ich++) if (HitsMuonChamber(ich)) nMatchedChambers++;
581
582 return (nMatchedChambers >= 2);
e1c744ca 583}
c683ddc2 584
6dc40b1c 585//______________________________________________________________________________
586Bool_t AliAODTrack::PropagateToDCA(const AliVVertex *vtx,
587 Double_t b, Double_t maxd, Double_t dz[2], Double_t covar[3])
588{
589 // compute impact parameters to the vertex vtx and their covariance matrix
590 // b is the Bz, needed to propagate correctly the track to vertex
591 // only the track parameters are update after the propagation (pos and mom),
592 // not the covariance matrix. This is OK for propagation over short distance
593 // inside the beam pipe.
594 // return kFALSE is something went wrong
595
596 // convert to AliExternalTrackParam
4ec1ca0f 597 AliExternalTrackParam etp; etp.CopyFromVTrack(this);
6dc40b1c 598
599 Float_t xstart = etp.GetX();
600 if(xstart>3.) {
601 AliError("This method can be used only for propagation inside the beam pipe");
602 return kFALSE;
603 }
604
605 if(!etp.PropagateToDCA(vtx,b,maxd,dz,covar)) return kFALSE;
606
607 // update track position and momentum
608 Double_t mom[3];
609 etp.GetPxPyPz(mom);
610 SetP(mom,kTRUE);
611 etp.GetXYZ(mom);
612 SetPosition(mom,kFALSE);
613
614
615 return kTRUE;
616}
617
c8fe2783 618//______________________________________________________________________________
619Bool_t AliAODTrack::GetPxPyPz(Double_t p[3]) const
620{
621 //---------------------------------------------------------------------
622 // This function returns the global track momentum components
623 //---------------------------------------------------------------------
624 p[0]=Px(); p[1]=Py(); p[2]=Pz();
625 return kTRUE;
626}
9006fe9c 627
25f906db 628
629//_______________________________________________________________________
630Float_t AliAODTrack::GetTPCClusterInfo(Int_t nNeighbours/*=3*/, Int_t type/*=0*/, Int_t row0, Int_t row1, Int_t bitType ) const
9006fe9c 631{
632 //
25f906db 633 // TPC cluster information
9006fe9c 634 // type 0: get fraction of found/findable clusters with neighbourhood definition
635 // 1: findable clusters with neighbourhood definition
636 // 2: found clusters
25f906db 637 // bitType:
638 // 0 - all cluster used
639 // 1 - clusters used for the kalman update
9006fe9c 640 // definition of findable clusters:
641 // a cluster is defined as findable if there is another cluster
642 // within +- nNeighbours pad rows. The idea is to overcome threshold
643 // effects with a very simple algorithm.
644 //
25f906db 645
9006fe9c 646
647 Int_t found=0;
648 Int_t findable=0;
649 Int_t last=-nNeighbours;
25f906db 650 const TBits & clusterMap = (bitType%2==0) ? fTPCClusterMap : fTPCFitMap;
9006fe9c 651
25f906db 652 Int_t upperBound=clusterMap.GetNbits();
653 if (upperBound>row1) upperBound=row1;
654 for (Int_t i=row0; i<upperBound; ++i){
9006fe9c 655 //look to current row
25f906db 656 if (clusterMap[i]) {
9006fe9c 657 last=i;
658 ++found;
659 ++findable;
660 continue;
661 }
662 //look to nNeighbours before
663 if ((i-last)<=nNeighbours) {
664 ++findable;
665 continue;
666 }
667 //look to nNeighbours after
668 for (Int_t j=i+1; j<i+1+nNeighbours; ++j){
25f906db 669 if (clusterMap[j]){
9006fe9c 670 ++findable;
671 break;
672 }
673 }
674 }
25f906db 675 if (type==2) return found;
9006fe9c 676 if (type==1) return findable;
677
678 if (type==0){
679 Float_t fraction=0;
25f906db 680 if (findable>0)
9006fe9c 681 fraction=(Float_t)found/(Float_t)findable;
25f906db 682 else
9006fe9c 683 fraction=0;
684 return fraction;
25f906db 685 }
9006fe9c 686 return 0; // undefined type - default value
687}
fd21ec8d 688
25f906db 689
fd21ec8d 690//______________________________________________________________________________
691Double_t AliAODTrack::GetTRDslice(Int_t plane, Int_t slice) const {
692 //
693 // return TRD Pid information
694 //
695 if (!fDetPid) return -1;
6736efd5 696 Double32_t *trdSlices=fDetPid->GetTRDslices();
fd21ec8d 697 if (!trdSlices) return -1;
698 if ((plane<0) || (plane>=kTRDnPlanes)) {
699 return -1.;
700 }
701
99e9d5ec 702 Int_t ns=fDetPid->GetTRDnSlices()/kTRDnPlanes;
fd21ec8d 703 if ((slice<-1) || (slice>=ns)) {
704 return -1.;
705 }
706
707 if(slice>=0) return trdSlices[plane*ns + slice];
708
709 // return average of the dEdx measurements
710 Double_t q=0.; Double32_t *s = &trdSlices[plane*ns];
711 for (Int_t i=0; i<ns; i++, s++) if((*s)>0.) q+=(*s);
712 return q/ns;
713}
714
99e9d5ec 715//______________________________________________________________________________
716UChar_t AliAODTrack::GetTRDntrackletsPID() const{
717 //
718 // return number of tracklets calculated from the slices
719 //
720 if(!fDetPid) return -1;
59a8e853 721 return fDetPid->GetTRDntrackletsPID();
722}
99e9d5ec 723
59a8e853 724//______________________________________________________________________________
725UChar_t AliAODTrack::GetTRDncls(Int_t layer) const {
726 //
727 // return number of TRD clusters
728 //
729 if(!fDetPid || layer > 5) return -1;
730 if(layer < 0) return fDetPid->GetTRDncls();
731 else return fDetPid->GetTRDncls(layer);
99e9d5ec 732}
733
fd21ec8d 734//______________________________________________________________________________
735Double_t AliAODTrack::GetTRDmomentum(Int_t plane, Double_t */*sp*/) const
736{
737 //Returns momentum estimation
738 // in TRD layer "plane".
739
740 if (!fDetPid) return -1;
c997f0f9 741 const Double_t *trdMomentum=fDetPid->GetTRDmomentum();
fd21ec8d 742
743 if (!trdMomentum) {
744 return -1.;
745 }
746 if ((plane<0) || (plane>=kTRDnPlanes)) {
747 return -1.;
748 }
749
750 return trdMomentum[plane];
751}
76e6ee6a 752
753//_______________________________________________________________________
1cecd6e3 754Int_t AliAODTrack::GetTOFBunchCrossing(Double_t b, Bool_t) const
76e6ee6a 755{
756 // Returns the number of bunch crossings after trigger (assuming 25ns spacing)
76e6ee6a 757 const double kSpacing = 25e3; // min interbanch spacing
758 const double kShift = 0;
3f2db92f 759 Int_t bcid = kTOFBCNA; // defualt one
a512bf97 760 if (!IsOn(kTOFout) || !IsOn(kESDpid)) return bcid; // no info
761 //
762 double tdif = GetTOFsignal();
763 if (IsOn(kTIME)) { // integrated time info is there
764 int pid = (int)GetMostProbablePID();
765 double ttimes[10];
766 GetIntegratedTimes(ttimes);
767 tdif -= ttimes[pid];
768 }
769 else { // assume integrated time info from TOF radius and momentum
770 const double kRTOF = 385.;
771 const double kCSpeed = 3.e-2; // cm/ps
772 double p = P();
773 if (p<0.001) p = 1.0;
774 double m = M();
775 double path = kRTOF; // mean TOF radius
776 if (TMath::Abs(b)>kAlmost0) { // account for curvature
777 double curv = Pt()/(b*kB2C);
778 if (curv>kAlmost0) {
779 double tgl = Pz()/Pt();
780 path = 2./curv*TMath::ASin(kRTOF*curv/2.)*TMath::Sqrt(1.+tgl*tgl);
781 }
782 }
783 tdif -= path/kCSpeed*TMath::Sqrt(1.+m*m/(p*p));
784 }
76e6ee6a 785 bcid = TMath::Nint((tdif - kShift)/kSpacing);
786 return bcid;
787}
086400fc 788
00a38d07 789void AliAODTrack::SetDetectorPID(const AliDetectorPID *pid)
790{
791 //
792 // Set the detector PID
793 //
794 if (fDetectorPID) delete fDetectorPID;
795 fDetectorPID=pid;
796
797}
798
567624b5 799//_____________________________________________________________________________
800Double_t AliAODTrack::GetHMPIDsignal() const
801{
802 if(fAODEvent->GetHMPIDringForTrackID(fID)) return fAODEvent->GetHMPIDringForTrackID(fID)->GetHmpSignal();
803 else return -999.;
804}
805
806//_____________________________________________________________________________
807Double_t AliAODTrack::GetHMPIDoccupancy() const
808{
809 if(fAODEvent->GetHMPIDringForTrackID(fID)) return fAODEvent->GetHMPIDringForTrackID(fID)->GetHmpOccupancy();
810 else return -999.;
811}
812
813//_____________________________________________________________________________
814Int_t AliAODTrack::GetHMPIDcluIdx() const
815{
816 if(fAODEvent->GetHMPIDringForTrackID(fID)) return fAODEvent->GetHMPIDringForTrackID(fID)->GetHmpCluIdx();
817 else return -999;
818}
819
820//_____________________________________________________________________________
821void AliAODTrack::GetHMPIDtrk(Float_t &x, Float_t &y, Float_t &th, Float_t &ph) const
822{
823 x = -999; y = -999.; th = -999.; ph = -999.;
824
825 const AliAODHMPIDrings *ring=fAODEvent->GetHMPIDringForTrackID(fID);
826 if(ring){
827 x = ring->GetHmpTrackX();
828 y = ring->GetHmpTrackY();
829 th = ring->GetHmpTrackTheta();
830 ph = ring->GetHmpTrackPhi();
831 }
832}
833
834//_____________________________________________________________________________
835void AliAODTrack::GetHMPIDmip(Float_t &x,Float_t &y,Int_t &q, Int_t &nph) const
836{
837 x = -999; y = -999.; q = -999; nph = -999;
838
839 const AliAODHMPIDrings *ring=fAODEvent->GetHMPIDringForTrackID(fID);
840 if(ring){
841 x = ring->GetHmpMipX();
842 y = ring->GetHmpMipY();
843 q = (Int_t)ring->GetHmpMipCharge();
844 nph = (Int_t)ring->GetHmpNumOfPhotonClusters();
845 }
846}
847
848//_____________________________________________________________________________
849Bool_t AliAODTrack::GetOuterHmpPxPyPz(Double_t *p) const
850{
851 if(fAODEvent->GetHMPIDringForTrackID(fID)) {fAODEvent->GetHMPIDringForTrackID(fID)->GetHmpMom(p); return kTRUE;}
852
853 else return kFALSE;
854}
086400fc 855//_____________________________________________________________________________
856Bool_t AliAODTrack::GetXYZAt(Double_t x, Double_t b, Double_t *r) const
857{
858 //---------------------------------------------------------------------
859 // This function returns the global track position extrapolated to
860 // the radial position "x" (cm) in the magnetic field "b" (kG)
861 //---------------------------------------------------------------------
862
863 //conversion of track parameter representation is
864 //based on the implementation of AliExternalTrackParam::Set(...)
865 //maybe some of this code can be moved to AliVTrack to avoid code duplication
866 const double kSafe = 1e-5;
867 Double_t alpha=0.0;
868 Double_t radPos2 = fPosition[0]*fPosition[0]+fPosition[1]*fPosition[1];
869 Double_t radMax = 45.; // approximately ITS outer radius
870 if (radPos2 < radMax*radMax) { // inside the ITS
871 alpha = TMath::ATan2(fMomentum[1],fMomentum[0]);
872 } else { // outside the ITS
873 Float_t phiPos = TMath::Pi()+TMath::ATan2(-fPosition[1], -fPosition[0]);
874 alpha =
875 TMath::DegToRad()*(20*((((Int_t)(phiPos*TMath::RadToDeg()))/20))+10);
876 }
877 //
878 Double_t cs=TMath::Cos(alpha), sn=TMath::Sin(alpha);
879 // protection: avoid alpha being too close to 0 or +-pi/2
880 if (TMath::Abs(sn)<kSafe) {
881 alpha = kSafe;
882 cs=TMath::Cos(alpha);
883 sn=TMath::Sin(alpha);
884 }
885 else if (cs<kSafe) {
886 alpha -= TMath::Sign(kSafe, alpha);
887 cs=TMath::Cos(alpha);
888 sn=TMath::Sin(alpha);
889 }
890
891 // Get the vertex of origin and the momentum
892 TVector3 ver(fPosition[0],fPosition[1],fPosition[2]);
893 TVector3 mom(fMomentum[0],fMomentum[1],fMomentum[2]);
894 //
895 // avoid momenta along axis
896 if (TMath::Abs(mom[0])<kSafe) mom[0] = TMath::Sign(kSafe*TMath::Abs(mom[1]), mom[0]);
897 if (TMath::Abs(mom[1])<kSafe) mom[1] = TMath::Sign(kSafe*TMath::Abs(mom[0]), mom[1]);
898
899 // Rotate to the local coordinate system
900 ver.RotateZ(-alpha);
901 mom.RotateZ(-alpha);
902
903 Double_t param0 = ver.Y();
904 Double_t param1 = ver.Z();
905 Double_t param2 = TMath::Sin(mom.Phi());
906 Double_t param3 = mom.Pz()/mom.Pt();
907 Double_t param4 = TMath::Sign(1/mom.Pt(),(Double_t)fCharge);
908
909 //calculate the propagated coordinates
910 //this is based on AliExternalTrackParam::GetXYZAt(Double_t x, Double_t b, Double_t *r)
911 Double_t dx=x-ver.X();
912 if(TMath::Abs(dx)<=kAlmost0) return GetXYZ(r);
913
914 Double_t f1=param2;
915 Double_t f2=f1 + dx*param4*b*kB2C;
916
917 if (TMath::Abs(f1) >= kAlmost1) return kFALSE;
918 if (TMath::Abs(f2) >= kAlmost1) return kFALSE;
919
920 Double_t r1=TMath::Sqrt((1.-f1)*(1.+f1)), r2=TMath::Sqrt((1.-f2)*(1.+f2));
921 r[0] = x;
922 r[1] = param0 + dx*(f1+f2)/(r1+r2);
923 r[2] = param1 + dx*(r2 + f2*(f1+f2)/(r1+r2))*param3;//Thanks to Andrea & Peter
924
925 return Local2GlobalPosition(r,alpha);
926}
927
928
74ca66e3 929//_______________________________________________________
930void AliAODTrack::GetITSdEdxSamples(Double_t s[4]) const
931{
932 // get ITS dedx samples
933 if (!fDetPid) for (int i=4;i--;) s[i]=0;
934 else for (int i=4;i--;) s[i] = fDetPid->GetITSdEdxSample(i);
935}